From 1f2f436a38f7ae2d39a943ad2898d8fed4ed2e58 Mon Sep 17 00:00:00 2001 From: Apple Date: Wed, 20 Jul 2011 19:30:47 +0000 Subject: [PATCH] Libc-763.11.tar.gz --- BSDmakefile | 60 +- Makefile | 13 +- Makefile.features | 28 +- Makefile.xbs | 50 +- Platforms/AppleTV/Makefile.inc | 56 - Platforms/AppleTV/i386/libc.syscall.i386 | 46 - Platforms/MacOSX/Makefile.inc | 6 +- Platforms/MacOSX/arm/libc.syscall.arm | 89 - Platforms/MacOSX/i386/libc.syscall.i386 | 89 - Platforms/MacOSX/ppc/libc.syscall.ppc | 89 - Platforms/MacOSX/ppc64/libc.syscall.ppc64 | 31 - Platforms/MacOSX/x86_64/libc.syscall.x86_64 | 31 - Platforms/iPhone/Makefile.inc | 10 +- Platforms/iPhone/arm/libc.syscall.arm | 45 - arm/gen/Makefile.inc | 6 +- .../gen/cpu_number.s | 20 +- arm/pthreads/Makefile.inc | 4 + arm/pthreads/pthread_getspecific.s | 3 +- arm/pthreads/pthread_self.s | 2 + arm/string/Makefile.inc | 49 +- arm/string/NEON/bcopy.s | 433 -- arm/string/NEON/bzero.s | 171 - arm/string/bcopy.s | 415 -- arm/string/bcopy_CortexA8.s | 0 arm/string/bcopy_CortexA9.s | 0 arm/string/bcopy_Generic.s | 0 arm/string/bzero.s | 173 - arm/string/bzero_CortexA8.s | 0 arm/string/bzero_CortexA9.s | 0 arm/string/bzero_Generic.s | 0 arm/string/dyld_resolvers.c | 65 + arm/string/ffs.s | 50 - arm/string/memcmp.s | 105 - arm/string/memset_pattern.s | 351 -- arm/string/strchr.s | 0 arm/string/strcmp.s | 44 - arm/string/strcpy.s | 0 arm/string/strlcpy.s | 0 arm/string/strlen.s | 78 - arm/string/strncmp.s | 0 arm/string/strncpy.s | 0 arm/string/strnlen.s | 0 arm/string/strstr.s | 0 arm/sys/Makefile.inc | 9 +- arm/sys/OSAtomic-v4.c | 23 + arm/sys/OSAtomic.s | 526 ++- arm/sys/OSAtomic_resolvers.c | 74 + arm/sys/OSAtomic_resolvers.h | 59 + arm/sys/gcc_atomic.c | 31 +- sys/rmdir.c => arm/sys/mach_absolute_time.s | 23 +- compat-43/FreeBSD/creat.2 | 6 +- compat-43/FreeBSD/creat.c | 6 +- compat-43/FreeBSD/creat.c.patch | 8 +- compat-43/FreeBSD/gethostid.3 | 10 +- compat-43/FreeBSD/gethostid.3.patch | 6 +- compat-43/FreeBSD/gethostid.c | 8 +- compat-43/FreeBSD/gethostid.c.patch | 11 + compat-43/FreeBSD/getwd.c | 11 +- compat-43/FreeBSD/killpg.2 | 10 +- compat-43/FreeBSD/killpg.2.patch | 8 +- compat-43/FreeBSD/killpg.c | 6 +- compat-43/FreeBSD/killpg.c.patch | 8 +- compat-43/FreeBSD/sethostid.c | 14 +- compat-43/FreeBSD/setpgrp.c | 6 +- compat-43/FreeBSD/setpgrp.c.patch | 6 +- compat-43/FreeBSD/setrgid.c | 6 +- compat-43/FreeBSD/setruid.3 | 12 +- compat-43/FreeBSD/setruid.c | 6 +- compat-43/creat-fbsd.c | 6 +- compat-43/gethostid-fbsd.c | 55 +- compat-43/gethostid.3 | 10 +- compat-43/killpg-fbsd.c | 6 +- compat-43/killpg.2 | 10 +- compat-43/setpgrp-fbsd.c | 6 +- darwin/Makefile.inc | 3 +- darwin/_dirhelper.c | 163 +- darwin/dirhelper_priv.h | 8 +- darwin/libproc.c | 270 +- darwin/libproc.h | 28 +- darwin/libproc_internal.h | 86 + db/btree/FreeBSD/bt_close.c | 16 +- db/btree/FreeBSD/bt_conv.c | 19 +- db/btree/FreeBSD/bt_debug.c | 40 +- db/btree/FreeBSD/bt_delete.c | 116 +- db/btree/FreeBSD/bt_get.c | 12 +- db/btree/FreeBSD/bt_open.c | 43 +- db/btree/FreeBSD/bt_overflow.c | 24 +- db/btree/FreeBSD/bt_overflow.c.patch | 8 +- db/btree/FreeBSD/bt_page.c | 14 +- db/btree/FreeBSD/bt_put.c | 51 +- db/btree/FreeBSD/bt_search.c | 35 +- db/btree/FreeBSD/bt_seq.c | 59 +- db/btree/FreeBSD/bt_seq.c.patch | 6 +- db/btree/FreeBSD/bt_split.c | 63 +- db/btree/FreeBSD/bt_split.c.patch | 14 +- db/btree/FreeBSD/bt_utils.c | 34 +- db/btree/FreeBSD/btree.h | 10 +- db/btree/FreeBSD/btree.h.patch | 6 +- db/btree/FreeBSD/extern.h | 6 +- db/btree/bt_overflow-fbsd.c | 24 +- db/btree/bt_seq-fbsd.c | 59 +- db/btree/bt_split-fbsd.c | 63 +- db/btree/btree.h | 10 +- db/hash/FreeBSD/extern.h | 6 +- db/hash/FreeBSD/hash.c | 171 +- db/hash/FreeBSD/hash.c.patch | 10 +- db/hash/FreeBSD/hash.h | 40 +- db/hash/FreeBSD/hash.h.patch | 6 +- db/hash/FreeBSD/hash_bigkey.c | 124 +- db/hash/FreeBSD/hash_bigkey.c.patch | 6 +- db/hash/FreeBSD/hash_buf.c | 78 +- db/hash/FreeBSD/hash_buf.c.patch | 15 +- db/hash/FreeBSD/hash_func.c | 6 +- db/hash/FreeBSD/hash_func.c.patch | 6 +- db/hash/FreeBSD/hash_log2.c | 14 +- db/hash/FreeBSD/hash_log2.c.patch | 11 + db/hash/FreeBSD/hash_page.c | 188 +- db/hash/FreeBSD/hash_page.c.patch | 29 +- db/hash/FreeBSD/ndbm.c | 6 +- db/hash/FreeBSD/ndbm.c.patch | 12 +- db/hash/FreeBSD/page.h | 8 +- db/hash/hash-fbsd.c | 171 +- db/hash/hash.h | 40 +- db/hash/hash_bigkey-fbsd.c | 124 +- db/hash/hash_buf-fbsd.c | 78 +- db/hash/hash_func-fbsd.c | 6 +- db/hash/hash_log2-fbsd.c | 53 +- db/hash/hash_page-fbsd.c | 185 +- db/hash/ndbm-fbsd.c | 6 +- db/man/FreeBSD/btree.3 | 6 +- db/man/FreeBSD/dbm.3 | 12 +- db/man/FreeBSD/dbm.3.patch | 20 +- db/man/FreeBSD/dbopen.3 | 14 +- db/man/FreeBSD/hash.3 | 6 +- db/man/FreeBSD/mpool.3 | 8 +- db/man/FreeBSD/recno.3 | 6 +- db/man/dbm.3 | 12 +- db/mpool/FreeBSD/mpool.c | 61 +- db/mpool/FreeBSD/mpool.c.patch | 12 +- db/mpool/mpool-fbsd.c | 61 +- db/recno/FreeBSD/extern.h | 6 +- db/recno/FreeBSD/extern.h.patch | 8 +- db/recno/FreeBSD/rec_close.c | 22 +- db/recno/FreeBSD/rec_delete.c | 28 +- db/recno/FreeBSD/rec_get.c | 40 +- db/recno/FreeBSD/rec_open.c | 17 +- db/recno/FreeBSD/rec_put.c | 40 +- db/recno/FreeBSD/rec_search.c | 33 +- db/recno/FreeBSD/rec_seq.c | 13 +- db/recno/FreeBSD/rec_utils.c | 22 +- db/recno/FreeBSD/recno.h | 6 +- db/recno/FreeBSD/recno.h.patch | 6 +- db/recno/rec_extern.h | 6 +- db/recno/recno.h | 6 +- emulated/Makefile.inc | 5 + emulated/brk.2 | 150 + emulated/brk.c | 81 + fbsdcompat/_fbsd_compat_.h | 2 + fbsdcompat/reentrant.h | 134 + gdtoa/FreeBSD/gdtoa-dtoa.c | 154 +- gdtoa/FreeBSD/gdtoa-gdtoa.c | 141 +- gdtoa/FreeBSD/gdtoa-gethex.c | 14 +- gdtoa/FreeBSD/gdtoa-gethex.c.patch | 76 +- gdtoa/FreeBSD/gdtoa-hexnan.c | 6 +- gdtoa/FreeBSD/gdtoa-hexnan.c.patch | 167 +- gdtoa/FreeBSD/gdtoa-misc.c | 82 +- gdtoa/FreeBSD/gdtoa-misc.c.patch | 53 +- gdtoa/FreeBSD/gdtoa-smisc.c | 28 +- gdtoa/FreeBSD/gdtoa-smisc.c.patch | 27 - gdtoa/FreeBSD/gdtoa-strtoIg.c | 2 +- gdtoa/FreeBSD/gdtoa-strtod.c | 353 +- gdtoa/FreeBSD/gdtoa-strtod.c.patch | 131 +- gdtoa/FreeBSD/gdtoa-strtodg.c | 134 +- gdtoa/FreeBSD/gdtoa-strtodg.c.patch | 70 +- gdtoa/FreeBSD/gdtoa-strtof.c | 2 +- gdtoa/FreeBSD/gdtoa-strtopdd.c | 36 +- gdtoa/FreeBSD/gdtoa-strtopdd.c.patch | 16 +- gdtoa/FreeBSD/gdtoa-strtopx.c | 3 +- gdtoa/FreeBSD/gdtoa-strtopx.c.patch | 14 +- gdtoa/FreeBSD/gdtoa-ulp.c | 20 +- gdtoa/FreeBSD/gdtoaimp.h | 49 +- gdtoa/FreeBSD/gdtoaimp.h.patch | 107 +- gdtoa/gdtoa-gethex-fbsd.c | 68 +- gdtoa/gdtoa-hexnan-fbsd.c | 110 +- gdtoa/gdtoa-misc-fbsd.c | 70 +- gdtoa/gdtoa-smisc-fbsd.c | 192 +- gdtoa/gdtoa-strtod-fbsd.c | 381 +- gdtoa/gdtoa-strtodg-fbsd.c | 152 +- gdtoa/gdtoa-strtof-fbsd.c | 2 +- gdtoa/gdtoa-strtopdd-fbsd.c | 36 +- gdtoa/gdtoa-strtopx-fbsd.c | 2 +- gdtoa/gdtoa.tgz | Bin 0 -> 118424 bytes gdtoa/gdtoaimp.h | 121 +- gen/FreeBSD/_rand48.c.patch | 6 +- gen/FreeBSD/alarm.3 | 6 +- gen/FreeBSD/alarm.3.patch | 6 +- gen/FreeBSD/alarm.c | 6 +- gen/FreeBSD/arc4random.3 | 28 +- gen/FreeBSD/arc4random.c | 294 +- gen/FreeBSD/arc4random.c.patch | 11 - gen/FreeBSD/assert.c | 6 +- gen/FreeBSD/assert.c.patch | 70 +- gen/FreeBSD/clock.3 | 18 +- gen/FreeBSD/clock.c | 6 +- gen/FreeBSD/closedir.c | 12 +- gen/FreeBSD/closedir.c.patch | 8 +- gen/FreeBSD/ctermid.3 | 6 +- gen/FreeBSD/ctermid.3.patch | 8 +- gen/FreeBSD/ctermid.c | 6 +- gen/FreeBSD/daemon.3 | 6 +- gen/FreeBSD/daemon.3.patch | 6 +- gen/FreeBSD/daemon.c | 7 +- gen/FreeBSD/daemon.c.patch | 12 +- gen/FreeBSD/dirname.3 | 69 +- gen/FreeBSD/dirname.3.patch | 12 +- gen/FreeBSD/dirname.c | 78 +- gen/FreeBSD/dirname.c.patch | 15 +- gen/FreeBSD/drand48.c.patch | 6 +- gen/FreeBSD/erand48.c.patch | 6 +- gen/FreeBSD/err.3 | 19 +- gen/FreeBSD/err.3.patch | 16 +- gen/FreeBSD/err.c | 30 +- gen/FreeBSD/err.c.patch | 42 +- gen/FreeBSD/exec.3 | 74 +- gen/FreeBSD/exec.3.patch | 40 +- gen/FreeBSD/exec.c | 75 +- gen/FreeBSD/exec.c.patch | 22 +- gen/FreeBSD/fmtcheck.3 | 6 +- gen/FreeBSD/fmtcheck.c | 148 +- gen/FreeBSD/fmtmsg.c | 4 +- gen/FreeBSD/fmtmsg.c.patch | 12 +- gen/FreeBSD/fnmatch.3 | 6 +- gen/FreeBSD/fnmatch.3.patch | 17 +- gen/FreeBSD/fnmatch.c | 23 +- gen/FreeBSD/fnmatch.c.patch | 69 +- gen/FreeBSD/ftok.3 | 8 +- gen/FreeBSD/ftok.3.patch | 16 +- gen/FreeBSD/getbsize.3 | 6 +- gen/FreeBSD/getcap.3 | 40 +- gen/FreeBSD/getcap.c | 23 +- gen/FreeBSD/getcap.c.patch | 22 +- gen/FreeBSD/getcwd.3 | 6 +- gen/FreeBSD/getcwd.c | 20 +- gen/FreeBSD/getcwd.c.patch | 25 +- gen/FreeBSD/gethostname.3 | 6 +- gen/FreeBSD/gethostname.3.patch | 26 +- gen/FreeBSD/gethostname.c | 10 +- gen/FreeBSD/gethostname.c.patch | 12 +- gen/FreeBSD/getlogin.c | 7 +- gen/FreeBSD/getlogin.c.patch | 18 +- gen/FreeBSD/getmntinfo.3 | 6 +- gen/FreeBSD/getmntinfo.3.patch | 91 +- gen/FreeBSD/getmntinfo.c | 6 +- gen/FreeBSD/getpagesize.3 | 6 +- gen/FreeBSD/getpagesize.c | 8 +- gen/FreeBSD/getpass.3 | 6 +- gen/FreeBSD/getprogname.3.patch | 6 +- gen/FreeBSD/getprogname.c.patch | 6 +- gen/FreeBSD/isatty.c | 6 +- gen/FreeBSD/isatty.c.patch | 6 +- gen/FreeBSD/jrand48.c.patch | 6 +- gen/FreeBSD/lcong48.c.patch | 6 +- gen/FreeBSD/lockf.3 | 11 +- gen/FreeBSD/lockf.3.patch | 14 +- gen/FreeBSD/lockf.c | 18 +- gen/FreeBSD/lockf.c.patch | 28 +- gen/FreeBSD/lrand48.c.patch | 6 +- gen/FreeBSD/makecontext.3.patch | 6 +- gen/FreeBSD/mrand48.c.patch | 6 +- gen/FreeBSD/nice.3 | 6 +- gen/FreeBSD/nice.c | 6 +- gen/FreeBSD/nice.c.patch | 13 +- gen/FreeBSD/nrand48.c.patch | 6 +- gen/FreeBSD/opendir.c | 15 +- gen/FreeBSD/opendir.c.patch | 12 +- gen/FreeBSD/pause.3 | 6 +- gen/FreeBSD/pause.c | 8 +- gen/FreeBSD/pause.c.patch | 10 +- gen/FreeBSD/popen.c | 30 +- gen/FreeBSD/popen.c.patch | 53 +- gen/FreeBSD/pselect.3.patch | 10 +- gen/FreeBSD/pselect.c.patch | 4 +- gen/FreeBSD/psignal.3 | 6 +- gen/FreeBSD/psignal.3.patch | 22 + gen/FreeBSD/psignal.c | 6 +- gen/FreeBSD/raise.3 | 6 +- gen/FreeBSD/raise.c | 6 +- gen/FreeBSD/rand48.3 | 6 +- gen/FreeBSD/rand48.3.patch | 10 +- gen/FreeBSD/rand48.h.patch | 6 +- gen/FreeBSD/readdir.c | 28 +- gen/FreeBSD/readdir.c.patch | 11 +- gen/FreeBSD/readpassphrase.3 | 56 +- gen/FreeBSD/readpassphrase.c.patch | 10 +- gen/FreeBSD/rewinddir.c | 6 +- gen/FreeBSD/scandir.3 | 6 +- gen/FreeBSD/scandir.3.patch | 16 +- gen/FreeBSD/scandir.c | 22 +- gen/FreeBSD/scandir.c.patch | 8 +- gen/FreeBSD/scandir_b.c.patch | 12 +- gen/FreeBSD/seed48.c.patch | 6 +- gen/FreeBSD/seekdir.c | 10 +- gen/FreeBSD/sethostname.c | 8 +- gen/FreeBSD/setmode.3 | 6 +- gen/FreeBSD/setmode.c | 25 +- gen/FreeBSD/setmode.c.patch | 26 +- gen/FreeBSD/setprogname.c.patch | 10 +- gen/FreeBSD/siginterrupt.3 | 6 +- gen/FreeBSD/siginterrupt.3.patch | 6 +- gen/FreeBSD/siginterrupt.c | 6 +- gen/FreeBSD/siglist.c | 7 +- gen/FreeBSD/siglist.c.patch | 6 +- gen/FreeBSD/signal.3 | 41 +- gen/FreeBSD/signal.3.patch | 24 +- gen/FreeBSD/signal.c | 6 +- gen/FreeBSD/signal.c.patch | 8 +- gen/FreeBSD/signbit.3.patch | 6 +- gen/FreeBSD/sleep.3 | 6 +- gen/FreeBSD/sleep.3.patch | 8 +- gen/FreeBSD/sleep.c | 9 +- gen/FreeBSD/sleep.c.patch | 6 +- gen/FreeBSD/srand48.c.patch | 4 +- gen/FreeBSD/stringlist.3 | 4 +- gen/FreeBSD/stringlist.c | 5 +- gen/FreeBSD/sysconf.3 | 31 +- gen/FreeBSD/sysctl.3.patch | 68 +- gen/FreeBSD/sysctl.c | 6 +- gen/FreeBSD/sysctl.c.patch | 38 + gen/FreeBSD/telldir.c | 12 +- gen/FreeBSD/telldir.c.patch | 22 +- gen/FreeBSD/telldir.h | 4 +- gen/FreeBSD/telldir.h.patch | 10 +- gen/FreeBSD/termios.c | 29 +- gen/FreeBSD/termios.c.patch | 33 +- gen/FreeBSD/time.3 | 16 +- gen/FreeBSD/time.3.patch | 6 +- gen/FreeBSD/time.c | 6 +- gen/FreeBSD/time.c.patch | 8 +- gen/FreeBSD/timezone.3 | 6 +- gen/FreeBSD/timezone.c | 6 +- gen/FreeBSD/ttyname.c.patch | 40 +- gen/FreeBSD/ttyslot.c | 17 +- gen/FreeBSD/ualarm.3 | 6 +- gen/FreeBSD/ualarm.3.patch | 10 +- gen/FreeBSD/ualarm.c | 6 +- gen/FreeBSD/ulimit.3.patch | 4 +- gen/FreeBSD/unvis.3 | 6 +- gen/FreeBSD/unvis.c | 6 +- gen/FreeBSD/unvis.c.patch | 14 +- gen/FreeBSD/usleep.3 | 6 +- gen/FreeBSD/usleep.3.patch | 6 +- gen/FreeBSD/usleep.c | 12 +- gen/FreeBSD/usleep.c.patch | 22 +- gen/FreeBSD/utime.3 | 24 +- gen/FreeBSD/utime.3.patch | 20 +- gen/FreeBSD/utime.c | 6 +- gen/FreeBSD/vis.3 | 39 +- gen/FreeBSD/vis.c | 6 +- gen/FreeBSD/vis.c.patch | 16 +- gen/FreeBSD/wait.c | 6 +- gen/FreeBSD/wait.c.patch | 6 +- gen/FreeBSD/wait3.c | 6 +- gen/FreeBSD/waitpid.c | 6 +- gen/FreeBSD/waitpid.c.patch | 6 +- gen/Makefile.inc | 50 +- gen/NSSystemDirectories.c | 30 +- gen/NetBSD/endutxent.3 | 9 +- gen/NetBSD/endutxent.3.patch | 8 +- gen/NetBSD/getlastlogx.3 | 9 +- gen/NetBSD/utmpx.5 | 27 +- gen/NetBSD/utmpx.5.patch | 19 +- gen/NetBSD/utmpx.c | 52 +- gen/NetBSD/utmpx.c.patch | 501 ++- gen/_simple.c | 162 +- gen/_simple.h | 3 +- gen/alarm.3 | 6 +- gen/arc4random-fbsd.c | 294 +- gen/asl.3 | 150 +- gen/asl.c | 3307 ++++----------- gen/asl_core.c | 175 + gen/asl_core.h | 17 +- gen/asl_file.c | 522 ++- gen/asl_file.h | 68 +- gen/asl_ipc.defs | 28 +- gen/asl_legacy1.c | 1259 +----- gen/asl_legacy1.h | 9 +- gen/asl_msg.c | 3589 +++++++++++++++++ gen/asl_msg.h | 138 + gen/asl_private.h | 69 +- gen/asl_store.c | 277 +- gen/asl_store.h | 58 +- gen/assert-fbsd.c | 64 +- gen/assumes.c | 164 + gen/assumes.h | 60 + gen/backtrace.c | 58 +- gen/closedir-fbsd.c | 12 +- gen/compat.5 | 123 +- gen/crypt.c | 9 +- gen/ctermid.3 | 6 +- gen/daemon-fbsd.c | 7 +- gen/daemon.3 | 6 +- gen/dirname-fbsd.c | 78 +- gen/dirname.3 | 87 +- gen/endutxent.3 | 13 +- gen/endutxent.3.orig | 202 + gen/err-fbsd.c | 40 +- gen/err.3 | 19 +- gen/errlst.c | 2 + gen/errno_-fbsd.c | 1 - gen/exec-fbsd.c | 78 +- gen/exec.3 | 70 +- gen/execinfo.h | 7 +- gen/fmtmsg-fbsd.c | 4 +- gen/fnmatch-fbsd.c | 38 +- gen/fnmatch.3 | 17 +- gen/ftok.3 | 6 +- gen/fts.c | 12 +- gen/get_compat.c | 1 - gen/getcap-fbsd.c | 23 +- gen/getcap-fbsd.c.orig | 1055 +++++ gen/getcwd-fbsd.c | 14 +- gen/gethostname-fbsd.c | 10 +- gen/gethostname.3 | 12 +- gen/getlastlogx.3 | 9 +- gen/getlastlogx.3.orig | 173 + gen/getlogin-fbsd.c | 6 +- gen/getmntinfo.3 | 61 +- gen/getmntinfo64-fbsd.c | 6 +- gen/getmntinfo64-fbsd.c.orig | 68 + gen/isatty-fbsd.c | 6 +- gen/lockf-fbsd.c | 21 +- gen/lockf.3 | 11 +- gen/magazine_malloc.c | 1724 +++++--- gen/magmallocProvider.d | 9 +- gen/malloc.3 | 2 + gen/malloc.c | 364 +- gen/malloc_zone_malloc.3 | 3 +- gen/nanosleep.c | 51 +- gen/nftw.c | 31 +- gen/nice-fbsd.c | 6 +- gen/opendir-fbsd.c | 15 +- gen/pause-fbsd.c | 8 +- gen/pause-fbsd.c.orig | 48 + gen/platfunc.c | 66 + gen/platfunc.h | 131 + gen/popen-fbsd.c | 39 +- gen/psignal.3 | 123 +- gen/rand48.3 | 8 +- gen/readdir-fbsd.c | 29 +- gen/scandir-fbsd.c | 22 +- gen/scandir.3 | 6 +- gen/scandir_b-fbsd.c | 22 +- gen/setmode-fbsd.c | 25 +- gen/setprogname-fbsd.c | 2 +- gen/siginterrupt.3 | 6 +- gen/siglist-fbsd.c | 7 +- gen/signal-fbsd.c | 6 +- gen/signal.3 | 39 +- gen/sleep-fbsd.c | 9 +- gen/sleep.3 | 6 +- gen/stack_logging.c | 18 +- gen/stack_logging.h | 2 + gen/stack_logging_disk.c | 208 +- gen/strtofflags.c | 1 + gen/sysctl-fbsd.c | 210 +- gen/sysctl.3 | 24 +- gen/syslog.3 | 10 +- gen/syslog.c | 520 +-- gen/telldir-fbsd.c | 16 +- gen/telldir.h | 4 +- gen/termios-fbsd.c | 31 +- gen/time-fbsd.c | 6 +- gen/time.3 | 16 +- gen/ttyname-fbsd.c | 21 +- gen/ualarm.3 | 6 +- gen/unvis-fbsd.c | 6 +- gen/usleep-fbsd.c | 9 +- gen/usleep.3 | 6 +- gen/utime.3 | 24 +- gen/utmpx-darwin.c | 73 +- gen/utmpx-darwin.h | 41 +- gen/utmpx-nbsd.c | 352 +- gen/utmpx.5 | 22 +- gen/utmpx_thread.h | 48 + gen/vis-fbsd.c | 6 +- gen/wait-fbsd.c | 6 +- gen/waitpid-fbsd.c | 6 +- gen/wordexp.c | 4 +- gmon/gmon.c | 6 +- i386/gen/Makefile.inc | 9 +- i386/gen/cpu_number.s | 58 + i386/gen/getmcontext.c | 2 +- i386/gen/icacheinval.s | 25 +- i386/pthreads/Makefile.inc | 7 + i386/pthreads/preempt.s | 67 + i386/pthreads/pthread_getspecific.s | 2 +- i386/pthreads/pthread_mutex_lock.s | 32 +- i386/pthreads/pthread_self.s | 2 +- i386/string/Makefile.inc | 29 +- i386/string/__bzero.s | 3 + i386/string/bcopy.c | 44 + i386/string/bcopy_scalar.s | 135 + i386/string/bcopy_sse2.s | 472 +++ i386/string/bcopy_sse3x.s | 806 ++++ i386/string/bcopy_sse42.s | 310 ++ i386/string/bzero.c | 42 + i386/string/bzero_scalar.s | 115 + i386/string/bzero_sse2.s | 162 + i386/string/bzero_sse42.s | 151 + i386/string/longcopy_sse3x.s | 220 + i386/string/memcpy.c | 44 + i386/string/memcpy.s | 33 - i386/string/memmove.c | 44 + i386/string/memmove.s | 33 - i386/string/memset.s | 11 +- i386/string/memset_pattern_sse2.s | 183 + i386/string/strncpy.s | 3 +- i386/sys/Makefile.inc | 15 +- i386/sys/OSAtomic.s | 504 ++- i386/sys/_setjmp.s | 41 +- i386/sys/_sigtramp.s | 16 +- i386/sys/atomic.c | 87 + i386/sys/i386_gettimeofday_asm.s | 79 + i386/sys/mach_absolute_time.c | 40 + i386/sys/mach_absolute_time_asm.s | 148 + i386/sys/spinlocks.c | 45 + i386/sys/spinlocks_asm.s | 129 + .../CrashReporterClient.h | 49 +- include/FreeBSD/nl_types.h | 105 + include/FreeBSD/nl_types.h.patch | 32 + include/Makefile.inc | 9 +- include/NSSystemDirectories.h | 2 +- include/NetBSD/utmpx.h.patch | 59 +- include/asl.h | 119 +- include/assert.h | 8 + include/dirent.h | 4 +- include/err.h | 27 +- include/float.h | 281 -- include/fsproperties.h | 3 + include/fts.h | 3 +- include/glob.h | 4 +- include/inttypes.h | 12 +- include/langinfo.h | 2 +- include/libc.h | 1 - include/libkern/OSAtomic.h | 668 ++- include/libkern/OSCacheControl.h | 3 +- include/libkern/OSThermalNotification.h | 40 +- include/limits.h | 77 +- include/malloc/malloc.h | 64 +- include/nl_types.h | 128 +- include/protocols/Makefile.inc | 3 +- include/protocols/dumprestore.h | 160 - include/rune.h | 18 +- include/secure/_stdio.h | 8 +- include/secure/_string.h | 29 +- include/spawn.h | 51 +- include/spawn_private.h | 6 +- include/standards.h | 9 +- include/stdarg.h | 9 - include/stdbool.h | 4 +- include/stddef.h | 4 +- include/stdint.h | 253 ++ include/stdio.h | 320 +- include/stdlib.h | 25 +- include/string.h | 118 +- include/strings.h | 47 +- include/sys/acl.h | 87 +- include/ucontext.h | 11 +- include/unistd.h | 523 ++- include/utmpx.h | 20 +- include/varargs.h | 9 - include/wchar.h | 62 +- include/xlocale/_stdio.h | 71 +- include/xlocale/_wchar.h | 85 +- interposable.list | 33 + locale/FreeBSD/ascii.c | 187 + locale/FreeBSD/ascii.c.patch | 89 + locale/FreeBSD/big5.c | 24 +- locale/FreeBSD/big5.c.patch | 56 +- locale/FreeBSD/btowc.3.patch | 6 +- locale/FreeBSD/btowc.c.patch | 10 +- locale/FreeBSD/collate.c | 27 +- locale/FreeBSD/collate.c.patch | 111 +- locale/FreeBSD/collate.h | 4 +- locale/FreeBSD/collate.h.patch | 12 +- locale/FreeBSD/collcmp.c | 5 +- locale/FreeBSD/collcmp.c.patch | 15 +- locale/FreeBSD/ctype.3 | 6 +- locale/FreeBSD/ctype.3.patch | 8 +- locale/FreeBSD/digittoint.3 | 6 +- locale/FreeBSD/digittoint.3.patch | 8 +- locale/FreeBSD/euc.5 | 6 +- locale/FreeBSD/euc.c | 22 +- locale/FreeBSD/euc.c.patch | 66 +- locale/FreeBSD/fix_grouping.c.patch | 8 +- locale/FreeBSD/gb18030.c | 21 +- locale/FreeBSD/gb18030.c.patch | 51 +- locale/FreeBSD/gb2312.c | 21 +- locale/FreeBSD/gb2312.c.patch | 55 +- locale/FreeBSD/gbk.c | 28 +- locale/FreeBSD/gbk.c.patch | 56 +- locale/FreeBSD/isalnum.3 | 19 +- locale/FreeBSD/isalnum.3.patch | 18 +- locale/FreeBSD/isalpha.3 | 19 +- locale/FreeBSD/isalpha.3.patch | 18 +- locale/FreeBSD/isascii.3 | 6 +- locale/FreeBSD/isblank.3 | 32 +- locale/FreeBSD/isblank.3.patch | 27 +- locale/FreeBSD/iscntrl.3 | 19 +- locale/FreeBSD/iscntrl.3.patch | 20 +- locale/FreeBSD/isdigit.3 | 19 +- locale/FreeBSD/isdigit.3.patch | 24 +- locale/FreeBSD/isgraph.3 | 21 +- locale/FreeBSD/isgraph.3.patch | 25 +- locale/FreeBSD/isideogram.3 | 2 +- locale/FreeBSD/isideogram.3.patch | 6 +- locale/FreeBSD/islower.3 | 19 +- locale/FreeBSD/islower.3.patch | 8 +- locale/FreeBSD/isphonogram.3 | 2 +- locale/FreeBSD/isphonogram.3.patch | 6 +- locale/FreeBSD/isprint.3 | 21 +- locale/FreeBSD/isprint.3.patch | 26 +- locale/FreeBSD/ispunct.3 | 19 +- locale/FreeBSD/ispunct.3.patch | 22 +- locale/FreeBSD/isrune.3 | 2 +- locale/FreeBSD/isrune.3.patch | 6 +- locale/FreeBSD/isspace.3 | 17 +- locale/FreeBSD/isspace.3.patch | 19 +- locale/FreeBSD/isspecial.3 | 2 +- locale/FreeBSD/isspecial.3.patch | 6 +- locale/FreeBSD/isupper.3 | 19 +- locale/FreeBSD/isupper.3.patch | 20 +- locale/FreeBSD/iswalnum.3 | 6 +- locale/FreeBSD/iswalnum.3.patch | 10 +- locale/FreeBSD/isxdigit.3 | 18 +- locale/FreeBSD/isxdigit.3.patch | 17 +- locale/FreeBSD/ldpart.c.patch | 4 +- locale/FreeBSD/ldpart.h.patch | 4 +- locale/FreeBSD/lmessages.c.patch | 6 +- locale/FreeBSD/lmessages.h.patch | 6 +- locale/FreeBSD/lmonetary.c.patch | 16 +- locale/FreeBSD/lmonetary.h.patch | 6 +- locale/FreeBSD/lnumeric.c.patch | 4 +- locale/FreeBSD/lnumeric.h.patch | 4 +- locale/FreeBSD/localeconv.3 | 6 +- locale/FreeBSD/localeconv.3.patch | 10 +- locale/FreeBSD/localeconv.c | 6 +- locale/FreeBSD/localeconv.c.patch | 12 +- locale/FreeBSD/mblen.3 | 6 +- locale/FreeBSD/mblen.3.patch | 10 +- locale/FreeBSD/mblen.c.patch | 8 +- locale/FreeBSD/mblocal.h | 30 +- locale/FreeBSD/mblocal.h.patch | 59 +- locale/FreeBSD/mbrlen.3.patch | 10 +- locale/FreeBSD/mbrlen.c.patch | 4 +- locale/FreeBSD/mbrtowc.3.patch | 10 +- locale/FreeBSD/mbrtowc.c.patch | 4 +- locale/FreeBSD/mbsinit.3.patch | 8 +- locale/FreeBSD/mbsinit.c.patch | 4 +- locale/FreeBSD/mbsnrtowcs.c.patch | 8 +- locale/FreeBSD/mbsrtowcs.3 | 4 +- locale/FreeBSD/mbsrtowcs.3.patch | 10 +- locale/FreeBSD/mbsrtowcs.c.patch | 6 +- locale/FreeBSD/mbstowcs.3 | 6 +- locale/FreeBSD/mbstowcs.3.patch | 10 +- locale/FreeBSD/mbstowcs.c | 6 +- locale/FreeBSD/mbstowcs.c.patch | 14 +- locale/FreeBSD/mbtowc.3 | 6 +- locale/FreeBSD/mbtowc.3.patch | 12 +- locale/FreeBSD/mbtowc.c.patch | 8 +- locale/FreeBSD/mskanji.c | 24 +- locale/FreeBSD/mskanji.c.patch | 59 +- locale/FreeBSD/multibyte.3 | 6 +- locale/FreeBSD/nextwctype.3 | 21 +- locale/FreeBSD/nextwctype.3.patch | 27 +- locale/FreeBSD/nextwctype.c.patch | 6 +- locale/FreeBSD/nl_langinfo.3 | 26 +- locale/FreeBSD/nl_langinfo.3.patch | 21 +- locale/FreeBSD/nl_langinfo.c.patch | 12 +- locale/FreeBSD/none.c | 55 +- locale/FreeBSD/none.c.patch | 91 +- locale/FreeBSD/rune.c.patch | 26 +- locale/FreeBSD/runetype.c | 10 +- locale/FreeBSD/runetype.c.patch | 20 +- locale/FreeBSD/setlocale.3 | 10 +- locale/FreeBSD/setlocale.3.patch | 8 +- locale/FreeBSD/setlocale.c | 6 +- locale/FreeBSD/setlocale.c.patch | 30 +- locale/FreeBSD/setlocale.h.patch | 4 +- locale/FreeBSD/setrunelocale.c | 57 +- locale/FreeBSD/setrunelocale.c.patch | 99 +- locale/FreeBSD/table.c | 16 +- locale/FreeBSD/table.c.patch | 31 +- locale/FreeBSD/toascii.3 | 6 +- locale/FreeBSD/tolower.3 | 18 +- locale/FreeBSD/tolower.3.patch | 21 +- locale/FreeBSD/tolower.c | 7 +- locale/FreeBSD/tolower.c.patch | 16 +- locale/FreeBSD/toupper.3 | 18 +- locale/FreeBSD/toupper.3.patch | 21 +- locale/FreeBSD/toupper.c | 7 +- locale/FreeBSD/toupper.c.patch | 16 +- locale/FreeBSD/towlower.3 | 6 +- locale/FreeBSD/towlower.3.patch | 6 +- locale/FreeBSD/towupper.3 | 6 +- locale/FreeBSD/towupper.3.patch | 6 +- locale/FreeBSD/utf2.c.patch | 107 +- locale/FreeBSD/utf8.5 | 6 +- locale/FreeBSD/utf8.c | 44 +- locale/FreeBSD/utf8.c.patch | 95 +- locale/FreeBSD/wcrtomb.3.patch | 12 +- locale/FreeBSD/wcrtomb.c.patch | 4 +- locale/FreeBSD/wcsftime.3.patch | 4 +- locale/FreeBSD/wcsftime.c | 13 +- locale/FreeBSD/wcsftime.c.patch | 30 +- locale/FreeBSD/wcsnrtombs.c | 6 +- locale/FreeBSD/wcsnrtombs.c.patch | 20 +- locale/FreeBSD/wcsrtombs.3.patch | 8 +- locale/FreeBSD/wcsrtombs.c.patch | 6 +- locale/FreeBSD/wcstod.3.patch | 4 +- locale/FreeBSD/wcstod.c.patch | 4 +- locale/FreeBSD/wcstof.c.patch | 4 +- locale/FreeBSD/wcstoimax.c | 6 +- locale/FreeBSD/wcstoimax.c.patch | 16 +- locale/FreeBSD/wcstol.3.patch | 8 +- locale/FreeBSD/wcstol.c | 6 +- locale/FreeBSD/wcstol.c.patch | 21 +- locale/FreeBSD/wcstold.c.patch | 4 +- locale/FreeBSD/wcstoll.c | 6 +- locale/FreeBSD/wcstoll.c.patch | 21 +- locale/FreeBSD/wcstombs.3 | 6 +- locale/FreeBSD/wcstombs.3.patch | 10 +- locale/FreeBSD/wcstombs.c | 6 +- locale/FreeBSD/wcstombs.c.patch | 14 +- locale/FreeBSD/wcstoul.c | 6 +- locale/FreeBSD/wcstoul.c.patch | 21 +- locale/FreeBSD/wcstoull.c | 6 +- locale/FreeBSD/wcstoull.c.patch | 21 +- locale/FreeBSD/wcstoumax.c | 6 +- locale/FreeBSD/wcstoumax.c.patch | 16 +- locale/FreeBSD/wctob.c.patch | 4 +- locale/FreeBSD/wctomb.3 | 6 +- locale/FreeBSD/wctomb.3.patch | 10 +- locale/FreeBSD/wctomb.c.patch | 4 +- locale/FreeBSD/wctrans.3.patch | 8 +- locale/FreeBSD/wctrans.c.patch | 10 +- locale/FreeBSD/wctype.3 | 7 +- locale/FreeBSD/wctype.3.patch | 16 +- locale/FreeBSD/wctype.c | 4 +- locale/FreeBSD/wctype.c.patch | 63 +- locale/FreeBSD/wcwidth.3.patch | 8 +- locale/FreeBSD/wcwidth.c | 6 +- locale/FreeBSD/wcwidth.c.patch | 10 +- locale/Makefile.inc | 7 +- locale/ascii-fbsd.c | 186 + locale/big5-fbsd.c | 20 +- locale/collate-fbsd.c | 2 +- locale/collate.h | 4 +- locale/collcmp-fbsd.c | 6 +- locale/ctype.3 | 6 +- locale/digittoint.3 | 6 +- locale/euc-fbsd.c | 28 +- locale/gb18030-fbsd.c | 17 +- locale/gb2312-fbsd.c | 18 +- locale/gbk-fbsd.c | 24 +- locale/isalnum.3 | 19 +- locale/isalpha.3 | 19 +- locale/isblank.3 | 32 +- locale/iscntrl.3 | 19 +- locale/isdigit.3 | 17 +- locale/isgraph.3 | 21 +- locale/isideogram.3 | 2 +- locale/islower.3 | 19 +- locale/isphonogram.3 | 2 +- locale/isprint.3 | 19 +- locale/ispunct.3 | 19 +- locale/isrune.3 | 2 +- locale/isspace.3 | 17 +- locale/isspecial.3 | 2 +- locale/isupper.3 | 19 +- locale/iswalnum.3 | 6 +- locale/isxdigit.3 | 18 +- locale/localeconv-fbsd.c | 6 +- locale/localeconv.3 | 6 +- locale/mblen.3 | 6 +- locale/mblocal.h | 36 +- locale/mbsrtowcs.3 | 4 +- locale/mbstowcs-fbsd.c | 6 +- locale/mbstowcs.3 | 6 +- locale/mbtowc.3 | 6 +- locale/mskanji-fbsd.c | 19 +- locale/nextwctype.3 | 27 +- locale/nl_langinfo.3 | 24 +- locale/none-fbsd.c | 31 +- locale/rune-fbsd.c | 4 +- locale/runetype-fbsd.c | 14 +- locale/setlocale-fbsd.c | 6 +- locale/setlocale.3 | 10 +- locale/setrunelocale-fbsd.c | 38 +- locale/table-fbsd.c | 13 +- locale/tolower-fbsd.c | 9 +- locale/tolower.3 | 18 +- locale/toupper-fbsd.c | 9 +- locale/toupper.3 | 18 +- locale/towlower.3 | 6 +- locale/towupper.3 | 6 +- locale/utf2-fbsd.c | 29 +- locale/utf8-fbsd.c | 28 +- locale/wcsftime-fbsd.c | 13 +- locale/wcsnrtombs-fbsd.c | 6 +- locale/wcstoimax-fbsd.c | 6 +- locale/wcstol-fbsd.c | 6 +- locale/wcstoll-fbsd.c | 6 +- locale/wcstombs-fbsd.c | 6 +- locale/wcstombs.3 | 6 +- locale/wcstoul-fbsd.c | 6 +- locale/wcstoull-fbsd.c | 6 +- locale/wcstoumax-fbsd.c | 6 +- locale/wctomb.3 | 6 +- locale/wctype-fbsd.c | 49 +- locale/wctype.3 | 5 +- locale/wcwidth-fbsd.c | 6 +- locale/xlocale.c | 2 +- locale/xlocale_private.h | 1 + net/FreeBSD/inet.3 | 46 +- net/FreeBSD/inet.3.patch | 48 +- net/FreeBSD/inet_net_pton.c | 8 +- net/FreeBSD/inet_net_pton.c.patch | 22 +- net/FreeBSD/linkaddr.3 | 16 +- net/FreeBSD/sourcefilter.3 | 240 ++ net/FreeBSD/sourcefilter.3.patch | 13 + net/FreeBSD/sourcefilter.c | 402 ++ net/FreeBSD/sourcefilter.c.patch | 23 + net/Makefile.inc | 10 +- net/ethers.3 | 2 +- net/inet.3 | 57 +- net/inet_net_pton-fbsd.c | 6 +- net/sourcefilter-fbsd.c | 409 ++ net/sourcefilter.3 | 238 ++ nls/FreeBSD/catclose.3 | 6 +- nls/FreeBSD/catgets.3 | 19 +- nls/FreeBSD/catopen.3 | 8 +- nls/FreeBSD/msgcat.c | 72 +- nls/FreeBSD/msgcat.c.patch | 53 +- nls/FreeBSD/msgcat.h | 25 +- nls/FreeBSD/msgcat.h.patch | 31 +- nls/msgcat-fbsd.c | 64 +- nls/msgcat.h | 26 +- posix1e/Makefile.inc | 12 + posix1e/acl.3 | 12 - posix1e/acl.c | 4 +- posix1e/acl_copy_ext.3 | 174 + posix1e/acl_create_entry.3 | 3 + posix1e/acl_entry.c | 10 +- posix1e/acl_flag.c | 21 +- posix1e/acl_get_permset_mask_np.3 | 93 + posix1e/acl_perm.c | 81 +- posix1e/acl_translate.c | 51 +- posix1e/aclvar.h | 16 +- ppc/sys/Makefile.inc | 2 - ppc/sys/_sigtramp.s | 4 +- ppc64/sys/Makefile.inc | 2 - pthreads/Makefile.inc | 4 +- pthreads/pthread.c | 228 +- pthreads/pthread.h | 25 +- pthreads/pthread_cond.c | 1285 +++--- pthreads/pthread_impl.h | 6 + pthreads/pthread_internals.h | 212 +- pthreads/pthread_machdep.h | 125 +- pthreads/pthread_mutex.c | 1231 +++--- pthreads/pthread_rwlock.c | 3287 ++++++--------- pthreads/pthread_spis.h | 77 + pthreads/pthread_workqueue.h | 35 +- regex/FreeBSD/cname.h | 6 +- regex/FreeBSD/cname.h.patch | 13 + regex/FreeBSD/engine.c | 263 +- regex/FreeBSD/engine.c.patch | 48 +- regex/FreeBSD/re_format.7 | 10 +- regex/FreeBSD/regcomp.c | 168 +- regex/FreeBSD/regcomp.c.patch | 112 +- regex/FreeBSD/regerror.c | 19 +- regex/FreeBSD/regerror.c.patch | 38 + regex/FreeBSD/regex.3 | 32 +- regex/FreeBSD/regex.3.patch | 10 +- regex/FreeBSD/regex2.h | 16 +- regex/FreeBSD/regex2.h.patch | 28 +- regex/FreeBSD/regexec.c | 35 +- regex/FreeBSD/regexec.c.patch | 43 +- regex/FreeBSD/regfree.c | 9 +- regex/FreeBSD/regfree.c.patch | 6 +- regex/FreeBSD/utils.h | 6 +- regex/cname.h | 139 +- regex/cname.h.orig | 138 + regex/engine.c | 263 +- regex/regcomp-fbsd.c | 174 +- regex/regerror-fbsd.c | 175 +- regex/regerror-fbsd.c.orig | 174 + regex/regex.3 | 32 +- regex/regex2.h | 18 +- regex/regexec-fbsd.c | 38 +- regex/regfree-fbsd.c | 9 +- secure/Makefile.inc | 1 + sys/unlink.c => secure/stpncpy_chk.c | 26 +- stdio/FreeBSD/_flock_stub.c | 49 +- stdio/FreeBSD/asprintf.c | 68 +- stdio/FreeBSD/asprintf.c.patch | 52 +- stdio/FreeBSD/clrerr.c | 17 +- stdio/FreeBSD/dprintf.c | 46 + stdio/FreeBSD/dprintf.c.patch | 33 + stdio/FreeBSD/fclose.3 | 24 +- stdio/FreeBSD/fclose.c | 6 +- stdio/FreeBSD/fclose.c.patch | 8 +- stdio/FreeBSD/fdopen.c | 21 +- stdio/FreeBSD/fdopen.c.patch | 8 +- stdio/FreeBSD/feof.c | 14 +- stdio/FreeBSD/ferror.3 | 17 +- stdio/FreeBSD/ferror.c | 14 +- stdio/FreeBSD/fflush.3 | 6 +- stdio/FreeBSD/fflush.c | 6 +- stdio/FreeBSD/fflush.c.patch | 8 +- stdio/FreeBSD/fgetc.c | 6 +- stdio/FreeBSD/fgetln.3 | 7 +- stdio/FreeBSD/fgetln.3.patch | 12 + stdio/FreeBSD/fgetln.c | 6 +- stdio/FreeBSD/fgetln.c.patch | 29 + stdio/FreeBSD/fgetpos.c | 6 +- stdio/FreeBSD/fgets.3 | 14 +- stdio/FreeBSD/fgets.3.patch | 56 - stdio/FreeBSD/fgets.c | 6 +- stdio/FreeBSD/fgetwc.c | 4 +- stdio/FreeBSD/fgetwc.c.patch | 14 +- stdio/FreeBSD/fgetwln.3 | 116 + stdio/FreeBSD/fgetwln.3.patch | 44 + stdio/FreeBSD/fgetwln.c | 67 + stdio/FreeBSD/fgetwln.c.patch | 30 + stdio/FreeBSD/fgetws.3 | 6 +- stdio/FreeBSD/fgetws.3.patch | 18 +- stdio/FreeBSD/fgetws.c | 8 +- stdio/FreeBSD/fgetws.c.patch | 24 +- stdio/FreeBSD/fileno.c | 14 +- stdio/FreeBSD/findfp.c | 73 +- stdio/FreeBSD/findfp.c.patch | 153 +- stdio/FreeBSD/flags.c | 6 +- stdio/FreeBSD/flags.c.patch | 6 +- stdio/FreeBSD/floatio.h | 6 +- stdio/FreeBSD/fopen.3 | 10 +- stdio/FreeBSD/fopen.3.patch | 16 +- stdio/FreeBSD/fopen.c | 21 +- stdio/FreeBSD/fopen.c.patch | 10 +- stdio/FreeBSD/fprintf.c | 6 +- stdio/FreeBSD/fprintf.c.patch | 10 +- stdio/FreeBSD/fpurge.c | 6 +- stdio/FreeBSD/fputc.c | 6 +- stdio/FreeBSD/fputs.3 | 15 +- stdio/FreeBSD/fputs.3.patch | 12 +- stdio/FreeBSD/fputs.c | 6 +- stdio/FreeBSD/fputs.c.patch | 15 +- stdio/FreeBSD/fputwc.c | 5 +- stdio/FreeBSD/fputwc.c.patch | 18 +- stdio/FreeBSD/fputws.3 | 6 +- stdio/FreeBSD/fputws.3.patch | 12 +- stdio/FreeBSD/fputws.c | 8 +- stdio/FreeBSD/fputws.c.patch | 29 +- stdio/FreeBSD/fread.3 | 6 +- stdio/FreeBSD/fread.3.patch | 12 +- stdio/FreeBSD/fread.c | 33 +- stdio/FreeBSD/fread.c.patch | 12 +- stdio/FreeBSD/freopen.c | 53 +- stdio/FreeBSD/freopen.c.patch | 25 +- stdio/FreeBSD/fscanf.c | 6 +- stdio/FreeBSD/fscanf.c.patch | 10 +- stdio/FreeBSD/fseek.3 | 9 +- stdio/FreeBSD/fseek.3.patch | 8 +- stdio/FreeBSD/fseek.c | 23 +- stdio/FreeBSD/fsetpos.c | 6 +- stdio/FreeBSD/ftell.c | 6 +- stdio/FreeBSD/ftell.c.patch | 11 +- stdio/FreeBSD/funopen.3 | 6 +- stdio/FreeBSD/funopen.c | 16 +- stdio/FreeBSD/funopen.c.patch | 6 +- stdio/FreeBSD/fvwrite.c | 8 +- stdio/FreeBSD/fvwrite.h | 6 +- stdio/FreeBSD/fwalk.c | 6 +- stdio/FreeBSD/fwide.c | 8 +- stdio/FreeBSD/fwrite.c | 15 +- stdio/FreeBSD/fwrite.c.patch | 24 +- stdio/FreeBSD/getc.3 | 8 +- stdio/FreeBSD/getc.3.patch | 10 +- stdio/FreeBSD/getc.c | 14 +- stdio/FreeBSD/getchar.c | 14 +- stdio/FreeBSD/getdelim.c | 160 + stdio/FreeBSD/getline.3 | 164 + stdio/FreeBSD/getline.3.patch | 45 + stdio/FreeBSD/getline.c | 39 + stdio/FreeBSD/gets.c | 6 +- stdio/FreeBSD/getw.c | 6 +- stdio/FreeBSD/getwc.3 | 8 +- stdio/FreeBSD/getwc.3.patch | 16 +- stdio/FreeBSD/glue.h | 9 +- stdio/FreeBSD/glue.h.patch | 9 - stdio/FreeBSD/local.h | 34 +- stdio/FreeBSD/local.h.patch | 68 +- stdio/FreeBSD/makebuf.c | 10 +- stdio/FreeBSD/makebuf.c.patch | 14 +- stdio/FreeBSD/mktemp.3 | 60 +- stdio/FreeBSD/mktemp.3.patch | 44 +- stdio/FreeBSD/mktemp.c | 49 +- stdio/FreeBSD/mktemp.c.patch | 84 +- stdio/FreeBSD/perror.c | 6 +- stdio/FreeBSD/perror.c.patch | 10 - stdio/FreeBSD/printf-pos.c | 758 ++++ stdio/FreeBSD/printf-pos.c.patch | 128 + stdio/FreeBSD/printf.3 | 126 +- stdio/FreeBSD/printf.3.patch | 173 +- stdio/FreeBSD/printf.c | 6 +- stdio/FreeBSD/printf.c.patch | 10 +- stdio/FreeBSD/printfcommon.h | 301 ++ stdio/FreeBSD/printfcommon.h.patch | 86 + stdio/FreeBSD/printflocal.h | 94 + stdio/FreeBSD/printflocal.h.patch | 60 + stdio/FreeBSD/putc.3 | 6 +- stdio/FreeBSD/putc.3.patch | 8 +- stdio/FreeBSD/putc.c | 14 +- stdio/FreeBSD/putchar.c | 14 +- stdio/FreeBSD/puts.c | 6 +- stdio/FreeBSD/puts.c.patch | 8 +- stdio/FreeBSD/putw.c | 6 +- stdio/FreeBSD/putwc.3 | 6 +- stdio/FreeBSD/putwc.3.patch | 10 +- stdio/FreeBSD/refill.c | 8 +- stdio/FreeBSD/refill.c.patch | 10 +- stdio/FreeBSD/remove.3 | 6 +- stdio/FreeBSD/remove.3.patch | 6 +- stdio/FreeBSD/remove.c | 6 +- stdio/FreeBSD/rewind.c | 6 +- stdio/FreeBSD/rewind.c.patch | 11 +- stdio/FreeBSD/rget.c | 6 +- stdio/FreeBSD/scanf.3 | 6 +- stdio/FreeBSD/scanf.3.patch | 20 +- stdio/FreeBSD/scanf.c | 6 +- stdio/FreeBSD/scanf.c.patch | 10 +- stdio/FreeBSD/setbuf.3 | 10 +- stdio/FreeBSD/setbuf.3.patch | 10 +- stdio/FreeBSD/setbuf.c | 6 +- stdio/FreeBSD/setbuffer.c | 6 +- stdio/FreeBSD/setvbuf.c | 6 +- stdio/FreeBSD/snprintf.c | 11 +- stdio/FreeBSD/snprintf.c.patch | 60 +- stdio/FreeBSD/sprintf.c | 11 +- stdio/FreeBSD/sprintf.c.patch | 40 +- stdio/FreeBSD/sscanf.c | 11 +- stdio/FreeBSD/sscanf.c.patch | 73 +- stdio/FreeBSD/stdio.3 | 20 +- stdio/FreeBSD/stdio.3.patch | 31 +- stdio/FreeBSD/stdio.c | 6 +- stdio/FreeBSD/tempnam.c | 6 +- stdio/FreeBSD/tempnam.c.patch | 14 +- stdio/FreeBSD/tmpfile.c | 6 +- stdio/FreeBSD/tmpnam.3 | 74 +- stdio/FreeBSD/tmpnam.3.patch | 38 +- stdio/FreeBSD/tmpnam.c | 6 +- stdio/FreeBSD/tmpnam.c.patch | 41 + stdio/FreeBSD/ungetc.3 | 6 +- stdio/FreeBSD/ungetc.3.patch | 8 +- stdio/FreeBSD/ungetc.c | 8 +- stdio/FreeBSD/ungetwc.3 | 6 +- stdio/FreeBSD/ungetwc.3.patch | 12 +- stdio/FreeBSD/ungetwc.c | 5 +- stdio/FreeBSD/ungetwc.c.patch | 16 +- stdio/FreeBSD/vasprintf.c | 7 +- stdio/FreeBSD/vasprintf.c.patch | 77 +- stdio/FreeBSD/vdprintf.c | 66 + stdio/FreeBSD/vdprintf.c.patch | 44 + stdio/FreeBSD/vfprintf.c | 1027 +---- stdio/FreeBSD/vfprintf.c.patch | 625 ++- stdio/FreeBSD/vfscanf.c | 65 +- stdio/FreeBSD/vfscanf.c.patch | 192 +- stdio/FreeBSD/vfwprintf.c | 1020 ++--- stdio/FreeBSD/vfwprintf.c.patch | 656 ++- stdio/FreeBSD/vfwscanf.c | 39 +- stdio/FreeBSD/vfwscanf.c.patch | 161 +- stdio/FreeBSD/vprintf.c | 6 +- stdio/FreeBSD/vprintf.c.patch | 8 +- stdio/FreeBSD/vscanf.c | 6 +- stdio/FreeBSD/vscanf.c.patch | 10 +- stdio/FreeBSD/vsnprintf.c | 11 +- stdio/FreeBSD/vsnprintf.c.patch | 73 +- stdio/FreeBSD/vsprintf.c | 11 +- stdio/FreeBSD/vsprintf.c.patch | 52 +- stdio/FreeBSD/vsscanf.c | 11 +- stdio/FreeBSD/vsscanf.c.patch | 55 +- stdio/FreeBSD/vswprintf.c | 16 +- stdio/FreeBSD/vswprintf.c.patch | 121 +- stdio/FreeBSD/vswscanf.c | 15 +- stdio/FreeBSD/vswscanf.c.patch | 79 +- stdio/FreeBSD/wbuf.c | 6 +- stdio/FreeBSD/wbuf.c.patch | 10 +- stdio/FreeBSD/wprintf.3 | 6 +- stdio/FreeBSD/wprintf.3.patch | 16 +- stdio/FreeBSD/wscanf.3 | 6 +- stdio/FreeBSD/wscanf.3.patch | 18 +- stdio/FreeBSD/wsetup.c | 7 +- stdio/Makefile.inc | 30 +- stdio/asprintf-fbsd.c | 94 +- stdio/{FreeBSD/unlocked.c => dprintf-fbsd.c} | 77 +- stdio/fclose-fbsd.c | 6 +- stdio/fdopen-fbsd.c | 21 +- stdio/fflush-fbsd.c | 6 +- stdio/fgetln-fbsd.c | 171 +- stdio/fgetln.3 | 129 +- stdio/fgets.3 | 162 +- stdio/fgetwc-fbsd.c | 4 +- stdio/fgetwln-fbsd.c | 73 + stdio/fgetwln.3 | 129 + stdio/fgetws-fbsd.c | 8 +- stdio/fgetws.3 | 6 +- stdio/findfp-fbsd.c | 89 +- stdio/flags-fbsd.c | 6 +- stdio/fopen-fbsd.c | 21 +- stdio/fopen.3 | 10 +- stdio/fprintf-fbsd.c | 6 +- stdio/fputs-fbsd.c | 6 +- stdio/fputs.3 | 15 +- stdio/fputwc-fbsd.c | 5 +- stdio/fputws-fbsd.c | 9 +- stdio/fputws.3 | 6 +- stdio/fread-fbsd.c | 35 +- stdio/fread.3 | 6 +- stdio/freopen-fbsd.c | 53 +- stdio/fscanf-fbsd.c | 6 +- stdio/fseek.3 | 9 +- stdio/ftell-fbsd.c | 6 +- stdio/funopen-fbsd.c | 16 +- stdio/fwrite-fbsd.c | 21 +- stdio/getc.3 | 6 +- stdio/getdelim-fbsd.c | 1 + stdio/getline-fbsd.c | 1 + stdio/getline.3 | 135 + stdio/getwc.3 | 10 +- stdio/glue.h | 50 +- stdio/local.h | 45 +- stdio/makebuf-fbsd.c | 10 +- stdio/mktemp-fbsd.c | 15 +- stdio/mktemp.3 | 68 +- stdio/perror-fbsd.c | 82 +- stdio/printf-fbsd.c | 6 +- stdio/printf-pos-fbsd.c | 798 ++++ stdio/printf.3 | 153 +- stdio/printf_l.3 | 22 +- stdio/printfcommon.h | 301 ++ stdio/printflocal.h | 124 + stdio/putc.3 | 6 +- stdio/puts-fbsd.c | 6 +- stdio/putwc.3 | 6 +- stdio/refill-fbsd.c | 8 +- stdio/remove.3 | 6 +- stdio/rewind-fbsd.c | 6 +- stdio/scanf-fbsd.c | 6 +- stdio/scanf.3 | 6 +- stdio/setbuf.3 | 10 +- stdio/snprintf-fbsd.c | 43 +- stdio/sprintf-fbsd.c | 29 +- stdio/sscanf-fbsd.c | 46 +- stdio/stdio.3 | 18 +- stdio/tempnam-fbsd.c | 14 +- stdio/tmpnam-fbsd.c | 76 +- stdio/tmpnam.3 | 69 +- stdio/ungetc.3 | 6 +- stdio/ungetwc-fbsd.c | 5 +- stdio/ungetwc.3 | 6 +- stdio/unlocked-fbsd.c | 1 - stdio/vasprintf-fbsd.c | 46 +- stdio/vdprintf-fbsd.c | 78 + stdio/vfprintf-fbsd.c | 1158 ++---- stdio/vfscanf-fbsd.c | 110 +- stdio/vfwprintf-fbsd.c | 1146 ++---- stdio/vfwscanf-fbsd.c | 65 +- stdio/vprintf-fbsd.c | 6 +- stdio/vscanf-fbsd.c | 6 +- stdio/vsnprintf-fbsd.c | 51 +- stdio/vsprintf-fbsd.c | 35 +- stdio/vsscanf-fbsd.c | 36 +- stdio/vswprintf-fbsd.c | 82 +- stdio/vswscanf-fbsd.c | 61 +- stdio/wbuf-fbsd.c | 6 +- stdio/wprintf.3 | 6 +- stdio/wscanf.3 | 6 +- stdlib/FreeBSD/abort.3 | 6 +- stdlib/FreeBSD/abort.3.patch | 16 + stdlib/FreeBSD/abort.c | 8 +- stdlib/FreeBSD/abort.c.patch | 102 +- stdlib/FreeBSD/abs.3 | 6 +- stdlib/FreeBSD/abs.3.patch | 6 +- stdlib/FreeBSD/abs.c | 6 +- stdlib/FreeBSD/alloca.3 | 23 +- stdlib/FreeBSD/alloca.3.patch | 67 +- stdlib/FreeBSD/atexit.3 | 6 +- stdlib/FreeBSD/atexit.3.patch | 8 +- stdlib/FreeBSD/atexit.c | 6 +- stdlib/FreeBSD/atexit.c.patch | 22 +- stdlib/FreeBSD/atexit.h | 6 +- stdlib/FreeBSD/atexit.h.patch | 6 +- stdlib/FreeBSD/atof.3 | 6 +- stdlib/FreeBSD/atof.3.patch | 27 +- stdlib/FreeBSD/atof.c | 6 +- stdlib/FreeBSD/atof.c.patch | 8 +- stdlib/FreeBSD/atoi.3 | 10 +- stdlib/FreeBSD/atoi.3.patch | 30 +- stdlib/FreeBSD/atoi.c | 6 +- stdlib/FreeBSD/atoi.c.patch | 8 +- stdlib/FreeBSD/atol.3 | 41 +- stdlib/FreeBSD/atol.3.patch | 30 +- stdlib/FreeBSD/atol.c | 6 +- stdlib/FreeBSD/atol.c.patch | 8 +- stdlib/FreeBSD/atoll.c | 6 +- stdlib/FreeBSD/atoll.c.patch | 8 +- stdlib/FreeBSD/bsearch.3 | 6 +- stdlib/FreeBSD/bsearch.3.patch | 10 +- stdlib/FreeBSD/bsearch.c | 6 +- stdlib/FreeBSD/bsearch.c.patch | 6 +- stdlib/FreeBSD/div.3 | 6 +- stdlib/FreeBSD/div.3.patch | 6 +- stdlib/FreeBSD/div.c | 6 +- stdlib/FreeBSD/exit.3 | 6 +- stdlib/FreeBSD/exit.c | 10 +- stdlib/FreeBSD/exit.c.patch | 12 +- stdlib/FreeBSD/getenv.c | 6 +- stdlib/FreeBSD/getenv.c.patch | 12 +- stdlib/FreeBSD/getopt.3 | 6 +- stdlib/FreeBSD/getopt.c | 6 +- stdlib/FreeBSD/getopt.c.patch | 10 +- stdlib/FreeBSD/getopt_long.3 | 34 +- stdlib/FreeBSD/getopt_long.c | 33 +- stdlib/FreeBSD/getsubopt.3 | 6 +- stdlib/FreeBSD/getsubopt.3.patch | 12 +- stdlib/FreeBSD/getsubopt.c | 6 +- stdlib/FreeBSD/hcreate.3 | 60 +- stdlib/FreeBSD/hcreate.c | 8 +- stdlib/FreeBSD/labs.3 | 6 +- stdlib/FreeBSD/labs.3.patch | 6 +- stdlib/FreeBSD/labs.c | 6 +- stdlib/FreeBSD/ldiv.3 | 6 +- stdlib/FreeBSD/ldiv.3.patch | 6 +- stdlib/FreeBSD/ldiv.c | 6 +- stdlib/FreeBSD/lsearch.3 | 16 +- stdlib/FreeBSD/lsearch.3.patch | 6 +- stdlib/FreeBSD/memory.3 | 6 +- stdlib/FreeBSD/memory.3.patch | 6 +- stdlib/FreeBSD/putenv.c | 6 +- stdlib/FreeBSD/putenv.c.patch | 49 +- stdlib/FreeBSD/qsort.3 | 18 +- stdlib/FreeBSD/qsort.3.patch | 42 +- stdlib/FreeBSD/radixsort.3 | 6 +- stdlib/FreeBSD/radixsort.c | 6 +- stdlib/FreeBSD/radixsort.c.patch | 79 +- stdlib/FreeBSD/rand.3 | 12 +- stdlib/FreeBSD/rand.3.patch | 14 +- stdlib/FreeBSD/rand.c | 8 +- stdlib/FreeBSD/random.3 | 10 +- stdlib/FreeBSD/random.3.patch | 37 +- stdlib/FreeBSD/random.c | 6 +- stdlib/FreeBSD/random.c.patch | 16 +- stdlib/FreeBSD/realpath.3 | 6 +- stdlib/FreeBSD/realpath.3.patch | 10 +- stdlib/FreeBSD/realpath.c.patch | 91 +- stdlib/FreeBSD/setenv.c | 6 +- stdlib/FreeBSD/setenv.c.patch | 68 +- stdlib/FreeBSD/strtod.3 | 33 +- stdlib/FreeBSD/strtod.3.patch | 24 +- stdlib/FreeBSD/strtoimax.c | 11 +- stdlib/FreeBSD/strtoimax.c.patch | 16 +- stdlib/FreeBSD/strtol.3 | 11 +- stdlib/FreeBSD/strtol.3.patch | 29 +- stdlib/FreeBSD/strtol.c | 11 +- stdlib/FreeBSD/strtol.c.patch | 16 +- stdlib/FreeBSD/strtoll.c | 11 +- stdlib/FreeBSD/strtoll.c.patch | 16 +- stdlib/FreeBSD/strtoq.c | 6 +- stdlib/FreeBSD/strtoq.c.patch | 10 +- stdlib/FreeBSD/strtoul.3 | 13 +- stdlib/FreeBSD/strtoul.3.patch | 21 +- stdlib/FreeBSD/strtoul.c | 11 +- stdlib/FreeBSD/strtoul.c.patch | 14 +- stdlib/FreeBSD/strtoull.c | 11 +- stdlib/FreeBSD/strtoull.c.patch | 14 +- stdlib/FreeBSD/strtoumax.c | 11 +- stdlib/FreeBSD/strtoumax.c.patch | 14 +- stdlib/FreeBSD/strtouq.c | 6 +- stdlib/FreeBSD/strtouq.c.patch | 10 +- stdlib/FreeBSD/system.3 | 8 +- stdlib/FreeBSD/system.3.patch | 8 +- stdlib/FreeBSD/system.c | 6 +- stdlib/FreeBSD/system.c.patch | 8 +- stdlib/FreeBSD/tsearch.3 | 12 +- stdlib/FreeBSD/tsearch.3.patch | 20 +- stdlib/Makefile.inc | 1 + stdlib/NetBSD/strfmon.3.patch | 23 +- stdlib/NetBSD/strfmon.c | 6 +- stdlib/OpenBSD/ecvt.3 | 4 +- stdlib/OpenBSD/ecvt.c | 30 +- stdlib/OpenBSD/ecvt.c.patch | 41 +- stdlib/OpenBSD/gcvt.c | 38 +- stdlib/OpenBSD/gcvt.c.patch | 81 +- stdlib/abort-fbsd.c | 87 +- stdlib/abort.3 | 87 +- stdlib/abs.3 | 6 +- stdlib/alloca.3 | 39 +- stdlib/atexit-fbsd.c | 8 +- stdlib/atexit.3 | 6 +- stdlib/atexit.h | 6 +- stdlib/atof-fbsd.c | 6 +- stdlib/atof.3 | 16 +- stdlib/atoi-fbsd.c | 6 +- stdlib/atoi.3 | 16 +- stdlib/atol-fbsd.c | 6 +- stdlib/atol.3 | 49 +- stdlib/atoll-fbsd.c | 6 +- stdlib/bsearch-fbsd.c | 6 +- stdlib/bsearch.3 | 6 +- stdlib/div.3 | 6 +- stdlib/ecvt-obsd.c | 26 +- stdlib/ecvt.3 | 4 +- stdlib/exit-fbsd.c | 10 +- stdlib/gcvt-obsd.c | 41 +- stdlib/getenv-fbsd.c | 6 +- stdlib/getopt-fbsd.c | 6 +- stdlib/getsubopt.3 | 6 +- stdlib/labs.3 | 6 +- stdlib/ldiv.3 | 6 +- stdlib/lsearch.3 | 16 +- stdlib/memory.3 | 6 +- stdlib/psort.3 | 54 +- stdlib/psort.3.patch | 146 +- stdlib/putenv-fbsd.c | 28 +- stdlib/qsort.3 | 28 +- stdlib/radixsort-fbsd.c | 35 +- stdlib/rand.3 | 12 +- stdlib/random-fbsd.c | 6 +- stdlib/random.3 | 19 +- stdlib/realpath-fbsd.c | 36 +- stdlib/realpath.3 | 6 +- stdlib/setenv-fbsd.c | 54 +- stdlib/strfmon-nbsd.c | 6 +- stdlib/strfmon.3 | 14 + stdlib/strtod.3 | 36 +- stdlib/strtoimax-fbsd.c | 11 +- stdlib/strtol-fbsd.c | 11 +- stdlib/strtol.3 | 6 +- stdlib/strtoll-fbsd.c | 11 +- stdlib/strtoq-fbsd.c | 6 +- stdlib/strtoul-fbsd.c | 11 +- stdlib/strtoul.3 | 13 +- stdlib/strtoull-fbsd.c | 11 +- stdlib/strtoumax-fbsd.c | 11 +- stdlib/strtouq-fbsd.c | 6 +- stdlib/system-fbsd.c | 6 +- stdlib/system.3 | 8 +- stdlib/tsearch.3 | 12 +- stdtime/FreeBSD/asctime.c | 108 +- stdtime/FreeBSD/asctime.c.patch | 61 +- stdtime/FreeBSD/ctime.3 | 8 +- stdtime/FreeBSD/ctime.3.patch | 26 +- stdtime/FreeBSD/difftime.c | 100 +- stdtime/FreeBSD/localtime.c | 129 +- stdtime/FreeBSD/localtime.c.patch | 426 +- stdtime/FreeBSD/private.h | 156 +- stdtime/FreeBSD/strftime.3 | 37 +- stdtime/FreeBSD/strftime.3.patch | 16 +- stdtime/FreeBSD/strftime.c | 191 +- stdtime/FreeBSD/strftime.c.patch | 244 +- stdtime/FreeBSD/strptime.3 | 12 +- stdtime/FreeBSD/strptime.3.patch | 12 +- stdtime/FreeBSD/strptime.c | 30 +- stdtime/FreeBSD/strptime.c.patch | 94 +- stdtime/FreeBSD/time2posix.3 | 13 +- stdtime/FreeBSD/time2posix.3.patch | 14 - stdtime/FreeBSD/tzfile.h.patch | 27 +- stdtime/asctime-fbsd.c | 107 +- stdtime/ctime.3 | 6 +- stdtime/localtime-fbsd.c | 279 +- stdtime/strftime-fbsd.c | 219 +- stdtime/strftime.3 | 37 +- stdtime/strptime-fbsd.c | 43 +- stdtime/strptime.3 | 12 +- stdtime/time2posix.3 | 121 +- stdtime/tzfile.h | 14 + string/FreeBSD/bcmp.3 | 6 +- string/FreeBSD/bcmp.3.patch | 6 +- string/FreeBSD/bcmp.c | 6 +- string/FreeBSD/bcopy.3 | 6 +- string/FreeBSD/bcopy.3.patch | 6 +- string/FreeBSD/bstring.3 | 6 +- string/FreeBSD/bstring.3.patch | 8 +- string/FreeBSD/bzero.3 | 6 +- string/FreeBSD/bzero.3.patch | 6 +- string/FreeBSD/ffs.3 | 39 +- string/FreeBSD/ffs.3.patch | 52 +- string/FreeBSD/index.3 | 6 +- string/FreeBSD/index.3.patch | 8 +- string/FreeBSD/index.c | 6 +- string/FreeBSD/memccpy.3 | 6 +- string/FreeBSD/memccpy.3.patch | 6 +- string/FreeBSD/memccpy.c | 12 +- string/FreeBSD/memchr.3 | 41 +- string/FreeBSD/memchr.3.patch | 46 +- string/FreeBSD/memchr.c | 13 +- string/FreeBSD/memcmp.3 | 9 +- string/FreeBSD/memcmp.3.patch | 6 +- string/FreeBSD/memcmp.c | 10 +- string/FreeBSD/memcpy.3 | 9 +- string/FreeBSD/memcpy.3.patch | 8 +- string/FreeBSD/memmem.3 | 86 + string/FreeBSD/memmem.c | 65 + string/FreeBSD/memmove.3 | 9 +- string/FreeBSD/memmove.3.patch | 6 +- string/FreeBSD/memset.3 | 9 +- string/FreeBSD/memset.3.patch | 14 +- string/FreeBSD/memset.c | 6 +- string/FreeBSD/rindex.c | 6 +- string/FreeBSD/stpcpy.c | 4 +- string/FreeBSD/stpncpy.c | 45 + string/FreeBSD/strcasecmp.3 | 9 +- string/FreeBSD/strcasecmp.3.patch | 15 +- string/FreeBSD/strcasecmp.c | 13 +- string/FreeBSD/strcasecmp.c.patch | 29 +- string/FreeBSD/strcasestr.c | 9 +- string/FreeBSD/strcasestr.c.patch | 17 +- string/FreeBSD/strcat.3 | 19 +- string/FreeBSD/strcat.3.patch | 33 +- string/FreeBSD/strcat.c | 6 +- string/FreeBSD/strchr.3 | 10 +- string/FreeBSD/strchr.3.patch | 10 +- string/FreeBSD/strcmp.3 | 11 +- string/FreeBSD/strcmp.3.patch | 8 +- string/FreeBSD/strcoll.3 | 13 +- string/FreeBSD/strcoll.3.patch | 26 +- string/FreeBSD/strcoll.c | 5 +- string/FreeBSD/strcoll.c.patch | 17 +- string/FreeBSD/strcpy.3 | 53 +- string/FreeBSD/strcpy.3.patch | 98 +- string/FreeBSD/strcpy.c | 6 +- string/FreeBSD/strcspn.3 | 13 +- string/FreeBSD/strcspn.3.patch | 23 +- string/FreeBSD/strdup.3 | 30 +- string/FreeBSD/strdup.3.patch | 32 +- string/FreeBSD/strdup.c | 9 +- string/FreeBSD/strerror.3 | 6 +- string/FreeBSD/strerror.3.patch | 17 +- string/FreeBSD/strerror.c | 67 +- string/FreeBSD/strerror.c.patch | 45 +- string/FreeBSD/string.3 | 6 +- string/FreeBSD/string.3.patch | 6 +- string/FreeBSD/strlcat.c | 43 +- string/FreeBSD/strlcpy.3 | 43 +- string/FreeBSD/strlcpy.3.patch | 6 +- string/FreeBSD/strlcpy.c | 52 +- string/FreeBSD/strlen.3 | 35 +- string/FreeBSD/strlen.c | 101 +- string/FreeBSD/strmode.3 | 10 +- string/FreeBSD/strmode.3.patch | 6 +- string/FreeBSD/strmode.c | 12 +- string/FreeBSD/strncat.c | 6 +- string/FreeBSD/strncmp.c | 12 +- string/FreeBSD/strncpy.c | 10 +- string/FreeBSD/strndup.c | 53 + .../errno_.c => string/FreeBSD/strnlen.c | 18 +- string/FreeBSD/strnstr.c | 11 +- string/FreeBSD/strpbrk.3 | 9 +- string/FreeBSD/strpbrk.3.patch | 6 +- string/FreeBSD/strpbrk.c | 11 +- string/FreeBSD/strsep.3 | 23 +- string/FreeBSD/strsep.c | 10 +- string/FreeBSD/strsignal.c | 116 +- string/FreeBSD/strsignal.c.patch | 84 +- string/FreeBSD/strspn.3 | 18 +- string/FreeBSD/strspn.3.patch | 19 +- string/FreeBSD/strstr.3 | 10 +- string/FreeBSD/strstr.3.patch | 26 +- string/FreeBSD/strstr.c | 13 +- string/FreeBSD/strtok.3 | 24 +- string/FreeBSD/strtok.3.patch | 6 +- string/FreeBSD/strtok.c | 6 +- string/FreeBSD/strxfrm.3 | 6 +- string/FreeBSD/strxfrm.3.patch | 10 +- string/FreeBSD/strxfrm.c | 16 +- string/FreeBSD/strxfrm.c.patch | 19 +- string/FreeBSD/swab.3 | 12 +- string/FreeBSD/swab.3.patch | 52 +- string/FreeBSD/swab.c | 10 +- string/FreeBSD/swab.c.patch | 13 +- string/FreeBSD/wcpcpy.c | 46 + string/FreeBSD/wcpncpy.c | 45 + string/FreeBSD/wcscasecmp.c | 45 + string/FreeBSD/wcscasecmp.c.patch | 33 + string/FreeBSD/wcscat.c | 6 +- string/FreeBSD/wcscmp.c | 11 +- string/FreeBSD/wcscoll.3 | 6 +- string/FreeBSD/wcscoll.3.patch | 8 +- string/FreeBSD/wcscpy.c | 6 +- string/FreeBSD/wcscspn.c | 6 +- string/FreeBSD/wcsdup.c | 43 + string/FreeBSD/wcslcat.c | 7 +- string/FreeBSD/wcslcpy.c | 7 +- string/FreeBSD/wcslen.c | 5 +- string/FreeBSD/wcsncasecmp.c | 49 + string/FreeBSD/wcsncasecmp.c.patch | 37 + string/FreeBSD/wcsncat.c | 7 +- string/FreeBSD/wcsncmp.c | 10 +- string/FreeBSD/wcsncpy.c | 6 +- string/FreeBSD/wcsnlen.c | 42 + string/FreeBSD/wcspbrk.c | 6 +- string/FreeBSD/wcsspn.c | 6 +- string/FreeBSD/wcsstr.c | 8 +- string/FreeBSD/wcstok.c | 6 +- string/FreeBSD/wcswidth.c | 6 +- string/FreeBSD/wcswidth.c.patch | 8 +- string/FreeBSD/wcsxfrm.3 | 6 +- string/FreeBSD/wcsxfrm.3.patch | 12 +- string/FreeBSD/wmemchr.3 | 41 +- string/FreeBSD/wmemchr.3.patch | 210 +- string/FreeBSD/wmemchr.c | 7 +- string/FreeBSD/wmemcmp.c | 7 +- string/FreeBSD/wmemcpy.c | 8 +- string/FreeBSD/wmemmove.c | 8 +- string/FreeBSD/wmemset.c | 7 +- string/Makefile.inc | 43 +- string/bcmp.3 | 6 +- string/bcopy.3 | 6 +- string/bstring.3 | 6 +- string/bzero.3 | 6 +- string/ffs.3 | 15 +- string/index.3 | 6 +- string/memccpy.3 | 6 +- string/memchr.3 | 11 +- string/memcmp.3 | 9 +- string/memcpy.3 | 9 +- string/memmem-fbsd.c | 1 + string/memmem.3 | 1 + string/memmove.3 | 9 +- string/memset.3 | 9 +- string/stpncpy-fbsd.c | 1 + string/strcasecmp-fbsd.c | 13 +- string/strcasecmp.3 | 6 +- string/strcasestr-fbsd.c | 9 +- string/strcat.3 | 11 +- string/strchr.3 | 10 +- string/strcmp.3 | 11 +- string/strcoll-fbsd.c | 9 +- string/strcoll.3 | 16 +- string/strcpy.3 | 71 +- string/strcspn.3 | 16 +- string/strdup.3 | 30 +- string/strerror-fbsd.c | 71 +- string/strerror.3 | 8 +- string/string.3 | 6 +- string/strlcpy.3 | 43 +- string/strmode.3 | 10 +- string/strndup-fbsd.c | 1 + string/strnlen-fbsd.c | 1 + string/strpbrk.3 | 9 +- string/strsignal-fbsd.c | 112 +- string/strspn.3 | 18 +- string/strstr.3 | 7 +- string/strtok.3 | 24 +- string/strxfrm-fbsd.c | 16 +- string/strxfrm.3 | 6 +- string/swab-fbsd.c | 8 +- string/swab.3 | 37 +- string/wcpcpy-fbsd.c | 1 + string/wcpncpy-fbsd.c | 1 + string/wcscasecmp-fbsd.c | 53 + string/wcscoll.3 | 6 +- string/wcsdup-fbsd.c | 1 + string/wcsncasecmp-fbsd.c | 57 + string/wcsnlen-fbsd.c | 1 + string/wcswidth-fbsd.c | 6 +- string/wcsxfrm.3 | 6 +- string/wmemchr.3 | 172 +- sys/Makefile.inc | 83 +- sys/OSThermalNotification.c | 55 +- sys/OpenBSD/stack_protector.c | 71 +- sys/OpenBSD/stack_protector.c.patch | 182 +- sys/__libc_init.c | 27 +- .../string/bzero.s => sys/_libc_fork_child.c | 29 +- sys/accept.c | 48 - sys/bind.c | 48 - sys/chmod.c | 55 - sys/connect.c | 48 - sys/fchmod.c | 55 - sys/fcntl.c | 73 - sys/fix-3375657.c | 407 -- sys/fork.c | 73 + sys/getattrlist.c | 59 - sys/getdtablesize.2 | 63 - sys/getpeername.c | 48 - sys/getrlimit.c | 39 - sys/getsockname.c | 48 - sys/ioctl.c | 42 - sys/kill.c | 42 - sys/lchown.c | 47 - sys/libc.syscall | 16 - sys/listen.c | 47 - sys/mmap.c | 55 - sys/mprotect.c | 63 - sys/msync.2 | 103 - sys/msync.c | 48 - sys/munmap.c | 59 - sys/nanosleep.2 | 10 - sys/open.c | 47 - sys/posix_spawn.c | 83 +- sys/recvfrom.c | 47 - sys/recvmsg.c | 47 - sys/remove_counter.c | 49 - sys/rename.c | 35 - sys/select.c | 80 - sys/sem_close.2 | 60 - sys/sem_open.2 | 169 - sys/sem_open.c | 70 - sys/sem_post.2 | 65 - sys/sem_unlink.2 | 74 - sys/sem_unlink.c | 59 - sys/sem_wait.2 | 88 - sys/sendmsg.c | 48 - sys/sendto.c | 48 - sys/setattrlist.c | 59 - sys/setregid.2 | 92 - sys/setreuid.2 | 90 - sys/setrlimit.c | 39 - sys/shm_open.2 | 179 - sys/shm_open.c | 59 - sys/shm_unlink.2 | 87 - sys/shm_unlink.c | 59 - sys/slot_name.c | 66 + sys/socketpair.c | 49 - sys/spinlock.3 | 3 +- sys/stack_protector-obsd.c | 125 +- sys/undelete.2 | 109 - threads/Makefile.inc | 4 +- threads/cprocs.c | 7 +- threads/cthreads.c | 19 +- threads/lu_utils.c | 109 - threads/mig_support.c | 104 +- util/login.c | 1 - util/logout.c | 16 +- util/opendev.c | 34 +- util/pty.c | 2 - uuid/unparse-uuid.c | 87 +- uuid/uuid_unparse.3 | 8 +- uuid/uuid_unparse.3-uuid.in | 8 +- uuid/uuidsrc/unparse.c.patch | 48 + uuid/uuidsrc/uuid_unparse.3.in.patch | 17 +- x86_64/gen/Makefile.inc | 3 +- x86_64/gen/cpu_number.s | 53 + x86_64/gen/getmcontext.c | 2 +- x86_64/gen/icacheinval.s | 23 +- x86_64/gen/setcontext.c | 3 +- x86_64/pthreads/Makefile.inc | 8 +- x86_64/pthreads/preempt.s | 63 + x86_64/pthreads/pthread_getspecific.s | 2 +- x86_64/pthreads/pthread_mutex_lock.s | 26 +- x86_64/pthreads/pthread_self.s | 2 +- x86_64/string/Makefile.inc | 24 +- x86_64/string/__bzero.s | 3 + i386/string/bcopy.s => x86_64/string/bcopy.c | 35 +- x86_64/string/bcopy_sse3x.s | 806 ++++ x86_64/string/bcopy_sse42.s | 300 ++ x86_64/string/{bcopy.s => bzero.c} | 36 +- x86_64/string/bzero_sse2.s | 161 + x86_64/string/bzero_sse42.s | 148 + x86_64/string/longcopy_sse3x.s | 204 + i386/string/bzero.s => x86_64/string/memcpy.c | 28 +- x86_64/string/memcpy.s | 33 - x86_64/string/memmove.c | 40 + x86_64/string/memmove.s | 33 - x86_64/string/memset.s | 212 +- x86_64/string/strncpy.s | 3 +- x86_64/sys/Makefile.inc | 14 +- x86_64/sys/OSAtomic.s | 362 +- x86_64/sys/_setjmp.s | 27 +- x86_64/sys/_sigtramp.s | 17 +- x86_64/sys/atomic.c | 70 + x86_64/sys/i386_gettimeofday.s | 33 - x86_64/sys/i386_gettimeofday_asm.s | 81 + x86_64/sys/nanotime.s | 58 + x86_64/sys/spinlocks.c | 45 + x86_64/sys/spinlocks_asm.s | 123 + 1686 files changed, 49322 insertions(+), 37923 deletions(-) delete mode 100644 Platforms/AppleTV/Makefile.inc delete mode 100644 Platforms/AppleTV/i386/libc.syscall.i386 delete mode 100644 Platforms/MacOSX/arm/libc.syscall.arm delete mode 100644 Platforms/MacOSX/i386/libc.syscall.i386 delete mode 100644 Platforms/MacOSX/ppc/libc.syscall.ppc delete mode 100644 Platforms/MacOSX/ppc64/libc.syscall.ppc64 delete mode 100644 Platforms/MacOSX/x86_64/libc.syscall.x86_64 delete mode 100644 Platforms/iPhone/arm/libc.syscall.arm rename i386/sys/i386_gettimeofday.s => arm/gen/cpu_number.s (81%) delete mode 100644 arm/string/NEON/bcopy.s delete mode 100644 arm/string/NEON/bzero.s delete mode 100644 arm/string/bcopy.s create mode 100644 arm/string/bcopy_CortexA8.s create mode 100644 arm/string/bcopy_CortexA9.s create mode 100644 arm/string/bcopy_Generic.s delete mode 100644 arm/string/bzero.s create mode 100644 arm/string/bzero_CortexA8.s create mode 100644 arm/string/bzero_CortexA9.s create mode 100644 arm/string/bzero_Generic.s create mode 100644 arm/string/dyld_resolvers.c mode change 100755 => 100644 arm/string/memset_pattern.s create mode 100644 arm/string/strchr.s create mode 100644 arm/string/strcpy.s create mode 100644 arm/string/strlcpy.s create mode 100644 arm/string/strncmp.s create mode 100644 arm/string/strncpy.s create mode 100644 arm/string/strnlen.s create mode 100644 arm/string/strstr.s create mode 100644 arm/sys/OSAtomic_resolvers.c create mode 100644 arm/sys/OSAtomic_resolvers.h rename sys/rmdir.c => arm/sys/mach_absolute_time.s (78%) create mode 100644 compat-43/FreeBSD/gethostid.c.patch mode change 120000 => 100644 compat-43/gethostid-fbsd.c create mode 100644 darwin/libproc_internal.h create mode 100644 db/hash/FreeBSD/hash_log2.c.patch mode change 120000 => 100644 db/hash/hash_log2-fbsd.c create mode 100644 emulated/brk.2 create mode 100644 emulated/brk.c create mode 100644 fbsdcompat/reentrant.h delete mode 100644 gdtoa/FreeBSD/gdtoa-smisc.c.patch mode change 100644 => 120000 gdtoa/gdtoa-smisc-fbsd.c create mode 100644 gdtoa/gdtoa.tgz create mode 100644 gen/FreeBSD/psignal.3.patch create mode 100644 gen/FreeBSD/sysctl.c.patch create mode 100644 gen/asl_msg.c create mode 100644 gen/asl_msg.h create mode 100644 gen/assumes.c create mode 100644 gen/assumes.h create mode 100644 gen/endutxent.3.orig delete mode 120000 gen/errno_-fbsd.c create mode 100644 gen/getcap-fbsd.c.orig create mode 100644 gen/getlastlogx.3.orig create mode 100644 gen/getmntinfo64-fbsd.c.orig create mode 100644 gen/pause-fbsd.c.orig create mode 100644 gen/platfunc.c create mode 100644 gen/platfunc.h mode change 120000 => 100644 gen/psignal.3 mode change 120000 => 100644 gen/sysctl-fbsd.c create mode 100644 gen/utmpx_thread.h create mode 100644 i386/gen/cpu_number.s create mode 100644 i386/pthreads/preempt.s create mode 100644 i386/string/__bzero.s create mode 100644 i386/string/bcopy.c create mode 100644 i386/string/bcopy_scalar.s create mode 100644 i386/string/bcopy_sse2.s create mode 100644 i386/string/bcopy_sse3x.s create mode 100644 i386/string/bcopy_sse42.s create mode 100644 i386/string/bzero.c create mode 100644 i386/string/bzero_scalar.s create mode 100644 i386/string/bzero_sse2.s create mode 100644 i386/string/bzero_sse42.s create mode 100644 i386/string/longcopy_sse3x.s create mode 100644 i386/string/memcpy.c delete mode 100644 i386/string/memcpy.s create mode 100644 i386/string/memmove.c delete mode 100644 i386/string/memmove.s create mode 100644 i386/string/memset_pattern_sse2.s create mode 100644 i386/sys/atomic.c create mode 100644 i386/sys/i386_gettimeofday_asm.s create mode 100644 i386/sys/mach_absolute_time.c create mode 100644 i386/sys/mach_absolute_time_asm.s create mode 100644 i386/sys/spinlocks.c create mode 100644 i386/sys/spinlocks_asm.s rename sys/sigsuspend.c => include/CrashReporterClient.h (57%) create mode 100644 include/FreeBSD/nl_types.h create mode 100644 include/FreeBSD/nl_types.h.patch delete mode 100644 include/float.h delete mode 100644 include/protocols/dumprestore.h delete mode 100644 include/stdarg.h create mode 100644 include/stdint.h delete mode 100644 include/varargs.h create mode 100644 interposable.list create mode 100644 locale/FreeBSD/ascii.c create mode 100644 locale/FreeBSD/ascii.c.patch create mode 100644 locale/ascii-fbsd.c create mode 100644 net/FreeBSD/sourcefilter.3 create mode 100644 net/FreeBSD/sourcefilter.3.patch create mode 100644 net/FreeBSD/sourcefilter.c create mode 100644 net/FreeBSD/sourcefilter.c.patch create mode 100644 net/sourcefilter-fbsd.c create mode 100644 net/sourcefilter.3 create mode 100644 posix1e/acl_copy_ext.3 create mode 100644 posix1e/acl_get_permset_mask_np.3 create mode 100644 pthreads/pthread_spis.h create mode 100644 regex/FreeBSD/cname.h.patch create mode 100644 regex/FreeBSD/regerror.c.patch mode change 120000 => 100644 regex/cname.h create mode 100644 regex/cname.h.orig mode change 120000 => 100644 regex/regerror-fbsd.c create mode 100644 regex/regerror-fbsd.c.orig rename sys/unlink.c => secure/stpncpy_chk.c (71%) create mode 100644 stdio/FreeBSD/dprintf.c create mode 100644 stdio/FreeBSD/dprintf.c.patch create mode 100644 stdio/FreeBSD/fgetln.3.patch create mode 100644 stdio/FreeBSD/fgetln.c.patch delete mode 100644 stdio/FreeBSD/fgets.3.patch create mode 100644 stdio/FreeBSD/fgetwln.3 create mode 100644 stdio/FreeBSD/fgetwln.3.patch create mode 100644 stdio/FreeBSD/fgetwln.c create mode 100644 stdio/FreeBSD/fgetwln.c.patch create mode 100644 stdio/FreeBSD/getdelim.c create mode 100644 stdio/FreeBSD/getline.3 create mode 100644 stdio/FreeBSD/getline.3.patch create mode 100644 stdio/FreeBSD/getline.c delete mode 100644 stdio/FreeBSD/glue.h.patch delete mode 100644 stdio/FreeBSD/perror.c.patch create mode 100644 stdio/FreeBSD/printf-pos.c create mode 100644 stdio/FreeBSD/printf-pos.c.patch create mode 100644 stdio/FreeBSD/printfcommon.h create mode 100644 stdio/FreeBSD/printfcommon.h.patch create mode 100644 stdio/FreeBSD/printflocal.h create mode 100644 stdio/FreeBSD/printflocal.h.patch create mode 100644 stdio/FreeBSD/tmpnam.c.patch create mode 100644 stdio/FreeBSD/vdprintf.c create mode 100644 stdio/FreeBSD/vdprintf.c.patch rename stdio/{FreeBSD/unlocked.c => dprintf-fbsd.c} (64%) mode change 120000 => 100644 stdio/fgetln-fbsd.c mode change 120000 => 100644 stdio/fgetln.3 mode change 100644 => 120000 stdio/fgets.3 create mode 100644 stdio/fgetwln-fbsd.c create mode 100644 stdio/fgetwln.3 create mode 120000 stdio/getdelim-fbsd.c create mode 120000 stdio/getline-fbsd.c create mode 100644 stdio/getline.3 mode change 100644 => 120000 stdio/glue.h mode change 100644 => 120000 stdio/perror-fbsd.c create mode 100644 stdio/printf-pos-fbsd.c create mode 100644 stdio/printfcommon.h create mode 100644 stdio/printflocal.h mode change 120000 => 100644 stdio/tmpnam-fbsd.c delete mode 120000 stdio/unlocked-fbsd.c create mode 100644 stdio/vdprintf-fbsd.c create mode 100644 stdlib/FreeBSD/abort.3.patch mode change 120000 => 100644 stdlib/abort.3 delete mode 100644 stdtime/FreeBSD/time2posix.3.patch mode change 100644 => 120000 stdtime/time2posix.3 create mode 100644 string/FreeBSD/memmem.3 create mode 100644 string/FreeBSD/memmem.c create mode 100644 string/FreeBSD/stpncpy.c create mode 100644 string/FreeBSD/strndup.c rename gen/FreeBSD/errno_.c => string/FreeBSD/strnlen.c (81%) create mode 100644 string/FreeBSD/wcpcpy.c create mode 100644 string/FreeBSD/wcpncpy.c create mode 100644 string/FreeBSD/wcscasecmp.c create mode 100644 string/FreeBSD/wcscasecmp.c.patch create mode 100644 string/FreeBSD/wcsdup.c create mode 100644 string/FreeBSD/wcsncasecmp.c create mode 100644 string/FreeBSD/wcsncasecmp.c.patch create mode 100644 string/FreeBSD/wcsnlen.c create mode 120000 string/memmem-fbsd.c create mode 120000 string/memmem.3 create mode 120000 string/stpncpy-fbsd.c create mode 120000 string/strndup-fbsd.c create mode 120000 string/strnlen-fbsd.c create mode 120000 string/wcpcpy-fbsd.c create mode 120000 string/wcpncpy-fbsd.c create mode 100644 string/wcscasecmp-fbsd.c create mode 120000 string/wcsdup-fbsd.c create mode 100644 string/wcsncasecmp-fbsd.c create mode 120000 string/wcsnlen-fbsd.c rename x86_64/string/bzero.s => sys/_libc_fork_child.c (70%) delete mode 100644 sys/accept.c delete mode 100644 sys/bind.c delete mode 100644 sys/chmod.c delete mode 100644 sys/connect.c delete mode 100644 sys/fchmod.c delete mode 100644 sys/fcntl.c delete mode 100644 sys/fix-3375657.c create mode 100644 sys/fork.c delete mode 100644 sys/getattrlist.c delete mode 100644 sys/getdtablesize.2 delete mode 100644 sys/getpeername.c delete mode 100644 sys/getrlimit.c delete mode 100644 sys/getsockname.c delete mode 100644 sys/ioctl.c delete mode 100644 sys/kill.c delete mode 100644 sys/lchown.c delete mode 100644 sys/libc.syscall delete mode 100644 sys/listen.c delete mode 100644 sys/mmap.c delete mode 100644 sys/mprotect.c delete mode 100644 sys/msync.2 delete mode 100644 sys/msync.c delete mode 100644 sys/munmap.c delete mode 100644 sys/open.c delete mode 100644 sys/recvfrom.c delete mode 100644 sys/recvmsg.c delete mode 100644 sys/remove_counter.c delete mode 100644 sys/rename.c delete mode 100644 sys/select.c delete mode 100644 sys/sem_close.2 delete mode 100644 sys/sem_open.2 delete mode 100644 sys/sem_open.c delete mode 100644 sys/sem_post.2 delete mode 100644 sys/sem_unlink.2 delete mode 100644 sys/sem_unlink.c delete mode 100644 sys/sem_wait.2 delete mode 100644 sys/sendmsg.c delete mode 100644 sys/sendto.c delete mode 100644 sys/setattrlist.c delete mode 100644 sys/setregid.2 delete mode 100644 sys/setreuid.2 delete mode 100644 sys/setrlimit.c delete mode 100644 sys/shm_open.2 delete mode 100644 sys/shm_open.c delete mode 100644 sys/shm_unlink.2 delete mode 100644 sys/shm_unlink.c create mode 100644 sys/slot_name.c delete mode 100644 sys/socketpair.c delete mode 100644 sys/undelete.2 delete mode 100644 threads/lu_utils.c mode change 120000 => 100644 uuid/unparse-uuid.c create mode 100644 uuid/uuidsrc/unparse.c.patch create mode 100644 x86_64/gen/cpu_number.s create mode 100644 x86_64/pthreads/preempt.s create mode 100644 x86_64/string/__bzero.s rename i386/string/bcopy.s => x86_64/string/bcopy.c (64%) create mode 100644 x86_64/string/bcopy_sse3x.s create mode 100644 x86_64/string/bcopy_sse42.s rename x86_64/string/{bcopy.s => bzero.c} (64%) create mode 100644 x86_64/string/bzero_sse2.s create mode 100644 x86_64/string/bzero_sse42.s create mode 100644 x86_64/string/longcopy_sse3x.s rename i386/string/bzero.s => x86_64/string/memcpy.c (63%) delete mode 100644 x86_64/string/memcpy.s create mode 100644 x86_64/string/memmove.c delete mode 100644 x86_64/string/memmove.s create mode 100644 x86_64/sys/atomic.c delete mode 100644 x86_64/sys/i386_gettimeofday.s create mode 100644 x86_64/sys/i386_gettimeofday_asm.s create mode 100644 x86_64/sys/nanotime.s create mode 100644 x86_64/sys/spinlocks.c create mode 100644 x86_64/sys/spinlocks_asm.s diff --git a/BSDmakefile b/BSDmakefile index 51f03de..f787db5 100644 --- a/BSDmakefile +++ b/BSDmakefile @@ -2,6 +2,7 @@ .include ALLARCHS = arm i386 ppc ppc64 x86_64 # installsrc doesn't set RC_ARCHS +CODESIGN != xcrun -find codesign TOP != ${PWD} .ifdef DSTROOT DESTDIR = $(DSTROOT) @@ -36,6 +37,11 @@ LIBSYS = $(ALTUSRLOCALLIBSYSTEM) .else LIBSYS = $(SDKROOT)/usr/local/lib/system .endif +.ifdef ALTUSRLIBSYSTEM +LSYS = $(ALTUSRLIBSYSTEM) +.else +LSYS = $(SDKROOT)/usr/lib/system +.endif NJOBS != ${PERL} -e '$$n = `$(SYSCTL) -n hw.ncpu`; printf "%d\n", $$n < 2 ? 2 : ($$n * 1.5)' .ifdef DEBUG MYBSDMAKE = $(BSDMAKE) -f Makefile -P @@ -76,40 +82,49 @@ $($(R)): # These are the non B&I defaults .ifndef RC_ProjectName +RC_ProjectName = Libc + installhdrs: roots installhdrs-real build: roots build-static build-profile build-debug build-dynamic install: roots installhdrs install-all .else # RC_ProjectName +RC_ProjectNameBase := $(RC_ProjectName:%_Sim=%) +.if $(RC_ProjectName) == $(RC_ProjectNameBase) +INSTALL_PREFIX = +.else +INSTALL_PREFIX = $(SDKROOT) +.endif + # And these are to deal with B&I building libc differently # based on RC_ProjectName. -.if $(RC_ProjectName) == Libc +.if $(RC_ProjectNameBase) == Libc installhdrs: build: roots build-dynamic install: roots BI-install-dynamic .endif -.if $(RC_ProjectName) == Libc_headers +.if $(RC_ProjectNameBase) == Libc_headers installhdrs: roots installhdrs-real build: install: roots installhdrs-real .endif -.if $(RC_ProjectName) == Libc_man +.if $(RC_ProjectNameBase) == Libc_man installhdrs: build: install: roots install-man .endif -.if $(RC_ProjectName) == Libc_static +.if $(RC_ProjectNameBase) == Libc_static installhdrs: build: roots build-static install: roots BI-install-static .endif -.if $(RC_ProjectName) == Libc_debug +.if $(RC_ProjectNameBase) == Libc_debug installhdrs: build: roots build-debug install: roots BI-install-debug .endif -.if $(RC_ProjectName) == Libc_profile +.if $(RC_ProjectNameBase) == Libc_profile installhdrs: build: roots build-profile install: roots BI-install-profile @@ -132,7 +147,7 @@ $(FRAMEWORKS): ${LN} -fs $(VERSIONSB)/PrivateHeaders $(FRAMEWORKS)/$(SYSTEMFRAMEWORK)/PrivateHeaders AUTOPATCHED = $(SRCROOT)/.autopatched -PARTIAL = -partial +PARTIAL = .for F in $(FORMS) # { .if $(dynamic) == $(F) # { SUFFIX-$(F) = @@ -196,13 +211,13 @@ $(AUTOPATCHED): touch $(AUTOPATCHED) copysrc: - ${PAX} -rw -p p . "$(SRCROOT)" + ${TAR} -cp --exclude .git --exclude .svn --exclude CVS . | ${TAR} -pox -C "$(SRCROOT)" installsrc: copysrc $(AUTOPATCHED) installhdrs-real: - MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)" MAKEFLAGS="" \ - DSTROOT=$(DSTROOT) OBJROOT=$(OBJROOT) SYMROOT=$(SYMROOT) \ + MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)$(INSTALL_PREFIX)" MAKEFLAGS="" \ + DSTROOT="$(DSTROOT)$(INSTALL_PREFIX)" OBJROOT=$(OBJROOT) SYMROOT=$(SYMROOT) \ $(MYBSDMAKEJ) installhdrs .for A in $(RC_ARCHS) # { ${MKDIR} "$(OBJROOT)/obj.$(A)" && \ @@ -214,19 +229,24 @@ installhdrs-real: .for F in $(FORMS) # { BI-install-$(F): build-$(F) + $(CC) -dynamiclib -o $(SYMROOT)/libsystem_c$(SUFFIX-$(F)).dylib $(RC_ARCHS:C/^/-arch /g) \ + -compatibility_version 1 -current_version $(RC_ProjectSourceVersion) \ + -install_name /usr/lib/system/libsystem_c$(SUFFIX-$(F)).dylib -nostdlib -Wl,-umbrella,System \ + -all_load $(SYMROOT)/libc$(PSUFFIX-$(F)).a -Wl,-interposable_list,$(SRCROOT)/interposable.list \ + -L$(LSYS) -L$(SDKROOT)/usr/lib -lSystem -lgcc ${MKDIR} $(DSTROOT)/usr/local/lib/system - if [ -f "$(SYMROOT)/libc$(PSUFFIX-$(F)).a" ]; then \ - ${ECHO} "Installing libc$(PSUFFIX-$(F)).a" && \ - ${INSTALL} -m 444 "$(SYMROOT)/libc$(PSUFFIX-$(F)).a" \ - $(DSTROOT)/usr/local/lib/system && \ - ${RANLIB} "$(DSTROOT)/usr/local/lib/system/libc$(PSUFFIX-$(F)).a" || exit 1; \ - fi + ${MKDIR} $(DSTROOT)/usr/lib/system + ${INSTALL} $(SYMROOT)/libsystem_c$(SUFFIX-$(F)).dylib $(DSTROOT)/usr/lib/system + ${STRIP} -S $(DSTROOT)/usr/lib/system/libsystem_c$(SUFFIX-$(F)).dylib + -${CODESIGN} -s - $(DSTROOT)/usr/lib/system/libsystem_c$(SUFFIX-$(F)).dylib .if $(dynamic) == $(F) # { if [ -f "$(SYMROOT)/libc-dyld.a" ]; then \ ${ECHO} "Installing libc-dyld.a" && \ + ${MKDIR} $(DSTROOT)/usr/local/lib/dyld && \ ${INSTALL} -m 444 "$(SYMROOT)/libc-dyld.a" \ - $(DSTROOT)/usr/local/lib/system && \ - ${RANLIB} "$(DSTROOT)/usr/local/lib/system/libc-dyld.a" || exit 1; \ + $(DSTROOT)/usr/local/lib/dyld/libc.a && \ + ${LN} -sf "../dyld/libc.a" "$(DSTROOT)/usr/local/lib/system/libc-dyld.a" && \ + ${RANLIB} "$(DSTROOT)/usr/local/lib/dyld/libc.a" || exit 1; \ fi .for A in $(RC_ARCHS) # { MAKEOBJDIR="$(OBJROOT)/obj.$(A)" MACHINE_ARCH=$(MACHINE_ARCH-$(A)) CCARCH=$(A) \ @@ -249,8 +269,8 @@ install-man: ${MKDIR} $(DSTROOT)/usr/share/man/man4 ${MKDIR} $(DSTROOT)/usr/share/man/man5 ${MKDIR} $(DSTROOT)/usr/share/man/man7 - MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)" \ - DSTROOT='$(DSTROOT)' OBJROOT='$(OBJROOT)' SYMROOT='$(SYMROOT)' \ + MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)$(INSTALL_PREFIX)" \ + DSTROOT='$(DSTROOT)$(INSTALL_PREFIX)' OBJROOT='$(OBJROOT)' SYMROOT='$(SYMROOT)' \ MACHINE_ARCH="$(MACHINE_ARCH-$(FIRST_ARCH))" CCARCH=$(FIRST_ARCH) MAKEFLAGS="" \ RC_NONARCH_CFLAGS="$(RC_NONARCH_CFLAGS)" \ $(MYBSDMAKE) all-man maninstall $(MANARGS) diff --git a/Makefile b/Makefile index d2a3e7c..c86cdf5 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,10 @@ LP64 = 1 RC_TARGET_CONFIG = MacOSX .endif +.ifndef RC_ProjectName +RC_ProjectName = Libc +.endif + # Use default compiler, so comment out OTHERCC #OTHERCC = gcc-4.0 # HOSTCC is the compiler on the local host, so we need to unset any SDKROOT @@ -52,7 +56,7 @@ SYMROOTINC = ${SYMROOT}/include CFLAGS = -g -arch ${CCARCH} ${RC_NONARCH_CFLAGS} -std=gnu99 -fno-common -fno-builtin -Wmost CFLAGS += -D__LIBC__ -D__DARWIN_UNIX03=1 -D__DARWIN_64_BIT_INO_T=1 -D__DARWIN_NON_CANCELABLE=1 -D__DARWIN_VERS_1050=1 -D_FORTIFY_SOURCE=0 CFLAGS += -DNOID -DLIBC_MAJOR=${SHLIB_MAJOR} -CFLAGS += -I${.OBJDIR} -I${SYMROOTINC} -I${.CURDIR}/include +CFLAGS += -I${.OBJDIR} ${VARIANTINC} -I${SYMROOTINC} -I${.CURDIR}/include AINC = -g -arch ${CCARCH} ${RC_NONARCH_CFLAGS} AINC += -I${.CURDIR}/${MACHINE_ARCH} ${PRIVINC} .if $(MACHINE_ARCH) != arm @@ -64,10 +68,6 @@ CFLAGS += -isysroot '${SDKROOT}' AINC += -isysroot '${SDKROOT}' .endif # SDKROOT -.if ${GCC_42} != YES -CFLAGS += -no-cpp-precomp -AINC += -no-cpp-precomp -.endif CLEANFILES+=tags INSTALL_PIC_ARCHIVE= yes PRECIOUSLIB= yes @@ -85,11 +85,12 @@ _x_ != ${TEST} -d ${SYMROOT} || ${MKDIR} ${SYMROOT} .endif DESTDIR ?= ${DSTROOT} MAKEOBJDIR ?= ${OBJROOT} +PLATROOT != xcodebuild -version -sdk $(SDKROOT) PlatformPath | tr -d '\n' # add version string SRCS += libc_version.c libc_version.c: - ${SDKROOT}/Developer/Makefiles/bin/version.pl Libc > $@ + ${PLATROOT}/Developer/Makefiles/bin/version.pl Libc > $@ .include "Makefile.features" .include "${.CURDIR}/Makefile.inc" diff --git a/Makefile.features b/Makefile.features index ea2c13d..56906a2 100644 --- a/Makefile.features +++ b/Makefile.features @@ -7,6 +7,11 @@ _BLOCKS != ${MYCC} -arch ${CCARCH} -E -dD -x c /dev/null | fgrep -q __BLOCKS__ | FEATURE_BLOCKS = YES .endif # _BLOCKS .endif # CCARCH +_LIBCRASHREPORTERCLIENT_A = ${SDKROOT}/usr/local/lib/libCrashReporterClient.a +_LIBCRASHREPORTERCLIENT != test -f ${_LIBCRASHREPORTERCLIENT_A} || echo NO +.if ${_LIBCRASHREPORTERCLIENT} == NO +FEATURE_NO_LIBCRASHREPORTERCLIENT = YES +.endif # !_LIBCRASHREPORTERCLIENT ${SYMROOTINC}/${MACHINE_ARCH}/libc-features.h: ${MKDIR} ${.TARGET:H} @@ -15,14 +20,19 @@ ${SYMROOTINC}/${MACHINE_ARCH}/libc-features.h: @echo '#define _LIBC_FEATURES_H_' >> ${.TARGET} @echo >> ${.TARGET} .ifdef FEATURE_LEGACY_RUNE_APIS - @echo '#define LEGACY_RUNE_APIS 1' >> ${.TARGET} + @echo '#define UNIFDEF_LEGACY_RUNE_APIS 1' >> ${.TARGET} .else - @echo '/* #undef LEGACY_RUNE_APIS */' >> ${.TARGET} + @echo '/* #undef UNIFDEF_LEGACY_RUNE_APIS */' >> ${.TARGET} +.endif +.ifdef FEATURE_LEGACY_CRT1_ENVIRON + @echo '#define LEGACY_CRT1_ENVIRON 1' >> ${.TARGET} +.else + @echo '/* #undef LEGACY_CRT1_ENVIRON */' >> ${.TARGET} .endif .ifdef FEATURE_LEGACY_UTMP_APIS - @echo '#define LEGACY_UTMP_APIS 1' >> ${.TARGET} + @echo '#define UNIFDEF_LEGACY_UTMP_APIS 1' >> ${.TARGET} .else - @echo '/* #undef LEGACY_UTMP_APIS */' >> ${.TARGET} + @echo '/* #undef UNIFDEF_LEGACY_UTMP_APIS */' >> ${.TARGET} .endif .ifdef FEATURE_MOVE_LOCALTIME @echo '#define UNIFDEF_MOVE_LOCALTIME 1' >> ${.TARGET} @@ -70,11 +80,6 @@ ${SYMROOTINC}/${MACHINE_ARCH}/libc-features.h: @echo '# error Feature mismatch: __DARWIN_ONLY_64_BIT_INO_T == 1' >> ${.TARGET} @echo '#endif /* __DARWIN_ONLY_64_BIT_INO_T */' >> ${.TARGET} .endif -.ifdef FEATURE_PATCH_3375657 - @echo '#define __APPLE_PR3375657_HACK__ 1' >> ${.TARGET} -.else - @echo '/* #undef __APPLE_PR3375657_HACK__ */' >> ${.TARGET} -.endif .ifdef FEATURE_PATCH_3417676 @echo '#define __APPLE_PR3417676_HACK__ 1' >> ${.TARGET} .else @@ -94,6 +99,11 @@ ${SYMROOTINC}/${MACHINE_ARCH}/libc-features.h: @echo '#define NOTIFY_TZ 1' >> ${.TARGET} .else @echo '/* #undef NOTIFY_TZ */' >> ${.TARGET} +.endif +.ifdef FEATURE_NO_LIBCRASHREPORTERCLIENT + @echo '#define LIBC_NO_LIBCRASHREPORTERCLIENT 1' >> ${.TARGET} +.else + @echo '/* #undef LIBC_NO_LIBCRASHREPORTERCLIENT */' >> ${.TARGET} .endif @echo >> ${.TARGET} @echo '#endif /* _LIBC_FEATURES_H_ */' >> ${.TARGET} diff --git a/Makefile.xbs b/Makefile.xbs index 7ca23a0..6191453 100644 --- a/Makefile.xbs +++ b/Makefile.xbs @@ -82,7 +82,7 @@ MDSRCS += ldbl64.s CFLAGS_CANCELABLE= -DVARIANT_CANCELABLE CFLAGS_DARWINEXTSN= -DVARIANT_DARWINEXTSN -CFLAGS_DYLD= -DVARIANT_DYLD +CFLAGS_DYLD= -DVARIANT_DYLD -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0 CFLAGS_INODE32= -U__DARWIN_64_BIT_INO_T -D__DARWIN_64_BIT_INO_T=0 -DVARIANT_INODE32 CFLAGS_LDBL= -mlong-double-64 -DLDBL_COMPAT CFLAGS_LEGACY= -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0 -U__DARWIN_64_BIT_INO_T -D__DARWIN_64_BIT_INO_T=0 -DVARIANT_LEGACY @@ -111,22 +111,22 @@ ${_v:H:S,/,,}_BUILDING_VARIANT = -DBUILDING_VARIANT ${_v:H:S,/,,}: .ifdef ${_v:H:S,/,,}SRCS ${MKDIR} ${MAKEOBJDIR}/${_v:H:S,/,,}; \ - MAKEOBJDIR="${MAKEOBJDIR}/${_v:H:S,/,,}" VARIANTCFLAGS="-DBUILDING_VARIANT ${_v:T:S/@/ /g}" ${MYBSDMAKE} -C "${.CURDIR}" build_${_v:H:S,/,,} + MAKEOBJDIR="${MAKEOBJDIR}/${_v:H:S,/,,}" VARIANTCFLAGS="-DBUILDING_VARIANT ${_v:T:S/@/ /g}" VARIANTINC="-I${MAKEOBJDIR}" ${MYBSDMAKE} -C "${.CURDIR}" build_${_v:H:S,/,,} .endif ${_v:H:S,/,,}_D: .ifdef ${_v:H:S,/,,}SRCS ${MKDIR} ${MAKEOBJDIR}/${_v:H:S,/,,}; \ - MAKEOBJDIR="${MAKEOBJDIR}/${_v:H:S,/,,}" VARIANTCFLAGS="-DBUILDING_VARIANT ${_v:T:S/@/ /g}" ${MYBSDMAKE} -C "${.CURDIR}" build_${_v:H:S,/,,}_D + MAKEOBJDIR="${MAKEOBJDIR}/${_v:H:S,/,,}" VARIANTCFLAGS="-DBUILDING_VARIANT ${_v:T:S/@/ /g}" VARIANTINC="-I${MAKEOBJDIR}" ${MYBSDMAKE} -C "${.CURDIR}" build_${_v:H:S,/,,}_D .endif ${_v:H:S,/,,}_P: .ifdef ${_v:H:S,/,,}SRCS ${MKDIR} ${MAKEOBJDIR}/${_v:H:S,/,,}; \ - MAKEOBJDIR="${MAKEOBJDIR}/${_v:H:S,/,,}" VARIANTCFLAGS="-DBUILDING_VARIANT ${_v:T:S/@/ /g}" ${MYBSDMAKE} -C "${.CURDIR}" build_${_v:H:S,/,,}_P + MAKEOBJDIR="${MAKEOBJDIR}/${_v:H:S,/,,}" VARIANTCFLAGS="-DBUILDING_VARIANT ${_v:T:S/@/ /g}" VARIANTINC="-I${MAKEOBJDIR}" ${MYBSDMAKE} -C "${.CURDIR}" build_${_v:H:S,/,,}_P .endif ${_v:H:S,/,,}_S: .ifdef ${_v:H:S,/,,}SRCS ${MKDIR} ${MAKEOBJDIR}/${_v:H:S,/,,}; \ - MAKEOBJDIR="${MAKEOBJDIR}/${_v:H:S,/,,}" VARIANTCFLAGS="${${_v:H:S,/,,}_BUILDING_VARIANT} ${_v:T:S/@/ /g}" ${MYBSDMAKE} -C "${.CURDIR}" build_${_v:H:S,/,,}_S + MAKEOBJDIR="${MAKEOBJDIR}/${_v:H:S,/,,}" VARIANTCFLAGS="${${_v:H:S,/,,}_BUILDING_VARIANT} ${_v:T:S/@/ /g}" VARIANTINC="-I${MAKEOBJDIR}" ${MYBSDMAKE} -C "${.CURDIR}" build_${_v:H:S,/,,}_S .endif .endfor @@ -321,22 +321,25 @@ UUIDFLAGS= -include uuid-config.h ${MYCC} -static -x assembler-with-cpp \ ${PRECFLAGS:M-[BIDFU]*} ${PRECFLAGS-${.IMPSRC:T}:M-[BIDFU]*} \ ${CFLAGS:M-[BIDFU]*} ${CFLAGS-${.IMPSRC:T}:M-[BIDFU]*} ${AINC} \ - -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} + ${VARIANTCFLAGS:M-[BIDFU]*} -Os ${OPTIMIZE-${.IMPSRC:T}} \ + -c ${.IMPSRC} -o ${.TARGET} .s.po .S.po: ${MYCC} -pg -x assembler-with-cpp -DPROFILE \ ${PRECFLAGS:M-[BIDFU]*} ${PRECFLAGS-${.IMPSRC:T}:M-[BIDFU]*} \ ${CFLAGS:M-[BIDFU]*} ${CFLAGS-${.IMPSRC:T}:M-[BIDFU]*} ${AINC} \ - -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} + ${VARIANTCFLAGS:M-[BIDFU]*} -Os ${OPTIMIZE-${.IMPSRC:T}} \ + -c ${.IMPSRC} -o ${.TARGET} .s.So .S.So: ${MYCC} -x assembler-with-cpp \ ${PRECFLAGS:M-[BIDFU]*} ${PRECFLAGS-${.IMPSRC:T}:M-[BIDFU]*} \ ${CFLAGS:M-[BIDFU]*} ${CFLAGS-${.IMPSRC:T}:M-[BIDFU]*} ${AINC} \ - -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} + ${VARIANTCFLAGS:M-[BIDFU]*} -Os ${OPTIMIZE-${.IMPSRC:T}} \ + -c ${.IMPSRC} -o ${.TARGET} .s.do .S.do: ${MYCC} -x assembler-with-cpp -DDEBUG \ ${PRECFLAGS:M-[BIDFU]*} ${PRECFLAGS-${.IMPSRC:T}:M-[BIDFU]*} \ ${CFLAGS:M-[BIDFU]*} ${CFLAGS-${.IMPSRC:T}:M-[BIDFU]*} ${AINC} \ - -c ${.IMPSRC} -o ${.TARGET} + ${VARIANTCFLAGS:M-[BIDFU]*} -c ${.IMPSRC} -o ${.TARGET} #### mig Rules ######################################################## .defs.h .defsUser.c .defsServer.c: @@ -345,33 +348,46 @@ UUIDFLAGS= -include uuid-config.h gen_mig_defs: ${SRVMIGHDRS} ${MIGHDRS} gen_md_mig_defs: ${MD_MIGHDRS} +#### CrashReporterClient Rules ######################################## +.ifdef FEATURE_NO_LIBCRASHREPORTERCLIENT +CRASHREPORTERCLIENTOBJ = +.else # !FEATURE_NO_LIBCRASHREPORTERCLIENT +CRASHREPORTERCLIENT = CrashReporterClient +CRASHREPORTERCLIENTOBJ = ${CRASHREPORTERCLIENT}.${OBJSUFFIX} +LIBCRASHREPORTERCLIENT = lib${CRASHREPORTERCLIENT}.a +${CRASHREPORTERCLIENTOBJ}: ${SDKROOT}/usr/local/lib/${LIBCRASHREPORTERCLIENT} + ditto -arch ${MACHINE_ARCH} $> ${LIBCRASHREPORTERCLIENT} + ar x ${LIBCRASHREPORTERCLIENT} + mv ${CRASHREPORTERCLIENT}.o $@ +.endif # !FEATURE_NO_LIBCRASHREPORTERCLIENT + #### Library Rules #################################################### ${VARIANTCOMBOS:N*DYLD*} ${OBJS} ${STATICOBJS}: ${SYMROOTINC}/${MACHINE_ARCH}/libc-features.h -lib${LIB}_static.a:: ${VARIANTCOMBOS:N*DYLD*} ${OBJS} ${STATICOBJS} +lib${LIB}_static.a:: ${BUILDFIRST} ${VARIANTCOMBOS:N*DYLD*} ${OBJS} ${STATICOBJS} ${CRASHREPORTERCLIENTOBJ} @${ECHO} building static ${LIB} library @${RM} lib${LIB}_static.a - @${AR} cq lib${LIB}_static.a `${LORDER} ${OBJS} ${STATICOBJS} ${VARIANTOBJS} | ${TSORT} -q` + @${AR} cq lib${LIB}_static.a `${LORDER} ${OBJS} ${STATICOBJS} ${VARIANTOBJS} ${CRASHREPORTERCLIENTOBJ} | ${TSORT} -q` ${RANLIB} lib${LIB}_static.a ${VARIANTCOMBOS:N*DYLD*:S/$/_P/g} ${POBJS}: ${SYMROOTINC}/${MACHINE_ARCH}/libc-features.h -lib${LIB}_profile.a:: ${VARIANTCOMBOS:N*DYLD*:S/$/_P/g} ${POBJS} +lib${LIB}_profile.a:: ${BUILDFIRST} ${VARIANTCOMBOS:N*DYLD*:S/$/_P/g} ${POBJS} ${CRASHREPORTERCLIENTOBJ} @${ECHO} building profiled ${LIB} library @${RM} lib${LIB}_profile.a - @${AR} cq lib${LIB}_profile.a `${LORDER} ${POBJS} ${VARIANTPOBJS} | ${TSORT} -q` + @${AR} cq lib${LIB}_profile.a `${LORDER} ${POBJS} ${VARIANTPOBJS} ${CRASHREPORTERCLIENTOBJ} | ${TSORT} -q` ${RANLIB} lib${LIB}_profile.a ${VARIANTCOMBOS:N*DYLD*:S/$/_D/g} ${DOBJS}: ${SYMROOTINC}/${MACHINE_ARCH}/libc-features.h -lib${LIB}_debug.a:: ${VARIANTCOMBOS:N*DYLD*:S/$/_D/g} ${DOBJS} +lib${LIB}_debug.a:: ${BUILDFIRST} ${VARIANTCOMBOS:N*DYLD*:S/$/_D/g} ${DOBJS} ${CRASHREPORTERCLIENTOBJ} @${ECHO} building debug ${LIB} library @${RM} lib${LIB}_debug.a - @${AR} cq lib${LIB}_debug.a `${LORDER} ${DOBJS} ${VARIANTDOBJS} | ${TSORT} -q` + @${AR} cq lib${LIB}_debug.a `${LORDER} ${DOBJS} ${VARIANTDOBJS} ${CRASHREPORTERCLIENTOBJ} | ${TSORT} -q` ${RANLIB} lib${LIB}_debug.a ${VARIANTCOMBOS:S/$/_S/g} ${SOBJS}: ${SYMROOTINC}/${MACHINE_ARCH}/libc-features.h -lib${LIB}.a:: ${VARIANTCOMBOS:S/$/_S/g} ${SOBJS} +lib${LIB}.a:: ${BUILDFIRST} ${VARIANTCOMBOS:S/$/_S/g} ${SOBJS} ${CRASHREPORTERCLIENTOBJ} @${ECHO} building standard ${LIB} library @${RM} lib${LIB}.a - @${AR} cq lib${LIB}.a `${LORDER} ${SOBJS} ${VARIANTSOBJS} | ${TSORT} -q` + @${AR} cq lib${LIB}.a `${LORDER} ${SOBJS} ${VARIANTSOBJS} ${CRASHREPORTERCLIENTOBJ} | ${TSORT} -q` ${RANLIB} lib${LIB}.a @${ECHO} building custom ${LIB} library for dyld @${RM} lib${LIB}-dyld.a diff --git a/Platforms/AppleTV/Makefile.inc b/Platforms/AppleTV/Makefile.inc deleted file mode 100644 index 1b391d9..0000000 --- a/Platforms/AppleTV/Makefile.inc +++ /dev/null @@ -1,56 +0,0 @@ -# -# Selectable features for iPhone -# - -# Legacy *64 APIs -#FEATURE_LEGACY_64_APIS = 1 - -# Legacy NX international APIs -FEATURE_LEGACY_NX_INTERNAT_APIS = 1 - -# Legacy NXZone APIs -FEATURE_LEGACY_NXZONE_APIS = 1 - -# Legacy rune APIs -#FEATURE_LEGACY_RUNE_APIS = 1 - -# Legacy utmp APIs -#FEATURE_LEGACY_UTMP_APIS = 1 - -# New OSMemoryNotification and OSThermalNotification APIs -FEATURE_MEM_THERM_NOTIFICATION_APIS = 1 - -# Move localtime to /var/db/timezone -FEATURE_MOVE_LOCALTIME = 1 - -# Long doubles are doubles (should match sys/cdefs.h) -.if (${MACHINE_ARCH} == arm) -FEATURE_ONLY_LONG_DOUBLE_IS_DOUBLE = 1 -.endif - -# No pre-1050 variants (should match sys/cdefs.h) -FEATURE_ONLY_1050_VARIANTS = 1 - -# No legacy variants (should match sys/cdefs.h) -FEATURE_ONLY_UNIX_CONFORMANCE = 1 - -# Only 64-bit ino_t (should match sys/cdefs.h) -FEATURE_ONLY_64_BIT_INO_T = 1 - -# Patch 3333969 -#FEATURE_PATCH_3333969 = 1 - -# Patch 3375657 -#FEATURE_PATCH_3375657 = 1 - -# Patch 3417676 -#FEATURE_PATCH_3417676 = 1 - -# Patch 5243343 -FEATURE_PATCH_5243343 = 1 - -# plockstat dtrace support -#FEATURE_PLOCKSTAT = 1 - -# Timezone change notification -#FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1 diff --git a/Platforms/AppleTV/i386/libc.syscall.i386 b/Platforms/AppleTV/i386/libc.syscall.i386 deleted file mode 100644 index 50ba3d4..0000000 --- a/Platforms/AppleTV/i386/libc.syscall.i386 +++ /dev/null @@ -1,46 +0,0 @@ -_accept$NOCANCEL ___accept_nocancel -_aio_suspend$NOCANCEL ___aio_suspend_nocancel -_close$NOCANCEL ___close_nocancel -_connect$NOCANCEL ___connect_nocancel -_fcntl$NOCANCEL ___fcntl_nocancel -_fstat ___fstat64 -_fstat64 -_fstatfs ___fstatfs64 -_fstatfs64 -_fstatx_np ___fstatx64_np -_fstatx64_np -_fsync$NOCANCEL ___fsync_nocancel -_getfsstat ___getfsstat64 -_getfsstat64 -_getmntinfo ___getmntinfo64 -_getmntinfo64 -_lstat ___lstat64 -_lstat64 -_lstatx_np ___lstatx64_np -_lstatx64_np -_msgrcv$NOCANCEL ___msgrcv_nocancel -_msgsnd$NOCANCEL ___msgsnd_nocancel -_msync$NOCANCEL ___msync_nocancel -_open$NOCANCEL ___open_nocancel -_poll$NOCANCEL ___poll_nocancel -_pread$NOCANCEL ___pread_nocancel -_pwrite$NOCANCEL ___pwrite_nocancel -_read$NOCANCEL ___read_nocancel -_readv$NOCANCEL ___readv_nocancel -_recvfrom$NOCANCEL ___recvfrom_nocancel -_recvmsg$NOCANCEL ___recvmsg_nocancel -_select$DARWIN_EXTSN ___select -_select$DARWIN_EXTSN$NOCANCEL ___select_nocancel -_sem_wait$NOCANCEL ___sem_wait_nocancel -_sendmsg$NOCANCEL ___sendmsg_nocancel -_sendto$NOCANCEL ___sendto_nocancel -_sendto$NOCANCEL ___sendto_nocancel -_stat ___stat64 -_stat64 -_statfs ___statfs64 -_statfs64 -_statx_np ___statx64_np -_statx64_np -_waitid$NOCANCEL ___waitid_nocancel -_write$NOCANCEL ___write_nocancel -_writev$NOCANCEL ___writev_nocancel diff --git a/Platforms/MacOSX/Makefile.inc b/Platforms/MacOSX/Makefile.inc index 99921ee..97d5f07 100644 --- a/Platforms/MacOSX/Makefile.inc +++ b/Platforms/MacOSX/Makefile.inc @@ -5,6 +5,9 @@ # Legacy *64 APIs FEATURE_LEGACY_64_APIS = 1 +# Legacy crt1.o environ support +FEATURE_LEGACY_CRT1_ENVIRON = 1 + # Legacy NX international APIs FEATURE_LEGACY_NX_INTERNAT_APIS = 1 @@ -42,9 +45,6 @@ FEATURE_ONLY_UNIX_CONFORMANCE = 1 # Patch 3333969 FEATURE_PATCH_3333969 = 1 -# Patch 3375657 -#FEATURE_PATCH_3375657 = 1 - # Patch 3417676 FEATURE_PATCH_3417676 = 1 diff --git a/Platforms/MacOSX/arm/libc.syscall.arm b/Platforms/MacOSX/arm/libc.syscall.arm deleted file mode 100644 index ea8beef..0000000 --- a/Platforms/MacOSX/arm/libc.syscall.arm +++ /dev/null @@ -1,89 +0,0 @@ -_accept$NOCANCEL$UNIX2003 ___accept_nocancel -_accept$UNIX2003 ___accept -_accept$UNIX2003 ___accept -_aio_suspend ___aio_suspend_nocancel -_aio_suspend$NOCANCEL$UNIX2003 ___aio_suspend_nocancel -_aio_suspend$UNIX2003 ___aio_suspend -_bind$UNIX2003 ___bind -_close ___close_nocancel -_close$NOCANCEL$UNIX2003 ___close_nocancel -_close$UNIX2003 ___close -_connect$NOCANCEL$UNIX2003 ___connect_nocancel -_connect$UNIX2003 ___connect -_connect$UNIX2003 ___connect -_fcntl ___fcntl_nocancel -_fcntl$NOCANCEL$UNIX2003 ___fcntl_nocancel -_fcntl$UNIX2003 ___fcntl -_fstat$INODE64 ___fstat64 -_fstatfs$INODE64 ___fstatfs64 -_fsync ___fsync_nocancel -_fsync$NOCANCEL$UNIX2003 ___fsync_nocancel -_fsync$UNIX2003 ___fsync -_getattrlist$UNIX2003 ___getattrlist -_getfsstat$INODE64 ___getfsstat64 -_getpeername$UNIX2003 ___getpeername -_getsockname$UNIX2003 ___getsockname -_lchown$UNIX2003 ___lchown -_listen$UNIX2003 ___listen -_lstat$INODE64 ___lstat64 -_mprotect$UNIX2003 ___mprotect -_msgctl$UNIX2003 ___msgctl -_msgrcv ___msgrcv_nocancel -_msgrcv$NOCANCEL$UNIX2003 ___msgrcv_nocancel -_msgrcv$UNIX2003 ___msgrcv -_msgsnd ___msgsnd_nocancel -_msgsnd$NOCANCEL$UNIX2003 ___msgsnd_nocancel -_msgsnd$UNIX2003 ___msgsnd -_msync$NOCANCEL$UNIX2003 ___msync_nocancel -_msync$UNIX2003 ___msync -_munmap$UNIX2003 ___munmap -_open$NOCANCEL$UNIX2003 ___open_nocancel -_open$UNIX2003 ___open -_poll ___poll_nocancel -_poll$NOCANCEL$UNIX2003 ___poll_nocancel -_poll$UNIX2003 ___poll -_pread ___pread_nocancel -_pread$NOCANCEL$UNIX2003 ___pread_nocancel -_pread$UNIX2003 ___pread -_pwrite ___pwrite_nocancel -_pwrite$NOCANCEL$UNIX2003 ___pwrite_nocancel -_pwrite$UNIX2003 ___pwrite -_read ___read_nocancel -_read$NOCANCEL$UNIX2003 ___read_nocancel -_read$UNIX2003 ___read -_readv ___readv_nocancel -_readv$NOCANCEL$UNIX2003 ___readv_nocancel -_readv$UNIX2003 ___readv -_recvfrom$NOCANCEL$UNIX2003 ___recvfrom_nocancel -_recvfrom$UNIX2003 ___recvfrom -_recvmsg$NOCANCEL$UNIX2003 ___recvmsg_nocancel -_recvmsg$UNIX2003 ___recvmsg -_select$DARWIN_EXTSN ___select -_select$DARWIN_EXTSN$NOCANCEL ___select_nocancel -_sem_wait ___sem_wait_nocancel -_sem_wait$NOCANCEL$UNIX2003 ___sem_wait_nocancel -_sem_wait$UNIX2003 ___sem_wait -_semctl$UNIX2003 ___semctl -_sendmsg$NOCANCEL$UNIX2003 ___sendmsg_nocancel -_sendmsg$UNIX2003 ___sendmsg -_sendto$NOCANCEL$UNIX2003 ___sendto_nocancel -_sendto$NOCANCEL$UNIX2003 ___sendto_nocancel -_sendto$UNIX2003 ___sendto -_sendto$UNIX2003 ___sendto -_setattrlist$UNIX2003 ___setattrlist -_setpgrp ___setpgid -_setregid$UNIX2003 ___setregid -_setreuid$UNIX2003 ___setreuid -_shmctl$UNIX2003 ___shmctl -_socketpair$UNIX2003 ___socketpair -_stat$INODE64 ___stat64 -_statfs$INODE64 ___statfs64 -_waitid ___waitid_nocancel -_waitid$NOCANCEL$UNIX2003 ___waitid_nocancel -_waitid$UNIX2003 ___waitid -_write ___write_nocancel -_write$NOCANCEL$UNIX2003 ___write_nocancel -_write$UNIX2003 ___write -_writev ___writev_nocancel -_writev$NOCANCEL$UNIX2003 ___writev_nocancel -_writev$UNIX2003 ___writev diff --git a/Platforms/MacOSX/i386/libc.syscall.i386 b/Platforms/MacOSX/i386/libc.syscall.i386 deleted file mode 100644 index ea8beef..0000000 --- a/Platforms/MacOSX/i386/libc.syscall.i386 +++ /dev/null @@ -1,89 +0,0 @@ -_accept$NOCANCEL$UNIX2003 ___accept_nocancel -_accept$UNIX2003 ___accept -_accept$UNIX2003 ___accept -_aio_suspend ___aio_suspend_nocancel -_aio_suspend$NOCANCEL$UNIX2003 ___aio_suspend_nocancel -_aio_suspend$UNIX2003 ___aio_suspend -_bind$UNIX2003 ___bind -_close ___close_nocancel -_close$NOCANCEL$UNIX2003 ___close_nocancel -_close$UNIX2003 ___close -_connect$NOCANCEL$UNIX2003 ___connect_nocancel -_connect$UNIX2003 ___connect -_connect$UNIX2003 ___connect -_fcntl ___fcntl_nocancel -_fcntl$NOCANCEL$UNIX2003 ___fcntl_nocancel -_fcntl$UNIX2003 ___fcntl -_fstat$INODE64 ___fstat64 -_fstatfs$INODE64 ___fstatfs64 -_fsync ___fsync_nocancel -_fsync$NOCANCEL$UNIX2003 ___fsync_nocancel -_fsync$UNIX2003 ___fsync -_getattrlist$UNIX2003 ___getattrlist -_getfsstat$INODE64 ___getfsstat64 -_getpeername$UNIX2003 ___getpeername -_getsockname$UNIX2003 ___getsockname -_lchown$UNIX2003 ___lchown -_listen$UNIX2003 ___listen -_lstat$INODE64 ___lstat64 -_mprotect$UNIX2003 ___mprotect -_msgctl$UNIX2003 ___msgctl -_msgrcv ___msgrcv_nocancel -_msgrcv$NOCANCEL$UNIX2003 ___msgrcv_nocancel -_msgrcv$UNIX2003 ___msgrcv -_msgsnd ___msgsnd_nocancel -_msgsnd$NOCANCEL$UNIX2003 ___msgsnd_nocancel -_msgsnd$UNIX2003 ___msgsnd -_msync$NOCANCEL$UNIX2003 ___msync_nocancel -_msync$UNIX2003 ___msync -_munmap$UNIX2003 ___munmap -_open$NOCANCEL$UNIX2003 ___open_nocancel -_open$UNIX2003 ___open -_poll ___poll_nocancel -_poll$NOCANCEL$UNIX2003 ___poll_nocancel -_poll$UNIX2003 ___poll -_pread ___pread_nocancel -_pread$NOCANCEL$UNIX2003 ___pread_nocancel -_pread$UNIX2003 ___pread -_pwrite ___pwrite_nocancel -_pwrite$NOCANCEL$UNIX2003 ___pwrite_nocancel -_pwrite$UNIX2003 ___pwrite -_read ___read_nocancel -_read$NOCANCEL$UNIX2003 ___read_nocancel -_read$UNIX2003 ___read -_readv ___readv_nocancel -_readv$NOCANCEL$UNIX2003 ___readv_nocancel -_readv$UNIX2003 ___readv -_recvfrom$NOCANCEL$UNIX2003 ___recvfrom_nocancel -_recvfrom$UNIX2003 ___recvfrom -_recvmsg$NOCANCEL$UNIX2003 ___recvmsg_nocancel -_recvmsg$UNIX2003 ___recvmsg -_select$DARWIN_EXTSN ___select -_select$DARWIN_EXTSN$NOCANCEL ___select_nocancel -_sem_wait ___sem_wait_nocancel -_sem_wait$NOCANCEL$UNIX2003 ___sem_wait_nocancel -_sem_wait$UNIX2003 ___sem_wait -_semctl$UNIX2003 ___semctl -_sendmsg$NOCANCEL$UNIX2003 ___sendmsg_nocancel -_sendmsg$UNIX2003 ___sendmsg -_sendto$NOCANCEL$UNIX2003 ___sendto_nocancel -_sendto$NOCANCEL$UNIX2003 ___sendto_nocancel -_sendto$UNIX2003 ___sendto -_sendto$UNIX2003 ___sendto -_setattrlist$UNIX2003 ___setattrlist -_setpgrp ___setpgid -_setregid$UNIX2003 ___setregid -_setreuid$UNIX2003 ___setreuid -_shmctl$UNIX2003 ___shmctl -_socketpair$UNIX2003 ___socketpair -_stat$INODE64 ___stat64 -_statfs$INODE64 ___statfs64 -_waitid ___waitid_nocancel -_waitid$NOCANCEL$UNIX2003 ___waitid_nocancel -_waitid$UNIX2003 ___waitid -_write ___write_nocancel -_write$NOCANCEL$UNIX2003 ___write_nocancel -_write$UNIX2003 ___write -_writev ___writev_nocancel -_writev$NOCANCEL$UNIX2003 ___writev_nocancel -_writev$UNIX2003 ___writev diff --git a/Platforms/MacOSX/ppc/libc.syscall.ppc b/Platforms/MacOSX/ppc/libc.syscall.ppc deleted file mode 100644 index ea8beef..0000000 --- a/Platforms/MacOSX/ppc/libc.syscall.ppc +++ /dev/null @@ -1,89 +0,0 @@ -_accept$NOCANCEL$UNIX2003 ___accept_nocancel -_accept$UNIX2003 ___accept -_accept$UNIX2003 ___accept -_aio_suspend ___aio_suspend_nocancel -_aio_suspend$NOCANCEL$UNIX2003 ___aio_suspend_nocancel -_aio_suspend$UNIX2003 ___aio_suspend -_bind$UNIX2003 ___bind -_close ___close_nocancel -_close$NOCANCEL$UNIX2003 ___close_nocancel -_close$UNIX2003 ___close -_connect$NOCANCEL$UNIX2003 ___connect_nocancel -_connect$UNIX2003 ___connect -_connect$UNIX2003 ___connect -_fcntl ___fcntl_nocancel -_fcntl$NOCANCEL$UNIX2003 ___fcntl_nocancel -_fcntl$UNIX2003 ___fcntl -_fstat$INODE64 ___fstat64 -_fstatfs$INODE64 ___fstatfs64 -_fsync ___fsync_nocancel -_fsync$NOCANCEL$UNIX2003 ___fsync_nocancel -_fsync$UNIX2003 ___fsync -_getattrlist$UNIX2003 ___getattrlist -_getfsstat$INODE64 ___getfsstat64 -_getpeername$UNIX2003 ___getpeername -_getsockname$UNIX2003 ___getsockname -_lchown$UNIX2003 ___lchown -_listen$UNIX2003 ___listen -_lstat$INODE64 ___lstat64 -_mprotect$UNIX2003 ___mprotect -_msgctl$UNIX2003 ___msgctl -_msgrcv ___msgrcv_nocancel -_msgrcv$NOCANCEL$UNIX2003 ___msgrcv_nocancel -_msgrcv$UNIX2003 ___msgrcv -_msgsnd ___msgsnd_nocancel -_msgsnd$NOCANCEL$UNIX2003 ___msgsnd_nocancel -_msgsnd$UNIX2003 ___msgsnd -_msync$NOCANCEL$UNIX2003 ___msync_nocancel -_msync$UNIX2003 ___msync -_munmap$UNIX2003 ___munmap -_open$NOCANCEL$UNIX2003 ___open_nocancel -_open$UNIX2003 ___open -_poll ___poll_nocancel -_poll$NOCANCEL$UNIX2003 ___poll_nocancel -_poll$UNIX2003 ___poll -_pread ___pread_nocancel -_pread$NOCANCEL$UNIX2003 ___pread_nocancel -_pread$UNIX2003 ___pread -_pwrite ___pwrite_nocancel -_pwrite$NOCANCEL$UNIX2003 ___pwrite_nocancel -_pwrite$UNIX2003 ___pwrite -_read ___read_nocancel -_read$NOCANCEL$UNIX2003 ___read_nocancel -_read$UNIX2003 ___read -_readv ___readv_nocancel -_readv$NOCANCEL$UNIX2003 ___readv_nocancel -_readv$UNIX2003 ___readv -_recvfrom$NOCANCEL$UNIX2003 ___recvfrom_nocancel -_recvfrom$UNIX2003 ___recvfrom -_recvmsg$NOCANCEL$UNIX2003 ___recvmsg_nocancel -_recvmsg$UNIX2003 ___recvmsg -_select$DARWIN_EXTSN ___select -_select$DARWIN_EXTSN$NOCANCEL ___select_nocancel -_sem_wait ___sem_wait_nocancel -_sem_wait$NOCANCEL$UNIX2003 ___sem_wait_nocancel -_sem_wait$UNIX2003 ___sem_wait -_semctl$UNIX2003 ___semctl -_sendmsg$NOCANCEL$UNIX2003 ___sendmsg_nocancel -_sendmsg$UNIX2003 ___sendmsg -_sendto$NOCANCEL$UNIX2003 ___sendto_nocancel -_sendto$NOCANCEL$UNIX2003 ___sendto_nocancel -_sendto$UNIX2003 ___sendto -_sendto$UNIX2003 ___sendto -_setattrlist$UNIX2003 ___setattrlist -_setpgrp ___setpgid -_setregid$UNIX2003 ___setregid -_setreuid$UNIX2003 ___setreuid -_shmctl$UNIX2003 ___shmctl -_socketpair$UNIX2003 ___socketpair -_stat$INODE64 ___stat64 -_statfs$INODE64 ___statfs64 -_waitid ___waitid_nocancel -_waitid$NOCANCEL$UNIX2003 ___waitid_nocancel -_waitid$UNIX2003 ___waitid -_write ___write_nocancel -_write$NOCANCEL$UNIX2003 ___write_nocancel -_write$UNIX2003 ___write -_writev ___writev_nocancel -_writev$NOCANCEL$UNIX2003 ___writev_nocancel -_writev$UNIX2003 ___writev diff --git a/Platforms/MacOSX/ppc64/libc.syscall.ppc64 b/Platforms/MacOSX/ppc64/libc.syscall.ppc64 deleted file mode 100644 index 6fa9db6..0000000 --- a/Platforms/MacOSX/ppc64/libc.syscall.ppc64 +++ /dev/null @@ -1,31 +0,0 @@ -_accept$NOCANCEL ___accept_nocancel -_aio_suspend$NOCANCEL ___aio_suspend_nocancel -_close$NOCANCEL ___close_nocancel -_connect$NOCANCEL ___connect_nocancel -_fstat$INODE64 ___fstat64 -_fstatfs$INODE64 ___fstatfs64 -_fsync$NOCANCEL ___fsync_nocancel -_getfsstat$INODE64 ___getfsstat64 -_lstat$INODE64 ___lstat64 -_msgrcv$NOCANCEL ___msgrcv_nocancel -_msgsnd$NOCANCEL ___msgsnd_nocancel -_msync$NOCANCEL ___msync_nocancel -_open$NOCANCEL ___open_nocancel -_poll$NOCANCEL ___poll_nocancel -_pread$NOCANCEL ___pread_nocancel -_pwrite$NOCANCEL ___pwrite_nocancel -_read$NOCANCEL ___read_nocancel -_readv$NOCANCEL ___readv_nocancel -_recvfrom$NOCANCEL ___recvfrom_nocancel -_recvmsg$NOCANCEL ___recvmsg_nocancel -_select$DARWIN_EXTSN ___select -_select$DARWIN_EXTSN$NOCANCEL ___select_nocancel -_sem_wait$NOCANCEL ___sem_wait_nocancel -_sendmsg$NOCANCEL ___sendmsg_nocancel -_sendto$NOCANCEL ___sendto_nocancel -_sendto$NOCANCEL ___sendto_nocancel -_stat$INODE64 ___stat64 -_statfs$INODE64 ___statfs64 -_waitid$NOCANCEL ___waitid_nocancel -_write$NOCANCEL ___write_nocancel -_writev$NOCANCEL ___writev_nocancel diff --git a/Platforms/MacOSX/x86_64/libc.syscall.x86_64 b/Platforms/MacOSX/x86_64/libc.syscall.x86_64 deleted file mode 100644 index 6fa9db6..0000000 --- a/Platforms/MacOSX/x86_64/libc.syscall.x86_64 +++ /dev/null @@ -1,31 +0,0 @@ -_accept$NOCANCEL ___accept_nocancel -_aio_suspend$NOCANCEL ___aio_suspend_nocancel -_close$NOCANCEL ___close_nocancel -_connect$NOCANCEL ___connect_nocancel -_fstat$INODE64 ___fstat64 -_fstatfs$INODE64 ___fstatfs64 -_fsync$NOCANCEL ___fsync_nocancel -_getfsstat$INODE64 ___getfsstat64 -_lstat$INODE64 ___lstat64 -_msgrcv$NOCANCEL ___msgrcv_nocancel -_msgsnd$NOCANCEL ___msgsnd_nocancel -_msync$NOCANCEL ___msync_nocancel -_open$NOCANCEL ___open_nocancel -_poll$NOCANCEL ___poll_nocancel -_pread$NOCANCEL ___pread_nocancel -_pwrite$NOCANCEL ___pwrite_nocancel -_read$NOCANCEL ___read_nocancel -_readv$NOCANCEL ___readv_nocancel -_recvfrom$NOCANCEL ___recvfrom_nocancel -_recvmsg$NOCANCEL ___recvmsg_nocancel -_select$DARWIN_EXTSN ___select -_select$DARWIN_EXTSN$NOCANCEL ___select_nocancel -_sem_wait$NOCANCEL ___sem_wait_nocancel -_sendmsg$NOCANCEL ___sendmsg_nocancel -_sendto$NOCANCEL ___sendto_nocancel -_sendto$NOCANCEL ___sendto_nocancel -_stat$INODE64 ___stat64 -_statfs$INODE64 ___statfs64 -_waitid$NOCANCEL ___waitid_nocancel -_write$NOCANCEL ___write_nocancel -_writev$NOCANCEL ___writev_nocancel diff --git a/Platforms/iPhone/Makefile.inc b/Platforms/iPhone/Makefile.inc index 1b391d9..f9ac61c 100644 --- a/Platforms/iPhone/Makefile.inc +++ b/Platforms/iPhone/Makefile.inc @@ -5,6 +5,9 @@ # Legacy *64 APIs #FEATURE_LEGACY_64_APIS = 1 +# Legacy crt1.o environ support +#FEATURE_LEGACY_CRT1_ENVIRON = 1 + # Legacy NX international APIs FEATURE_LEGACY_NX_INTERNAT_APIS = 1 @@ -21,7 +24,9 @@ FEATURE_LEGACY_NXZONE_APIS = 1 FEATURE_MEM_THERM_NOTIFICATION_APIS = 1 # Move localtime to /var/db/timezone +.if $(RC_ProjectName) == $(RC_ProjectName:%_Sim=%) FEATURE_MOVE_LOCALTIME = 1 +.endif # Long doubles are doubles (should match sys/cdefs.h) .if (${MACHINE_ARCH} == arm) @@ -40,9 +45,6 @@ FEATURE_ONLY_64_BIT_INO_T = 1 # Patch 3333969 #FEATURE_PATCH_3333969 = 1 -# Patch 3375657 -#FEATURE_PATCH_3375657 = 1 - # Patch 3417676 #FEATURE_PATCH_3417676 = 1 @@ -53,4 +55,4 @@ FEATURE_PATCH_5243343 = 1 #FEATURE_PLOCKSTAT = 1 # Timezone change notification -#FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1 +FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1 diff --git a/Platforms/iPhone/arm/libc.syscall.arm b/Platforms/iPhone/arm/libc.syscall.arm deleted file mode 100644 index a5ff2f1..0000000 --- a/Platforms/iPhone/arm/libc.syscall.arm +++ /dev/null @@ -1,45 +0,0 @@ -_accept$NOCANCEL ___accept_nocancel -_aio_suspend$NOCANCEL ___aio_suspend_nocancel -_close$NOCANCEL ___close_nocancel -_connect$NOCANCEL ___connect_nocancel -_fstat ___fstat64 -_fstat64 -_fstatfs ___fstatfs64 -_fstatfs64 -_fstatx_np ___fstatx64_np -_fstatx64_np -_fsync$NOCANCEL ___fsync_nocancel -_getfsstat ___getfsstat64 -_getfsstat64 -_getmntinfo ___getmntinfo64 -_getmntinfo64 -_lstat ___lstat64 -_lstat64 -_lstatx_np ___lstatx64_np -_lstatx64_np -_msgrcv$NOCANCEL ___msgrcv_nocancel -_msgsnd$NOCANCEL ___msgsnd_nocancel -_msync$NOCANCEL ___msync_nocancel -_open$NOCANCEL ___open_nocancel -_poll$NOCANCEL ___poll_nocancel -_pread$NOCANCEL ___pread_nocancel -_pwrite$NOCANCEL ___pwrite_nocancel -_read$NOCANCEL ___read_nocancel -_readv$NOCANCEL ___readv_nocancel -_recvfrom$NOCANCEL ___recvfrom_nocancel -_recvmsg$NOCANCEL ___recvmsg_nocancel -_select$DARWIN_EXTSN ___select -_select$DARWIN_EXTSN$NOCANCEL ___select_nocancel -_sem_wait$NOCANCEL ___sem_wait_nocancel -_sendmsg$NOCANCEL ___sendmsg_nocancel -_sendto$NOCANCEL ___sendto_nocancel -_sendto$NOCANCEL ___sendto_nocancel -_stat ___stat64 -_stat64 -_statfs ___statfs64 -_statfs64 -_statx_np ___statx64_np -_statx64_np -_waitid$NOCANCEL ___waitid_nocancel -_write$NOCANCEL ___write_nocancel -_writev$NOCANCEL ___writev_nocancel diff --git a/arm/gen/Makefile.inc b/arm/gen/Makefile.inc index 160fdbb..4796738 100644 --- a/arm/gen/Makefile.inc +++ b/arm/gen/Makefile.inc @@ -1,2 +1,6 @@ .PATH: ${.CURDIR}/arm/gen -MDSRCS+= icacheinval.s +MDSRCS += \ + cpu_number.s \ + icacheinval.s + +DYLDSRCS += icacheinval.s diff --git a/i386/sys/i386_gettimeofday.s b/arm/gen/cpu_number.s similarity index 81% rename from i386/sys/i386_gettimeofday.s rename to arm/gen/cpu_number.s index 3d50e2d..a466238 100644 --- a/i386/sys/i386_gettimeofday.s +++ b/arm/gen/cpu_number.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,14 +20,20 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* Copyright 1998 Apple Computer, Inc. */ - -#include +#include #define __APPLE_API_PRIVATE #include #undef __APPLE_API_PRIVATE -LABEL(___commpage_gettimeofday) - mov $ _COMM_PAGE_GETTIMEOFDAY,%eax - jmp *%eax + .text + .align 2 + .globl _cpu_number +_cpu_number: +#ifdef _ARM_ARCH_7 + mrc p15, 0, r0, c13, c0, 3 + and r0, r0, #3 +#else + mov r0, #0 +#endif + bx lr diff --git a/arm/pthreads/Makefile.inc b/arm/pthreads/Makefile.inc index 4addcfe..a37d6ea 100644 --- a/arm/pthreads/Makefile.inc +++ b/arm/pthreads/Makefile.inc @@ -8,3 +8,7 @@ MDSRCS += \ start_wqthread.s \ thread_start.s +DYLDSRCS += \ + pthread_getspecific.s \ + pthread_self.s \ + pthread_set_self.s diff --git a/arm/pthreads/pthread_getspecific.s b/arm/pthreads/pthread_getspecific.s index 5af3fe0..90e0e98 100644 --- a/arm/pthreads/pthread_getspecific.s +++ b/arm/pthreads/pthread_getspecific.s @@ -33,9 +33,10 @@ _pthread_getspecific: #ifdef _ARM_ARCH_6 mrc p15, 0, r1, c13, c0, 3 + bic r1, r1, #3 add r0, r1, r0, lsl #2 #else add r0, r9, r0, lsl #2 #endif - ldr r0, [r0, #_PTHREAD_TSD_OFFSET] + ldr r0, [r0, #0] bx lr diff --git a/arm/pthreads/pthread_self.s b/arm/pthreads/pthread_self.s index b14dfbc..0e84b6d 100644 --- a/arm/pthreads/pthread_self.s +++ b/arm/pthreads/pthread_self.s @@ -32,7 +32,9 @@ _pthread_self: #ifdef _ARM_ARCH_6 mrc p15, 0, r0, c13, c0, 3 + bic r0, r0, #3 #else mov r0, r9 #endif + ldr r0, [r0, #0] bx lr diff --git a/arm/string/Makefile.inc b/arm/string/Makefile.inc index 9e1f368..8125ca7 100644 --- a/arm/string/Makefile.inc +++ b/arm/string/Makefile.inc @@ -4,13 +4,48 @@ # .PATH: ${.CURDIR}/arm/string -MDSRCS += \ - bcopy.s \ - bzero.s \ - ffs.s \ - memcmp.s \ - memset_pattern.s \ +MDSRCS += \ + bcopy_Generic.s \ + bcopy_CortexA8.s \ + bcopy_CortexA9.s \ + bzero_Generic.s \ + bzero_CortexA8.s \ + bzero_CortexA9.s \ + dyld_resolvers.c \ + ffs.s \ + memcmp.s \ + strcmp.s \ + strncmp.s \ + strlen.s \ + strchr.s \ + strstr.s \ + strcpy.s \ + strlcpy.s \ + strncpy.s \ + strnlen.s + +DYLDSRCS += \ + bcopy_Generic.s \ + bzero_Generic.s \ + ffs.s \ strcmp.s \ strlen.s -SUPPRESSSRCS += bcmp.c memcpy.c memmove.c memset.c strlen.c +.if defined(FEATURE_ARM_ARCH_6) +MDSRCS += memset_pattern.s +.endif + +SUPPRESSSRCS += \ + bcmp.c \ + memcpy.c \ + memmove.c \ + memset.c \ + strncmp.c \ + strlen.c \ + strchr.c \ + strstr.c \ + strcpy.c \ + strlcpy.c \ + strncpy.c \ + strnlen.c + diff --git a/arm/string/NEON/bcopy.s b/arm/string/NEON/bcopy.s deleted file mode 100644 index 30abab1..0000000 --- a/arm/string/NEON/bcopy.s +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/***************************************************************************** - * Cortex-A8 implementation * - *****************************************************************************/ - -// Cortex-A8 implementations of memcpy( ), memmove( ) and bcopy( ). -// -// Our tests have shown that NEON is always a performance win for memcpy( ). -// However, for the specific case of copies from a warm source to a cold -// destination when the buffer size is between 1k and 32k, it is not enough -// of a performance win to offset the increased power footprint, resulting -// in an energy usage regression. Thus, we detect that particular case, and -// pass those copies through the ARM core registers. All other copies larger -// than 8 bytes are handled on NEON. -// -// Stephen Canon, August 2009 - -.text -.code 16 -.syntax unified - -// void bcopy(const void * source, -// void * destination, -// size_t length); -// -// void *memmove(void * destination, -// const void * source, -// size_t n); -// -// void *memcpy(void * restrict destination, -// const void * restrict source, -// size_t n); -// -// all copy n successive bytes from source to destination. memmove and memcpy -// returns destination, whereas bcopy has no return value. copying takes place -// as if it were through a temporary buffer -- after return destination contains -// exactly the bytes from source, even if the buffers overlap. - -.thumb_func _bcopy -.globl _bcopy -.thumb_func _memmove -.globl _memmove -.thumb_func _memcpy -.globl _memcpy - -.align 2 -_bcopy: - mov r3, r0 // swap the first and second arguments - mov r0, r1 // and fall through into memmove - mov r1, r3 // - -.align 2 -_memmove: -_memcpy: - subs r3, r0, r1 // offset = destination addr - source addr - it eq - bxeq lr // if source == destination, early out - -// Our preference is for using a (faster) front-to-back copy. However, if -// 0 < offset < length, it is necessary to copy back-to-front for correctness. -// We have already ruled out offset == 0, so we can use an unsigned compare -// with length -- if offset is higher, offset is either greater than length -// or negative. - - cmp r3, r2 - bhs L_copyFrontToBack - -/***************************************************************************** - * back to front copy * - *****************************************************************************/ - - mov ip, r0 // copy destination pointer. - add r1, r2 // move source pointer to end of source array - add ip, r2 // move destination pointer to end of dest array - - subs r2, $8 // if length - 8 is negative (i.e. length - blt L_scalarReverseCopy // is less than 8), jump to cleanup path. - tst ip, $7 // if (destination + length) is doubleword - beq L_vectorReverseCopy // aligned, jump to fast path. - -0: ldrb r3, [r1, $-1]! // load byte - sub r2, $1 // decrement length - strb r3, [ip, $-1]! // store byte - tst ip, $7 // test alignment - bne 0b - - cmp r2, $0 // if length - 8 is negative, - blt L_scalarReverseCopy // jump to the cleanup code - -/***************************************************************************** - * destination is doubleword aligned * - *****************************************************************************/ - -L_vectorReverseCopy: - ands r3, r1, $3 // Extract the alignment of the source - bic r1, $3 - tbh [pc, r3, lsl $1] // Dispatch table on source alignment -0: -.short (L_reverseAligned0-0b)/2 // The NEON alignment hardware does not work -.short (L_reverseAligned1-0b)/2 // properly with sub 4-byte alignment and -.short (L_reverseAligned2-0b)/2 // buffers that are uncacheable, so we need -.short (L_reverseAligned3-0b)/2 // to have a software workaround. - -/***************************************************************************** - * source is also at least word aligned * - *****************************************************************************/ - -L_reverseAligned0: - subs r2, $0x38 // if length - 64 is negative, jump to - blt L_reverseVectorCleanup// the cleanup path. - tst ip, $0x38 // if (destination + length) is cacheline - beq L_reverseCachelineAligned // aligned, jump to the fast path. - -0: sub r1, $8 // copy eight bytes at a time until the - vld1.32 {d0}, [r1] // destination is 8 byte aligned. - sub ip, $8 // - sub r2, $8 // - tst ip, $0x38 // - vst1.64 {d0}, [ip, :64] // - bne 0b // - - cmp r2, $0 // if length - 64 is negative, - blt L_reverseVectorCleanup// jump to the cleanup code - -L_reverseCachelineAligned: - sub r3, r2, $0x3c0 // If 1024 < length < 32768, use core - cmp r3, $0x7c00 // register copies instead of NEON to - blo L_useSTMDB // control energy usage. - - sub r1, $32 // decrement source - sub ip, $32 // decrement destination - mov r3, $-32 // load address increment - tst r1, $0x1f // if source shares 32 byte alignment - beq L_reverseSourceAligned// jump to loop with more alignment hints - - vld1.32 {q2,q3}, [r1], r3 // This loop handles 4-byte aligned copies - vld1.32 {q0,q1}, [r1], r3 // as generally as possible. - subs r2, $64 // - vst1.64 {q2,q3}, [ip,:256], r3 // The Cortex-A8 NEON unit does not always - blt 1f // properly handle misalignment in vld1 -.align 3 // with an element size of 8 or 16, so -0: vld1.32 {q2,q3}, [r1], r3 // this is the best we can do without - vst1.64 {q0,q1}, [ip,:256], r3 // handling alignment in software. - vld1.32 {q0,q1}, [r1], r3 // - subs r2, $64 // - vst1.64 {q2,q3}, [ip,:256], r3 // - bge 0b // - b 1f // - -L_reverseSourceAligned: - vld1.64 {q2,q3}, [r1,:256], r3 // Identical to loop above except for - vld1.64 {q0,q1}, [r1,:256], r3 // additional alignment information; this - subs r2, $64 // gets an additional .5 bytes per cycle - vst1.64 {q2,q3}, [ip,:256], r3 // on Cortex-A8. - blt 1f // -.align 3 // -0: vld1.64 {q2,q3}, [r1,:256], r3 // - vst1.64 {q0,q1}, [ip,:256], r3 // - vld1.64 {q0,q1}, [r1,:256], r3 // - subs r2, $64 // - vst1.64 {q2,q3}, [ip,:256], r3 // - bge 0b // -1: vst1.64 {q0,q1}, [ip,:256], r3 // loop cleanup: final 32 byte store - add r1, $32 // point source at last element stored - add ip, $32 // point destination at last element stored - -L_reverseVectorCleanup: - adds r2, $0x38 // If (length - 8) < 0, goto scalar cleanup - blt L_scalarReverseCopy // - -0: sub r1, $8 // copy eight bytes at a time until - vld1.32 {d0}, [r1] // (length - 8) < 0. - sub ip, $8 // - subs r2, $8 // - vst1.64 {d0}, [ip, :64] // - bge 0b // - -/***************************************************************************** - * sub-doubleword cleanup copies * - *****************************************************************************/ - -L_scalarReverseCopy: - adds r2, #0x8 // restore length - it eq // if this is zero - bxeq lr // early out - -0: ldrb r3, [r1, #-1]! // load a byte from source - strb r3, [ip, #-1]! // store to destination - subs r2, #0x1 // subtract one from length - bne 0b // if non-zero, repeat - bx lr // return - -/***************************************************************************** - * STMDB loop for 1k-32k buffers * - *****************************************************************************/ - -L_useSTMDB: - push {r4-r8,r10,r11} -.align 3 -0: ldmdb r1!, {r3-r8,r10,r11} - subs r2, #0x40 - stmdb ip!, {r3-r8,r10,r11} - ldmdb r1!, {r3-r8,r10,r11} - pld [r1, #-0x40] - stmdb ip!, {r3-r8,r10,r11} - bge 0b - pop {r4-r8,r10,r11} - b L_reverseVectorCleanup - -/***************************************************************************** - * Misaligned vld1 loop * - *****************************************************************************/ - -// Software alignment fixup to handle source and dest that are relatively -// misaligned mod 4 bytes. Load two 4-byte aligned double words from source, -// use vext.8 to extract a double word to store, and perform an 8-byte aligned -// store to destination. - -#define RCOPY_UNALIGNED(offset) \ - subs r2, $8 ;\ - blt 2f ;\ - sub r1, $8 ;\ - sub ip, $8 ;\ - mov r3, $-8 ;\ - vld1.32 {d2,d3}, [r1], r3 ;\ - subs r2, $8 ;\ - blt 1f ;\ -0: vext.8 d0, d2, d3, $(offset);\ - vmov d3, d2 ;\ - vld1.32 {d2}, [r1], r3 ;\ - subs r2, $8 ;\ - vst1.64 {d0}, [ip, :64], r3 ;\ - bge 0b ;\ -1: vext.8 d0, d2, d3, $(offset);\ - add r1, $8 ;\ - vst1.64 {d0}, [ip, :64] ;\ -2: add r2, $8 ;\ - add r1, $(offset);\ - b L_scalarReverseCopy - -L_reverseAligned1: - RCOPY_UNALIGNED(1) -L_reverseAligned2: - RCOPY_UNALIGNED(2) -L_reverseAligned3: - RCOPY_UNALIGNED(3) - -/***************************************************************************** - * front to back copy * - *****************************************************************************/ - -L_copyFrontToBack: - mov ip, r0 // copy destination pointer. - subs r2, $8 // if length - 8 is negative (i.e. length - blt L_scalarCopy // is less than 8), jump to cleanup path. - tst ip, $7 // if the destination is doubleword - beq L_vectorCopy // aligned, jump to fast path. - -0: ldrb r3, [r1], $1 // load byte - sub r2, $1 // decrement length - strb r3, [ip], $1 // store byte - tst ip, $7 // test alignment - bne 0b - - cmp r2, $0 // if length - 8 is negative, - blt L_scalarCopy // jump to the cleanup code - -/***************************************************************************** - * destination is doubleword aligned * - *****************************************************************************/ - -L_vectorCopy: - ands r3, r1, $3 // Extract the alignment of the source - bic r1, $3 - tbh [pc, r3, lsl $1] // Dispatch table on source alignment -0: -.short (L_sourceAligned0-0b)/2 // The NEON alignment hardware does not work -.short (L_sourceAligned1-0b)/2 // properly with sub 4-byte alignment and -.short (L_sourceAligned2-0b)/2 // buffers that are uncacheable, so we need -.short (L_sourceAligned3-0b)/2 // to have a software workaround. - -/***************************************************************************** - * source is also at least word aligned * - *****************************************************************************/ - -L_sourceAligned0: - subs r2, $0x38 // If (length - 64) < 0 - blt L_vectorCleanup // jump to cleanup code - tst ip, $0x38 // If destination is 64 byte aligned - beq L_cachelineAligned // jump to main loop - -0: vld1.32 {d0}, [r1]! // Copy one double word at a time until - sub r2, $8 // the destination is 64-byte aligned. - vst1.64 {d0}, [ip, :64]! // - tst ip, $0x38 // - bne 0b // - - cmp r2, $0 // If (length - 64) < 0, goto cleanup - blt L_vectorCleanup // - -L_cachelineAligned: - sub r3, r2, $0x3c0 // If 1024 < length < 32768, use core - cmp r3, $0x7c00 // register copies instead of NEON to - blo L_useSTMIA // control energy usage. - tst r1, $0x1f // If source has 32-byte alignment, use - beq L_sourceAligned32 // an optimized loop. - - vld1.32 {q2,q3}, [r1]! // This is the most common path for small - vld1.32 {q0,q1}, [r1]! // copies, which are alarmingly frequent. - subs r2, #0x40 // It requires 4-byte alignment on the - vst1.64 {q2,q3}, [ip, :256]! // source. For ordinary malloc'd buffers, - blt 1f // this path could handle only single-byte -.align 3 // alignment at speed by using vld1.8 -0: vld1.32 {q2,q3}, [r1]! // instead of vld1.32; however, the NEON - vst1.64 {q0,q1}, [ip, :256]! // alignment handler misbehaves for some - vld1.32 {q0,q1}, [r1]! // special copies if the element size is - subs r2, #0x40 // 8 or 16, so we need to work around - vst1.64 {q2,q3}, [ip, :256]! // sub 4-byte alignment in software, in - bge 0b // another code path. - b 1f - -L_sourceAligned32: - vld1.64 {q2,q3}, [r1, :256]! // When the source shares 32-byte alignment - vld1.64 {q0,q1}, [r1, :256]! // with the destination, we use this loop - subs r2, #0x40 // instead, which specifies the maximum - vst1.64 {q2,q3}, [ip, :256]! // :256 alignment on all loads and stores. - blt 1f // -.align 3 // This gets an additional .5 bytes per -0: vld1.64 {q2,q3}, [r1, :256]! // cycle for in-cache copies, which is not - vst1.64 {q0,q1}, [ip, :256]! // insignificant for this (rather common) - vld1.64 {q0,q1}, [r1, :256]! // case. - subs r2, #0x40 // - vst1.64 {q2,q3}, [ip, :256]! // This is identical to the above loop, - bge 0b // except for the additional alignment. -1: vst1.64 {q0,q1}, [ip, :256]! // - -L_vectorCleanup: - adds r2, $0x38 // If (length - 8) < 0, goto scalar cleanup - blt L_scalarCopy // - -0: vld1.32 {d0}, [r1]! // Copy one doubleword at a time until - subs r2, $8 // (length - 8) < 0. - vst1.64 {d0}, [ip, :64]! // - bge 0b // - -/***************************************************************************** - * sub-doubleword cleanup copies * - *****************************************************************************/ - -L_scalarCopy: - adds r2, #0x8 // restore length - it eq // if this is zero - bxeq lr // early out - -0: ldrb r3, [r1], #1 // load a byte from source - strb r3, [ip], #1 // store to destination - subs r2, #1 // subtract one from length - bne 0b // if non-zero, repeat - bx lr // return - -/***************************************************************************** - * STMIA loop for 1k-32k buffers * - *****************************************************************************/ - -L_useSTMIA: - push {r4-r8,r10,r11} -.align 3 -0: ldmia r1!, {r3-r8,r10,r11} - subs r2, r2, #64 - stmia ip!, {r3-r8,r10,r11} - ldmia r1!, {r3-r8,r10,r11} - pld [r1, #64] - stmia ip!, {r3-r8,r10,r11} - bge 0b - pop {r4-r8,r10,r11} - b L_vectorCleanup - -/***************************************************************************** - * Misaligned reverse vld1 loop * - *****************************************************************************/ - -// Software alignment fixup to handle source and dest that are relatively -// misaligned mod 4 bytes. Load two 4-byte aligned double words from source, -// use vext.8 to extract a double word to store, and perform an 8-byte aligned -// store to destination. - -#define COPY_UNALIGNED(offset) \ - subs r2, $8 ;\ - blt 2f ;\ - vld1.32 {d2,d3}, [r1]! ;\ - subs r2, $8 ;\ - blt 1f ;\ -0: vext.8 d0, d2, d3, $(offset);\ - vmov d2, d3 ;\ - vld1.32 {d3}, [r1]! ;\ - subs r2, $8 ;\ - vst1.64 {d0}, [ip, :64]! ;\ - bge 0b ;\ -1: vext.8 d0, d2, d3, $(offset);\ - sub r1, $8 ;\ - vst1.64 {d0}, [ip, :64]! ;\ -2: add r1, $(offset);\ - add r2, $8 ;\ - b L_scalarCopy - -L_sourceAligned1: - COPY_UNALIGNED(1) -L_sourceAligned2: - COPY_UNALIGNED(2) -L_sourceAligned3: - COPY_UNALIGNED(3) diff --git a/arm/string/NEON/bzero.s b/arm/string/NEON/bzero.s deleted file mode 100644 index 50b1c8e..0000000 --- a/arm/string/NEON/bzero.s +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/********************************************************************** - * Cortex-A8 implementation * - **********************************************************************/ - -// Cortex-A8 implementations of memset( ) and bzero( ). Main loop is 64-byte -// NEON stores, unless the buffer length is > 1k. Beyond that point, there is -// little to no speed advantage with NEON (and a slight regression in some -// measured cases), so we switch to the GPRs. -// -// The crossover point should be reevaluated for future architectures. -// -// -- Stephen Canon, August 2009 - -.text -.syntax unified -.code 16 - -// void bzero(void * destination, -// size_t length); -// -// zeros out a buffer length bytes long, beginning at the address destination. -.thumb_func ___bzero -.globl ___bzero -.thumb_func _bzero -.globl _bzero -.align 2 -___bzero: -_bzero: - mov r2, r1 // match the API to memset(dest, 0, length) - eor r1, r1 // and fall through into memset - -// void *memset(void * destination, -// int value, size_t n); -// -// writes value converted to an unsigned char to n successive bytes, beginning -// at destination. - -// Notes on register usage: -// -// Throughout this function, registers have nearly constant usage; the pattern -// is: -// -// r0 holds the original destination pointer, unmodified. This value -// must be returned by the routine, so it is easiest to just leave it -// in place. -// r1 holds the value that is being copied into the buffer, in some stage -// of splattedness. The low byte is guaranteed to always have the value -// but the higher bytes may or may not contain copies of it. -// r2 holds the length minus some offset, where the offset is always the -// number of bytes that the current loop stores per iteration. -// r3-r6,r8,r10,r11 are used with stmia, and will only ever contain splatted -// copies of the value to be stored. -// ip holds a pointer to the lowest byte in the array that has not yet been -// set to hold value. -// q0 and q1 hold splatted copies of the value in the vector path, and are -// otherwise unused. - -.thumb_func _memset -.globl _memset -.align 2 -_memset: - mov ip, r0 // copy destination pointer. - subs r2, #0x8 // if length - 8 is negative (i.e. length - and r1, #0xff // is less than 8), jump to cleanup path. - blt L_scalarCleanup // - - tst ip, #0x7 // if the destination is doubleword - beq L_vectorCopy // aligned, jump to fast path. - -0: strb r1, [ip], #1 // store one byte at a time until - sub r2, #1 // destination pointer is 8 byte aligned. - tst ip, #7 // - bne 0b // - - cmp r2, #0x0 // if length - 8 is negative, - blt L_scalarCleanup // jump to the cleanup code - -L_vectorCopy: - vdup.8 q0, r1 // splat the byte to be stored across - subs r2, #0x38 // q0 and q1, and check if length - 64 - vmov q1, q0 // is negative; if so, jump to the - blt L_vectorCleanup // cleanup code. - - tst ip, #0x38 // if the destination is cacheline - beq L_cachelineAligned // aligned, jump to the fast path. - -0: vst1.64 {d0}, [ip, :64]! // store one double word at a time until - sub r2, #8 // the destination is 64-byte aligned - tst ip, #0x38 // - bne 0b - - cmp r2, #0x0 // if length - 64 is negative, - blt L_vectorCleanup // jump to the cleanup code - -L_cachelineAligned: - cmp r2, #0x3c0 // if length > 1024 - bge L_useSTMIA // we use stmia instead - -.align 4 // main loop -0: vst1.64 {q0,q1}, [ip, :256]! // store 32 bytes - subs r2, #0x40 // decrement length by 64 - vst1.64 {q0,q1}, [ip, :256]! // store 32 bytes - bge 0b // if length - 64 >= 0, continue - -L_vectorCleanup: - adds r2, #0x38 // if (length - 8) < 0, goto scalar cleanup - blt L_scalarCleanup // - -0: subs r2, #8 // store one double word at a time until - vst1.64 {d0}, [ip, :64]! // (length - 8) < 0. - bge 0b - -L_scalarCleanup: - adds r2, #8 // restore length - beq 1f // early out if zero. - -0: strb r1, [ip], #1 // store one byte at a time until length - subs r2, #1 // is zero. - bne 0b // -1: bx lr // return. - -// STMIA loop for large buffers -// -// For stores larger than 1024 bytes, we use STMIA because we can't get enough -// of a speedup from NEON to offset the higher power draw of the NEON unit. -// -// This crossover should be reevaluated on future architectures. -// -// We avoid using r7 and r9 even though it's not strictly necessary. - -L_useSTMIA: - push {r4,r5,r6,r8,r10,r11} - orr r1, r1, r1, lsl #8 - orr r1, r1, r1, lsl #16 - mov r3, r1 - mov r4, r1 - mov r5, r1 - mov r6, r1 - mov r8, r1 - mov r10, r1 - mov r11, r1 -.align 4 -0: stmia ip!, {r1,r3,r4,r5,r6,r8,r10,r11} - subs r2, #0x40 - stmia ip!, {r1,r3,r4,r5,r6,r8,r10,r11} - bge 0b - pop {r4,r5,r6,r8,r10,r11} - b L_vectorCleanup diff --git a/arm/string/bcopy.s b/arm/string/bcopy.s deleted file mode 100644 index 2e67e1c..0000000 --- a/arm/string/bcopy.s +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright (c) 2006, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined __thumb2__ && defined __ARM_NEON__ - -// Use our tuned NEON implementation when it is available. Otherwise fall back -// on more generic ARM code. - -#include "NEON/bcopy.s" - -#else // defined __thumb2__ && defined __ARM_NEON__ - -/***************************************************************************** - * ARMv5 and ARMv6 implementation * - *****************************************************************************/ - -#include - -.text -.align 2 - - .globl _memcpy - .globl _bcopy - .globl _memmove - -_bcopy: /* void bcopy(const void *src, void *dest, size_t len); */ - mov r3, r0 - mov r0, r1 - mov r1, r3 - -_memcpy: /* void *memcpy(void *dest, const void *src, size_t len); */ -_memmove: /* void *memmove(void *dest, const void *src, size_t len); */ - /* check for zero len or if the pointers are the same */ - cmp r2, #0 - cmpne r0, r1 - bxeq lr - - /* save r0 (return value), r4 (scratch), and r5 (scratch) */ - stmfd sp!, { r0, r4, r5, r7, lr } - add r7, sp, #12 - - /* check for overlap. r3 <- distance between src & dest */ - subhs r3, r0, r1 - sublo r3, r1, r0 - cmp r3, r2 /* if distance(src, dest) < len, we have overlap */ - blo Loverlap - -Lnormalforwardcopy: - /* are src and dest dissimilarly word aligned? */ - mov r12, r0, lsl #30 - cmp r12, r1, lsl #30 - bne Lnonwordaligned_forward - - /* if len < 64, do a quick forward copy */ - cmp r2, #64 - blt Lsmallforwardcopy - - /* check for 16 byte src/dest unalignment */ - tst r0, #0xf - bne Lsimilarlyunaligned - - /* check for 32 byte dest unalignment */ - tst r0, #(1<<4) - bne Lunaligned_32 - -Lmorethan64_aligned: - /* save some more registers to use in the copy */ - stmfd sp!, { r6, r8, r10, r11 } - - /* pre-subtract 64 from the len counter to avoid an extra compare in the loop */ - sub r2, r2, #64 - -L64loop: - /* copy 64 bytes at a time */ - ldmia r1!, { r3, r4, r5, r6, r8, r10, r11, r12 } -#ifdef _ARM_ARCH_6 - pld [r1, #32] -#endif - stmia r0!, { r3, r4, r5, r6, r8, r10, r11, r12 } - ldmia r1!, { r3, r4, r5, r6, r8, r10, r11, r12 } - subs r2, r2, #64 -#ifdef _ARM_ARCH_6 - pld [r1, #32] -#endif - stmia r0!, { r3, r4, r5, r6, r8, r10, r11, r12 } - bge L64loop - - /* restore the scratch registers we just saved */ - ldmfd sp!, { r6, r8, r10, r11 } - - /* fix up the len counter (previously subtracted an extra 64 from it) and test for completion */ - adds r2, r2, #64 - beq Lexit - -Llessthan64_aligned: - /* copy 16 bytes at a time until we have < 16 bytes */ - cmp r2, #16 - ldmgeia r1!, { r3, r4, r5, r12 } - stmgeia r0!, { r3, r4, r5, r12 } - subges r2, r2, #16 - bgt Llessthan64_aligned - beq Lexit - -Llessthan16_aligned: - mov r2, r2, lsl #28 - msr cpsr_f, r2 - - ldmmiia r1!, { r2, r3 } - ldreq r4, [r1], #4 - ldrcsh r5, [r1], #2 - ldrvsb r12, [r1], #1 - - stmmiia r0!, { r2, r3 } - streq r4, [r0], #4 - strcsh r5, [r0], #2 - strvsb r12, [r0], #1 - b Lexit - -Lsimilarlyunaligned: - /* both src and dest are unaligned in similar ways, align to dest on 32 byte boundary */ - mov r12, r0, lsl #28 - rsb r12, r12, #0 - msr cpsr_f, r12 - - ldrvsb r3, [r1], #1 - ldrcsh r4, [r1], #2 - ldreq r5, [r1], #4 - - strvsb r3, [r0], #1 - strcsh r4, [r0], #2 - streq r5, [r0], #4 - - ldmmiia r1!, { r3, r4 } - stmmiia r0!, { r3, r4 } - - subs r2, r2, r12, lsr #28 - beq Lexit - -Lunaligned_32: - /* bring up to dest 32 byte alignment */ - tst r0, #(1 << 4) - ldmneia r1!, { r3, r4, r5, r12 } - stmneia r0!, { r3, r4, r5, r12 } - subne r2, r2, #16 - - /* we should now be aligned, see what copy method we should use */ - cmp r2, #64 - bge Lmorethan64_aligned - b Llessthan64_aligned - -Lbytewise2: - /* copy 2 bytes at a time */ - subs r2, r2, #2 - - ldrb r3, [r1], #1 - ldrplb r4, [r1], #1 - - strb r3, [r0], #1 - strplb r4, [r0], #1 - - bhi Lbytewise2 - b Lexit - -Lbytewise: - /* simple bytewise forward copy */ - ldrb r3, [r1], #1 - subs r2, r2, #1 - strb r3, [r0], #1 - bne Lbytewise - b Lexit - -Lsmallforwardcopy: - /* src and dest are word aligned similarly, less than 64 bytes to copy */ - cmp r2, #4 - blt Lbytewise2 - - /* bytewise copy until word aligned */ - tst r1, #3 -Lwordalignloop: - ldrneb r3, [r1], #1 - strneb r3, [r0], #1 - subne r2, r2, #1 - tstne r1, #3 - bne Lwordalignloop - - cmp r2, #16 - bge Llessthan64_aligned - blt Llessthan16_aligned - -Loverlap: - /* src and dest overlap in some way, len > 0 */ - cmp r0, r1 /* if dest > src */ - bhi Loverlap_srclower - -Loverlap_destlower: - /* dest < src, see if we can still do a fast forward copy or fallback to slow forward copy */ - cmp r3, #64 - bge Lnormalforwardcopy /* overlap is greater than one stride of the copy, use normal copy */ - - cmp r3, #2 - bge Lbytewise2 - b Lbytewise - - /* the following routines deal with having to copy in the reverse direction */ -Loverlap_srclower: - /* src < dest, with overlap */ - - /* src += len; dest += len; */ - add r0, r0, r2 - add r1, r1, r2 - - /* we have to copy in reverse no matter what, test if we can we use a large block reverse copy */ - cmp r2, #64 /* less than 64 bytes to copy? */ - cmpgt r3, #64 /* less than 64 bytes of nonoverlap? */ - blt Lbytewise_reverse - - /* test of src and dest are nonword aligned differently */ - mov r3, r0, lsl #30 - cmp r3, r1, lsl #30 - bne Lbytewise_reverse - - /* test if src and dest are non word aligned or dest is non 16 byte aligned */ - tst r0, #0xf - bne Lunaligned_reverse_similarly - - /* test for dest 32 byte alignment */ - tst r0, #(1<<4) - bne Lunaligned_32_reverse_similarly - - /* 64 byte reverse block copy, src and dest aligned */ -Lmorethan64_aligned_reverse: - /* save some more registers to use in the copy */ - stmfd sp!, { r6, r8, r10, r11 } - - /* pre-subtract 64 from the len counter to avoid an extra compare in the loop */ - sub r2, r2, #64 - -L64loop_reverse: - /* copy 64 bytes at a time */ - ldmdb r1!, { r3, r4, r5, r6, r8, r10, r11, r12 } -#ifdef _ARM_ARCH_6 - pld [r1, #-32] -#endif - stmdb r0!, { r3, r4, r5, r6, r8, r10, r11, r12 } - ldmdb r1!, { r3, r4, r5, r6, r8, r10, r11, r12 } - subs r2, r2, #64 -#ifdef _ARM_ARCH_6 - pld [r1, #-32] -#endif - stmdb r0!, { r3, r4, r5, r6, r8, r10, r11, r12 } - bge L64loop_reverse - - /* restore the scratch registers we just saved */ - ldmfd sp!, { r6, r8, r10, r11 } - - /* fix up the len counter (previously subtracted an extra 64 from it) and test for completion */ - adds r2, r2, #64 - beq Lexit - -Lbytewise_reverse: - ldrb r3, [r1, #-1]! - strb r3, [r0, #-1]! - subs r2, r2, #1 - bne Lbytewise_reverse - b Lexit - -Lunaligned_reverse_similarly: - /* both src and dest are unaligned in similar ways, align to dest on 32 byte boundary */ - mov r12, r0, lsl #28 - msr cpsr_f, r12 - - ldrvsb r3, [r1, #-1]! - ldrcsh r4, [r1, #-2]! - ldreq r5, [r1, #-4]! - - strvsb r3, [r0, #-1]! - strcsh r4, [r0, #-2]! - streq r5, [r0, #-4]! - - ldmmidb r1!, { r3, r4 } - stmmidb r0!, { r3, r4 } - - subs r2, r2, r12, lsr #28 - beq Lexit - -Lunaligned_32_reverse_similarly: - /* bring up to dest 32 byte alignment */ - tst r0, #(1 << 4) - ldmnedb r1!, { r3, r4, r5, r12 } - stmnedb r0!, { r3, r4, r5, r12 } - subne r2, r2, #16 - - /* we should now be aligned, see what copy method we should use */ - cmp r2, #64 - bge Lmorethan64_aligned_reverse - b Lbytewise_reverse - - /* the following routines deal with non word aligned copies */ -Lnonwordaligned_forward: - cmp r2, #8 - blt Lbytewise2 /* not worth the effort with less than 24 bytes total */ - - /* bytewise copy until src word aligned */ - tst r1, #3 -Lwordalignloop2: - ldrneb r3, [r1], #1 - strneb r3, [r0], #1 - subne r2, r2, #1 - tstne r1, #3 - bne Lwordalignloop2 - - /* figure out how the src and dest are unaligned */ - and r3, r0, #3 - cmp r3, #2 - blt Lalign1_forward - beq Lalign2_forward - bgt Lalign3_forward - -Lalign1_forward: - /* the dest pointer is 1 byte off from src */ - mov r12, r2, lsr #2 /* number of words we should copy */ - sub r0, r0, #1 - - /* prime the copy */ - ldrb r4, [r0] /* load D[7:0] */ - -Lalign1_forward_loop: - ldr r3, [r1], #4 /* load S */ - orr r4, r4, r3, lsl #8 /* D[31:8] = S[24:0] */ - str r4, [r0], #4 /* save D */ - mov r4, r3, lsr #24 /* D[7:0] = S[31:25] */ - subs r12, r12, #1 - bne Lalign1_forward_loop - - /* finish the copy off */ - strb r4, [r0], #1 /* save D[7:0] */ - - ands r2, r2, #3 - beq Lexit - b Lbytewise2 - -Lalign2_forward: - /* the dest pointer is 2 bytes off from src */ - mov r12, r2, lsr #2 /* number of words we should copy */ - sub r0, r0, #2 - - /* prime the copy */ - ldrh r4, [r0] /* load D[15:0] */ - -Lalign2_forward_loop: - ldr r3, [r1], #4 /* load S */ - orr r4, r4, r3, lsl #16 /* D[31:16] = S[15:0] */ - str r4, [r0], #4 /* save D */ - mov r4, r3, lsr #16 /* D[15:0] = S[31:15] */ - subs r12, r12, #1 - bne Lalign2_forward_loop - - /* finish the copy off */ - strh r4, [r0], #2 /* save D[15:0] */ - - ands r2, r2, #3 - beq Lexit - b Lbytewise2 - -Lalign3_forward: - /* the dest pointer is 3 bytes off from src */ - mov r12, r2, lsr #2 /* number of words we should copy */ - sub r0, r0, #3 - - /* prime the copy */ - ldr r4, [r0] - and r4, r4, #0x00ffffff /* load D[24:0] */ - -Lalign3_forward_loop: - ldr r3, [r1], #4 /* load S */ - orr r4, r4, r3, lsl #24 /* D[31:25] = S[7:0] */ - str r4, [r0], #4 /* save D */ - mov r4, r3, lsr #8 /* D[24:0] = S[31:8] */ - subs r12, r12, #1 - bne Lalign3_forward_loop - - /* finish the copy off */ - strh r4, [r0], #2 /* save D[15:0] */ - mov r4, r4, lsr #16 - strb r4, [r0], #1 /* save D[23:16] */ - - ands r2, r2, #3 - beq Lexit - b Lbytewise2 - -Lexit: - ldmfd sp!, {r0, r4, r5, r7, pc} - -#endif // defined __thumb2__ && defined __ARM_NEON__ - diff --git a/arm/string/bcopy_CortexA8.s b/arm/string/bcopy_CortexA8.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/bcopy_CortexA9.s b/arm/string/bcopy_CortexA9.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/bcopy_Generic.s b/arm/string/bcopy_Generic.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/bzero.s b/arm/string/bzero.s deleted file mode 100644 index e3a3a8d..0000000 --- a/arm/string/bzero.s +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2006, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined __thumb2__ && defined __ARM_NEON__ - -// Use our tuned NEON implementation when it is available. Otherwise fall back -// on more generic ARM code. - -#include "NEON/bzero.s" - -#else // defined __thumb2__ && defined __ARM_NEON__ - -#include -#include - -/* - * A reasonably well-optimized bzero/memset. Should work equally well on arm11 and arm9 based - * cores. - * - * The algorithm is to align the destination pointer on a 32 byte boundary and then - * blast data 64 bytes at a time, in two stores of 32 bytes per loop. - */ - .text - .align 2 - - .globl _memset -/* void *memset(void *ptr, int c, size_t len); */ -_memset: - /* move len into r1, unpack c into r2 */ - mov r3, r2 - and r1, r1, #0xff - orr r1, r1, r1, lsl #8 - orr r2, r1, r1, lsl #16 - mov r1, r3 - b Lbzeroengine - - .globl _bzero -/* void bzero(void *ptr, size_t len); */ -_bzero: - /* zero out r2 so we can be just like memset(0) */ - mov r2, #0 - -Lbzeroengine: - /* move the base pointer into r12 and leave r0 alone so that we return the original pointer */ - mov r12, r0 - - /* copy r2 into r3 for 64-bit stores */ - mov r3, r2 - - /* check for zero len */ - cmp r1, #0 - bxeq lr - - /* fall back to a bytewise store for less than 32 bytes */ - cmp r1, #32 - blt L_bytewise - - /* check for 32 byte unaligned ptr */ - tst r12, #0x1f - bne L_unaligned - - /* make sure we have more than 64 bytes to zero */ - cmp r1, #64 - blt L_lessthan64aligned - - /* >= 64 bytes of len, 32 byte aligned */ -L_64ormorealigned: - - /* we need some registers, avoid r7 (frame pointer) and r9 (thread register) */ - stmfd sp!, { r4-r6, r8, r10-r11 } - mov r4, r2 - mov r5, r2 - mov r6, r2 - mov r8, r2 - mov r10, r2 - mov r11, r2 - - /* pre-subtract 64 from the len to avoid an extra compare in the loop */ - sub r1, r1, #64 - -L_64loop: - stmia r12!, { r2-r6, r8, r10-r11 } - subs r1, r1, #64 - stmia r12!, { r2-r6, r8, r10-r11 } - bge L_64loop - - /* restore the saved regs */ - ldmfd sp!, { r4-r6, r8, r10-r11 } - - /* check for completion (had previously subtracted an extra 64 from len) */ - adds r1, r1, #64 - bxeq lr - -L_lessthan64aligned: - /* do we have 16 or more bytes left */ - cmp r1, #16 - stmgeia r12!, { r2-r3 } - stmgeia r12!, { r2-r3 } - subges r1, r1, #16 - bgt L_lessthan64aligned - bxeq lr - -L_lessthan16aligned: - /* store 0 to 15 bytes */ - mov r1, r1, lsl #28 /* move the remaining len bits [3:0] to the flags area of cpsr */ - msr cpsr_f, r1 - - stmmiia r12!, { r2-r3 } /* n is set, store 8 bytes */ - streq r2, [r12], #4 /* z is set, store 4 bytes */ - strcsh r2, [r12], #2 /* c is set, store 2 bytes */ - strvsb r2, [r12], #1 /* v is set, store 1 byte */ - bx lr - -L_bytewise: - /* bytewise copy, 2 bytes at a time, alignment not guaranteed */ - subs r1, r1, #2 - strb r2, [r12], #1 - strplb r2, [r12], #1 - bhi L_bytewise - bx lr - -L_unaligned: - /* unaligned on 32 byte boundary, store 1-15 bytes until we're 16 byte aligned */ - mov r3, r12, lsl #28 - rsb r3, r3, #0x00000000 - msr cpsr_f, r3 - - strvsb r2, [r12], #1 /* v is set, unaligned in the 1s column */ - strcsh r2, [r12], #2 /* c is set, unaligned in the 2s column */ - streq r2, [r12], #4 /* z is set, unaligned in the 4s column */ - strmi r2, [r12], #4 /* n is set, unaligned in the 8s column */ - strmi r2, [r12], #4 - - subs r1, r1, r3, lsr #28 - bxeq lr - - /* we had previously trashed r3, restore it */ - mov r3, r2 - - /* now make sure we're 32 byte aligned */ - tst r12, #(1 << 4) - stmneia r12!, { r2-r3 } - stmneia r12!, { r2-r3 } - subnes r1, r1, #16 - - /* we're now aligned, check for >= 64 bytes left */ - cmp r1, #64 - bge L_64ormorealigned - b L_lessthan64aligned - -X_LEAF(___bzero, _bzero) - -#endif // defined __thumb2__ && defined __ARM_NEON__ diff --git a/arm/string/bzero_CortexA8.s b/arm/string/bzero_CortexA8.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/bzero_CortexA9.s b/arm/string/bzero_CortexA9.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/bzero_Generic.s b/arm/string/bzero_Generic.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/dyld_resolvers.c b/arm/string/dyld_resolvers.c new file mode 100644 index 0000000..2adb0ef --- /dev/null +++ b/arm/string/dyld_resolvers.c @@ -0,0 +1,65 @@ +// This file implements resolvers to assist dyld in choosing the correct +// implementation of routines on ARMv7 processors. The +// micro-architectural differences between Cortex-A8 and Cortex-A9 are such +// that optimal write loops are quite different on the two processors. +// +// The MakeResolver_a8_a9(name) macro creates a function that dyld calls to +// pick an implementation of the name function. It does a check to determine +// if it is running on a8 or a9 hardware, and returns a pointer to either +// +// name$VARIANT$CortexA8 +// or +// name$VARIANT$CortexA9 +// +// This resolution only occurs once per process; once a symbol is bound to an +// implementation in dyld, no further calls to the resolver occur. +// +// On unknown implementations of the ARMv7 architecture, the Cortex-A9 variant +// is returned by these resolvers. + +#include +#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD + +#include +#include +#include + +#define MakeResolver_a8_a9(name) \ + void * name ## Resolver(void) __asm__("_" #name);\ + void * name ## Resolver(void) {\ + __asm__(".symbol_resolver _" #name);\ + if (*(int *)_COMM_PAGE_CPUFAMILY == CPUFAMILY_ARM_13)\ + return name ## $VARIANT$CortexA8;\ + else\ + return name ## $VARIANT$CortexA9;\ + } + +void bcopy$VARIANT$CortexA8(const void *, void *, size_t); +void bcopy$VARIANT$CortexA9(const void *, void *, size_t); +MakeResolver_a8_a9(bcopy) + +void *memmove$VARIANT$CortexA8(void *, const void *, size_t); +void *memmove$VARIANT$CortexA9(void *, const void *, size_t); +MakeResolver_a8_a9(memmove) + +void *memcpy$VARIANT$CortexA8(void *, const void *, size_t); +void *memcpy$VARIANT$CortexA9(void *, const void *, size_t); +MakeResolver_a8_a9(memcpy) + +void bzero$VARIANT$CortexA8(void *, size_t); +void bzero$VARIANT$CortexA9(void *, size_t); +MakeResolver_a8_a9(bzero) + +void __bzero$VARIANT$CortexA8(void *, size_t); +void __bzero$VARIANT$CortexA9(void *, size_t); +MakeResolver_a8_a9(__bzero) + +void *memset$VARIANT$CortexA8(void *, int, size_t); +void *memset$VARIANT$CortexA9(void *, int, size_t); +MakeResolver_a8_a9(memset) + +#else // defined _ARM_ARCH_7 && !defined VARIANT_DYLD + +typedef int emptyFilesArentCFiles; + +#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD diff --git a/arm/string/ffs.s b/arm/string/ffs.s index 62e492a..e69de29 100644 --- a/arm/string/ffs.s +++ b/arm/string/ffs.s @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#ifdef _ARM_ARCH_5 - .text - - .align 2 - .globl _ffs -_ffs: - .globl _ffsl -_ffsl: - rsb r3, r0, #0 - and r0, r0, r3 - clz r0, r0 - rsb r0, r0, #32 - bx lr - - .align 2 - .globl _fls -_fls: - .globl _flsl -_flsl: - clz r0, r0 - rsb r0, r0, #32 - bx lr -#else -#error need to define ffs for this architecture -#endif diff --git a/arm/string/memcmp.s b/arm/string/memcmp.s index 83e0f87..e69de29 100644 --- a/arm/string/memcmp.s +++ b/arm/string/memcmp.s @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -// ARM Assembly implementation of memcmp( ) from -// Uses Thumb2 if it is available, otherwise generates ARM code. -// -// -- Stephen Canon, August 2009 -// -// The basic idea is to use word compares instead of byte compares as long as -// at least four bytes remain to be compared. However, because memcmp( ) -// compares the buffers as though they were big-endian unsigned integers, we -// need to byte-reverse each word before comparing them. -// -// If the buffers are not word aligned, or they are shorter than four bytes, -// we just use a simple byte comparison loop instead. -// -// int bcmp(void *src1, void *src2, size_t length); -// int memcmp(void *src1, void *src2, size_t length); - -#include - - .text - .syntax unified -#if defined __thumb2__ - .code 16 - .thumb_func _bcmp - .thumb_func _memcmp -#else - .code 32 -#endif - .globl _bcmp - .globl _memcmp - .align 3 -_bcmp: -_memcmp: - -#ifdef _ARM_ARCH_6 - subs ip, r2, #4 // if length < 4 - bmi L_useByteCompares // jump to the byte comparison loop - - orr r3, r0, r1 // if the buffers are - tst r3, #3 // not word aligned - bne L_useByteCompares // jump to the byte comparison loop - -.align 3 -L_wordCompare: // Here we know that both buffers are word - ldr r2, [r0], #4 // aligned, and (length - 4) > 0, so at least - ldr r3, [r1], #4 // four bytes remain to be compared. We load - subs ip, #4 // a word from each buffer, and byte reverse - bmi L_lastWord // the loaded words. We also decrement the - rev r2, r2 // length by four and jump out of this loop if - rev r3, r3 // the result is negative. Then we compare the - cmp r2, r3 // reversed words, and continue the loop only - beq L_wordCompare // if they are equal. -L_wordsUnequal: - ite hi // If the words compared unequal, return +/- 1 - movhi r0, #1 // according to the result of the comparison. - movls r0, #-1 // - bx lr // -L_lastWord: - rev r2, r2 // If we just loaded the last complete words - rev r3, r3 // from the buffers, byte-reverse them and - cmp r2, r3 // compare. If they are unequal, jump to the - bne L_wordsUnequal // return path. - add r2, ip, #4 // Otherwise, fall into the cleanup code. -#endif // _ARM_ARCH_6 - -L_useByteCompares: - tst r2, r2 // If the length is exactly zero - beq L_returnZero // avoid doing any loads and return zero. - mov r3, r0 -.align 3 -L_byteCompareLoop: - ldrb r0, [r3], #1 // Load a byte from each buffer, and decrement - ldrb ip, [r1], #1 // the length by one. If the decremented - subs r2, #1 // length is zero, exit the loop. Otherwise - beq L_lastByte // subtract the loaded bytes; if their - subs r0, ip // difference is zero, continue the comparison - beq L_byteCompareLoop // loop. Otherwise, return their difference. - bx lr -L_returnZero: - mov r0, ip -L_lastByte: - sub r0, ip // Return the difference of the final bytes - bx lr diff --git a/arm/string/memset_pattern.s b/arm/string/memset_pattern.s old mode 100755 new mode 100644 index 1d0eb4f..e69de29 --- a/arm/string/memset_pattern.s +++ b/arm/string/memset_pattern.s @@ -1,351 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -/* - * This file contains the following functions: - * - * void memset_pattern4(void *b, const void *c4, size_t len) - * void memset_pattern8(void *b, const void *c8, size_t len) - * void memset_pattern16(void *b, const void *c16, size_t len) - * - * The memset() is implemented in the bzero.s file. - * - * This is a reasonably well optimized version of memset_pattern* routines - * implemented for ARM processors using the ARMv4 and later instruction sets. - * These routines use the ARM's core registers. - * - * The algorithm is to align the destination pointer on a 16 byte boundary - * and then blast data 64 bytes at a time, in two stores of 32 bytes per loop. - * - */ - .text - .align 2 - .syntax unified - -/*----------------------------------------------------------------------------*/ -/* void memset_pattern4(void *ptr, const void *pattern4, size_t len); */ -/* */ -/* r0 << destination pointer */ -/* r1 << pointer to 4-byte pattern */ -/* r2 << 'len' (length of destination buffer in bytes) */ -/*----------------------------------------------------------------------------*/ - .globl _memset_pattern4 -_memset_pattern4: - cmp r2, #0 /* check if len is zero */ - bxeq lr /* return if length is zero */ - - /* We need some registers, so save volatiles on stack */ - /* Avoid r7 (frame pointer) and r9 (thread register) */ - stmfd sp!, {r4-r7, lr} - add r7, sp, #12 /* establish frame */ - stmfd sp!, {r8, r10-r11} - - /* copy destination base pointer r0 to r12 and leave r0 alone */ - /* so that we return original pointer back to the caller */ - mov r12, r0 - - /* Check if 'len' is long enough to bother alignment of destination */ - /* pointer */ - cmp r2, #32 /* long enough to bother aligning? */ - movlt r3, #4 /* move pattern length into r3 */ - movlt r10, #4 /* pattern index */ - movlt r11, r1 /* move pattern pointer into r11 */ - blt L_Short /* no */ - - /* move 'len' into r1, get 4-byte pattern in r2 */ - mov r6, r2 /* temporarily move 'len' in to r6 */ - bl L_GetPatternWord /* get unaligned pattern word in r5 */ - mov r2, r5 /* move pattern word into r2 */ - mov r0, r12 /* r0 was clobbered - restore it */ - mov r1, r6 /* move 'len' from r6 to r1 */ - - mov r3, r2 /* copy 4-byte pattern into r3, r4 and r5 registers */ - mov r4, r2 - mov r5, r2 - -L_NotShort: - - /* Check for 16 or 32 byte aligned destination pointer */ - tst r12, #0x1F /* check for 32 byte aligned */ - beq L_Aligned - tst r12, #0xF /* check for 16 byte aligned */ - beq L_16ByteAligned - b L_Unaligned /* yes */ - -L_Bytewise: - ldrb r4, [r11], #1 - strb r4, [r12], #1 - subs r10, #1 - moveq r10, r3 - moveq r11, r1 - sub r2, #1 - -L_Short: - cmp r2, #0 /* more bytes left? */ - bne L_Bytewise - ldm sp!, {r8, r10-r11} /* restores registers from stack */ - ldm sp!, {r4-r7, lr} /* restore & return from subroutine */ - bx lr - -/* 'len' is long enough to justify aligning the destination pointer */ -/* */ -/* By the time we reach here, data is stored in registers as follows: */ -/* r1 << 'len' (length of destination buffer in bytes) */ -/* r2-r5 << pattern; either 4x4byte OR 2x8byte OR 1x16-byte */ -/* r12 << destination pointer copy (scratch register) */ -/* r0 << destination pointer original */ -/* */ -/* Use r11 as scratch register to store the #bytes offset to 16-byte align */ -/* */ -/* Unaligned on 32-byte boundary, store 1-15 bytes until 16-byte aligned */ -/* As we store these bytes, we rotate the pattern stored in r2-r5 to reflect */ -/* the alignment. */ - -L_Unaligned: - mov r11, r12, lsl #28 - rsb r11, r11, #0 - msr cpsr_f, r11 /* Bits[31:28] of cpsr now contain #bytes to align*/ - -L_Store15BytesAndRotatePattern: - strbvs r2, [r12], #1 /* v is set, unaligned in the 1s column */ - andvs r6, r2, #0xFF /* Rotate pattern right in r2-r5 by 1-byte */ - andvs r8, r3, #0xFF /* Consider register r2-r5 and a contiguous */ - andvs r10, r4, #0xFF /* 16-byte register with r2 containing LSB */ - andvs r11, r5, #0xFF /* and r5 containing MSB */ - lsrvs r2, r2, #8 - lsrvs r3, r3, #8 - lsrvs r4, r4, #8 - lsrvs r5, r5, #8 - orrvs r2, r2, r8, lsl #24 - orrvs r3, r3, r10, lsl #24 - orrvs r4, r4, r11, lsl #24 - orrvs r5, r5, r6, lsl #24 - - strhcs r2, [r12], #2 /* c is set, unaligned in the 2s column */ - movcs r6, r2, lsl #16 /* Rotate pattern right in r2-r5 by 2-bytes */ - movcs r8, r3, lsl #16 - movcs r10, r4, lsl #16 - movcs r11, r5, lsl #16 - lsrcs r2, r2, #16 - lsrcs r3, r3, #16 - lsrcs r4, r4, #16 - lsrcs r5, r5, #16 - orrcs r2, r2, r8 - orrcs r3, r3, r10 - orrcs r4, r4, r11 - orrcs r5, r5, r6 - - streq r2, [r12], #4 /* z is set, unaligned in the 4s column */ - moveq r6, r2 /* Rotate pattern right in r2-r5 by 4-bytes */ - moveq r2, r3 - moveq r3, r4 - moveq r4, r5 - moveq r5, r6 - - stmmi r12!, {r2-r3} /* n is set, unaligned in the 8s column */ - movmi r6, r2 /* Rotate pattern right in r2-r5 by 4-bytes */ - movmi r8, r3 - movmi r2, r4 - movmi r3, r5 - movmi r4, r6 - movmi r5, r8 - - mrs r11, cpsr /*copy cpsr in to r11 */ - subs r1, r1, r11, lsr #28 - ldmeq sp!, {r8, r10-r11} /* restores registers from stack */ - ldmeq sp!, {r4-r7, lr} /* restore & return from subroutine */ - bxeq lr - -/* By the time we reach here, we are 16-byte aligned and r2-r5 contains */ -/* rotated pattern. Now lets make sure we are 32-byte aligned. */ -L_16ByteAligned: - tst r12, #(1 << 4) - stmne r12!, {r2-r5} - subsne r1, r1, #16 - -/* By the time we reach here, data is stored in registers as follows: */ -/* r1 << 'len' (remaining length of destination buffer in bytes) */ -/* r2-r5 << rotated pattern; either 4x4byte OR 2x8byte OR 1x16-byte */ -/* r12 << aligned destination pointer copy (scratch register) */ -L_Aligned: - cmp r1, #64 - blt L_AlignedLessThan64 - -/* Copy pattern in four more registers so that we can do 64 byte transfers */ - mov r6, r2 - mov r8, r3 - mov r10, r4 - mov r11, r5 - -/* At this point, we are 16-byte aligned and 'len' is greater than 64 bytes */ -/* Lets transfer 64 bytes at a time until len becomes less than 64 bytes */ - sub r1, r1, #64 /* pre-subtract to avoid extra compare in loop */ -L_Loop64: - stm r12!, {r2-r6, r8, r10-r11} - subs r1, r1, #64 - stm r12!, {r2-r6, r8, r10-r11} - bge L_Loop64 - - /* return if 'len' is zero */ - adds r1, r1, #64 /* readjust length; previously subtracted extra 64*/ - ldmeq sp!, {r8, r10-r11} /* restores registers from stack */ - ldmeq sp!, {r4-r7, lr} /* restore & return from subroutine */ - bxeq lr - -L_AlignedLessThan64: - /* do we have 16 or more bytes left */ - cmp r1, #16 - stmge r12!, {r2-r5} - subsge r1, r1, #16 - bgt L_AlignedLessThan64 - ldmeq sp!, {r8, r10-r11} /* restores registers from stack */ - ldmeq sp!, {r4-r7, lr} /* restore & return from subroutine */ - bxeq lr - -L_AlignedLessThan16: - /* store last up-to 15 bytes */ - /* move the remaining len bits [3:0] to the flags area of cpsr */ - mov r1, r1, lsl #28 - msr cpsr_f, r1 - - stmmi r12!, {r2-r3} /* n is set, store 8 bytes */ - movmi r2, r4 /* shift vector down 8 bytes */ - movmi r3, r5 - - streq r2, [r12], #4 /* z is set, store 4 bytes */ - moveq r2, r3 /* shift vector down 4 bytes */ - - strhcs r2, [r12], #2 /* c is set, store 2 bytes */ - lsrcs r2, #16 /* shift register right 2 bytes */ - - strbvs r2, [r12], #1 /* v is set, store 1 byte */ - ldm sp!, {r8, r10-r11} /* restores registers from stack */ - ldm sp!, {r4-r7, lr} /* restore & return from subroutine */ - bx lr - -/*----------------------------------------------------------------------------*/ -/* void memset_pattern8(void *ptr, const void *pattern8, size_t len); */ -/* */ -/* r0 << destination pointer */ -/* r1 << pointer to 8-byte pattern */ -/* r2 << 'len' (length of destination buffer in bytes) */ -/*----------------------------------------------------------------------------*/ - .globl _memset_pattern8 -_memset_pattern8: - cmp r2, #0 /* check if len is zero */ - bxeq lr /* return if length is zero */ - - /* We need some registers, so save volatiles on stack */ - /* Avoid r7 (frame pointer) and r9 (thread register) */ - stmfd sp!, {r4-r7, lr} - add r7, sp, #12 /* establish frame */ - stmfd sp!, {r8, r10-r11} - - /* copy destination base pointer r0 to r12 and leave r0 alone */ - /* so that we return original pointer back to the caller */ - mov r12, r0 - - /* Check if 'len' is long enough to bother alignment of destination */ - /* pointer */ - cmp r2, #32 /* long enough to bother aligning? */ - movlt r3, #8 /* move pattern length into r3 */ - movlt r10, #8 /* pattern index */ - movlt r11, r1 /* move pattern pointer into r11 */ - blt L_Short /* no */ - - /* move 'len' into r1, get 8-byte pattern in r2-r3 */ - mov r6, r2 /* temporarily move 'len' in to r6 */ - bl L_GetPatternWord /* get unaligned pattern word in r5 */ - mov r2, r5 /* move pattern word into r2 */ - bl L_GetPatternWord - mov r3, r5 - mov r0, r12 /* r0 was clobbered - restore it */ - mov r1, r6 /* move 'len' from r6 to r1 */ - - mov r4, r2 /* copy 8-byte pattern into r4-r5 registers */ - mov r5, r3 - b L_NotShort /* yes */ - - -/*----------------------------------------------------------------------------*/ -/* void memset_pattern16(void *ptr, const void *pattern16, size_t len); */ -/* */ -/* r0 << destination pointer */ -/* r1 << pointer to 16-byte pattern */ -/* r2 << 'len' (length of destination buffer in bytes) */ -/*----------------------------------------------------------------------------*/ - .globl _memset_pattern16 -_memset_pattern16: - cmp r2, #0 /* check if len is zero */ - bxeq lr /* return if length is zero */ - - /* We need some registers, so save volatiles on stack */ - /* Avoid r7 (frame pointer) and r9 (thread register) */ - stmfd sp!, {r4-r7, lr} - add r7, sp, #12 /* establish frame */ - stmfd sp!, {r8, r10-r11} - - /* copy destination base pointer r0 to r12 and leave r0 alone */ - /* so that we return original pointer back to the caller */ - mov r12, r0 - - /* Check if 'len' is long enough to bother alignment of destination */ - /* pointer */ - cmp r2, #32 /* long enough to bother aligning? */ - movlt r3, #16 /* move pattern length into r3 */ - movlt r10, #16 /* pattern index */ - movlt r11, r1 /* move pattern pointer into r11 */ - blt L_Short /* no */ - - /* move 'len' into r1, get 16-byte pattern in r2-r5 */ - mov r6, r2 /* temporarily move 'len' in to r6 */ - bl L_GetPatternWord /* get unaligned pattern word in r5 */ - mov r2, r5 /* move pattern word into r2 */ - bl L_GetPatternWord - mov r3, r5 - bl L_GetPatternWord - mov r4, r5 - bl L_GetPatternWord - mov r0, r12 /* r0 was clobbered - restore it */ - mov r1, r6 /* move 'len' from r6 to r1 */ - - b L_NotShort /* yes */ - - -/*----------------------------------------------------------------------------*/ -/* Get an unaligned word at r1, returning it in r5. */ -/* Increments r1 by 4, clobbers r0. */ -/* This is tailored to fit the register usage by the call sites. */ -/*----------------------------------------------------------------------------*/ -L_GetPatternWord: - ldrb r5, [r1], #1 /* get the 1st byte at r1 */ - ldrb r0, [r1], #1 /* get the 2nd byte at r1 */ - orr r5, r5, r0, lsl #8 /* move into bits 15:8 */ - ldrb r0, [r1], #1 /* get the 3rd byte */ - orr r5, r5, r0, lsl #16 /* bits 23:16 */ - ldrb r0, [r1], #1 /* get the 4th byte */ - orr r5, r5, r0, lsl #24 /* bits 31:24 */ - bx lr diff --git a/arm/string/strchr.s b/arm/string/strchr.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/strcmp.s b/arm/string/strcmp.s index 4f1008e..e69de29 100644 --- a/arm/string/strcmp.s +++ b/arm/string/strcmp.s @@ -1,44 +0,0 @@ -/* $NetBSD: strcmp.S,v 1.3 2003/04/05 23:08:52 bjh21 Exp $ */ -/* $FreeBSD: src/lib/libc/arm/string/strcmp.S,v 1.2 2004/11/09 16:49:14 cognet Exp $ */ - -/* - * Copyright (c) 2002 ARM Ltd - * 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. - * 3. The name of the company may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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. - */ - - .text - .align 2 - .globl _strcmp - -_strcmp: -1: - ldrb r2, [r0], #1 - ldrb r3, [r1], #1 - cmp r2, #1 - cmpcs r2, r3 - beq 1b - sub r0, r2, r3 - bx lr diff --git a/arm/string/strcpy.s b/arm/string/strcpy.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/strlcpy.s b/arm/string/strlcpy.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/strlen.s b/arm/string/strlen.s index 2a18590..e69de29 100644 --- a/arm/string/strlen.s +++ b/arm/string/strlen.s @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -.text - .align 2 - - .globl _strlen -/* size_t strlen(const char *s); */ -_strlen: - /* save the original pointer */ - mov r12, r0 - - /* see if the string is aligned */ - ands r3, r0, #3 - - /* load the first word, address rounded down */ - bic r0, r0, #3 - ldr r2, [r0], #4 - - /* skip the next part if the string is already aligned */ - beq Laligned - -Lunaligned: - /* unaligned pointer, mask out the bytes that we've read that we should be ignoring */ - cmp r3, #2 - orr r2, r2, #0x000000ff - orrge r2, r2, #0x0000ff00 - orrgt r2, r2, #0x00ff0000 - -Laligned: - /* load 0x01010101 into r1 */ - mov r1, #0x01 - orr r1, r1, r1, lsl #8 - orr r1, r1, r1, lsl #16 - -Laligned_loop: - /* ((x - 0x01010101) & ~x & 0x80808080) == hasnull(word) */ - sub r3, r2, r1 /* x - 0x01010101 */ - bic r3, r3, r2 /* above & ~x */ - tst r3, r1, lsl #7 /* above & 0x80808080 */ - ldreq r2, [r0], #4 /* load next word */ - beq Laligned_loop - - /* we found a nullbyte */ - /* r0 (ptr) has overshot by up to 4 bytes, so subtract off until we find a nullbyte */ - sub r0, r0, #1 - tst r2, #0x000000ff - subeq r0, r0, #1 - tstne r2, #0x0000ff00 - subeq r0, r0, #1 - tstne r2, #0x00ff0000 - subeq r0, r0, #1 - -Lexit: - /* len = ptr - original pointer */ - sub r0, r0, r12 - bx lr - diff --git a/arm/string/strncmp.s b/arm/string/strncmp.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/strncpy.s b/arm/string/strncpy.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/strnlen.s b/arm/string/strnlen.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/string/strstr.s b/arm/string/strstr.s new file mode 100644 index 0000000..e69de29 diff --git a/arm/sys/Makefile.inc b/arm/sys/Makefile.inc index e4e7d8f..7991b41 100644 --- a/arm/sys/Makefile.inc +++ b/arm/sys/Makefile.inc @@ -2,15 +2,18 @@ MDSRCS+= \ OSAtomic.s \ + OSAtomic_resolvers.c \ gcc_atomic.c \ _longjmp.s \ _setjmp.s \ arm_commpage_gettimeofday.c \ longjmp.s \ - setjmp.s + setjmp.s \ + mach_absolute_time.s + +DYLDSRCS += OSAtomic.s arm_commpage_gettimeofday.c mach_absolute_time.s .if !defined(FEATURE_ARM_ARCH_6) MDSRCS+= OSAtomic-v4.c +DYLDSRCS+= OSAtomic-v4.c .endif - -MDCOPYFILES+= ${.CURDIR}/Platforms/${RC_TARGET_CONFIG}/arm/libc.syscall.arm diff --git a/arm/sys/OSAtomic-v4.c b/arm/sys/OSAtomic-v4.c index 723d84f..8f79420 100644 --- a/arm/sys/OSAtomic-v4.c +++ b/arm/sys/OSAtomic-v4.c @@ -289,4 +289,27 @@ bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * vo return result; } +void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset ) +{ + OSSpinLockLock(&_atomic_lock); + *((void **)((char *)__new + __offset)) = __list->opaque1; + __list->opaque1 = __new; + OSSpinLockUnlock(&_atomic_lock); +} + +void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset ) +{ + void *head; + + OSSpinLockLock(&_atomic_lock); + head = __list->opaque1; + if (head != NULL) { + void **next = (void **)((char *)head + __offset); + __list->opaque1 = *next; + } + OSSpinLockUnlock(&_atomic_lock); + + return head; +} + #endif /* !defined(_ARM_ARCH_6) */ diff --git a/arm/sys/OSAtomic.s b/arm/sys/OSAtomic.s index fe94f73..6bcf8d1 100644 --- a/arm/sys/OSAtomic.s +++ b/arm/sys/OSAtomic.s @@ -27,75 +27,222 @@ .text +/* Number of times we spin in a spinlock before going to kernel */ +#define MP_SPIN_TRIES 1000 +#define MP_SPIN_TRIES_WFE 10 + +#if defined(VARIANT_DYLD) + #if defined(_ARM_ARCH_7) + /* This makes sure we pick up MP variants for dyld on armv7 */ + #define ENTRY_POINT_RESOLVER(symbol, variant) \ + ENTRY_POINT(symbol##$VARIANT$##variant) ;\ + .private_extern symbol##$VARIANT$##variant + + #define ENTRY_POINT_DEFAULT(symbol, variant) \ + ENTRY_POINT(symbol##$VARIANT$##variant) ;\ + .private_extern symbol##$VARIANT$##variant + + #define makeResolver_up_mp(name) \ + ENTRY_POINT(_##name) \ + ldr ip, L##name##$commpage ; \ + ldr ip, [ip] ; \ + tst ip, $(kUP) ; \ + beq _##name##$VARIANT$mp ; \ + b _##name##$VARIANT$up ; \ + L##name##$commpage: .long _COMM_PAGE_CPU_CAPABILITIES ; + + #define makeResolver_up_mp_wfe(name) \ + makeResolver_up_mp(name) + #else + #define ENTRY_POINT_RESOLVER(symbol, variant) \ + ENTRY_POINT(symbol##$VARIANT$##variant) ;\ + .private_extern symbol##$VARIANT$##variant + + #define ENTRY_POINT_DEFAULT(symbol, variant) ENTRY_POINT(symbol) + #endif +#else + #if defined(_ARM_ARCH_7) + #define ENTRY_POINT_RESOLVER(symbol, variant) \ + ENTRY_POINT(symbol##$VARIANT$##variant) ;\ + .private_extern symbol##$VARIANT$##variant + #define ENTRY_POINT_DEFAULT(symbol, variant) \ + ENTRY_POINT(symbol##$VARIANT$##variant) ;\ + .private_extern symbol##$VARIANT$##variant + #else // !_ARM_ARCH_7 + /* _RESOLVER shouldn't be used on armv5/6, so intentionally plants bad text. */ + #define ENTRY_POINT_RESOLVER(symbol, variant) .error + #define ENTRY_POINT_DEFAULT(symbol, variant) ENTRY_POINT(symbol) + #endif +#endif // VARIANT_DYLD + +#if defined(VARIANT_DYLD) && defined(_ARM_ARCH_7) /* - * Use LDREX/STREX to perform atomic operations. - * Memory barriers are not needed on a UP system + * In dyld's build only, we include the list of resolvers needed and + * this generates entry points for dyld which are run on every execution + * in order to pick the correct variant. */ +#include "OSAtomic_resolvers.h" +#endif #if defined(_ARM_ARCH_6) /* Implement a generic atomic arithmetic operation: * operand is in R0, pointer is in R1. Return new - * value into R0 + * value into R0 (or old valule in _ORIG cases). + * + * Return instructions are separate to the + * _ATOMIC_ARITHMETIC macro. */ -#define ATOMIC_ARITHMETIC(op) \ -1: ldrex r2, [r1] /* load existing value and tag memory */ ;\ +#define _ATOMIC_ARITHMETIC(op) \ + ldrex r2, [r1] /* load existing value and tag memory */ ;\ op r3, r2, r0 /* compute new value */ ;\ strex ip, r3, [r1] /* store new value if memory is still tagged */ ;\ cmp ip, #0 /* check if the store succeeded */ ;\ - bne 1b /* if not, try again */ ;\ + bne 1b /* if not, try again */ + +#if defined(_ARM_ARCH_7) +/* + * ARMv7 barrier operations: + * - Full Barrier (FB); store barrier before store exclusive, full barrier after op. + */ + +#define ATOMIC_ARITHMETIC_FB(op) \ + dmb ishst /* store barrier before store exclusive */ ;\ +1: _ATOMIC_ARITHMETIC(op) ;\ + dmb ish /* issue data memory barrier */ ;\ + mov r0, r3 /* return new value */ + +#define ATOMIC_ARITHMETIC_ORIG_FB(op) \ + dmb ishst /* store barrier before store exclusive */ ;\ +1: _ATOMIC_ARITHMETIC(op) ;\ + dmb ish /* issue data memory barrier */ ;\ + mov r0, r2 /* return orig value */ + +#endif + +/* + * For the non-MP ARMv7 cases, and ARMv5/6, these provide atomic arithmetic + * without any barriers at all. + */ +#define ATOMIC_ARITHMETIC(op) \ +1: _ATOMIC_ARITHMETIC(op) ;\ mov r0, r3 /* return new value */ #define ATOMIC_ARITHMETIC_ORIG(op) \ -1: ldrex r2, [r1] /* load existing value and tag memory */ ;\ - op r3, r2, r0 /* compute new value */ ;\ - strex ip, r3, [r1] /* store new value if memory is still tagged */ ;\ - cmp ip, #0 /* check if the store succeeded */ ;\ - bne 1b /* if not, try again */ ;\ + 1: _ATOMIC_ARITHMETIC(op) ;\ mov r0, r2 /* return orig value */ -ENTRY_POINT(_OSAtomicAdd32Barrier) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicAdd32Barrier, mp) + ATOMIC_ARITHMETIC_FB(add) + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicAdd32Barrier, up) ENTRY_POINT(_OSAtomicAdd32) ATOMIC_ARITHMETIC(add) bx lr -ENTRY_POINT(_OSAtomicOr32Barrier) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicOr32Barrier, mp) + ATOMIC_ARITHMETIC_FB(orr) + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicOr32Barrier, up) ENTRY_POINT(_OSAtomicOr32) ATOMIC_ARITHMETIC(orr) bx lr -ENTRY_POINT(_OSAtomicOr32OrigBarrier) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicOr32OrigBarrier, mp) + ATOMIC_ARITHMETIC_ORIG_FB(orr) + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicOr32OrigBarrier, up) ENTRY_POINT(_OSAtomicOr32Orig) ATOMIC_ARITHMETIC_ORIG(orr) bx lr -ENTRY_POINT(_OSAtomicAnd32Barrier) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicAnd32Barrier, mp) + ATOMIC_ARITHMETIC_FB(and) + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicAnd32Barrier, up) ENTRY_POINT(_OSAtomicAnd32) ATOMIC_ARITHMETIC(and) bx lr -ENTRY_POINT(_OSAtomicAnd32OrigBarrier) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicAnd32OrigBarrier, mp) + ATOMIC_ARITHMETIC_ORIG_FB(and) + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicAnd32OrigBarrier, up) ENTRY_POINT(_OSAtomicAnd32Orig) ATOMIC_ARITHMETIC_ORIG(and) bx lr -ENTRY_POINT(_OSAtomicXor32Barrier) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicXor32Barrier, mp) + ATOMIC_ARITHMETIC_FB(eor) + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicXor32Barrier, up) ENTRY_POINT(_OSAtomicXor32) ATOMIC_ARITHMETIC(eor) bx lr -ENTRY_POINT(_OSAtomicXor32OrigBarrier) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicXor32OrigBarrier, mp) + ATOMIC_ARITHMETIC_ORIG_FB(eor) + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicXor32OrigBarrier, up) ENTRY_POINT(_OSAtomicXor32Orig) ATOMIC_ARITHMETIC_ORIG(eor) bx lr -ENTRY_POINT(_OSAtomicCompareAndSwap32Barrier) + +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicCompareAndSwap32Barrier, mp) +ENTRY_POINT_RESOLVER(_OSAtomicCompareAndSwapIntBarrier, mp) +ENTRY_POINT_RESOLVER(_OSAtomicCompareAndSwapLongBarrier, mp) +ENTRY_POINT_RESOLVER(_OSAtomicCompareAndSwapPtrBarrier, mp) + ldrex r3, [r2] // load existing value and tag memory + teq r3, r0 // is it the same as oldValue? + movne r0, #0 // if not, return 0 immediately + bxne lr + dmb ishst // store barrier before store exclusive + strex r3, r1, [r2] // otherwise, try to store new value + cmp r3, #0 // check if the store succeeded + bne 2f // if not, try again +1: dmb ish // memory barrier + mov r0, #1 // return true + bx lr +2: ldrex r3, [r2] // load existing value and tag memory + teq r3, r0 // is it the same as oldValue? + movne r0, #0 // if not, return 0 immediately + bxne lr + strex r3, r1, [r2] // otherwise, try to store new value + cmp r3, #0 // check if the store succeeded + bne 2b // if not, try again + b 1b // return +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicCompareAndSwap32Barrier, up) +ENTRY_POINT_DEFAULT(_OSAtomicCompareAndSwapIntBarrier, up) +ENTRY_POINT_DEFAULT(_OSAtomicCompareAndSwapLongBarrier, up) +ENTRY_POINT_DEFAULT(_OSAtomicCompareAndSwapPtrBarrier, up) ENTRY_POINT(_OSAtomicCompareAndSwap32) -ENTRY_POINT(_OSAtomicCompareAndSwapIntBarrier) ENTRY_POINT(_OSAtomicCompareAndSwapInt) -ENTRY_POINT(_OSAtomicCompareAndSwapLongBarrier) ENTRY_POINT(_OSAtomicCompareAndSwapLong) -ENTRY_POINT(_OSAtomicCompareAndSwapPtrBarrier) ENTRY_POINT(_OSAtomicCompareAndSwapPtr) 1: ldrex r3, [r2] // load existing value and tag memory teq r3, r0 // is it the same as oldValue? @@ -112,81 +259,208 @@ ENTRY_POINT(_OSAtomicCompareAndSwapPtr) * bit to set is in R0, base address is in R1. Return * previous value (0 or 1) of the bit in R0. */ -#define ATOMIC_BITOP(op) \ +#define _BITOP(op) \ /* Adjust pointer to point at the correct word ;\ * R1 = R1 + 4 * (R0 / 32) ;\ */ ;\ - mov r3, r0, lsr #5 ;\ - add r1, r1, r3, asl #2 ;\ + mov r3, r0, lsr #5 ;\ + add r1, r1, r3, asl #2 ;\ /* Generate a bit mask for the bit we want to test ;\ * R0 = (0x80 >> (R0 & 7)) << (R0 & ~7 & 31) ;\ */ ;\ - and r2, r0, #7 ;\ - mov r3, #0x80 ;\ - mov r3, r3, asr r2 ;\ - and r0, r0, #0x18 ;\ - mov r0, r3, asl r0 ;\ + and r2, r0, #7 ;\ + mov r3, #0x80 ;\ + mov r3, r3, asr r2 ;\ + and r0, r0, #0x18 ;\ + mov r0, r3, asl r0 ;\ + +#define ATOMIC_BITOP(op) \ + _BITOP(op) ;\ 1: ;\ ldrex r2, [r1] /* load existing value and tag memory */ ;\ op r3, r2, r0 /* compute new value */ ;\ strex ip, r3, [r1] /* attempt to store new value */ ;\ cmp ip, #0 /* check if the store succeeded */ ;\ - bne 1b /* if so, try again */ ;\ + bne 1b /* if not, try again */ ;\ ands r0, r2, r0 /* mask off the bit from the old value */ ;\ movne r0, #1 /* if non-zero, return exactly 1 */ -ENTRY_POINT(_OSAtomicTestAndSetBarrier) +#if defined(_ARM_ARCH_7) +#define ATOMIC_BITOP_FB(op) \ + _BITOP(op) ;\ + dmb ishst /* store barrier before store exclusive */ ;\ +1: ldrex r2, [r1] /* load existing value and tag memory */ ;\ + op r3, r2, r0 /* compute new value */ ;\ + strex ip, r3, [r1] /* attempt to store new value */ ;\ + cmp ip, #0 /* check if the store succeeded */ ;\ + bne 1b /* if not, try again */ ;\ + dmb ish /* memory barrier */ ;\ + ands r0, r2, r0 /* mask off the bit from the old value */ ;\ + movne r0, #1 /* if non-zero, return exactly 1 */ +#endif + +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicTestAndSetBarrier, mp) + ATOMIC_BITOP_FB(orr) + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicTestAndSetBarrier, up) ENTRY_POINT(_OSAtomicTestAndSet) ATOMIC_BITOP(orr) bx lr -ENTRY_POINT(_OSAtomicTestAndClearBarrier) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicTestAndClearBarrier, mp) + ATOMIC_BITOP_FB(bic) + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicTestAndClearBarrier, up) ENTRY_POINT(_OSAtomicTestAndClear) ATOMIC_BITOP(bic) bx lr -ENTRY_POINT(_OSMemoryBarrier) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSMemoryBarrier, mp) + dmb ish + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSMemoryBarrier, up) bx lr +/* void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset); */ +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicEnqueue, mp) + dmb ishst +1: ldrex r3, [r0] // get link to 1st on list + str r3, [r1, r2] // hang list off new node + strex r3, r1, [r0] // make new 1st on list + cmp r3, #0 + bne 1b + dmb ish + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicEnqueue, up) +1: ldrex r3, [r0] // get link to 1st on list + str r3, [r1, r2] // hang list off new node + strex r3, r1, [r0] // make new 1st on list + cmp r3, #0 + bne 1b + bx lr + +/* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */ +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicDequeue, mp) + mov r2, r0 + dmb ishst +1: ldrex r0, [r2] // get 1st in list + cmp r0, #0 // null? + bxeq lr // yes, list empty + ldr r3, [r0, r1] // get 2nd + strex ip, r3, [r2] // make 2nd first + cmp ip, #0 + bne 1b + dmb ish + bx lr +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicDequeue, up) + mov r2, r0 +1: ldrex r0, [r2] // get 1st in list + cmp r0, #0 // null? + bxeq lr // yes, list empty + ldr r3, [r0, r1] // get 2nd + strex ip, r3, [r2] // make 2nd first + cmp ip, #0 + bne 1b + bx lr #if defined(_ARM_ARCH_6K) /* If we can use LDREXD/STREXD, then we can implement 64-bit atomic operations */ -ENTRY_POINT(_OSAtomicAdd64Barrier) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicAdd64Barrier, mp) + // R0,R1 contain the amount to add + // R2 contains the pointer + stmfd sp!, {r4, r5, r8, r9, lr} + dmb ishst // store memory barrier before store exclusive +1: ldrexd r4, r5, [r2] // load existing value to R4/R5 and tag memory + adds r8, r4, r0 // add lower half of new value into R8 and set carry bit + adc r9, r5, r1 // add upper half of new value into R9 with carry + strexd r3, r8, r9, [r2] // store new value if memory is still tagged + cmp r3, #0 // check if store succeeded + bne 1b // if not, try again + dmb ish // memory barrier + mov r0, r8 // return new value + mov r1, r9 + ldmfd sp!, {r4, r5, r8, r9, pc} +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicAdd64Barrier, up) ENTRY_POINT(_OSAtomicAdd64) // R0,R1 contain the amount to add // R2 contains the pointer stmfd sp!, {r4, r5, r8, r9, lr} -1: - ldrexd r4, r5, [r2] // load existing value to R4/R5 and tag memory - adds r8, r4, r0 // add lower half of new value into R6 and set carry bit - adc r9, r5, r1 // add upper half of new value into R8 with carry +1: ldrexd r4, r5, [r2] // load existing value to R4/R5 and tag memory + adds r8, r4, r0 // add lower half of new value into R8 and set carry bit + adc r9, r5, r1 // add upper half of new value into R9 with carry strexd r3, r8, r9, [r2] // store new value if memory is still tagged cmp r3, #0 // check if store succeeded - bne 1b // if so, try again + bne 1b // if not, try again mov r0, r8 // return new value mov r1, r9 ldmfd sp!, {r4, r5, r8, r9, pc} -ENTRY_POINT(_OSAtomicCompareAndSwap64Barrier) -ENTRY_POINT(_OSAtomicCompareAndSwap64) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_OSAtomicCompareAndSwap64Barrier, mp) // R0,R1 contains the old value // R2,R3 contains the new value // the pointer is pushed onto the stack ldr ip, [sp, #0] // load pointer into IP stmfd sp!, {r4, r5, lr} -1: ldrexd r4, [ip] // load existing value into R4/R5 and tag memory teq r0, r4 // check low word teqeq r1, r5 // if low words match, check high word movne r0, #0 // if either match fails, return 0 bne 2f + dmb ishst // store barrier before store exclusive strexd r4, r2, [ip] // otherwise, try to store new values - cmp r3, #0 // check if store succeeded - bne 1b // if so, try again + cmp r4, #0 // check if store succeeded + bne 3f // if not, try again +1: dmb ish // memory barrier mov r0, #1 // return true -2: - ldmfd sp!, {r4, r5, pc} +2: ldmfd sp!, {r4, r5, pc} +3: ldrexd r4, [ip] // load existing value into R4/R5 and tag memory + teq r0, r4 // check low word + teqeq r1, r5 // if low words match, check high word + movne r0, #0 // if either match fails, return 0 + bne 2b + strexd r4, r2, [ip] // otherwise, try to store new values + cmp r4, #0 // check if store succeeded + bne 3f // if not, try again + b 1b // return +#endif + +ENTRY_POINT_DEFAULT(_OSAtomicCompareAndSwap64Barrier, up) +ENTRY_POINT(_OSAtomicCompareAndSwap64) + // R0,R1 contains the old value + // R2,R3 contains the new value + // the pointer is pushed onto the stack + ldr ip, [sp, #0] // load pointer into IP + stmfd sp!, {r4, r5, lr} +1: ldrexd r4, [ip] // load existing value into R4/R5 and tag memory + teq r0, r4 // check low word + teqeq r1, r5 // if low words match, check high word + movne r0, #0 // if either match fails, return 0 + bne 2f + strexd r4, r2, [ip] // otherwise, try to store new values + cmp r4, #0 // check if store succeeded + bne 1b // if not, try again + mov r0, #1 // return true +2: ldmfd sp!, {r4, r5, pc} #endif /* defined(_ARM_ARCH_6K) */ @@ -200,29 +474,127 @@ ENTRY_POINT(_OSAtomicCompareAndSwap64) * Lock the lock pointed to by p. Spin (possibly forever) until the next * lock is available. */ -ENTRY_POINT(_spin_lock) -ENTRY_POINT(__spin_lock) -ENTRY_POINT(_OSSpinLockLock) -L_spin_lock_loop: + +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_spin_lock, mp) +ENTRY_POINT_RESOLVER(__spin_lock, mp) +ENTRY_POINT_RESOLVER(_OSSpinLockLock, mp) mov r1, #1 +1: ldrex r2, [r0] // load the value of [r0] into r2 + cmp r2, #0 // compare the lock value to zero + bne 2f // jump to the spin if we don't own the lock + strex r3, r1, [r0] // try to store the one + cmp r3, #0 // test to see if we stored our value + bne 2f // if not, jump to the spin too + dmb ish // memory barrier if we acquired the lock + bx lr // and return +2: mov r3, $(MP_SPIN_TRIES) // load up r3 with spin counter +3: ldr r2, [r0] // load the lock + cmp r2, #0 // if unlocked + beq 1b // then go back to the top + subs r3, r3, #1 // counter-- + bne 3b // if nonzero, back to 3: + + mov r3, r0 // r0 is clobbered by the syscall return value + mov r0, #0 // THREAD_NULL + // SWITCH_OPTION_DEPRESS (r1==1 already) + mov r2, #1 // timeout (ms) + mov r12, #-61 // SYSCALL_THREAD_SWITCH + swi 0x80 + mov r0, r3 // restore state of r0 + b 1b + +#if !defined(VARIANT_DYLD) +/* + This sucks from a code sharing PoV. The only difference in this version is + the presence of a WFE instruction in the spin loop. This is only used on + CPU's which get woken up regularly out of WFE waits. + + Additionally, completely compiled out of the dyld variant so we can easily + use macros to pick the normal MP version for dyld on armv7 platforms. + */ +ENTRY_POINT_RESOLVER(_spin_lock, wfe) +ENTRY_POINT_RESOLVER(__spin_lock, wfe) +ENTRY_POINT_RESOLVER(_OSSpinLockLock, wfe) + mov r1, #1 +1: ldrex r2, [r0] // load the value of [r0] into r2 + cmp r2, #0 // compare the lock value to zero + bne 2f // jump to the spin if we don't own the lock + strex r3, r1, [r0] // try to store the one + cmp r3, #0 // test to see if we stored our value + bne 2f // if not, jump to the spin too + dmb ish // memory barrier if we acquired the lock + bx lr // and return +2: mov r3, $(MP_SPIN_TRIES_WFE) // load up r3 with spin counter +3: wfe // sleepy time + ldr r2, [r0] // load the lock + cmp r2, #0 // if unlocked + beq 1b // then go back to the top + subs r3, r3, #1 // counter-- + bne 3b // if nonzero, back to 3: + + mov r3, r0 // r0 is clobbered by the syscall return value + mov r0, #0 // THREAD_NULL + // SWITCH_OPTION_DEPRESS (r1==1 already) + mov r2, #1 // timeout (ms) + mov r12, #-61 // SYSCALL_THREAD_SWITCH + swi 0x80 + mov r0, r3 // restore state of r0 + b 1b +#endif // VARIANT_DYLD +#endif // _ARM_ARCH_7 + +ENTRY_POINT_DEFAULT(_spin_lock, up) +ENTRY_POINT_DEFAULT(__spin_lock, up) +ENTRY_POINT_DEFAULT(_OSSpinLockLock, up) + mov r1, #1 +1: +#if !defined(_ARM_ARCH_7) swp r2, r1, [r0] cmp r2, #0 - bxeq lr - mov ip, sp - stmfd sp!, {r0, r8} - mov r0, #0 // THREAD_NULL - mov r1, #1 // SWITCH_OPTION_DEPRESS - mov r2, #1 // timeout (ms) - mov r12, #-61 // SYSCALL_THREAD_SWITCH +#else + ldrex r2, [r0] // load the value of [r0] into r2 + cmp r2, #0 // compare the lock value to zero + bne 2f // jump to the spin if we don't own the lock + strex r3, r1, [r0] // try to store the one + cmp r3, #0 // test to see if we stored our value +#endif // !_ARM_ARCH_6 + bxeq lr // if so, return +2: mov r3, r0 // r0 is clobbered by the syscall return value + mov r0, #0 // THREAD_NULL + // SWITCH_OPTION_DEPRESS (r1==1 already) + mov r2, #1 // timeout (ms) + mov r12, #-61 // SYSCALL_THREAD_SWITCH swi 0x80 - ldmfd sp!, {r0, r8} - b L_spin_lock_loop + mov r0, r3 // restore state of r0 + b 1b -ENTRY_POINT(_spin_lock_try) -ENTRY_POINT(__spin_lock_try) -ENTRY_POINT(_OSSpinLockTry) +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_spin_lock_try, mp) +ENTRY_POINT_RESOLVER(__spin_lock_try, mp) +ENTRY_POINT_RESOLVER(_OSSpinLockTry, mp) mov r1, #1 +1: ldrex r2, [r0] + strex r3, r1, [r0] + cmp r3, #0 + bne 1b + dmb ish + bic r0, r1, r2 + bx lr +#endif + +ENTRY_POINT_DEFAULT(_spin_lock_try, up) +ENTRY_POINT_DEFAULT(__spin_lock_try, up) +ENTRY_POINT_DEFAULT(_OSSpinLockTry, up) + mov r1, #1 +#if !defined(_ARM_ARCH_7) swp r2, r1, [r0] +#else +1: ldrex r2, [r0] + strex r3, r1, [r0] + cmp r3, #0 + bne 1b +#endif // !_ARM_ARCH_6 bic r0, r1, r2 bx lr @@ -233,10 +605,30 @@ ENTRY_POINT(_OSSpinLockTry) * * Unlock the lock pointed to by p. */ -ENTRY_POINT(_spin_unlock) -ENTRY_POINT(__spin_unlock) -ENTRY_POINT(_OSSpinLockUnlock) + +#if defined(_ARM_ARCH_7) +ENTRY_POINT_RESOLVER(_spin_unlock, mp) +ENTRY_POINT_RESOLVER(__spin_unlock, mp) +ENTRY_POINT_RESOLVER(_OSSpinLockUnlock, mp) mov r1, #0 - str r1, [r0] + dmb ish // barrier so that previous accesses are observed before unlock +1: ldrex r2, [r0] // load the lock to get exclusive access + strex r3, r1, [r0] // strex is instantly visible to (at least) {st,ld}rex + cmp r3, #0 // did the unlock succeed? + bne 1b // if not, try try again. bx lr +#endif +ENTRY_POINT_DEFAULT(_spin_unlock, up) +ENTRY_POINT_DEFAULT(__spin_unlock, up) +ENTRY_POINT_DEFAULT(_OSSpinLockUnlock, up) + mov r1, #0 +#if !defined(_ARM_ARCH_7) + str r1, [r0] +#else +1: ldrex r2, [r0] // load the lock to get exclusive access + strex r3, r1, [r0] // store zero to the lock + cmp r3, #0 // did the unlock succeed? + bne 1b // if not, try try again. +#endif // !_ARM_ARCH_6 + bx lr diff --git a/arm/sys/OSAtomic_resolvers.c b/arm/sys/OSAtomic_resolvers.c new file mode 100644 index 0000000..6b26d30 --- /dev/null +++ b/arm/sys/OSAtomic_resolvers.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * This holds the C versions of OSAtomic.s resolver functions, used by + * everyone except dyld. + */ + +#include +#if defined(_ARM_ARCH_7) && !defined(VARIANT_DYLD) + +#include +#include +#include + +#define makeResolver_up_mp(name) \ + void name ## $VARIANT$up(void); \ + void name ## $VARIANT$mp(void); \ + void* name ## Resolver(void) __asm__( "_" #name ) ; \ + void* name ## Resolver(void) { \ + __asm__(".symbol_resolver _" #name); \ + /* return MP variant functions on kNumCPUs > 1 */ \ + if ((_get_cpu_capabilities() & kUP) == 0) { \ + return name ## $VARIANT$mp; \ + } \ + return name ## $VARIANT$up; \ + } + +#define makeResolver_up_mp_wfe(name) \ + void name ## $VARIANT$up(void); \ + void name ## $VARIANT$mp(void); \ + void name ## $VARIANT$wfe(void); \ + void* name ## Resolver(void) __asm__( "_" #name ) ; \ + void* name ## Resolver(void) { \ + __asm__(".symbol_resolver _" #name); \ + int caps = _get_cpu_capabilities(); \ + /* return WFE variant if we will get woken up */ \ + if ((caps & (kHasEvent | kUP)) == kHasEvent) { \ + return name ## $VARIANT$wfe; \ + } \ + /* return MP variant functions on kNumCPUs > 1 */ \ + else if ((caps & kUP) == 0) { \ + return name ## $VARIANT$mp; \ + } \ + return name ## $VARIANT$up; \ + } + +#include "OSAtomic_resolvers.h" + +#else // defined _ARM_ARCH_7 && !defined VARIANT_DYLD + +typedef int emptyFilesArentCFiles; + +#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD diff --git a/arm/sys/OSAtomic_resolvers.h b/arm/sys/OSAtomic_resolvers.h new file mode 100644 index 0000000..ea82afe --- /dev/null +++ b/arm/sys/OSAtomic_resolvers.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * This header file gets included by OSAtomic_resolvers.c and OSAtomic.s + * in order to create the appropriate resolvers for both libsystem_c.dylib + * and dyld's libc.a + */ + +makeResolver_up_mp(OSAtomicAdd32Barrier) +makeResolver_up_mp(OSAtomicOr32Barrier) +makeResolver_up_mp(OSAtomicOr32OrigBarrier) +makeResolver_up_mp(OSAtomicAnd32Barrier) +makeResolver_up_mp(OSAtomicAnd32OrigBarrier) +makeResolver_up_mp(OSAtomicXor32Barrier) +makeResolver_up_mp(OSAtomicXor32OrigBarrier) +makeResolver_up_mp(OSAtomicCompareAndSwap32Barrier) +makeResolver_up_mp(OSAtomicCompareAndSwapIntBarrier) +makeResolver_up_mp(OSAtomicCompareAndSwapLongBarrier) +makeResolver_up_mp(OSAtomicCompareAndSwapPtrBarrier) +makeResolver_up_mp(OSAtomicTestAndSetBarrier) +makeResolver_up_mp(OSAtomicTestAndClearBarrier) +makeResolver_up_mp(OSMemoryBarrier) +makeResolver_up_mp(OSAtomicEnqueue) +makeResolver_up_mp(OSAtomicDequeue) +makeResolver_up_mp(OSAtomicAdd64Barrier) +makeResolver_up_mp(OSAtomicCompareAndSwap64Barrier) + +makeResolver_up_mp_wfe(spin_lock) +makeResolver_up_mp_wfe(_spin_lock) +makeResolver_up_mp_wfe(OSSpinLockLock) + +makeResolver_up_mp(spin_lock_try) +makeResolver_up_mp(_spin_lock_try) +makeResolver_up_mp(OSSpinLockTry) + +makeResolver_up_mp(spin_unlock) +makeResolver_up_mp(_spin_unlock) +makeResolver_up_mp(OSSpinLockUnlock) diff --git a/arm/sys/gcc_atomic.c b/arm/sys/gcc_atomic.c index fd8c8c1..4fc25d2 100644 --- a/arm/sys/gcc_atomic.c +++ b/arm/sys/gcc_atomic.c @@ -20,6 +20,9 @@ * * @APPLE_LICENSE_HEADER_END@ */ + +#ifndef __clang__ + #include #include #include @@ -32,63 +35,63 @@ int32_t __sync_fetch_and_add_4 (int32_t *ptr, int32_t value) { - return OSAtomicAdd32(value, ptr) - value; + return OSAtomicAdd32Barrier(value, ptr) - value; } int32_t __sync_fetch_and_sub_4 (int32_t *ptr, int32_t value) { - return OSAtomicAdd32(-value, ptr) + value; + return OSAtomicAdd32Barrier(-value, ptr) + value; } uint32_t __sync_fetch_and_or_4(uint32_t *ptr, uint32_t value) { - return OSAtomicOr32Orig(value, ptr); + return OSAtomicOr32OrigBarrier(value, ptr); } uint32_t __sync_fetch_and_and_4(uint32_t *ptr, uint32_t value) { - return OSAtomicAnd32Orig(value, ptr); + return OSAtomicAnd32OrigBarrier(value, ptr); } uint32_t __sync_fetch_and_xor_4(uint32_t *ptr, uint32_t value) { - OSAtomicXor32Orig(value, ptr); + return OSAtomicXor32OrigBarrier(value, ptr); } int32_t __sync_add_and_fetch_4 (int32_t *ptr, int32_t value) { - return OSAtomicAdd32(value, ptr); + return OSAtomicAdd32Barrier(value, ptr); } int32_t __sync_sub_and_fetch_4 (int32_t *ptr, int32_t value) { - return OSAtomicAdd32(-value, ptr); + return OSAtomicAdd32Barrier(-value, ptr); } uint32_t __sync_or_and_fetch_4 (uint32_t *ptr, int32_t value) { - return OSAtomicOr32(value, ptr); + return OSAtomicOr32Barrier(value, ptr); } uint32_t __sync_and_and_fetch_4 (uint32_t *ptr, int32_t value) { - return OSAtomicAnd32(value, ptr); + return OSAtomicAnd32Barrier(value, ptr); } uint32_t __sync_xor_and_fetch_4 (uint32_t *ptr, int32_t value) { - return OSAtomicXor32(value, ptr); + return OSAtomicXor32Barrier(value, ptr); } bool __sync_bool_compare_and_swap_4(int32_t *ptr, int32_t oldval, int32_t newval) { - return OSAtomicCompareAndSwap32(oldval, newval, ptr); + return OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr); } int32_t __sync_val_compare_and_swap_4(int32_t *ptr, int32_t oldval, int32_t newval) { int32_t old = *ptr; - OSAtomicCompareAndSwap32(oldval, newval, ptr); + OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr); return old; } @@ -98,7 +101,7 @@ int32_t __sync_lock_test_and_set_4(int32_t *ptr, int32_t value) do { old = *ptr; - } while (!OSAtomicCompareAndSwap32(old, value, ptr)); + } while (!OSAtomicCompareAndSwap32Barrier(old, value, ptr)); return old; } @@ -107,3 +110,5 @@ void __sync_lock_release_4(int32_t *ptr) { *ptr = 0; } + +#endif diff --git a/sys/rmdir.c b/arm/sys/mach_absolute_time.s similarity index 78% rename from sys/rmdir.c rename to arm/sys/mach_absolute_time.s index 68dd4ca..716affc 100644 --- a/sys/rmdir.c +++ b/arm/sys/mach_absolute_time.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Apple Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,15 +21,14 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include +#include -void __inc_remove_counter(void); -int __rmdir(const char *path); - -int -rmdir(const char *path) -{ - int res = __rmdir(path); - if (res == 0) __inc_remove_counter(); - return res; -} +#if __arm__ + .text + .align 2 + .globl _mach_absolute_time +_mach_absolute_time: + mov r12, #-3 + swi 0x80 + bx lr +#endif diff --git a/compat-43/FreeBSD/creat.2 b/compat-43/FreeBSD/creat.2 index b62365a..50acae4 100644 --- a/compat-43/FreeBSD/creat.2 +++ b/compat-43/FreeBSD/creat.2 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)creat.2 8.1 (Berkeley) 6/2/93 -.\" $FreeBSD: src/lib/libc/compat-43/creat.2,v 1.10 2002/12/18 12:45:08 ru Exp $ +.\" $FreeBSD: src/lib/libc/compat-43/creat.2,v 1.11 2007/01/09 00:27:49 imp Exp $ .\" .Dd June 2, 1993 .Dt CREAT 2 diff --git a/compat-43/FreeBSD/creat.c b/compat-43/FreeBSD/creat.c index 7af5b25..2ee5dd4 100644 --- a/compat-43/FreeBSD/creat.c +++ b/compat-43/FreeBSD/creat.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)creat.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/creat.c,v 1.7 2002/03/22 21:51:56 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/creat.c,v 1.8 2007/01/09 00:27:49 imp Exp $"); #include "namespace.h" #include diff --git a/compat-43/FreeBSD/creat.c.patch b/compat-43/FreeBSD/creat.c.patch index afaec01..c3bad77 100644 --- a/compat-43/FreeBSD/creat.c.patch +++ b/compat-43/FreeBSD/creat.c.patch @@ -1,8 +1,8 @@ ---- creat.c.orig 2006-09-16 19:12:44.000000000 -0700 -+++ creat.c 2006-09-17 00:17:18.000000000 -0700 -@@ -37,14 +37,26 @@ +--- creat.c.orig 2009-11-06 10:36:38.000000000 -0800 ++++ creat.c 2009-11-06 10:39:44.000000000 -0800 +@@ -33,14 +33,26 @@ static char sccsid[] = "@(#)creat.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/compat-43/creat.c,v 1.7 2002/03/22 21:51:56 obrien Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/compat-43/creat.c,v 1.8 2007/01/09 00:27:49 imp Exp $"); + #include "namespace.h" diff --git a/compat-43/FreeBSD/gethostid.3 b/compat-43/FreeBSD/gethostid.3 index fcd7d71..472dca6 100644 --- a/compat-43/FreeBSD/gethostid.3 +++ b/compat-43/FreeBSD/gethostid.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)gethostid.3 8.1 (Berkeley) 6/2/93 -.\" $FreeBSD: src/lib/libc/compat-43/gethostid.3,v 1.12 2004/07/02 23:52:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/compat-43/gethostid.3,v 1.14 2007/01/09 00:27:49 imp Exp $ .\" .Dd June 2, 1993 .Dt GETHOSTID 3 @@ -71,8 +67,6 @@ The hostid should be set or retrieved by use of .Xr gethostname 3 , .Xr sysctl 3 , .Xr sysctl 8 -.Sh BUGS -32 bits for the identifier is too small. .Sh HISTORY The .Fn gethostid @@ -82,3 +76,5 @@ syscalls appeared in .Bx 4.2 and were dropped in .Bx 4.4 . +.Sh BUGS +32 bits for the identifier is too small. diff --git a/compat-43/FreeBSD/gethostid.3.patch b/compat-43/FreeBSD/gethostid.3.patch index 5cfd027..184729b 100644 --- a/compat-43/FreeBSD/gethostid.3.patch +++ b/compat-43/FreeBSD/gethostid.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/compat-43/FreeBSD/gethostid.3 2004-11-25 11:37:56.000000000 -0800 -+++ _SB/Libc/compat-43/FreeBSD/gethostid.3.edit 2006-06-28 16:55:50.000000000 -0700 -@@ -51,11 +51,9 @@ +--- gethostid.3.orig 2009-11-06 10:36:38.000000000 -0800 ++++ gethostid.3 2009-11-06 10:41:15.000000000 -0800 +@@ -47,11 +47,9 @@ The .Fn sethostid function diff --git a/compat-43/FreeBSD/gethostid.c b/compat-43/FreeBSD/gethostid.c index 0f08fad..3a7da22 100644 --- a/compat-43/FreeBSD/gethostid.c +++ b/compat-43/FreeBSD/gethostid.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,11 +31,13 @@ static char sccsid[] = "@(#)gethostid.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/gethostid.c,v 1.3 2002/05/28 16:56:57 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/gethostid.c,v 1.5 2007/01/09 00:27:49 imp Exp $"); #include #include +#include + long gethostid(void) { diff --git a/compat-43/FreeBSD/gethostid.c.patch b/compat-43/FreeBSD/gethostid.c.patch new file mode 100644 index 0000000..29aa613 --- /dev/null +++ b/compat-43/FreeBSD/gethostid.c.patch @@ -0,0 +1,11 @@ +--- gethostid.c.orig 2011-02-15 16:30:07.000000000 -0800 ++++ gethostid.c 2011-02-18 12:19:33.000000000 -0800 +@@ -43,7 +43,7 @@ gethostid(void) + { + int mib[2]; + size_t size; +- long value; ++ int value; + + mib[0] = CTL_KERN; + mib[1] = KERN_HOSTID; diff --git a/compat-43/FreeBSD/getwd.c b/compat-43/FreeBSD/getwd.c index b15d2e2..3ed8490 100644 --- a/compat-43/FreeBSD/getwd.c +++ b/compat-43/FreeBSD/getwd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)getwd.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/getwd.c,v 1.3 2002/03/22 21:51:56 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/getwd.c,v 1.6 2007/01/09 00:27:49 imp Exp $"); #include #include @@ -44,13 +40,12 @@ __FBSDID("$FreeBSD: src/lib/libc/compat-43/getwd.c,v 1.3 2002/03/22 21:51:56 obr #include char * -getwd(buf) - char *buf; +getwd(char *buf) { char *p; if ( (p = getcwd(buf, MAXPATHLEN)) ) return(p); - (void)strcpy(buf, strerror(errno)); + (void)strerror_r(errno, buf, MAXPATHLEN); return((char *)NULL); } diff --git a/compat-43/FreeBSD/killpg.2 b/compat-43/FreeBSD/killpg.2 index dc48c22..97bc9b1 100644 --- a/compat-43/FreeBSD/killpg.2 +++ b/compat-43/FreeBSD/killpg.2 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)killpg.2 8.1 (Berkeley) 6/2/93 -.\" $FreeBSD: src/lib/libc/compat-43/killpg.2,v 1.12 2002/12/19 09:40:21 ru Exp $ +.\" $FreeBSD: src/lib/libc/compat-43/killpg.2,v 1.14 2007/01/09 00:27:49 imp Exp $ .\" -.Dd June 2, 1993 +.Dd October 10, 2006 .Dt KILLPG 2 .Os .Sh NAME @@ -66,7 +62,7 @@ The sending process and members of the process group must have the same effective user ID, or the sender must be the super-user. As a single special case the continue signal SIGCONT may be sent -to any process that is a descendant of the current process. +to any process with the same session ID as the caller. .Sh RETURN VALUES .Rv -std killpg .Sh ERRORS diff --git a/compat-43/FreeBSD/killpg.2.patch b/compat-43/FreeBSD/killpg.2.patch index 7bfa229..8a00461 100644 --- a/compat-43/FreeBSD/killpg.2.patch +++ b/compat-43/FreeBSD/killpg.2.patch @@ -1,6 +1,6 @@ ---- killpg.2 2003-05-20 15:20:40.000000000 -0700 -+++ killpg.2.edit 2006-07-12 10:52:21.000000000 -0700 -@@ -41,7 +41,6 @@ +--- killpg.2.orig 2009-11-06 10:36:38.000000000 -0800 ++++ killpg.2 2009-11-06 10:41:32.000000000 -0800 +@@ -37,7 +37,6 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -8,7 +8,7 @@ .In signal.h .Ft int .Fn killpg "pid_t pgrp" "int sig" -@@ -80,21 +79,29 @@ +@@ -76,21 +75,29 @@ The .Fa sig argument is not a valid signal number. diff --git a/compat-43/FreeBSD/killpg.c b/compat-43/FreeBSD/killpg.c index a6220f7..ca8097e 100644 --- a/compat-43/FreeBSD/killpg.c +++ b/compat-43/FreeBSD/killpg.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)killpg.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/killpg.c,v 1.4 2002/05/28 16:56:57 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/killpg.c,v 1.5 2007/01/09 00:27:49 imp Exp $"); #include #include diff --git a/compat-43/FreeBSD/killpg.c.patch b/compat-43/FreeBSD/killpg.c.patch index 37d7abd..6c18982 100644 --- a/compat-43/FreeBSD/killpg.c.patch +++ b/compat-43/FreeBSD/killpg.c.patch @@ -1,6 +1,6 @@ ---- killpg.c.orig 2005-01-26 12:24:56.000000000 -0800 -+++ killpg.c 2005-01-26 12:23:37.000000000 -0800 -@@ -41,6 +41,16 @@ +--- killpg.c.orig 2009-11-06 10:36:38.000000000 -0800 ++++ killpg.c 2009-11-06 10:41:47.000000000 -0800 +@@ -37,6 +37,16 @@ __FBSDID("$FreeBSD: src/lib/libc/compat- #include #include @@ -17,7 +17,7 @@ /* * Backwards-compatible killpg(). */ -@@ -48,8 +58,8 @@ +@@ -44,8 +54,8 @@ int killpg(pid_t pgid, int sig) { if (pgid == 1) { diff --git a/compat-43/FreeBSD/sethostid.c b/compat-43/FreeBSD/sethostid.c index a23ec8e..8f36a98 100644 --- a/compat-43/FreeBSD/sethostid.c +++ b/compat-43/FreeBSD/sethostid.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,19 +31,19 @@ static char sccsid[] = "@(#)sethostid.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/sethostid.c,v 1.3 2002/05/28 16:56:57 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/sethostid.c,v 1.5 2007/01/09 00:27:49 imp Exp $"); #include #include -long +#include + +void sethostid(long hostid) { int mib[2]; mib[0] = CTL_KERN; mib[1] = KERN_HOSTID; - if (sysctl(mib, 2, NULL, NULL, &hostid, sizeof hostid) == -1) - return (-1); - return (0); + sysctl(mib, 2, NULL, NULL, &hostid, sizeof hostid); } diff --git a/compat-43/FreeBSD/setpgrp.c b/compat-43/FreeBSD/setpgrp.c index 0c07ce8..011f7bc 100644 --- a/compat-43/FreeBSD/setpgrp.c +++ b/compat-43/FreeBSD/setpgrp.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)setpgrp.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/setpgrp.c,v 1.4 2002/05/28 16:56:57 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/setpgrp.c,v 1.5 2007/01/09 00:27:49 imp Exp $"); #include #include diff --git a/compat-43/FreeBSD/setpgrp.c.patch b/compat-43/FreeBSD/setpgrp.c.patch index c728f03..3b8c176 100644 --- a/compat-43/FreeBSD/setpgrp.c.patch +++ b/compat-43/FreeBSD/setpgrp.c.patch @@ -1,6 +1,6 @@ ---- setpgrp.c.orig 2006-09-17 12:11:20.000000000 -0700 -+++ setpgrp.c 2006-09-24 16:13:25.000000000 -0700 -@@ -40,8 +40,13 @@ +--- setpgrp.c.orig 2009-11-06 10:36:38.000000000 -0800 ++++ setpgrp.c 2009-11-06 10:42:14.000000000 -0800 +@@ -36,8 +36,13 @@ __FBSDID("$FreeBSD: src/lib/libc/compat- #include #include diff --git a/compat-43/FreeBSD/setrgid.c b/compat-43/FreeBSD/setrgid.c index 360e562..94e57ec 100644 --- a/compat-43/FreeBSD/setrgid.c +++ b/compat-43/FreeBSD/setrgid.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)setrgid.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/setrgid.c,v 1.3 2002/05/28 16:56:57 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/setrgid.c,v 1.4 2007/01/09 00:27:49 imp Exp $"); #include diff --git a/compat-43/FreeBSD/setruid.3 b/compat-43/FreeBSD/setruid.3 index ae6900b..f738d3c 100644 --- a/compat-43/FreeBSD/setruid.3 +++ b/compat-43/FreeBSD/setruid.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setruid.3 8.1 (Berkeley) 6/2/93 -.\" $FreeBSD: src/lib/libc/compat-43/setruid.3,v 1.10 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD: src/lib/libc/compat-43/setruid.3,v 1.12 2007/01/09 00:27:49 imp Exp $ .\" .Dd June 2, 1993 .Dt SETRUID 3 @@ -56,6 +52,9 @@ sets the real user ID (group ID) of the current process. .Sh RETURN VALUES .Rv -std +.Sh COMPATIBILITY +The use of these calls is not portable. +Their use is discouraged; they will be removed in the future. .Sh ERRORS The functions fail if: .Bl -tag -width Er @@ -63,9 +62,6 @@ The functions fail if: The user is not the super user and the ID specified is not the real or effective ID. .El -.Sh COMPATIBILITY -The use of these calls is not portable. -Their use is discouraged; they will be removed in the future. .Sh SEE ALSO .Xr getgid 2 , .Xr getuid 2 , diff --git a/compat-43/FreeBSD/setruid.c b/compat-43/FreeBSD/setruid.c index 5fb6d60..1a2a5c8 100644 --- a/compat-43/FreeBSD/setruid.c +++ b/compat-43/FreeBSD/setruid.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)setruid.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/setruid.c,v 1.3 2002/05/28 16:56:57 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/setruid.c,v 1.4 2007/01/09 00:27:49 imp Exp $"); #include diff --git a/compat-43/creat-fbsd.c b/compat-43/creat-fbsd.c index 3293e46..f913d4a 100644 --- a/compat-43/creat-fbsd.c +++ b/compat-43/creat-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)creat.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/creat.c,v 1.7 2002/03/22 21:51:56 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/creat.c,v 1.8 2007/01/09 00:27:49 imp Exp $"); #include "namespace.h" diff --git a/compat-43/gethostid-fbsd.c b/compat-43/gethostid-fbsd.c deleted file mode 120000 index e66bc70..0000000 --- a/compat-43/gethostid-fbsd.c +++ /dev/null @@ -1 +0,0 @@ -./gethostid.c \ No newline at end of file diff --git a/compat-43/gethostid-fbsd.c b/compat-43/gethostid-fbsd.c new file mode 100644 index 0000000..5f77a9b --- /dev/null +++ b/compat-43/gethostid-fbsd.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)gethostid.c 8.1 (Berkeley) 6/2/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/compat-43/gethostid.c,v 1.5 2007/01/09 00:27:49 imp Exp $"); + +#include +#include + +#include + +long +gethostid(void) +{ + int mib[2]; + size_t size; + int value; + + mib[0] = CTL_KERN; + mib[1] = KERN_HOSTID; + size = sizeof value; + if (sysctl(mib, 2, &value, &size, NULL, 0) == -1) + return (-1); + return (value); +} diff --git a/compat-43/gethostid.3 b/compat-43/gethostid.3 index b0d07c3..e938320 100644 --- a/compat-43/gethostid.3 +++ b/compat-43/gethostid.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)gethostid.3 8.1 (Berkeley) 6/2/93 -.\" $FreeBSD: src/lib/libc/compat-43/gethostid.3,v 1.12 2004/07/02 23:52:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/compat-43/gethostid.3,v 1.14 2007/01/09 00:27:49 imp Exp $ .\" .Dd June 2, 1993 .Dt GETHOSTID 3 @@ -69,8 +65,6 @@ The hostid should be set or retrieved by use of .Xr gethostname 3 , .Xr sysctl 3 , .Xr sysctl 8 -.Sh BUGS -32 bits for the identifier is too small. .Sh HISTORY The .Fn gethostid @@ -80,3 +74,5 @@ syscalls appeared in .Bx 4.2 and were dropped in .Bx 4.4 . +.Sh BUGS +32 bits for the identifier is too small. diff --git a/compat-43/killpg-fbsd.c b/compat-43/killpg-fbsd.c index b57bec0..d66425b 100644 --- a/compat-43/killpg-fbsd.c +++ b/compat-43/killpg-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)killpg.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/killpg.c,v 1.4 2002/05/28 16:56:57 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/killpg.c,v 1.5 2007/01/09 00:27:49 imp Exp $"); #include #include diff --git a/compat-43/killpg.2 b/compat-43/killpg.2 index 5671153..2518ab9 100644 --- a/compat-43/killpg.2 +++ b/compat-43/killpg.2 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)killpg.2 8.1 (Berkeley) 6/2/93 -.\" $FreeBSD: src/lib/libc/compat-43/killpg.2,v 1.12 2002/12/19 09:40:21 ru Exp $ +.\" $FreeBSD: src/lib/libc/compat-43/killpg.2,v 1.14 2007/01/09 00:27:49 imp Exp $ .\" -.Dd June 2, 1993 +.Dd October 10, 2006 .Dt KILLPG 2 .Os .Sh NAME @@ -65,7 +61,7 @@ The sending process and members of the process group must have the same effective user ID, or the sender must be the super-user. As a single special case the continue signal SIGCONT may be sent -to any process that is a descendant of the current process. +to any process with the same session ID as the caller. .Sh RETURN VALUES .Rv -std killpg .Sh ERRORS diff --git a/compat-43/setpgrp-fbsd.c b/compat-43/setpgrp-fbsd.c index bc18609..ebed79a 100644 --- a/compat-43/setpgrp-fbsd.c +++ b/compat-43/setpgrp-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)setpgrp.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/compat-43/setpgrp.c,v 1.4 2002/05/28 16:56:57 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/compat-43/setpgrp.c,v 1.5 2007/01/09 00:27:49 imp Exp $"); #include #include diff --git a/darwin/Makefile.inc b/darwin/Makefile.inc index a72b3be..b83c1fe 100644 --- a/darwin/Makefile.inc +++ b/darwin/Makefile.inc @@ -10,7 +10,8 @@ INSTHDRS += ${.CURDIR}/darwin/libproc.h LOCALHDRS += ${.CURDIR}/darwin/dirhelper.defs \ ${.CURDIR}/darwin/dirhelper_priv.h \ - ${.CURDIR}/darwin/libproc.h + ${.CURDIR}/darwin/libproc.h \ + ${.CURDIR}/darwin/libproc_internal.h MISRCS += ${DARWINMIGSRCS} _dirhelper.c libproc.c proc_listpidspath.c .ifndef LP64 diff --git a/darwin/_dirhelper.c b/darwin/_dirhelper.c index 0a07a5a..bfd9959 100644 --- a/darwin/_dirhelper.c +++ b/darwin/_dirhelper.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (c) 2006, 2007, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include "dirhelper.h" #include "dirhelper_priv.h" @@ -47,14 +49,16 @@ #define MUTEX_LOCK(x) if(__is_threaded) pthread_mutex_lock(x) #define MUTEX_UNLOCK(x) if(__is_threaded) pthread_mutex_unlock(x) -#define ENCODEBITS 6 +// Use 5 bits per character, to avoid uppercase and shell magic characters +#define ENCODEBITS 5 #define ENCODEDSIZE ((8 * UUID_UID_SIZE + ENCODEBITS - 1) / ENCODEBITS) +#define MASK(x) ((1 << (x)) - 1) #define UUID_UID_SIZE (sizeof(uuid_t) + sizeof(uid_t)) extern int __is_threaded; static const mode_t modes[] = { - 0, /* unused */ + 0755, /* user */ 0700, /* temp */ 0700, /* cache */ }; @@ -65,39 +69,60 @@ static const char *subdirs[] = { DIRHELPER_CACHE_STR, }; -static const char encode[] = "+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +static pthread_once_t userdir_control = PTHREAD_ONCE_INIT; +static char *userdir = NULL; + +// lower case letter (minus vowels), plus numbers and _, making +// 32 characters. +static const char encode[] = "0123456789_bcdfghjklmnpqrstvwxyz"; static void -encode_uuid_uid(uuid_t uuid, uid_t uid, char *str) +encode_uuid_uid(const uuid_t uuid, uid_t uid, char *str) { unsigned char buf[UUID_UID_SIZE + 1]; unsigned char *bp = buf; - int i = 0; + int i; unsigned int n; memcpy(bp, uuid, sizeof(uuid_t)); uid = OSSwapHostToBigInt32(uid); memcpy(bp + sizeof(uuid_t), &uid, sizeof(uid_t)); bp[UUID_UID_SIZE] = 0; // this ensures the last encoded byte will have trailing zeros - while(i < ENCODEDSIZE) { - switch(i % 4) { + for(i = 0; i < ENCODEDSIZE; i++) { + // 5 bits has 8 states + switch(i % 8) { case 0: n = *bp++; - *str++ = encode[n >> 2]; + *str++ = encode[n >> 3]; break; case 1: - n = ((n & 0x3) << 8) | *bp++; - *str++ = encode[n >> 4]; + n = ((n & MASK(3)) << 8) | *bp++; + *str++ = encode[n >> 6]; break; case 2: - n = ((n & 0xf) << 8) | *bp++; - *str++ = encode[n >> 6]; + n &= MASK(6); + *str++ = encode[n >> 1]; break; case 3: - *str++ = encode[n & 0x3f]; + n = ((n & MASK(1)) << 8) | *bp++; + *str++ = encode[n >> 4]; + break; + case 4: + n = ((n & MASK(4)) << 8) | *bp++; + *str++ = encode[n >> 7]; + break; + case 5: + n &= MASK(7); + *str++ = encode[n >> 2]; + break; + case 6: + n = ((n & MASK(2)) << 8) | *bp++; + *str++ = encode[n >> 5]; + break; + case 7: + *str++ = encode[n & MASK(5)]; break; } - i++; } *str = 0; } @@ -119,13 +144,23 @@ __user_local_dirname(uid_t uid, dirhelper_which_t which, char *path, size_t path } #if TARGET_OS_EMBEDDED - tmpdir = getenv("TMPDIR"); - if(!tmpdir) { + /* We only support DIRHELPER_USER_LOCAL_TEMP on embedded. + * This interface really doesn't map from OSX to embedded, + * and clients of this interface will need to adapt when + * porting their applications to embedded. + * See: + */ + if(which == DIRHELPER_USER_LOCAL_TEMP) { + tmpdir = getenv("TMPDIR"); + if(!tmpdir) { + errno = EINVAL; + return NULL; + } + res = snprintf(path, pathlen, "%s", tmpdir); + } else { errno = EINVAL; return NULL; } - - res = snprintf(path, pathlen, "%s/%s", tmpdir, subdirs[which]); #else res = mbr_uid_to_uuid(uid, uuid); if(res != 0) { @@ -135,14 +170,14 @@ __user_local_dirname(uid_t uid, dirhelper_which_t which, char *path, size_t path // // We partition the namespace so that we don't end up with too - // many users in a single directory. With 4096 buckets, we + // many users in a single directory. With 1024 buckets, we // could scale to 1,000,000 users while keeping the average - // number of files in a single directory below 250 + // number of files in a single directory around 1000 // encode_uuid_uid(uuid, uid, str); res = snprintf(path, pathlen, "%s%.*s/%s/%s", - VAR_FOLDERS_PATH, BUCKETLEN, str, str, subdirs[which]); + VAR_FOLDERS_PATH, BUCKETLEN, str, str + BUCKETLEN, subdirs[which]); #endif if(res >= pathlen) { errno = EINVAL; @@ -168,12 +203,26 @@ __user_local_mkdir_p(char *path) return path; } +static void userdir_allocate(void) +{ + userdir = calloc(PATH_MAX, sizeof(char)); +} + +/* + * 9407258: Invalidate the dirhelper cache (userdir) of the child after fork. + * There is a rare case when launchd will have userdir set, and child process + * will sometimes inherit this cached value. + */ +__private_extern__ void +_dirhelper_fork_child(void) +{ + if(userdir) *userdir = 0; +} + __private_extern__ char * _dirhelper(dirhelper_which_t which, char *path, size_t pathlen) { - static char userdir[PATH_MAX]; static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; - int res; struct stat sb; if(which < 0 || which > DIRHELPER_USER_LOCAL_LAST) { @@ -181,14 +230,26 @@ _dirhelper(dirhelper_which_t which, char *path, size_t pathlen) return NULL; } + if (pthread_once(&userdir_control, userdir_allocate) + || !userdir) { + errno = ENOMEM; + return NULL; + } + if(!*userdir) { MUTEX_LOCK(&lock); if (!*userdir) { - if(__user_local_dirname(geteuid(), DIRHELPER_USER_LOCAL, userdir, sizeof(userdir)) == NULL) { + if(__user_local_dirname(geteuid(), DIRHELPER_USER_LOCAL, userdir, PATH_MAX) == NULL) { MUTEX_UNLOCK(&lock); return NULL; } + /* + * All dirhelper directories are now at the same level, so + * we need to remove the DIRHELPER_TOP_STR suffix to get the + * parent directory. + */ + userdir[strlen(userdir) - (sizeof(DIRHELPER_TOP_STR) - 1)] = 0; /* * check if userdir exists, and if not, either do the work * ourself if we are root, or call @@ -244,13 +305,55 @@ _dirhelper(dirhelper_which_t which, char *path, size_t pathlen) /* * now for subdirectories, create it with the appropriate permissions - * if it doesn't already exist. + * if it doesn't already exist. On OS X, if we're under App Sandbox, we + * rely on xpchelper having created the subdir for us. */ - if(which != DIRHELPER_USER_LOCAL) { - res = mkdir(path, modes[which]); - if(res != 0 && errno != EEXIST) - return NULL; +#if !TARGET_OS_EMBEDDED + if (!_xpc_runtime_is_app_sandboxed()) +#endif + if(mkdir(path, modes[which]) != 0 && errno != EEXIST) + return NULL; + +#if !TARGET_OS_EMBEDDED + if (_xpc_runtime_is_app_sandboxed()) { + /* + * if xpchelper didn't make the subdir for us, bail since we don't have + * permission to create it ourselves. + */ + if(stat(path, &sb) < 0) { + errno = EPERM; + return NULL; + } + + /* + * sandboxed applications get per-application directories named + * after the container + */ + char *container_id = getenv(XPC_ENV_SANDBOX_CONTAINER_ID); + if(!container_id) { + errno = EINVAL; + return NULL; + } + + /* + * container ID doesn't end in a slash, so +2 is for slash and \0 + */ + if (pathlen < strlen(path) + strlen(container_id) + 2) { + errno = EINVAL; + return NULL; /* buffer too small */ + } + + strcat(path, container_id); + strcat(path, "/"); + + /* + * create per-app subdirectory with the appropriate permissions + * if it doesn't already exist. + */ + if(mkdir(path, modes[which]) != 0 && errno != EEXIST) + return NULL; } +#endif return path; } diff --git a/darwin/dirhelper_priv.h b/darwin/dirhelper_priv.h index 5b2e52f..cf2ae3c 100644 --- a/darwin/dirhelper_priv.h +++ b/darwin/dirhelper_priv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (c) 2006, 2007, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -30,9 +30,9 @@ #define VAR_FOLDERS_PATH "/var/folders/" #define DIRHELPER_BOOTSTRAP_NAME "com.apple.bsd.dirhelper" -#define DIRHELPER_CACHE_STR "-Caches-/" -#define DIRHELPER_TEMP_STR "-Tmp-/" -#define DIRHELPER_TOP_STR "" +#define DIRHELPER_CACHE_STR "C/" +#define DIRHELPER_TEMP_STR "T/" +#define DIRHELPER_TOP_STR "0/" typedef enum { DIRHELPER_USER_LOCAL = 0, diff --git a/darwin/libproc.c b/darwin/libproc.c index 6858f2f..0b6eb47 100644 --- a/darwin/libproc.c +++ b/darwin/libproc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2006, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -28,10 +28,14 @@ #include #include #include +#define CONFIG_EMBEDDED 1 +#include -#include "libproc.h" +#include "libproc_internal.h" int __proc_info(int callnum, int pid, int flavor, uint64_t arg, void * buffer, int buffersize); +__private_extern__ int proc_setthreadname(void * buffer, int buffersize); +int __process_policy(int scope, int action, int policy, int policy_subtype, proc_policy_attribute_t * attrp, pid_t target_pid, uint64_t target_threadid); @@ -40,7 +44,7 @@ proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize) { int retval; - if ((type == PROC_ALL_PIDS) || (type == PROC_PGRP_ONLY) || (type == PROC_TTY_ONLY) || (type == PROC_UID_ONLY) || (type == PROC_RUID_ONLY)) { + if ((type >= PROC_ALL_PIDS) || (type <= PROC_PPID_ONLY)) { if ((retval = __proc_info(1, type, typeinfo,(uint64_t)0, buffer, buffersize)) == -1) return(0); } else { @@ -51,6 +55,41 @@ proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize) } +int +proc_listallpids(void * buffer, int buffersize) +{ + int numpids; + numpids = proc_listpids(PROC_ALL_PIDS, (uint32_t)0, buffer, buffersize); + + if (numpids == -1) + return(-1); + else + return(numpids/sizeof(int)); +} + +int +proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize) +{ + int numpids; + numpids = proc_listpids(PROC_PGRP_ONLY, (uint32_t)pgrpid, buffer, buffersize); + if (numpids == -1) + return(-1); + else + return(numpids/sizeof(int)); +} + +int +proc_listchildpids(pid_t ppid, void * buffer, int buffersize) +{ + int numpids; + numpids = proc_listpids(PROC_PPID_ONLY, (uint32_t)ppid, buffer, buffersize); + if (numpids == -1) + return(-1); + else + return(numpids/sizeof(int)); +} + + int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize) { @@ -75,6 +114,16 @@ proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize) } +int +proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize) +{ + int retval; + + if ((retval = __proc_info(6, pid, flavor, (uint64_t)fileport, buffer, buffersize)) == -1) + return (0); + return (retval); +} + int proc_name(int pid, void * buffer, uint32_t buffersize) @@ -179,10 +228,223 @@ proc_setpcontrol(const int control) if (control < PROC_SETPC_NONE || control > PROC_SETPC_TERMINATE) return(EINVAL); - if ((retval = __proc_info(5, getpid(), PROC_SELFSET_PCONTROL,(uint64_t)control, NULL, 0)) == -1) + if ((retval = __proc_info(5, getpid(), PROC_SELFSET_PCONTROL, (uint64_t)control, NULL, 0)) == -1) return(errno); return(0); } +__private_extern__ int +proc_setthreadname(void * buffer, int buffersize) +{ + int retval; + + retval = __proc_info(5, getpid(), PROC_SELFSET_THREADNAME, (uint64_t)0, buffer, buffersize); + + if (retval == -1) + return(errno); + else + return(0); +} + +#if TARGET_OS_EMBEDDED + +int +proc_setcpu_percentage(pid_t pid, int action, int percentage) +{ + proc_policy_cpuusage_attr_t attr; + + bzero(&attr, sizeof(proc_policy_cpuusage_attr_t)); + attr.ppattr_cpu_attr = action; + attr.ppattr_cpu_percentage = percentage; + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, &attr, pid, (uint64_t)0) != -1) + return(0); + else + return(errno); +} + +int +proc_setcpu_deadline(pid_t pid, int action, uint64_t deadline) +{ + proc_policy_cpuusage_attr_t attr; + + bzero(&attr, sizeof(proc_policy_cpuusage_attr_t)); + attr.ppattr_cpu_attr = action; + attr.ppattr_cpu_attr_deadline = deadline; + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, &attr, pid, (uint64_t)0) != -1) + return(0); + else + return(errno); + +} + + +int +proc_setcpu_percentage_withdeadline(pid_t pid, int action, int percentage, uint64_t deadline) +{ + proc_policy_cpuusage_attr_t attr; + + bzero(&attr, sizeof(proc_policy_cpuusage_attr_t)); + attr.ppattr_cpu_attr = action; + attr.ppattr_cpu_percentage = percentage; + attr.ppattr_cpu_attr_deadline = deadline; + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, &attr, pid, (uint64_t)0) != -1) + return(0); + else + return(errno); +} + +int +proc_clear_cpulimits(pid_t pid) +{ + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_RESTORE, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, NULL, pid, (uint64_t)0) != -1) + return(0); + else + return(errno); + + +} + +int +proc_appstate(int pid, int * appstatep) +{ + int state; + + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_GET, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_STATE, (int *)&state, pid, (uint64_t)0) != -1) { + if (appstatep != NULL) + *appstatep = state; + return(0); + } else + return(errno); + +} + + +int +proc_setappstate(int pid, int appstate) +{ + int state = appstate; + + switch (state) { + case PROC_APPSTATE_NONE: + case PROC_APPSTATE_ACTIVE: + case PROC_APPSTATE_INACTIVE: + case PROC_APPSTATE_BACKGROUND: + case PROC_APPSTATE_NONUI: + break; + default: + return(EINVAL); + } + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_STATE, (int *)&state, pid, (uint64_t)0) != -1) + return(0); + else + return(errno); +} + +int +proc_devstatusnotify(int devicestatus) +{ + int state = devicestatus; + + switch (devicestatus) { + case PROC_DEVSTATUS_SHORTTERM: + case PROC_DEVSTATUS_LONGTERM: + break; + default: + return(EINVAL); + } + + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_DEVSTATUS, (int *)&state, getpid(), (uint64_t)0) != -1) { + return(0); + } else + return(errno); + +} + +int +proc_pidbind(int pid, uint64_t threadid, int bind) +{ + int state = bind; + pid_t passpid = pid; + + switch (bind) { + case PROC_PIDBIND_CLEAR: + passpid = getpid(); /* ignore pid on clear */ + break; + case PROC_PIDBIND_SET: + break; + default: + return(EINVAL); + } + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_PIDBIND, (int *)&state, passpid, threadid) != -1) + return(0); + else + return(errno); +} + +#else /* TARGET_OS_EMBEDDED */ + +int +proc_clear_vmpressure(pid_t pid) +{ + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_RESTORE, PROC_POLICY_RESOURCE_STARVATION, PROC_POLICY_RS_VIRTUALMEM, NULL, pid, (uint64_t)0) != -1) + return(0); + else + return(errno); +} + +/* set the current process as one who can resume suspended processes due to low virtual memory. Need to be root */ +int +proc_set_owner_vmpressure(void) +{ + int retval; + + if ((retval = __proc_info(5, getpid(), PROC_SELFSET_VMRSRCOWNER, (uint64_t)0, NULL, 0)) == -1) + return(errno); + + return(0); +} + +/* disable the launch time backgroudn policy and restore the process to default group */ +int +proc_disable_apptype(pid_t pid, int apptype) +{ + switch (apptype) { + case PROC_POLICY_OSX_APPTYPE_TAL: + case PROC_POLICY_OSX_APPTYPE_DASHCLIENT: + break; + default: + return(EINVAL); + + } + + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_DISABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1) + return(0); + else + return(errno); + +} + +/* re-enable the launch time background policy if it had been disabled. */ +int +proc_enable_apptype(pid_t pid, int apptype) +{ + switch (apptype) { + case PROC_POLICY_OSX_APPTYPE_TAL: + case PROC_POLICY_OSX_APPTYPE_DASHCLIENT: + break; + default: + return(EINVAL); + + } + + if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_ENABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1) + return(0); + else + return(errno); + +} + +#endif /* TARGET_OS_EMBEDDED */ + diff --git a/darwin/libproc.h b/darwin/libproc.h index 40e6477..7692f85 100644 --- a/darwin/libproc.h +++ b/darwin/libproc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (c) 2006, 2007, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -32,6 +32,8 @@ #include +#include + /* * This header file contains private interfaces to obtain process information. * These interfaces are subject to change in future releases. @@ -56,7 +58,6 @@ __BEGIN_DECLS -int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize); /*! @function proc_listpidspath @@ -82,15 +83,20 @@ int proc_listpidspath(uint32_t type, const char *path, uint32_t pathflags, void *buffer, - int buffersize); + int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize); -int proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize); -int proc_name(int pid, void * buffer, uint32_t buffersize); -int proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize); -int proc_kmsgbuf(void * buffer, uint32_t buffersize); -int proc_pidpath(int pid, void * buffer, uint32_t buffersize); -int proc_libversion(int *major, int * minor); +int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_listallpids(void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); +int proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); +int proc_listchildpids(pid_t ppid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); +int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +int proc_name(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_kmsgbuf(void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_pidpath(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_libversion(int *major, int * minor) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); /* * A process can use the following api to set its own process control * state on resoure starvation. The argument can have one of the PROC_SETPC_XX values @@ -100,7 +106,9 @@ int proc_libversion(int *major, int * minor); #define PROC_SETPC_SUSPEND 2 #define PROC_SETPC_TERMINATE 3 +int proc_setpcontrol(const int control) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); int proc_setpcontrol(const int control); + __END_DECLS #endif /*_LIBPROC_H_ */ diff --git a/darwin/libproc_internal.h b/darwin/libproc_internal.h new file mode 100644 index 0000000..20feee7 --- /dev/null +++ b/darwin/libproc_internal.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#ifndef _LIBPROC_INTERNALH_ +#define _LIBPROC_INTERNALH_ + +#include + +#include +#include +#include + +__BEGIN_DECLS + +#if TARGET_OS_EMBEDDED + +#define PROC_SETCPU_ACTION_NONE 0 +#define PROC_SETCPU_ACTION_THROTTLE 1 +#define PROC_SETCPU_ACTION_SUSPEND 2 +#define PROC_SETCPU_ACTION_TERMINATE 3 +#define PROC_SETCPU_ACTION_NOTIFY 4 + +int proc_setcpu_percentage(pid_t pid, int action, int percentage) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0); +int proc_setcpu_deadline(pid_t pid, int action, uint64_t deadline) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0); +int proc_setcpu_percentage_withdeadline(pid_t pid, int action, int percentage, uint64_t deadline) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0); +int proc_clear_cpulimits(pid_t pid) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0); + +#define PROC_APPSTATE_NONE 0 +#define PROC_APPSTATE_ACTIVE 1 +#define PROC_APPSTATE_BACKGROUND 2 +#define PROC_APPSTATE_NONUI 3 +#define PROC_APPSTATE_INACTIVE 4 + +int proc_setappstate(int pid, int appstate); +int proc_appstate(int pid, int * appstatep); + +#define PROC_DEVSTATUS_SHORTTERM 1 +#define PROC_DEVSTATUS_LONGTERM 2 + +int proc_devstatusnotify(int devicestatus); + +#define PROC_PIDBIND_CLEAR 0 +#define PROC_PIDBIND_SET 1 +int proc_pidbind(int pid, uint64_t threadid, int bind); + + +#else /* TARGET_OS_EMBEDDED */ + +/* resume the process suspend due to low VM resource */ +int proc_clear_vmpressure(pid_t pid); +/* set self as the one who is going to resume suspended processes due to low VM. Need to be root */ +int proc_set_owner_vmpressure(void); + +/* + * Resumes the backgrounded TAL or dashboard client. Only priv users can disable TAL apps. + * Valid apptype are PROC_POLICY_OSX_APPTYPE_DASHCLIENT and PROC_POLICY_OSX_APPTYPE_TAL. + * Returns 0 on success otherwise appropriate error code. + */ +int proc_disable_apptype(pid_t pid, int apptype); +int proc_enable_apptype(pid_t pid, int apptype); + +#endif /* TARGET_OS_EMBEDDED */ + +__END_DECLS + +#endif /* _LIBPROC_INTERNALH_ */ + diff --git a/db/btree/FreeBSD/bt_close.c b/db/btree/FreeBSD/bt_close.c index c211d5b..89359b5 100644 --- a/db/btree/FreeBSD/bt_close.c +++ b/db/btree/FreeBSD/bt_close.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_close.c 8.7 (Berkeley) 8/17/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_close.c,v 1.8 2002/03/22 21:52:00 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_close.c,v 1.10 2009/03/02 23:47:18 delphij Exp $"); #include "namespace.h" #include @@ -65,8 +61,7 @@ static int bt_meta(BTREE *); * RET_ERROR, RET_SUCCESS */ int -__bt_close(dbp) - DB *dbp; +__bt_close(DB *dbp) { BTREE *t; int fd; @@ -120,9 +115,7 @@ __bt_close(dbp) * RET_SUCCESS, RET_ERROR. */ int -__bt_sync(dbp, flags) - const DB *dbp; - u_int flags; +__bt_sync(const DB *dbp, u_int flags) { BTREE *t; int status; @@ -163,8 +156,7 @@ __bt_sync(dbp, flags) * RET_ERROR, RET_SUCCESS */ static int -bt_meta(t) - BTREE *t; +bt_meta(BTREE *t) { BTMETA m; void *p; diff --git a/db/btree/FreeBSD/bt_conv.c b/db/btree/FreeBSD/bt_conv.c index 7496a3c..3774ed4 100644 --- a/db/btree/FreeBSD/bt_conv.c +++ b/db/btree/FreeBSD/bt_conv.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_conv.c 8.5 (Berkeley) 8/17/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_conv.c,v 1.2 2002/03/21 22:46:25 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_conv.c,v 1.4 2009/03/02 23:47:18 delphij Exp $"); #include @@ -60,10 +56,7 @@ static void mswap(PAGE *); * h: page to convert */ void -__bt_pgin(t, pg, pp) - void *t; - pgno_t pg; - void *pp; +__bt_pgin(void *t, pgno_t pg, void *pp) { PAGE *h; indx_t i, top; @@ -128,10 +121,7 @@ __bt_pgin(t, pg, pp) } void -__bt_pgout(t, pg, pp) - void *t; - pgno_t pg; - void *pp; +__bt_pgout(void *t, pgno_t pg, void *pp) { PAGE *h; indx_t i, top; @@ -202,8 +192,7 @@ __bt_pgout(t, pg, pp) * p: page to convert */ static void -mswap(pg) - PAGE *pg; +mswap(PAGE *pg) { char *p; diff --git a/db/btree/FreeBSD/bt_debug.c b/db/btree/FreeBSD/bt_debug.c index bd95774..fa0481b 100644 --- a/db/btree/FreeBSD/bt_debug.c +++ b/db/btree/FreeBSD/bt_debug.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_debug.c,v 1.3 2004/09/10 05:41:41 kuriyama Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_debug.c,v 1.6 2009/03/23 23:22:09 delphij Exp $"); #include @@ -57,8 +53,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_debug.c,v 1.3 2004/09/10 05:41:41 k * dbp: pointer to the DB */ void -__bt_dump(dbp) - DB *dbp; +__bt_dump(DB *dbp) { BTREE *t; PAGE *h; @@ -66,7 +61,7 @@ __bt_dump(dbp) char *sep; t = dbp->internal; - (void)fprintf(stderr, "%s: pgsz %d", + (void)fprintf(stderr, "%s: pgsz %u", F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize); if (F_ISSET(t, R_RECNO)) (void)fprintf(stderr, " keys %u", t->bt_nrecs); @@ -101,8 +96,7 @@ __bt_dump(dbp) * h: pointer to the PAGE */ void -__bt_dmpage(h) - PAGE *h; +__bt_dmpage(PAGE *h) { BTMETA *m; char *sep; @@ -135,9 +129,7 @@ __bt_dmpage(h) * n: page number to dump. */ void -__bt_dnpage(dbp, pgno) - DB *dbp; - pgno_t pgno; +__bt_dnpage(DB *dbp, pgno_t pgno) { BTREE *t; PAGE *h; @@ -156,8 +148,7 @@ __bt_dnpage(dbp, pgno) * h: pointer to the PAGE */ void -__bt_dpage(h) - PAGE *h; +__bt_dpage(PAGE *h) { BINTERNAL *bi; BLEAF *bl; @@ -166,7 +157,7 @@ __bt_dpage(h) indx_t cur, top; char *sep; - (void)fprintf(stderr, " page %d: (", h->pgno); + (void)fprintf(stderr, " page %u: (", h->pgno); #undef X #define X(flag, name) \ if (h->flags & flag) { \ @@ -183,7 +174,7 @@ __bt_dpage(h) (void)fprintf(stderr, ")\n"); #undef X - (void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg); + (void)fprintf(stderr, "\tprev %2u next %2u", h->prevpg, h->nextpg); if (h->flags & P_OVERFLOW) return; @@ -253,8 +244,7 @@ __bt_dpage(h) * dbp: pointer to the DB */ void -__bt_stat(dbp) - DB *dbp; +__bt_stat(DB *dbp) { extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit; extern u_long bt_sortsplit, bt_split; @@ -302,27 +292,27 @@ __bt_stat(dbp) (void)mpool_put(t->bt_mp, h, 0); } - (void)fprintf(stderr, "%d level%s with %ld keys", + (void)fprintf(stderr, "%d level%s with %lu keys", levels, levels == 1 ? "" : "s", nkeys); if (F_ISSET(t, R_RECNO)) - (void)fprintf(stderr, " (%d header count)", t->bt_nrecs); + (void)fprintf(stderr, " (%u header count)", t->bt_nrecs); (void)fprintf(stderr, - "\n%u pages (leaf %d, internal %d, overflow %d)\n", + "\n%u pages (leaf %u, internal %u, overflow %u)\n", pinternal + pleaf + pcont, pleaf, pinternal, pcont); - (void)fprintf(stderr, "%ld cache hits, %ld cache misses\n", + (void)fprintf(stderr, "%lu cache hits, %lu cache misses\n", bt_cache_hit, bt_cache_miss); (void)fprintf(stderr, "%lu splits (%lu root splits, %lu sort splits)\n", bt_split, bt_rootsplit, bt_sortsplit); pleaf *= t->bt_psize - BTDATAOFF; if (pleaf) (void)fprintf(stderr, - "%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n", + "%.0f%% leaf fill (%lu bytes used, %lu bytes free)\n", ((double)(pleaf - lfree) / pleaf) * 100, pleaf - lfree, lfree); pinternal *= t->bt_psize - BTDATAOFF; if (pinternal) (void)fprintf(stderr, - "%.0f%% internal fill (%ld bytes used, %ld bytes free\n", + "%.0f%% internal fill (%lu bytes used, %lu bytes free\n", ((double)(pinternal - ifree) / pinternal) * 100, pinternal - ifree, ifree); if (bt_pfxsaved) diff --git a/db/btree/FreeBSD/bt_delete.c b/db/btree/FreeBSD/bt_delete.c index 6204464..1289b72 100644 --- a/db/btree/FreeBSD/bt_delete.c +++ b/db/btree/FreeBSD/bt_delete.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_delete.c 8.13 (Berkeley) 7/28/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_delete.c,v 1.2 2002/03/21 22:46:25 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_delete.c,v 1.6 2009/03/04 00:58:04 delphij Exp $"); #include @@ -62,10 +58,7 @@ static int __bt_stkacq(BTREE *, PAGE **, CURSOR *); * Return RET_SPECIAL if the key is not found. */ int -__bt_delete(dbp, key, flags) - const DB *dbp; - const DBT *key; - u_int flags; +__bt_delete(const DB *dbp, const DBT *key, u_int flags) { BTREE *t; CURSOR *c; @@ -143,20 +136,17 @@ __bt_delete(dbp, key, flags) * 0 on success, 1 on failure */ static int -__bt_stkacq(t, hp, c) - BTREE *t; - PAGE **hp; - CURSOR *c; +__bt_stkacq(BTREE *t, PAGE **hp, CURSOR *c) { BINTERNAL *bi; EPG *e; EPGNO *parent; PAGE *h; - indx_t index; + indx_t idx; pgno_t pgno; recno_t nextpg, prevpg; int exact, level; - + /* * Find the first occurrence of the key in the tree. Toss the * currently locked page so we don't hit an already-locked page. @@ -190,8 +180,8 @@ __bt_stkacq(t, hp, c) /* Move to the next index. */ if (parent->index != NEXTINDEX(h) - 1) { - index = parent->index + 1; - BT_PUSH(t, h->pgno, index); + idx = parent->index + 1; + BT_PUSH(t, h->pgno, idx); break; } mpool_put(t->bt_mp, h, 0); @@ -200,7 +190,7 @@ __bt_stkacq(t, hp, c) /* Restore the stack. */ while (level--) { /* Push the next level down onto the stack. */ - bi = GETBINTERNAL(h, index); + bi = GETBINTERNAL(h, idx); pgno = bi->pgno; BT_PUSH(t, pgno, 0); @@ -210,7 +200,7 @@ __bt_stkacq(t, hp, c) /* Get the next level down. */ if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL) return (1); - index = 0; + idx = 0; } mpool_put(t->bt_mp, h, 0); if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL) @@ -245,8 +235,8 @@ __bt_stkacq(t, hp, c) /* Move to the next index. */ if (parent->index != 0) { - index = parent->index - 1; - BT_PUSH(t, h->pgno, index); + idx = parent->index - 1; + BT_PUSH(t, h->pgno, idx); break; } mpool_put(t->bt_mp, h, 0); @@ -255,7 +245,7 @@ __bt_stkacq(t, hp, c) /* Restore the stack. */ while (level--) { /* Push the next level down onto the stack. */ - bi = GETBINTERNAL(h, index); + bi = GETBINTERNAL(h, idx); pgno = bi->pgno; /* Lose the currently pinned page. */ @@ -265,14 +255,14 @@ __bt_stkacq(t, hp, c) if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL) return (1); - index = NEXTINDEX(h) - 1; - BT_PUSH(t, pgno, index); + idx = NEXTINDEX(h) - 1; + BT_PUSH(t, pgno, idx); } mpool_put(t->bt_mp, h, 0); if ((h = mpool_get(t->bt_mp, prevpg, 0)) == NULL) return (1); } - + ret: mpool_put(t->bt_mp, h, 0); return ((*hp = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL); @@ -290,9 +280,7 @@ ret: mpool_put(t->bt_mp, h, 0); * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. */ static int -__bt_bdelete(t, key) - BTREE *t; - const DBT *key; +__bt_bdelete(BTREE *t, const DBT *key) { EPG *e; PAGE *h; @@ -377,14 +365,12 @@ loop: if ((e = __bt_search(t, key, &exact)) == NULL) * mpool_put's the page */ static int -__bt_pdelete(t, h) - BTREE *t; - PAGE *h; +__bt_pdelete(BTREE *t, PAGE *h) { BINTERNAL *bi; PAGE *pg; EPGNO *parent; - indx_t cnt, index, *ip, offset; + indx_t cnt, idx, *ip, offset; u_int32_t nksize; char *from; @@ -404,9 +390,9 @@ __bt_pdelete(t, h) /* Get the parent page. */ if ((pg = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) return (RET_ERROR); - - index = parent->index; - bi = GETBINTERNAL(pg, index); + + idx = parent->index; + bi = GETBINTERNAL(pg, idx); /* Free any overflow pages. */ if (bi->flags & P_BIGKEY && @@ -420,7 +406,7 @@ __bt_pdelete(t, h) * root page. If it's the rootpage, turn it back into an empty * leaf page. */ - if (NEXTINDEX(pg) == 1) + if (NEXTINDEX(pg) == 1) { if (pg->pgno == P_ROOT) { pg->lower = BTDATAOFF; pg->upper = t->bt_psize; @@ -430,7 +416,7 @@ __bt_pdelete(t, h) return (RET_ERROR); continue; } - else { + } else { /* Pack remaining key items at the end of the page. */ nksize = NBINTERNAL(bi->ksize); from = (char *)pg + pg->upper; @@ -438,11 +424,11 @@ __bt_pdelete(t, h) pg->upper += nksize; /* Adjust indices' offsets, shift the indices down. */ - offset = pg->linp[index]; - for (cnt = index, ip = &pg->linp[0]; cnt--; ++ip) + offset = pg->linp[idx]; + for (cnt = idx, ip = &pg->linp[0]; cnt--; ++ip) if (ip[0] < offset) ip[0] += nksize; - for (cnt = NEXTINDEX(pg) - index; --cnt; ++ip) + for (cnt = NEXTINDEX(pg) - idx; --cnt; ++ip) ip[0] = ip[1] < offset ? ip[1] + nksize : ip[1]; pg->lower -= sizeof(indx_t); } @@ -467,17 +453,13 @@ __bt_pdelete(t, h) * t: tree * key: referenced key * h: page - * index: index on page to delete + * idx: index on page to delete * * Returns: * RET_SUCCESS, RET_ERROR. */ int -__bt_dleaf(t, key, h, index) - BTREE *t; - const DBT *key; - PAGE *h; - u_int index; +__bt_dleaf(BTREE *t, const DBT *key, PAGE *h, u_int idx) { BLEAF *bl; indx_t cnt, *ip, offset; @@ -488,12 +470,12 @@ __bt_dleaf(t, key, h, index) /* If this record is referenced by the cursor, delete the cursor. */ if (F_ISSET(&t->bt_cursor, CURS_INIT) && !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) && - t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index == index && - __bt_curdel(t, key, h, index)) + t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index == idx && + __bt_curdel(t, key, h, idx)) return (RET_ERROR); /* If the entry uses overflow pages, make them available for reuse. */ - to = bl = GETBLEAF(h, index); + to = bl = GETBLEAF(h, idx); if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR) return (RET_ERROR); if (bl->flags & P_BIGDATA && @@ -507,18 +489,18 @@ __bt_dleaf(t, key, h, index) h->upper += nbytes; /* Adjust the indices' offsets, shift the indices down. */ - offset = h->linp[index]; - for (cnt = index, ip = &h->linp[0]; cnt--; ++ip) + offset = h->linp[idx]; + for (cnt = idx, ip = &h->linp[0]; cnt--; ++ip) if (ip[0] < offset) ip[0] += nbytes; - for (cnt = NEXTINDEX(h) - index; --cnt; ++ip) + for (cnt = NEXTINDEX(h) - idx; --cnt; ++ip) ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1]; h->lower -= sizeof(indx_t); /* If the cursor is on this page, adjust it as necessary. */ if (F_ISSET(&t->bt_cursor, CURS_INIT) && !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) && - t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index > index) + t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index > idx) --t->bt_cursor.pg.index; return (RET_SUCCESS); @@ -532,17 +514,13 @@ __bt_dleaf(t, key, h, index) * t: tree * key: referenced key (or NULL) * h: page - * index: index on page to delete + * idx: index on page to delete * * Returns: * RET_SUCCESS, RET_ERROR. */ static int -__bt_curdel(t, key, h, index) - BTREE *t; - const DBT *key; - PAGE *h; - u_int index; +__bt_curdel(BTREE *t, const DBT *key, PAGE *h, u_int idx) { CURSOR *c; EPG e; @@ -565,7 +543,7 @@ __bt_curdel(t, key, h, index) */ if (key == NULL) { e.page = h; - e.index = index; + e.index = idx; if ((status = __bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) != RET_SUCCESS) return (status); @@ -573,25 +551,25 @@ __bt_curdel(t, key, h, index) key = &c->key; } /* Check previous key, if not at the beginning of the page. */ - if (index > 0) { + if (idx > 0) { e.page = h; - e.index = index - 1; + e.index = idx - 1; if (__bt_cmp(t, key, &e) == 0) { F_SET(c, CURS_BEFORE); goto dup2; } } /* Check next key, if not at the end of the page. */ - if (index < NEXTINDEX(h) - 1) { + if (idx < NEXTINDEX(h) - 1) { e.page = h; - e.index = index + 1; + e.index = idx + 1; if (__bt_cmp(t, key, &e) == 0) { F_SET(c, CURS_AFTER); goto dup2; } } /* Check previous key if at the beginning of the page. */ - if (index == 0 && h->prevpg != P_INVALID) { + if (idx == 0 && h->prevpg != P_INVALID) { if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL) return (RET_ERROR); e.page = pg; @@ -603,7 +581,7 @@ __bt_curdel(t, key, h, index) mpool_put(t->bt_mp, pg, 0); } /* Check next key if at the end of the page. */ - if (index == NEXTINDEX(h) - 1 && h->nextpg != P_INVALID) { + if (idx == NEXTINDEX(h) - 1 && h->nextpg != P_INVALID) { if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) return (RET_ERROR); e.page = pg; @@ -619,7 +597,7 @@ dup2: c->pg.pgno = e.page->pgno; } } e.page = h; - e.index = index; + e.index = idx; if (curcopy || (status = __bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) == RET_SUCCESS) { F_SET(c, CURS_ACQUIRE); @@ -637,9 +615,7 @@ dup2: c->pg.pgno = e.page->pgno; * h: page to be deleted */ static int -__bt_relink(t, h) - BTREE *t; - PAGE *h; +__bt_relink(BTREE *t, PAGE *h) { PAGE *pg; diff --git a/db/btree/FreeBSD/bt_get.c b/db/btree/FreeBSD/bt_get.c index 0d91ae4..7de592e 100644 --- a/db/btree/FreeBSD/bt_get.c +++ b/db/btree/FreeBSD/bt_get.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_get.c 8.6 (Berkeley) 7/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_get.c,v 1.2 2002/03/22 21:52:01 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_get.c,v 1.4 2009/03/02 23:47:18 delphij Exp $"); #include @@ -62,11 +58,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_get.c,v 1.2 2002/03/22 21:52:01 obr * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. */ int -__bt_get(dbp, key, data, flags) - const DB *dbp; - const DBT *key; - DBT *data; - u_int flags; +__bt_get(const DB *dbp, const DBT *key, DBT *data, u_int flags) { BTREE *t; EPG *e; diff --git a/db/btree/FreeBSD/bt_open.c b/db/btree/FreeBSD/bt_open.c index c8a103a..955032a 100644 --- a/db/btree/FreeBSD/bt_open.c +++ b/db/btree/FreeBSD/bt_open.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_open.c 8.10 (Berkeley) 8/17/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_open.c,v 1.11 2002/03/22 21:52:01 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_open.c,v 1.17 2009/03/28 05:57:27 delphij Exp $"); /* * Implementation of btree access method for 4.4BSD. @@ -91,10 +87,7 @@ static int tmp(void); * */ DB * -__bt_open(fname, flags, mode, openinfo, dflags) - const char *fname; - int flags, mode, dflags; - const BTREEINFO *openinfo; +__bt_open(const char *fname, int flags, int mode, const BTREEINFO *openinfo, int dflags) { struct stat sb; BTMETA m; @@ -103,7 +96,7 @@ __bt_open(fname, flags, mode, openinfo, dflags) DB *dbp; pgno_t ncache; ssize_t nr; - int machine_lorder; + int machine_lorder, saved_errno; t = NULL; @@ -163,9 +156,8 @@ __bt_open(fname, flags, mode, openinfo, dflags) goto einval; /* Allocate and initialize DB and BTREE structures. */ - if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL) + if ((t = (BTREE *)calloc(1, sizeof(BTREE))) == NULL) goto err; - memset(t, 0, sizeof(BTREE)); t->bt_fd = -1; /* Don't close unopened fd on error. */ t->bt_lorder = b.lorder; t->bt_order = NOT; @@ -173,9 +165,8 @@ __bt_open(fname, flags, mode, openinfo, dflags) t->bt_pfx = b.prefix; t->bt_rfd = -1; - if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL) + if ((t->bt_dbp = dbp = (DB *)calloc(1, sizeof(DB))) == NULL) goto err; - memset(t->bt_dbp, 0, sizeof(DB)); if (t->bt_lorder != machine_lorder) F_SET(t, B_NEEDSWAP); @@ -204,7 +195,7 @@ __bt_open(fname, flags, mode, openinfo, dflags) default: goto einval; } - + if ((t->bt_fd = _open(fname, flags, mode)) < 0) goto err; @@ -334,13 +325,15 @@ einval: errno = EINVAL; eftype: errno = EFTYPE; goto err; -err: if (t) { +err: saved_errno = errno; + if (t) { if (t->bt_dbp) free(t->bt_dbp); if (t->bt_fd != -1) (void)_close(t->bt_fd); free(t); } + errno = saved_errno; return (NULL); } @@ -354,8 +347,7 @@ err: if (t) { * RET_ERROR, RET_SUCCESS */ static int -nroot(t) - BTREE *t; +nroot(BTREE *t) { PAGE *meta, *root; pgno_t npg; @@ -388,17 +380,21 @@ nroot(t) } static int -tmp() +tmp(void) { sigset_t set, oset; - int fd; + int fd, len; char *envtmp = NULL; char path[MAXPATHLEN]; if (issetugid() == 0) envtmp = getenv("TMPDIR"); - (void)snprintf(path, + len = snprintf(path, sizeof(path), "%s/bt.XXXXXXXXXX", envtmp ? envtmp : "/tmp"); + if (len < 0 || len >= (int)sizeof(path)) { + errno = ENAMETOOLONG; + return(-1); + } (void)sigfillset(&set); (void)_sigprocmask(SIG_BLOCK, &set, &oset); @@ -409,7 +405,7 @@ tmp() } static int -byteorder() +byteorder(void) { u_int32_t x; u_char *p; @@ -427,8 +423,7 @@ byteorder() } int -__bt_fd(dbp) - const DB *dbp; +__bt_fd(const DB *dbp) { BTREE *t; diff --git a/db/btree/FreeBSD/bt_overflow.c b/db/btree/FreeBSD/bt_overflow.c index 5e0f1ae..344b7c1 100644 --- a/db/btree/FreeBSD/bt_overflow.c +++ b/db/btree/FreeBSD/bt_overflow.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_overflow.c 8.5 (Berkeley) 7/16/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_overflow.c,v 1.3 2002/03/22 21:52:01 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_overflow.c,v 1.6 2009/03/05 00:57:01 delphij Exp $"); #include @@ -79,12 +75,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_overflow.c,v 1.3 2002/03/22 21:52:0 * RET_ERROR, RET_SUCCESS */ int -__ovfl_get(t, p, ssz, buf, bufsz) - BTREE *t; - void *p; - size_t *ssz; - void **buf; - size_t *bufsz; +__ovfl_get(BTREE *t, void *p, size_t *ssz, void **buf, size_t *bufsz) { PAGE *h; pgno_t pg; @@ -101,7 +92,7 @@ __ovfl_get(t, p, ssz, buf, bufsz) #endif /* Make the buffer bigger as necessary. */ if (*bufsz < sz) { - *buf = (char *)(*buf == NULL ? malloc(sz) : reallocf(*buf, sz)); + *buf = reallocf(*buf, sz); if (*buf == NULL) return (RET_ERROR); *bufsz = sz; @@ -138,10 +129,7 @@ __ovfl_get(t, p, ssz, buf, bufsz) * RET_ERROR, RET_SUCCESS */ int -__ovfl_put(t, dbt, pg) - BTREE *t; - const DBT *dbt; - pgno_t *pg; +__ovfl_put(BTREE *t, const DBT *dbt, pgno_t *pg) { PAGE *h, *last; void *p; @@ -192,9 +180,7 @@ __ovfl_put(t, dbt, pg) * RET_ERROR, RET_SUCCESS */ int -__ovfl_delete(t, p) - BTREE *t; - void *p; +__ovfl_delete(BTREE *t, void *p) { PAGE *h; pgno_t pg; diff --git a/db/btree/FreeBSD/bt_overflow.c.patch b/db/btree/FreeBSD/bt_overflow.c.patch index d004ec6..d2bf3b5 100644 --- a/db/btree/FreeBSD/bt_overflow.c.patch +++ b/db/btree/FreeBSD/bt_overflow.c.patch @@ -1,6 +1,6 @@ ---- bt_overflow.c.orig 2008-09-07 11:37:54.000000000 -0700 -+++ bt_overflow.c 2008-09-07 12:00:45.000000000 -0700 -@@ -97,7 +97,7 @@ __ovfl_get(t, p, ssz, buf, bufsz) +--- bt_overflow.c.orig 2009-11-06 12:39:34.000000000 -0800 ++++ bt_overflow.c 2009-11-06 12:40:06.000000000 -0800 +@@ -88,7 +88,7 @@ __ovfl_get(BTREE *t, void *p, size_t *ss #ifdef DEBUG if (pg == P_INVALID || sz == 0) @@ -9,7 +9,7 @@ #endif /* Make the buffer bigger as necessary. */ if (*bufsz < sz) { -@@ -206,7 +206,7 @@ __ovfl_delete(t, p) +@@ -192,7 +192,7 @@ __ovfl_delete(BTREE *t, void *p) #ifdef DEBUG if (pg == P_INVALID || sz == 0) diff --git a/db/btree/FreeBSD/bt_page.c b/db/btree/FreeBSD/bt_page.c index 3392709..f4fbd2c 100644 --- a/db/btree/FreeBSD/bt_page.c +++ b/db/btree/FreeBSD/bt_page.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)bt_page.c 8.3 (Berkeley) 7/14/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_page.c,v 1.3 2002/03/22 21:52:01 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_page.c,v 1.5 2009/03/02 23:47:18 delphij Exp $"); #include @@ -59,9 +55,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_page.c,v 1.3 2002/03/22 21:52:01 ob * mpool_put's the page. */ int -__bt_free(t, h) - BTREE *t; - PAGE *h; +__bt_free(BTREE *t, PAGE *h) { /* Insert the page at the head of the free list. */ h->prevpg = P_INVALID; @@ -85,9 +79,7 @@ __bt_free(t, h) * Pointer to a page, NULL on error. */ PAGE * -__bt_new(t, npg) - BTREE *t; - pgno_t *npg; +__bt_new(BTREE *t, pgno_t *npg) { PAGE *h; diff --git a/db/btree/FreeBSD/bt_put.c b/db/btree/FreeBSD/bt_put.c index 0dca165..78db11a 100644 --- a/db/btree/FreeBSD/bt_put.c +++ b/db/btree/FreeBSD/bt_put.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_put.c 8.8 (Berkeley) 7/26/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_put.c,v 1.4 2003/05/30 11:05:08 tmm Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_put.c,v 1.9 2009/03/28 05:45:29 delphij Exp $"); #include @@ -66,17 +62,13 @@ static EPG *bt_fast(BTREE *, const DBT *, const DBT *, int *); * tree and R_NOOVERWRITE specified. */ int -__bt_put(dbp, key, data, flags) - const DB *dbp; - DBT *key; - const DBT *data; - u_int flags; +__bt_put(const DB *dbp, DBT *key, const DBT *data, u_int flags) { BTREE *t; DBT tkey, tdata; EPG *e; PAGE *h; - indx_t index, nxtindex; + indx_t idx, nxtindex; pgno_t pg; u_int32_t nbytes, tmp; int dflags, exact, status; @@ -107,7 +99,7 @@ __bt_put(dbp, key, data, flags) */ if (F_ISSET(&t->bt_cursor, CURS_INIT) && !F_ISSET(&t->bt_cursor, - CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE)) + CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE)) break; /* FALLTHROUGH */ default: @@ -157,7 +149,7 @@ storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR) if (flags == R_CURSOR) { if ((h = mpool_get(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL) return (RET_ERROR); - index = t->bt_cursor.pg.index; + idx = t->bt_cursor.pg.index; goto delete; } @@ -169,7 +161,7 @@ storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR) if ((e = __bt_search(t, key, &exact)) == NULL) return (RET_ERROR); h = e->page; - index = e->index; + idx = e->index; /* * Add the key/data pair to the tree. If an identical key is already @@ -191,7 +183,7 @@ storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR) * Note, the delete may empty the page, so we need to put a * new entry into the page immediately. */ -delete: if (__bt_dleaf(t, key, h, index) == RET_ERROR) { +delete: if (__bt_dleaf(t, key, h, idx) == RET_ERROR) { mpool_put(t->bt_mp, h, 0); return (RET_ERROR); } @@ -205,37 +197,37 @@ delete: if (__bt_dleaf(t, key, h, index) == RET_ERROR) { * into the offset array, shift the pointers up. */ nbytes = NBLEAFDBT(key->size, data->size); - if (h->upper - h->lower < nbytes + sizeof(indx_t)) { + if ((u_int32_t)(h->upper - h->lower) < nbytes + sizeof(indx_t)) { if ((status = __bt_split(t, h, key, - data, dflags, nbytes, index)) != RET_SUCCESS) + data, dflags, nbytes, idx)) != RET_SUCCESS) return (status); goto success; } - if (index < (nxtindex = NEXTINDEX(h))) - memmove(h->linp + index + 1, h->linp + index, - (nxtindex - index) * sizeof(indx_t)); + if (idx < (nxtindex = NEXTINDEX(h))) + memmove(h->linp + idx + 1, h->linp + idx, + (nxtindex - idx) * sizeof(indx_t)); h->lower += sizeof(indx_t); - h->linp[index] = h->upper -= nbytes; + h->linp[idx] = h->upper -= nbytes; dest = (char *)h + h->upper; WR_BLEAF(dest, key, data, dflags); /* If the cursor is on this page, adjust it as necessary. */ if (F_ISSET(&t->bt_cursor, CURS_INIT) && !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) && - t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index >= index) + t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index >= idx) ++t->bt_cursor.pg.index; if (t->bt_order == NOT) { if (h->nextpg == P_INVALID) { - if (index == NEXTINDEX(h) - 1) { + if (idx == NEXTINDEX(h) - 1) { t->bt_order = FORWARD; - t->bt_last.index = index; + t->bt_last.index = idx; t->bt_last.pgno = h->pgno; } } else if (h->prevpg == P_INVALID) { - if (index == 0) { + if (idx == 0) { t->bt_order = BACK; t->bt_last.index = 0; t->bt_last.pgno = h->pgno; @@ -265,13 +257,10 @@ u_long bt_cache_hit, bt_cache_miss; * key: key to insert * * Returns: - * EPG for new record or NULL if not found. + * EPG for new record or NULL if not found. */ static EPG * -bt_fast(t, key, data, exactp) - BTREE *t; - const DBT *key, *data; - int *exactp; +bt_fast(BTREE *t, const DBT *key, const DBT *data, int *exactp) { PAGE *h; u_int32_t nbytes; @@ -289,7 +278,7 @@ bt_fast(t, key, data, exactp) * have to search to get split stack. */ nbytes = NBLEAFDBT(key->size, data->size); - if (h->upper - h->lower < nbytes + sizeof(indx_t)) + if ((u_int32_t)(h->upper - h->lower) < nbytes + sizeof(indx_t)) goto miss; if (t->bt_order == FORWARD) { diff --git a/db/btree/FreeBSD/bt_search.c b/db/btree/FreeBSD/bt_search.c index cee177d..c49d27c 100644 --- a/db/btree/FreeBSD/bt_search.c +++ b/db/btree/FreeBSD/bt_search.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_search.c 8.8 (Berkeley) 7/31/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_search.c,v 1.2 2002/03/21 22:46:25 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_search.c,v 1.5 2009/03/03 02:16:12 delphij Exp $"); #include @@ -65,13 +61,10 @@ static int __bt_sprev(BTREE *, PAGE *, const DBT *, int *); * the bt_cur field of the tree. A pointer to the field is returned. */ EPG * -__bt_search(t, key, exactp) - BTREE *t; - const DBT *key; - int *exactp; +__bt_search(BTREE *t, const DBT *key, int *exactp) { PAGE *h; - indx_t base, index, lim; + indx_t base, idx, lim; pgno_t pg; int cmp; @@ -83,7 +76,7 @@ __bt_search(t, key, exactp) /* Do a binary search on the current page. */ t->bt_cur.page = h; for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) { - t->bt_cur.index = index = base + (lim >> 1); + t->bt_cur.index = idx = base + (lim >> 1); if ((cmp = __bt_cmp(t, key, &t->bt_cur)) == 0) { if (h->flags & P_BLEAF) { *exactp = 1; @@ -92,7 +85,7 @@ __bt_search(t, key, exactp) goto next; } if (cmp > 0) { - base = index + 1; + base = idx + 1; --lim; } } @@ -128,10 +121,10 @@ __bt_search(t, key, exactp) * be a parent page for the key. If a split later occurs, the * inserted page will be to the right of the saved page. */ - index = base ? base - 1 : base; + idx = base ? base - 1 : base; -next: BT_PUSH(t, h->pgno, index); - pg = GETBINTERNAL(h, index)->pgno; +next: BT_PUSH(t, h->pgno, idx); + pg = GETBINTERNAL(h, idx)->pgno; mpool_put(t->bt_mp, h, 0); } } @@ -150,11 +143,7 @@ next: BT_PUSH(t, h->pgno, index); * If an exact match found. */ static int -__bt_snext(t, h, key, exactp) - BTREE *t; - PAGE *h; - const DBT *key; - int *exactp; +__bt_snext(BTREE *t, PAGE *h, const DBT *key, int *exactp) { EPG e; @@ -189,11 +178,7 @@ __bt_snext(t, h, key, exactp) * If an exact match found. */ static int -__bt_sprev(t, h, key, exactp) - BTREE *t; - PAGE *h; - const DBT *key; - int *exactp; +__bt_sprev(BTREE *t, PAGE *h, const DBT *key, int *exactp) { EPG e; diff --git a/db/btree/FreeBSD/bt_seq.c b/db/btree/FreeBSD/bt_seq.c index 662e195..2ffe71f 100644 --- a/db/btree/FreeBSD/bt_seq.c +++ b/db/btree/FreeBSD/bt_seq.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_seq.c 8.7 (Berkeley) 7/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_seq.c,v 1.3 2002/03/21 22:46:25 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_seq.c,v 1.7 2009/03/04 00:58:04 delphij Exp $"); #include @@ -76,10 +72,7 @@ static int __bt_seqset(BTREE *, EPG *, DBT *, int); * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. */ int -__bt_seq(dbp, key, data, flags) - const DB *dbp; - DBT *key, *data; - u_int flags; +__bt_seq(const DB *dbp, DBT *key, DBT *data, u_int flags) { BTREE *t; EPG e; @@ -151,11 +144,7 @@ __bt_seq(dbp, key, data, flags) * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. */ static int -__bt_seqset(t, ep, key, flags) - BTREE *t; - EPG *ep; - DBT *key; - int flags; +__bt_seqset(BTREE *t, EPG *ep, DBT *key, int flags) { PAGE *h; pgno_t pg; @@ -239,14 +228,11 @@ __bt_seqset(t, ep, key, flags) * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. */ static int -__bt_seqadv(t, ep, flags) - BTREE *t; - EPG *ep; - int flags; +__bt_seqadv(BTREE *t, EPG *ep, int flags) { CURSOR *c; PAGE *h; - indx_t index; + indx_t idx; pgno_t pg; int exact; @@ -272,7 +258,7 @@ __bt_seqadv(t, ep, flags) return (RET_ERROR); /* - * Find the next/previous record in the tree and point the cursor at + * Find the next/previous record in the tree and point the cursor at * it. The cursor may not be moved until a new key has been found. */ switch (flags) { @@ -284,15 +270,15 @@ __bt_seqadv(t, ep, flags) */ if (F_ISSET(c, CURS_AFTER)) goto usecurrent; - index = c->pg.index; - if (++index == NEXTINDEX(h)) { + idx = c->pg.index; + if (++idx == NEXTINDEX(h)) { pg = h->nextpg; mpool_put(t->bt_mp, h, 0); if (pg == P_INVALID) return (RET_SPECIAL); if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) return (RET_ERROR); - index = 0; + idx = 0; } break; case R_PREV: /* Previous record. */ @@ -307,22 +293,22 @@ usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE); ep->index = c->pg.index; return (RET_SUCCESS); } - index = c->pg.index; - if (index == 0) { + idx = c->pg.index; + if (idx == 0) { pg = h->prevpg; mpool_put(t->bt_mp, h, 0); if (pg == P_INVALID) return (RET_SPECIAL); if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) return (RET_ERROR); - index = NEXTINDEX(h) - 1; + idx = NEXTINDEX(h) - 1; } else - --index; + --idx; break; } ep->page = h; - ep->index = index; + ep->index = idx; return (RET_SUCCESS); } @@ -341,11 +327,7 @@ usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE); * or RET_SPECIAL if no such key exists. */ static int -__bt_first(t, key, erval, exactp) - BTREE *t; - const DBT *key; - EPG *erval; - int *exactp; +__bt_first(BTREE *t, const DBT *key, EPG *erval, int *exactp) { PAGE *h; EPG *ep, save; @@ -366,7 +348,7 @@ __bt_first(t, key, erval, exactp) *erval = *ep; return (RET_SUCCESS); } - + /* * Walk backwards, as long as the entry matches and there are * keys left in the tree. Save a copy of each match in case @@ -439,13 +421,10 @@ __bt_first(t, key, erval, exactp) * Parameters: * t: the tree * pgno: page number - * index: page index + * idx: page index */ void -__bt_setcur(t, pgno, index) - BTREE *t; - pgno_t pgno; - u_int index; +__bt_setcur(BTREE *t, pgno_t pgno, u_int idx) { /* Lose any already deleted key. */ if (t->bt_cursor.key.data != NULL) { @@ -457,6 +436,6 @@ __bt_setcur(t, pgno, index) /* Update the cursor. */ t->bt_cursor.pg.pgno = pgno; - t->bt_cursor.pg.index = index; + t->bt_cursor.pg.index = idx; F_SET(&t->bt_cursor, CURS_INIT); } diff --git a/db/btree/FreeBSD/bt_seq.c.patch b/db/btree/FreeBSD/bt_seq.c.patch index e091ce4..afdfbea 100644 --- a/db/btree/FreeBSD/bt_seq.c.patch +++ b/db/btree/FreeBSD/bt_seq.c.patch @@ -1,6 +1,6 @@ ---- bt_seq.c.orig 2008-10-09 11:40:48.000000000 -0700 -+++ bt_seq.c 2008-10-09 11:43:28.000000000 -0700 -@@ -387,18 +387,19 @@ __bt_first(t, key, erval, exactp) +--- bt_seq.c.orig 2009-11-06 12:39:34.000000000 -0800 ++++ bt_seq.c 2009-11-06 12:40:06.000000000 -0800 +@@ -369,18 +369,19 @@ __bt_first(BTREE *t, const DBT *key, EPG * occurs. */ if (ep->index == 0) { diff --git a/db/btree/FreeBSD/bt_split.c b/db/btree/FreeBSD/bt_split.c index 07373de..2f34975 100644 --- a/db/btree/FreeBSD/bt_split.c +++ b/db/btree/FreeBSD/bt_split.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_split.c 8.9 (Berkeley) 7/26/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_split.c,v 1.7 2004/09/13 22:07:24 kuriyama Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_split.c,v 1.12 2009/03/28 05:45:29 delphij Exp $"); #include @@ -51,10 +47,10 @@ __FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_split.c,v 1.7 2004/09/13 22:07:24 k #include "btree.h" static int bt_broot(BTREE *, PAGE *, PAGE *, PAGE *); -static PAGE *bt_page (BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t); +static PAGE *bt_page(BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t); static int bt_preserve(BTREE *, pgno_t); -static PAGE *bt_psplit (BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t); -static PAGE *bt_root (BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t); +static PAGE *bt_psplit(BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t); +static PAGE *bt_root(BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t); static int bt_rroot(BTREE *, PAGE *, PAGE *, PAGE *); static recno_t rec_total(PAGE *); @@ -78,13 +74,8 @@ u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved; * RET_ERROR, RET_SUCCESS */ int -__bt_split(t, sp, key, data, flags, ilen, argskip) - BTREE *t; - PAGE *sp; - const DBT *key, *data; - int flags; - size_t ilen; - u_int32_t argskip; +__bt_split(BTREE *t, PAGE *sp, const DBT *key, const DBT *data, int flags, + size_t ilen, u_int32_t argskip) { BINTERNAL *bi; BLEAF *bl, *tbl; @@ -158,7 +149,7 @@ __bt_split(t, sp, key, data, flags, ilen, argskip) if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) goto err2; - /* + /* * The new key goes ONE AFTER the index, because the split * was to the right. */ @@ -214,7 +205,7 @@ __bt_split(t, sp, key, data, flags, ilen, argskip) } /* Split the parent page if necessary or shift the indices. */ - if (h->upper - h->lower < nbytes + sizeof(indx_t)) { + if ((u_int32_t)(h->upper - h->lower) < nbytes + sizeof(indx_t)) { sp = h; h = h->pgno == P_ROOT ? bt_root(t, h, &l, &r, &skip, nbytes) : @@ -340,11 +331,7 @@ err2: mpool_put(t->bt_mp, l, 0); * Pointer to page in which to insert or NULL on error. */ static PAGE * -bt_page(t, h, lp, rp, skip, ilen) - BTREE *t; - PAGE *h, **lp, **rp; - indx_t *skip; - size_t ilen; +bt_page(BTREE *t, PAGE *h, PAGE **lp, PAGE **rp, indx_t *skip, size_t ilen) { PAGE *l, *r, *tp; pgno_t npg; @@ -385,13 +372,10 @@ bt_page(t, h, lp, rp, skip, ilen) } /* Put the new left page for the split into place. */ - if ((l = (PAGE *)malloc(t->bt_psize)) == NULL) { + if ((l = (PAGE *)calloc(1, t->bt_psize)) == NULL) { mpool_put(t->bt_mp, r, 0); return (NULL); } -#ifdef PURIFY - memset(l, 0xff, t->bt_psize); -#endif l->pgno = h->pgno; l->nextpg = r->pgno; l->prevpg = h->prevpg; @@ -445,11 +429,7 @@ bt_page(t, h, lp, rp, skip, ilen) * Pointer to page in which to insert or NULL on error. */ static PAGE * -bt_root(t, h, lp, rp, skip, ilen) - BTREE *t; - PAGE *h, **lp, **rp; - indx_t *skip; - size_t ilen; +bt_root(BTREE *t, PAGE *h, PAGE **lp, PAGE **rp, indx_t *skip, size_t ilen) { PAGE *l, *r, *tp; pgno_t lnpg, rnpg; @@ -492,9 +472,7 @@ bt_root(t, h, lp, rp, skip, ilen) * RET_ERROR, RET_SUCCESS */ static int -bt_rroot(t, h, l, r) - BTREE *t; - PAGE *h, *l, *r; +bt_rroot(BTREE *t, PAGE *h, PAGE *l, PAGE *r) { char *dest; @@ -532,9 +510,7 @@ bt_rroot(t, h, l, r) * RET_ERROR, RET_SUCCESS */ static int -bt_broot(t, h, l, r) - BTREE *t; - PAGE *h, *l, *r; +bt_broot(BTREE *t, PAGE *h, PAGE *l, PAGE *r) { BINTERNAL *bi; BLEAF *bl; @@ -609,11 +585,7 @@ bt_broot(t, h, l, r) * Pointer to page in which to insert. */ static PAGE * -bt_psplit(t, h, l, r, pskip, ilen) - BTREE *t; - PAGE *h, *l, *r; - indx_t *pskip; - size_t ilen; +bt_psplit(BTREE *t, PAGE *h, PAGE *l, PAGE *r, indx_t *pskip, size_t ilen) { BINTERNAL *bi; BLEAF *bl; @@ -787,9 +759,7 @@ bt_psplit(t, h, l, r, pskip, ilen) * RET_SUCCESS, RET_ERROR. */ static int -bt_preserve(t, pg) - BTREE *t; - pgno_t pg; +bt_preserve(BTREE *t, pgno_t pg) { PAGE *h; @@ -815,8 +785,7 @@ bt_preserve(t, pg) * all the way back to bt_split/bt_rroot and it's not very clean. */ static recno_t -rec_total(h) - PAGE *h; +rec_total(PAGE *h) { recno_t recs; indx_t nxt, top; diff --git a/db/btree/FreeBSD/bt_split.c.patch b/db/btree/FreeBSD/bt_split.c.patch index b0835c8..a180794 100644 --- a/db/btree/FreeBSD/bt_split.c.patch +++ b/db/btree/FreeBSD/bt_split.c.patch @@ -1,6 +1,6 @@ ---- bt_split.c.orig 2008-09-07 11:37:54.000000000 -0700 -+++ bt_split.c 2008-09-07 12:29:24.000000000 -0700 -@@ -210,7 +210,7 @@ __bt_split(t, sp, key, data, flags, ilen +--- bt_split.c.orig 2009-11-06 12:39:34.000000000 -0800 ++++ bt_split.c 2009-11-06 12:40:06.000000000 -0800 +@@ -201,7 +201,7 @@ __bt_split(BTREE *t, PAGE *sp, const DBT nbytes = NRINTERNAL; break; default: @@ -9,7 +9,7 @@ } /* Split the parent page if necessary or shift the indices. */ -@@ -285,7 +285,7 @@ __bt_split(t, sp, key, data, flags, ilen +@@ -276,7 +276,7 @@ __bt_split(BTREE *t, PAGE *sp, const DBT ((RINTERNAL *)dest)->pgno = rchild->pgno; break; default: @@ -18,7 +18,7 @@ } /* Unpin the held pages. */ -@@ -580,7 +580,7 @@ bt_broot(t, h, l, r) +@@ -556,7 +556,7 @@ bt_broot(BTREE *t, PAGE *h, PAGE *l, PAG ((BINTERNAL *)dest)->pgno = r->pgno; break; default: @@ -27,7 +27,7 @@ } /* There are two keys on the page. */ -@@ -663,7 +663,7 @@ bt_psplit(t, h, l, r, pskip, ilen) +@@ -635,7 +635,7 @@ bt_psplit(BTREE *t, PAGE *h, PAGE *l, PA isbigkey = 0; break; default: @@ -36,7 +36,7 @@ } /* -@@ -756,7 +756,7 @@ bt_psplit(t, h, l, r, pskip, ilen) +@@ -728,7 +728,7 @@ bt_psplit(BTREE *t, PAGE *h, PAGE *l, PA nbytes = NRLEAF(rl); break; default: diff --git a/db/btree/FreeBSD/bt_utils.c b/db/btree/FreeBSD/bt_utils.c index e9acfb7..27d745b 100644 --- a/db/btree/FreeBSD/bt_utils.c +++ b/db/btree/FreeBSD/bt_utils.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_utils.c 8.8 (Berkeley) 7/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_utils.c,v 1.3 2003/01/01 18:48:42 schweikh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_utils.c,v 1.7 2009/03/05 00:57:01 delphij Exp $"); #include @@ -66,11 +62,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_utils.c,v 1.3 2003/01/01 18:48:42 s * RET_SUCCESS, RET_ERROR. */ int -__bt_ret(t, e, key, rkey, data, rdata, copy) - BTREE *t; - EPG *e; - DBT *key, *rkey, *data, *rdata; - int copy; +__bt_ret(BTREE *t, EPG *e, DBT *key, DBT *rkey, DBT *data, DBT *rdata, int copy) { BLEAF *bl; void *p; @@ -92,8 +84,7 @@ __bt_ret(t, e, key, rkey, data, rdata, copy) key->data = rkey->data; } else if (copy || F_ISSET(t, B_DB_LOCK)) { if (bl->ksize > rkey->size) { - p = (void *)(rkey->data == NULL ? - malloc(bl->ksize) : realloc(rkey->data, bl->ksize)); + p = realloc(rkey->data, bl->ksize); if (p == NULL) return (RET_ERROR); rkey->data = p; @@ -119,9 +110,7 @@ dataonly: } else if (copy || F_ISSET(t, B_DB_LOCK)) { /* Use +1 in case the first record retrieved is 0 length. */ if (bl->dsize + 1 > rdata->size) { - p = (void *)(rdata->data == NULL ? - malloc(bl->dsize + 1) : - realloc(rdata->data, bl->dsize + 1)); + p = realloc(rdata->data, bl->dsize + 1); if (p == NULL) return (RET_ERROR); rdata->data = p; @@ -152,10 +141,7 @@ dataonly: * > 0 if k1 is > record */ int -__bt_cmp(t, k1, e) - BTREE *t; - const DBT *k1; - EPG *e; +__bt_cmp(BTREE *t, const DBT *k1, EPG *e) { BINTERNAL *bi; BLEAF *bl; @@ -207,7 +193,7 @@ __bt_cmp(t, k1, e) * * Parameters: * a: DBT #1 - * b: DBT #2 + * b: DBT #2 * * Returns: * < 0 if a is < b @@ -215,8 +201,7 @@ __bt_cmp(t, k1, e) * > 0 if a is > b */ int -__bt_defcmp(a, b) - const DBT *a, *b; +__bt_defcmp(const DBT *a, const DBT *b) { size_t len; u_char *p1, *p2; @@ -239,14 +224,13 @@ __bt_defcmp(a, b) * * Parameters: * a: DBT #1 - * b: DBT #2 + * b: DBT #2 * * Returns: * Number of bytes needed to distinguish b from a. */ size_t -__bt_defpfx(a, b) - const DBT *a, *b; +__bt_defpfx(const DBT *a, const DBT *b) { u_char *p1, *p2; size_t cnt, len; diff --git a/db/btree/FreeBSD/btree.h b/db/btree/FreeBSD/btree.h index d5adeb7..02001b3 100644 --- a/db/btree/FreeBSD/btree.h +++ b/db/btree/FreeBSD/btree.h @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,7 +30,7 @@ * SUCH DAMAGE. * * @(#)btree.h 8.11 (Berkeley) 8/17/94 - * $FreeBSD: src/lib/libc/db/btree/btree.h,v 1.3 2002/03/22 23:41:40 obrien Exp $ + * $FreeBSD: src/lib/libc/db/btree/btree.h,v 1.5 2009/03/04 00:58:04 delphij Exp $ */ /* Macros to set/clear/test flags. */ @@ -313,8 +309,8 @@ typedef struct _btree { CURSOR bt_cursor; /* cursor */ #define BT_PUSH(t, p, i) { \ - t->bt_sp->pgno = p; \ - t->bt_sp->index = i; \ + t->bt_sp->pgno = p; \ + t->bt_sp->index = i; \ ++t->bt_sp; \ } #define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL : --t->bt_sp) diff --git a/db/btree/FreeBSD/btree.h.patch b/db/btree/FreeBSD/btree.h.patch index 58d011b..ee96ee7 100644 --- a/db/btree/FreeBSD/btree.h.patch +++ b/db/btree/FreeBSD/btree.h.patch @@ -1,6 +1,6 @@ ---- btree.h.orig Fri Mar 22 15:41:40 2002 -+++ btree.h Sat Oct 18 18:14:05 2003 -@@ -381,4 +381,4 @@ +--- btree.h.orig 2009-11-06 12:39:34.000000000 -0800 ++++ btree.h 2009-11-06 12:40:06.000000000 -0800 +@@ -377,4 +377,4 @@ typedef struct _btree { u_int32_t flags; } BTREE; diff --git a/db/btree/FreeBSD/extern.h b/db/btree/FreeBSD/extern.h index 478f6af..2edf1c1 100644 --- a/db/btree/FreeBSD/extern.h +++ b/db/btree/FreeBSD/extern.h @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -31,7 +27,7 @@ * SUCH DAMAGE. * * @(#)extern.h 8.10 (Berkeley) 7/20/94 - * $FreeBSD: src/lib/libc/db/btree/extern.h,v 1.3 2002/03/22 09:18:22 obrien Exp $ + * $FreeBSD: src/lib/libc/db/btree/extern.h,v 1.4 2007/01/09 00:27:50 imp Exp $ */ int __bt_close(DB *); diff --git a/db/btree/bt_overflow-fbsd.c b/db/btree/bt_overflow-fbsd.c index c0d363f..25e3000 100644 --- a/db/btree/bt_overflow-fbsd.c +++ b/db/btree/bt_overflow-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_overflow.c 8.5 (Berkeley) 7/16/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_overflow.c,v 1.3 2002/03/22 21:52:01 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_overflow.c,v 1.6 2009/03/05 00:57:01 delphij Exp $"); #include @@ -79,12 +75,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_overflow.c,v 1.3 2002/03/22 21:52:0 * RET_ERROR, RET_SUCCESS */ int -__ovfl_get(t, p, ssz, buf, bufsz) - BTREE *t; - void *p; - size_t *ssz; - void **buf; - size_t *bufsz; +__ovfl_get(BTREE *t, void *p, size_t *ssz, void **buf, size_t *bufsz) { PAGE *h; pgno_t pg; @@ -101,7 +92,7 @@ __ovfl_get(t, p, ssz, buf, bufsz) #endif /* Make the buffer bigger as necessary. */ if (*bufsz < sz) { - *buf = (char *)(*buf == NULL ? malloc(sz) : reallocf(*buf, sz)); + *buf = reallocf(*buf, sz); if (*buf == NULL) return (RET_ERROR); *bufsz = sz; @@ -138,10 +129,7 @@ __ovfl_get(t, p, ssz, buf, bufsz) * RET_ERROR, RET_SUCCESS */ int -__ovfl_put(t, dbt, pg) - BTREE *t; - const DBT *dbt; - pgno_t *pg; +__ovfl_put(BTREE *t, const DBT *dbt, pgno_t *pg) { PAGE *h, *last; void *p; @@ -192,9 +180,7 @@ __ovfl_put(t, dbt, pg) * RET_ERROR, RET_SUCCESS */ int -__ovfl_delete(t, p) - BTREE *t; - void *p; +__ovfl_delete(BTREE *t, void *p) { PAGE *h; pgno_t pg; diff --git a/db/btree/bt_seq-fbsd.c b/db/btree/bt_seq-fbsd.c index 5cac84b..b0b8b04 100644 --- a/db/btree/bt_seq-fbsd.c +++ b/db/btree/bt_seq-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_seq.c 8.7 (Berkeley) 7/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_seq.c,v 1.3 2002/03/21 22:46:25 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_seq.c,v 1.7 2009/03/04 00:58:04 delphij Exp $"); #include @@ -76,10 +72,7 @@ static int __bt_seqset(BTREE *, EPG *, DBT *, int); * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. */ int -__bt_seq(dbp, key, data, flags) - const DB *dbp; - DBT *key, *data; - u_int flags; +__bt_seq(const DB *dbp, DBT *key, DBT *data, u_int flags) { BTREE *t; EPG e; @@ -151,11 +144,7 @@ __bt_seq(dbp, key, data, flags) * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. */ static int -__bt_seqset(t, ep, key, flags) - BTREE *t; - EPG *ep; - DBT *key; - int flags; +__bt_seqset(BTREE *t, EPG *ep, DBT *key, int flags) { PAGE *h; pgno_t pg; @@ -239,14 +228,11 @@ __bt_seqset(t, ep, key, flags) * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. */ static int -__bt_seqadv(t, ep, flags) - BTREE *t; - EPG *ep; - int flags; +__bt_seqadv(BTREE *t, EPG *ep, int flags) { CURSOR *c; PAGE *h; - indx_t index; + indx_t idx; pgno_t pg; int exact; @@ -272,7 +258,7 @@ __bt_seqadv(t, ep, flags) return (RET_ERROR); /* - * Find the next/previous record in the tree and point the cursor at + * Find the next/previous record in the tree and point the cursor at * it. The cursor may not be moved until a new key has been found. */ switch (flags) { @@ -284,15 +270,15 @@ __bt_seqadv(t, ep, flags) */ if (F_ISSET(c, CURS_AFTER)) goto usecurrent; - index = c->pg.index; - if (++index == NEXTINDEX(h)) { + idx = c->pg.index; + if (++idx == NEXTINDEX(h)) { pg = h->nextpg; mpool_put(t->bt_mp, h, 0); if (pg == P_INVALID) return (RET_SPECIAL); if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) return (RET_ERROR); - index = 0; + idx = 0; } break; case R_PREV: /* Previous record. */ @@ -307,22 +293,22 @@ usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE); ep->index = c->pg.index; return (RET_SUCCESS); } - index = c->pg.index; - if (index == 0) { + idx = c->pg.index; + if (idx == 0) { pg = h->prevpg; mpool_put(t->bt_mp, h, 0); if (pg == P_INVALID) return (RET_SPECIAL); if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) return (RET_ERROR); - index = NEXTINDEX(h) - 1; + idx = NEXTINDEX(h) - 1; } else - --index; + --idx; break; } ep->page = h; - ep->index = index; + ep->index = idx; return (RET_SUCCESS); } @@ -341,11 +327,7 @@ usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE); * or RET_SPECIAL if no such key exists. */ static int -__bt_first(t, key, erval, exactp) - BTREE *t; - const DBT *key; - EPG *erval; - int *exactp; +__bt_first(BTREE *t, const DBT *key, EPG *erval, int *exactp) { PAGE *h; EPG *ep, save; @@ -366,7 +348,7 @@ __bt_first(t, key, erval, exactp) *erval = *ep; return (RET_SUCCESS); } - + /* * Walk backwards, as long as the entry matches and there are * keys left in the tree. Save a copy of each match in case @@ -440,13 +422,10 @@ __bt_first(t, key, erval, exactp) * Parameters: * t: the tree * pgno: page number - * index: page index + * idx: page index */ void -__bt_setcur(t, pgno, index) - BTREE *t; - pgno_t pgno; - u_int index; +__bt_setcur(BTREE *t, pgno_t pgno, u_int idx) { /* Lose any already deleted key. */ if (t->bt_cursor.key.data != NULL) { @@ -458,6 +437,6 @@ __bt_setcur(t, pgno, index) /* Update the cursor. */ t->bt_cursor.pg.pgno = pgno; - t->bt_cursor.pg.index = index; + t->bt_cursor.pg.index = idx; F_SET(&t->bt_cursor, CURS_INIT); } diff --git a/db/btree/bt_split-fbsd.c b/db/btree/bt_split-fbsd.c index eb16921..3e93e20 100644 --- a/db/btree/bt_split-fbsd.c +++ b/db/btree/bt_split-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)bt_split.c 8.9 (Berkeley) 7/26/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_split.c,v 1.7 2004/09/13 22:07:24 kuriyama Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_split.c,v 1.12 2009/03/28 05:45:29 delphij Exp $"); #include @@ -51,10 +47,10 @@ __FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_split.c,v 1.7 2004/09/13 22:07:24 k #include "btree.h" static int bt_broot(BTREE *, PAGE *, PAGE *, PAGE *); -static PAGE *bt_page (BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t); +static PAGE *bt_page(BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t); static int bt_preserve(BTREE *, pgno_t); -static PAGE *bt_psplit (BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t); -static PAGE *bt_root (BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t); +static PAGE *bt_psplit(BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t); +static PAGE *bt_root(BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t); static int bt_rroot(BTREE *, PAGE *, PAGE *, PAGE *); static recno_t rec_total(PAGE *); @@ -78,13 +74,8 @@ u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved; * RET_ERROR, RET_SUCCESS */ int -__bt_split(t, sp, key, data, flags, ilen, argskip) - BTREE *t; - PAGE *sp; - const DBT *key, *data; - int flags; - size_t ilen; - u_int32_t argskip; +__bt_split(BTREE *t, PAGE *sp, const DBT *key, const DBT *data, int flags, + size_t ilen, u_int32_t argskip) { BINTERNAL *bi; BLEAF *bl, *tbl; @@ -158,7 +149,7 @@ __bt_split(t, sp, key, data, flags, ilen, argskip) if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) goto err2; - /* + /* * The new key goes ONE AFTER the index, because the split * was to the right. */ @@ -214,7 +205,7 @@ __bt_split(t, sp, key, data, flags, ilen, argskip) } /* Split the parent page if necessary or shift the indices. */ - if (h->upper - h->lower < nbytes + sizeof(indx_t)) { + if ((u_int32_t)(h->upper - h->lower) < nbytes + sizeof(indx_t)) { sp = h; h = h->pgno == P_ROOT ? bt_root(t, h, &l, &r, &skip, nbytes) : @@ -340,11 +331,7 @@ err2: mpool_put(t->bt_mp, l, 0); * Pointer to page in which to insert or NULL on error. */ static PAGE * -bt_page(t, h, lp, rp, skip, ilen) - BTREE *t; - PAGE *h, **lp, **rp; - indx_t *skip; - size_t ilen; +bt_page(BTREE *t, PAGE *h, PAGE **lp, PAGE **rp, indx_t *skip, size_t ilen) { PAGE *l, *r, *tp; pgno_t npg; @@ -385,13 +372,10 @@ bt_page(t, h, lp, rp, skip, ilen) } /* Put the new left page for the split into place. */ - if ((l = (PAGE *)malloc(t->bt_psize)) == NULL) { + if ((l = (PAGE *)calloc(1, t->bt_psize)) == NULL) { mpool_put(t->bt_mp, r, 0); return (NULL); } -#ifdef PURIFY - memset(l, 0xff, t->bt_psize); -#endif l->pgno = h->pgno; l->nextpg = r->pgno; l->prevpg = h->prevpg; @@ -445,11 +429,7 @@ bt_page(t, h, lp, rp, skip, ilen) * Pointer to page in which to insert or NULL on error. */ static PAGE * -bt_root(t, h, lp, rp, skip, ilen) - BTREE *t; - PAGE *h, **lp, **rp; - indx_t *skip; - size_t ilen; +bt_root(BTREE *t, PAGE *h, PAGE **lp, PAGE **rp, indx_t *skip, size_t ilen) { PAGE *l, *r, *tp; pgno_t lnpg, rnpg; @@ -492,9 +472,7 @@ bt_root(t, h, lp, rp, skip, ilen) * RET_ERROR, RET_SUCCESS */ static int -bt_rroot(t, h, l, r) - BTREE *t; - PAGE *h, *l, *r; +bt_rroot(BTREE *t, PAGE *h, PAGE *l, PAGE *r) { char *dest; @@ -532,9 +510,7 @@ bt_rroot(t, h, l, r) * RET_ERROR, RET_SUCCESS */ static int -bt_broot(t, h, l, r) - BTREE *t; - PAGE *h, *l, *r; +bt_broot(BTREE *t, PAGE *h, PAGE *l, PAGE *r) { BINTERNAL *bi; BLEAF *bl; @@ -609,11 +585,7 @@ bt_broot(t, h, l, r) * Pointer to page in which to insert. */ static PAGE * -bt_psplit(t, h, l, r, pskip, ilen) - BTREE *t; - PAGE *h, *l, *r; - indx_t *pskip; - size_t ilen; +bt_psplit(BTREE *t, PAGE *h, PAGE *l, PAGE *r, indx_t *pskip, size_t ilen) { BINTERNAL *bi; BLEAF *bl; @@ -787,9 +759,7 @@ bt_psplit(t, h, l, r, pskip, ilen) * RET_SUCCESS, RET_ERROR. */ static int -bt_preserve(t, pg) - BTREE *t; - pgno_t pg; +bt_preserve(BTREE *t, pgno_t pg) { PAGE *h; @@ -815,8 +785,7 @@ bt_preserve(t, pg) * all the way back to bt_split/bt_rroot and it's not very clean. */ static recno_t -rec_total(h) - PAGE *h; +rec_total(PAGE *h) { recno_t recs; indx_t nxt, top; diff --git a/db/btree/btree.h b/db/btree/btree.h index 7153fb9..c7c1f0f 100644 --- a/db/btree/btree.h +++ b/db/btree/btree.h @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,7 +30,7 @@ * SUCH DAMAGE. * * @(#)btree.h 8.11 (Berkeley) 8/17/94 - * $FreeBSD: src/lib/libc/db/btree/btree.h,v 1.3 2002/03/22 23:41:40 obrien Exp $ + * $FreeBSD: src/lib/libc/db/btree/btree.h,v 1.5 2009/03/04 00:58:04 delphij Exp $ */ /* Macros to set/clear/test flags. */ @@ -313,8 +309,8 @@ typedef struct _btree { CURSOR bt_cursor; /* cursor */ #define BT_PUSH(t, p, i) { \ - t->bt_sp->pgno = p; \ - t->bt_sp->index = i; \ + t->bt_sp->pgno = p; \ + t->bt_sp->index = i; \ ++t->bt_sp; \ } #define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL : --t->bt_sp) diff --git a/db/hash/FreeBSD/extern.h b/db/hash/FreeBSD/extern.h index 2259ac0..9c0afaf 100644 --- a/db/hash/FreeBSD/extern.h +++ b/db/hash/FreeBSD/extern.h @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -31,7 +27,7 @@ * SUCH DAMAGE. * * @(#)extern.h 8.4 (Berkeley) 6/16/94 - * $FreeBSD: src/lib/libc/db/hash/extern.h,v 1.3 2002/03/22 09:18:22 obrien Exp $ + * $FreeBSD: src/lib/libc/db/hash/extern.h,v 1.4 2007/01/09 00:27:50 imp Exp $ */ BUFHEAD *__add_ovflpage(HTAB *, BUFHEAD *); diff --git a/db/hash/FreeBSD/hash.c b/db/hash/FreeBSD/hash.c index e4d40f9..a353818 100644 --- a/db/hash/FreeBSD/hash.c +++ b/db/hash/FreeBSD/hash.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash.c,v 1.12 2004/09/10 05:41:41 kuriyama Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash.c,v 1.21 2009/03/28 07:20:39 delphij Exp $"); #include "namespace.h" #include @@ -72,7 +68,7 @@ static void *hash_realloc(SEGMENT **, int, int); static int hash_seq(const DB *, DBT *, DBT *, u_int32_t); static int hash_sync(const DB *, u_int32_t); static int hdestroy(HTAB *); -static HTAB *init_hash(HTAB *, const char *, HASHINFO *); +static HTAB *init_hash(HTAB *, const char *, const HASHINFO *); static int init_htab(HTAB *, int); #if BYTE_ORDER == LITTLE_ENDIAN static void swap_header(HTAB *); @@ -96,11 +92,11 @@ int hash_accesses, hash_collisions, hash_expansions, hash_overflows; /************************** INTERFACE ROUTINES ***************************/ /* OPEN/CLOSE */ -extern DB * -__hash_open(file, flags, mode, info, dflags) - const char *file; - int flags, mode, dflags; - const HASHINFO *info; /* Special directives for create */ +/* ARGSUSED */ +DB * +__hash_open(const char *file, int flags, int mode, + const HASHINFO *info, /* Special directives for create */ + int dflags) { HTAB *hashp; struct stat statbuf; @@ -124,27 +120,17 @@ __hash_open(file, flags, mode, info, dflags) */ hashp->flags = flags; - new_table = 0; - if (!file || (flags & O_TRUNC) || - (stat(file, &statbuf) && (errno == ENOENT))) { - if (errno == ENOENT) - errno = 0; /* Just in case someone looks at errno */ - new_table = 1; - } if (file) { if ((hashp->fp = _open(file, flags, mode)) == -1) RETURN_ERROR(errno, error0); - - /* if the .db file is empty, and we had permission to create - a new .db file, then reinitialize the database */ - if ((flags & O_CREAT) && - _fstat(hashp->fp, &statbuf) == 0 && statbuf.st_size == 0) - new_table = 1; - (void)_fcntl(hashp->fp, F_SETFD, 1); - } + new_table = _fstat(hashp->fp, &statbuf) == 0 && + statbuf.st_size == 0 && (flags & O_ACCMODE) != O_RDONLY; + } else + new_table = 1; + if (new_table) { - if (!(hashp = init_hash(hashp, file, (HASHINFO *)info))) + if (!(hashp = init_hash(hashp, file, info))) RETURN_ERROR(errno, error1); } else { /* Table already exists */ @@ -168,7 +154,7 @@ __hash_open(file, flags, mode, info, dflags) if (hashp->VERSION != HASHVERSION && hashp->VERSION != OLDHASHVERSION) RETURN_ERROR(EFTYPE, error1); - if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY) + if ((int32_t)hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY) RETURN_ERROR(EFTYPE, error1); /* * Figure out how many segments we need. Max_Bucket is the @@ -177,7 +163,6 @@ __hash_open(file, flags, mode, info, dflags) */ nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) / hashp->SGSIZE; - hashp->nsegs = 0; if (alloc_segs(hashp, nsegs)) /* * If alloc_segs fails, table will have been destroyed @@ -253,8 +238,7 @@ error0: } static int -hash_close(dbp) - DB *dbp; +hash_close(DB *dbp) { HTAB *hashp; int retval; @@ -269,8 +253,7 @@ hash_close(dbp) } static int -hash_fd(dbp) - const DB *dbp; +hash_fd(const DB *dbp) { HTAB *hashp; @@ -287,10 +270,7 @@ hash_fd(dbp) /************************** LOCAL CREATION ROUTINES **********************/ static HTAB * -init_hash(hashp, file, info) - HTAB *hashp; - const char *file; - HASHINFO *info; +init_hash(HTAB *hashp, const char *file, const HASHINFO *info) { struct stat statbuf; int nelem; @@ -354,12 +334,9 @@ init_hash(hashp, file, info) * Returns 0 on No Error */ static int -init_htab(hashp, nelem) - HTAB *hashp; - int nelem; +init_htab(HTAB *hashp, int nelem) { - int nbuckets, nsegs; - int l2; + int nbuckets, nsegs, l2; /* * Divide number of elements by the fill factor and determine a @@ -400,8 +377,7 @@ init_htab(hashp, nelem) * structure, freeing all allocated space. */ static int -hdestroy(hashp) - HTAB *hashp; +hdestroy(HTAB *hashp) { int i, save_errno; @@ -440,6 +416,10 @@ hdestroy(hashp) for (i = 0; i < hashp->nmaps; i++) if (hashp->mapp[i]) free(hashp->mapp[i]); + if (hashp->tmp_key) + free(hashp->tmp_key); + if (hashp->tmp_buf) + free(hashp->tmp_buf); if (hashp->fp != -1) (void)_close(hashp->fp); @@ -460,9 +440,7 @@ hdestroy(hashp) * -1 ERROR */ static int -hash_sync(dbp, flags) - const DB *dbp; - u_int32_t flags; +hash_sync(const DB *dbp, u_int32_t flags) { HTAB *hashp; @@ -489,8 +467,7 @@ hash_sync(dbp, flags) * -1 indicates that errno should be set */ static int -flush_meta(hashp) - HTAB *hashp; +flush_meta(HTAB *hashp) { HASHHDR *whdrp; #if BYTE_ORDER == LITTLE_ENDIAN @@ -510,8 +487,7 @@ flush_meta(hashp) whdrp = &whdr; swap_header_copy(&hashp->hdr, whdrp); #endif - if ((lseek(fp, (off_t)0, SEEK_SET) == -1) || - ((wsize = _write(fp, whdrp, sizeof(HASHHDR))) == -1)) + if ((wsize = pwrite(fp, whdrp, sizeof(HASHHDR), (off_t)0)) == -1) return (-1); else if (wsize != sizeof(HASHHDR)) { @@ -537,11 +513,7 @@ flush_meta(hashp) * -1 to indicate an internal ERROR (i.e. out of memory, etc) */ static int -hash_get(dbp, key, data, flag) - const DB *dbp; - const DBT *key; - DBT *data; - u_int32_t flag; +hash_get(const DB *dbp, const DBT *key, DBT *data, u_int32_t flag) { HTAB *hashp; @@ -554,18 +526,13 @@ hash_get(dbp, key, data, flag) } static int -hash_put(dbp, key, data, flag) - const DB *dbp; - DBT *key; - const DBT *data; - u_int32_t flag; +hash_put(const DB *dbp, DBT *key, const DBT *data, u_int32_t flag) { HTAB *hashp; hashp = (HTAB *)dbp->internal; if (flag && flag != R_NOOVERWRITE) { - hashp->error = EINVAL; - errno = EINVAL; + hashp->error = errno = EINVAL; return (ERROR); } if ((hashp->flags & O_ACCMODE) == O_RDONLY) { @@ -577,10 +544,8 @@ hash_put(dbp, key, data, flag) } static int -hash_delete(dbp, key, flag) - const DB *dbp; - const DBT *key; - u_int32_t flag; /* Ignored */ +hash_delete(const DB *dbp, const DBT *key, + u_int32_t flag) /* Ignored */ { HTAB *hashp; @@ -600,10 +565,7 @@ hash_delete(dbp, key, flag) * Assume that hashp has been set in wrapper routine. */ static int -hash_access(hashp, action, key, val) - HTAB *hashp; - ACTION action; - DBT *key, *val; +hash_access(HTAB *hashp, ACTION action, DBT *key, DBT *val) { BUFHEAD *rbufp; BUFHEAD *bufp, *save_bufp; @@ -729,10 +691,7 @@ found: } static int -hash_seq(dbp, key, data, flag) - const DB *dbp; - DBT *key, *data; - u_int32_t flag; +hash_seq(const DB *dbp, DBT *key, DBT *data, u_int32_t flag) { u_int32_t bucket; BUFHEAD *bufp; @@ -752,7 +711,7 @@ hash_seq(dbp, key, data, flag) hashp->cndx = 1; hashp->cpage = NULL; } - + next_bucket: for (bp = NULL; !bp || !bp[0]; ) { if (!(bufp = hashp->cpage)) { for (bucket = hashp->cbucket; @@ -767,12 +726,22 @@ hash_seq(dbp, key, data, flag) break; } hashp->cbucket = bucket; - if (hashp->cbucket > hashp->MAX_BUCKET) { + if ((u_int32_t)hashp->cbucket > hashp->MAX_BUCKET) { hashp->cbucket = -1; return (ABNORMAL); } - } else + } else { bp = (u_int16_t *)hashp->cpage->page; + if (flag == R_NEXT) { + hashp->cndx += 2; + if (hashp->cndx > bp[0]) { + hashp->cpage = NULL; + hashp->cbucket++; + hashp->cndx = 1; + goto next_bucket; + } + } + } #ifdef DEBUG assert(bp); @@ -796,17 +765,12 @@ hash_seq(dbp, key, data, flag) if (__big_keydata(hashp, bufp, key, data, 1)) return (ERROR); } else { + if (hashp->cpage == 0) + return (ERROR); key->data = (u_char *)hashp->cpage->page + bp[ndx]; key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx]; data->data = (u_char *)hashp->cpage->page + bp[ndx + 1]; data->size = bp[ndx] - bp[ndx + 1]; - ndx += 2; - if (ndx > bp[0]) { - hashp->cpage = NULL; - hashp->cbucket++; - hashp->cndx = 1; - } else - hashp->cndx = ndx; } return (SUCCESS); } @@ -818,9 +782,8 @@ hash_seq(dbp, key, data, flag) * 0 ==> OK * -1 ==> Error */ -extern int -__expand_table(hashp) - HTAB *hashp; +int +__expand_table(HTAB *hashp) { u_int32_t old_bucket, new_bucket; int dirsize, new_segnum, spare_ndx; @@ -874,9 +837,7 @@ __expand_table(hashp) * fails, then this routine can go away. */ static void * -hash_realloc(p_ptr, oldsize, newsize) - SEGMENT **p_ptr; - int oldsize, newsize; +hash_realloc(SEGMENT **p_ptr, int oldsize, int newsize) { void *p; @@ -889,13 +850,10 @@ hash_realloc(p_ptr, oldsize, newsize) return (p); } -extern u_int32_t -__call_hash(hashp, k, len) - HTAB *hashp; - char *k; - int len; +u_int32_t +__call_hash(HTAB *hashp, char *k, int len) { - int n, bucket; + unsigned int n, bucket; n = hashp->hash(k, len); bucket = n & hashp->HIGH_MASK; @@ -910,9 +868,7 @@ __call_hash(hashp, k, len) * Returns 0 on success */ static int -alloc_segs(hashp, nsegs) - HTAB *hashp; - int nsegs; +alloc_segs(HTAB *hashp, int nsegs) { int i; SEGMENT store; @@ -926,15 +882,18 @@ alloc_segs(hashp, nsegs) errno = save_errno; return (-1); } + hashp->nsegs = nsegs; + if (nsegs == 0) + return (0); /* Allocate segments */ - if ((store = - (SEGMENT)calloc(nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) { + if ((store = (SEGMENT)calloc(nsegs << hashp->SSHIFT, + sizeof(SEGMENT))) == NULL) { save_errno = errno; (void)hdestroy(hashp); errno = save_errno; return (-1); } - for (i = 0; i < nsegs; i++, hashp->nsegs++) + for (i = 0; i < nsegs; i++) hashp->dir[i] = &store[i << hashp->SSHIFT]; return (0); } @@ -944,8 +903,7 @@ alloc_segs(hashp, nsegs) * Hashp->hdr needs to be byteswapped. */ static void -swap_header_copy(srcp, destp) - HASHHDR *srcp, *destp; +swap_header_copy(HASHHDR *srcp, HASHHDR *destp) { int i; @@ -973,8 +931,7 @@ swap_header_copy(srcp, destp) } static void -swap_header(hashp) - HTAB *hashp; +swap_header(HTAB *hashp) { HASHHDR *hdrp; int i; diff --git a/db/hash/FreeBSD/hash.c.patch b/db/hash/FreeBSD/hash.c.patch index 425c032..9533941 100644 --- a/db/hash/FreeBSD/hash.c.patch +++ b/db/hash/FreeBSD/hash.c.patch @@ -1,6 +1,6 @@ ---- hash.c.orig 2008-09-07 11:37:54.000000000 -0700 -+++ hash.c 2008-09-07 12:42:15.000000000 -0700 -@@ -58,7 +58,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash +--- hash.c.orig 2009-11-06 12:41:16.000000000 -0800 ++++ hash.c 2009-11-06 12:41:27.000000000 -0800 +@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash #include #include "hash.h" #include "page.h" @@ -9,7 +9,7 @@ static int alloc_segs(HTAB *, int); static int flush_meta(HTAB *); -@@ -108,8 +108,7 @@ __hash_open(file, flags, mode, info, dfl +@@ -104,8 +104,7 @@ __hash_open(const char *file, int flags, int bpages, hdrsize, new_table, nsegs, save_errno; if ((flags & O_ACCMODE) == O_WRONLY) { @@ -19,7 +19,7 @@ } if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB)))) -@@ -722,7 +721,7 @@ found: +@@ -684,7 +683,7 @@ found: return (ERROR); break; default: diff --git a/db/hash/FreeBSD/hash.h b/db/hash/FreeBSD/hash.h index 33fefa7..f8ea5ca 100644 --- a/db/hash/FreeBSD/hash.h +++ b/db/hash/FreeBSD/hash.h @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,7 +30,7 @@ * SUCH DAMAGE. * * @(#)hash.h 8.3 (Berkeley) 5/31/94 - * $FreeBSD: src/lib/libc/db/hash/hash.h,v 1.6 2002/03/21 22:46:26 obrien Exp $ + * $FreeBSD: src/lib/libc/db/hash/hash.h,v 1.9 2009/03/28 05:45:29 delphij Exp $ */ /* Operations */ @@ -64,28 +60,28 @@ typedef BUFHEAD **SEGMENT; /* Hash Table Information */ typedef struct hashhdr { /* Disk resident portion */ - int magic; /* Magic NO for hash tables */ - int version; /* Version ID */ + int32_t magic; /* Magic NO for hash tables */ + int32_t version; /* Version ID */ u_int32_t lorder; /* Byte Order */ - int bsize; /* Bucket/Page Size */ - int bshift; /* Bucket shift */ - int dsize; /* Directory Size */ - int ssize; /* Segment Size */ - int sshift; /* Segment shift */ - int ovfl_point; /* Where overflow pages are being + int32_t bsize; /* Bucket/Page Size */ + int32_t bshift; /* Bucket shift */ + int32_t dsize; /* Directory Size */ + int32_t ssize; /* Segment Size */ + int32_t sshift; /* Segment shift */ + int32_t ovfl_point; /* Where overflow pages are being * allocated */ - int last_freed; /* Last overflow page freed */ - int max_bucket; /* ID of Maximum bucket in use */ - int high_mask; /* Mask to modulo into entire table */ - int low_mask; /* Mask to modulo into lower half of + int32_t last_freed; /* Last overflow page freed */ + u_int32_t max_bucket; /* ID of Maximum bucket in use */ + u_int32_t high_mask; /* Mask to modulo into entire table */ + u_int32_t low_mask; /* Mask to modulo into lower half of * table */ - int ffactor; /* Fill factor */ - int nkeys; /* Number of keys in hash table */ - int hdrpages; /* Size of table header */ - int h_charkey; /* value of hash(CHARKEY) */ + u_int32_t ffactor; /* Fill factor */ + int32_t nkeys; /* Number of keys in hash table */ + int32_t hdrpages; /* Size of table header */ + int32_t h_charkey; /* value of hash(CHARKEY) */ #define NCACHED 32 /* number of bit maps and spare * points */ - int spares[NCACHED];/* spare pages for overflow */ + int32_t spares[NCACHED];/* spare pages for overflow */ u_int16_t bitmaps[NCACHED]; /* address of overflow page * bitmaps */ } HASHHDR; diff --git a/db/hash/FreeBSD/hash.h.patch b/db/hash/FreeBSD/hash.h.patch index 3a8d49a..efe6e7d 100644 --- a/db/hash/FreeBSD/hash.h.patch +++ b/db/hash/FreeBSD/hash.h.patch @@ -1,6 +1,6 @@ ---- hash.h.orig 2003-10-22 19:07:01.000000000 -0700 -+++ hash.h 2004-10-23 22:52:09.000000000 -0700 -@@ -117,6 +117,8 @@ +--- hash.h.orig 2009-11-06 12:41:16.000000000 -0800 ++++ hash.h 2009-11-06 12:41:27.000000000 -0800 +@@ -113,6 +113,8 @@ typedef struct htab { /* Memory reside * allocate */ BUFHEAD bufhead; /* Header of buffer lru list */ SEGMENT *dir; /* Hash Bucket directory */ diff --git a/db/hash/FreeBSD/hash_bigkey.c b/db/hash/FreeBSD/hash_bigkey.c index 487df5b..de8180e 100644 --- a/db/hash/FreeBSD/hash_bigkey.c +++ b/db/hash/FreeBSD/hash_bigkey.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_bigkey.c,v 1.5 2003/02/16 17:29:09 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_bigkey.c,v 1.10 2009/03/28 06:47:05 delphij Exp $"); /* * PACKAGE: hash @@ -86,14 +82,12 @@ static int collect_data(HTAB *, BUFHEAD *, int, int); * 0 ==> OK *-1 ==> ERROR */ -extern int -__big_insert(hashp, bufp, key, val) - HTAB *hashp; - BUFHEAD *bufp; - const DBT *key, *val; +int +__big_insert(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val) { u_int16_t *p; - int key_size, n, val_size; + int key_size, n; + unsigned int val_size; u_int16_t space, move_bytes, off; char *cp, *key_data, *val_data; @@ -124,18 +118,30 @@ __big_insert(hashp, bufp, key, val) return (-1); n = p[0]; if (!key_size) { - if (FREESPACE(p)) { - move_bytes = MIN(FREESPACE(p), val_size); + space = FREESPACE(p); + if (space) { + move_bytes = MIN(space, val_size); + /* + * If the data would fit exactly in the + * remaining space, we must overflow it to the + * next page; otherwise the invariant that the + * data must end on a page with FREESPACE + * non-zero would fail. + */ + if (space == val_size && val_size == val->size) + goto toolarge; off = OFFSET(p) - move_bytes; - p[n] = off; memmove(cp + off, val_data, move_bytes); val_data += move_bytes; val_size -= move_bytes; + p[n] = off; p[n - 2] = FULL_KEY_DATA; FREESPACE(p) = FREESPACE(p) - move_bytes; OFFSET(p) = off; - } else + } else { + toolarge: p[n - 2] = FULL_KEY; + } } p = (u_int16_t *)bufp->page; cp = bufp->page; @@ -186,10 +192,8 @@ __big_insert(hashp, bufp, key, val) * 0 => OK *-1 => ERROR */ -extern int -__big_delete(hashp, bufp) - HTAB *hashp; - BUFHEAD *bufp; +int +__big_delete(HTAB *hashp, BUFHEAD *bufp) { BUFHEAD *last_bfp, *rbufp; u_int16_t *bp, pageno; @@ -247,12 +251,12 @@ __big_delete(hashp, bufp) n -= 2; bp[0] = n; FREESPACE(bp) = hashp->BSIZE - PAGE_META(n); - OFFSET(bp) = hashp->BSIZE - 1; + OFFSET(bp) = hashp->BSIZE; bufp->flags |= BUF_MOD; if (rbufp) __free_ovflpage(hashp, rbufp); - if (last_bfp != rbufp) + if (last_bfp && last_bfp != rbufp) __free_ovflpage(hashp, last_bfp); hashp->NKEYS--; @@ -265,13 +269,8 @@ __big_delete(hashp, bufp) * -2 means key not found and this is big key/data * -3 error */ -extern int -__find_bigpair(hashp, bufp, ndx, key, size) - HTAB *hashp; - BUFHEAD *bufp; - int ndx; - char *key; - int size; +int +__find_bigpair(HTAB *hashp, BUFHEAD *bufp, int ndx, char *key, int size) { u_int16_t *bp; char *p; @@ -317,10 +316,8 @@ __find_bigpair(hashp, bufp, ndx, key, size) * of the pair; 0 if there isn't any (i.e. big pair is the last key in the * bucket) */ -extern u_int16_t -__find_last_page(hashp, bpp) - HTAB *hashp; - BUFHEAD **bpp; +u_int16_t +__find_last_page(HTAB *hashp, BUFHEAD **bpp) { BUFHEAD *bufp; u_int16_t *bp, pageno; @@ -358,13 +355,8 @@ __find_last_page(hashp, bpp) * Return the data for the key/data pair that begins on this page at this * index (index should always be 1). */ -extern int -__big_return(hashp, bufp, ndx, val, set_current) - HTAB *hashp; - BUFHEAD *bufp; - int ndx; - DBT *val; - int set_current; +int +__big_return(HTAB *hashp, BUFHEAD *bufp, int ndx, DBT *val, int set_current) { BUFHEAD *save_p; u_int16_t *bp, len, off, save_addr; @@ -433,8 +425,8 @@ __big_return(hashp, bufp, ndx, val, set_current) return (0); } - val->size = collect_data(hashp, bufp, (int)len, set_current); - if (val->size == -1) + val->size = (size_t)collect_data(hashp, bufp, (int)len, set_current); + if (val->size == (size_t)-1) return (-1); if (save_p->addr != save_addr) { /* We are pretty short on buffers. */ @@ -450,10 +442,7 @@ __big_return(hashp, bufp, ndx, val, set_current) * allocate a buffer and copy the data as you recurse up. */ static int -collect_data(hashp, bufp, len, set) - HTAB *hashp; - BUFHEAD *bufp; - int len, set; +collect_data(HTAB *hashp, BUFHEAD *bufp, int len, int set) { u_int16_t *bp; char *p; @@ -505,15 +494,11 @@ collect_data(hashp, bufp, len, set) /* * Fill in the key and data for this big pair. */ -extern int -__big_keydata(hashp, bufp, key, val, set) - HTAB *hashp; - BUFHEAD *bufp; - DBT *key, *val; - int set; +int +__big_keydata(HTAB *hashp, BUFHEAD *bufp, DBT *key, DBT *val, int set) { - key->size = collect_key(hashp, bufp, 0, val, set); - if (key->size == -1) + key->size = (size_t)collect_key(hashp, bufp, 0, val, set); + if (key->size == (size_t)-1) return (-1); key->data = (u_char *)hashp->tmp_key; return (0); @@ -524,12 +509,7 @@ __big_keydata(hashp, bufp, key, val, set) * collect the data, allocate a buffer and copy the key as you recurse up. */ static int -collect_key(hashp, bufp, len, val, set) - HTAB *hashp; - BUFHEAD *bufp; - int len; - DBT *val; - int set; +collect_key(HTAB *hashp, BUFHEAD *bufp, int len, DBT *val, int set) { BUFHEAD *xbp; char *p; @@ -568,23 +548,19 @@ collect_key(hashp, bufp, len, val, set) * 0 => OK * -1 => error */ -extern int -__big_split(hashp, op, np, big_keyp, addr, obucket, ret) - HTAB *hashp; - BUFHEAD *op; /* Pointer to where to put keys that go in old bucket */ - BUFHEAD *np; /* Pointer to new bucket page */ - /* Pointer to first page containing the big key/data */ - BUFHEAD *big_keyp; - int addr; /* Address of big_keyp */ - u_int32_t obucket;/* Old Bucket */ - SPLIT_RETURN *ret; +int +__big_split(HTAB *hashp, + BUFHEAD *op, /* Pointer to where to put keys that go in old bucket */ + BUFHEAD *np, /* Pointer to new bucket page */ + BUFHEAD *big_keyp, /* Pointer to first page containing the big key/data */ + int addr, /* Address of big_keyp */ + u_int32_t obucket, /* Old Bucket */ + SPLIT_RETURN *ret) { - BUFHEAD *tmpp; - u_int16_t *tp; - BUFHEAD *bp; + BUFHEAD *bp, *tmpp; DBT key, val; u_int32_t change; - u_int16_t free_space, n, off; + u_int16_t free_space, n, off, *tp; bp = big_keyp; @@ -596,7 +572,7 @@ __big_split(hashp, op, np, big_keyp, addr, obucket, ret) if ( (ret->next_addr = __find_last_page(hashp, &big_keyp)) ) { if (!(ret->nextp = __get_buf(hashp, ret->next_addr, big_keyp, 0))) - return (-1);; + return (-1); } else ret->nextp = NULL; diff --git a/db/hash/FreeBSD/hash_bigkey.c.patch b/db/hash/FreeBSD/hash_bigkey.c.patch index 64e0c6c..54a30d8 100644 --- a/db/hash/FreeBSD/hash_bigkey.c.patch +++ b/db/hash/FreeBSD/hash_bigkey.c.patch @@ -1,6 +1,6 @@ ---- hash_bigkey.c.orig Sun Feb 16 09:29:09 2003 -+++ hash_bigkey.c Sat Oct 18 18:30:43 2003 -@@ -72,7 +72,7 @@ +--- hash_bigkey.c.orig 2009-11-06 12:41:16.000000000 -0800 ++++ hash_bigkey.c 2009-11-06 12:41:27.000000000 -0800 +@@ -68,7 +68,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash #include #include "hash.h" #include "page.h" diff --git a/db/hash/FreeBSD/hash_buf.c b/db/hash/FreeBSD/hash_buf.c index 2a81cb6..62117c9 100644 --- a/db/hash/FreeBSD/hash_buf.c +++ b/db/hash/FreeBSD/hash_buf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_buf.c,v 1.7 2002/03/21 22:46:26 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_buf.c,v 1.12 2009/03/28 06:40:48 delphij Exp $"); /* * PACKAGE: hash @@ -61,6 +57,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_buf.c,v 1.7 2002/03/21 22:46:26 ob #include #include #include +#include #ifdef DEBUG #include @@ -102,12 +99,10 @@ static BUFHEAD *newbuf(HTAB *, u_int32_t, BUFHEAD *); * be valid. Therefore, you must always verify that its address matches the * address you are seeking. */ -extern BUFHEAD * -__get_buf(hashp, addr, prev_bp, newpage) - HTAB *hashp; - u_int32_t addr; - BUFHEAD *prev_bp; - int newpage; /* If prev_bp set, indicates a new overflow page. */ +BUFHEAD * +__get_buf(HTAB *hashp, u_int32_t addr, + BUFHEAD *prev_bp, /* If prev_bp set, indicates a new overflow page. */ + int newpage) { BUFHEAD *bp; u_int32_t is_disk_mask; @@ -158,10 +153,7 @@ __get_buf(hashp, addr, prev_bp, newpage) * If newbuf finds an error (returning NULL), it also sets errno. */ static BUFHEAD * -newbuf(hashp, addr, prev_bp) - HTAB *hashp; - u_int32_t addr; - BUFHEAD *prev_bp; +newbuf(HTAB *hashp, u_int32_t addr, BUFHEAD *prev_bp) { BUFHEAD *bp; /* The buffer we're going to use */ BUFHEAD *xbp; /* Temp pointer */ @@ -172,24 +164,38 @@ newbuf(hashp, addr, prev_bp) oaddr = 0; bp = LRU; + + /* It is bad to overwrite the page under the cursor. */ + if (bp == hashp->cpage) { + BUF_REMOVE(bp); + MRU_INSERT(bp); + bp = LRU; + } + + /* If prev_bp is part of bp overflow, create a new buffer. */ + if (hashp->nbufs == 0 && prev_bp && bp->ovfl) { + BUFHEAD *ovfl; + + for (ovfl = bp->ovfl; ovfl ; ovfl = ovfl->ovfl) { + if (ovfl == prev_bp) { + hashp->nbufs++; + break; + } + } + } + /* * If LRU buffer is pinned, the buffer pool is too small. We need to * allocate more buffers. */ - if (hashp->nbufs || (bp->flags & BUF_PIN)) { + if (hashp->nbufs || (bp->flags & BUF_PIN) || bp == hashp->cpage) { /* Allocate a new one */ - if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL) + if ((bp = (BUFHEAD *)calloc(1, sizeof(BUFHEAD))) == NULL) return (NULL); -#ifdef PURIFY - memset(bp, 0xff, sizeof(BUFHEAD)); -#endif - if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) { + if ((bp->page = (char *)calloc(1, hashp->BSIZE)) == NULL) { free(bp); return (NULL); } -#ifdef PURIFY - memset(bp->page, 0xff, hashp->BSIZE); -#endif if (hashp->nbufs) hashp->nbufs--; } else { @@ -276,7 +282,7 @@ newbuf(hashp, addr, prev_bp) */ #ifdef DEBUG1 (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n", - prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0), + prev_bp->addr, (prev_bp->ovfl ? prev_bp->ovfl->addr : 0), (bp ? bp->addr : 0)); #endif prev_bp->ovfl = bp; @@ -287,10 +293,8 @@ newbuf(hashp, addr, prev_bp) return (bp); } -extern void -__buf_init(hashp, nbytes) - HTAB *hashp; - int nbytes; +void +__buf_init(HTAB *hashp, int nbytes) { BUFHEAD *bfp; int npages; @@ -312,10 +316,8 @@ __buf_init(hashp, nbytes) */ } -extern int -__buf_free(hashp, do_free, to_disk) - HTAB *hashp; - int do_free, to_disk; +int +__buf_free(HTAB *hashp, int do_free, int to_disk) { BUFHEAD *bp; @@ -332,8 +334,10 @@ __buf_free(hashp, do_free, to_disk) } /* Check if we are freeing stuff */ if (do_free) { - if (bp->page) + if (bp->page) { + (void)memset(bp->page, 0, hashp->BSIZE); free(bp->page); + } BUF_REMOVE(bp); free(bp); bp = LRU; @@ -343,10 +347,8 @@ __buf_free(hashp, do_free, to_disk) return (0); } -extern void -__reclaim_buf(hashp, bp) - HTAB *hashp; - BUFHEAD *bp; +void +__reclaim_buf(HTAB *hashp, BUFHEAD *bp) { bp->ovfl = 0; bp->addr = 0; diff --git a/db/hash/FreeBSD/hash_buf.c.patch b/db/hash/FreeBSD/hash_buf.c.patch index 5431734..11e5799 100644 --- a/db/hash/FreeBSD/hash_buf.c.patch +++ b/db/hash/FreeBSD/hash_buf.c.patch @@ -1,6 +1,6 @@ ---- hash_buf.c.orig Thu Mar 21 14:46:26 2002 -+++ hash_buf.c Sat Oct 18 18:30:49 2003 -@@ -69,7 +69,7 @@ +--- hash_buf.c (revision 61187) ++++ hash_buf.c (working copy) +@@ -66,7 +66,7 @@ #include #include "hash.h" #include "page.h" @@ -9,3 +9,12 @@ static BUFHEAD *newbuf(HTAB *, u_int32_t, BUFHEAD *); +@@ -293,7 +293,7 @@ + return (bp); + } + +-void ++__private_extern__ void + __buf_init(HTAB *hashp, int nbytes) + { + BUFHEAD *bfp; diff --git a/db/hash/FreeBSD/hash_func.c b/db/hash/FreeBSD/hash_func.c index d46d620..88d21f7 100644 --- a/db/hash/FreeBSD/hash_func.c +++ b/db/hash/FreeBSD/hash_func.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_func.c,v 1.5 2003/02/16 17:29:09 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_func.c,v 1.6 2007/01/09 00:27:50 imp Exp $"); #include diff --git a/db/hash/FreeBSD/hash_func.c.patch b/db/hash/FreeBSD/hash_func.c.patch index 16336d9..db68d77 100644 --- a/db/hash/FreeBSD/hash_func.c.patch +++ b/db/hash/FreeBSD/hash_func.c.patch @@ -1,6 +1,6 @@ ---- hash_func.c.orig Sun Feb 16 09:29:09 2003 -+++ hash_func.c Sat Oct 18 18:30:57 2003 -@@ -45,7 +45,7 @@ +--- hash_func.c.orig 2009-11-06 12:41:16.000000000 -0800 ++++ hash_func.c 2009-11-06 12:41:27.000000000 -0800 +@@ -41,7 +41,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash #include #include "hash.h" #include "page.h" diff --git a/db/hash/FreeBSD/hash_log2.c b/db/hash/FreeBSD/hash_log2.c index 827dbef..6f8b522 100644 --- a/db/hash/FreeBSD/hash_log2.c +++ b/db/hash/FreeBSD/hash_log2.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,15 +34,15 @@ static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_log2.c,v 1.2 2002/03/21 18:47:38 obrien Exp $"); - -#include +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_log2.c,v 1.5 2009/03/28 05:45:29 delphij Exp $"); #include +#include "hash.h" +#include "page.h" +#include "extern.h" u_int32_t -__log2(num) - u_int32_t num; +__log2(u_int32_t num) { u_int32_t i, limit; diff --git a/db/hash/FreeBSD/hash_log2.c.patch b/db/hash/FreeBSD/hash_log2.c.patch new file mode 100644 index 0000000..056340a --- /dev/null +++ b/db/hash/FreeBSD/hash_log2.c.patch @@ -0,0 +1,11 @@ +--- hash_log2.c.orig 2009-11-06 14:27:02.000000000 -0800 ++++ hash_log2.c 2009-11-06 14:27:42.000000000 -0800 +@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash + #include + #include "hash.h" + #include "page.h" +-#include "extern.h" ++#include "hash_extern.h" + + u_int32_t + __log2(u_int32_t num) diff --git a/db/hash/FreeBSD/hash_page.c b/db/hash/FreeBSD/hash_page.c index 8c4b0b5..1f44bde 100644 --- a/db/hash/FreeBSD/hash_page.c +++ b/db/hash/FreeBSD/hash_page.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_page.c,v 1.8 2002/03/21 22:46:26 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_page.c,v 1.16 2009/03/28 06:30:43 delphij Exp $"); /* * PACKAGE: hashing @@ -57,7 +53,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_page.c,v 1.8 2002/03/21 22:46:26 o */ #include "namespace.h" -#include +#include #include #include @@ -76,14 +72,13 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_page.c,v 1.8 2002/03/21 22:46:26 o #include "page.h" #include "extern.h" -static u_int32_t *fetch_bitmap(HTAB *, int); -static u_int32_t first_free(u_int32_t); -static int open_temp(HTAB *); -static u_int16_t overflow_page(HTAB *); -static void putpair(char *, const DBT *, const DBT *); -static void squeeze_key(u_int16_t *, const DBT *, const DBT *); -static int ugly_split -(HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int); +static u_int32_t *fetch_bitmap(HTAB *, int); +static u_int32_t first_free(u_int32_t); +static int open_temp(HTAB *); +static u_int16_t overflow_page(HTAB *); +static void putpair(char *, const DBT *, const DBT *); +static void squeeze_key(u_int16_t *, const DBT *, const DBT *); +static int ugly_split(HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int); #define PAGE_INIT(P) { \ ((u_int16_t *)(P))[0] = 0; \ @@ -97,9 +92,7 @@ static int ugly_split * stuff on. */ static void -putpair(p, key, val) - char *p; - const DBT *key, *val; +putpair(char *p, const DBT *key, const DBT *val) { u_int16_t *bp, n, off; @@ -128,15 +121,11 @@ putpair(p, key, val) * 0 OK * -1 error */ -extern int -__delpair(hashp, bufp, ndx) - HTAB *hashp; - BUFHEAD *bufp; - int ndx; +int +__delpair(HTAB *hashp, BUFHEAD *bufp, int ndx) { - u_int16_t *bp, newoff; + u_int16_t *bp, newoff, pairlen; int n; - u_int16_t pairlen; bp = (u_int16_t *)bufp->page; n = bp[0]; @@ -166,6 +155,14 @@ __delpair(hashp, bufp, ndx) bp[i - 1] = bp[i + 1] + pairlen; } } + if (ndx == hashp->cndx) { + /* + * We just removed pair we were "pointing" to. + * By moving back the cndx we ensure subsequent + * hash_seq() calls won't skip over any entries. + */ + hashp->cndx -= 2; + } } /* Finally adjust the page data */ bp[n] = OFFSET(bp) + pairlen; @@ -181,10 +178,8 @@ __delpair(hashp, bufp, ndx) * 0 ==> OK * -1 ==> Error */ -extern int -__split_page(hashp, obucket, nbucket) - HTAB *hashp; - u_int32_t obucket, nbucket; +int +__split_page(HTAB *hashp, u_int32_t obucket, u_int32_t nbucket) { BUFHEAD *new_bufp, *old_bufp; u_int16_t *ino; @@ -278,17 +273,17 @@ __split_page(hashp, obucket, nbucket) * -1 ==> failure */ static int -ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) - HTAB *hashp; - u_int32_t obucket; /* Same as __split_page. */ - BUFHEAD *old_bufp, *new_bufp; - int copyto; /* First byte on page which contains key/data values. */ - int moved; /* Number of pairs moved to new page. */ +ugly_split(HTAB *hashp, + u_int32_t obucket, /* Same as __split_page. */ + BUFHEAD *old_bufp, + BUFHEAD *new_bufp, + int copyto, /* First byte on page which contains key/data values. */ + int moved) /* Number of pairs moved to new page. */ { - BUFHEAD *bufp; /* Buffer header for ino */ - u_int16_t *ino; /* Page keys come off of */ - u_int16_t *np; /* New page */ - u_int16_t *op; /* Page keys go on to if they aren't moving */ + BUFHEAD *bufp; /* Buffer header for ino */ + u_int16_t *ino; /* Page keys come off of */ + u_int16_t *np; /* New page */ + u_int16_t *op; /* Page keys go on to if they aren't moving */ BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */ DBT key, val; @@ -398,11 +393,8 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) * 0 ==> OK * 1 ==> failure */ -extern int -__addel(hashp, bufp, key, val) - HTAB *hashp; - BUFHEAD *bufp; - const DBT *key, *val; +int +__addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val) { u_int16_t *bp, *sop; int do_expand; @@ -420,17 +412,22 @@ __addel(hashp, bufp, key, val) if (!bufp) return (-1); bp = (u_int16_t *)bufp->page; - } else + } else if (bp[bp[0]] != OVFLPAGE) { + /* Short key/data pairs, no more pages */ + break; + } else { /* Try to squeeze key on this page */ - if (FREESPACE(bp) > PAIRSIZE(key, val)) { + if (bp[2] >= REAL_KEY && + FREESPACE(bp) >= PAIRSIZE(key, val)) { squeeze_key(bp, key, val); - return (0); + goto stats; } else { bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); if (!bufp) return (-1); bp = (u_int16_t *)bufp->page; } + } if (PAIRFITS(bp, key, val)) putpair(bufp->page, key, val); @@ -447,6 +444,7 @@ __addel(hashp, bufp, key, val) if (__big_insert(hashp, bufp, key, val)) return (-1); } +stats: bufp->flags |= BUF_MOD; /* * If the average number of keys per bucket exceeds the fill factor, @@ -465,13 +463,10 @@ __addel(hashp, bufp, key, val) * pointer on success * NULL on error */ -extern BUFHEAD * -__add_ovflpage(hashp, bufp) - HTAB *hashp; - BUFHEAD *bufp; +BUFHEAD * +__add_ovflpage(HTAB *hashp, BUFHEAD *bufp) { - u_int16_t *sp; - u_int16_t ndx, ovfl_num; + u_int16_t *sp, ndx, ovfl_num; #ifdef DEBUG1 int tmp1, tmp2; #endif @@ -518,15 +513,11 @@ __add_ovflpage(hashp, bufp) * 0 indicates SUCCESS * -1 indicates FAILURE */ -extern int -__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap) - HTAB *hashp; - char *p; - u_int32_t bucket; - int is_bucket, is_disk, is_bitmap; +int +__get_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_disk, + int is_bitmap) { - int fd, page, size; - int rsize; + int fd, page, size, rsize; u_int16_t *bp; fd = hashp->fp; @@ -540,8 +531,7 @@ __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap) page = BUCKET_TO_PAGE(bucket); else page = OADDR_TO_PAGE(bucket); - if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) || - ((rsize = _read(fd, p, size)) == -1)) + if ((rsize = pread(fd, p, size, (off_t)page << hashp->BSHIFT)) == -1) return (-1); bp = (u_int16_t *)p; if (!rsize) @@ -578,15 +568,10 @@ __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap) * 0 ==> OK * -1 ==>failure */ -extern int -__put_page(hashp, p, bucket, is_bucket, is_bitmap) - HTAB *hashp; - char *p; - u_int32_t bucket; - int is_bucket, is_bitmap; +int +__put_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_bitmap) { - int fd, page, size; - int wsize; + int fd, page, size, wsize; size = hashp->BSIZE; if ((hashp->fp == -1) && open_temp(hashp)) @@ -594,8 +579,7 @@ __put_page(hashp, p, bucket, is_bucket, is_bitmap) fd = hashp->fp; if (hashp->LORDER != BYTE_ORDER) { - int i; - int max; + int i, max; if (is_bitmap) { max = hashp->BSIZE >> 2; /* divide by 4 */ @@ -611,8 +595,7 @@ __put_page(hashp, p, bucket, is_bucket, is_bitmap) page = BUCKET_TO_PAGE(bucket); else page = OADDR_TO_PAGE(bucket); - if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) || - ((wsize = _write(fd, p, size)) == -1)) + if ((wsize = pwrite(fd, p, size, (off_t)page << hashp->BSHIFT)) == -1) /* Errno is set */ return (-1); if (wsize != size) { @@ -627,10 +610,8 @@ __put_page(hashp, p, bucket, is_bucket, is_bitmap) * Initialize a new bitmap page. Bitmap pages are left in memory * once they are read in. */ -extern int -__ibitmap(hashp, pnum, nbits, ndx) - HTAB *hashp; - int pnum, nbits, ndx; +int +__ibitmap(HTAB *hashp, int pnum, int nbits, int ndx) { u_int32_t *ip; int clearbytes, clearints; @@ -651,8 +632,7 @@ __ibitmap(hashp, pnum, nbits, ndx) } static u_int32_t -first_free(map) - u_int32_t map; +first_free(u_int32_t map) { u_int32_t i, mask; @@ -666,8 +646,7 @@ first_free(map) } static u_int16_t -overflow_page(hashp) - HTAB *hashp; +overflow_page(HTAB *hashp) { u_int32_t *freep; int max_free, offset, splitnum; @@ -717,6 +696,7 @@ overflow_page(hashp) if (offset > SPLITMASK) { if (++splitnum >= NCACHED) { (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + errno = EFBIG; return (0); } hashp->OVFL_POINT = splitnum; @@ -730,6 +710,7 @@ overflow_page(hashp) free_page++; if (free_page >= NCACHED) { (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + errno = EFBIG; return (0); } /* @@ -755,6 +736,7 @@ overflow_page(hashp) if (++splitnum >= NCACHED) { (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + errno = EFBIG; return (0); } hashp->OVFL_POINT = splitnum; @@ -798,8 +780,11 @@ found: /* Calculate the split number for this page */ for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++); offset = (i ? bit - hashp->SPARES[i - 1] : bit); - if (offset >= SPLITMASK) + if (offset >= SPLITMASK) { + (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + errno = EFBIG; return (0); /* Out of overflow pages */ + } addr = OADDR_OF(i, offset); #ifdef DEBUG2 (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n", @@ -813,10 +798,8 @@ found: /* * Mark this overflow page as free. */ -extern void -__free_ovflpage(hashp, obufp) - HTAB *hashp; - BUFHEAD *obufp; +void +__free_ovflpage(HTAB *hashp, BUFHEAD *obufp) { u_int16_t addr; u_int32_t *freep; @@ -860,17 +843,27 @@ __free_ovflpage(hashp, obufp) * -1 failure */ static int -open_temp(hashp) - HTAB *hashp; +open_temp(HTAB *hashp) { sigset_t set, oset; - static char namestr[] = "_hashXXXXXX"; + int len; + char *envtmp = NULL; + char path[MAXPATHLEN]; + + if (issetugid() == 0) + envtmp = getenv("TMPDIR"); + len = snprintf(path, + sizeof(path), "%s/_hash.XXXXXX", envtmp ? envtmp : "/tmp"); + if (len < 0 || len >= sizeof(path)) { + errno = ENAMETOOLONG; + return (-1); + } /* Block signals; make sure file goes away at process exit. */ (void)sigfillset(&set); (void)_sigprocmask(SIG_BLOCK, &set, &oset); - if ((hashp->fp = mkstemp(namestr)) != -1) { - (void)unlink(namestr); + if ((hashp->fp = mkstemp(path)) != -1) { + (void)unlink(path); (void)_fcntl(hashp->fp, F_SETFD, 1); } (void)_sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL); @@ -882,9 +875,7 @@ open_temp(hashp) * an overflow pair, so we need to shift things. */ static void -squeeze_key(sp, key, val) - u_int16_t *sp; - const DBT *key, *val; +squeeze_key(u_int16_t *sp, const DBT *key, const DBT *val) { char *p; u_int16_t free_space, n, off, pageno; @@ -909,9 +900,7 @@ squeeze_key(sp, key, val) } static u_int32_t * -fetch_bitmap(hashp, ndx) - HTAB *hashp; - int ndx; +fetch_bitmap(HTAB *hashp, int ndx) { if (ndx >= hashp->nmaps) return (NULL); @@ -927,8 +916,7 @@ fetch_bitmap(hashp, ndx) #ifdef DEBUG4 int -print_chain(addr) - int addr; +print_chain(int addr) { BUFHEAD *bufp; short *bp, oaddr; diff --git a/db/hash/FreeBSD/hash_page.c.patch b/db/hash/FreeBSD/hash_page.c.patch index 64d1390..904c9a0 100644 --- a/db/hash/FreeBSD/hash_page.c.patch +++ b/db/hash/FreeBSD/hash_page.c.patch @@ -1,32 +1,33 @@ ---- hash_page.c.orig 2006-04-22 23:04:55.000000000 -0700 -+++ hash_page.c 2006-04-23 00:23:46.000000000 -0700 -@@ -74,7 +74,7 @@ +--- hash_page.c.orig 2009-11-06 12:41:16.000000000 -0800 ++++ hash_page.c 2009-11-06 12:43:23.000000000 -0800 +@@ -70,7 +70,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash #include #include "hash.h" #include "page.h" -#include "extern.h" +#include "hash_extern.h" - static u_int32_t *fetch_bitmap(HTAB *, int); - static u_int32_t first_free(u_int32_t); -@@ -586,7 +586,7 @@ - int is_bucket, is_bitmap; + static u_int32_t *fetch_bitmap(HTAB *, int); + static u_int32_t first_free(u_int32_t); +@@ -571,7 +571,7 @@ __get_page(HTAB *hashp, char *p, u_int32 + int + __put_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_bitmap) { - int fd, page, size; -- int wsize; -+ int wsize, max; +- int fd, page, size, wsize; ++ int fd, page, size, wsize, max; size = hashp->BSIZE; if ((hashp->fp == -1) && open_temp(hashp)) -@@ -595,7 +595,6 @@ +@@ -579,7 +579,7 @@ __put_page(HTAB *hashp, char *p, u_int32 + fd = hashp->fp; if (hashp->LORDER != BYTE_ORDER) { - int i; -- int max; +- int i, max; ++ int i; if (is_bitmap) { max = hashp->BSIZE >> 2; /* divide by 4 */ -@@ -619,6 +618,18 @@ +@@ -602,6 +602,18 @@ __put_page(HTAB *hashp, char *p, u_int32 errno = EFTYPE; return (-1); } diff --git a/db/hash/FreeBSD/ndbm.c b/db/hash/FreeBSD/ndbm.c index 8561c8c..8c23b79 100644 --- a/db/hash/FreeBSD/ndbm.c +++ b/db/hash/FreeBSD/ndbm.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/ndbm.c,v 1.6 2002/03/22 21:52:01 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/ndbm.c,v 1.7 2007/01/09 00:27:51 imp Exp $"); /* * This package provides a dbm compatible interface to the new hashing diff --git a/db/hash/FreeBSD/ndbm.c.patch b/db/hash/FreeBSD/ndbm.c.patch index 42d88ef..6292cd6 100644 --- a/db/hash/FreeBSD/ndbm.c.patch +++ b/db/hash/FreeBSD/ndbm.c.patch @@ -1,6 +1,6 @@ ---- ndbm.c.org 2006-09-08 18:47:42.000000000 -0700 -+++ ndbm.c 2006-09-08 18:48:03.000000000 -0700 -@@ -51,6 +51,9 @@ +--- ndbm.c.orig 2009-11-06 12:41:16.000000000 -0800 ++++ ndbm.c 2009-11-06 12:41:27.000000000 -0800 +@@ -47,6 +47,9 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash #include #include @@ -10,7 +10,7 @@ #include #include "hash.h" -@@ -62,7 +65,8 @@ +@@ -58,7 +61,8 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash extern DBM * dbm_open(file, flags, mode) const char *file; @@ -20,7 +20,7 @@ { HASHINFO info; char path[MAXPATHLEN]; -@@ -128,10 +132,14 @@ +@@ -124,10 +128,14 @@ dbm_firstkey(db) int status; datum retkey; DBT dbtretkey, dbtretdata; @@ -36,7 +36,7 @@ retkey.dptr = dbtretkey.data; retkey.dsize = dbtretkey.size; return (retkey); -@@ -146,13 +154,20 @@ +@@ -142,13 +150,20 @@ extern datum dbm_nextkey(db) DBM *db; { diff --git a/db/hash/FreeBSD/page.h b/db/hash/FreeBSD/page.h index 2cf7460..76082dd 100644 --- a/db/hash/FreeBSD/page.h +++ b/db/hash/FreeBSD/page.h @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,7 +30,7 @@ * SUCH DAMAGE. * * @(#)page.h 8.2 (Berkeley) 5/31/94 - * $FreeBSD: src/lib/libc/db/hash/page.h,v 1.2 2002/03/22 23:41:40 obrien Exp $ + * $FreeBSD: src/lib/libc/db/hash/page.h,v 1.4 2009/03/04 00:58:04 delphij Exp $ */ /* @@ -52,7 +48,7 @@ * +--------+---------------------+ * | F R E E A R E A | * +--------------+---------------+ - * | <---- - - - | data | + * | <---- - - - | data | * +--------+-----+----+----------+ * | key | data | key | * +--------+----------+----------+ diff --git a/db/hash/hash-fbsd.c b/db/hash/hash-fbsd.c index 10b4ab8..e5517d0 100644 --- a/db/hash/hash-fbsd.c +++ b/db/hash/hash-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash.c,v 1.12 2004/09/10 05:41:41 kuriyama Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash.c,v 1.21 2009/03/28 07:20:39 delphij Exp $"); #include "namespace.h" #include @@ -72,7 +68,7 @@ static void *hash_realloc(SEGMENT **, int, int); static int hash_seq(const DB *, DBT *, DBT *, u_int32_t); static int hash_sync(const DB *, u_int32_t); static int hdestroy(HTAB *); -static HTAB *init_hash(HTAB *, const char *, HASHINFO *); +static HTAB *init_hash(HTAB *, const char *, const HASHINFO *); static int init_htab(HTAB *, int); #if BYTE_ORDER == LITTLE_ENDIAN static void swap_header(HTAB *); @@ -96,11 +92,11 @@ int hash_accesses, hash_collisions, hash_expansions, hash_overflows; /************************** INTERFACE ROUTINES ***************************/ /* OPEN/CLOSE */ -extern DB * -__hash_open(file, flags, mode, info, dflags) - const char *file; - int flags, mode, dflags; - const HASHINFO *info; /* Special directives for create */ +/* ARGSUSED */ +DB * +__hash_open(const char *file, int flags, int mode, + const HASHINFO *info, /* Special directives for create */ + int dflags) { HTAB *hashp; struct stat statbuf; @@ -123,27 +119,17 @@ __hash_open(file, flags, mode, info, dflags) */ hashp->flags = flags; - new_table = 0; - if (!file || (flags & O_TRUNC) || - (stat(file, &statbuf) && (errno == ENOENT))) { - if (errno == ENOENT) - errno = 0; /* Just in case someone looks at errno */ - new_table = 1; - } if (file) { if ((hashp->fp = _open(file, flags, mode)) == -1) RETURN_ERROR(errno, error0); - - /* if the .db file is empty, and we had permission to create - a new .db file, then reinitialize the database */ - if ((flags & O_CREAT) && - _fstat(hashp->fp, &statbuf) == 0 && statbuf.st_size == 0) - new_table = 1; - (void)_fcntl(hashp->fp, F_SETFD, 1); - } + new_table = _fstat(hashp->fp, &statbuf) == 0 && + statbuf.st_size == 0 && (flags & O_ACCMODE) != O_RDONLY; + } else + new_table = 1; + if (new_table) { - if (!(hashp = init_hash(hashp, file, (HASHINFO *)info))) + if (!(hashp = init_hash(hashp, file, info))) RETURN_ERROR(errno, error1); } else { /* Table already exists */ @@ -167,7 +153,7 @@ __hash_open(file, flags, mode, info, dflags) if (hashp->VERSION != HASHVERSION && hashp->VERSION != OLDHASHVERSION) RETURN_ERROR(EFTYPE, error1); - if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY) + if ((int32_t)hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY) RETURN_ERROR(EFTYPE, error1); /* * Figure out how many segments we need. Max_Bucket is the @@ -176,7 +162,6 @@ __hash_open(file, flags, mode, info, dflags) */ nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) / hashp->SGSIZE; - hashp->nsegs = 0; if (alloc_segs(hashp, nsegs)) /* * If alloc_segs fails, table will have been destroyed @@ -252,8 +237,7 @@ error0: } static int -hash_close(dbp) - DB *dbp; +hash_close(DB *dbp) { HTAB *hashp; int retval; @@ -268,8 +252,7 @@ hash_close(dbp) } static int -hash_fd(dbp) - const DB *dbp; +hash_fd(const DB *dbp) { HTAB *hashp; @@ -286,10 +269,7 @@ hash_fd(dbp) /************************** LOCAL CREATION ROUTINES **********************/ static HTAB * -init_hash(hashp, file, info) - HTAB *hashp; - const char *file; - HASHINFO *info; +init_hash(HTAB *hashp, const char *file, const HASHINFO *info) { struct stat statbuf; int nelem; @@ -353,12 +333,9 @@ init_hash(hashp, file, info) * Returns 0 on No Error */ static int -init_htab(hashp, nelem) - HTAB *hashp; - int nelem; +init_htab(HTAB *hashp, int nelem) { - int nbuckets, nsegs; - int l2; + int nbuckets, nsegs, l2; /* * Divide number of elements by the fill factor and determine a @@ -399,8 +376,7 @@ init_htab(hashp, nelem) * structure, freeing all allocated space. */ static int -hdestroy(hashp) - HTAB *hashp; +hdestroy(HTAB *hashp) { int i, save_errno; @@ -439,6 +415,10 @@ hdestroy(hashp) for (i = 0; i < hashp->nmaps; i++) if (hashp->mapp[i]) free(hashp->mapp[i]); + if (hashp->tmp_key) + free(hashp->tmp_key); + if (hashp->tmp_buf) + free(hashp->tmp_buf); if (hashp->fp != -1) (void)_close(hashp->fp); @@ -459,9 +439,7 @@ hdestroy(hashp) * -1 ERROR */ static int -hash_sync(dbp, flags) - const DB *dbp; - u_int32_t flags; +hash_sync(const DB *dbp, u_int32_t flags) { HTAB *hashp; @@ -488,8 +466,7 @@ hash_sync(dbp, flags) * -1 indicates that errno should be set */ static int -flush_meta(hashp) - HTAB *hashp; +flush_meta(HTAB *hashp) { HASHHDR *whdrp; #if BYTE_ORDER == LITTLE_ENDIAN @@ -509,8 +486,7 @@ flush_meta(hashp) whdrp = &whdr; swap_header_copy(&hashp->hdr, whdrp); #endif - if ((lseek(fp, (off_t)0, SEEK_SET) == -1) || - ((wsize = _write(fp, whdrp, sizeof(HASHHDR))) == -1)) + if ((wsize = pwrite(fp, whdrp, sizeof(HASHHDR), (off_t)0)) == -1) return (-1); else if (wsize != sizeof(HASHHDR)) { @@ -536,11 +512,7 @@ flush_meta(hashp) * -1 to indicate an internal ERROR (i.e. out of memory, etc) */ static int -hash_get(dbp, key, data, flag) - const DB *dbp; - const DBT *key; - DBT *data; - u_int32_t flag; +hash_get(const DB *dbp, const DBT *key, DBT *data, u_int32_t flag) { HTAB *hashp; @@ -553,18 +525,13 @@ hash_get(dbp, key, data, flag) } static int -hash_put(dbp, key, data, flag) - const DB *dbp; - DBT *key; - const DBT *data; - u_int32_t flag; +hash_put(const DB *dbp, DBT *key, const DBT *data, u_int32_t flag) { HTAB *hashp; hashp = (HTAB *)dbp->internal; if (flag && flag != R_NOOVERWRITE) { - hashp->error = EINVAL; - errno = EINVAL; + hashp->error = errno = EINVAL; return (ERROR); } if ((hashp->flags & O_ACCMODE) == O_RDONLY) { @@ -576,10 +543,8 @@ hash_put(dbp, key, data, flag) } static int -hash_delete(dbp, key, flag) - const DB *dbp; - const DBT *key; - u_int32_t flag; /* Ignored */ +hash_delete(const DB *dbp, const DBT *key, + u_int32_t flag) /* Ignored */ { HTAB *hashp; @@ -599,10 +564,7 @@ hash_delete(dbp, key, flag) * Assume that hashp has been set in wrapper routine. */ static int -hash_access(hashp, action, key, val) - HTAB *hashp; - ACTION action; - DBT *key, *val; +hash_access(HTAB *hashp, ACTION action, DBT *key, DBT *val) { BUFHEAD *rbufp; BUFHEAD *bufp, *save_bufp; @@ -728,10 +690,7 @@ found: } static int -hash_seq(dbp, key, data, flag) - const DB *dbp; - DBT *key, *data; - u_int32_t flag; +hash_seq(const DB *dbp, DBT *key, DBT *data, u_int32_t flag) { u_int32_t bucket; BUFHEAD *bufp; @@ -751,7 +710,7 @@ hash_seq(dbp, key, data, flag) hashp->cndx = 1; hashp->cpage = NULL; } - + next_bucket: for (bp = NULL; !bp || !bp[0]; ) { if (!(bufp = hashp->cpage)) { for (bucket = hashp->cbucket; @@ -766,12 +725,22 @@ hash_seq(dbp, key, data, flag) break; } hashp->cbucket = bucket; - if (hashp->cbucket > hashp->MAX_BUCKET) { + if ((u_int32_t)hashp->cbucket > hashp->MAX_BUCKET) { hashp->cbucket = -1; return (ABNORMAL); } - } else + } else { bp = (u_int16_t *)hashp->cpage->page; + if (flag == R_NEXT) { + hashp->cndx += 2; + if (hashp->cndx > bp[0]) { + hashp->cpage = NULL; + hashp->cbucket++; + hashp->cndx = 1; + goto next_bucket; + } + } + } #ifdef DEBUG assert(bp); @@ -795,17 +764,12 @@ hash_seq(dbp, key, data, flag) if (__big_keydata(hashp, bufp, key, data, 1)) return (ERROR); } else { + if (hashp->cpage == 0) + return (ERROR); key->data = (u_char *)hashp->cpage->page + bp[ndx]; key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx]; data->data = (u_char *)hashp->cpage->page + bp[ndx + 1]; data->size = bp[ndx] - bp[ndx + 1]; - ndx += 2; - if (ndx > bp[0]) { - hashp->cpage = NULL; - hashp->cbucket++; - hashp->cndx = 1; - } else - hashp->cndx = ndx; } return (SUCCESS); } @@ -817,9 +781,8 @@ hash_seq(dbp, key, data, flag) * 0 ==> OK * -1 ==> Error */ -extern int -__expand_table(hashp) - HTAB *hashp; +int +__expand_table(HTAB *hashp) { u_int32_t old_bucket, new_bucket; int dirsize, new_segnum, spare_ndx; @@ -873,9 +836,7 @@ __expand_table(hashp) * fails, then this routine can go away. */ static void * -hash_realloc(p_ptr, oldsize, newsize) - SEGMENT **p_ptr; - int oldsize, newsize; +hash_realloc(SEGMENT **p_ptr, int oldsize, int newsize) { void *p; @@ -888,13 +849,10 @@ hash_realloc(p_ptr, oldsize, newsize) return (p); } -extern u_int32_t -__call_hash(hashp, k, len) - HTAB *hashp; - char *k; - int len; +u_int32_t +__call_hash(HTAB *hashp, char *k, int len) { - int n, bucket; + unsigned int n, bucket; n = hashp->hash(k, len); bucket = n & hashp->HIGH_MASK; @@ -909,9 +867,7 @@ __call_hash(hashp, k, len) * Returns 0 on success */ static int -alloc_segs(hashp, nsegs) - HTAB *hashp; - int nsegs; +alloc_segs(HTAB *hashp, int nsegs) { int i; SEGMENT store; @@ -925,15 +881,18 @@ alloc_segs(hashp, nsegs) errno = save_errno; return (-1); } + hashp->nsegs = nsegs; + if (nsegs == 0) + return (0); /* Allocate segments */ - if ((store = - (SEGMENT)calloc(nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) { + if ((store = (SEGMENT)calloc(nsegs << hashp->SSHIFT, + sizeof(SEGMENT))) == NULL) { save_errno = errno; (void)hdestroy(hashp); errno = save_errno; return (-1); } - for (i = 0; i < nsegs; i++, hashp->nsegs++) + for (i = 0; i < nsegs; i++) hashp->dir[i] = &store[i << hashp->SSHIFT]; return (0); } @@ -943,8 +902,7 @@ alloc_segs(hashp, nsegs) * Hashp->hdr needs to be byteswapped. */ static void -swap_header_copy(srcp, destp) - HASHHDR *srcp, *destp; +swap_header_copy(HASHHDR *srcp, HASHHDR *destp) { int i; @@ -972,8 +930,7 @@ swap_header_copy(srcp, destp) } static void -swap_header(hashp) - HTAB *hashp; +swap_header(HTAB *hashp) { HASHHDR *hdrp; int i; diff --git a/db/hash/hash.h b/db/hash/hash.h index 737b0f8..e4f77c2 100644 --- a/db/hash/hash.h +++ b/db/hash/hash.h @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,7 +30,7 @@ * SUCH DAMAGE. * * @(#)hash.h 8.3 (Berkeley) 5/31/94 - * $FreeBSD: src/lib/libc/db/hash/hash.h,v 1.6 2002/03/21 22:46:26 obrien Exp $ + * $FreeBSD: src/lib/libc/db/hash/hash.h,v 1.9 2009/03/28 05:45:29 delphij Exp $ */ /* Operations */ @@ -64,28 +60,28 @@ typedef BUFHEAD **SEGMENT; /* Hash Table Information */ typedef struct hashhdr { /* Disk resident portion */ - int magic; /* Magic NO for hash tables */ - int version; /* Version ID */ + int32_t magic; /* Magic NO for hash tables */ + int32_t version; /* Version ID */ u_int32_t lorder; /* Byte Order */ - int bsize; /* Bucket/Page Size */ - int bshift; /* Bucket shift */ - int dsize; /* Directory Size */ - int ssize; /* Segment Size */ - int sshift; /* Segment shift */ - int ovfl_point; /* Where overflow pages are being + int32_t bsize; /* Bucket/Page Size */ + int32_t bshift; /* Bucket shift */ + int32_t dsize; /* Directory Size */ + int32_t ssize; /* Segment Size */ + int32_t sshift; /* Segment shift */ + int32_t ovfl_point; /* Where overflow pages are being * allocated */ - int last_freed; /* Last overflow page freed */ - int max_bucket; /* ID of Maximum bucket in use */ - int high_mask; /* Mask to modulo into entire table */ - int low_mask; /* Mask to modulo into lower half of + int32_t last_freed; /* Last overflow page freed */ + u_int32_t max_bucket; /* ID of Maximum bucket in use */ + u_int32_t high_mask; /* Mask to modulo into entire table */ + u_int32_t low_mask; /* Mask to modulo into lower half of * table */ - int ffactor; /* Fill factor */ - int nkeys; /* Number of keys in hash table */ - int hdrpages; /* Size of table header */ - int h_charkey; /* value of hash(CHARKEY) */ + u_int32_t ffactor; /* Fill factor */ + int32_t nkeys; /* Number of keys in hash table */ + int32_t hdrpages; /* Size of table header */ + int32_t h_charkey; /* value of hash(CHARKEY) */ #define NCACHED 32 /* number of bit maps and spare * points */ - int spares[NCACHED];/* spare pages for overflow */ + int32_t spares[NCACHED];/* spare pages for overflow */ u_int16_t bitmaps[NCACHED]; /* address of overflow page * bitmaps */ } HASHHDR; diff --git a/db/hash/hash_bigkey-fbsd.c b/db/hash/hash_bigkey-fbsd.c index e4d75a5..d325105 100644 --- a/db/hash/hash_bigkey-fbsd.c +++ b/db/hash/hash_bigkey-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_bigkey.c,v 1.5 2003/02/16 17:29:09 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_bigkey.c,v 1.10 2009/03/28 06:47:05 delphij Exp $"); /* * PACKAGE: hash @@ -86,14 +82,12 @@ static int collect_data(HTAB *, BUFHEAD *, int, int); * 0 ==> OK *-1 ==> ERROR */ -extern int -__big_insert(hashp, bufp, key, val) - HTAB *hashp; - BUFHEAD *bufp; - const DBT *key, *val; +int +__big_insert(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val) { u_int16_t *p; - int key_size, n, val_size; + int key_size, n; + unsigned int val_size; u_int16_t space, move_bytes, off; char *cp, *key_data, *val_data; @@ -124,18 +118,30 @@ __big_insert(hashp, bufp, key, val) return (-1); n = p[0]; if (!key_size) { - if (FREESPACE(p)) { - move_bytes = MIN(FREESPACE(p), val_size); + space = FREESPACE(p); + if (space) { + move_bytes = MIN(space, val_size); + /* + * If the data would fit exactly in the + * remaining space, we must overflow it to the + * next page; otherwise the invariant that the + * data must end on a page with FREESPACE + * non-zero would fail. + */ + if (space == val_size && val_size == val->size) + goto toolarge; off = OFFSET(p) - move_bytes; - p[n] = off; memmove(cp + off, val_data, move_bytes); val_data += move_bytes; val_size -= move_bytes; + p[n] = off; p[n - 2] = FULL_KEY_DATA; FREESPACE(p) = FREESPACE(p) - move_bytes; OFFSET(p) = off; - } else + } else { + toolarge: p[n - 2] = FULL_KEY; + } } p = (u_int16_t *)bufp->page; cp = bufp->page; @@ -186,10 +192,8 @@ __big_insert(hashp, bufp, key, val) * 0 => OK *-1 => ERROR */ -extern int -__big_delete(hashp, bufp) - HTAB *hashp; - BUFHEAD *bufp; +int +__big_delete(HTAB *hashp, BUFHEAD *bufp) { BUFHEAD *last_bfp, *rbufp; u_int16_t *bp, pageno; @@ -247,12 +251,12 @@ __big_delete(hashp, bufp) n -= 2; bp[0] = n; FREESPACE(bp) = hashp->BSIZE - PAGE_META(n); - OFFSET(bp) = hashp->BSIZE - 1; + OFFSET(bp) = hashp->BSIZE; bufp->flags |= BUF_MOD; if (rbufp) __free_ovflpage(hashp, rbufp); - if (last_bfp != rbufp) + if (last_bfp && last_bfp != rbufp) __free_ovflpage(hashp, last_bfp); hashp->NKEYS--; @@ -265,13 +269,8 @@ __big_delete(hashp, bufp) * -2 means key not found and this is big key/data * -3 error */ -extern int -__find_bigpair(hashp, bufp, ndx, key, size) - HTAB *hashp; - BUFHEAD *bufp; - int ndx; - char *key; - int size; +int +__find_bigpair(HTAB *hashp, BUFHEAD *bufp, int ndx, char *key, int size) { u_int16_t *bp; char *p; @@ -317,10 +316,8 @@ __find_bigpair(hashp, bufp, ndx, key, size) * of the pair; 0 if there isn't any (i.e. big pair is the last key in the * bucket) */ -extern u_int16_t -__find_last_page(hashp, bpp) - HTAB *hashp; - BUFHEAD **bpp; +u_int16_t +__find_last_page(HTAB *hashp, BUFHEAD **bpp) { BUFHEAD *bufp; u_int16_t *bp, pageno; @@ -358,13 +355,8 @@ __find_last_page(hashp, bpp) * Return the data for the key/data pair that begins on this page at this * index (index should always be 1). */ -extern int -__big_return(hashp, bufp, ndx, val, set_current) - HTAB *hashp; - BUFHEAD *bufp; - int ndx; - DBT *val; - int set_current; +int +__big_return(HTAB *hashp, BUFHEAD *bufp, int ndx, DBT *val, int set_current) { BUFHEAD *save_p; u_int16_t *bp, len, off, save_addr; @@ -433,8 +425,8 @@ __big_return(hashp, bufp, ndx, val, set_current) return (0); } - val->size = collect_data(hashp, bufp, (int)len, set_current); - if (val->size == -1) + val->size = (size_t)collect_data(hashp, bufp, (int)len, set_current); + if (val->size == (size_t)-1) return (-1); if (save_p->addr != save_addr) { /* We are pretty short on buffers. */ @@ -450,10 +442,7 @@ __big_return(hashp, bufp, ndx, val, set_current) * allocate a buffer and copy the data as you recurse up. */ static int -collect_data(hashp, bufp, len, set) - HTAB *hashp; - BUFHEAD *bufp; - int len, set; +collect_data(HTAB *hashp, BUFHEAD *bufp, int len, int set) { u_int16_t *bp; char *p; @@ -505,15 +494,11 @@ collect_data(hashp, bufp, len, set) /* * Fill in the key and data for this big pair. */ -extern int -__big_keydata(hashp, bufp, key, val, set) - HTAB *hashp; - BUFHEAD *bufp; - DBT *key, *val; - int set; +int +__big_keydata(HTAB *hashp, BUFHEAD *bufp, DBT *key, DBT *val, int set) { - key->size = collect_key(hashp, bufp, 0, val, set); - if (key->size == -1) + key->size = (size_t)collect_key(hashp, bufp, 0, val, set); + if (key->size == (size_t)-1) return (-1); key->data = (u_char *)hashp->tmp_key; return (0); @@ -524,12 +509,7 @@ __big_keydata(hashp, bufp, key, val, set) * collect the data, allocate a buffer and copy the key as you recurse up. */ static int -collect_key(hashp, bufp, len, val, set) - HTAB *hashp; - BUFHEAD *bufp; - int len; - DBT *val; - int set; +collect_key(HTAB *hashp, BUFHEAD *bufp, int len, DBT *val, int set) { BUFHEAD *xbp; char *p; @@ -568,23 +548,19 @@ collect_key(hashp, bufp, len, val, set) * 0 => OK * -1 => error */ -extern int -__big_split(hashp, op, np, big_keyp, addr, obucket, ret) - HTAB *hashp; - BUFHEAD *op; /* Pointer to where to put keys that go in old bucket */ - BUFHEAD *np; /* Pointer to new bucket page */ - /* Pointer to first page containing the big key/data */ - BUFHEAD *big_keyp; - int addr; /* Address of big_keyp */ - u_int32_t obucket;/* Old Bucket */ - SPLIT_RETURN *ret; +int +__big_split(HTAB *hashp, + BUFHEAD *op, /* Pointer to where to put keys that go in old bucket */ + BUFHEAD *np, /* Pointer to new bucket page */ + BUFHEAD *big_keyp, /* Pointer to first page containing the big key/data */ + int addr, /* Address of big_keyp */ + u_int32_t obucket, /* Old Bucket */ + SPLIT_RETURN *ret) { - BUFHEAD *tmpp; - u_int16_t *tp; - BUFHEAD *bp; + BUFHEAD *bp, *tmpp; DBT key, val; u_int32_t change; - u_int16_t free_space, n, off; + u_int16_t free_space, n, off, *tp; bp = big_keyp; @@ -596,7 +572,7 @@ __big_split(hashp, op, np, big_keyp, addr, obucket, ret) if ( (ret->next_addr = __find_last_page(hashp, &big_keyp)) ) { if (!(ret->nextp = __get_buf(hashp, ret->next_addr, big_keyp, 0))) - return (-1);; + return (-1); } else ret->nextp = NULL; diff --git a/db/hash/hash_buf-fbsd.c b/db/hash/hash_buf-fbsd.c index 2710d75..e19beda 100644 --- a/db/hash/hash_buf-fbsd.c +++ b/db/hash/hash_buf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_buf.c,v 1.7 2002/03/21 22:46:26 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_buf.c,v 1.12 2009/03/28 06:40:48 delphij Exp $"); /* * PACKAGE: hash @@ -61,6 +57,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_buf.c,v 1.7 2002/03/21 22:46:26 ob #include #include #include +#include #ifdef DEBUG #include @@ -102,12 +99,10 @@ static BUFHEAD *newbuf(HTAB *, u_int32_t, BUFHEAD *); * be valid. Therefore, you must always verify that its address matches the * address you are seeking. */ -extern BUFHEAD * -__get_buf(hashp, addr, prev_bp, newpage) - HTAB *hashp; - u_int32_t addr; - BUFHEAD *prev_bp; - int newpage; /* If prev_bp set, indicates a new overflow page. */ +BUFHEAD * +__get_buf(HTAB *hashp, u_int32_t addr, + BUFHEAD *prev_bp, /* If prev_bp set, indicates a new overflow page. */ + int newpage) { BUFHEAD *bp; u_int32_t is_disk_mask; @@ -158,10 +153,7 @@ __get_buf(hashp, addr, prev_bp, newpage) * If newbuf finds an error (returning NULL), it also sets errno. */ static BUFHEAD * -newbuf(hashp, addr, prev_bp) - HTAB *hashp; - u_int32_t addr; - BUFHEAD *prev_bp; +newbuf(HTAB *hashp, u_int32_t addr, BUFHEAD *prev_bp) { BUFHEAD *bp; /* The buffer we're going to use */ BUFHEAD *xbp; /* Temp pointer */ @@ -172,24 +164,38 @@ newbuf(hashp, addr, prev_bp) oaddr = 0; bp = LRU; + + /* It is bad to overwrite the page under the cursor. */ + if (bp == hashp->cpage) { + BUF_REMOVE(bp); + MRU_INSERT(bp); + bp = LRU; + } + + /* If prev_bp is part of bp overflow, create a new buffer. */ + if (hashp->nbufs == 0 && prev_bp && bp->ovfl) { + BUFHEAD *ovfl; + + for (ovfl = bp->ovfl; ovfl ; ovfl = ovfl->ovfl) { + if (ovfl == prev_bp) { + hashp->nbufs++; + break; + } + } + } + /* * If LRU buffer is pinned, the buffer pool is too small. We need to * allocate more buffers. */ - if (hashp->nbufs || (bp->flags & BUF_PIN)) { + if (hashp->nbufs || (bp->flags & BUF_PIN) || bp == hashp->cpage) { /* Allocate a new one */ - if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL) + if ((bp = (BUFHEAD *)calloc(1, sizeof(BUFHEAD))) == NULL) return (NULL); -#ifdef PURIFY - memset(bp, 0xff, sizeof(BUFHEAD)); -#endif - if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) { + if ((bp->page = (char *)calloc(1, hashp->BSIZE)) == NULL) { free(bp); return (NULL); } -#ifdef PURIFY - memset(bp->page, 0xff, hashp->BSIZE); -#endif if (hashp->nbufs) hashp->nbufs--; } else { @@ -276,7 +282,7 @@ newbuf(hashp, addr, prev_bp) */ #ifdef DEBUG1 (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n", - prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0), + prev_bp->addr, (prev_bp->ovfl ? prev_bp->ovfl->addr : 0), (bp ? bp->addr : 0)); #endif prev_bp->ovfl = bp; @@ -287,10 +293,8 @@ newbuf(hashp, addr, prev_bp) return (bp); } -extern void -__buf_init(hashp, nbytes) - HTAB *hashp; - int nbytes; +__private_extern__ void +__buf_init(HTAB *hashp, int nbytes) { BUFHEAD *bfp; int npages; @@ -312,10 +316,8 @@ __buf_init(hashp, nbytes) */ } -extern int -__buf_free(hashp, do_free, to_disk) - HTAB *hashp; - int do_free, to_disk; +int +__buf_free(HTAB *hashp, int do_free, int to_disk) { BUFHEAD *bp; @@ -332,8 +334,10 @@ __buf_free(hashp, do_free, to_disk) } /* Check if we are freeing stuff */ if (do_free) { - if (bp->page) + if (bp->page) { + (void)memset(bp->page, 0, hashp->BSIZE); free(bp->page); + } BUF_REMOVE(bp); free(bp); bp = LRU; @@ -343,10 +347,8 @@ __buf_free(hashp, do_free, to_disk) return (0); } -extern void -__reclaim_buf(hashp, bp) - HTAB *hashp; - BUFHEAD *bp; +void +__reclaim_buf(HTAB *hashp, BUFHEAD *bp) { bp->ovfl = 0; bp->addr = 0; diff --git a/db/hash/hash_func-fbsd.c b/db/hash/hash_func-fbsd.c index 537b94f..a402e49 100644 --- a/db/hash/hash_func-fbsd.c +++ b/db/hash/hash_func-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_func.c,v 1.5 2003/02/16 17:29:09 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_func.c,v 1.6 2007/01/09 00:27:50 imp Exp $"); #include diff --git a/db/hash/hash_log2-fbsd.c b/db/hash/hash_log2-fbsd.c deleted file mode 120000 index ee8306e..0000000 --- a/db/hash/hash_log2-fbsd.c +++ /dev/null @@ -1 +0,0 @@ -./hash_log2.c \ No newline at end of file diff --git a/db/hash/hash_log2-fbsd.c b/db/hash/hash_log2-fbsd.c new file mode 100644 index 0000000..56714a1 --- /dev/null +++ b/db/hash/hash_log2-fbsd.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_log2.c,v 1.5 2009/03/28 05:45:29 delphij Exp $"); + +#include +#include "hash.h" +#include "page.h" +#include "hash_extern.h" + +u_int32_t +__log2(u_int32_t num) +{ + u_int32_t i, limit; + + limit = 1; + for (i = 0; limit < num; limit = limit << 1, i++); + return (i); +} diff --git a/db/hash/hash_page-fbsd.c b/db/hash/hash_page-fbsd.c index f64a1df..809a3b9 100644 --- a/db/hash/hash_page-fbsd.c +++ b/db/hash/hash_page-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_page.c,v 1.8 2002/03/21 22:46:26 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_page.c,v 1.16 2009/03/28 06:30:43 delphij Exp $"); /* * PACKAGE: hashing @@ -57,7 +53,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_page.c,v 1.8 2002/03/21 22:46:26 o */ #include "namespace.h" -#include +#include #include #include @@ -76,14 +72,13 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_page.c,v 1.8 2002/03/21 22:46:26 o #include "page.h" #include "hash_extern.h" -static u_int32_t *fetch_bitmap(HTAB *, int); -static u_int32_t first_free(u_int32_t); -static int open_temp(HTAB *); -static u_int16_t overflow_page(HTAB *); -static void putpair(char *, const DBT *, const DBT *); -static void squeeze_key(u_int16_t *, const DBT *, const DBT *); -static int ugly_split -(HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int); +static u_int32_t *fetch_bitmap(HTAB *, int); +static u_int32_t first_free(u_int32_t); +static int open_temp(HTAB *); +static u_int16_t overflow_page(HTAB *); +static void putpair(char *, const DBT *, const DBT *); +static void squeeze_key(u_int16_t *, const DBT *, const DBT *); +static int ugly_split(HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int); #define PAGE_INIT(P) { \ ((u_int16_t *)(P))[0] = 0; \ @@ -97,9 +92,7 @@ static int ugly_split * stuff on. */ static void -putpair(p, key, val) - char *p; - const DBT *key, *val; +putpair(char *p, const DBT *key, const DBT *val) { u_int16_t *bp, n, off; @@ -128,15 +121,11 @@ putpair(p, key, val) * 0 OK * -1 error */ -extern int -__delpair(hashp, bufp, ndx) - HTAB *hashp; - BUFHEAD *bufp; - int ndx; +int +__delpair(HTAB *hashp, BUFHEAD *bufp, int ndx) { - u_int16_t *bp, newoff; + u_int16_t *bp, newoff, pairlen; int n; - u_int16_t pairlen; bp = (u_int16_t *)bufp->page; n = bp[0]; @@ -166,6 +155,14 @@ __delpair(hashp, bufp, ndx) bp[i - 1] = bp[i + 1] + pairlen; } } + if (ndx == hashp->cndx) { + /* + * We just removed pair we were "pointing" to. + * By moving back the cndx we ensure subsequent + * hash_seq() calls won't skip over any entries. + */ + hashp->cndx -= 2; + } } /* Finally adjust the page data */ bp[n] = OFFSET(bp) + pairlen; @@ -181,10 +178,8 @@ __delpair(hashp, bufp, ndx) * 0 ==> OK * -1 ==> Error */ -extern int -__split_page(hashp, obucket, nbucket) - HTAB *hashp; - u_int32_t obucket, nbucket; +int +__split_page(HTAB *hashp, u_int32_t obucket, u_int32_t nbucket) { BUFHEAD *new_bufp, *old_bufp; u_int16_t *ino; @@ -278,17 +273,17 @@ __split_page(hashp, obucket, nbucket) * -1 ==> failure */ static int -ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) - HTAB *hashp; - u_int32_t obucket; /* Same as __split_page. */ - BUFHEAD *old_bufp, *new_bufp; - int copyto; /* First byte on page which contains key/data values. */ - int moved; /* Number of pairs moved to new page. */ +ugly_split(HTAB *hashp, + u_int32_t obucket, /* Same as __split_page. */ + BUFHEAD *old_bufp, + BUFHEAD *new_bufp, + int copyto, /* First byte on page which contains key/data values. */ + int moved) /* Number of pairs moved to new page. */ { - BUFHEAD *bufp; /* Buffer header for ino */ - u_int16_t *ino; /* Page keys come off of */ - u_int16_t *np; /* New page */ - u_int16_t *op; /* Page keys go on to if they aren't moving */ + BUFHEAD *bufp; /* Buffer header for ino */ + u_int16_t *ino; /* Page keys come off of */ + u_int16_t *np; /* New page */ + u_int16_t *op; /* Page keys go on to if they aren't moving */ BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */ DBT key, val; @@ -398,11 +393,8 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) * 0 ==> OK * 1 ==> failure */ -extern int -__addel(hashp, bufp, key, val) - HTAB *hashp; - BUFHEAD *bufp; - const DBT *key, *val; +int +__addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val) { u_int16_t *bp, *sop; int do_expand; @@ -420,17 +412,22 @@ __addel(hashp, bufp, key, val) if (!bufp) return (-1); bp = (u_int16_t *)bufp->page; - } else + } else if (bp[bp[0]] != OVFLPAGE) { + /* Short key/data pairs, no more pages */ + break; + } else { /* Try to squeeze key on this page */ - if (FREESPACE(bp) > PAIRSIZE(key, val)) { + if (bp[2] >= REAL_KEY && + FREESPACE(bp) >= PAIRSIZE(key, val)) { squeeze_key(bp, key, val); - return (0); + goto stats; } else { bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); if (!bufp) return (-1); bp = (u_int16_t *)bufp->page; } + } if (PAIRFITS(bp, key, val)) putpair(bufp->page, key, val); @@ -447,6 +444,7 @@ __addel(hashp, bufp, key, val) if (__big_insert(hashp, bufp, key, val)) return (-1); } +stats: bufp->flags |= BUF_MOD; /* * If the average number of keys per bucket exceeds the fill factor, @@ -465,13 +463,10 @@ __addel(hashp, bufp, key, val) * pointer on success * NULL on error */ -extern BUFHEAD * -__add_ovflpage(hashp, bufp) - HTAB *hashp; - BUFHEAD *bufp; +BUFHEAD * +__add_ovflpage(HTAB *hashp, BUFHEAD *bufp) { - u_int16_t *sp; - u_int16_t ndx, ovfl_num; + u_int16_t *sp, ndx, ovfl_num; #ifdef DEBUG1 int tmp1, tmp2; #endif @@ -518,15 +513,11 @@ __add_ovflpage(hashp, bufp) * 0 indicates SUCCESS * -1 indicates FAILURE */ -extern int -__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap) - HTAB *hashp; - char *p; - u_int32_t bucket; - int is_bucket, is_disk, is_bitmap; +int +__get_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_disk, + int is_bitmap) { - int fd, page, size; - int rsize; + int fd, page, size, rsize; u_int16_t *bp; fd = hashp->fp; @@ -540,8 +531,7 @@ __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap) page = BUCKET_TO_PAGE(bucket); else page = OADDR_TO_PAGE(bucket); - if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) || - ((rsize = _read(fd, p, size)) == -1)) + if ((rsize = pread(fd, p, size, (off_t)page << hashp->BSHIFT)) == -1) return (-1); bp = (u_int16_t *)p; if (!rsize) @@ -578,15 +568,10 @@ __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap) * 0 ==> OK * -1 ==>failure */ -extern int -__put_page(hashp, p, bucket, is_bucket, is_bitmap) - HTAB *hashp; - char *p; - u_int32_t bucket; - int is_bucket, is_bitmap; +int +__put_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_bitmap) { - int fd, page, size; - int wsize, max; + int fd, page, size, wsize, max; size = hashp->BSIZE; if ((hashp->fp == -1) && open_temp(hashp)) @@ -610,8 +595,7 @@ __put_page(hashp, p, bucket, is_bucket, is_bitmap) page = BUCKET_TO_PAGE(bucket); else page = OADDR_TO_PAGE(bucket); - if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) || - ((wsize = _write(fd, p, size)) == -1)) + if ((wsize = pwrite(fd, p, size, (off_t)page << hashp->BSHIFT)) == -1) /* Errno is set */ return (-1); if (wsize != size) { @@ -638,10 +622,8 @@ __put_page(hashp, p, bucket, is_bucket, is_bitmap) * Initialize a new bitmap page. Bitmap pages are left in memory * once they are read in. */ -extern int -__ibitmap(hashp, pnum, nbits, ndx) - HTAB *hashp; - int pnum, nbits, ndx; +int +__ibitmap(HTAB *hashp, int pnum, int nbits, int ndx) { u_int32_t *ip; int clearbytes, clearints; @@ -662,8 +644,7 @@ __ibitmap(hashp, pnum, nbits, ndx) } static u_int32_t -first_free(map) - u_int32_t map; +first_free(u_int32_t map) { u_int32_t i, mask; @@ -677,8 +658,7 @@ first_free(map) } static u_int16_t -overflow_page(hashp) - HTAB *hashp; +overflow_page(HTAB *hashp) { u_int32_t *freep; int max_free, offset, splitnum; @@ -728,6 +708,7 @@ overflow_page(hashp) if (offset > SPLITMASK) { if (++splitnum >= NCACHED) { (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + errno = EFBIG; return (0); } hashp->OVFL_POINT = splitnum; @@ -741,6 +722,7 @@ overflow_page(hashp) free_page++; if (free_page >= NCACHED) { (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + errno = EFBIG; return (0); } /* @@ -766,6 +748,7 @@ overflow_page(hashp) if (++splitnum >= NCACHED) { (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + errno = EFBIG; return (0); } hashp->OVFL_POINT = splitnum; @@ -809,8 +792,11 @@ found: /* Calculate the split number for this page */ for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++); offset = (i ? bit - hashp->SPARES[i - 1] : bit); - if (offset >= SPLITMASK) + if (offset >= SPLITMASK) { + (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + errno = EFBIG; return (0); /* Out of overflow pages */ + } addr = OADDR_OF(i, offset); #ifdef DEBUG2 (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n", @@ -824,10 +810,8 @@ found: /* * Mark this overflow page as free. */ -extern void -__free_ovflpage(hashp, obufp) - HTAB *hashp; - BUFHEAD *obufp; +void +__free_ovflpage(HTAB *hashp, BUFHEAD *obufp) { u_int16_t addr; u_int32_t *freep; @@ -871,17 +855,27 @@ __free_ovflpage(hashp, obufp) * -1 failure */ static int -open_temp(hashp) - HTAB *hashp; +open_temp(HTAB *hashp) { sigset_t set, oset; - static char namestr[] = "_hashXXXXXX"; + int len; + char *envtmp = NULL; + char path[MAXPATHLEN]; + + if (issetugid() == 0) + envtmp = getenv("TMPDIR"); + len = snprintf(path, + sizeof(path), "%s/_hash.XXXXXX", envtmp ? envtmp : "/tmp"); + if (len < 0 || len >= sizeof(path)) { + errno = ENAMETOOLONG; + return (-1); + } /* Block signals; make sure file goes away at process exit. */ (void)sigfillset(&set); (void)_sigprocmask(SIG_BLOCK, &set, &oset); - if ((hashp->fp = mkstemp(namestr)) != -1) { - (void)unlink(namestr); + if ((hashp->fp = mkstemp(path)) != -1) { + (void)unlink(path); (void)_fcntl(hashp->fp, F_SETFD, 1); } (void)_sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL); @@ -893,9 +887,7 @@ open_temp(hashp) * an overflow pair, so we need to shift things. */ static void -squeeze_key(sp, key, val) - u_int16_t *sp; - const DBT *key, *val; +squeeze_key(u_int16_t *sp, const DBT *key, const DBT *val) { char *p; u_int16_t free_space, n, off, pageno; @@ -920,9 +912,7 @@ squeeze_key(sp, key, val) } static u_int32_t * -fetch_bitmap(hashp, ndx) - HTAB *hashp; - int ndx; +fetch_bitmap(HTAB *hashp, int ndx) { if (ndx >= hashp->nmaps) return (NULL); @@ -938,8 +928,7 @@ fetch_bitmap(hashp, ndx) #ifdef DEBUG4 int -print_chain(addr) - int addr; +print_chain(int addr) { BUFHEAD *bufp; short *bp, oaddr; diff --git a/db/hash/ndbm-fbsd.c b/db/hash/ndbm-fbsd.c index ba819d7..c589af8 100644 --- a/db/hash/ndbm-fbsd.c +++ b/db/hash/ndbm-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/hash/ndbm.c,v 1.6 2002/03/22 21:52:01 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/hash/ndbm.c,v 1.7 2007/01/09 00:27:51 imp Exp $"); /* * This package provides a dbm compatible interface to the new hashing diff --git a/db/man/FreeBSD/btree.3 b/db/man/FreeBSD/btree.3 index 7f04c3a..d886f97 100644 --- a/db/man/FreeBSD/btree.3 +++ b/db/man/FreeBSD/btree.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)btree.3 8.4 (Berkeley) 8/18/94 -.\" $FreeBSD: src/lib/libc/db/man/btree.3,v 1.8 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/db/man/btree.3,v 1.9 2007/01/09 00:27:51 imp Exp $ .\" .Dd August 18, 1994 .Dt BTREE 3 diff --git a/db/man/FreeBSD/dbm.3 b/db/man/FreeBSD/dbm.3 index f8cb6b8..e04bc20 100644 --- a/db/man/FreeBSD/dbm.3 +++ b/db/man/FreeBSD/dbm.3 @@ -13,11 +13,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/db/man/dbm.3,v 1.8 2003/09/08 19:57:13 ru Exp $ +.\" $FreeBSD: src/lib/libc/db/man/dbm.3,v 1.10 2009/01/30 15:28:35 gabor Exp $ .\" -.\" Note: The date here should be updated whenever a non-trivial -.\" change is made to the manual page. -.Dd July 7, 1999 +.Dd April 16, 2006 .Dt DBM 3 .Os .Sh NAME @@ -104,7 +102,7 @@ is a typical value for is a typical value for .Fa mode . .Dv O_WRONLY -is treated as O_RDWR in +is not allowed in .Fa flags . The pointer returned by .Fn dbm_open @@ -124,10 +122,6 @@ The .Fn dbm_close db function closes the database. -The -.Fn dbm_close -function -normally returns zero. .Pp The .Fn dbm_store db key data flags diff --git a/db/man/FreeBSD/dbm.3.patch b/db/man/FreeBSD/dbm.3.patch index 02014ab..c0f8688 100644 --- a/db/man/FreeBSD/dbm.3.patch +++ b/db/man/FreeBSD/dbm.3.patch @@ -1,6 +1,6 @@ ---- dbm.3 2005-07-28 16:23:28.000000000 -0700 -+++ dbm.3.edit 2006-07-12 11:16:35.000000000 -0700 -@@ -33,28 +33,54 @@ +--- dbm.3.orig 2009-11-06 12:44:50.000000000 -0800 ++++ dbm.3 2009-11-06 12:49:59.000000000 -0800 +@@ -31,28 +31,54 @@ .Nm dbm_store .Nd database access functions .Sh SYNOPSIS @@ -70,7 +70,7 @@ .Sh DESCRIPTION Database access functions. These functions are implemented using -@@ -74,38 +100,38 @@ +@@ -72,38 +98,38 @@ typedef struct { .Ed .Pp The @@ -112,14 +112,14 @@ -.Fa mode . +.Fa file_mode . .Dv O_WRONLY - is treated as O_RDWR in + is not allowed in -.Fa flags . +.Fa open_flags . The pointer returned by .Fn dbm_open identifies the database and is the -@@ -130,18 +156,18 @@ - normally returns zero. +@@ -124,18 +150,18 @@ function + closes the database. .Pp The -.Fn dbm_store db key data flags @@ -140,7 +140,7 @@ is .Dv DBM_INSERT and the database already contains an entry for -@@ -153,7 +179,7 @@ +@@ -147,7 +173,7 @@ The function normally returns zero but returns 1 if the entry could not be inserted (because @@ -149,7 +149,7 @@ is .Dv DBM_INSERT , and an entry with -@@ -168,7 +194,7 @@ +@@ -162,7 +188,7 @@ function returns .Dv NULL or the @@ -158,7 +158,7 @@ corresponding to .Fa key . .Pp -@@ -223,10 +249,30 @@ +@@ -217,10 +243,30 @@ The .Fn dbm_dirfno db function returns the file descriptor to the database. diff --git a/db/man/FreeBSD/dbopen.3 b/db/man/FreeBSD/dbopen.3 index f3aee09..f976042 100644 --- a/db/man/FreeBSD/dbopen.3 +++ b/db/man/FreeBSD/dbopen.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)dbopen.3 8.5 (Berkeley) 1/2/94 -.\" $FreeBSD: src/lib/libc/db/man/dbopen.3,v 1.10 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/db/man/dbopen.3,v 1.13 2007/01/09 00:27:51 imp Exp $ .\" .Dd January 2, 1994 .Dt DBOPEN 3 @@ -98,7 +94,7 @@ is not possible.) .\".Bl -tag -width indent .\".It Dv DB_LOCK .\"Do the necessary locking in the database to support concurrent access. -.\"If concurrent access isn't needed or the database is read-only this +.\"If concurrent access is not needed or the database is read-only this .\"flag should not be set, as it tends to have an associated performance .\"penalty. .\".It Dv DB_SHMEM @@ -154,10 +150,10 @@ least the following fields: .Bd -literal typedef struct { DBTYPE type; - int (*close)(const DB *db); + int (*close)(DB *db); int (*del)(const DB *db, const DBT *key, u_int flags); int (*fd)(const DB *db); - int (*get)(const DB *db, DBT *key, DBT *data, u_int flags); + int (*get)(const DB *db, const DBT *key, DBT *data, u_int flags); int (*put)(const DB *db, DBT *key, const DBT *data, u_int flags); int (*sync)(const DB *db, u_int flags); @@ -541,7 +537,7 @@ The typedef is a mnemonic for .Dq "data base thang" , and was used -because noone could think of a reasonable name that wasn't already used. +because noone could think of a reasonable name that was not already used. .Pp The file descriptor interface is a kluge and will be deleted in a future version of the interface. diff --git a/db/man/FreeBSD/hash.3 b/db/man/FreeBSD/hash.3 index d60c809..ea8db05 100644 --- a/db/man/FreeBSD/hash.3 +++ b/db/man/FreeBSD/hash.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)hash.3 8.6 (Berkeley) 8/18/94 -.\" $FreeBSD: src/lib/libc/db/man/hash.3,v 1.8 2003/09/08 19:57:13 ru Exp $ +.\" $FreeBSD: src/lib/libc/db/man/hash.3,v 1.9 2007/01/09 00:27:51 imp Exp $ .\" .Dd August 18, 1994 .Dt HASH 3 diff --git a/db/man/FreeBSD/mpool.3 b/db/man/FreeBSD/mpool.3 index 8be65da..d5c51ae 100644 --- a/db/man/FreeBSD/mpool.3 +++ b/db/man/FreeBSD/mpool.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)mpool.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/db/man/mpool.3,v 1.13 2004/08/27 14:51:21 roam Exp $ +.\" $FreeBSD: src/lib/libc/db/man/mpool.3,v 1.15 2007/01/09 00:27:51 imp Exp $ .\" .Dd June 4, 1993 .Dt MPOOL 3 @@ -196,7 +192,7 @@ function may fail and set for the following: .Bl -tag -width Er .It Bq Er EINVAL -The requested record doesn't exist. +The requested record does not exist. .El .Pp The diff --git a/db/man/FreeBSD/recno.3 b/db/man/FreeBSD/recno.3 index b5e6f58..ff32fed 100644 --- a/db/man/FreeBSD/recno.3 +++ b/db/man/FreeBSD/recno.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)recno.3 8.5 (Berkeley) 8/18/94 -.\" $FreeBSD: src/lib/libc/db/man/recno.3,v 1.8 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/db/man/recno.3,v 1.9 2007/01/09 00:27:51 imp Exp $ .\" .Dd August 18, 1994 .Dt RECNO 3 diff --git a/db/man/dbm.3 b/db/man/dbm.3 index 0e2f3a7..6258f1c 100644 --- a/db/man/dbm.3 +++ b/db/man/dbm.3 @@ -13,11 +13,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/db/man/dbm.3,v 1.8 2003/09/08 19:57:13 ru Exp $ +.\" $FreeBSD: src/lib/libc/db/man/dbm.3,v 1.10 2009/01/30 15:28:35 gabor Exp $ .\" -.\" Note: The date here should be updated whenever a non-trivial -.\" change is made to the manual page. -.Dd July 7, 1999 +.Dd April 16, 2006 .Dt DBM 3 .Os .Sh NAME @@ -130,7 +128,7 @@ is a typical value for is a typical value for .Fa file_mode . .Dv O_WRONLY -is treated as O_RDWR in +is not allowed in .Fa open_flags . The pointer returned by .Fn dbm_open @@ -150,10 +148,6 @@ The .Fn dbm_close db function closes the database. -The -.Fn dbm_close -function -normally returns zero. .Pp The .Fn dbm_store db key content store_mode diff --git a/db/mpool/FreeBSD/mpool.c b/db/mpool/FreeBSD/mpool.c index 3a1c29d..6938194 100644 --- a/db/mpool/FreeBSD/mpool.c +++ b/db/mpool/FreeBSD/mpool.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/mpool/mpool.c,v 1.12 2004/09/10 05:41:41 kuriyama Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/mpool/mpool.c,v 1.16 2009/03/28 04:00:46 delphij Exp $"); #include "namespace.h" #include @@ -62,11 +58,9 @@ static int mpool_write(MPOOL *, BKT *); * mpool_open -- * Initialize a memory pool. */ +/* ARGSUSED */ MPOOL * -mpool_open(key, fd, pagesize, maxcache) - void *key; - int fd; - pgno_t pagesize, maxcache; +mpool_open(void *key, int fd, pgno_t pagesize, pgno_t maxcache) { struct stat sb; MPOOL *mp; @@ -103,11 +97,8 @@ mpool_open(key, fd, pagesize, maxcache) * Initialize input/output filters. */ void -mpool_filter(mp, pgin, pgout, pgcookie) - MPOOL *mp; - void (*pgin)(void *, pgno_t, void *); - void (*pgout)(void *, pgno_t, void *); - void *pgcookie; +mpool_filter(MPOOL *mp, void (*pgin) (void *, pgno_t, void *), + void (*pgout) (void *, pgno_t, void *), void *pgcookie) { mp->pgin = pgin; mp->pgout = pgout; @@ -153,11 +144,10 @@ mpool_new(mp, pgnoaddr) * mpool_get * Get a page. */ +/* ARGSUSED */ void * -mpool_get(mp, pgno, flags) - MPOOL *mp; - pgno_t pgno; - u_int flags; /* XXX not used? */ +mpool_get(MPOOL *mp, pgno_t pgno, + u_int flags) /* XXX not used? */ { struct _hqh *head; BKT *bp; @@ -237,11 +227,9 @@ mpool_get(mp, pgno, flags) * mpool_put * Return a page. */ +/* ARGSUSED */ int -mpool_put(mp, page, flags) - MPOOL *mp; - void *page; - u_int flags; +mpool_put(MPOOL *mp, void *page, u_int flags) { BKT *bp; @@ -266,8 +254,7 @@ mpool_put(mp, page, flags) * Close the buffer pool. */ int -mpool_close(mp) - MPOOL *mp; +mpool_close(MPOOL *mp) { BKT *bp; @@ -288,8 +275,7 @@ mpool_close(mp) * Sync the pool to disk. */ int -mpool_sync(mp) - MPOOL *mp; +mpool_sync(MPOOL *mp) { BKT *bp; @@ -308,8 +294,7 @@ mpool_sync(mp) * Get a page from the cache (or create one). */ static BKT * -mpool_bkt(mp) - MPOOL *mp; +mpool_bkt(MPOOL *mp) { struct _hqh *head; BKT *bp; @@ -347,13 +332,10 @@ mpool_bkt(mp) return (bp); } -new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL) +new: if ((bp = (BKT *)calloc(1, sizeof(BKT) + mp->pagesize)) == NULL) return (NULL); #ifdef STATISTICS ++mp->pagealloc; -#endif -#if defined(DEBUG) || defined(PURIFY) - memset(bp, 0xff, sizeof(BKT) + mp->pagesize); #endif bp->page = (char *)bp + sizeof(BKT); ++mp->curcache; @@ -365,9 +347,7 @@ new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL) * Write a page to disk. */ static int -mpool_write(mp, bp) - MPOOL *mp; - BKT *bp; +mpool_write(MPOOL *mp, BKT *bp) { off_t off; @@ -392,9 +372,7 @@ mpool_write(mp, bp) * Lookup a page in the cache. */ static BKT * -mpool_look(mp, pgno) - MPOOL *mp; - pgno_t pgno; +mpool_look(MPOOL *mp, pgno_t pgno) { struct _hqh *head; BKT *bp; @@ -419,16 +397,15 @@ mpool_look(mp, pgno) * Print out cache statistics. */ void -mpool_stat(mp) - MPOOL *mp; +mpool_stat(MPOOL *mp) { BKT *bp; int cnt; char *sep; - (void)fprintf(stderr, "%u pages in the file\n", mp->npages); + (void)fprintf(stderr, "%lu pages in the file\n", mp->npages); (void)fprintf(stderr, - "page size %lu, cacheing %u pages of %u page max cache\n", + "page size %lu, cacheing %lu pages of %lu page max cache\n", mp->pagesize, mp->curcache, mp->maxcache); (void)fprintf(stderr, "%lu page puts, %lu page gets, %lu page new\n", mp->pageput, mp->pageget, mp->pagenew); diff --git a/db/mpool/FreeBSD/mpool.c.patch b/db/mpool/FreeBSD/mpool.c.patch index c824f5d..2193284 100644 --- a/db/mpool/FreeBSD/mpool.c.patch +++ b/db/mpool/FreeBSD/mpool.c.patch @@ -1,6 +1,6 @@ ---- mpool.c.orig 2008-09-07 11:37:54.000000000 -0700 -+++ mpool.c 2008-09-07 12:46:41.000000000 -0700 -@@ -128,7 +128,7 @@ mpool_new(mp, pgnoaddr) +--- mpool.c.orig 2009-11-06 12:36:03.000000000 -0800 ++++ mpool.c 2009-11-06 12:36:15.000000000 -0800 +@@ -119,7 +119,7 @@ mpool_new(mp, pgnoaddr) if (mp->npages == MAX_PAGE_NUMBER) { (void)fprintf(stderr, "mpool_new: page allocation overflow.\n"); @@ -9,7 +9,7 @@ } #ifdef STATISTICS ++mp->pagenew; -@@ -180,7 +180,7 @@ mpool_get(mp, pgno, flags) +@@ -170,7 +170,7 @@ mpool_get(MPOOL *mp, pgno_t pgno, if (bp->flags & MPOOL_PINNED) { (void)fprintf(stderr, "mpool_get: page %d already pinned\n", bp->pgno); @@ -18,7 +18,7 @@ } #endif /* -@@ -253,7 +253,7 @@ mpool_put(mp, page, flags) +@@ -241,7 +241,7 @@ mpool_put(MPOOL *mp, void *page, u_int f if (!(bp->flags & MPOOL_PINNED)) { (void)fprintf(stderr, "mpool_put: page %d not pinned\n", bp->pgno); @@ -27,7 +27,7 @@ } #endif bp->flags &= ~MPOOL_PINNED; -@@ -294,10 +294,16 @@ mpool_sync(mp) +@@ -280,10 +280,16 @@ mpool_sync(MPOOL *mp) BKT *bp; /* Walk the lru chain, flushing any dirty pages to disk. */ diff --git a/db/mpool/mpool-fbsd.c b/db/mpool/mpool-fbsd.c index 4928ed2..36fb30b 100644 --- a/db/mpool/mpool-fbsd.c +++ b/db/mpool/mpool-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/mpool/mpool.c,v 1.12 2004/09/10 05:41:41 kuriyama Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/mpool/mpool.c,v 1.16 2009/03/28 04:00:46 delphij Exp $"); #include "namespace.h" #include @@ -62,11 +58,9 @@ static int mpool_write(MPOOL *, BKT *); * mpool_open -- * Initialize a memory pool. */ +/* ARGSUSED */ MPOOL * -mpool_open(key, fd, pagesize, maxcache) - void *key; - int fd; - pgno_t pagesize, maxcache; +mpool_open(void *key, int fd, pgno_t pagesize, pgno_t maxcache) { struct stat sb; MPOOL *mp; @@ -103,11 +97,8 @@ mpool_open(key, fd, pagesize, maxcache) * Initialize input/output filters. */ void -mpool_filter(mp, pgin, pgout, pgcookie) - MPOOL *mp; - void (*pgin)(void *, pgno_t, void *); - void (*pgout)(void *, pgno_t, void *); - void *pgcookie; +mpool_filter(MPOOL *mp, void (*pgin) (void *, pgno_t, void *), + void (*pgout) (void *, pgno_t, void *), void *pgcookie) { mp->pgin = pgin; mp->pgout = pgout; @@ -153,11 +144,10 @@ mpool_new(mp, pgnoaddr) * mpool_get * Get a page. */ +/* ARGSUSED */ void * -mpool_get(mp, pgno, flags) - MPOOL *mp; - pgno_t pgno; - u_int flags; /* XXX not used? */ +mpool_get(MPOOL *mp, pgno_t pgno, + u_int flags) /* XXX not used? */ { struct _hqh *head; BKT *bp; @@ -237,11 +227,9 @@ mpool_get(mp, pgno, flags) * mpool_put * Return a page. */ +/* ARGSUSED */ int -mpool_put(mp, page, flags) - MPOOL *mp; - void *page; - u_int flags; +mpool_put(MPOOL *mp, void *page, u_int flags) { BKT *bp; @@ -266,8 +254,7 @@ mpool_put(mp, page, flags) * Close the buffer pool. */ int -mpool_close(mp) - MPOOL *mp; +mpool_close(MPOOL *mp) { BKT *bp; @@ -288,8 +275,7 @@ mpool_close(mp) * Sync the pool to disk. */ int -mpool_sync(mp) - MPOOL *mp; +mpool_sync(MPOOL *mp) { BKT *bp; @@ -314,8 +300,7 @@ mpool_sync(mp) * Get a page from the cache (or create one). */ static BKT * -mpool_bkt(mp) - MPOOL *mp; +mpool_bkt(MPOOL *mp) { struct _hqh *head; BKT *bp; @@ -353,13 +338,10 @@ mpool_bkt(mp) return (bp); } -new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL) +new: if ((bp = (BKT *)calloc(1, sizeof(BKT) + mp->pagesize)) == NULL) return (NULL); #ifdef STATISTICS ++mp->pagealloc; -#endif -#if defined(DEBUG) || defined(PURIFY) - memset(bp, 0xff, sizeof(BKT) + mp->pagesize); #endif bp->page = (char *)bp + sizeof(BKT); ++mp->curcache; @@ -371,9 +353,7 @@ new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL) * Write a page to disk. */ static int -mpool_write(mp, bp) - MPOOL *mp; - BKT *bp; +mpool_write(MPOOL *mp, BKT *bp) { off_t off; @@ -398,9 +378,7 @@ mpool_write(mp, bp) * Lookup a page in the cache. */ static BKT * -mpool_look(mp, pgno) - MPOOL *mp; - pgno_t pgno; +mpool_look(MPOOL *mp, pgno_t pgno) { struct _hqh *head; BKT *bp; @@ -425,16 +403,15 @@ mpool_look(mp, pgno) * Print out cache statistics. */ void -mpool_stat(mp) - MPOOL *mp; +mpool_stat(MPOOL *mp) { BKT *bp; int cnt; char *sep; - (void)fprintf(stderr, "%u pages in the file\n", mp->npages); + (void)fprintf(stderr, "%lu pages in the file\n", mp->npages); (void)fprintf(stderr, - "page size %lu, cacheing %u pages of %u page max cache\n", + "page size %lu, cacheing %lu pages of %lu page max cache\n", mp->pagesize, mp->curcache, mp->maxcache); (void)fprintf(stderr, "%lu page puts, %lu page gets, %lu page new\n", mp->pageput, mp->pageget, mp->pagenew); diff --git a/db/recno/FreeBSD/extern.h b/db/recno/FreeBSD/extern.h index 8c59f47..ad00805 100644 --- a/db/recno/FreeBSD/extern.h +++ b/db/recno/FreeBSD/extern.h @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -31,7 +27,7 @@ * SUCH DAMAGE. * * @(#)extern.h 8.3 (Berkeley) 6/4/94 - * $FreeBSD: src/lib/libc/db/recno/extern.h,v 1.2 2002/03/21 22:46:28 obrien Exp $ + * $FreeBSD: src/lib/libc/db/recno/extern.h,v 1.3 2007/01/09 00:27:51 imp Exp $ */ #include "../btree/extern.h" diff --git a/db/recno/FreeBSD/extern.h.patch b/db/recno/FreeBSD/extern.h.patch index 9a200e8..e5ff9e2 100644 --- a/db/recno/FreeBSD/extern.h.patch +++ b/db/recno/FreeBSD/extern.h.patch @@ -1,7 +1,7 @@ ---- extern.h.orig Thu Mar 21 14:46:28 2002 -+++ extern.h Sat Oct 18 19:49:46 2003 -@@ -34,7 +34,7 @@ - * $FreeBSD: src/lib/libc/db/recno/extern.h,v 1.2 2002/03/21 22:46:28 obrien Exp $ +--- extern.h.orig 2009-11-06 12:44:16.000000000 -0800 ++++ extern.h 2009-11-06 12:44:28.000000000 -0800 +@@ -30,7 +30,7 @@ + * $FreeBSD: src/lib/libc/db/recno/extern.h,v 1.3 2007/01/09 00:27:51 imp Exp $ */ -#include "../btree/extern.h" diff --git a/db/recno/FreeBSD/rec_close.c b/db/recno/FreeBSD/rec_close.c index fea96ae..f335a9f 100644 --- a/db/recno/FreeBSD/rec_close.c +++ b/db/recno/FreeBSD/rec_close.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)rec_close.c 8.6 (Berkeley) 8/18/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_close.c,v 1.7 2003/02/16 17:29:09 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_close.c,v 1.11 2009/03/28 05:45:29 delphij Exp $"); #include "namespace.h" #include @@ -61,8 +57,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_close.c,v 1.7 2003/02/16 17:29:09 * RET_ERROR, RET_SUCCESS */ int -__rec_close(dbp) - DB *dbp; +__rec_close(DB *dbp) { BTREE *t; int status; @@ -87,9 +82,10 @@ __rec_close(dbp) if (F_ISSET(t, R_CLOSEFP)) { if (fclose(t->bt_rfp)) status = RET_ERROR; - } else + } else { if (_close(t->bt_rfd)) status = RET_ERROR; + } } if (__bt_close(dbp) == RET_ERROR) @@ -108,9 +104,7 @@ __rec_close(dbp) * RET_SUCCESS, RET_ERROR. */ int -__rec_sync(dbp, flags) - const DB *dbp; - u_int flags; +__rec_sync(const DB *dbp, u_int flags) { struct iovec iov[2]; BTREE *t; @@ -156,19 +150,19 @@ __rec_sync(dbp, flags) status = (dbp->seq)(dbp, &key, &data, R_FIRST); while (status == RET_SUCCESS) { if (_write(t->bt_rfd, data.data, data.size) != - data.size) + (ssize_t)data.size) return (RET_ERROR); status = (dbp->seq)(dbp, &key, &data, R_NEXT); } } else { - iov[1].iov_base = (char *)&t->bt_bval; + iov[1].iov_base = &t->bt_bval; iov[1].iov_len = 1; status = (dbp->seq)(dbp, &key, &data, R_FIRST); while (status == RET_SUCCESS) { iov[0].iov_base = data.data; iov[0].iov_len = data.size; - if (_writev(t->bt_rfd, iov, 2) != data.size + 1) + if (_writev(t->bt_rfd, iov, 2) != (ssize_t)(data.size + 1)) return (RET_ERROR); status = (dbp->seq)(dbp, &key, &data, R_NEXT); } diff --git a/db/recno/FreeBSD/rec_delete.c b/db/recno/FreeBSD/rec_delete.c index 1205594..f7062d2 100644 --- a/db/recno/FreeBSD/rec_delete.c +++ b/db/recno/FreeBSD/rec_delete.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)rec_delete.c 8.7 (Berkeley) 7/14/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_delete.c,v 1.2 2002/03/21 22:46:28 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_delete.c,v 1.5 2009/03/03 02:16:12 delphij Exp $"); #include @@ -63,10 +59,7 @@ static int rec_rdelete(BTREE *, recno_t); * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. */ int -__rec_delete(dbp, key, flags) - const DB *dbp; - const DBT *key; - u_int flags; +__rec_delete(const DB *dbp, const DBT *key, u_int flags) { BTREE *t; recno_t nrec; @@ -119,9 +112,7 @@ einval: errno = EINVAL; * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. */ static int -rec_rdelete(t, nrec) - BTREE *t; - recno_t nrec; +rec_rdelete(BTREE *t, recno_t nrec) { EPG *e; PAGE *h; @@ -147,16 +138,13 @@ rec_rdelete(t, nrec) * * Parameters: * t: tree - * index: index on current page to delete + * idx: index on current page to delete * * Returns: * RET_SUCCESS, RET_ERROR. */ int -__rec_dleaf(t, h, index) - BTREE *t; - PAGE *h; - u_int32_t index; +__rec_dleaf(BTREE *t, PAGE *h, u_int32_t idx) { RLEAF *rl; indx_t *ip, cnt, offset; @@ -174,7 +162,7 @@ __rec_dleaf(t, h, index) * down, overwriting the deleted record and its index. If the record * uses overflow pages, make them available for reuse. */ - to = rl = GETRLEAF(h, index); + to = rl = GETRLEAF(h, idx); if (rl->flags & P_BIGDATA && __ovfl_delete(t, rl->bytes) == RET_ERROR) return (RET_ERROR); nbytes = NRLEAF(rl); @@ -187,8 +175,8 @@ __rec_dleaf(t, h, index) memmove(from + nbytes, from, (char *)to - from); h->upper += nbytes; - offset = h->linp[index]; - for (cnt = &h->linp[index] - (ip = &h->linp[0]); cnt--; ++ip) + offset = h->linp[idx]; + for (cnt = &h->linp[idx] - (ip = &h->linp[0]); cnt--; ++ip) if (ip[0] < offset) ip[0] += nbytes; for (cnt = &h->linp[NEXTINDEX(h)] - ip; --cnt; ++ip) diff --git a/db/recno/FreeBSD/rec_get.c b/db/recno/FreeBSD/rec_get.c index d9da658..84b9ef0 100644 --- a/db/recno/FreeBSD/rec_get.c +++ b/db/recno/FreeBSD/rec_get.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_get.c,v 1.5 2002/03/22 21:52:02 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_get.c,v 1.8 2009/03/05 00:57:01 delphij Exp $"); #include @@ -62,11 +58,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_get.c,v 1.5 2002/03/22 21:52:02 ob * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. */ int -__rec_get(dbp, key, data, flags) - const DB *dbp; - const DBT *key; - DBT *data; - u_int flags; +__rec_get(const DB *dbp, const DBT *key, DBT *data, u_int flags) { BTREE *t; EPG *e; @@ -121,9 +113,7 @@ __rec_get(dbp, key, data, flags) * RET_ERROR, RET_SUCCESS */ int -__rec_fpipe(t, top) - BTREE *t; - recno_t top; +__rec_fpipe(BTREE *t, recno_t top) { DBT data; recno_t nrec; @@ -132,9 +122,7 @@ __rec_fpipe(t, top) u_char *p; if (t->bt_rdata.size < t->bt_reclen) { - t->bt_rdata.data = t->bt_rdata.data == NULL ? - malloc(t->bt_reclen) : - reallocf(t->bt_rdata.data, t->bt_reclen); + t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_reclen); if (t->bt_rdata.data == NULL) return (RET_ERROR); t->bt_rdata.size = t->bt_reclen; @@ -177,9 +165,7 @@ __rec_fpipe(t, top) * RET_ERROR, RET_SUCCESS */ int -__rec_vpipe(t, top) - BTREE *t; - recno_t top; +__rec_vpipe(BTREE *t, recno_t top) { DBT data; recno_t nrec; @@ -205,9 +191,7 @@ __rec_vpipe(t, top) if (sz == 0) { len = p - (u_char *)t->bt_rdata.data; t->bt_rdata.size += (sz = 256); - t->bt_rdata.data = t->bt_rdata.data == NULL ? - malloc(t->bt_rdata.size) : - reallocf(t->bt_rdata.data, t->bt_rdata.size); + t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_rdata.size); if (t->bt_rdata.data == NULL) return (RET_ERROR); p = (u_char *)t->bt_rdata.data + len; @@ -234,9 +218,7 @@ __rec_vpipe(t, top) * RET_ERROR, RET_SUCCESS */ int -__rec_fmap(t, top) - BTREE *t; - recno_t top; +__rec_fmap(BTREE *t, recno_t top) { DBT data; recno_t nrec; @@ -244,9 +226,7 @@ __rec_fmap(t, top) size_t len; if (t->bt_rdata.size < t->bt_reclen) { - t->bt_rdata.data = t->bt_rdata.data == NULL ? - malloc(t->bt_reclen) : - reallocf(t->bt_rdata.data, t->bt_reclen); + t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_reclen); if (t->bt_rdata.data == NULL) return (RET_ERROR); t->bt_rdata.size = t->bt_reclen; @@ -284,9 +264,7 @@ __rec_fmap(t, top) * RET_ERROR, RET_SUCCESS */ int -__rec_vmap(t, top) - BTREE *t; - recno_t top; +__rec_vmap(BTREE *t, recno_t top) { DBT data; u_char *sp, *ep; diff --git a/db/recno/FreeBSD/rec_open.c b/db/recno/FreeBSD/rec_open.c index a431f6f..c6e5571 100644 --- a/db/recno/FreeBSD/rec_open.c +++ b/db/recno/FreeBSD/rec_open.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)rec_open.c 8.10 (Berkeley) 9/1/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_open.c,v 1.6 2002/03/22 21:52:02 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_open.c,v 1.9 2009/03/04 00:58:04 delphij Exp $"); #include "namespace.h" #include @@ -57,10 +53,8 @@ __FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_open.c,v 1.6 2002/03/22 21:52:02 o #include "recno.h" DB * -__rec_open(fname, flags, mode, openinfo, dflags) - const char *fname; - int flags, mode, dflags; - const RECNOINFO *openinfo; +__rec_open(const char *fname, int flags, int mode, const RECNOINFO *openinfo, + int dflags) { BTREE *t; BTREEINFO btopeninfo; @@ -209,7 +203,7 @@ slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL) if (openinfo && openinfo->flags & R_SNAPSHOT && !F_ISSET(t, R_EOF | R_INMEM) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) - goto err; + goto err; return (dbp); einval: errno = EINVAL; @@ -223,8 +217,7 @@ err: sverrno = errno; } int -__rec_fd(dbp) - const DB *dbp; +__rec_fd(const DB *dbp) { BTREE *t; diff --git a/db/recno/FreeBSD/rec_put.c b/db/recno/FreeBSD/rec_put.c index 14cc811..1730066 100644 --- a/db/recno/FreeBSD/rec_put.c +++ b/db/recno/FreeBSD/rec_put.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)rec_put.c 8.7 (Berkeley) 8/18/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_put.c,v 1.6 2002/03/22 21:52:02 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_put.c,v 1.11 2009/03/28 05:45:29 delphij Exp $"); #include @@ -61,11 +57,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_put.c,v 1.6 2002/03/22 21:52:02 ob * already in the tree and R_NOOVERWRITE specified. */ int -__rec_put(dbp, key, data, flags) - const DB *dbp; - DBT *key; - const DBT *data; - u_int flags; +__rec_put(const DB *dbp, DBT *key, const DBT *data, u_int flags) { BTREE *t; DBT fdata, tdata; @@ -177,7 +169,7 @@ einval: errno = EINVAL; t->bt_cursor.rcursor = nrec; break; } - + F_SET(t, R_MODIFIED); return (__rec_ret(t, NULL, nrec, key, NULL)); } @@ -194,16 +186,12 @@ einval: errno = EINVAL; * RET_ERROR, RET_SUCCESS */ int -__rec_iput(t, nrec, data, flags) - BTREE *t; - recno_t nrec; - const DBT *data; - u_int flags; +__rec_iput(BTREE *t, recno_t nrec, const DBT *data, u_int flags) { DBT tdata; EPG *e; PAGE *h; - indx_t index, nxtindex; + indx_t idx, nxtindex; pgno_t pg; u_int32_t nbytes; int dflags, status; @@ -234,7 +222,7 @@ __rec_iput(t, nrec, data, flags) return (RET_ERROR); h = e->page; - index = e->index; + idx = e->index; /* * Add the specified key/data pair to the tree. The R_IAFTER and @@ -244,13 +232,13 @@ __rec_iput(t, nrec, data, flags) */ switch (flags) { case R_IAFTER: - ++index; + ++idx; break; case R_IBEFORE: break; default: if (nrec < t->bt_nrecs && - __rec_dleaf(t, h, index) == RET_ERROR) { + __rec_dleaf(t, h, idx) == RET_ERROR) { mpool_put(t->bt_mp, h, 0); return (RET_ERROR); } @@ -263,19 +251,19 @@ __rec_iput(t, nrec, data, flags) * the offset array, shift the pointers up. */ nbytes = NRLEAFDBT(data->size); - if (h->upper - h->lower < nbytes + sizeof(indx_t)) { - status = __bt_split(t, h, NULL, data, dflags, nbytes, index); + if ((u_int32_t)(h->upper - h->lower) < nbytes + sizeof(indx_t)) { + status = __bt_split(t, h, NULL, data, dflags, nbytes, idx); if (status == RET_SUCCESS) ++t->bt_nrecs; return (status); } - if (index < (nxtindex = NEXTINDEX(h))) - memmove(h->linp + index + 1, h->linp + index, - (nxtindex - index) * sizeof(indx_t)); + if (idx < (nxtindex = NEXTINDEX(h))) + memmove(h->linp + idx + 1, h->linp + idx, + (nxtindex - idx) * sizeof(indx_t)); h->lower += sizeof(indx_t); - h->linp[index] = h->upper -= nbytes; + h->linp[idx] = h->upper -= nbytes; dest = (char *)h + h->upper; WR_RLEAF(dest, data, dflags); diff --git a/db/recno/FreeBSD/rec_search.c b/db/recno/FreeBSD/rec_search.c index 3353bfb..545209f 100644 --- a/db/recno/FreeBSD/rec_search.c +++ b/db/recno/FreeBSD/rec_search.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)rec_search.c 8.4 (Berkeley) 7/14/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_search.c,v 1.4 2002/03/21 18:47:38 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_search.c,v 1.8 2009/03/04 00:58:04 delphij Exp $"); #include @@ -51,7 +47,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_search.c,v 1.4 2002/03/21 18:47:38 * Parameters: * t: tree to search * recno: key to find - * op: search operation + * op: search operation * * Returns: * EPG for matching record, if any, or the EPG for the location of the @@ -63,12 +59,9 @@ __FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_search.c,v 1.4 2002/03/21 18:47:38 * the bt_cur field of the tree. A pointer to the field is returned. */ EPG * -__rec_search(t, recno, op) - BTREE *t; - recno_t recno; - enum SRCHOP op; +__rec_search(BTREE *t, recno_t recno, enum SRCHOP op) { - indx_t index; + indx_t idx; PAGE *h; EPGNO *parent; RINTERNAL *r; @@ -86,23 +79,23 @@ __rec_search(t, recno, op) t->bt_cur.index = recno - total; return (&t->bt_cur); } - for (index = 0, top = NEXTINDEX(h);;) { - r = GETRINTERNAL(h, index); - if (++index == top || total + r->nrecs > recno) + for (idx = 0, top = NEXTINDEX(h);;) { + r = GETRINTERNAL(h, idx); + if (++idx == top || total + r->nrecs > recno) break; total += r->nrecs; } - BT_PUSH(t, pg, index - 1); - + BT_PUSH(t, pg, idx - 1); + pg = r->pgno; switch (op) { case SDELETE: - --GETRINTERNAL(h, (index - 1))->nrecs; + --GETRINTERNAL(h, (idx - 1))->nrecs; mpool_put(t->bt_mp, h, MPOOL_DIRTY); break; case SINSERT: - ++GETRINTERNAL(h, (index - 1))->nrecs; + ++GETRINTERNAL(h, (idx - 1))->nrecs; mpool_put(t->bt_mp, h, MPOOL_DIRTY); break; case SEARCH: @@ -121,8 +114,8 @@ err: sverrno = errno; --GETRINTERNAL(h, parent->index)->nrecs; else ++GETRINTERNAL(h, parent->index)->nrecs; - mpool_put(t->bt_mp, h, MPOOL_DIRTY); - } + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + } errno = sverrno; return (NULL); } diff --git a/db/recno/FreeBSD/rec_seq.c b/db/recno/FreeBSD/rec_seq.c index 6ed3384..fc9c644 100644 --- a/db/recno/FreeBSD/rec_seq.c +++ b/db/recno/FreeBSD/rec_seq.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -36,7 +32,7 @@ /* XXX use __SCCSID */ static char sccsid[] __unused = "@(#)rec_seq.c 8.3 (Berkeley) 7/14/94"; #endif /* not lint */ -__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_seq.c,v 1.5 2003/02/16 17:29:09 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_seq.c,v 1.8 2009/03/04 00:58:04 delphij Exp $"); #include @@ -61,10 +57,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_seq.c,v 1.5 2003/02/16 17:29:09 ne * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. */ int -__rec_seq(dbp, key, data, flags) - const DB *dbp; - DBT *key, *data; - u_int flags; +__rec_seq(const DB *dbp, DBT *key, DBT *data, u_int flags) { BTREE *t; EPG *e; @@ -110,7 +103,7 @@ __rec_seq(dbp, key, data, flags) einval: errno = EINVAL; return (RET_ERROR); } - + if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) { if (!F_ISSET(t, R_EOF | R_INMEM) && (status = t->bt_irec(t, nrec)) != RET_SUCCESS) diff --git a/db/recno/FreeBSD/rec_utils.c b/db/recno/FreeBSD/rec_utils.c index 81fa1d6..3e69af2 100644 --- a/db/recno/FreeBSD/rec_utils.c +++ b/db/recno/FreeBSD/rec_utils.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)rec_utils.c 8.6 (Berkeley) 7/16/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_utils.c,v 1.2 2002/03/22 21:52:02 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_utils.c,v 1.6 2009/03/05 00:57:01 delphij Exp $"); #include @@ -55,17 +51,13 @@ __FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_utils.c,v 1.2 2002/03/22 21:52:02 * e: key/data pair to be returned * nrec: record number * key: user's key structure - * data: user's data structure + * data: user's data structure * * Returns: * RET_SUCCESS, RET_ERROR. */ int -__rec_ret(t, e, nrec, key, data) - BTREE *t; - EPG *e; - recno_t nrec; - DBT *key, *data; +__rec_ret(BTREE *t, EPG *e, recno_t nrec, DBT *key, DBT *data) { RLEAF *rl; void *p; @@ -75,9 +67,7 @@ __rec_ret(t, e, nrec, key, data) /* We have to copy the key, it's not on the page. */ if (sizeof(recno_t) > t->bt_rkey.size) { - p = (void *)(t->bt_rkey.data == NULL ? - malloc(sizeof(recno_t)) : - realloc(t->bt_rkey.data, sizeof(recno_t))); + p = realloc(t->bt_rkey.data, sizeof(recno_t)); if (p == NULL) return (RET_ERROR); t->bt_rkey.data = p; @@ -105,9 +95,7 @@ dataonly: } else if (F_ISSET(t, B_DB_LOCK)) { /* Use +1 in case the first record retrieved is 0 length. */ if (rl->dsize + 1 > t->bt_rdata.size) { - p = (void *)(t->bt_rdata.data == NULL ? - malloc(rl->dsize + 1) : - realloc(t->bt_rdata.data, rl->dsize + 1)); + p = realloc(t->bt_rdata.data, rl->dsize + 1); if (p == NULL) return (RET_ERROR); t->bt_rdata.data = p; diff --git a/db/recno/FreeBSD/recno.h b/db/recno/FreeBSD/recno.h index b0c0af7..d5e10f0 100644 --- a/db/recno/FreeBSD/recno.h +++ b/db/recno/FreeBSD/recno.h @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -31,7 +27,7 @@ * SUCH DAMAGE. * * @(#)recno.h 8.1 (Berkeley) 6/4/93 - * $FreeBSD: src/lib/libc/db/recno/recno.h,v 1.2 2002/03/22 23:41:40 obrien Exp $ + * $FreeBSD: src/lib/libc/db/recno/recno.h,v 1.3 2007/01/09 00:27:52 imp Exp $ */ enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */ diff --git a/db/recno/FreeBSD/recno.h.patch b/db/recno/FreeBSD/recno.h.patch index 0226317..4b968d4 100644 --- a/db/recno/FreeBSD/recno.h.patch +++ b/db/recno/FreeBSD/recno.h.patch @@ -1,6 +1,6 @@ ---- recno/FreeBSD/recno.h.orig 2007-03-13 10:38:09.000000000 -0700 -+++ recno/FreeBSD/recno.h 2007-03-14 22:20:30.000000000 -0700 -@@ -37,4 +37,4 @@ +--- recno.h.orig 2009-11-06 12:44:16.000000000 -0800 ++++ recno.h 2009-11-06 12:44:28.000000000 -0800 +@@ -33,4 +33,4 @@ enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */ #include "../btree/btree.h" diff --git a/db/recno/rec_extern.h b/db/recno/rec_extern.h index a0e37cb..179a612 100644 --- a/db/recno/rec_extern.h +++ b/db/recno/rec_extern.h @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -31,7 +27,7 @@ * SUCH DAMAGE. * * @(#)extern.h 8.3 (Berkeley) 6/4/94 - * $FreeBSD: src/lib/libc/db/recno/extern.h,v 1.2 2002/03/21 22:46:28 obrien Exp $ + * $FreeBSD: src/lib/libc/db/recno/extern.h,v 1.3 2007/01/09 00:27:51 imp Exp $ */ #include "../btree/bt_extern.h" diff --git a/db/recno/recno.h b/db/recno/recno.h index 9a247bc..26eb9f3 100644 --- a/db/recno/recno.h +++ b/db/recno/recno.h @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -31,7 +27,7 @@ * SUCH DAMAGE. * * @(#)recno.h 8.1 (Berkeley) 6/4/93 - * $FreeBSD: src/lib/libc/db/recno/recno.h,v 1.2 2002/03/22 23:41:40 obrien Exp $ + * $FreeBSD: src/lib/libc/db/recno/recno.h,v 1.3 2007/01/09 00:27:52 imp Exp $ */ enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */ diff --git a/emulated/Makefile.inc b/emulated/Makefile.inc index 3e5ac1c..1d8399b 100644 --- a/emulated/Makefile.inc +++ b/emulated/Makefile.inc @@ -1,6 +1,7 @@ .PATH: ${.CURDIR}/emulated MISRCS+=bsd_signal.c \ + brk.c \ lchflags.c \ lchmod.c \ lutimes.c \ @@ -8,6 +9,10 @@ MISRCS+=bsd_signal.c \ tcgetsid.c .if ${LIB} == "c" +MAN2+= brk.2 + +MLINKS+=brk.2 sbrk.2 + MAN3+= bsd_signal.3 lchflags.3 lchmod.3 lutimes.3 statvfs.3 tcgetsid.3 MLINKS+=statvfs.3 fstatvfs.3 diff --git a/emulated/brk.2 b/emulated/brk.2 new file mode 100644 index 0000000..9ea4f61 --- /dev/null +++ b/emulated/brk.2 @@ -0,0 +1,150 @@ +.\" $NetBSD: brk.2,v 1.7 1995/02/27 12:31:57 cgd Exp $ +.\" +.\" Copyright (c) 1980, 1991, 1993 +.\" The Regents of the University of California. 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. +.\" +.\" @(#)brk.2 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt BRK 2 +.Os BSD 4 +.Sh NAME +.Nm brk , +.Nm sbrk +.Nd change data segment size +.Sh SYNOPSIS +.Fd #include +.Ft void * +.Fn brk "const void *addr" +.Ft void * +.Fn sbrk "int incr" +.Sh DESCRIPTION +.Bf -symbolic +The brk and sbrk functions are historical curiosities +left over from earlier days before the advent of virtual memory management. +.Ef +The +.Fn brk +function +sets the break or lowest address +of a process's data segment (uninitialized data) to +.Fa addr +(immediately above bss). +Data addressing is restricted between +.Fa addr +and the lowest stack pointer to the stack segment. +Memory is allocated by +.Fa brk +in page size pieces; +if +.Fa addr +is not evenly divisible by the system page size, it is +increased to the next page boundary. +.Pp +.\" The +.\" .Nm sbrk +.\" function +.\" allocates chunks of +.\" .Fa incr +.\" bytes +.\" to the process's data space +.\" and returns an address pointer. +.\" The +.\" .Xr malloc 3 +.\" function utilizes +.\" .Nm sbrk . +.\" .Pp +The current value of the program break is reliably returned by +.Dq Li sbrk(0) +(see also +.Xr end 3 ) . +The +.Xr getrlimit 2 +system call may be used to determine +the maximum permissible size of the +.Em data +segment; +it will not be possible to set the break +beyond the +.Em rlim_max +value returned from a call to +.Xr getrlimit , +e.g. +.Dq qetext + rlp\(->rlim_max. +(see +.Xr end 3 +for the definition of +.Em etext ) . +.Sh RETURN VALUES +.Nm Brk +returns a pointer to the new end of memory if successful; +otherwise -1 with +.Va errno +set to indicate why the allocation failed. +The +.Nm sbrk +function returns a pointer to the base of the new storage if successful; +otherwise -1 with +.Va errno +set to indicate why the allocation failed. +.Sh ERRORS +.Xr Sbrk +will fail and no additional memory will be allocated if +one of the following are true: +.Bl -tag -width Er +.It Bq Er ENOMEM +The limit, as set by +.Xr setrlimit 2 , +was exceeded. +.It Bq Er ENOMEM +The maximum possible size of a data segment (compiled into the +system) was exceeded. +.It Bq Er ENOMEM +Insufficient space existed in the swap area +to support the expansion. +.El +.Sh SEE ALSO +.Xr execve 2 , +.Xr getrlimit 2 , +.Xr malloc 3 , +.Xr mmap 2 , +.Xr end 3 +.Sh BUGS +Setting the break may fail due to a temporary lack of +swap space. It is not possible to distinguish this +from a failure caused by exceeding the maximum size of +the data segment without consulting +.Xr getrlimit . +.Sh HISTORY +A +.Fn brk +function call appeared in +.At v7 . diff --git a/emulated/brk.c b/emulated/brk.c new file mode 100644 index 0000000..3d20446 --- /dev/null +++ b/emulated/brk.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1999-2010 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * File: brk.c + * + * Unix compatibility for sbrk system call. + * + * HISTORY + * 09-Mar-90 Gregg Kellogg (gk) at NeXT. + * include instead of + * + * 14-Feb-89 Avadis Tevanian (avie) at NeXT. + * Total rewrite using a fixed area of VM from break region. + */ + +#include /* for vm_allocate, vm_offset_t */ +#include +#include + +static int sbrk_needs_init = TRUE; +static vm_size_t sbrk_region_size = 4*1024*1024; /* Well, what should it be? */ +static vm_address_t sbrk_curbrk; + +void *sbrk(int size) +{ + kern_return_t ret; + + if (sbrk_needs_init) { + sbrk_needs_init = FALSE; + /* + * Allocate a big region to simulate break region. + */ + ret = vm_allocate(mach_task_self(), &sbrk_curbrk, sbrk_region_size, + VM_MAKE_TAG(VM_MEMORY_SBRK)|TRUE); + if (ret != KERN_SUCCESS) { + errno = ENOMEM; + return((void *)-1); + } + } + + if (size <= 0) + return((void *)sbrk_curbrk); + else if (size > sbrk_region_size) { + errno = ENOMEM; + return((void *)-1); + } + sbrk_curbrk += size; + sbrk_region_size -= size; + return((void *)(sbrk_curbrk - size)); +} + +void *brk(void *x) +{ + errno = ENOMEM; + return((void *)-1); +} diff --git a/fbsdcompat/_fbsd_compat_.h b/fbsdcompat/_fbsd_compat_.h index 4ed8bbb..cd2875e 100644 --- a/fbsdcompat/_fbsd_compat_.h +++ b/fbsdcompat/_fbsd_compat_.h @@ -122,6 +122,7 @@ #define _socketpair socketpair #define _system system #define _tcdrain tcdrain +#define _usleep usleep #define _wait wait #define _wait4 wait4 #define _waitpid waitpid @@ -155,6 +156,7 @@ #define __swapcontext swapcontext #define __system system #define __tcdrain tcdrain +#define __usleep usleep #define __vfscanf vfscanf #define __wait wait #define __waitpid waitpid diff --git a/fbsdcompat/reentrant.h b/fbsdcompat/reentrant.h new file mode 100644 index 0000000..c642dc4 --- /dev/null +++ b/fbsdcompat/reentrant.h @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 1997,98 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by J.T. Conklin. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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: src/lib/libc/include/reentrant.h,v 1.3 2004/02/25 21:03:45 green Exp $ + */ + +/* + * Requirements: + * + * 1. The thread safe mechanism should be lightweight so the library can + * be used by non-threaded applications without unreasonable overhead. + * + * 2. There should be no dependency on a thread engine for non-threaded + * applications. + * + * 3. There should be no dependency on any particular thread engine. + * + * 4. The library should be able to be compiled without support for thread + * safety. + * + * + * Rationale: + * + * One approach for thread safety is to provide discrete versions of the + * library: one thread safe, the other not. The disadvantage of this is + * that libc is rather large, and two copies of a library which are 99%+ + * identical is not an efficent use of resources. + * + * Another approach is to provide a single thread safe library. However, + * it should not add significant run time or code size overhead to non- + * threaded applications. + * + * Since the NetBSD C library is used in other projects, it should be + * easy to replace the mutual exclusion primitives with ones provided by + * another system. Similarly, it should also be easy to remove all + * support for thread safety completely if the target environment does + * not support threads. + * + * + * Implementation Details: + * + * The mutex primitives used by the library (mutex_t, mutex_lock, etc.) + * are macros which expand to the cooresponding primitives provided by + * the thread engine or to nothing. The latter is used so that code is + * not unreasonably cluttered with #ifdefs when all thread safe support + * is removed. + * + * The mutex macros can be directly mapped to the mutex primitives from + * pthreads, however it should be reasonably easy to wrap another mutex + * implementation so it presents a similar interface. + * + * Stub implementations of the mutex functions are provided with *weak* + * linkage. These functions simply return success. When linked with a + * thread library (i.e. -lpthread), the functions will override the + * stubs. + */ + +#include +#include "libc_private.h" + +#define mutex_t pthread_mutex_t +#define cond_t pthread_cond_t +#define rwlock_t pthread_rwlock_t +#define once_t pthread_once_t + +#define thread_key_t pthread_key_t +#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER +#define ONCE_INITIALIZER PTHREAD_ONCE_INIT + +#define mutex_init(m, a) _pthread_mutex_init(m, a) +#define mutex_lock(m) if (__isthreaded) \ + _pthread_mutex_lock(m) +#define mutex_unlock(m) if (__isthreaded) \ + _pthread_mutex_unlock(m) +#define mutex_trylock(m) (__isthreaded ? 0 : _pthread_mutex_trylock(m)) + +#define cond_init(c, a, p) _pthread_cond_init(c, a) +#define cond_signal(m) if (__isthreaded) \ + _pthread_cond_signal(m) +#define cond_broadcast(m) if (__isthreaded) \ + _pthread_cond_broadcast(m) +#define cond_wait(c, m) if (__isthreaded) \ + _pthread_cond_wait(c, m) + +#define rwlock_init(l, a) _pthread_rwlock_init(l, a) +#define rwlock_rdlock(l) if (__isthreaded) \ + _pthread_rwlock_rdlock(l) +#define rwlock_wrlock(l) if (__isthreaded) \ + _pthread_rwlock_wrlock(l) +#define rwlock_unlock(l) if (__isthreaded) \ + _pthread_rwlock_unlock(l) + +#define thr_keycreate(k, d) _pthread_key_create(k, d) +#define thr_setspecific(k, p) _pthread_setspecific(k, p) +#define thr_getspecific(k) _pthread_getspecific(k) +#define thr_sigsetmask(f, n, o) _pthread_sigmask(f, n, o) + +#define thr_once(o, i) _pthread_once(o, i) +#define thr_self() _pthread_self() +#define thr_exit(x) _pthread_exit(x) +#define thr_main() _pthread_main_np() diff --git a/gdtoa/FreeBSD/gdtoa-dtoa.c b/gdtoa/FreeBSD/gdtoa-dtoa.c index 48fdf5e..f89ac0c 100644 --- a/gdtoa/FreeBSD/gdtoa-dtoa.c +++ b/gdtoa/FreeBSD/gdtoa-dtoa.c @@ -75,10 +75,10 @@ THIS SOFTWARE. char * dtoa #ifdef KR_headers - (d, mode, ndigits, decpt, sign, rve) - double d; int mode, ndigits, *decpt, *sign; char **rve; + (d0, mode, ndigits, decpt, sign, rve) + double d0; int mode, ndigits, *decpt, *sign; char **rve; #else - (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) + (double d0, int mode, int ndigits, int *decpt, int *sign, char **rve) #endif { /* Arguments ndigits, decpt, sign are similar to those @@ -124,7 +124,8 @@ dtoa ULong x; #endif Bigint *b, *b1, *delta, *mlo, *mhi, *S; - double d2, ds, eps; + U d, d2, eps; + double ds; char *s, *s0; #ifdef SET_INEXACT int inexact, oldinexact; @@ -149,35 +150,35 @@ dtoa dtoa_result = 0; } #endif - - if (word0(d) & Sign_bit) { + d.d = d0; + if (word0(&d) & Sign_bit) { /* set sign for everything, including 0's and NaNs */ *sign = 1; - word0(d) &= ~Sign_bit; /* clear sign bit */ + word0(&d) &= ~Sign_bit; /* clear sign bit */ } else *sign = 0; #if defined(IEEE_Arith) + defined(VAX) #ifdef IEEE_Arith - if ((word0(d) & Exp_mask) == Exp_mask) + if ((word0(&d) & Exp_mask) == Exp_mask) #else - if (word0(d) == 0x8000) + if (word0(&d) == 0x8000) #endif { /* Infinity or NaN */ *decpt = 9999; #ifdef IEEE_Arith - if (!word1(d) && !(word0(d) & 0xfffff)) + if (!word1(&d) && !(word0(&d) & 0xfffff)) return nrv_alloc("Infinity", rve, 8); #endif return nrv_alloc("NaN", rve, 3); } #endif #ifdef IBM - dval(d) += 0; /* normalize */ + dval(&d) += 0; /* normalize */ #endif - if (!dval(d)) { + if (!dval(&d)) { *decpt = 1; return nrv_alloc("0", rve, 1); } @@ -196,26 +197,26 @@ dtoa } #endif - b = d2b(dval(d), &be, &bbits); + b = d2b(dval(&d), &be, &bbits); #ifdef Sudden_Underflow - i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); + i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); #else - if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { + if (( i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { #endif - dval(d2) = dval(d); - word0(d2) &= Frac_mask1; - word0(d2) |= Exp_11; + dval(&d2) = dval(&d); + word0(&d2) &= Frac_mask1; + word0(&d2) |= Exp_11; #ifdef IBM - if (( j = 11 - hi0bits(word0(d2) & Frac_mask) )!=0) - dval(d2) /= 1 << j; + if (( j = 11 - hi0bits(word0(&d2) & Frac_mask) )!=0) + dval(&d2) /= 1 << j; #endif /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * log10(&d) = (i-Bias)*log(2)/log(10) + log10(&d2) * - * This suggests computing an approximation k to log10(d) by + * This suggests computing an approximation k to log10(&d) by * * k = (i - Bias)*0.301029995663981 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); @@ -244,21 +245,21 @@ dtoa /* d is denormalized */ i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 - : word1(d) << 32 - i; - dval(d2) = x; - word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + x = i > 32 ? word0(&d) << (64 - i) | word1(&d) >> (i - 32) + : word1(&d) << (32 - i); + dval(&d2) = x; + word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ i -= (Bias + (P-1) - 1) + 1; denorm = 1; } #endif - ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; k = (int)ds; if (ds < 0. && ds != k) k--; /* want k = floor(ds) */ k_check = 1; if (k >= 0 && k <= Ten_pmax) { - if (dval(d) < tens[k]) + if (dval(&d) < tens[k]) k--; k_check = 0; } @@ -297,10 +298,11 @@ dtoa try_quick = 0; } leftright = 1; + ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ + /* silence erroneous "gcc -Wall" warning. */ switch(mode) { case 0: case 1: - ilim = ilim1 = -1; i = 18; ndigits = 0; break; @@ -334,7 +336,7 @@ dtoa /* Try to get by with floating-point arithmetic. */ i = 0; - dval(d2) = dval(d); + dval(&d2) = dval(&d); k0 = k; ilim0 = ilim; ieps = 2; /* conservative */ @@ -344,7 +346,7 @@ dtoa if (j & Bletch) { /* prevent overflows */ j &= Bletch - 1; - dval(d) /= bigtens[n_bigtens-1]; + dval(&d) /= bigtens[n_bigtens-1]; ieps++; } for(; j; j >>= 1, i++) @@ -352,32 +354,32 @@ dtoa ieps++; ds *= bigtens[i]; } - dval(d) /= ds; + dval(&d) /= ds; } else if (( j1 = -k )!=0) { - dval(d) *= tens[j1 & 0xf]; + dval(&d) *= tens[j1 & 0xf]; for(j = j1 >> 4; j; j >>= 1, i++) if (j & 1) { ieps++; - dval(d) *= bigtens[i]; + dval(&d) *= bigtens[i]; } } - if (k_check && dval(d) < 1. && ilim > 0) { + if (k_check && dval(&d) < 1. && ilim > 0) { if (ilim1 <= 0) goto fast_failed; ilim = ilim1; k--; - dval(d) *= 10.; + dval(&d) *= 10.; ieps++; } - dval(eps) = ieps*dval(d) + 7.; - word0(eps) -= (P-1)*Exp_msk1; + dval(&eps) = ieps*dval(&d) + 7.; + word0(&eps) -= (P-1)*Exp_msk1; if (ilim == 0) { S = mhi = 0; - dval(d) -= 5.; - if (dval(d) > dval(eps)) + dval(&d) -= 5.; + if (dval(&d) > dval(&eps)) goto one_digit; - if (dval(d) < -dval(eps)) + if (dval(&d) < -dval(&eps)) goto no_digits; goto fast_failed; } @@ -386,34 +388,34 @@ dtoa /* Use Steele & White method of only * generating digits needed. */ - dval(eps) = 0.5/tens[ilim-1] - dval(eps); + dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); for(i = 0;;) { - L = dval(d); - dval(d) -= L; + L = dval(&d); + dval(&d) -= L; *s++ = '0' + (int)L; - if (dval(d) < dval(eps)) + if (dval(&d) < dval(&eps)) goto ret1; - if (1. - dval(d) < dval(eps)) + if (1. - dval(&d) < dval(&eps)) goto bump_up; if (++i >= ilim) break; - dval(eps) *= 10.; - dval(d) *= 10.; + dval(&eps) *= 10.; + dval(&d) *= 10.; } } else { #endif /* Generate ilim digits, then fix them up. */ - dval(eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d)); - if (!(dval(d) -= L)) + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&d) *= 10.) { + L = (Long)(dval(&d)); + if (!(dval(&d) -= L)) ilim = i; *s++ = '0' + (int)L; if (i == ilim) { - if (dval(d) > 0.5 + dval(eps)) + if (dval(&d) > 0.5 + dval(&eps)) goto bump_up; - else if (dval(d) < 0.5 - dval(eps)) { + else if (dval(&d) < 0.5 - dval(&eps)) { while(*--s == '0'); s++; goto ret1; @@ -426,7 +428,7 @@ dtoa #endif fast_failed: s = s0; - dval(d) = dval(d2); + dval(&d) = dval(&d2); k = k0; ilim = ilim0; } @@ -438,22 +440,22 @@ dtoa ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = 0; - if (ilim < 0 || dval(d) <= 5*ds) + if (ilim < 0 || dval(&d) <= 5*ds) goto no_digits; goto one_digit; } - for(i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d) / ds); - dval(d) -= L*ds; + for(i = 1;; i++, dval(&d) *= 10.) { + L = (Long)(dval(&d) / ds); + dval(&d) -= L*ds; #ifdef Check_FLT_ROUNDS /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(d) < 0) { + if (dval(&d) < 0) { L--; - dval(d) += ds; + dval(&d) += ds; } #endif *s++ = '0' + (int)L; - if (!dval(d)) { + if (!dval(&d)) { #ifdef SET_INEXACT inexact = 0; #endif @@ -467,8 +469,8 @@ dtoa case 2: goto bump_up; } #endif - dval(d) += dval(d); - if (dval(d) > ds || dval(d) == ds && L & 1) { + dval(&d) += dval(&d); + if (dval(&d) > ds || (dval(&d) == ds && L & 1)) { bump_up: while(*--s == '9') if (s == s0) { @@ -533,9 +535,9 @@ dtoa && Rounding == 1 #endif ) { - if (!word1(d) && !(word0(d) & Bndry_mask) + if (!word1(&d) && !(word0(&d) & Bndry_mask) #ifndef Sudden_Underflow - && word0(d) & (Exp_mask & ~Exp_msk1) + && word0(&d) & (Exp_mask & ~Exp_msk1) #endif ) { /* The special case */ @@ -621,7 +623,7 @@ dtoa j1 = delta->sign ? 1 : cmp(b, delta); Bfree(delta); #ifndef ROUND_BIASED - if (j1 == 0 && mode != 1 && !(word1(d) & 1) + if (j1 == 0 && mode != 1 && !(word1(&d) & 1) #ifdef Honor_FLT_ROUNDS && Rounding >= 1 #endif @@ -638,11 +640,11 @@ dtoa goto ret; } #endif - if (j < 0 || j == 0 && mode != 1 + if (j < 0 || (j == 0 && mode != 1 #ifndef ROUND_BIASED - && !(word1(d) & 1) + && !(word1(&d) & 1) #endif - ) { + )) { if (!b->x[0] && b->wds <= 1) { #ifdef SET_INEXACT inexact = 0; @@ -659,7 +661,7 @@ dtoa if (j1 > 0) { b = lshift(b, 1); j1 = cmp(b, S); - if ((j1 > 0 || j1 == 0 && dig & 1) + if ((j1 > 0 || (j1 == 0 && dig & 1)) && dig++ == '9') goto round_9_up; } @@ -719,7 +721,7 @@ dtoa #endif b = lshift(b, 1); j = cmp(b, S); - if (j > 0 || j == 0 && dig & 1) { + if (j > 0 || (j == 0 && dig & 1)) { roundoff: while(*--s == '9') if (s == s0) { @@ -730,7 +732,9 @@ dtoa ++*s++; } else { +#ifdef Honor_FLT_ROUNDS trimzeros: +#endif while(*--s == '0'); s++; } @@ -745,9 +749,9 @@ dtoa #ifdef SET_INEXACT if (inexact) { if (!oldinexact) { - word0(d) = Exp_1 + (70 << Exp_shift); - word1(d) = 0; - dval(d) += 1.; + word0(&d) = Exp_1 + (70 << Exp_shift); + word1(&d) = 0; + dval(&d) += 1.; } } else if (!oldinexact) diff --git a/gdtoa/FreeBSD/gdtoa-gdtoa.c b/gdtoa/FreeBSD/gdtoa-gdtoa.c index 3b64250..4ebdf41 100644 --- a/gdtoa/FreeBSD/gdtoa-gdtoa.c +++ b/gdtoa/FreeBSD/gdtoa-gdtoa.c @@ -157,8 +157,9 @@ gdtoa int rdir, s2, s5, spec_case, try_quick; Long L; Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S; - double d, d2, ds, eps; + double d2, ds; char *s, *s0; + U d, eps; #ifndef MULTIPLE_THREADS if (dtoa_result) { @@ -197,21 +198,21 @@ gdtoa return nrv_alloc("0", rve, 1); } - dval(d) = b2d(b, &i); + dval(&d) = b2d(b, &i); i = be + bbits - 1; - word0(d) &= Frac_mask1; - word0(d) |= Exp_11; + word0(&d) &= Frac_mask1; + word0(&d) |= Exp_11; #ifdef IBM - if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) - dval(d) /= 1 << j; + if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0) + dval(&d) /= 1 << j; #endif /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * log10(&d) = (i-Bias)*log(2)/log(10) + log10(d2) * - * This suggests computing an approximation k to log10(d) by + * This suggests computing an approximation k to log10(&d) by * * k = (i - Bias)*0.301029995663981 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); @@ -231,7 +232,7 @@ gdtoa i <<= 2; i += j; #endif - ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + ds = (dval(&d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; /* correct assumption about exponent range */ if ((j = i) < 0) @@ -246,13 +247,13 @@ gdtoa #ifdef IBM j = be + bbits - 1; if ( (j1 = j & 3) !=0) - dval(d) *= 1 << j1; - word0(d) += j << Exp_shift - 2 & Exp_mask; + dval(&d) *= 1 << j1; + word0(&d) += j << Exp_shift - 2 & Exp_mask; #else - word0(d) += (be + bbits - 1) << Exp_shift; + word0(&d) += (be + bbits - 1) << Exp_shift; #endif if (k >= 0 && k <= Ten_pmax) { - if (dval(d) < tens[k]) + if (dval(&d) < tens[k]) k--; k_check = 0; } @@ -283,10 +284,11 @@ gdtoa try_quick = 0; } leftright = 1; + ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ + /* silence erroneous "gcc -Wall" warning. */ switch(mode) { case 0: case 1: - ilim = ilim1 = -1; i = (int)(nbits * .30103) + 3; ndigits = 0; break; @@ -328,10 +330,10 @@ gdtoa /* Try to get by with floating-point arithmetic. */ i = 0; - d2 = dval(d); + d2 = dval(&d); #ifdef IBM - if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) - dval(d) /= 1 << j; + if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0) + dval(&d) /= 1 << j; #endif k0 = k; ilim0 = ilim; @@ -342,7 +344,7 @@ gdtoa if (j & Bletch) { /* prevent overflows */ j &= Bletch - 1; - dval(d) /= bigtens[n_bigtens-1]; + dval(&d) /= bigtens[n_bigtens-1]; ieps++; } for(; j; j >>= 1, i++) @@ -354,30 +356,30 @@ gdtoa else { ds = 1.; if ( (j1 = -k) !=0) { - dval(d) *= tens[j1 & 0xf]; + dval(&d) *= tens[j1 & 0xf]; for(j = j1 >> 4; j; j >>= 1, i++) if (j & 1) { ieps++; - dval(d) *= bigtens[i]; + dval(&d) *= bigtens[i]; } } } - if (k_check && dval(d) < 1. && ilim > 0) { + if (k_check && dval(&d) < 1. && ilim > 0) { if (ilim1 <= 0) goto fast_failed; ilim = ilim1; k--; - dval(d) *= 10.; + dval(&d) *= 10.; ieps++; } - dval(eps) = ieps*dval(d) + 7.; - word0(eps) -= (P-1)*Exp_msk1; + dval(&eps) = ieps*dval(&d) + 7.; + word0(&eps) -= (P-1)*Exp_msk1; if (ilim == 0) { S = mhi = 0; - dval(d) -= 5.; - if (dval(d) > dval(eps)) + dval(&d) -= 5.; + if (dval(&d) > dval(&eps)) goto one_digit; - if (dval(d) < -dval(eps)) + if (dval(&d) < -dval(&eps)) goto no_digits; goto fast_failed; } @@ -386,38 +388,38 @@ gdtoa /* Use Steele & White method of only * generating digits needed. */ - dval(eps) = ds*0.5/tens[ilim-1] - dval(eps); + dval(&eps) = ds*0.5/tens[ilim-1] - dval(&eps); for(i = 0;;) { - L = (Long)(dval(d)/ds); - dval(d) -= L*ds; + L = (Long)(dval(&d)/ds); + dval(&d) -= L*ds; *s++ = '0' + (int)L; - if (dval(d) < dval(eps)) { - if (dval(d)) + if (dval(&d) < dval(&eps)) { + if (dval(&d)) inex = STRTOG_Inexlo; goto ret1; } - if (ds - dval(d) < dval(eps)) + if (ds - dval(&d) < dval(&eps)) goto bump_up; if (++i >= ilim) break; - dval(eps) *= 10.; - dval(d) *= 10.; + dval(&eps) *= 10.; + dval(&d) *= 10.; } } else { #endif /* Generate ilim digits, then fix them up. */ - dval(eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(d) *= 10.) { - if ( (L = (Long)(dval(d)/ds)) !=0) - dval(d) -= L*ds; + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&d) *= 10.) { + if ( (L = (Long)(dval(&d)/ds)) !=0) + dval(&d) -= L*ds; *s++ = '0' + (int)L; if (i == ilim) { ds *= 0.5; - if (dval(d) > ds + dval(eps)) + if (dval(&d) > ds + dval(&eps)) goto bump_up; - else if (dval(d) < ds - dval(eps)) { - if (dval(d)) + else if (dval(&d) < ds - dval(&eps)) { + if (dval(&d)) inex = STRTOG_Inexlo; goto clear_trailing0; } @@ -429,7 +431,7 @@ gdtoa #endif fast_failed: s = s0; - dval(d) = d2; + dval(&d) = d2; k = k0; ilim = ilim0; } @@ -441,22 +443,22 @@ gdtoa ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = 0; - if (ilim < 0 || dval(d) <= 5*ds) + if (ilim < 0 || dval(&d) <= 5*ds) goto no_digits; goto one_digit; } - for(i = 1;; i++, dval(d) *= 10.) { - L = dval(d) / ds; - dval(d) -= L*ds; + for(i = 1;; i++, dval(&d) *= 10.) { + L = dval(&d) / ds; + dval(&d) -= L*ds; #ifdef Check_FLT_ROUNDS /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(d) < 0) { + if (dval(&d) < 0) { L--; - dval(d) += ds; + dval(&d) += ds; } #endif *s++ = '0' + (int)L; - if (dval(d) == 0.) + if (dval(&d) == 0.) break; if (i == ilim) { if (rdir) { @@ -465,8 +467,8 @@ gdtoa inex = STRTOG_Inexlo; goto ret1; } - dval(d) += dval(d); - if (dval(d) > ds || dval(d) == ds && L & 1) { + dval(&d) += dval(&d); + if (dval(&d) > ds || (dval(&d) == ds && L & 1)) { bump_up: inex = STRTOG_Inexhi; while(*--s == '9') @@ -560,28 +562,11 @@ gdtoa * and for all and pass them and a shift to quorem, so it * can do shifts and ors to compute the numerator for q. */ -#ifdef Pack_32 - if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) !=0) - i = 32 - i; -#else - if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) !=0) - i = 16 - i; -#endif - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } - else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - if (b2 > 0) + i = ((s5 ? hi0bits(S->x[S->wds-1]) : ULbits - 1) - s2 - 4) & kmask; + m2 += i; + if ((b2 += i) > 0) b = lshift(b, b2); - if (s2 > 0) + if ((s2 += i) > 0) S = lshift(S, s2); if (k_check) { if (cmp(b,S) < 0) { @@ -646,11 +631,11 @@ gdtoa goto ret; } #endif - if (j < 0 || j == 0 && !mode + if (j < 0 || (j == 0 && !mode #ifndef ROUND_BIASED && !(bits[0] & 1) #endif - ) { + )) { if (rdir && (b->wds > 1 || b->x[0])) { if (rdir == 2) { inex = STRTOG_Inexlo; @@ -673,7 +658,7 @@ gdtoa if (j1 > 0) { b = lshift(b, 1); j1 = cmp(b, S); - if ((j1 > 0 || j1 == 0 && dig & 1) + if ((j1 > 0 || (j1 == 0 && dig & 1)) && dig++ == '9') goto round_9_up; inex = STRTOG_Inexhi; @@ -718,13 +703,13 @@ gdtoa /* Round off last digit */ if (rdir) { - if (rdir == 2 || b->wds <= 1 && !b->x[0]) + if (rdir == 2 || (b->wds <= 1 && !b->x[0])) goto chopzeros; goto roundoff; } b = lshift(b, 1); j = cmp(b, S); - if (j > 0 || j == 0 && dig & 1) { + if (j > 0 || (j == 0 && dig & 1)) { roundoff: inex = STRTOG_Inexhi; while(*--s == '9') diff --git a/gdtoa/FreeBSD/gdtoa-gethex.c b/gdtoa/FreeBSD/gdtoa-gethex.c index 13908e5..a9982c9 100644 --- a/gdtoa/FreeBSD/gdtoa-gethex.c +++ b/gdtoa/FreeBSD/gdtoa-gethex.c @@ -57,7 +57,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) static unsigned char *decimalpoint_cache; if (!(s0 = decimalpoint_cache)) { s0 = (unsigned char*)localeconv()->decimal_point; - if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) { + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { strcpy(decimalpoint_cache, s0); s0 = decimalpoint_cache; } @@ -199,7 +199,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) return STRTOG_Normal | STRTOG_Inexlo; } n = s1 - s0 - 1; - for(k = 0; n > 7; n >>= 1) + for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) k++; b = Balloc(k); x = b->x; @@ -218,7 +218,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) if (*--s1 == '.') continue; #endif - if (n == 32) { + if (n == ULbits) { *x++ = L; L = 0; n = 0; @@ -228,7 +228,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) } *x++ = L; b->wds = n = x - b->x; - n = 32*n - hi0bits(L); + n = ULbits*n - hi0bits(L); nbits = fpi->nbits; lostbits = 0; x = b->x; @@ -314,7 +314,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) break; case FPI_Round_near: if (lostbits & 2 - && (lostbits & 1) | x[0] & 1) + && (lostbits | x[0]) & 1) up = 1; break; case FPI_Round_up: @@ -333,8 +333,8 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) irv = STRTOG_Normal; } else if (b->wds > k - || (n = nbits & kmask) !=0 - && hi0bits(x[k-1]) < 32-n) { + || ((n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n)) { rshift(b,1); if (++e > fpi->emax) goto ovfl; diff --git a/gdtoa/FreeBSD/gdtoa-gethex.c.patch b/gdtoa/FreeBSD/gdtoa-gethex.c.patch index d83e41f..655851b 100644 --- a/gdtoa/FreeBSD/gdtoa-gethex.c.patch +++ b/gdtoa/FreeBSD/gdtoa-gethex.c.patch @@ -1,6 +1,6 @@ ---- gdtoa-gethex.c.orig 2008-10-28 11:14:40.000000000 -0700 -+++ gdtoa-gethex.c 2008-10-28 11:20:32.000000000 -0700 -@@ -29,6 +29,8 @@ THIS SOFTWARE. +--- gdtoa-gethex.c.orig 2010-02-24 20:50:10.000000000 -0800 ++++ gdtoa-gethex.c 2010-02-24 21:26:32.000000000 -0800 +@@ -29,34 +29,40 @@ THIS SOFTWARE. /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -8,8 +8,11 @@ + #include "gdtoaimp.h" ++#include ++ #ifdef USE_LOCALE -@@ -37,10 +39,10 @@ THIS SOFTWARE. + #include "locale.h" + #endif int #ifdef KR_headers @@ -23,7 +26,10 @@ #endif { Bigint *b; -@@ -50,13 +52,14 @@ gethex( CONST char **sp, FPI *fpi, Long + CONST unsigned char *decpt, *s0, *s, *s1; ++ unsigned char *strunc; + int big, esign, havedig, irv, j, k, n, n0, nbits, up, zret; + ULong L, lostbits, *x; Long e, e1; #ifdef USE_LOCALE int i; @@ -37,6 +43,64 @@ if (!(s0 = decimalpoint_cache)) { - s0 = (unsigned char*)localeconv()->decimal_point; + s0 = (unsigned char*)localeconv_l(loc)->decimal_point; - if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) { + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { strcpy(decimalpoint_cache, s0); s0 = decimalpoint_cache; +@@ -198,6 +204,57 @@ gethex( CONST char **sp, FPI *fpi, Long + *exp = fpi->emin; + return STRTOG_Normal | STRTOG_Inexlo; + } ++ /* ++ * Truncate the hex string if it is longer than the precision needed, ++ * to avoid denial-of-service issues with very large strings. Use ++ * additional digits to insure precision. Scan to-be-truncated digits ++ * and replace with either '1' or '0' to ensure proper rounding. ++ */ ++ { ++ int maxdigits = ((fpi->nbits + 3) >> 2) + 2; ++ size_t nd = s1 - s0; ++#ifdef USE_LOCALE ++ int dplen = strlen((const char *)decimalpoint); ++#else ++ int dplen = 1; ++#endif ++ ++ if (decpt && s0 < decpt) ++ nd -= dplen; ++ if (nd > maxdigits && (strunc = alloca(maxdigits + dplen + 2)) != NULL) { ++ ssize_t nd0 = decpt ? decpt - s0 - dplen : nd; ++ unsigned char *tp = strunc + maxdigits; ++ int found = 0; ++ if ((nd0 -= maxdigits) >= 0 || s0 >= decpt) ++ memcpy(strunc, s0, maxdigits); ++ else { ++ memcpy(strunc, s0, maxdigits + dplen); ++ tp += dplen; ++ } ++ s0 += maxdigits; ++ e += (nd - (maxdigits + 1)) << 2; ++ if (nd0 > 0) { ++ while(nd0-- > 0) ++ if (*s0++ != '0') { ++ found++; ++ break; ++ } ++ s0 += dplen; ++ } ++ if (!found && decpt) { ++ while(s0 < s1) ++ if(*s0++ != '0') { ++ found++; ++ break; ++ } ++ } ++ *tp++ = found ? '1' : '0'; ++ *tp = 0; ++ s0 = strunc; ++ s1 = tp; ++ } ++ } ++ + n = s1 - s0 - 1; + for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) + k++; diff --git a/gdtoa/FreeBSD/gdtoa-hexnan.c b/gdtoa/FreeBSD/gdtoa-hexnan.c index e07e069..a443721 100644 --- a/gdtoa/FreeBSD/gdtoa-hexnan.c +++ b/gdtoa/FreeBSD/gdtoa-hexnan.c @@ -77,7 +77,7 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0) if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') && *(CONST unsigned char*)(s+3) > ' ') s += 2; - while(c = *(CONST unsigned char*)++s) { + while((c = *(CONST unsigned char*)++s)) { if (!(h = hexdig[c])) { if (c <= ' ') { if (hd0 < havedig) { @@ -109,7 +109,7 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0) *sp = s + 1; break; } - } while(c = *++s); + } while((c = *++s)); #endif return STRTOG_NaN; } @@ -120,7 +120,7 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0) i = 1; *--x = 0; } - *x = (*x << 4) | h & 0xf; + *x = (*x << 4) | (h & 0xf); } if (!havedig) return STRTOG_NaN; diff --git a/gdtoa/FreeBSD/gdtoa-hexnan.c.patch b/gdtoa/FreeBSD/gdtoa-hexnan.c.patch index c9c60ba..ac98f17 100644 --- a/gdtoa/FreeBSD/gdtoa-hexnan.c.patch +++ b/gdtoa/FreeBSD/gdtoa-hexnan.c.patch @@ -1,106 +1,83 @@ ---- gdtoa-hexnan.c.orig 2008-03-15 10:08:33.000000000 -0700 -+++ gdtoa-hexnan.c 2008-08-30 17:55:23.000000000 -0700 -@@ -30,6 +30,7 @@ THIS SOFTWARE. +--- gdtoa-hexnan.c.orig 2010-01-29 16:36:11.000000000 -0800 ++++ gdtoa-hexnan.c 2010-01-29 16:40:59.000000000 -0800 +@@ -30,7 +30,9 @@ THIS SOFTWARE. * with " at " changed at "@" and " dot " changed to "."). */ #include "gdtoaimp.h" +#include ++#ifndef __APPLE__ static void #ifdef KR_headers -@@ -57,94 +58,53 @@ hexnan(sp, fpi, x0) + L_shift(x, x1, i) ULong *x; ULong *x1; int i; +@@ -48,6 +50,7 @@ L_shift(ULong *x, ULong *x1, int i) + x[1] >>= i; + } while(++x < x1); + } ++#endif /* !__APPLE__ */ + + int + #ifdef KR_headers +@@ -57,10 +60,21 @@ hexnan(sp, fpi, x0) hexnan( CONST char **sp, FPI *fpi, ULong *x0) #endif { -- ULong c, h, *x, *x1, *xe; ++#ifdef __APPLE__ + int nbits, len; + char *cp; ++#else /* !__APPLE__ */ + ULong c, h, *x, *x1, *xe; ++#endif /* __APPLE__ */ CONST char *s; -- int havedig, hd0, i, nbits; ++#ifndef __APPLE__ + int havedig, hd0, i, nbits; ++#endif /* !__APPLE__ */ -- if (!hexdig['0']) -- hexdig_init_D2A(); -- nbits = fpi->nbits; -- x = x0 + (nbits >> kshift); -- if (nbits & kmask) -- x++; -- *--x = 0; -- x1 = xe = x; -- havedig = hd0 = i = 0; ++#ifdef __APPLE__ + if (sp == NULL || *sp == NULL || **sp != '(') + return STRTOG_NaN; ++#else /* !__APPLE__ */ + if (!hexdig['0']) + hexdig_init_D2A(); + nbits = fpi->nbits; +@@ -70,7 +84,17 @@ hexnan( CONST char **sp, FPI *fpi, ULong + *--x = 0; + x1 = xe = x; + havedig = hd0 = i = 0; ++#endif /* __APPLE__ */ s = *sp; -- /* allow optional initial 0x or 0X */ -- while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') -- ++s; -- if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') -- && *(CONST unsigned char*)(s+3) > ' ') -- s += 2; -- while(c = *(CONST unsigned char*)++s) { -- if (!(h = hexdig[c])) { -- if (c <= ' ') { -- if (hd0 < havedig) { -- if (x < x1 && i < 8) -- L_shift(x, x1, i); -- if (x <= x0) { -- i = 8; -- continue; -- } -- hd0 = havedig; -- *--x = 0; -- x1 = x; -- i = 0; -- } -- while(*(CONST unsigned char*)(s+1) <= ' ') -- ++s; -- if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') -- && *(CONST unsigned char*)(s+3) > ' ') -- s += 2; -- continue; -- } -- if (/*(*/ c == ')' && havedig) { -- *sp = s + 1; -- break; -- } --#ifndef GDTOA_NON_PEDANTIC_NANCHECK -- do { -- if (/*(*/ c == ')') { -- *sp = s + 1; -- break; -- } -- } while(c = *++s); --#endif ++#ifdef __APPLE__ + if ((cp = strchr(s + 1, ')')) == NULL) { -+ *sp += strlen(s); -+ cp = s + 1; ++ return STRTOG_NaN; + } + else { + len = cp - (s + 1); + cp = alloca(len + 1); + if (!cp) ++#else /* !__APPLE__ */ + /* allow optional initial 0x or 0X */ + while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') + ++s; +@@ -111,7 +135,12 @@ hexnan( CONST char **sp, FPI *fpi, ULong + } + } while((c = *++s)); + #endif ++#endif /* __APPLE__ */ return STRTOG_NaN; -- } -- havedig++; -- if (++i > 8) { -- if (x <= x0) -- continue; -- i = 1; -- *--x = 0; -- } -- *x = (*x << 4) | h & 0xf; ++#ifdef __APPLE__ + strlcpy(cp, s + 1, len + 1); + *sp += len + 2; ++#else /* !__APPLE__ */ + } + havedig++; + if (++i > 8) { +@@ -121,7 +150,17 @@ hexnan( CONST char **sp, FPI *fpi, ULong + *--x = 0; + } + *x = (*x << 4) | (h & 0xf); ++#endif /* __APPLE__ */ } -- if (!havedig) -- return STRTOG_NaN; -- if (x < x1 && i < 8) -- L_shift(x, x1, i); -- if (x > x0) { -- x1 = x0; -- do *x1++ = *x++; -- while(x <= xe); -- do *x1++ = 0; -- while(x1 <= xe); ++#ifdef __APPLE__ + nbits = fpi->nbits; + /* a hack */ + if (nbits == 52) { /* double */ @@ -108,23 +85,29 @@ + u.d = nan(cp); + x0[1] = u.bits.manh; + x0[0] = u.bits.manl; ++#else /* !__APPLE__ */ + if (!havedig) + return STRTOG_NaN; + if (x < x1 && i < 8) +@@ -132,12 +171,36 @@ hexnan( CONST char **sp, FPI *fpi, ULong + while(x <= xe); + do *x1++ = 0; + while(x1 <= xe); ++#endif /* __APPLE__ */ } -- else { -- /* truncate high-order word if necessary */ -- if ( (i = nbits & (ULbits-1)) !=0) -- *xe &= ((ULong)0xffffffff) >> (ULbits - i); ++#ifdef __APPLE__ + else if (nbits < 52) { /* float */ + union IEEEf2bits u; + u.f = nanf(cp); + x0[0] = u.bits.man; ++#else /* !__APPLE__ */ + else { + /* truncate high-order word if necessary */ + if ( (i = nbits & (ULbits-1)) !=0) + *xe &= ((ULong)0xffffffff) >> (ULbits - i); ++#endif /* __APPLE__ */ } -- for(x1 = xe;; --x1) { -- if (*x1 != 0) -- break; -- if (x1 == x0) { -- *x1 = 1; -- break; -- } ++#ifdef __APPLE__ + else { /* long double */ + union IEEEl2bits u; + u.e = nanl(cp); @@ -139,7 +122,15 @@ +#else +#error unsupported architecture +#endif ++#else /* !__APPLE__ */ + for(x1 = xe;; --x1) { + if (*x1 != 0) + break; +@@ -145,6 +208,7 @@ hexnan( CONST char **sp, FPI *fpi, ULong + *x1 = 1; + break; + } ++#endif /* __APPLE__ */ } -+ return STRTOG_NaNbits; } diff --git a/gdtoa/FreeBSD/gdtoa-misc.c b/gdtoa/FreeBSD/gdtoa-misc.c index b3ce7c9..e5f7b04 100644 --- a/gdtoa/FreeBSD/gdtoa-misc.c +++ b/gdtoa/FreeBSD/gdtoa-misc.c @@ -55,7 +55,9 @@ Balloc #endif ACQUIRE_DTOA_LOCK(0); - if ( (rv = freelist[k]) !=0) { + /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ + /* but this case seems very unlikely. */ + if (k <= Kmax && (rv = freelist[k]) !=0) { freelist[k] = rv->next; } else { @@ -65,7 +67,7 @@ Balloc #else len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); - if (pmem_next - private_mem + len <= PRIVATE_mem) { + if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { rv = (Bigint*)pmem_next; pmem_next += len; } @@ -89,10 +91,18 @@ Bfree #endif { if (v) { - ACQUIRE_DTOA_LOCK(0); - v->next = freelist[v->k]; - freelist[v->k] = v; - FREE_DTOA_LOCK(0); + if (v->k > Kmax) +#ifdef FREE + FREE((void*)v); +#else + free((void*)v); +#endif + else { + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); + } } } @@ -104,8 +114,8 @@ lo0bits (ULong *y) #endif { - register int k; - register ULong x = *y; + int k; + ULong x = *y; if (x & 7) { if (x & 1) @@ -204,12 +214,12 @@ multadd int hi0bits_D2A #ifdef KR_headers - (x) register ULong x; + (x) ULong x; #else - (register ULong x) + (ULong x) #endif { - register int k = 0; + int k = 0; if (!(x & 0xffff0000)) { k = 16; @@ -612,12 +622,12 @@ b2d { ULong *xa, *xa0, w, y, z; int k; - double d; + U d; #ifdef VAX ULong d0, d1; #else -#define d0 word0(d) -#define d1 word1(d) +#define d0 word0(&d) +#define d1 word1(&d) #endif xa0 = a->x; @@ -630,16 +640,16 @@ b2d *e = 32 - k; #ifdef Pack_32 if (k < Ebits) { - d0 = Exp_1 | y >> Ebits - k; + d0 = Exp_1 | y >> (Ebits - k); w = xa > xa0 ? *--xa : 0; - d1 = y << (32-Ebits) + k | w >> Ebits - k; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); goto ret_d; } z = xa > xa0 ? *--xa : 0; if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> 32 - k; + d0 = Exp_1 | y << k | z >> (32 - k); y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> 32 - k; + d1 = z << k | y >> (32 - k); } else { d0 = Exp_1 | y; @@ -663,10 +673,10 @@ b2d #endif ret_d: #ifdef VAX - word0(d) = d0 >> 16 | d0 << 16; - word1(d) = d1 >> 16 | d1 << 16; + word0(&d) = d0 >> 16 | d0 << 16; + word1(&d) = d1 >> 16 | d1 << 16; #endif - return dval(d); + return dval(&d); } #undef d0 #undef d1 @@ -674,12 +684,13 @@ b2d Bigint * d2b #ifdef KR_headers - (d, e, bits) double d; int *e, *bits; + (dd, e, bits) double dd; int *e, *bits; #else - (double d, int *e, int *bits) + (double dd, int *e, int *bits) #endif { Bigint *b; + U d; #ifndef Sudden_Underflow int i; #endif @@ -687,11 +698,14 @@ d2b ULong *x, y, z; #ifdef VAX ULong d0, d1; - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; #else -#define d0 word0(d) -#define d1 word1(d) +#define d0 word0(&d) +#define d1 word1(&d) +#endif + d.d = dd; +#ifdef VAX + d0 = word0(&d) >> 16 | word0(&d) << 16; + d1 = word1(&d) >> 16 | word1(&d) << 16; #endif #ifdef Pack_32 @@ -715,7 +729,7 @@ d2b #ifdef Pack_32 if ( (y = d1) !=0) { if ( (k = lo0bits(&y)) !=0) { - x[0] = y | z << 32 - k; + x[0] = y | z << (32 - k); z >>= k; } else @@ -726,10 +740,6 @@ d2b b->wds = (x[1] = z) !=0 ? 2 : 1; } else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif k = lo0bits(&z); x[0] = z; #ifndef Sudden_Underflow @@ -788,7 +798,7 @@ d2b #endif #ifdef IBM *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); + *bits = 4*P + 8 - k - hi0bits(word0(&d) & Frac_mask); #else *e = de - Bias - (P-1) + k; *bits = P - k; @@ -841,7 +851,7 @@ strcp_D2A(a, b) char *a; char *b; strcp_D2A(char *a, CONST char *b) #endif { - while(*a = *b++) + while((*a = *b++)) a++; return a; } @@ -855,8 +865,8 @@ memcpy_D2A(a, b, len) Char *a; Char *b; size_t len; memcpy_D2A(void *a1, void *b1, size_t len) #endif { - register char *a = (char*)a1, *ae = a + len; - register char *b = (char*)b1, *a0 = a; + char *a = (char*)a1, *ae = a + len; + char *b = (char*)b1, *a0 = a; while(a < ae) *a++ = *b++; return a0; diff --git a/gdtoa/FreeBSD/gdtoa-misc.c.patch b/gdtoa/FreeBSD/gdtoa-misc.c.patch index 261ec59..ec8c295 100644 --- a/gdtoa/FreeBSD/gdtoa-misc.c.patch +++ b/gdtoa/FreeBSD/gdtoa-misc.c.patch @@ -1,5 +1,5 @@ ---- gdtoa-misc.c.orig 2010-01-07 22:03:21.000000000 -0800 -+++ gdtoa-misc.c 2010-01-07 22:25:33.000000000 -0800 +--- gdtoa-misc.c.orig 2010-01-12 10:59:42.000000000 -0800 ++++ gdtoa-misc.c 2010-01-12 12:08:17.000000000 -0800 @@ -29,9 +29,20 @@ THIS SOFTWARE. /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -48,7 +48,7 @@ Bigint * Balloc #ifdef KR_headers -@@ -53,9 +84,26 @@ Balloc +@@ -53,8 +84,25 @@ Balloc #ifndef Omit_Private_Memory unsigned int len; #endif @@ -70,22 +70,11 @@ + } +#else /* !GDTOA_TSD */ ACQUIRE_DTOA_LOCK(0); -- if ( (rv = freelist[k]) !=0) { +#endif /* GDTOA_TSD */ -+ if (k <= Kmax && (rv = freelist[k]) !=0) { - freelist[k] = rv->next; - } - else { -@@ -65,7 +113,7 @@ Balloc - #else - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); -- if (pmem_next - private_mem + len <= PRIVATE_mem) { -+ if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { - rv = (Bigint*)pmem_next; - pmem_next += len; - } -@@ -75,7 +123,9 @@ Balloc + /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ + /* but this case seems very unlikely. */ + if (k <= Kmax && (rv = freelist[k]) !=0) { +@@ -77,7 +125,9 @@ Balloc rv->k = k; rv->maxwds = x; } @@ -95,28 +84,20 @@ rv->sign = rv->wds = 0; return rv; } -@@ -89,10 +139,20 @@ Bfree +@@ -98,10 +148,16 @@ Bfree + free((void*)v); #endif - { - if (v) { -- ACQUIRE_DTOA_LOCK(0); -- v->next = freelist[v->k]; -- freelist[v->k] = v; -- FREE_DTOA_LOCK(0); -+ if (v->k > Kmax) -+ free((void*)v); -+ else { + else { +#ifdef GDTOA_TSD + Bigint **freelist = (Bigint **)pthread_getspecific(gdtoa_tsd_key); +#else /* !GDTOA_TSD */ -+ ACQUIRE_DTOA_LOCK(0); -+#endif /* GDTOA_TSD */ -+ v->next = freelist[v->k]; -+ freelist[v->k] = v; + ACQUIRE_DTOA_LOCK(0); ++#endif /* !GDTOA_TSD */ + v->next = freelist[v->k]; + freelist[v->k] = v; +#ifndef GDTOA_TSD -+ FREE_DTOA_LOCK(0); -+#endif /* GDTOA_TSD */ -+ } + FREE_DTOA_LOCK(0); ++#endif /* !GDTOA_TSD */ + } } } - diff --git a/gdtoa/FreeBSD/gdtoa-smisc.c b/gdtoa/FreeBSD/gdtoa-smisc.c index 163011e..f4dbafb 100644 --- a/gdtoa/FreeBSD/gdtoa-smisc.c +++ b/gdtoa/FreeBSD/gdtoa-smisc.c @@ -34,9 +34,9 @@ THIS SOFTWARE. Bigint * s2b #ifdef KR_headers - (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; + (s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9; #else - (CONST char *s, int nd0, int nd, ULong y9) + (CONST char *s, int nd0, int nd, ULong y9, int dplen) #endif { Bigint *b; @@ -60,10 +60,10 @@ s2b s += 9; do b = multadd(b, 10, *s++ - '0'); while(++i < nd0); - s++; + s += dplen; } else - s += 10; + s += dplen + 9; for(; i < nd; i++) b = multadd(b, 10, *s++ - '0'); return b; @@ -77,33 +77,33 @@ ratio (Bigint *a, Bigint *b) #endif { - double da, db; + U da, db; int k, ka, kb; - dval(da) = b2d(a, &ka); - dval(db) = b2d(b, &kb); + dval(&da) = b2d(a, &ka); + dval(&db) = b2d(b, &kb); k = ka - kb + ULbits*(a->wds - b->wds); #ifdef IBM if (k > 0) { - word0(da) += (k >> 2)*Exp_msk1; + word0(&da) += (k >> 2)*Exp_msk1; if (k &= 3) - dval(da) *= 1 << k; + dval(&da) *= 1 << k; } else { k = -k; - word0(db) += (k >> 2)*Exp_msk1; + word0(&db) += (k >> 2)*Exp_msk1; if (k &= 3) - dval(db) *= 1 << k; + dval(&db) *= 1 << k; } #else if (k > 0) - word0(da) += k*Exp_msk1; + word0(&da) += k*Exp_msk1; else { k = -k; - word0(db) += k*Exp_msk1; + word0(&db) += k*Exp_msk1; } #endif - return dval(da) / dval(db); + return dval(&da) / dval(&db); } #ifdef INFNAN_CHECK diff --git a/gdtoa/FreeBSD/gdtoa-smisc.c.patch b/gdtoa/FreeBSD/gdtoa-smisc.c.patch deleted file mode 100644 index b942b4c..0000000 --- a/gdtoa/FreeBSD/gdtoa-smisc.c.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- gdtoa-smisc.c.orig 2005-01-20 20:12:36.000000000 -0800 -+++ gdtoa-smisc.c 2005-03-24 17:33:43.000000000 -0800 -@@ -34,9 +34,9 @@ - Bigint * - s2b - #ifdef KR_headers -- (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; -+ (s, nd0, nd, y9, decpt) CONST char *s; int nd0, nd; ULong y9; int decpt; - #else -- (CONST char *s, int nd0, int nd, ULong y9) -+ (CONST char *s, int nd0, int nd, ULong y9, int decpt) - #endif - { - Bigint *b; -@@ -60,10 +60,10 @@ - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); -- s++; -+ s += decpt; - } - else -- s += 10; -+ s += 9 + decpt; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; diff --git a/gdtoa/FreeBSD/gdtoa-strtoIg.c b/gdtoa/FreeBSD/gdtoa-strtoIg.c index 90c88db..6a17760 100644 --- a/gdtoa/FreeBSD/gdtoa-strtoIg.c +++ b/gdtoa/FreeBSD/gdtoa-strtoIg.c @@ -74,7 +74,7 @@ strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp) goto swapcheck; } if (b1->wds > nw - || nb1 && b1->x[nw1] & 1L << nb1) { + || (nb1 && b1->x[nw1] & 1L << nb1)) { if (++e1 > fpi->emax) rv1 = STRTOG_Infinite | STRTOG_Inexhi; rshift(b1, 1); diff --git a/gdtoa/FreeBSD/gdtoa-strtod.c b/gdtoa/FreeBSD/gdtoa-strtod.c index cb11666..fdc933a 100644 --- a/gdtoa/FreeBSD/gdtoa-strtod.c +++ b/gdtoa/FreeBSD/gdtoa-strtod.c @@ -71,29 +71,36 @@ strtod int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; - double aadj, aadj1, adj, rv, rv0; + double aadj; Long L; + U adj, aadj1, rv, rv0; ULong y, z; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; #ifdef SET_INEXACT int inexact, oldinexact; #endif -#ifdef USE_LOCALE +#ifdef USE_LOCALE /*{{*/ #ifdef NO_LOCALE_CACHE char *decimalpoint = localeconv()->decimal_point; + int dplen = strlen(decimalpoint); #else char *decimalpoint; static char *decimalpoint_cache; + static int dplen; if (!(s0 = decimalpoint_cache)) { s0 = localeconv()->decimal_point; - if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) { + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { strcpy(decimalpoint_cache, s0); s0 = decimalpoint_cache; } + dplen = strlen(s0); } decimalpoint = (char*)s0; -#endif -#endif +#endif /*NO_LOCALE_CACHE*/ +#else /*USE_LOCALE}{*/ +#define dplen 1 +#endif /*USE_LOCALE}}*/ + #ifdef Honor_FLT_ROUNDS /*{*/ int Rounding; #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ @@ -109,7 +116,7 @@ strtod #endif /*}*/ sign = nz0 = nz = decpt = 0; - dval(rv) = 0.; + dval(&rv) = 0.; for(s = s00;;s++) switch(*s) { case '-': sign = 1; @@ -141,20 +148,12 @@ strtod case 'x': case 'X': { -#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) /*{{*/ +#ifdef Honor_FLT_ROUNDS FPI fpi1 = fpi; -#ifdef Honor_FLT_ROUNDS /*{{*/ fpi1.rounding = Rounding; -#else /*}{*/ - switch(fegetround()) { - case FE_TOWARDZERO: fpi1.rounding = 0; break; - case FE_UPWARD: fpi1.rounding = 2; break; - case FE_DOWNWARD: fpi1.rounding = 3; - } -#endif /*}}*/ -#else /*}{*/ +#else #define fpi1 fpi -#endif /*}}*/ +#endif switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { case STRTOG_NoNumber: s = s00; @@ -279,8 +278,8 @@ strtod --s; if (!match(&s,"inity")) ++s; - word0(rv) = 0x7ff00000; - word1(rv) = 0; + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; goto ret; } break; @@ -291,13 +290,13 @@ strtod if (*s == '(' /*)*/ && hexnan(&s, &fpinan, bits) == STRTOG_NaNbits) { - word0(rv) = 0x7ff00000 | bits[1]; - word1(rv) = bits[0]; + word0(&rv) = 0x7ff00000 | bits[1]; + word1(&rv) = bits[0]; } else { #endif - word0(rv) = NAN_WORD0; - word1(rv) = NAN_WORD1; + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; #ifndef No_Hex_NaN } #endif @@ -321,13 +320,13 @@ strtod if (!nd0) nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv) = y; + dval(&rv) = y; if (k > 9) { #ifdef SET_INEXACT if (k > DBL_DIG) oldinexact = get_inexact(); #endif - dval(rv) = tens[k - 9] * dval(rv) + z; + dval(&rv) = tens[k - 9] * dval(&rv) + z; } bd0 = 0; if (nd <= DBL_DIG @@ -351,7 +350,7 @@ strtod sign = 0; } #endif - /* rv = */ rounded_product(dval(rv), tens[e]); + /* rv = */ rounded_product(dval(&rv), tens[e]); goto ret; #endif } @@ -368,20 +367,20 @@ strtod } #endif e -= i; - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; #ifdef VAX /* VAX exponent range is so narrow we must * worry about overflow here... */ vax_ovfl_check: - word0(rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(rv), tens[e]); - if ((word0(rv) & Exp_mask) + word0(&rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(&rv), tens[e]); + if ((word0(&rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) goto ovfl; - word0(rv) += P*Exp_msk1; + word0(&rv) += P*Exp_msk1; #else - /* rv = */ rounded_product(dval(rv), tens[e]); + /* rv = */ rounded_product(dval(&rv), tens[e]); #endif goto ret; } @@ -395,7 +394,7 @@ strtod sign = 0; } #endif - /* rv = */ rounded_quotient(dval(rv), tens[-e]); + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); goto ret; } #endif @@ -426,7 +425,7 @@ strtod if (e1 > 0) { if ( (i = e1 & 15) !=0) - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; if (e1 &= ~15) { if (e1 > DBL_MAX_10_EXP) { ovfl: @@ -439,25 +438,25 @@ strtod switch(Rounding) { case 0: /* toward 0 */ case 3: /* toward -infinity */ - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; break; default: - word0(rv) = Exp_mask; - word1(rv) = 0; + word0(&rv) = Exp_mask; + word1(&rv) = 0; } #else /*Honor_FLT_ROUNDS*/ - word0(rv) = Exp_mask; - word1(rv) = 0; + word0(&rv) = Exp_mask; + word1(&rv) = 0; #endif /*Honor_FLT_ROUNDS*/ #ifdef SET_INEXACT /* set overflow bit */ - dval(rv0) = 1e300; - dval(rv0) *= dval(rv0); + dval(&rv0) = 1e300; + dval(&rv0) *= dval(&rv0); #endif #else /*IEEE_Arith*/ - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; #endif /*IEEE_Arith*/ if (bd0) goto retfree; @@ -466,27 +465,27 @@ strtod e1 >>= 4; for(j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= bigtens[j]; + dval(&rv) *= bigtens[j]; /* The last multiplication could overflow. */ - word0(rv) -= P*Exp_msk1; - dval(rv) *= bigtens[j]; - if ((z = word0(rv) & Exp_mask) + word0(&rv) -= P*Exp_msk1; + dval(&rv) *= bigtens[j]; + if ((z = word0(&rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-P)) goto ovfl; if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { /* set to largest number */ /* (Can't trust DBL_MAX) */ - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; } else - word0(rv) += P*Exp_msk1; + word0(&rv) += P*Exp_msk1; } } else if (e1 < 0) { e1 = -e1; if ( (i = e1 & 15) !=0) - dval(rv) /= tens[i]; + dval(&rv) /= tens[i]; if (e1 >>= 4) { if (e1 >= 1 << n_bigtens) goto undfl; @@ -495,34 +494,34 @@ strtod scale = 2*P; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= tinytens[j]; - if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + dval(&rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) >> Exp_shift)) > 0) { /* scaled rv is denormal; zap j low bits */ if (j >= 32) { - word1(rv) = 0; + word1(&rv) = 0; if (j >= 53) - word0(rv) = (P+2)*Exp_msk1; + word0(&rv) = (P+2)*Exp_msk1; else - word0(rv) &= 0xffffffff << j-32; + word0(&rv) &= 0xffffffff << (j-32); } else - word1(rv) &= 0xffffffff << j; + word1(&rv) &= 0xffffffff << j; } #else for(j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= tinytens[j]; + dval(&rv) *= tinytens[j]; /* The last multiplication could underflow. */ - dval(rv0) = dval(rv); - dval(rv) *= tinytens[j]; - if (!dval(rv)) { - dval(rv) = 2.*dval(rv0); - dval(rv) *= tinytens[j]; + dval(&rv0) = dval(&rv); + dval(&rv) *= tinytens[j]; + if (!dval(&rv)) { + dval(&rv) = 2.*dval(&rv0); + dval(&rv) *= tinytens[j]; #endif - if (!dval(rv)) { + if (!dval(&rv)) { undfl: - dval(rv) = 0.; + dval(&rv) = 0.; #ifndef NO_ERRNO errno = ERANGE; #endif @@ -531,8 +530,8 @@ strtod goto ret; } #ifndef Avoid_Underflow - word0(rv) = Tiny0; - word1(rv) = Tiny1; + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; /* The refinement below will clean * this approximation up. */ @@ -545,12 +544,12 @@ strtod /* Put digits into bd: true value = bd * 10^e */ - bd0 = s2b(s0, nd0, nd, y); + bd0 = s2b(s0, nd0, nd, y, dplen); for(;;) { bd = Balloc(bd0->k); Bcopy(bd, bd0); - bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bb = d2b(dval(&rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ bs = i2b(1); if (e >= 0) { @@ -572,7 +571,7 @@ strtod #endif #ifdef Avoid_Underflow j = bbe - scale; - i = j + bbbits - 1; /* logb(rv) */ + i = j + bbbits - 1; /* logb(&rv) */ if (i < Emin) /* denormal */ j += P - Emin; else @@ -586,7 +585,7 @@ strtod #endif #else /*Sudden_Underflow*/ j = bbe; - i = j + bbbits - 1; /* logb(rv) */ + i = j + bbbits - 1; /* logb(&rv) */ if (i < Emin) /* denormal */ j += P - Emin; else @@ -637,15 +636,15 @@ strtod } if (Rounding) { if (dsign) { - adj = 1.; + dval(&adj) = 1.; goto apply_adj; } } else if (!dsign) { - adj = -1.; - if (!word1(rv) - && !(word0(rv) & Frac_mask)) { - y = word0(rv) & Exp_mask; + dval(&adj) = -1.; + if (!word1(&rv) + && !(word0(&rv) & Frac_mask)) { + y = word0(&rv) & Exp_mask; #ifdef Avoid_Underflow if (!scale || y > 2*P*Exp_msk1) #else @@ -654,66 +653,66 @@ strtod { delta = lshift(delta,Log2P); if (cmp(delta, bs) <= 0) - adj = -0.5; + dval(&adj) = -0.5; } } apply_adj: #ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) + if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; + word0(&adj) += (2*P+1)*Exp_msk1 - y; #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - dval(rv) += adj*ulp(dval(rv)); - word0(rv) -= P*Exp_msk1; + word0(&rv) += P*Exp_msk1; + dval(&rv) += adj*ulp(&rv); + word0(&rv) -= P*Exp_msk1; } else #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - dval(rv) += adj*ulp(dval(rv)); + dval(&rv) += adj*ulp(&rv); } break; } - adj = ratio(delta, bs); + dval(&adj) = ratio(delta, bs); if (adj < 1.) - adj = 1.; + dval(&adj) = 1.; if (adj <= 0x7ffffffe) { - /* adj = Rounding ? ceil(adj) : floor(adj); */ + /* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */ y = adj; if (y != adj) { if (!((Rounding>>1) ^ dsign)) y++; - adj = y; + dval(&adj) = y; } } #ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; + if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(&adj) += (2*P+1)*Exp_msk1 - y; #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - adj *= ulp(dval(rv)); + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + word0(&rv) += P*Exp_msk1; + dval(&adj) *= ulp(&rv); if (dsign) - dval(rv) += adj; + dval(&rv) += adj; else - dval(rv) -= adj; - word0(rv) -= P*Exp_msk1; + dval(&rv) -= adj; + word0(&rv) -= P*Exp_msk1; goto cont; } #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - adj *= ulp(dval(rv)); + dval(&adj) *= ulp(&rv); if (dsign) { - if (word0(rv) == Big0 && word1(rv) == Big1) + if (word0(&rv) == Big0 && word1(&rv) == Big1) goto ovfl; - dval(rv) += adj; + dval(&rv) += adj; } else - dval(rv) -= adj; + dval(&rv) -= adj; goto cont; } #endif /*Honor_FLT_ROUNDS*/ @@ -722,12 +721,12 @@ strtod /* Error is less than half an ulp -- check for * special case of mantissa a power of two. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask #ifdef IEEE_Arith #ifdef Avoid_Underflow - || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 + || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 #else - || (word0(rv) & Exp_mask) <= Exp_msk1 + || (word0(&rv) & Exp_mask) <= Exp_msk1 #endif #endif ) { @@ -752,32 +751,32 @@ strtod if (i == 0) { /* exactly half-way between */ if (dsign) { - if ((word0(rv) & Bndry_mask1) == Bndry_mask1 - && word1(rv) == ( + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 + && word1(&rv) == ( #ifdef Avoid_Underflow - (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : #endif 0xffffffff)) { /*boundary case -- increment exponent*/ - word0(rv) = (word0(rv) & Exp_mask) + word0(&rv) = (word0(&rv) & Exp_mask) + Exp_msk1 #ifdef IBM | Exp_msk1 >> 4 #endif ; - word1(rv) = 0; + word1(&rv) = 0; #ifdef Avoid_Underflow dsign = 0; #endif break; } } - else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { + else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { drop_down: /* boundary case -- decrement exponent */ #ifdef Sudden_Underflow /*{{*/ - L = word0(rv) & Exp_mask; + L = word0(&rv) & Exp_mask; #ifdef IBM if (L < Exp_msk1) #else @@ -792,7 +791,7 @@ strtod #else /*Sudden_Underflow}{*/ #ifdef Avoid_Underflow if (scale) { - L = word0(rv) & Exp_mask; + L = word0(&rv) & Exp_mask; if (L <= (2*P+1)*Exp_msk1) { if (L > (P+2)*Exp_msk1) /* round even ==> */ @@ -803,10 +802,10 @@ strtod } } #endif /*Avoid_Underflow*/ - L = (word0(rv) & Exp_mask) - Exp_msk1; + L = (word0(&rv) & Exp_mask) - Exp_msk1; #endif /*Sudden_Underflow}}*/ - word0(rv) = L | Bndry_mask1; - word1(rv) = 0xffffffff; + word0(&rv) = L | Bndry_mask1; + word1(&rv) = 0xffffffff; #ifdef IBM goto cont; #else @@ -814,16 +813,16 @@ strtod #endif } #ifndef ROUND_BIASED - if (!(word1(rv) & LSB)) + if (!(word1(&rv) & LSB)) break; #endif if (dsign) - dval(rv) += ulp(dval(rv)); + dval(&rv) += ulp(&rv); #ifndef ROUND_BIASED else { - dval(rv) -= ulp(dval(rv)); + dval(&rv) -= ulp(&rv); #ifndef Sudden_Underflow - if (!dval(rv)) + if (!dval(&rv)) goto undfl; #endif } @@ -835,14 +834,14 @@ strtod } if ((aadj = ratio(delta, bs)) <= 2.) { if (dsign) - aadj = aadj1 = 1.; - else if (word1(rv) || word0(rv) & Bndry_mask) { + aadj = dval(&aadj1) = 1.; + else if (word1(&rv) || word0(&rv) & Bndry_mask) { #ifndef Sudden_Underflow - if (word1(rv) == Tiny1 && !word0(rv)) + if (word1(&rv) == Tiny1 && !word0(&rv)) goto undfl; #endif aadj = 1.; - aadj1 = -1.; + dval(&aadj1) = -1.; } else { /* special case -- power of FLT_RADIX to be */ @@ -852,45 +851,45 @@ strtod aadj = 1./FLT_RADIX; else aadj *= 0.5; - aadj1 = -aadj; + dval(&aadj1) = -aadj; } } else { aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; + dval(&aadj1) = dsign ? aadj : -aadj; #ifdef Check_FLT_ROUNDS switch(Rounding) { case 2: /* towards +infinity */ - aadj1 -= 0.5; + dval(&aadj1) -= 0.5; break; case 0: /* towards 0 */ case 3: /* towards -infinity */ - aadj1 += 0.5; + dval(&aadj1) += 0.5; } #else if (Flt_Rounds == 0) - aadj1 += 0.5; + dval(&aadj1) += 0.5; #endif /*Check_FLT_ROUNDS*/ } - y = word0(rv) & Exp_mask; + y = word0(&rv) & Exp_mask; /* Check for overflow */ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(rv0) = dval(rv); - word0(rv) -= P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; - if ((word0(rv) & Exp_mask) >= + dval(&rv0) = dval(&rv); + word0(&rv) -= P*Exp_msk1; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += dval(&adj); + if ((word0(&rv) & Exp_mask) >= Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(rv0) == Big0 && word1(rv0) == Big1) + if (word0(&rv0) == Big0 && word1(&rv0) == Big1) goto ovfl; - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; goto cont; } else - word0(rv) += P*Exp_msk1; + word0(&rv) += P*Exp_msk1; } else { #ifdef Avoid_Underflow @@ -899,58 +898,58 @@ strtod if ((z = aadj) <= 0) z = 1; aadj = z; - aadj1 = dsign ? aadj : -aadj; + dval(&aadj1) = dsign ? aadj : -aadj; } - word0(aadj1) += (2*P+1)*Exp_msk1 - y; + word0(&aadj1) += (2*P+1)*Exp_msk1 - y; } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += dval(&adj); #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - dval(rv0) = dval(rv); - word0(rv) += P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + dval(&rv0) = dval(&rv); + word0(&rv) += P*Exp_msk1; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += adj; #ifdef IBM - if ((word0(rv) & Exp_mask) < P*Exp_msk1) + if ((word0(&rv) & Exp_mask) < P*Exp_msk1) #else - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) #endif { - if (word0(rv0) == Tiny0 - && word1(rv0) == Tiny1) + if (word0(&rv0) == Tiny0 + && word1(&rv0) == Tiny1) goto undfl; - word0(rv) = Tiny0; - word1(rv) = Tiny1; + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; goto cont; } else - word0(rv) -= P*Exp_msk1; + word0(&rv) -= P*Exp_msk1; } else { - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += adj; } #else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., + /* Compute dval(&adj) so that the IEEE rounding rules will + * correctly round rv + dval(&adj) in some half-way cases. + * If rv * ulp(&rv) is denormalized (i.e., * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid * trouble from bits lost to denormalization; * example: 1.2e-307 . */ if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); + dval(&aadj1) = (double)(int)(aadj + 0.5); if (!dsign) - aadj1 = -aadj1; + dval(&aadj1) = -dval(&aadj1); } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += adj; #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ } - z = word0(rv) & Exp_mask; + z = word0(&rv) & Exp_mask; #ifndef SET_INEXACT #ifdef Avoid_Underflow if (!scale) @@ -960,7 +959,7 @@ strtod L = (Long)aadj; aadj -= L; /* The tolerances below are conservative. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) { if (aadj < .4999999 || aadj > .5000001) break; } @@ -977,9 +976,9 @@ strtod #ifdef SET_INEXACT if (inexact) { if (!oldinexact) { - word0(rv0) = Exp_1 + (70 << Exp_shift); - word1(rv0) = 0; - dval(rv0) += 1.; + word0(&rv0) = Exp_1 + (70 << Exp_shift); + word1(&rv0) = 0; + dval(&rv0) += 1.; } } else if (!oldinexact) @@ -987,25 +986,25 @@ strtod #endif #ifdef Avoid_Underflow if (scale) { - word0(rv0) = Exp_1 - 2*P*Exp_msk1; - word1(rv0) = 0; - dval(rv) *= dval(rv0); + word0(&rv0) = Exp_1 - 2*P*Exp_msk1; + word1(&rv0) = 0; + dval(&rv) *= dval(&rv0); #ifndef NO_ERRNO /* try to avoid the bug of testing an 8087 register value */ #ifdef IEEE_Arith - if (!(word0(rv) & Exp_mask)) + if (!(word0(&rv) & Exp_mask)) #else - if (word0(rv) == 0 && word1(rv) == 0) + if (word0(&rv) == 0 && word1(&rv) == 0) #endif errno = ERANGE; #endif } #endif /* Avoid_Underflow */ #ifdef SET_INEXACT - if (inexact && !(word0(rv) & Exp_mask)) { + if (inexact && !(word0(&rv) & Exp_mask)) { /* set underflow bit */ - dval(rv0) = 1e-300; - dval(rv0) *= dval(rv0); + dval(&rv0) = 1e-300; + dval(&rv0) *= dval(&rv0); } #endif retfree: @@ -1017,6 +1016,6 @@ strtod ret: if (se) *se = (char *)s; - return sign ? -dval(rv) : dval(rv); + return sign ? -dval(&rv) : dval(&rv); } diff --git a/gdtoa/FreeBSD/gdtoa-strtod.c.patch b/gdtoa/FreeBSD/gdtoa-strtod.c.patch index 29f9906..9134046 100644 --- a/gdtoa/FreeBSD/gdtoa-strtod.c.patch +++ b/gdtoa/FreeBSD/gdtoa-strtod.c.patch @@ -1,5 +1,5 @@ ---- gdtoa-strtod.c.orig 2008-10-28 12:07:31.000000000 -0700 -+++ gdtoa-strtod.c 2008-10-28 12:22:37.000000000 -0700 +--- gdtoa-strtod.c.orig 2010-01-29 16:43:20.000000000 -0800 ++++ gdtoa-strtod.c 2010-01-29 18:05:44.000000000 -0800 @@ -29,6 +29,8 @@ THIS SOFTWARE. /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -24,56 +24,135 @@ #endif { #ifdef Avoid_Underflow -@@ -79,13 +81,14 @@ strtod +@@ -71,6 +73,7 @@ strtod + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + CONST char *s, *s0, *s1; ++ char *strunc = NULL; + double aadj; + Long L; + U adj, aadj1, rv, rv0; +@@ -80,15 +83,16 @@ strtod int inexact, oldinexact; #endif - #ifdef USE_LOCALE + #ifdef USE_LOCALE /*{{*/ + NORMALIZE_LOCALE(loc); #ifdef NO_LOCALE_CACHE - char *decimalpoint = localeconv()->decimal_point; + char *decimalpoint = localeconv_l(loc)->decimal_point; + int dplen = strlen(decimalpoint); #else char *decimalpoint; static char *decimalpoint_cache; + static int dplen; if (!(s0 = decimalpoint_cache)) { - s0 = localeconv()->decimal_point; + s0 = localeconv_l(loc)->decimal_point; - if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) { + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { strcpy(decimalpoint_cache, s0); s0 = decimalpoint_cache; -@@ -155,7 +158,7 @@ strtod - #else /*}{*/ +@@ -154,7 +158,7 @@ strtod + #else #define fpi1 fpi - #endif /*}}*/ + #endif - switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { + switch((i = gethex(&s, &fpi1, &exp, &bb, sign, loc)) & STRTOG_Retmask) { case STRTOG_NoNumber: s = s00; sign = 0; -@@ -545,7 +548,11 @@ strtod - - /* Put digits into bd: true value = bd * 10^e */ - -- bd0 = s2b(s0, nd0, nd, y); -+#ifdef USE_LOCALE -+ bd0 = s2b(s0, nd0, nd, y, strlen(decimalpoint)); -+#else -+ bd0 = s2b(s0, nd0, nd, y, 1); -+#endif +@@ -310,6 +314,9 @@ strtod + } + goto ret; + } ++#define FPIEMIN (1-1023-53+1) // fpi.emin ++#define FPINBITS 52 // fpi.nbits ++ TRUNCATE_DIGITS(s0, strunc, nd, nd0, nf, FPINBITS, FPIEMIN, dplen); + e1 = e -= nf; - for(;;) { - bd = Balloc(bd0->k); -@@ -992,7 +999,7 @@ strtod - dval(rv) *= dval(rv0); + /* Now we have nd0 digits, starting at s0, followed by a +@@ -346,7 +353,7 @@ strtod + #ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { +- rv = -rv; ++ dval(&rv) = -dval(&rv); + sign = 0; + } + #endif +@@ -362,7 +369,7 @@ strtod + #ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { +- rv = -rv; ++ dval(&rv) = -dval(&rv); + sign = 0; + } + #endif +@@ -390,7 +397,7 @@ strtod + #ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { +- rv = -rv; ++ dval(&rv) = -dval(&rv); + sign = 0; + } + #endif +@@ -672,17 +679,17 @@ strtod + else + #endif /*Sudden_Underflow*/ + #endif /*Avoid_Underflow*/ +- dval(&rv) += adj*ulp(&rv); ++ dval(&rv) += dval(&adj)*ulp(&rv); + } + break; + } + dval(&adj) = ratio(delta, bs); +- if (adj < 1.) ++ if (dval(&adj) < 1.) + dval(&adj) = 1.; +- if (adj <= 0x7ffffffe) { ++ if (dval(&adj) <= 0x7ffffffe) { + /* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */ +- y = adj; +- if (y != adj) { ++ y = dval(&adj); ++ if (y != dval(&adj)) { + if (!((Rounding>>1) ^ dsign)) + y++; + dval(&adj) = y; +@@ -709,10 +716,10 @@ strtod + if (dsign) { + if (word0(&rv) == Big0 && word1(&rv) == Big1) + goto ovfl; +- dval(&rv) += adj; ++ dval(&rv) += dval(&adj); + } + else +- dval(&rv) -= adj; ++ dval(&rv) -= dval(&adj); + goto cont; + } + #endif /*Honor_FLT_ROUNDS*/ +@@ -991,7 +998,7 @@ strtod + dval(&rv) *= dval(&rv0); #ifndef NO_ERRNO /* try to avoid the bug of testing an 8087 register value */ -#ifdef IEEE_Arith +#if defined(IEEE_Arith) && __DARWIN_UNIX03 - if (!(word0(rv) & Exp_mask)) + if (!(word0(&rv) & Exp_mask)) #else - if (word0(rv) == 0 && word1(rv) == 0) -@@ -1020,3 +1027,13 @@ strtod - return sign ? -dval(rv) : dval(rv); + if (word0(&rv) == 0 && word1(&rv) == 0) +@@ -1016,6 +1023,22 @@ strtod + ret: + if (se) + *se = (char *)s; ++ if (strunc) ++#ifdef FREE ++ FREE(strunc); ++#else ++ free(strunc); ++#endif + return sign ? -dval(&rv) : dval(&rv); } + double diff --git a/gdtoa/FreeBSD/gdtoa-strtodg.c b/gdtoa/FreeBSD/gdtoa-strtodg.c index 41ead32..5059869 100644 --- a/gdtoa/FreeBSD/gdtoa-strtodg.c +++ b/gdtoa/FreeBSD/gdtoa-strtodg.c @@ -172,9 +172,9 @@ set_ones(Bigint *b, int n) rvOK #ifdef KR_headers (d, fpi, exp, bits, exact, rd, irv) - double d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; + U *d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; #else - (double d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) + (U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) #endif { Bigint *b; @@ -182,7 +182,7 @@ rvOK int bdif, e, j, k, k1, nb, rv; carry = rv = 0; - b = d2b(d, &e, &bdif); + b = d2b(dval(d), &e, &bdif); bdif -= nb = fpi->nbits; e += bdif; if (bdif <= 0) { @@ -291,9 +291,9 @@ rvOK static int #ifdef KR_headers -mantbits(d) double d; +mantbits(d) U *d; #else -mantbits(double d) +mantbits(U *d) #endif { ULong L; @@ -327,30 +327,36 @@ strtodg int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign; int sudden_underflow; CONST char *s, *s0, *s1; - double adj, adj0, rv, tol; + double adj0, tol; Long L; + U adj, rv; ULong *b, *be, y, z; Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; -#ifdef USE_LOCALE +#ifdef USE_LOCALE /*{{*/ #ifdef NO_LOCALE_CACHE char *decimalpoint = localeconv()->decimal_point; + int dplen = strlen(decimalpoint); #else char *decimalpoint; static char *decimalpoint_cache; + static int dplen; if (!(s0 = decimalpoint_cache)) { s0 = localeconv()->decimal_point; - if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) { + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { strcpy(decimalpoint_cache, s0); s0 = decimalpoint_cache; } + dplen = strlen(s0); } decimalpoint = (char*)s0; -#endif -#endif +#endif /*NO_LOCALE_CACHE*/ +#else /*USE_LOCALE}{*/ +#define dplen 1 +#endif /*USE_LOCALE}}*/ irv = STRTOG_Zero; denorm = sign = nz0 = nz = 0; - dval(rv) = 0.; + dval(&rv) = 0.; rvb = 0; nbits = fpi->nbits; for(s = s00;;s++) switch(*s) { @@ -542,13 +548,13 @@ strtodg if (!nd0) nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv) = y; + dval(&rv) = y; if (k > 9) - dval(rv) = tens[k - 9] * dval(rv) + z; + dval(&rv) = tens[k - 9] * dval(&rv) + z; bd0 = 0; if (nbits <= P && nd <= DBL_DIG) { if (!e) { - if (rvOK(dval(rv), fpi, exp, bits, 1, rd, &irv)) + if (rvOK(&rv, fpi, exp, bits, 1, rd, &irv)) goto ret; } else if (e > 0) { @@ -556,9 +562,9 @@ strtodg #ifdef VAX goto vax_ovfl_check; #else - i = fivesbits[e] + mantbits(dval(rv)) <= P; - /* rv = */ rounded_product(dval(rv), tens[e]); - if (rvOK(dval(rv), fpi, exp, bits, i, rd, &irv)) + i = fivesbits[e] + mantbits(&rv) <= P; + /* rv = */ rounded_product(dval(&rv), tens[e]); + if (rvOK(&rv, fpi, exp, bits, i, rd, &irv)) goto ret; e1 -= e; goto rv_notOK; @@ -571,32 +577,32 @@ strtodg */ e2 = e - i; e1 -= i; - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; #ifdef VAX /* VAX exponent range is so narrow we must * worry about overflow here... */ vax_ovfl_check: - dval(adj) = dval(rv); - word0(adj) -= P*Exp_msk1; - /* adj = */ rounded_product(dval(adj), tens[e2]); - if ((word0(adj) & Exp_mask) + dval(&adj) = dval(&rv); + word0(&adj) -= P*Exp_msk1; + /* adj = */ rounded_product(dval(&adj), tens[e2]); + if ((word0(&adj) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) goto rv_notOK; - word0(adj) += P*Exp_msk1; - dval(rv) = dval(adj); + word0(&adj) += P*Exp_msk1; + dval(&rv) = dval(&adj); #else - /* rv = */ rounded_product(dval(rv), tens[e2]); + /* rv = */ rounded_product(dval(&rv), tens[e2]); #endif - if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) goto ret; e1 -= e2; } } #ifndef Inaccurate_Divide else if (e >= -Ten_pmax) { - /* rv = */ rounded_quotient(dval(rv), tens[-e]); - if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); + if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) goto ret; e1 -= e; } @@ -610,45 +616,45 @@ strtodg e2 = 0; if (e1 > 0) { if ( (i = e1 & 15) !=0) - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; if (e1 &= ~15) { e1 >>= 4; - while(e1 >= (1 << n_bigtens-1)) { - e2 += ((word0(rv) & Exp_mask) + while(e1 >= (1 << (n_bigtens-1))) { + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; - dval(rv) *= bigtens[n_bigtens-1]; - e1 -= 1 << n_bigtens-1; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; + dval(&rv) *= bigtens[n_bigtens-1]; + e1 -= 1 << (n_bigtens-1); } - e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= bigtens[j]; + dval(&rv) *= bigtens[j]; } } else if (e1 < 0) { e1 = -e1; if ( (i = e1 & 15) !=0) - dval(rv) /= tens[i]; + dval(&rv) /= tens[i]; if (e1 &= ~15) { e1 >>= 4; - while(e1 >= (1 << n_bigtens-1)) { - e2 += ((word0(rv) & Exp_mask) + while(e1 >= (1 << (n_bigtens-1))) { + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; - dval(rv) *= tinytens[n_bigtens-1]; - e1 -= 1 << n_bigtens-1; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; + dval(&rv) *= tinytens[n_bigtens-1]; + e1 -= 1 << (n_bigtens-1); } - e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= tinytens[j]; + dval(&rv) *= tinytens[j]; } } #ifdef IBM @@ -659,7 +665,7 @@ strtodg */ e2 <<= 2; #endif - rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */ + rvb = d2b(dval(&rv), &rve, &rvbits); /* rv = rvb * 2^rve */ rve += e2; if ((j = rvbits - nbits) > 0) { rshift(rvb, j); @@ -703,7 +709,7 @@ strtodg /* Put digits into bd: true value = bd * 10^e */ - bd0 = s2b(s0, nd0, nd, y); + bd0 = s2b(s0, nd0, nd, y, dplen); for(;;) { bd = Balloc(bd0->k); @@ -837,7 +843,7 @@ strtodg } else irv = STRTOG_Normal | STRTOG_Inexhi; - if (bbbits < nbits && !denorm || !(rvb->x[0] & 1)) + if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1)) break; if (dsign) { rvb = increment(rvb); @@ -854,7 +860,7 @@ strtodg } break; } - if ((dval(adj) = ratio(delta, bs)) <= 2.) { + if ((dval(&adj) = ratio(delta, bs)) <= 2.) { adj1: inex = STRTOG_Inexlo; if (dsign) { @@ -868,15 +874,15 @@ strtodg irv = STRTOG_Underflow | STRTOG_Inexlo; break; } - adj0 = dval(adj) = 1.; + adj0 = dval(&adj) = 1.; } else { - adj0 = dval(adj) *= 0.5; + adj0 = dval(&adj) *= 0.5; if (dsign) { asub = 0; inex = STRTOG_Inexlo; } - if (dval(adj) < 2147483647.) { + if (dval(&adj) < 2147483647.) { L = adj0; adj0 -= L; switch(rd) { @@ -895,12 +901,12 @@ strtodg inex = STRTOG_Inexact - inex; } } - dval(adj) = L; + dval(&adj) = L; } } y = rve + rvbits; - /* adj *= ulp(dval(rv)); */ + /* adj *= ulp(dval(&rv)); */ /* if (asub) rv -= adj; else rv += adj; */ if (!denorm && rvbits < nbits) { @@ -908,7 +914,7 @@ strtodg rve -= j; rvbits = nbits; } - ab = d2b(dval(adj), &abe, &abits); + ab = d2b(dval(&adj), &abe, &abits); if (abe < 0) rshift(ab, -abe); else if (abe > 0) @@ -962,15 +968,15 @@ strtodg z = rve + rvbits; if (y == z && L) { /* Can we stop now? */ - tol = dval(adj) * 5e-16; /* > max rel error */ - dval(adj) = adj0 - .5; - if (dval(adj) < -tol) { + tol = dval(&adj) * 5e-16; /* > max rel error */ + dval(&adj) = adj0 - .5; + if (dval(&adj) < -tol) { if (adj0 > tol) { irv |= inex; break; } } - else if (dval(adj) > tol && adj0 < 1. - tol) { + else if (dval(&adj) > tol && adj0 < 1. - tol) { irv |= inex; break; } diff --git a/gdtoa/FreeBSD/gdtoa-strtodg.c.patch b/gdtoa/FreeBSD/gdtoa-strtodg.c.patch index 263b91c..4c233cd 100644 --- a/gdtoa/FreeBSD/gdtoa-strtodg.c.patch +++ b/gdtoa/FreeBSD/gdtoa-strtodg.c.patch @@ -1,5 +1,5 @@ ---- gdtoa-strtodg.c.orig 2008-10-28 12:23:36.000000000 -0700 -+++ gdtoa-strtodg.c 2008-10-28 12:34:18.000000000 -0700 +--- gdtoa-strtodg.c.orig 2010-01-29 16:43:20.000000000 -0800 ++++ gdtoa-strtodg.c 2010-01-29 18:13:37.000000000 -0800 @@ -29,13 +29,29 @@ THIS SOFTWARE. /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -23,8 +23,8 @@ +extern CONST int fivesbits[]; +int all_on(Bigint *b, int n); +Bigint *set_ones(Bigint *b, int n); -+int rvOK(double d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv); -+int mantbits(double d); ++int rvOK(U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv); ++int mantbits(U *d); +#else /* !BUILDING_VARIANT */ + + __private_extern__ CONST int @@ -56,9 +56,9 @@ - static int + __private_extern__ int #ifdef KR_headers - mantbits(d) double d; + mantbits(d) U *d; #else -@@ -312,13 +328,15 @@ mantbits(double d) +@@ -312,13 +328,15 @@ mantbits(U *d) return P - 32 - lo0bits(&L); } @@ -77,24 +77,33 @@ #endif { int abe, abits, asub; -@@ -332,13 +350,14 @@ strtodg +@@ -327,21 +345,23 @@ strtodg + int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign; + int sudden_underflow; + CONST char *s, *s0, *s1; ++ char *strunc = NULL; + double adj0, tol; + Long L; + U adj, rv; ULong *b, *be, y, z; Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; - #ifdef USE_LOCALE -+ NORMALIZE_LOCALE(loc) + #ifdef USE_LOCALE /*{{*/ ++ NORMALIZE_LOCALE(loc); #ifdef NO_LOCALE_CACHE - char *decimalpoint = localeconv()->decimal_point; + char *decimalpoint = localeconv_l(loc)->decimal_point; + int dplen = strlen(decimalpoint); #else char *decimalpoint; static char *decimalpoint_cache; + static int dplen; if (!(s0 = decimalpoint_cache)) { - s0 = localeconv()->decimal_point; + s0 = localeconv_l(loc)->decimal_point; - if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) { + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { strcpy(decimalpoint_cache, s0); s0 = decimalpoint_cache; -@@ -382,7 +401,7 @@ strtodg +@@ -388,7 +408,7 @@ strtodg switch(s[1]) { case 'x': case 'X': @@ -103,7 +112,15 @@ if (irv == STRTOG_NoNumber) { s = s00; sign = 0; -@@ -687,6 +706,10 @@ strtodg +@@ -525,6 +545,7 @@ strtodg + } + goto ret; + } ++ TRUNCATE_DIGITS(s0, strunc, nd, nd0, nf, fpi->nbits, fpi->emin, dplen); + + irv = STRTOG_Normal; + e1 = e -= nf; +@@ -693,6 +714,10 @@ strtodg rvb->x[0] = 0; *exp = emin; irv = STRTOG_Underflow | STRTOG_Inexlo; @@ -114,20 +131,7 @@ goto ret; } rvb->x[0] = rvb->wds = rvbits = 1; -@@ -703,7 +726,11 @@ strtodg - - /* Put digits into bd: true value = bd * 10^e */ - -- bd0 = s2b(s0, nd0, nd, y); -+#ifdef USE_LOCALE -+ bd0 = s2b(s0, nd0, nd, y, strlen(decimalpoint)); -+#else -+ bd0 = s2b(s0, nd0, nd, y, 1); -+#endif - - for(;;) { - bd = Balloc(bd0->k); -@@ -1032,7 +1059,7 @@ strtodg +@@ -1038,7 +1063,7 @@ strtodg if (sudden_underflow) { rvb->wds = 0; irv = STRTOG_Underflow | STRTOG_Inexlo; @@ -136,7 +140,7 @@ errno = ERANGE; #endif } -@@ -1041,7 +1068,7 @@ strtodg +@@ -1047,7 +1072,7 @@ strtodg (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero); if (irv & STRTOG_Inexact) { irv |= STRTOG_Underflow; @@ -145,3 +149,15 @@ errno = ERANGE; #endif } +@@ -1061,5 +1086,11 @@ strtodg + copybits(bits, nbits, rvb); + Bfree(rvb); + } ++ if (strunc) ++#ifdef FREE ++ FREE(strunc); ++#else ++ free(strunc); ++#endif + return irv; + } diff --git a/gdtoa/FreeBSD/gdtoa-strtof.c b/gdtoa/FreeBSD/gdtoa-strtof.c index f8111b7..a8beb35 100644 --- a/gdtoa/FreeBSD/gdtoa-strtof.c +++ b/gdtoa/FreeBSD/gdtoa-strtof.c @@ -58,7 +58,7 @@ strtof(CONST char *s, char **sp) case STRTOG_Normal: case STRTOG_NaNbits: - u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + u.L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23); break; case STRTOG_Denormal: diff --git a/gdtoa/FreeBSD/gdtoa-strtopdd.c b/gdtoa/FreeBSD/gdtoa-strtopdd.c index c665976..738372d 100644 --- a/gdtoa/FreeBSD/gdtoa-strtopdd.c +++ b/gdtoa/FreeBSD/gdtoa-strtopdd.c @@ -67,8 +67,8 @@ strtopdd(CONST char *s, char **sp, double *dd) case STRTOG_Normal: u->L[_1] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL; - u->L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff - | exp + 0x3ff + 105 << 20; + u->L[_0] = (bits[2] >> 21) | ((bits[3] << 11) & 0xfffff) + | ((exp + 0x3ff + 105) << 20); exp += 0x3ff + 52; if (bits[1] &= 0x1fffff) { i = hi0bits(bits[1]) - 11; @@ -79,7 +79,7 @@ strtopdd(CONST char *s, char **sp, double *dd) else exp -= i; if (i > 0) { - bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[1] = bits[1] << i | bits[0] >> (32-i); bits[0] = bits[0] << i & 0xffffffffL; } } @@ -92,11 +92,11 @@ strtopdd(CONST char *s, char **sp, double *dd) else exp -= i; if (i < 32) { - bits[1] = bits[0] >> 32 - i; + bits[1] = bits[0] >> (32 - i); bits[0] = bits[0] << i & 0xffffffffL; } else { - bits[1] = bits[0] << i - 32; + bits[1] = bits[0] << (i - 32); bits[0] = 0; } } @@ -105,7 +105,7 @@ strtopdd(CONST char *s, char **sp, double *dd) break; } u->L[2+_1] = bits[0]; - u->L[2+_0] = bits[1] & 0xfffff | exp << 20; + u->L[2+_0] = (bits[1] & 0xfffff) | (exp << 20); break; case STRTOG_Denormal: @@ -124,10 +124,10 @@ strtopdd(CONST char *s, char **sp, double *dd) nearly_normal: i = hi0bits(bits[3]) - 11; /* i >= 12 */ j = 32 - i; - u->L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff - | 65 - i << 20; + u->L[_0] = ((bits[3] << i | bits[2] >> j) & 0xfffff) + | ((65 - i) << 20); u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; - u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[2+_0] = bits[1] & ((1L << j) - 1); u->L[2+_1] = bits[0]; break; @@ -136,34 +136,34 @@ strtopdd(CONST char *s, char **sp, double *dd) if (i < 0) { j = -i; i += 32; - u->L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20; - u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; - u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[_0] = (bits[2] >> j & 0xfffff) | (33 + j) << 20; + u->L[_1] = ((bits[2] << i) | (bits[1] >> j)) & 0xffffffffL; + u->L[2+_0] = bits[1] & ((1L << j) - 1); u->L[2+_1] = bits[0]; break; } if (i == 0) { - u->L[_0] = bits[2] & 0xfffff | 33 << 20; + u->L[_0] = (bits[2] & 0xfffff) | (33 << 20); u->L[_1] = bits[1]; u->L[2+_0] = 0; u->L[2+_1] = bits[0]; break; } j = 32 - i; - u->L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff - | j + 1 << 20; + u->L[_0] = (((bits[2] << i) | (bits[1] >> j)) & 0xfffff) + | ((j + 1) << 20); u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[2+_0] = 0; - u->L[2+_1] = bits[0] & (1L << j) - 1; + u->L[2+_1] = bits[0] & ((1L << j) - 1); break; hardly_normal: j = 11 - hi0bits(bits[1]); i = 32 - j; - u->L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20; + u->L[_0] = (bits[1] >> j & 0xfffff) | ((j + 1) << 20); u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[2+_0] = 0; - u->L[2+_1] = bits[0] & (1L << j) - 1; + u->L[2+_1] = bits[0] & ((1L << j) - 1); break; case STRTOG_Infinite: diff --git a/gdtoa/FreeBSD/gdtoa-strtopdd.c.patch b/gdtoa/FreeBSD/gdtoa-strtopdd.c.patch index 3352908..63a7ee2 100644 --- a/gdtoa/FreeBSD/gdtoa-strtopdd.c.patch +++ b/gdtoa/FreeBSD/gdtoa-strtopdd.c.patch @@ -1,5 +1,5 @@ ---- gdtoa-strtopdd.c.orig 2008-10-28 12:43:22.000000000 -0700 -+++ gdtoa-strtopdd.c 2008-10-28 12:51:49.000000000 -0700 +--- gdtoa-strtopdd.c.orig 2010-01-12 10:59:42.000000000 -0800 ++++ gdtoa-strtopdd.c 2010-01-12 11:09:40.000000000 -0800 @@ -29,13 +29,25 @@ THIS SOFTWARE. /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -56,7 +56,7 @@ @@ -106,6 +124,9 @@ strtopdd(CONST char *s, char **sp, doubl } u->L[2+_1] = bits[0]; - u->L[2+_0] = bits[1] & 0xfffff | exp << 20; + u->L[2+_0] = (bits[1] & 0xfffff) | (exp << 20); +#ifdef __APPLE__ + fixLDBL(u->ld); +#endif /* __APPLE__ */ @@ -65,7 +65,7 @@ case STRTOG_Denormal: @@ -129,6 +150,9 @@ strtopdd(CONST char *s, char **sp, doubl u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; - u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[2+_0] = bits[1] & ((1L << j) - 1); u->L[2+_1] = bits[0]; +#ifdef __APPLE__ + fixLDBL(u->ld); @@ -74,8 +74,8 @@ partly_normal: @@ -140,6 +164,9 @@ strtopdd(CONST char *s, char **sp, doubl - u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; - u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[_1] = ((bits[2] << i) | (bits[1] >> j)) & 0xffffffffL; + u->L[2+_0] = bits[1] & ((1L << j) - 1); u->L[2+_1] = bits[0]; +#ifdef __APPLE__ + fixLDBL(u->ld); @@ -96,7 +96,7 @@ @@ -155,6 +185,9 @@ strtopdd(CONST char *s, char **sp, doubl u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[2+_0] = 0; - u->L[2+_1] = bits[0] & (1L << j) - 1; + u->L[2+_1] = bits[0] & ((1L << j) - 1); +#ifdef __APPLE__ + fixLDBL(u->ld); +#endif /* __APPLE__ */ @@ -106,7 +106,7 @@ @@ -164,20 +197,45 @@ strtopdd(CONST char *s, char **sp, doubl u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[2+_0] = 0; - u->L[2+_1] = bits[0] & (1L << j) - 1; + u->L[2+_1] = bits[0] & ((1L << j) - 1); +#ifdef __APPLE__ + fixLDBL(u->ld); +#endif /* __APPLE__ */ diff --git a/gdtoa/FreeBSD/gdtoa-strtopx.c b/gdtoa/FreeBSD/gdtoa-strtopx.c index 07d0458..f7a25ff 100644 --- a/gdtoa/FreeBSD/gdtoa-strtopx.c +++ b/gdtoa/FreeBSD/gdtoa-strtopx.c @@ -92,7 +92,8 @@ strtopx(CONST char *s, char **sp, void *V) case STRTOG_Infinite: L[_0] = 0x7fff; - L[_1] = L[_2] = L[_3] = L[_4] = 0; + L[_1] = 0x8000; + L[_2] = L[_3] = L[_4] = 0; break; case STRTOG_NaN: diff --git a/gdtoa/FreeBSD/gdtoa-strtopx.c.patch b/gdtoa/FreeBSD/gdtoa-strtopx.c.patch index bbd9f3c..d251fb4 100644 --- a/gdtoa/FreeBSD/gdtoa-strtopx.c.patch +++ b/gdtoa/FreeBSD/gdtoa-strtopx.c.patch @@ -1,5 +1,5 @@ ---- gdtoa-strtopx.c.orig 2008-10-28 12:54:18.000000000 -0700 -+++ gdtoa-strtopx.c 2008-10-28 12:57:26.000000000 -0700 +--- gdtoa-strtopx.c.orig 2010-01-12 10:59:42.000000000 -0800 ++++ gdtoa-strtopx.c 2010-01-12 12:11:48.000000000 -0800 @@ -29,6 +29,8 @@ THIS SOFTWARE. /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -35,13 +35,3 @@ case STRTOG_Zero: L[0] = L[1] = L[2] = L[3] = L[4] = 0; break; -@@ -92,7 +97,8 @@ strtopx(CONST char *s, char **sp, void * - - case STRTOG_Infinite: - L[_0] = 0x7fff; -- L[_1] = L[_2] = L[_3] = L[_4] = 0; -+ L[_1] = 0x8000; /* 4306392: to match gcc */ -+ L[_2] = L[_3] = L[_4] = 0; - break; - - case STRTOG_NaN: diff --git a/gdtoa/FreeBSD/gdtoa-ulp.c b/gdtoa/FreeBSD/gdtoa-ulp.c index 7810a5c..17e9f86 100644 --- a/gdtoa/FreeBSD/gdtoa-ulp.c +++ b/gdtoa/FreeBSD/gdtoa-ulp.c @@ -34,13 +34,13 @@ THIS SOFTWARE. double ulp #ifdef KR_headers - (x) double x; + (x) U *x; #else - (double x) + (U *x) #endif { Long L; - double a; + U a; L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; #ifndef Sudden_Underflow @@ -49,22 +49,22 @@ ulp #ifdef IBM L |= Exp_msk1 >> 4; #endif - word0(a) = L; - word1(a) = 0; + word0(&a) = L; + word1(&a) = 0; #ifndef Sudden_Underflow } else { L = -L >> Exp_shift; if (L < Exp_shift) { - word0(a) = 0x80000 >> L; - word1(a) = 0; + word0(&a) = 0x80000 >> L; + word1(&a) = 0; } else { - word0(a) = 0; + word0(&a) = 0; L -= Exp_shift; - word1(a) = L >= 31 ? 1 : 1 << 31 - L; + word1(&a) = L >= 31 ? 1 : 1 << (31 - L); } } #endif - return a; + return dval(&a); } diff --git a/gdtoa/FreeBSD/gdtoaimp.h b/gdtoa/FreeBSD/gdtoaimp.h index e403aba..2c188d6 100644 --- a/gdtoa/FreeBSD/gdtoaimp.h +++ b/gdtoa/FreeBSD/gdtoaimp.h @@ -113,7 +113,12 @@ THIS SOFTWARE. * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) * if memory is available and otherwise does something you deem * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. + * directly -- and assumed always to succeed. Similarly, if you + * want something other than the system's free() to be called to + * recycle memory acquired from MALLOC, #define FREE to be the + * name of the alternate routine. (FREE or free is only called in + * pathological cases, e.g., in a gdtoa call after a gdtoa return in + * mode 3 with thousands of digits requested.) * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making * memory allocations from a private pool of memory when possible. * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, @@ -126,8 +131,10 @@ THIS SOFTWARE. * conversions of IEEE doubles in single-threaded executions with * 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with * 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate. - * #define INFNAN_CHECK on IEEE systems to cause strtod to check for - * Infinity and NaN (case insensitively). + * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK + * #defined automatically on IEEE systems. On such systems, + * when INFNAN_CHECK is #defined, strtod checks + * for Infinity and NaN (case insensitively). * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, * strtodg also accepts (case insensitively) strings of the form * NaN(x), where x is a string of hexadecimal digits (optionally @@ -160,11 +167,6 @@ THIS SOFTWARE. * #define NO_STRING_H to use private versions of memcpy. * On some K&R systems, it may also be necessary to * #define DECLARE_SIZE_T in this case. - * #define YES_ALIAS to permit aliasing certain double values with - * arrays of ULongs. This leads to slightly better code with - * some compilers and was always used prior to 19990916, but it - * is not strictly legal and can cause trouble with aggressively - * optimizing compilers (e.g., gcc 2.95.1 under -O2). * #define USE_LOCALE to use the current locale's decimal_point value. */ @@ -268,25 +270,14 @@ Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. typedef union { double d; ULong L[2]; } U; -#ifdef YES_ALIAS -#define dval(x) x #ifdef IEEE_8087 -#define word0(x) ((ULong *)&x)[1] -#define word1(x) ((ULong *)&x)[0] +#define word0(x) (x)->L[1] +#define word1(x) (x)->L[0] #else -#define word0(x) ((ULong *)&x)[0] -#define word1(x) ((ULong *)&x)[1] +#define word0(x) (x)->L[0] +#define word1(x) (x)->L[1] #endif -#else /* !YES_ALIAS */ -#ifdef IEEE_8087 -#define word0(x) ((U*)&x)->L[1] -#define word1(x) ((U*)&x)->L[0] -#else -#define word0(x) ((U*)&x)->L[0] -#define word1(x) ((U*)&x)->L[1] -#endif -#define dval(x) ((U*)&x)->d -#endif /* YES_ALIAS */ +#define dval(x) (x)->d /* The following definition of Storeinc is appropriate for MIPS processors. * An alternative that might be better on some machines is @@ -460,7 +451,7 @@ extern double rnd_prod(double, double), rnd_quot(double, double); #define FREE_DTOA_LOCK(n) /*nothing*/ #endif -#define Kmax 15 +#define Kmax 9 struct Bigint { @@ -566,14 +557,14 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); extern double ratio ANSI((Bigint*, Bigint*)); extern void rshift ANSI((Bigint*, int)); extern char *rv_alloc ANSI((int)); - extern Bigint *s2b ANSI((CONST char*, int, int, ULong)); + extern Bigint *s2b ANSI((CONST char*, int, int, ULong, int)); extern Bigint *set_ones ANSI((Bigint*, int)); extern char *strcp ANSI((char*, const char*)); extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*)); extern double strtod ANSI((const char *s00, char **se)); extern Bigint *sum ANSI((Bigint*, Bigint*)); extern int trailz ANSI((Bigint*)); - extern double ulp ANSI((double)); + extern double ulp ANSI((U*)); #ifdef __cplusplus } @@ -588,6 +579,10 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) */ #ifdef IEEE_Arith +#ifndef NO_INFNAN_CHECK +#undef INFNAN_CHECK +#define INFNAN_CHECK +#endif #ifdef IEEE_MC68k #define _0 0 #define _1 1 diff --git a/gdtoa/FreeBSD/gdtoaimp.h.patch b/gdtoa/FreeBSD/gdtoaimp.h.patch index c9329ee..3d10bf4 100644 --- a/gdtoa/FreeBSD/gdtoaimp.h.patch +++ b/gdtoa/FreeBSD/gdtoaimp.h.patch @@ -1,6 +1,6 @@ ---- gdtoaimp.h.orig 2008-10-28 11:36:44.000000000 -0700 -+++ gdtoaimp.h 2008-10-28 12:01:07.000000000 -0700 -@@ -170,6 +170,91 @@ +--- gdtoaimp.h.orig 2010-01-29 16:43:20.000000000 -0800 ++++ gdtoaimp.h 2010-02-01 10:58:41.000000000 -0800 +@@ -172,6 +172,91 @@ #ifndef GDTOAIMP_H_INCLUDED #define GDTOAIMP_H_INCLUDED @@ -92,7 +92,7 @@ #include "gdtoa.h" #include "gd_qnan.h" #ifdef Honor_FLT_ROUNDS -@@ -181,8 +266,11 @@ +@@ -183,8 +268,11 @@ #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} #endif @@ -104,7 +104,7 @@ #ifdef KR_headers #define Char char -@@ -196,6 +284,10 @@ +@@ -198,6 +286,10 @@ #define MALLOC malloc #endif @@ -115,7 +115,7 @@ #undef IEEE_Arith #undef Avoid_Underflow #ifdef IEEE_MC68k -@@ -455,10 +547,14 @@ +@@ -446,10 +538,14 @@ #define ALL_ON 0xffff #endif @@ -132,9 +132,9 @@ + if (__isthreaded) _SPINUNLOCK(&__gdtoa_locks[n]); \ +} while(0) - #define Kmax 15 + #define Kmax 9 -@@ -481,52 +577,6 @@ +@@ -472,52 +568,6 @@ #define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int)) #endif /* NO_STRING_H */ @@ -187,7 +187,7 @@ extern char *dtoa_result; extern CONST double bigtens[], tens[], tinytens[]; extern unsigned char hexdig[]; -@@ -549,7 +599,7 @@ +@@ -540,7 +590,7 @@ extern char *dtoa ANSI((double d, int mode, int ndigits, int *decpt, int *sign, char **rve)); extern char *g__fmt ANSI((char*, char*, char*, int, ULong, size_t)); @@ -196,17 +196,90 @@ extern void hexdig_init_D2A(Void); extern int hexnan ANSI((CONST char**, FPI*, ULong*)); extern int hi0bits_D2A ANSI((ULong)); -@@ -566,11 +616,12 @@ - extern double ratio ANSI((Bigint*, Bigint*)); - extern void rshift ANSI((Bigint*, int)); - extern char *rv_alloc ANSI((int)); -- extern Bigint *s2b ANSI((CONST char*, int, int, ULong)); -+ extern Bigint *s2b ANSI((CONST char*, int, int, ULong, int)); - extern Bigint *set_ones ANSI((Bigint*, int)); +@@ -562,6 +612,7 @@ extern char *strcp ANSI((char*, const char*)); extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*)); extern double strtod ANSI((const char *s00, char **se)); + extern double strtod_l ANSI((const char *s00, char **se, locale_t)); extern Bigint *sum ANSI((Bigint*, Bigint*)); extern int trailz ANSI((Bigint*)); - extern double ulp ANSI((double)); + extern double ulp ANSI((U*)); +@@ -613,4 +664,78 @@ + #define SI 0 + #endif + ++/* ++ * For very large strings, strtod and family might exhaust memory in tight ++ * memory conditions (especially in 32-bits). Such large strings could also ++ * tie up a CPU for minutes at a time. Either can be considered a denial-of- ++ * service vunerability. ++ * ++ * To fix, we limit the string size to the maximum we need to calculate the ++ * rounding point correctly. The longest string corresponding to the exact ++ * value of a floating point number occuring at 1.f...f p^-n, where n is ++ * the (absolute value of the) smallest exponent for a normalize number. ++ * ++ * To calculate this number of decimal digits, we use the formula: ++ * ++ * (n + m) - int(n * log10(2)) + 3 ++ * ++ * where m is the number of bits in the f...f fraction. This is the number ++ * of decimal digits for the least significant bit minus the number of leading ++ * zeros for the most significant bit (the '1'), plus a few to compensate for ++ * an extra digits due to the full 1.f...f value, an extra digit for the ++ * mid-way point for rounding and an extra guard digit. ++ * ++ * Using the approximation log10(2) ~ 1233 / (2^12), converting to the fpi.emin ++ * and fpi.nbits values, we get: ++ * ++ * -fpi.emin -((1233 * (-fpi.nbits - fpi.emin)) >> 12) + 3 ++ * ++ * Finally, we add an extra digit, either '1' or '0', to represent whether ++ * to-be-truncated digits contain a non-zero digit, or are all zeros, ++ * respectively. ++ * ++ * The truncated string is allocated on the heap, so code using ++ * TRUNCATE_DIGITS() will need to free that space when no longer needed. ++ * Pass a char * as the second argument, initialized to NULL; if its value ++ * becomes non-NULL, memory was allocated. ++ */ ++#define LOG2NUM 1233 ++#define LOG2DENOMSHIFT 12 ++#define TRUNCATEDIGITS(_nbits, _emin) (-(_emin) - ((LOG2NUM * (-(_nbits) - (_emin))) >> LOG2DENOMSHIFT) + 3) ++ ++#define TRUNCATE_DIGITS(_s0, _temp, _nd, _nd0, _nf, _nbits, _emin, _dplen) \ ++{ \ ++ int _maxdigits = TRUNCATEDIGITS((_nbits), (_emin)); \ ++ if ((_nd) > _maxdigits && \ ++ ((_temp) = MALLOC(_maxdigits + (_dplen) + 2)) != NULL) { \ ++ char *_tp = (_temp) + _maxdigits; \ ++ if ((_nd0) >= _maxdigits) { \ ++ memcpy((_temp), (_s0), _maxdigits); \ ++ if ((_nd) > (_nd0)) *_tp++ = '1'; \ ++ else { \ ++ const char *_q = (_s0) + _maxdigits; \ ++ int _n = (_nd0) - _maxdigits; \ ++ for(; _n > 0 && *_q == '0'; _n--, _q++) {} \ ++ *_tp++ = _n > 0 ? '1' : '0'; \ ++ } \ ++ (_nf) = -((_nd0) - (_maxdigits + 1)); \ ++ (_nd0) = _maxdigits + 1; \ ++ } \ ++ else if ((_nd0) == 0) { \ ++ memcpy((_temp), (_s0), _maxdigits); \ ++ *_tp++ = '1'; \ ++ (_nf) -= ((_nd) - (_maxdigits + 1)); \ ++ } \ ++ else { \ ++ memcpy((_temp), (_s0), _maxdigits + (_dplen)); \ ++ _tp += (_dplen); \ ++ *_tp++ = '1'; \ ++ (_nf) = (_maxdigits + 1) - (_nd0); \ ++ } \ ++ *_tp = 0; \ ++ (_nd) = _maxdigits + 1; \ ++ (_s0) = (_temp); \ ++ } \ ++ } ++ + #endif /* GDTOAIMP_H_INCLUDED */ diff --git a/gdtoa/gdtoa-gethex-fbsd.c b/gdtoa/gdtoa-gethex-fbsd.c index f970946..855726a 100644 --- a/gdtoa/gdtoa-gethex-fbsd.c +++ b/gdtoa/gdtoa-gethex-fbsd.c @@ -33,6 +33,8 @@ THIS SOFTWARE. #include "gdtoaimp.h" +#include + #ifdef USE_LOCALE #include "locale.h" #endif @@ -47,6 +49,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t lo { Bigint *b; CONST unsigned char *decpt, *s0, *s, *s1; + unsigned char *strunc; int big, esign, havedig, irv, j, k, n, n0, nbits, up, zret; ULong L, lostbits, *x; Long e, e1; @@ -60,7 +63,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t lo static unsigned char *decimalpoint_cache; if (!(s0 = decimalpoint_cache)) { s0 = (unsigned char*)localeconv_l(loc)->decimal_point; - if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) { + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { strcpy(decimalpoint_cache, s0); s0 = decimalpoint_cache; } @@ -201,8 +204,59 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t lo *exp = fpi->emin; return STRTOG_Normal | STRTOG_Inexlo; } + /* + * Truncate the hex string if it is longer than the precision needed, + * to avoid denial-of-service issues with very large strings. Use + * additional digits to insure precision. Scan to-be-truncated digits + * and replace with either '1' or '0' to ensure proper rounding. + */ + { + int maxdigits = ((fpi->nbits + 3) >> 2) + 2; + size_t nd = s1 - s0; +#ifdef USE_LOCALE + int dplen = strlen((const char *)decimalpoint); +#else + int dplen = 1; +#endif + + if (decpt && s0 < decpt) + nd -= dplen; + if (nd > maxdigits && (strunc = alloca(maxdigits + dplen + 2)) != NULL) { + ssize_t nd0 = decpt ? decpt - s0 - dplen : nd; + unsigned char *tp = strunc + maxdigits; + int found = 0; + if ((nd0 -= maxdigits) >= 0 || s0 >= decpt) + memcpy(strunc, s0, maxdigits); + else { + memcpy(strunc, s0, maxdigits + dplen); + tp += dplen; + } + s0 += maxdigits; + e += (nd - (maxdigits + 1)) << 2; + if (nd0 > 0) { + while(nd0-- > 0) + if (*s0++ != '0') { + found++; + break; + } + s0 += dplen; + } + if (!found && decpt) { + while(s0 < s1) + if(*s0++ != '0') { + found++; + break; + } + } + *tp++ = found ? '1' : '0'; + *tp = 0; + s0 = strunc; + s1 = tp; + } + } + n = s1 - s0 - 1; - for(k = 0; n > 7; n >>= 1) + for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) k++; b = Balloc(k); x = b->x; @@ -221,7 +275,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t lo if (*--s1 == '.') continue; #endif - if (n == 32) { + if (n == ULbits) { *x++ = L; L = 0; n = 0; @@ -231,7 +285,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t lo } *x++ = L; b->wds = n = x - b->x; - n = 32*n - hi0bits(L); + n = ULbits*n - hi0bits(L); nbits = fpi->nbits; lostbits = 0; x = b->x; @@ -317,7 +371,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t lo break; case FPI_Round_near: if (lostbits & 2 - && (lostbits & 1) | x[0] & 1) + && (lostbits | x[0]) & 1) up = 1; break; case FPI_Round_up: @@ -336,8 +390,8 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t lo irv = STRTOG_Normal; } else if (b->wds > k - || (n = nbits & kmask) !=0 - && hi0bits(x[k-1]) < 32-n) { + || ((n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n)) { rshift(b,1); if (++e > fpi->emax) goto ovfl; diff --git a/gdtoa/gdtoa-hexnan-fbsd.c b/gdtoa/gdtoa-hexnan-fbsd.c index a953da1..2e0089e 100644 --- a/gdtoa/gdtoa-hexnan-fbsd.c +++ b/gdtoa/gdtoa-hexnan-fbsd.c @@ -32,6 +32,7 @@ THIS SOFTWARE. #include "gdtoaimp.h" #include +#ifndef __APPLE__ static void #ifdef KR_headers L_shift(x, x1, i) ULong *x; ULong *x1; int i; @@ -49,6 +50,7 @@ L_shift(ULong *x, ULong *x1, int i) x[1] >>= i; } while(++x < x1); } +#endif /* !__APPLE__ */ int #ifdef KR_headers @@ -58,25 +60,99 @@ hexnan(sp, fpi, x0) hexnan( CONST char **sp, FPI *fpi, ULong *x0) #endif { +#ifdef __APPLE__ int nbits, len; char *cp; +#else /* !__APPLE__ */ + ULong c, h, *x, *x1, *xe; +#endif /* __APPLE__ */ CONST char *s; +#ifndef __APPLE__ + int havedig, hd0, i, nbits; +#endif /* !__APPLE__ */ +#ifdef __APPLE__ if (sp == NULL || *sp == NULL || **sp != '(') return STRTOG_NaN; +#else /* !__APPLE__ */ + if (!hexdig['0']) + hexdig_init_D2A(); + nbits = fpi->nbits; + x = x0 + (nbits >> kshift); + if (nbits & kmask) + x++; + *--x = 0; + x1 = xe = x; + havedig = hd0 = i = 0; +#endif /* __APPLE__ */ s = *sp; +#ifdef __APPLE__ if ((cp = strchr(s + 1, ')')) == NULL) { - *sp += strlen(s); - cp = s + 1; + return STRTOG_NaN; } else { len = cp - (s + 1); cp = alloca(len + 1); if (!cp) +#else /* !__APPLE__ */ + /* allow optional initial 0x or 0X */ + while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') + ++s; + if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') + && *(CONST unsigned char*)(s+3) > ' ') + s += 2; + while((c = *(CONST unsigned char*)++s)) { + if (!(h = hexdig[c])) { + if (c <= ' ') { + if (hd0 < havedig) { + if (x < x1 && i < 8) + L_shift(x, x1, i); + if (x <= x0) { + i = 8; + continue; + } + hd0 = havedig; + *--x = 0; + x1 = x; + i = 0; + } + while(*(CONST unsigned char*)(s+1) <= ' ') + ++s; + if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') + && *(CONST unsigned char*)(s+3) > ' ') + s += 2; + continue; + } + if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } +#ifndef GDTOA_NON_PEDANTIC_NANCHECK + do { + if (/*(*/ c == ')') { + *sp = s + 1; + break; + } + } while((c = *++s)); +#endif +#endif /* __APPLE__ */ return STRTOG_NaN; +#ifdef __APPLE__ strlcpy(cp, s + 1, len + 1); *sp += len + 2; +#else /* !__APPLE__ */ + } + havedig++; + if (++i > 8) { + if (x <= x0) + continue; + i = 1; + *--x = 0; + } + *x = (*x << 4) | (h & 0xf); +#endif /* __APPLE__ */ } +#ifdef __APPLE__ nbits = fpi->nbits; /* a hack */ if (nbits == 52) { /* double */ @@ -84,12 +160,32 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0) u.d = nan(cp); x0[1] = u.bits.manh; x0[0] = u.bits.manl; +#else /* !__APPLE__ */ + if (!havedig) + return STRTOG_NaN; + if (x < x1 && i < 8) + L_shift(x, x1, i); + if (x > x0) { + x1 = x0; + do *x1++ = *x++; + while(x <= xe); + do *x1++ = 0; + while(x1 <= xe); +#endif /* __APPLE__ */ } +#ifdef __APPLE__ else if (nbits < 52) { /* float */ union IEEEf2bits u; u.f = nanf(cp); x0[0] = u.bits.man; +#else /* !__APPLE__ */ + else { + /* truncate high-order word if necessary */ + if ( (i = nbits & (ULbits-1)) !=0) + *xe &= ((ULong)0xffffffff) >> (ULbits - i); +#endif /* __APPLE__ */ } +#ifdef __APPLE__ else { /* long double */ union IEEEl2bits u; u.e = nanl(cp); @@ -104,7 +200,15 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0) #else #error unsupported architecture #endif +#else /* !__APPLE__ */ + for(x1 = xe;; --x1) { + if (*x1 != 0) + break; + if (x1 == x0) { + *x1 = 1; + break; + } +#endif /* __APPLE__ */ } - return STRTOG_NaNbits; } diff --git a/gdtoa/gdtoa-misc-fbsd.c b/gdtoa/gdtoa-misc-fbsd.c index 659f69c..84fe199 100644 --- a/gdtoa/gdtoa-misc-fbsd.c +++ b/gdtoa/gdtoa-misc-fbsd.c @@ -103,6 +103,8 @@ Balloc #else /* !GDTOA_TSD */ ACQUIRE_DTOA_LOCK(0); #endif /* GDTOA_TSD */ + /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ + /* but this case seems very unlikely. */ if (k <= Kmax && (rv = freelist[k]) !=0) { freelist[k] = rv->next; } @@ -140,18 +142,22 @@ Bfree { if (v) { if (v->k > Kmax) +#ifdef FREE + FREE((void*)v); +#else free((void*)v); +#endif else { #ifdef GDTOA_TSD Bigint **freelist = (Bigint **)pthread_getspecific(gdtoa_tsd_key); #else /* !GDTOA_TSD */ ACQUIRE_DTOA_LOCK(0); -#endif /* GDTOA_TSD */ +#endif /* !GDTOA_TSD */ v->next = freelist[v->k]; freelist[v->k] = v; #ifndef GDTOA_TSD FREE_DTOA_LOCK(0); -#endif /* GDTOA_TSD */ +#endif /* !GDTOA_TSD */ } } } @@ -164,8 +170,8 @@ lo0bits (ULong *y) #endif { - register int k; - register ULong x = *y; + int k; + ULong x = *y; if (x & 7) { if (x & 1) @@ -264,12 +270,12 @@ multadd int hi0bits_D2A #ifdef KR_headers - (x) register ULong x; + (x) ULong x; #else - (register ULong x) + (ULong x) #endif { - register int k = 0; + int k = 0; if (!(x & 0xffff0000)) { k = 16; @@ -672,12 +678,12 @@ b2d { ULong *xa, *xa0, w, y, z; int k; - double d; + U d; #ifdef VAX ULong d0, d1; #else -#define d0 word0(d) -#define d1 word1(d) +#define d0 word0(&d) +#define d1 word1(&d) #endif xa0 = a->x; @@ -690,16 +696,16 @@ b2d *e = 32 - k; #ifdef Pack_32 if (k < Ebits) { - d0 = Exp_1 | y >> Ebits - k; + d0 = Exp_1 | y >> (Ebits - k); w = xa > xa0 ? *--xa : 0; - d1 = y << (32-Ebits) + k | w >> Ebits - k; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); goto ret_d; } z = xa > xa0 ? *--xa : 0; if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> 32 - k; + d0 = Exp_1 | y << k | z >> (32 - k); y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> 32 - k; + d1 = z << k | y >> (32 - k); } else { d0 = Exp_1 | y; @@ -723,10 +729,10 @@ b2d #endif ret_d: #ifdef VAX - word0(d) = d0 >> 16 | d0 << 16; - word1(d) = d1 >> 16 | d1 << 16; + word0(&d) = d0 >> 16 | d0 << 16; + word1(&d) = d1 >> 16 | d1 << 16; #endif - return dval(d); + return dval(&d); } #undef d0 #undef d1 @@ -734,12 +740,13 @@ b2d Bigint * d2b #ifdef KR_headers - (d, e, bits) double d; int *e, *bits; + (dd, e, bits) double dd; int *e, *bits; #else - (double d, int *e, int *bits) + (double dd, int *e, int *bits) #endif { Bigint *b; + U d; #ifndef Sudden_Underflow int i; #endif @@ -747,11 +754,14 @@ d2b ULong *x, y, z; #ifdef VAX ULong d0, d1; - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; #else -#define d0 word0(d) -#define d1 word1(d) +#define d0 word0(&d) +#define d1 word1(&d) +#endif + d.d = dd; +#ifdef VAX + d0 = word0(&d) >> 16 | word0(&d) << 16; + d1 = word1(&d) >> 16 | word1(&d) << 16; #endif #ifdef Pack_32 @@ -775,7 +785,7 @@ d2b #ifdef Pack_32 if ( (y = d1) !=0) { if ( (k = lo0bits(&y)) !=0) { - x[0] = y | z << 32 - k; + x[0] = y | z << (32 - k); z >>= k; } else @@ -786,10 +796,6 @@ d2b b->wds = (x[1] = z) !=0 ? 2 : 1; } else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif k = lo0bits(&z); x[0] = z; #ifndef Sudden_Underflow @@ -848,7 +854,7 @@ d2b #endif #ifdef IBM *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); + *bits = 4*P + 8 - k - hi0bits(word0(&d) & Frac_mask); #else *e = de - Bias - (P-1) + k; *bits = P - k; @@ -901,7 +907,7 @@ strcp_D2A(a, b) char *a; char *b; strcp_D2A(char *a, CONST char *b) #endif { - while(*a = *b++) + while((*a = *b++)) a++; return a; } @@ -915,8 +921,8 @@ memcpy_D2A(a, b, len) Char *a; Char *b; size_t len; memcpy_D2A(void *a1, void *b1, size_t len) #endif { - register char *a = (char*)a1, *ae = a + len; - register char *b = (char*)b1, *a0 = a; + char *a = (char*)a1, *ae = a + len; + char *b = (char*)b1, *a0 = a; while(a < ae) *a++ = *b++; return a0; diff --git a/gdtoa/gdtoa-smisc-fbsd.c b/gdtoa/gdtoa-smisc-fbsd.c deleted file mode 100644 index b748c7e..0000000 --- a/gdtoa/gdtoa-smisc-fbsd.c +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************** - -The author of this software is David M. Gay. - -Copyright (C) 1998, 1999 by Lucent Technologies -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and -its documentation for any purpose and without fee is hereby -granted, provided that the above copyright notice appear in all -copies and that both that the copyright notice and this -permission notice and warranty disclaimer appear in supporting -documentation, and that the name of Lucent or any of its entities -not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. -IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY -SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER -IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. - -****************************************************************/ - -/* Please send bug reports to David M. Gay (dmg at acm dot org, - * with " at " changed at "@" and " dot " changed to "."). */ - -#include "gdtoaimp.h" - - Bigint * -s2b -#ifdef KR_headers - (s, nd0, nd, y9, decpt) CONST char *s; int nd0, nd; ULong y9; int decpt; -#else - (CONST char *s, int nd0, int nd, ULong y9, int decpt) -#endif -{ - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; -#ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); - s += decpt; - } - else - s += 9 + decpt; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; - } - - double -ratio -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - double da, db; - int k, ka, kb; - - dval(da) = b2d(a, &ka); - dval(db) = b2d(b, &kb); - k = ka - kb + ULbits*(a->wds - b->wds); -#ifdef IBM - if (k > 0) { - word0(da) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(da) *= 1 << k; - } - else { - k = -k; - word0(db) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(db) *= 1 << k; - } -#else - if (k > 0) - word0(da) += k*Exp_msk1; - else { - k = -k; - word0(db) += k*Exp_msk1; - } -#endif - return dval(da) / dval(db); - } - -#ifdef INFNAN_CHECK - - int -match -#ifdef KR_headers - (sp, t) char **sp, *t; -#else - (CONST char **sp, char *t) -#endif -{ - int c, d; - CONST char *s = *sp; - - while( (d = *t++) !=0) { - if ((c = *++s) >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != d) - return 0; - } - *sp = s + 1; - return 1; - } -#endif /* INFNAN_CHECK */ - - void -#ifdef KR_headers -copybits(c, n, b) ULong *c; int n; Bigint *b; -#else -copybits(ULong *c, int n, Bigint *b) -#endif -{ - ULong *ce, *x, *xe; -#ifdef Pack_16 - int nw, nw1; -#endif - - ce = c + ((n-1) >> kshift) + 1; - x = b->x; -#ifdef Pack_32 - xe = x + b->wds; - while(x < xe) - *c++ = *x++; -#else - nw = b->wds; - nw1 = nw & 1; - for(xe = x + (nw - nw1); x < xe; x += 2) - Storeinc(c, x[1], x[0]); - if (nw1) - *c++ = *x; -#endif - while(c < ce) - *c++ = 0; - } - - ULong -#ifdef KR_headers -any_on(b, k) Bigint *b; int k; -#else -any_on(Bigint *b, int k) -#endif -{ - int n, nwds; - ULong *x, *x0, x1, x2; - - x = b->x; - nwds = b->wds; - n = k >> kshift; - if (n > nwds) - n = nwds; - else if (n < nwds && (k &= kmask)) { - x1 = x2 = x[n]; - x1 >>= k; - x1 <<= k; - if (x1 != x2) - return 1; - } - x0 = x; - x += n; - while(x > x0) - if (*--x) - return 1; - return 0; - } diff --git a/gdtoa/gdtoa-smisc-fbsd.c b/gdtoa/gdtoa-smisc-fbsd.c new file mode 120000 index 0000000..e467f82 --- /dev/null +++ b/gdtoa/gdtoa-smisc-fbsd.c @@ -0,0 +1 @@ +./gdtoa-smisc.c \ No newline at end of file diff --git a/gdtoa/gdtoa-strtod-fbsd.c b/gdtoa/gdtoa-strtod-fbsd.c index 538b066..3186f25 100644 --- a/gdtoa/gdtoa-strtod-fbsd.c +++ b/gdtoa/gdtoa-strtod-fbsd.c @@ -73,30 +73,38 @@ strtod_l int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; - double aadj, aadj1, adj, rv, rv0; + char *strunc = NULL; + double aadj; Long L; + U adj, aadj1, rv, rv0; ULong y, z; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; #ifdef SET_INEXACT int inexact, oldinexact; #endif -#ifdef USE_LOCALE +#ifdef USE_LOCALE /*{{*/ NORMALIZE_LOCALE(loc); #ifdef NO_LOCALE_CACHE char *decimalpoint = localeconv_l(loc)->decimal_point; + int dplen = strlen(decimalpoint); #else char *decimalpoint; static char *decimalpoint_cache; + static int dplen; if (!(s0 = decimalpoint_cache)) { s0 = localeconv_l(loc)->decimal_point; - if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) { + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { strcpy(decimalpoint_cache, s0); s0 = decimalpoint_cache; } + dplen = strlen(s0); } decimalpoint = (char*)s0; -#endif -#endif +#endif /*NO_LOCALE_CACHE*/ +#else /*USE_LOCALE}{*/ +#define dplen 1 +#endif /*USE_LOCALE}}*/ + #ifdef Honor_FLT_ROUNDS /*{*/ int Rounding; #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ @@ -112,7 +120,7 @@ strtod_l #endif /*}*/ sign = nz0 = nz = decpt = 0; - dval(rv) = 0.; + dval(&rv) = 0.; for(s = s00;;s++) switch(*s) { case '-': sign = 1; @@ -144,20 +152,12 @@ strtod_l case 'x': case 'X': { -#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) /*{{*/ +#ifdef Honor_FLT_ROUNDS FPI fpi1 = fpi; -#ifdef Honor_FLT_ROUNDS /*{{*/ fpi1.rounding = Rounding; -#else /*}{*/ - switch(fegetround()) { - case FE_TOWARDZERO: fpi1.rounding = 0; break; - case FE_UPWARD: fpi1.rounding = 2; break; - case FE_DOWNWARD: fpi1.rounding = 3; - } -#endif /*}}*/ -#else /*}{*/ +#else #define fpi1 fpi -#endif /*}}*/ +#endif switch((i = gethex(&s, &fpi1, &exp, &bb, sign, loc)) & STRTOG_Retmask) { case STRTOG_NoNumber: s = s00; @@ -282,8 +282,8 @@ strtod_l --s; if (!match(&s,"inity")) ++s; - word0(rv) = 0x7ff00000; - word1(rv) = 0; + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; goto ret; } break; @@ -294,13 +294,13 @@ strtod_l if (*s == '(' /*)*/ && hexnan(&s, &fpinan, bits) == STRTOG_NaNbits) { - word0(rv) = 0x7ff00000 | bits[1]; - word1(rv) = bits[0]; + word0(&rv) = 0x7ff00000 | bits[1]; + word1(&rv) = bits[0]; } else { #endif - word0(rv) = NAN_WORD0; - word1(rv) = NAN_WORD1; + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; #ifndef No_Hex_NaN } #endif @@ -314,6 +314,9 @@ strtod_l } goto ret; } +#define FPIEMIN (1-1023-53+1) // fpi.emin +#define FPINBITS 52 // fpi.nbits + TRUNCATE_DIGITS(s0, strunc, nd, nd0, nf, FPINBITS, FPIEMIN, dplen); e1 = e -= nf; /* Now we have nd0 digits, starting at s0, followed by a @@ -324,13 +327,13 @@ strtod_l if (!nd0) nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv) = y; + dval(&rv) = y; if (k > 9) { #ifdef SET_INEXACT if (k > DBL_DIG) oldinexact = get_inexact(); #endif - dval(rv) = tens[k - 9] * dval(rv) + z; + dval(&rv) = tens[k - 9] * dval(&rv) + z; } bd0 = 0; if (nd <= DBL_DIG @@ -350,11 +353,11 @@ strtod_l #ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv = -rv; + dval(&rv) = -dval(&rv); sign = 0; } #endif - /* rv = */ rounded_product(dval(rv), tens[e]); + /* rv = */ rounded_product(dval(&rv), tens[e]); goto ret; #endif } @@ -366,25 +369,25 @@ strtod_l #ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv = -rv; + dval(&rv) = -dval(&rv); sign = 0; } #endif e -= i; - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; #ifdef VAX /* VAX exponent range is so narrow we must * worry about overflow here... */ vax_ovfl_check: - word0(rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(rv), tens[e]); - if ((word0(rv) & Exp_mask) + word0(&rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(&rv), tens[e]); + if ((word0(&rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) goto ovfl; - word0(rv) += P*Exp_msk1; + word0(&rv) += P*Exp_msk1; #else - /* rv = */ rounded_product(dval(rv), tens[e]); + /* rv = */ rounded_product(dval(&rv), tens[e]); #endif goto ret; } @@ -394,11 +397,11 @@ strtod_l #ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv = -rv; + dval(&rv) = -dval(&rv); sign = 0; } #endif - /* rv = */ rounded_quotient(dval(rv), tens[-e]); + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); goto ret; } #endif @@ -429,7 +432,7 @@ strtod_l if (e1 > 0) { if ( (i = e1 & 15) !=0) - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; if (e1 &= ~15) { if (e1 > DBL_MAX_10_EXP) { ovfl: @@ -442,25 +445,25 @@ strtod_l switch(Rounding) { case 0: /* toward 0 */ case 3: /* toward -infinity */ - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; break; default: - word0(rv) = Exp_mask; - word1(rv) = 0; + word0(&rv) = Exp_mask; + word1(&rv) = 0; } #else /*Honor_FLT_ROUNDS*/ - word0(rv) = Exp_mask; - word1(rv) = 0; + word0(&rv) = Exp_mask; + word1(&rv) = 0; #endif /*Honor_FLT_ROUNDS*/ #ifdef SET_INEXACT /* set overflow bit */ - dval(rv0) = 1e300; - dval(rv0) *= dval(rv0); + dval(&rv0) = 1e300; + dval(&rv0) *= dval(&rv0); #endif #else /*IEEE_Arith*/ - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; #endif /*IEEE_Arith*/ if (bd0) goto retfree; @@ -469,27 +472,27 @@ strtod_l e1 >>= 4; for(j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= bigtens[j]; + dval(&rv) *= bigtens[j]; /* The last multiplication could overflow. */ - word0(rv) -= P*Exp_msk1; - dval(rv) *= bigtens[j]; - if ((z = word0(rv) & Exp_mask) + word0(&rv) -= P*Exp_msk1; + dval(&rv) *= bigtens[j]; + if ((z = word0(&rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-P)) goto ovfl; if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { /* set to largest number */ /* (Can't trust DBL_MAX) */ - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; } else - word0(rv) += P*Exp_msk1; + word0(&rv) += P*Exp_msk1; } } else if (e1 < 0) { e1 = -e1; if ( (i = e1 & 15) !=0) - dval(rv) /= tens[i]; + dval(&rv) /= tens[i]; if (e1 >>= 4) { if (e1 >= 1 << n_bigtens) goto undfl; @@ -498,34 +501,34 @@ strtod_l scale = 2*P; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= tinytens[j]; - if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + dval(&rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) >> Exp_shift)) > 0) { /* scaled rv is denormal; zap j low bits */ if (j >= 32) { - word1(rv) = 0; + word1(&rv) = 0; if (j >= 53) - word0(rv) = (P+2)*Exp_msk1; + word0(&rv) = (P+2)*Exp_msk1; else - word0(rv) &= 0xffffffff << j-32; + word0(&rv) &= 0xffffffff << (j-32); } else - word1(rv) &= 0xffffffff << j; + word1(&rv) &= 0xffffffff << j; } #else for(j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= tinytens[j]; + dval(&rv) *= tinytens[j]; /* The last multiplication could underflow. */ - dval(rv0) = dval(rv); - dval(rv) *= tinytens[j]; - if (!dval(rv)) { - dval(rv) = 2.*dval(rv0); - dval(rv) *= tinytens[j]; + dval(&rv0) = dval(&rv); + dval(&rv) *= tinytens[j]; + if (!dval(&rv)) { + dval(&rv) = 2.*dval(&rv0); + dval(&rv) *= tinytens[j]; #endif - if (!dval(rv)) { + if (!dval(&rv)) { undfl: - dval(rv) = 0.; + dval(&rv) = 0.; #ifndef NO_ERRNO errno = ERANGE; #endif @@ -534,8 +537,8 @@ strtod_l goto ret; } #ifndef Avoid_Underflow - word0(rv) = Tiny0; - word1(rv) = Tiny1; + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; /* The refinement below will clean * this approximation up. */ @@ -548,16 +551,12 @@ strtod_l /* Put digits into bd: true value = bd * 10^e */ -#ifdef USE_LOCALE - bd0 = s2b(s0, nd0, nd, y, strlen(decimalpoint)); -#else - bd0 = s2b(s0, nd0, nd, y, 1); -#endif + bd0 = s2b(s0, nd0, nd, y, dplen); for(;;) { bd = Balloc(bd0->k); Bcopy(bd, bd0); - bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bb = d2b(dval(&rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ bs = i2b(1); if (e >= 0) { @@ -579,7 +578,7 @@ strtod_l #endif #ifdef Avoid_Underflow j = bbe - scale; - i = j + bbbits - 1; /* logb(rv) */ + i = j + bbbits - 1; /* logb(&rv) */ if (i < Emin) /* denormal */ j += P - Emin; else @@ -593,7 +592,7 @@ strtod_l #endif #else /*Sudden_Underflow*/ j = bbe; - i = j + bbbits - 1; /* logb(rv) */ + i = j + bbbits - 1; /* logb(&rv) */ if (i < Emin) /* denormal */ j += P - Emin; else @@ -644,15 +643,15 @@ strtod_l } if (Rounding) { if (dsign) { - adj = 1.; + dval(&adj) = 1.; goto apply_adj; } } else if (!dsign) { - adj = -1.; - if (!word1(rv) - && !(word0(rv) & Frac_mask)) { - y = word0(rv) & Exp_mask; + dval(&adj) = -1.; + if (!word1(&rv) + && !(word0(&rv) & Frac_mask)) { + y = word0(&rv) & Exp_mask; #ifdef Avoid_Underflow if (!scale || y > 2*P*Exp_msk1) #else @@ -661,66 +660,66 @@ strtod_l { delta = lshift(delta,Log2P); if (cmp(delta, bs) <= 0) - adj = -0.5; + dval(&adj) = -0.5; } } apply_adj: #ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) + if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; + word0(&adj) += (2*P+1)*Exp_msk1 - y; #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - dval(rv) += adj*ulp(dval(rv)); - word0(rv) -= P*Exp_msk1; + word0(&rv) += P*Exp_msk1; + dval(&rv) += adj*ulp(&rv); + word0(&rv) -= P*Exp_msk1; } else #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - dval(rv) += adj*ulp(dval(rv)); + dval(&rv) += dval(&adj)*ulp(&rv); } break; } - adj = ratio(delta, bs); - if (adj < 1.) - adj = 1.; - if (adj <= 0x7ffffffe) { - /* adj = Rounding ? ceil(adj) : floor(adj); */ - y = adj; - if (y != adj) { + dval(&adj) = ratio(delta, bs); + if (dval(&adj) < 1.) + dval(&adj) = 1.; + if (dval(&adj) <= 0x7ffffffe) { + /* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */ + y = dval(&adj); + if (y != dval(&adj)) { if (!((Rounding>>1) ^ dsign)) y++; - adj = y; + dval(&adj) = y; } } #ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; + if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(&adj) += (2*P+1)*Exp_msk1 - y; #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - adj *= ulp(dval(rv)); + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + word0(&rv) += P*Exp_msk1; + dval(&adj) *= ulp(&rv); if (dsign) - dval(rv) += adj; + dval(&rv) += adj; else - dval(rv) -= adj; - word0(rv) -= P*Exp_msk1; + dval(&rv) -= adj; + word0(&rv) -= P*Exp_msk1; goto cont; } #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - adj *= ulp(dval(rv)); + dval(&adj) *= ulp(&rv); if (dsign) { - if (word0(rv) == Big0 && word1(rv) == Big1) + if (word0(&rv) == Big0 && word1(&rv) == Big1) goto ovfl; - dval(rv) += adj; + dval(&rv) += dval(&adj); } else - dval(rv) -= adj; + dval(&rv) -= dval(&adj); goto cont; } #endif /*Honor_FLT_ROUNDS*/ @@ -729,12 +728,12 @@ strtod_l /* Error is less than half an ulp -- check for * special case of mantissa a power of two. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask #ifdef IEEE_Arith #ifdef Avoid_Underflow - || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 + || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 #else - || (word0(rv) & Exp_mask) <= Exp_msk1 + || (word0(&rv) & Exp_mask) <= Exp_msk1 #endif #endif ) { @@ -759,32 +758,32 @@ strtod_l if (i == 0) { /* exactly half-way between */ if (dsign) { - if ((word0(rv) & Bndry_mask1) == Bndry_mask1 - && word1(rv) == ( + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 + && word1(&rv) == ( #ifdef Avoid_Underflow - (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : #endif 0xffffffff)) { /*boundary case -- increment exponent*/ - word0(rv) = (word0(rv) & Exp_mask) + word0(&rv) = (word0(&rv) & Exp_mask) + Exp_msk1 #ifdef IBM | Exp_msk1 >> 4 #endif ; - word1(rv) = 0; + word1(&rv) = 0; #ifdef Avoid_Underflow dsign = 0; #endif break; } } - else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { + else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { drop_down: /* boundary case -- decrement exponent */ #ifdef Sudden_Underflow /*{{*/ - L = word0(rv) & Exp_mask; + L = word0(&rv) & Exp_mask; #ifdef IBM if (L < Exp_msk1) #else @@ -799,7 +798,7 @@ strtod_l #else /*Sudden_Underflow}{*/ #ifdef Avoid_Underflow if (scale) { - L = word0(rv) & Exp_mask; + L = word0(&rv) & Exp_mask; if (L <= (2*P+1)*Exp_msk1) { if (L > (P+2)*Exp_msk1) /* round even ==> */ @@ -810,10 +809,10 @@ strtod_l } } #endif /*Avoid_Underflow*/ - L = (word0(rv) & Exp_mask) - Exp_msk1; + L = (word0(&rv) & Exp_mask) - Exp_msk1; #endif /*Sudden_Underflow}}*/ - word0(rv) = L | Bndry_mask1; - word1(rv) = 0xffffffff; + word0(&rv) = L | Bndry_mask1; + word1(&rv) = 0xffffffff; #ifdef IBM goto cont; #else @@ -821,16 +820,16 @@ strtod_l #endif } #ifndef ROUND_BIASED - if (!(word1(rv) & LSB)) + if (!(word1(&rv) & LSB)) break; #endif if (dsign) - dval(rv) += ulp(dval(rv)); + dval(&rv) += ulp(&rv); #ifndef ROUND_BIASED else { - dval(rv) -= ulp(dval(rv)); + dval(&rv) -= ulp(&rv); #ifndef Sudden_Underflow - if (!dval(rv)) + if (!dval(&rv)) goto undfl; #endif } @@ -842,14 +841,14 @@ strtod_l } if ((aadj = ratio(delta, bs)) <= 2.) { if (dsign) - aadj = aadj1 = 1.; - else if (word1(rv) || word0(rv) & Bndry_mask) { + aadj = dval(&aadj1) = 1.; + else if (word1(&rv) || word0(&rv) & Bndry_mask) { #ifndef Sudden_Underflow - if (word1(rv) == Tiny1 && !word0(rv)) + if (word1(&rv) == Tiny1 && !word0(&rv)) goto undfl; #endif aadj = 1.; - aadj1 = -1.; + dval(&aadj1) = -1.; } else { /* special case -- power of FLT_RADIX to be */ @@ -859,45 +858,45 @@ strtod_l aadj = 1./FLT_RADIX; else aadj *= 0.5; - aadj1 = -aadj; + dval(&aadj1) = -aadj; } } else { aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; + dval(&aadj1) = dsign ? aadj : -aadj; #ifdef Check_FLT_ROUNDS switch(Rounding) { case 2: /* towards +infinity */ - aadj1 -= 0.5; + dval(&aadj1) -= 0.5; break; case 0: /* towards 0 */ case 3: /* towards -infinity */ - aadj1 += 0.5; + dval(&aadj1) += 0.5; } #else if (Flt_Rounds == 0) - aadj1 += 0.5; + dval(&aadj1) += 0.5; #endif /*Check_FLT_ROUNDS*/ } - y = word0(rv) & Exp_mask; + y = word0(&rv) & Exp_mask; /* Check for overflow */ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(rv0) = dval(rv); - word0(rv) -= P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; - if ((word0(rv) & Exp_mask) >= + dval(&rv0) = dval(&rv); + word0(&rv) -= P*Exp_msk1; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += dval(&adj); + if ((word0(&rv) & Exp_mask) >= Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(rv0) == Big0 && word1(rv0) == Big1) + if (word0(&rv0) == Big0 && word1(&rv0) == Big1) goto ovfl; - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; goto cont; } else - word0(rv) += P*Exp_msk1; + word0(&rv) += P*Exp_msk1; } else { #ifdef Avoid_Underflow @@ -906,58 +905,58 @@ strtod_l if ((z = aadj) <= 0) z = 1; aadj = z; - aadj1 = dsign ? aadj : -aadj; + dval(&aadj1) = dsign ? aadj : -aadj; } - word0(aadj1) += (2*P+1)*Exp_msk1 - y; + word0(&aadj1) += (2*P+1)*Exp_msk1 - y; } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += dval(&adj); #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - dval(rv0) = dval(rv); - word0(rv) += P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + dval(&rv0) = dval(&rv); + word0(&rv) += P*Exp_msk1; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += adj; #ifdef IBM - if ((word0(rv) & Exp_mask) < P*Exp_msk1) + if ((word0(&rv) & Exp_mask) < P*Exp_msk1) #else - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) #endif { - if (word0(rv0) == Tiny0 - && word1(rv0) == Tiny1) + if (word0(&rv0) == Tiny0 + && word1(&rv0) == Tiny1) goto undfl; - word0(rv) = Tiny0; - word1(rv) = Tiny1; + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; goto cont; } else - word0(rv) -= P*Exp_msk1; + word0(&rv) -= P*Exp_msk1; } else { - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += adj; } #else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., + /* Compute dval(&adj) so that the IEEE rounding rules will + * correctly round rv + dval(&adj) in some half-way cases. + * If rv * ulp(&rv) is denormalized (i.e., * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid * trouble from bits lost to denormalization; * example: 1.2e-307 . */ if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); + dval(&aadj1) = (double)(int)(aadj + 0.5); if (!dsign) - aadj1 = -aadj1; + dval(&aadj1) = -dval(&aadj1); } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += adj; #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ } - z = word0(rv) & Exp_mask; + z = word0(&rv) & Exp_mask; #ifndef SET_INEXACT #ifdef Avoid_Underflow if (!scale) @@ -967,7 +966,7 @@ strtod_l L = (Long)aadj; aadj -= L; /* The tolerances below are conservative. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) { if (aadj < .4999999 || aadj > .5000001) break; } @@ -984,9 +983,9 @@ strtod_l #ifdef SET_INEXACT if (inexact) { if (!oldinexact) { - word0(rv0) = Exp_1 + (70 << Exp_shift); - word1(rv0) = 0; - dval(rv0) += 1.; + word0(&rv0) = Exp_1 + (70 << Exp_shift); + word1(&rv0) = 0; + dval(&rv0) += 1.; } } else if (!oldinexact) @@ -994,25 +993,25 @@ strtod_l #endif #ifdef Avoid_Underflow if (scale) { - word0(rv0) = Exp_1 - 2*P*Exp_msk1; - word1(rv0) = 0; - dval(rv) *= dval(rv0); + word0(&rv0) = Exp_1 - 2*P*Exp_msk1; + word1(&rv0) = 0; + dval(&rv) *= dval(&rv0); #ifndef NO_ERRNO /* try to avoid the bug of testing an 8087 register value */ #if defined(IEEE_Arith) && __DARWIN_UNIX03 - if (!(word0(rv) & Exp_mask)) + if (!(word0(&rv) & Exp_mask)) #else - if (word0(rv) == 0 && word1(rv) == 0) + if (word0(&rv) == 0 && word1(&rv) == 0) #endif errno = ERANGE; #endif } #endif /* Avoid_Underflow */ #ifdef SET_INEXACT - if (inexact && !(word0(rv) & Exp_mask)) { + if (inexact && !(word0(&rv) & Exp_mask)) { /* set underflow bit */ - dval(rv0) = 1e-300; - dval(rv0) *= dval(rv0); + dval(&rv0) = 1e-300; + dval(&rv0) *= dval(&rv0); } #endif retfree: @@ -1024,7 +1023,13 @@ strtod_l ret: if (se) *se = (char *)s; - return sign ? -dval(rv) : dval(rv); + if (strunc) +#ifdef FREE + FREE(strunc); +#else + free(strunc); +#endif + return sign ? -dval(&rv) : dval(&rv); } double diff --git a/gdtoa/gdtoa-strtodg-fbsd.c b/gdtoa/gdtoa-strtodg-fbsd.c index 31d3a1e..e1acc54 100644 --- a/gdtoa/gdtoa-strtodg-fbsd.c +++ b/gdtoa/gdtoa-strtodg-fbsd.c @@ -47,8 +47,8 @@ THIS SOFTWARE. extern CONST int fivesbits[]; int all_on(Bigint *b, int n); Bigint *set_ones(Bigint *b, int n); -int rvOK(double d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv); -int mantbits(double d); +int rvOK(U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv); +int mantbits(U *d); #else /* !BUILDING_VARIANT */ __private_extern__ CONST int @@ -188,9 +188,9 @@ set_ones(Bigint *b, int n) rvOK #ifdef KR_headers (d, fpi, exp, bits, exact, rd, irv) - double d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; + U *d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; #else - (double d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) + (U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) #endif { Bigint *b; @@ -198,7 +198,7 @@ rvOK int bdif, e, j, k, k1, nb, rv; carry = rv = 0; - b = d2b(d, &e, &bdif); + b = d2b(dval(d), &e, &bdif); bdif -= nb = fpi->nbits; e += bdif; if (bdif <= 0) { @@ -307,9 +307,9 @@ rvOK __private_extern__ int #ifdef KR_headers -mantbits(d) double d; +mantbits(d) U *d; #else -mantbits(double d) +mantbits(U *d) #endif { ULong L; @@ -345,31 +345,38 @@ strtodg int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign; int sudden_underflow; CONST char *s, *s0, *s1; - double adj, adj0, rv, tol; + char *strunc = NULL; + double adj0, tol; Long L; + U adj, rv; ULong *b, *be, y, z; Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; -#ifdef USE_LOCALE - NORMALIZE_LOCALE(loc) +#ifdef USE_LOCALE /*{{*/ + NORMALIZE_LOCALE(loc); #ifdef NO_LOCALE_CACHE char *decimalpoint = localeconv_l(loc)->decimal_point; + int dplen = strlen(decimalpoint); #else char *decimalpoint; static char *decimalpoint_cache; + static int dplen; if (!(s0 = decimalpoint_cache)) { s0 = localeconv_l(loc)->decimal_point; - if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) { + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { strcpy(decimalpoint_cache, s0); s0 = decimalpoint_cache; } + dplen = strlen(s0); } decimalpoint = (char*)s0; -#endif -#endif +#endif /*NO_LOCALE_CACHE*/ +#else /*USE_LOCALE}{*/ +#define dplen 1 +#endif /*USE_LOCALE}}*/ irv = STRTOG_Zero; denorm = sign = nz0 = nz = 0; - dval(rv) = 0.; + dval(&rv) = 0.; rvb = 0; nbits = fpi->nbits; for(s = s00;;s++) switch(*s) { @@ -538,6 +545,7 @@ strtodg } goto ret; } + TRUNCATE_DIGITS(s0, strunc, nd, nd0, nf, fpi->nbits, fpi->emin, dplen); irv = STRTOG_Normal; e1 = e -= nf; @@ -561,13 +569,13 @@ strtodg if (!nd0) nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv) = y; + dval(&rv) = y; if (k > 9) - dval(rv) = tens[k - 9] * dval(rv) + z; + dval(&rv) = tens[k - 9] * dval(&rv) + z; bd0 = 0; if (nbits <= P && nd <= DBL_DIG) { if (!e) { - if (rvOK(dval(rv), fpi, exp, bits, 1, rd, &irv)) + if (rvOK(&rv, fpi, exp, bits, 1, rd, &irv)) goto ret; } else if (e > 0) { @@ -575,9 +583,9 @@ strtodg #ifdef VAX goto vax_ovfl_check; #else - i = fivesbits[e] + mantbits(dval(rv)) <= P; - /* rv = */ rounded_product(dval(rv), tens[e]); - if (rvOK(dval(rv), fpi, exp, bits, i, rd, &irv)) + i = fivesbits[e] + mantbits(&rv) <= P; + /* rv = */ rounded_product(dval(&rv), tens[e]); + if (rvOK(&rv, fpi, exp, bits, i, rd, &irv)) goto ret; e1 -= e; goto rv_notOK; @@ -590,32 +598,32 @@ strtodg */ e2 = e - i; e1 -= i; - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; #ifdef VAX /* VAX exponent range is so narrow we must * worry about overflow here... */ vax_ovfl_check: - dval(adj) = dval(rv); - word0(adj) -= P*Exp_msk1; - /* adj = */ rounded_product(dval(adj), tens[e2]); - if ((word0(adj) & Exp_mask) + dval(&adj) = dval(&rv); + word0(&adj) -= P*Exp_msk1; + /* adj = */ rounded_product(dval(&adj), tens[e2]); + if ((word0(&adj) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) goto rv_notOK; - word0(adj) += P*Exp_msk1; - dval(rv) = dval(adj); + word0(&adj) += P*Exp_msk1; + dval(&rv) = dval(&adj); #else - /* rv = */ rounded_product(dval(rv), tens[e2]); + /* rv = */ rounded_product(dval(&rv), tens[e2]); #endif - if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) goto ret; e1 -= e2; } } #ifndef Inaccurate_Divide else if (e >= -Ten_pmax) { - /* rv = */ rounded_quotient(dval(rv), tens[-e]); - if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); + if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) goto ret; e1 -= e; } @@ -629,45 +637,45 @@ strtodg e2 = 0; if (e1 > 0) { if ( (i = e1 & 15) !=0) - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; if (e1 &= ~15) { e1 >>= 4; - while(e1 >= (1 << n_bigtens-1)) { - e2 += ((word0(rv) & Exp_mask) + while(e1 >= (1 << (n_bigtens-1))) { + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; - dval(rv) *= bigtens[n_bigtens-1]; - e1 -= 1 << n_bigtens-1; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; + dval(&rv) *= bigtens[n_bigtens-1]; + e1 -= 1 << (n_bigtens-1); } - e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= bigtens[j]; + dval(&rv) *= bigtens[j]; } } else if (e1 < 0) { e1 = -e1; if ( (i = e1 & 15) !=0) - dval(rv) /= tens[i]; + dval(&rv) /= tens[i]; if (e1 &= ~15) { e1 >>= 4; - while(e1 >= (1 << n_bigtens-1)) { - e2 += ((word0(rv) & Exp_mask) + while(e1 >= (1 << (n_bigtens-1))) { + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; - dval(rv) *= tinytens[n_bigtens-1]; - e1 -= 1 << n_bigtens-1; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; + dval(&rv) *= tinytens[n_bigtens-1]; + e1 -= 1 << (n_bigtens-1); } - e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= tinytens[j]; + dval(&rv) *= tinytens[j]; } } #ifdef IBM @@ -678,7 +686,7 @@ strtodg */ e2 <<= 2; #endif - rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */ + rvb = d2b(dval(&rv), &rve, &rvbits); /* rv = rvb * 2^rve */ rve += e2; if ((j = rvbits - nbits) > 0) { rshift(rvb, j); @@ -726,11 +734,7 @@ strtodg /* Put digits into bd: true value = bd * 10^e */ -#ifdef USE_LOCALE - bd0 = s2b(s0, nd0, nd, y, strlen(decimalpoint)); -#else - bd0 = s2b(s0, nd0, nd, y, 1); -#endif + bd0 = s2b(s0, nd0, nd, y, dplen); for(;;) { bd = Balloc(bd0->k); @@ -864,7 +868,7 @@ strtodg } else irv = STRTOG_Normal | STRTOG_Inexhi; - if (bbbits < nbits && !denorm || !(rvb->x[0] & 1)) + if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1)) break; if (dsign) { rvb = increment(rvb); @@ -881,7 +885,7 @@ strtodg } break; } - if ((dval(adj) = ratio(delta, bs)) <= 2.) { + if ((dval(&adj) = ratio(delta, bs)) <= 2.) { adj1: inex = STRTOG_Inexlo; if (dsign) { @@ -895,15 +899,15 @@ strtodg irv = STRTOG_Underflow | STRTOG_Inexlo; break; } - adj0 = dval(adj) = 1.; + adj0 = dval(&adj) = 1.; } else { - adj0 = dval(adj) *= 0.5; + adj0 = dval(&adj) *= 0.5; if (dsign) { asub = 0; inex = STRTOG_Inexlo; } - if (dval(adj) < 2147483647.) { + if (dval(&adj) < 2147483647.) { L = adj0; adj0 -= L; switch(rd) { @@ -922,12 +926,12 @@ strtodg inex = STRTOG_Inexact - inex; } } - dval(adj) = L; + dval(&adj) = L; } } y = rve + rvbits; - /* adj *= ulp(dval(rv)); */ + /* adj *= ulp(dval(&rv)); */ /* if (asub) rv -= adj; else rv += adj; */ if (!denorm && rvbits < nbits) { @@ -935,7 +939,7 @@ strtodg rve -= j; rvbits = nbits; } - ab = d2b(dval(adj), &abe, &abits); + ab = d2b(dval(&adj), &abe, &abits); if (abe < 0) rshift(ab, -abe); else if (abe > 0) @@ -989,15 +993,15 @@ strtodg z = rve + rvbits; if (y == z && L) { /* Can we stop now? */ - tol = dval(adj) * 5e-16; /* > max rel error */ - dval(adj) = adj0 - .5; - if (dval(adj) < -tol) { + tol = dval(&adj) * 5e-16; /* > max rel error */ + dval(&adj) = adj0 - .5; + if (dval(&adj) < -tol) { if (adj0 > tol) { irv |= inex; break; } } - else if (dval(adj) > tol && adj0 < 1. - tol) { + else if (dval(&adj) > tol && adj0 < 1. - tol) { irv |= inex; break; } @@ -1082,5 +1086,11 @@ strtodg copybits(bits, nbits, rvb); Bfree(rvb); } + if (strunc) +#ifdef FREE + FREE(strunc); +#else + free(strunc); +#endif return irv; } diff --git a/gdtoa/gdtoa-strtof-fbsd.c b/gdtoa/gdtoa-strtof-fbsd.c index efb0286..fc29f59 100644 --- a/gdtoa/gdtoa-strtof-fbsd.c +++ b/gdtoa/gdtoa-strtof-fbsd.c @@ -64,7 +64,7 @@ strtof_l(CONST char *s, char **sp, locale_t loc) case STRTOG_Normal: case STRTOG_NaNbits: - u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + u.L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23); break; case STRTOG_Denormal: diff --git a/gdtoa/gdtoa-strtopdd-fbsd.c b/gdtoa/gdtoa-strtopdd-fbsd.c index 1ff034b..2695746 100644 --- a/gdtoa/gdtoa-strtopdd-fbsd.c +++ b/gdtoa/gdtoa-strtopdd-fbsd.c @@ -85,8 +85,8 @@ strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) case STRTOG_Normal: u->L[_1] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL; - u->L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff - | exp + 0x3ff + 105 << 20; + u->L[_0] = (bits[2] >> 21) | ((bits[3] << 11) & 0xfffff) + | ((exp + 0x3ff + 105) << 20); exp += 0x3ff + 52; if (bits[1] &= 0x1fffff) { i = hi0bits(bits[1]) - 11; @@ -97,7 +97,7 @@ strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) else exp -= i; if (i > 0) { - bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[1] = bits[1] << i | bits[0] >> (32-i); bits[0] = bits[0] << i & 0xffffffffL; } } @@ -110,11 +110,11 @@ strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) else exp -= i; if (i < 32) { - bits[1] = bits[0] >> 32 - i; + bits[1] = bits[0] >> (32 - i); bits[0] = bits[0] << i & 0xffffffffL; } else { - bits[1] = bits[0] << i - 32; + bits[1] = bits[0] << (i - 32); bits[0] = 0; } } @@ -123,7 +123,7 @@ strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) break; } u->L[2+_1] = bits[0]; - u->L[2+_0] = bits[1] & 0xfffff | exp << 20; + u->L[2+_0] = (bits[1] & 0xfffff) | (exp << 20); #ifdef __APPLE__ fixLDBL(u->ld); #endif /* __APPLE__ */ @@ -145,10 +145,10 @@ strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) nearly_normal: i = hi0bits(bits[3]) - 11; /* i >= 12 */ j = 32 - i; - u->L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff - | 65 - i << 20; + u->L[_0] = ((bits[3] << i | bits[2] >> j) & 0xfffff) + | ((65 - i) << 20); u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; - u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[2+_0] = bits[1] & ((1L << j) - 1); u->L[2+_1] = bits[0]; #ifdef __APPLE__ fixLDBL(u->ld); @@ -160,9 +160,9 @@ strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) if (i < 0) { j = -i; i += 32; - u->L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20; - u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; - u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[_0] = (bits[2] >> j & 0xfffff) | (33 + j) << 20; + u->L[_1] = ((bits[2] << i) | (bits[1] >> j)) & 0xffffffffL; + u->L[2+_0] = bits[1] & ((1L << j) - 1); u->L[2+_1] = bits[0]; #ifdef __APPLE__ fixLDBL(u->ld); @@ -170,7 +170,7 @@ strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) break; } if (i == 0) { - u->L[_0] = bits[2] & 0xfffff | 33 << 20; + u->L[_0] = (bits[2] & 0xfffff) | (33 << 20); u->L[_1] = bits[1]; u->L[2+_0] = 0; u->L[2+_1] = bits[0]; @@ -180,11 +180,11 @@ strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) break; } j = 32 - i; - u->L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff - | j + 1 << 20; + u->L[_0] = (((bits[2] << i) | (bits[1] >> j)) & 0xfffff) + | ((j + 1) << 20); u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[2+_0] = 0; - u->L[2+_1] = bits[0] & (1L << j) - 1; + u->L[2+_1] = bits[0] & ((1L << j) - 1); #ifdef __APPLE__ fixLDBL(u->ld); #endif /* __APPLE__ */ @@ -193,10 +193,10 @@ strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) hardly_normal: j = 11 - hi0bits(bits[1]); i = 32 - j; - u->L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20; + u->L[_0] = (bits[1] >> j & 0xfffff) | ((j + 1) << 20); u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[2+_0] = 0; - u->L[2+_1] = bits[0] & (1L << j) - 1; + u->L[2+_1] = bits[0] & ((1L << j) - 1); #ifdef __APPLE__ fixLDBL(u->ld); #endif /* __APPLE__ */ diff --git a/gdtoa/gdtoa-strtopx-fbsd.c b/gdtoa/gdtoa-strtopx-fbsd.c index 4b190e3..b8e8a34 100644 --- a/gdtoa/gdtoa-strtopx-fbsd.c +++ b/gdtoa/gdtoa-strtopx-fbsd.c @@ -97,7 +97,7 @@ strtopx(CONST char *s, char **sp, void *V, locale_t loc) case STRTOG_Infinite: L[_0] = 0x7fff; - L[_1] = 0x8000; /* 4306392: to match gcc */ + L[_1] = 0x8000; L[_2] = L[_3] = L[_4] = 0; break; diff --git a/gdtoa/gdtoa.tgz b/gdtoa/gdtoa.tgz new file mode 100644 index 0000000000000000000000000000000000000000..24495296a90391f521bd2d6a42cd9306123700ea GIT binary patch literal 118424 zcmV()K;OR~iwFRcpBzg71Jqki)H*UbAIh)T?GaTros3&y61DI81^28*=1y*ADwbSF{<1pGZ zEh3CD8!if)S2`+fHP1|ClQydRr#L*CbEJ>V&5bDsdiy}1gfT98=8qsG5)T?hD=9effO1KhTTCNbl`E9qv8dQzQe-zI~cIn;1MBW3s}{U+K$YY0Aq( z8O6p910E!abwxh>Y+P#A1HJq51V?8x?;@}z|f^b+DUIybR#4uTx$ zxt+~*`#Rn+Gf2FBZ=^LXAk3;FygxI!DWlYW#Z(1M3f2QLX;+n1k!Us>#GZDgiE(jh zCngb997VS_(dQ%mYlIbS9~LDUX}Z=|MNOun-?Em6N8a{Ggj@cXq1@AljX+$`gpKj+ zK^~=R2g^T?@|tE{RBG#@80nWg!`+>MerwWHpG6bc?0H?5(OSQ=Y09GBd9AkQRke8a z_;H+#CU|fNox4$7WccE7>>e-YQS~^=7AeB&$@SxsmJ3;r7H%~As#I?hIo_jQL}jH5 z`dnaKhJGtUTJ3xn^|e5&`u8B&=@4qXj0r78KplGOMtGN zfo31F2sbb4G|>}!5ffAe+ennNe|NlYpngC2W1wN@r*F@P8N$M}jIsx;sWk((j1t04 zp|VL`=~LZHvRPlvBdpLBdK#73F_buuU;;XxN7x80p)#(b&18Cs!DJcUNt=mO$KHa$ zmk(P#*`FBNj6L;x0m^X%nz1p`v-d(=_gOJ?*P6O6Aoi#-iUk2vVMDLs$g>=3ezG^5 z*eZC8IKg^h^ry2TpCNkbjpvkEEsC5J7oPKvVSybfLu_RfL(>1oTBAB(vZ0A#`y94W&~rolV&i-3>L;iD~TQz=@JXE72B#`961eaOuMzK zOy+#NI{g_oHZdj-cCFZ`Z1q=+B{LDEjvc@)5Ft|R8vZypDYV;$HQw}1UM#Uu-UnRiQ+ld zkRbR~vNKp2JX=-ELZ_y};@m65-02n%C^@?0cw5QV!ydV{k{cm^x3^$%j`Vbjou~T6 z&g#W;wY5c7=!$8zB$=BG0&8-^d4bIrX{4XMSglsDal3GMgGHVcIxi|nIbmrp5s>Lq zo=ghD7Kk=@nq!NrNYgKNAQ(t#YjyVT*7)$$AGW^K(F0Fk*Z3a_kHdpWvbBLHklQ0G zzTTBuUS|`?8LM2*;a0Hfj9h>=0%b${2~?ZbMyZp37qJHPR%zIBt9gmcFpV;sS_(%~ zb;oR8v9if_I28?Z6R|1w@C{8KBg2sahD4>Z0*>wx*sx>A!QEITAt2BQhc931DdJnj zL-hJ;TIX@aBC}JhJ6l+CD30vIqjyDKl;e}LkK?QNpDvEB`($|>tf&4n37_F&(OiT_ z7OUpsEL?q1igwD=gw1%jB7b)ah;(XA(#%(e(aNN`Xs%YxMVO%cz(B1LCvA*GjF2jr zsD%D>55ma`SMg&M`NIICnyXcF5f*j&L82Qx2@BxZ zC7JJZMnKNO@w4cL3?rAwMw$(&k@HIOui90zB-llrR^52twa&0b1g`h_o#30pk#CLa zCMgKTM9#t?X#q6%=>e>q2Jn6U}&P8yl^Gu($C(E^pfteVi<@{jDw9EXifFMwpm55AOjji+11a}HSOs99*Z%-<3^s<) zNQR$6;}zfU>oc3ztMJ%}jZ_M?X|u5<1jRbDrMEqnfqVfZL9o7@)nqI^hd3ek{2j_& z;V$c>sV+`Oqmk|fbM3biO0l^y%DoYIjo6LE6dI`!N{Qcqus^fK0~$HY(Y|6p7zT3R zQx4!TtK^ZwY^gZ^|qFUqQ~#QjG19Xh2Ey#4qr1&b()1ze_*r44*c$<-oquKUKL z`^xiD?;vN7f5^Wj?{SFSd?pCbufYGtkLzh!WRk!rs*yZ6(5N=Py$(f_HVCpLn4q+c zkz5xBD|PKLDRP$6vvHD4vuXqom01_lr)w^FmiB5k5nx5+CDz-;0-Xra z1F``^8_h<66KRl2ANCpyg1HlzAf=lgO+tG2)B^(@Y_HG1a8#S5Tv5kBq$W|G@7U(t zC=Q)rr|)y)foumHS{9!#AxQ9T?7~K%QB(QA*Nt|S zv*j|70whMbIeqRw;o`Ne^a(nuZ_7oqT*$8rO=jYYzXpsASeZ(u>XFk4MbyVGzSNe$ zEMhvjv+JUi9)%f6TWi9nyL-=gUEK-?%Mi5LVXZb_^SkL7Es-T}*Hp7c(3IF17m4Kt zSeUg503XN^h>{NHaQ*kRM#WwxV(;Q}nfK4Ny=3#brLD^n5OrZKoOH02O^8FDD@+sXtwQqt+39VLaY3E_}6-F;7q^&07l^eL|Lg*hmie4>@Hdll*i9Jz+iXqk7*wpyyTz|@Kw_4`A$IW zh7#Vr;7(Rdi{-g6=}8q+6`_#nYbGs$yP6EvP)HB(%B7iEM+NWTK5*-ajr7|on|qXg zMb8;?>`yn^TW^M%ftR_ zMb)gpMBYV4yqu3+C8f;IT_j1gNiLv@lOUX{o1_txv3vF3?QmI?H-fBz zawkB~!GY-JkHVP)J}_7r&9}RAioAz14efqzBAB?M)VY~Rz5eqOiBZoGZ?tBYJ$SMg?)i!fn^LZxPO(}aH`~gvZpcp<==UsT#1;7i z#t#YJts&U)IFfg26L<+%CKQou-T;SAUXbbyuaNT4NT%X0Iu4F)0<7cu7h>FyF==SFJJylq}(bBrTd*S6~;k`r;;5& zUj=gc*QU}^cU9D*(ojlDL)8KxP9$EiCXhu`COqnvN@$`oflfwBQU`;^1O@`0n`dx4}2;$ZtdQ{uMODLTxgeTjy1@f_~1C zFev*$tT}tYMKOM7R%3btD+vo6JSdAOb;aGe$QpW7bNM-53Dk<>*eoj5i;>>oPR``c z5{60FeOf(a)9|tc0eO^FKOAeVr1qBwi9_uwG_f;+(wy)Y5dz_BE!n+f6K612NRA~H zFxhtZZ4RasTj5E0Q-4i~v8Slwv3dtG&^oZj&Qy_yLU@<6aA#K!%}4aE@=K!4Ie)0& z3*8*CO-Ie)q(g+I^CKF~A5S0$BupKKRXSNFieMtPgRyaZAZn`vQX$upD48K#c_v2+ zis|Ms%}Dsn@1Cj*guM5pQ=*9>5}J)@&9!K0lhjmdYc`&uG^5WXe1?lv_&oC$ALvs_ zm_tz!>Fu9p+mP!z-8d64R+1|{(Gn$6q>#MAq4y#s;{b-8da?pBde(9YPy#AVHp)Jq zpm|L=D!SpxD#*Yqje{je`oMp1lFYwB?Mt~#lk>Fy@ka0TrJ7!QN`;P(v4x3bK03%r ztuG1kW|>Te_%z`+9%-JzG%Gg5cQyyNQhY)lz#7dVR6kHeGTXqLahQA=d1?StYb2_@vBu28K^I1EaB@80pek!l?n zc)GHHw-Vn7Hb|T-O*n^RQ?Hxamcnqia&AuDc?OTg8qgG%#-CaGo|%CsmLjQ&Jw@%K znQB{O+S5@Wzf0LIArsvmpT0HaK68-@`yA>;Q{g(AMG8;2Kg~WS26bORt!uPa^VjnL`Cjv z-gXlIE+;G=n{$s?{df#P{|=)lYC2NRglCN=5MN8_HA4w=-H>{`qk$r`@`RQITzpX zej_ONpD`H&n+0q|>WIFswISDw zeDGEc3X6*cH?2r}5_L*3MB0C?i_BJ)WL7H2Fpnp=EY;mf9Ru)dmr>0ONlc=NO_`*b zQo7<7GXwAOT`ck{JIm5KYBGR>lo?^%Q9tl5O-lsEdJ2~^O^4irXg9_rHiFFL{crwY3S)YnmQEI^gt%t|8xWk$pygC&<3|X^ zZKFdT|Ji+D%=?2C9}zZ)j-@D@3LuivR5*Zc+v;sJ(DfHZ|WdrKU}q9{^!9hNs; zr6!-jhWB=McCc?mQ$;q!UXz)GiH$Ech4IR=17j!W2WPN1q;S)Xavc7BGY8pBAnG=z zZiokB32aR4rA$qBLlvOMEuvkSNNtWQ#GXdhqs!WnlgGA<>x`;F#)MXAnU%tSF2A#0o}8W=(ezl6XJ&oTcWpM(ML_E4mTJz?K*O1 zM_+Z0xULPiLuqNT9w{z#I0i^bFK*>3SfB2h6;-x+qno6wnZ9Dx{*D~1FQb(!a>M`{ zhhSPj5Zo$=^62-Ge}-lHd8B`fn62GD(3c)-kgPr$33$wxZuV5Ft+s)3dq7h4&5{Fs z4pZ2D`Eqxlwx-++iGN4NjM7OuniaQ?!=i=&R;YQX`SHIrWGCUD+6eJNr{{?PN2eJq zypHgyuG`b*4%HYXiLHXQ9-f>X{CXXbSwLe{Bfk4I{Pf2wJv@l;zfoK7uTOOE==e~7 z%I&I;8`c;zCaI3|Vho+FP}8Wb>pFjbt)Gr|S9s*;x2v%*n-0Icjgm3fW8=9}r&Fe% zmcDsx5%?U@r?0}?oDSidE^5*SUP7Se&Oxq1cy|FUI5tpVABw_)?KXy>u&0FGNYjE3 z0h`ksD(^b(*%^qWL7@=}^I4~X#pxfe5avj`cP+&uws>kiOCT>aS_tAib86^3~?x_1yB0}Qvsg@#J|&P zD@=P{Eal|O2LWNk84QG^qs~o~BY{#of%P_J-MpRM=jpa}f(91&eq$xHsfWs^fkY+P zK^o-&L3Iy!0}$X|Iqo0`VVQl@KB3cr;yD zf7;(Z#(dh{Zdl(2+qBPyPIG#SlH4W_5)O~K;R16Ef5~}#E(cXZ8~Bcj&cW)FJz0nq zI_|%B{%6oKW$jJHH+ON%i zTm9_%9j{>iqmkC6B?{#0)W#NI__dla#L4wN)AdP7S_XEBE}GCkdpl2`-IFd6>LKq_ zPb=3=(!VZ`dAv(EFu-$ZMH3>P1V#7g1ZAX9ic3F2zR`EW8A+IDzYU2AwG(gco_Mp3 zK|&@N^xBJ(B#CGD{)F6mp>C)1_~tJ|M1U~LI+m8a*2b~&AblESe~f6%a|@=3TO_mYU3HrC0UXf+%aZE;veTXyx^b}sB=ws9D#1t7A?)X$maZX8xY_b5Rxq{<&kYU(K+%ZmYw9Bte2O|AYma;7_gBq``h2T^=)QAlJCjFZe*D0 zuI{d`uCA)CuA0Tf$xm^95D9e1ILSDHb9V&f-tMlTt<-i0BE{)}X^OTHa>wb*To|(5 zwhR(wdg-%~{P|=PJzYGvGP}HExh5yS*fGtb%pU3;wOZnCX1&XtJy#oeDi2;9?xBrk z_h652VR$~p`aDvb=*6*APNa5xD^8wb)>dmA(oEV;LkMJ7Di21%1 z=J}`@G^vR7)%-&L6S>*q+`rHgj^k7@Jg;UQUM3CU_5`#r9%WkF^G;#f=3JwD+jWf< zT0zUa-l~e?bD1))`~E2?E=7DV#%T?mab`zH=j6PAw!i{;#}-XDVU@D?18t-T%(y}I zflupR(j5fpS>9}-F}i)ioXHvjSmaocLQv`uHgg0dn03%kU8c{+6Z1^=X`snWUfA$Fu*rG8C9*L}>Rj7@#&`W<=v zL`t^q@817uPagsCbssDB>z-ZrI&$4vb8=pWJ?pm7{=&pAorKv&lONuI1G%6#n+cG<;YcWI|4 z3*>d$yr0rB&ULae^?LGC+)U-R5g)eUMcIdZ=wszjKHLx|XzWCLIL7k??S9HGFTKGy zL{}3~R2YCrn)F>HY$(W9#D5&L%kU?{KYiwa|2SY=B2&dN=bbU*QK+N#7NPJT1mF*X z@P`5MhlPPiu@*E%{XjSCeEuma3@CfkF`^tcOvm1hR8kSqw$$#TISw|B$&pB-*YWZ7 zJkM;8e*8aXbl0imb){bc0DJ* zH|u{3!Z2twR`>tE#^+Y)6F2BA(I&V__oQ#D0}%f8mH9Dn1W-`&czF2? z3&-ji@QVpZ2(aGJ@DghuZeaaoI@u}9Ng=OY6tO0Q&Wv2k=;o;0B1AzIMY`U&OFA+u zG<2hMbgmEj2n4Q9WZ(UW_Ba&m(F+bVvng(f#{0y$uJQ3l*9;JN_MjU%=Zomf39q&4 zMHM^a>9GZot~_FsZ~n}V+IjVcwC5>WuVdhzps!Ax_UJ|~IppNM;g)Ul`ur4CV3`3y z1ztm);*l+%oa9m7=tQjg;aGZjDRn>&aZuw7m@Dcv=eVJuFhKj$IB(`bOi5&=&~u?N zEP@osuBdNKBVw=Pi8E$kvj;Ek?>&C59_%09KiJ)Wbf|U@4%Dx^&z|i*e!jnVsD9ml z{*!vP_v7xf2kQ9~_57#(Lv{G%;d3amSI+N0zJKuI!T#ePsoMUdrw99c58Ucc9;!!s z&+h*OKX>o#AM8K>U$y)AfqJDq+9%*kh+hJF+QauzSZ{J8x)?kR!_7OjMx$O+ zH*T0(+p4m@etYvy(5T(UHbmXNVR7sL3KswhE&_zJnd(rb7Hl+XVf{|M;rA#EHXAh; z2Fzc2IJJ$<+qKO*>vg~KX0X1oUJo`s06-N0Kz<>fKBT97aN(3AF<)xNso+OXIMiOv z_vfE)=1X{he~ykB+v@uDW)9dS9Z6fCC)jmI?5z^V?W0Ja{G&=$xPHAzJTgf--Ai%{ zOE~oV{-k{#B5^=3=sR?39pv@RjoQYY`ewKhhK=>c23a3O4A57h=nB$!RJl+0Q=v~e z4M4i8$5~W&RiJ)=|F$%2L2aU7nY&O#AIt!8sR4#8ewX<7n&Pf~A`l+g0s_WqWjM~1 zBDY?+hM^Pr{#$1jv?g0t9odBji0C%9RfQ*L?yusq0;#qzz^9Eyv#C0&w5>X2HBdV+ z0vHF*Blc>bZs?x?1PkF@$}6N!>}oF8nMCaqdh;Pq|6w~&UbSu4J6Jxb$^fwEcvGFb zEdTw=rS)h+qUrqKqhTB| zd=MLeQk(E-1iFUL`ZTWt4Ae^A{)UlEpt9a~0V+aN7t|$INj(-cQFjo~zyiW~SOP4o z8(mu)E48@|v8)vOfHUo)^N;wSBmI3BG1U4Wn8McX;eq-`4{%i`imB|NJOnyLWd~=N zdWC?o*F-s4py|drJhct%kEUHbc%^Z3kM(pQG~O>3!h1ktZtY?rx0)aT`D2MNa(f|& z-!|4;ox!vvF6}Xc0cso}`pM4s_(%HV!zOk|{RMUe;Dt68wBo{XJ1W?tvp(De%!*&w z-{hs_1n~w!9d1=vMK4AekjRU|Rk|fr9kTzBZDeBmk2scoAsfST`wwi`VeM}r27+9N z*TKf$f-tDpH&*taukrbG`wuz5w`Z{9i${ZNoPqDI)s)Qs33JhHJO*CbidMFwm96Nn zZ!7vt#v=EG2E<0iPNw7vdf_2W9t2$HoJL*YoF?a)oUU6>^XqvdRwUi-^NLkDEZgGy zo>tnFcUnTWex~`!>lQGKaknriDp3enYPB!$sS!@zvHbn2tWL_RG(q*@l``TY`PUUi zfjAKXJtr^k4USMkQx(6o{Y`Jz)GHKa23Qfk-PKye$=VtU8tB#oz*OYTF821;$UYFj)(WqJu0%*~p+KE-TnA%4$@U((s^Ef=5llPQB@d37j zUNu%!o4n>>qIzU6hp@A#X2ANUh!id)-N8clu%SZ7 zQ6bWFOj-nLB@RK8am=M}Tz#6vwO0MdY&?lhGX|b3fQElqRAwYVe204Ixq|ape?3ex z1)%pFM+7T%=4Jc?#Qg_+iRbhuYU*}h9AGglO~pIo$pn3uyC7(QXodebSQm&3iZHmR z?e0mdUejgcL0P?p|Ho$dM(akq;bCP5X24W_uy^mpk7#Y`MZn@qw@4xGP#Lv@>(ai; z-J2a1u8)Zn-$tr~WXuR9g-=lJ)W1vhUBxP%a}Vb99Tz1$SyPn?BCmrlJN&XkFFW`W zU;TkZg3oTL0-_SFMMbjI@dY;Z2VD@xa5vDSDTM<8I$t)%KVW!w77wpy0WBQnA8Z2P z$!Yda1=$*N00A1tH$DVSa!IPf9ZdJPX}S+uys2M=VffvD ztBXM6;f8)+;L*SXZ;Wr{sTpGd2Wf%(!(BAc0*{A`ibV(DTMbaU0?^)G0@~YbXou(o z4x&i`mpH7l^P*X)iFsW%pUzm*^Lf<)rsp%c@Wu2fJ0`5SySVNmV?()yOG^xy?jqDR zDivIMJGdNg+)!MaOq;xJb2(Y>+iK+6IT3XC^h`J_S%0aGKbVe|EE}&AF3-4lLH&sr z(Xs{fAGLV?6br|r(ZqI@T2-I4j%5G*W3hR0_4&>}V*e$t>@U^Ea{KRkxVawu4UcVu z+Qw$MSws78EvT*RzhC3?9oT=#UGUDz3cRucudKi;EAXG&3Jkq6d4!VpS?N;wmRu7z zK^_3=?&1CYeYq}zW-#pA{wO|^usiDdParKqIl7jS%t-cFZoKVwyED9vJv_gTw~hhC zk2Bz?Rmme&R{uTWNcR5?s}LSjRw?!S)5*A7g=v1I4)=e2dH^(X^G?9Y$-=N!32PfK zb(bC?Z^hetXztsBC%Leyo;kOH03gRRpevV@R7%AI3Nbd~)LY~cgz+X$F=G-yP)d1G zJJIIWACAY90X6LTwD z27sf=)vC%wcEzhtXj!U(ZisQK_b(Ox2M` za7HOo&M@lJ-8N$D6vscFMi^7&jYa~e5)uEceuTHfJ30_0`nCTK)qGQy}<$E#}euR9fYs(1WPRI615#&c>d<_o(R*#hqXQn~}a zK{P%)qoG9@6+?&4mAZav8;m*2J;wW~yyH;Jk*qk13;;UIK{R405%=3&Z@Y5a=1Jno zmC8W6(o-7CdKF1_5}mRzaC(a3MH}x%#+-yeN2;o^gY!bNCTI;@taSU47zcJEF%A=X zfG*z=p2H~I&~qb;abbQaZ-M}SA}^TbsY3=;QW*fbgB#Mpc6?%zg^?FG6EgRwVWO43 zLCTz9x;I0+Q;rwkk+X$`J#AuT?jcGRLV63k=Oy97Kuxf0-cZI0ynV;Dk7jKW=bVVe z$*8{VVOJ7WQJ5OK@~k_~A>$vF_3IRI8XKhKHN)GC`pYHR%trNd-e#$04O^E=-kA_^F^b*0HW{Qz6Iu-xTssD+^$Il zlhtt!Z#_62V754#8;ql!!x-f5Hq(Ul(dJ9xc;#K9VuLs@=^g0qZEk9^qC`C{LQtf7 zl+`g#E1m|wChY}78{**Mcd>a4R`Z5T}CfXEI9x0-%I4l^JXCAeTF0em!>d*9eLV@d~N9wH2DK?dNV_7k#r@a=!o)WIPCA3RG(ubG($$>x2G5p+~*1E^~osjmc;j|6^o({+O z_jthP{kazk)=&?+1LJDiT@SxoAD1{V$LEK8&s+PC_kIHnUak~yY`d}o49j3?M(e zOB6z1<`|Y)_qgDOrJ&;sMUE@#;a=FxDD_6@Z z_u$E|k5eVkN3?lk*$`vi@2U5?6|M}S==|xEGH7a%fN)xqpK;sKpc!P zqJL1h(JR8vcnCXDi_+R4_**3oa*UD)nkgcTJxa2qn;|{8X`@NeJmpB}(U%q+@Z0L& zx&iWg=nm2JNQE)@1l5&04Gxrm?}cdZp8{RPqALk_q^O_%vin<6)0-{9BlL#2H$Q8g zg8o4_0?ZFB;`s=n8!hwOc;;r0(*!dKQAbA3g3dMxIL)m7@Ua>;5psuasB2#T;ZdUtm0^P)YECel}*07(_m8xfrqG=a%D0Fy8-8I!xnYqZKAPTE}p z7bf1l=M@)*O^^Jfr|5+mVobN=K|qoDU8okQbPG{$yK_st@m@Livv8FT$47;EG57E7 zf792n+8{rKc?G}Sfs>ZdrDoOt_h-@U5dg+5Hdd(cgFcc$CP(ZQ`b$-4{ zxJn3*>RJpo<3TexN0}w`N_5y*u=^8b?Lp%xrBKeON@)e%dA%)F3%}~@3utGP%n)rk zGJr|$oO3`ZvM3?lNpF?OQ00W%CffomitSJ@^UC3yjPj1%7-;C}SV zW%LUK=NwDTmI3p<<3>v=SDz!*33KWCn_Sr(jdC zOcZ^8H`bxp02rIHJ325|B9l6A4+=h8&TFg&ps-pq!BOW4b_ocohb7|8$V+iwmiaW% z21)85RHi$R4yH{PIblK$B>ybafy*)gd@@Kg6M%i9w;IwlNMc0?+MtS34t#|z^8|5n zQmK&qCu~EXg`N{FOFE2TPRR2Pp`74?dJeOHcG{lX{oDvJcNL~E`TgW2-#CDV zuss7%lgBGF^)L^JENSSK>Az&uKdS+dMhc34mRa)qGKh!SpzFyUbaWa+fR z3b*d$j%qLx*vPQ0)^QjvG(9e(QR`_34ICF9D&mNVkSOLC8!eMA9smxAr8YVJ69r%e z&PJ<(^%vke$O@6Uk0K2Idi|)|Rh3_1C%UdVRhT(G6Tg>xpsi@S31NuXCe8J1+$=y!A$v-toO zVc4260X^jjVwTQKMDq~l)y&#%fQCq+T8N9C;C{1i@c#-V<$J>j2w5uP(9R~9?!wJC zEDPinO6y$Q%%W8WL8k5uj;K-8+38y)Y?XQ%VJ6;dz`uiqaG zt->=TR(w~o>OV-JjtoL&P_#gi!pb3e+fg!*Naqg$-087d61FP+Y@J~ zz@}Tod(t)Ts!C>+(YWRCzf6REu)!S0EyFuxB<8n_1VbeNeI?F|@ECPWM_`m8C`VGS zIC5}w?jxHhuFCIkSwslJgKFaz6APdZRuil{``(ZzW3j18?;yceeB`n>e-7^tLb;p4 zO_Tyr43ifL941l72%ALH&=v>ktf&j?bY`b#t=XBawzf7vzKcVXayD>`iw1`{Gbz?C zAQ6qMFFVZ5kJ@>LC{Q1p(m`W?Fz4vs=){u3zGer4dJo%Svx#fJtP=fkr=UQWoD43D zcHq|v-h^l@c^l^P38H8_ggC=){KW!;dV(Hks0#lR~{`~X;$-aS0@S_EF3udsI!gMcpt@`F3|g^a6SeNtroDE+dGs&%V=30u)`FkFB@_K7)+}N zVpAxKE=hc570EW`S)65GcQn(*Yb9lZ&N3%sIb$exZqWMl`oYSq&eB^bkxF4Ll=9?> z&Y-1JJxn~l8GzvmYilLTJ3eG09{+gA!G(N^dUOYEKc}ekb{hDN zR@CWmEbA&`!yaHDfW^ikZ2U5!qU9 z(D{nF35M04>Ix18c1ZCbSQ`L+sQI)ZtHTJ;6VpQKZw*h&yyKNd(P9$uomCl@9T^zNn)Vl7vp_)9`jd zo8ua=cSnyi5<2EXlar|?il901cW6{wX==DSEsB>h7+23l^NY(4>~t+VJiIsRfo3Zw znu}KiR&=YG^B?&BZ!PB+)6J8fj2;&*l9=N&VIPc-YENmh;^c1!MWLBa*}Zo;50uR= zIT~=9G(7e&smSzY_88b0h~9Kc#SYW1k24+x^aig7F~C9}%ymra#Rt{oC|%9d$prv- zD(Mg2L^`$w*;ciKwXRmX%?{SkgG1PryHQ?S^6BINHbQc}Zj(PPh@OHG&pmSuf@h8K>1 z=U53K?gEQrqi|f~bLOyb)*M1$qjc8k;nhL=ki!iP*`6b#MSWc}G;J7kxZ`OiqjV!4 z4q$N^2vDGQ`?4U23Dz`MKvpuO$sk5jGkl}w@(n40T*H(Q&E76ezA1j_iac5|?+BA@ z_j=e&7?hz1Tfrl|)9>`Fv5FQ7LlQqkEOBdm$QBRGR!Z1oj{46~J;5kXo*>DfG!Hm zkC;r?j3{SRsPky5th=Fh$kl$J?DdEhGy+Hy;3HS`fBb>p5#i$IF0m6#*U4uMwYx#T zkBbR<&o9V~M{g@T(2cG#%S5 zQ+804sS5ysD33 zqoGqeJdFv_yHMqkRRe8sT|U+A^bLJH!=KIdwT*F4;~(qdSSBGxw$A?w9O`*x-dy9ceqUBZb-?LrcU2Baw%+ zO>=#oHB0nJi=+YO_52W>C3L<_0!7wqN4j+>I!cY@BK%)7s9rFS&Lk(+mU@TBCMLEy zyya-sw9VMTh`y`$jXPRxwPPM*z>J(3fHO#Q>XlwF3&v$8e=BXs&{*^B4Xo`L%{W^| zFe(}DA+(8z5TN&zC8B^iSvJLWLG&4R3SJ;mSe@PaXC};1LcI{2 zFhpMl$)b!9RbpmGHAD}1z7)Ca;!~y-D8V*h-#jIs^kzQEG8{T|O+Xn;;8kM%n{6b) zug$_o(~ky^Ya!e4lVSBSCLdqq%EGp_^;l1ag)79M!C4~N_GbeVTienh^~|tw6v)<%PRiM zpF94GT$gVJ=37WzML$N#8qGH-$8v#)l2|E;7DJh+oRG{Wp|vBZ+FIt4eJfCb{Sl%@ zuYc53&HkvXdh$3-H|oNwyRd35tk8uO_!s%JB671>QRvM2W%UbR%E!CAeGFr(!#KlF zeJ%f&rnz?Cq}b!FsV=Pz*aFd1EmOQ`sA_NQmlIXpXvmU)>EY9T%;%1td+#tyGDzZ; zaHD>^UV$HLVOiB{n;U4}rib`%SVx(wjQ-1oEU#Pw?d8u1-)TaU>&O@|{g1@E_YEYakl%H;-W&Y`7+2XeUrq0uaaF5Gvrii;m}!|6U?K4WL%ERjzl~M?r?2w)4)nj3=C{)PR+`^R^ZS!)eiHisaIban zLH`-V7ra-!Dr1q~(bP(!?+_NsT&9lL<$EkpxFnrKxn*6%2f)bt0&5b*Yx4 zOO;h32U09i(4>6}tn30y=9&SS33E_c4JneaG&!ln9mqgd-z4S42d(?N_kY^cP{dP# zZ)|NV#wYre6^fM|dC6%$Z9_e1iA8MqQg9(ym(Dcwrcn~p?^@k<_c*d8oQ6acy;h*> zaOp~NOipi?_de(MI}S`Tj6xbLsz#g%^${?oC-)1s7Wu#G(|OV}&NBd%l{AoB&~f(^ zBQXnc;M^H?wNe^^QArsxo=ot-3UO44DaZ@{UQ-)%S#AT%prW~^qP1QR{xMOXFp3>% zY$VxZrMrqK&mLSMeRU|&0Xpwu5qtYr>mi>0MJLa6oN^aagOeja{oH{yhndd+j$Cq; zdip$!1C2OGnhp`?awhi|Dl{JPtgXqB{n}c`aVgfls=CUN55>(O2HKu;=}T9RNQuIW zv631VHOhaiRcpQL!aw-lyS;^2smSP!gF-?*)n`py&a{~9_8OJeckgOty7(OiP57@w zcQJ$&y~3LfCw!%$_)gz@Fn6H_N=m9*e6f<}8c%yWk#nO$rrNYWNE|>{DzBVNcJ_E! zZ~zrb?gQ$MgH1;(w6|?El?03C{K6^sW;}Dk)J!_~|4Mco&wI1Uy1{F8%1k=_M;d9|dQjhb<%iide8D{Ogw;3KGQ&wiEG@ zI3QXbE!d2t8EUtz%c+o-_>`i+F$CU_5WV)%NYPJ$p4K0 zll&iz#%4(R|Hdl+^Vj*T^#7IqztaC#`u|^7|NnoW{8vHoFILrJ_1!$ZD>1Z>ca|&Z zv|qB-zlV{-7oTlPq}EbTM<`!@zR7@{15T&@M9BPiJl$IoRdy9t_T$3JI=xSa*nhgu z<7{Cx>_pY%>2FBxrK!{4+sVV=UXMy z9}*LkPveJv@@Slv#W%M1JK{=5ynvrL$=JNaIWS|t;BZ-Y$Q{pO^j!7Sc`;?*RhcL} z5JQ_D)||(s+)+2Z_ksUDl=l?Fxkn)b-KB<|!i=X*)LDXARyUA2-{{P>3v~u!^EMm> zW-i5(d}P+=Nq8Z{J4blu8XjG2PsZkwlK6- z85GlaU%0ZUxwrbV*_?B=E?+5coWrzZY9k%BHm_TR0HcvbP zA(U^imkVN@P|t~3Z9E`#4L4qR$@UPs^-39m>DzG3S99N*85S4$3FGgrMmFHuxeN>Y ze|4mr<(n8K|E@3gQ7xq&X%i|hx*!{F(A%M|ST zjZni0=Me-Moeqc+DgdxvY1G${Ciq1gXS^1yZ}2-noOwA(hp3h}F<8t(Pdn?2D z$NH|^xSI0{a=yi$D?;9$^NNEOhg<$>?Ov-7e~kU_8{Yp2>Ou1UM?=Z)N}c>)QXmlK;<=OAwB!@KT1tOPL85SqVS>B1D7lL1-bi>`;wO*YJZi> z5549Emme0`2{H{T%j{pSSuW+SevyIfGIp_qNh#Ac|FSkDYSjn7K|Tj_r*{colJt@OVyr~mbh z*wtUA|50KZRq9_x{p%;xKVA3ZwZGarX@9lNN^KpLJymP0J3lX}`-OiM-LLQJev4H< zqxs$TH9!6HV$TQXTD!Ti{#Et4Qvc%);J>J*=3ynJmx)?d*O_&Ftt=3&?Dj=k*(NGw zwfZupEaNOO+_>mQ`JYL5)AIlP;9L2B2aS5Ik(B>8);Cx3|JV4e*S4e+(Go)zC~WBp3uz5X&MT$c;)6{b#4 z0ylVHmAW}GB}X=;$L2u3$avONp}+wfFnlc@E1j4Gj40a9 zQCsV9K#ks*qxH@?S})bQfh)cB^YLWgz_@9*zRX7DO37F;j; zqxftvft3JT_4S{|Z?N1`3^=SFqWdY7tURUI(2r-Q9UyhJ+wIOK?P)YTzYcW}#E&!B z<*Vv&8bw2(w*Q_~X{r4;>w zu(t71cj*!C_k%8NY4H|3$%R$*tWAa%*xW|2e?=4OS{d`8&v0J{!T$6NMmd7rZ~{1h z9eWbR)4?h96d@=@NzbDxZatt&Bf0j6t8i`7nA78?aRU zW7d}K5?aF@@CjC{0cjW2#Oc@*ctR;_2WLY)0321WR#gu%HT@WNWK>^(I#o>-y5kA- z@@&jOL!g6E_w|&J*M~1f8eVTax~cmyot$H-qiBQ(h&bbIOf%Y@4$svv>QAu%i5f5- znA|CFD1;*ry5rL`6rPAp_MSq3BM z8mFlTc0nxwU1Hobn8~uVPKsgx6NF%56-Ko>0OEh$skl?Uvth(NJ{r7cyu~PW_4V4}xazOl!J<&XHp6+bOipw#O36j)Ecbt?6 z;1;yb_1b_QLZ4v4A#*u_pMT7NZla!M45$=w{p+*Q0QQPghYQ@6L>&or`;Lw zGKi%faxBnOfE0#>YhnNGVYRpb1k^ zqq-f@EEBy#Meb2VN!XPI!~Bk6^sw4mC1JWPQ>!CEjsqDvHRuv#55%~MAPjEr;2Fw< zI3o9siSK+64MC>r$%X{<1NcUH3rDY42!_aGUR{M(AweTb4$ulHES4n~kQ7-~F-#b_ zJ6nsZfDtN6vewhh#=5)Y%X(MB6&qs(+K%3!X#v(Ty$t!~f_*8Mt5MfZ+w($L7CI=B zwUR`kkz}`z_2$aJ+Kw5OaPAWeAW0|!O{m@IY>MTX{Vbyk>`$HgGd%`G9vvIXJZs0y zx+La5Q-XAg1Yho#TG}bvi;zCcgk0*Gy0}|p-oP5VH-HzE6h;vUEzmA@d%bc;pSbxu zvfH5;H{n{P4hyszRjCu}s0GkO!M}Hy=$vXYi&(OT8Vr@Z0s0FKJ&LtdhaEm`4{!?r zZkwm16rjZ(VIVk>hM-5lz-J(5496sXp`ir1?BJAXhs7n{%@`_lmBve~NZNtB(!!iCn9`Ij$bx4{oDQ!Ifk0Fk8CXW;6U3!60XJCZQywS-Yq5bIT!Cve6 zPtW#t9~?^PP&`p&F+pNJ>U)p96bBI?VN3mCa+s;udv5@Bwv)(?P9t!?Z=k}hlh>=sm_pKy4rx|E$=9nLPPU8 zUfP(1+UnV$vLl9|8*Bt3y9$|0B6GHiHVj%ZZwsBGbE+z#MLRmQDDX`kT9i!@6&q-j z3>|E;;L02)vLnU_njdfYVfM%aJ?>EMCgydpT#S?3sr9fsHwN1Df?ZM_Z5l!o%y`lZ zs5Fq-!%4f_LJIQVyx&%P^RreM8hgBS?H_q5FmPb?lkpt6KPnt2 z$dqj>opS@?gqj2-a-)G8Wwn0ic1R;yLv;6Q)O{#YyM3ooyR*?)-w0~q#%<_YPz^UX zf;(ZYaVKarHg1QC)&e&HO6(hyai|j=v{gZ0K&*{CjS-*5u+)cD85)S5lgXHlMA!@g z%3cL#7%Dt(pAXUC5>4n-#vLkEM*9S4-Lnboim%7W$j7M7ydrG|Wk)qT6QyeuPqA;n zXFw97%Fs!~WHgG=SfbCEyuSEGAlN^tqD3RBpeanEGt3C~%J;h1dz41PU~{uf)lsm; zU+|Ud*5O<2UzJ8pAwg|cYf&X!m$E%F&xG)#uJ>Cr7PNxFZas+@u`zAdXa&HUKSkIF zG>!BK9qF0?&Y#ZPT(j^imL%B=r1>_t&=z|kOl}A5E3d~Vq)sBKaaTzMnu^JYwNQ|s zQ2Bu6Iz1*sY?Vm*mcPcyLT#cd+qIe_Q>zYwUA!z&;*&v|zMH)EMf-NGR_zX+az*pA z@dyQ-2_7k!q;|x721V_egTE@Tn&w@FC$>o8wvqM3GzLJ&CQR8THp&ZcG%b<@K)X4H zZw{&$qYJ)X+g5CPuT&@$y(}SZ*hJ=yoe{A{?DG!(US;uIVVs~TL1%7Y9Oxu(ENR~8 zGh*sJJVtIzdkp}r0R;SwT-NB-UX_C1fuaY&PAK;31T)7`d@@Qx_dFW4&Ol$X4ko6D zcY#bt@$V<>1%&89EEzOtCleaKv^;Qz|B4!ttMfHoA;xd7QhqlzJ+E9KaJJAB7f!># z!EYy0VNJd!Kvv{2)vBDBYA$qERurXtpzk~CP9olzkwj&SHq~}?9z^;Dt*s+qx43S} z2*DZz$k0gFC`x1BLZUp;5|9(3loUg+h*x3!!%;*>?8r3OUyE`Y!jeWVgFJH-jc2jC ze$?%%%CErPujA?Wh>Q?eL4--{DfgM=FvQY7{iWAk&JHCuhfl(8M{GpG{~Y>9>@@nJQO13GAT;dkna4ZI_QV+~Y-TND#pxP% zRVA~^XxwtPgG_{3$BW0~mf0L+B<8pElYW7Q3g4!Ur#NFW)8qLRmV+%)8w`Pc%lwlKG?Dbm!-iV>+Z0ke}i+QNzkAGdl^+(Y$2smFN8 zVWwJkMMk|CclLv(S(*+~9h{n_>XazzWxxh3$5b^O3)yS4Q|PW@EpAs-c3V!>4yXgI z*_rL#+S&lO7(|eivq_6xd^%K~N%{$X^3K^|V3L2-P5?y8`oxJ&Rr-TDemSMX_|!CN z79$hr%~{x_{4Qmc=#R!NbFc-|=_IuNm`NSrdL*RjiDWhl6xU2oEUv)VB%N~RBx6#X z#Lv!T#vbW995aJ_meCJ4*d2l>($co-z-Os00T?d3U`<=AtIG#a(qpNtna{aav>u66 zD6*dfde;`_8aVRP12S(Mw_l^L%yqJ&T-T@9KUnbyv@uV~+8<3@M#lm${~N_ZQO@@M zQZrQ}4Ey5MA|7k_uxK%Ma)9Ro%`9hC4ulz8nvvZAnvJ zsl*89=AD~nKft>%_$&_W%GZvLIp$UNCQND#n}xl$R@Q zXIhE9CY-LAJ;FmfuKLp&8QJ0IDcTM?$VGYioesy!UJ^?P5RPr3rX@SnFvU|({#2Vw` zJ8rNU3f`T{rqOALZBVLd=EI01W86ULMd7T-)0#OEakMc9-<_H{K#A>FM)084Dd;l~ z?tBdeWu)S`W<_S2iyE{F4}ZXKTkx%!*CrqaXurm_1BaiLr4;8{$3==qHEfl&_L1D!({3)spZRX!hJLm*Ph55^vHh_2L!CLwd8~i)wt+nK@)?JrEYBXNU}q7p4zEt`YgnWf`_&s5~(RDTD2vp z?kV0VJ#;ycR*E~aCfhwaE)9b+6k&URgtv?U61z;C7-tSg*svVIS^gRvt#ScK6_Sei z2g_=VFozT`Mr3D2xN@8f#%buV+$aadqALutMN_LS=nSOd>G_cQZpA&?8BfU240Gh# zO&1Cv3D%TIY2#3VHz5kzyR~_J81ax3qA;6lS|k z&NNEW$HGd3p7RT`wb5Hi?)n3;>@8iNUI;R1kJAsdYDUt1>)!tE;obwiq7bAkgKO*t z24Bn_ZnC{;!?7!66PjERl&OnSd*AWQ2d~^^BKr+rAK8JrYKiol*FVYvE`}DO6F({Jd3N+-QcK&f7oQ>mnfZl-ccED06ZjyG0qCe_Q?9RKhdQrO{Z$fB71p?;!rmD)P%J^2;jn%PR8ApC!%hI z*WLpYdolIG2^K@%dlarwKe`)Fdr+}@yo3518TmL=rP~%=lh*L*qS%n0m?)l9imn{z zr{`x8{+f-@iUqx=^7O8mszJdV(^bgqCU5Pv7F}!i@!@{Pb!^=~e2w>53Ptni7YxXG zs{~vG?}wvrz89@h*O>biFpQ_^G5v!m!onVMa1}jY(jR({H9N!hhvI$+_ z+|!2rqeoXflK_qf1fUjBXBGiyzk#vRtYyJycc%oT?o1p7B0=X;e6jAlcp^@xIZikS zN>LLiMXx6yidlD>$KU|(_$H`(D-;g^&DXZRXR5uVv!M010hxNT#X_@-sl;K>R%rW{>MtBf`G@zY2f*?lCQUHPu z`X{sc{1dAmd`k7n@;RU>T!OsGa{OOdeL3!_`eMXSmLr~OFCO@Ev|m(tDboGQuv@4w z1){fq8RE}s{OnT8CcEZkR!e5h%Pf-2ikDa%ne{HQDzfWcyc}p!JegRqQ;5rPR0hdh zXq$hB@FZC>RdjLLexhi9VacBpC4XL6a-JwTUtIDaS@ggyYgL`3K=UE393(Y86tKRv zLGOwm$Np=x34G=@F3A4`?f%fJo~QdHBH#8mUjg$`!7c_^5!zrs0I;1Ut{O~SO2>T*sJltzNfAZ_@vj>>IV9Tu>G*u$X3zU8F6w7+$YFXtTJo)u;s${*% zp;rtC`0xQcjL9~(Io*bwq?tO`wzY#NVpq{kSn>|Gbwc?WS`}{FnSk7vJ!f;)KgBTq z5^Y=%|9_*lQIq)pjYimL!1@Pfuv-6LJVsk2(&r`y22rljvU=q zuiKM>+-w*rPG!TiE#ZkV*kWfe#S0Cc!HB|Bt7KdSjCkATBP65rt5=sOf?%T?{{3R=@22rXIBPSj$)$!@%ErM6oCP6EYH;${5HIN_^V!n)=w| zHIDiVGy7zO5uw`MV-zfHELBu((SYxadlDTDFa##rW~UsA*txv|fSIwJr!iJ&)GI&} zMH`;nyh9+JsE-k;ObjZqyaMisz9?QT1@DqxB2lOUg}D7=HhA40Mie?5CZdQpW22$E z9n5cUI=C+Dc^+Z_*;-rqbJ8Iw2KioPH~Fyg3Dlt z@vaqyx|Y~y7)c$uH%H$@=zm%=2{S|lM_^kWGlQs0hv}D$`)M5I`}^a ztmFE8)5-a9hUWOtEp;Jm~7Esiw5}=Js1WD2i;?;$f4np0|QaxI)a{@C_1Gao^#d*Ik|0f z<_@Z*FTWLfB`ja$5fmZ}B|~_k%XxUft9@;C$^|!fMjP+yRod|X3Pv23Ab+PMAu{*V zyJ-nSdeRxI#56p{6IzaOn;GdpIniFi4U(j7TgZzB=r}-?u+z}3rUcI)X)A+i5e0i} z6yuX5@zK^H(V@44-mE>;sS)l)-8S|T##OJ{TpA3dEdeH{gkmpQLKqmT0K&v5%Ybx3 zF6HlFI-z>7Ls4jOs`RfDQ!PN3YYL!HtJy6OmzB0#+WfGFNoFub4k1ps!`+)O?8XG| zoKGXV!$~Dz05OUiJq(;&O|{0kX)oE_>GcsjwAU&`6>68g9?{j#Z_Nb^48d zFFuGvJ|Q2!M!KUTa_E{VR`hWNVpKmV zPF47B;^MGfE(BzPeP)Ii)l&s4$NAlGqk>?s$EO3n%PS$jQI#eJm=V<*k&w6=OahJz zKN;2{Vdg{rM3F9;9K~>mH5v6?f5Bo`TgOxG_!NG`~EwsF>SG@RqV0F#_BIIQ5KMO;IDfIj5+&@cE6xB#< z*FIs4bSTr-g8|wIvO%P>ba>swP^SX}$o7~SNtr>CXgRpO5%?7Gq;>G*@sIS!TUvZw zbWD4bj_@+n{$$s&dA$*#4+}^|eY}dYu}-(PQ5JfFHiho7fml}O;~A0w*454bHyVq> z4U)g7C`Q9~xd!`;jYtZ3_3pKM%&J<)IF@saoy-aW?4;cjl+s0K!0E!PYEv^l z9DqKs!!1<80stXCxOdQcu>WJ3zC7CftrZ5Xz2BbN-}nQo6K~pmu>V`xVNNGkXV+O1wd5n$7Ps6k1fs3XW zMW;05Rx@LIlMVqi$|R3@;LFmaNqI$zDKm`TK$r*!uoN$WcrpAteA7NBW(X^`8xb`h za(WFkOYp=X015`2NxEdKqlvp2lUq}vC}f11rID|o{qycH(r9RRN!}MD3XjH;e~89a^H{)C(OB#^FyZ#R0X3qOxO@hqM!7D#lkZXTghbHmD}-#OOo8rj$ot> zxBHkeLq8HvP6k3(wCl{8QBsK8#54Lj;+@HvR4uyn^8~ir*3$_n{lM-YF$&BsOj|E% za?sWPZjY*D@h;MGI&Gf_5$f7#1x2tRagJ#XNJ-+G`mQI*u$1g-Mww4I zL6cJtF!uD>{x7@FL9p9=(g9;-jL(Gy5~yZ;~0x97WO^dqiF-YhpxrPWm8CIU_?VvBdJ;Y=jOfIk6T?Q@WQi zs-@a+)E9_EP`87?$-6}ij+0y^>WdjqI!$rt(cBJ-@bnn77{Lrh^Qb#xnnA)v2)8RF zev^DhrZIQ+VLRVkhvxZ=K-dFKSMW|qQ6g#4bJR#zth2ghssky8tg92*M zhRrgR7%2s&3Ew|Pxl_+snh)ykWvPnvXv6k z!4#_1YLNx=nC>Xh)=p+cqIGy}^z1hiLYfHbGX1O!zP$IKbKjS$_NNIm`lV9Y$?7YXwhmiDrQ=XvrCCQKLyx z!IbmT4Pt6dQhW~3{7)Gw#k?rGpvkic_1}R0PIom(3XrUHRND%g9WuV1BE6BAlKWqc zW@0)lHyRi9LQDc3306jVSFyc1L8j@PoOuwa_BjRI8YBIYq=@JQMwg}+OVPe^oD7Yg z*d4lbNKbn#CoyD%@#c|0$-7`)hiyJPg zWdC#Hnb~yp0g*ukcp z=NMBi-!#Hu%gLE5wo~tV9+29?8+yrienNNejvhQ}{V@XRogR`y+)ra*nQo|8d!er% zjb2xecapxO5BBc8_|btGPkVzgLDX9FjM6{7>z`px?LO>3pjc1J>iR$8e~zw~)x6jQ zX>TyaAcr3u=nlZ)pyPL3QgmW!`Xv|S@ahOU1Sc=X;dA#Ao`%7~ymmFFVkHsq+11$I zaquBZA=YIr)ETEtK+E$k8hiAUU2NQ1c1=bDW1=>I-MZ$AqbZBV^Cd+ce9E z)(EISHJI%o)vJv~z1mFo7awobGrE+9f?1^Mn?cZMY;M-;wc184jMfmO-=$x6f4f4L z>I?8x+q^8Af^aSqU;j7Iz)EYx(7TKZ$)N|B86;s{%x`PvN>6XlNOBs`A@(n zTh5R`DLb|!y8P`wy!RmjLBXs`jD6%iq=oH1g}!=)?ma4!Uu}MmPeJuXRRgl@a0qfI zC~Kb=2~CO{yB17z=jPixp=HbXGEgfd%)Ct%Od)z@WRK>iPHiikr*Tcn$j8Hp1K(!8^xlOlXN-IAZjmY z2eXkx)!hWI#*p|hb6nFVM$%1iHWh?#7`9D7N%3^KrX&tXbZtqUB@EMMlvA}J{WMHI z#XK(xKFD72lX@90eA$jq@YQC&@4tMi8g~1{%#66l+b4S%_PJ1jXSJdSFhpqeBs5M~ zn)!zGo-nlAqR!u>WEu6-ufo(TLm4%@nFynUC3e{gtD**+cu5w|+D zpWPNuc_*&LQSGTy_W59R9;m?k9XjtV#f4Uc(!>Oh%qC{9nrO;#<#vrCQ^&a!4Pj!Wq)x?j;Vc_FIfUaun9t+CyZ+*Yqt(kaZ z12%d4(1OuoqP`19c#8^Yl$vF76sUqjzwgcBD-|3yd=1xA1*0lEH7)n*TVsxT+6G!d zHD6|#e%CFfo8SKIx}HlK7W=R065?E>UuMFE*FbM{Tqp1Kah&K5qko%um}V z;=2Lc#|TP+lzIja2B&93bS1#EGjyI9oMN%|YxFc6Pfo~he?~`Beui(^p9bhfi#MI( zC_1HcSZqkUEyY9Jwdfp#{F$OjRY|&S+|zn;?oOk6V;!wvpk^?76t_Gg;@tGwp~)VO zvBJfMkf9fD%$Cj$I_3o@6JI0WdntW$-g8iMMEc}xO7;!s$qDZ&mH|;B4pq0DZ1>=x z_2jWjl>X`wn2rfbV6G=%I$X|!nX-~3k3MX*j1#Jy7Y9vm9m!KFzf@wm{tq(TJNdj0 zFa?Vc&EW6yIewtzK?x5)=rlx!ZE+0CngLO2ih23G=s+mk zm~#?`@{M!(a!z5JO9)`xFVL{jmQd4AFh5$+NfZU&tDu&$3OGm)bl?7O+D}N-}G~Nk$yAhzv<@(@{jkXJvwjU4K@15dxMfV z{O3OtQ>6Usz3ZNy;eY-!m=0Rb`iu9rSL@(^{$ z-79m{YGLpv{>OiVC#7@w$9n_6G4?tClYBF3kK`Z!jU+3Y7xh=7d7(6TY`5nDAYhO{ zz+j{iV7__phhu`N|MlNVqA2>udvn^Jl3OtR^`9fgPLrsTAoluS@7+je61U&H_xd#6 zeDU6LRDJo!dxPm~$NblS&SRRS$7DK^*^d}-8z*oZM^m8kC^ldGx6?`YjQ=K|PsjU5 z`d|Ou>=gg=p3w?PEsrUP>-87ad|&pqK#b~ZeGqFo9j`z9Kaoo;bMHY%l8 z&F+0J5oFEIz|4B0i>AQn!kHeB|4ERdxh!z9O)g&=G~u*sW{uoL4NbzPt?yz=bBnio zS*tJAAtoKW{idi#WlXYe$Lz`%4_db9i^rhtCbV&1k}pgygL)oJVxS8K78}~}0_bT3 znnkpzx|Rqo(<2rTe7uwTlcI)!4(_^t`QWbJLd`<77hcvj4E+iMLjiG=In3E*CKQW` zsIhRJNncRzkY&d4XqScL;|sIsmi_CKXAc5)#g<Sv-3sW)5C>Zv70Ss&NQN+Ka^ilelhRJj%Rh z+FClYe~rz0qb~WM8tbe4PhaKp9mM}zh5lQG{#%9qTZR6+Lg>G5oBzqXC_+-TyAQSR7w9x~?|fsfwp)P;iGT1v9b~#Q z0IfM$lQQonZH$!awsR)AZiTkw7xki4 z$fVU$F+RhCS}4Xjd*k4Dsr^!??#1T#5v2+SaBJI|eDSw*JEs%u;&-H5`5MW;I1Cv@ zDSnxRYBEzx&1`};Nv4CQhu7Z+FPmy@P0|N*Qe=3BmnIU$iZ&DS8C{AulcBpG4aH*IccTU%G8?8Y){Id9fvyvd4^B{_Bwos)FTX=J%5btaf%snZNgYGr}y zS0<=g41&i7?fdH<(_z!FB$B&H?ftc|ZaW4@Pj)98;aTI>==^Z2L~-jWgFFF(he()} zLZQHC$Z>^V6!CUO4XtzB(=DLzP|({UloJEjYl}nmmtr?S|IM?TTlU9O{9y`0pLr1a zb%kE%G*HeQ4;%hy%rW{Yi-0M;#-(Lg7@1%A7}j;h&S}QqzgHtnJw6ZbXr_fD;WliJ zbp#UO7)Po?-jtR&J-E>Kmv|A0@|TY=fS&^ydjUY`LW_9pN-lRxr`$>yl;GbrueF>W zNF@8dl&wTmF+%E~uQX)Xy)BoH^%fzEf)aXr1p>TBA*FB?VF`(C;v_DV0?=KXgq(XL zsFSP=XM@U)4uK}GbP@$8eH={_F9|&$7v&}wdkas8o0&i`j+X^K2p6&5BX)NNDTsG({33kO~<8Q1@@)u{WsO;$cg}G5cD`cC+GqtlLPIQ`G^Wz)rNk{Fjt&N(( zJzrrxknwoydIhzKo35>$&=m02?aT~6HWTB)ApmzlQpEbNie}1Q;gqr4p6L^;{!x%9 zBHn;7fP#FjBzw=D0(n?tK{7WcmJMh3RPX(ym$DCyh}8gWv;J@Zf&uJUAw*VNU@TT@ zMY`@puMj!d=@VjeNwna-DI86c+d%$t!2f3Ka0>;7wNN%MyM>4Z6hhxn*n5{LfzZxW zsoV$)peOJ2c{)E_-_ug;$WNmQ9|CWow5#aQZmfon z&cqqww4)j!(#&eZ0_<*4=#)oV=5_$`Qa+Jgi+^FI`R^w?J4{nJVxcih*$l{qRBIY0 zdxEPwmjUs{%|!Xsc=~&^I-~7MIbr2 zL#VVlL1$%gwlRuAo>&|*F!Bj1bWn&PuD9hL8&NJ0O0Q2R|4V-09q8$)%i_MwrY0|r_EYk%g)l2 zUn!QJK^VCuw2@1ahn}+}F>u+Od1{Wuq$eL7QN(Xr7SRlZ73aeiP}>v@PH&!WssD zW*Jcv<>Ce8HVMP2(R|`6vZGN*n?)QoQ$O`7p?oY_Ib0T{2eRZXtzy;*Rnir#ax^;= zc5q@AN>fY1#tn+-FXuB_s!c2^#iR5-VkN(Ack@GnqW6fB`R@sl(NaP}?Bcb-Ofkhm z^{O#6C~F>|67qp@vA*U5MTLzQ8-AcW#+mx}lS&Bla~CfGnJw0mTUfLk79YKOqPB!3K_A{GAvKt$gTNn&Vk#h<`AGYLibjLBeBu!aVe?K_{MJPV3z)DY1kzkI1UA z=178bqp-7Re`8zAPVcl`#aPN%S3AceHME#uYxIPTM{{Uw9%)eu`b|ca!Z`@Th0>fX zFGZAyt(h(hmPk@)*Duik&q<17sS9DI1S+p}uWf|vXbAaYnfD7dR`g+hv%KsZ1^_Bep zH9p^1{$HhjUdjI}`F|z<{{`g#%uDRG#s=ME7YDxuI>PZ3ci+NsSz$o+QMZ_MOgnBS zpTw*|Kw&Lw3Xo*Ya;j!o*L0;(dQ?`gn%*HXov_DrmJ1R$G|9r{F&~`|Kq93MkZ??6 z%e?Ii@J*PI!}}`PMS!RgK()(M>Ut2?>g$b-&D(dbm&r2*Wz(#J?M@e^507STgiW) zD*r7P@eVldZDC$kXucg3l{V-$&9_iwIxW%ZI@a`SN{S4Zl;B>W;SgoF+p0n?cLR0z zF1t~@a?Q5*sy8N6U}=tL&lms@?Xj=O0E|D-?U0?A6q{4m*2sbw7MB`BS(30fnC8Lq zYfE}Wfe~XFz_R;ErcT{-d1e)F-ISsE`Px!)5njD@F-dq z5>5_9ZGTVt#j-)VRH@9hUm%*e+2Y%DFRwsHN#+(;d$iyJD)Z)-m>^BwpVbZk%xy=yjTQKC>68~P~-}9U3ZDD@? zhV`(-;&$pqwWAxLyAJls&9WZibph*+eywn9-SN9Gi;nBP8Gz%Lg7~|u=UuO&~^9+!9v4FFZQ9rD!Flg8G-_=I_c z@qrojwmvpnFX9o}G2buIXEw=eA6Z>oK<-(j&P8_&l{0Ble*nkH12uc*hRmy&C>6Lx zLZ{3J=dK$tvgu?t>SC}PN(Dcjz?MSEZ@f4&dHqa$qh4DNH#X_~C#bFT|F7}+yZUqsz~9y7ox1+6vef#& z!}Cwq?EkJlMYsRE`c&=y@9Jaq`@gGC)bRhVK3&KEyZSgS|L^LP^n7>hRicDXQ}+L^ zK3UyI5TB~>|6P5&%KvxusY*YM;8WCoSf`(+`2SrcRDYb=&!GKR4_`cdxc}SU;g+g) zRdt-de;@YRZa07b;lb{Yhj>f&2ugLU=)3=4h5NvdDqRI%=yg&3SE<^~Bdg#<$k!?9 z!c)q)dL0=L#>(Ubtkp5a-=l1>Z4fmu8(oai|BCrMEcY$d#u#+fV;h-I7l!xzO3HMP zPoPohjqQqkhw``d^?{cfA**mcSH0D);*#2tW5jMpEq5zz2(q?0JK0$ zzvw~9f1e(UWrBsi-#}(&9R!6O$`=?X-($ZggJ@bve{1Y_9qgG!(oFABP z@UHG_FIo@@~^&meq_GQ?Y9H{)zt6pJJoxp zl7Vw(+C1yoZ}w~7seWc!I1-I&uaHpb$sjS=Kn``{U&NMdu_=6zy52EPk{j78xTT!G#qryTOeBy z*`s`(7tj`NgL?I3cf!6*G^E!Y5u5!n9nZSQvOaOy?o+DpiOxblYE>gtcHRwLA9Jgn(9%I^!{)<8TDe#AvhA}V%j!@jS#eK zu8CY@(0mDWv`|a_y}>x-_Lnb(!3H9oH=X4lKREVB6CexQondvWUdJU z;4BLuAZGZLiJIdJU}(hkDYyj*i&G$`Sc_uOWHO$_O%P^glP;%6#cGN~wox<%s=FDh z>vL|SKN+8@eyw}GtfJ~s6*tlT^la#4I7s&#Vf}LzX#z<0+a6! zqc+|g6K0><+)CBo+vAtA7A-K_k#DWbtUg!&i2na2uYX;j|JT>UT7c*On{|x5yjes2 zKimvf`v2GXdcP4RjF@>@>9k~CIFn8Rq~9H=FUzWQ2LHA&sUT=nPO+wqYpMsH=NLs99s;?- zNzuRkmMf%gyWs;o2G!v3s{1m`<-9C|!)Ro?luIXJB)897nBFtOD{`Dqk-{kS#!+nb z$E=!VI(~x6nAL&yl`az@Ch-J*c&=ukjGjcp^QzK8_D=A`iyFamSBhs~2;+o(YbCUx zeF|kJuPZx}!O=S?n^Q1|yLSnLjNeS0XQ}*exTE`1j*UUg$`mYaaCO60-)FhDCiKQ9JILuEENp^I&QPz@P=D7O5GCl zD+_XvM^NT-XgY6d`oQ;`E@5raVYlqMExVpkw(gd#*|N1%*-)2cmjLOk#@DsEi^jUH z&X}=_;Y8Mg*+?XTRpyL$K;j2UHg&NYAEsA`T&q6if7+O1SEpt^NA=^BwtYMRXggVx z?d1r%daI-0aoS^ZEt{x`UC=-tKc~Cd(*6tgF}kLm8z?&6v8F_5A{TBbp9h-hATe-JLwL9Y;r-3aea)+DA7=M?UQm~fsSm=It& zj?2`soP=(r1I)EG-cU=n5~*wRP-3#C+G;yP+D+@|!k)=Oy^2#W__CwnQeJB|pV(AG5k7$!GF*S|Dn0K7O5*>Qi(cJ=^OG7Dy zV=tOm6k6;=@U0s_qlV=n|3y~Y!G}hlVSi{s9>B)$U3LZ39GHI@pUt;A_=nw_&Y^EW z3oiRkYzcL7JB3oj!{4U1siXrfqm9)NtmZOO5jeAVwiFUzxaEbYa5lY9!U#Hjy89=h zq=4PF4;N#Hc`g8|F(i(x!dtBYBu}!T)Lbx!)A1x4jJgF}qi<{QU-2XG>!V3pzbcMs zL;(E?2wOVN#lysr7B7Lui{`__0<1+?Mts7rwWb2|UVJ{KF zpc1|;D^#SlWOKr*ThZ|k*V|Fytbta&Ml2DKv`=<_Fo~yXIyjA-9Gs8P0{!%0ul4*V z^sG3{XW0TmW9PYMfeTUU-zcrrI)#l|gX!X|VJrvM^*v!32ps``0URHUE5g$nYT89} zLW-*+pd$_mfsKoWaTlp!G3^%)!w#u`+#8G8#b{iJM}tTYqQ2AMKi0zlBGbdb5((7u z>Rf`{i=iff+WQe7?A(Oe`iNO?9OnD8uQpNIPeRTlg}rb!>CAv?Z*irh1E-xxST&s2 z5vK;xvAE<8iH@0IRK6y(2;6DVRD1=GBlvT$GFJ~gp~>aAZ6OO~PW%N_Ge;)uf_s}{ zX>_o3+_sd8PD85KbO^V%nke)(VDER3p;^60+_<{~;>RuoKjfMrf4&Iu*51chTf>Ra z^hKQrH!j@?v$=d+cXV&uj#$P(R?XfxpAHt61cnnODFH%>mF+MIP3B?K>fPPbv(K+) zX#!>yDzGY4(9ApWJlHT~)RI?@Rw7+`uy^mpk4!aqQ;DtyT|@1GHV{PDz1dOWI=UHk zfodZ@7bpGVcZOTxn`OauZ4h~7;BcmmWpJoOCk02(4R@=utzJ2s)_@e7z}0d{%0bcK z6)84>tL2cAqu(WW0F)itc(Dh+bX-*)&HEg3`=NO~P zOV%QDAsmpbr=keM90FIWuzZifDycRNR>KjKElM=3_G+;_ZMk*LnOdPh49JtV$m*sS zy7fW+K{P+p22}&i$PQ?QJHsq*i!dygDLN zqx-bMe0t|)kvkJ`2})bg!}QF5R!X~Ks|jtA8)Q`x+4h@urQ)fI?X;@MXTbSRE&Kcl zSZn0)ZkA6=Q6~T9S4%f=>FIHYnWa745^2 z9)|o-Gv-Bmr{Q)q6Sy&ENeS1^VbHjhV~Pww`vAn9TF>3I(JHDlD-fZTB1hg#E`D(Z zPZ0@hcs9Hn~KoON6#Ws7vU@C_JtA zx;@0=#M=HoBVVdsV7`T(w7TGos@E%HhGnLF@fYj$G~Ywnl`gYu_Ge0zO$nA^DWgz! z7HQ4$s8@%xUN0KiL`61>v(^saXAi(ycMdvXch7!4AK%RNsy#$@f+rKT*!j{EVV~$3 zV@fd7<`xXyf|^Yy`DEh6Pq6GftvM{%S_pVuKre5ohm&@7;@*9}6bW;ShCR+RO z63B$I2H_-^F$hNYSiOl9JOTN^F#)EhrbpSL(LJod6pJfJN59cCx_|Ex_UApXuhaM> z3?03}urAC@yAYbOCwOoyn2ha(ZR5SrF^uzL+^J0b^Yfx-IA;aqT(5eUALrhZ(a%X4 zD<(5tX&DWp3Sw;!l!?e3*A^)Hk~W$EE2(L{)7=8RUh@%*H2n5z4g1+n=~!GJV0*K1 z73^ta<%uF^C2gWiqLZVrohzR1Qh8{54|Y@@7jXYDv< zuV!HOuI!dYTc;zul=BFm}39@wTFuum(YWWPqqk@O6S__bbo3Xg6RvDn0)mfbsS)-k426X_Nb zu%C*Ae9>?`ZmiLH>}~cp{Ul_z(X+?oWj)3 zUhN83uWgu3V^`gCw$qEDwg-+BidD_l|`Vh0+gY7_BJ1{wjK;Hi~_fG+5Y1nTR$Pb7j^YCI_;jFo4%IO0lg^2p~Ls3!{jdCG8Y!G^G;24 zy@uj|KmLa2#CZyiHwwO_MdO+LLFO(&Y{^5VC*qyj%icUoKl+)K{_5X z#IDUvD-akRgrIQvt?x6gK3Dtj{a+nQ;LEgeLHw_vR^OobUz=gL8LS5s|GU15|NT`y z!n#_mcs8<8`s1j@VHSU$o}Wc_YgAmIS7@~c_1ho{Vk80cXnuR6wXt5z0Mj2&s6uN9 zT6jzE``+edFVva17S~tY#2E0&^^Yk5)EDW@m-_rk*Z-&A|4&`$ z-{cGZWen~guI}`&?)0zj^#2Fk>Hj=e`k&*X9-N*HDGPlJYd@YMeeFIz+*kK+#uD@j zgUiboB>7l=;HCcYDUjNLGi#E2(Lbue5tV{3KdPg_Ya(H!*JD^jQHAgM4~@#l4W(w-c}7*0UTUHVl#?Ljqq<35Apsb?5(iXeC=3CkriQ0Lyg zBLlw|+rab$-hbftY?T7l?r_t zD4Qpb#}ioh@GP{?9z-Mkv}T{~kNOyzFM_9ar+)h}JXrT0pm7u)Hr!So6Yqeh8}{k5 zXo?16c(_ScFGLCs7dk%cPV<=U;+h`s9GKOy-)XbRS#vOFn9d{x; z_0UGWc06TM9ZVMjbm@Yt6-sBc;EJ>(77Bpe5}&D~SEn3+BfZE$`^jJ=XYU|I%jr8H z;mDSN&F^el)`?a?6vu!U8RU2mrAFhlgiZXu{*sQ2<5?esyaCFXxXJwiY^W(hJI3vY zy)p)Y8nFo*B}Vi|*s&%o&I6Or@whlXrl#Y;ks9A1o>*#O7yJS1@fR&eZ@PfjUBLB)fI}B>V2@7R^iA_Vp{(#im1Y`S zbZ%gs_FSGkFT2;bkfwp813Ivw!=_5OQNLZUY^<+^WmT_jZfwxOHavrWH`ei-u8jW= z_<~obvIF&@`V9obXPvw_w$1YB7)Rw8&4Y(y%fd#~oRMrvW*TGFR@Y8vLoKLNKr6 zO_epZQJ0iiast{iXQ8doe5;vnb@OdKAvhg8Xfa_bA<)k&>ZK*RPY~r?wrcvFtgVOh zvl&iW47P***&Fm{V>1_Xmbwe8=E4eHSPPiR&!3H%gmm~S+ys7Pu@iXw>HK8i@e}+U zEMzL=lj2trM-O^kb6$rpJx(M~6I@50))O42;5V@;fkqCBsoUcz&cd!JSL7}7t!BQ} zUy?`9#XKkB0+Y%84C>x*Yk&5X7f&Y7%IeqG;$vZ0yDB5I?8)U93oIbAlJ0}NI7Rik zOJ5v$9+OF*O(&d#%y1_bo?9(bOr&YbPv||uGMaY~DiUo{gQ?ai09xMG1pm`s}Lp1`s`d6Sp*^rw?2AUOY6F1+Zqur?YuLyjYK93XFEz0u~Rj z3qah3K9V{=E+#nWg2K|j_wQAruHVsC_iQ+e@xOdDpGKfyU%!9d`cHuZ&QDpkC5FOs zDsKfO)!IKL{Z}*%5_bgx395L5(gDIQ3Ml5Ronp~iH4YB$ z?LR*>Ao!=+NLo=|U=|RkANcJbg@lk;b&xW2YHbo2*yteU10`&sQzrQS2 z+kDg9M{rj=?6{1QJ4U4+{z{RT%70fYc;H ziB{5xwzb$*o$jV5o>{=I=dP6zxU+@6&i3m{v}e%RY%0!m0H&;i?$UTZsVJvo zYwV)8vu)|i_SPXeeU-5wA?+yR>bbezl?^^Q64Uufvh(n*EPeNeYiqCZl`n6sGF0{* zbcR?~G(9*LG_hHLCM0gjYbEe!TRbt(`Z(Qe;w;H*mnN^z3`@4&g=6BM{mRam_%N2j zwnpYE2fd0gYyye$c){e^F>o^Fo1J>HU0i#Ek1N>EYQ_^pG{Y9u&N%^>Xim5>a}2f!~OlW^z$%V zKQ{_`kW|o@D&2uqx@*B=rTgP_?$4=PhpujYN#*)$DAK^b8_U#aO~OBoq3M=$4rk8h z>Gku;ES_e)780iexBHaT3WxekAN0Wl;mr{HTRj|3`FJjF`bDqd=JxKN$i)V@s!Omo zs(4m|L>}6+!)*f%-%t^u<*@l7`(W;Z-o11C7dBP=W-#p@7YhC8D4J5c1yn#VxfciD zf4J9r{^Zx)XAk~w@7a^BoKrh!Di)8u!Y`g;VXt5N{B6npW=5~hb_SS%Fak`iigatnw04w zz!-riMd4V?0w~s3{U!cgFHt<~{+r%PR}=W*(G@7Bw~m{s#}YJ~I0lUf={Kpf zdfXg83Mk@K57ixquJK+EdW}!A_;T)`=nj|vdKuUgL7AO}&|%JE)&UDexHjy!kQWCQ zM87b6fbkFm&7W#vY8mfL+$DAIV1H^? z6M!>Is*Gazg5AS+6G3?nSBP~R;l*g)@2G@x2T+MfAha}{-NW_wSW^jKkBaA+;Dy5Mj8;WjEf=Ch1cgC}ov0_eTRoqUl_MM&j zOCeW^N&%e+&BEbT3|&4g>WHOOt1zhCE@Dk2;8&$}2H@8>)SKuZ&dZh)a1j~bsYIib zR;QXVI2?|;QaHJ>S%l_rso&OX5vxpz`DG15R;BK_hG-Vvt73LFR+j1NuxUxSpR?Q< zCgBjuQ1vZY`#hVW=4=EW{T<+Wg4^jOzi`^^9aRlsD{pz(X$j-T4+xFI%1#Wm$%9uS z*b#bB8ix(zls60t8P5xGrWCYkgvaVN6h0sskc{;7UGV^rGTd8; zOkM*P6Z`ADC2rc8=87@;uVH=o3;#cbf7@q8YlOhqGVrwN*fYeJifT2LcsD^UYu|7x zyM@cj8b0`tkqc6*7LIER5vc$qcEBM!R4KL<;O^}B^=aQa?chhqfiL(d#wRf`;{$8g8aq_7^Lhw#|aIc@CIx1cr+5xmZL{ndz?#z^xxb*eLQySlEkP||Z5r%;7 z0RQPv@rL#=8kI%BAub31U|VQ7Dl7i>X3(1+>+T#(PtRZkgEO>wkhfcW+|2NRYo=V~ zmh8o1HPLaf9X+d(4(pJu&g9ttaSkYW<2sh6iep*VdPC;nUx)qx{5XGP4$p1ymoodFMUucP)%`NohQt>VWRD;RjpJ zw%P-x*0k?#{^RCWO3;Viw`aqtydXQh?94z4Q&8OmLRvJ=0Tpcn(QFf$Y$KJxpV2nb z#x_yLHvJ)**e08bc;;-Yo>>ezq-VqcEY>{!9gfE&O6hR|K_-XFqftB>{;?)Q6RQ{2 zYFgOGo(qUBk&SO z)BS#bMX=RBy!mV_hSr5k9JyBaau#cTDqB*4xLKjWKv5bXJ zMQTgS9^Bko;H9RyO3tD0M3JQ5u=a1$qeE=r26^)ji=eeNS`s-A?$37Jt=CsXFv+LPlQBO$2m}y&w z!?*>4R(uiw$c1EKrJ8OwUfyi1YkhE;Yv9lVDn_k=GvtBGEP9t6|3bo{ew=)n(Z|P2 zTP0z|8GRy%bQWo1waUOypkRlaLvf3E9>1Oql`&z7IcOUN4A=y*q}~OSOGj@C0);FY zv%Xzq*JeX0$-9u0Guc{5`CxaB*^p&GJ?2tOQag9%cj#Y*UYCrSP_H!R@-%=~MZI7| z!NC=UR#dN3*cIFZXe$SNjcH4uDt9r#g~t^f`$2&hHG(aA_E2(lAl=i{&Y7}CGvspG z3T4Vr6koS%+nC`bvxJ>^6ac*DlNFH{z$S**jL60v%;oGV-3u)0{APSsDm);I4+D~a z!W80zQl%1`&Qi@7umI@R)2P8QK2q?MhUbfS&QPUd0^LM-mMdqWAkpE}xRV24($yp= z;x%#05q&f@+CBe5aAxRstcf9bttPr}J1-sK<+*6~JW%Pm%bL234P>On#IrPmD>-}X zwZWMHrjj>M^=g_ePSgxKPX~ExBBJqyT)9-Bi$(-eFR8^mxO73ent@7+pAT0vSzC<} zaOO!Yo@5ORZ8YXnI9Y03Wv&GmkER7t{Ux^%9Nm!WgH31 zllus1ab&7#6q!ReGZcE0)g)df!3}kJ%Na5$S;3RZPN?uo#2Ng***1ZFfIo=jta^Jl`P1glZ9szye? zxM=VfTNn;!B5~B(`aFBHZp)yMyY8Uy(nELCh`L*uOEbwH+YUSZ^}Fl#)^Fl-?}Inp4?wU)t&Gf!W4Ra*=Ai>RDe!tpCzvxD~WEQTlr*a`}N5w~0uZ%H- zcx(+op-Ks$_|q~nU$oU#Fkx_kU2thlL#G?i>2=*hQ1mD$*U{j06ss^$llJtO9H-hN z3?FR_EguqN*in^r+%ODJWuL5s8OP;=$xX|l1>JcVvRfi!-8l=-L0-$6^FQci{~Ft? zIp`8gnJ~F-F$-_Z&>TG|GN74XL@x8#`|~pobbnv5kG~H4V1oU4!MWgx%IG1Vwhk{B zkg1+8K=_3$Cm}IGWRaq?KIpNmLY4wZ#s~x34orfhWU#1>wy< zzH@}{r0iWWHh9r=D(()Dve00aHL0R)LAA2t6YnOUdf(Oi3>t>;T?t=0&dlVy z_il>NtY_{&nv*B)XXxu#_Rth9t@@hRbu9%1DS62iHXRO=(Zu8SV;?#^xEf$BiR#NO ziD97?$sAaU5b2Asav1>Yc`kASr1Qp_M>=#rg*RYWzU;~B9D2fgpViUwr>BmHNe?Rn zZF1q|3J+-uvfIVlTIWsER&jTrw2{Tzhv^H3{LuKm=3lwF)cy?P{>a@qyzKVu$pT@~ z+eqb$yMccGUCr=c{2_D+|T_^6|}G?F3{_x zK`57ZoZbq6q=CiTo4s1 zwct1_B#omoL$+JKfRdaaml!r2^y2DYEMG8hsC4v3csbc3B$P5l?wsXts z;Y@k3R0o=`k+xW=blzmi5m=j~2vxGjz3}W~r3go6aMJ{(TyYc5ss!U7p14T9q<4|U zJMECiw3a+QTN``4lbbAnEE#WHa>Qjfcnm-waaI!t=|z2#{=vGz-@{-Q7^NbgCm;5w ziyhc;t3}80Vjg$hUUz7((33Ww&$%Azd>;#2V^?%^t}!0q)apyA5>MNcDeT}l`{Y%a zdHm@}0qFOhbZW0wt8|C`)4D)@`Ht?|uVP38r6WjT2dnG{&E7)zivj{5j@Ja4bVDf> z@qqU$igi$scvLntl@kPk$)235&3%Fbw^LTXl5hVF=l%dvg+wACH~fB8=H3ksl1v-Q zv2J*yp!TzZvn=SsSwFK666E6IKIC#sfIrNH%|Rvzv|vu)!ps3sA)REnB|nP9;g^dd zfoSAqQ@H-m(Y+TxUQ^hb>b8f&sCVt3qw93z18d=m#=Da3I99LE=oy9A*YTS0%4K{! z!}wn9qtQ5q0bqEpJ~NYOKA0A24L87q4rhW(_i)MOlO=06mU|}`uAS6kUF4~7=|!yD z|Jc=h!P@1Oiq_r)xj~bMS(LVvo)EX@Wn^E1S3dNS%wejofPU%Q$D{va znd!r;^HGW!=rAlD@$VtUX-hNPt8v?_vD+p5*5*mh=D5_YhgsbAitKg?zfJWa$1L}1 zJlAEq553!V4rma2aAJr#z57;U{enZikRSZA?80Acn^FGiUviZ%iyJPuuxFN`^voYG zvAzX-&UC-Or27w@?rSz?dzC$g#VjRz3@HYZ$>djzW5qcBWMf^*IVcdOS(lmbVrF zf!O#4anl4?JaD72(bC3uUiiJ3f6S^easx829Vj<+Ta5NKs>>vVZ#5{ku43jo(I>F} zfwub43)I^s<{gjZ$0xqXgRQMG1}gN%w|(vs=riV{xJXBILh3<+4Z8EkO0B{SS0wa!^5TQ>QZ zQp(JRXh_1B%P*~!jr`{l2KHmrwI!scH3!q{gp@RFs;VE`=hb{7U2H7~8me>d75YNyVKMD#{v*@FDxDrS|8ePIRU$oX{*vio z)$;VP`3us+s!ODY%}<@_Gbv)R?e1(ck;JipC~PA-JsXbCfjuifYi#~TE-F@-=rzg+8RpwZw_8;dHsbig9+4Qm4?EM$do=H+!Org5>OzlB~PyToB z8D^Bt`x#}`l{3ob_0NyYD4Umzvg(^=l%*NU+l;cGDW&YwVTA4`G3{;Tpg6x z)#W;>&^tX+ur}J=Qw*I0bbLe!WhuGqb$oLj_wvyZkUakQf7fX}U8lnK6@bN1e$||A zeliB;ajHm`K0QO$^v7%vO)(lSC6~ZN6XRLz=8P>+&d+j=vsCDG8rT{vg5&mC?74#I zBo}(U#^>=gI@Pruh84*xT(+_53`XtAImJp=g{Pa1^`e5FOpi|^;4@XJ{di2Q6vjIq z>FPIQI|6kIm;*-8rg%XhuR*u)@pvQv+8Ck~SO-^yRfD?)wP_neRch30PkJ$Tq^zFa zhVGc*6SrZuaITKWZ!{}`#%6=~*l$|$e^L(x0(3ntTb|mBfF%tH@5qw7lW`nN|Ke(n zIw&*M(^!BJNpex#OrlYD+~aiFa!|-=NOb;DVxu{!Ya$`lYm}P=)GZ(=Z>shDw_}wEyTpwHf}f1Kk#748NTaQ$utAh@{xLT<{&{+zMmQKE zE5|nWp;JS3|LKdECR?f>w|gYbj{60#6L>5P4ebJ?c-B33V8NUWhkD-3UflaZj@Z4d zn|CSeX7zZ-$#z3DK?ycZo)pS)qO+u6FTAWLHrb;fgNhJ3Z3c&*c7NGxAtw04B*8XEWK2j4;+tWN^O~Yfw@^aWpWsxXr!pYw5tak-mjy-U^wvGItF*Q zippTSiYM-!Dt1-$nd>HxM(gLtumc72e+=hjd;$D)2^K0g2);ExG*4-~=0JuQ^-wZeEe+$EKGpN-Y8=E!M|LgFN z`a<3LGM|9*&PdKKnw(fIK>Pf21)WuZ;of zK#v@!27j<}YPaqio^1XI#3k9WBChIz_6)>D%&j*Rue~Si|t`x6~bxr_ePW8aiih zWy~ab-h^M25e=YVWLG2hK5chTTJ;*pmw38J3C{{AD42CBJ9E|&a8UU3O)utyGcA!i zHP*sp9WU9iu3VrJp_Gv1zdICp94NMDp@MU2^O*R!bWv!6gfwg%-a*> z>zO2nidxZ7Cj7z~*EHljHuT^U$qUtkS3ON5CosG4o3m>6UblyZ8@)D~1Uj`IHgw~p zja`&C9sQ<*Z|DjRQqD=65@rGtUL2rbf2q*s>8mK7N2@dK-+RQ9bYjmW-;5`{fZJW$ zrZ<>pq_j6bYn{d?bnMDCZh)3TZsNA1B}s95;>?Vs?9@R>HTcd|!FN*N1aec}tl-F_ma^K7I)LP3!(od-wmx7#gPC<7`%SR#sDe>|VlOrD-bYM4#b7{k=!3_r=&~oBdGhiB7LAW6BD9xNjPHf6t;HOBc-M(N{C|8?po@69 z*}jR(WA~<>oGxB(>QMnlE2Bf{_)HGjL%Wp1rk`riMH43+B(Ib-l2BNq%X3{ik%d{3 zR4rZR;iIN65U3la2xGsiVqhJh$QH9eW zoy5ljyr#sXN9K;~GR>;zSQW3c@p^3PiNeb+bBYvH>QZ#k(j0H<3QdgOFhH&Woq?b5 z>;^T4yv~3vz~c&bw}`t3!o+{qBy!{7bUeZI9Eerq<@lHFF63?TCiFUBO;h^b_FdI= z`=}jGUa&DSHHjeVw#FmmQ71)bx;TBX9-I_1uX)l=lGKhHHV)jl^RpvxDnA6iCiXAm4-bOLFDwTP%_Mg!*@}Kb$ z`wyDp!|L&uY2yO>Poq(9{4EUYL1VKKZmb7r|5@Ltuk1fx^})xKefcD(=*4j8E@P=&I>#XLrcXQTBVaHrUA$qx1!9w$%AjY z?FdVc!l4YNH-U=`Cm@raD-E=)Olns=KZoK`^{84#TY2|v7|j`ShDfV>**e_+zrEIT zdnzrzQ|IQCa-2L@?J<|s*?oMtkIBFaMaSy(x;<%6j$$-=>9+2JZf7dt57PGRp&8vL zNWh#sAOS4^aydj+!`x#yFV`(kSEk2nG@nKwf?mIW-9|Ih4{`89V%#&js#9`3cuVZP z3p$8X=c!xeg0hDmd?|KOol#aLo~EUh5lxEkP^5d8XhdIgS~7BRQ%+WlFC5aMikBak z10it}Mga1qDti~k$3dZV*6+;vEozUi$~bL0{bIue7fwOx_kn_r@wtnnqP0?S0Yj?e zVXx)X(Qnxs#r*VF89#NJa_Kus%+~ayp=w8Z{?+$?#{SPUxm?4)UMC8_Hl=kgK%T3o z{!>jg4--wv)Dp8oM*gVXeRB94@i7fw7fF{8*oHpr1p)m=zex6xXjn8**{=Yi;Unz?#W$`~lS^P}e;`ey+k7sFVMND>9x*vO1R(uqj zIP5oPXiXM3OKttdoEd2_i4%Y4^i68&FWwQ7Tve7-yJ}m#Q(;&ytFRJo)Nj`-@B?Eq z*K3;_8~!8s|KYy+puGa3`PuK3o>(7)+~c2eGCXxI#X8nu+<{9IUWC8fCa|&=ky-FQm^>%=pKeQ zE!=aClJ22@E}fEa^+#AewADkdPENczQ(u0%r^k{MXZxOFw}B!etVm zT(~M>$x=V`1;E}C0nn{zzK0ixfen@dgIc}PAc3zItZ%r#KS}^h%5`BI)O{Ul^>f z;(vUV&r1GV$$u;PZzcb&E7Y2*NaB27bECle>i@VZ6FLbv}ou` zh45I!!VslGar|ChKP6gPAOQnm_w7%RFhA9D*!yfE=JzFIdWCAKLbY_EdaBTOV5MAr zzSPH+|NGy_{@X~O|8If>t-eTSzSL(W|F7i#mHfYw|5x(=O8!sD|NYC0{~X3ETl()W z5&oTe`s+o;-`YA!=(WvCZ5`!tRcov}KR=7^507STgiW4QvL%m zCjjvUxm7~WIZMcbL13l9s7c~l392+Xux$w{+K3{hd+A&F0JPeIQ8KS(1;f`P=lH-E<-^;`o z#>~*d-L(RgzF~8cNAq@fDgiI<{chsEYQc=s2D`d0!Vyz7Kk zmW2*b+^T!Xs0%n6imo%l5kNO9J0lG1LQg32Ne6mZ5BYaUakM&^goSb!^YiR@DV+NS zhnXDYa4bQp0KIyM)E3a>BtjMs-74x>9$xil(UgLMIC<77?>DE8;&kCKgqY6;X8LSE z=NayVCh(S|1m-8uX?zwQVALa-TuKxbVvG=-(0x2PZ4Y5wPQ$j`jcxUBd0~zu_$_51 z!m)ObqpoBt{*brTJj|%~Dhb6tGA&}w_g>B8fi3nR8c|oNXh!QF1hY7HRA(?Q3p~Qi zKQy^FZYT#WH!NC;4xZQ6B21o5=#Ea?94tkM(DbVhn<$7c@BNAN>r$7Q zbv;I>N7;Q2_1rI?Ob=%lOy~zE379$U5MtKgqod2xuf~$}lNLf8Oqaa!Buef?7rdz33y>TLSYsE-?meQrCD61}~ecQW@C%;@1Wy)3?`UBDM@ zTtLXz7S6px9*91Jzrjd%Xfe;Q{ay1rT=6l^owV7|{Tdow*|q$IoJD7bz=Sl0sdZzy z+IvaYg^A>&Fh#5uds~uI4r%sZK7$6zE$ZaZXUr<0lTG;@zBC(nO*UPar z!rhv3{0$%JC`@KpPAiE_02}&zH3S%sl$$wu|{yX?g0^q@)NCN!GATXaS{vCXx{CDt`1i5vgus;$xDo>Y)Iy*WiTvT- z<6l}oIYHn1(dacLJNKhH1HxJdPwwv?>^U$&3~CP}g6Nl~q~p7oB;9R`o*rTq8($q| zK<9?9#9jtQa1M(rM)V=u?zg*BX4|!Yg~0}{YFz})QOD8nEQa;2+9XoO(R8XK?VH1X z#o6Bb!}bw897WwIj@y&L@Vu(j{#3yn^=L}ku;`&Kapv|2nHRGjoIPk?BoKrqvMLL@ za*x^c>Lp(;jzDlN<3IHp{X@bmJgnU=gJg9FlM3ItQ){emt_SdMwUl}iRceh56vCPr z;p8dT`gk;+v>qNjZ#{eR;_-t+jl%or1>ik5@#&K5j`Z9QuQb>%Ck(lhoY<$$|0H!;g2L6Hlw$sC(J^G1WZ}4vn zPcYeA)IFQRKj`^~lcAt=1S&*C571@sRT=dJOi;D!qG0nICNWcYNNuzkC0uy?l;`2lyJC zwufh9guktL?RUqc*M(wbM_#t*t>{>sK$7$!_)>7|+g$Ex*iEAarr))??e1}8OPFSi zyJd{IztUC2;f3BV?>T!&r6Hg;$ies@!It{uenEy62b86*s2!2uarf*z0|3wrXWh&# z=%aPo@)0N1;7wu*q(5=cv;p1|lSgSeQ0s$NcEUfrbAs4&YoP_6Xh?MN~jq#Dd7 zkA2Zh!w}^2$t<2G3cpk1(GcW6ZkA+SXwNA#i9qZ;S8v9XllU5CsyEDN+hIpSI{=c# z;TFP$7sGzpJudX4qi8z8R|TFL#raDf?zNsjf&Kl#|Lr|{vgK9=9;IEw`2TEOezaP7o{RDsmczhI9!uPJXF1NbSFXk<{f)t+qRudY-3{EwrzW2 z+qUhAZQK05d7jRg*HHV=S)0LTE7wKZ;;3{@SZZr985LFX>d3_Ol~%<1GO7k zAd-gO(y4|`<+oJb%Gf46@RDZ?+|C{4j!Q0lWyuDAQNO1~^*lueP6ch9vazTDjqAXI zKDC(T5MMFivUkhIdWWtoubQQMEAK%U_ddaLeU@@?T0V`CXnrLpWkTg58InRRrerN; z4FIE^>^BD*$Tg}Yp}nn_owRWTIa4=^?Ia%s6}F~xu$MMIU6Y;&Di>$SR4tZv71|xG zXbHdZRvbM4poxW@y4;iti$^=mG+68&e)Ue`gg0p;^VMMTr(b8XC?{`xRF7X}FCI3v zm_kLG!=Q*y>U(Rht07$DHQ`?ZBo^Y6{Vq~xfle37TpDy?7K@iy1FIQW85Dz51Z7Ew zY5PSu?!>_Sb~-H@xj-EVTWW!gzr~sPK6vn&L22dWy$>C^_Uf)#kC43@%lkSTTd{ap z|2FF0Y7`O1yGR-A@mXME%rW5maaw~wAZiAh?ndCQKy&i)K>h^(V!{(Vf?=1UBTl_9 zkRBtTgd7}^QDS(oN%IR!1K}g-j>^$Ay=R{F*sucZy&b!SLL4azoWw;+ZS2lU4X(0d zla5H~5~*cz=uzCElOO?_ZBuY24o0LZN)zCV{G5=Bx4OM(jCS=Qb*S*S92-mNpPP<( zXS3H{Sl6uYYnZs12Gtza@1hRn7lKxCXeWUxd;J23?t9HIo$?J^?QaZD)} zR$@Vr3LRaLeImplvPW}|rVChT4oI1`_mgkg&UR%>w`9SZxc8MP)52Pn;O{nQt;kR~ z@Q_J!WDbo}QSBVN=MU$xy{=!=S{|pi6Q10Biou;c_g(r zTY;7X#I+`Sl+*gMa?}%oBF1zAlJI`FRJlh+r{_?3pdt=zm_TggC!-k3%8iW=dqOPmn_0 z;eiV32K`tG*3cGPIpT_)YxzBn(>`-;FvPqXxj9zeh<&Iy8^pOsOnG$cJ5Ge;Mp~SC4^V=NuT67hFKFQUf^Z#(LIqIm+@poPLb^8i6IzK zXo8!=CuaWM|HG2y*0#ZZO{KObOPN*f|DEY?UQGXdL8TZ}2bVJr*h2$Pq4KbOvV& zbhb?A%`@Z&+i)e*G7=eP)Sep7V1I-nLBr8$ClWH7sAWR1+ykN6F~A*0)xVz0cz`By z#qLzPv1UX0R(Iq{h+WyDOU##UV#;|DVX$KC0VKdcsR)GboKgD~sBKT#d8z4eR%h^Q zX~EaOk))7eoqzRU8;Hx^(u&Vp)L}PMpqMI`Ho8|R0`s~##zMBU(0t5|+cjI(C*%oi zH{$BTcmF)uKgv+K1C(~zS0fFlm)ukHTBu&CL>X*!Vl z<5AJ-NX&3)$FjD_)?4bwfxM#naWR$HdlP=1w>I|kt$#H`er55`ld6BmjrmXZ^P^pvmE{- zK4NC|P=n3i18Hm2s2Q)*sxZi#G?@cjEq2pC>E)Rw*J6==sqBCEW)y;KnEiDcN@B=7 zm1Od*pyF44RDQmt6Fyq+)bP>wB=#?9eu zZumBQJ`Z$R>eDvu;%w!XP=5i=OECnln}1&B_MDEH&deT7lnB_(o><|Vc-Hx>oOrz! z@}7*c1La31TRs|CubGNM!QC936aQd#+i!orczO=tp9L*c*+wMx576dnkc!i7X@M|9 z&nu`yl*vTIlu*R}^#M`Uv-q

pwSGR?|#&!iAXpb@W&G!JijfFYpwO*Q^$$yU_Vh zmCGwCwo8&@xWSgh91pHS7M)h@s=rh)KKl|4Yl>9<90dJt23pTEj!d+PfvQ~Go9p1uA8|A%O#H+1os}a@Cp``+pHIqxH_AoKDYUh=~fyrG*nOa4dJX>iDu2Vh-L!E zaXAaQKP|g;u2z$Qs*2s3(PA=(Je!0pt+}mGs(m~8-BPlcr82Cpww`#O8`MckaW3?2 z$eY0$bjR5mkZsDKLFzD_JcqJxdD3h-Zt^<$aV-ICG4`VgN<27eyp$m_%1BOFMQ45v zX`++lNUW##!GFSqNEt4=ZC{G9k0p1miR7=SKq0E`#exf~;E7%*sm@L)IFE8`WT{NE z@LV7<$}y!?GDqeXqdJBI6ICtGn?=0+gNkL)-w(6~oYn-r>|d$b;|+73hZzk)!b@^v zLlhL-hPnRfNow>h4JTo38ex?UlG(mGTdpo9PI?bZRgfJ$lba+ zf5h|DYM6Af-`t4L|H7PrV~p$q!pjgXOUxpmflT!Sqs!#bd9H%Pzk{ebmxVg*STI{I zrh*Ob=JfGY5+QdLg%wA0w3?{It2MG2>)xQTsl=+rU};Phy3TQ!_i6~Pds&-!le`(q z6jlLk_JUr)*RdALH&~qV@?iu$O}%ddD;qWD7ZW!wfs1kRcB0yyy&VDx@t)UoRS3M^ zJUVQ1y+4nTwc-uxX0S__g{*9B!u zoC!ecs zJA`TrXTcHVmj8mO@&-*^5M`#pcm|(rCZ4)t5nC-e$*g=OeQO^h~$T*;CfaeH8j zG2si$DHde@n$>o=%5;t>hz&TU6u2wd(1Fd_t>-eUzduV40rBIJ7xjM_F<9>lIW9IOwM$;cZoPy6F^YbpB^`ERMGEUsgwxxZjoHmgn^LCS_X?w6PS?}{T(|o$ zMhIo@b>ify>7!gZ4+w~T} zafXs?z^6-E7W8r|u13eL8Q4oJOU0EwB7ay%QX9KxAW&w@Iyc+Os0s#^|5#bRhME|w zanuAK|DXsS=Acc38QRbY+W5lo{K_!{da_TKa{AdGmW6;}{*sn&mLfTx8y200QZJ=^ zf^GG zFAM3gsb-U$K-@$2VXA$!-^!c3H*!cQ>Wg*W$#E__6Y-6n1z<@<9;VQh85tio;240V z=0-y<{caDjg-=5XN`>W=O!WlspBPh3qJ%JTiEwvW8(~NUV-5zQJBsu>H}+osQL0A& zq2$;Vzzp2ncBM+}VB@7=uIjSLt(0T+K@lw^rE8z8t@Do-(sh64`1xN#wrpwu?cu|k z_5B+SH);3R4TdIq1U*g2LpI*1K1|@Qni9PeZIq~Z@bxalQqJE8rQl-Afg+qZ|0(6F zqvs8_uxlMUT!EWup615FdXt34obFTOO?MQ9r60DfQqtXiL4+-&@ooMClV{!vCc8`b$l1SYn zu#Ou%$M$L4&7E7P)>5UX$Mw~lp!p^wMveK_4%k;pd` zs-w6Egc9fB(UIzbc-`ZS|AH7j>QkFQ!}c-ENwINBgK3wk!Vl8+mhvWbdUc4Wq~ zyNhCdq~oqH{oi)(Rryx{*J5$L5V&5=>U)O}xT0xGvue-De`z^c^y?gwF~O0^w@?)c ze6cMI?H`cPHZeb9*6(s!qI`hRvyt7I*74oFtBGx)ToM zEjcVyy&0T?4kK13(-y;ANW+qMI@Upk*sUE61_6@6_DSKlWG#)}`}Dzgmh~O;T+jMH zg1^+B)W7+<1AfBR;Me`wEmEC4Xa%KK1x{*3rpA#EvL+I#Gh8++twG#QA}lRRHNse^4du-9CsymJhj%mYQLfPgzjoZ@g-oA1NM7y&FRa zv2%&*+nffw_?t4}2j8(_phAG)}~ATI;zzX=F1C(6QOPc zflb(OD#kl2cVf5Ere+)8>I0LRYL*S4x><0`F3x`B;AagwX2i}no{C8Jmz@;)FAj>s z0ptVN-2D?4JcL5%5&y{HSxA!pe#_xoUqRs7!gKK~(M7HFikh8#gk|K3GWJvS++$A3 zsGNC3WW+?F`pRmkp766gtYIFDGy=XC@yk!bX0gC|<99$Int~(l`i08!iQbN?s|Gz1 zFn0(lJ1A?325e@+030Yf2cB7{Cd<0S0^L6wblrTnRF zmkhw$G5Fk>p0-EPwf}xur~bbAkM-c49}|oaVigEb?f(Rz92DpzWhf-UzvfJ$CJ(A$ zuX~QB0;A&Jq8h~)W^TI&4(a+?)!C8qsj4gdoGy>DcjRKD#XN$qT?oUHSBTyml2ESU z9yD0?+{OuaI`kXKl!5fI9-+>36_M^x1y+>YWTN)tvx{k{uAN3GES6Ha8ANR*gPe`Q zg?9YEeHbE$?sR_g+bR?{L{NLfGELe_DHf47N#S|vqWs-CU+=HL6Y!wDJ;bN2dlUvm z#_iCY9dwO7AY+x}ileass5Gz&r*1$otNFK&fM_(=rzw6ZZc(+*b_R#vLX2@p=CN8CHY0pW^qz)3f zx*QRVY(xQHlC$wP=F31J$jvV;g!=G{7NF$d<1&x#oiIO~W@5`5Hl@hqYY_IQ35p6I zyqMMgPBZk~)Ezr3DKjWvo4Ia1EM8cyo_ir{Pw3HB`li%be`OQKznz>tp`Y$)Y*)Ia zE7lG-k3)1-_1D;jZ{7T)xo6RI5hJ($vyeAuFWO@ly>4p@XHEUq6=Cd|5oRWi&VGJN z?KF;bY$vL6= zd#qsUe?u?vdD7iTFlc|bJ|F4z1(3~X7kPxSM8d6ueD6Z)Ny9NjozjoyH)0S?z#~N< zKxSObc#h#3=l(5n|2_tB??-l*o_lHg!ekQH4rOLQGqp09|2%K@_3ipdpA!@ns+BO0 z3YKP%YTSCHG{RmlGm@Wc5;gqcWTce!&bHyLP zK1m(CLo|Xo;w=99A*Zn<DF0wo<50Uxs;Az`sCgg)6+d_1A#Q*}KCGKvig#Dr}W#_;nNe8SFLoVxR{fPaTOA)@1U zER`6rvMT0^$RiGSiB{9jtgW_Kdk@-&+J>^kUrUEsfOBmL-pbE00_O{M>cT^|Wu@zK zGOAb<`e38hmT@IsBG+TwZ}2>SB*a3%bOP)Y8FgY=n)z%>0mH6{a z0ulZmRMv7G8veA?9?{&Kw*E9LRg1@jort24={=R5D05$L#~{qVhPsHQ96UQK&K%e! zC0aK4qP|kJXT|h-%xtWbaGgk9z@w|*0W~bwnQYE#B5{Pnk-SK_I1D-I+(6eZh**7B zHb+&Nz(bLYXj#NVA2M~p+^fsXw?@ejZ7)JGLNh#=xZ5Qt+#TTMdNFPU$5ztI4Lc~p zGD4_K@m`bKC4y-F=fD!xI-0rGJbVMYpxHG{s7=~k4_6i#Qqdc@LZ;qitYBz-8m=h6 z9Sb5vQJYdKGcU5B4VCWN_^~Y-*li#5h<-Cx=YoR!1TCaNuK$+FUC6DChZ~9InaK)Y zp7~gg@}GXH|3TE-4Vpq1)8CaS&qioK780MC^(j-b6Pi#JDaqZdEuf{hw_FbjvC|mXL**$N6<5+nY#7~X-%&A^ z%8V}7PkZBX0yjGm?h~Ar)Oe`4OgYd0PWLxeL-$3=$d&M>qxay=V+YI}jND34Xin{Q z9~O6GWW5xf;I{`mCj{wO&109raAQ`;p%5X(^3Ex>AFJeKXH-~4RIoo}u+y$vax&6~ zM5R*9n{IODf1ICr5Mk{PF+J)uvYduFp&a*fl)515b~eB1+vE{eIW#m5eu7$|i~J?l z6%`XdCiVUp2a?f0107cHl&h_6G`mk7Ru8A?jFvhGzi28|Ome6rd9jJsUY&AEpo>k9 zc55)9qr$nOP1tpPh7i!A* z6-x;{sZu!S90YFzcj9egiHiU-vt?q!Oq!V1WYpuhWmtPQANf+r;w}xg4{Zlo%9l-o zw>)SH=J;1Q!-kQoqrPyWqM%;53T$EyCXNvm^XW>&iPRg6?S2>58 zK{K^v&a0!bC>mslhT$cF9o?A_C3hZ_yx6hv+osG|FoIQ(|rF@NeZkN@A(0|T{ z)ug&i)L*IJ0{BS?%O+t0&oJK`idFI3{>dWB=4kwa7N+kgV^6$mj*la0HLsJBgfccO zU7{vTi<2ms`!&a^0P|536N{&dTj(#81Zw@a5EH&|tb!FZ2g(EQnc2M%#e$10$osxW zxc;@F8qd=<|J(%B79EG~>{Rz==0GQ0gE1lIsU4?jiOWG=`j%t7H5Vft4UT31G2QKX zx4aJgY-h}h)i^#T0tOenMrt@0l@~e+SJc zjIQ`21uH#wavpd8Q&yTJ)|MA|T#3=4>v-4vKb{!LDR8`$B+0^!zpS1f$L6mX+%tYQ z=5eZ0r#~TG96aN(f!1M0^tLduNDrhdb}%I~BItQaLG#m|15mvWlYl|30)cT90Rq+mWSq53PnbNE-iF|2%%%gjW#ug-Ms7w&26@K7wNyT>IjwN^{D{*Sv@Zc-{cv? zEcs>B&h*?(c8)XXVwi|mNVIf~elE^BGn7V_A%0b{#-L|~7Bzs#TdN~WkY%uR)OlZw zHtMmMKS_yNyL;Nn{_RPrsms;peR|H*E9#N2*vXUz3r)j7qjWSNp z5M4EV!H4&CQQ@pBUDTr^chgUH)_p8_O_0IG;YEr;QQLiv*oD*vyDaT(MQ%Zp0{U`( zre)z{A@&J=-{wihpb>te9pX4;+JL53#e~cgqIjM<66>lAFff-4dAv-hHlFx!<5n&2 z^6r&Q>5Av4T5wI&FqxQ&F3&?8)G+0^-qHTF53uUmZDvJi%Yy-!n*<;+dn=mb~ytRFrmb`(j12rsr- ztkqDea3uoy$gb?91K;!%Q=QgGvUztKe=metXE`=F>|l*Vt{>|Wo~#F56zS-rr^_`U zK;oM|5Fr*h5?IUM<=Bu#3VT0O`-JT@y5dtsO;k$2HZHyw^Xxk(rr^nXLX-ZU;TjU( ze~29U?x_AZ`mu1_^{*{v!Pr#5C9<>Ez$?AdrZ)Oe24a9pyhddAL$Nb z3%!OTic}Kj&oGG$6>V5}oYxW{7_PpM%UkkR8cG-cTI#Vv41`v6t|r4Yeq35>pdHjpD+RQ> z3T^ylAd4u*!mMcn}++Tq?-lAFOm?PKbL39jI8Q{B}5M zwl!gFxhC#Dsi6P5gd;~Q#5>mCBRiOOG>$?)gkwP$EA|Y{JD#JY?Wj^DJOQ_fCbhSP zT$%+Erbn~NQ~*xcZmV20+uiDWtGS*6rEQ)k2}$%DZ*MeOhR z{^M4D!iwcfAsIJAzkjG+$6<3dS0na`Ws#L?+U}CbG4DEpZwE`iT4W}2NOdLLcBm2=_!U_e6#x7!(chvSfV^o&a{Z;U@(iO!e(z< zwb|as>C4r}$Y=3TTF?Qpvu~-4g*?=6KT>`5B=N>Ak>Q{yUSoDy$!D3x) zk@Z<9RPfmewuriCbAUE>kUSl|aK@xhiagn|;pGbUJW#^Di$+M0xAl7{Bcz~G;$m(7 zeUpI*6&F}AjZW<}b7SATvM0d3Gl5`$L~Y(+Py7x|wD31G_CrB3aLwdGI`iQCeQj6* zmHXqX1n+u7FI>q|ScBf$QevSOMbYr6tYiey&@cxU&cq9mVC;)aJMs%hdfgTT2{%AP z2fMT8IoC{2A@|7ML2fUQcfXH56Wl|)JDx`G~hS5 zWz;OfHa5{&Axjr&hAUAJ-p0YDdMFz`^Q#pV*I>gHv$GdL!pbE@$>AI>xet<4xtaF5 z-!Hq?4On!?)P}L3SO+s5sc!D_A2t{TSIeoH`UxGL#NUcMhn&CO`{gbgRtJ0yi_i1s zjKk@2A|IwU=ROmw3-lDi6x}p;SQ%m_Pl;Du!oLMC`S4#g5Y8x5WK)sf!0851eM!{M z6+UAkxz@<3oq!bnWbjuC6ib1(>hl(sXeG$-K2L=xG^NN#jq2^WR=a?1O$es;oP6}l zA{{h5R-xe1V7xVan}~iy&oK1hSaWc%m`h=}+LrlI9C-IqG&Bu>>N0YW)A?v^WFFjx zru#vg|IS+p_W9SYoz0d`R(N;)h2n^Dc;JAMx$}B(I#!2}u&dNscyw-N__7G6VtWUF z$o$wEoBw9^-FBxZp47;I4E!AUDR7Y$v%WJxxCyssfVljP9&BLa*|A{lR|a_w1MVS6ikq%hWW|H$ZhbdvjrBaR=;XGMuMoGJ z^jO8|99>PiUQ$9(RSz)zKaqP-LGISOVzbM8xiG3luKb*JcStI>-Gp#~hN+BGbo$Dh zBUb7xd7V0xDH@oJb3~m9dexs;<8L~TH>cU?>*;LH4&DP?iLnAQm@eWs1%U$R&O-)C z3}$9^(EJ2_+TB-*?V^NVA?4GX;D})+VL0UInN8*q+_m`|RvFSK-}(2nN&%q?j~U6| za5v`!p;HnkV3U)V3{^5B5MSsRt?hzfNb;;-=yr-86bZlh4vk?6 zk_Jr`D{Vt_VAov|skMo#L#t0tX6j;SMMI6#%S?-s%Y0?vBdV@nBZwQs6YAqxW9lz=cCqGLaE>t!4q15EwzFbGs-y%G++)5b)A z`kR2deT-m(t;V6hFVf$#n5kd`?(aA*N`%LD(#bp4mk^*=k+ z1>`~6u(*_)KpyCdYGQv+g^&dnAw*@{F<;$WT{ZvL95b-?bmeOIxg;`<3I>Um6)D~; zQtJ>3tRyud_Xojw8HWf8cR|3W+9+^dQA1{pfysV8P|;auNnbS=Vp9AB{`*w4Z0`Pp zLHZxQ6jF&)ulqZKicS$wic3foYd)hfEI{nbwHri0;j4Uwor8TY3zcBM*8p!T9Q{=E z0``#@8a)>O@89PlmCqxFLfD8^hG!ez@jSot+!}nm&+Q6|CJc8K>GUT)PTLbQf|uLRv|ZINai>%mKnD!9wK9 z_)D*fTOKNUHOF)U*01-_mFl^(?+#DB+pY6}^S*fH_nr3_!lvW#LORZCCtO z&Dtx_dfci4eQwd;tv;pVHzYkqe!j4TP9s<{Axb@G_T=#H`aT^6`uMO=p*Cyk&6l+4 zN(239#Gmu|5(3tDbWb4RdlB#ou>LnN?eYkKgtjLG_{7Y*5dx|&0W?(hWZ*SLeZ4)X z=EHs4%tmcUSBd+(#fQJu36pbh@4^2#T{s0)^RCV%7SNCm7$qPJqau^ZeS-rj6_kV^ zGotn=cn0MA2wL2nWu82K(hk&z3n=lIE_yx>!BpZUL&;qSc?Jj-Qu`1=l64Gw)&Juz zJOGYY_gWUY*w7`oK{TlXY_g_|b8rojdQQHmeh2!`UHwtNc~08Rbk= z3hnIAsBZL#IT6sBcBtCpqL}QV){*T1YgPu#>)f>C3iYSPxQQS{*mqu&!{naBIYl(&2t_7o# z8=m`JuOBkuSH9s$+mGe`-;$@T-^^;asPySZ{rox^k5ofb_G$ z|D%}RU)LS*^YiR^$KHvh=m9Wt{t2k`R(sw_`EoM>=&bpvKkqQu0j_X__n0pj^lE6I zd^T?OC-Y2{4<@x?=_(ic-Hu^*xpiK8<8K~HJGlJDdGZKcKp#o2{dD)9PZm0JX>y}) zo)0Df4|dLgMzsyWH@`;souFy#aRAPb{^*B3`2S360O4!DbAk)YFXpu0|6|>IOJ)~3 zBk*l{`nhNqYFo7tm5+0w@gl^roTd${g9>^-OmrEf?8A`k`&p_DC%Tdai&{G5B3)^I z$Hm!gbtWT8;Lw~5L{1-Q`!CA_qY1URX95oGize6QMYW$RG_kYj-L^!1qZjXd1%7K? zy$Abzz~pJ-D)_n!RSkZU$kcJM03ZJZk%GQA+hwjX)m2 z^NRir=zkyaB*_Pa7}PBQdM3<@0o9MaDc`LN0JZlWJ#|3mpUFzPDqjtq>s^%O_MjW} ztdBU@`v;^^-B_ho8IDS_*ed2OmKazAsgNXvAG`x33-HD0upZd)aH~3wp7$Cvpu&n zzEv0dR9o+jHa3MQxJcgOHc>8}a^a;jKtpgsLwML29{jA+Hpoe@YvUH?MtoqN#yZo& zSn_-fC>57a4ViSQv?_kzEetw&kE;@kX_hW(8OW{k$l&aF!#&w2acQG+%XD6Nwc3c_ zz4Pvd4xo_&kxPmcs4SUj5k=`m*-a$>gqbh#WuGreq`hQt);>D-+oAkEc^@(5`{}0I z#~+P`#+e_@m)-yFv=@(S0Igz(XRa{XxsP7O9NORR#62|n-02r3&40wVxonbmLO#QM zGHupC{?1~1D*Su1wQi3Ko}&wYjC-~d@Jd}9Xz4R*J-j2znkSoL!6ChN>X+|Qj5a;* z0UVKl4y5$gS_6_*QUHSj=)bhnNsN!G|6Bg`)1N1UDR4|e!!-N{41YLGi3-%nq0Fq=H{ObcG`Sc&M2!)`GJt#n7V1nuH=>&Q3 zEQbFhix|Pz*j(Y-JX?sp^4_mr$;L~?D*aPQlg=)5DOid!L33rCV}Nf0lt;5wJ}eb^#EH|(r@LuhW}txC%!uy05zArG#@t; z-yg$QyPMFwttiVFuBH72qiJ^tQ{vP@SEHU>6+UUAk3Ge5;fl1@f zTX~9umzeM!zzo^v5rO(QKz;Ys6vkKzAjH-KDPfFIz+uh;f- zh3tHeR~T=hUzwp6VH&n%!EFz*7bcb7u zIsES8%P=5$rr{Ga;fmjLk&vH+TuygkPlYE9QEE{O;*`VTzfnMFz9jhz0Ml~4b87^? z^!I>`Rj@AxsB@f))0ftO6F&vt;{WCZd4QjEBjvbt;ZrShCs*r1`2|9p(krFmaB#U)Zn9ST!c_0UI^6L zLgF}ASrS+gU%o?;{^5hK{uD;PsXhwn(eX0hsZGA>HUp)OGRs;Lbct1 z-fQ70!>8gs;RHdm?{%&mY~6k=L@nJWoeSPZH~p_0z$L3vs%{=7)o|t8H@{XE{SqZA zJcCACEs+(D82=41xn?D}#o^|RP;6Y*lRlqyD-Yii#@Vm= z8)hhjRf(F$TOg6zt)`GP)8TR??qZWQ170+c{ls{jWZXlW0r1fZL=}Mw3{p@P_Mm7( z8v%kIA+vrZ@|E6ph?dQD&- zHkv*>w|-O!d0L7y+gWHfNDVdffyiIyM-b@R!<2RPiw`Qo=CG^EsOunieN!gw4 zN5crT4Qj^22~}P^1D%^E5CtjaUwDg5vc{fj@-9JL+772=M7lDb5lCZW>JCO!Z%QiP z9ffq=*RLfwfo$r0!Y;pzxqj!Zn=**A#WY_}F(EC;p;QUtvaZq~HrDszUj50%2&THIa%g&Q4_ zxUeGg4tSV2Q&pjOMOmh&n6A3ePNa!{Sg}ZvV=s$;IEN*IkriL*bD)c8okilnn((mo z^FhnqeS^OKp8U^nlXnS~=Aq#3M|?0zM~eQk4U=uC%$P+nN)88twnnafCFxXVS#2|pBQt1m$c6}Q3c+G%D6Ea-Fexi0@^Yut z#^>s*`}u#Bn1_~_ltJmQtvaC^Yjs>ubJmt&ODig``cG60fD0OxS3zO?RnuVFNA4^^ zU5B)$o}gmT&-XyL{&Fcip#rWF(pT_|3~-iR6e2kBVL(DdSXI$R6ivmBa*!;qFRO1Z zq8vEa%Z%*q0~(&|t8_CM#dt*QDqjWdo)co6aE*_%j4CfnDJ%e^x3CkLYolC^DQ*O6 z*Vmo>2Lf)<6Qeo^+wW-~*+I7#5oDG;4?4Dx;$M&{CFYQztb9!fE)T59 zf@4}?BIt-o?_008CAl2S*uS6k<>W(^65r_97**by(u*>~%aZ>T>)Axv#vHFCEbVpo zQP~VC4lW}1NCcc|{}|kx@)oz@;ts`PNIR@Sff}FELlzOUw7U?|0n-71)zYNtg1aPZB3Z5L5HN4ai!*9 z6jyr&DKk;u#WFpmRHGj1=tSe8kmxLyPe2i*Mm_Cq=8>_u7xH+R0*Eiw_QWC7 z*2)l~%7S!om2chMO3-yj@71tb+b&R3o{Bf^dqp_GxPa2uULIidMf}3X~@!nG~z3SV81} zi+7Ak{cCU@|AUThV7v_W-xk4ssfmdQtLd)7M-}Z@Mm<(l?NAR;lPC_yM184292t{Y zT1=Q&t57YBuTnx=mLSf9@E| zx6&EcfyiFMFrs{J|K4HflWuLlPB~#S!j5uPCON)3_Fhp)SchFIy;NH4`cLqh7+kzp zlpq>tm7%}%t5PD9V5$#NNOa_3h>Q3TJF&O+2Qk*3(OTM1H3=B#1}#Xv2Wx56zUsp_ zL%s@Vy&HG0c#}De*}u5_6hCn%O$(f~z38#Bjn*E1PS|6PV%!MtzPt25^Qtton|zH* ztmjDeG2p>*{NAq-S#En4Wo{U0V3=GWBVp)7=J?N*ZPkXShrSKhK5m*cFt5@MNl)!m zZ)GmwR9jc8-_UtdMe0}9-(YmSCzFZYucUxtX`EDnYGC^44ix^c5*KgOdgg_22{Fh5 zSZx`E`0B?Mgt}-$m4WUE{Nd_bhU)B7qluJ?#^tZ6@@sTQu`nZ1Shm;vUncKN6>bfj$liRKv zjYpaP`3+YVz0naV9rP1fZ65Jt4ASCSjZAs}ZItSvq{@@|O(wxrwXI-sTG=^-NJ|$jp3U@X znbO{}jR;y}(S|Ab;Cb_eRsMHrM=VqLrsIWQMMb&A?besAn7rQdx z!4>rvxq%NrQko;K_SuY$WGqjs{MUNy=nRArIGNA^KQTcAW3taqiin4^Nq&1wL!k{k zbry}^U>dIhYwCV;^*xu32dc6VZB-Kq+2A>9RoOqG9IF>K(&j$Hxq3W)#TG67X1Xw= z<$I{}x)S|+JQ3Bg`ll4Dqm6v`RUw|HxAhtucvGv|w~pv;-2uniN)_5sZzrmjWy1y< z4M!d8@fEdbwdLdsEM@u{EgGvy7b>luW8_w1FJ1kW^o!dO>BEUNmytkP!sx#?@`GE3 zdpblI8JR72_gz<_(afG?KPbXUB(Cmt301Co*XjDz1Q=%n{u+X z_70j(*@wjI1QK(;F(JttRJ6y)42mim+np#XqS{Wt#~|y{gtNDo?CSj*>rAt+&d96@ z$Jt}$l|n`cY^*KEo=Y^rqvmKAc$DsR?fC_(CF*1b4%U(YADBOw%vw%FSB7dch^xNc zSFZ4-kAdV>ec9JDCQU>*wm%;Vtq8Ro~vt{xYK+xGuP0e zCTpZEcTgF_e5|PEXN(ZdGPczuU)Tu>WmUaS6eCkTchu-!*&VeCekD{Qb>`fI8Jlk8 z$VGQzTle_$hJkX4MB{>AVm5D;3-0KGT>O(Fs!^K-vOabm$pkjd%9K@WNi#VIfdT5* zXHo4L>zp*Y8=$+KBEBh?Y@@AU_?P6S6V^WiM;0uol$5$6rKaO0xh#2Vehf-wqZgY! zQ&Hu7*pxCYwO2HBiDq>Uq96@IS+{{^ZdsGlRd49v#g-s3x`H++?tA)Y7slZ$`16&^ zsBi=mZB=)MbSR59^~z+{pWC3_!8vuDY^>w}hc}XO*MVYIb%j@o=3ZVSo;@y@Ck7F# zClXIS#jL1@cjHlYRV})0;82er{qpdQq6kWwk<*&Si}*pvpm7>EYhcSOB2H#)oJ^`@EMki2`rYx+}aVYNOx84 z;vFN(mv5Gd6t`k>ZKeB^;tX#rm4>oi<`+fe=avV8&aD|QFPVAH}zGqh!NvVuQ=1Q_b z)!(vJvt4qmF`1ygU8)C*VpmEs*x+iV`{!QfXsbFCBVJ2)xH<8&p}Q2OMQPZz8oE(c zdOMYhPZ9BSM@}P>&8)LUVYpzzRdua~dPCKu6W_h1Qby5$o`Q_|*9N6T*OvBj#Zk;; zGS*&{F*LeOk=S?(i>g+chmuJ}g$!DpuGW}J3f0yWLY-Z4#e?ReOl7J+{r|_;HwJea zyvxS6Hnwfswr$(Cxv}m1V%v5$ww-Kjo&BG>b?e^q;e4H%>Un3TYO4Bup6*tOE+ypc z&1I&unMJlMtddD3sd5%oi;sM={RPl>Po;dnLlIj()KQ5RI2&uzj2?Z)I>o0FNF^l( zC0R}JdKO#zAu=y+&r&xlZhx$5R1#2Suk!Y#X+hpt|2JK`-<{@Eo<;+f6a^*BMyPV~ z7*XJOWVxC8Sgo|XDn%ppzDimDA9`0Vn$F!FU0P9;GwEkZMkHJ?US<1_$TYx-t!5J7 zbgp*1>|fEX{q(ACEz#MO;Ly-4m?FM!9VBX9>PUz5@o4HL6F_S-(Z<$gFnNN`iG_u?wSj@ z$DA}!f&h7kntW;G<}y#38}X-S>VC9wrC`KYuhNR-3t3un(q`HLp|to43stl`h}k26 zcq`Yoyi=X0jM0k)_F5-2mR|2>JC6S>vN5V0oTR1P!J0uBKm>Nn*yPDeS263fl`6Vd zb;_xZxE8gp%xBnk$knMvP;WvdG{Fnd#jf^bqe`{cb;{R6dVSny~As4yflAJzz zgS>A$-u=N8b*CLFxM@Z2159|lmTa`%C0AWUm*P}a>Ie*wIXd|Zza&gx8$`uV?+}b% zzBQp6v}}y9iSKM5d2 zD|lA|t*rlpZ%GJd*gAign*fRG8uWEJP%qFOecSH7c2msq$2WHN7Bhk0gb}Ila6yh0 zUt$P&VtqG`sUfg!H;eR|AnaD&))y&=FUs2kwL1{?Q}dtoCFXlQBOLioC=f9Rtmi)m z$!B|49^6Is$ZGhZE@&90+zB@P{hhXr<#8NY$9d7VVj@|1NTA*9euA?l9RE?YbkFFJ zebW2=`)j&qaY}5$y4|{gIi*H~h4>z#YC#sHx7lVr*4ph^i`;kUGSS;N@srD!o->F9 z<-@oedxwZ(=xVr@Y1izB{fPq58wk`BGF(YX;9pR=d(x~#-GNFuJi*Ia0O$g z>p}Q!9zFg?5`oZ!+;>I59sF1;=DviHD!>CS`m$8Ky(9i;;{K?9SYpZ0_&`p@`;=@J zNV$ho#j_LO-rIZv-27L)0um8pV`m9NO-)0|G4`jpUkg2+5wqM5h;#bIF)FTiwLbB) z3cI?3$?{Drd|ceUzT13WGF@)FKmJ?S-SQp+ejz&^v++9vt3$h;W7{zS#Y4%fXL2tG zB`*FuAV6nFXl~zPj+_A!fuvBmc|t=0$=};CE?^p+Xgdygu3LPc*X7E!3?Y5_TiZ`WT*OaKPGskz$k*N>On8KFGFNd`=yyN$eRV>3f1LlJ%Jpn@_@)5l-q*5gc}+HC&~Ggz3zQLpW6fv0 zTN{M}N%!XXLA28HDqey}hnWc{ueZ!p6(S!?A;fCg9SHF8Az_uaH+qlR8WgPy>V#ZS z`@H*G79sI?cxdyf2Auq;Mi#(&FOgt$V2m*m6V&`mUGV zmbr~17BGJ*fLr2UP(oUUJhFx?b6yDa_%?c3Trcn#`Nq|b7yPfqxA3U^b+L7r9|;Gg z$Y66^=;l^~(OhHr5vdWy$B6|@JE0f=+<32NZLRFy_SK?G<`;X;Zsa?MO6U& z&3(Bg>Uq#+{1*vk49|gYk0Ngm8NDQ6J=M`^tSO*z!XZC8)Ef>sCRI zDMvw$HOJ3i%LlHaj>z%}l#J9lp14uRHez_`L=b}=VAb_m^H z$l*}|2&e_168=07NuXJu<)nNg){^PI3d!7nh2QKyMI=4Xn2)S5EdApJR+`?}X=&l5 zWkysgnoTk375*HA_rRDh5g`BwBzQ~Bt{}6D?>ZwiR_lP(XUeaaew@#c$Zy=ZF(&NWO;0!sO48q1mOoNI zG}2$24n_Gl#)ChlzSe)0kmju%+||BPtcyzf&hoJtk`Y{x0zGo0H9~3$JigvD)@-<6 z=R^b508Av%dv7pt%ceU}Gh;_V1F(un#sirmf6@X|!o(_h^DmeUd&daQHd$Zqoqi8{ z=fwt{s0JF81xP?b)+tI7qr>99a|S-AQ;v{Euail$oS~F*vHpl_ie?$W8(9Uq?K2dm zK2E-*e4@$_38zH6Tp^QoN|wV{Atj)5fV{_5c%ydIQv4O&!p{QC%oSWZxhQI*Av=NF z0VN3#m#9vp)8a!5m1s*|HU>6JHhoXGsh}3S0gvtjn@5wHmj7HK_c|}Y5yUO zzxK-ke@VI#b??VlDG8dq9_Fh+q=GDGC4V+I*O^d=o2E_XR|v+sHN*xDO&lW#s&*xW zDN7^YU~E{#{0gD}Is@PMadTX~>D$Pkm?EJLixacq#`9(Jd?mFUb(Qm%gf)>?=MOoK z1E*t2Ro!ypj=~t>n>yukj$&;j90S41&e7W3bl{yRJzyO%x$BJ*ZQ}=`Zx}q_N4mZl zG(u zk%MLi#8_6zvM!6UE<0ORv9NL-cu}Bra9ZZ3Hq$byL1avVrddg{_nmQ|Fo3*pfLY}6 zPoumDAB}0P-eB?I8HCz2?5O;@=80=6Kj^c_9a_ENv592D7z;q3S~~bwqt&`?dP^>% zZne_5+m-94m$YP!6km&2{>EWCBXyN1D)k@{@CtF*bAqsB^*^(JWMw={NPa{ZB{;$CqyGz!>|gK=fxESAe1f{ECQwD% z9iI-pWCLJ_;4}xTYM0lJpjDsl7$53+G-r8u5UlS`B*_2ly(4R8V810GM0f~RdL#`1 zv*-&C(?#yxJzpcga>6)#->cgbJlvCD1s+KF1BInC*8YL93TfWN>&qHC8}8ace;@&_ zLujVSuLcvlM^lLc+`;>q<~=}33_$F-O7z3{HlJMqP6I=XBPT>g{miX_oCkR3iBV|y zXjy(Dkg&yKP!`Osu(slj>r8tBJqz-^8Rl2r8u2$0EL8So?r%}XJx_@EK_St{R{t3_ z=*8=^xY6kq7&ne>r*uT8TlqfY4vV;(`%82*!Hp2m_0a@^onQUMqnq5i^foT;QOsZP1+0m#IwMZShnI2wgRyZ0N3a)XpXBW~&whLORJKKdjAkJ1lZ%o_zFghH ziQ7}F_Jb$Pqp#(+=lfZHppj5t$^rvw}^j+W%lTrbgOIVnRQk z8o8VC+!fSNXUKYKv)pqr3nu`=o37}`Lt3`GPl6!PWp0&#IeSDGtI)8#W2WqovivEwL6mfc ztl1*1Jp8RAWl!C`PHHQ~0<1jWY*v2@%A!x0PQ-||_s9$xA|#=)7g*4e5uo`QKI+~n z+V%Q;E_nn_$uAED zJIpkNzKj7x;J}v|ZM)=*=&N0}9P8|Ye+@<#OowF{QfsyF)KZq6;Nfo*a1SuwIEEuE z4w#;NDk%-r^-uR&z5l8H{8cefje$JTxO`Cj}OPULrS-qg3x$1xnKtK;QkTj%<{N!js4~= zircM`zoxAmT@fdqie-Fnehk|rLcwaXk5l^AR)Q|O?*z#spPQlR zuzN)y#EvaML&K4@^RVbTLV4*UC0)Vz11xY&SA@X77~|wKF^1-lON+G_arEf;dFQe@ zWz+K{rc56V3WgKDWZR}9e7+OJ8OsCW*|YM0_6v7edzJC@)Zk|tWLtk^THe155byWn zbs1A^Asn`t0bG^wvg@6t_NLk1@cGu{PPY`Fiv5L^>+tbz(R$TNGy0}ZzX0>1E5241 zPL-mwhE}jPhnLTtLiy)afx$E)g>WD%BKWc@4_|~?D0(b4{j93MP;FpfE6G6vCi^Qr zc$$l0L-BfyvCagOI(~_8B5Y73%jM+IE-`2DE}-#6bEkD=c8>gr=}Wxj>Zj2OEwT?64M$4G}w>pib{s5C8b8o&-hhNWoe z30PUHq1seuX=9kHnOl}@^uj_3r&_jg3Fi8{Dm-Xv#!@as{Hnc5th=KqJX+TN+MZ%% zO4UL~wLBd9zcBZ z2fWK1l;g5UqIni>;I$#nlYszs3P!c0c4aLch>W~dD^S^GYYWMq2RJRoN_mmOV>vRG z5}F`-iUpYb9bT12^3v%E3u#({$w>|ZL-Kx#51GgIK3T~b22f?|isv44_?+L0@V)M3 z@)aBLa)Xkvc6QWNH59UC&wS?5);wjtWr7zvkzgmDf3qzhm&}o|>tI$-GN6@1F6~$mgEa?Y0*bLdv$~or_-1f`@3j-u(+d(0hwjR*!aaEITgdO z!&u5d;@lkG_AHE&n^XIau5-7pi!ORPZHxA3j*R3NZ?+*N0o>hli$t3E<=LBx;Pe1Q z>Z=lNe9JtnKn_$a+vkm<4K!`)bJ!GarPRO%VJ>P-)IFC^g0;Ua z>&S)Iw$JA%nb;OGf)ynqPPyVZSC$&(W{@10;=FNHxUUVRn>#k_`Lc7^HK;R_q~()lly;?YP#bFAY_KU$?Kj39ckufwgS%kb2c<^VG*EFIu2$`av~*XVBUAZj;I z*2`86teCnp&1xbceVBzy2EVZ;o#Fl%m+JIjK)VZW1Kh+}cWkKODnjSN*F$$q^agR% zW;5o`S@aZ&y@N_6s^o?T-o}&qvX8B2aOD384gqvsV{r%S; z9ILy7H_>shR`UzXq2wa%)Ux&vi#vk{vP8#2R6;b}VrOrpLU`OHbd4p-AOdw<3qiG| zcdDw*+o{tNCE*&nLM>{O%4N$WxevUijDpATth34}*rhnD>iEP?4S7bP$x3k=Qn=Z< zIgx~T125OkNKSce6C({^2AlF1LD3(0kSgT9Fia&vLO{k1Zq=D?i=$wl6a=C;Ir!l~ zQzUZcrUl7f?|0V4HGO2o-Udc|=Z>9TLJcE~Sx-^5E@l|aD8l^R!HeO1%Z9knYgMzF z0)ioA{Y|2lILXI4yG@#+I33F5UJ&fDE_3i~oA>N;3HCZ@^5{1`hA+;)hm3TCP5)U^ z!(M4p=RC1imER4FMoVHNsnzukctC)zKdFR}=zPG;&eHDC3k4gcog3Gb($!$PQ<+~^ zu3uwN+63wZf3Wm4VfR=>2=F?dT(l(L^CwX7?Nf;fT>7nEg;>h-Puk8A{y~w&TH9lv zYketPAOhq)^cU)4OiF@1Iug$jVRAV_M+8vH@ze~&5N&?`IxbVy@AiB*sy52w8dCbw z`|}`dJ1w5SBm^j)!S0^YCncc#c+*ky21E=IfdwVk!jSP|5;LgTe55RSWrc-M#!QTp|O+zn4a?VFAvPZZvRptNnz9Y zJ!NFN~845l*Bf^Tn+A|T^rK7y%HRAiMCR&=TjBEQ*jLH#A7mk;-o`LS{KxiOsx z`;OuQnzSzt)bvUF>jNdI)$82GWP2Cmd8th1ByfqMo{OL8D5X0YF_BC!ak(qOPkIY> zeVZ~Z1?kJ3fm+x%xc>$coYa~E`+QY4$-OelFYTw| zP?E*X*^<79$MJb+?S)FIukPdq|ZvUT=nWZX~)d4 z!3A3z_JB!DTAmAaOskCv;H-43w17;3crDKW{M)t!?-wElerJ~n*zeTYC)Vwv*qYYE z-CuMO5pZtH@n&s`8Y7NV^T-GCGa|Ghr%WO`Pj5UQ^Xdc}8w=i&CR#J`+azPP*4H9! zYic9>k|Anz@!Q3abSYa5ZI*iLdL@;j| zMy#{A z$iKXj%#TA*vYJKZ)O$N=eQ_E7L|QYW z*DF6|UU1f0D=(*xRkEw(XyDf%U>#(!4Bo}IKr2SX+Lkt;GB>Iru8tA3K(B3-L|If* z;ccXq{ym?+_>+H4th>FKU?UlkE=mSEB-&70T z+-YjJw^l8+NvN?DZVRm(Rx_2hx5dMNE`aI_oa1ty?>?WUr_6-D#a3=yCD$|DKsMLY zYzFWlE(xwI6P0XB}E>8$9b%rTQkzC-+cc<)mg3P4vSmLvTD5hoKMm=>jUd-bx zCsRV0E9OmwfHd$6&Wb(3Xqk<&`i7UqPQM8|ZMKVFBkP)UAMdizIM0y_v*?tAaF^6q zzTG17l2R{qsZC-}n{qE3$4W}ti=Aedk@S{HgEEbPMAM>=XN`k6Rd<)~A(Cqua8gOO z3E`mLUNmqN7fbstGULAoNYtD*S!?9gX>FX7UC zynLh_1W0{q5eM4c2@Ey#Dcemg*~u*1p&tgMl|9|{MZ7-V_3?kNj{Us98W8+k9tQY* z-uxJR&Z)hfIyXCC*ni&>n9N><1o|P>BZBa|Bi$NU*uEPY62M)B1o<)EqFzrNj_CEK zC{TSz^oj5Hb;q5&=38r5-J!>(8D%@_v@m^JY*-Wg_(aY_7Q3>FAEID#e?#IL9BOI?JPWz6+9wdC6#SI3*3oaP>m;N>To8(c6K)le_nX z>06K%WztOKT&uPUqiU}l7G%&4HPkt=35W~5{c;KLmq^QAc22BUw%xroZX#Ei>~xmX zU~N~aRsZ&tD<;ya#hB;72KEbp7bsA!e-*@Hup&5(al;)vK2Cb4L79sZ$fk1SnWe=7 zVA8Iv>Yx~#sng4+9Jj7+(Vd~(yF`4!Tlo8mXz2P(n0M$_uiSk~Q@MGx+u`HnesG{k zFyI8i!L$c*4y1aV52G_CGxdQ;h;+ zS)d5FnIw|r&{|!f@N@N$GK~HjOD?|4hIMAm{GA^^ zJC`8OFh=p~sQm8O#@YY=;_MT=gO?<|ZtU05!PPMt8W$Gz;o{*$*RR7xjp~ipnazpU zBXEPSD>5$^Xa7&^Ui>e{yjX?+a*1+=@u|Dx^NEoWD5&3yEY9~FNBakCC=;06JQ2YH zCSP~Q;6XGd;x`ef%vc0pj9f$vizt&Lo5_cF3#O8zvFqu+T<_4+x`UHCVIYOJK^8+y+$ud`CQx8oXrq1pIngJe8%%KPA5}HrfZ&>wy zOr!!m{2ji2&hgy@1AT{6ck5JX;o=N)`XyNyAMFu>6X@wO! zyYlz;W6bU78QW1pfd!48OGzgZA*v<9u6$2$J-*E#7r!f0#eu;cm1F0gM&Ex1cIPS) zps^JaP7IvDY=NLXfyse5xQ_d~x`+wRf89d3;+K9{SNslntO?}nZqmr%2r~FKNuV0T zr|IqiH+>QJ30Xk3{l4_XpJhiT^Rb19b4V+`?73dh7*`+xnk1i>D!0Rg@kJ= zrIK?``*t6A9Db7J?dU*Pn>tp)uN$b6QA zJqV+ZA?-Na!Vt3bn}B5aZGIyGwj!uBDSnc{{#^Im0t0t5h8Xtu{62&LC(+~EuSbdo zjWCXP)+Enj1(Gvzxc%hKOHc8a3I0LGo}x=r0rLto$Nh9*Ur^{wM2I7WT>vNu-((dY z=@G+jvcp6hX!|2+UecEU9_d_OgM&gKFyk=}j4X!bk6#|}9V_tfL%0?Srioo3EQ^_d z5Ju63KtOB{PEt=buIg^YRLEB-zPapZwJSA)&-Ch!2=;B4v&fXaWx1?~M*z5}r0n;bf}-sw>f`|4XWsj}BQ&+yZp&3yp0MWmudL{9EvZv~ zGdp{p!UlTFQ~-BZ);;9l_;L}X+Bn=XcG^ugUKKUB#isMZwB9{jZcUVQU@fv= zyBz=@F;tw5UQ>-1W#hXvJ+wF*4@zDV<0&nLyyg0-vxyfL$+He?IzAbO@#Q?0VY>iI zc(I4?i0&fSWDzE8YYZynLi${)Axf$JlLdExWib&w9suZbl@6)JJuc>Y{8vbcjD(m% zPhw$Kl|5#b%{lgGafCRvd#y=m`$B(HwO|`x4SI|S7sl~RF*u{?r8XgT>I#ceqT7vD z3u0D;5g>`t-BM_?5L|Cjnr{3!*#L|h-ei+K#m?+J4{g@GBCmWS3*a@L8MI(HBX1YZ z@kFvq%;*=2U6IV`$%VRpR(jo%9pA0J?4IH=Q&6kH^}8C%TlT>$w?Z?C{lZ-1B3@mw zj)QhNm-~1iIqUsm&FraE$0PcVMXlBBz(xhW5wqGfWBP*8tVCxfo?P<{!M%J9w7E%& zP4(QJu(qiaV3k(momHMyU5$V7&oxAEy8142+V!m>T=J|^1 z(rZn;6g6|Jx6H<7ApoYZPstFQ+ygE=cPZAWds(xef`{4xPb)?R!gbMzRx%!3?X(uE zd*Z&Y`mwM%O4D2Q#;@(v=?pqLw7)v#7_tD%LOFzCqN zIq7=VD4WDlBmDI-dbDYnfn>%(CSI+FU0Wt_;@C26{;^D7V!RBG5v;7t6IS^%I|<4e zEqERk>?jz(H%n)iE0MQ~M48pU<$jAyfjJN2lX#SOeu$wII)B6{hhkwK=Vc^4Ox{`T zKG`O?`~?@AMvLuFdL1q<95TFGF0}-F=7W5gYi+>iDK`2^yi%jk7sn^f+s9$=Dh;d3 z&6}v4<;cv>m{#qAQb`OE2+eLaR+{M`g+Xkk9pffIzx0cXiS*H1NR-xKM{k)|cG*b% zOB2&0OGmMz-5XVAShR!4-HZ=fiuo#Ti{*DhrBt$`qk9wEOM^7djQPMf{2Syz!=5N$ zNa6#;XF!j;PDb#okk@L}-Pq;#MjGW&MUAQ#bV9P3t3&GfwQ?MgGR_D%il}8(nzB$F= za(!HLB---OeRLRt4neVU2NKV7p=*?6#oY2LbaWp%5A-lmthj&VLrp>8vpqdkck^4~ zfuR_=0;DQs$vzifD4unQ)dRV9HH_q?!MUTlF41mC2Z0(%(y!c~X`o=l5oNJRd!agt z7Iee*zOgllS{(*r*ms`FNH^LG^}8dazr`2P*Y-HWkh0@+klBGq(5f_O{yY z59}Zs8Oba3Xj(#KF+N#(2ll|b%h$6x<-GTY@9`IjOW3wLWcoI;eQG$z8f^*9JurAa zt!+53RTm@vqo8a>rKAdcM^g~Yz>VJHjT6?>m@l*X$|Auk%(y2RvJcU%FHtdzoO9>QdWcp0QY%5BYH2&?o zLzyc|G!v910EoU-!N~}3&~jg)T^=o*35y56%_*qB-ZF+G!N!s?LnOEJ*1AP)Z(MR* z5l!!(5crW+>PeE-3tH(oHMI=i)}{tu6i=((`dhcyRvyJmWjm+ycWlbkj5KgXV^(yE zbuHS|vMhrsI{XauFkBJoeZ3-?Hl=dSm@de>cB}3v+3!|pNsm2mpa`Z(N2x^=E=ikZ z(@t@x{hCngf-%iYYaOKH{SKa5SbLKA@grOw4Qtdb@zGCqW_2n(@D?@ca-s&Qno^m4 zZ@&5>$R{XGt@3r-E*bfTC}(yb4YK5FV9UKXYFTDFS1KhEyw1k1)L$vq+2GDBBJ?~q zP8~;${_^x1xZ2?9HpLnQJ^>u0K@6Ct0`q9Oj$PXKpH68u$-cj(`WMw=7t#`L+!lqB4W?dy4EX-cWY|cP`5$Tb@4Y_D{pQBS3O}RKp6dIlkT*&`= zYpZb$qmTKu9EQf)<7wzL&~Jd*mw=CbhR6N*wLoQ|OL$e-6NU7uLk*b|Nk$i?1VJCSOu`nNVeQD}Zy z#pf<}s&L(?Ph+7Er)L zKrk=os8d)O$6cyT55{NR*9PdC&T=>|e!P-fYIJt4AD>Y}LjATa74WQ=&OBbRXcs>#q;k#XQ1GOF zV*`|CBe2H-eQ-k~z>`v1?UNI;E(~HP12RgrEB2h@IJ-Ilf57-TA`GxdX=aP;R|b<% z)DesA<5StjRBRg2*|xQEYt8_bih0U<_|eNERS!&*XM0vux8g??33cprz{+;9w#~8T z7McOK8Co4Ge}=o#krzj&*&3&fPyYL&Lo&3;>da*-P&BW{FA|VhXvEA>V3snfqB7BS z*`hLW26#^P;Em0XvwV}&tPozl=b4%&4myuu+T$oMm))r+6JVIZfkgfD*e+>t63Ln%jrsX9;seWu}@%#aU-|gkuByw`X{v zB4=3|#ZCMN%IrT-|IW28E;G)hIMtN$L_+5L4?D-kiTLK0Wj2nTOR=5(W6Vt4WEfW? zc5OD!lbcgsQEx*v&ZOS;3+qc|+A4O3Lb`NT@$WV64h4f>V^pH#R!Pd{FPv?aG<8ff zcGBLh=JtyV;MVZoX1CmlKFQrn7pYeF$}0f3OW*T>?DSK=P9 zJy^Rc9$Mv^Vv_P|GWE7tt+zP=0g#Ik+C9v21e4w^_V12|6>f*LUwAW!litl%*Cn~- zuwCmu#OzWi($ZdCq=oDo%H0t98z6!;srhkDcpeN96>9tJ5tI@pFEkO9r*bP(M9c=i z;;Hl<$bKc(sCUJwyf7aaNG2%(wCs`^3u^amYtC^cumnRCb#yI=awx83S#e46{; zXP4~`D7Is`^`bx~ai@6I{-lakp0*n#BF2x8eU|X6et*RKN^5Z}hFNeW@0mhZGM3RB zy`uV`Z4q)%+O?U!l9Ji~u{@UNzpCJhRHSr)XE8zn@Rg@5`6i%kOJCFgB8B7r+-9!p~r$JfdXIby~|$>}+qag)>N>l(8OTkAd_T-KrjZ}l=+IolbSCF1Wx zS;0vpqL0#J#bwTQqm&NxH|S2e<4*ny2kmRWAsvcm$w9#i8uzyR0Jb|4Gnj$(s;y%Z z3BpB4mA*MwR7zZ}`6CF*>!pPq3&A(f=3P&f>aCcdu=;?dG4r`(-HIV~D4Q(4LP=UX zlS^4Plr&Qx+<#A14s3j~H*ukLh88@C`Dn3-ytdV0%^`*Xt*%W{cS}@@1*Wr|SkbZ0+H=H_vepfN1s1fWci&AViuZ zWXJRPbH$k4boE2xbTwCpZE2=lg-0+E!6q*6N`r+G4ct`KWPddHw0nOHEahvbeNkoa zO(+RFxjb4t$s`(}Ta5*<4{pQUq;{m3VBKRgaam}T(Z}Tw6N5~4^1}tru0v{d^!laH~ zOy~FqZH;5@pZ1d)RC?HIS;V(pPD8xIl1DhndP$ zD-uaPz;^9VwP3LT*^oV4V(7|4o`q#*|BY zR}=UL>`>(qaGDa2S@L6vx$n={QlDu81tO<(w_bo;5PdfVH67R+BMcYAN!^Jpu9(%+ z?GztSQa3TMN#?Qr`#b(O2F0Q%nXJ>n`hfoXgbX=LMu-d488H1-FzW{dvqW@ulhh}z z`!K}HJedy#k#-%VF<|81sCU8q$cZ_%S)<8t!6Qv^cQYR4?sc9=%MetfZdcCep2pIb zTbybXRR|KXh!=b*@ULeI4Slhm52ytoKs2R znBAl<`)!7eH%usX0ZNrfTH3lzK7ml8aeYQF^wMpA+^t_!{HnU20fj$01MN#+-1%Sq~N#K*h=y3H$Pv;&J#1O_)NK4`9R2a1h_m~uei}(N1 z8EX@OtX34#)vn+ub+P&gCSCkLHnUy&f7y&q%m2@20?0qi1B9O8{g%@>`m@(~xAir_ zFyrKtys^C9P1j9_jW5Cv|C~@nxa^|ftm|IbG%=9zNo2%vMY^fbH;Aakw@Z&NG05tx zC+5FW9>RUaa?V_%Be<^!OBFC^(TxZi9(u+SFv|-J%E27joYRY+K(=E~`)wBDi-aWE zn!$l2bfuYq=N&R*zn+n=C(*Fei>pReptNj%&Y_1_u*2~&!Kqc1Z5X~#sme9r{Z*;Z zu0cOdJA7vp)|)!?FE~UUcA;^hRcq%JDvR}^8mzaQGe)RYJd~%1E>tfnQ#EKAa(>2M zFsz@*TNYC^XQ30%&s)XTW=(366YK{Xc@?18#Ch4`@$YF`giAsJdz{3@qef9e+ZR7*t&oD^KW)0UF|Jn?7<~Xt z7&B$c-KFYt#9+>xJbmEzqT4cu?^;$CLu0m1+?r!)I0k3u{`1&3C#k<#G;0?Xe5G%2 ze9zO}ovyQhy+eDm15w?ko#4bs(H(y9eC>7NM=YP>yhyx!gOiLQ2_&H3hh)W`-5CK% z4;?o(MKb^h#PT97CY@M=yZjZ6!zUA=_#Ia zbVi?(`J%J0t+RL_lcm6m+R|U(bLWPyGe*;=4oX3H1bze4AeTu2f0Pbqy5~V@7QHbB z>gn%*(bnCCW1t{`(*#;Dg93)tHJIh@z(sOm54^_dS}U;7wdi0_Ga1bNl zAJC!$UY60Ck>4*0fhVgzAQv(5q|iu5c6PHIxw9M!;|b|bP|=-{Mx=-ivjZ`Mg}s8w zimhCx6rJ1@jPpYa=x4m~e;@QCc#%yKY!7pF7)}*@x zLMBk;{>gS|jQErt>Li%^YSS6wNH55HXNoO>dPqP9QT2Y~&Bu%|XUTf>g#mPQT$mMh zonK*lj}>)6QxnKfC-ONohCJ!NeI1d1?1Qx4a}N-40yv?s=%B&8e(CQ7Zcf9BTbeh^YO700=*y% z(&?5@EI;iTceTGGrX1Ni-u3vNJ2Ma4;DPv!Jx~ep=Zwh^k zOStbN?`^g}SXjtxNnGLLIBs@k77hF~1&Z(Bf>lShUUBLtwJu)kbl;jN5clE3c z+aS~XjZh>d$ZPj(8U*u@!MhVCqm#_E{`Njmw28jkN|*-L(-j4rO(!HB{jvgLyL$$L zO;G@aRY>N?8}LcjDk9u8&;g3wBKSNp--xkTG6JSeO9YKD=>LY_tC=uS zEJ50V%)2A!4dIej&!Rg^&J#l~*O~Ob0kSZVu+NL|b3+9@#RFgd6V|C&a7QQvs>v{T zfVuxhG;y%0g8rqcr`gMZs z)J|9_8YS=-e6$T~k9dp?Na;}(o!(5ITM{5s{*za3l@*^Jh=fVMO8*F&Q0nB7^p$lUx4{VM)hJsSd_zNd?UJ`g%!`rEWg3MvM zxd^y8r0*vB+#cw;VcEIl1O%gBRzkZgzueO?GBpF7Mm^PnJwM86`*7mG+IuS6TXYdt zB!(*|p7+G<*E`QW4T3&cc*w;i>7h{%`rMI+r9b3%a10~nK98U*8sjMnC*9ki@;bU; z9UpK0*xkPjN8T@YpElN=rm`pS%7{c`p$nrF8PxKm?Od@f1-UU(j&$sehfs7ZqxJW> zS>bwOoSJoQb$1r}?JqzwBBW}UtM?klZL1H~)NoU&4{Klg+96&4QJ1arb|$pe-u3X{ z$%#YS3=o${BROKRtrnfhc-xUh2BCjA)7#ILpN-Du=!#{ZcAqf}4>ZJ;rK^Tzqk**K zqPayU$-WZ4rof+Th zmFcPe$nDZ+s+}VD7gn_;jA1$)ThT4sV&F!luA)%&R7M9ay|mWDc6(S^GjgR8Ykay_ zj#4pkn934idC^LLhybj2t4~4LtXhAO%3AGCAvwI=AE5FL>K`A1G0^d!TID{#(hc=fm-H7qH@^8r`WV92OTQ;K z#lRFxY9H?*LBpHbIBM?Aj#07_Qxi>HYqja6-ig*gTLUlKx}epuVXN3ZI@V}~%za%X z6epx@s=^?-?Too0S%-RF%1A6NN`SAktMlvq*A)KQn~g8r)LLSRa55?N3E0GDcR+yez4OhNk5#8ezoa!p`l$x$XL%&;?Z%FF68>Wug%dkkXNBD z@(fz#4NNz6s~TXFSTm@n0@?p@b`i#ieH%Y+>|cf29YMrP{MWK!NOEtS)$aP7`TZ14 z8YiC(1Lii|q%6{d@=f`TR*_G(E`^ncz)Xh$#rUms5$8;sLHhkQuNxlO+XZEN4*A=~ zZfoX*QFP`pTdh~L;o|NFF)cyYP;F8UV}4F#Cd^3@7HnNx)Z}*nt)YN;h7~gu@L`-g zgyU%xr6HZ8b(l`XMn;ERz7_Z{r#<+A9G1!}c;LX}x=peabELkZwgcnVID_7PU-<}G z!*H7uNl`&57&0lha!q%vx2D>~`1O*xQ@V9gdMo4x48ajm*=yfvCPvv2AT^+xEux#DX z*gEG$D9ltFbCueKmu#bzn-G%KH>yu2xu&UBv_M%3k*?M_<{c%w(mzjEGEh(KL0%e^ zth@1|T{@2d^=}~sctO5Ba8Am(p>EvTKt-WKhHP`;X@wkY`jNEdQMDTohH4lwA~9=S zK^y#!FbDSO;rzB>wvHJ*yGO2Wv%gbPG+8#L*2a_{AeEg(?ItA@ZAtgSJX{!e@1~bn zgu*VjN}_)-d54UJu1xd;bSx3k+vxpM9~iX8qPn!Sama#>`7xs1B8HC=+AOv0R+l6W z2UkW48#So6)C{B}3xZER&>i(!7ay4wiX7#Wsdftf+9XDrP9@vku}Tk?>Vcl$3A4Ef zZ-_VLB>m|lVMMG%_%4rrmmL3?wTS}NEaO1Nd@F{2kUfp2RCzYj7Hp7(omHFa3=EyuV zLv`gFmR_q~`q!*;bjkRwLMNWMqtf%clpiVP8ou?=c!P02GBIeBK;cSgv z9m`xE)l`9!ja`@n>fFYK`XoYte{b@3;o&TmJG2_~>>5&iSWj8zpq6>KfXAf9)lvV4>@ z7cMV{VU2Aq8`QTT?g}4Gue}+y3;F<-V zmDl~oU;u$B?275!8!uCX#xt`2bNsiC169YVRb= zBv$1=6GOy9-#hvwmW(S?Pw)lw{){pwZo{p+q6VUgPE7*ZE;|}!w zgL$46D`dDYP_X%vsric0Box(>$SMAYPv{tG%Pe8zk<@+ga{8%j;^}Qy{u~w;++Bn`PwN_8;V)M$l5* zaHzS#S@(dJ*K5Sdc88V+WLSr&9sJH-{LWhZ!_Ga>+$$!);Xm%o?DA~c0?IAXp@zsx zvm2?#2dA=U*eXzc#SGWhkMmYe(8tm2N$!=-KY>9sY-P@}PX3^ue;p3*O?q5jp zeB1k=bz(I;81nrMnN}#@?EL2>A8mynUAPG&LU85Cs zNEHL@ovo~B=lRe(Qd+}b;&fo9oZ#^D4|&<8D~AdhyDIIp(##BCqnb@Burr?Q{dIhr zwve>%vce!;z>``7K2?Jgl|f*BeX@=h6YI^`Vkzk)Wkp*C*97aQG&LOtvo&VA>UsIQ?hD`S;6(Tg5}oG5rarh2A0-!4F5k5>bhkw)eS3?Q98EXvbKMh3&@m%37ph? zVL{c}ZW%yyiZOC2sKvv(;D3o@?r!>qCk*-%1x+o&x1$-l)!8^YL_2`S9HZxp?@;@O zu{xP|)@y0}6~B*r8HI-BnsN)Y>2;5IR)VihGa;H_C)>Nm5)~&B>Qy*?wUKRnq-~Vj z+QFK_5E|tYrPySCC!l_|>bwbDwHA46oufb?5_eAnLHOOZ(hStQ2Mw35|rV1O9Cl#bxrIW$_+Ir1d`70X9 z3J^DiwHwqb0&_TzP`2MPvRzHX zmsQ)R!{;Nna|piK))K+9k?Cv58WHM@Z<&pzNyBzx#M4$=+@FhQv?uh~6&Q1*y>mMq z!<{vGkqJ+p4tFl?N?N-5;4(V>JJG}s2;wbLUsNI*D7AAqQM@;@uOP#G!IO72L-nHhPdch0aJ`YQH(O$&rJsr7pE8pF%OX zkaDQ?^OyA2j-NFJ$o9)aA6=_FC#eik!a3|frJR*D?OBH*Z+N%Q%vohKXLT5rC`j=a_o)!ejF4B4m=BH=VG4`v9Bv$g}=9^U>R-2AD5yV{mIo zX%ZZ1RfnPNrj<}zTDy*kCW&6^9xbOn$U)V=mKAna4#ZyRr=Z`0JsR?hOu@mr^nMWC zg>~GAN4xOIvN{ZfvxsVAb!An&4;eOFBWpHOOL^A5rON3gPO2de)zZ10RU*-5anj&UL$@zY>{gLX= z5tTws45MwA5S#lQBtR$Fo}G`<`C?1qU(@zD_zI_e9}i%9lZpq`;Ti7G2(tb%f{|iL zGm9~^!{;Y7J+>=@DV3NNhuX5B2%aJBDs5YD0d4c1rND&XkCr3L{i8~9p3R$Yx!WR2 zOSCUd%S7)jX3e()@0~QZ8n=8U#b~cvVFO8^PotErb4%*NPbV3K1Y9m0*?45CRf%3)8hQXDB2n<^!kF69&-xU6z&k5<#50WgTi*S*AUP`rI| z?n{pi{CA(0dFSgjC9h3-gP;8%v+F^1qY(Q06o&BCuxup2`QLGp4bxJ$g;?k4s+ zg<10BJq&n_l;cN4&jWJ1wpHMhW4UcqHp(>kwq%G0m~bE znx|Vr*9Xsq%%N<8=M_RL4wLT4qMjzlvSVN9-ooXhgvc5#Yy_>|S=SVVtvkg)6iRN8uRZ_QJMHDeTl@$h#lmo8a|C4^Xf# zIUVTF_WTLVvYvOKR+pc*-D#rk0~&^!IAeEgZ;;U6%lZKQSJ!ASi_z{bi&?^svsn%g z`rLlHe}^(5K-T=2_7|1!TQMQew?>_NbgJm(4lVe*m3dPfaiLG~DH9P;lRTZ(ndEm$ zcCOh$Ljfd=)l!yW>S9tkQB$HQ%5#%NlxK_DK{Ho~V-+`N|thKi8h6Ww`RD> zHM!L41Ftvj$=b;mc1n_K2GerTS8v%Qww8sZA^GE9#HQnuquWVc`9>B`#aI{OLT{;lkLEZq9jUk(oR4*L@mI z%sQ4Y`-*}w+3MWo!_9WwbD(pVLv3bI6W;b*VeA(?#6JIyuHFw}cQe;6G~P_Ybedus zbJk+FWqNV@NK(%8S#ByyBJjs)x9JMg3>Qg)NWL$V1fZl?>m`LtEL1EX8#zGB2|CTp zY&S)tXsri7S8ktCo<_5n&<9^V^1^3D^Q!Mr{rTYddI=X(c*#tC;f6gO26Y~MjH$dwCS(iUlU7WfvtyHQ~ zPRzr?#=MhZW4X%UTxC)2Gmc%=u*ibbhfOAteWwq95v}7{IO_p2S>s<`9Fq#f`*uGBZ;guOll~yX142+r5l9zvnTMS2Dc# z%}me+{$;=!bbpS3I#gj2`o1!LMdX{y1B-bb`Tncpep(uj7L8)lqP3HUSqWflNFk21 zKdOx!fH>lIQNd>Q>3BAGdjkVz)keGz3E5RzC@TtBs5ypM=LIZ4lBc_;1_8v^JtHto zYmX;O)TJ0jvkk>{4V+h&XVUee{3TI@njz~@&V2!?!R(#KBi==p2g*fs*`T>UG5{r` zpln`e+B}W#`~*i^{(rA(w5K;vA79iTakN z1{4tbO-d`vn1lG?{y&_Vos_8yYU??!s?28U!~n(-2Ux(53>X&ZQg+_kiZb$qH#1}j z-tx8MX%=k^+?btU%s}~-4|b?fmW${hooYb-v-;{lGym@AuM_*8wGv&4$AJMm zfw{`_Yd}y?odI2mAOFQA3}X(;uRSn;e5%$N6jrpVfQpJ3SNH)E!}7bEzJQzUR+hfv zuBDxMZnVqo7t_ovj}4^!jd7JOu04C+#o{GFi@`i=P?}(Ot=u#hMnYPy&MKT# zcQ~$HX#n1wRqLf%vw_fm=Ob&;=B?4XvqtJD8>^)+u~{Npo7g6Fuymf8oodZIk0Ps6 zbCp-w^d#o*Ppj06#g;m&a&xIy;U@aRUw{3FrFeBY()d4E6#rq#bY&&gm6dpKQ!vzw zSf3-fwY|G>Fnvy@8}+wIUugDSPUZ@`<7sDeVgI`^e$t`o^uN92praRHtHw-g3}~?D zOs>UPwWjRO0@PVF0V62Z>+N*jQ<=Ig#*?hR25#t?)3$B;*^7i4{QL#9g(ZG51f1Jg{MNM%~>e;eruWhc-<u1i`Kbf4j(tBvCMZJ@K#{C1)k^zium8at&fj_+sF4RCbNzTrba>7;58 z7~OvR*}vT4rn_c`zXyc3tbPXWj^DYu42mi%%#t4J%g;%eg7rCgb7mv}sPn$AW68iy znR?@c6MC+be)K5ni*MlT`{5xg%zevB8lpL|a4M$f2UP3W+ z^XHEo0^@(MJW-SjFQyo@lZp#3Cd`=#5~9;h`tqc%f$8~eEXrIF2TX5Ujv$P-`-bwx zUQC7?>gdz zZXG-GgDn=J?E9#`1WJ6JnT|LfkRwSh34^pVF_AgQL5Uvb=F=(hqnLu(oW++}vZ0)e z)$AG->CINmVt`6V%u$taaX&+0FK{pI9beo#v*!)X7aULQZMU?aS z6c3o|P5uE`_(JZMWC8$4cwQSlMGbA?hr?Mgiw*8Ja_JZ`~lR((EI``dx6TOYTW zUcLS;&t!VnetUnP6~1KMkqweGdy|7dkB%5Yh@r#HfPxXjckwV{#IBwYn84^OAF6SP z>qnfPn`i0%_V?fZ`8|gmDM$HF&)(gic8h$T8+@C4rt;57$Z^kmJ);)gzwe!&|6L5C5-IBNeyFF9ISIIvk1{#aftD)jD|{qb@1 z1&Du_jCg1K==WIU;~&_ZKL?=d*?(W#kGI|*PsmSCjRz#FP=5%8N887X2HTo^mifkr zkoWS8Y%2cCSve>WKEaJFj|#sE{6d}o@J<*0U3yFo8l<;;%CDYMo_$>YFaa)_D^>vb zTA>jWtGGaSh1Jd%d1=g?}X_=;4ii5b< zcCTKyi9J&>>lDF*csLIBK*#U5i64`HJtZYiWo!``ibQk=fRYXtjl*t$Y-Pv|4>o)v zT({|%vSLLe-#Fa`?%+2usopMC!wcdyFa2vi%Nn*m$x4XdeZ>rkuR-ezq-Zvd*%`i7 zCXYt_zm#SF$gYYtK<3ur{qCp}m%2!FhFK?;Vy$r(8%L*7w1b!G>NAF5_<1Mlmh z?SgbAWO=>jahiyCH1zcX?~Jqu(~&qL5dvQT%Zq#vp&m+v>4<5bAVhjy1kV(kPon`( zhi4^#XcxeNI@KJ=9S<|?ajZwgkuaX^{K?$d1b5bu0&3QSLn z4}Rf;fbgGy>79-FO9VI6epI&L)XV@lKcd%>ca(J^q}Q|Kj7RVXfGPgnAq_XyF;1Ic zZW+W<2<9l8HuFw@tt0YY6iH>=C$|)=B)6=>}^5y>IOEZxZ9bV5Z=1qdwDWnh}G>+^0 zZx12$DikM<#zU|>6gPV;nVDwA9eD9<<=UukXxB8W|8af29ZkI3g$Hoqcn|v*2hGfD zomvTPn4x(NQFA`UJ@O-=dezyu$mz{7eF2yd!xQn#5{xg0N8-k4;Weq61PpUra{};adu)+KthUJ8c0N^s82~u|D5; zbz96&%x&q6;GZA4iGD2Qf$V8Xc=27cza-Xh>}Vi|bU`M0DCAm^uR?xTNgoSIt zR(0JzO|U60nS3NiiTOaiZ6F)|StC92bJkFV>4*}OAi#! zK%ucJjZ8%~VwOtT4xUnNSr)~Kc579)3824XfnRAFYoQY*^w5_1r?_e0!aKoDiS|Hl z2kT?K6O@l!kGP1Y)^;-{5T`Kd#z_S_c>xEE>?tOKnT%d8+hT^k6ZW}7pi%kmrhB&E z{9X`n+x3VspYsuKT#fa|-&VaDQ8oBoO_iZ*61Y8n2XZf1y*x+zuUY1^Mny0-ZZ7}r zR~F+0B`D|c;0yM*>=Fd%P@;kt?q*F4?*C%>91<;THMuvB{fK=H7ABBjd39nZh~4YI z$nO#4_4T>E=MI)5KolgU1w)_48d>m(;1Pt=Gq~y(MO)w zYwA<%^c9hR`^!3`fHx;vRMB%FtI|9bdz3GYZ&mYtxf4O}ZXNxezWoYVk+*ArB9<@S zPP>%vR?Nd1;4tyKrC;;iih62p@yMj4$GWdi4h{B$XtY}ISFr!_QlBg?>Mt=!Iw-h) zZgK$RrI7TE z@#t23wazbpY&`oAIaj^c(}pIbvibc+a9wj?@&~2n;Sg<1=$c6C)Ep1}lRSvDC2&?Y z22MqN#yj(FLsDRJA ztmUh<5t^tO9fjMtq8-rB*&SFEK<6bP($*IaKVv)rY%qK(!SWjRtAGDcEL$}r))|C- zFQz6LLpx~UBL!}TMqAG7bK8~g#5Yj6M}Jf!w|eEzLE>1Y{(<5FanA-dw&W4&vD1OD z{Jja4VGPEWGK`>_VGL`LF@OLmC&n5`1)VNJ2P$hcBQy%8Mh}TeRd7gJp%oD2lG2Ad zzbjSPD_zh_BjQ6=&aE4V zQ4o`7aXv-*bJCq!^AuoIHlHl4U0PTy=QQ@j4b@8zm4lDFeWF3rbt&C-In#Ans&8R7 zkrTpwL_7*9f>Ev=AYH6YQoPT~Qa&}32eMe&Kx*`?Xxk-Guwf1;Vnk2wlCy;asjE*O zCOH>Yb64PGE-^08eHe65&XyC9FIyOe7{WvlyG4y98L`ck&2UE2BIbxwAYmRHffyJR zN?>3x~NlI?IulMR(7Y7`8(AuJfLm6YF}NT0u(g~B2i5pC9tNg#8U_~V@1wupSM`hkwTdSBCQ_Gc!1@c$f!0Bt%Kj>b1>y%7iw~Ucbhb*B`*y#Zf zDhOu>SN&h4*grOKL430?NR}Y}>`~lSAN;E-_;=qBkViRB87$-36CsR{Es9W05(X=_ z+y?qqhC=xa@d!>Xx_cRLpGcoP4geS)YnDRB7`(6bL)n;&Q2*Hyev0< zyrU5qBgM0WAW6GSNEyw}sU66eh42c_^C9mbQ3_}#Gy@<7uI^kTN&A58{Up>MJR|*s zY1Bq$pJAdFj%3kXYu6MeEsnFY;UeJc1o`LHa`%MXa2ePD)xbHhsNF>V*Q)`si|EhJ zkQFP=kqP4Vqd<_$ZAY~xM2;nCkWgE+)*;^)_6n4G@Lw^sEST1PGtQgY}Opb}&a zP#EgkJ7{i~=<24=w|6clg|?^0F@gNJuZrpm#uT;i2S&5=^3!sHm=WH-FC%d?ys+Z5 z|ErxXw@+O#IgLRQh1e}A3Y9|=(kq2WB@dbJn>VFF)3Hf(g}nrZip z5J@jvZjUoGea6bhOG>8OD5RXQxl9h943T7kab)Rz)GE6cV2G-G-%XARSlqd(*b#P;dAlj<< zC>sfeZ$$+s18CAl!D1M}kJbY2;Em+4vJRpg*vEW_k4ZYWi#{KWO*(%sZwlh{S^R~3 zUt3=J+I#0=W#V2Ew}&n>Xk}uacMD~Rd+D&B*h@ws1B@Wrtt^RV@5f)@%G?``71v3; zm)ii?-rUz#IV9UTW=hMhl+as--HPK5n%epFp6PZOgSg8agh1#|Ze(ft!3yDo^}QH} zLodPxDBfu!;Lu7@ES8Ud;Pqdh?oyXa>SoazcaizPO5~k}Su2GpS!F3-RuL_T#2afmMIZ|fjiS*NJ1mEei0(y{FTSP1V@SOlJRuq|it6J$m_vd|r{Ic6=H>_|~# zM6=A_N7jC>v6$3md2cBh7c{7^ap*6BDx9}%B)lm={&OdMZPgN}m!y8bX5oR+M;a<{ zg%YX#(`&5Lb|ll0-{V$NI4C*aFM%jhtQA@~Th-<{-iUDfN=r@BDy(c5L0v^J@Nkig z+w_1a_=~dj1FVdaZJSg@W5M3$SE}$tf_nX@P|A4+CQ`uUwtXpd1N$1XTW*H%zE3OC zz~bN;L)EV~>yEIij4D-gu;uR+UBI`7JnvO6Lgyp=*%k-#XlN=IK{%k;jA#<>w{I1u zISSb;%OLMTkDXDTT_(?fu$t8+{HYOF05x^`52n;w3w9_y7{tx?7^Y~p)~kNJZcYi# zc5U7bKOK_*eR;3`@F%28;JQNa!Gb%&io5MjYfYKLi+fM~;Jw#RkqxfONnr>T6eySj zD1{CaoRsc>NvHW0#0Xgew7-Rz7Zy9*R_DANwm5VJ{^^@xrRq@ymknl5H^k@Ufm+~#msG(r)yt7mtiBn2Yz#QnM8!VpI< zPKYW(+dBOhAzf1hLYfjh&+!aZ6hOHm97PGQG6_b5w4H`EQg{>c5R3sI#God)v^-Nq zES?NW!`5;dEpCHWSHdk=FIi7%fJ#it6CpR?0$w;VYt}qoFQPPtO9NrX>Hg$^CS;%D}iV;NkO|BI%#6q_KljOpkT4{ zRFq+8*`Su@&_vs$%ciwVDY1pv%oNqxqEr>?^XL4**jcv%h$xm50@=K&4o`eTch-TH zP@df;vw#ZDE-^&?y)eb~lxRigcD=}wxj=D5BKV*c;7U!E7Ce!}I(5cteS_fE_{pwV z^EQG%!v$>4m7k5Y&`#UfOw;>EZ?z4E8iXp`J`;&hiGsYuc#3#EGsJp3oT1J9Z-aPk zcZ7uCh7w}-SkAZIWj3BiALK(IAyj{6(Y}GKP@&$gpr1-K@O~{J4e=7(?R;h&4Ye5J(``N#vdDH zo%8fzqtC6Wttr!4?pUM;X^ZNaXfKy8w;|*%%Ji24J~W`*ZjD^Ogz5nNT9AhsX|zWb z8x#l235>xBh0gXSyo#pfA_A(Pw(?)7EipnHTYanOISeG2 z>Q7%p^y#5vurD`SeiwWHgjSzuGlG(3(B*K0CRNy})0+cKkZdL~6|eb~6uYBREmqRM zI1~ji`#F+?B#M%W{)@1G5w=~WH^q&Edcew7!Gt2rkX1oZz}(PCvmJ2mt4md{1rsOx z^RPn7Syr5ihLkEMLo$6<`KNPBonxuB(p2;(PMA|b0B-X%@aeN=#U(<#T`Ba7fOr^*`So|Ss-lLEeTDfk=Z12xSqg? z-o=$T9cujQ3cG5n+qmmKGQt3qgrkCLIc28Q62HB~2|BIL8oTkb8-wmrrCo9TcN}En z!D?4CTn_&9hS{}T(Cvfwc2n}1iD@<$6roe4`9>Pj591EyBJzTt4iM?kli~tg|ZNrEBD3QN%-V z`KPmrk*>!o2{SnCY)p{Ay3zu3LE%*;goplr?I6g%enylfrOee}w}yt$olB=;)YR4D z;>AS7l@1bLukUyKyC6_o#X3u}D~x$~@O~r*41&QZB8hn9QnnE%55?LZ)RiPOhlZJ0 z*}}IUkkmpis3ocBCY&(ao56o<&83Nt>`ivSe?(nqbzR`$5kqEFQMS^RC*CtTYbuIY zVfM%DKX~g+Mj1jFPYJVoqBWD9zQjI$#c}7ow^gT{APNY1+4wDZ!^nqHt~i-06P_AQ zuey;9d{@>@))_x ziIdgd)f#sgWYR${teh|5wdY*9gTqArW5H^*=1iTD^Gh{Dw<^p$o7b*n>(4g9W6xY4 z_Oh%*ja=_G+?5VzBj%5UIVGQBrioJuI-l7~iCsGC(b?2Y)YQ!^al#B`-8Ksy9MSbu zwmaJvYepU&hNF)jqTVJ^x*!-jA?}AC1UD0+&aC8|I7HzAa+w9 zbX}P2S=^R7doTq&zs6N}gei8pV9sVp8$g@V*sIr1Z*yJhpj%p@j96P?%251`A$@5Q zOZab~bu9Z~Q61!>O7hY+V%de=39O>B2N*;s(KToGWD%)DowkFDFxAemM8a2ma#I_O z|Bu}nI%K2ijUN)<=2iN+(H|;#Tu3$!!_5D|t(WL9`Xt>*=n!$`N}qM?|LMpoK0xn8 zf;gZI@sn@q88r3b&@qs>_4>(Z&cGDJOe@q8+oIRie@dz2_YL-|Gvze4^@9_k_#bgr z)D>qnf2cX3-Z_B&W7{OP+&SN$N8LZz?dpQd$E>z=P}K<8LAuI5C@r&o#raBBucmVKzATy}_5V$U{M)=tWlEEdtvWSx zWpdiu+@h7WStnDwcG?#}$Cm13#nbB-%mG@S7=nNK>F+tkyz;im zYyTCTJCti(t;e#|h-RxE&0IO0*6ibM-XwcKd77wMwb_0*sMofO@PffNp~dXasdebf zW0pNw3vU3>Wv5{d`IV{XTI*`nUhuE0=gN#SQQbN;j3|9l6z3dv%W8bgwaly5zEp?i zg}2R<>23^S{`lFur)@TB`LC*F6gv>hUwzZsa7KQ#?Y1v##b*J_5JKmp*Q&aflM8dp zx_Sn?eWgqVaAOtAz-4UTG4V8@=}X({*ZTUW(7vy7`HfGu7c{cn?P=Rq%5s?;mJ~|U_Et!B z8N=*4CZFcNp)vhi<4*^#zr#g7x^>K^X#9rN+rq!0QHHsyP4AA_bK-i+iBHd$raFM2 ziebe7=Xaq%-LS#0O)Q}7D2L$M_uq@AaRgU|xnJ-e^h%7wgmYuZk?4HV*QZFFr2e>R zeyTc=n;o(r`^S0tGkYtLq%)w~yJX`MB1ppT4b%Y-Nw7HafHuQuem@@+NbvI9DXmAy zAvybXr^uz{{ln#QkJT=COAzWK3+hQxUQ~Yr_?tkH3!5L~GY+LtG*K?h>EWnm>{1acsUDv0S-Bo^hOPfE^CB zk1O;0G+Gx_doCo8UgY;Xnoelv}d8}X1R)W{EEql_Rr zaFc&f=qJu&fpVw`;T^w4HiKOp98qK0ek;~7GD#lMjJU|exuT4G+XT&?uK@AklE>yZ zp7s4(KELJM-+$jfTrVtK4@x@#Gd{NYUK0tffDJy6NjU^b$v=F?k6&(AVAVGEG`yjG zKHHgmpamN&de;R1`MfhV&mbEnuDwh82o9ZGKll3G9QT_&?^AfK@bRn*3S5JMI6F!` z0h_;Vu5tci#JDAWdsLsh*Uz87@8Rm)k-uc){5SXhUOlx--|U;;Soz8h zHXf;eXG;B60K!bwhgD2Dh~8UrciqpCIroA;QwA@QtYgasO{_3&b`#!nscnGjnb5BIQBO;I9n#|}0sllsJVL#NVM4DsDOkR{{??257 zA*$lYhy)5%2K`)Hxy&4>2t{B$WsYz%B&7)x4Hwpx!Z2+I5ZGrSyI1$Q_Iuo9aA!(aLy^~Sul?jC3aI@D)- z?ii*2@Uet2nK$!Sh9Ntmjl1Oo%CKVc@C90elL(0e`Tb)0_XMaE{Rjm%NOW}tp4K-XAw?MWQ8|qm z3d%L;a1f2Hx}qAGzk_A$nxYhmejfa8oaHuO2f*KlL@+uNT=dJSfn>E%GN(aXg2)V5 zp`v*bZ&Q6z&8>4BVa~8+(h$=QTBAI z&ZlXJForjuJJ?ZNqJ3Nt>rQw?5(wp8h2+&lB$g9w^kd$UfjmqG;r2($3MWpUA6O5v z(jA2Le|nM%&1ex{ELn=j(q}{n+33xdq-SyM9yAE1`hDfuTE&l<~GYd{#l>luP{Qbi~XbM47 z+d78~;0fv=6<##a{r_RKXNvuCSKUfZ49vNrIoFc zE&(dl_(|OG@jr(WU2{=b(X5_<{6e=w0iT)tKBZzS>-*QcFu8=x1CUEU{uWA`m+UTD_RK8KHfPhvMHHBb>Krndfd;g+c+F92bn45D?d-}6nd-|{m826A zioZC~7r0}1Rf^^_?{tZyxbZMsaog6kZ3`(yH8ipdeRIWet=VGCTXA>ux4f|hWxjxK zY%l&Z8MVOmY2aTq-B;i{_fV1MvaCQuA~3zp_7GT#i2ve$7^Fy%N3{7OYP-VbEU?#o zc{Y=6{?W4)il-&~fx{-mgRQ8S&pYxklQ6=W^Qw{X55*oksu2TTow{e+nV{2!%78#? zM72_yJ^k&BDwdwQ9{xltrc?{2;IhY1v4=PFbPc^;;m_;8k?LeGzn^y(C6R`fb4cks zznG7l#%jT3%~FM%bT+EdHFY+6FXx+7sa^tvJDY}apE~XC1>%!{H~w00Ak1^X>}9#n zev9feAYxVh$M@&jupJ0=oXP+W*9Lvf{Ur63Qeq`Qg83*vksMhj+~QzJ*0L5NyXYK2 ztRND{3z|-dN=@#PR##UGy&Eio6)c3-d=&c4)+AlR8(8jx6v?pGNO*y^7Y!!37^QD? zRpP9|RT-skRXIUh2KECkcq{y^b0B;O<+;$0^|p|C{&z(_qVLOnIXDHd|FOJ3iyvri zkq2yA09L+(R}MdD&U<8LNDPB;5212?|YTUOPHKt#;> zYnOF4eLt45svrk-<9dz3cDV*k`F#c7Ho_lVRLz8wRtvVL)b=N)@2`$F=v#Xs-Gb{_ zD86`kKhXrsJU~>t!86|Ojs5Jsb{{9!1^19qh@R6vVb1v9H5uMwtwqVpM1Ad=K7Occ zKKV0A-b+p0spCitKRbjQv&YRz_FED`|8+-SIfJq>%n7QG+bp&PPI-VlTp7}B_J1!K z;Is4g#Fr-0el=gz(~l>OBVcV@{odE`?&L>*SFst;qXE=5?o&66CJ(rXXnkP?TsF7@ zcI6*E+yIBx1{1#2Q4q_I$>C8A zJfKwn%U$vT^Ge97GZc>+khc%M^uK;v-~$jSx!%DfyZLb`YDf{>OR-jz(ILahQ`9&k z!A9910z`7<3n&?UII(Q(!K;sZ*9Vl1;mykO#NbPR=P`&-sTWd#O;Zn*7~l#!#!?AoN96 zcM@W64^sk)dUo%;>#f&1-CJlo`2&tL z?y|11s9eb5z8=$@Mn}Tgcl-AQh6AWcHuvYakDG7+7qp-zL(kI?hl=6ujv-GdjXm60 zk|$C@iM8Wm4?oPrGdz0Jte&?%(9kf7h@ zC3!MBu&= ztENDjjpDmr>^y%F^`6_Zireq?DMG+XB=1OvbcCLcjLxwa$a1{=Cu7Ln;AMxoITyC1 zq;2WbGT_gg5PkxE1;p`&eAcd5+DGOU@nCcQ=wDpWK~y7}udPh&>JBndAN&;^BWAwx z5B|g`Zb)(!Zwq|MFxw+3i)a$sIxd0Gh2-jglzP5qP{c7L>Yfc5s(s}NzxduNji9fN z;W&t711;C_8U}a==pkY@%MW(@9Gu!WMo*xs!MN+)zIxLxAutfYut6Cuvuk>DJ`m^k`4h${TOAN4zwOGift)EOH)^MDXKN=Dq5s$>V7BDbClf5jGQQ+`r zcw)+MkOJQhu*e+Naf2RA?R(uuQ*sZ}X7km#yV1s`JW#*n8WUUxsBRpUxYv#t7J6gB z8+VvfpFK=e$`3?qN<$BOeEURZyKD#KxYL^Nfv1ZUehNKOvAyL66 zKz*S?8gTUQvtr0cydu^`zx|SO3nS?>D*0mwb*FwtJpiZXvVr4-MjxMw)vv%_0tYP~fGAO^iyFR~;V8+UjTXwpH6eAz1|!*`?p`#Z}>Bv9qWx zHEv6^5*Wz-wa%*C>@wx0M9Ntfg2=u9ox4|`=)duGzUXF~_lXY`^Lil!X2)3tOUsG@O_dN<+Tp2dI={>Y_fRFi2t8S2mc=RI>8 zt^G@f_0`@!f~hEKEI3{|?{NiZR^j{24(0M?B}p%a)zvW=PpP#?)JzoYyC2Jkanpy# zo(@_VHDAMrw!CG_$kP{F5}sGb;8HP0aoA`)_1?eHMe3^*TOx%FV_tFB)w$g0!`x)R z`#&^&WmFu|(k(i;ySohT?i$?P-Q9g~4G^5*?ykYz-8EQn4-gz4_ulvY>mOD7)IPmt zR(Exsy=^P6b%RYqv2>dcrFt+nROD9Q#ug0Z8uEiJTiux(Jz@cjI}P_NjU4tO1>oPi z*5a4y56@fAeRGkaE05Y4`SXLXv!o^?2ETgxtQ1(U5v+@`p|p;f9GYf3aVFoiG^E2J z%9M={`YPLKdw%^cVax$UVDSry6_&2BnJJZdnzt5eKl&Rq>3|#C`OZaRL)U--yp)#B zBnKf7;G4z3lT7B)O2bQSs^;3xBbPiOz6|JFusw{E2uE!vW5{P&?NNNH@O>wpzveV+ z7h?qIh=`CXm~1YXlth3BN*qwc|FZ)om%PObo*TwT^6|;kJVUR%(jZNC9RuK z$lVS-m;Ch}?3OrOFZ+#B(@xkadz;|%%mNe#&Q)iQNIK-R^zRe-;T>4bri0P;vnW{7 zFjFGt04O!C`nE$gNK+LI2*F~tHrKMO^EqUqS@WJq$gzuH z-NU*QJ}nm@TL&MHeo110dQG6fh zI)Sz=31N^Oo`a7@Dv#*nBdkS!*u0<(rgma+kof})3MP= z_JPRQHw#80qJSk3A3cFG(1nPMGKu&ZU@(IE##g?_8Ib_EtGST&KF>oG(-5T9nWhU@(WC$>u(u!$BIz3AF z>#;O!+*2o`!8H59@S5PVCAUf66bY&Fm0{!#bvW)vJu) z?Yef^ai`E1@iD~o>I>-b?@z;Wf^@3=fgVy{vLWfa@08BTbbavim>Lv)E;QZ5jS|>^ zt;mK+`e8Q>KKa8b6pTPgKJnB<)+s4<^j2f?at<~qIL6^9_ET@<;5Gd|3V9BD%3m^Y zfI~@5y5E#75qpy+o_p)XUP7oAhPD0`R19A}$xk_5!IF{LIkeSbpFg!nzqiT6-MeVa zO%R|tg>l00q&SyXkFgRoMYGAmx}MxfP?ZAe3X@;U5%^;z5I2t^PJZ%26AJym;093lcUCy2vmF~UcH$@s@qTL`q_*cLiFPGz0#Zb zbKUh)8CM$uI51fG0pr`Tivih{mhwpeT^Jc2NQp(RKeJ=KZF!jcQRuTn{~4d#Zf_6w1t1T! zt=N^ps{_S0!HIFD0@df=eVd!t|!GM zoI>}3y@sL#=0M6H&tP|v<<;&f7^i;wvQ>-jMPyDQG!3&^ffDES!Qy^3tO?vH1v|m% zP!Z8U(`M77(^iCUW?_F?HP9mW6GXnKsq`x+z>YF$z}cEhg<`p>)18vQ(}QhBVjJ&s%NevcjvLGv1 zm?WH6j%N`zu~6WK_1RPcJtfsxB5!Z~OEcF0IIFbCR1&fnC`(iz-B1_Vb9S-Z3x`?) zK~IR*0tXxn`g(0RCwOnPP$O@%IZSoXyfUr=h6$Zx1G%GUt-7k#9ky#pI43Ar z8E?-aM3Q6S+q5}cwqkrZ_@)kYGNe+WW$EvBteggjG$^wIz5#E1SWF)Pt(Yk0z7JPH z6b@O-&2I>Qi6JR(80(&tL@V)cJAIL^b)1;o4YK^peb(tKnvG!AYD3EM<5Q}QWRR{+ zg&~17u)APn>=K$^HVA#lvn&$$iCp_aeUPLLjg|dw5;LmjHczxbAOvlM6DZ602ZGLk z6z-bnp@Co#3u=QETv4+21mwieLXM1}at>~GTqK|?ZlA{T6 zL!^>C9T=L*1mPWKKPm2csSC}|F~XH*k#Dxz!;?}Fs*sUl21uFWF^eXOXqD$l7w}>{ z#{7}W@U?)LqGN?ESqy)K!=$ZOmkCFe_)^R{4?{9}Fnbt47@HfCv~-#hpSGfe23~ec z4XmIT&;Pof32rj|O9NRn6C z(KY_Y7PeFd!I;D&d^f{YTbYxuO9gEUTmw%02Fj&xjSI_^W)~m{!dgfR)CD7jACTsC zlVSQ<3NbqmH9&UE)Lju-Nou;QP>YdnC(-|t4G1BNw4-#2#)1S-YGQAPgrU4DUKmNcuXvS(7*Uaqx{4GUToy*{ob^j}Q|o{3kgh)-1DQ$>_X< zx*8DqX_$`|g%vK4Jczvf&fiqysR!lJjTLJ=Qd0^SVBxUr83>_ADYc*+c*$X=rqL}? z7kh!wR65j{#iGjcdb;a3z_LnOc3l760C0A?bqT$wX#J*tdl;l_A@t>tZ?;TmQsUhp zPBPTgdAz0Kqcjnt+(9X7c+lW7zCi(aN^Ht#nKB+#6pOkZ7$A5uMRP#E=yV`z^^VK5 z6KAeq)mY$ks)kjB0_?|Y;`{u;=l+`C}yWnhYo&Fneu~pB+gUTT_CVmBUh10)x_Bp zkgV%UCXxJ^o%y9|t+A7905L~YCd5eLBU3isOkj=uwqSUOYrlLbel3h?0|+g~Yf)Ds zyF-jXSYS99kW)s7Qo)WlD#1KqeC+zwO(C0vtpyV5w!l*<5D6qS)`T0_mMCS2Ho{*> zt|pPIh=mluHqbemEgw}N8&N_Ji|~dk`0iOw+hG^pbXhFdrK{-tA95B`G_ZrbL5Ss=Nr9F$(leQ!xn35yKJ9-&km_ z@B)m%D48Er0B{`W8xmQk6$KM1em~>WSCQIH8G)tH1`Gj0II`3FE^2Wp+(u}^22isL zrKNPz<3t)q-a@SM|F~1R_JQDdA&i|Rcu|{Hd2Tvc>G7pMcfGvru41cSqdF%v;GWXP zDgkSwH<%^h9L{_ImT9^WxE7YeYJ47&AvHh*QZeL-@`#={!s#~EjhOfxl3J1bPe^tA zd=(QA{=*W{i>7Nys`DQ#LKt|Md@}Piv?XnouX844IsK$zUZ_GiU)rtQ{~U{xhq&PmF@kykt%Fu0!jPa)%H)E<>@kfI z=_fZx<-=3awz#N7t*7)#X~T-1ubNI%Dnq;qDd|VZKrCpEV7wI7q7;RbB4UO0(1iiI ztm5t?cX0VEJmJTzcJD9W$5QX8$+dVk0n;)Ut0aLsMRrP=3)r!n9g zmz66C6<7O) zxhWsy(c?haPf*m1FymX*QW};3+Ci%RrIu7J~3| zfGJrW7!HL#h@3@JsNLoetFQ`)yPE=a%H2BAtweD670g&SgndLEz9`(4MOc(%w4io$ zfcn|cHyG5FC1>q9vLxg^wd1?oxFkzw3QjRK@n}Ya5I)uMII%FqCd@UL6~(${aeG_Z zBmf%>46lj2HC!A-3A&rSWd2!4@Nmd_Xh6tmnljBbw11~>NsfD3J$A9NiEE8?Qawnr z2LC(WB^|VWDJmMi__70NA9~Fy;3MttvJayyz$w3980rla?2SwfwuN+q7!J4>$ko#% zJqr^~j(TT1aEk)lJ|Ps5_vK*(&UtF6K`evminuU_uuFW8A*T{IX)sDHegIYOa|B^% zf~BvNgcwoo!rWQIUeR&K>Jsj|DdZ~Pl_M#ziFKL-i-UjSvbI%&f_)Y#PYP^o5vnMl z;{*;dFeTCd#EW8!O(E8T0XkKXZrDZ5o;%1;BwVHH5LRR1Py8nadu_R31kupfxX zfe!nuh=&4bTKnMb#)Z41;yk|lL#oV$$yKhj0 zfa;J9`22kxxew)Ab%1He6gG(Uc$b_dAza6$*;D+0RK<*3i4nFGtmu1a2A+%pcoa7h zZWCYt5;XV+Lyd#9pvhL!Y98;6`y*^vLS)Ya#!WGFwy#`6b(w0PK;Q>lAGnBnr5a<+ zeH9KWqR5-9xb!!SZ84IrveJ8ivIPWlUllrT`P7$U4Zf*4;Tg)2IaEf*KS0Q!2-t7Z zE=38*IYeOuXT{d+A9oN-AdYuF2nOo1{H9Wib%+9|@Nc?2NnECqk_aR*Do+0m^OC>KXr|(i$|o;p^NM> zh}w;9&AVPTQyJOFK&O++M=Hnt;5N6%{*K+=%`_2q5i^a}AeMM@>OPVhoG^ajemdmW zi^xKV+B{{=3#IDSObUOFc));~=d%^^1g4S%{28%=NjeD#7Sk3cmBVdm1WOLHMU9oy z?Q?H-1ZzXim!I481&hd^Jc8a6f~vuYaRf%y z@ZKQFB)pXs=NK`XpqzCI2diZ#WDDv_W9H$J$FtEYWsJvy+k>}@^SgS&%E}}vO1d%r zl+KBnk*Bjzx6t)zMb@JkV{l0rbJ^x2Aas{1pz1&bfwj$pEt31!;9Z&(UZ_i%HHMHQ zaBb^COM|p)Lk#=a`t2ck7AB&(*OSQ2Xi3Zvdi9Pa6*Jwy?07az#jZkHec)t)rcyex zj7kqmwI_Kc%CX9DT>u_YAcYuJ-vDegqQ!!?0h#&jxn_!Cv9jzUkL9^jePa}eC`2j> ztO<%v2hsoowJ9YxINCL7W$V!x68z|vqsAs2zdp{BXI@AM7AJSjatM5)MLvCeve2b# z3?rkwF%eIhRJ)kPH0IqVT!Lo@6AJ8|kvlwGIUf8>Es?o&yz`d~u;8t$c-l~>#E!q9 z1SNw{AboL?^2DTp6{(8mNs>ZG(QcpPq00_RF+z$@jGoXsTp8~2GckPTu5gSd z%7*RJ6MjHo4XfQ_W18JzQgdVAII$xColRsV-m`IHy*7UYvh9QjYXi?}FGfkevg6LRiS1I~Zc^2HA>NjK*+Hq*9lqRI8+ThEPL%fJlDl zDYgO9zH6qIgELOTW0T-hqn_CPwMn6joF02?1hT!CoZz6NQTG$(XF=WlSfIBpBs%PeD%r)en7)b4w)>?w?`lku zrxj`u2H?+N>HRDDO!(w&*bvtmqdX&>^b<00(83NvouzFfN~iD#TV|zo65*ie9|aqZ z<2EF)3buo7nqiiZYB4jpWo6&c)Gim^Os711sQWT^JVv${9n}VVHW53C`=_t-mRa(F zIV;z9ZGm=|I^xpH`g8M0$5zW4I$G{8SVPl8i_N@&!tYu0)qM`rx6i{=IRe9+q6|GosPvN(_r*4pH2faFgB9G)#ARvNa$ujWk8==NU=uz-9r~( zP9aclBU9jBdEp}#YSyD z2eb=;&B$lB;V5Ee1ye9a>s5V%fs)r_0R|u?h`9|Z_ulkjo2fsE^(U$on-$!KV8_ue zO0Ek)pTI~Ue2S?NewTsdr3&N-k85s=GA5I6Ee^NlDi63b$PiK+5Z1Acw_3VQ5(rS^8RphlEN+92PW;{wZ=T06+WNy~Mf@u|$#TQu@G%2hi^0|JCd>kWMeeBF-@53Ct*EPUu-}9JNjXJAG7wbv zc$BIQXUd~ZTG(ii=IU7VzuB-8%kvvljofwe`EH%6)X=$tN)0)!yNkCiB(14ouyozh zu~SijAs5YKkS|kz=qN0=Yt`&p`N~#LIlCx`F0$kSJM{EwA-Bx4p04X_-1Hckf!nqG;PNPW+BwHzZ=12n*J+7{MFlXqb7_ zjLMUU2gyM(7Wb`=zH;711<6GEoF@`l&3o+0E3?tunv>icS69y?V?cc5v*Wd;de835 zKVXNIo5e}RY2@ebFMNaI$NV)auTiF;jBj*>OG5 z>Cqlumlgwz_rA;+yC8y)99fpE-%tv2hFU;+gyfiry2C!h49Ll`aSsjBtsMIbk+^)$ zC!H|;DN5B>?TTW-7O2vL-QTJ~RbxU}_^PIp*+vLJT@{ zotvr?|CD4zXUSXBy_*of1AY^k&s9Q0UkyJBz8mV0ho7#lU9_N{&OrxqGbm|5`~2!U zo2mAY-yj$&o+Cs+H{Nt(5Zf=6-{-beRT*z~;gr(>NBKrmP)v2%yqPWYW+@MkVVo}D zkuk)Rd{)4_;b>U~5&*$vVk_%lQw1XJ>PpQDwnm5%+=f z)|2QBBMS*kN;(KJ=CyY^!iNJH!b^{AN7t<A$=Q@w zRtve4;EeD4`F_~dsCC~L4Z_WIH%{M~0>)p2(bnn)~(Dx;pOt!v>9~{|& znkkA*0~mc*w+|VM4PePs8}5s=HvX0_AbT`3Tsk7G(_i-0!^ruK)u$H|;XjhvNJ|aB z=tc?IR0S^}!*<3|T(!n6ca-~S3<;_{8Yb>0X6uW{3qmo=&`30N+TPQzh_yl`mjxo?l%j$vgos*&*&xxPfVL+PN65 zyfeu+?=YXx2$79jjSeCC&H9ao9Ma;eWED-)A);!GhX`7`02Trjkh1h7{M>(| z2Z^h}#3Q=R*ToNr|9Jh6po*q(ze9a<7Lv-!%W_Lpvp5l>T<2yXiA6Zq8Di?cL=$Ei zevT{Ah4{FbhZflU>VCYeR7@lb2VI%$X?CuD#{L3z(Y%#vBdU(`dwI+|B>CBIT(p9V zME{aj!bZBc_2u1xFW3vnRNybg(_XpW(XxKV`&6`-WP^rDp4MBN(~U#Lf|fcX43ila zcufpuX%?|MY58@C;g11bhP}&=wQ6)Kyh!pDPyvVkDTRUK>heg*w8z!>gOc`AdG|NX zB{)Ci6^{;j>c2j78Rd;HdX$%Q?QL0j(K3EhadDYHSlR!^PQ_JUSnS10jMGGxP2Zm0 z9?qKins0TpS;~*p&=F9ngutW5-1_0HNVLAd;e}rwX%zCY9%*oCf|S>Gs=)qUVeXDp zq?JR&Riv>lvz6+4=Gx+U)x8ZgF&}8A8bZS!BKYQ1ck|Qu9S|z0(~J;KkHDkKlHJpR zI{Bg7T{fsI!OS+OQ(EB;ZD@liuvZ@)fAr!ReR~PN_Qu;0!sqUPL+Ac_Y80e(Xn|sk zJgjNW>Wv2WwKH3qLF1;h>Z*cFe5x*woJ`?aj+}_UeOUUFo#OQPS^B?PZz;y zl|Fvb*c$5m4oJSJ`QL4Wwg?Xvrg2Df|LRoYsB2{mc=2~W9Z~Y)%a>A8(sU&iOXE*c zvv+!~PPUoaoV1=wt@dZ)rMo}e8>aqE{vp&)Hr2a0s$%D1X%1bZ_0{mz3-{Q^@YyiC zmiS1ly0K>~csH5huieDRoKsW9*2QK#`?~TC^z#>UD%hX3?E0-Yd(K~rhI#mqtId}C z140bVFzfm9Jnk5~5}~Fk&!Na7^vagzA&T5`DWXfWOzSX8MCA>UA02;(Lr)GQJ`| z&M0=JkOOv!GFrI-PE5=QFgL?aAA_C(>$b(#B}lmb*EzWw0Tpg3)I~d!M%bRM>{N^6 zs1)ub55snE=TFTnHUW@*t3H4}Z7UPqZTe;n)(>~aPqB#Pj@Ur8HScjv>R0V_J%8$D zM;*M8%F|V}Ey11hdmT%RxxGse^J|+1QFY#DWo&xnO%OfwFtTs7?dCt{Ukxko4wyj! zpRflcq>fvX4NZF&dDwiNpJ&!4tW)E5>xE-cgN@o9uf*q-4x|Y{j!k`XFT)r{Hdf0& zE!Aq~Q$N-l{67WLTsF<)pFXa;uk<9yO=S%UenvQ>sdMUFqjd;=FJes5@$0o#e zY?w6s3SGMNVrfY>N74&qkF3&Ux^#VHn<9JY0;jJWAP9gM+zm23yC$g&}nb;r9rX(H1tqtCOMKD?zp0=X(#T z(f6hfEkekW_PdurG&py;_2;OKM}H+MaFj3Fk(rawkdTl4L2fWa>^pU=}z zz2Wd-;DLYZ2?rkF#9hPOqM{D=aG2vDZuUxnogGB^Zxk#h8y5YO0g-v#*{y zFFVIV6VhXy`TU#pLCc*2->>@ENe3D@uX#x%BA0L+f8P?!sk9(>y>B6Tdp`Hvi^i3w zE@>UF=$tjs7k{LKU%kwAwd|jLn#zLQ#tPptmDsRIz?|CZ0kcY z#bh{lKB=+k;H=;AX&c7a=M#vk+vLZXqc?~XwEN8^9JR1hRPXgp?5l1fnO@JtwY8yl z4#NtchQ)QC#=X4}@T1GA+XNvJeFV!B)u_!YqCl$y*KehZCPx$$JIoz;w<8ITik8_56rElm?Xm}Ff2W!l!P{+u#l|8lE_07Xmv zNSIp>zfoJ?lGp~T>0l%nl@~wEf3*p&QFPUp=qn`UTc`af|Kseg46(f-7;B=C@49;I z`~Nv3mj9PCA&biw=c0O)UTjAJHGDA*etM*)68lew*l|Q5pJp0HzOb*IEqAx8c-JF# zQ-_a;ny-bG+iwcueCFz#28;)pMbAr=7p#? zMkQXwnQDYAH%Gf4P~4r~GeFnqK`?MnE))UMikq9?gxmW91cuj%mVS!W3{J!dHgg21 z*Nk$!3znUR@)62zN_p^POk6JSnWWAW>mCVJ4w@YWPHiP*zOuUYHch>^w*@Afe=t6- zB#gf?-FhWXk#H|~{b}z0elJRdeCT&@x^R{Mb#Dgg?gX1tg1(SbJ_XC({(}rI{e_Hu z^@ThPO|n5Jq8>S_0rJy@hAnxw;T2)1z1}wEH5Lf4(ki=-d%bOIAqf(&wbGKljMKXx zWqcu7!hX*maIBv|pX_{;ju~9hA^zfPK#49wW?< zySF~_Q++z*$fB30$IDE6TacdL>u8aur^nJv`*zUQ)u*V#BMRLGpo*cP%TIWWpmpZ& zO&X*rpFj_|bDk3zl!teyMw<5TZllP^nkIp+Ly(1I(Ea3dS1r@*U#0$!Nu?c<%RB=M zy^~PN;*$GMe8Knh>5ma^G2B~~(o~fg0^qbXo>^Q~!UAJrWB05)2F_<7X`bg{>n{`D zvo?l;2R(e(GrHu%LN?(0m@CR$JUQ(5m(Es1X|#(?PNaqzO%}(D+|<5D>ynUbnpG@+ zJqFmcn@e@MJ9<`|67}tN1|^?V_P;F#*wrb2-ir;A9%-`^v>C@Yqj$An8oB*RgLQ`j zDb?$}RO(i>UJbaDy2ri&)N$hP*OIJ@6=1$jR+|12vW>-IP$%WAUE`d>NJX*mNY;=n z>YOqzs4P3j$_|gs0r+Wq z->C@g(mW7G<6id8wCRON<-)%22QMk5lby8a3A~CSu<=()KmeEC#I)ncg@@nvzUmx! z)WN3-XI}iNQ(|sVo%hOpAfc4NsFBe8F{?UA}MkDQ@n3r$X}tIrKn50TP)V)EH0vxc?txp(AN0d zA*-WThRwpI`x?V04 z$7HoR4X1%g512vRIMQd4+y}ilzO^K6=Bn78&**01rcstU-%+VxoLjHV>dr=VB&FC< zcHVjk+oog1Z)q}Q7{*zEz8laVct_*UWPnJ#?&DByV$3n-Kq%;`KW+*g&eZ!dky!P0LLb|1m@*B zHkG?Wk8$QyH*BZaUF~_tdP>X|upensO~Yd2P{a6ljoIpN7SC`?fF+6PRo% zA+|0hAC%e7SKH`wSzeXU2nDHRg{ioMn2alF%Td48$YL8+g2_()q0Sxn0zJcVPZhZs z5ztC#XMz|8@ z3gGV>O^}VZ{}y{i0&|# zWgAcxcnX zP~Xy2Iy%sOYm`#*-9hdO&UJr9ktm^ecoBQ-W>Ml=NGAJAncG3Sr{pnS*(nwN2`>pl za0=J$(y}&i(#GoPjqU@<3?H~JJAYYSg<0kBqQ7RC0ZsrM1_KPmkMr9K2IK>vq(@&i z@13*~+m^w6jcgjg=bRuemce}Jkxo2UmO;y0IhPNU_^76RQur(&@CNZC$9(Yq`Gya! z9C4R44iThfP!vRp;5XsFvf7mF_5X6}EylxPNuD&rFs20>~s>qLeVtN}65 z;|$=taM@c$Q{}Ld-;Vl!yx}+gk2lG1c*xcF`{Lh-!$`1oekp~UI$A)@&1z8>GJt(C zCL}H@zxV|}NPvg$Ym>f$)5y3NK$h&7+{V)l(vTfF9-PK4)A*P;TgWZZ07PSv3#eKG zYY}JnuR>sl9U8(O@D*aN4z8%#eK~FVV%E79WL(sFIdU+4AMI!%O=&bQ*}O1~dU|UB z?eU@K%V2@R(S_{*L5KF}JPK#QW8pzmhs+M@6_H5^m$DDZ+Tpe^9R^{)-B; zcEOg6@r9bqZs|HAKa(;3>lMGkjL&L|h{Mu*q(-FeH$0|Bj3ahoP(#Dx)QQ1S@V+nG zQLtkb=Jt?8uj)PVK-c8gco1-8X)XgFUrii^os;7V8NW&LKr?@nR+77D{<_`|Wog?& z5m-xO_NC}0JFnn+PcL~5*U~A^KAdVQ&+gC$yYm#X(OzWjPjLCqspxxFT;OR|Tp>OS z?YHlf=UVQBhj`dFoJR`B3*FPq6b)sY1VUEaFjKIvox|TGnl%M^TxH&ZgQI5 zV*;!M7e{v-l+(Us+xe>91!d78)%4qdgSSGt!BLiGhU-p=7x9o)%Lm4$7zyPM>vx(F zwu&Wb1`K)I!7yX>PawO0^=EVJ?C8CWQ8#bTx2%I?zTw_7tMt?7+jH*pR~ujN%-j_Z z57E=*LPew1vIn0)9j()Ko1aRh+(vKyE;_vm-7RB_b+b&fGfIEe_3U(fJ#!6vDi&Wz zv_^%GXdX@vKNfr{ARXp!V$^<^dRp$lI)?9Uv05;w%}F1h37)>V9e5d)oRLZ(V7N-j zk$Sc94eesoN-uW)a^&Z%C6_;b)py;)#Q>PQj%29C`LV5%OnmGu4ada)9+R({GM@pK zG4N2GSTBec^}bS^qP)P_o*LW_z3fs@nyn^ie>J#4uWdC$SUI;Vws6eJqHvkPh4=;L z_9NHDzN?}j+HO84zfpW&F+1(|jo#q}BNxbgXzFgu>@0aco9YRBdwBnw!vS)A)K_^o zlNQLkFx7}t`L%+G-7C2`qI-;H<-uHd^L}X&A{e}oOHA6>RX{6VGs@Mxb|#)(*rIPa zTF+gfCCocii@Zqlk)! zH4DZ!*zQc)R@JbYI@MO!OcUfpL_TvyFH>=qt$@AO|3ozvs;x3U!S-(h3fFAcQ(8zR zA?<&>0IAdwi!a)jCPamO1idX(qN$#uuy@x*X!+^bA6cMUbZk0av6eh1HY9VR_kUWp z8q1;ysBF>VG#PI)hkMN_&2whNXiXpp51jTJ+aiSD7j8wSH-*^H{{qin&4fV58+&KO z+~J2+F?Z)K{hq+_6m>3IGf87#;%>AAaIxWxuu2IIGIw?Y?XnUyzq7t?|QF&@g+~(&sw#r2Cz6Z$i!)JShfC59z0~C$L?Rb? zyCUcTf$yVh=YA9z7G9isFr7Fzq{J{6T{CuL+|9K1a#T;SSlQIxVI1>IBQPpdp6$aJ zf^a{!d)i4jv0@HNkt>w}eZMv-CVCG|Y*F7hQDN{$b9ZWBO|Y!C77u;Y1`0zj7n(X4P@2#|?;n zq0X9`YsOB=AQy_*lx9Rn{MZyI-OJBQtKIiP;e-`3?Ngk(Bqa5vA>27DD6)HQ`4<&s zBDT28E#+EI{iuf0cvT)le99QP`Bpdw%^HbkO5Lc(j3s)lO6>tY6C~mij zS6t?l3|I3#lsdmqYj=2hauzMGrQrF63Oof-R*7lZMyN?dw1d|1hy;5n zp4N)Xq>XefG^`dVP`vrAcJ?RlNm)tN;dZjlK!S5Qp=?>gvo3Hy{--sH)Q_GAs zp=Q}jf@-@_rGIOdy!AN@r&~Q4YXBPF|AxKXDXus<26)~BS|%du2=%RwymWW$X<|9s z>f&4b=a;+&{?-s%btk808W2Ya)=tIIvmZ=MwX?DR-{p*^B^PafTmMfG5#?Sd(`H+; zMaCx1`{wS@1HZ|$rjpIh_|M6jS?`_v(%mn?CeCk@*B!`virCtYM#Ijb6o0P64)p{* z18J&&odV5)`U-ejY9q@jE}Rzn3O?FZK>F*cuu9!{IXaSoq=~1rDRFN(OMQ!9{e}Hc zvQyp6U0W}y8Rh$4$rpp^;NEZ3tN(}xgDv<;o>b-ispI5WQ9OXul@Hs^uK)zdc{78w z=0IbE1(+TljMWzx7fbzYJRGZ$;mn}h;mlj2%*dPgsdmEy&u&BZ9@INj!>DMwKyE!@ zf5APz@EsHr7|pYQlPbR3Uo5r%m1z1}7UPM4fpv%;j}iFMXFG%vP(V}rbRae>uJ`o^ zbukx{psl~tIUO_Wt-f)I6YLnIzVT!@{dKbL!H@Icmvx&FRLA=->w_w;FJ&eF<)cu) zW$Ma5db(zM@EI^nje<8=dF3k!%sT>0=}v{Zy(OHjR5c|3Q*J8M6|Q}HThQ_!30-jP zg>`=oT^QkZ=fc{o*_p#rlI(mZpSx6&Brw`oSGPZq<0tto$FIV;vqHX!9zpa!fu_P3 z;hxbu2>=jFq! zrn~!U8Ri{AqhcJZ=|iPwpPcu~n14;ne=TWJTIJsr9*K>CaSxQ7cY&i+PJ) zTF2KjO#W3Vh$rjI78^@}lul=N9Zx=gUj&4^tE&7uy=b)JX-EtJ(>Q!@?EN_W1%cOw!(Mv zNh0a3nbmtY(C_y1@(hGK=hMNzT0Fn1SX_K_P#DOPF&=@}Cl%V8xTPA0=q{C1c&mNW zt|YM&cnOi`zVi0c$Rg;m^>Hk>_(bA9%=otG)ER5*vk z$Z)01`094u$8JhFr|7!J`(wK5esVC~h)|IK?Zx8d;)M1+!HU^X;Pq&E?=Jl`h_L5{ zF5vcUcGl28v*(2?;9+@h^8Tj z?w@;A>A+gTm*e+aA7A&Uiv;P}MPUU!dBcyxXPn5{_}tRS9e>Urx%stTS%z34sx65~0MuI`2&BBA9z1|*Am)uMEIX%9?!g-}T0-tyDdwF?5 zcf)QSw|cfnN8KWW*M>8W-h4j)_HU>jo-V!WP8>OgAaCQGa+UH#fARiZf^HGEuaA`!BKGD>%8y=6H)h6LZ?T<^lJ>ti0msaUI1KtLtq%mZR$E;~tvrHmW-j z>SCFopu~;)suw}~b-PA^Aq_Shr`f)<*n`zFb8_Pg|2!*Fb4x|bgdA7Xm#KrcQJUxH zxAi-iuc<2>ZefM z(?`nwrg!cj?H+em{c1yskdqBcXx4{k8`(G?10&xCle8WI|2N$9T(RpJ;lRIt+&H>O ziwu&eL%N4G?u-a;*B_M@n})BgAI>Wyl+W%v?{AlZtO$I5uAVP1a6JRb=hW|HdT%3L z@OcH#aqKsuEsr~qvw6awd*{r}@B9IWpN*NEr_dMoGLrv-R#Z3-WW-UrdhA3;QBrD* z-uhKN-(i%V|Ey-Tj!rMUFDbox5_bz`?Ff-wDf}MT6!>^-Iyf8u6GR6alt(#qdUo@d5O(kBRQ&|T<{yXPsPO&!GVrK=H3iQPurZDz?)Egth9wNRGKebP95fpkDsZ zZ7X*YB(vIY39Lj+xpRVYN?AKDeBB4QUizfUFaC-{w{eyCL7(X#PmmvDf$1Or+D`8g z9y`}bjU!68CYfjBNsRmlN(~qvQYk-+^M-wLKHu*!&pdzTeSGzaIq`aPlY+0Am{=MJ zd>0n)=baRPmo!I9wTgN?sHJ>Sm4Kjh_Sa z6X%Sct>kcQYO5(Gt5&A=rm4e8i0@rD)|;`~-4$86D5ye5-p`EpIO?uVId&Sa%i4a} z?k73vBs1+@w>@nBz3d!aglWSM%_6+3ou=xG^!X^hOokIWuA4o7(dvEKJhe*5Wk{$` zc6nC#e*v%wPxci^x%{RgZhQWc1%Cqh@69a0@zMjA5;H5pnk-2tTar#tR$kGj=B8!0 zo_MD6rJ>LM{oAA8Ofx-yTcmnsf0M3U?N@m0LiRL2p~eSuSNQnM3uVq}vH}ZhM_)Zz z8tD9{-&Bj9s(G3SWL*3Wyqynv`ltot&Ss{wPXEpOx%9L2(eF>MPEP*tXffznt#()%$Cyp2$MKfwx!XuQdRR|?0cRqOZ%F}w&C{V+-UDpnfgoEh^VAnXOXEf>g4*qmnJCj40>TT7?Vh+49rakf+79cBv)B zdg&i2Jp!!P0H6Bp^!_%WPka`){&UG(PcP!ybmDvL^v{3A?CtG8?fmaw?rN57+7moauM;<&qqA&i63(WtVHhkBR zZ})%Cey3mONNEndZrW4U>FIr>r)e_invdCM*T3`6CLI#kDhX^(!fM~1q(_@jP}NO- zb#fW#H9qhg_Ubb^4-$;F@gHK_jEKJLKGxtrriEPKKdl+zKW)^A|90_t@%-7BUq4Uk zrpU8ORf&*{PrQaFwN#E5RwdjTIlah|I?oCrB^o+qaB&(k;QpEyqLGP$>?RdyQPOb3 z>ZWwKp9wap4*k_iabDL=B87Iic5&>lvZ~Tm#_6)kaC!b%A#9eFb;5KPxSlxwUvg#wPPjJatz)Raa=PG7c~G_qsVg zsS}VTb1hk-G;P9aj{ZTkdWe&mOW3Hvr@>WO038x zEi(jq${Ite5@YS`i=%%`ztN6WMN=kLs@XTxZ(SCpD{2i6vdQ^^8nCsj8l4ECXIr?c zmxmz96is1m0lv;J&#v>@TE!DcavG~2`pb2d*}}+d(cX)qVR^1Zj&TVir`O-jo&z2m zCTz8M(E03(#?-Q4m7*^ev|HN6Tj@kvHNVIbQ!~vuRM5%!MUgbQDs5io38U>N6L0Yo zCZT>-NC-(lvAy#l;u@7_88O|m$hLEmSWdb$PYBJwU1=%y! zXantolqT=5Ck!+dyoU5J;oi@$mab7%4VHqEo%o2h{ohjfzkdIhE2=!c*m@?T*Wm>jwb>`i{s z?A>ZB*y0HT_k(>f+rb{Yiuq^9wurU<5UWk)_sc8!8|=CQ9oPS#ZKhc! zs7+6soEA0dDj|2e73)SjvF>IgRuN&X$beMkAf z$qbcE;85qutpEGshc|Uz)#n$J38YJ??0dXdWw1;(_c^KSt{UV|El2;fXjDj zPPwBadRdIplNsIn+w}SScR#$%FaG`{-Af<;Wsg1i*k8H$JNukE^qIbwS5;M?{_q|C zIB!nQewujPca;7i%_y!}$+i9QYk;Ps^nVZ1`IFK={2`T}&)X%*wEN%Yz?z;ke}T;| zWPSY-7+XXFG?cv~dN_4-@#eU>oX2BF>F=*E&SI~2ui1Nlk`mqP30S3|6Lc)y?7u%s z_YRgjUV6w8<*@`qK+6!#vh?@APaosYz4YiBY5sG;k{Q6Pe#}qk{tp;uPVwK?wto4~ z8vMt(S?vFkg46!5%#7>*yZOxae`zf%DOtjlQQ0Ji3w~3+`8(}MDT-PZrAcIF)TDwh zE^)QARh~1ONNxGVFMi+}0DM(s2{Xdz$?G5fN-HI0(&#*|m@X6UI9>i>dbxI*Ice%d zNZKp)Lsd<$v&N{pVLXvc`|GpIS*4wk6>lfIQ&9;x?b17I`63yDeJN*WMZJ&lh-pYGOJvbF`e)XgL+f_K&xqf zZ%|d#jzb#8nF*e7nxEpbb*#uFaZKCRF0v-Ct*){}Fp0~vCs$U2Ktmm~`C)=|U6sz{ z1^%^*i&;{ZDlZ@k?hJR6e@uG=5kgd2(vCngxtKk;sSC70XWG#wuIl)VVc4~L_R#kb)J--%v$NXk6QH!D!31^v_ebM;qywrIk@kBGf z{@Rlx4V057Lb>^a-uwN1S!0;4NDkTJ*fGD0E-Nf&MXP7uuVWf21Jz(gn)$9Z-*HtG zS>Di=zS-`y>a~APSsKYDZeZ5VzBoNc6rJRab*gr>k8Jh@ji6>_!DUt920iQe9kHn4 zQWhCBiEF9m+u!_NLQ%T1h6*UQ*cC_Dje)M04pUFgM)uBgNMx$iHH|>cpW`)8aaXg3 zrUIL{_ng3VVzvgSrJjlAoak{vXW$X$h*k4VcYaW+R2fu6&iQ=q$*D!fvz)d7IzGGZ zsVQn+lY!ten_u_TXbW|%K@H8d#d#>0Wsq-KmqaC)cJ-E?p|~pY%2A(k;xiOUT@^}~ xAdgwCKTwZ5e#X!E89(D^{EVORGk(U;_!&RrXZ(zx@w3~{{|9x5?ePFG3;-YdgWdoD literal 0 HcmV?d00001 diff --git a/gdtoa/gdtoaimp.h b/gdtoa/gdtoaimp.h index f417705..39012aa 100644 --- a/gdtoa/gdtoaimp.h +++ b/gdtoa/gdtoaimp.h @@ -113,7 +113,12 @@ THIS SOFTWARE. * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) * if memory is available and otherwise does something you deem * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. + * directly -- and assumed always to succeed. Similarly, if you + * want something other than the system's free() to be called to + * recycle memory acquired from MALLOC, #define FREE to be the + * name of the alternate routine. (FREE or free is only called in + * pathological cases, e.g., in a gdtoa call after a gdtoa return in + * mode 3 with thousands of digits requested.) * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making * memory allocations from a private pool of memory when possible. * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, @@ -126,8 +131,10 @@ THIS SOFTWARE. * conversions of IEEE doubles in single-threaded executions with * 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with * 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate. - * #define INFNAN_CHECK on IEEE systems to cause strtod to check for - * Infinity and NaN (case insensitively). + * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK + * #defined automatically on IEEE systems. On such systems, + * when INFNAN_CHECK is #defined, strtod checks + * for Infinity and NaN (case insensitively). * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, * strtodg also accepts (case insensitively) strings of the form * NaN(x), where x is a string of hexadecimal digits (optionally @@ -160,11 +167,6 @@ THIS SOFTWARE. * #define NO_STRING_H to use private versions of memcpy. * On some K&R systems, it may also be necessary to * #define DECLARE_SIZE_T in this case. - * #define YES_ALIAS to permit aliasing certain double values with - * arrays of ULongs. This leads to slightly better code with - * some compilers and was always used prior to 19990916, but it - * is not strictly legal and can cause trouble with aggressively - * optimizing compilers (e.g., gcc 2.95.1 under -O2). * #define USE_LOCALE to use the current locale's decimal_point value. */ @@ -360,25 +362,14 @@ Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. typedef union { double d; ULong L[2]; } U; -#ifdef YES_ALIAS -#define dval(x) x #ifdef IEEE_8087 -#define word0(x) ((ULong *)&x)[1] -#define word1(x) ((ULong *)&x)[0] +#define word0(x) (x)->L[1] +#define word1(x) (x)->L[0] #else -#define word0(x) ((ULong *)&x)[0] -#define word1(x) ((ULong *)&x)[1] +#define word0(x) (x)->L[0] +#define word1(x) (x)->L[1] #endif -#else /* !YES_ALIAS */ -#ifdef IEEE_8087 -#define word0(x) ((U*)&x)->L[1] -#define word1(x) ((U*)&x)->L[0] -#else -#define word0(x) ((U*)&x)->L[0] -#define word1(x) ((U*)&x)->L[1] -#endif -#define dval(x) ((U*)&x)->d -#endif /* YES_ALIAS */ +#define dval(x) (x)->d /* The following definition of Storeinc is appropriate for MIPS processors. * An alternative that might be better on some machines is @@ -556,7 +547,7 @@ extern spinlock_t __gdtoa_locks[2]; if (__isthreaded) _SPINUNLOCK(&__gdtoa_locks[n]); \ } while(0) -#define Kmax 15 +#define Kmax 9 struct Bigint { @@ -624,7 +615,7 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); extern double strtod_l ANSI((const char *s00, char **se, locale_t)); extern Bigint *sum ANSI((Bigint*, Bigint*)); extern int trailz ANSI((Bigint*)); - extern double ulp ANSI((double)); + extern double ulp ANSI((U*)); #ifdef __cplusplus } @@ -639,6 +630,10 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) */ #ifdef IEEE_Arith +#ifndef NO_INFNAN_CHECK +#undef INFNAN_CHECK +#define INFNAN_CHECK +#endif #ifdef IEEE_MC68k #define _0 0 #define _1 1 @@ -669,4 +664,78 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); #define SI 0 #endif +/* + * For very large strings, strtod and family might exhaust memory in tight + * memory conditions (especially in 32-bits). Such large strings could also + * tie up a CPU for minutes at a time. Either can be considered a denial-of- + * service vunerability. + * + * To fix, we limit the string size to the maximum we need to calculate the + * rounding point correctly. The longest string corresponding to the exact + * value of a floating point number occuring at 1.f...f p^-n, where n is + * the (absolute value of the) smallest exponent for a normalize number. + * + * To calculate this number of decimal digits, we use the formula: + * + * (n + m) - int(n * log10(2)) + 3 + * + * where m is the number of bits in the f...f fraction. This is the number + * of decimal digits for the least significant bit minus the number of leading + * zeros for the most significant bit (the '1'), plus a few to compensate for + * an extra digits due to the full 1.f...f value, an extra digit for the + * mid-way point for rounding and an extra guard digit. + * + * Using the approximation log10(2) ~ 1233 / (2^12), converting to the fpi.emin + * and fpi.nbits values, we get: + * + * -fpi.emin -((1233 * (-fpi.nbits - fpi.emin)) >> 12) + 3 + * + * Finally, we add an extra digit, either '1' or '0', to represent whether + * to-be-truncated digits contain a non-zero digit, or are all zeros, + * respectively. + * + * The truncated string is allocated on the heap, so code using + * TRUNCATE_DIGITS() will need to free that space when no longer needed. + * Pass a char * as the second argument, initialized to NULL; if its value + * becomes non-NULL, memory was allocated. + */ +#define LOG2NUM 1233 +#define LOG2DENOMSHIFT 12 +#define TRUNCATEDIGITS(_nbits, _emin) (-(_emin) - ((LOG2NUM * (-(_nbits) - (_emin))) >> LOG2DENOMSHIFT) + 3) + +#define TRUNCATE_DIGITS(_s0, _temp, _nd, _nd0, _nf, _nbits, _emin, _dplen) \ +{ \ + int _maxdigits = TRUNCATEDIGITS((_nbits), (_emin)); \ + if ((_nd) > _maxdigits && \ + ((_temp) = MALLOC(_maxdigits + (_dplen) + 2)) != NULL) { \ + char *_tp = (_temp) + _maxdigits; \ + if ((_nd0) >= _maxdigits) { \ + memcpy((_temp), (_s0), _maxdigits); \ + if ((_nd) > (_nd0)) *_tp++ = '1'; \ + else { \ + const char *_q = (_s0) + _maxdigits; \ + int _n = (_nd0) - _maxdigits; \ + for(; _n > 0 && *_q == '0'; _n--, _q++) {} \ + *_tp++ = _n > 0 ? '1' : '0'; \ + } \ + (_nf) = -((_nd0) - (_maxdigits + 1)); \ + (_nd0) = _maxdigits + 1; \ + } \ + else if ((_nd0) == 0) { \ + memcpy((_temp), (_s0), _maxdigits); \ + *_tp++ = '1'; \ + (_nf) -= ((_nd) - (_maxdigits + 1)); \ + } \ + else { \ + memcpy((_temp), (_s0), _maxdigits + (_dplen)); \ + _tp += (_dplen); \ + *_tp++ = '1'; \ + (_nf) = (_maxdigits + 1) - (_nd0); \ + } \ + *_tp = 0; \ + (_nd) = _maxdigits + 1; \ + (_s0) = (_temp); \ + } \ + } + #endif /* GDTOAIMP_H_INCLUDED */ diff --git a/gen/FreeBSD/_rand48.c.patch b/gen/FreeBSD/_rand48.c.patch index 6e4caca..893fa6b 100644 --- a/gen/FreeBSD/_rand48.c.patch +++ b/gen/FreeBSD/_rand48.c.patch @@ -1,6 +1,6 @@ ---- _rand48.c.orig 2003-05-20 15:21:01.000000000 -0700 -+++ _rand48.c 2005-11-03 13:52:27.000000000 -0800 -@@ -16,34 +16,6 @@ +--- _rand48.c.orig 2009-11-07 14:51:37.000000000 -0800 ++++ _rand48.c 2009-11-07 14:51:38.000000000 -0800 +@@ -16,34 +16,6 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/_ra #include "rand48.h" diff --git a/gen/FreeBSD/alarm.3 b/gen/FreeBSD/alarm.3 index e9be94f..0139e0c 100644 --- a/gen/FreeBSD/alarm.3 +++ b/gen/FreeBSD/alarm.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)alarm.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/alarm.3,v 1.16 2002/12/18 13:33:02 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/alarm.3,v 1.17 2007/01/09 00:27:52 imp Exp $ .\" .Dd April 19, 1994 .Dt ALARM 3 diff --git a/gen/FreeBSD/alarm.3.patch b/gen/FreeBSD/alarm.3.patch index fa80522..2678eea 100644 --- a/gen/FreeBSD/alarm.3.patch +++ b/gen/FreeBSD/alarm.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/gen/FreeBSD/alarm.3 2003-05-20 15:21:01.000000000 -0700 -+++ _SB/Libc/gen/FreeBSD/alarm.3.edit 2006-06-28 16:55:50.000000000 -0700 -@@ -42,8 +42,8 @@ +--- alarm.3.orig 2009-11-07 14:51:37.000000000 -0800 ++++ alarm.3 2009-11-07 14:51:40.000000000 -0800 +@@ -38,8 +38,8 @@ .Lb libc .Sh SYNOPSIS .In unistd.h diff --git a/gen/FreeBSD/alarm.c b/gen/FreeBSD/alarm.c index 58cce20..6846af3 100644 --- a/gen/FreeBSD/alarm.c +++ b/gen/FreeBSD/alarm.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)alarm.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/alarm.c,v 1.2 2002/02/01 01:08:47 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/alarm.c,v 1.3 2007/01/09 00:27:53 imp Exp $"); /* * Backwards compatible alarm. diff --git a/gen/FreeBSD/arc4random.3 b/gen/FreeBSD/arc4random.3 index 3e2aaa3..44015af 100644 --- a/gen/FreeBSD/arc4random.3 +++ b/gen/FreeBSD/arc4random.3 @@ -28,13 +28,15 @@ .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" Manual page, using -mandoc macros -.\" $FreeBSD: src/lib/libc/gen/arc4random.3,v 1.16 2003/07/31 06:18:24 das Exp $ +.\" $FreeBSD: src/lib/libc/gen/arc4random.3,v 1.18 2008/07/22 11:33:49 ache Exp $ .\" .Dd April 15, 1997 .Dt ARC4RANDOM 3 .Os .Sh NAME .Nm arc4random , +.Nm arc4random_buf , +.Nm arc4random_uniform , .Nm arc4random_stir , .Nm arc4random_addrandom .Nd arc4 random number generator @@ -45,6 +47,10 @@ .Ft u_int32_t .Fn arc4random "void" .Ft void +.Fn arc4random_buf "void *buf" "size_t nbytes" +.Ft u_int32_t +.Fn arc4random_uniform "u_int32_t upper_bound" +.Ft void .Fn arc4random_stir "void" .Ft void .Fn arc4random_addrandom "unsigned char *dat" "int datlen" @@ -68,6 +74,21 @@ and therefore has twice the range of and .Xr random 3 . .Pp +.Fn arc4random_buf +function fills the region +.Fa buf +of length +.Fa nbytes +with ARC4-derived random data. +.Pp +.Fn arc4random_uniform +will return a uniformly distributed random number less than +.Fa upper_bound . +.Fn arc4random_uniform +is recommended over constructions like +.Dq Li arc4random() % upper_bound +as it avoids "modulo bias" when the upper bound is not a power of two. +.Pp The .Fn arc4random_stir function reads data from @@ -78,10 +99,9 @@ and uses it to permute the S-Boxes via There is no need to call .Fn arc4random_stir before using -.Fn arc4random , -since .Fn arc4random -automatically initializes itself. +functions family, since +they automatically initialize themselves. .Sh EXAMPLES The following produces a drop-in replacement for the traditional .Fn rand diff --git a/gen/FreeBSD/arc4random.c b/gen/FreeBSD/arc4random.c index 7d882b8..869effa 100644 --- a/gen/FreeBSD/arc4random.c +++ b/gen/FreeBSD/arc4random.c @@ -1,14 +1,23 @@ /* - * Arc4 random number generator for OpenBSD. - * Copyright 1996 David Mazieres . + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * Modification and redistribution in source and binary forms is - * permitted provided that due credit is given to the author and the - * OpenBSD project (for instance by leaving this copyright notice - * intact). + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* + * Arc4 random number generator for OpenBSD. + * * This code is derived from section 17.1 of Applied Cryptography, * second edition, which describes a stream cipher allegedly * compatible with RSA Labs "RC4" cipher (the actual description of @@ -24,7 +33,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.10 2004/03/24 14:44:57 green Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.25 2008/09/09 09:46:36 ache Exp $"); #include "namespace.h" #include @@ -43,81 +52,111 @@ struct arc4_stream { u_int8_t s[256]; }; -static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +static int lock = 0; +extern void spin_lock(int*); +extern void spin_unlock(int*); -#define RANDOMDEV "/dev/urandom" +#define RANDOMDEV "/dev/random" +#define KEYSIZE 128 #define THREAD_LOCK() \ do { \ if (__isthreaded) \ - _pthread_mutex_lock(&arc4random_mtx); \ + spin_lock(&lock); \ } while (0) #define THREAD_UNLOCK() \ do { \ if (__isthreaded) \ - _pthread_mutex_unlock(&arc4random_mtx); \ + spin_unlock(&lock); \ } while (0) -static struct arc4_stream rs; +static struct arc4_stream rs = { + .i = 0, + .j = 0, + .s = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + } +}; static int rs_initialized; static int rs_stired; +static int arc4_count; -static inline u_int8_t arc4_getbyte(struct arc4_stream *); -static void arc4_stir(struct arc4_stream *); +static inline u_int8_t arc4_getbyte(void); +static void arc4_stir(void); -static inline void -arc4_init(as) - struct arc4_stream *as; -{ - int n; - - for (n = 0; n < 256; n++) - as->s[n] = n; - as->i = 0; - as->j = 0; -} +static struct { + struct timeval tv; + pid_t pid; + u_int8_t rnd[KEYSIZE]; +} rdat; +static volatile int rs_data_available = 0; static inline void -arc4_addrandom(as, dat, datlen) - struct arc4_stream *as; - u_char *dat; - int datlen; +arc4_addrandom(u_char *dat, int datlen) { int n; u_int8_t si; - as->i--; + rs.i--; for (n = 0; n < 256; n++) { - as->i = (as->i + 1); - si = as->s[as->i]; - as->j = (as->j + si + dat[n % datlen]); - as->s[as->i] = as->s[as->j]; - as->s[as->j] = si; + rs.i = (rs.i + 1); + si = rs.s[rs.i]; + rs.j = (rs.j + si + dat[n % datlen]); + rs.s[rs.i] = rs.s[rs.j]; + rs.s[rs.j] = si; } + rs.j = rs.i; } static void -arc4_stir(as) - struct arc4_stream *as; +arc4_fetch(void) { - int fd, n; - struct { - struct timeval tv; - pid_t pid; - u_int8_t rnd[128 - sizeof(struct timeval) - sizeof(pid_t)]; - } rdat; - - gettimeofday(&rdat.tv, NULL); - rdat.pid = getpid(); + int done, fd; fd = _open(RANDOMDEV, O_RDONLY, 0); + done = 0; if (fd >= 0) { - (void) _read(fd, rdat.rnd, sizeof(rdat.rnd)); - _close(fd); + if (_read(fd, &rdat, KEYSIZE) == KEYSIZE) + done = 1; + (void)_close(fd); } - /* fd < 0? Ah, what the heck. We'll just take whatever was on the - * stack... */ + if (!done) { + (void)gettimeofday(&rdat.tv, NULL); + rdat.pid = getpid(); + /* We'll just take whatever was on the stack too... */ + } +} - arc4_addrandom(as, (void *) &rdat, sizeof(rdat)); +static void +arc4_stir(void) +{ + int n; + /* + * If we don't have data, we need some now before we can integrate + * it into the static buffers + */ + if (!rs_data_available) + { + arc4_fetch(); + } + rs_data_available = 0; + __sync_synchronize(); + + arc4_addrandom((u_char *)&rdat, KEYSIZE); /* * Throw away the first N bytes of output, as suggested in the @@ -127,92 +166,169 @@ arc4_stir(as) * by Ilya Mironov. */ for (n = 0; n < 1024; n++) - arc4_getbyte(as); + (void) arc4_getbyte(); + arc4_count = 1600000; + rs_stired = 1; } static inline u_int8_t -arc4_getbyte(as) - struct arc4_stream *as; +arc4_getbyte(void) { u_int8_t si, sj; - as->i = (as->i + 1); - si = as->s[as->i]; - as->j = (as->j + si); - sj = as->s[as->j]; - as->s[as->i] = sj; - as->s[as->j] = si; + rs.i = (rs.i + 1); + si = rs.s[rs.i]; + rs.j = (rs.j + si); + sj = rs.s[rs.j]; + rs.s[rs.i] = sj; + rs.s[rs.j] = si; - return (as->s[(si + sj) & 0xff]); + return (rs.s[(si + sj) & 0xff]); } static inline u_int32_t -arc4_getword(as) - struct arc4_stream *as; +arc4_getword(void) { u_int32_t val; - val = arc4_getbyte(as) << 24; - val |= arc4_getbyte(as) << 16; - val |= arc4_getbyte(as) << 8; - val |= arc4_getbyte(as); + val = arc4_getbyte() << 24; + val |= arc4_getbyte() << 16; + val |= arc4_getbyte() << 8; + val |= arc4_getbyte(); return (val); } -static void -arc4_check_init(void) +/* 7944700: force restir in child */ +__private_extern__ void +_arc4_fork_child(void) { - if (!rs_initialized) { - arc4_init(&rs); - rs_initialized = 1; - } + rs_stired = 0; + rs_data_available = 0; } -static void +static inline int arc4_check_stir(void) { - if (!rs_stired) { - arc4_stir(&rs); - rs_stired = 1; + if (!rs_stired || arc4_count <= 0) { + arc4_stir(); + return 1; } + return 0; } void -arc4random_stir() +arc4random_stir(void) { THREAD_LOCK(); - arc4_check_init(); - arc4_stir(&rs); + arc4_stir(); THREAD_UNLOCK(); } void -arc4random_addrandom(dat, datlen) - u_char *dat; - int datlen; +arc4random_addrandom(u_char *dat, int datlen) { THREAD_LOCK(); - arc4_check_init(); arc4_check_stir(); - arc4_addrandom(&rs, dat, datlen); + arc4_addrandom(dat, datlen); THREAD_UNLOCK(); } u_int32_t -arc4random() +arc4random(void) { u_int32_t rnd; THREAD_LOCK(); - arc4_check_init(); - arc4_check_stir(); - rnd = arc4_getword(&rs); + + int did_stir = arc4_check_stir(); + rnd = arc4_getword(); + arc4_count -= 4; + THREAD_UNLOCK(); + if (did_stir) + { + /* stirring used up our data pool, we need to read in new data outside of the lock */ + arc4_fetch(); + rs_data_available = 1; + __sync_synchronize(); + } return (rnd); } +void +arc4random_buf(void *_buf, size_t n) +{ + u_char *buf = (u_char *)_buf; + int did_stir = 0; + + THREAD_LOCK(); + + while (n--) { + if (arc4_check_stir()) + { + did_stir = 1; + } + buf[n] = arc4_getbyte(); + arc4_count--; + } + + THREAD_UNLOCK(); + if (did_stir) + { + /* stirring used up our data pool, we need to read in new data outside of the lock */ + arc4_fetch(); + rs_data_available = 1; + __sync_synchronize(); + } +} + +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +u_int32_t +arc4random_uniform(u_int32_t upper_bound) +{ + u_int32_t r, min; + + if (upper_bound < 2) + return (0); + +#if (ULONG_MAX > 0xffffffffUL) + min = 0x100000000UL % upper_bound; +#else + /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ + if (upper_bound > 0x80000000) + min = 1 + ~upper_bound; /* 2**32 - upper_bound */ + else { + /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ + min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound; + } +#endif + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = arc4random(); + if (r >= min) + break; + } + + return (r % upper_bound); +} + #if 0 /*-------- Test code for i386 --------*/ #include diff --git a/gen/FreeBSD/arc4random.c.patch b/gen/FreeBSD/arc4random.c.patch index 8931f1b..e69de29 100644 --- a/gen/FreeBSD/arc4random.c.patch +++ b/gen/FreeBSD/arc4random.c.patch @@ -1,11 +0,0 @@ ---- arc4random.c.orig 2006-02-19 03:33:43.000000000 -0800 -+++ arc4random.c 2006-02-19 15:35:04.000000000 -0800 -@@ -117,7 +117,7 @@ - /* fd < 0? Ah, what the heck. We'll just take whatever was on the - * stack... */ - -- arc4_addrandom(as, (void *) &rdat, sizeof(rdat)); -+ arc4_addrandom(as, (u_char *) &rdat, sizeof(rdat)); - - /* - * Throw away the first N bytes of output, as suggested in the diff --git a/gen/FreeBSD/assert.c b/gen/FreeBSD/assert.c index f14e39c..3e380c3 100644 --- a/gen/FreeBSD/assert.c +++ b/gen/FreeBSD/assert.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)assert.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/assert.c,v 1.7 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/assert.c,v 1.8 2007/01/09 00:27:53 imp Exp $"); #include #include diff --git a/gen/FreeBSD/assert.c.patch b/gen/FreeBSD/assert.c.patch index cc0a51f..4297577 100644 --- a/gen/FreeBSD/assert.c.patch +++ b/gen/FreeBSD/assert.c.patch @@ -1,13 +1,15 @@ ---- assert.c.orig 2008-09-06 16:27:37.000000000 -0700 -+++ assert.c 2008-09-07 01:35:02.000000000 -0700 -@@ -41,20 +41,39 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/ass - #include +--- assert.c.orig 2010-09-24 10:27:46.000000000 -0700 ++++ assert.c 2010-09-24 10:37:33.000000000 -0700 +@@ -34,23 +34,60 @@ static char sccsid[] = "@(#)assert.c 8.1 + __FBSDID("$FreeBSD: src/lib/libc/gen/assert.c,v 1.8 2007/01/09 00:27:53 imp Exp $"); + + #include +-#include #include ++#include ++#include "CrashReporterClient.h" ++#include "_simple.h" -+extern const char *__crashreporter_info__; -+static const char badasprintf[] = -+ "Assertion failed and asprintf also failed to create full error string"; -+ void -__assert(func, file, line, failedexpr) +__assert_rtn(func, file, line, failedexpr) @@ -16,28 +18,50 @@ const char *failedexpr; { - if (func == NULL) -+ char *str = NULL; -+ -+ if (func == NULL) { - (void)fprintf(stderr, +- (void)fprintf(stderr, ++ if (func == (const char *)-1L) { ++ /* 8462256: special case to replace __eprintf */ ++ _simple_dprintf(STDERR_FILENO, ++ "%s:%u: failed assertion `%s'\n", file, line, failedexpr); ++ if (!CRGetCrashLogMessage()) { ++ _SIMPLE_STRING s = _simple_salloc(); ++ if (s) { ++ _simple_sprintf(s, ++ "%s:%u: failed assertion `%s'\n", ++ file, line, failedexpr); ++ CRSetCrashLogMessage(_simple_string(s)); ++ } else ++ CRSetCrashLogMessage(failedexpr); ++ } ++ } else if (func == NULL) { ++ _simple_dprintf(STDERR_FILENO, "Assertion failed: (%s), file %s, line %d.\n", failedexpr, file, line); - else -+ if (!__crashreporter_info__) { -+ asprintf(&str, -+ "Assertion failed: (%s), file %s, line %d.\n", -+ failedexpr, file, line); -+ __crashreporter_info__ = str ? str : badasprintf; +- (void)fprintf(stderr, ++ if (!CRGetCrashLogMessage()) { ++ _SIMPLE_STRING s = _simple_salloc(); ++ if (s) { ++ _simple_sprintf(s, ++ "Assertion failed: (%s), file %s, line %d.\n", ++ failedexpr, file, line); ++ CRSetCrashLogMessage(_simple_string(s)); ++ } else ++ CRSetCrashLogMessage(failedexpr); + } + } else { - (void)fprintf(stderr, ++ _simple_dprintf(STDERR_FILENO, "Assertion failed: (%s), function %s, file %s, line %d.\n", failedexpr, func, file, line); -+ if (!__crashreporter_info__) { -+ asprintf(&str, -+ "Assertion failed: (%s), function %s, file %s, line %d.\n", -+ failedexpr, func, file, line); -+ __crashreporter_info__ = str ? str : badasprintf; ++ if (!CRGetCrashLogMessage()) { ++ _SIMPLE_STRING s = _simple_salloc(); ++ if (s) { ++ _simple_sprintf(s, ++ "Assertion failed: (%s), function %s, file %s, line %d.\n", ++ failedexpr, func, file, line); ++ CRSetCrashLogMessage(_simple_string(s)); ++ } else ++ CRSetCrashLogMessage(failedexpr); + } + } abort(); diff --git a/gen/FreeBSD/clock.3 b/gen/FreeBSD/clock.3 index cff60dc..1869d09 100644 --- a/gen/FreeBSD/clock.3 +++ b/gen/FreeBSD/clock.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)clock.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/clock.3,v 1.11 2001/11/20 13:43:58 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/clock.3,v 1.12 2007/01/09 00:27:53 imp Exp $ .\" .Dd June 4, 1993 .Dt CLOCK 3 @@ -68,13 +64,9 @@ case the return value is \-1. The .Fn clock function conforms to -.St -isoC . -However, -.St -susv2 -requires +.St -isoC +and +.St -susv3 +which requires .Dv CLOCKS_PER_SEC to be defined as one million. -.Fx -does not conform to this requirement; -changing the value would introduce binary incompatibility -and one million is still inadequate on modern processors. diff --git a/gen/FreeBSD/clock.c b/gen/FreeBSD/clock.c index ddfccbe..8a4ec9e 100644 --- a/gen/FreeBSD/clock.c +++ b/gen/FreeBSD/clock.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)clock.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/clock.c,v 1.3 2002/03/22 21:52:05 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/clock.c,v 1.4 2007/01/09 00:27:53 imp Exp $"); #include #include diff --git a/gen/FreeBSD/closedir.c b/gen/FreeBSD/closedir.c index 31dedc0..e268572 100644 --- a/gen/FreeBSD/closedir.c +++ b/gen/FreeBSD/closedir.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)closedir.c 8.1 (Berkeley) 6/10/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/closedir.c,v 1.10 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/closedir.c,v 1.13 2007/12/03 14:33:50 des Exp $"); #include "namespace.h" #include @@ -58,7 +54,7 @@ closedir(dirp) int fd; if (__isthreaded) - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_lock(&dirp->dd_lock); _seekdir(dirp, dirp->dd_rewind); /* free seekdir storage */ fd = dirp->dd_fd; dirp->dd_fd = -1; @@ -66,8 +62,8 @@ closedir(dirp) free((void *)dirp->dd_buf); _reclaim_telldir(dirp); if (__isthreaded) { - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); - _pthread_mutex_destroy((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_unlock(&dirp->dd_lock); + _pthread_mutex_destroy(&dirp->dd_lock); } free((void *)dirp); return(_close(fd)); diff --git a/gen/FreeBSD/closedir.c.patch b/gen/FreeBSD/closedir.c.patch index 2f4be68..2c46432 100644 --- a/gen/FreeBSD/closedir.c.patch +++ b/gen/FreeBSD/closedir.c.patch @@ -1,9 +1,9 @@ ---- closedir.c.orig 2007-01-24 14:10:41.000000000 -0800 -+++ closedir.c 2007-01-25 00:17:23.000000000 -0800 -@@ -59,7 +59,9 @@ +--- closedir.c.orig 2009-11-07 15:27:55.000000000 -0800 ++++ closedir.c 2009-11-07 15:28:09.000000000 -0800 +@@ -55,7 +55,9 @@ closedir(dirp) if (__isthreaded) - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_lock(&dirp->dd_lock); +#if !__DARWIN_UNIX03 _seekdir(dirp, dirp->dd_rewind); /* free seekdir storage */ +#endif /* __DARWIN_UNIX03 */ diff --git a/gen/FreeBSD/ctermid.3 b/gen/FreeBSD/ctermid.3 index c36d55f..dfc28c3 100644 --- a/gen/FreeBSD/ctermid.3 +++ b/gen/FreeBSD/ctermid.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ctermid.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/ctermid.3,v 1.11 2003/09/08 19:57:14 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/ctermid.3,v 1.12 2007/01/09 00:27:53 imp Exp $ .\" .Dd June 4, 1993 .Dt CTERMID 3 diff --git a/gen/FreeBSD/ctermid.3.patch b/gen/FreeBSD/ctermid.3.patch index 1c392db..8f3f177 100644 --- a/gen/FreeBSD/ctermid.3.patch +++ b/gen/FreeBSD/ctermid.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/gen/FreeBSD/ctermid.3 2004-11-25 11:38:00.000000000 -0800 -+++ _SB/Libc/gen/FreeBSD/ctermid.3.edit 2006-06-28 16:55:50.000000000 -0700 -@@ -36,31 +36,32 @@ +--- ctermid.3.orig 2009-11-07 14:51:37.000000000 -0800 ++++ ctermid.3 2009-11-07 14:51:40.000000000 -0800 +@@ -32,31 +32,32 @@ .Dt CTERMID 3 .Os .Sh NAME @@ -40,7 +40,7 @@ is assumed to be at least .Dv L_ctermid (as defined in the include -@@ -72,9 +73,9 @@ +@@ -68,9 +69,9 @@ The .Fn ctermid_r function provides the same functionality as diff --git a/gen/FreeBSD/ctermid.c b/gen/FreeBSD/ctermid.c index 6b2c682..d517719 100644 --- a/gen/FreeBSD/ctermid.c +++ b/gen/FreeBSD/ctermid.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)ctermid.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/ctermid.c,v 1.3 2002/03/22 21:52:05 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/ctermid.c,v 1.4 2007/01/09 00:27:53 imp Exp $"); #include #include diff --git a/gen/FreeBSD/daemon.3 b/gen/FreeBSD/daemon.3 index 04e0a51..4d0b5b7 100644 --- a/gen/FreeBSD/daemon.3 +++ b/gen/FreeBSD/daemon.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)daemon.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/daemon.3,v 1.14 2003/11/10 22:04:51 ghelmer Exp $ +.\" $FreeBSD: src/lib/libc/gen/daemon.3,v 1.15 2007/01/09 00:27:53 imp Exp $ .\" .Dd June 9, 1993 .Dt DAEMON 3 diff --git a/gen/FreeBSD/daemon.3.patch b/gen/FreeBSD/daemon.3.patch index 3a7d273..afe6ae2 100644 --- a/gen/FreeBSD/daemon.3.patch +++ b/gen/FreeBSD/daemon.3.patch @@ -1,6 +1,6 @@ ---- daemon.3.orig 2007-09-11 10:52:31.000000000 -0700 -+++ daemon.3 2007-09-11 10:49:51.000000000 -0700 -@@ -49,6 +49,8 @@ +--- daemon.3.orig 2009-11-07 14:51:37.000000000 -0800 ++++ daemon.3 2009-11-07 14:51:40.000000000 -0800 +@@ -45,6 +45,8 @@ The .Fn daemon function is for programs wishing to detach themselves from the controlling terminal and run in the background as system daemons. diff --git a/gen/FreeBSD/daemon.c b/gen/FreeBSD/daemon.c index 1b9b706..451bcb8 100644 --- a/gen/FreeBSD/daemon.c +++ b/gen/FreeBSD/daemon.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,12 +31,13 @@ static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/daemon.c,v 1.6 2003/11/10 22:01:42 ghelmer Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/daemon.c,v 1.8 2007/01/09 00:27:53 imp Exp $"); #include "namespace.h" #include #include #include +#include #include #include #include "un-namespace.h" diff --git a/gen/FreeBSD/daemon.c.patch b/gen/FreeBSD/daemon.c.patch index 095cf26..2a5cb49 100644 --- a/gen/FreeBSD/daemon.c.patch +++ b/gen/FreeBSD/daemon.c.patch @@ -1,8 +1,8 @@ ---- daemon.c.orig 2007-09-29 23:58:54.000000000 -0700 -+++ daemon.c 2007-09-30 00:46:19.000000000 -0700 -@@ -37,6 +37,10 @@ +--- daemon.c.orig 2009-11-07 15:29:09.000000000 -0800 ++++ daemon.c 2009-11-07 15:30:24.000000000 -0800 +@@ -33,6 +33,10 @@ static char sccsid[] = "@(#)daemon.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/gen/daemon.c,v 1.6 2003/11/10 22:01:42 ghelmer Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/gen/daemon.c,v 1.8 2007/01/09 00:27:53 imp Exp $"); +#ifndef VARIANT_PRE1050 +#include @@ -11,7 +11,7 @@ #include "namespace.h" #include #include -@@ -45,6 +49,33 @@ +@@ -42,6 +46,33 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/dae #include #include "un-namespace.h" @@ -45,7 +45,7 @@ int daemon(nochdir, noclose) int nochdir, noclose; -@@ -60,7 +91,9 @@ +@@ -57,7 +88,9 @@ daemon(nochdir, noclose) sa.sa_handler = SIG_IGN; sa.sa_flags = 0; osa_ok = _sigaction(SIGHUP, &sa, &osa); diff --git a/gen/FreeBSD/dirname.3 b/gen/FreeBSD/dirname.3 index b2d0f6f..43a1853 100644 --- a/gen/FreeBSD/dirname.3 +++ b/gen/FreeBSD/dirname.3 @@ -1,33 +1,22 @@ +.\" $OpenBSD: dirname.3,v 1.17 2007/05/31 19:19:28 jmc Exp $ .\" .\" Copyright (c) 1997 Todd C. Miller -.\" 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. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. .\" -.\" THIS SOFTWARE IS PROVIDED ``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 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. +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.\" $OpenBSD: dirname.3,v 1.9 2000/04/18 03:01:25 aaron Exp $ -.\" $FreeBSD: src/lib/libc/gen/dirname.3,v 1.8 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/dirname.3,v 1.10 2008/11/03 05:19:45 delphij Exp $ .\" -.Dd August 17, 1997 +.Dd October 12, 2006 .Dt DIRNAME 3 .Os .Sh NAME @@ -40,8 +29,7 @@ .Sh DESCRIPTION The .Fn dirname -function -is the converse of +function is the converse of .Xr basename 3 ; it returns a pointer to the parent directory of the pathname pointed to by .Fa path . @@ -58,6 +46,20 @@ characters, returns a pointer to the string .Qq \&. , signifying the current directory. +.Sh IMPLEMENTATION NOTES +The +.Fn dirname +function +returns a pointer to internal storage space allocated on the first call +that will be overwritten +by subsequent calls. +.Pp +Other vendor implementations of +.Fn dirname +may modify the contents of the string passed to +.Fn dirname ; +this should be taken into account when writing code which calls this function +if portability is desired. .Sh RETURN VALUES On successful completion, .Fn dirname @@ -77,19 +79,6 @@ The following error codes may be set in The path component to be returned was larger than .Dv MAXPATHLEN . .El -.Sh WARNINGS -The -.Fn dirname -function -returns a pointer to internal static storage space that will be overwritten -by subsequent calls (each function has its own separate storage). -.Pp -Other vendor implementations of -.Fn dirname -may modify the contents of the string passed to -.Fn dirname ; -this should be taken into account when writing code which calls this function -if portability is desired. .Sh SEE ALSO .Xr basename 1 , .Xr dirname 1 , @@ -107,4 +96,4 @@ function first appeared in and .Fx 4.2 . .Sh AUTHORS -.An "Todd C. Miller" Aq Todd.Miller@courtesan.com +.An "Todd C. Miller" diff --git a/gen/FreeBSD/dirname.3.patch b/gen/FreeBSD/dirname.3.patch index ee49f42..9fb8483 100644 --- a/gen/FreeBSD/dirname.3.patch +++ b/gen/FreeBSD/dirname.3.patch @@ -1,6 +1,6 @@ ---- dirname.3 2004-11-25 11:38:00.000000000 -0800 -+++ dirname.3.edit 2006-07-12 11:18:01.000000000 -0700 -@@ -36,7 +36,9 @@ +--- dirname.3.orig 2009-11-07 15:32:33.000000000 -0800 ++++ dirname.3 2009-11-07 15:35:29.000000000 -0800 +@@ -25,7 +25,9 @@ .Sh SYNOPSIS .In libgen.h .Ft char * @@ -11,7 +11,7 @@ .Sh DESCRIPTION The .Fn dirname -@@ -88,12 +90,25 @@ +@@ -58,8 +60,20 @@ Other vendor implementations of .Fn dirname may modify the contents of the string passed to .Fn dirname ; @@ -31,6 +31,10 @@ +In legacy mode, +.Fa path +will not be changed. + .Sh RETURN VALUES + On successful completion, + .Fn dirname +@@ -82,7 +96,8 @@ The path component to be returned was la .Sh SEE ALSO .Xr basename 1 , .Xr dirname 1 , diff --git a/gen/FreeBSD/dirname.c b/gen/FreeBSD/dirname.c index 8a4e1c9..551d068 100644 --- a/gen/FreeBSD/dirname.c +++ b/gen/FreeBSD/dirname.c @@ -1,37 +1,23 @@ +/* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */ + /* - * Copyright (c) 1997 Todd C. Miller - * All rights reserved. + * Copyright (c) 1997, 2004 Todd C. Miller * - * 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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 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. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#if 0 -#ifndef lint -static char rcsid[] = "$OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $"; -#endif /* not lint */ -#endif #include -__FBSDID("$FreeBSD: src/lib/libc/gen/dirname.c,v 1.7 2002/12/30 01:41:14 marcel Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/dirname.c,v 1.8 2008/11/03 05:19:45 delphij Exp $"); #include #include @@ -40,25 +26,26 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/dirname.c,v 1.7 2002/12/30 01:41:14 marcel #include char * -dirname(path) - const char *path; +dirname(const char *path) { - static char *bname = NULL; + static char *dname = NULL; + size_t len; const char *endp; - if (bname == NULL) { - bname = (char *)malloc(MAXPATHLEN); - if (bname == NULL) + if (dname == NULL) { + dname = (char *)malloc(MAXPATHLEN); + if (dname == NULL) return(NULL); } /* Empty or NULL string gets treated as "." */ if (path == NULL || *path == '\0') { - (void)strcpy(bname, "."); - return(bname); + dname[0] = '.'; + dname[1] = '\0'; + return (dname); } - /* Strip trailing slashes */ + /* Strip any trailing slashes */ endp = path + strlen(path) - 1; while (endp > path && *endp == '/') endp--; @@ -69,19 +56,22 @@ dirname(path) /* Either the dir is "/" or there are no slashes */ if (endp == path) { - (void)strcpy(bname, *endp == '/' ? "/" : "."); - return(bname); + dname[0] = *endp == '/' ? '/' : '.'; + dname[1] = '\0'; + return (dname); } else { + /* Move forward past the separating slashes */ do { endp--; } while (endp > path && *endp == '/'); } - if (endp - path + 2 > MAXPATHLEN) { + len = endp - path + 1; + if (len >= MAXPATHLEN) { errno = ENAMETOOLONG; - return(NULL); + return (NULL); } - (void)strncpy(bname, path, endp - path + 1); - bname[endp - path + 1] = '\0'; - return(bname); + memcpy(dname, path, len); + dname[len] = '\0'; + return (dname); } diff --git a/gen/FreeBSD/dirname.c.patch b/gen/FreeBSD/dirname.c.patch index 213726d..b4e5b77 100644 --- a/gen/FreeBSD/dirname.c.patch +++ b/gen/FreeBSD/dirname.c.patch @@ -1,11 +1,6 @@ -Index: dirname.c -=================================================================== -RCS file: /cvs/root/Libc/gen/FreeBSD/dirname.c,v -retrieving revision 1.2 -diff -u -d -b -w -p -u -r1.2 dirname.c ---- dirname.c 2003/05/20 22:21:01 1.2 -+++ dirname.c 2004/12/10 18:48:49 -@@ -39,6 +39,10 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/dir +--- dirname.c.orig 2009-11-07 14:51:37.000000000 -0800 ++++ dirname.c 2009-11-07 14:51:40.000000000 -0800 +@@ -25,6 +25,10 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/dir #include #include @@ -14,5 +9,5 @@ diff -u -d -b -w -p -u -r1.2 dirname.c +#endif + char * - dirname(path) - const char *path; + dirname(const char *path) + { diff --git a/gen/FreeBSD/drand48.c.patch b/gen/FreeBSD/drand48.c.patch index 31e01bb..ce1dfeb 100644 --- a/gen/FreeBSD/drand48.c.patch +++ b/gen/FreeBSD/drand48.c.patch @@ -1,6 +1,6 @@ ---- drand48.c.orig 2003-05-20 15:21:01.000000000 -0700 -+++ drand48.c 2005-11-03 13:20:19.000000000 -0800 -@@ -16,10 +16,10 @@ +--- drand48.c.orig 2009-11-07 14:51:37.000000000 -0800 ++++ drand48.c 2009-11-07 14:51:39.000000000 -0800 +@@ -16,10 +16,10 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/dra #include "rand48.h" diff --git a/gen/FreeBSD/erand48.c.patch b/gen/FreeBSD/erand48.c.patch index d18f27c..8abfe80 100644 --- a/gen/FreeBSD/erand48.c.patch +++ b/gen/FreeBSD/erand48.c.patch @@ -1,6 +1,6 @@ ---- erand48.c.orig 2003-05-20 15:21:01.000000000 -0700 -+++ erand48.c 2005-11-03 12:30:30.000000000 -0800 -@@ -19,8 +19,8 @@ +--- erand48.c.orig 2009-11-07 14:51:37.000000000 -0800 ++++ erand48.c 2009-11-07 14:51:39.000000000 -0800 +@@ -19,8 +19,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/era double erand48(unsigned short xseed[3]) { diff --git a/gen/FreeBSD/err.3 b/gen/FreeBSD/err.3 index 997df58..4243e84 100644 --- a/gen/FreeBSD/err.3 +++ b/gen/FreeBSD/err.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)err.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/err.3,v 1.20 2004/10/04 14:04:37 jkoshy Exp $ +.\" $FreeBSD: src/lib/libc/gen/err.3,v 1.24 2008/10/31 15:14:40 rwatson Exp $ .\" .Dd March 6, 1999 .Dt ERR 3 @@ -98,7 +94,7 @@ and a space are output. If the .Fa fmt argument is not NULL, the -.Xr printf 3 +.Xr printf 3 Ns -like formatted error message is output. The output is terminated by a newline character. .Pp @@ -114,7 +110,7 @@ and .Fn vwarnc functions append an error message obtained from .Xr strerror 3 -based on a code or the global variable +based on a supplied error code value or the global variable .Va errno , preceded by another colon and space unless the .Fa fmt @@ -182,15 +178,16 @@ or a null pointer Display the current errno information string and exit: .Bd -literal -offset indent if ((p = malloc(size)) == NULL) - err(1, NULL); + err(EX_OSERR, NULL); if ((fd = open(file_name, O_RDONLY, 0)) == -1) - err(1, "%s", file_name); + err(EX_NOINPUT, "%s", file_name); .Ed .Pp Display an error message and exit: .Bd -literal -offset indent if (tm.tm_hour < START_TIME) - errx(1, "too early, wait until %s", start_time_string); + errx(EX_DATAERR, "too early, wait until %s", + start_time_string); .Ed .Pp Warn of an error: @@ -199,7 +196,7 @@ if ((fd = open(raw_device, O_RDONLY, 0)) == -1) warnx("%s: %s: trying the block device", raw_device, strerror(errno)); if ((fd = open(block_device, O_RDONLY, 0)) == -1) - err(1, "%s", block_device); + err(EX_OSFILE, "%s", block_device); .Ed .Pp Warn of an error without using the global variable diff --git a/gen/FreeBSD/err.3.patch b/gen/FreeBSD/err.3.patch index 3e345fa..d62bfe7 100644 --- a/gen/FreeBSD/err.3.patch +++ b/gen/FreeBSD/err.3.patch @@ -1,15 +1,15 @@ ---- err.3.orig 2009-05-12 11:21:55.000000000 -0700 -+++ err.3 2009-05-20 16:48:17.000000000 -0700 -@@ -32,7 +32,7 @@ +--- err.3.orig 2009-11-07 14:51:37.000000000 -0800 ++++ err.3 2009-11-07 14:51:40.000000000 -0800 +@@ -28,7 +28,7 @@ .\" From: @(#)err.3 8.1 (Berkeley) 6/9/93 - .\" $FreeBSD: src/lib/libc/gen/err.3,v 1.20 2004/10/04 14:04:37 jkoshy Exp $ + .\" $FreeBSD: src/lib/libc/gen/err.3,v 1.24 2008/10/31 15:14:40 rwatson Exp $ .\" -.Dd March 6, 1999 +.Dd May 20, 2008 .Dt ERR 3 .Os .Sh NAME -@@ -49,6 +49,9 @@ +@@ -45,6 +45,9 @@ .Nm warnx , .Nm vwarnx , .Nm err_set_exit , @@ -19,7 +19,7 @@ .Nm err_set_file .Nd formatted error messages .Sh LIBRARY -@@ -59,6 +62,10 @@ +@@ -55,6 +58,10 @@ .Fn err "int eval" "const char *fmt" "..." .Ft void .Fn err_set_exit "void (*exitf)(int)" @@ -30,7 +30,7 @@ .Ft void .Fn err_set_file "void *vfp" .Ft void -@@ -169,6 +176,24 @@ +@@ -165,6 +172,24 @@ function can be used to specify a functi to perform any necessary cleanup; passing a null function pointer for .Va exitf resets the hook to do nothing. @@ -55,7 +55,7 @@ The .Fn err_set_file function sets the output stream used by the other functions. -@@ -234,3 +259,8 @@ +@@ -231,3 +256,8 @@ and .Fn warnc functions first appeared in .Fx 3.0 . diff --git a/gen/FreeBSD/err.c b/gen/FreeBSD/err.c index aa0d306..196c90c 100644 --- a/gen/FreeBSD/err.c +++ b/gen/FreeBSD/err.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)err.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/err.c,v 1.13 2002/03/29 22:43:41 markm Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/err.c,v 1.15 2008/04/03 20:36:44 imp Exp $"); #include "namespace.h" #include @@ -101,11 +97,7 @@ errc(int eval, int code, const char *fmt, ...) } void -verrc(eval, code, fmt, ap) - int eval; - int code; - const char *fmt; - va_list ap; +verrc(int eval, int code, const char *fmt, va_list ap) { if (err_file == 0) err_set_file((FILE *)0); @@ -130,10 +122,7 @@ errx(int eval, const char *fmt, ...) } void -verrx(eval, fmt, ap) - int eval; - const char *fmt; - va_list ap; +verrx(int eval, const char *fmt, va_list ap) { if (err_file == 0) err_set_file((FILE *)0); @@ -158,9 +147,7 @@ _warn(const char *fmt, ...) } void -vwarn(fmt, ap) - const char *fmt; - va_list ap; +vwarn(const char *fmt, va_list ap) { vwarnc(errno, fmt, ap); } @@ -175,10 +162,7 @@ warnc(int code, const char *fmt, ...) } void -vwarnc(code, fmt, ap) - int code; - const char *fmt; - va_list ap; +vwarnc(int code, const char *fmt, va_list ap) { if (err_file == 0) err_set_file((FILE *)0); @@ -200,9 +184,7 @@ warnx(const char *fmt, ...) } void -vwarnx(fmt, ap) - const char *fmt; - va_list ap; +vwarnx(const char *fmt, va_list ap) { if (err_file == 0) err_set_file((FILE *)0); diff --git a/gen/FreeBSD/err.c.patch b/gen/FreeBSD/err.c.patch index 7ca732a..d2e3159 100644 --- a/gen/FreeBSD/err.c.patch +++ b/gen/FreeBSD/err.c.patch @@ -1,6 +1,6 @@ ---- err.c.orig 2009-05-12 11:21:55.000000000 -0700 -+++ err.c 2009-05-23 13:27:52.000000000 -0700 -@@ -44,12 +44,105 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/err +--- err.c.orig 2011-02-15 16:29:48.000000000 -0800 ++++ err.c 2011-02-15 18:01:51.000000000 -0800 +@@ -40,12 +40,107 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/err #include #include #include @@ -49,10 +49,12 @@ + * (NUL isn't used) + */ +static unsigned char escape[256] = { -+ /* NUL SOH STX ETX EOT ENQ ACK BEL */ -+ 0 , 255, 255, 255, 255, 255, 255, 'a', ++ /* NUL */ ++ 0, /* Unused: strings can't contain nulls */ ++ /* SOH STX ETX EOT ENQ ACK BEL */ ++ 255, 255, 255, 255, 255, 255, 'a', + /* BS HT NL VT NP CR SO SI */ -+ 'b', 't', 'n', 'v', 'f', 'r', 255, 255, ++ 'b', 0, 0, 'v', 'f', 'r', 255, 255, + /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ + 255, 255, 255, 255, 255, 255, 255, 255, + /* CAN EM SUB ESC FS GS RS US */ @@ -83,7 +85,7 @@ + *tp++ = *fp; + break; + case 255: -+ sprintf(tp, "\\%03o", *fp); ++ sprintf((char *)tp, "\\%03o", *fp); + tp += 4; + break; + default: @@ -108,7 +110,7 @@ /* * This is declared to take a `void *' so that the caller is not required -@@ -60,16 +153,27 @@ void +@@ -56,16 +151,27 @@ void err_set_file(void *fp) { if (fp) @@ -139,9 +141,9 @@ __weak_reference(_err, err); -@@ -107,16 +211,21 @@ verrc(eval, code, fmt, ap) - const char *fmt; - va_list ap; +@@ -99,16 +205,21 @@ errc(int eval, int code, const char *fmt + void + verrc(int eval, int code, const char *fmt, va_list ap) { - if (err_file == 0) + if (_e_err_file == 0) @@ -168,9 +170,9 @@ exit(eval); } -@@ -135,14 +244,19 @@ verrx(eval, fmt, ap) - const char *fmt; - va_list ap; +@@ -124,14 +235,19 @@ errx(int eval, const char *fmt, ...) + void + verrx(int eval, const char *fmt, va_list ap) { - if (err_file == 0) + if (_e_err_file == 0) @@ -194,9 +196,9 @@ exit(eval); } -@@ -180,14 +294,14 @@ vwarnc(code, fmt, ap) - const char *fmt; - va_list ap; +@@ -164,14 +280,14 @@ warnc(int code, const char *fmt, ...) + void + vwarnc(int code, const char *fmt, va_list ap) { - if (err_file == 0) + if (_e_err_file == 0) @@ -214,9 +216,9 @@ } void -@@ -204,10 +318,10 @@ vwarnx(fmt, ap) - const char *fmt; - va_list ap; +@@ -186,10 +302,10 @@ warnx(const char *fmt, ...) + void + vwarnx(const char *fmt, va_list ap) { - if (err_file == 0) + if (_e_err_file == 0) diff --git a/gen/FreeBSD/exec.3 b/gen/FreeBSD/exec.3 index b741da2..bf5164e 100644 --- a/gen/FreeBSD/exec.3 +++ b/gen/FreeBSD/exec.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)exec.3 8.3 (Berkeley) 1/24/94 -.\" $FreeBSD: src/lib/libc/gen/exec.3,v 1.23 2003/09/10 19:24:32 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/exec.3,v 1.28 2008/06/23 05:22:06 ed Exp $ .\" .Dd January 24, 1994 .Dt EXEC 3 @@ -159,7 +155,7 @@ and search path is the path specified in the environment by .Dq Ev PATH variable. -If this variable isn't specified, +If this variable is not specified, the default path is set according to the .Dv _PATH_DEFPATH definition in @@ -196,7 +192,7 @@ or according to whether at least one file with suitable execute permissions was found. .Pp -If the header of a file isn't recognized (the attempted +If the header of a file is not recognized (the attempted .Fn execve returned .Er ENOEXEC ) , @@ -220,38 +216,6 @@ will be set to indicate the error. .It Pa /bin/sh The shell. .El -.Sh ERRORS -The -.Fn execl , -.Fn execle , -.Fn execlp , -.Fn execvp -and -.Fn execvP -functions -may fail and set -.Va errno -for any of the errors specified for the library functions -.Xr execve 2 -and -.Xr malloc 3 . -.Pp -The -.Fn exect -and -.Fn execv -functions -may fail and set -.Va errno -for any of the errors specified for the library function -.Xr execve 2 . -.Sh SEE ALSO -.Xr sh 1 , -.Xr execve 2 , -.Xr fork 2 , -.Xr ktrace 2 , -.Xr ptrace 2 , -.Xr environ 7 .Sh COMPATIBILITY Historically, the default path for the .Fn execlp @@ -308,6 +272,38 @@ and the unusual error .Er EIO . The behaviour was changed to match the behaviour of .Xr sh 1 . +.Sh ERRORS +The +.Fn execl , +.Fn execle , +.Fn execlp , +.Fn execvp +and +.Fn execvP +functions +may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr execve 2 +and +.Xr malloc 3 . +.Pp +The +.Fn exect +and +.Fn execv +functions +may fail and set +.Va errno +for any of the errors specified for the library function +.Xr execve 2 . +.Sh SEE ALSO +.Xr sh 1 , +.Xr execve 2 , +.Xr fork 2 , +.Xr ktrace 2 , +.Xr ptrace 2 , +.Xr environ 7 .Sh STANDARDS The .Fn execl , diff --git a/gen/FreeBSD/exec.3.patch b/gen/FreeBSD/exec.3.patch index 96cdf19..7a46542 100644 --- a/gen/FreeBSD/exec.3.patch +++ b/gen/FreeBSD/exec.3.patch @@ -1,6 +1,6 @@ ---- exec.3.orig 2006-09-18 18:04:52.000000000 -0700 -+++ exec.3 2006-09-18 18:05:37.000000000 -0700 -@@ -37,9 +37,8 @@ +--- exec.3.orig 2009-12-15 13:07:38.000000000 -0800 ++++ exec.3 2009-12-15 13:09:07.000000000 -0800 +@@ -33,9 +33,8 @@ .Os .Sh NAME .Nm execl , @@ -11,7 +11,7 @@ .Nm execv , .Nm execvp , .Nm execvP -@@ -50,25 +49,43 @@ +@@ -46,25 +45,43 @@ .In unistd.h .Vt extern char **environ ; .Ft int @@ -63,7 +63,7 @@ .Sh DESCRIPTION The .Nm exec -@@ -84,7 +101,7 @@ +@@ -80,7 +97,7 @@ The initial argument for these functions is to be executed. .Pp The @@ -72,7 +72,7 @@ and subsequent ellipses in the .Fn execl , .Fn execlp , -@@ -106,7 +123,6 @@ +@@ -102,7 +119,6 @@ be terminated by a pointer. .Pp The @@ -80,7 +80,7 @@ .Fn execv , .Fn execvp , and -@@ -123,10 +139,8 @@ +@@ -119,10 +135,8 @@ pointer. .Pp The .Fn execle @@ -93,7 +93,7 @@ .Dv NULL pointer that terminates the list of arguments in the argument list or the pointer to the argv array with an additional argument. -@@ -203,11 +217,6 @@ +@@ -199,11 +213,6 @@ returned these functions will execute the shell with the path of the file as its first argument. (If this attempt fails, no further searching is done.) @@ -105,7 +105,7 @@ .Sh RETURN VALUES If any of the .Fn exec -@@ -225,7 +234,7 @@ +@@ -277,7 +286,7 @@ The .Fn execl , .Fn execle , .Fn execlp , @@ -114,7 +114,7 @@ and .Fn execvP functions -@@ -237,11 +246,8 @@ +@@ -289,11 +298,8 @@ and .Xr malloc 3 . .Pp The @@ -127,29 +127,15 @@ .Va errno for any of the errors specified for the library function .Xr execve 2 . -@@ -249,7 +255,6 @@ +@@ -301,7 +307,6 @@ for any of the errors specified for the .Xr sh 1 , .Xr execve 2 , .Xr fork 2 , -.Xr ktrace 2 , .Xr ptrace 2 , .Xr environ 7 - .Sh COMPATIBILITY -@@ -272,11 +277,11 @@ - .Tn POSIX - standard. - .Pp --Traditionally, the functions -+Traditionally, the - .Fn execlp - and - .Fn execvp --ignored all errors except for the ones described above and -+functions ignored all errors except for the ones described above and - .Er ETXTBSY , - upon which they retried after sleeping for several seconds, and - .Er ENOMEM -@@ -313,7 +318,7 @@ + .Sh STANDARDS +@@ -309,7 +314,7 @@ The .Fn execl , .Fn execv , .Fn execle , diff --git a/gen/FreeBSD/exec.c b/gen/FreeBSD/exec.c index 211eb78..811b425 100644 --- a/gen/FreeBSD/exec.c +++ b/gen/FreeBSD/exec.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/exec.c,v 1.22 2003/07/01 12:30:03 bde Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/exec.c,v 1.27 2009/12/05 18:55:16 ed Exp $"); #include "namespace.h" #include @@ -50,6 +46,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/exec.c,v 1.22 2003/07/01 12:30:03 bde Exp $ #include #include "un-namespace.h" +#include "libc_private.h" extern char **environ; @@ -57,7 +54,7 @@ int execl(const char *name, const char *arg, ...) { va_list ap; - char **argv; + const char **argv; int n; va_start(ap, arg); @@ -72,18 +69,19 @@ execl(const char *name, const char *arg, ...) } va_start(ap, arg); n = 1; - argv[0] = (char *)arg; + argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; va_end(ap); - return (_execve(name, argv, environ)); + return (_execve(name, __DECONST(char **, argv), environ)); } int execle(const char *name, const char *arg, ...) { va_list ap; - char **argv, **envp; + const char **argv; + char **envp; int n; va_start(ap, arg); @@ -98,19 +96,19 @@ execle(const char *name, const char *arg, ...) } va_start(ap, arg); n = 1; - argv[0] = (char *)arg; + argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; envp = va_arg(ap, char **); va_end(ap); - return (_execve(name, argv, envp)); + return (_execve(name, __DECONST(char **, argv), envp)); } int execlp(const char *name, const char *arg, ...) { va_list ap; - char **argv; + const char **argv; int n; va_start(ap, arg); @@ -125,11 +123,11 @@ execlp(const char *name, const char *arg, ...) } va_start(ap, arg); n = 1; - argv[0] = (char *)arg; + argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; va_end(ap); - return (execvp(name, argv)); + return (execvp(name, __DECONST(char **, argv))); } int @@ -144,33 +142,25 @@ execv(name, argv) int execvp(const char *name, char * const *argv) { - const char *path; - - /* Get the path we're searching. */ - if ((path = getenv("PATH")) == NULL) - path = _PATH_DEFPATH; - - return (execvP(name, path, argv)); + return (_execvpe(name, argv, environ)); } -int -execvP(name, path, argv) - const char *name; - const char *path; - char * const *argv; +static int +execvPe(const char *name, const char *path, char * const *argv, + char * const *envp) { - char **memp; - int cnt, lp, ln; - char *p; + const char **memp; + size_t cnt, lp, ln; int eacces, save_errno; - char *bp, *cur, buf[MAXPATHLEN]; + char *cur, buf[MAXPATHLEN]; + const char *p, *bp; struct stat sb; eacces = 0; /* If it's an absolute or relative path name, it's easy. */ if (index(name, '/')) { - bp = (char *)name; + bp = name; cur = NULL; goto retry; } @@ -217,7 +207,7 @@ execvP(name, path, argv) bcopy(name, buf + lp + 1, ln); buf[lp + ln + 1] = '\0'; -retry: (void)_execve(bp, argv, environ); +retry: (void)_execve(bp, argv, envp); switch (errno) { case E2BIG: goto done; @@ -236,7 +226,8 @@ retry: (void)_execve(bp, argv, environ); memp[0] = "sh"; memp[1] = bp; bcopy(argv + 1, memp + 2, cnt * sizeof(char *)); - (void)_execve(_PATH_BSHELL, memp, environ); + (void)_execve(_PATH_BSHELL, + __DECONST(char **, memp), envp); goto done; case ENOMEM: goto done; @@ -273,3 +264,21 @@ retry: (void)_execve(bp, argv, environ); done: return (-1); } + +int +execvP(const char *name, const char *path, char * const argv[]) +{ + return execvPe(name, path, argv, environ); +} + +int +_execvpe(const char *name, char * const argv[], char * const envp[]) +{ + const char *path; + + /* Get the path we're searching. */ + if ((path = getenv("PATH")) == NULL) + path = _PATH_DEFPATH; + + return (execvPe(name, path, argv, envp)); +} diff --git a/gen/FreeBSD/exec.c.patch b/gen/FreeBSD/exec.c.patch index 84a2aae..e1303a4 100644 --- a/gen/FreeBSD/exec.c.patch +++ b/gen/FreeBSD/exec.c.patch @@ -1,16 +1,19 @@ ---- exec.c.orig 2004-11-24 00:12:00.000000000 -0800 -+++ exec.c 2004-11-24 15:46:54.000000000 -0800 -@@ -51,7 +51,8 @@ - #include +--- exec.c.orig 2010-07-06 16:02:22.000000000 -0700 ++++ exec.c 2010-07-06 16:31:46.000000000 -0700 +@@ -48,7 +48,11 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/exe #include "un-namespace.h" + #include "libc_private.h" -extern char **environ; +#include +#define environ (*_NSGetEnviron()) ++ ++int ++_execvpe(const char *name, char * const argv[], char * const envp[]); int execl(const char *name, const char *arg, ...) -@@ -268,8 +269,9 @@ +@@ -259,8 +263,9 @@ retry: (void)_execve(bp, argv, envp); } if (eacces) errno = EACCES; @@ -21,3 +24,12 @@ done: return (-1); } +@@ -271,7 +276,7 @@ execvP(const char *name, const char *pat + return execvPe(name, path, argv, environ); + } + +-int ++__private_extern__ int + _execvpe(const char *name, char * const argv[], char * const envp[]) + { + const char *path; diff --git a/gen/FreeBSD/fmtcheck.3 b/gen/FreeBSD/fmtcheck.3 index 1a5bb54..90d0f03 100644 --- a/gen/FreeBSD/fmtcheck.3 +++ b/gen/FreeBSD/fmtcheck.3 @@ -31,7 +31,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/fmtcheck.3,v 1.9 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/fmtcheck.3,v 1.10 2008/08/02 06:02:42 das Exp $ .Dd October 16, 2002 .Os .Dt FMTCHECK 3 @@ -112,6 +112,4 @@ the first requires an integer and the second requires a long. .Sh BUGS The .Fn fmtcheck -function does not understand all of the conversions that -.Xr printf 3 -does. +function does not recognize positional parameters. diff --git a/gen/FreeBSD/fmtcheck.c b/gen/FreeBSD/fmtcheck.c index e907995..74b1d21 100644 --- a/gen/FreeBSD/fmtcheck.c +++ b/gen/FreeBSD/fmtcheck.c @@ -1,3 +1,5 @@ +/* $NetBSD: fmtcheck.c,v 1.8 2008/04/28 20:22:59 martin Exp $ */ + /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. * All rights reserved. @@ -12,13 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -33,9 +28,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* $NetBSD: fmtcheck.c,v 1.2 2000/11/01 01:17:20 briggs Exp $ */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/fmtcheck.c,v 1.7 2004/05/02 10:55:05 das Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/fmtcheck.c,v 1.10 2009/06/23 23:52:12 delphij Exp $"); #include #include @@ -47,14 +41,18 @@ enum __e_fmtcheck_types { FMTCHECK_START, FMTCHECK_SHORT, FMTCHECK_INT, + FMTCHECK_WINTT, FMTCHECK_LONG, FMTCHECK_QUAD, + FMTCHECK_INTMAXT, FMTCHECK_PTRDIFFT, FMTCHECK_SIZET, + FMTCHECK_CHARPOINTER, FMTCHECK_SHORTPOINTER, FMTCHECK_INTPOINTER, FMTCHECK_LONGPOINTER, FMTCHECK_QUADPOINTER, + FMTCHECK_INTMAXTPOINTER, FMTCHECK_PTRDIFFTPOINTER, FMTCHECK_SIZETPOINTER, #ifndef NO_FLOATING_POINT @@ -62,6 +60,7 @@ enum __e_fmtcheck_types { FMTCHECK_LONGDOUBLE, #endif FMTCHECK_STRING, + FMTCHECK_WSTRING, FMTCHECK_WIDTH, FMTCHECK_PRECISION, FMTCHECK_DONE, @@ -69,6 +68,18 @@ enum __e_fmtcheck_types { }; typedef enum __e_fmtcheck_types EFT; +enum e_modifier { + MOD_NONE, + MOD_CHAR, + MOD_SHORT, + MOD_LONG, + MOD_QUAD, + MOD_INTMAXT, + MOD_LONGDOUBLE, + MOD_PTRDIFFT, + MOD_SIZET, +}; + #define RETURN(pf,f,r) do { \ *(pf) = (f); \ return r; \ @@ -77,101 +88,148 @@ typedef enum __e_fmtcheck_types EFT; static EFT get_next_format_from_precision(const char **pf) { - int sh, lg, quad, longdouble, ptrdifft, sizet; + enum e_modifier modifier; const char *f; - sh = lg = quad = longdouble = ptrdifft = sizet = 0; - f = *pf; switch (*f) { case 'h': f++; - sh = 1; + if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN); + if (*f == 'h') { + f++; + modifier = MOD_CHAR; + } else { + modifier = MOD_SHORT; + } + break; + case 'j': + f++; + modifier = MOD_INTMAXT; break; case 'l': f++; if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN); if (*f == 'l') { f++; - quad = 1; + modifier = MOD_QUAD; } else { - lg = 1; + modifier = MOD_LONG; } break; case 'q': f++; - quad = 1; + modifier = MOD_QUAD; break; case 't': f++; - ptrdifft = 1; + modifier = MOD_PTRDIFFT; break; case 'z': f++; - sizet = 1; + modifier = MOD_SIZET; break; case 'L': f++; - longdouble = 1; + modifier = MOD_LONGDOUBLE; break; default: + modifier = MOD_NONE; break; } if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN); if (strchr("diouxX", *f)) { - if (longdouble) - RETURN(pf,f,FMTCHECK_UNKNOWN); - if (lg) + switch (modifier) { + case MOD_LONG: RETURN(pf,f,FMTCHECK_LONG); - if (quad) + case MOD_QUAD: RETURN(pf,f,FMTCHECK_QUAD); - if (ptrdifft) + case MOD_INTMAXT: + RETURN(pf,f,FMTCHECK_INTMAXT); + case MOD_PTRDIFFT: RETURN(pf,f,FMTCHECK_PTRDIFFT); - if (sizet) + case MOD_SIZET: RETURN(pf,f,FMTCHECK_SIZET); - RETURN(pf,f,FMTCHECK_INT); + case MOD_CHAR: + case MOD_SHORT: + case MOD_NONE: + RETURN(pf,f,FMTCHECK_INT); + default: + RETURN(pf,f,FMTCHECK_UNKNOWN); + } } if (*f == 'n') { - if (longdouble) - RETURN(pf,f,FMTCHECK_UNKNOWN); - if (sh) + switch (modifier) { + case MOD_CHAR: + RETURN(pf,f,FMTCHECK_CHARPOINTER); + case MOD_SHORT: RETURN(pf,f,FMTCHECK_SHORTPOINTER); - if (lg) + case MOD_LONG: RETURN(pf,f,FMTCHECK_LONGPOINTER); - if (quad) + case MOD_QUAD: RETURN(pf,f,FMTCHECK_QUADPOINTER); - if (ptrdifft) + case MOD_INTMAXT: + RETURN(pf,f,FMTCHECK_INTMAXTPOINTER); + case MOD_PTRDIFFT: RETURN(pf,f,FMTCHECK_PTRDIFFTPOINTER); - if (sizet) + case MOD_SIZET: RETURN(pf,f,FMTCHECK_SIZETPOINTER); - RETURN(pf,f,FMTCHECK_INTPOINTER); + case MOD_NONE: + RETURN(pf,f,FMTCHECK_INTPOINTER); + default: + RETURN(pf,f,FMTCHECK_UNKNOWN); + } } if (strchr("DOU", *f)) { - if (sh + lg + quad + longdouble + ptrdifft + sizet) + if (modifier != MOD_NONE) RETURN(pf,f,FMTCHECK_UNKNOWN); RETURN(pf,f,FMTCHECK_LONG); } #ifndef NO_FLOATING_POINT if (strchr("aAeEfFgG", *f)) { - if (longdouble) + switch (modifier) { + case MOD_LONGDOUBLE: RETURN(pf,f,FMTCHECK_LONGDOUBLE); - if (sh + lg + quad + ptrdifft + sizet) + case MOD_LONG: + case MOD_NONE: + RETURN(pf,f,FMTCHECK_DOUBLE); + default: RETURN(pf,f,FMTCHECK_UNKNOWN); - RETURN(pf,f,FMTCHECK_DOUBLE); + } } #endif if (*f == 'c') { - if (sh + lg + quad + longdouble + ptrdifft + sizet) + switch (modifier) { + case MOD_LONG: + RETURN(pf,f,FMTCHECK_WINTT); + case MOD_NONE: + RETURN(pf,f,FMTCHECK_INT); + default: RETURN(pf,f,FMTCHECK_UNKNOWN); - RETURN(pf,f,FMTCHECK_INT); + } + } + if (*f == 'C') { + if (modifier != MOD_NONE) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_WINTT); } if (*f == 's') { - if (sh + lg + quad + longdouble + ptrdifft + sizet) + switch (modifier) { + case MOD_LONG: + RETURN(pf,f,FMTCHECK_WSTRING); + case MOD_NONE: + RETURN(pf,f,FMTCHECK_STRING); + default: + RETURN(pf,f,FMTCHECK_UNKNOWN); + } + } + if (*f == 'S') { + if (modifier != MOD_NONE) RETURN(pf,f,FMTCHECK_UNKNOWN); - RETURN(pf,f,FMTCHECK_STRING); + RETURN(pf,f,FMTCHECK_WSTRING); } if (*f == 'p') { - if (sh + lg + quad + longdouble + ptrdifft + sizet) + if (modifier != MOD_NONE) RETURN(pf,f,FMTCHECK_UNKNOWN); RETURN(pf,f,FMTCHECK_LONG); } @@ -228,7 +286,7 @@ get_next_format(const char **pf, EFT eft) } /* Eat any of the flags */ - while (*f && (strchr("#0- +", *f))) + while (*f && (strchr("#'0- +", *f))) f++; if (*f == '*') { @@ -244,7 +302,7 @@ get_next_format(const char **pf, EFT eft) /*NOTREACHED*/ } -__const char * +const char * __fmtcheck(const char *f1, const char *f2) { const char *f1p, *f2p; diff --git a/gen/FreeBSD/fmtmsg.c b/gen/FreeBSD/fmtmsg.c index 4db35dc..f40efb6 100644 --- a/gen/FreeBSD/fmtmsg.c +++ b/gen/FreeBSD/fmtmsg.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/fmtmsg.c,v 1.5 2003/05/01 19:03:13 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/fmtmsg.c,v 1.6 2009/11/08 14:02:54 brueffer Exp $"); #include #include @@ -128,7 +128,7 @@ printfmt(char *msgverb, long class, const char *label, int sev, size += strlen(sevname); if (text != MM_NULLTXT) size += strlen(text); - if (text != MM_NULLACT) + if (act != MM_NULLACT) size += strlen(act); if (tag != MM_NULLTAG) size += strlen(tag); diff --git a/gen/FreeBSD/fmtmsg.c.patch b/gen/FreeBSD/fmtmsg.c.patch index 2e2f322..6bbcea4 100644 --- a/gen/FreeBSD/fmtmsg.c.patch +++ b/gen/FreeBSD/fmtmsg.c.patch @@ -1,6 +1,6 @@ ---- fmtmsg.c 2004-04-15 15:49:49.000000000 -0700 -+++ ../../../test/fmtmsg.c 2005-03-02 10:53:07.000000000 -0800 -@@ -31,6 +31,8 @@ +--- fmtmsg.c.orig 2009-11-07 14:51:37.000000000 -0800 ++++ fmtmsg.c 2009-11-07 14:51:39.000000000 -0800 +@@ -31,6 +31,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/fmt #include #include #include @@ -9,7 +9,7 @@ /* Default value for MSGVERB. */ #define DFLT_MSGVERB "label:severity:text:action:tag" -@@ -55,6 +57,9 @@ +@@ -55,6 +57,9 @@ fmtmsg(long class, const char *label, in { FILE *fp; char *env, *msgverb, *output; @@ -19,7 +19,7 @@ if (class & MM_PRINT) { if ((env = getenv("MSGVERB")) != NULL && *env != '\0' && -@@ -76,8 +81,12 @@ +@@ -76,8 +81,12 @@ def: free(msgverb); return (MM_NOTOK); } @@ -34,7 +34,7 @@ free(msgverb); free(output); } -@@ -87,16 +96,58 @@ +@@ -87,16 +96,58 @@ def: if (output == NULL) return (MM_NOCON); if (*output != '\0') { diff --git a/gen/FreeBSD/fnmatch.3 b/gen/FreeBSD/fnmatch.3 index 3d268cc..0ff709b 100644 --- a/gen/FreeBSD/fnmatch.3 +++ b/gen/FreeBSD/fnmatch.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fnmatch.3 8.3 (Berkeley) 4/28/95 -.\" $FreeBSD: src/lib/libc/gen/fnmatch.3,v 1.18 2004/07/18 06:56:40 tjr Exp $ +.\" $FreeBSD: src/lib/libc/gen/fnmatch.3,v 1.19 2007/01/09 00:27:53 imp Exp $ .\" .Dd July 18, 2004 .Dt FNMATCH 3 diff --git a/gen/FreeBSD/fnmatch.3.patch b/gen/FreeBSD/fnmatch.3.patch index 1a4522c..0a45f2b 100644 --- a/gen/FreeBSD/fnmatch.3.patch +++ b/gen/FreeBSD/fnmatch.3.patch @@ -1,10 +1,21 @@ ---- _SB/Libc/gen/FreeBSD/fnmatch.3 2004-11-25 11:38:00.000000000 -0800 -+++ _SB/Libc/gen/FreeBSD/fnmatch.3.edit 2006-06-28 16:55:50.000000000 -0700 -@@ -126,7 +126,7 @@ +--- fnmatch.3.orig 2011-02-17 17:09:58.000000000 -0800 ++++ fnmatch.3 2011-02-18 12:10:47.000000000 -0800 +@@ -122,7 +122,18 @@ function returns zero if .Fa string matches the pattern specified by -.Fa pattern , ++.Fa pattern . ++It returns the value ++.Dv FNM_NOMATCH ++if no match is found. ++Otherwise, another non-zero value is returned on error. ++.Sh LEGACY RETURN VALUES ++The ++.Fn fnmatch ++function returns zero if ++.Fa string ++matches the pattern specified by +.Fa pattern ; otherwise, it returns the value .Dv FNM_NOMATCH . diff --git a/gen/FreeBSD/fnmatch.c b/gen/FreeBSD/fnmatch.c index b97db73..0799e34 100644 --- a/gen/FreeBSD/fnmatch.c +++ b/gen/FreeBSD/fnmatch.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.16 2004/07/29 03:13:10 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.19 2010/04/16 22:29:24 jilles Exp $"); /* * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. @@ -71,7 +67,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.16 2004/07/29 03:13:10 tjr Ex #define RANGE_ERROR (-1) static int rangematch(const char *, wchar_t, int, char **, mbstate_t *); -static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t); +static int fnmatch1(const char *, const char *, const char *, int, mbstate_t, + mbstate_t); int fnmatch(pattern, string, flags) @@ -80,22 +77,21 @@ fnmatch(pattern, string, flags) { static const mbstate_t initial; - return (fnmatch1(pattern, string, flags, initial, initial)); + return (fnmatch1(pattern, string, string, flags, initial, initial)); } static int -fnmatch1(pattern, string, flags, patmbs, strmbs) - const char *pattern, *string; +fnmatch1(pattern, string, stringstart, flags, patmbs, strmbs) + const char *pattern, *string, *stringstart; int flags; mbstate_t patmbs, strmbs; { - const char *stringstart; char *newp; char c; wchar_t pc, sc; size_t pclen, sclen; - for (stringstart = string;;) { + for (;;) { pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (FNM_NOMATCH); @@ -149,8 +145,8 @@ fnmatch1(pattern, string, flags, patmbs, strmbs) /* General case, use recursion. */ while (sc != EOS) { - if (!fnmatch1(pattern, string, - flags & ~FNM_PERIOD, patmbs, strmbs)) + if (!fnmatch1(pattern, string, stringstart, + flags, patmbs, strmbs)) return (0); sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs); @@ -254,7 +250,6 @@ rangematch(pattern, test, flags, newp, patmbs) } else if (*pattern == '\0') { return (RANGE_ERROR); } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { - pattern++; return (RANGE_NOMATCH); } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) pattern++; diff --git a/gen/FreeBSD/fnmatch.c.patch b/gen/FreeBSD/fnmatch.c.patch index 5145423..b45f0ea 100644 --- a/gen/FreeBSD/fnmatch.c.patch +++ b/gen/FreeBSD/fnmatch.c.patch @@ -1,56 +1,64 @@ ---- fnmatch.c.orig 2004-11-25 11:38:00.000000000 -0800 -+++ fnmatch.c 2005-03-30 14:33:09.000000000 -0800 -@@ -40,6 +40,8 @@ +--- fnmatch.c.orig 2011-02-17 17:11:04.000000000 -0800 ++++ fnmatch.c 2011-02-18 12:00:31.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)fnmatch.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.16 2004/07/29 03:13:10 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.19 2010/04/16 22:29:24 jilles Exp $"); +#include "xlocale_private.h" + /* * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. * Compares a filename or pathname to a pattern. -@@ -66,12 +68,15 @@ +@@ -62,13 +64,16 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/fnm #define EOS '\0' -+#if __DARWIN_UNIX03 +#define RETURN_ERROR 2 /* neither 0 or FNM_NOMATCH */ -+#endif /* __DARWIN_UNIX03 */ #define RANGE_MATCH 1 #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) -static int rangematch(const char *, wchar_t, int, char **, mbstate_t *); --static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t); ++#define RECURSION_MAX 64 ++ +__private_extern__ int rangematch(const char *, wchar_t, const char *, int, char **, char **, mbstate_t *, mbstate_t *, locale_t); -+static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t, locale_t); + static int fnmatch1(const char *, const char *, const char *, int, mbstate_t, +- mbstate_t); ++ mbstate_t, locale_t, int); int fnmatch(pattern, string, flags) -@@ -80,27 +85,32 @@ +@@ -76,27 +81,38 @@ fnmatch(pattern, string, flags) + int flags; { static const mbstate_t initial; - -- return (fnmatch1(pattern, string, flags, initial, initial)); -+ return (fnmatch1(pattern, string, flags, initial, initial, __current_locale())); +- +- return (fnmatch1(pattern, string, string, flags, initial, initial)); ++#if __DARWIN_UNIX03 ++ return (fnmatch1(pattern, string, string, flags, initial, initial, __current_locale(), RECURSION_MAX)); ++#else /* !__DARWIN_UNIX03 */ ++ return (fnmatch1(pattern, string, string, flags, initial, initial, __current_locale(), RECURSION_MAX) != 0 ? FNM_NOMATCH : 0); ++#endif /* __DARWIN_UNIX03 */ } static int --fnmatch1(pattern, string, flags, patmbs, strmbs) -+fnmatch1(pattern, string, flags, patmbs, strmbs, loc) - const char *pattern, *string; +-fnmatch1(pattern, string, stringstart, flags, patmbs, strmbs) ++fnmatch1(pattern, string, stringstart, flags, patmbs, strmbs, loc, recursion) + const char *pattern, *string, *stringstart; int flags; mbstate_t patmbs, strmbs; + locale_t loc; ++ int recursion; { - const char *stringstart; - char *newp; + char *newp, *news; char c; wchar_t pc, sc; size_t pclen, sclen; - for (stringstart = string;;) { ++ if (recursion-- <= 0) ++ return RETURN_ERROR; + for (;;) { - pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); + pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX, &patmbs, loc); if (pclen == (size_t)-1 || pclen == (size_t)-2) @@ -65,21 +73,26 @@ if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*string; sclen = 1; -@@ -150,10 +160,10 @@ +@@ -144,12 +160,13 @@ fnmatch1(pattern, string, stringstart, f + } + /* General case, use recursion. */ ++ int ret; while (sc != EOS) { - if (!fnmatch1(pattern, string, -- flags & ~FNM_PERIOD, patmbs, strmbs)) -+ flags & ~FNM_PERIOD, patmbs, strmbs, loc)) - return (0); +- if (!fnmatch1(pattern, string, stringstart, +- flags, patmbs, strmbs)) +- return (0); - sclen = mbrtowc(&sc, string, MB_LEN_MAX, - &strmbs); ++ if ((ret = fnmatch1(pattern, string, stringstart, ++ flags, patmbs, strmbs, loc, recursion)) != FNM_NOMATCH) ++ return (ret); + sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, + &strmbs, loc); if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*string; -@@ -175,35 +185,45 @@ +@@ -171,35 +188,45 @@ fnmatch1(pattern, string, stringstart, f ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) return (FNM_NOMATCH); @@ -131,7 +144,7 @@ ; else return (FNM_NOMATCH); -@@ -214,18 +234,22 @@ +@@ -210,18 +237,22 @@ fnmatch1(pattern, string, stringstart, f /* NOTREACHED */ } @@ -162,7 +175,7 @@ /* * A bracket expression starting with an unquoted circumflex -@@ -238,7 +262,7 @@ +@@ -234,7 +265,7 @@ rangematch(pattern, test, flags, newp, p ++pattern; if (flags & FNM_CASEFOLD) @@ -171,7 +184,7 @@ /* * A right bracket shall lose its special meaning and represent -@@ -248,8 +272,8 @@ +@@ -244,8 +275,8 @@ rangematch(pattern, test, flags, newp, p ok = 0; origpat = pattern; for (;;) { @@ -181,7 +194,7 @@ break; } else if (*pattern == '\0') { return (RANGE_ERROR); -@@ -258,39 +282,188 @@ +@@ -253,39 +284,188 @@ rangematch(pattern, test, flags, newp, p return (RANGE_NOMATCH); } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) pattern++; diff --git a/gen/FreeBSD/ftok.3 b/gen/FreeBSD/ftok.3 index 436b77e..e904beb 100644 --- a/gen/FreeBSD/ftok.3 +++ b/gen/FreeBSD/ftok.3 @@ -23,8 +23,8 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/ftok.3,v 1.16 2004/07/02 23:52:10 ru Exp $ -.Dd June 24, 1994 +.\" $FreeBSD: src/lib/libc/gen/ftok.3,v 1.17 2009/07/13 12:53:43 trasz Exp $ +.Dd July 9, 2009 .Os .Dt FTOK 3 .Sh NAME @@ -41,7 +41,7 @@ The .Fn ftok function attempts to create a unique key suitable for use with the -.Xr msgget 3 , +.Xr msgget 2 , .Xr semget 2 and .Xr shmget 2 @@ -66,7 +66,7 @@ does not exist or if it cannot be accessed by the calling process. .Sh SEE ALSO .Xr semget 2 , .Xr shmget 2 , -.Xr msgget 3 +.Xr msgget 2 .Sh HISTORY The .Fn ftok diff --git a/gen/FreeBSD/ftok.3.patch b/gen/FreeBSD/ftok.3.patch index bf415a8..2b3cdf2 100644 --- a/gen/FreeBSD/ftok.3.patch +++ b/gen/FreeBSD/ftok.3.patch @@ -1,5 +1,5 @@ ---- ftok.3 2004-11-25 11:38:00.000000000 -0800 -+++ ftok.3.edit 2006-07-12 11:19:51.000000000 -0700 +--- ftok.3.bsdnew 2009-11-08 14:20:21.000000000 -0800 ++++ ftok.3 2009-11-08 14:23:16.000000000 -0800 @@ -33,7 +33,6 @@ .Sh LIBRARY .Lb libc @@ -8,10 +8,11 @@ .In sys/ipc.h .Ft key_t .Fn ftok "const char *path" "int id" -@@ -42,10 +41,10 @@ +@@ -41,11 +40,10 @@ + The .Fn ftok function attempts to create a unique key suitable for use with the - .Xr msgget 3 , +-.Xr msgget 2 , -.Xr semget 2 +.Xr semget 2 , and @@ -21,7 +22,7 @@ .Fa path of an existing file and a user-selectable .Fa id . -@@ -63,10 +62,18 @@ +@@ -63,10 +61,17 @@ The function will return -1 if .Fa path does not exist or if it cannot be accessed by the calling process. @@ -35,13 +36,12 @@ .Sh SEE ALSO .Xr semget 2 , .Xr shmget 2 , --.Xr msgget 3 -+.Xr msgget 3 , +-.Xr msgget 2 +.Xr compat 5 .Sh HISTORY The .Fn ftok -@@ -75,9 +82,9 @@ +@@ -75,9 +80,9 @@ that use the System V IPC routines. .Sh AUTHORS .An Thorsten Lockert Aq tholo@sigmasoft.com .Sh BUGS diff --git a/gen/FreeBSD/getbsize.3 b/gen/FreeBSD/getbsize.3 index cf3bc8a..55d3348 100644 --- a/gen/FreeBSD/getbsize.3 +++ b/gen/FreeBSD/getbsize.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getbsize.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/getbsize.3,v 1.10 2002/12/30 11:12:16 obrien Exp $ +.\" $FreeBSD: src/lib/libc/gen/getbsize.3,v 1.11 2007/01/09 00:27:53 imp Exp $ .\" .Dd June 4, 1993 .Dt GETBSIZE 3 diff --git a/gen/FreeBSD/getcap.3 b/gen/FreeBSD/getcap.3 index d0ce237..60c383a 100644 --- a/gen/FreeBSD/getcap.3 +++ b/gen/FreeBSD/getcap.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,9 +29,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)getcap.3 8.4 (Berkeley) 5/13/94 -.\" $FreeBSD: src/lib/libc/gen/getcap.3,v 1.25 2004/07/03 22:30:08 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/getcap.3,v 1.30 2007/02/11 18:14:49 maxim Exp $ .\" -.Dd May 13, 1994 +.Dd March 22, 2002 .Dt GETCAP 3 .Os .Sh NAME @@ -55,19 +51,19 @@ .Sh SYNOPSIS .In stdlib.h .Ft int -.Fn cgetent "char **buf" "char **db_array" "char *name" +.Fn cgetent "char **buf" "char **db_array" "const char *name" .Ft int -.Fn cgetset "char *ent" +.Fn cgetset "const char *ent" .Ft int -.Fn cgetmatch "char *buf" "char *name" +.Fn cgetmatch "const char *buf" "const char *name" .Ft char * -.Fn cgetcap "char *buf" "char *cap" "int type" +.Fn cgetcap "char *buf" "const char *cap" "int type" .Ft int -.Fn cgetnum "char *buf" "char *cap" "long *num" +.Fn cgetnum "char *buf" "const char *cap" "long *num" .Ft int -.Fn cgetstr "char *buf" "char *cap" "char **str" +.Fn cgetstr "char *buf" "const char *cap" "char **str" .Ft int -.Fn cgetustr "char *buf" "char *cap" "char **str" +.Fn cgetustr "char *buf" "const char *cap" "char **str" .Ft int .Fn cgetfirst "char **buf" "char **db_array" .Ft int @@ -110,8 +106,8 @@ On success 0 is returned, 1 if the returned record contains an unresolved .Ic tc expansion, -\-1 if the requested record couldn't be found, -\-2 if a system error was encountered (couldn't open/read a file, etc.) also +\-1 if the requested record could not be found, +\-2 if a system error was encountered (could not open/read a file, etc.) also setting .Va errno , and \-3 if a potential reference loop is detected (see @@ -178,7 +174,7 @@ in .Fa buf is returned on success, .Dv NULL -if the requested capability couldn't be +if the requested capability could not be found. The end of the capability value is signaled by a `:' or .Tn ASCII @@ -195,7 +191,7 @@ The numeric value is returned in the .Ft long pointed to by .Fa num . -0 is returned on success, \-1 if the requested numeric capability couldn't +0 is returned on success, \-1 if the requested numeric capability could not be found. .Pp The @@ -214,7 +210,7 @@ pointed to by .Fa str . The number of characters in the decoded string not including the trailing .Dv NUL -is returned on success, \-1 if the requested string capability couldn't +is returned on success, \-1 if the requested string capability could not be found, \-2 if a system error was encountered (storage allocation failure). .Pp @@ -257,7 +253,7 @@ expansion is done (see .Ic tc= comments below). Upon completion of the database 0 is returned, 1 is returned upon successful -return of record with possibly more remaining (we haven't reached the end of +return of record with possibly more remaining (we have not reached the end of the database yet), 2 is returned if the record contains an unresolved .Ic tc expansion, \-1 is returned if a system error occurred, and \-2 @@ -324,7 +320,7 @@ does not exist .Pp Names consist of one or more characters. Names may contain any character -except `:', but it's usually best to restrict them to the printable +except `:', but it is usually best to restrict them to the printable characters and avoid use of graphics like `#', `=', `%', `@', etc. Types are single characters used to separate capability names from their @@ -531,7 +527,7 @@ on failure. The .Fn cgetent , and -.Fn cgetseq +.Fn cgetset functions may fail and set .Va errno for any of the errors specified for the library functions: @@ -559,7 +555,7 @@ No memory to allocate. .Xr cap_mkdb 1 , .Xr malloc 3 .Sh BUGS -Colons (`:') can't be used in names, types, or values. +Colons (`:') cannot be used in names, types, or values. .Pp There are no checks for .Ic tc Ns = Ns Ic name diff --git a/gen/FreeBSD/getcap.c b/gen/FreeBSD/getcap.c index 3cf07fa..649a9f4 100644 --- a/gen/FreeBSD/getcap.c +++ b/gen/FreeBSD/getcap.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)getcap.c 8.3 (Berkeley) 3/25/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/getcap.c,v 1.19 2003/01/02 10:19:43 thomas Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/getcap.c,v 1.23 2009/11/25 04:45:45 wollman Exp $"); #include "namespace.h" #include @@ -193,7 +189,7 @@ getent(char **cap, u_int *len, char **db_array, int fd, const char *name, { DB *capdbp; char *r_end, *rp, **db_p; - int myfd, eof, foundit, retval, clen; + int myfd, eof, foundit, retval; char *record, *cbuf; int tc_not_resolved; char pbuf[_POSIX_PATH_MAX]; @@ -255,14 +251,16 @@ getent(char **cap, u_int *len, char **db_array, int fd, const char *name, return (retval); } /* save the data; close frees it */ - clen = strlen(record); - cbuf = malloc(clen + 1); - memcpy(cbuf, record, clen + 1); + cbuf = strdup(record); if (capdbp->close(capdbp) < 0) { free(cbuf); return (-2); } - *len = clen; + if (cbuf == NULL) { + errno = ENOMEM; + return (-2); + } + *len = strlen(cbuf); *cap = cbuf; return (retval); } else { @@ -649,7 +647,7 @@ int cgetnext(char **bp, char **db_array) { size_t len; - int done, hadreaderr, i, savederrno, status; + int done, hadreaderr, savederrno, status; char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; u_int dummy; @@ -660,7 +658,7 @@ cgetnext(char **bp, char **db_array) (void)cgetclose(); return (-1); } - for(;;) { + for (;;) { if (toprec && !gottoprec) { gottoprec = 1; line = toprec; @@ -711,7 +709,6 @@ cgetnext(char **bp, char **db_array) /* * Line points to a name line. */ - i = 0; done = 0; np = nbuf; for (;;) { diff --git a/gen/FreeBSD/getcap.c.patch b/gen/FreeBSD/getcap.c.patch index 47bac17..d400e40 100644 --- a/gen/FreeBSD/getcap.c.patch +++ b/gen/FreeBSD/getcap.c.patch @@ -1,15 +1,15 @@ ---- getcap.c.orig 2003-05-20 15:21:01.000000000 -0700 -+++ getcap.c 2005-02-27 15:52:46.000000000 -0800 -@@ -40,6 +40,8 @@ +--- getcap.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ getcap.c 2009-11-07 14:51:40.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)getcap.c 8.3 #include - __FBSDID("$FreeBSD: src/lib/libc/gen/getcap.c,v 1.19 2003/01/02 10:19:43 thomas Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/gen/getcap.c,v 1.22 2009/05/14 23:09:33 delphij Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include -@@ -70,7 +72,7 @@ +@@ -66,7 +68,7 @@ static char *toprec; /* Additional recor static int gottoprec; /* Flag indicating retrieval of toprecord */ static int cdbget(DB *, char **, const char *); @@ -18,7 +18,7 @@ static int nfcmp(char *, char *); /* -@@ -166,7 +168,7 @@ +@@ -162,7 +164,7 @@ cgetent(char **buf, char **db_array, con { u_int dummy; @@ -27,7 +27,7 @@ } /* -@@ -189,7 +191,7 @@ +@@ -185,7 +187,7 @@ cgetent(char **buf, char **db_array, con */ static int getent(char **cap, u_int *len, char **db_array, int fd, const char *name, @@ -36,7 +36,7 @@ { DB *capdbp; char *r_end, *rp, **db_p; -@@ -428,7 +430,7 @@ +@@ -426,7 +428,7 @@ tc_exp: { tcend = s; iret = getent(&icap, &ilen, db_p, fd, tc, depth+1, @@ -45,7 +45,7 @@ newicap = icap; /* Put into a register. */ newilen = ilen; if (iret != 0) { -@@ -652,6 +654,7 @@ +@@ -650,6 +652,7 @@ cgetnext(char **bp, char **db_array) int done, hadreaderr, i, savederrno, status; char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; u_int dummy; @@ -53,7 +53,7 @@ if (dbp == NULL) dbp = db_array; -@@ -693,7 +696,7 @@ +@@ -691,7 +694,7 @@ cgetnext(char **bp, char **db_array) slash = 0; continue; } @@ -62,7 +62,7 @@ *line == ':' || *line == '#' || slash) { if (line[len - 2] == '\\') slash = 1; -@@ -765,7 +768,7 @@ +@@ -763,7 +766,7 @@ cgetnext(char **bp, char **db_array) * rather than the duplicate entry record. This is a * matter of semantics that should be resolved. */ diff --git a/gen/FreeBSD/getcwd.3 b/gen/FreeBSD/getcwd.3 index e7591d9..17f039e 100644 --- a/gen/FreeBSD/getcwd.3 +++ b/gen/FreeBSD/getcwd.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getcwd.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/gen/getcwd.3,v 1.16 2003/09/08 19:57:14 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/getcwd.3,v 1.17 2007/01/09 00:27:53 imp Exp $ .\" .Dd November 24, 1997 .Dt GETCWD 3 diff --git a/gen/FreeBSD/getcwd.c b/gen/FreeBSD/getcwd.c index 3b6a813..d06210b 100644 --- a/gen/FreeBSD/getcwd.c +++ b/gen/FreeBSD/getcwd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)getcwd.c 8.5 (Berkeley) 2/7/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/getcwd.c,v 1.25 2003/10/29 10:45:01 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/getcwd.c,v 1.29 2007/01/09 00:27:53 imp Exp $"); #include "namespace.h" #include @@ -91,7 +87,7 @@ getcwd(pt, size) } ept = pt + size; } else { - if ((pt = malloc(ptsize = 1024 - 4)) == NULL) + if ((pt = malloc(ptsize = PATH_MAX)) == NULL) return (NULL); ept = pt + ptsize; } @@ -111,13 +107,13 @@ getcwd(pt, size) *bpt = '\0'; /* - * Allocate bytes (1024 - malloc space) for the string of "../"'s. - * Should always be enough (it's 340 levels). If it's not, allocate + * Allocate 1024 bytes for the string of "../"'s. + * Should always be enough. If it's not, allocate * as necessary. Special case the first stat, it's ".", not "..". */ - if ((up = malloc(upsize = 1024 - 4)) == NULL) + if ((up = malloc(upsize = 1024)) == NULL) goto err; - eup = up + MAXPATHLEN; + eup = up + upsize; bup = up; up[0] = '.'; up[1] = '\0'; @@ -157,7 +153,7 @@ getcwd(pt, size) * as necessary. Max length is 3 for "../", the largest * possible component name, plus a trailing NUL. */ - if (bup + 3 + MAXNAMLEN + 1 >= eup) { + while (bup + 3 + MAXNAMLEN + 1 >= eup) { if ((up = reallocf(up, upsize *= 2)) == NULL) goto err; bup = up; @@ -211,7 +207,7 @@ getcwd(pt, size) * Check for length of the current name, preceding slash, * leading slash. */ - if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { + while (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { size_t len, off; if (!ptsize) { diff --git a/gen/FreeBSD/getcwd.c.patch b/gen/FreeBSD/getcwd.c.patch index ccf6071..bd22ed8 100644 --- a/gen/FreeBSD/getcwd.c.patch +++ b/gen/FreeBSD/getcwd.c.patch @@ -1,6 +1,6 @@ ---- getcwd.c.orig 2006-06-07 17:42:52.000000000 -0700 -+++ getcwd.c 2006-06-07 17:44:47.000000000 -0700 -@@ -54,12 +54,87 @@ +--- getcwd.c.bsdnew 2009-11-08 15:25:00.000000000 -0800 ++++ getcwd.c 2009-11-08 15:30:17.000000000 -0800 +@@ -50,12 +50,87 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/get (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) @@ -91,11 +91,11 @@ { struct dirent *dp; DIR *dir = NULL; -@@ -91,31 +166,25 @@ +@@ -87,33 +162,27 @@ getcwd(pt, size) } ept = pt + size; } else { -- if ((pt = malloc(ptsize = 1024 - 4)) == NULL) +- if ((pt = malloc(ptsize = PATH_MAX)) == NULL) + if ((pt = malloc(ptsize = MAXPATHLEN)) == NULL) return (NULL); ept = pt + ptsize; @@ -121,17 +121,20 @@ *bpt = '\0'; /* -- * Allocate bytes (1024 - malloc space) for the string of "../"'s. -+ * Allocate bytes MAXPATHLEN) for the string of "../"'s. - * Should always be enough (it's 340 levels). If it's not, allocate +- * Allocate 1024 bytes for the string of "../"'s. ++ * Allocate MAXPATHLEN bytes for the string of "../"'s. + * Should always be enough. If it's not, allocate * as necessary. Special case the first stat, it's ".", not "..". */ -- if ((up = malloc(upsize = 1024 - 4)) == NULL) +- if ((up = malloc(upsize = 1024)) == NULL) + if ((up = malloc(upsize = MAXPATHLEN)) == NULL) goto err; - eup = up + MAXPATHLEN; +- eup = up + upsize; ++ eup = up + MAXPATHLEN; bup = up; -@@ -259,3 +328,11 @@ + up[0] = '.'; + up[1] = '\0'; +@@ -255,3 +324,11 @@ err: errno = save_errno; return (NULL); } diff --git a/gen/FreeBSD/gethostname.3 b/gen/FreeBSD/gethostname.3 index 3a25abd..d48103b 100644 --- a/gen/FreeBSD/gethostname.3 +++ b/gen/FreeBSD/gethostname.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)gethostname.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/gethostname.3,v 1.16 2004/07/03 22:30:08 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/gethostname.3,v 1.17 2007/01/09 00:27:54 imp Exp $ .\" .Dd August 18, 2003 .Dt GETHOSTNAME 3 diff --git a/gen/FreeBSD/gethostname.3.patch b/gen/FreeBSD/gethostname.3.patch index 695847a..e114453 100644 --- a/gen/FreeBSD/gethostname.3.patch +++ b/gen/FreeBSD/gethostname.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/gen/FreeBSD/gethostname.3 2004-11-25 11:38:01.000000000 -0800 -+++ _SB/Libc/gen/FreeBSD/gethostname.3.edit 2006-06-28 16:55:50.000000000 -0700 -@@ -60,7 +60,7 @@ +--- gethostname.3.orig 2010-04-28 23:38:49.000000000 -0700 ++++ gethostname.3 2010-04-28 23:47:57.000000000 -0700 +@@ -56,7 +56,7 @@ argument specifies the size of the .Fa name array. @@ -9,3 +9,23 @@ .Pp The .Fn sethostname +@@ -68,8 +68,8 @@ which has length + This call is restricted to the super-user and + is normally used only when the system is bootstrapped. + .Pp +-Host names are limited to +-.Brq Dv HOST_NAME_MAX ++Host names are limited in length to ++.Brq Dv sysconf(_SC_HOST_NAME_MAX) + characters, not including the trailing null, currently 255. + .Sh RETURN VALUES + .Rv -std +@@ -101,7 +101,7 @@ The + function conforms to + .St -p1003.1-2001 . + Callers should be aware that +-.Brq Dv HOST_NAME_MAX ++.Brq Dv sysconf(_SC_HOST_NAME_MAX) + may be variable or infinite, but is guaranteed to be no less than + .Brq Dv _POSIX_HOST_NAME_MAX . + On older systems, this limit was defined in the non-standard header diff --git a/gen/FreeBSD/gethostname.c b/gen/FreeBSD/gethostname.c index 9071be2..65af716 100644 --- a/gen/FreeBSD/gethostname.c +++ b/gen/FreeBSD/gethostname.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,12 +31,13 @@ static char sccsid[] = "@(#)gethostname.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/gethostname.c,v 1.5 2003/08/19 23:01:46 wollman Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/gethostname.c,v 1.8 2007/01/09 00:27:54 imp Exp $"); #include #include #include +#include int gethostname(name, namelen) @@ -49,9 +46,6 @@ gethostname(name, namelen) { int mib[2]; - /* Kluge to avoid ABI breakage. */ - namelen = (int)namelen; - mib[0] = CTL_KERN; mib[1] = KERN_HOSTNAME; if (sysctl(mib, 2, name, &namelen, NULL, 0) == -1) { diff --git a/gen/FreeBSD/gethostname.c.patch b/gen/FreeBSD/gethostname.c.patch index fe4d466..803bd60 100644 --- a/gen/FreeBSD/gethostname.c.patch +++ b/gen/FreeBSD/gethostname.c.patch @@ -1,8 +1,8 @@ ---- gethostname.c.orig 2008-04-05 00:47:41.000000000 -0700 -+++ gethostname.c 2008-04-05 01:04:59.000000000 -0700 -@@ -37,8 +37,10 @@ static char sccsid[] = "@(#)gethostname. +--- gethostname.c.orig 2009-11-07 15:38:57.000000000 -0800 ++++ gethostname.c 2009-11-07 15:44:48.000000000 -0800 +@@ -33,8 +33,10 @@ static char sccsid[] = "@(#)gethostname. #include - __FBSDID("$FreeBSD: src/lib/libc/gen/gethostname.c,v 1.5 2003/08/19 23:01:46 wollman Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/gen/gethostname.c,v 1.8 2007/01/09 00:27:54 imp Exp $"); +#include #include @@ -10,8 +10,8 @@ +#include #include - -@@ -54,10 +56,22 @@ gethostname(name, namelen) + #include +@@ -48,10 +50,22 @@ gethostname(name, namelen) mib[0] = CTL_KERN; mib[1] = KERN_HOSTNAME; diff --git a/gen/FreeBSD/getlogin.c b/gen/FreeBSD/getlogin.c index 6e3208c..823d520 100644 --- a/gen/FreeBSD/getlogin.c +++ b/gen/FreeBSD/getlogin.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,12 +31,11 @@ static char sccsid[] = "@(#)getlogin.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/getlogin.c,v 1.9 2003/10/29 10:45:01 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/getlogin.c,v 1.11 2009/12/05 19:04:21 ed Exp $"); #include #include #include -#include #include #include #include diff --git a/gen/FreeBSD/getlogin.c.patch b/gen/FreeBSD/getlogin.c.patch index d3b63f9..3e8de44 100644 --- a/gen/FreeBSD/getlogin.c.patch +++ b/gen/FreeBSD/getlogin.c.patch @@ -1,14 +1,6 @@ ---- getlogin.c.orig 2007-08-19 17:24:10.000000000 -0700 -+++ getlogin.c 2007-08-19 20:51:27.000000000 -0700 -@@ -40,7 +40,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -53,7 +52,7 @@ +--- getlogin.c.bsdnew 2009-12-08 00:37:57.000000000 -0800 ++++ getlogin.c 2009-12-08 00:44:06.000000000 -0800 +@@ -48,7 +48,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/get #define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&logname_mutex) #define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&logname_mutex) @@ -17,7 +9,7 @@ int _logname_valid; /* known to setlogin() */ static pthread_mutex_t logname_mutex = PTHREAD_MUTEX_INITIALIZER; -@@ -64,7 +63,7 @@ +@@ -59,7 +59,7 @@ getlogin_basic(int *status) static char logname[MAXLOGNAME]; if (_logname_valid == 0) { @@ -26,7 +18,7 @@ *status = errno; return (NULL); } -@@ -87,7 +86,7 @@ +@@ -82,7 +82,7 @@ getlogin(void) } int diff --git a/gen/FreeBSD/getmntinfo.3 b/gen/FreeBSD/getmntinfo.3 index 307d494..e5b6f17 100644 --- a/gen/FreeBSD/getmntinfo.3 +++ b/gen/FreeBSD/getmntinfo.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getmntinfo.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/getmntinfo.3,v 1.12 2002/12/19 09:40:21 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/getmntinfo.3,v 1.13 2007/01/09 00:27:54 imp Exp $ .\" .Dd June 9, 1993 .Dt GETMNTINFO 3 diff --git a/gen/FreeBSD/getmntinfo.3.patch b/gen/FreeBSD/getmntinfo.3.patch index 8a4de0f..2a3e504 100644 --- a/gen/FreeBSD/getmntinfo.3.patch +++ b/gen/FreeBSD/getmntinfo.3.patch @@ -1,15 +1,16 @@ ---- getmntinfo.3.orig 2008-05-13 13:37:51.000000000 -0700 -+++ getmntinfo.3 2008-05-15 19:58:50.000000000 -0700 -@@ -32,26 +32,30 @@ +--- getmntinfo.3.orig 2010-06-17 09:25:28.000000000 -0700 ++++ getmntinfo.3 2010-06-17 09:26:43.000000000 -0700 +@@ -28,28 +28,37 @@ .\" @(#)getmntinfo.3 8.1 (Berkeley) 6/9/93 - .\" $FreeBSD: src/lib/libc/gen/getmntinfo.3,v 1.12 2002/12/19 09:40:21 ru Exp $ + .\" $FreeBSD: src/lib/libc/gen/getmntinfo.3,v 1.13 2007/01/09 00:27:54 imp Exp $ .\" -.Dd June 9, 1993 -+.Dd May 15, 2008 ++.Dd May 4, 2010 .Dt GETMNTINFO 3 .Os .Sh NAME .Nm getmntinfo ++.Nm getmntinfo64 .Nd get information about mounted file systems -.Sh LIBRARY -.Lb libc @@ -19,12 +20,10 @@ .In sys/mount.h .Ft int .Fn getmntinfo "struct statfs **mntbufp" "int flags" -+#ifdef UNIFDEF_LEGACY_64_APIS +.Sh TRANSITIIONAL SYNOPSIS (NOW DEPRECATED) +.Ft int +.br +.Fn getmntinfo64 "struct statfs64 **mntbufp" "int flags" ; -+#endif /* UNIFDEF_LEGACY_64_APIS */ .Sh DESCRIPTION The .Fn getmntinfo @@ -34,46 +33,19 @@ +.Ft statfs structures describing each currently mounted file system (see .Xr statfs 2 ) . ++As ++.Xr statfs 2 ++indicates, the structure is defined differently depending on ++whether the macro _DARWIN_FEATURE_64_BIT_INODE is defined (see ++.Xr stat 2 ++for more information on this macro). .Pp -@@ -62,6 +66,33 @@ - .Fa flags - argument transparently to - .Xr getfsstat 2 . -+#ifdef UNIFDEF_LEGACY_64_APIS -+.Pp -+Like -+.Xr getfsstat 2 , -+when the macro -+.Dv _DARWIN_FEATURE_64_BIT_INODE -+is defined, the -+.Ft ino_t -+type will be 64-bits (force 64-bit inode mode by defining the -+.Dv _DARWIN_USE_64_BIT_INODE -+macro before including header files). -+This will cause the symbol variant of -+.Fn getmntinfo , -+with the -+.Fa $INODE64 -+suffixes, to be automatically linked in. -+In addition, the -+.Ft statfs -+structure will be the 64-bit inode version. -+If -+.Dv _DARWIN_USE_64_BIT_INODE -+is not defined, both -+.Fn getmntinfo -+and the -+.Ft statfs -+structure will refer to the 32-bit inode versions. -+#endif /* UNIFDEF_LEGACY_64_APIS */ - .Sh RETURN VALUES - On successful completion, + The .Fn getmntinfo -@@ -86,6 +117,24 @@ +@@ -82,9 +91,26 @@ routines .Xr getfsstat 2 or .Xr malloc 3 . -+#ifdef UNIFDEF_LEGACY_64_APIS +.Sh TRANSITIONAL DESCRIPTION (NOW DEPRECATED) +The +.Fn getmntinfo64 @@ -90,37 +62,10 @@ +structure used by this deprecated routine is the same as the +.Ft statfs +structure when 64-bit inodes are in effect. -+#endif /* UNIFDEF_LEGACY_64_APIS */ .Sh SEE ALSO .Xr getfsstat 2 , .Xr mount 2 , -@@ -99,15 +148,29 @@ - .Sh BUGS - The - .Fn getmntinfo -+#ifdef UNIFDEF_LEGACY_64_APIS -+and -+.Fn getmntinfo64 -+functions write the array of structures to an internal static object -+#else /* !UNIFDEF_LEGACY_64_APIS */ - function writes the array of structures to an internal static object -+#endif /* UNIFDEF_LEGACY_64_APIS */ - and returns - a pointer to that object. - Subsequent calls to - .Fn getmntinfo -+#ifdef UNIFDEF_LEGACY_64_APIS -+and -+.Fn getmntinfo64 -+#endif /* UNIFDEF_LEGACY_64_APIS */ - will modify the same object. - .Pp - The memory allocated by - .Fn getmntinfo -+#ifdef UNIFDEF_LEGACY_64_APIS -+and -+.Fn getmntinfo64 -+#endif /* UNIFDEF_LEGACY_64_APIS */ - cannot be - .Xr free 3 Ns 'd - by the application. ++.Xr stat 2 , + .Xr statfs 2 , + .Xr mount 8 + .Sh HISTORY diff --git a/gen/FreeBSD/getmntinfo.c b/gen/FreeBSD/getmntinfo.c index 383df1e..24b7886 100644 --- a/gen/FreeBSD/getmntinfo.c +++ b/gen/FreeBSD/getmntinfo.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)getmntinfo.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/getmntinfo.c,v 1.4 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/getmntinfo.c,v 1.5 2007/01/09 00:27:54 imp Exp $"); #include #include diff --git a/gen/FreeBSD/getpagesize.3 b/gen/FreeBSD/getpagesize.3 index a8e57e1..2c10efd 100644 --- a/gen/FreeBSD/getpagesize.3 +++ b/gen/FreeBSD/getpagesize.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getpagesize.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/getpagesize.3,v 1.11 2002/12/27 12:15:28 schweikh Exp $ +.\" $FreeBSD: src/lib/libc/gen/getpagesize.3,v 1.12 2007/01/09 00:27:54 imp Exp $ .\" .Dd June 4, 1993 .Dt GETPAGESIZE 3 diff --git a/gen/FreeBSD/getpagesize.c b/gen/FreeBSD/getpagesize.c index 3c8881e..1467ca8 100644 --- a/gen/FreeBSD/getpagesize.c +++ b/gen/FreeBSD/getpagesize.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,11 +31,13 @@ static char sccsid[] = "@(#)getpagesize.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/getpagesize.c,v 1.4 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/getpagesize.c,v 1.6 2007/01/09 00:27:54 imp Exp $"); #include #include +#include + /* * This is unlikely to change over the running time of any * program, so we cache the result to save some syscalls. diff --git a/gen/FreeBSD/getpass.3 b/gen/FreeBSD/getpass.3 index f3317bd..62d20a7 100644 --- a/gen/FreeBSD/getpass.3 +++ b/gen/FreeBSD/getpass.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getpass.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/getpass.3,v 1.11 2001/11/22 09:48:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/getpass.3,v 1.12 2007/01/09 00:27:54 imp Exp $ .\" .Dd June 4, 1993 .Dt GETPASS 3 diff --git a/gen/FreeBSD/getprogname.3.patch b/gen/FreeBSD/getprogname.3.patch index be7858d..a3fff66 100644 --- a/gen/FreeBSD/getprogname.3.patch +++ b/gen/FreeBSD/getprogname.3.patch @@ -1,6 +1,6 @@ ---- getprogname.3.orig Fri May 28 17:17:08 2004 -+++ getprogname.3 Fri May 28 17:17:39 2004 -@@ -85,8 +85,7 @@ +--- getprogname.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ getprogname.3 2009-11-07 14:51:39.000000000 -0800 +@@ -85,8 +85,7 @@ Calling allows the aforementioned library to learn the program name without modifications to the start-up code. .Sh SEE ALSO diff --git a/gen/FreeBSD/getprogname.c.patch b/gen/FreeBSD/getprogname.c.patch index 54f9906..274026c 100644 --- a/gen/FreeBSD/getprogname.c.patch +++ b/gen/FreeBSD/getprogname.c.patch @@ -1,6 +1,6 @@ ---- getprogname.c.orig Mon Apr 28 15:05:02 2003 -+++ getprogname.c Sat May 3 14:04:57 2003 -@@ -3,6 +3,8 @@ +--- getprogname.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ getprogname.c 2009-11-07 14:51:39.000000000 -0800 +@@ -3,6 +3,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/get #include "namespace.h" #include diff --git a/gen/FreeBSD/isatty.c b/gen/FreeBSD/isatty.c index d16a963..e6153ac 100644 --- a/gen/FreeBSD/isatty.c +++ b/gen/FreeBSD/isatty.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)isatty.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/isatty.c,v 1.5 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/isatty.c,v 1.6 2007/01/09 00:27:54 imp Exp $"); #include #include diff --git a/gen/FreeBSD/isatty.c.patch b/gen/FreeBSD/isatty.c.patch index 8ab1b76..aba10e1 100644 --- a/gen/FreeBSD/isatty.c.patch +++ b/gen/FreeBSD/isatty.c.patch @@ -1,6 +1,6 @@ ---- isatty.c.orig 2008-04-05 00:47:41.000000000 -0700 -+++ isatty.c 2008-04-05 01:05:40.000000000 -0700 -@@ -39,14 +39,22 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/isa +--- isatty.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ isatty.c 2009-11-07 14:51:40.000000000 -0800 +@@ -35,14 +35,22 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/isa #include #include diff --git a/gen/FreeBSD/jrand48.c.patch b/gen/FreeBSD/jrand48.c.patch index c1bc3df..bb0ec7c 100644 --- a/gen/FreeBSD/jrand48.c.patch +++ b/gen/FreeBSD/jrand48.c.patch @@ -1,6 +1,6 @@ ---- jrand48.c.orig 2003-05-20 15:21:02.000000000 -0700 -+++ jrand48.c 2005-11-03 13:31:28.000000000 -0800 -@@ -19,6 +19,7 @@ +--- jrand48.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ jrand48.c 2009-11-07 14:51:39.000000000 -0800 +@@ -19,6 +19,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/jra long jrand48(unsigned short xseed[3]) { diff --git a/gen/FreeBSD/lcong48.c.patch b/gen/FreeBSD/lcong48.c.patch index 3146983..91ad712 100644 --- a/gen/FreeBSD/lcong48.c.patch +++ b/gen/FreeBSD/lcong48.c.patch @@ -1,6 +1,6 @@ ---- lcong48.c.orig 2003-05-20 15:21:02.000000000 -0700 -+++ lcong48.c 2005-11-03 13:36:03.000000000 -0800 -@@ -16,18 +16,10 @@ +--- lcong48.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ lcong48.c 2009-11-07 14:51:39.000000000 -0800 +@@ -16,18 +16,10 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/lco #include "rand48.h" diff --git a/gen/FreeBSD/lockf.3 b/gen/FreeBSD/lockf.3 index bf6b7b1..cad5fa7 100644 --- a/gen/FreeBSD/lockf.3 +++ b/gen/FreeBSD/lockf.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: lockf.3,v 1.2 1998/02/05 18:47:28 perry Exp $ +.\" $NetBSD: lockf.3,v 1.10 2008/04/30 13:10:50 martin Exp $ .\" .\" Copyright (c) 1997 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -14,13 +14,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -34,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/lockf.3,v 1.13 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/lockf.3,v 1.14 2009/03/04 01:01:26 delphij Exp $ .\" .Dd December 19, 1997 .Dt LOCKF 3 diff --git a/gen/FreeBSD/lockf.3.patch b/gen/FreeBSD/lockf.3.patch index 417bd14..51a735f 100644 --- a/gen/FreeBSD/lockf.3.patch +++ b/gen/FreeBSD/lockf.3.patch @@ -1,6 +1,6 @@ ---- lockf.3 2004-11-25 11:38:01.000000000 -0800 -+++ lockf.3.edit 2006-07-15 14:04:01.000000000 -0700 -@@ -47,7 +47,7 @@ +--- lockf.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ lockf.3 2009-11-07 14:51:40.000000000 -0800 +@@ -40,7 +40,7 @@ .Sh SYNOPSIS .In unistd.h .Ft int @@ -9,7 +9,7 @@ .Sh DESCRIPTION The .Fn lockf -@@ -56,10 +56,10 @@ +@@ -49,10 +49,10 @@ Calls to .Fn lockf from other processes which attempt to lock the locked file section will either return an error value or block until the section becomes unlocked. @@ -22,7 +22,7 @@ is an open file descriptor. The file descriptor must have been opened either for write-only .Dv ( O_WRONLY ) -@@ -214,7 +214,7 @@ +@@ -207,7 +207,7 @@ or and the section is already locked by another process. .It Bq Er EBADF The argument @@ -31,7 +31,7 @@ is not a valid open file descriptor. .Pp The argument -@@ -224,7 +224,7 @@ +@@ -217,7 +217,7 @@ is or .Dv F_TLOCK , and @@ -40,7 +40,7 @@ is not a valid file descriptor open for writing. .It Bq Er EDEADLK The argument -@@ -243,25 +243,29 @@ +@@ -236,25 +236,29 @@ was interrupted by the delivery of a sig The argument .Fa function is not one of diff --git a/gen/FreeBSD/lockf.c b/gen/FreeBSD/lockf.c index 375b2ce..3581270 100644 --- a/gen/FreeBSD/lockf.c +++ b/gen/FreeBSD/lockf.c @@ -1,3 +1,4 @@ +/* $NetBSD: lockf.c,v 1.3 2008/04/28 20:22:59 martin Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. * All rights reserved. @@ -13,13 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -34,9 +28,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* $NetBSD: lockf.c,v 1.1 1997/12/20 20:23:18 kleink Exp $ */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/lockf.c,v 1.8 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/lockf.c,v 1.10 2009/03/04 01:01:26 delphij Exp $"); #include "namespace.h" #include @@ -45,10 +38,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/lockf.c,v 1.8 2002/02/01 00:57:29 obrien Ex #include "un-namespace.h" int -lockf(filedes, function, size) - int filedes; - int function; - off_t size; +lockf(int filedes, int function, off_t size) { struct flock fl; int cmd; @@ -74,7 +64,7 @@ lockf(filedes, function, size) fl.l_type = F_WRLCK; if (_fcntl(filedes, F_GETLK, &fl) == -1) return (-1); - if (fl.l_type == F_UNLCK || fl.l_pid == getpid()) + if (fl.l_type == F_UNLCK || (fl.l_sysid == 0 && fl.l_pid == getpid())) return (0); errno = EAGAIN; return (-1); diff --git a/gen/FreeBSD/lockf.c.patch b/gen/FreeBSD/lockf.c.patch index 4d31bc7..ff083eb 100644 --- a/gen/FreeBSD/lockf.c.patch +++ b/gen/FreeBSD/lockf.c.patch @@ -1,8 +1,8 @@ ---- lockf.c.orig 2006-09-16 19:12:39.000000000 -0700 -+++ lockf.c 2006-09-16 20:35:36.000000000 -0700 -@@ -38,6 +38,13 @@ +--- lockf.c.orig 2009-11-07 15:52:44.000000000 -0800 ++++ lockf.c 2009-11-07 16:04:57.000000000 -0800 +@@ -31,6 +31,13 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/gen/lockf.c,v 1.8 2002/02/01 00:57:29 obrien Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/gen/lockf.c,v 1.10 2009/03/04 01:01:26 delphij Exp $"); +#ifdef VARIANT_CANCELABLE +int __fcntl(int, int, void *); @@ -14,15 +14,7 @@ #include "namespace.h" #include #include -@@ -53,6 +60,7 @@ - struct flock fl; - int cmd; - -+ - fl.l_start = 0; - fl.l_len = size; - fl.l_whence = SEEK_CUR; -@@ -72,8 +80,13 @@ +@@ -62,9 +69,14 @@ lockf(int filedes, int function, off_t s break; case F_TEST: fl.l_type = F_WRLCK; @@ -30,22 +22,24 @@ +#ifdef VARIANT_CANCELABLE + if (__fcntl(filedes, F_GETLK, &fl) == -1) return (-1); +- if (fl.l_type == F_UNLCK || (fl.l_sysid == 0 && fl.l_pid == getpid())) +#else /* !VARIANT_CANCELABLE */ + if (__fcntl_nocancel(filedes, F_GETLK, &fl) == -1) + return (-1); +#endif /* VARIANT_CANCELABLE */ - if (fl.l_type == F_UNLCK || fl.l_pid == getpid()) ++ if (fl.l_type == F_UNLCK || fl.l_pid == getpid()) return (0); errno = EAGAIN; -@@ -85,5 +98,10 @@ + return (-1); +@@ -75,5 +87,10 @@ lockf(int filedes, int function, off_t s /* NOTREACHED */ } - return (_fcntl(filedes, cmd, &fl)); +#ifdef VARIANT_CANCELABLE -+ return (__fcntl(filedes, cmd, &fl)); ++ return (__fcntl(filedes, cmd, &fl)); +#else /* !VARIANT_CANCELABLE */ -+ return (__fcntl_nocancel(filedes, cmd, &fl)); ++ return (__fcntl_nocancel(filedes, cmd, &fl)); +#endif /* VARIANT_CANCELABLE */ } + diff --git a/gen/FreeBSD/lrand48.c.patch b/gen/FreeBSD/lrand48.c.patch index 1b1734e..90798d9 100644 --- a/gen/FreeBSD/lrand48.c.patch +++ b/gen/FreeBSD/lrand48.c.patch @@ -1,6 +1,6 @@ ---- lrand48.c.orig 2003-05-20 15:21:02.000000000 -0700 -+++ lrand48.c 2005-11-03 13:41:09.000000000 -0800 -@@ -16,11 +16,9 @@ +--- lrand48.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ lrand48.c 2009-11-07 14:51:39.000000000 -0800 +@@ -16,11 +16,9 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/lra #include "rand48.h" diff --git a/gen/FreeBSD/makecontext.3.patch b/gen/FreeBSD/makecontext.3.patch index 19ea7f9..40520a8 100644 --- a/gen/FreeBSD/makecontext.3.patch +++ b/gen/FreeBSD/makecontext.3.patch @@ -1,5 +1,5 @@ ---- makecontext.3.orig 2009-03-13 03:05:02.000000000 -0700 -+++ makecontext.3 2009-03-13 03:12:49.000000000 -0700 +--- makecontext.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ makecontext.3 2009-11-07 14:51:39.000000000 -0800 @@ -48,7 +48,7 @@ .Ft void .Fo makecontext @@ -9,7 +9,7 @@ .Fa "int argc" ... .Fc .Ft int -@@ -64,7 +64,9 @@ +@@ -64,7 +64,9 @@ which must have previously been initiali and had a stack allocated for it. The context is modified so that it will continue execution by invoking .Fn func diff --git a/gen/FreeBSD/mrand48.c.patch b/gen/FreeBSD/mrand48.c.patch index 97ee465..23149dd 100644 --- a/gen/FreeBSD/mrand48.c.patch +++ b/gen/FreeBSD/mrand48.c.patch @@ -1,6 +1,6 @@ ---- mrand48.c.orig 2003-05-20 15:21:02.000000000 -0700 -+++ mrand48.c 2005-11-03 13:42:32.000000000 -0800 -@@ -16,11 +16,9 @@ +--- mrand48.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ mrand48.c 2009-11-07 14:51:39.000000000 -0800 +@@ -16,11 +16,9 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/mra #include "rand48.h" diff --git a/gen/FreeBSD/nice.3 b/gen/FreeBSD/nice.3 index 6a98d9e..2bb58a3 100644 --- a/gen/FreeBSD/nice.3 +++ b/gen/FreeBSD/nice.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)nice.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/nice.3,v 1.11 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/nice.3,v 1.12 2007/01/09 00:27:54 imp Exp $ .\" .Dd June 4, 1993 .Dt NICE 3 diff --git a/gen/FreeBSD/nice.c b/gen/FreeBSD/nice.c index 453caa7..f24d12d 100644 --- a/gen/FreeBSD/nice.c +++ b/gen/FreeBSD/nice.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)nice.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/nice.c,v 1.3 2002/03/22 21:52:05 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/nice.c,v 1.4 2007/01/09 00:27:54 imp Exp $"); #include #include diff --git a/gen/FreeBSD/nice.c.patch b/gen/FreeBSD/nice.c.patch index 6ce1320..f1a3fec 100644 --- a/gen/FreeBSD/nice.c.patch +++ b/gen/FreeBSD/nice.c.patch @@ -1,11 +1,6 @@ -Index: nice.c -=================================================================== -RCS file: /cvs/root/Libc/gen/FreeBSD/nice.c,v -retrieving revision 1.2 -diff -u -d -b -w -p -r1.2 nice.c ---- nice.c 2003/05/20 22:21:02 1.2 -+++ nice.c 2005/04/06 22:28:10 -@@ -42,7 +42,9 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/nic +--- nice.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ nice.c 2009-11-07 14:51:40.000000000 -0800 +@@ -38,7 +38,9 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/nic #include #include #include @@ -16,7 +11,7 @@ diff -u -d -b -w -p -r1.2 nice.c /* * Backwards compatible nice. */ -@@ -50,11 +52,18 @@ int +@@ -46,11 +48,18 @@ int nice(incr) int incr; { diff --git a/gen/FreeBSD/nrand48.c.patch b/gen/FreeBSD/nrand48.c.patch index 06935d5..101d6ef 100644 --- a/gen/FreeBSD/nrand48.c.patch +++ b/gen/FreeBSD/nrand48.c.patch @@ -1,6 +1,6 @@ ---- nrand48.c.orig 2003-05-20 15:21:02.000000000 -0700 -+++ nrand48.c 2005-11-03 13:43:51.000000000 -0800 -@@ -19,6 +19,7 @@ +--- nrand48.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ nrand48.c 2009-11-07 14:51:39.000000000 -0800 +@@ -19,6 +19,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/nra long nrand48(unsigned short xseed[3]) { diff --git a/gen/FreeBSD/opendir.c b/gen/FreeBSD/opendir.c index 9148240..1892c36 100644 --- a/gen/FreeBSD/opendir.c +++ b/gen/FreeBSD/opendir.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)opendir.c 8.8 (Berkeley) 5/1/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/opendir.c,v 1.22 2004/08/14 17:46:10 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/opendir.c,v 1.24 2008/04/16 18:40:52 delphij Exp $"); #include "namespace.h" #include @@ -55,17 +51,14 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/opendir.c,v 1.22 2004/08/14 17:46:10 stefan * Open a directory. */ DIR * -opendir(name) - const char *name; +opendir(const char *name) { return (__opendir2(name, DTF_HIDEW|DTF_NODUP)); } DIR * -__opendir2(name, flags) - const char *name; - int flags; +__opendir2(const char *name, int flags) { DIR *dirp; int fd; diff --git a/gen/FreeBSD/opendir.c.patch b/gen/FreeBSD/opendir.c.patch index d4ddb1e..5453b80 100644 --- a/gen/FreeBSD/opendir.c.patch +++ b/gen/FreeBSD/opendir.c.patch @@ -1,6 +1,6 @@ ---- opendir.c.orig 2007-01-24 14:10:41.000000000 -0800 -+++ opendir.c 2007-01-28 01:37:51.000000000 -0800 -@@ -48,6 +48,7 @@ +--- opendir.c.orig 2009-11-08 17:01:43.000000000 -0800 ++++ opendir.c 2009-11-08 17:01:51.000000000 -0800 +@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/ope #include #include #include @@ -8,7 +8,7 @@ #include "un-namespace.h" #include "telldir.h" -@@ -72,27 +73,15 @@ +@@ -65,27 +66,15 @@ __opendir2(const char *name, int flags) int incr; int saved_errno; int unionstack; @@ -40,7 +40,7 @@ if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 || (dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL) goto fail; -@@ -154,7 +143,11 @@ +@@ -147,7 +136,11 @@ __opendir2(const char *name, int flags) ddptr = buf + (len - space); } @@ -52,7 +52,7 @@ if (n > 0) { ddptr += n; space -= n; -@@ -262,14 +255,18 @@ +@@ -255,14 +248,18 @@ __opendir2(const char *name, int flags) dirp->dd_buf = malloc(dirp->dd_len); if (dirp->dd_buf == NULL) goto fail; diff --git a/gen/FreeBSD/pause.3 b/gen/FreeBSD/pause.3 index b8c257e..b7ddcae 100644 --- a/gen/FreeBSD/pause.3 +++ b/gen/FreeBSD/pause.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)pause.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/pause.3,v 1.8 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/pause.3,v 1.9 2007/01/09 00:27:54 imp Exp $ .\" .Dd June 4, 1993 .Dt PAUSE 3 diff --git a/gen/FreeBSD/pause.c b/gen/FreeBSD/pause.c index 4f56289..6f78fe9 100644 --- a/gen/FreeBSD/pause.c +++ b/gen/FreeBSD/pause.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.8 2009/12/05 19:31:38 ed Exp $"); #include #include @@ -44,7 +40,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.6 2002/02/01 00:57:29 obrien Ex * Backwards compatible pause. */ int -__pause() +__pause(void) { return sigpause(sigblock(0L)); } diff --git a/gen/FreeBSD/pause.c.patch b/gen/FreeBSD/pause.c.patch index 07f2f75..5b78b5e 100644 --- a/gen/FreeBSD/pause.c.patch +++ b/gen/FreeBSD/pause.c.patch @@ -1,6 +1,6 @@ ---- pause.c.orig 2006-09-17 12:11:15.000000000 -0700 -+++ pause.c 2006-09-24 16:38:00.000000000 -0700 -@@ -34,6 +34,13 @@ +--- pause.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ pause.c 2009-11-07 14:51:40.000000000 -0800 +@@ -30,6 +30,13 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ @@ -12,9 +12,9 @@ +#endif /* VARIANT_CANCELABLE */ + #include - __FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.7 2007/01/09 00:27:54 imp Exp $"); -@@ -46,7 +53,10 @@ +@@ -42,7 +49,10 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pau int __pause() { diff --git a/gen/FreeBSD/popen.c b/gen/FreeBSD/popen.c index 0ed5657..3432686 100644 --- a/gen/FreeBSD/popen.c +++ b/gen/FreeBSD/popen.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,10 +34,11 @@ static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/popen.c,v 1.18 2003/01/04 00:15:15 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/popen.c,v 1.21 2009/05/27 19:28:04 ed Exp $"); #include "namespace.h" #include +#include #include #include @@ -57,11 +54,12 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/popen.c,v 1.18 2003/01/04 00:15:15 tjr Exp extern char **environ; -static struct pid { - struct pid *next; +struct pid { + SLIST_ENTRY(pid) next; FILE *fp; pid_t pid; -} *pidlist; +}; +static SLIST_HEAD(, pid) pidlist = SLIST_HEAD_INITIALIZER(pidlist); static pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER; #define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&pidlist_mutex) @@ -137,9 +135,8 @@ popen(command, type) } (void)_close(pdes[1]); } - for (p = pidlist; p; p = p->next) { + SLIST_FOREACH(p, &pidlist, next) (void)_close(fileno(p->fp)); - } _execve(_PATH_BSHELL, argv, environ); _exit(127); /* NOTREACHED */ @@ -159,8 +156,7 @@ popen(command, type) cur->fp = iop; cur->pid = pid; THREAD_LOCK(); - cur->next = pidlist; - pidlist = cur; + SLIST_INSERT_HEAD(&pidlist, cur, next); THREAD_UNLOCK(); return (iop); @@ -175,7 +171,7 @@ int pclose(iop) FILE *iop; { - struct pid *cur, *last; + struct pid *cur, *last = NULL; int pstat; pid_t pid; @@ -183,17 +179,19 @@ pclose(iop) * Find the appropriate file pointer and remove it from the list. */ THREAD_LOCK(); - for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next) + SLIST_FOREACH(cur, &pidlist, next) { if (cur->fp == iop) break; + last = cur; + } if (cur == NULL) { THREAD_UNLOCK(); return (-1); } if (last == NULL) - pidlist = cur->next; + SLIST_REMOVE_HEAD(&pidlist, next); else - last->next = cur->next; + SLIST_REMOVE_AFTER(last, next); THREAD_UNLOCK(); (void)fclose(iop); diff --git a/gen/FreeBSD/popen.c.patch b/gen/FreeBSD/popen.c.patch index f4467ff..e58f314 100644 --- a/gen/FreeBSD/popen.c.patch +++ b/gen/FreeBSD/popen.c.patch @@ -1,6 +1,6 @@ ---- popen.c.orig 2009-03-03 02:04:57.000000000 -0800 -+++ popen.c 2009-03-03 15:28:31.000000000 -0800 -@@ -34,6 +34,10 @@ +--- popen.c.orig 2009-12-02 15:21:37.000000000 -0800 ++++ popen.c 2009-12-02 15:36:51.000000000 -0800 +@@ -30,6 +30,10 @@ * SUCH DAMAGE. */ @@ -11,9 +11,9 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95"; #endif /* LIBC_SCCS and not lint */ -@@ -43,7 +47,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop - #include "namespace.h" +@@ -40,7 +44,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop #include + #include #include - +#include @@ -21,7 +21,7 @@ #include #include #include -@@ -52,17 +57,29 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop +@@ -49,18 +54,39 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop #include #include #include @@ -32,30 +32,39 @@ -extern char **environ; +#include +#define environ (*_NSGetEnviron()) ++ ++/* Our queue.h doesn't have SLIST_REMOVE_AFTER in it yet ++ * API: Add SLIST_REMOVE_AFTER to sys/queue.h (from FreeBSD) ++ */ ++#ifndef SLIST_REMOVE_AFTER ++#define SLIST_REMOVE_AFTER(elm, field) do { \ ++ SLIST_NEXT(elm, field) = \ ++ SLIST_NEXT(SLIST_NEXT(elm, field), field); \ ++} while (0) ++#endif --static struct pid { +/* 3516149 - store file descriptor and use that to close to prevent blocking */ -+struct pid { - struct pid *next; + struct pid { + SLIST_ENTRY(pid) next; FILE *fp; + int fd; pid_t pid; --} *pidlist; + }; +-static SLIST_HEAD(, pid) pidlist = SLIST_HEAD_INITIALIZER(pidlist); -static pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER; -+}; +#define pidlist __popen_pidlist +#define pidlist_mutex __popen_pidlist_mutex +#ifndef BUILDING_VARIANT -+__private_extern__ struct pid *pidlist = NULL; ++__private_extern__ SLIST_HEAD(, pid) pidlist = SLIST_HEAD_INITIALIZER(pidlist); +__private_extern__ pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER; +#else /* BUILDING_VARIANT */ -+extern struct pid *pidlist; ++extern SLIST_HEAD(, pid) pidlist; +extern pthread_mutex_t pidlist_mutex; +#endif /* !BUILDING_VARIANT */ #define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&pidlist_mutex) #define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&pidlist_mutex) -@@ -73,85 +90,109 @@ popen(command, type) +@@ -71,84 +97,108 @@ popen(command, type) { struct pid *cur; FILE *iop; @@ -145,9 +154,8 @@ + } + (void)posix_spawn_file_actions_addclose(&file_actions, pdes[1]); + } -+ for (p = pidlist; p; p = p->next) { ++ SLIST_FOREACH(p, &pidlist, next) + (void)posix_spawn_file_actions_addclose(&file_actions, p->fd); -+ } + argv[0] = "sh"; argv[1] = "-c"; @@ -195,9 +203,8 @@ - } - (void)_close(pdes[1]); - } -- for (p = pidlist; p; p = p->next) { +- SLIST_FOREACH(p, &pidlist, next) - (void)_close(fileno(p->fp)); -- } - _execve(_PATH_BSHELL, argv, environ); - _exit(127); - /* NOTREACHED */ @@ -217,9 +224,9 @@ (void)_close(pdes[0]); } -@@ -162,10 +203,11 @@ popen(command, type) - cur->next = pidlist; - pidlist = cur; +@@ -158,10 +208,11 @@ popen(command, type) + THREAD_LOCK(); + SLIST_INSERT_HEAD(&pidlist, cur, next); THREAD_UNLOCK(); - + fwide(iop, -1); /* byte stream */ @@ -230,7 +237,7 @@ /* * pclose -- * Pclose returns -1 if stream is not associated with a `popened' command, -@@ -198,6 +240,10 @@ pclose(iop) +@@ -196,6 +247,10 @@ pclose(iop) (void)fclose(iop); @@ -241,7 +248,7 @@ do { pid = _wait4(cur->pid, &pstat, 0, (struct rusage *)0); } while (pid == -1 && errno == EINTR); -@@ -206,3 +252,4 @@ pclose(iop) +@@ -204,3 +259,4 @@ pclose(iop) return (pid == -1 ? -1 : pstat); } diff --git a/gen/FreeBSD/pselect.3.patch b/gen/FreeBSD/pselect.3.patch index b435243..a1099cd 100644 --- a/gen/FreeBSD/pselect.3.patch +++ b/gen/FreeBSD/pselect.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/gen/FreeBSD/pselect.3 2003-05-20 15:21:02.000000000 -0700 -+++ _SB/Libc/gen/FreeBSD/pselect.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- pselect.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ pselect.3 2009-11-07 14:51:39.000000000 -0800 @@ -37,15 +37,15 @@ .Sh LIBRARY .Lb libc @@ -22,7 +22,7 @@ .Fc .Sh DESCRIPTION The -@@ -57,7 +57,7 @@ +@@ -57,7 +57,7 @@ as a slightly stronger version of The .Fa nfds , readfds , writefds , and @@ -31,7 +31,7 @@ arguments are all identical to the analogous arguments of .Fn select . The -@@ -65,7 +65,7 @@ +@@ -65,7 +65,7 @@ The argument in .Fn pselect points to a @@ -40,7 +40,7 @@ rather than the (modifiable) .Vt "struct timeval" used by -@@ -76,7 +76,7 @@ +@@ -76,7 +76,7 @@ a null pointer may be passed to indicate .Fn pselect should wait indefinitely. Finally, diff --git a/gen/FreeBSD/pselect.c.patch b/gen/FreeBSD/pselect.c.patch index b72ccfc..26ecf91 100644 --- a/gen/FreeBSD/pselect.c.patch +++ b/gen/FreeBSD/pselect.c.patch @@ -1,5 +1,5 @@ ---- pselect.c.orig 2007-08-19 17:38:56.000000000 -0700 -+++ pselect.c 2007-08-19 19:15:50.000000000 -0700 +--- pselect.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ pselect.c 2009-11-07 14:51:39.000000000 -0800 @@ -27,12 +27,22 @@ * SUCH DAMAGE. */ diff --git a/gen/FreeBSD/psignal.3 b/gen/FreeBSD/psignal.3 index 02013a4..c59d79e 100644 --- a/gen/FreeBSD/psignal.3 +++ b/gen/FreeBSD/psignal.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)psignal.3 8.2 (Berkeley) 2/27/95 -.\" $FreeBSD: src/lib/libc/gen/psignal.3,v 1.16 2002/12/30 21:18:02 schweikh Exp $ +.\" $FreeBSD: src/lib/libc/gen/psignal.3,v 1.17 2007/01/09 00:27:54 imp Exp $ .\" .Dd February 27, 1995 .Dt PSIGNAL 3 diff --git a/gen/FreeBSD/psignal.3.patch b/gen/FreeBSD/psignal.3.patch new file mode 100644 index 0000000..fd4a161 --- /dev/null +++ b/gen/FreeBSD/psignal.3.patch @@ -0,0 +1,22 @@ +--- psignal.3.orig 2010-05-06 12:14:16.000000000 -0700 ++++ psignal.3 2010-05-06 12:21:47.000000000 -0700 +@@ -98,6 +98,19 @@ contains a count of the strings in + .Va sys_siglist + and + .Va sys_signame . ++.Sh RETURN VALUES ++.Fn strsignal ++a pointer to the desired message or a NULL value indicating an error. This ++string is not to be freed by the caller. Beginning with Mac OSX 10.7, this ++string is unique to each thread. ++.Sh ERRORS ++.Fn strsignal ++will fail and no additional memory will be allocated if ++one of the following are true: ++.Bl -tag -width Er ++.It Bq Er ENOMEM ++There was insufficient memory to allocate storage space for the return value in the running thread. ++.El + .Sh SEE ALSO + .Xr sigaction 2 , + .Xr perror 3 , diff --git a/gen/FreeBSD/psignal.c b/gen/FreeBSD/psignal.c index 832e04b..8894b1b 100644 --- a/gen/FreeBSD/psignal.c +++ b/gen/FreeBSD/psignal.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)psignal.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/psignal.c,v 1.7 2002/02/01 01:08:48 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/psignal.c,v 1.8 2007/01/09 00:27:54 imp Exp $"); /* * Print the name of the signal indicated diff --git a/gen/FreeBSD/raise.3 b/gen/FreeBSD/raise.3 index 1a8fcd7..dbdff26 100644 --- a/gen/FreeBSD/raise.3 +++ b/gen/FreeBSD/raise.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)raise.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/raise.3,v 1.7 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/raise.3,v 1.8 2007/01/09 00:27:55 imp Exp $ .\" .Dd June 4, 1993 .Dt RAISE 3 diff --git a/gen/FreeBSD/raise.c b/gen/FreeBSD/raise.c index 4a94cb9..e9665e8 100644 --- a/gen/FreeBSD/raise.c +++ b/gen/FreeBSD/raise.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)raise.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/raise.c,v 1.4 2003/07/19 05:22:56 davidxu Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/raise.c,v 1.5 2007/01/09 00:27:55 imp Exp $"); #include #include diff --git a/gen/FreeBSD/rand48.3 b/gen/FreeBSD/rand48.3 index c009a2d..d67f163 100644 --- a/gen/FreeBSD/rand48.3 +++ b/gen/FreeBSD/rand48.3 @@ -10,7 +10,7 @@ .\" to anyone/anything when using this software. .\" .\" @(#)rand48.3 V1.0 MB 8 Oct 1993 -.\" $FreeBSD: src/lib/libc/gen/rand48.3,v 1.16 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/rand48.3,v 1.17 2005/01/20 09:17:02 ru Exp $ .\" .Dd October 8, 1993 .Dt RAND48 3 @@ -177,8 +177,8 @@ generator calls. .Pp For a more powerful random number generator, see .Xr random 3 . -.Sh AUTHORS -.An Martin Birgmeier .Sh SEE ALSO .Xr rand 3 , .Xr random 3 +.Sh AUTHORS +.An Martin Birgmeier diff --git a/gen/FreeBSD/rand48.3.patch b/gen/FreeBSD/rand48.3.patch index 7b06dd0..362ce14 100644 --- a/gen/FreeBSD/rand48.3.patch +++ b/gen/FreeBSD/rand48.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/gen/FreeBSD/rand48.3 2004-11-25 11:38:01.000000000 -0800 -+++ _SB/Libc/gen/FreeBSD/rand48.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- rand48.3.orig 2010-02-08 16:26:16.000000000 -0800 ++++ rand48.3 2010-02-13 19:48:39.000000000 -0800 @@ -18,51 +18,68 @@ .Sh NAME .Nm drand48 , @@ -79,7 +79,7 @@ -for the multiplicand a = 0xfdeece66d = 25214903917 and -the addend c = 0xb = 11. +r(n+1) = (a * r(n) + c) mod m. -+The default value for the multiplicand `a' is 0xfdeece66d (25214903917). ++The default value for the multiplicand `a' is 0x5deece66d (25214903917). +The default value for the the addend `c' is 0xb (11). The modulo is always fixed at m = 2 ** 48. r(n) is called the seed of the random number generator. @@ -89,7 +89,7 @@ computational step is to perform a single iteration of the algorithm. .Pp The -@@ -124,7 +141,7 @@ +@@ -124,7 +141,7 @@ is used to initialize the internal buffe .Fn drand48 , .Fn lrand48 , and @@ -98,7 +98,7 @@ such that the 32 bits of the seed value are copied into the upper 32 bits of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e. Additionally, the constant multiplicand and addend of the algorithm are -@@ -147,7 +164,7 @@ +@@ -147,7 +164,7 @@ The .Fn seed48 function returns a pointer to an array of 3 shorts which contains the old seed. diff --git a/gen/FreeBSD/rand48.h.patch b/gen/FreeBSD/rand48.h.patch index c305cb7..404c774 100644 --- a/gen/FreeBSD/rand48.h.patch +++ b/gen/FreeBSD/rand48.h.patch @@ -1,5 +1,5 @@ ---- rand48.h.orig 2003-05-20 15:21:02.000000000 -0700 -+++ rand48.h 2005-11-03 14:06:17.000000000 -0800 +--- rand48.h.orig 2009-11-07 14:51:38.000000000 -0800 ++++ rand48.h 2009-11-07 14:51:39.000000000 -0800 @@ -19,8 +19,6 @@ #include #include @@ -9,7 +9,7 @@ #define RAND48_SEED_0 (0x330e) #define RAND48_SEED_1 (0xabcd) #define RAND48_SEED_2 (0x1234) -@@ -29,4 +27,55 @@ +@@ -29,4 +27,55 @@ void _dorand48(unsigned short[3]); #define RAND48_MULT_2 (0x0005) #define RAND48_ADD (0x000b) diff --git a/gen/FreeBSD/readdir.c b/gen/FreeBSD/readdir.c index fa0438c..a78c8b1 100644 --- a/gen/FreeBSD/readdir.c +++ b/gen/FreeBSD/readdir.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/readdir.c,v 1.11 2002/02/26 21:39:32 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/readdir.c,v 1.15 2008/05/05 14:05:23 kib Exp $"); #include "namespace.h" #include @@ -46,13 +42,15 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/readdir.c,v 1.11 2002/02/26 21:39:32 alfred #include "un-namespace.h" #include "libc_private.h" +#include "telldir.h" /* * get next entry in a directory. */ struct dirent * -_readdir_unlocked(dirp) +_readdir_unlocked(dirp, skip) DIR *dirp; + int skip; { struct dirent *dp; @@ -75,7 +73,7 @@ _readdir_unlocked(dirp) dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) return (NULL); dirp->dd_loc += dp->d_reclen; - if (dp->d_ino == 0) + if (dp->d_ino == 0 && skip) continue; if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) continue; @@ -90,12 +88,12 @@ readdir(dirp) struct dirent *dp; if (__isthreaded) { - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); - dp = _readdir_unlocked(dirp); - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_lock(&dirp->dd_lock); + dp = _readdir_unlocked(dirp, 1); + _pthread_mutex_unlock(&dirp->dd_lock); } else - dp = _readdir_unlocked(dirp); + dp = _readdir_unlocked(dirp, 1); return (dp); } @@ -111,12 +109,12 @@ readdir_r(dirp, entry, result) saved_errno = errno; errno = 0; if (__isthreaded) { - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); - if ((dp = _readdir_unlocked(dirp)) != NULL) + _pthread_mutex_lock(&dirp->dd_lock); + if ((dp = _readdir_unlocked(dirp, 1)) != NULL) memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_unlock(&dirp->dd_lock); } - else if ((dp = _readdir_unlocked(dirp)) != NULL) + else if ((dp = _readdir_unlocked(dirp, 1)) != NULL) memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); if (errno != 0) { diff --git a/gen/FreeBSD/readdir.c.patch b/gen/FreeBSD/readdir.c.patch index 56c8c12..8d7058d 100644 --- a/gen/FreeBSD/readdir.c.patch +++ b/gen/FreeBSD/readdir.c.patch @@ -1,17 +1,14 @@ ---- readdir.c.orig 2007-01-24 14:10:41.000000000 -0800 -+++ readdir.c 2007-01-27 02:51:25.000000000 -0800 -@@ -43,8 +43,10 @@ +--- readdir.c.orig 2009-11-08 13:59:03.000000000 -0800 ++++ readdir.c 2009-11-08 13:59:22.000000000 -0800 +@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/rea #include #include #include +#include #include "un-namespace.h" -+#include "telldir.h" #include "libc_private.h" - - /* -@@ -63,8 +65,13 @@ +@@ -61,8 +62,13 @@ _readdir_unlocked(dirp, skip) dirp->dd_loc = 0; } if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) { diff --git a/gen/FreeBSD/readpassphrase.3 b/gen/FreeBSD/readpassphrase.3 index ea143ec..3bd3617 100644 --- a/gen/FreeBSD/readpassphrase.3 +++ b/gen/FreeBSD/readpassphrase.3 @@ -25,7 +25,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/readpassphrase.3,v 1.6 2002/12/27 12:15:28 schweikh Exp $ +.\" $FreeBSD: src/lib/libc/gen/readpassphrase.3,v 1.7 2005/01/20 09:17:02 ru Exp $ .\" .Dd December 7, 2001 .Dt READPASSPHRASE 3 @@ -92,30 +92,9 @@ If an error is encountered, the terminal state is restored and a .Dv NULL pointer is returned. -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er EINTR -The -.Fn readpassphrase -function was interrupted by a signal. -.It Bq Er EINVAL -The -.Fa bufsiz -argument was zero. -.It Bq Er EIO -The process is a member of a background process attempting to read -from its controlling terminal, the process is ignoring or blocking -the -.Dv SIGTTIN -signal or the process group is orphaned. -.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 ENOTTY -There is no controlling terminal and the -.Dv RPP_REQUIRE_TTY -flag was specified. +.Sh FILES +.Bl -tag -width ".Pa /dev/tty" -compact +.It Pa /dev/tty .El .Sh EXAMPLES The following code fragment will read a passphrase from @@ -172,9 +151,30 @@ from a background process) are treated specially. When the process is resumed after it has been stopped, .Fn readpassphrase will reprint the prompt and the user may then enter a passphrase. -.Sh FILES -.Bl -tag -width ".Pa /dev/tty" -compact -.It Pa /dev/tty +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EINTR +The +.Fn readpassphrase +function was interrupted by a signal. +.It Bq Er EINVAL +The +.Fa bufsiz +argument was zero. +.It Bq Er EIO +The process is a member of a background process attempting to read +from its controlling terminal, the process is ignoring or blocking +the +.Dv SIGTTIN +signal or the process group is orphaned. +.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 ENOTTY +There is no controlling terminal and the +.Dv RPP_REQUIRE_TTY +flag was specified. .El .Sh SEE ALSO .Xr sigaction 2 , diff --git a/gen/FreeBSD/readpassphrase.c.patch b/gen/FreeBSD/readpassphrase.c.patch index f3bc8e6..ea6527a 100644 --- a/gen/FreeBSD/readpassphrase.c.patch +++ b/gen/FreeBSD/readpassphrase.c.patch @@ -1,6 +1,6 @@ ---- readpassphrase.c.orig 2003-05-20 15:21:02.000000000 -0700 -+++ readpassphrase.c 2005-02-24 17:00:36.000000000 -0800 -@@ -33,6 +33,8 @@ +--- readpassphrase.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ readpassphrase.c 2009-11-07 14:51:39.000000000 -0800 +@@ -33,6 +33,8 @@ static const char rcsid[] = "$OpenBSD: r #include __FBSDID("$FreeBSD: src/lib/libc/gen/readpassphrase.c,v 1.6 2002/03/09 03:16:41 green Exp $"); @@ -9,7 +9,7 @@ #include "namespace.h" #include #include -@@ -59,6 +61,7 @@ +@@ -59,6 +61,7 @@ readpassphrase(const char *prompt, char struct termios term, oterm; struct sigaction sa, saveint, savehup, savequit, saveterm; struct sigaction savetstp, savettin, savettou; @@ -17,7 +17,7 @@ /* I suppose we could alloc on demand in this case (XXX). */ if (bufsiz == 0) { -@@ -115,11 +118,11 @@ +@@ -115,11 +118,11 @@ restart: if (p < end) { if ((flags & RPP_SEVENBIT)) ch &= 0x7f; diff --git a/gen/FreeBSD/rewinddir.c b/gen/FreeBSD/rewinddir.c index dae75cc..bdbb33e 100644 --- a/gen/FreeBSD/rewinddir.c +++ b/gen/FreeBSD/rewinddir.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)rewinddir.c 8.1 (Berkeley) 6/8/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/rewinddir.c,v 1.5 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/rewinddir.c,v 1.6 2007/01/09 00:27:55 imp Exp $"); #include #include diff --git a/gen/FreeBSD/scandir.3 b/gen/FreeBSD/scandir.3 index b76eff8..507fbde 100644 --- a/gen/FreeBSD/scandir.3 +++ b/gen/FreeBSD/scandir.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)scandir.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/scandir.3,v 1.8 2002/12/19 09:40:21 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/scandir.3,v 1.9 2007/01/09 00:27:55 imp Exp $ .\" .Dd June 4, 1993 .Dt SCANDIR 3 diff --git a/gen/FreeBSD/scandir.3.patch b/gen/FreeBSD/scandir.3.patch index f91cf48..2152839 100644 --- a/gen/FreeBSD/scandir.3.patch +++ b/gen/FreeBSD/scandir.3.patch @@ -1,8 +1,8 @@ ---- scandir.3.orig 2009-05-12 11:21:55.000000000 -0700 -+++ scandir.3 2009-05-20 15:41:07.000000000 -0700 -@@ -32,15 +32,16 @@ +--- scandir.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ scandir.3 2009-11-07 14:51:40.000000000 -0800 +@@ -28,15 +28,16 @@ .\" @(#)scandir.3 8.1 (Berkeley) 6/4/93 - .\" $FreeBSD: src/lib/libc/gen/scandir.3,v 1.8 2002/12/19 09:40:21 ru Exp $ + .\" $FreeBSD: src/lib/libc/gen/scandir.3,v 1.9 2007/01/09 00:27:55 imp Exp $ .\" -.Dd June 4, 1993 +.Dd May 20, 2008 @@ -20,7 +20,7 @@ .Sh SYNOPSIS .In sys/types.h .In dirent.h -@@ -48,6 +49,10 @@ +@@ -44,6 +45,10 @@ .Fn scandir "const char *dirname" "struct dirent ***namelist" "int \\*(lp*select\\*(rp\\*(lpstruct dirent *\\*(rp" "int \\*(lp*compar\\*(rp\\*(lpconst void *, const void *\\*(rp" .Ft int .Fn alphasort "const void *d1" "const void *d2" @@ -31,7 +31,7 @@ .Sh DESCRIPTION The .Fn scandir -@@ -80,6 +85,13 @@ +@@ -76,6 +81,13 @@ argument is a pointer to a user supplied .Xr qsort 3 to sort the completed array. If this pointer is null, the array is not sorted. @@ -45,7 +45,7 @@ .Pp The .Fn alphasort -@@ -91,6 +103,18 @@ +@@ -87,6 +99,18 @@ argument to sort the array alphabeticall The memory allocated for the array can be deallocated with .Xr free 3 , by freeing each pointer in the array and then the array itself. @@ -64,7 +64,7 @@ .Sh DIAGNOSTICS Returns \-1 if the directory cannot be opened for reading or if .Xr malloc 3 -@@ -107,3 +131,8 @@ +@@ -103,3 +127,8 @@ and .Fn alphasort functions appeared in .Bx 4.2 . diff --git a/gen/FreeBSD/scandir.c b/gen/FreeBSD/scandir.c index cf79bce..e21bd09 100644 --- a/gen/FreeBSD/scandir.c +++ b/gen/FreeBSD/scandir.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)scandir.c 8.3 (Berkeley) 1/2/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/scandir.c,v 1.7 2002/02/01 01:32:19 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/scandir.c,v 1.9 2008/03/16 19:08:53 das Exp $"); /* * Scan the directory dirname calling select to make a list of selected @@ -45,8 +41,6 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/scandir.c,v 1.7 2002/02/01 01:32:19 obrien */ #include "namespace.h" -#include -#include #include #include #include @@ -72,20 +66,13 @@ scandir(dirname, namelist, select, dcomp) { struct dirent *d, *p, **names = NULL; size_t nitems = 0; - struct stat stb; long arraysz; DIR *dirp; if ((dirp = opendir(dirname)) == NULL) return(-1); - if (_fstat(dirp->dd_fd, &stb) < 0) - goto fail; - /* - * estimate the array size by taking the size of the directory file - * and dividing it by a multiple of the minimum size entry. - */ - arraysz = (stb.st_size / 24); + arraysz = 32; /* initial estimate of the array size */ names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *)); if (names == NULL) goto fail; @@ -109,17 +96,16 @@ scandir(dirname, namelist, select, dcomp) * realloc the maximum size. */ if (nitems >= arraysz) { - const int inc = 10; /* increase by this much */ struct dirent **names2; names2 = (struct dirent **)realloc((char *)names, - (arraysz + inc) * sizeof(struct dirent *)); + (arraysz * 2) * sizeof(struct dirent *)); if (names2 == NULL) { free(p); goto fail; } names = names2; - arraysz += inc; + arraysz *= 2; } names[nitems++] = p; } diff --git a/gen/FreeBSD/scandir.c.patch b/gen/FreeBSD/scandir.c.patch index 66a07d1..860cdc7 100644 --- a/gen/FreeBSD/scandir.c.patch +++ b/gen/FreeBSD/scandir.c.patch @@ -1,6 +1,6 @@ ---- scandir.c.orig 2008-07-28 02:49:02.000000000 -0700 -+++ scandir.c 2008-07-29 12:02:49.000000000 -0700 -@@ -53,15 +53,11 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/sca +--- scandir.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ scandir.c 2009-11-07 14:51:40.000000000 -0800 +@@ -47,15 +47,11 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/sca #include "un-namespace.h" /* @@ -17,7 +17,7 @@ int scandir(dirname, namelist, select, dcomp) -@@ -96,7 +92,7 @@ scandir(dirname, namelist, select, dcomp +@@ -83,7 +79,7 @@ scandir(dirname, namelist, select, dcomp /* * Make a minimum size copy of the data */ diff --git a/gen/FreeBSD/scandir_b.c.patch b/gen/FreeBSD/scandir_b.c.patch index 5dd1961..f243dae 100644 --- a/gen/FreeBSD/scandir_b.c.patch +++ b/gen/FreeBSD/scandir_b.c.patch @@ -1,6 +1,6 @@ ---- scandir_b.c.orig 2008-07-29 12:03:05.000000000 -0700 -+++ scandir_b.c 2008-07-29 12:03:31.000000000 -0700 -@@ -53,22 +53,18 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/sca +--- scandir_b.c 2009-11-07 14:51:38.000000000 -0800 ++++ scandir_b.c 2009-11-07 18:46:38.000000000 -0800 +@@ -47,22 +47,18 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/sca #include "un-namespace.h" /* @@ -27,7 +27,7 @@ { struct dirent *d, *p, **names = NULL; size_t nitems = 0; -@@ -91,12 +87,12 @@ scandir(dirname, namelist, select, dcomp +@@ -78,12 +74,12 @@ scandir(dirname, namelist, select, dcomp goto fail; while ((d = readdir(dirp)) != NULL) { @@ -42,7 +42,7 @@ if (p == NULL) goto fail; p->d_fileno = d->d_fileno; -@@ -125,7 +121,7 @@ scandir(dirname, namelist, select, dcomp +@@ -111,7 +107,7 @@ scandir(dirname, namelist, select, dcomp } closedir(dirp); if (nitems && dcomp != NULL) @@ -51,7 +51,7 @@ *namelist = names; return(nitems); -@@ -136,15 +132,3 @@ fail: +@@ -122,15 +118,3 @@ fail: closedir(dirp); return -1; } diff --git a/gen/FreeBSD/seed48.c.patch b/gen/FreeBSD/seed48.c.patch index 036fa2b..7efb4f1 100644 --- a/gen/FreeBSD/seed48.c.patch +++ b/gen/FreeBSD/seed48.c.patch @@ -1,6 +1,6 @@ ---- seed48.c.orig 2003-05-20 15:21:02.000000000 -0700 -+++ seed48.c 2005-11-03 13:48:11.000000000 -0800 -@@ -16,24 +16,14 @@ +--- seed48.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ seed48.c 2009-11-07 14:51:39.000000000 -0800 +@@ -16,24 +16,14 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/see #include "rand48.h" diff --git a/gen/FreeBSD/seekdir.c b/gen/FreeBSD/seekdir.c index 5385819..cfadd8c 100644 --- a/gen/FreeBSD/seekdir.c +++ b/gen/FreeBSD/seekdir.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)seekdir.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/seekdir.c,v 1.5 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/seekdir.c,v 1.7 2007/12/03 14:33:51 des Exp $"); #include "namespace.h" #include @@ -56,8 +52,8 @@ seekdir(dirp, loc) long loc; { if (__isthreaded) - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_lock(&dirp->dd_lock); _seekdir(dirp, loc); if (__isthreaded) - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_unlock(&dirp->dd_lock); } diff --git a/gen/FreeBSD/sethostname.c b/gen/FreeBSD/sethostname.c index 3a15727..af1a129 100644 --- a/gen/FreeBSD/sethostname.c +++ b/gen/FreeBSD/sethostname.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,11 +31,13 @@ static char sccsid[] = "@(#)sethostname.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/sethostname.c,v 1.4 2002/05/28 16:59:39 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/sethostname.c,v 1.6 2007/01/09 00:27:55 imp Exp $"); #include #include +#include + int sethostname(const char *name, int namelen) { diff --git a/gen/FreeBSD/setmode.3 b/gen/FreeBSD/setmode.3 index ac41f4c..94fd5d1 100644 --- a/gen/FreeBSD/setmode.3 +++ b/gen/FreeBSD/setmode.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setmode.3 8.2 (Berkeley) 4/28/95 -.\" $FreeBSD: src/lib/libc/gen/setmode.3,v 1.11 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/setmode.3,v 1.12 2007/01/09 00:27:55 imp Exp $ .\" .Dd April 28, 1995 .Dt SETMODE 3 diff --git a/gen/FreeBSD/setmode.c b/gen/FreeBSD/setmode.c index 3e4a6ee..4c1e5a0 100644 --- a/gen/FreeBSD/setmode.c +++ b/gen/FreeBSD/setmode.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/setmode.c,v 1.9 2003/02/23 00:24:03 mikeh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/setmode.c,v 1.11 2007/01/09 00:27:55 imp Exp $"); #include "namespace.h" #include @@ -83,9 +79,7 @@ static void dumpmode(BITCMD *); * bits) followed by a '+' (set bits). */ mode_t -getmode(bbox, omode) - const void *bbox; - mode_t omode; +getmode(const void *bbox, mode_t omode) { const BITCMD *set; mode_t clrval, newmode, value; @@ -172,8 +166,7 @@ common: if (set->cmd2 & CMD2_CLR) { #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) void * -setmode(p) - const char *p; +setmode(const char *p) { int perm, who; char op, *ep; @@ -340,11 +333,7 @@ apply: if (!*p) } static BITCMD * -addcmd(set, op, who, oparg, mask) - BITCMD *set; - int oparg, who; - int op; - u_int mask; +addcmd(BITCMD *set, int op, int who, int oparg, u_int mask) { switch (op) { case '=': @@ -388,8 +377,7 @@ addcmd(set, op, who, oparg, mask) #ifdef SETMODE_DEBUG static void -dumpmode(set) - BITCMD *set; +dumpmode(BITCMD *set) { for (; set->cmd; ++set) (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n", @@ -409,8 +397,7 @@ dumpmode(set) * compacted, but it's not worth the effort. */ static void -compress_mode(set) - BITCMD *set; +compress_mode(BITCMD *set) { BITCMD *nset; int setbits, clrbits, Xbits, op; diff --git a/gen/FreeBSD/setmode.c.patch b/gen/FreeBSD/setmode.c.patch index c6bf7a1..03dda3b 100644 --- a/gen/FreeBSD/setmode.c.patch +++ b/gen/FreeBSD/setmode.c.patch @@ -1,6 +1,6 @@ ---- setmode.c.orig 2008-02-08 00:45:35.000000000 -0800 -+++ setmode.c 2008-02-17 19:36:02.000000000 -0800 -@@ -70,12 +70,15 @@ typedef struct bitcmd { +--- setmode.c.orig 2009-11-08 14:13:46.000000000 -0800 ++++ setmode.c 2009-11-08 14:13:39.000000000 -0800 +@@ -66,12 +66,15 @@ typedef struct bitcmd { #define CMD2_OBITS 0x08 #define CMD2_UBITS 0x10 @@ -17,7 +17,7 @@ /* * Given the old mode and an array of bitcmd structures, apply the operations * described in the bitcmd structures to the old mode, and return the new mode. -@@ -151,6 +154,7 @@ common: if (set->cmd2 & CMD2_CLR) { +@@ -145,6 +148,7 @@ common: if (set->cmd2 & CMD2_CLR) { return (newmode); } } @@ -25,7 +25,7 @@ #define ADDCMD(a, b, c, d) \ if (set >= endset) { \ -@@ -169,7 +173,11 @@ common: if (set->cmd2 & CMD2_CLR) { +@@ -163,7 +167,11 @@ common: if (set->cmd2 & CMD2_CLR) { } \ set = addcmd(set, (a), (b), (c), (d)) @@ -36,8 +36,8 @@ +#endif /* !VARIANT_LEGACY */ void * - setmode(p) -@@ -211,12 +219,21 @@ setmode(p) + setmode(const char *p) +@@ -204,12 +212,21 @@ setmode(const char *p) */ if (isdigit((unsigned char)*p)) { perml = strtol(p, &ep, 8); @@ -60,7 +60,7 @@ set->cmd = 0; return (saveset); } -@@ -253,7 +270,9 @@ getop: if ((op = *p++) != '+' && op != +@@ -246,7 +263,9 @@ getop: if ((op = *p++) != '+' && op != if (op == '=') equalopdone = 0; @@ -70,7 +70,7 @@ for (perm = 0, permXbits = 0;; ++p) { switch (*p) { case 'r': -@@ -267,7 +286,9 @@ getop: if ((op = *p++) != '+' && op != +@@ -260,7 +279,9 @@ getop: if ((op = *p++) != '+' && op != case 't': /* If only "other" bits ignore sticky. */ if (!who || who & ~S_IRWXO) { @@ -80,7 +80,7 @@ perm |= S_ISTXT; } break; -@@ -402,13 +423,14 @@ dumpmode(set) +@@ -390,13 +411,14 @@ dumpmode(BITCMD *set) } #endif @@ -93,10 +93,10 @@ */ -static void +__private_extern__ void - compress_mode(set) - BITCMD *set; + compress_mode(BITCMD *set) { -@@ -457,3 +479,4 @@ compress_mode(set) + BITCMD *nset; +@@ -444,3 +466,4 @@ compress_mode(BITCMD *set) } } } diff --git a/gen/FreeBSD/setprogname.c.patch b/gen/FreeBSD/setprogname.c.patch index 19af5a0..dafccfd 100644 --- a/gen/FreeBSD/setprogname.c.patch +++ b/gen/FreeBSD/setprogname.c.patch @@ -1,6 +1,6 @@ ---- setprogname.c.orig 2008-01-31 02:47:06.000000000 -0800 -+++ setprogname.c 2008-01-31 03:07:50.000000000 -0800 -@@ -3,6 +3,10 @@ +--- setprogname.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ setprogname.c 2009-11-07 14:51:39.000000000 -0800 +@@ -3,6 +3,10 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/set #include #include @@ -11,7 +11,7 @@ #include "libc_private.h" -@@ -10,10 +14,20 @@ +@@ -10,10 +14,20 @@ void setprogname(const char *progname) { const char *p; @@ -22,7 +22,7 @@ p = strrchr(progname, '/'); if (p != NULL) - __progname = p + 1; -+ __progname = (char *)(p + 1); ++ __progname = (char *)(p = p + 1); else - __progname = progname; + __progname = (char *)(p = progname); diff --git a/gen/FreeBSD/siginterrupt.3 b/gen/FreeBSD/siginterrupt.3 index 34e1a9c..aae9120 100644 --- a/gen/FreeBSD/siginterrupt.3 +++ b/gen/FreeBSD/siginterrupt.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)siginterrupt.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/siginterrupt.3,v 1.14 2002/12/19 09:40:21 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/siginterrupt.3,v 1.15 2007/01/09 00:27:55 imp Exp $ .\" .Dd June 4, 1993 .Dt SIGINTERRUPT 3 diff --git a/gen/FreeBSD/siginterrupt.3.patch b/gen/FreeBSD/siginterrupt.3.patch index 071ae27..8b6d16b 100644 --- a/gen/FreeBSD/siginterrupt.3.patch +++ b/gen/FreeBSD/siginterrupt.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/gen/FreeBSD/siginterrupt.3 2003-05-20 15:21:02.000000000 -0700 -+++ _SB/Libc/gen/FreeBSD/siginterrupt.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -96,8 +96,8 @@ +--- siginterrupt.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ siginterrupt.3 2009-11-07 14:51:40.000000000 -0800 +@@ -92,8 +92,8 @@ the new action to take place on the next This library routine uses an extension of the .Xr sigaction 2 system call that is not available in diff --git a/gen/FreeBSD/siginterrupt.c b/gen/FreeBSD/siginterrupt.c index 8c719f8..8620ebe 100644 --- a/gen/FreeBSD/siginterrupt.c +++ b/gen/FreeBSD/siginterrupt.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)siginterrupt.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/siginterrupt.c,v 1.4 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/siginterrupt.c,v 1.5 2007/01/09 00:27:55 imp Exp $"); #include "namespace.h" #include diff --git a/gen/FreeBSD/siglist.c b/gen/FreeBSD/siglist.c index f269026..d3de563 100644 --- a/gen/FreeBSD/siglist.c +++ b/gen/FreeBSD/siglist.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,9 +31,8 @@ static char sccsid[] = "@(#)siglist.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/siglist.c,v 1.4 2002/09/07 08:14:19 jmallett Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/siglist.c,v 1.6 2007/01/20 08:24:01 maxim Exp $"); -#include #include const char *const sys_signame[NSIG] = { diff --git a/gen/FreeBSD/siglist.c.patch b/gen/FreeBSD/siglist.c.patch index c2e14f7..24677f1 100644 --- a/gen/FreeBSD/siglist.c.patch +++ b/gen/FreeBSD/siglist.c.patch @@ -1,6 +1,6 @@ ---- siglist.c.orig Sat Sep 7 01:14:19 2002 -+++ siglist.c Thu May 8 00:46:49 2003 -@@ -109,4 +109,3 @@ +--- siglist.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ siglist.c 2009-11-07 14:51:40.000000000 -0800 +@@ -104,4 +104,3 @@ const char *const sys_siglist[NSIG] = { "User defined signal 1", /* SIGUSR1 */ "User defined signal 2" /* SIGUSR2 */ }; diff --git a/gen/FreeBSD/signal.3 b/gen/FreeBSD/signal.3 index 4fa65c9..7d68346 100644 --- a/gen/FreeBSD/signal.3 +++ b/gen/FreeBSD/signal.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)signal.3 8.3 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/signal.3,v 1.38 2004/07/03 22:30:08 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/signal.3,v 1.43 2008/07/17 21:54:23 simon Exp $ .\" .Dd June 7, 2004 .Dt SIGNAL 3 @@ -42,16 +38,25 @@ .Lb libc .Sh SYNOPSIS .In signal.h -.\" The following is Quite Ugly, but syntactically correct. -.\" Don't try to -.\" fix it. -.Ft void \*(lp* -.Fn signal "int sig" "void \*(lp*func\*(rp\*(lpint\*(rp\*(rp\*(rp\*(lpint" +.\" XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX +.\" The prototype for signal(3) cannot be cleanly marked up in -mdoc +.\" without the following lower-level tweak. +.nr in-synopsis-section 0 .Pp +.Ft "void \*(lp*" Ns +.Fo signal +.Fa "int sig" +.Fa "void \*(lp*func\*(rp\*(lpint\*(rp" +.Fc Ns +.Ft "\*(rp\*(lpint\*(rp" ; +.Pp +.nr in-synopsis-section 1 +.\" XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX or in -.Fx Ns 's +.Fx Ap s equivalent but easier to read typedef'd version: .Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp" ; +.Pp .Ft sig_t .Fn signal "int sig" "sig_t func" .Sh DESCRIPTION @@ -176,10 +181,12 @@ func() remains installed after a signal has been delivered. For some system calls, if a signal is caught while the call is executing and the call is prematurely terminated, the call is automatically restarted. -(The handler is installed using the +Any handler installed with +.Xr signal 3 +will have the .Dv SA_RESTART -flag with -.Xr sigaction 2 . ) +flag set, meaning that any restartable system call will not return on +receipt of a signal. The affected system calls include .Xr read 2 , .Xr write 2 , @@ -247,7 +254,7 @@ is not a valid signal number. An attempt is made to ignore or supply a handler for .Dv SIGKILL or -.Ev SIGSTOP . +.Dv SIGSTOP . .El .Sh SEE ALSO .Xr kill 1 , @@ -263,8 +270,8 @@ or .Xr siginterrupt 3 , .Xr tty 4 .Sh HISTORY -This -.Fn signal +The +.Nm facility appeared in .Bx 4.0 . The option to avoid the creation of child zombies through ignoring diff --git a/gen/FreeBSD/signal.3.patch b/gen/FreeBSD/signal.3.patch index dd821a6..49cdecf 100644 --- a/gen/FreeBSD/signal.3.patch +++ b/gen/FreeBSD/signal.3.patch @@ -1,17 +1,17 @@ ---- signal.3.orig 2006-12-15 11:55:30.000000000 -0800 -+++ signal.3 2006-12-15 11:57:08.000000000 -0800 -@@ -48,9 +48,7 @@ - .Ft void \*(lp* - .Fn signal "int sig" "void \*(lp*func\*(rp\*(lpint\*(rp\*(rp\*(rp\*(lpint" +--- signal.3.bsdnew 2009-11-08 14:20:21.000000000 -0800 ++++ signal.3 2009-11-08 14:26:22.000000000 -0800 +@@ -52,9 +52,7 @@ .Pp + .nr in-synopsis-section 1 + .\" XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX -or in --.Fx Ns 's +-.Fx Ap s -equivalent but easier to read typedef'd version: +or in the equivalent but easier to read typedef'd version: .Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp" ; + .Pp .Ft sig_t - .Fn signal "int sig" "sig_t func" -@@ -62,9 +60,9 @@ +@@ -67,9 +65,9 @@ is a simplified interface to the more ge .Xr sigaction 2 facility. .Pp @@ -24,7 +24,7 @@ There are two general types of signals: those that cause termination of a process and those that do not. Signals which cause termination of a program might result from -@@ -77,11 +75,10 @@ +@@ -82,11 +80,10 @@ Signals are optionally generated when a process resumes after being stopped, when the status of child processes changes, or when input is ready at the control terminal. @@ -40,7 +40,7 @@ Except for the .Dv SIGKILL and -@@ -135,7 +132,6 @@ +@@ -140,7 +137,6 @@ is possible on a descriptor (see .It 29 Ta Dv SIGINFO Ta "discard signal" Ta "status request from keyboard" .It 30 Ta Dv SIGUSR1 Ta "terminate process" Ta "User defined signal 1" .It 31 Ta Dv SIGUSR2 Ta "terminate process" Ta "User defined signal 2" @@ -48,7 +48,7 @@ .El .Pp The -@@ -151,7 +147,7 @@ +@@ -156,7 +152,7 @@ should be A .Dv SIG_DFL resets the default action. @@ -57,7 +57,7 @@ .Fa func should be .Dv SIG_IGN . -@@ -185,7 +181,7 @@ +@@ -192,7 +188,7 @@ The affected system calls include .Xr write 2 , .Xr sendto 2 , .Xr recvfrom 2 , diff --git a/gen/FreeBSD/signal.c b/gen/FreeBSD/signal.c index a958347..6407da3 100644 --- a/gen/FreeBSD/signal.c +++ b/gen/FreeBSD/signal.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)signal.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/signal.c,v 1.3 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/signal.c,v 1.4 2007/01/09 00:27:55 imp Exp $"); /* * Almost backwards compatible signal. diff --git a/gen/FreeBSD/signal.c.patch b/gen/FreeBSD/signal.c.patch index c4169f4..9064ec8 100644 --- a/gen/FreeBSD/signal.c.patch +++ b/gen/FreeBSD/signal.c.patch @@ -1,6 +1,6 @@ ---- signal.c.orig Thu Jan 31 16:57:29 2002 -+++ signal.c Fri May 16 14:16:12 2003 -@@ -47,10 +47,13 @@ +--- signal.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ signal.c 2009-11-07 14:51:40.000000000 -0800 +@@ -43,10 +43,13 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/sig sigset_t _sigintr; /* shared with siginterrupt */ @@ -16,7 +16,7 @@ { struct sigaction sa, osa; -@@ -59,7 +62,34 @@ +@@ -55,7 +58,34 @@ signal(s, a) sa.sa_flags = 0; if (!sigismember(&_sigintr, s)) sa.sa_flags |= SA_RESTART; diff --git a/gen/FreeBSD/signbit.3.patch b/gen/FreeBSD/signbit.3.patch index 6fa0fb5..a0dba44 100644 --- a/gen/FreeBSD/signbit.3.patch +++ b/gen/FreeBSD/signbit.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/gen/FreeBSD/signbit.3 2003-11-12 00:44:46.000000000 -0800 -+++ _SB/Libc/gen/FreeBSD/signbit.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- signbit.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ signbit.3 2009-11-07 14:51:39.000000000 -0800 @@ -40,8 +40,9 @@ The .Fn signbit @@ -12,7 +12,7 @@ .Sh SEE ALSO .Xr fpclassify 3 , .Xr math 3 -@@ -50,8 +51,3 @@ +@@ -50,8 +51,3 @@ The .Fn signbit macro conforms to .St -isoC-99 . diff --git a/gen/FreeBSD/sleep.3 b/gen/FreeBSD/sleep.3 index b77a2c5..a3c42fc 100644 --- a/gen/FreeBSD/sleep.3 +++ b/gen/FreeBSD/sleep.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)sleep.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/sleep.3,v 1.16 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/sleep.3,v 1.17 2007/01/09 00:27:55 imp Exp $ .\" .Dd February 13, 1998 .Dt SLEEP 3 diff --git a/gen/FreeBSD/sleep.3.patch b/gen/FreeBSD/sleep.3.patch index 29adecb..0a27b75 100644 --- a/gen/FreeBSD/sleep.3.patch +++ b/gen/FreeBSD/sleep.3.patch @@ -1,6 +1,6 @@ ---- /Volumes/XDisk/tmp/Libc/gen/FreeBSD/sleep.3.orig 2004-07-02 16:52:10.000000000 -0700 -+++ /Volumes/XDisk/tmp/Libc/gen/FreeBSD/sleep.3 2004-10-24 17:08:28.000000000 -0700 -@@ -37,7 +37,7 @@ +--- sleep.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ sleep.3 2009-11-07 14:51:40.000000000 -0800 +@@ -33,7 +33,7 @@ .Os .Sh NAME .Nm sleep @@ -9,7 +9,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -@@ -47,11 +47,11 @@ +@@ -43,11 +43,11 @@ .Sh DESCRIPTION The .Fn sleep diff --git a/gen/FreeBSD/sleep.c b/gen/FreeBSD/sleep.c index bd48358..badd7c7 100644 --- a/gen/FreeBSD/sleep.c +++ b/gen/FreeBSD/sleep.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/sleep.c,v 1.31 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/sleep.c,v 1.33 2009/12/05 19:31:38 ed Exp $"); #include "namespace.h" #include @@ -45,8 +41,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/sleep.c,v 1.31 2002/02/01 00:57:29 obrien E #include "un-namespace.h" unsigned int -__sleep(seconds) - unsigned int seconds; +__sleep(unsigned int seconds) { struct timespec time_to_sleep; struct timespec time_remaining; diff --git a/gen/FreeBSD/sleep.c.patch b/gen/FreeBSD/sleep.c.patch index 4c6b2dc..291c010 100644 --- a/gen/FreeBSD/sleep.c.patch +++ b/gen/FreeBSD/sleep.c.patch @@ -1,6 +1,6 @@ ---- sleep.c.orig 2007-05-23 18:18:17.000000000 -0700 -+++ sleep.c 2007-05-23 22:15:14.000000000 -0700 -@@ -31,6 +31,11 @@ +--- sleep.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ sleep.c 2009-11-07 14:51:40.000000000 -0800 +@@ -27,6 +27,11 @@ * SUCH DAMAGE. */ diff --git a/gen/FreeBSD/srand48.c.patch b/gen/FreeBSD/srand48.c.patch index e109d25..89f6b7f 100644 --- a/gen/FreeBSD/srand48.c.patch +++ b/gen/FreeBSD/srand48.c.patch @@ -1,5 +1,5 @@ ---- srand48.c.orig 2003-05-20 15:21:03.000000000 -0700 -+++ srand48.c 2005-11-03 13:50:51.000000000 -0800 +--- srand48.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ srand48.c 2009-11-07 14:51:39.000000000 -0800 @@ -13,18 +13,10 @@ #include "rand48.h" diff --git a/gen/FreeBSD/stringlist.3 b/gen/FreeBSD/stringlist.3 index f28dd5a..d1dd2f4 100644 --- a/gen/FreeBSD/stringlist.3 +++ b/gen/FreeBSD/stringlist.3 @@ -33,7 +33,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/stringlist.3,v 1.10 2003/02/23 01:47:47 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/stringlist.3,v 1.11 2005/02/13 23:45:46 ru Exp $ .\" .Dd November 28, 1999 .Os @@ -121,7 +121,7 @@ Find .Fa item in .Fa sl , -returning NULL if it's not found. +returning NULL if it is not found. .El .Sh SEE ALSO .Xr free 3 , diff --git a/gen/FreeBSD/stringlist.c b/gen/FreeBSD/stringlist.c index 1d977e4..a4ad68a 100644 --- a/gen/FreeBSD/stringlist.c +++ b/gen/FreeBSD/stringlist.c @@ -10,9 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christos Zoulas. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * @@ -33,7 +30,7 @@ static char *rcsid = "$NetBSD: stringlist.c,v 1.2 1997/01/17 07:26:20 lukem Exp $"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/stringlist.c,v 1.7 2003/01/19 01:16:01 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/stringlist.c,v 1.8 2007/01/09 00:27:55 imp Exp $"); #include "namespace.h" #include diff --git a/gen/FreeBSD/sysconf.3 b/gen/FreeBSD/sysconf.3 index 815e2a7..5fca1ba 100644 --- a/gen/FreeBSD/sysconf.3 +++ b/gen/FreeBSD/sysconf.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)sysconf.3 8.3 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/sysconf.3,v 1.20 2003/12/23 18:42:55 trhodes Exp $ +.\" $FreeBSD: src/lib/libc/gen/sysconf.3,v 1.25 2007/01/09 00:27:55 imp Exp $ .\" -.Dd June 18, 2001 +.Dd December 14, 2006 .Dt SYSCONF 3 .Os .Sh NAME @@ -89,6 +85,8 @@ The number of processors configured. The number of processors currently online. .It Li _SC_OPEN_MAX The maximum number of open files per user id. +.It Li _SC_PAGESIZE +The size of a system page in bytes. .It Li _SC_STREAM_MAX The minimum maximum number of streams that a process may have open at any one time. @@ -165,6 +163,19 @@ otherwise \-1. Return 1 if the system supports the User Portability Utilities Option, otherwise \-1. .El +.Pp +These values also exist, but may not be standard: +.Pp +.Bl -tag -width 6n +.Pp +.It Li _SC_PHYS_PAGES +The number of pages of physical memory. +Note that it is possible that the product of this value and the value of +.Li _SC_PAGESIZE +will overflow a +.Vt long +in some configurations on a 32bit machine. +.El .Sh RETURN VALUES If the call to .Fn sysconf @@ -195,10 +206,6 @@ argument is invalid. .Xr pathconf 2 , .Xr confstr 3 , .Xr sysctl 3 -.Sh BUGS -The value for _SC_STREAM_MAX is a minimum maximum, and required to be -the same as ANSI C's FOPEN_MAX, so the returned value is a ridiculously -small and misleading number. .Sh STANDARDS Except for the fact that values returned by .Fn sysconf @@ -210,3 +217,7 @@ The .Fn sysconf function first appeared in .Bx 4.4 . +.Sh BUGS +The value for _SC_STREAM_MAX is a minimum maximum, and required to be +the same as ANSI C's FOPEN_MAX, so the returned value is a ridiculously +small and misleading number. diff --git a/gen/FreeBSD/sysctl.3.patch b/gen/FreeBSD/sysctl.3.patch index 53ff08a..876b362 100644 --- a/gen/FreeBSD/sysctl.3.patch +++ b/gen/FreeBSD/sysctl.3.patch @@ -1,5 +1,5 @@ ---- sysctl.3.orig 2008-10-21 16:45:53.000000000 -0700 -+++ sysctl.3 2008-10-22 09:33:13.000000000 -0700 +--- sysctl.3.orig 2010-04-28 23:38:49.000000000 -0700 ++++ sysctl.3 2010-04-29 10:13:28.000000000 -0700 @@ -32,7 +32,7 @@ .\" @(#)sysctl.3 8.4 (Berkeley) 5/9/95 .\" $FreeBSD: src/lib/libc/gen/sysctl.3,v 1.63 2004/07/02 23:52:10 ru Exp $ @@ -9,7 +9,7 @@ .Dt SYSCTL 3 .Os .Sh NAME -@@ -182,13 +182,21 @@ +@@ -182,13 +182,21 @@ for (i = 0; i < 100; i++) { } .Ed .Pp @@ -18,7 +18,7 @@ +-- to print whatever data deemed necessary from the large +.Vt kinfo_proc +structure ( -+.In sysctl.h ++.In sys/sysctl.h +) -- is left as an exercise for the reader. +.Pp The top level names are defined with a CTL_ prefix in @@ -32,7 +32,7 @@ .It Sy "Name Next level names Description" .It "CTL_DEBUG sys/sysctl.h Debugging" .It "CTL_VFS sys/mount.h File system" -@@ -197,7 +205,8 @@ +@@ -197,7 +205,8 @@ listed here, and described in separate s .It "CTL_MACHDEP sys/sysctl.h Machine dependent" .It "CTL_NET sys/socket.h Networking" .It "CTL_USER sys/sysctl.h User-level" @@ -42,7 +42,57 @@ .El .Pp For example, the following retrieves the maximum number of processes allowed -@@ -456,16 +465,6 @@ +@@ -279,7 +288,7 @@ privilege may change the value. + .It Sy "Second level name Type Changeable" + .It "HW_MACHINE string no" + .It "HW_MODEL string no" +-.It "HW_NCPU integer no" ++.It "HW_NCPU integer no (DEPRECATED)" + .It "HW_BYTEORDER integer no" + .It "HW_PHYSMEM integer no" + .It "HW_MEMSIZE integer no" +@@ -296,8 +305,16 @@ privilege may change the value. + The machine class. + .It Li HW_MODEL + The machine model +-.It Li HW_NCPU +-The number of cpus. ++.It Li HW_NCPU (DEPRECATED) ++The number of cpus. It is recommended that you use "hw.physicalcpu" "hw.physicalcpu_max" "hw.logicalcpu" or "hw.logicalcpu_max" instead. ++.It Li "hw.physicalcpu" ++The number of physical processors available in the current power management mode. ++.It Li "hw.physicalcpu_max" ++The maximum number of physical processors that could be available this boot. ++.It Li "hw.logicalcpu" ++The number of logical processors available in the current power management mode. ++.It Li "hw.logicalcpu_max" ++The maximum number of logical processors that could be available this boot. + .It Li HW_BYTEORDER + The byteorder (4,321, or 1,234). + .It Li HW_PHYSMEM +@@ -346,7 +363,7 @@ information. + .It "KERN_OSREV integer no" + .It "KERN_OSTYPE string no" + .It "KERN_POSIX1 integer no" +-.It "KERN_PROC struct proc no" ++.It "KERN_PROC struct kinfo_proc no" + .It "KERN_PROF node not applicable" + .It "KERN_QUANTUM integer yes" + .It "KERN_SAVED_IDS integer no" +@@ -440,10 +457,8 @@ with which the system + attempts to comply. + .It Li KERN_PROC + Return the entire process table, or a subset of it. +-An array of pairs of +-.Va struct proc +-followed by corresponding +-.Va struct eproc ++An array of ++.Va struct kinfo_proc + structures is returned, + whose size depends on the current number of such objects in the system. + The third and fourth level names are as follows: +@@ -456,16 +471,6 @@ The third and fourth level names are as .It "KERN_PROC_UID A user ID" .It "KERN_PROC_RUID A real user ID" .El @@ -59,7 +109,7 @@ .It Li KERN_PROF Return profiling information about the kernel. If the kernel is not compiled for profiling, -@@ -731,7 +730,6 @@ +@@ -731,7 +736,6 @@ privilege may change the value. .Bl -column "Second level nameXXXXXX" "struct loadavgXXX" -offset indent .It Sy "Second level name Type Changeable" .It "VM_LOADAVG struct loadavg no" @@ -67,7 +117,7 @@ .It "VM_PAGEOUT_ALGORITHM integer yes" .It "VM_SWAPPING_ENABLED integer maybe" .It "VM_V_CACHE_MAX integer yes" -@@ -748,10 +746,6 @@ +@@ -748,10 +752,6 @@ privilege may change the value. Return the load average history. The returned data consists of a .Va struct loadavg . @@ -78,7 +128,7 @@ .It Li VM_PAGEOUT_ALGORITHM 0 if the statistics-based page management algorithm is in use or 1 if the near-LRU algorithm is in use. -@@ -848,7 +842,7 @@ +@@ -848,7 +848,7 @@ identifiers, and user level identifiers definitions for second level network identifiers .It In sys/gmon.h definitions for third level profiling identifiers diff --git a/gen/FreeBSD/sysctl.c b/gen/FreeBSD/sysctl.c index b6c89a0..66d82d0 100644 --- a/gen/FreeBSD/sysctl.c +++ b/gen/FreeBSD/sysctl.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)sysctl.c 8.2 (Berkeley) 1/4/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/sysctl.c,v 1.5 2003/02/16 17:29:09 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/sysctl.c,v 1.6 2007/01/09 00:27:55 imp Exp $"); #include #include diff --git a/gen/FreeBSD/sysctl.c.patch b/gen/FreeBSD/sysctl.c.patch new file mode 100644 index 0000000..7fa1c90 --- /dev/null +++ b/gen/FreeBSD/sysctl.c.patch @@ -0,0 +1,38 @@ +--- sysctl.c.orig 2010-06-30 01:03:07.000000000 -0700 ++++ sysctl.c 2010-07-01 23:10:13.000000000 -0700 +@@ -53,8 +53,34 @@ sysctl(name, namelen, oldp, oldlenp, new + void *oldp, *newp; + size_t *oldlenp, newlen; + { +- if (name[0] != CTL_USER) ++ if (name[0] != CTL_USER) { ++ if (namelen == 2 && name[0] == CTL_KERN && name[1] == KERN_EXEC) { ++ /* ++ * 7723306: intercept kern.exec and fake a return of ++ * a dummy string ("/" in this case) ++ */ ++ if (newp != NULL) { ++ errno = EPERM; ++ return -1; ++ } ++ if (oldp == NULL) { ++ if (oldlenp != NULL) *oldlenp = 2; ++ return 0; ++ } ++ if (oldlenp == NULL) { ++ errno = EFAULT; ++ return -1; ++ } ++ if (*oldlenp < 2) { ++ errno = ENOMEM; ++ return -1; ++ } ++ memmove(oldp, "/", 2); ++ *oldlenp = 2; ++ return 0; ++ } + return (__sysctl(name, namelen, oldp, oldlenp, newp, newlen)); ++ } + + if (newp != NULL) { + errno = EPERM; diff --git a/gen/FreeBSD/telldir.c b/gen/FreeBSD/telldir.c index f321910..9ed3413 100644 --- a/gen/FreeBSD/telldir.c +++ b/gen/FreeBSD/telldir.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/telldir.c,v 1.8 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/telldir.c,v 1.11 2008/05/05 14:05:23 kib Exp $"); #include "namespace.h" #include @@ -68,13 +64,13 @@ telldir(dirp) if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) return (-1); if (__isthreaded) - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_lock(&dirp->dd_lock); lp->loc_index = dirp->dd_td->td_loccnt++; lp->loc_seek = dirp->dd_seek; lp->loc_loc = dirp->dd_loc; LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe); if (__isthreaded) - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_unlock(&dirp->dd_lock); return (lp->loc_index); } @@ -102,7 +98,7 @@ _seekdir(dirp, loc) dirp->dd_seek = lp->loc_seek; dirp->dd_loc = 0; while (dirp->dd_loc < lp->loc_loc) { - dp = _readdir_unlocked(dirp); + dp = _readdir_unlocked(dirp, 0); if (dp == NULL) break; } diff --git a/gen/FreeBSD/telldir.c.patch b/gen/FreeBSD/telldir.c.patch index a5de764..f73f1f2 100644 --- a/gen/FreeBSD/telldir.c.patch +++ b/gen/FreeBSD/telldir.c.patch @@ -1,6 +1,6 @@ ---- telldir.c.orig 2007-01-24 14:10:41.000000000 -0800 -+++ telldir.c 2007-01-27 02:51:57.000000000 -0800 -@@ -54,7 +54,9 @@ +--- telldir.c.orig 2009-11-08 14:02:31.000000000 -0800 ++++ telldir.c 2009-11-08 14:02:24.000000000 -0800 +@@ -50,7 +50,9 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/tel * cookie may be used only once before it is freed. This option * is used to avoid having memory usage grow without bound. */ @@ -10,13 +10,13 @@ /* * return a pointer into a directory -@@ -65,14 +67,41 @@ +@@ -61,14 +63,41 @@ telldir(dirp) { struct ddloc *lp; +#if __DARWIN_UNIX03 + if (__isthreaded) -+ _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); ++ _pthread_mutex_lock(&dirp->dd_lock); + LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { + if ( +#if __DARWIN_64_BIT_INO_T @@ -29,14 +29,14 @@ + } + if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) { + if (__isthreaded) -+ _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); ++ _pthread_mutex_unlock(&dirp->dd_lock); + return (-1); + } +#else /* !__DARWIN_UNIX03 */ if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) return (-1); if (__isthreaded) - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_lock(&dirp->dd_lock); +#endif /* __DARWIN_UNIX03 */ lp->loc_index = dirp->dd_td->td_loccnt++; +#if __DARWIN_64_BIT_INO_T @@ -50,9 +50,9 @@ +found: +#endif /* __DARWIN_UNIX03 */ if (__isthreaded) - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_unlock(&dirp->dd_lock); return (lp->loc_index); -@@ -96,23 +125,34 @@ +@@ -92,23 +121,34 @@ _seekdir(dirp, loc) } if (lp == NULL) return; @@ -73,7 +73,7 @@ +#endif /* __DARWIN_64_BIT_INO_T */ dirp->dd_loc = 0; while (dirp->dd_loc < lp->loc_loc) { - dp = _readdir_unlocked(dirp); + dp = _readdir_unlocked(dirp, 0); if (dp == NULL) break; } @@ -89,7 +89,7 @@ /* * Reclaim memory for telldir cookies which weren't used. */ -@@ -131,3 +171,4 @@ +@@ -127,3 +167,4 @@ _reclaim_telldir(dirp) } LIST_INIT(&dirp->dd_td->td_locq); } diff --git a/gen/FreeBSD/telldir.h b/gen/FreeBSD/telldir.h index 82cf9c1..93b1893 100644 --- a/gen/FreeBSD/telldir.h +++ b/gen/FreeBSD/telldir.h @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/lib/libc/gen/telldir.h,v 1.2 2001/01/24 12:59:24 deischen Exp $ + * $FreeBSD: src/lib/libc/gen/telldir.h,v 1.3 2008/05/05 14:05:23 kib Exp $ */ #ifndef _TELLDIR_H_ @@ -59,7 +59,7 @@ struct _telldir { long td_loccnt; /* index of entry for sequential readdir's */ }; -struct dirent *_readdir_unlocked(DIR *); +struct dirent *_readdir_unlocked(DIR *, int); void _reclaim_telldir(DIR *); void _seekdir(DIR *, long); diff --git a/gen/FreeBSD/telldir.h.patch b/gen/FreeBSD/telldir.h.patch index 6d53d68..ca64554 100644 --- a/gen/FreeBSD/telldir.h.patch +++ b/gen/FreeBSD/telldir.h.patch @@ -1,5 +1,5 @@ ---- telldir.h.orig 2007-01-24 14:10:41.000000000 -0800 -+++ telldir.h 2007-01-25 01:18:29.000000000 -0800 +--- telldir.h.orig 2009-11-08 13:57:20.000000000 -0800 ++++ telldir.h 2009-11-08 13:57:11.000000000 -0800 @@ -46,7 +46,11 @@ struct ddloc { LIST_ENTRY(ddloc) loc_lqe; /* entry in list */ @@ -12,7 +12,7 @@ long loc_loc; /* offset of entry in buffer */ }; -@@ -57,10 +61,17 @@ +@@ -57,10 +61,17 @@ struct ddloc { struct _telldir { LIST_HEAD(, ddloc) td_locq; /* list of locations */ long td_loccnt; /* index of entry for sequential readdir's */ @@ -21,11 +21,11 @@ +#endif /* __DARWIN_64_BIT_INO_T */ }; --struct dirent *_readdir_unlocked(DIR *); +-struct dirent *_readdir_unlocked(DIR *, int); +#if __DARWIN_64_BIT_INO_T +size_t __getdirentries64(int fd, void *buf, size_t bufsize, __darwin_off_t *basep); +#endif /* __DARWIN_64_BIT_INO_T */ -+struct dirent *_readdir_unlocked(DIR *) __DARWIN_INODE64(_readdir_unlocked); ++struct dirent *_readdir_unlocked(DIR *, int) __DARWIN_INODE64(_readdir_unlocked); void _reclaim_telldir(DIR *); -void _seekdir(DIR *, long); +void _seekdir(DIR *, long) __DARWIN_ALIAS_I(_seekdir); diff --git a/gen/FreeBSD/termios.c b/gen/FreeBSD/termios.c index 65f8141..b79489a 100644 --- a/gen/FreeBSD/termios.c +++ b/gen/FreeBSD/termios.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)termios.c 8.2 (Berkeley) 2/21/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/termios.c,v 1.13 2002/05/28 16:59:39 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/termios.c,v 1.16 2009/05/07 13:49:48 ed Exp $"); #include "namespace.h" #include @@ -103,6 +99,29 @@ tcgetpgrp(fd) return ((pid_t)s); } +pid_t +tcgetsid(int fd) +{ + int s; + + if (_ioctl(fd, TIOCGSID, &s) < 0) + return ((pid_t)-1); + + return ((pid_t)s); +} + +int +tcsetsid(int fd, pid_t pid) +{ + + if (pid != getsid(0)) { + errno = EINVAL; + return (-1); + } + + return (_ioctl(fd, TIOCSCTTY, NULL)); +} + speed_t cfgetospeed(t) const struct termios *t; diff --git a/gen/FreeBSD/termios.c.patch b/gen/FreeBSD/termios.c.patch index 16d32ef..880c37d 100644 --- a/gen/FreeBSD/termios.c.patch +++ b/gen/FreeBSD/termios.c.patch @@ -1,8 +1,8 @@ ---- termios.c.orig 2007-03-16 00:36:09.000000000 -0700 -+++ termios.c 2007-03-16 00:45:15.000000000 -0700 -@@ -37,6 +37,14 @@ +--- termios.c.orig 2009-11-08 16:27:01.000000000 -0800 ++++ termios.c 2009-11-08 16:28:15.000000000 -0800 +@@ -33,6 +33,14 @@ static char sccsid[] = "@(#)termios.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/gen/termios.c,v 1.13 2002/05/28 16:59:39 alfred Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/gen/termios.c,v 1.16 2009/05/07 13:49:48 ed Exp $"); +#if __DARWIN_UNIX03 +#ifdef VARIANT_CANCELABLE @@ -15,7 +15,7 @@ #include "namespace.h" #include #include -@@ -48,6 +56,7 @@ +@@ -44,6 +52,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/ter #include #include "un-namespace.h" @@ -23,7 +23,7 @@ int tcgetattr(fd, t) int fd; -@@ -87,6 +96,9 @@ +@@ -83,6 +92,9 @@ tcsetpgrp(int fd, pid_t pgrp) { int s; @@ -33,7 +33,7 @@ s = pgrp; return (_ioctl(fd, TIOCSPGRP, &s)); } -@@ -97,6 +109,9 @@ +@@ -93,12 +105,16 @@ tcgetpgrp(fd) { int s; @@ -43,7 +43,22 @@ if (_ioctl(fd, TIOCGPGRP, &s) < 0) return ((pid_t)-1); -@@ -183,17 +198,24 @@ + return ((pid_t)s); + } + ++#if 0 // Needs API review first + pid_t + tcgetsid(int fd) + { +@@ -121,6 +137,7 @@ tcsetsid(int fd, pid_t pid) + + return (_ioctl(fd, TIOCSCTTY, NULL)); + } ++#endif + + speed_t + cfgetospeed(t) +@@ -202,17 +219,24 @@ tcsendbreak(fd, len) return (-1); return (0); } @@ -68,7 +83,7 @@ int tcflush(fd, which) int fd, which; -@@ -230,16 +252,13 @@ +@@ -249,16 +273,13 @@ tcflow(fd, action) case TCOON: return (_ioctl(fd, TIOCSTART, 0)); case TCION: diff --git a/gen/FreeBSD/time.3 b/gen/FreeBSD/time.3 index a3ba1d9..6b63883 100644 --- a/gen/FreeBSD/time.3 +++ b/gen/FreeBSD/time.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)time.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/time.3,v 1.13 2004/07/02 19:07:30 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/time.3,v 1.15 2007/01/09 00:27:55 imp Exp $ .\" .Dd July 18, 2003 .Dt TIME 3 @@ -77,6 +73,11 @@ The .Nm function conforms to .St -p1003.1-2001 . +.Sh HISTORY +A +.Fn time +function appeared in +.At v6 . .Sh BUGS Neither .St -isoC-99 @@ -97,8 +98,3 @@ standards (including older versions of did not set .No \&* Ns Va tloc in the error case. -.Sh HISTORY -A -.Fn time -function appeared in -.At v6 . diff --git a/gen/FreeBSD/time.3.patch b/gen/FreeBSD/time.3.patch index 66d521f..f8e5d2e 100644 --- a/gen/FreeBSD/time.3.patch +++ b/gen/FreeBSD/time.3.patch @@ -1,6 +1,6 @@ ---- time.3.orig 2004-07-02 12:07:30.000000000 -0700 -+++ time.3 2004-10-24 17:39:18.000000000 -0700 -@@ -53,7 +53,8 @@ +--- time.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ time.3 2009-11-07 14:51:40.000000000 -0800 +@@ -49,7 +49,8 @@ The .Fn time function returns the value of time in seconds since 0 hours, 0 minutes, diff --git a/gen/FreeBSD/time.c b/gen/FreeBSD/time.c index 5bf0ce0..4ab4238 100644 --- a/gen/FreeBSD/time.c +++ b/gen/FreeBSD/time.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)time.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/time.c,v 1.4 2003/07/19 02:53:46 wollman Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/time.c,v 1.5 2007/01/09 00:27:55 imp Exp $"); #include #include diff --git a/gen/FreeBSD/time.c.patch b/gen/FreeBSD/time.c.patch index df72dfe..0e5a6e6 100644 --- a/gen/FreeBSD/time.c.patch +++ b/gen/FreeBSD/time.c.patch @@ -1,6 +1,6 @@ ---- time.c.orig 2008-07-30 13:29:30.000000000 -0700 -+++ time.c 2008-07-30 13:36:03.000000000 -0700 -@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/tim +--- time.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ time.c 2009-11-07 14:51:40.000000000 -0800 +@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/tim #include #include @@ -8,7 +8,7 @@ time_t time(t) -@@ -46,12 +47,21 @@ time(t) +@@ -42,12 +43,21 @@ time(t) { struct timeval tt; time_t retval; diff --git a/gen/FreeBSD/timezone.3 b/gen/FreeBSD/timezone.3 index 27caaa2..450c5b2 100644 --- a/gen/FreeBSD/timezone.3 +++ b/gen/FreeBSD/timezone.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)timezone.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/timezone.3,v 1.9 2002/12/19 09:40:21 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/timezone.3,v 1.10 2007/01/09 00:27:55 imp Exp $ .\" .Dd April 19, 1994 .Dt TIMEZONE 3 diff --git a/gen/FreeBSD/timezone.c b/gen/FreeBSD/timezone.c index 8d8139a..3b26967 100644 --- a/gen/FreeBSD/timezone.c +++ b/gen/FreeBSD/timezone.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)timezone.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/timezone.c,v 1.5 2002/02/01 01:08:48 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/timezone.c,v 1.6 2007/01/09 00:27:55 imp Exp $"); #include #include diff --git a/gen/FreeBSD/ttyname.c.patch b/gen/FreeBSD/ttyname.c.patch index 2542515..7871bc3 100644 --- a/gen/FreeBSD/ttyname.c.patch +++ b/gen/FreeBSD/ttyname.c.patch @@ -1,6 +1,6 @@ ---- ttyname.c.orig 2008-10-09 21:30:31.000000000 -0700 -+++ ttyname.c 2008-10-09 22:00:10.000000000 -0700 -@@ -48,10 +48,12 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/tty +--- ttyname.c.orig 2010-05-01 19:18:09.000000000 -0700 ++++ ttyname.c 2010-05-03 10:18:47.000000000 -0700 +@@ -48,11 +48,14 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/tty #include #include #include @@ -9,11 +9,14 @@ #include "libc_private.h" +-static char buf[sizeof(_PATH_DEV) + MAXNAMLEN]; +#ifndef BUILDING_VARIANT - static char buf[sizeof(_PATH_DEV) + MAXNAMLEN]; ++static pthread_once_t ttyname_buf_control = PTHREAD_ONCE_INIT; ++static char *buf = NULL; static char *ttyname_threaded(int fd); static char *ttyname_unthreaded(int fd); -@@ -71,31 +73,63 @@ ttyname(int fd) + +@@ -71,31 +74,63 @@ ttyname(int fd) ret = ttyname_threaded(fd); return (ret); } @@ -70,7 +73,7 @@ - devname_r(sb.st_rdev, S_IFCHR, - buf + strlen(buf), sizeof(buf) - strlen(buf)); - return (buf); -+ strcpy(thrbuf, _PATH_DEV); ++ strlcpy(thrbuf, _PATH_DEV, len); + if (devname_r(sb.st_rdev, S_IFCHR, + thrbuf + strlen(thrbuf), len - strlen(thrbuf)) == NULL) +#if __DARWIN_UNIX03 @@ -89,7 +92,7 @@ static char * ttyname_threaded(int fd) { -@@ -104,8 +138,12 @@ ttyname_threaded(int fd) +@@ -104,8 +139,12 @@ ttyname_threaded(int fd) if (ttyname_init == 0) { _pthread_mutex_lock(&ttyname_lock); if (ttyname_init == 0) { @@ -103,7 +106,7 @@ return (NULL); } ttyname_init = 1; -@@ -117,14 +155,20 @@ ttyname_threaded(int fd) +@@ -117,14 +156,26 @@ ttyname_threaded(int fd) if ((buf = _pthread_getspecific(ttyname_key)) == NULL) { if ((buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) { if (_pthread_setspecific(ttyname_key, buf) != 0) { @@ -121,26 +124,39 @@ +#else /* !__DARWIN_UNIX03 */ return (ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN)); +#endif /* __DARWIN_UNIX03 */ ++} ++ ++static void ++ttyname_buf_allocate(void) ++{ ++ buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN); } static char * -@@ -137,11 +181,19 @@ ttyname_unthreaded(int fd) +@@ -137,11 +188,25 @@ ttyname_unthreaded(int fd) if (tcgetattr(fd, &ttyb) < 0) return (NULL); /* Must be a character device. */ - if (_fstat(fd, &sb) || !S_ISCHR(sb.st_mode)) + if (_fstat(fd, &sb)) - return (NULL); ++ return (NULL); + if (!S_ISCHR(sb.st_mode)) { + errno = ENOTTY; + return (NULL); ++ } ++ ++ if (pthread_once(&ttyname_buf_control, ttyname_buf_allocate) ++ || !buf) { ++ errno = ENOMEM; + return (NULL); + } - strcpy(buf, _PATH_DEV); +- strcpy(buf, _PATH_DEV); - devname_r(sb.st_rdev, S_IFCHR, - buf + strlen(buf), sizeof(buf) - strlen(buf)); ++ strlcpy(buf, _PATH_DEV, sizeof(_PATH_DEV) + MAXNAMLEN); + if (devname_r(sb.st_rdev, S_IFCHR, -+ buf + strlen(buf), sizeof(buf) - strlen(buf)) == NULL) { ++ buf + strlen(buf), sizeof(_PATH_DEV) + MAXNAMLEN - strlen(buf)) == NULL) { + errno = ERANGE; + return (NULL); + } diff --git a/gen/FreeBSD/ttyslot.c b/gen/FreeBSD/ttyslot.c index 0d7359c..a553e16 100644 --- a/gen/FreeBSD/ttyslot.c +++ b/gen/FreeBSD/ttyslot.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,8 +31,9 @@ static char sccsid[] = "@(#)ttyslot.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/ttyslot.c,v 1.4 2002/02/01 01:08:48 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/ttyslot.c,v 1.6 2009/02/12 19:00:13 ed Exp $"); +#include #include #include #include @@ -47,19 +44,17 @@ ttyslot() { struct ttyent *ttyp; int slot; - char *p; int cnt; char *name; setttyent(); for (cnt = 0; cnt < 3; ++cnt) if ( (name = ttyname(cnt)) ) { - if ( (p = rindex(name, '/')) ) - ++p; - else - p = name; + if (strncmp(name, _PATH_DEV, sizeof _PATH_DEV - 1) != 0) + break; + name += sizeof _PATH_DEV - 1; for (slot = 1; (ttyp = getttyent()); ++slot) - if (!strcmp(ttyp->ty_name, p)) { + if (!strcmp(ttyp->ty_name, name)) { endttyent(); return(slot); } diff --git a/gen/FreeBSD/ualarm.3 b/gen/FreeBSD/ualarm.3 index 65cc711..4b02cd9 100644 --- a/gen/FreeBSD/ualarm.3 +++ b/gen/FreeBSD/ualarm.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)ualarm.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/ualarm.3,v 1.19 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/ualarm.3,v 1.20 2007/01/09 00:27:56 imp Exp $ .\" .Dd April 19, 1994 .Dt UALARM 3 diff --git a/gen/FreeBSD/ualarm.3.patch b/gen/FreeBSD/ualarm.3.patch index b09aacd..40f2ccb 100644 --- a/gen/FreeBSD/ualarm.3.patch +++ b/gen/FreeBSD/ualarm.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/gen/FreeBSD/ualarm.3 2004-11-25 11:38:02.000000000 -0800 -+++ _SB/Libc/gen/FreeBSD/ualarm.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -43,7 +43,10 @@ +--- ualarm.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ ualarm.3 2009-11-07 14:51:40.000000000 -0800 +@@ -39,7 +39,10 @@ .Sh SYNOPSIS .In unistd.h .Ft useconds_t @@ -12,7 +12,7 @@ .Sh DESCRIPTION .Bf -symbolic This is a simplified interface to -@@ -54,7 +57,7 @@ +@@ -50,7 +53,7 @@ The .Fn ualarm function waits a count of @@ -21,7 +21,7 @@ before asserting the terminating signal .Dv SIGALRM . System activity or time used in processing the call may cause a slight -@@ -67,17 +70,17 @@ +@@ -63,17 +66,17 @@ argument is non-zero, the signal will be sent to the process every .Fa interval diff --git a/gen/FreeBSD/ualarm.c b/gen/FreeBSD/ualarm.c index a9200ae..23e8161 100644 --- a/gen/FreeBSD/ualarm.c +++ b/gen/FreeBSD/ualarm.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)ualarm.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/ualarm.c,v 1.4 2002/12/29 00:59:09 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/ualarm.c,v 1.5 2007/01/09 00:27:56 imp Exp $"); #include #include diff --git a/gen/FreeBSD/ulimit.3.patch b/gen/FreeBSD/ulimit.3.patch index effba16..d81c748 100644 --- a/gen/FreeBSD/ulimit.3.patch +++ b/gen/FreeBSD/ulimit.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/gen/FreeBSD/ulimit.3 2003-05-20 15:21:03.000000000 -0700 -+++ _SB/Libc/gen/FreeBSD/ulimit.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- ulimit.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ ulimit.3 2009-11-07 14:51:39.000000000 -0800 @@ -34,28 +34,31 @@ .Sh SYNOPSIS .In ulimit.h diff --git a/gen/FreeBSD/unvis.3 b/gen/FreeBSD/unvis.3 index 8d160d8..cee1e61 100644 --- a/gen/FreeBSD/unvis.3 +++ b/gen/FreeBSD/unvis.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)unvis.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/gen/unvis.3,v 1.17 2004/07/03 22:30:08 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/unvis.3,v 1.18 2007/01/09 00:27:56 imp Exp $ .\" .Dd December 11, 1993 .Dt UNVIS 3 diff --git a/gen/FreeBSD/unvis.c b/gen/FreeBSD/unvis.c index 35443d1..e9c045f 100644 --- a/gen/FreeBSD/unvis.c +++ b/gen/FreeBSD/unvis.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/unvis.c,v 1.9 2004/08/02 08:46:23 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/unvis.c,v 1.10 2007/01/09 00:27:56 imp Exp $"); #include #include diff --git a/gen/FreeBSD/unvis.c.patch b/gen/FreeBSD/unvis.c.patch index 014c731..5f139ef 100644 --- a/gen/FreeBSD/unvis.c.patch +++ b/gen/FreeBSD/unvis.c.patch @@ -1,15 +1,15 @@ ---- unvis.c.orig 2004-11-25 11:38:02.000000000 -0800 -+++ unvis.c 2005-02-27 01:14:02.000000000 -0800 -@@ -37,6 +37,8 @@ +--- unvis.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ unvis.c 2009-11-07 14:51:40.000000000 -0800 +@@ -33,6 +33,8 @@ static char sccsid[] = "@(#)unvis.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/gen/unvis.c,v 1.9 2004/08/02 08:46:23 stefanf Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/gen/unvis.c,v 1.10 2007/01/09 00:27:56 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -64,6 +66,7 @@ +@@ -60,6 +62,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/unv int unvis(char *cp, int c, int *astate, int flag) { @@ -17,7 +17,7 @@ if (flag & UNVIS_END) { if (*astate == S_OCTAL2 || *astate == S_OCTAL3) { -@@ -90,8 +93,8 @@ +@@ -86,8 +89,8 @@ unvis(char *cp, int c, int *astate, int case S_START: if (*astate & S_HTTP) { @@ -28,7 +28,7 @@ *astate = S_HEX2; return (0); } -@@ -216,8 +219,8 @@ +@@ -212,8 +215,8 @@ unvis(char *cp, int c, int *astate, int return (UNVIS_VALIDPUSH); case S_HEX2: /* second mandatory hex digit */ diff --git a/gen/FreeBSD/usleep.3 b/gen/FreeBSD/usleep.3 index 72fb098..dc61096 100644 --- a/gen/FreeBSD/usleep.3 +++ b/gen/FreeBSD/usleep.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)usleep.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/usleep.3,v 1.18 2002/12/29 00:59:09 mike Exp $ +.\" $FreeBSD: src/lib/libc/gen/usleep.3,v 1.19 2007/01/09 00:27:56 imp Exp $ .\" .Dd February 13, 1998 .Dt USLEEP 3 diff --git a/gen/FreeBSD/usleep.3.patch b/gen/FreeBSD/usleep.3.patch index 470d185..2a695e9 100644 --- a/gen/FreeBSD/usleep.3.patch +++ b/gen/FreeBSD/usleep.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/gen/FreeBSD/usleep.3 2004-11-25 11:38:02.000000000 -0800 -+++ _SB/Libc/gen/FreeBSD/usleep.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -37,30 +37,34 @@ +--- usleep.3.orig 2009-11-07 14:51:38.000000000 -0800 ++++ usleep.3 2009-11-07 14:51:40.000000000 -0800 +@@ -33,30 +33,34 @@ .Os .Sh NAME .Nm usleep diff --git a/gen/FreeBSD/usleep.c b/gen/FreeBSD/usleep.c index 81eb948..a4aa59c 100644 --- a/gen/FreeBSD/usleep.c +++ b/gen/FreeBSD/usleep.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/usleep.c,v 1.28 2002/12/29 00:59:09 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/usleep.c,v 1.31 2009/12/05 19:31:38 ed Exp $"); #include "namespace.h" #include @@ -43,8 +39,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/usleep.c,v 1.28 2002/12/29 00:59:09 mike Ex #include "un-namespace.h" int -usleep(useconds) - useconds_t useconds; +__usleep(useconds_t useconds) { struct timespec time_to_sleep; @@ -52,3 +47,6 @@ usleep(useconds) time_to_sleep.tv_sec = useconds / 1000000; return (_nanosleep(&time_to_sleep, NULL)); } + +__weak_reference(__usleep, usleep); +__weak_reference(__usleep, _usleep); diff --git a/gen/FreeBSD/usleep.c.patch b/gen/FreeBSD/usleep.c.patch index 5957746..338b4ca 100644 --- a/gen/FreeBSD/usleep.c.patch +++ b/gen/FreeBSD/usleep.c.patch @@ -1,6 +1,6 @@ ---- usleep.c.orig 2007-05-23 18:18:17.000000000 -0700 -+++ usleep.c 2007-05-23 22:15:42.000000000 -0700 -@@ -31,6 +31,11 @@ +--- usleep.c.bsdnew 2009-12-08 00:38:07.000000000 -0800 ++++ usleep.c 2009-12-08 00:41:05.000000000 -0800 +@@ -27,6 +27,11 @@ * SUCH DAMAGE. */ @@ -12,3 +12,19 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +@@ -39,7 +44,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/usl + #include "un-namespace.h" + + int +-__usleep(useconds_t useconds) ++usleep(useconds_t useconds) + { + struct timespec time_to_sleep; + +@@ -47,6 +52,3 @@ __usleep(useconds_t useconds) + time_to_sleep.tv_sec = useconds / 1000000; + return (_nanosleep(&time_to_sleep, NULL)); + } +- +-__weak_reference(__usleep, usleep); +-__weak_reference(__usleep, _usleep); diff --git a/gen/FreeBSD/utime.3 b/gen/FreeBSD/utime.3 index 7dc3611..875fc83 100644 --- a/gen/FreeBSD/utime.3 +++ b/gen/FreeBSD/utime.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)utime.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/utime.3,v 1.11 2002/08/24 00:39:43 mike Exp $ +.\" $FreeBSD: src/lib/libc/gen/utime.3,v 1.14 2007/01/09 00:27:56 imp Exp $ .\" .Dd June 4, 1993 .Dt UTIME 3 @@ -53,7 +49,13 @@ This interface is obsoleted by The .Fn utime function sets the access and modification times of the named file from -the structures in the argument array +the +.Va actime +and +.Va modtime +fields of the +.Vt "struct utimbuf" +pointed at by .Fa timep . .Pp If the times are specified (the @@ -78,13 +80,13 @@ for any of the errors specified for the library function .Sh SEE ALSO .Xr stat 2 , .Xr utimes 2 -.Sh HISTORY -A -.Fn utime -function appeared in -.At v7 . .Sh STANDARDS The .Fn utime function conforms to .St -p1003.1-88 . +.Sh HISTORY +A +.Fn utime +function appeared in +.At v7 . diff --git a/gen/FreeBSD/utime.3.patch b/gen/FreeBSD/utime.3.patch index c9de60f..6e88ffe 100644 --- a/gen/FreeBSD/utime.3.patch +++ b/gen/FreeBSD/utime.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/gen/FreeBSD/utime.3 2003-05-20 15:21:03.000000000 -0700 -+++ _SB/Libc/gen/FreeBSD/utime.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -43,7 +43,10 @@ +--- utime.3.bsdnew 2009-11-08 14:20:21.000000000 -0800 ++++ utime.3 2009-11-08 14:32:59.000000000 -0800 +@@ -39,7 +39,10 @@ .Sh SYNOPSIS .In utime.h .Ft int @@ -12,15 +12,21 @@ .Sh DESCRIPTION .Bf -symbolic This interface is obsoleted by -@@ -52,22 +55,22 @@ +@@ -48,28 +51,28 @@ This interface is obsoleted by .Pp The .Fn utime -function sets the access and modification times of the named file from --the structures in the argument array --.Fa timep . +-the +function sets the access and modification times of the named file, -+based on the structures in the argument array ++based on the + .Va actime + and + .Va modtime + fields of the + .Vt "struct utimbuf" + pointed at by +-.Fa timep . +.Fa times . .Pp If the times are specified (the diff --git a/gen/FreeBSD/utime.c b/gen/FreeBSD/utime.c index cefa020..f5a5d8a 100644 --- a/gen/FreeBSD/utime.c +++ b/gen/FreeBSD/utime.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)utime.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/utime.c,v 1.2 2002/03/22 21:52:05 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/utime.c,v 1.3 2007/01/09 00:27:56 imp Exp $"); #include diff --git a/gen/FreeBSD/vis.3 b/gen/FreeBSD/vis.3 index 01b926f..2fa771c 100644 --- a/gen/FreeBSD/vis.3 +++ b/gen/FreeBSD/vis.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)vis.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/vis.3,v 1.26 2004/07/17 12:27:25 tjr Exp $ +.\" $FreeBSD: src/lib/libc/gen/vis.3,v 1.30 2007/01/09 00:27:56 imp Exp $ .\" -.Dd March 21, 2004 +.Dd April 9, 2006 .Dt VIS 3 .Os .Sh NAME @@ -231,16 +227,27 @@ Represents Meta-space. Use C-style backslash sequences to represent standard non-printable characters. The following sequences are used to represent the indicated characters: -.Bd -unfilled -offset indent -.Li \ea Tn - BEL No (007) -.Li \eb Tn - BS No (010) -.Li \ef Tn - NP No (014) -.Li \en Tn - NL No (012) -.Li \er Tn - CR No (015) -.Li \et Tn - HT No (011) -.Li \ev Tn - VT No (013) -.Li \e0 Tn - NUL No (000) -.Ed +.Pp +.Bl -tag -width ".Li \e0" -offset indent -compact +.It Li \ea +.Dv BEL No (007) +.It Li \eb +.Dv BS No (010) +.It Li \ef +.Dv NP No (014) +.It Li \en +.Dv NL No (012) +.It Li \er +.Dv CR No (015) +.It Li \es +.Dv SP No (040) +.It Li \et +.Dv HT No (011) +.It Li \ev +.Dv VT No (013) +.It Li \e0 +.Dv NUL No (000) +.El .Pp When using this format, the .Fa nextc diff --git a/gen/FreeBSD/vis.c b/gen/FreeBSD/vis.c index 8b82877..94d1b22 100644 --- a/gen/FreeBSD/vis.c +++ b/gen/FreeBSD/vis.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)vis.c 8.1 (Berkeley) 7/19/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/vis.c,v 1.13 2003/10/30 12:41:50 phk Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/vis.c,v 1.14 2007/01/09 00:27:56 imp Exp $"); #include #include diff --git a/gen/FreeBSD/vis.c.patch b/gen/FreeBSD/vis.c.patch index 832488d..faf9578 100644 --- a/gen/FreeBSD/vis.c.patch +++ b/gen/FreeBSD/vis.c.patch @@ -1,15 +1,15 @@ ---- vis.c.orig 2004-11-25 11:38:02.000000000 -0800 -+++ vis.c 2005-02-24 16:58:00.000000000 -0800 -@@ -37,6 +37,8 @@ +--- vis.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ vis.c 2009-11-07 14:51:40.000000000 -0800 +@@ -33,6 +33,8 @@ static char sccsid[] = "@(#)vis.c 8.1 (B #include - __FBSDID("$FreeBSD: src/lib/libc/gen/vis.c,v 1.13 2003/10/30 12:41:50 phk Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/gen/vis.c,v 1.14 2007/01/09 00:27:56 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -54,18 +56,20 @@ +@@ -50,18 +52,20 @@ vis(dst, c, flag, nextc) int c, nextc; int flag; { @@ -32,7 +32,7 @@ dst += 2; goto done; } -@@ -74,7 +78,7 @@ +@@ -70,7 +74,7 @@ vis(dst, c, flag, nextc) if ((flag & VIS_GLOB) && (c == '*' || c == '?' || c == '[' || c == '#')) ; @@ -41,7 +41,7 @@ ((flag & VIS_SP) == 0 && c == ' ') || ((flag & VIS_TAB) == 0 && c == '\t') || ((flag & VIS_NL) == 0 && c == '\n') || -@@ -130,7 +134,7 @@ +@@ -126,7 +130,7 @@ vis(dst, c, flag, nextc) goto done; } } @@ -50,7 +50,7 @@ *dst++ = '\\'; *dst++ = ((u_char)c >> 6 & 07) + '0'; *dst++ = ((u_char)c >> 3 & 07) + '0'; -@@ -143,7 +147,7 @@ +@@ -139,7 +143,7 @@ vis(dst, c, flag, nextc) c &= 0177; *dst++ = 'M'; } diff --git a/gen/FreeBSD/wait.c b/gen/FreeBSD/wait.c index 8cb80a4..46e7f72 100644 --- a/gen/FreeBSD/wait.c +++ b/gen/FreeBSD/wait.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)wait.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/wait.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/wait.c,v 1.7 2007/01/09 00:27:56 imp Exp $"); #include "namespace.h" #include diff --git a/gen/FreeBSD/wait.c.patch b/gen/FreeBSD/wait.c.patch index 23446fb..459adb3 100644 --- a/gen/FreeBSD/wait.c.patch +++ b/gen/FreeBSD/wait.c.patch @@ -1,6 +1,6 @@ ---- wait.c.orig 2006-09-13 16:57:37.000000000 -0700 -+++ wait.c 2006-09-13 17:00:15.000000000 -0700 -@@ -44,10 +44,20 @@ +--- wait.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ wait.c 2009-11-07 14:51:40.000000000 -0800 +@@ -40,10 +40,20 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/wai #include #include "un-namespace.h" diff --git a/gen/FreeBSD/wait3.c b/gen/FreeBSD/wait3.c index a4b91a7..0aca311 100644 --- a/gen/FreeBSD/wait3.c +++ b/gen/FreeBSD/wait3.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)wait3.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/wait3.c,v 1.3 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/wait3.c,v 1.4 2007/01/09 00:27:56 imp Exp $"); #include "namespace.h" #include diff --git a/gen/FreeBSD/waitpid.c b/gen/FreeBSD/waitpid.c index 273d1f3..47a06e8 100644 --- a/gen/FreeBSD/waitpid.c +++ b/gen/FreeBSD/waitpid.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)waitpid.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/waitpid.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/waitpid.c,v 1.7 2007/01/09 00:27:56 imp Exp $"); #include "namespace.h" #include diff --git a/gen/FreeBSD/waitpid.c.patch b/gen/FreeBSD/waitpid.c.patch index 7129f8d..13ebf93 100644 --- a/gen/FreeBSD/waitpid.c.patch +++ b/gen/FreeBSD/waitpid.c.patch @@ -1,6 +1,6 @@ ---- waitpid.c.orig 2006-09-16 19:12:38.000000000 -0700 -+++ waitpid.c 2006-09-16 20:38:56.000000000 -0700 -@@ -44,10 +44,31 @@ +--- waitpid.c.orig 2009-11-07 14:51:38.000000000 -0800 ++++ waitpid.c 2009-11-07 14:51:40.000000000 -0800 +@@ -40,10 +40,31 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/wai #include #include "un-namespace.h" diff --git a/gen/Makefile.inc b/gen/Makefile.inc index 64f43a7..2edd5c1 100644 --- a/gen/Makefile.inc +++ b/gen/Makefile.inc @@ -15,7 +15,8 @@ GENMIGHDRS += ${GENMIGDEFS:.defs=.h} GENMIGSRCS += ${GENMIGDEFS:.defs=User.c} MISRCS += ${GENMIGSRCS} NSSystemDirectories.c \ - asl.c asl_core.c asl_file.c asl_legacy1.c asl_store.c asl_util.c \ + asl.c asl_core.c asl_file.c asl_legacy1.c asl_msg.c asl_store.c asl_util.c \ + assumes.c \ backtrace.c \ cache.c confstr.c crypt.c devname.c disklabel.c errlst.c \ filesec.c fts.c \ @@ -23,7 +24,8 @@ MISRCS += ${GENMIGSRCS} NSSystemDirectories.c \ isinf.c isnan.c \ malloc.c nanosleep.c nftw.c magazine_malloc.c setlogin.c \ sigsetops.c _simple.c stack_logging.c stack_logging_disk.c strtofflags.c syslog.c \ - thread_stack_pcs.c uname.c utmpx-darwin.c wordexp.c + thread_stack_pcs.c uname.c utmpx-darwin.c wordexp.c \ + platfunc.c .ifdef FEATURE_LEGACY_NXZONE_APIS MISRCS += zone.c @@ -38,19 +40,27 @@ ${SYMROOTINC}/magmallocProvider.h: ${.CURDIR}/gen/magmallocProvider.d magazine_malloc.${OBJSUFFIX}: ${SYMROOTINC}/magmallocProvider.h malloc.${OBJSUFFIX}: ${SYMROOTINC}/magmallocProvider.h -# Force these files to build after the mig stuff -asl.${OBJSUFFIX}: asl_ipcUser.c -syslog.${OBJSUFFIX}: asl_ipcUser.c -utmpx-darwin.${OBJSUFFIX}: asl_ipcUser.c +# Force the ASL-related mig files to build first +BUILDFIRST += asl_ipcUser.c CLEANFILES += ${GENMIGHDRS} ${GENMIGSRCS} ${GENMIGDEFS:.defs=Server.c} -LOCALHDRS += ${.CURDIR}/gen/asl_core.h ${.CURDIR}/gen/asl_file.h ${.CURDIR}/gen/asl_legacy1.h \ - ${.CURDIR}/gen/asl_private.h ${.CURDIR}/gen/asl_store.h \ - ${.CURDIR}/gen/_simple.h ${.CURDIR}/gen/stack_logging.h +LOCALHDRS += \ + ${.CURDIR}/gen/asl_core.h \ + ${.CURDIR}/gen/asl_file.h \ + ${.CURDIR}/gen/asl_ipc.defs \ + ${.CURDIR}/gen/asl_legacy1.h \ + ${.CURDIR}/gen/asl_msg.h \ + ${.CURDIR}/gen/asl_private.h \ + ${.CURDIR}/gen/asl_store.h \ + ${.CURDIR}/gen/assumes.h \ + ${.CURDIR}/gen/_simple.h \ + ${.CURDIR}/gen/stack_logging.h \ + ${.CURDIR}/gen/utmpx_thread.h CFLAGS-asl_file.c += -D_DARWIN_UNLIMITED_STREAMS CFLAGS-asl_legacy1.c += -D_DARWIN_UNLIMITED_STREAMS +CFLAGS-asl_msg.c += -D_DARWIN_UNLIMITED_STREAMS CFLAGS-asl_store.c += -D_DARWIN_UNLIMITED_STREAMS CFLAGS-confstr.c += -I${.CURDIR}/darwin CFLAGS-fmtmsg-fbsd.c += -D_DARWIN_UNLIMITED_STREAMS @@ -79,7 +89,7 @@ LDBLSRCS += asl.c err.c syslog.c .include "Makefile.fbsd_begin" FBSDMISRCS = _rand48.c alarm.c arc4random.c assert.c \ basename.c clock.c closedir.c ctermid.c \ - daemon.c dirname.c drand48.c erand48.c err.c errno_.c exec.c \ + daemon.c dirname.c drand48.c erand48.c err.c exec.c \ fmtcheck.c fmtmsg.c fnmatch.c ftok.c \ getbsize.c getcap.c getcwd.c gethostname.c getpeereid.c \ getlogin.c getmntinfo.c getpagesize.c getprogname.c glob.c isatty.c \ @@ -157,7 +167,21 @@ CANCELABLESRCS += lockf.c nanosleep.c pause.c pselect.c sleep.c termios.c \ usleep.c wait.c waitpid.c CANCELABLE-DARWINEXTSNSRCS += pselect.c DARWINEXTSNSRCS += popen.c pselect.c -DYLDSRCS += _simple.c + +DYLDSRCS += \ + _simple.c \ + arc4random.c \ + closedir.c \ + getcwd.c \ + getpagesize.c \ + nanosleep.c \ + opendir.c \ + readdir.c \ + scandir.c \ + sysctl.c \ + sysctlbyname.c \ + telldir.c \ + usleep.c # include __dirent.h to rename DIR structure elements .for _src in closedir-fbsd.c opendir-fbsd.c readdir-fbsd.c rewinddir-fbsd.c \ @@ -244,7 +268,9 @@ NBSDMAN5= utmpx.5 .include "Makefile.nbsd_end" MLINKS+= arc4random.3 arc4random_addrandom.3 \ - arc4random.3 arc4random_stir.3 + arc4random.3 arc4random_buf.3 \ + arc4random.3 arc4random_stir.3 \ + arc4random.3 arc4random_uniform.3 MLINKS+= asl.3 asl_add_log_file.3 \ asl.3 asl_close.3 \ diff --git a/gen/NSSystemDirectories.c b/gen/NSSystemDirectories.c index 1d0c3e4..574b1a1 100644 --- a/gen/NSSystemDirectories.c +++ b/gen/NSSystemDirectories.c @@ -25,6 +25,7 @@ #include #include #include +#include #define NSUserDomainIndex 0 #define NSLocalDomainIndex 1 @@ -226,7 +227,7 @@ static struct { }, { // NSCachesDirectory 1, - (const void * const * const)prefixAll, + (const void * const * const)prefixNoNetwork, (const void * const)NSCachesDirectoryBase }, { // NSApplicationSupportDirectory @@ -241,7 +242,7 @@ static struct { }, { // NSInputMethodsDirectory 1, - (const void * const * const)prefixAll, + (const void * const * const)prefixAllSystem, (const void * const)NSInputMethodsDirectoryBase }, { // NSMoviesDirectory @@ -315,8 +316,21 @@ NSSearchPathEnumerationState NSStartSearchPathEnumeration(NSSearchPathDirectory return (dir << DirShift) + domainMask; } +static const char *nextRoot = NULL; +static pthread_once_t nextRoot_init_once = PTHREAD_ONCE_INIT; + +static void +nextRoot_init(void) +{ + if (!issetugid() && (nextRoot = getenv("NEXT_ROOT")) != NULL) { + nextRoot = strdup(nextRoot); + } + if (nextRoot == NULL) { + nextRoot = ""; + } +} + NSSearchPathEnumerationState NSGetNextSearchPathEnumeration(NSSearchPathEnumerationState state, char *path) { - static const char *nextRoot = NULL; int dir = (state >> DirShift) & ByteMask; int domainMask = state & DomainMask; int domain, i, n; @@ -359,14 +373,8 @@ NSSearchPathEnumerationState NSGetNextSearchPathEnumeration(NSSearchPathEnumerat } if (addNextRoot(prefix)) { - if (nextRoot == NULL) { // Get NEXT_ROOT - if (!issetugid() && (nextRoot = getenv("NEXT_ROOT")) != NULL) { - nextRoot = strdup(nextRoot); - } - if (nextRoot == NULL) { - nextRoot = ""; - } - } + if (pthread_once(&nextRoot_init_once, nextRoot_init) != 0 || nextRoot == NULL)// Error + return 0; strlcpy(path, nextRoot, PATH_MAX); } else { *path = 0; diff --git a/gen/NetBSD/endutxent.3 b/gen/NetBSD/endutxent.3 index c3f6be5..06a4433 100644 --- a/gen/NetBSD/endutxent.3 +++ b/gen/NetBSD/endutxent.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: endutxent.3,v 1.4 2004/05/04 02:38:35 atatat Exp $ +.\" $NetBSD: endutxent.3,v 1.5 2008/04/30 13:10:50 martin Exp $ .\" .\" Copyright (c) 2002 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -14,13 +14,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED diff --git a/gen/NetBSD/endutxent.3.patch b/gen/NetBSD/endutxent.3.patch index 81978c9..3b04979 100644 --- a/gen/NetBSD/endutxent.3.patch +++ b/gen/NetBSD/endutxent.3.patch @@ -1,5 +1,5 @@ ---- endutxent.3.orig 2007-04-08 18:49:40.000000000 -0700 -+++ endutxent.3 2007-04-08 19:03:43.000000000 -0700 +--- endutxent.3.orig 2009-04-03 22:48:14.000000000 -0700 ++++ endutxent.3 2009-04-04 18:16:44.000000000 -0700 @@ -34,7 +34,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. @@ -124,11 +124,11 @@ +.El +.Ss Other extensions to the standards +The -+.Fa ut_tv ++.Fa ut_type +value may also be OR-ed with the following masks: +.Bl -tag -width XXXX -compact -offset indent +.It Dv UTMPX_AUTOFILL_MASK -+Depending on the ++Depending on the main part of +.Fa ut_type +value, other fields are automatically filled in (as specified in the +meaningful fields table above). diff --git a/gen/NetBSD/getlastlogx.3 b/gen/NetBSD/getlastlogx.3 index 78fbd5e..cb7404c 100644 --- a/gen/NetBSD/getlastlogx.3 +++ b/gen/NetBSD/getlastlogx.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: getlastlogx.3,v 1.1 2003/08/26 17:37:51 wiz Exp $ +.\" $NetBSD: getlastlogx.3,v 1.2 2008/04/30 13:10:50 martin Exp $ .\" .\" Copyright (c) 2003 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -14,13 +14,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED diff --git a/gen/NetBSD/utmpx.5 b/gen/NetBSD/utmpx.5 index 3f5ed33..25a803d 100644 --- a/gen/NetBSD/utmpx.5 +++ b/gen/NetBSD/utmpx.5 @@ -1,4 +1,4 @@ -.\" $NetBSD: utmpx.5,v 1.2 2003/04/16 13:35:24 wiz Exp $ +.\" $NetBSD: utmpx.5,v 1.7 2008/04/30 13:10:57 martin Exp $ .\" .\" Copyright (c) 2002 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -14,13 +14,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -34,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd September 26, 2002 +.Dd January 31, 2007 .Dt UTMPX 5 .Os .Sh NAME @@ -45,6 +38,17 @@ .Sh SYNOPSIS .In utmpx.h .Sh DESCRIPTION +In contrast to +.Pa utmp +and +.Pa wtmp , +the extended databases in +.Pa utmpx +and +.Pa wtmpx +reserve more space for logging hostnames, and also +information on a process' ID, termination signal and exit status. +.Pp The .Aq Pa utmpx.h header defines the structures and functions for logging user. @@ -55,13 +59,11 @@ and date changes, is kept in .Pa /var/log/wtmpx , and the last login of each user is noted in .Pa /var/log/lastlogx . -The files are not automatically created if they do not exist; they -must be created manually. .Pp The interface to the .Nm utmpx file is described in -.Xr endutxent 3 . +.Xr getutxent 3 . .Pp The .Nm wtmpx @@ -131,6 +133,7 @@ file. .Xr who 1 , .Xr endutxent 3 , .Xr logwtmpx 3 , +.Xr utmp 5 , .Xr ac 8 , .Xr init 8 , .Xr newsyslog 8 , diff --git a/gen/NetBSD/utmpx.5.patch b/gen/NetBSD/utmpx.5.patch index 768fb89..49f9b47 100644 --- a/gen/NetBSD/utmpx.5.patch +++ b/gen/NetBSD/utmpx.5.patch @@ -1,11 +1,6 @@ ---- utmpx.5.orig 2004-09-20 17:32:52.000000000 -0700 -+++ utmpx.5 2005-12-26 11:25:30.000000000 -0800 -@@ -34,13 +34,11 @@ - .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - .\" POSSIBILITY OF SUCH DAMAGE. - .\" --.Dd September 26, 2002 -+.Dd Dec 26, 2005 +--- utmpx.5.orig 2009-11-06 10:28:19.000000000 -0800 ++++ utmpx.5 2009-11-06 10:29:23.000000000 -0800 +@@ -31,9 +31,7 @@ .Dt UTMPX 5 .Os .Sh NAME @@ -16,7 +11,7 @@ .Nd user accounting database .Sh SYNOPSIS .In utmpx.h -@@ -49,89 +47,51 @@ +@@ -53,88 +51,51 @@ The .Aq Pa utmpx.h header defines the structures and functions for logging user. Currently logged in users are tracked in @@ -26,14 +21,13 @@ -.Pa /var/log/wtmpx , -and the last login of each user is noted in -.Pa /var/log/lastlogx . --The files are not automatically created if they do not exist; they --must be created manually. -.Pp +.Pa /var/run/utmpx . The interface to the .Nm utmpx file is described in - .Xr endutxent 3 . +-.Xr getutxent 3 . ++.Xr endutxent 3 . +The file is not automatically created if they do not exist; it +must be created manually. .Pp @@ -132,6 +126,7 @@ +.Xr asl 3 , .Xr endutxent 3 , -.Xr logwtmpx 3 , +-.Xr utmp 5 , -.Xr ac 8 , -.Xr init 8 , -.Xr newsyslog 8 , diff --git a/gen/NetBSD/utmpx.c b/gen/NetBSD/utmpx.c index 6efedc3..b7497eb 100644 --- a/gen/NetBSD/utmpx.c +++ b/gen/NetBSD/utmpx.c @@ -1,4 +1,4 @@ -/* $NetBSD: utmpx.c,v 1.21 2003/09/06 16:42:10 wiz Exp $ */ +/* $NetBSD: utmpx.c,v 1.25 2008/04/28 20:22:59 martin Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -15,13 +15,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -38,7 +31,7 @@ #include #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: utmpx.c,v 1.21 2003/09/06 16:42:10 wiz Exp $"); +__RCSID("$NetBSD: utmpx.c,v 1.25 2008/04/28 20:22:59 martin Exp $"); #endif /* LIBC_SCCS and not lint */ #include "namespace.h" @@ -58,21 +51,13 @@ __RCSID("$NetBSD: utmpx.c,v 1.21 2003/09/06 16:42:10 wiz Exp $"); #include #include #include -/* don't define earlier, has side effects in fcntl.h */ -#define __LIBC12_SOURCE__ #include #include -__warn_references(getlastlogx, - "warning: reference to compatibility getlastlogx(); include for correct reference") -__warn_references(lastlogxname, - "warning: reference to deprecated lastlogxname()") - static FILE *fp; static int readonly = 0; static struct utmpx ut; static char utfile[MAXPATHLEN] = _PATH_UTMPX; -static char llfile[MAXPATHLEN] = _PATH_LASTLOGX; static struct utmpx *utmp_update(const struct utmpx *); @@ -294,7 +279,7 @@ utmp_update(const struct utmpx *utx) case 0: (void)execl(_PATH_UTMP_UPDATE, strrchr(_PATH_UTMP_UPDATE, '/') + 1, buf, NULL); - exit(1); + _exit(1); /*NOTREACHED*/ case -1: return NULL; @@ -400,35 +385,8 @@ getutmpx(const struct utmp *u, struct utmpx *ux) ux->ut_exit.e_exit = 0; } -int -lastlogxname(const char *fname) -{ - size_t len; - - _DIAGASSERT(fname != NULL); - - len = strlen(fname); - - if (len >= sizeof(llfile)) - return 0; - - /* must end in x! */ - if (fname[len - 1] != 'x') - return 0; - - (void)strlcpy(llfile, fname, sizeof(llfile)); - return 1; -} - -struct lastlogx * -getlastlogx(uid_t uid, struct lastlogx *ll) -{ - - return __getlastlogx13(_PATH_LASTLOGX, uid, ll); -} - struct lastlogx * -__getlastlogx13(const char *fname, uid_t uid, struct lastlogx *ll) +getlastlogx(const char *fname, uid_t uid, struct lastlogx *ll) { DBT key, data; DB *db; @@ -475,7 +433,7 @@ updlastlogx(const char *fname, uid_t uid, struct lastlogx *ll) _DIAGASSERT(fname != NULL); _DIAGASSERT(ll != NULL); - db = dbopen(fname, O_RDWR|O_CREAT|O_EXLOCK, 0, DB_HASH, NULL); + db = dbopen(fname, O_RDWR|O_CREAT|O_EXLOCK, 0644, DB_HASH, NULL); if (db == NULL) return -1; diff --git a/gen/NetBSD/utmpx.c.patch b/gen/NetBSD/utmpx.c.patch index f0125d8..a0da286 100644 --- a/gen/NetBSD/utmpx.c.patch +++ b/gen/NetBSD/utmpx.c.patch @@ -1,6 +1,6 @@ ---- utmpx.c.orig 2009-04-01 04:01:12.000000000 -0700 -+++ utmpx.c 2009-04-01 04:09:50.000000000 -0700 -@@ -49,48 +49,57 @@ __RCSID("$NetBSD: utmpx.c,v 1.21 2003/09 +--- utmpx.c.orig 2010-06-24 19:43:32.000000000 -0700 ++++ utmpx.c 2010-06-29 11:25:57.000000000 -0700 +@@ -42,111 +42,240 @@ __RCSID("$NetBSD: utmpx.c,v 1.25 2008/04 #include #include @@ -12,249 +12,377 @@ #include #include #include -+#ifdef LEGACY_UTMP_APIS ++#ifdef UNIFDEF_LEGACY_UTMP_APIS #include --/* don't define earlier, has side effects in fcntl.h */ --#define __LIBC12_SOURCE__ -+#endif /* LEGACY_UTMP_APIS */ ++#endif /* UNIFDEF_LEGACY_UTMP_APIS */ #include +#include +#include #include -- --__warn_references(getlastlogx, -- "warning: reference to compatibility getlastlogx(); include for correct reference") --__warn_references(lastlogxname, -- "warning: reference to deprecated lastlogxname()") +#include - static FILE *fp; - static int readonly = 0; - static struct utmpx ut; - static char utfile[MAXPATHLEN] = _PATH_UTMPX; --static char llfile[MAXPATHLEN] = _PATH_LASTLOGX; -+__private_extern__ int utfile_system = 1; /* are we using _PATH_UTMPX? */ -+__private_extern__ pthread_mutex_t utmpx_mutex = PTHREAD_MUTEX_INITIALIZER; +-static FILE *fp; +-static int readonly = 0; +-static struct utmpx ut; +-static char utfile[MAXPATHLEN] = _PATH_UTMPX; ++/* This is the default struct _utmpx shared by the POSIX APIs */ ++__private_extern__ ++struct _utmpx __utx__ = { ++ __UTX_MAGIC__, /* magic */ ++ {}, /* ut */ ++ PTHREAD_MUTEX_INITIALIZER, /* utmpx_mutex */ ++ _PATH_UTMPX, /* utfile */ ++ NULL, /* fp */ ++ 1, /* utfile_system */ ++ 0, /* readonly */ ++}; ++ ++static struct utmpx *__getutxid(struct _utmpx *, const struct utmpx *); -static struct utmpx *utmp_update(const struct utmpx *); -+static struct utmpx *_getutxid(const struct utmpx *); - --static const char vers[] = "utmpx-1.00"; +__private_extern__ const char _utmpx_vers[] = "utmpx-1.00"; --void --setutxent() +-static const char vers[] = "utmpx-1.00"; +__private_extern__ void -+_setutxent() - { - - (void)memset(&ut, 0, sizeof(ut)); - if (fp == NULL) - return; ++__setutxent(struct _utmpx *U) ++{ ++ ++ (void)memset(&U->ut, 0, sizeof(U->ut)); ++ if (U->fp == NULL) ++ return; +#ifdef __LP64__ -+ (void)fseeko(fp, (off_t)sizeof(struct utmpx32), SEEK_SET); ++ (void)fseeko(U->fp, (off_t)sizeof(struct utmpx32), SEEK_SET); +#else /* __LP64__ */ - (void)fseeko(fp, (off_t)sizeof(ut), SEEK_SET); ++ (void)fseeko(U->fp, (off_t)sizeof(U->ut), SEEK_SET); +#endif /* __LP64__ */ ++} + + void +-setutxent() ++_setutxent(struct _utmpx *U) + { + +- (void)memset(&ut, 0, sizeof(ut)); +- if (fp == NULL) +- return; +- (void)fseeko(fp, (off_t)sizeof(ut), SEEK_SET); ++ TEST_UTMPX_T("_setutxent", U); ++ UTMPX_LOCK(U); ++ __setutxent(U); ++ UTMPX_UNLOCK(U); } void -endutxent() +setutxent() -+{ -+ UTMPX_LOCK; -+ _setutxent(); -+ UTMPX_UNLOCK; + { ++ _setutxent(&__utx__); +} + -+ -+__private_extern__ void -+_endutxent() - { - (void)memset(&ut, 0, sizeof(ut)); -@@ -102,9 +111,21 @@ endutxent() +- (void)memset(&ut, 0, sizeof(ut)); +- if (fp != NULL) { +- (void)fclose(fp); +- fp = NULL; +- readonly = 0; ++__private_extern__ void ++__endutxent(struct _utmpx *U) ++{ ++ (void)memset(&U->ut, 0, sizeof(U->ut)); ++ if (U->fp != NULL) { ++ int saveerrno = errno; ++ (void)fclose(U->fp); ++ errno = saveerrno; ++ U->fp = NULL; ++ U->readonly = 0; + } } -struct utmpx * -getutxent() +void -+endutxent() ++_endutxent(struct _utmpx *U) { -+ UTMPX_LOCK; -+ _endutxent(); -+ UTMPX_UNLOCK; ++ TEST_UTMPX_T("_endutxent", U); ++ UTMPX_LOCK(U); ++ __endutxent(U); ++ UTMPX_UNLOCK(U); ++} + +- if (fp == NULL) { ++ ++void ++endutxent() ++{ ++ _endutxent(&__utx__); +} + + -+static struct utmpx * -+_getutxent() ++__private_extern__ struct utmpx * ++__getutxent(struct _utmpx *U) +{ ++ int saveerrno; +#ifdef __LP64__ + struct utmpx32 ut32; +#endif /* __LP64__ */ - - if (fp == NULL) { ++ ++ if (U->fp == NULL) { struct stat st; -@@ -116,7 +137,8 @@ getutxent() + +- if ((fp = fopen(utfile, "r+")) == NULL) +- if ((fp = fopen(utfile, "w+")) == NULL) { +- if ((fp = fopen(utfile, "r")) == NULL) ++ if ((U->fp = fopen(U->utfile, "r+")) == NULL) ++ if ((U->fp = fopen(U->utfile, "w+")) == NULL) { ++ if ((U->fp = fopen(U->utfile, "r")) == NULL) + goto fail; else - readonly = 1; +- readonly = 1; ++ U->readonly = 1; } - + -+ fcntl(fileno(fp), F_SETFD, 1); /* set close-on-exec flag */ ++ fcntl(fileno(U->fp), F_SETFD, 1); /* set close-on-exec flag */ /* get file size in order to check if new file */ - if (fstat(fileno(fp), &st) == -1) -@@ -124,27 +146,51 @@ getutxent() +- if (fstat(fileno(fp), &st) == -1) ++ if (fstat(fileno(U->fp), &st) == -1) + goto failclose; if (st.st_size == 0) { /* new file, add signature record */ +- (void)memset(&ut, 0, sizeof(ut)); +- ut.ut_type = SIGNATURE; +- (void)memcpy(ut.ut_user, vers, sizeof(vers)); +- if (fwrite(&ut, sizeof(ut), 1, fp) != 1) +#ifdef __LP64__ + (void)memset(&ut32, 0, sizeof(ut32)); + ut32.ut_type = SIGNATURE; + (void)memcpy(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers)); -+ if (fwrite(&ut32, sizeof(ut32), 1, fp) != 1) ++ if (fwrite(&ut32, sizeof(ut32), 1, U->fp) != 1) +#else /* __LP64__ */ - (void)memset(&ut, 0, sizeof(ut)); - ut.ut_type = SIGNATURE; -- (void)memcpy(ut.ut_user, vers, sizeof(vers)); -+ (void)memcpy(ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)); - if (fwrite(&ut, sizeof(ut), 1, fp) != 1) ++ (void)memset(&U->ut, 0, sizeof(U->ut)); ++ U->ut.ut_type = SIGNATURE; ++ (void)memcpy(U->ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)); ++ if (fwrite(&U->ut, sizeof(U->ut), 1, U->fp) != 1) +#endif /* __LP64__ */ goto failclose; } else { /* old file, read signature record */ +- if (fread(&ut, sizeof(ut), 1, fp) != 1) +#ifdef __LP64__ -+ if (fread(&ut32, sizeof(ut32), 1, fp) != 1) ++ if (fread(&ut32, sizeof(ut32), 1, U->fp) != 1) +#else /* __LP64__ */ - if (fread(&ut, sizeof(ut), 1, fp) != 1) ++ if (fread(&U->ut, sizeof(U->ut), 1, U->fp) != 1) +#endif /* __LP64__ */ goto failclose; - if (memcmp(ut.ut_user, vers, sizeof(vers)) != 0 || +- ut.ut_type != SIGNATURE) +#ifdef __LP64__ + if (memcmp(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 || + ut32.ut_type != SIGNATURE) +#else /* __LP64__ */ -+ if (memcmp(ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 || - ut.ut_type != SIGNATURE) ++ if (memcmp(U->ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 || ++ U->ut.ut_type != SIGNATURE) +#endif /* __LP64__ */ ++ { ++ errno = EINVAL; goto failclose; ++ } } } +- if (fread(&ut, sizeof(ut), 1, fp) != 1) +#ifdef __LP64__ -+ if (fread(&ut32, sizeof(ut32), 1, fp) != 1) ++ if (fread(&ut32, sizeof(ut32), 1, U->fp) != 1) +#else /* __LP64__ */ - if (fread(&ut, sizeof(ut), 1, fp) != 1) ++ if (fread(&U->ut, sizeof(U->ut), 1, U->fp) != 1) +#endif /* __LP64__ */ goto fail; +- return &ut; +#ifdef __LP64__ -+ _utmpx32_64(&ut32, &ut); ++ _utmpx32_64(&ut32, &U->ut); +#endif /* __LP64__ */ - return &ut; ++ return &U->ut; failclose: - (void)fclose(fp); -+ fp = NULL; +- (void)fclose(fp); ++ saveerrno = errno; ++ (void)fclose(U->fp); ++ errno = saveerrno; ++ U->fp = NULL; fail: - (void)memset(&ut, 0, sizeof(ut)); +- (void)memset(&ut, 0, sizeof(ut)); ++ (void)memset(&U->ut, 0, sizeof(U->ut)); return NULL; -@@ -152,14 +198,45 @@ fail: + } struct utmpx * -+getutxent() -+{ +-getutxid(const struct utmpx *utx) ++_getutxent(struct _utmpx *U) + { + struct utmpx *ret; -+ UTMPX_LOCK; -+ ret = _getutxent(); -+ UTMPX_UNLOCK; ++ ++ TEST_UTMPX_T("_getutxent", U); ++ UTMPX_LOCK(U); ++ ret = __getutxent(U); ++ UTMPX_UNLOCK(U); + return ret; +} + ++ +struct utmpx * - getutxid(const struct utmpx *utx) - { ++getutxent() ++{ ++ return _getutxent(&__utx__); ++} + +- _DIAGASSERT(utx != NULL); ++ ++struct utmpx * ++_getutxid(struct _utmpx *U, const struct utmpx *utx) ++{ + struct utmpx temp; + const struct utmpx *ux; + struct utmpx *ret; - _DIAGASSERT(utx != NULL); - if (utx->ut_type == EMPTY) return NULL; -+ UTMPX_LOCK; ++ TEST_UTMPX_T("_getutxid", U); ++ UTMPX_LOCK(U); + /* make a copy as needed, and auto-fill if requested */ + ux = _utmpx_working_copy(utx, &temp, 1); + if (!ux) { -+ UTMPX_UNLOCK; ++ UTMPX_UNLOCK(U); + return NULL; + } + -+ ret = _getutxid(ux); -+ UTMPX_UNLOCK; ++ ret = __getutxid(U, ux); ++ UTMPX_UNLOCK(U); + return ret; +} + + ++struct utmpx * ++getutxid(const struct utmpx *utx) ++{ ++ return _getutxid(&__utx__, utx); ++} ++ ++ +static struct utmpx * -+_getutxid(const struct utmpx *utx) ++__getutxid(struct _utmpx *U, const struct utmpx *utx) +{ + do { - if (ut.ut_type == EMPTY) +- if (ut.ut_type == EMPTY) ++ if (U->ut.ut_type == EMPTY) continue; -@@ -193,7 +270,7 @@ getutxid(const struct utmpx *utx) + switch (utx->ut_type) { + case EMPTY: +@@ -155,21 +284,21 @@ getutxid(const struct utmpx *utx) + case BOOT_TIME: + case OLD_TIME: + case NEW_TIME: +- if (ut.ut_type == utx->ut_type) +- return &ut; ++ if (U->ut.ut_type == utx->ut_type) ++ return &U->ut; + break; + case INIT_PROCESS: + case LOGIN_PROCESS: + case USER_PROCESS: + case DEAD_PROCESS: +- switch (ut.ut_type) { ++ switch (U->ut.ut_type) { + case INIT_PROCESS: + case LOGIN_PROCESS: + case USER_PROCESS: + case DEAD_PROCESS: +- if (memcmp(ut.ut_id, utx->ut_id, +- sizeof(ut.ut_id)) == 0) +- return &ut; ++ if (memcmp(U->ut.ut_id, utx->ut_id, ++ sizeof(U->ut.ut_id)) == 0) ++ return &U->ut; + break; + default: + break; +@@ -178,188 +307,253 @@ getutxid(const struct utmpx *utx) default: return NULL; } - } while (getutxent() != NULL); -+ } while (_getutxent() != NULL); ++ } while (__getutxent(U) != NULL); return NULL; } -@@ -204,6 +281,7 @@ getutxline(const struct utmpx *utx) - _DIAGASSERT(utx != NULL); - -+ UTMPX_LOCK; +-struct utmpx * +-getutxline(const struct utmpx *utx) ++static struct utmpx * ++__getutxline(struct _utmpx *U, const struct utmpx *utx) + { +- +- _DIAGASSERT(utx != NULL); +- do { - switch (ut.ut_type) { +- switch (ut.ut_type) { ++ switch (U->ut.ut_type) { case EMPTY: -@@ -211,13 +289,16 @@ getutxline(const struct utmpx *utx) + break; case LOGIN_PROCESS: case USER_PROCESS: - if (strncmp(ut.ut_line, utx->ut_line, +- if (strncmp(ut.ut_line, utx->ut_line, - sizeof(ut.ut_line)) == 0) -+ sizeof(ut.ut_line)) == 0) { -+ UTMPX_UNLOCK; - return &ut; -+ } +- return &ut; ++ if (strncmp(U->ut.ut_line, utx->ut_line, ++ sizeof(U->ut.ut_line)) == 0) ++ return &U->ut; break; default: break; } - } while (getutxent() != NULL); -+ } while (_getutxent() != NULL); -+ UTMPX_UNLOCK; ++ } while (__getutxent(U) != NULL); return NULL; } -@@ -225,156 +306,180 @@ getutxline(const struct utmpx *utx) + struct utmpx * - pututxline(const struct utmpx *utx) +-pututxline(const struct utmpx *utx) ++_getutxline(struct _utmpx *U, const struct utmpx *utx) ++{ ++ struct utmpx *ret; ++ ++ TEST_UTMPX_T("_getutxline", U); ++ UTMPX_LOCK(U); ++ ret = __getutxline(U, utx); ++ UTMPX_UNLOCK(U); ++ return ret; ++} ++ ++ ++struct utmpx * ++getutxline(const struct utmpx *utx) { - struct utmpx temp, *u = NULL; - int gotlock = 0; -+ struct utmpx *ux; ++ return _getutxline(&__utx__, utx); ++} - _DIAGASSERT(utx != NULL); +- _DIAGASSERT(utx != NULL); - if (utx == NULL) ++struct utmpx * ++_pututxline(struct _utmpx *U, const struct utmpx *utx) ++{ ++ struct utmpx *ux; ++ + if (utx == NULL) { + errno = EINVAL; return NULL; @@ -263,21 +391,28 @@ - if (strcmp(_PATH_UTMPX, utfile) == 0) - if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) - return utmp_update(utx); -- -+ UTMPX_LOCK; -+ if ((ux = _pututxline(utx)) != NULL && utfile_system) { ++ TEST_UTMPX_T("_pututxline", U); ++ UTMPX_LOCK(U); ++ if ((ux = __pututxline(&__utx__, utx)) != NULL && __utx__.utfile_system) { + _utmpx_asl(ux); /* the equivalent of wtmpx and lastlogx */ +#ifdef UTMP_COMPAT + _write_utmp_compat(ux); +#endif /* UTMP_COMPAT */ + } -+ UTMPX_UNLOCK; ++ UTMPX_UNLOCK(U); + return ux; +} + - (void)memcpy(&temp, utx, sizeof(temp)); ++struct utmpx * ++pututxline(const struct utmpx *utx) ++{ ++ return _pututxline(&__utx__, utx); ++} ++ +__private_extern__ struct utmpx * -+_pututxline(const struct utmpx *utx) ++__pututxline(struct _utmpx *U, const struct utmpx *utx) +{ + struct utmpx temp, *u = NULL, *x; + const struct utmpx *ux; @@ -288,17 +423,18 @@ +#define gotlock (fl.l_start >= 0) + + fl.l_start = -1; /* also means we haven't locked */ -+ if (utfile_system) -+ if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) { ++ if (U->utfile_system) ++ if ((U->fp != NULL && U->readonly) || (U->fp == NULL && geteuid() != 0)) { + errno = EPERM; + return NULL; + } - if (fp == NULL) { +- if (fp == NULL) { - (void)getutxent(); - if (fp == NULL || readonly) -+ (void)_getutxent(); -+ if (fp == NULL || readonly) { ++ if (U->fp == NULL) { ++ (void)__getutxent(U); ++ if (U->fp == NULL || U->readonly) { + errno = EPERM; return NULL; + } @@ -313,9 +449,9 @@ + if (!ux) + return NULL; + -+ if ((x = _getutxid(ux)) == NULL) { -+ _setutxent(); -+ if ((x = _getutxid(ux)) == NULL) { ++ if ((x = __getutxid(U, ux)) == NULL) { ++ __setutxent(U); ++ if ((x = __getutxid(U, ux)) == NULL) { + /* + * utx->ut_type has any original mask bits, while + * ux->ut_type has those mask bits removed. If we @@ -326,21 +462,22 @@ + if (ux->ut_type == DEAD_PROCESS && + (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK)) { + errno = EINVAL; -+ return NULL; + return NULL; +- gotlock++; +- if (fseeko(fp, (off_t)0, SEEK_END) == -1) + } + /* + * Replace lockf() with fcntl() and a fixed start + * value. We should already be at EOF. + */ -+ if ((fl.l_start = lseek(fileno(fp), 0, SEEK_CUR)) < 0) ++ if ((fl.l_start = lseek(fileno(U->fp), 0, SEEK_CUR)) < 0) + return NULL; + fl.l_len = 0; + fl.l_whence = SEEK_SET; + fl.l_type = F_WRLCK; -+ if (fcntl(fileno(fp), F_SETLKW, &fl) == -1) - return NULL; -- gotlock++; - if (fseeko(fp, (off_t)0, SEEK_END) == -1) ++ if (fcntl(fileno(U->fp), F_SETLKW, &fl) == -1) ++ return NULL; ++ if (fseeko(U->fp, (off_t)0, SEEK_END) == -1) goto fail; } } @@ -360,10 +497,11 @@ + return NULL; + } /* we are not appending */ +- if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1) +#ifdef __LP64__ -+ if (fseeko(fp, -(off_t)sizeof(ut32), SEEK_CUR) == -1) ++ if (fseeko(U->fp, -(off_t)sizeof(ut32), SEEK_CUR) == -1) +#else /* __LP64__ */ - if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1) ++ if (fseeko(U->fp, -(off_t)sizeof(U->ut), SEEK_CUR) == -1) +#endif /* __LP64__ */ return NULL; } @@ -371,24 +509,25 @@ - if (fwrite(&temp, sizeof (temp), 1, fp) != 1) +#ifdef __LP64__ + _utmpx64_32(ux, &ut32); -+ if (fwrite(&ut32, sizeof (ut32), 1, fp) != 1) ++ if (fwrite(&ut32, sizeof (ut32), 1, U->fp) != 1) +#else /* __LP64__ */ -+ if (fwrite(ux, sizeof (*ux), 1, fp) != 1) ++ if (fwrite(ux, sizeof (*ux), 1, U->fp) != 1) +#endif /* __LP64__ */ goto fail; - if (fflush(fp) == -1) +- if (fflush(fp) == -1) ++ if (fflush(U->fp) == -1) goto fail; - u = memcpy(&ut, &temp, sizeof(ut)); -+ u = memcpy(&ut, ux, sizeof(ut)); ++ u = memcpy(&U->ut, ux, sizeof(U->ut)); + notify_post(UTMPX_CHANGE_NOTIFICATION); fail: if (gotlock) { - if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1) + int save = errno; + fl.l_type = F_UNLCK; -+ if (fcntl(fileno(fp), F_SETLK, &fl) == -1) ++ if (fcntl(fileno(U->fp), F_SETLK, &fl) == -1) return NULL; + errno = save; } @@ -411,7 +550,7 @@ - case 0: - (void)execl(_PATH_UTMP_UPDATE, - strrchr(_PATH_UTMP_UPDATE, '/') + 1, buf, NULL); -- exit(1); +- _exit(1); - /*NOTREACHED*/ - case -1: - return NULL; @@ -428,7 +567,7 @@ /* * The following are extensions and not part of the X/Open spec. */ - int +-int -updwtmpx(const char *file, const struct utmpx *utx) -{ - int fd; @@ -463,45 +602,64 @@ - - -int - utmpxname(const char *fname) +-utmpxname(const char *fname) ++__private_extern__ int ++__utmpxname(struct _utmpx *U, const char *fname) { size_t len; - _DIAGASSERT(fname != NULL); -+ UTMPX_LOCK; + if (fname == NULL) { -+ strcpy(utfile, _PATH_UTMPX); -+ utfile_system = 1; -+ _endutxent(); -+ UTMPX_UNLOCK; ++ if(!U->utfile_system) ++ free(U->utfile); ++ U->utfile = _PATH_UTMPX; ++ U->utfile_system = 1; ++ __endutxent(U); + return 1; + } len = strlen(fname); - if (len >= sizeof(utfile)) -+ if (len >= sizeof(utfile)) { -+ UTMPX_UNLOCK; ++ if (len >= MAXPATHLEN) return 0; -+ } /* must end in x! */ -- if (fname[len - 1] != 'x') -+ if (fname[len - 1] != 'x') { -+ UTMPX_UNLOCK; + if (fname[len - 1] != 'x') return 0; -+ } - (void)strlcpy(utfile, fname, sizeof(utfile)); +- (void)strlcpy(utfile, fname, sizeof(utfile)); - endutxent(); -+ _endutxent(); -+ utfile_system = 0; -+ UTMPX_UNLOCK; ++ if (U->utfile_system) ++ U->utfile = NULL; ++ U->utfile_system = 0; ++ if ((U->utfile = reallocf(U->utfile, len + 1)) == NULL) ++ return 0; ++ ++ (void)strcpy(U->utfile, fname); ++ __endutxent(U); return 1; } -- -+#ifdef LEGACY_UTMP_APIS ++int ++_utmpxname(struct _utmpx *U, const char *fname) ++{ ++ int ret; ++ ++ TEST_UTMPX_T("_utmpxname", U); ++ UTMPX_LOCK(U); ++ ret = __utmpxname(U, fname); ++ UTMPX_UNLOCK(U); ++ return ret; ++} ++ ++int ++utmpxname(const char *fname) ++{ ++ return _utmpxname(&__utx__, fname); ++} + ++#ifdef UNIFDEF_LEGACY_UTMP_APIS void getutmp(const struct utmpx *ux, struct utmp *u) { @@ -515,7 +673,7 @@ (void)memcpy(u->ut_line, ux->ut_line, sizeof(u->ut_line)); (void)memcpy(u->ut_host, ux->ut_host, sizeof(u->ut_host)); u->ut_time = ux->ut_tv.tv_sec; -@@ -384,109 +489,16 @@ void +@@ -369,82 +563,16 @@ void getutmpx(const struct utmp *u, struct utmpx *ux) { @@ -541,35 +699,8 @@ - ux->ut_exit.e_exit = 0; -} - --int --lastlogxname(const char *fname) --{ -- size_t len; -- -- _DIAGASSERT(fname != NULL); -- -- len = strlen(fname); -- -- if (len >= sizeof(llfile)) -- return 0; -- -- /* must end in x! */ -- if (fname[len - 1] != 'x') -- return 0; -- -- (void)strlcpy(llfile, fname, sizeof(llfile)); -- return 1; --} -- --struct lastlogx * --getlastlogx(uid_t uid, struct lastlogx *ll) --{ -- -- return __getlastlogx13(_PATH_LASTLOGX, uid, ll); --} -- -struct lastlogx * --__getlastlogx13(const char *fname, uid_t uid, struct lastlogx *ll) +-getlastlogx(const char *fname, uid_t uid, struct lastlogx *ll) -{ - DBT key, data; - DB *db; @@ -616,7 +747,7 @@ - _DIAGASSERT(fname != NULL); - _DIAGASSERT(ll != NULL); - -- db = dbopen(fname, O_RDWR|O_CREAT|O_EXLOCK, 0, DB_HASH, NULL); +- db = dbopen(fname, O_RDWR|O_CREAT|O_EXLOCK, 0644, DB_HASH, NULL); - - if (db == NULL) - return -1; @@ -631,4 +762,4 @@ - (db->close)(db); - return error; } -+#endif /* LEGACY_UTMP_APIS */ ++#endif /* UNIFDEF_LEGACY_UTMP_APIS */ diff --git a/gen/_simple.c b/gen/_simple.c index 381d997..8cde186 100644 --- a/gen/_simple.c +++ b/gen/_simple.c @@ -38,10 +38,15 @@ #include #include #include +#include +#include #include "_simple.h" +#ifndef VM_PAGE_SIZE #define VM_PAGE_SIZE 4096 +#endif + #define SBUF_SIZE(s) (((SBUF *)(s))->b.end - ((SBUF *)(s))->b.buf + 1) /* we use a small buffer to minimize stack usage constraints */ #define MYBUFSIZE 32 @@ -61,8 +66,10 @@ typedef struct _SBUF { #endif /* !VARIANT_DYLD */ } SBUF; -static int asl_socket; -static pthread_once_t asl_socket_once = PTHREAD_ONCE_INIT; +#define ASL_SERVICE_NAME "com.apple.system.logger" + +static mach_port_t asl_port; +static pthread_once_t asl_init_once = PTHREAD_ONCE_INIT; /* private extern exports from asl.c */ const char *_asl_escape(unsigned char); @@ -608,6 +615,7 @@ _simple_sfree(_SIMPLE_STRING b) { vm_size_t s; + if(b == NULL) return; if(((intptr_t)(((SBUF *)b)->b.buf) & (VM_PAGE_SIZE - 1)) == 0) { vm_deallocate(mach_task_self(), (vm_address_t)((SBUF *)b)->b.buf, SBUF_SIZE(b)); s = VM_PAGE_SIZE; @@ -620,95 +628,87 @@ _simple_sfree(_SIMPLE_STRING b) * Simplified ASL log interface; does not use malloc. Unfortunately, this * requires knowledge of the format used by ASL. */ + static void -socket_init(void) +_simple_asl_init(void) { - struct sockaddr_un server; + kern_return_t status; + char *str; - server.sun_family = AF_UNIX; - strncpy(server.sun_path, _PATH_LOG, sizeof(server.sun_path)); - asl_socket = socket(AF_UNIX, SOCK_DGRAM, 0); - if (asl_socket < 0) return; - - fcntl(asl_socket, F_SETFD, 1); - - if (connect(asl_socket, (struct sockaddr *)&server, sizeof(server)) == -1) + if (asl_port == MACH_PORT_NULL) { - close(asl_socket); - asl_socket = -1; + str = getenv("ASL_DISABLE"); + if ((str != NULL) && (!strcmp(str, "1"))) return; + + status = bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &asl_port); + if (status != KERN_SUCCESS) asl_port = MACH_PORT_NULL; } } void -_simple_asl_log(int level, const char *facility, const char *message) +_simple_asl_log_prog(int level, const char *facility, const char *message, const char *prog) { _SIMPLE_STRING b; - if(pthread_once(&asl_socket_once, socket_init) != 0) - return; - if((b = _simple_salloc()) == NULL) - return; - do { - char *cp, *bp; - unsigned u; - struct timeval tv; + if (pthread_once(&asl_init_once, _simple_asl_init) != 0) return; + if (asl_port == MACH_PORT_NULL) return; - if(_simple_sprintf(b, "%10u [Time ", 0)) - break; - gettimeofday(&tv, NULL); - if(_simple_esprintf(b, _asl_escape, "%lu", tv.tv_sec)) - break; - if(_simple_sappend(b, "] [Host] [Sender ")) - break; - if(_simple_esappend(b, _asl_escape, getprogname())) - break; - if(_simple_sappend(b, "] [PID ")) - break; - if(_simple_esprintf(b, _asl_escape, "%u", getpid())) - break; - if(_simple_sappend(b, "] [UID ")) - break; - if(_simple_esprintf(b, _asl_escape, "%d", getuid())) - break; - if(_simple_sappend(b, "] [GID ")) - break; - if(_simple_esprintf(b, _asl_escape, "%d", getgid())) - break; - if(_simple_sappend(b, "] [Level ")) - break; - if(_simple_esprintf(b, _asl_escape, "%d", level)) - break; - if(_simple_sappend(b, "] [Message ")) - break; - if(_simple_esappend(b, _asl_escape, message)) - break; - /* remove trailing (escaped) newlines */ - cp = _simple_string(b); - cp += strlen(cp); - for(;;) { - cp -= 2; - if(strcmp(cp, "\\n") != 0) - break; - *cp = 0; - } - _simple_sresize(b); - if(_simple_sappend(b, "] [Facility ")) - break; - if(_simple_esappend(b, _asl_escape, facility)) - break; - if(_simple_sappend(b, "]\n")) - break; - cp = _simple_string(b); - u = strlen(cp) - 10; // includes newline and null - bp = cp + 10; - if(u == 0) - *--bp = '0'; - else - while(bp > cp && u) { - *--bp = u % 10 + '0'; - u /= 10; - } - write(asl_socket, cp, strlen(cp) + 1); - } while(0); - _simple_sfree(b); + if ((b = _simple_salloc()) == NULL) return; + + do + { + kern_return_t kstatus; + vm_address_t out; + int outlen; + char *cp; + struct timeval tv; + + gettimeofday(&tv, NULL); + + if (_simple_sprintf(b, " 0 [Time ", 0)) break; + if (_simple_esprintf(b, _asl_escape, "%lu", tv.tv_sec)) break; + if (_simple_sappend(b, "] [Sender ")) break; + if (_simple_esappend(b, _asl_escape, prog)) break; + if (_simple_sappend(b, "] [Level ")) break; + if (_simple_esprintf(b, _asl_escape, "%d", level)) break; + if (_simple_sappend(b, "] [Facility ")) break; + if (_simple_esappend(b, _asl_escape, facility)) break; + if (_simple_sappend(b, "] [Message ")) break; + if (_simple_esappend(b, _asl_escape, message)) break; + + /* remove trailing (escaped) newlines */ + cp = _simple_string(b); + cp += strlen(cp); + for (;;) + { + cp -= 2; + if (strcmp(cp, "\\n") != 0) break; + *cp = 0; + } + + _simple_sresize(b); + + if (_simple_sappend(b, "]\n")) break; + + cp = _simple_string(b); + + /* + * The MIG defs for _asl_server_message specifies "dealloc", + * so we copy the string into a new vm buffer and send that. + */ + outlen = strlen(cp); + kstatus = vm_allocate(mach_task_self(), &out, outlen, TRUE); + if (kstatus != KERN_SUCCESS) break; + + memcpy((void *)out, cp, outlen); + _asl_server_message(asl_port, (caddr_t)out, outlen); + } while (0); + + _simple_sfree(b); +} + +void +_simple_asl_log(int level, const char *facility, const char *message) +{ + _simple_asl_log_prog(level, facility, message, getprogname()); } diff --git a/gen/_simple.h b/gen/_simple.h index 62182d5..db547df 100644 --- a/gen/_simple.h +++ b/gen/_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2006, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -127,3 +127,4 @@ void _simple_sfree(_SIMPLE_STRING __b); * requires knowledge of the format used by ASL. */ void _simple_asl_log(int __level, const char *__facility, const char *__message); +void _simple_asl_log_prog(int level, const char *facility, const char *message, const char *progname); diff --git a/gen/alarm.3 b/gen/alarm.3 index ed12c10..9826ce1 100644 --- a/gen/alarm.3 +++ b/gen/alarm.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)alarm.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/alarm.3,v 1.16 2002/12/18 13:33:02 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/alarm.3,v 1.17 2007/01/09 00:27:52 imp Exp $ .\" .Dd April 19, 1994 .Dt ALARM 3 diff --git a/gen/arc4random-fbsd.c b/gen/arc4random-fbsd.c index 4728787..869effa 100644 --- a/gen/arc4random-fbsd.c +++ b/gen/arc4random-fbsd.c @@ -1,14 +1,23 @@ /* - * Arc4 random number generator for OpenBSD. - * Copyright 1996 David Mazieres . + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * Modification and redistribution in source and binary forms is - * permitted provided that due credit is given to the author and the - * OpenBSD project (for instance by leaving this copyright notice - * intact). + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* + * Arc4 random number generator for OpenBSD. + * * This code is derived from section 17.1 of Applied Cryptography, * second edition, which describes a stream cipher allegedly * compatible with RSA Labs "RC4" cipher (the actual description of @@ -24,7 +33,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.10 2004/03/24 14:44:57 green Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.25 2008/09/09 09:46:36 ache Exp $"); #include "namespace.h" #include @@ -43,81 +52,111 @@ struct arc4_stream { u_int8_t s[256]; }; -static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +static int lock = 0; +extern void spin_lock(int*); +extern void spin_unlock(int*); -#define RANDOMDEV "/dev/urandom" +#define RANDOMDEV "/dev/random" +#define KEYSIZE 128 #define THREAD_LOCK() \ do { \ if (__isthreaded) \ - _pthread_mutex_lock(&arc4random_mtx); \ + spin_lock(&lock); \ } while (0) #define THREAD_UNLOCK() \ do { \ if (__isthreaded) \ - _pthread_mutex_unlock(&arc4random_mtx); \ + spin_unlock(&lock); \ } while (0) -static struct arc4_stream rs; +static struct arc4_stream rs = { + .i = 0, + .j = 0, + .s = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + } +}; static int rs_initialized; static int rs_stired; +static int arc4_count; -static inline u_int8_t arc4_getbyte(struct arc4_stream *); -static void arc4_stir(struct arc4_stream *); +static inline u_int8_t arc4_getbyte(void); +static void arc4_stir(void); -static inline void -arc4_init(as) - struct arc4_stream *as; -{ - int n; - - for (n = 0; n < 256; n++) - as->s[n] = n; - as->i = 0; - as->j = 0; -} +static struct { + struct timeval tv; + pid_t pid; + u_int8_t rnd[KEYSIZE]; +} rdat; +static volatile int rs_data_available = 0; static inline void -arc4_addrandom(as, dat, datlen) - struct arc4_stream *as; - u_char *dat; - int datlen; +arc4_addrandom(u_char *dat, int datlen) { int n; u_int8_t si; - as->i--; + rs.i--; for (n = 0; n < 256; n++) { - as->i = (as->i + 1); - si = as->s[as->i]; - as->j = (as->j + si + dat[n % datlen]); - as->s[as->i] = as->s[as->j]; - as->s[as->j] = si; + rs.i = (rs.i + 1); + si = rs.s[rs.i]; + rs.j = (rs.j + si + dat[n % datlen]); + rs.s[rs.i] = rs.s[rs.j]; + rs.s[rs.j] = si; } + rs.j = rs.i; } static void -arc4_stir(as) - struct arc4_stream *as; +arc4_fetch(void) { - int fd, n; - struct { - struct timeval tv; - pid_t pid; - u_int8_t rnd[128 - sizeof(struct timeval) - sizeof(pid_t)]; - } rdat; - - gettimeofday(&rdat.tv, NULL); - rdat.pid = getpid(); + int done, fd; fd = _open(RANDOMDEV, O_RDONLY, 0); + done = 0; if (fd >= 0) { - (void) _read(fd, rdat.rnd, sizeof(rdat.rnd)); - _close(fd); + if (_read(fd, &rdat, KEYSIZE) == KEYSIZE) + done = 1; + (void)_close(fd); } - /* fd < 0? Ah, what the heck. We'll just take whatever was on the - * stack... */ + if (!done) { + (void)gettimeofday(&rdat.tv, NULL); + rdat.pid = getpid(); + /* We'll just take whatever was on the stack too... */ + } +} - arc4_addrandom(as, (u_char *) &rdat, sizeof(rdat)); +static void +arc4_stir(void) +{ + int n; + /* + * If we don't have data, we need some now before we can integrate + * it into the static buffers + */ + if (!rs_data_available) + { + arc4_fetch(); + } + rs_data_available = 0; + __sync_synchronize(); + + arc4_addrandom((u_char *)&rdat, KEYSIZE); /* * Throw away the first N bytes of output, as suggested in the @@ -127,92 +166,169 @@ arc4_stir(as) * by Ilya Mironov. */ for (n = 0; n < 1024; n++) - arc4_getbyte(as); + (void) arc4_getbyte(); + arc4_count = 1600000; + rs_stired = 1; } static inline u_int8_t -arc4_getbyte(as) - struct arc4_stream *as; +arc4_getbyte(void) { u_int8_t si, sj; - as->i = (as->i + 1); - si = as->s[as->i]; - as->j = (as->j + si); - sj = as->s[as->j]; - as->s[as->i] = sj; - as->s[as->j] = si; + rs.i = (rs.i + 1); + si = rs.s[rs.i]; + rs.j = (rs.j + si); + sj = rs.s[rs.j]; + rs.s[rs.i] = sj; + rs.s[rs.j] = si; - return (as->s[(si + sj) & 0xff]); + return (rs.s[(si + sj) & 0xff]); } static inline u_int32_t -arc4_getword(as) - struct arc4_stream *as; +arc4_getword(void) { u_int32_t val; - val = arc4_getbyte(as) << 24; - val |= arc4_getbyte(as) << 16; - val |= arc4_getbyte(as) << 8; - val |= arc4_getbyte(as); + val = arc4_getbyte() << 24; + val |= arc4_getbyte() << 16; + val |= arc4_getbyte() << 8; + val |= arc4_getbyte(); return (val); } -static void -arc4_check_init(void) +/* 7944700: force restir in child */ +__private_extern__ void +_arc4_fork_child(void) { - if (!rs_initialized) { - arc4_init(&rs); - rs_initialized = 1; - } + rs_stired = 0; + rs_data_available = 0; } -static void +static inline int arc4_check_stir(void) { - if (!rs_stired) { - arc4_stir(&rs); - rs_stired = 1; + if (!rs_stired || arc4_count <= 0) { + arc4_stir(); + return 1; } + return 0; } void -arc4random_stir() +arc4random_stir(void) { THREAD_LOCK(); - arc4_check_init(); - arc4_stir(&rs); + arc4_stir(); THREAD_UNLOCK(); } void -arc4random_addrandom(dat, datlen) - u_char *dat; - int datlen; +arc4random_addrandom(u_char *dat, int datlen) { THREAD_LOCK(); - arc4_check_init(); arc4_check_stir(); - arc4_addrandom(&rs, dat, datlen); + arc4_addrandom(dat, datlen); THREAD_UNLOCK(); } u_int32_t -arc4random() +arc4random(void) { u_int32_t rnd; THREAD_LOCK(); - arc4_check_init(); - arc4_check_stir(); - rnd = arc4_getword(&rs); + + int did_stir = arc4_check_stir(); + rnd = arc4_getword(); + arc4_count -= 4; + THREAD_UNLOCK(); + if (did_stir) + { + /* stirring used up our data pool, we need to read in new data outside of the lock */ + arc4_fetch(); + rs_data_available = 1; + __sync_synchronize(); + } return (rnd); } +void +arc4random_buf(void *_buf, size_t n) +{ + u_char *buf = (u_char *)_buf; + int did_stir = 0; + + THREAD_LOCK(); + + while (n--) { + if (arc4_check_stir()) + { + did_stir = 1; + } + buf[n] = arc4_getbyte(); + arc4_count--; + } + + THREAD_UNLOCK(); + if (did_stir) + { + /* stirring used up our data pool, we need to read in new data outside of the lock */ + arc4_fetch(); + rs_data_available = 1; + __sync_synchronize(); + } +} + +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +u_int32_t +arc4random_uniform(u_int32_t upper_bound) +{ + u_int32_t r, min; + + if (upper_bound < 2) + return (0); + +#if (ULONG_MAX > 0xffffffffUL) + min = 0x100000000UL % upper_bound; +#else + /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ + if (upper_bound > 0x80000000) + min = 1 + ~upper_bound; /* 2**32 - upper_bound */ + else { + /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ + min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound; + } +#endif + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = arc4random(); + if (r >= min) + break; + } + + return (r % upper_bound); +} + #if 0 /*-------- Test code for i386 --------*/ #include diff --git a/gen/asl.3 b/gen/asl.3 index a63af6b..e3b9943 100644 --- a/gen/asl.3 +++ b/gen/asl.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2005-2007 Apple Inc. +.\" Copyright (c) 2005-2010 Apple Inc. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -26,18 +26,22 @@ .\" SUCH DAMAGE. .\" .\" -.Dd January 11, 2007 +.Dd March 3, 2010 .Dt asl 3 .Os "Mac OS X" .Sh NAME .Nm asl_add_log_file , .Nm asl_close , +.Nm asl_close_auxiliary_file , +.Nm asl_create_auxiliary_file , .Nm asl_free , .Nm asl_get , .Nm asl_key , .Nm asl_log , +.Nm asl_log_auxiliary_location , .Nm asl_new , .Nm asl_open , +.Nm asl_open_from_file , .Nm asl_remove_log_file , .Nm asl_search , .Nm asl_send , @@ -62,6 +66,17 @@ .Fa "aslclient asl" .Fc .Ft void +.Fo asl_close_auxiliary_file +.Fa "int fd" +.Fc +.Ft void +.Fo asl_create_auxiliary_file +.Fa "aslmsg msg" +.Fa "const char *title" +.Fa "const char *uti" +.Fa "int *out_fd" +.Fc +.Ft void .Fo asl_free .Fa "aslmsg msg" .Fc @@ -83,6 +98,13 @@ .Fa "const char *format" .Fa "..." .Fc +.Ft void +.Fo asl_log_auxiliary_location +.Fa "aslmsg msg" +.Fa "const char *title" +.Fa "const char *uti" +.Fa "const char *url" +.Fc .Ft aslmsg .Fo asl_new .Fa "uint32_t type" @@ -93,6 +115,12 @@ .Fa "const char *facility" .Fa "uint32_t opts" .Fc +.Ft aslclient +.Fo asl_open_from_file +.Fa "int fd" +.Fa "const char *ident" +.Fa "const char *facility" +.Fc .Ft int .Fo asl_remove_log_file .Fa "aslclient asl" @@ -171,9 +199,9 @@ An introduction to the concepts underlying this interface follows the interface creates and returns a client handle, or NULL if an error occurs in the library. Messages sent using this handle will default to having the string .Ar ident -as the value assocated with the ASL_KEY_SENDER key, and the value +as the value associated with the ASL_KEY_SENDER key, and the value .Ar facility -assocated with the ASL_KEY_FACILITY key. +associated with the ASL_KEY_FACILITY key. Several options are available, as described in the .Sx CLIENT HANDLES section. @@ -375,6 +403,120 @@ Returns NULL when there are no further messages. frees the aslresponse structure .Ar r and all of its associated resources. +.Pp +.Fo asl_create_auxiliary_file +.Fa msg +.Fa title +.Fa uti +.Fa out_fd +.Fc +Creates an auxiliary file that may be used by the client to save arbitrary data. +When the file is closed using +.Fo asl_close_auxiliary_file +.Fc , +.Nm syslogd +will log the specified +.Fa msg +along with the +.Fa title +and the Uniform Type Identifier provided by +.Fa uti . +If a NULL value is supplied for +.Fa uti +the type +.Dq public.data +will be used. +The +.Nm Console +application will display the message with a link to the file. +.Pp +Auxiliary files are saved in the ASL data store. +They are automatically deleted at the same time that the log message expires. +Messages expire in 7 days by default. +A value set for the ASLExpireTime key will override the default. +Read access for the auxiliary file will be the same as read access for +.Fa msg . +By default, messages (and auxiliary files) are world-readable. +Access may be limited by setting values for the ReadUID and ReadGID keys. +.Pp +.Fo asl_close_auxiliary_file +.Fa fd +.Fc +closes the file descriptor +.Ar fd +previously returned by a call to +.Fn asl_create_auxiliary_file . +.Pp +.Fo asl_log_auxiliary_location +.Fa msg +.Fa title +.Fa uti +.Fa url +.Fc +will log the specified +.Fa msg +along with the +.Fa title , +the Uniform Type Identifier provided by +.Fa uti , +and the Uniform Resource Locator provided by +.Fa url . +The +.Nm Console +application will display the message with a link to the file. +This allows a client to save data in an auxiliary file, but unlike +.Fo asl_create_auxiliary_file +.Fc , +the life-cycle of this file must be managed by some external system. +The file will not be removed when the corresponding log message expired from the ASL data store. +.Pp +.Fo asl_open_from_file +.Fa fd +.Fa facility +.Fa opts +.Fc +creates a client handle for an open file descriptor +.Fa fd . +This routine may be used in conjunction with +.Fo asl_create_auxiliary_file +.Fc +or +.Fo asl_log_auxiliary_location +.Fc +to save ASL format log messages in an auxiliary file. +The UTI type +.Dq com.apple.asl-file +should be used for ASL format auxiliary files. +.Pp +Files with this format may be read from the command line using +.Nm syslog Fl f Ar file , +or from the +.Nm Console +utility. +.Pp +The file must be open for read and write access. +The file will be truncated and its existing contents will be lost. +.Fo asl_close +.Fc +must be called to close the client handle when logging to this file is complete. +The file should be closed using +.Fo asl_close_auxiliary_file +.Fc +if it was returned by +.Fo asl_create_auxiliary_file +.Fc , +or +.Fo close +.Fc +otherwise. +.Pp +The client handle may be used safely by multiple threads. +The threads will contend for a single internal lock when saving log messages to a file. +.Pp +Note that messages with ReadUID or ReadGID values will simply be saved to the file, +and will not effect read access to either the message or the file itself. +Similarly, messages with ASLExpireTime values will be saved, but will not effect the +life-cycle of either the individual messages or the file. .Ss MESSAGES At the core of this API is the aslmsg structure. Although the structure is opaque and may not be directly manipulated, diff --git a/gen/asl.c b/gen/asl.c index c73124f..9da9315 100644 --- a/gen/asl.c +++ b/gen/asl.c @@ -1,23 +1,22 @@ /* - * Copyright (c) 2004-2008 Apple Inc. All rights reserved. + * Copyright (c) 2004-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 2004 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -31,12 +30,12 @@ #include #include #include +#include #include #include +#include #include #include -#include -#include #include #include #include @@ -46,67 +45,45 @@ #include #include #include -#include "asl_core.h" +#include #include +#include "asl_core.h" +#include "asl_msg.h" +#include "asl_store.h" +#include "asl_private.h" #define streq(A, B) (strcmp(A, B) == 0) #define strcaseeq(A, B) (strcasecmp(A, B) == 0) -#ifndef ASL_QUERY_OP_FALSE -#define ASL_QUERY_OP_FALSE 0 -#endif - #define forever for(;;) -#define TOKEN_NULL 0 -#define TOKEN_OPEN 1 -#define TOKEN_CLOSE 2 -#define TOKEN_WORD 3 -#define TOKEN_INT 4 - -#define MFMT_RAW 0 -#define MFMT_STD 1 -#define MFMT_BSD 2 -#define MFMT_XML 3 -#define MFMT_STR 4 -#define MFMT_MSG 5 - -#define TFMT_SEC 0 -#define TFMT_UTC 1 -#define TFMT_LCL 2 - -#define XML_TAG_KEY 0 -#define XML_TAG_STRING 1 -#define XML_TAG_DATA 2 - #define FETCH_BATCH 256 /* forward */ time_t asl_parse_time(const char *); const char *asl_syslog_faciliy_num_to_name(int n); +__private_extern__ int _asl_send_message(aslclient ac, asl_msg_t *msg, int slevel, const char *aux_message); __private_extern__ asl_client_t *_asl_open_default(); -__private_extern__ int _asl_send_level_message(aslclient ac, aslmsg msg, int level, const char *message); + +/* private asl_msg SPI */ +__private_extern__ uint32_t _asl_msg_string_length_aux(asl_msg_t *msg, asl_msg_aux_t *aux); +__private_extern__ uint32_t _asl_msg_to_string_buffer_aux(asl_msg_t *msg, asl_msg_aux_t *aux, char *buf, uint32_t bufsize); + +/* private asl_file SPI */ +__private_extern__ uint32_t asl_file_open_write_fd(int fd, asl_file_t **s); /* notify SPI */ uint32_t notify_register_plain(const char *name, int *out_token); -/* from asl_util.c */ -int asl_is_utf8(const char *str); -uint8_t *asl_b64_encode(const uint8_t *buf, size_t len); - /* fork handling in syslog.c */ extern void _syslog_fork_child(); -/* character encoding lengths */ -static const uint8_t char_encode_len[128] = +typedef struct { - 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 -}; - -static const char *cvis_7_13 = "abtnvfr"; + int fd; + asl_msg_t *msg; + dispatch_semaphore_t sem; +} asl_aux_context_t; typedef struct { @@ -116,16 +93,18 @@ typedef struct int master_token; uint64_t proc_filter; uint64_t master_filter; - int port_count; + dispatch_once_t port_lookup_once; mach_port_t server_port; char *sender; pthread_mutex_t lock; - pthread_mutex_t port_lock; + int aux_count; + asl_aux_context_t **aux_ctx; asl_client_t *asl; } _asl_global_t; + #ifndef BUILDING_VARIANT -__private_extern__ _asl_global_t _asl_global = {0, -1, -1, -1, 0LL, 0LL, 0, MACH_PORT_NULL, NULL, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, NULL}; +__private_extern__ _asl_global_t _asl_global = {0, -1, -1, -1, 0LL, 0LL, 0, MACH_PORT_NULL, NULL, PTHREAD_MUTEX_INITIALIZER, 0, NULL, NULL}; #define ASL_SERVICE_NAME "com.apple.system.logger" @@ -143,11 +122,25 @@ _asl_fork_child() _asl_global.master_token = -1; _asl_global.notify_token = -1; - _asl_global.port_count = 0; + _asl_global.port_lookup_once = 0; _asl_global.server_port = MACH_PORT_NULL; +} + +/* + * asl_remote_notify_name: returns the notification key for remote-control filter + * changes for this process. + */ +char * +asl_remote_notify_name() +{ + pid_t pid = getpid(); + uid_t euid = geteuid(); + char *str = NULL; - /* clean up in syslog.c */ - _syslog_fork_child(); + if (euid == 0) asprintf(&str, "%s.%d", NOTIFY_PREFIX_SYSTEM, pid); + else asprintf(&str, "user.uid.%d.syslog.%d", euid, pid); + + return str; } static int @@ -155,7 +148,6 @@ _asl_notify_open(int do_lock) { char *notify_name; uint32_t status; - uint32_t euid; if (do_lock != 0) pthread_mutex_lock(&_asl_global.lock); @@ -179,11 +171,7 @@ _asl_notify_open(int do_lock) if (status != NOTIFY_STATUS_OK) _asl_global.master_token = -1; } - euid = geteuid(); - notify_name = NULL; - if (euid == 0) asprintf(¬ify_name, "%s.%d", NOTIFY_PREFIX_SYSTEM, getpid()); - else asprintf(¬ify_name, "user.uid.%d.syslog.%d", euid, getpid()); - + notify_name = asl_remote_notify_name(); if (notify_name != NULL) { status = notify_register_plain(notify_name, &_asl_global.notify_token); @@ -210,54 +198,28 @@ _asl_notify_close() return; } - if (_asl_global.rc_change_token > 0) notify_cancel(_asl_global.rc_change_token); + if (_asl_global.rc_change_token >= 0) notify_cancel(_asl_global.rc_change_token); _asl_global.rc_change_token = -1; - if (_asl_global.master_token > 0) notify_cancel(_asl_global.master_token); + if (_asl_global.master_token >= 0) notify_cancel(_asl_global.master_token); _asl_global.master_token = -1; - if (_asl_global.notify_token > 0) notify_cancel(_asl_global.notify_token); + if (_asl_global.notify_token >= 0) notify_cancel(_asl_global.notify_token); _asl_global.notify_token = -1; pthread_mutex_unlock(&_asl_global.lock); } static void -_asl_get_global_server_port() -{ - kern_return_t kstatus; - - pthread_mutex_lock(&(_asl_global.port_lock)); - - if (_asl_global.server_port == MACH_PORT_NULL) - { - _asl_global.port_count = 0; - - kstatus = bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &_asl_global.server_port); - if (kstatus == KERN_SUCCESS) _asl_global.port_count = 1; - else _asl_global.server_port = MACH_PORT_NULL; - } - else - { - _asl_global.port_count++; - } - - pthread_mutex_unlock(&(_asl_global.port_lock)); -} - -static void -_asl_release_global_server_port() +_asl_global_init() { - pthread_mutex_lock(&(_asl_global.port_lock)); - - if (_asl_global.port_count > 0) _asl_global.port_count--; - if (_asl_global.port_count == 0) - { - mach_port_deallocate(mach_task_self(), _asl_global.server_port); - _asl_global.server_port = MACH_PORT_NULL; - } - - pthread_mutex_unlock(&(_asl_global.port_lock)); + dispatch_once(&_asl_global.port_lookup_once, ^{ + char *str = getenv("ASL_DISABLE"); + if ((str == NULL) || strcmp(str, "1")) + { + bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &_asl_global.server_port); + } + }); } aslclient @@ -277,7 +239,7 @@ asl_open(const char *ident, const char *facility, uint32_t opts) asl->sock = -1; - _asl_get_global_server_port(); + _asl_global_init(); asl->pid = getpid(); asl->uid = getuid(); @@ -319,6 +281,7 @@ asl_open(const char *ident, const char *facility, uint32_t opts) if (asl->facility == NULL) { if (asl->sock >= 0) close(asl->sock); + if (asl->name != NULL) free(asl->name); free(asl); return NULL; } @@ -330,1585 +293,134 @@ asl_open(const char *ident, const char *facility, uint32_t opts) return (aslclient)asl; } -void -asl_close(aslclient ac) +aslclient +asl_open_from_file(int fd, const char *ident, const char *facility) { + char *name, *x; asl_client_t *asl; - uint32_t i; - - asl = (asl_client_t *)ac; - if (asl == NULL) return; - - if (asl->sock >= 0) close(asl->sock); - - pthread_mutex_lock(&(_asl_global.port_lock)); - - if (_asl_global.port_count > 0) _asl_global.port_count--; - if (_asl_global.port_count == 0) - { - mach_port_deallocate(mach_task_self(), _asl_global.server_port); - _asl_global.server_port = MACH_PORT_NULL; - } - - pthread_mutex_unlock(&(_asl_global.port_lock)); - - if (asl->name != NULL) free(asl->name); - if (asl->facility != NULL) free(asl->facility); - if (!(asl->options & ASL_OPT_NO_REMOTE)) _asl_notify_close(); - if (asl->fd_list != NULL) free(asl->fd_list); - - if (asl->fd_mfmt != NULL) - { - for (i = 0; i < asl->fd_count; i++) if (asl->fd_mfmt[i] != NULL) free(asl->fd_mfmt[i]); - free(asl->fd_mfmt); - } - - if (asl->fd_tfmt != NULL) - { - for (i = 0; i < asl->fd_count; i++) if (asl->fd_tfmt[i] != NULL) free(asl->fd_tfmt[i]); - free(asl->fd_tfmt); - } - - if (asl->fd_encoding != NULL) free(asl->fd_encoding); - - memset(asl, 0, sizeof(asl_client_t)); - free(asl); -} - -__private_extern__ asl_client_t * -_asl_open_default() -{ - if (_asl_global.asl != NULL) return _asl_global.asl; - - pthread_mutex_lock(&_asl_global.lock); - if (_asl_global.asl != NULL) - { - pthread_mutex_unlock(&_asl_global.lock); - return _asl_global.asl; - } - - /* - * Do a sleight-of-hand with ASL_OPT_NO_REMOTE to avoid a deadlock - * since asl_open(xxx, yyy, 0) calls _asl_notify_open(1) - * which locks _asl_global.lock. - */ - _asl_global.asl = asl_open(NULL, NULL, ASL_OPT_NO_REMOTE); - - /* Reset options to clear ASL_OPT_NO_REMOTE bit */ - if (_asl_global.asl != NULL) _asl_global.asl->options = 0; - - /* Now call _asl_notify_open(0) to finish the work */ - _asl_notify_open(0); - - pthread_mutex_unlock(&_asl_global.lock); - - return _asl_global.asl; -} - -static uint32_t -_asl_msg_index(asl_msg_t *msg, const char *k) -{ - uint32_t i; - - if (msg == NULL) return (uint32_t)-1; - if (k == NULL) return (uint32_t)-1; + uint32_t status; - for (i = 0; i < msg->count; i++) + asl = (asl_client_t *)calloc(1, sizeof(asl_client_t)); + if (asl == NULL) { - if (msg->key[i] == NULL) continue; - if (streq(msg->key[i], k)) return i; + errno = ENOMEM; + return NULL; } - return (uint32_t)-1; -} - -static void -_asl_encode_char(char **m, uint32_t *x, uint32_t c, uint32_t encode, uint32_t encode_space) -{ - char *p; - int meta; - - meta = 0; - - p = *m + *x - 1; - - /* NUL is not allowed */ - if (c == 0) return; + asl->options = ASL_OPT_NO_REMOTE; + asl->sock = -1; - /* Meta chars get \M prefix */ - if (c >= 128) - { - /* except meta-space, which is \240 */ - if (c == 160) - { - *p++ = '\\'; - *p++ = '2'; - *p++ = '4'; - *p++ = '0'; - *p = '\0'; - *x = *x + 4; - return; - } + asl->pid = getpid(); + asl->uid = getuid(); + asl->gid = getgid(); - *p++ = '\\'; - *p++ = 'M'; - *p = '\0'; - *x = *x + 2; - c &= 0x7f; - meta = 1; - } + asl->filter = ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG); - /* space is either ' ' or \s */ - if (c == 32) + if (ident != NULL) { - if (encode_space == 0) + asl->name = strdup(ident); + if (asl->name == NULL) { - *p++ = ' '; - *p = '\0'; - *x = *x + 1; - return; + free(asl); + return NULL; } - - *p++ = '\\'; - *p++ = 's'; - *p = '\0'; - *x = *x + 2; - return; - } - - /* \ is escaped */ - if ((meta == 0) && (c == 92)) - { - *p++ = '\\'; - *p++ = c; - *p = '\0'; - *x = *x + 2; - return; - } - - /* [ and ] are escaped in ASL encoding */ - if ((encode == ASL_ENCODE_ASL) && (meta == 0) && ((c == 91) || (c == 93))) - { - *p++ = '\\'; - *p++ = c; - *p = '\0'; - *x = *x + 2; - return; } - - /* DEL is \^? */ - if (c == 127) + else { - if (meta == 0) + name = *(*_NSGetArgv()); + if (name != NULL) { - *p++ = '\\'; - *x = *x + 1; + x = strrchr(name, '/'); + if (x != NULL) x++; + else x = name; + asl->name = strdup(x); + if (asl->name == NULL) + { + free(asl); + return NULL; + } } - - *p++ = '^'; - *p++ = '?'; - *p = '\0'; - *x = *x + 2; - return; } - /* 33-126 are printable (add a '-' prefix for meta) */ - if ((c >= 33) && (c <= 126)) + asl->facility = NULL; + if (facility != NULL) asl->facility = strdup(facility); + else asl->facility = strdup(asl_syslog_faciliy_num_to_name(LOG_USER)); + if (asl->facility == NULL) { - if (meta == 1) - { - *p++ = '-'; - *x = *x + 1; - } - - *p++ = c; - *p = '\0'; - *x = *x + 1; - return; + if (asl->name != NULL) free(asl->name); + free(asl); + return NULL; } - /* non-meta BEL, BS, HT, NL, VT, NP, CR (7-13) are \a, \b, \t, \n, \v, \f, and \r */ - if ((meta == 0) && (c >= 7) && (c <= 13)) + status = asl_file_open_write_fd(fd, &(asl->aslfile)); + if (status != ASL_STATUS_OK) { - *p++ = '\\'; - *p++ = cvis_7_13[c - 7]; - *p = '\0'; - *x = *x + 2; - return; + if (asl->name != NULL) free(asl->name); + if (asl->facility != NULL) free(asl->facility); + free(asl); + return NULL; } - /* 0 - 31 are ^@ - ^_ (non-meta get a leading \) */ - if ((c >= 0) && (c <= 31)) - { - if (meta == 0) - { - *p++ = '\\'; - *x = *x + 1; - } - - *p++ = '^'; - *p++ = 64 + c; - *p = '\0'; - *x = *x + 2; - return; - } + asl->aslfileid = 1; - return; + return (aslclient)asl; } -static void -_asl_append_string(char **m, uint32_t *x, const char *s, uint32_t encode, uint32_t escspace) +void +asl_close(aslclient ac) { - uint32_t i, n, spextra; - uint8_t c; - char *p; - - if (m == NULL) return; - if (x == NULL) return; - if (s == NULL) return; - - if (encode == ASL_ENCODE_NONE) - { - /* no encoding - just allocate enough space and copy the string */ - - n = strlen(s); - if (n == 0) return; - - if (*m == NULL) - { - *m = malloc(n + 1); - *x = 1; - } - else - { - *m = reallocf(*m, n + (*x)); - } - - if (*m == NULL) return; - - memcpy((*m) + (*x) - 1, s, n + 1); - *x += n; - - return; - } - else if (encode == ASL_ENCODE_SAFE) - { - /* - * Minor encoding to reduce the likelyhood of spoof attacks. - * - * - append a tab after newlines - * - translate \r to newline & append a tab - * - map backspace to ^H - * - * Note that there may be UTF-8 characters that could be used in a spoof - * attack that we don't check. Caveat Reador. - */ - n = 0; - for (i = 0; s[i] != '\0'; i++) - { - n++; - c = s[i]; - if ((c == 10) || (c == 13) || (c == 8)) n++; - } - - if (n == 0) return; - - if (*m == NULL) - { - *m = malloc(n + 1); - *x = 1; - } - else - { - *m = reallocf(*m, n + (*x)); - } - - if (*m == NULL) return; - - p = *m + *x - 1; - - for (i = 0; s[i] != '\0'; i++) - { - c = s[i]; - if ((c == 10) || (c == 13)) - { - *p++ = '\n'; - *p++ = '\t'; - *x = *x + 2; - } - else if (c == 8) - { - *p++ = '^'; - *p++ = 'H'; - *x = *x + 2; - } - else - { - *p++ = c; - *x = *x + 1; - } - } - - return; - } - - spextra = 0; - - if (escspace != 0) spextra = 1; - - n = 0; - for (i = 0; s[i] != '\0'; i++) - { - c = s[i]; - - if (c >= 128) - { - n += 4; - } - else if ((c == 91) || (c == 93)) - { - if (encode == ASL_ENCODE_ASL) n += 2; - else n += 1; - } - else - { - n += char_encode_len[c]; - if (c == 32) n += spextra; - } - } + asl_client_t *asl; + uint32_t i; - if (n == 0) return; + asl = (asl_client_t *)ac; + if (asl == NULL) return; - if (*m == NULL) - { - *m = malloc(n + 1); - *x = 1; - } - else - { - *m = reallocf(*m, n + (*x)); - } + free(asl->name); + free(asl->facility); - if (*m == NULL) return; + if (asl->sock >= 0) close(asl->sock); + if (!(asl->options & ASL_OPT_NO_REMOTE)) _asl_notify_close(); + if (asl->fd_list != NULL) free(asl->fd_list); - for (i = 0; s[i] != '\0'; i++) + if (asl->fd_mfmt != NULL) { - c = s[i]; - _asl_encode_char(m, x, c, encode, escspace); - } - - return; -} - -static void -_asl_append_xml_string(char **m, uint32_t *x, char *s) -{ - uint32_t i, n; - uint8_t c; - char tmp[8], *p; - - if (m == NULL) return; - if (x == NULL) return; - if (s == NULL) return; - - n = 0; - for (i = 0; s[i] != '\0'; i++) - { - c = s[i]; - - /* - * XML wants & < > " and ' - * We use &#xnn; for control chars. - * Everything else just gets printed "as is" (we know the input is UTF8) - */ - if (c == '&') n += 5; - else if (c == '<') n += 4; - else if (c == '>') n += 4; - else if (c == '"') n += 6; - else if (c == '\'') n += 6; - else if (iscntrl(c)) n += 6; - else n += 1; - } - - if (n == 0) return; - - if (*m == NULL) - { - *m = malloc(n + 1); - *x = 1; - } - else - { - *m = reallocf(*m, n + (*x)); - } - - if (*m == NULL) return; - - for (i = 0; s[i] != '\0'; i++) - { - c = s[i]; - - if (c == '&') - { - p = *m + *x - 1; - memcpy(p, "&", 5); - p += 5; - *p = '\0'; - *x = *x + 5; - } - else if (c == '<') - { - p = *m + *x - 1; - memcpy(p, "<", 4); - p += 4; - *p = '\0'; - *x = *x + 4; - } - else if (c == '>') - { - p = *m + *x - 1; - memcpy(p, ">", 4); - p += 4; - *p = '\0'; - *x = *x + 4; - } - else if (c == '"') - { - p = *m + *x - 1; - memcpy(p, """, 6); - p += 6; - *p = '\0'; - *x = *x + 6; - } - else if (c == '\'') - { - p = *m + *x - 1; - memcpy(p, "'", 6); - p += 6; - *p = '\0'; - *x = *x + 6; - } - else if (iscntrl(c)) - { - snprintf(tmp, sizeof(tmp), "&#x%02hhu;", c); - p = *m + *x - 1; - memcpy(p, tmp, 6); - p += 6; - *p = '\0'; - *x = *x + 6; - } - else - { - p = *m + *x - 1; - *p++ = c; - *p = '\0'; - *x = *x + 1; - } - } - - return; -} - -static void -_asl_append_xml_tag(char **m, uint32_t *x, int tag, char *s) -{ - char *b64; - - if (m == NULL) return; - if (x == NULL) return; - - if (tag == XML_TAG_KEY) - { - _asl_append_string(m, x, "\t\t", ASL_ENCODE_NONE, 0); - _asl_append_xml_string(m, x, s); - _asl_append_string(m, x, "\n", ASL_ENCODE_NONE, 0); - return; - } - - if (tag == XML_TAG_STRING) - { - _asl_append_string(m, x, "\t\t", ASL_ENCODE_NONE, 0); - _asl_append_xml_string(m, x, s); - _asl_append_string(m, x, "\n", ASL_ENCODE_NONE, 0); - return; - } - - if (tag == XML_TAG_DATA) - { - _asl_append_string(m, x, "\t\t", ASL_ENCODE_NONE, 0); - b64 = (char *)asl_b64_encode((uint8_t *)s, strlen(s)); - if (b64 != NULL) - { - _asl_append_string(m, x, b64, ASL_ENCODE_NONE, 0); - free(b64); - } - _asl_append_string(m, x, "\n", ASL_ENCODE_NONE, 0); - return; - } -} - -static void -_asl_append_op(char **m, uint32_t *x, uint32_t op) -{ - char opstr[8]; - uint32_t i; - - if (m == NULL) return; - if (x == NULL) return; - - if (op == ASL_QUERY_OP_NULL) return _asl_append_string(m, x, ".", ASL_ENCODE_NONE, 0); - - i = 0; - if (op & ASL_QUERY_OP_CASEFOLD) opstr[i++] = 'C'; - - if (op & ASL_QUERY_OP_REGEX) opstr[i++] = 'R'; - - if (op & ASL_QUERY_OP_NUMERIC) opstr[i++] = 'N'; - - if (op & ASL_QUERY_OP_PREFIX) - { - if (op & ASL_QUERY_OP_SUFFIX) opstr[i++] = 'S'; - else opstr[i++] = 'A'; - } - if (op & ASL_QUERY_OP_SUFFIX) opstr[i++] = 'Z'; - - switch (op & ASL_QUERY_OP_TRUE) - { - case ASL_QUERY_OP_EQUAL: - opstr[i++] = '='; - break; - case ASL_QUERY_OP_GREATER: - opstr[i++] = '>'; - break; - case ASL_QUERY_OP_GREATER_EQUAL: - opstr[i++] = '>'; - opstr[i++] = '='; - break; - case ASL_QUERY_OP_LESS: - opstr[i++] = '<'; - break; - case ASL_QUERY_OP_LESS_EQUAL: - opstr[i++] = '<'; - opstr[i++] = '='; - break; - case ASL_QUERY_OP_NOT_EQUAL: - opstr[i++] = '!'; - break; - case ASL_QUERY_OP_TRUE: - opstr[i++] = 'T'; - break; - default: - break; - } - - if (i == 0) return _asl_append_string(m, x, ".", ASL_ENCODE_NONE, 0); - - opstr[i++] = '\0'; - return _asl_append_string(m, x, opstr, ASL_ENCODE_NONE, 0); -} - -static char * -_asl_time_string(int fmt, const char *str) -{ - time_t tick; - struct tm *stm; - char *ltime; - char *out; - char ltbuf[32]; - out = NULL; - - tick = 0; - if (str != NULL) tick = asl_parse_time(str); - - if (fmt == TFMT_SEC) - { - asprintf(&out, "%lu", tick); - return out; - } - - if (fmt == TFMT_UTC) - { - stm = gmtime(&tick); - asprintf(&out, "%d.%02d.%02d %02d:%02d:%02d UTC", stm->tm_year + 1900, stm->tm_mon + 1, stm->tm_mday, stm->tm_hour, stm->tm_min, stm->tm_sec); - return out; - } - - if (fmt == TFMT_LCL) - { - ltime = ctime_r(&tick, ltbuf); - if (ltime == NULL) return NULL; - ltime[19] = '\0'; - asprintf(&out, "%s", ltime); - return out; - } - - return NULL; -} - -static char * -_asl_msg_to_string_time_fmt(asl_msg_t *msg, uint32_t *len, int tf) -{ - uint32_t i, outlen; - char *out, *s; - - *len = 0; - - if (msg == NULL) return NULL; - - s = NULL; - out = NULL; - outlen = 0; - - if (msg->count == 0) - { - if (out == NULL) return NULL; - *len = outlen; - return out; - } - - for (i = 0; i < msg->count; i++) - { - if (msg->key[i] == NULL) continue; - if (i > 0) _asl_append_string(&out, &outlen, " [", ASL_ENCODE_NONE, 0); - else _asl_append_string(&out, &outlen, "[", ASL_ENCODE_NONE, 0); - - _asl_append_string(&out, &outlen, msg->key[i], ASL_ENCODE_ASL, 1); - - if ((tf != TFMT_SEC) && (!strcmp(msg->key[i], ASL_KEY_TIME))) - { - s = _asl_time_string(tf, msg->val[i]); - if (s != NULL) - { - _asl_append_string(&out, &outlen, " ", ASL_ENCODE_NONE, 0); - _asl_append_string(&out, &outlen, s, ASL_ENCODE_ASL, 0); - } - } - else if (msg->val[i] != NULL) - { - _asl_append_string(&out, &outlen, " ", ASL_ENCODE_NONE, 0); - _asl_append_string(&out, &outlen, msg->val[i], ASL_ENCODE_ASL, 0); - } - - _asl_append_string(&out, &outlen, "]", ASL_ENCODE_NONE, 0); - } - - _asl_append_string(&out, &outlen, "\n", ASL_ENCODE_NONE, 0); - - *len = outlen; - return out; -} - -char * -asl_msg_to_string(asl_msg_t *msg, uint32_t *len) -{ - uint32_t i, outlen; - char *out, *s; - - *len = 0; - - if (msg == NULL) return NULL; - - s = NULL; - out = NULL; - outlen = 0; - - if (msg->type == ASL_TYPE_QUERY) - { - _asl_append_string(&out, &outlen, "Q ", ASL_ENCODE_NONE, 0); - if (out == NULL) return NULL; - } - - if (msg->count == 0) - { - if (out == NULL) return NULL; - *len = outlen; - return out; - } - - for (i = 0; i < msg->count; i++) - { - if (msg->key[i] == NULL) continue; - - if (i > 0) _asl_append_string(&out, &outlen, " [", ASL_ENCODE_NONE, 0); - else _asl_append_string(&out, &outlen, "[", ASL_ENCODE_NONE, 0); - - if (msg->type == ASL_TYPE_QUERY) - { - _asl_append_op(&out, &outlen, msg->op[i]); - _asl_append_string(&out, &outlen, " ", ASL_ENCODE_NONE, 0); - } - - _asl_append_string(&out, &outlen, msg->key[i], ASL_ENCODE_ASL, 1); - - if (msg->val[i] != NULL) - { - _asl_append_string(&out, &outlen, " ", ASL_ENCODE_NONE, 0); - _asl_append_string(&out, &outlen, msg->val[i], ASL_ENCODE_ASL, 0); - } - - _asl_append_string(&out, &outlen, "]", ASL_ENCODE_NONE, 0); - } - - *len = outlen; - return out; -} - -static uint32_t -_asl_msg_op_from_string(char *o) -{ - uint32_t op, i; - - op = ASL_QUERY_OP_NULL; - - if (o == NULL) return op; - - for (i = 0; o[i] != '\0'; i++) - { - if (o[i] == '.') return ASL_QUERY_OP_NULL; - if (o[i] == 'C') op |= ASL_QUERY_OP_CASEFOLD; - if (o[i] == 'R') op |= ASL_QUERY_OP_REGEX; - if (o[i] == 'N') op |= ASL_QUERY_OP_NUMERIC; - if (o[i] == 'S') op |= ASL_QUERY_OP_SUBSTRING; - if (o[i] == 'A') op |= ASL_QUERY_OP_PREFIX; - if (o[i] == 'Z') op |= ASL_QUERY_OP_SUFFIX; - if (o[i] == '<') op |= ASL_QUERY_OP_LESS; - if (o[i] == '>') op |= ASL_QUERY_OP_GREATER; - if (o[i] == '=') op |= ASL_QUERY_OP_EQUAL; - if (o[i] == '!') op |= ASL_QUERY_OP_NOT_EQUAL; - if (o[i] == 'T') op |= ASL_QUERY_OP_TRUE; - } - - return op; -} - -static char * -_asl_msg_get_next_word(char **p, uint32_t *tt, uint32_t spacedel) -{ - char *str, *out, c, oval; - uint32_t i, len, n, outlen; - - *tt = TOKEN_NULL; - - if (p == NULL) return NULL; - if (*p == NULL) return NULL; - if (**p == '\0') return NULL; - - /* skip one space if it's there (word separator) */ - if (**p == ' ') (*p)++; - - /* skip leading white space */ - if (spacedel != 0) - { - while ((**p == ' ') || (**p == '\t')) (*p)++; - } - - if (**p == '\0') return NULL; - if (**p == '\n') return NULL; - - str = *p; - - /* opening [ */ - if (**p == '[') - { - *tt = TOKEN_OPEN; - - (*p)++; - out = malloc(2); - if (out == NULL) return NULL; - - out[0] = '['; - out[1] = '\0'; - return out; - } - - /* scan for token and calulate it's length (input and decoded output len) */ - len = 0; - outlen = 0; - - forever - { - c = str[len]; - - /* stop scanning when we hit a delimiter */ - if (((spacedel != 0) && (c == ' ')) || (c == ']') || (c == '\0')) break; - - if (c == '\\') - { - len++; - c = str[len]; - if ((c == 'a') || (c == 'b') || (c == 't') || (c == 'n') || (c == 'v') || (c == 'f') || (c == 'r') || (c == 's') || (c == '[') || (c == '\\') || (c == ']')) - { - } - else if (c == '^') - { - if (str[++len] == '\0') return NULL; - } - else if (c == 'M') - { - if (str[++len] == '\0') return NULL; - if (str[++len] == '\0') return NULL; - } - else if ((c >= '0') && (c <= '3')) - { - if (str[++len] == '\0') return NULL; - if (str[++len] == '\0') return NULL; - } - else - { - return NULL; - } - } - - len++; - outlen++; - } - - (*p) += len; - - if ((len == 0) && (**p == ']')) - { - *tt = TOKEN_CLOSE; - (*p)++; - out = malloc(2); - if (out == NULL) return NULL; - - out[0] = ']'; - out[1] = '\0'; - return out; - } - - *tt = TOKEN_INT; - - out = malloc(outlen + 1); - if (out == NULL) return NULL; - - n = 0; - for (i = 0; i < len; i++) - { - c = str[i]; - - if (c == '\\') - { - *tt = TOKEN_WORD; - - i++; - c = str[i]; - if (c == 'a') - { - out[n++] = '\a'; - } - else if (c == 'b') - { - out[n++] = '\b'; - } - else if (c == 't') - { - out[n++] = '\t'; - } - else if (c == 'n') - { - out[n++] = '\n'; - } - else if (c == 'v') - { - out[n++] = '\v'; - } - else if (c == 'f') - { - out[n++] = '\f'; - } - else if (c == 'r') - { - out[n++] = '\r'; - } - else if (c == 's') - { - out[n++] = ' '; - } - else if (c == '[') - { - out[n++] = '['; - } - else if (c == '\\') - { - out[n++] = '\\'; - } - else if (c == ']') - { - out[n++] = ']'; - } - else if (c == '^') - { - i++; - if (str[i] == '?') out[n++] = 127; - else out[n++] = str[i] - 64; - } - else if (c == 'M') - { - i++; - c = str[i]; - if (c == '^') - { - i++; - if (str[i] == '?') out[n++] = 255; - else out[n++] = str[i] + 64; - } - else if (c == '-') - { - i++; - out[n++] = str[i] + 128; - } - else - { - *tt = TOKEN_NULL; - free(out); - return NULL; - } - - } - else if ((c >= '0') && (c <= '3')) - { - oval = (c - '0') * 64; - - i++; - c = str[i]; - if ((c < '0') || (c > '7')) - { - *tt = TOKEN_NULL; - free(out); - return NULL; - } - - oval += ((c - '0') * 8); - - i++; - c = str[i]; - if ((c < '0') || (c > '7')) - { - *tt = TOKEN_NULL; - free(out); - return NULL; - } - - oval += (c - '0'); - - out[n++] = oval; - } - else - { - *tt = TOKEN_NULL; - free(out); - return NULL; - } - } - else - { - - if ((c < '0') || (c > '9')) *tt = TOKEN_WORD; - out[n++] = c; - } - } - - out[n] = '\0'; - - return out; -} - -asl_msg_t * -asl_msg_from_string(const char *buf) -{ - uint32_t tt, type, op; - char *k, *v, *o, *p; - asl_msg_t *msg; - - if (buf == NULL) return NULL; - - type = ASL_TYPE_MSG; - p = (char *)buf; - - k = _asl_msg_get_next_word(&p, &tt, 1); - if (k == NULL) return NULL; - - if (streq(k, "Q")) - { - type = ASL_TYPE_QUERY; - free(k); - - k = _asl_msg_get_next_word(&p, &tt, 1); - } - else if (tt == TOKEN_INT) - { - /* Leading integer is a string length - skip it */ - free(k); - k = _asl_msg_get_next_word(&p, &tt, 1); - if (k == NULL) return NULL; - } - - msg = calloc(1, sizeof(asl_msg_t)); - if (msg == NULL) return NULL; - - msg->type = type; - - /* OPEN WORD [WORD [WORD]] CLOSE */ - while (k != NULL) - { - op = ASL_QUERY_OP_NULL; - - if (tt != TOKEN_OPEN) - { - asl_free(msg); - return NULL; - } - - free(k); - - /* get op for query type */ - if (type == ASL_TYPE_QUERY) - { - o = _asl_msg_get_next_word(&p, &tt, 1); - if ((o == NULL) || (tt != TOKEN_WORD)) - { - if (o != NULL) free(o); - asl_free(msg); - return NULL; - } - - op = _asl_msg_op_from_string(o); - free(o); - } - - k = _asl_msg_get_next_word(&p, &tt, 1); - if (tt == TOKEN_INT) tt = TOKEN_WORD; - if ((k == NULL) || (tt != TOKEN_WORD)) - { - if (k != NULL) free(k); - asl_free(msg); - return NULL; - } - - v = _asl_msg_get_next_word(&p, &tt, 0); - if (tt == TOKEN_INT) tt = TOKEN_WORD; - if (v == NULL) - { - asl_set_query(msg, k, NULL, op); - break; - } - - if (tt == TOKEN_CLOSE) - { - asl_set_query(msg, k, NULL, op); - } - else if (tt == TOKEN_WORD) - { - asl_set_query(msg, k, v, op); - } - else - { - if (k != NULL) free(k); - if (v != NULL) free(v); - asl_free(msg); - return NULL; - } - - if (k != NULL) free(k); - if (v != NULL) free(v); - - if (tt != TOKEN_CLOSE) - { - k = _asl_msg_get_next_word(&p, &tt, 1); - if (k == NULL) break; - - if (tt != TOKEN_CLOSE) - { - asl_free(msg); - return NULL; - } - - free(k); - } - - k = _asl_msg_get_next_word(&p, &tt, 1); - if (k == NULL) break; - } - - return msg; -} - -char * -asl_list_to_string(asl_search_result_t *list, uint32_t *outlen) -{ - uint32_t i, len, newlen; - char *msgbuf, *out; - - if (list == NULL) return NULL; - if (list->count == 0) return NULL; - if (list->msg == NULL) return NULL; - - out = NULL; - asprintf(&out, "%u\n", list->count); - if (out == NULL) return NULL; - *outlen = strlen(out) + 1; - - for (i = 0; i < list->count; i++) - { - len = 0; - msgbuf = asl_msg_to_string(list->msg[i], &len); - if (msgbuf == NULL) - { - free(out); - *outlen = 0; - return NULL; - } - - newlen = *outlen + len; - out = reallocf(out, newlen); - if (out == NULL) - { - *outlen = 0; - return NULL; - } - - memmove((out + *outlen - 1), msgbuf, len); - out[newlen - 2] = '\n'; - out[newlen - 1] = '\0'; - *outlen = newlen; - - free(msgbuf); - } - - return out; -} - -asl_search_result_t * -asl_list_from_string(const char *buf) -{ - uint32_t i, n; - const char *p; - asl_search_result_t *out; - asl_msg_t *m; - - if (buf == NULL) return NULL; - p = buf; - - n = atoi(buf); - if (n == 0) return NULL; - - out = (asl_search_result_t *)calloc(1, sizeof(asl_search_result_t)); - if (out == NULL) return NULL; - - out->msg = (asl_msg_t **)calloc(n, sizeof(asl_msg_t *)); - if (out->msg == NULL) - { - free(out); - return NULL; - } - - for (i = 0; i < n; i++) - { - p = strchr(p, '\n'); - if (p == NULL) - { - aslresponse_free((aslresponse)out); - return NULL; - } - - p++; - - m = asl_msg_from_string(p); - if (m == NULL) - { - aslresponse_free((aslresponse)out); - return NULL; - } - - out->msg[i] = m; - out->count += 1; - } - - return out; -} - -static int -_asl_msg_equal(asl_msg_t *a, asl_msg_t *b) -{ - uint32_t i, j; - - if (a->count != b->count) return 0; - - for (i = 0; i < a->count; i++) - { - j = _asl_msg_index(b, a->key[i]); - if (j == (uint32_t)-1) return 0; - - if (a->val[i] == NULL) - { - if (b->val[j] != NULL) return 0; - } - else - { - if (b->val[j] == NULL) return 0; - if (strcmp(a->val[i], b->val[j])) return 0; - } - - if (a->type == ASL_TYPE_QUERY) - { - if (a->op[i] != b->op[j]) return 0; - } - } - - return 1; -} - -static int -_asl_isanumber(char *s) -{ - int i; - - if (s == NULL) return 0; - - i = 0; - if ((s[0] == '-') || (s[0] == '+')) i = 1; - - if (s[i] == '\0') return 0; - - for (; s[i] != '\0'; i++) - { - if (!isdigit(s[i])) return 0; - } - - return 1; -} - -static int -_asl_msg_basic_test(uint32_t op, char *q, char *m, uint32_t n) -{ - int cmp; - uint32_t t; - int nq, nm, rflags; - regex_t rex; - - t = op & ASL_QUERY_OP_TRUE; - - /* NULL value from query or message string fails */ - if ((q == NULL) || (m == NULL)) return (t & ASL_QUERY_OP_NOT_EQUAL); - - if (op & ASL_QUERY_OP_REGEX) - { - /* greater than or less than make no sense in substring search */ - if ((t == ASL_QUERY_OP_GREATER) || (t == ASL_QUERY_OP_LESS)) return 0; - - memset(&rex, 0, sizeof(regex_t)); - - rflags = REG_EXTENDED | REG_NOSUB; - if (op & ASL_QUERY_OP_CASEFOLD) rflags |= REG_ICASE; - - /* A bad reqular expression matches nothing */ - if (regcomp(&rex, q, rflags) != 0) return (t & ASL_QUERY_OP_NOT_EQUAL); - - cmp = regexec(&rex, m, 0, NULL, 0); - regfree(&rex); - - if (t == ASL_QUERY_OP_NOT_EQUAL) return (cmp != 0); - return (cmp == 0); - } - - if (op & ASL_QUERY_OP_NUMERIC) - { - if (_asl_isanumber(q) == 0) return (t == ASL_QUERY_OP_NOT_EQUAL); - if (_asl_isanumber(m) == 0) return (t == ASL_QUERY_OP_NOT_EQUAL); - - nq = atoi(q); - nm = atoi(m); - - switch (t) - { - case ASL_QUERY_OP_EQUAL: return (nm == nq); - case ASL_QUERY_OP_GREATER: return (nm > nq); - case ASL_QUERY_OP_GREATER_EQUAL: return (nm >= nq); - case ASL_QUERY_OP_LESS: return (nm < nq); - case ASL_QUERY_OP_LESS_EQUAL: return (nm <= nq); - case ASL_QUERY_OP_NOT_EQUAL: return (nm != nq); - default: return (t == ASL_QUERY_OP_NOT_EQUAL); - } - } - - cmp = 0; - if (op & ASL_QUERY_OP_CASEFOLD) - { - if (n == 0) cmp = strcasecmp(m, q); - else cmp = strncasecmp(m, q, n); - } - else - { - if (n == 0) cmp = strcmp(m, q); - else cmp = strncmp(m, q, n); - } - - switch (t) - { - case ASL_QUERY_OP_EQUAL: return (cmp == 0); - case ASL_QUERY_OP_GREATER: return (cmp > 0); - case ASL_QUERY_OP_GREATER_EQUAL: return (cmp >= 0); - case ASL_QUERY_OP_LESS: return (cmp < 0); - case ASL_QUERY_OP_LESS_EQUAL: return (cmp <= 0); - case ASL_QUERY_OP_NOT_EQUAL: return (cmp != 0); - } - - return (t == ASL_QUERY_OP_NOT_EQUAL); -} - -static int -_asl_msg_test_substring(uint32_t op, char *q, char *m) -{ - uint32_t t, i, d, lm, lq, match, newop; - - t = op & ASL_QUERY_OP_TRUE; - - lm = 0; - if (m != NULL) lm = strlen(m); - - lq = 0; - if (q != NULL) lq = strlen(q); - - /* NULL is a substring of any string */ - if (lq == 0) return (t & ASL_QUERY_OP_EQUAL); - - /* A long string is defined to be not equal to a short string */ - if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL); - - /* greater than or less than make no sense in substring search */ - if ((t == ASL_QUERY_OP_GREATER) || (t == ASL_QUERY_OP_LESS)) return 0; - - /* - * We scan the string doing an equality test. - * If the input test is equality, we stop as soon as we hit a match. - * Otherwise we keep scanning the whole message string. - */ - newop = op & 0xff0; - newop |= ASL_QUERY_OP_EQUAL; - - match = 0; - d = lm - lq; - for (i = 0; i <= d; i++) - { - if (_asl_msg_basic_test(newop, q, m + i, lq) != 0) - { - if (t & ASL_QUERY_OP_EQUAL) return 1; - match++; - } - } - - /* If the input test was for equality, no matches were found */ - if (t & ASL_QUERY_OP_EQUAL) return 0; - - /* The input test was for not equal. Return true if no matches were found */ - return (match == 0); -} - -static int -_asl_msg_test_prefix(uint32_t op, char *q, char *m) -{ - uint32_t lm, lq, t; - - t = op & ASL_QUERY_OP_TRUE; - - lm = 0; - if (m != NULL) lm = strlen(m); - - lq = 0; - if (q != NULL) lq = strlen(q); - - /* NULL is a prefix of any string */ - if (lq == 0) return (t & ASL_QUERY_OP_EQUAL); - - /* A long string is defined to be not equal to a short string */ - if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL); - - /* Compare two equal-length strings */ - return _asl_msg_basic_test(op, q, m, lq); -} - -static int -_asl_msg_test_suffix(uint32_t op, char *q, char *m) -{ - uint32_t lm, lq, d, t; - - t = op & ASL_QUERY_OP_TRUE; - - lm = 0; - if (m != NULL) lm = strlen(m); - - lq = 0; - if (q != NULL) lq = strlen(q); - - /* NULL is a suffix of any string */ - if (lq == 0) return (t & ASL_QUERY_OP_EQUAL); - - /* A long string is defined to be not equal to a short string */ - if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL); - - /* Compare two equal-length strings */ - d = lm - lq; - return _asl_msg_basic_test(op, q, m + d, lq); -} - -/* - * Splits out prefix, suffix, and substring tests. - * Sends the rest to _asl_msg_basic_test(). - */ -static int -_asl_msg_test_expression(uint32_t op, char *q, char *m) -{ - uint32_t t; - - t = op & ASL_QUERY_OP_TRUE; - if (t == ASL_QUERY_OP_TRUE) return 1; - - if (op & ASL_QUERY_OP_PREFIX) - { - if (op & ASL_QUERY_OP_SUFFIX) return _asl_msg_test_substring(op, q, m); - return _asl_msg_test_prefix(op, q, m); - } - if (op & ASL_QUERY_OP_SUFFIX) return _asl_msg_test_suffix(op, q, m); - - return _asl_msg_basic_test(op, q, m, 0); -} - -/* - * Special case for comparing time values. - * If both inputs are time strings, this compares the time - * value in seconds. Otherwise it just does normal matching. - */ -static int -_asl_msg_test_time_expression(uint32_t op, char *q, char *m) -{ - time_t tq, tm; - uint32_t t; - - if ((op & ASL_QUERY_OP_PREFIX) || (op & ASL_QUERY_OP_SUFFIX) || (op & ASL_QUERY_OP_REGEX)) return _asl_msg_test_expression(op, q, m); - if ((q == NULL) || (m == NULL)) return _asl_msg_test_expression(op, q, m); - - tq = asl_parse_time(q); - if (tq < 0) return _asl_msg_test_expression(op, q, m); - - tm = asl_parse_time(m); - if (tm < 0) return _asl_msg_test_expression(op, q, m); - - t = op & ASL_QUERY_OP_TRUE; - - switch (t) - { - case ASL_QUERY_OP_FALSE: - { - return 0; - } - case ASL_QUERY_OP_EQUAL: - { - if (tm == tq) return 1; - return 0; - } - case ASL_QUERY_OP_GREATER: - { - if (tm > tq) return 1; - return 0; - } - case ASL_QUERY_OP_GREATER_EQUAL: - { - if (tm >= tq) return 1; - return 0; - } - case ASL_QUERY_OP_LESS: - { - if (tm < tq) return 1; - return 0; - } - case ASL_QUERY_OP_LESS_EQUAL: - { - if (tm <= tq) return 1; - return 0; - } - case ASL_QUERY_OP_NOT_EQUAL: - { - if (tm != tq) return 1; - return 0; - } - case ASL_QUERY_OP_TRUE: - { - return 1; - } - } - - /* NOTREACHED */ - return 0; -} - -/* test a query against a message */ -static int -_asl_msg_test(asl_msg_t *q, asl_msg_t *m) -{ - uint32_t i, j, t; - int cmp; - - /* - * Check each simple expression (key op val) separately. - * The query suceeds (returns 1) if all simple expressions - * succeed (i.e. AND the simple expressions). - */ - for (i = 0; i < q->count; i++) - { - /* Find query key[i] in the message */ - j = _asl_msg_index(m, q->key[i]); - - /* NULL op is meaningless, but we allow it to succeed */ - if (q->op == NULL) continue; - - /* ASL_QUERY_OP_TRUE tests if key[i] is present in the message */ - t = q->op[i] & ASL_QUERY_OP_TRUE; - if (t == ASL_QUERY_OP_TRUE) - { - if (j == (uint32_t)-1) return 0; - continue; - } - - /* ASL_QUERY_OP_FALSE tests if the key is NOT present in the message */ - if (t == ASL_QUERY_OP_FALSE) - { - if (j != (uint32_t)-1) return 0; - continue; - } - - if (j == (uint32_t)-1) - { - /* the message does NOT have query key[i] - fail unless we are testing not equal */ - if (t == ASL_QUERY_OP_NOT_EQUAL) continue; - return 0; - } - - cmp = 1; - if (streq(q->key[i], ASL_KEY_TIME)) - { - cmp = _asl_msg_test_time_expression(q->op[i], q->val[i], m->val[j]); - } - else - { - cmp = _asl_msg_test_expression(q->op[i], q->val[i], m->val[j]); - } + for (i = 0; i < asl->fd_count; i++) if (asl->fd_mfmt[i] != NULL) free(asl->fd_mfmt[i]); + free(asl->fd_mfmt); + } - if (cmp == 0) return 0; + if (asl->fd_tfmt != NULL) + { + for (i = 0; i < asl->fd_count; i++) if (asl->fd_tfmt[i] != NULL) free(asl->fd_tfmt[i]); + free(asl->fd_tfmt); } - return 1; + if (asl->fd_encoding != NULL) free(asl->fd_encoding); + + memset(asl, 0, sizeof(asl_client_t)); + free(asl); } -int -asl_msg_cmp(asl_msg_t *a, asl_msg_t *b) +__private_extern__ asl_client_t * +_asl_open_default() { - if (a == NULL) return 0; - if (b == NULL) return 0; + static dispatch_once_t once; + + dispatch_once(&once, ^{ + /* + * Do a sleight-of-hand with ASL_OPT_NO_REMOTE to avoid a deadlock + * since asl_open(xxx, yyy, 0) calls _asl_notify_open(1) + * which locks _asl_global.lock. + */ + _asl_global.asl = asl_open(NULL, NULL, ASL_OPT_NO_REMOTE); + + /* Reset options to clear ASL_OPT_NO_REMOTE bit */ + if (_asl_global.asl != NULL) _asl_global.asl->options = 0; + + /* Now call _asl_notify_open(0) to finish the work */ + _asl_notify_open(0); + }); - if (a->type == b->type) return _asl_msg_equal(a, b); - if (a->type == ASL_TYPE_QUERY) return _asl_msg_test(a, b); - return _asl_msg_test(b, a); + return _asl_global.asl; } /* @@ -2138,155 +650,6 @@ asl_set_filter(aslclient ac, int f) return last; } -/* - * asl_key: examine attribute keys - * returns the key of the nth attribute in a message (beginning at zero) - * returns NULL if the message has fewer attributes - */ -const char * -asl_key(aslmsg a, uint32_t n) -{ - asl_msg_t *msg; - - msg = (asl_msg_t *)a; - if (msg == NULL) return NULL; - - if (n >= msg->count) return NULL; - return msg->key[n]; -} - -/* - * asl_new: create a new log message. - */ -aslmsg -asl_new(uint32_t type) -{ - uint32_t i; - asl_msg_t *msg; - - msg = calloc(1, sizeof(asl_msg_t)); - if (msg == NULL) return NULL; - - msg->type = type; - if (type == ASL_TYPE_QUERY) return (aslmsg)msg; - - /* - * Defaut attributes are: - * 0 Time - * 1 Host - * 2 Sender - * 3 PID - * 4 UID - * 5 GID - * 6 Level - * 7 Message - */ - msg->count = 8; - - msg->key = calloc(msg->count, sizeof(char *)); - if (msg->key == NULL) - { - free(msg); - return NULL; - } - - msg->val = calloc(msg->count, sizeof(char *)); - if (msg->val == NULL) - { - free(msg->key); - free(msg); - return NULL; - } - - i = 0; - msg->key[i] = strdup(ASL_KEY_TIME); - if (msg->key[i] == NULL) - { - asl_free(msg); - return NULL; - } - - i++; - msg->key[i] = strdup(ASL_KEY_HOST); - if (msg->key[i] == NULL) - { - asl_free(msg); - return NULL; - } - - i++; - msg->key[i] = strdup(ASL_KEY_SENDER); - if (msg->key[i] == NULL) - { - asl_free(msg); - return NULL; - } - - i++; - msg->key[i] = strdup(ASL_KEY_PID); - if (msg->key[i] == NULL) - { - asl_free(msg); - return NULL; - } - - i++; - msg->key[i] = strdup(ASL_KEY_UID); - if (msg->key[i] == NULL) - { - asl_free(msg); - return NULL; - } - - i++; - msg->key[i] = strdup(ASL_KEY_GID); - if (msg->key[i] == NULL) - { - asl_free(msg); - return NULL; - } - - i++; - msg->key[i] = strdup(ASL_KEY_LEVEL); - if (msg->key[i] == NULL) - { - asl_free(msg); - return NULL; - } - - i++; - msg->key[i] = strdup(ASL_KEY_MSG); - if (msg->key[i] == NULL) - { - asl_free(msg); - return NULL; - } - - return (aslmsg)msg; -} - -/* - * asl_get: get attribute values from a message - * msg: an aslmsg - * key: attribute key - * returns the attribute value - * returns NULL if the message does not contain the key - */ -const char * -asl_get(aslmsg a, const char *key) -{ - asl_msg_t *msg; - uint32_t i; - - msg = (asl_msg_t *)a; - - if (msg == NULL) return NULL; - - i = _asl_msg_index(msg, key); - if (i == (uint32_t)-1) return NULL; - return msg->val[i]; -} - #endif /* BUILDING_VARIANT */ /* @@ -2298,12 +661,12 @@ asl_get(aslmsg a, const char *key) * returns 0 for success, non-zero for failure */ int -asl_vlog(aslclient ac, aslmsg a, int level, const char *format, va_list ap) +asl_vlog(aslclient ac, aslmsg msg, int level, const char *format, va_list ap) { - int status, saved_errno; - asl_msg_t *msg; - char *str, *fmt, *estr; - uint32_t i, len, elen, expand, my_msg; + int saved_errno = errno; + int status; + char *str, *fmt, estr[NL_TEXTMAX]; + uint32_t i, len, elen, expand; asl_client_t *asl; asl = (asl_client_t *)ac; @@ -2317,60 +680,33 @@ asl_vlog(aslclient ac, aslmsg a, int level, const char *format, va_list ap) if (asl == NULL) return -1; } - saved_errno = errno; - if (format == NULL) return -1; - msg = (asl_msg_t *)a; - - my_msg = 0; - if (msg == NULL) - { - my_msg = 1; - msg = asl_new(ASL_TYPE_MSG); - if (msg == NULL) return -1; - } - - if (msg->type != ASL_TYPE_MSG) return -1; - - if (level < ASL_LEVEL_EMERG) level = ASL_LEVEL_EMERG; - if (level > ASL_LEVEL_DEBUG) level = ASL_LEVEL_DEBUG; - /* insert strerror for %m */ len = 0; elen = 0; - estr = strdup(strerror(saved_errno)); - if (estr == NULL) - { - if ((msg != NULL) && (my_msg != 0)) asl_free(msg); - return -1; - } expand = 0; - - if (estr != NULL) + for (i = 0; format[i] != '\0'; i++) { - elen = strlen(estr); - - for (i = 0; format[i] != '\0'; i++) + if (format[i] == '%') { - if (format[i] == '%') + if (format[i+1] == '\0') len++; + else if (format[i+1] == 'm') { - if (format[i+1] == '\0') len++; - else if (format[i+1] == 'm') - { - expand = 1; - len += elen; - i++; - } - else - { - len += 2; - i++; - } + expand = 1; + strerror_r(saved_errno, estr, sizeof(estr)); + elen = strlen(estr); + len += elen; + i++; + } + else + { + len += 2; + i++; } - else len++; } + else len++; } fmt = (char *)format; @@ -2393,7 +729,7 @@ asl_vlog(aslclient ac, aslmsg a, int level, const char *format, va_list ap) if (format[i+1] == '\0') { } - else if (format[i+1] == 'm') + else if ((format[i+1] == 'm') && (elen != 0)) { memcpy(fmt+len, estr, elen); len += elen; @@ -2411,21 +747,14 @@ asl_vlog(aslclient ac, aslmsg a, int level, const char *format, va_list ap) fmt[len] = '\0'; } - if (estr != NULL) free(estr); - vasprintf(&str, fmt, ap); if (expand != 0) free(fmt); - if (str == NULL) - { - if ((msg != NULL) && (my_msg != 0)) asl_free(msg); - return -1; - } + if (str == NULL) return -1; - status = _asl_send_level_message(ac, (aslmsg)msg, level, str); + status = _asl_send_message(ac, (asl_msg_t *)msg, level, str); free(str); - if ((msg != NULL) && (my_msg != 0)) asl_free(msg); return status; } @@ -2453,311 +782,229 @@ asl_log(aslclient ac, aslmsg a, int level, const char *format, ...) #ifndef BUILDING_VARIANT -static const char * -_asl_level_string(int level) +static asl_msg_t * +_asl_merge_msg_aux0(asl_msg_t *msg, asl_msg_aux_0_t aux0) { - if (level == ASL_LEVEL_EMERG) return ASL_STRING_EMERG; - if (level == ASL_LEVEL_ALERT) return ASL_STRING_ALERT; - if (level == ASL_LEVEL_CRIT) return ASL_STRING_CRIT; - if (level == ASL_LEVEL_ERR) return ASL_STRING_ERR; - if (level == ASL_LEVEL_WARNING) return ASL_STRING_WARNING; - if (level == ASL_LEVEL_NOTICE) return ASL_STRING_NOTICE; - if (level == ASL_LEVEL_INFO) return ASL_STRING_INFO; - if (level == ASL_LEVEL_DEBUG) return ASL_STRING_DEBUG; - return "Unknown"; -} - -/* - * format a message for printing - * out parameter len returns string length including trailing NUL - */ -char * -asl_format_message(aslmsg msg, const char *mfmt, const char *tfmt, uint32_t text_encoding, uint32_t *len) -{ - char *out, *tstr, *k, c[2]; - const char *hstr, *sstr, *pstr, *mstr, *lstr, *rprc, *rpid, *v; - int i, j, l, mf, tf, paren, oval, level; - - out = NULL; - *len = 0; + const char *key, *val; + asl_msg_t *out; + uint32_t x; + int klevel, ktime, knano, khost, ksender, kfac, kpid, kuid, kgid, kmsg, kaux, kuti, kurl; - if (msg == NULL) return NULL; - - mf = MFMT_RAW; - tf = TFMT_SEC; - - if (mfmt == NULL) mf = MFMT_RAW; - else if (!strcmp(mfmt, ASL_MSG_FMT_RAW)) mf = MFMT_RAW; - else if (!strcmp(mfmt, ASL_MSG_FMT_STD)) mf = MFMT_STD; - else if (!strcmp(mfmt, ASL_MSG_FMT_BSD)) mf = MFMT_BSD; - else if (!strcmp(mfmt, ASL_MSG_FMT_XML)) mf = MFMT_XML; - else if (!strcmp(mfmt, ASL_MSG_FMT_MSG)) mf = MFMT_MSG; - else mf = MFMT_STR; - - if (tfmt == NULL) tf = TFMT_SEC; - else if (!strcmp(tfmt, ASL_TIME_FMT_SEC)) tf = TFMT_SEC; - else if (!strcmp(tfmt, ASL_TIME_FMT_UTC)) tf = TFMT_UTC; - else if (!strcmp(tfmt, ASL_TIME_FMT_LCL)) tf = TFMT_LCL; - - if (mf == MFMT_RAW) - { - out = _asl_msg_to_string_time_fmt((asl_msg_t *)msg, len, tf); - return out; - } - - if (mf == MFMT_MSG) - { - mstr = asl_get(msg, ASL_KEY_MSG); - if (mstr == NULL) return NULL; + out = asl_msg_new(ASL_TYPE_MSG); + if (out == NULL) return NULL; - _asl_append_string(&out, len, mstr, text_encoding, 0); - _asl_append_string(&out, len, "\n", ASL_ENCODE_NONE, 0); + klevel = 0; + ktime = 0; + knano = 0; + khost = 0; + ksender= 0; + kfac = 0; + kpid = 0; + kuid = 0; + kgid = 0; + kmsg = 0; + kaux = 0; + kuti = 0; + kurl = 0; - return out; - } + key = NULL; + val = NULL; - if ((mf == MFMT_STD) || (mf == MFMT_BSD)) + for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL)) { - /* BSD: Mth dd hh:mm:ss host sender[pid]: message */ - /* BSD: Mth dd hh:mm:ss host sender[pid] (refproc[refpid]): message */ - /* STD: Mth dd hh:mm:ss host sender[pid] : message */ - /* STD: Mth dd hh:mm:ss host sender[pid] (refproc[refpid]) : message */ - - v = asl_get(msg, ASL_KEY_TIME); - tstr = _asl_time_string(tf, v); - - hstr = asl_get(msg, ASL_KEY_HOST); - sstr = asl_get(msg, ASL_KEY_SENDER); - pstr = asl_get(msg, ASL_KEY_PID); - mstr = asl_get(msg, ASL_KEY_MSG); - - rprc = asl_get(msg, ASL_KEY_REF_PROC); - rpid = asl_get(msg, ASL_KEY_REF_PID); - - level = -1; - - if (mf == MFMT_STD) + if (streq(key, ASL_KEY_LEVEL)) { - lstr = asl_get(msg, ASL_KEY_LEVEL); - if (lstr != NULL) level = atoi(lstr); + klevel = 1; + if (aux0.level != NULL) asl_msg_set_key_val(out, key, aux0.level); + else asl_msg_set_key_val(out, key, val); } - - if (tstr == NULL) + else if (streq(key, ASL_KEY_TIME)) { - _asl_append_string(&out, len, "0", ASL_ENCODE_NONE, 0); + ktime = 1; + if (aux0.time != NULL) asl_msg_set_key_val(out, key, aux0.time); + else asl_msg_set_key_val(out, key, val); } - else + else if (streq(key, ASL_KEY_TIME_NSEC)) { - _asl_append_string(&out, len, tstr, ASL_ENCODE_NONE, 0); - free(tstr); + knano = 1; + if (aux0.nano != NULL) asl_msg_set_key_val(out, key, aux0.nano); + else asl_msg_set_key_val(out, key, val); } - - _asl_append_string(&out, len, " ", ASL_ENCODE_NONE, 0); - - if (hstr == NULL) _asl_append_string(&out, len, "unknown", ASL_ENCODE_NONE, 0); - else _asl_append_string(&out, len, hstr, text_encoding, 0); - - _asl_append_string(&out, len, " ", ASL_ENCODE_NONE, 0); - - if (sstr == NULL) _asl_append_string(&out, len, "unknown", ASL_ENCODE_NONE, 0); - else _asl_append_string(&out, len, sstr, text_encoding, 0); - - if ((pstr != NULL) && (strcmp(pstr, "-1"))) + else if (streq(key, ASL_KEY_HOST)) { - _asl_append_string(&out, len, "[", ASL_ENCODE_NONE, 0); - _asl_append_string(&out, len, pstr, ASL_ENCODE_NONE, 0); - _asl_append_string(&out, len, "]", ASL_ENCODE_NONE, 0); + khost = 1; + if (aux0.host != NULL) asl_msg_set_key_val(out, key, aux0.host); + else asl_msg_set_key_val(out, key, val); } - - if ((rprc != NULL) || (rpid != NULL)) _asl_append_string(&out, len, " (", ASL_ENCODE_NONE, 0); - - if (rprc != NULL) _asl_append_string(&out, len, rprc, text_encoding, 0); - if (rpid != NULL) + else if (streq(key, ASL_KEY_SENDER)) { - _asl_append_string(&out, len, "[", ASL_ENCODE_NONE, 0); - _asl_append_string(&out, len, rpid, ASL_ENCODE_NONE, 0); - _asl_append_string(&out, len, "]", ASL_ENCODE_NONE, 0); + ksender = 1; + if (aux0.sender != NULL) asl_msg_set_key_val(out, key, aux0.sender); + else asl_msg_set_key_val(out, key, val); } - - if ((rprc != NULL) || (rpid != NULL)) _asl_append_string(&out, len, ")", ASL_ENCODE_NONE, 0); - - if (mf == MFMT_STD) + else if (streq(key, ASL_KEY_FACILITY)) { - _asl_append_string(&out, len, " <", ASL_ENCODE_NONE, 0); - _asl_append_string(&out, len, _asl_level_string(level), ASL_ENCODE_NONE, 0); - _asl_append_string(&out, len, ">", ASL_ENCODE_NONE, 0); + kfac = 1; + if (aux0.facility != NULL) asl_msg_set_key_val(out, key, aux0.facility); + else asl_msg_set_key_val(out, key, val); } - - _asl_append_string(&out, len, ": ", ASL_ENCODE_NONE, 0); - - if (mstr != NULL) _asl_append_string(&out, len, mstr, text_encoding, 0); - - _asl_append_string(&out, len, "\n", ASL_ENCODE_NONE, 0); - return out; - } - - if (mf == MFMT_XML) - { - _asl_append_string(&out, len, "\t\n", ASL_ENCODE_NONE, 0); - - for (i = 0; i < msg->count; i++) + else if (streq(key, ASL_KEY_PID)) { - if (asl_is_utf8(msg->key[i]) == 1) - { - _asl_append_xml_tag(&out, len, XML_TAG_KEY, msg->key[i]); - if (!strcmp(msg->key[i], ASL_KEY_TIME)) - { - tstr = _asl_time_string(tf, msg->val[i]); - _asl_append_xml_tag(&out, len, XML_TAG_STRING, tstr); - if (tstr != NULL) free(tstr); - } - else - { - if (asl_is_utf8(msg->val[i]) == 1) _asl_append_xml_tag(&out, len, XML_TAG_STRING, msg->val[i]); - else _asl_append_xml_tag(&out, len, XML_TAG_DATA, msg->val[i]); - } - } + kpid = 1; + if (aux0.pid != NULL) asl_msg_set_key_val(out, key, aux0.pid); + else asl_msg_set_key_val(out, key, val); } - - _asl_append_string(&out, len, "\t\n", ASL_ENCODE_NONE, 0); - - return out; - } - - c[1] = '\0'; - - for (i = 0; mfmt[i] != '\0'; i++) - { - if (mfmt[i] == '$') + else if (streq(key, ASL_KEY_UID)) + { + kuid = 1; + if (aux0.uid != NULL) asl_msg_set_key_val(out, key, aux0.uid); + else asl_msg_set_key_val(out, key, val); + } + else if (streq(key, ASL_KEY_GID)) + { + kgid = 1; + if (aux0.gid != NULL) asl_msg_set_key_val(out, key, aux0.gid); + else asl_msg_set_key_val(out, key, val); + } + else if (streq(key, ASL_KEY_MSG)) + { + kmsg = 1; + if (aux0.message != NULL) asl_msg_set_key_val(out, key, aux0.message); + else asl_msg_set_key_val(out, key, val); + } + else if (streq(key, ASL_KEY_AUX_TITLE)) + { + kaux = 1; + if (aux0.auxtitle != NULL) asl_msg_set_key_val(out, key, aux0.auxtitle); + else asl_msg_set_key_val(out, key, val); + } + else if (streq(key, ASL_KEY_AUX_UTI)) + { + kuti = 1; + if (aux0.auxuti != NULL) asl_msg_set_key_val(out, key, aux0.auxuti); + else asl_msg_set_key_val(out, key, val); + } + else if (streq(key, ASL_KEY_AUX_URL)) + { + kurl = 1; + if (aux0.auxurl != NULL) asl_msg_set_key_val(out, key, aux0.auxurl); + else asl_msg_set_key_val(out, key, val); + } + else { - i++; - paren = 0; + asl_msg_set_key_val(out, key, val); + } + } - if (mfmt[i] == '(') - { - paren = 1; - i++; - } + if ((klevel == 0) && (aux0.level != NULL)) asl_msg_set_key_val(out, ASL_KEY_LEVEL, aux0.level); + if ((ktime == 0) && (aux0.time != NULL)) asl_msg_set_key_val(out, ASL_KEY_TIME, aux0.time); + if ((knano == 0) && (aux0.nano != NULL)) asl_msg_set_key_val(out, ASL_KEY_TIME_NSEC, aux0.nano); + if ((khost == 0) && (aux0.host != NULL)) asl_msg_set_key_val(out, ASL_KEY_HOST, aux0.host); + if ((ksender == 0) && (aux0.sender != NULL)) asl_msg_set_key_val(out, ASL_KEY_SENDER, aux0.sender); + if ((kfac == 0) && (aux0.facility != NULL)) asl_msg_set_key_val(out, ASL_KEY_FACILITY, aux0.facility); + if ((kpid == 0) && (aux0.pid != NULL)) asl_msg_set_key_val(out, ASL_KEY_PID, aux0.pid); + if ((kuid == 0) && (aux0.uid != NULL)) asl_msg_set_key_val(out, ASL_KEY_UID, aux0.uid); + if ((kgid == 0) && (aux0.gid != NULL)) asl_msg_set_key_val(out, ASL_KEY_GID, aux0.gid); + if ((kmsg == 0) && (aux0.message != NULL)) asl_msg_set_key_val(out, ASL_KEY_MSG, aux0.message); + if ((kaux == 0) && (aux0.auxtitle != NULL)) asl_msg_set_key_val(out, ASL_KEY_AUX_TITLE, aux0.auxtitle); + if ((kuti == 0) && (aux0.auxuti != NULL)) asl_msg_set_key_val(out, ASL_KEY_AUX_UTI, aux0.auxuti); + if ((kurl == 0) && (aux0.auxurl != NULL)) asl_msg_set_key_val(out, ASL_KEY_AUX_URL, aux0.auxurl); - k = calloc(1, 1); - if (k == NULL) - { - if (out != NULL) free(out); - return NULL; - } + return out; +} - l = 0; +/* + * asl_get_filter: gets the values for the local, master, and remote filters, + * and indicates which one is active. + */ +int +asl_get_filter(aslclient ac, int *local, int *master, int *remote, int *active) +{ + asl_client_t *asl, *asl_default; + int l, m, r, x; + int status, check; + uint64_t v64; - for (j = i; mfmt[j] != '\0'; j++) - { - c[0] = '\0'; - if (mfmt[j] == '\\') c[0] = mfmt[++j]; - else if ((paren == 1) && (mfmt[j] ==')')) break; - else if (mfmt[j] != ' ') c[0] = mfmt[j]; + l = 0; + m = 0; + r = 0; + x = 0; - if (c[0] == '\0') break; + asl_default = _asl_open_default(); - k = reallocf(k, l + 1); - if (k == NULL) - { - if (out != NULL) free(out); - return NULL; - } + asl = (asl_client_t *)ac; + if (asl == NULL) asl = asl_default; + if (asl != NULL) l = asl->filter & 0xff; - k[l] = c[0]; - k[l + 1] = '\0'; - l++; - } + if ((asl_default != NULL) && (!(asl_default->options & ASL_OPT_NO_REMOTE))) + { + pthread_mutex_lock(&_asl_global.lock); - if (paren == 1) j++; - i = j; - if (l > 0) + if (_asl_global.rc_change_token >= 0) + { + /* initialize or re-check process-specific and master filters */ + check = 0; + status = notify_check(_asl_global.rc_change_token, &check); + if ((status == NOTIFY_STATUS_OK) && (check != 0)) { - v = asl_get(msg, k); - if (v != NULL) + if (_asl_global.master_token >= 0) { - if (!strcmp(k, ASL_KEY_TIME)) - { - tstr = _asl_time_string(tf, v); - _asl_append_string(&out, len, tstr, ASL_ENCODE_NONE, 0); - if (tstr != NULL) free(tstr); - } - else - { - _asl_append_string(&out, len, (char *)v, ASL_ENCODE_NONE, 0); - } + v64 = 0; + status = notify_get_state(_asl_global.master_token, &v64); + if (status == NOTIFY_STATUS_OK) _asl_global.master_filter = v64; } - } - free(k); - } - if (mfmt[i] == '\\') - { - i++; - if (mfmt[i] == '$') _asl_append_string(&out, len, "$", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == 'e') _asl_append_string(&out, len, "\e", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == 's') _asl_append_string(&out, len, " ", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == 'a') _asl_append_string(&out, len, "\a", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == 'b') _asl_append_string(&out, len, "\b", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == 'f') _asl_append_string(&out, len, "\f", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == 'n') _asl_append_string(&out, len, "\n", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == 'r') _asl_append_string(&out, len, "\r", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == 't') _asl_append_string(&out, len, "\t", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == 'v') _asl_append_string(&out, len, "\v", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == '\'') _asl_append_string(&out, len, "\'", ASL_ENCODE_NONE, 0); - else if (mfmt[i] == '\\') _asl_append_string(&out, len, "\\", ASL_ENCODE_NONE, 0); - else if (isdigit(mfmt[i])) - { - oval = mfmt[i] - '0'; - if (isdigit(mfmt[i+1])) + if (_asl_global.notify_token >= 0) { - i++; - oval = (oval * 8) + (mfmt[i] - '0'); - if (isdigit(mfmt[i+1])) - { - i++; - oval = (oval * 8) + (mfmt[i] - '0'); - } + v64 = 0; + status = notify_get_state(_asl_global.notify_token, &v64); + if (status == NOTIFY_STATUS_OK) _asl_global.proc_filter = v64; } - c[0] = oval; - _asl_append_string(&out, len, c, ASL_ENCODE_NONE, 0); } - continue; } - if (mfmt[i] == '\0') break; - c[0] = mfmt[i]; - _asl_append_string(&out, len, c, ASL_ENCODE_NONE, 0); + m = _asl_global.master_filter; + if (m != 0) x = 1; + + r = _asl_global.proc_filter; + if (r != 0) x = 2; + + pthread_mutex_unlock(&_asl_global.lock); } - _asl_append_string(&out, len, "\n", ASL_ENCODE_NONE, 0); + if (local != NULL) *local = l; + if (master != NULL) *master = m; + if (remote != NULL) *remote = r; + if (active != NULL) *active = x; - return out; + return 0; } /* - * asl_send (internal version): send a message + * asl_send: send a message * This routine may be used instead of asl_log() or asl_vlog() if asl_set() * has been used to set all of a message's attributes. + * msg: an aslmsg * returns 0 for success, non-zero for failure */ __private_extern__ int -_asl_send_level_message(aslclient ac, aslmsg msg, int level, const char *message) +_asl_send_message(aslclient ac, asl_msg_t *msg, int slevel, const char *aux_message) { - char *str, *out_raw; vm_address_t out; - uint32_t i, len, outlen, lmask, outstatus, filter, check, senderx, facilityx; + uint32_t i, len, outlen, level, lmask, outstatus, filter, fd_write; uint64_t v64; const char *val; - char *name, *x; + char *name, *x, *str; time_t tick; struct timeval tval; - int status, rc_filter; + int status, check, tunnel; asl_client_t *asl; int use_global_lock; - asl_msg_t *mt, *tmp_msg; - char hname[_POSIX_HOST_NAME_MAX]; kern_return_t kstatus; + char aux_level[64], aux_time[64], aux_nano[64], aux_pid[64], aux_uid[64], aux_gid[64]; + char *aux_option, aux_host[_POSIX_HOST_NAME_MAX]; + asl_msg_aux_t aux; + asl_msg_aux_0_t aux0; use_global_lock = 0; asl = (asl_client_t *)ac; @@ -2768,10 +1015,22 @@ _asl_send_level_message(aslclient ac, aslmsg msg, int level, const char *message use_global_lock = 1; } - if (msg == NULL) return 0; + if (asl->aslfile != NULL) + { + use_global_lock = 1; + } + + level = ASL_LEVEL_DEBUG; + if (slevel >= 0) level = slevel; - val = asl_get(msg, ASL_KEY_LEVEL); - if (val != NULL) level = atoi(val); + val = asl_get((aslmsg)msg, ASL_KEY_LEVEL); + if (val != NULL) + { + check = atoi(val); + if (check < ASL_LEVEL_EMERG) check = ASL_LEVEL_EMERG; + else if (check > ASL_LEVEL_DEBUG) check = ASL_LEVEL_DEBUG; + level = check; + } lmask = ASL_FILTER_MASK(level); @@ -2805,129 +1064,80 @@ _asl_send_level_message(aslclient ac, aslmsg msg, int level, const char *message pthread_mutex_unlock(&_asl_global.lock); } - filter = asl->filter; - rc_filter = 0; + filter = asl->filter & 0xff; + tunnel = (asl->filter & ASL_FILTER_MASK_TUNNEL) >> 8; /* master filter overrides local filter */ if (_asl_global.master_filter != 0) { filter = _asl_global.master_filter; - rc_filter = 1; + tunnel = 1; } /* process-specific filter overrides local and master */ if (_asl_global.proc_filter != 0) { filter = _asl_global.proc_filter; - rc_filter = 1; + tunnel = 1; } - /* - * Copy the message to tmp_msg to make setting values thread-safe + /* + * Time, TimeNanoSec, Host, PID, UID, and GID values get set here. + * Also sets Sender & Facility (if unset) and "ASLOption store" if remote control is active. */ - tmp_msg = calloc(1, sizeof(asl_msg_t)); - if (tmp_msg == NULL) return -1; - tmp_msg->type = ASL_TYPE_MSG; + aux.type = ASL_MSG_TYPE_AUX_0; - mt = (asl_msg_t *)msg; - for (i = 0; i < mt->count; i++) - { - asl_set(tmp_msg, mt->key[i], mt->val[i]); - } + memset(&aux0, 0, sizeof(asl_msg_aux_0_t)); + aux.data.aux0 = &aux0; - /* - * Set Level and Message from parameters. - */ - if (message != NULL) asl_set(tmp_msg, ASL_KEY_MSG, message); - asl_set(tmp_msg, ASL_KEY_LEVEL, _asl_level_string(level)); + aux0.message = aux_message; + + snprintf(aux_level, sizeof(aux_level), "%u", level); + aux0.level = aux_level; - /* - * Time, TimeNanoSec, Host, PID, UID, and GID values get set here - */ - str = NULL; memset(&tval, 0, sizeof(struct timeval)); status = gettimeofday(&tval, NULL); if (status == 0) { - asprintf(&str, "%lu", tval.tv_sec); - if (str != NULL) - { - asl_set(tmp_msg, ASL_KEY_TIME, str); - free(str); - str = NULL; - } - - asprintf(&str, "%lu", tval.tv_usec * 1000); - if (str != NULL) - { - asl_set(tmp_msg, ASL_KEY_TIME_NSEC, str); - free(str); - str = NULL; - } + snprintf(aux_time, sizeof(aux_time), "%lu", tval.tv_sec); + snprintf(aux_nano, sizeof(aux_nano), "%d", tval.tv_usec * 1000); + aux0.time = aux_time; + aux0.nano = aux_nano; } else { tick = time(NULL); - asprintf(&str, "%lu", tick); - if (str != NULL) - { - asl_set(tmp_msg, ASL_KEY_TIME, str); - free(str); - str = NULL; - } - } - - memset(&hname, 0, _POSIX_HOST_NAME_MAX); - if (gethostname(hname, _POSIX_HOST_NAME_MAX) == 0) - { - asl_set(tmp_msg, ASL_KEY_HOST, hname); - } - - str = NULL; - asprintf(&str, "%u", getpid()); - if (str != NULL) - { - asl_set(tmp_msg, ASL_KEY_PID, str); - free(str); + snprintf(aux_time, sizeof(aux_time), "%lu", tick); + aux0.time = aux_time; } - str = NULL; - asprintf(&str, "%d", getuid()); - if (str != NULL) + memset(&aux_host, 0, _POSIX_HOST_NAME_MAX); + if (gethostname(aux_host, _POSIX_HOST_NAME_MAX) == 0) { - asl_set(tmp_msg, ASL_KEY_UID, str); - free(str); + aux0.host = aux_host; } - str = NULL; - asprintf(&str, "%u", getgid()); - if (str != NULL) - { - asl_set(tmp_msg, ASL_KEY_GID, str); - free(str); - } + snprintf(aux_pid, sizeof(aux_pid), "%u", getpid()); + aux0.pid = aux_pid; - senderx = (uint32_t)-1; - facilityx = (uint32_t)-1; + snprintf(aux_uid, sizeof(aux_uid), "%d", getuid()); + aux0.uid = aux_uid; - for (i = 0; (i < tmp_msg->count) && ((senderx == (uint32_t)-1) || (facilityx == (uint32_t)-1)); i++) - { - if (tmp_msg->key[i] == NULL) continue; - if (streq(tmp_msg->key[i], ASL_KEY_SENDER)) senderx = i; - else if (streq(tmp_msg->key[i], ASL_KEY_FACILITY)) facilityx = i; - } + snprintf(aux_gid, sizeof(aux_uid), "%d", getgid()); + aux0.gid = aux_gid; /* * Set Sender if needed */ - if ((senderx == (uint32_t)-1) || (tmp_msg->val[senderx] == NULL)) + status = asl_msg_lookup((asl_msg_t *)msg, ASL_KEY_SENDER, &val, NULL); + if ((status != 0) || (val == NULL)) { if ((ac != NULL) && (ac->name != NULL)) { /* Use the Sender name from the client handle */ - asl_set(tmp_msg, ASL_KEY_SENDER, ac->name); + aux0.sender = ac->name; } else { @@ -2942,47 +1152,44 @@ _asl_send_level_message(aslclient ac, aslmsg msg, int level, const char *message else x = name; pthread_mutex_lock(&_asl_global.lock); - if (_asl_global.sender == NULL) _asl_global.sender = strdup(x); pthread_mutex_unlock(&_asl_global.lock); } } - if (_asl_global.sender != NULL) asl_set(tmp_msg, ASL_KEY_SENDER, _asl_global.sender); - else asl_set(tmp_msg, ASL_KEY_SENDER, "Unknown"); + if (_asl_global.sender != NULL) aux0.sender = _asl_global.sender; + else aux0.sender = "Unknown"; } } /* * Set Facility */ - if ((facilityx == (uint32_t)-1) || (tmp_msg->val[facilityx] == NULL)) + status = asl_msg_lookup((asl_msg_t *)msg, ASL_KEY_FACILITY, &val, NULL); + if ((status != 0) || (val == NULL)) { if ((ac != NULL) && (ac->facility != NULL)) { /* Use the Facility name from the client handle */ - asl_set(tmp_msg, ASL_KEY_FACILITY, ac->facility); + aux0.facility = ac->facility; } } /* Set "ASLOption store" if remote control is active */ - if (rc_filter != 0) + + aux_option = NULL; + + if (tunnel != 0) { - val = asl_get(msg, ASL_KEY_OPTION); + val = asl_get((aslmsg)msg, ASL_KEY_OPTION); if (val == NULL) { - asl_set(tmp_msg, ASL_KEY_OPTION, ASL_OPT_STORE); + aux0.option = ASL_OPT_STORE; } else { - str = NULL; - asprintf(&str, "%s %s", ASL_OPT_STORE, val); - if (str != NULL) - { - asl_set(tmp_msg, ASL_KEY_OPTION, str); - free(str); - str = NULL; - } + asprintf(&aux_option, "%s %s", ASL_OPT_STORE, val); + aux0.option = aux_option; } } @@ -2990,411 +1197,423 @@ _asl_send_level_message(aslclient ac, aslmsg msg, int level, const char *message if (use_global_lock != 0) pthread_mutex_lock(&_asl_global.lock); - if ((filter != 0) && ((filter & lmask) != 0)) + /* + * If there is an aslfile this is a stand-alone file client. + * Just save to the file. + */ + if (asl->aslfile != NULL) { - len = 0; - out_raw = asl_msg_to_string(tmp_msg, &len); + asl_msg_t *merged_msg; + + outstatus = ASL_STATUS_FAILED; + + merged_msg = _asl_merge_msg_aux0(msg, aux0); + if (merged_msg != NULL) + { + outstatus = asl_file_save(asl->aslfile, (aslmsg)merged_msg, &(asl->aslfileid)); + asl->aslfileid++; + asl_msg_release(merged_msg); + } + + if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); + return outstatus; + } + + _asl_global_init(); + if ((_asl_global.server_port != MACH_PORT_NULL) && (filter != 0) && ((filter & lmask) != 0)) + { + len = _asl_msg_string_length_aux(msg, &aux); - if ((out_raw != NULL) && (len != 0)) + if (len != 0) { /* send a mach message to syslogd */ out = 0; outlen = len + 11; - kstatus = vm_allocate(mach_task_self(), &out, outlen + 1, TRUE); + kstatus = vm_allocate(mach_task_self(), &out, outlen, TRUE); if (kstatus == KERN_SUCCESS) { - memset((void *)out, 0, outlen + 1); - snprintf((char *)out, outlen, "%10u %s", len, out_raw); + memset((void *)out, 0, outlen); + snprintf((char *)out, 12, "%10u ", len); - status = 0; - - pthread_mutex_lock(&(_asl_global.port_lock)); - - if (_asl_global.server_port == MACH_PORT_NULL) + status = _asl_msg_to_string_buffer_aux(msg, &aux, (char *)(out + 11), len); + if (status == 0) { - _asl_global.port_count = 0; + if (kstatus == KERN_SUCCESS) kstatus = _asl_server_message(_asl_global.server_port, (caddr_t)out, outlen); + else vm_deallocate(mach_task_self(), out, outlen); - kstatus = bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &_asl_global.server_port); - if (kstatus == KERN_SUCCESS) _asl_global.port_count = 1; - else _asl_global.server_port = MACH_PORT_NULL; + if (kstatus == KERN_SUCCESS) outstatus = 0; + } + else + { + vm_deallocate(mach_task_self(), (vm_address_t)out, outlen); } - - pthread_mutex_unlock(&(_asl_global.port_lock)); - - if (kstatus == KERN_SUCCESS) kstatus = _asl_server_message(_asl_global.server_port, (caddr_t)out, outlen + 1); - else vm_deallocate(mach_task_self(), out, outlen + 1); - - if (kstatus == KERN_SUCCESS) outstatus = 0; } - - free(out_raw); } } + if (aux_option != NULL) free(aux_option); + aux0.option = NULL; + outstatus = 0; - /* write to file descriptors */ - for (i = 0; i < asl->fd_count; i++) + /* messages from syslog() get filtered on the way out to stderr */ + fd_write = 1; + if ((asl->options & ASL_OPT_SYSLOG_LEGACY) && (filter != 0) && ((filter & lmask) == 0)) fd_write = 0; + + if ((fd_write != 0) && (asl->fd_count > 0)) { - if (asl->fd_list[i] < 0) continue; + asl_msg_t *merged_msg; - len = 0; - str = asl_format_message(tmp_msg, asl->fd_mfmt[i], asl->fd_tfmt[i], asl->fd_encoding[i], &len); - if (str == NULL) continue; + /* + * It's easier to merge the aux fields with the msg into a new message + * than to have asl_format_messge deal with two inputs. Since this is + * an infrequently used code path, we pay a small price to merge them + * here and save a lot of code complexity. + */ - status = write(asl->fd_list[i], str, len - 1); - if (status < 0) + merged_msg = _asl_merge_msg_aux0(msg, aux0); + if (merged_msg != NULL) { - asl->fd_list[i] = -1; - outstatus = -1; - } + /* write to file descriptors */ - free(str); - } + for (i = 0; i < asl->fd_count; i++) + { + if (asl->fd_list[i] < 0) continue; + + len = 0; + str = asl_format_message(merged_msg, asl->fd_mfmt[i], asl->fd_tfmt[i], asl->fd_encoding[i], &len); + if (str == NULL) continue; - asl_free((aslmsg)tmp_msg); + status = write(asl->fd_list[i], str, len - 1); + if (status < 0) + { + asl->fd_list[i] = -1; + outstatus = -1; + } + + free(str); + } + + asl_msg_release(merged_msg); + } + } if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); return outstatus; } -/* - * asl_send: send a message - * returns 0 for success, non-zero for failure - */ int asl_send(aslclient ac, aslmsg msg) { - return _asl_send_level_message(ac, msg, ASL_LEVEL_DEBUG, NULL); + return _asl_send_message(ac, (asl_msg_t *)msg, -1, NULL); } -char * -asl_msg_string(aslmsg a) +static int +_asl_aux_save_context(asl_aux_context_t *ctx) { - uint32_t len; + if (ctx == NULL) return -1; + + pthread_mutex_lock(&_asl_global.lock); - return asl_msg_to_string((asl_msg_t *)a, &len); + _asl_global.aux_ctx = (asl_aux_context_t **)reallocf(_asl_global.aux_ctx, (_asl_global.aux_count + 1) * sizeof(asl_aux_context_t *)); + if (_asl_global.aux_ctx == NULL) + { + _asl_global.aux_count = 0; + return -1; + } + + _asl_global.aux_ctx[_asl_global.aux_count++] = ctx; + + pthread_mutex_unlock(&_asl_global.lock); + + return 0; } /* - * asl_free: free a message - * msg: an aslmsg to free + * Creates an auxiliary file that may be used to save arbitrary data. The ASL message msg + * will be saved at the time that the auxiliary file is created. The message will include + * any keys and values found in msg, and it will include the title and Uniform Type + * Identifier specified. Output parameter out_fd will contain the file descriptor of the + * new auxiliary file. */ -void -asl_free(aslmsg a) +static int +_asl_auxiliary(aslmsg msg, const char *title, const char *uti, const char *url, int *out_fd) { - uint32_t i; - asl_msg_t *msg; + asl_msg_t *merged_msg; + asl_msg_aux_t aux; + asl_msg_aux_0_t aux0; + fileport_t fileport; + kern_return_t kstatus; + uint32_t outlen, newurllen, len, where; + int status, fd, fdpair[2]; + caddr_t out, newurl; + dispatch_queue_t pipe_q; + dispatch_io_t pipe_channel; + dispatch_semaphore_t sem; + + aux.type = ASL_MSG_TYPE_AUX_0; - msg = (asl_msg_t *)a; + memset(&aux0, 0, sizeof(asl_msg_aux_0_t)); + aux.data.aux0 = &aux0; - if (msg == NULL) return; + aux0.auxtitle = title; + if (uti == NULL) aux0.auxuti = "public.data"; + else aux0.auxuti = uti; + aux0.auxurl = url; - for (i = 0; i < msg->count; i++) + merged_msg = _asl_merge_msg_aux0((asl_msg_t *)msg, aux0); + if (merged_msg == NULL) return -1; + + /* if (out_fd == NULL), this is from asl_log_auxiliary_location */ + if (out_fd == NULL) { - if (msg->key[i] != NULL) free(msg->key[i]); - if (msg->val[i] != NULL) free(msg->val[i]); + status = _asl_send_message(NULL, merged_msg, -1, NULL); + asl_msg_release(merged_msg); + return status; } - if (msg->count > 0) + where = asl_store_location(); + + if (where == ASL_STORE_LOCATION_MEMORY) { - if (msg->key != NULL) free(msg->key); - if (msg->val != NULL) free(msg->val); - if (msg->op != NULL) free(msg->op); - } + /* create a pipe */ - free(msg); -} + asl_aux_context_t *ctx = (asl_aux_context_t *)calloc(1, sizeof(asl_aux_context_t)); + if (ctx == NULL) return -1; -/* - * Called if there's a malloc error while manipulating a message in asl_set_query. - * Cleans up the key, val, and op fields, sets count to zero. - */ -static void -_asl_clear_msg(asl_msg_t *msg) -{ - uint32_t i; + status = pipe(fdpair); + if (status < 0) + { + free(ctx); + return -1; + } - if (msg == NULL) return; + /* give read end to dispatch_io_read */ + fd = fdpair[0]; + sem = dispatch_semaphore_create(0); + ctx->sem = sem; + ctx->fd = fdpair[1]; - for (i = 0; i < msg->count; i++) - { - if (msg->key != NULL && msg->key[i] != NULL) free(msg->key[i]); - if (msg->val != NULL && msg->val[i] != NULL) free(msg->val[i]); - } + status = _asl_aux_save_context(ctx); + if (status != 0) + { + close(fdpair[0]); + close(fdpair[1]); + dispatch_release(sem); + free(ctx); + return -1; + } - if (msg->key != NULL) free(msg->key); - if (msg->val != NULL) free(msg->val); - if (msg->op != NULL) free(msg->op); + pipe_q = dispatch_queue_create("PipeQ", NULL); + pipe_channel = dispatch_io_create(DISPATCH_IO_STREAM, fd, pipe_q, ^(int err){ + close(fd); + }); - msg->key = NULL; - msg->val = NULL; - msg->op = NULL; + *out_fd = fdpair[1]; - msg->count = 0; -} + dispatch_io_set_low_water(pipe_channel, SIZE_MAX); -/* - * asl_set_query: set arbitrary parameters of a query - * Similar to als_set, but allows richer query operations. - * See ASL_QUERY_OP_* above. - * msg: an aslmsg - * key: attribute key - * value: attribute value - * op: an operation from the set above. - * returns 0 for success, non-zero for failure - */ -int -asl_set_query(aslmsg a, const char *key, const char *val, uint32_t op) -{ - uint32_t i, len; - char *dk, *dv; - asl_msg_t *msg; + dispatch_io_read(pipe_channel, 0, SIZE_MAX, pipe_q, ^(bool done, dispatch_data_t pipedata, int err){ + if (err == 0) + { + size_t len = dispatch_data_get_size(pipedata); + if (len > 0) + { + const char *bytes = NULL; + char *encoded; + + dispatch_data_t md = dispatch_data_create_map(pipedata, (const void **)&bytes, &len); + encoded = asl_core_encode_buffer(bytes, len); + asl_set((aslmsg)merged_msg, ASL_KEY_AUX_DATA, encoded); + free(encoded); + _asl_send_message(NULL, merged_msg, -1, NULL); + asl_msg_release(merged_msg); + dispatch_release(md); + } + } - msg = (asl_msg_t *)a; + if (done) + { + dispatch_semaphore_signal(sem); + dispatch_release(pipe_channel); + dispatch_release(pipe_q); + } + }); - if (msg == NULL) return 0; - if (key == NULL) return -1; + return 0; + } - dv = NULL; + _asl_global_init(); + if (_asl_global.server_port == MACH_PORT_NULL) return -1; - if ((streq(key, ASL_KEY_MSG)) && (val != NULL)) + len = _asl_msg_string_length_aux(merged_msg, NULL); + if (len == 0) { - /* strip trailing newlines */ - dv = strdup(val); - if (dv == NULL) return -1; - - len = strlen(dv); - i = len - 1; - while ((len > 0) && (dv[i] == '\n')) - { - dv[i] = '\0'; - i--; - len--; - } + asl_msg_release(merged_msg); + return -1; } - else if (streq(key, ASL_KEY_LEVEL)) + + outlen = len + 11; + kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&out, outlen, TRUE); + if (kstatus != KERN_SUCCESS) { - if (val == NULL) return -1; - if (val[0] == '\0') return -1; - if ((val[0] >= '0') && (val[0] <= '9')) - { - i = atoi(val); - asprintf(&dv, "%d", i); - if (dv == NULL) return -1; - } - else if (!strcasecmp(val, ASL_STRING_EMERG)) - { - dv = strdup("0"); - if (dv == NULL) return -1; - } - else if (!strcasecmp(val, ASL_STRING_ALERT)) - { - dv = strdup("1"); - if (dv == NULL) return -1; - } - else if (!strcasecmp(val, ASL_STRING_CRIT)) - { - dv = strdup("2"); - if (dv == NULL) return -1; - } - else if (!strcasecmp(val, ASL_STRING_ERR)) - { - dv = strdup("3"); - if (dv == NULL) return -1; - } - else if (!strcasecmp(val, ASL_STRING_WARNING)) - { - dv = strdup("4"); - if (dv == NULL) return -1; - } - else if (!strcasecmp(val, ASL_STRING_NOTICE)) - { - dv = strdup("5"); - if (dv == NULL) return -1; - } - else if (!strcasecmp(val, ASL_STRING_INFO)) - { - dv = strdup("6"); - if (dv == NULL) return -1; - } - else if (!strcasecmp(val, ASL_STRING_DEBUG)) - { - dv = strdup("7"); - if (dv == NULL) return -1; - } - else return -1; + asl_msg_release(merged_msg); + return -1; } - if ((dv == NULL) && (val != NULL)) + memset(out, 0, outlen); + snprintf((char *)out, 12, "%10u ", len); + + status = _asl_msg_to_string_buffer_aux(merged_msg, NULL, (char *)(out + 11), len); + if (status != 0) { - dv = strdup(val); - if (dv == NULL) return -1; + asl_msg_release(merged_msg); + vm_deallocate(mach_task_self(), (vm_address_t)out, outlen); + return -1; } - for (i = 0; i < msg->count; i++) + status = 0; + fileport = MACH_PORT_NULL; + status = KERN_SUCCESS; + + kstatus = _asl_server_create_aux_link(_asl_global.server_port, out, outlen, &fileport, &newurl, &newurllen, &status); + if (kstatus != KERN_SUCCESS) { - if (msg->key[i] == NULL) continue; + asl_msg_release(merged_msg); + return -1; + } - if ((msg->type != ASL_TYPE_QUERY) && (streq(msg->key[i], key))) - { - if (msg->val[i] != NULL) free(msg->val[i]); - msg->val[i] = NULL; - if (val != NULL) msg->val[i] = dv; - if (msg->op != NULL) msg->op[i] = op; - return 0; - } + if (status != 0) + { + asl_msg_release(merged_msg); + return status; } - if (msg->count == 0) + if (newurl != NULL) { - msg->key = (char **)calloc(1, sizeof(char *)); - if (msg->key == NULL) - { - _asl_clear_msg(msg); - return -1; - } + asl_msg_set_key_val(merged_msg, ASL_KEY_AUX_URL, newurl); + vm_deallocate(mach_task_self(), (vm_address_t)newurl, newurllen); + } - msg->val = (char **)calloc(1, sizeof(char *)); - if (msg->val == NULL) - { - _asl_clear_msg(msg); - return -1; - } + if (fileport == MACH_PORT_NULL) + { + asl_msg_release(merged_msg); + return -1; + } - if (msg->type == ASL_TYPE_QUERY) - { - msg->op = (uint32_t *)calloc(1, sizeof(uint32_t)); - if (msg->op == NULL) - { - _asl_clear_msg(msg); - return -1; - } - } + fd = fileport_makefd(fileport); + mach_port_deallocate(mach_task_self(), fileport); + if (fd < 0) + { + asl_msg_release(merged_msg); + status = -1; } else { - msg->key = (char **)reallocf(msg->key, (msg->count + 1) * sizeof(char *)); - if (msg->key == NULL) + asl_aux_context_t *ctx = (asl_aux_context_t *)calloc(1, sizeof(asl_aux_context_t)); + if (ctx == NULL) { - _asl_clear_msg(msg); - return -1; + status = -1; } - - msg->val = (char **)reallocf(msg->val, (msg->count + 1) * sizeof(char *)); - if (msg->val == NULL) + else { - _asl_clear_msg(msg); - return -1; - } + *out_fd = fd; - if (msg->type == ASL_TYPE_QUERY) - { - msg->op = (uint32_t *)reallocf(msg->op, (msg->count + 1) * sizeof(uint32_t)); - if (msg->op == NULL) - { - _asl_clear_msg(msg); - return -1; - } + ctx->fd = fd; + ctx->msg = merged_msg; + + status = _asl_aux_save_context(ctx); } } - dk = strdup(key); - if (dk == NULL) - { - if (dv != NULL) free(dv); - _asl_clear_msg(msg); - return -1; - } + return status; +} - msg->key[msg->count] = dk; - msg->val[msg->count] = dv; - if (msg->op != NULL) msg->op[msg->count] = op; - msg->count++; +int +asl_create_auxiliary_file(aslmsg msg, const char *title, const char *uti, int *out_fd) +{ + if (out_fd == NULL) return -1; - return 0; + return _asl_auxiliary(msg, title, uti, NULL, out_fd); } -/* - * asl_set: set attributes of a message - * msg: an aslmsg - * key: attribute key - * value: attribute value - * returns 0 for success, non-zero for failure - */ int -asl_set(aslmsg msg, const char *key, const char *val) +asl_log_auxiliary_location(aslmsg msg, const char *title, const char *uti, const char *url) { - return asl_set_query(msg, key, val, 0); + return _asl_auxiliary(msg, title, uti, url, NULL); } /* - * asl_unset: remove attributes of a message - * msg: an aslmsg - * key: attribute key - * returns 0 for success, non-zero for failure + * Close an auxiliary file. + * Sends the cached auxiliary message to syslogd. */ int -asl_unset(aslmsg a, const char *key) +asl_close_auxiliary_file(int fd) { - uint32_t i, j; - asl_msg_t *msg; + int i, j, status; + asl_msg_t *aux_msg; + dispatch_semaphore_t aux_sem; - msg = (asl_msg_t *)a; + pthread_mutex_lock(&(_asl_global.lock)); - if (msg == NULL) return 0; - if (key == NULL) return 0; + aux_msg = NULL; + status = -1; - for (i = 0; i < msg->count; i++) + for (i = 0; i < _asl_global.aux_count; i++) { - if (msg->key[i] == NULL) continue; - - if (streq(msg->key[i], key)) + if (_asl_global.aux_ctx[i]->fd == fd) { - free(msg->key[i]); - if (msg->val[i] != NULL) free(msg->val[i]); + status = 0; - for (j = i + 1; j < msg->count; j++, i++) - { - msg->key[i] = msg->key[j]; - msg->val[i] = msg->val[j]; - if (msg->op != NULL) msg->op[i] = msg->op[j]; - } + aux_msg = _asl_global.aux_ctx[i]->msg; + aux_sem = _asl_global.aux_ctx[i]->sem; - msg->count--; + free(_asl_global.aux_ctx[i]); - if (msg->count == 0) + for (j = i + 1; j < _asl_global.aux_count; i++, j++) { - free(msg->key); - msg->key = NULL; + _asl_global.aux_ctx[i] = _asl_global.aux_ctx[j]; + } - free(msg->val); - msg->val = NULL; + _asl_global.aux_count--; - if (msg->op != NULL) free(msg->op); - msg->op = NULL; + if (_asl_global.aux_count == 0) + { + free(_asl_global.aux_ctx); + _asl_global.aux_ctx = NULL; } else { - msg->key = (char **)reallocf(msg->key, msg->count * sizeof(char *)); - if (msg->key == NULL) return -1; - - msg->val = (char **)reallocf(msg->val, msg->count * sizeof(char *)); - if (msg->val == NULL) return -1; - - if (msg->op != NULL) + _asl_global.aux_ctx = (asl_aux_context_t **)reallocf(_asl_global.aux_ctx, _asl_global.aux_count * sizeof(asl_aux_context_t *)); + if (_asl_global.aux_ctx == NULL) { - msg->op = (uint32_t *)reallocf(msg->op, msg->count * sizeof(uint32_t)); - if (msg->op == NULL) return -1; + _asl_global.aux_count = 0; + status = -1; } } - return 0; + break; } } - return 0; + pthread_mutex_unlock(&(_asl_global.lock)); + + close(fd); + + if (aux_msg != NULL) + { + if (_asl_send_message(NULL, aux_msg, -1, NULL) != ASL_STATUS_OK) status = -1; + asl_msg_release(aux_msg); + } + + if (aux_sem != NULL) + { + dispatch_semaphore_wait(aux_sem, DISPATCH_TIME_FOREVER); + dispatch_release(aux_sem); + } + + return status; } /* @@ -3417,9 +1636,10 @@ _asl_search_store(aslclient ac, aslmsg a) { asl_search_result_t query, *out; asl_msg_t *q, *qlist[1]; - uint32_t status, x; + uint32_t status, op; uint64_t last_id, start_id; asl_store_t *store; + const char *val; if (a == NULL) return NULL; @@ -3427,11 +1647,13 @@ _asl_search_store(aslclient ac, aslmsg a) /* check for "ASLMessageId >[=] n" and set start_id */ start_id = 0; - x = _asl_msg_index(q, ASL_KEY_MSG_ID); - if ((x != (uint32_t)-1) && (q->val[x] != NULL) && (q->op != NULL) && (q->op[x] & ASL_QUERY_OP_GREATER)) + val = NULL; + + status = asl_msg_lookup(q, ASL_KEY_MSG_ID, &val, &op); + if ((status == 0) && (val != NULL) && (op & ASL_QUERY_OP_GREATER)) { - if (q->op[x] & ASL_QUERY_OP_EQUAL) start_id = atoi(q->val[x]); - else start_id = atoi(q->val[x]) + 1; + if (op & ASL_QUERY_OP_EQUAL) start_id = atoll(val); + else start_id = atoll(val) + 1; } store = NULL; @@ -3505,7 +1727,7 @@ _asl_search_memory(aslclient ac, aslmsg a) { asl_search_result_t *batch, *out; char *qstr, *str, *res; - uint32_t i, len, reslen, status; + uint32_t len, reslen, status; uint64_t cmax, qmin; kern_return_t kstatus; security_token_t sec; @@ -3513,7 +1735,7 @@ _asl_search_memory(aslclient ac, aslmsg a) if (a == NULL) return 0; - _asl_get_global_server_port(); + _asl_global_init(); if (_asl_global.server_port == MACH_PORT_NULL) return NULL; len = 0; @@ -3528,15 +1750,11 @@ _asl_search_memory(aslclient ac, aslmsg a) else { asprintf(&str, "1\n%s\n", qstr); - len += 4; + len += 3; free(qstr); } - if (str == NULL) - { - _asl_release_global_server_port(); - return NULL; - } + if (str == NULL) return NULL; /* * Fetch a batch of results each time through the loop. @@ -3555,11 +1773,7 @@ _asl_search_memory(aslclient ac, aslmsg a) status = ASL_STATUS_OK; kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&vmstr, len, TRUE); - if (kstatus != KERN_SUCCESS) - { - _asl_release_global_server_port(); - return NULL; - } + if (kstatus != KERN_SUCCESS) return NULL; memmove(vmstr, str, len); @@ -3573,14 +1787,13 @@ _asl_search_memory(aslclient ac, aslmsg a) status = _asl_search_concat_results(batch, &out); if (status != ASL_STATUS_OK) break; - if (i < FETCH_BATCH) break; + if (out->count < FETCH_BATCH) break; - if (cmax > qmin) qmin = cmax + 1; + if (cmax >= qmin) qmin = cmax + 1; } free(str); - _asl_release_global_server_port(); return out; } @@ -3593,7 +1806,7 @@ asl_store_location() uint64_t cmax; security_token_t sec; - _asl_get_global_server_port(); + _asl_global_init(); if (_asl_global.server_port == MACH_PORT_NULL) return ASL_STORE_LOCATION_FILE; res = NULL; @@ -3604,7 +1817,6 @@ asl_store_location() status = ASL_STATUS_OK; kstatus = _asl_server_query(_asl_global.server_port, NULL, 0, 0, -1, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec); - _asl_release_global_server_port(); /* res should never be returned, but just to be certain we don't leak VM ... */ if (res != NULL) vm_deallocate(mach_task_self(), (vm_address_t)res, reslen); @@ -3621,56 +1833,15 @@ asl_search(aslclient ac, aslmsg a) int where; asl_search_result_t *out; - /* prevents fetching and destroying the send right twice if nobody has already lookup up the port */ - _asl_get_global_server_port(); + _asl_global_init(); where = asl_store_location(); if (where == ASL_STORE_LOCATION_FILE) out = _asl_search_store(ac, a); else out = _asl_search_memory(ac, a); - _asl_release_global_server_port(); return out; } -/* - * aslresponse_next: Iterate over responses returned from asl_search() - * a: a response returned from asl_search(); - * returns: The next log message (an aslmsg) or NULL on failure - */ -aslmsg -aslresponse_next(aslresponse r) -{ - asl_search_result_t *res; - aslmsg m; - - res = (asl_search_result_t *)r; - if (res == NULL) return NULL; - - if (res->curr >= res->count) return NULL; - m = res->msg[res->curr]; - res->curr++; - - return m; -} - -/* - * aslresponse_free: Free a response returned from asl_search() - * a: a response returned from asl_search() - */ -void -aslresponse_free(aslresponse r) -{ - asl_search_result_t *res; - uint32_t i; - - res = (asl_search_result_t *)r; - if (res == NULL) return; - - for (i = 0; i < res->count; i++) asl_free(res->msg[i]); - free(res->msg); - free(res); -} - int asl_syslog_faciliy_name_to_num(const char *name) { @@ -3759,6 +1930,9 @@ asl_syslog_faciliy_num_to_name(int n) #define SECONDS_PER_DAY 86400 #define SECONDS_PER_WEEK 604800 +static regex_t rex_canon, rex_ctime, rex_abs, rex_rel; +static int reg_status = 0; + /* * We use the last letter in the month name to determine * the month number (0-11). There are two collisions: @@ -3794,51 +1968,36 @@ _month_num(char *s) time_t asl_parse_time(const char *in) { - int len, y, status, rflags; + int len, y; struct tm t; time_t tick, delta, factor; char *str, *p, *x; - static regex_t rex_canon, rex_ctime, rex_abs, rex_rel; - static int init_canon = 0; - static int init_ctime = 0; - static int init_abs = 0; - static int init_rel = 0; + static dispatch_once_t once; if (in == NULL) return -1; - rflags = REG_EXTENDED | REG_NOSUB | REG_ICASE; + dispatch_once(&once, ^{ + int status; + int rflags = REG_EXTENDED | REG_NOSUB | REG_ICASE; - if (init_canon == 0) - { memset(&rex_canon, 0, sizeof(regex_t)); status = regcomp(&rex_canon, CANONICAL_TIME_REX, rflags); - if (status != 0) return -1; - init_canon = 1; - } + if (status != 0) reg_status = -1; - if (init_ctime == 0) - { memset(&rex_ctime, 0, sizeof(regex_t)); status = regcomp(&rex_ctime, CTIME_REX, rflags); - if (status != 0) return -1; - init_ctime = 1; - } + if (status != 0) reg_status = -1; - if (init_abs == 0) - { memset(&rex_abs, 0, sizeof(regex_t)); status = regcomp(&rex_abs, ABSOLUTE_TIME_REX, rflags); - if (status != 0) return -1; - init_abs = 1; - } + if (status != 0) reg_status = -1; - if (init_rel == 0) - { memset(&rex_rel, 0, sizeof(regex_t)); status = regcomp(&rex_rel, RELATIVE_TIME_REX, rflags); - if (status != 0) return -1; - init_rel = 1; - } + if (status != 0) reg_status = -1; + }); + + if (reg_status < 0) return -1; len = strlen(in) + 1; diff --git a/gen/asl_core.c b/gen/asl_core.c index b5871f1..ec2c4ac 100644 --- a/gen/asl_core.c +++ b/gen/asl_core.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include @@ -248,3 +249,177 @@ asl_core_new_msg_id(uint64_t start) return out; } + +/* + * asl_core_encode_buffer + * encode arbitrary data as a C string without embedded zero (nul) characters + * + * The routine computes a histogram of the input buffer and finds + * the two least frequently used non-nul chars (L[0] and L[1]). + * + * L[0] is used to stand in for nul. + * L[1] is used as the escape character. + * Occurrences of nul in the data are encoded as L[0] + * Occurrences of L[0] in the data are encoded as the sequence L[1] 1. + * Occurrences of L[1] in the data are encoded as the sequence L[1] 2. + * + * The output string is preceded by L[0] L[1], and is nul terminated. + * The output length is 2 + n + N(L[0]) + N(L[1]) + 1 + * where N(x) is the number of occurrences of x in the input string. + * The worst case occurs when all characters are equally frequent, + * In that case the output size will less that 1% larger than the input. + */ +char * +asl_core_encode_buffer(const char *in, uint32_t len) +{ + char *str; + uint32_t i, j, k, outlen, breakit, min, hist[256]; + uint32_t lfu[2], save[2]; + uint8_t v; + + if (in == NULL) return NULL; + if (len == 0) return NULL; + + memset(hist, 0, sizeof(hist)); + save[0] = 0; + save[1] = 0; + + for (i = 0; i < len; i++) + { + v = in[i]; + hist[v]++; + } + + for (j = 0; j < 2; j++) + { + lfu[j] = 1; + min = hist[1]; + + for (i = 2; i < 256; i++) + { + if (hist[i] < min) + { + lfu[j] = i; + min = hist[i]; + + /* + * Stop if there are no occurances or character i in the input. + * The minimum will never be less than zero. + */ + if (min == 0) break; + + /* + * When looking for the second least frequently used character, + * stop scanning if we hit the same minimum as we saw in the first + * pass. There will be no smaller values. + */ + if ((j == 1) && (min == save[0])) break; + } + } + + save[j] = hist[lfu[j]]; + hist[lfu[j]] = (uint32_t)-1; + } + + outlen = 2 + len + save[0] + save[1] + 1; + + str = malloc(outlen); + if (str == NULL) return NULL; + + str[outlen - 1] = '\0'; + + str[0] = lfu[0]; + str[1] = lfu[1]; + + j = 2; + + for (i = 0; i < len; i++) + { + v = in[i]; + if (v == 0) + { + str[j++] = lfu[0]; + continue; + } + + breakit = 0; + for (k = 0; (k < 2) && (breakit == 0); k++) + { + if (v == lfu[k]) + { + str[j++] = lfu[1]; + str[j++] = k + 1; + breakit = 1; + } + } + + if (breakit == 1) continue; + + str[j++] = v; + } + + return str; +} + +/* + * asl_core_decode_buffer + * decode a string produced by asl_encode_buffer to recreate the original data + */ +int32_t +asl_core_decode_buffer(const char *in, char **buf, uint32_t *len) +{ + uint8_t v; + uint32_t i, j, n, outlen; + uint32_t lfu[2]; + char *out; + + if (buf == NULL) return -1; + if (len == NULL) return -1; + + lfu[0] = in[0]; + lfu[1] = in[1]; + + outlen = 0; + + /* strip trailing nul */ + n = strlen(in); + + /* determine output length and check for invalid input */ + for (i = 2; i < n; i++) + { + if (in[i] == lfu[1]) + { + if ((i + 1) == n) return -1; + i++; + if ((in[i] < 1) || (in[i] > 2)) return -1; + outlen++; + } + else outlen++; + } + + if (outlen == 0) return -1; + + out = malloc(outlen); + if (out == NULL) return -1; + + j = 0; + for (i = 2; i < n; i++) + { + v = in[i]; + if (v == lfu[0]) + { + out[j++] = 0; + } + else if (v == lfu[1]) + { + i++; + v = in[i]; + out[j++] = lfu[v - 1]; + } + else out[j++] = v; + } + + *len = outlen; + *buf = out; + return 0; +} diff --git a/gen/asl_core.h b/gen/asl_core.h index 6b0dbc1..10292fb 100644 --- a/gen/asl_core.h +++ b/gen/asl_core.h @@ -26,6 +26,7 @@ */ #include +#include #define asl_msg_list_t asl_search_result_t @@ -74,11 +75,13 @@ #define ASL_QUERY_MATCH_FALSE 0x40000000 #define ASL_QUERY_MATCH_ERROR 0x20000000 -uint32_t asl_core_string_hash(const char *str, uint32_t len); -const char *asl_core_error(uint32_t code); -uint32_t asl_core_check_access(int32_t msgu, int32_t msgg, int32_t readu, int32_t readg, uint16_t flags); -uint64_t asl_core_htonq(uint64_t n); -uint64_t asl_core_ntohq(uint64_t n); -uint64_t asl_core_new_msg_id(uint64_t start); +uint32_t asl_core_string_hash(const char *str, uint32_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +const char *asl_core_error(uint32_t code) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_core_check_access(int32_t msgu, int32_t msgg, int32_t readu, int32_t readg, uint16_t flags) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint64_t asl_core_htonq(uint64_t n) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint64_t asl_core_ntohq(uint64_t n)__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint64_t asl_core_new_msg_id(uint64_t start) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +char *asl_core_encode_buffer(const char *in, uint32_t len) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0); +int32_t asl_core_decode_buffer(const char *in, char **buf, uint32_t *len) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0); -#endif __ASL_CORE_H__ \ No newline at end of file +#endif __ASL_CORE_H__ diff --git a/gen/asl_file.c b/gen/asl_file.c index f6c6fbb..6c7c63a 100644 --- a/gen/asl_file.c +++ b/gen/asl_file.c @@ -1,23 +1,22 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 2007 Apple Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -32,13 +31,16 @@ #include #include #include +#include +#include +#include #include #include #include #include extern time_t asl_parse_time(const char *str); -extern int asl_msg_cmp(asl_msg_t *a, asl_msg_t *b); +extern int asl_msg_cmp(aslmsg a, aslmsg b); #define forever for(;;) #define MILLION 1000000 @@ -208,135 +210,260 @@ asl_file_close(asl_file_t *s) return ASL_STATUS_OK; } -uint32_t -asl_file_open_write(const char *path, mode_t mode, uid_t uid, gid_t gid, asl_file_t **s) +__private_extern__ uint32_t +asl_file_open_write_fd(int fd, asl_file_t **s) { time_t now; - int i, status, fd; - struct stat sb; + int status; char buf[DB_HEADER_LEN]; asl_file_t *out; - uint32_t aslstatus, vers; - memset(&sb, 0, sizeof(struct stat)); + if (fd < 0) return ASL_STATUS_FAILED; + if (s == NULL) return ASL_STATUS_FAILED; - status = stat(path, &sb); - if (status == 0) + out = (asl_file_t *)calloc(1, sizeof(asl_file_t)); + if (out == NULL) return ASL_STATUS_NO_MEMORY; + + out->store = fdopen(fd, "w+"); + if (out->store == NULL) { - /* XXX Check that mode, uid, and gid are correct */ - out = (asl_file_t *)calloc(1, sizeof(asl_file_t)); - if (out == NULL) return ASL_STATUS_NO_MEMORY; + free(out); + return ASL_STATUS_FAILED; + } - out->store = fopen(path, "r+"); - if (out->store == NULL) - { - free(out); - return ASL_STATUS_FAILED; - } + memset(buf, 0, sizeof(buf)); + memcpy(buf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN); - i = fread(buf, DB_HEADER_LEN, 1, out->store); - if (i < 1) - { - asl_file_close(out); - return ASL_STATUS_READ_FAILED; - } + _asl_put_32(DB_VERSION, buf + DB_HEADER_VERS_OFFSET); - /* check cookie */ - if (strncmp(buf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN)) - { - asl_file_close(out); - return ASL_STATUS_INVALID_STORE; - } + now = time(NULL); + out->dob = now; + _asl_put_64(out->dob, buf + DB_HEADER_TIME_OFFSET); - /* check version */ - vers = _asl_get_32(buf + DB_HEADER_VERS_OFFSET); - if (vers != DB_VERSION) - { - asl_file_close(out); - return ASL_STATUS_INVALID_STORE; - } + _asl_put_32(CACHE_SIZE, buf + DB_HEADER_CSIZE_OFFSET); - out->dob = _asl_get_64(buf + DB_HEADER_TIME_OFFSET); - out->first = _asl_get_64(buf + DB_HEADER_FIRST_OFFSET); - out->last = _asl_get_64(buf + DB_HEADER_LAST_OFFSET); - out->file_size = (size_t)sb.st_size; + status = fwrite(buf, sizeof(buf), 1, out->store); + if (status != 1) + { + fclose(out->store); + free(out); + return ASL_STATUS_FAILED; + } - /* detect bogus last pointer */ - if (out->last >= out->file_size) out->last = 0; + /* flush data */ + fflush(out->store); - aslstatus = asl_file_read_set_position(out, ASL_FILE_POSITION_LAST); - if (aslstatus != ASL_STATUS_OK) - { - asl_file_close(out); - return aslstatus; - } + out->file_size = sizeof(buf); - out->prev = out->cursor; - status = fseeko(out->store, 0, SEEK_END); - if (status != 0) - { - asl_file_close(out); - return ASL_STATUS_READ_FAILED; - } + /* scratch buffer for file writes (we test for NULL before using it) */ + out->scratch = malloc(SCRATCH_BUFFER_SIZE); - out->file_size = (size_t)ftello(out->store); + *s = out; - /* scratch buffer for file writes (we test for NULL before using it) */ - out->scratch = malloc(SCRATCH_BUFFER_SIZE); + return ASL_STATUS_OK; +} - *s = out; +__private_extern__ int +asl_file_create(const char *path, uid_t uid, gid_t gid, mode_t mode) +{ + acl_t acl; + uuid_t uuid; + acl_entry_t entry; + acl_permset_t perms; + int status; + int fd = -1; - return ASL_STATUS_OK; - } + acl = acl_init(1); - if (errno != ENOENT) return ASL_STATUS_FAILED; + if (gid != 0) + { + status = mbr_gid_to_uuid(gid, uuid); + if (status != 0) goto asl_file_create_return; + + status = acl_create_entry_np(&acl, &entry, ACL_FIRST_ENTRY); + if (status != 0) goto asl_file_create_return; + + status = acl_set_tag_type(entry, ACL_EXTENDED_ALLOW); + if (status != 0) goto asl_file_create_return; + + status = acl_set_qualifier(entry, &uuid); + if (status != 0) goto asl_file_create_return; + + status = acl_get_permset(entry, &perms); + if (status != 0) goto asl_file_create_return; + + status = acl_add_perm(perms, ACL_READ_DATA); + if (status != 0) goto asl_file_create_return; + } + + if (uid != 0) + { + status = mbr_uid_to_uuid(uid, uuid); + if (status != 0) goto asl_file_create_return; + + status = acl_create_entry_np(&acl, &entry, ACL_FIRST_ENTRY); + if (status != 0) goto asl_file_create_return; + + status = acl_set_tag_type(entry, ACL_EXTENDED_ALLOW); + if (status != 0) goto asl_file_create_return; + + status = acl_set_qualifier(entry, &uuid); + if (status != 0) goto asl_file_create_return; + + status = acl_get_permset(entry, &perms); + if (status != 0) goto asl_file_create_return; + + status = acl_add_perm(perms, ACL_READ_DATA); + if (status != 0) goto asl_file_create_return; + } fd = open(path, O_RDWR | O_CREAT | O_EXCL, mode); - if (fd < 0) return ASL_STATUS_FAILED; + if (fd < 0) goto asl_file_create_return; - status = fchown(fd, uid, gid); + status = acl_set_fd(fd, acl); if (status != 0) { close(fd); + fd = -1; unlink(path); - return ASL_STATUS_FAILED; } - out = (asl_file_t *)calloc(1, sizeof(asl_file_t)); - if (out == NULL) return ASL_STATUS_NO_MEMORY; +asl_file_create_return: + + acl_free(acl); + return fd; +} - out->store = fdopen(fd, "w+"); - if (out->store == NULL) +uint32_t +asl_file_open_write(const char *path, mode_t mode, uid_t uid, gid_t gid, asl_file_t **s) +{ + int i, status, fd; + struct stat sb; + char buf[DB_HEADER_LEN]; + asl_file_t *out; + uint32_t aslstatus, vers, last_len; + off_t off; + + memset(&sb, 0, sizeof(struct stat)); + + status = stat(path, &sb); + if (status == 0) { - free(out); - return ASL_STATUS_FAILED; - } + /* must be a plain file */ + if (!S_ISREG(sb.st_mode)) return ASL_STATUS_INVALID_STORE; - memset(buf, 0, sizeof(buf)); - memcpy(buf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN); + if (sb.st_size == 0) + { + fd = open(path, O_RDWR | O_EXCL, mode); + if (fd < 0) return ASL_STATUS_FAILED; - _asl_put_32(DB_VERSION, buf + DB_HEADER_VERS_OFFSET); + return asl_file_open_write_fd(fd, s); + } + else + { + /* XXX Check that mode, uid, and gid are correct */ + out = (asl_file_t *)calloc(1, sizeof(asl_file_t)); + if (out == NULL) return ASL_STATUS_NO_MEMORY; - now = time(NULL); - out->dob = now; - _asl_put_64(out->dob, buf + DB_HEADER_TIME_OFFSET); + out->store = fopen(path, "r+"); + if (out->store == NULL) + { + free(out); + return ASL_STATUS_FAILED; + } - _asl_put_32(CACHE_SIZE, buf + DB_HEADER_CSIZE_OFFSET); + i = fread(buf, DB_HEADER_LEN, 1, out->store); + if (i < 1) + { + asl_file_close(out); + return ASL_STATUS_READ_FAILED; + } - status = fwrite(buf, sizeof(buf), 1, out->store); - if (status != 1) + /* check cookie */ + if (strncmp(buf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN)) + { + asl_file_close(out); + return ASL_STATUS_INVALID_STORE; + } + + /* check version */ + vers = _asl_get_32(buf + DB_HEADER_VERS_OFFSET); + if (vers != DB_VERSION) + { + asl_file_close(out); + return ASL_STATUS_INVALID_STORE; + } + + out->dob = _asl_get_64(buf + DB_HEADER_TIME_OFFSET); + out->first = _asl_get_64(buf + DB_HEADER_FIRST_OFFSET); + out->last = _asl_get_64(buf + DB_HEADER_LAST_OFFSET); + out->file_size = (size_t)sb.st_size; + + /* + * Detect bogus last pointer and check for odd-sized files. + * Setting out->last to zero forces asl_file_read_set_position to + * follow the linked list of records in the file to the last record. + * It's slower, but it's better at preventing crashes in corrupt files. + */ + + /* records are at least MSG_RECORD_FIXED_LENGTH bytes */ + if ((out->last + MSG_RECORD_FIXED_LENGTH) > out->file_size) + { + out->last = 0; + } + else + { + /* read last record length and make sure the file is at least that large */ + off = out->last + RECORD_TYPE_LEN; + status = asl_file_read_uint32(out, off, &last_len); + if (status != ASL_STATUS_OK) + { + asl_file_close(out); + return status; + } + + if ((out->last + last_len) > out->file_size) out->last = 0; + } + + aslstatus = asl_file_read_set_position(out, ASL_FILE_POSITION_LAST); + if (aslstatus != ASL_STATUS_OK) + { + asl_file_close(out); + return aslstatus; + } + + out->prev = out->cursor; + status = fseeko(out->store, 0, SEEK_END); + if (status != 0) + { + asl_file_close(out); + return ASL_STATUS_READ_FAILED; + } + + out->file_size = (size_t)ftello(out->store); + + /* scratch buffer for file writes (we test for NULL before using it) */ + out->scratch = malloc(SCRATCH_BUFFER_SIZE); + + *s = out; + + return ASL_STATUS_OK; + } + } + else if (errno != ENOENT) { - fclose(out->store); - free(out); - unlink(path); + /* unexpected status */ return ASL_STATUS_FAILED; } - out->file_size = sizeof(buf); + /* the file does not exist */ + fd = asl_file_create(path, uid, gid, mode); + if (fd < 0) return ASL_STATUS_FAILED; - *s = out; + aslstatus = asl_file_open_write_fd(fd, s); + if (aslstatus != ASL_STATUS_OK) unlink(path); - return ASL_STATUS_OK; + return aslstatus; } uint32_t @@ -452,6 +579,9 @@ asl_file_string_encode(asl_file_t *s, const char *str, uint64_t *out) i = fwrite(str, len + 1, 1, s->store); if (i != 1) return ASL_STATUS_WRITE_FAILED; + /* flush data */ + fflush(s->store); + /* create file_string_t and insert into the cache */ sx = (file_string_t *)calloc(1, offsetof(file_string_t, str) + len + 1); if (sx == NULL) return ASL_STATUS_NO_MEMORY; @@ -493,20 +623,24 @@ asl_file_string_encode(asl_file_t *s, const char *str, uint64_t *out) * Creates and caches strings. */ uint32_t -asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) +asl_file_save(asl_file_t *s, aslmsg in, uint64_t *mid) { char *buf, *p; - uint32_t len, i, status; + uint32_t i, len, x, status; file_record_t r; uint64_t k, v; uint64_t *kvlist; off_t off; + asl_msg_t *msg; + const char *key, *val; if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (msg == NULL) return ASL_STATUS_INVALID_MESSAGE; + if (in == NULL) return ASL_STATUS_INVALID_MESSAGE; if (s->flags & ASL_FILE_FLAG_READ_ONLY) return ASL_STATUS_READ_ONLY; + msg = (asl_msg_t *)in; + memset(&r, 0, sizeof(file_record_t)); r.flags = 0; @@ -521,25 +655,28 @@ asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) r.prev = s->prev; kvlist = NULL; - for (i = 0; i < msg->count; i++) + key = NULL; + val = NULL; + + for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL)) { - if (msg->key[i] == NULL) + if (key == NULL) { continue; } - else if (!strcmp(msg->key[i], ASL_KEY_TIME)) + else if (!strcmp(key, ASL_KEY_TIME)) { - if (msg->val[i] != NULL) r.time = asl_parse_time(msg->val[i]); + if (val != NULL) r.time = asl_parse_time(val); } - else if (!strcmp(msg->key[i], ASL_KEY_TIME_NSEC)) + else if (!strcmp(key, ASL_KEY_TIME_NSEC)) { - if (msg->val[i] != NULL) r.nano = atoi(msg->val[i]); + if (val != NULL) r.nano = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_HOST)) + else if (!strcmp(key, ASL_KEY_HOST)) { - if (msg->val[i] != NULL) + if (val != NULL) { - status = asl_file_string_encode(s, msg->val[i], &(r.host)); + status = asl_file_string_encode(s, val, &(r.host)); if (status != ASL_STATUS_OK) { if (kvlist != NULL) free(kvlist); @@ -547,11 +684,11 @@ asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) } } } - else if (!strcmp(msg->key[i], ASL_KEY_SENDER)) + else if (!strcmp(key, ASL_KEY_SENDER)) { - if (msg->val[i] != NULL) + if (val != NULL) { - status = asl_file_string_encode(s, msg->val[i], &(r.sender)); + status = asl_file_string_encode(s, val, &(r.sender)); if (status != ASL_STATUS_OK) { if (kvlist != NULL) free(kvlist); @@ -559,31 +696,31 @@ asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) } } } - else if (!strcmp(msg->key[i], ASL_KEY_PID)) + else if (!strcmp(key, ASL_KEY_PID)) { - if (msg->val[i] != NULL) r.pid = atoi(msg->val[i]); + if (val != NULL) r.pid = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_REF_PID)) + else if (!strcmp(key, ASL_KEY_REF_PID)) { - if (msg->val[i] != NULL) r.refpid = atoi(msg->val[i]); + if (val != NULL) r.refpid = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_UID)) + else if (!strcmp(key, ASL_KEY_UID)) { - if (msg->val[i] != NULL) r.uid = atoi(msg->val[i]); + if (val != NULL) r.uid = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_GID)) + else if (!strcmp(key, ASL_KEY_GID)) { - if (msg->val[i] != NULL) r.gid = atoi(msg->val[i]); + if (val != NULL) r.gid = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_LEVEL)) + else if (!strcmp(key, ASL_KEY_LEVEL)) { - if (msg->val[i] != NULL) r.level = atoi(msg->val[i]); + if (val != NULL) r.level = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_MSG)) + else if (!strcmp(key, ASL_KEY_MSG)) { - if (msg->val[i] != NULL) + if (val != NULL) { - status = asl_file_string_encode(s, msg->val[i], &(r.message)); + status = asl_file_string_encode(s, val, &(r.message)); if (status != ASL_STATUS_OK) { if (kvlist != NULL) free(kvlist); @@ -591,11 +728,11 @@ asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) } } } - else if (!strcmp(msg->key[i], ASL_KEY_FACILITY)) + else if (!strcmp(key, ASL_KEY_FACILITY)) { - if (msg->val[i] != NULL) + if (val != NULL) { - status = asl_file_string_encode(s, msg->val[i], &(r.facility)); + status = asl_file_string_encode(s, val, &(r.facility)); if (status != ASL_STATUS_OK) { if (kvlist != NULL) free(kvlist); @@ -603,11 +740,11 @@ asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) } } } - else if (!strcmp(msg->key[i], ASL_KEY_REF_PROC)) + else if (!strcmp(key, ASL_KEY_REF_PROC)) { - if (msg->val[i] != NULL) + if (val != NULL) { - status = asl_file_string_encode(s, msg->val[i], &(r.refproc)); + status = asl_file_string_encode(s, val, &(r.refproc)); if (status != ASL_STATUS_OK) { if (kvlist != NULL) free(kvlist); @@ -615,11 +752,11 @@ asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) } } } - else if (!strcmp(msg->key[i], ASL_KEY_SESSION)) + else if (!strcmp(key, ASL_KEY_SESSION)) { - if (msg->val[i] != NULL) + if (val != NULL) { - status = asl_file_string_encode(s, msg->val[i], &(r.session)); + status = asl_file_string_encode(s, val, &(r.session)); if (status != ASL_STATUS_OK) { if (kvlist != NULL) free(kvlist); @@ -627,33 +764,33 @@ asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) } } } - else if (!strcmp(msg->key[i], ASL_KEY_READ_UID)) + else if (!strcmp(key, ASL_KEY_READ_UID)) { - if (((r.flags & ASL_MSG_FLAG_READ_UID_SET) == 0) && (msg->val[i] != NULL)) + if (((r.flags & ASL_MSG_FLAG_READ_UID_SET) == 0) && (val != NULL)) { - r.ruid = atoi(msg->val[i]); + r.ruid = atoi(val); r.flags |= ASL_MSG_FLAG_READ_UID_SET; } } - else if (!strcmp(msg->key[i], ASL_KEY_READ_GID)) + else if (!strcmp(key, ASL_KEY_READ_GID)) { - if (((r.flags & ASL_MSG_FLAG_READ_GID_SET) == 0) && (msg->val[i] != NULL)) + if (((r.flags & ASL_MSG_FLAG_READ_GID_SET) == 0) && (val != NULL)) { - r.rgid = atoi(msg->val[i]); + r.rgid = atoi(val); r.flags |= ASL_MSG_FLAG_READ_GID_SET; } } - else if (!strcmp(msg->key[i], ASL_KEY_MSG_ID)) + else if (!strcmp(key, ASL_KEY_MSG_ID)) { - if (s->flags & ASL_FILE_FLAG_PRESERVE_MSG_ID) *mid = atoll(msg->val[i]); + if (s->flags & ASL_FILE_FLAG_PRESERVE_MSG_ID) *mid = atoll(val); } - else if (!strcmp(msg->key[i], ASL_KEY_OPTION)) + else if (!strcmp(key, ASL_KEY_OPTION)) { /* ignore - we don't save ASLOption */ } else { - status = asl_file_string_encode(s, msg->key[i], &k); + status = asl_file_string_encode(s, key, &k); if (status != ASL_STATUS_OK) { if (kvlist != NULL) free(kvlist); @@ -661,9 +798,9 @@ asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) } v = 0; - if (msg->val[i] != NULL) + if (val != NULL) { - status = asl_file_string_encode(s, msg->val[i], &v); + status = asl_file_string_encode(s, val, &v); if (status != ASL_STATUS_OK) { if (kvlist != NULL) free(kvlist); @@ -834,6 +971,9 @@ asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) status = fseeko(s->store, 0, SEEK_END); if (status != 0) return ASL_STATUS_WRITE_FAILED; + /* flush data */ + fflush(s->store); + s->file_size = (size_t)ftello(s->store); s->prev = s->last; @@ -1165,7 +1305,7 @@ asl_file_open_read(const char *path, asl_file_t **s) asl_file_t *out; FILE *f; int i; - uint32_t status, vers; + uint32_t status, vers, last_len; char buf[DB_HEADER_LEN]; off_t off; asl_legacy1_t *legacy; @@ -1212,6 +1352,7 @@ asl_file_open_read(const char *path, asl_file_t **s) return ASL_STATUS_NO_MEMORY; } + out->store = f; out->flags = ASL_FILE_FLAG_READ_ONLY; out->version = vers; @@ -1228,10 +1369,33 @@ asl_file_open_read(const char *path, asl_file_t **s) out->last = _asl_get_64(buf + DB_HEADER_LAST_OFFSET); out->file_size = (size_t)sb.st_size; - /* detect bogus last pointer */ - if (out->last >= out->file_size) out->last = 0; + /* + * Detect bogus last pointer and check for odd-sized files. + * Setting out->last to zero forces us to follow the linked + * list of records in the file to the last record. That's + * done in the set_position code. It's a bit slower, but it's + * better at preventing crashes in corrupt files. + */ - out->store = f; + /* records are at least MSG_RECORD_FIXED_LENGTH bytes */ + if ((out->last + MSG_RECORD_FIXED_LENGTH) > out->file_size) + { + out->last = 0; + } + else + { + /* read last record length and make sure the file is at least that large */ + off = out->last + RECORD_TYPE_LEN; + status = asl_file_read_uint32(out, off, &last_len); + if (status != ASL_STATUS_OK) + { + fclose(out->store); + free(out); + return status; + } + + if ((out->last + last_len) > out->file_size) out->last = 0; + } out->cursor = out->first; if (out->cursor != 0) @@ -1240,7 +1404,8 @@ asl_file_open_read(const char *path, asl_file_t **s) status = asl_file_read_uint64(out, off, &(out->cursor_xid)); if (status != ASL_STATUS_OK) { - fclose(f); + fclose(out->store); + free(out); return status; } } @@ -1306,7 +1471,7 @@ asl_file_read_set_position_last(asl_file_t *s) if (status != ASL_STATUS_OK) return status; /* detect bogus next pointer */ - if (next >= s->file_size) next = 0; + if (((next + MSG_RECORD_FIXED_LENGTH) > s->file_size) || (next <= s->cursor)) next = 0; if (next == 0) { @@ -1324,6 +1489,7 @@ asl_file_read_set_position_last(asl_file_t *s) uint32_t asl_file_read_set_position(asl_file_t *s, uint32_t pos) { + uint64_t next; uint32_t len, status; off_t off; @@ -1362,12 +1528,16 @@ asl_file_read_set_position(asl_file_t *s, uint32_t pos) /* * read offset of next / previous */ - status = asl_file_read_uint64(s, off, &(s->cursor)); + next = 0; + status = asl_file_read_uint64(s, off, &next); if (status != ASL_STATUS_OK) return ASL_STATUS_READ_FAILED; /* detect bogus next pointer */ - if (s->cursor >= s->file_size) s->cursor = 0; + if ((next + MSG_RECORD_FIXED_LENGTH) > s->file_size) next = 0; + else if ((pos == ASL_FILE_POSITION_PREVIOUS) && (next >= s->cursor)) next = 0; + else if ((pos == ASL_FILE_POSITION_NEXT) && (next <= s->cursor)) next = 0; + s->cursor = next; if (s->cursor == 0) return ASL_STATUS_NO_RECORDS; /* read ID of the record */ @@ -1436,7 +1606,7 @@ asl_file_fetch(asl_file_t *s, uint64_t mid, aslmsg *msg) return asl_file_fetch_pos(s, s->cursor, 1, msg); } -uint64_t +__private_extern__ uint64_t asl_file_cursor(asl_file_t *s) { if (s == NULL) return 0; @@ -1446,7 +1616,7 @@ asl_file_cursor(asl_file_t *s) return s->cursor_xid; } -uint32_t +__private_extern__ uint32_t asl_file_match_start(asl_file_t *s, uint64_t start_id, int32_t direction) { uint32_t status, d; @@ -1474,8 +1644,8 @@ asl_file_match_start(asl_file_t *s, uint64_t start_id, int32_t direction) return status; } -uint32_t -asl_file_match_next(asl_file_t *s, aslresponse query, asl_msg_t **msg, uint64_t *last_id, int32_t direction) +__private_extern__ uint32_t +asl_file_match_next(asl_file_t *s, aslresponse query, aslmsg *msg, uint64_t *last_id, int32_t direction) { uint32_t status, d, i, do_match, did_match; aslmsg m; @@ -1511,7 +1681,7 @@ asl_file_match_next(asl_file_t *s, aslresponse query, asl_msg_t **msg, uint64_t for (i = 0; (i < query->count) && (did_match == 0); i++) { - did_match = asl_msg_cmp(query->msg[i], m); + did_match = asl_msg_cmp((aslmsg)(query->msg[i]), m); } } @@ -1529,7 +1699,7 @@ uint32_t asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) { uint32_t status, d, i, do_match, did_match, rescount; - asl_msg_t *m; + aslmsg m; if (s == NULL) return ASL_STATUS_INVALID_STORE; if (res == NULL) return ASL_STATUS_INVALID_ARG; @@ -1581,7 +1751,7 @@ asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *las for (i = 0; (i < query->count) && (did_match == 0); i++) { - did_match = asl_msg_cmp(query->msg[i], m); + did_match = asl_msg_cmp((aslmsg)query->msg[i], m); } } @@ -1592,7 +1762,7 @@ asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *las { *res = (aslresponse)calloc(1, sizeof(aslresponse)); if (*res == NULL) return ASL_STATUS_NO_MEMORY; - (*res)->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *)); + (*res)->msg = (asl_msg_t **)calloc(1, sizeof(aslmsg)); if ((*res)->msg == NULL) { free(*res); @@ -1601,7 +1771,7 @@ asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *las } else { - (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(asl_msg_t *)); + (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(aslmsg)); if ((*res)->msg == NULL) { free(*res); @@ -1609,7 +1779,7 @@ asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *las } } - (*res)->msg[(*res)->count] = m; + (*res)->msg[(*res)->count] = (asl_msg_t *)m; (*res)->count++; rescount++; @@ -1666,7 +1836,7 @@ asl_file_list_free(asl_file_list_t *head) } } -asl_file_list_t * +static asl_file_list_t * asl_file_list_insert(asl_file_list_t *list, asl_file_t *f, int32_t dir) { asl_file_list_t *a, *b, *tmp; @@ -1751,7 +1921,7 @@ asl_file_list_match_next(void *token, aslresponse query, aslresponse *res, uint3 { uint32_t status, rescount; asl_file_list_t *n; - asl_msg_t *m; + aslmsg m; asl_file_match_token_t *work; uint64_t last_id; @@ -1777,8 +1947,8 @@ asl_file_list_match_next(void *token, aslresponse query, aslresponse *res, uint3 return ASL_STATUS_NO_MEMORY; } - if ((*res)->msg == NULL) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *)); - else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(asl_msg_t *)); + if ((*res)->msg == NULL) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(aslmsg)); + else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(aslmsg)); if ((*res)->msg == NULL) { free(*res); @@ -1788,7 +1958,7 @@ asl_file_list_match_next(void *token, aslresponse query, aslresponse *res, uint3 return ASL_STATUS_NO_MEMORY; } - (*res)->msg[(*res)->count] = m; + (*res)->msg[(*res)->count] = (asl_msg_t *)m; (*res)->count++; rescount++; } @@ -1839,7 +2009,7 @@ asl_file_list_match_timeout(asl_file_list_t *list, aslresponse query, aslrespons { uint32_t status, rescount; asl_file_list_t *files, *n; - asl_msg_t *m; + aslmsg m; struct timeval now, finish; if (list == NULL) return ASL_STATUS_INVALID_ARG; @@ -1899,8 +2069,8 @@ asl_file_list_match_timeout(asl_file_list_t *list, aslresponse query, aslrespons return ASL_STATUS_NO_MEMORY; } - if ((*res)->msg == NULL) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *)); - else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(asl_msg_t *)); + if ((*res)->msg == NULL) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(aslmsg)); + else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(aslmsg)); if ((*res)->msg == NULL) { free(*res); @@ -1909,7 +2079,7 @@ asl_file_list_match_timeout(asl_file_list_t *list, aslresponse query, aslrespons return ASL_STATUS_NO_MEMORY; } - (*res)->msg[(*res)->count] = m; + (*res)->msg[(*res)->count] = (asl_msg_t *)m; (*res)->count++; rescount++; } diff --git a/gen/asl_file.h b/gen/asl_file.h index f7f3f8c..491cca1 100644 --- a/gen/asl_file.h +++ b/gen/asl_file.h @@ -1,34 +1,34 @@ -#ifndef __ASL_FILE_H__ -#define __ASL_FILE_H__ - /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 2007 Apple Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ +#ifndef __ASL_FILE_H__ +#define __ASL_FILE_H__ + #include #include #include #include +#include #define DB_HEADER_LEN 80 #define DB_HEADER_COOKIE_OFFSET 0 @@ -119,32 +119,32 @@ typedef struct asl_file_list_s struct asl_file_list_s *next; } asl_file_list_t; -asl_file_list_t *asl_file_list_add(asl_file_list_t *list, asl_file_t *f); -void asl_file_list_close(asl_file_list_t *list); +asl_file_list_t *asl_file_list_add(asl_file_list_t *list, asl_file_t *f) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +void asl_file_list_close(asl_file_list_t *list) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_open_write(const char *path, mode_t mode, uid_t uid, gid_t gid, asl_file_t **s); -uint32_t asl_file_close(asl_file_t *s); +uint32_t asl_file_open_write(const char *path, mode_t mode, uid_t uid, gid_t gid, asl_file_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_file_close(asl_file_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid); +uint32_t asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_open_read(const char *path, asl_file_t **s); -uint32_t asl_file_fetch(asl_file_t *s, uint64_t mid, aslmsg *msg); +uint32_t asl_file_open_read(const char *path, asl_file_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_file_fetch(asl_file_t *s, uint64_t mid, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_read_set_position(asl_file_t *s, uint32_t pos); -uint32_t asl_file_fetch_next(asl_file_t *s, aslmsg *msg); -uint32_t asl_file_fetch_previous(asl_file_t *s, aslmsg *msg); +uint32_t asl_file_read_set_position(asl_file_t *s, uint32_t pos) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_file_fetch_next(asl_file_t *s, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_file_fetch_previous(asl_file_t *s, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction); -uint32_t asl_file_list_match_timeout(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec); -uint32_t asl_file_list_match(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction); +uint32_t asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_file_list_match_timeout(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); +uint32_t asl_file_list_match(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -void *asl_file_list_match_start(asl_file_list_t *list, uint64_t start_id, int32_t direction); -uint32_t asl_file_list_match_next(void *token, aslresponse query, aslresponse *res, uint32_t count); -void asl_file_list_match_end(void *token); +void *asl_file_list_match_start(asl_file_list_t *list, uint64_t start_id, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_file_list_match_next(void *token, aslresponse query, aslresponse *res, uint32_t count) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +void asl_file_list_match_end(void *token) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -size_t asl_file_size(asl_file_t *s); -uint64_t asl_file_ctime(asl_file_t *s); +size_t asl_file_size(asl_file_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint64_t asl_file_ctime(asl_file_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_compact(asl_file_t *s, const char *path, mode_t mode, uid_t uid, gid_t gid); +uint32_t asl_file_compact(asl_file_t *s, const char *path, mode_t mode, uid_t uid, gid_t gid) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); #endif __ASL_FILE_H__ diff --git a/gen/asl_ipc.defs b/gen/asl_ipc.defs index 1fe5bce..c7ef1d3 100644 --- a/gen/asl_ipc.defs +++ b/gen/asl_ipc.defs @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2008 Apple Inc. All rights reserved. + * Copyright (c) 2007-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -24,7 +24,7 @@ #include #include -subsystem asl_ipc 1; +subsystem asl_ipc 114; serverprefix _; import ; @@ -67,9 +67,33 @@ routine _asl_server_prune SecToken token : security_token_t ); +routine _asl_server_create_aux_link +( + server : mach_port_t; + message : ooline_data, dealloc; + out fileport : mach_port_move_send_t; + out url : ooline_data, dealloc; + out status : int; + ServerAuditToken token : audit_token_t +); + simpleroutine _asl_server_message ( server : mach_port_t; message : ooline_data, dealloc; ServerAuditToken token : audit_token_t ); + +simpleroutine _asl_server_register_direct_watch +( + server : mach_port_t; + port : int; + ServerAuditToken token : audit_token_t +); + +simpleroutine _asl_server_cancel_direct_watch +( + server : mach_port_t; + port : int; + ServerAuditToken token : audit_token_t +); diff --git a/gen/asl_legacy1.c b/gen/asl_legacy1.c index fdfa65d..5a7a000 100644 --- a/gen/asl_legacy1.c +++ b/gen/asl_legacy1.c @@ -86,52 +86,15 @@ #define MSG_OFF_KEY_FLAGS 77 extern time_t asl_parse_time(const char *str); -extern int asl_msg_cmp(asl_msg_t *a, asl_msg_t *b); +extern int asl_msg_cmp(aslmsg a, aslmsg b); #define asl_msg_list_t asl_search_result_t -#define PMSG_SEL_TIME 0x0001 -#define PMSG_SEL_HOST 0x0002 -#define PMSG_SEL_SENDER 0x0004 -#define PMSG_SEL_FACILITY 0x0008 -#define PMSG_SEL_MESSAGE 0x0010 -#define PMSG_SEL_LEVEL 0x0020 -#define PMSG_SEL_PID 0x0040 -#define PMSG_SEL_UID 0x0080 -#define PMSG_SEL_GID 0x0100 -#define PMSG_SEL_RUID 0x0200 -#define PMSG_SEL_RGID 0x0400 - -#define PMSG_FETCH_ALL 0 -#define PMSG_FETCH_STD 1 -#define PMSG_FETCH_KV 2 - #define Q_NULL 100001 #define Q_FAST 100002 #define Q_SLOW 100003 #define Q_FAIL 100004 -typedef struct -{ - uint16_t kselect; - uint16_t vselect; - uint64_t msgid; - uint64_t time; - uint64_t host; - uint64_t sender; - uint64_t facility; - uint64_t message; - uint32_t level; - uint32_t pid; - int32_t uid; - int32_t gid; - int32_t ruid; - int32_t rgid; - uint32_t next; - uint32_t kvcount; - uint64_t *kvlist; -} pmsg_t; - static uint64_t _asl_htonq(uint64_t n) { @@ -518,108 +481,115 @@ string_fetch_sid(asl_legacy1_t *s, uint64_t sid, char **out) } static uint32_t -pmsg_fetch(asl_legacy1_t *s, uint32_t slot, uint32_t action, pmsg_t **pmsg) +asl_legacy1_fetch_helper_32(asl_legacy1_t *s, char **p, aslmsg m, const char *key, int ignore, uint32_t ignoreval) { - off_t offset; - uint32_t status, i, n, v32, next; - int32_t msgu, msgg; - uint64_t msgid; - uint16_t flags; - pmsg_t *out; - char *p, tmp[DB_RECORD_LEN]; + uint32_t out, doit; + char str[256]; - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (pmsg == NULL) return ASL_STATUS_INVALID_ARG; + out = _asl_get_32(*p); + *p += sizeof(uint32_t); - out = NULL; + if ((m == NULL) || (key == NULL)) return out; - if ((action == PMSG_FETCH_ALL) || (action == PMSG_FETCH_STD)) + doit = 1; + if ((ignore != 0) && (out == ignoreval)) doit = 0; + if (doit != 0) { - *pmsg = NULL; - - offset = slot * DB_RECORD_LEN; - status = fseek(s->db, offset, SEEK_SET); + snprintf(str, sizeof(str), "%u", out); + asl_set(m, key, str); + } - if (status < 0) return ASL_STATUS_READ_FAILED; + return out; +} - status = fread(tmp, DB_RECORD_LEN, 1, s->db); - if (status != 1) return ASL_STATUS_READ_FAILED; +static uint64_t +asl_legacy1_fetch_helper_64(asl_legacy1_t *s, char **p, aslmsg m, const char *key) +{ + uint64_t out; + char str[256]; - msgid = _asl_get_64(tmp + MSG_OFF_KEY_ID); - msgu = _asl_get_32(tmp + MSG_OFF_KEY_RUID); - msgg = _asl_get_32(tmp + MSG_OFF_KEY_RGID); - flags = _asl_get_16(tmp + MSG_OFF_KEY_FLAGS); + out = _asl_get_64(*p); + *p += sizeof(uint64_t); - out = (pmsg_t *)calloc(1, sizeof(pmsg_t)); - if (out == NULL) return ASL_STATUS_NO_MEMORY; + if ((m == NULL) || (key == NULL)) return out; + snprintf(str, sizeof(str), "%llu", out); + asl_set(m, key, str); - p = tmp + 21; + return out; +} - /* ID */ - out->msgid = msgid; +static uint64_t +asl_legacy1_fetch_helper_str(asl_legacy1_t *s, char **p, aslmsg m, const char *key, uint32_t *err) +{ + uint64_t out; + char *val; + uint32_t status; - /* ReadUID */ - out->ruid = msgu; + out = _asl_get_64(*p); + *p += sizeof(uint64_t); - /* ReadGID */ - out->rgid = msgg; + val = NULL; + status = ASL_STATUS_OK; + if (out != 0) status = string_fetch_sid(s, out, &val); - /* Time */ - out->time = _asl_get_64(p); - p += 8; + if (err != NULL) *err = status; + if ((status == ASL_STATUS_OK) && (val != NULL)) + { + asl_set(m, key, val); + free(val); + } - /* Host */ - out->host = _asl_get_64(p); - p += 8; + return out; +} - /* Sender */ - out->sender = _asl_get_64(p); - p += 8; +static uint32_t +msg_fetch(asl_legacy1_t *s, uint32_t slot, aslmsg *out) +{ + off_t offset; + uint32_t status, i, n, kvcount, next; + uint16_t flags; + uint64_t sid; + aslmsg msg; + char *p, tmp[DB_RECORD_LEN], *key, *val; - /* Facility */ - out->facility = _asl_get_64(p); - p += 8; + if (s == NULL) return ASL_STATUS_INVALID_STORE; + if (out == NULL) return ASL_STATUS_INVALID_ARG; - /* Level */ - out->level = _asl_get_32(p); - p += 4; + *out = NULL; - /* PID */ - out->pid = _asl_get_32(p); - p += 4; + offset = slot * DB_RECORD_LEN; + status = fseek(s->db, offset, SEEK_SET); - /* UID */ - out->uid = _asl_get_32(p); - p += 4; + if (status < 0) return ASL_STATUS_READ_FAILED; - /* GID */ - out->gid = _asl_get_32(p); - p += 4; + status = fread(tmp, DB_RECORD_LEN, 1, s->db); + if (status != 1) return ASL_STATUS_READ_FAILED; - /* Message */ - out->message = _asl_get_64(p); - p += 8; + flags = _asl_get_16(tmp + MSG_OFF_KEY_FLAGS); - next = header_get_next(tmp); - out->next = next; + msg = asl_new(ASL_TYPE_MSG); + if (msg == NULL) return ASL_STATUS_NO_MEMORY; - if (action == PMSG_FETCH_STD) - { - /* caller only wants "standard" keys */ - *pmsg = out; - return ASL_STATUS_OK; - } + p = tmp + 5; + + asl_legacy1_fetch_helper_64(s, &p, msg, ASL_KEY_MSG_ID); + asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_READ_UID, 1, (uint32_t)-1); + asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_READ_GID, 1, (uint32_t)-1); + asl_legacy1_fetch_helper_64(s, &p, msg, ASL_KEY_TIME); + asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_HOST, &status); + asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_SENDER, &status); + asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_FACILITY, &status); + asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_LEVEL, 0, 0); + asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_PID, 0, 0); + asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_UID, 0, 0); + asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_GID, 0, 0); + asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_MSG, &status); - *pmsg = out; - } - else - { - out = *pmsg; - } + next = header_get_next(tmp); + kvcount = 0; n = 0; - next = out->next; while (next != 0) { @@ -627,7 +597,6 @@ pmsg_fetch(asl_legacy1_t *s, uint32_t slot, uint32_t action, pmsg_t **pmsg) status = fseek(s->db, offset, SEEK_SET); if (status < 0) { - *pmsg = NULL; free(out); return ASL_STATUS_READ_FAILED; } @@ -635,919 +604,60 @@ pmsg_fetch(asl_legacy1_t *s, uint32_t slot, uint32_t action, pmsg_t **pmsg) status = fread(tmp, DB_RECORD_LEN, 1, s->db); if (status != 1) { - *pmsg = NULL; free(out); return ASL_STATUS_READ_FAILED; } - if (out->kvcount == 0) - { - v32 = _asl_get_32(tmp + 5); - out->kvcount = v32 * 2; - out->kvlist = (uint64_t *)calloc(out->kvcount, sizeof(uint64_t)); - if (out->kvlist == NULL) - { - *pmsg = NULL; - free(out); - return ASL_STATUS_NO_MEMORY; - } - } + if (kvcount == 0) kvcount = _asl_get_32(tmp + 5); p = tmp + 9; - for (i = 0; (i < 4) && (n < out->kvcount); i++) + for (i = 0; (i < 4) && (n < kvcount); i++) { - out->kvlist[n++] = _asl_get_64(p); + key = NULL; + sid = _asl_get_64(p); p += 8; + status = string_fetch_sid(s, sid, &key); - out->kvlist[n++] = _asl_get_64(p); + val = NULL; + sid = _asl_get_64(p); p += 8; - } - - next = header_get_next(tmp); - } - - return ASL_STATUS_OK; -} - -static uint32_t -pmsg_match(asl_legacy1_t *s, pmsg_t *q, pmsg_t *m) -{ - uint32_t i, j; - - if (s == NULL) return 0; - if (q == NULL) return 1; - if (m == NULL) return 0; - - if (q->kselect & PMSG_SEL_TIME) - { - if (q->time == ASL_REF_NULL) return 0; - if ((q->vselect & PMSG_SEL_TIME) && (q->time != m->time)) return 0; - } - - if (q->kselect & PMSG_SEL_HOST) - { - if (q->host == ASL_REF_NULL) return 0; - if ((q->vselect & PMSG_SEL_HOST) && (q->host != m->host)) return 0; - } - - if (q->kselect & PMSG_SEL_SENDER) - { - if (q->sender == ASL_REF_NULL) return 0; - if ((q->vselect & PMSG_SEL_SENDER) && (q->sender != m->sender)) return 0; - } - - if (q->kselect & PMSG_SEL_FACILITY) - { - if (q->facility == ASL_REF_NULL) return 0; - if ((q->vselect & PMSG_SEL_FACILITY) && (q->facility != m->facility)) return 0; - } - - if (q->kselect & PMSG_SEL_MESSAGE) - { - if (q->message == ASL_REF_NULL) return 0; - if ((q->vselect & PMSG_SEL_MESSAGE) && (q->message != m->message)) return 0; - } - - if (q->kselect & PMSG_SEL_LEVEL) - { - if (q->level == ASL_INDEX_NULL) return 0; - if ((q->vselect & PMSG_SEL_LEVEL) && (q->level != m->level)) return 0; - } - - if (q->kselect & PMSG_SEL_PID) - { - if (q->pid == -1) return 0; - if ((q->vselect & PMSG_SEL_PID) && (q->pid != m->pid)) return 0; - } - - if (q->kselect & PMSG_SEL_UID) - { - if (q->uid == -2) return 0; - if ((q->vselect & PMSG_SEL_UID) && (q->uid != m->uid)) return 0; - } - - if (q->kselect & PMSG_SEL_GID) - { - if (q->gid == -2) return 0; - if ((q->vselect & PMSG_SEL_GID) && (q->gid != m->gid)) return 0; - } - - if (q->kselect & PMSG_SEL_RUID) - { - if (q->ruid == -1) return 0; - if ((q->vselect & PMSG_SEL_RUID) && (q->ruid != m->ruid)) return 0; - } - - if (q->kselect & PMSG_SEL_RGID) - { - if (q->rgid == -1) return 0; - if ((q->vselect & PMSG_SEL_RGID) && (q->rgid != m->rgid)) return 0; - } - - for (i = 0; i < q->kvcount; i += 2) - { - for (j = 0; j < m->kvcount; j += 2) - { - if (q->kvlist[i] == m->kvlist[j]) - { - if (q->kvlist[i + 1] == m->kvlist[j + 1]) break; - return 0; - } - } - - if (j >= m->kvcount) return 0; - } - - return 1; -} - -static void -free_pmsg(pmsg_t *p) -{ - if (p == NULL) return; - if (p->kvlist != NULL) free(p->kvlist); - free(p); -} - -static uint32_t -pmsg_fetch_by_id(asl_legacy1_t *s, uint64_t msgid, pmsg_t **pmsg, uint32_t *slot) -{ - uint32_t i, status; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (msgid == ASL_REF_NULL) return ASL_STATUS_INVALID_ARG; - if (slot == NULL) return ASL_STATUS_INVALID_ARG; - - *slot = ASL_INDEX_NULL; - - i = slotlist_find(s, msgid, 0); - if (i == ASL_INDEX_NULL) return ASL_STATUS_INVALID_ID; - - *slot = s->slotlist[i].slot; - - /* read the message */ - *pmsg = NULL; - status = pmsg_fetch(s, s->slotlist[i].slot, PMSG_FETCH_ALL, pmsg); - if (status != ASL_STATUS_OK) return status; - if (pmsg == NULL) return ASL_STATUS_FAILED; - - return status; -} - -static uint32_t -msg_decode(asl_legacy1_t *s, pmsg_t *pmsg, asl_msg_t **out) -{ - uint32_t status, i, n; - char *key, *val; - asl_msg_t *msg; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (out == NULL) return ASL_STATUS_INVALID_ARG; - if (pmsg == NULL) return ASL_STATUS_INVALID_ARG; - - *out = NULL; - - msg = (asl_msg_t *)calloc(1, sizeof(asl_msg_t)); - if (msg == NULL) return ASL_STATUS_NO_MEMORY; - - msg->type = ASL_TYPE_MSG; - msg->count = 0; - if (pmsg->time != ASL_REF_NULL) msg->count++; - if (pmsg->host != ASL_REF_NULL) msg->count++; - if (pmsg->sender != ASL_REF_NULL) msg->count++; - if (pmsg->facility != ASL_REF_NULL) msg->count++; - if (pmsg->message != ASL_REF_NULL) msg->count++; - if (pmsg->level != ASL_INDEX_NULL) msg->count++; - if (pmsg->pid != -1) msg->count++; - if (pmsg->uid != -2) msg->count++; - if (pmsg->gid != -2) msg->count++; - if (pmsg->ruid != -1) msg->count++; - if (pmsg->rgid != -1) msg->count++; - - msg->count += pmsg->kvcount / 2; - - if (msg->count == 0) - { - free(msg); - return ASL_STATUS_INVALID_MESSAGE; - } - - /* Message ID */ - msg->count += 1; - - msg->key = (char **)calloc(msg->count, sizeof(char *)); - if (msg->key == NULL) - { - free(msg); - return ASL_STATUS_NO_MEMORY; - } - - msg->val = (char **)calloc(msg->count, sizeof(char *)); - if (msg->val == NULL) - { - free(msg->key); - free(msg); - return ASL_STATUS_NO_MEMORY; - } - - n = 0; - - /* Time */ - if (pmsg->time != ASL_REF_NULL) - { - msg->key[n] = strdup(ASL_KEY_TIME); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%llu", pmsg->time); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; - } - - /* Host */ - if (pmsg->host != ASL_REF_NULL) - { - msg->key[n] = strdup(ASL_KEY_HOST); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - status = string_fetch_sid(s, pmsg->host, &(msg->val[n])); - n++; - } - - /* Sender */ - if (pmsg->sender != ASL_REF_NULL) - { - msg->key[n] = strdup(ASL_KEY_SENDER); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - status = string_fetch_sid(s, pmsg->sender, &(msg->val[n])); - n++; - } - - /* Facility */ - if (pmsg->facility != ASL_REF_NULL) - { - msg->key[n] = strdup(ASL_KEY_FACILITY); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - status = string_fetch_sid(s, pmsg->facility, &(msg->val[n])); - n++; - } - - /* Level */ - if (pmsg->level != ASL_INDEX_NULL) - { - msg->key[n] = strdup(ASL_KEY_LEVEL); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%u", pmsg->level); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; - } - - /* PID */ - if (pmsg->pid != -1) - { - msg->key[n] = strdup(ASL_KEY_PID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%d", pmsg->pid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; - } - - /* UID */ - if (pmsg->uid != -2) - { - msg->key[n] = strdup(ASL_KEY_UID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%d", pmsg->uid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; - } - - /* GID */ - if (pmsg->gid != -2) - { - msg->key[n] = strdup(ASL_KEY_GID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%d", pmsg->gid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; - } - - /* Message */ - if (pmsg->message != ASL_REF_NULL) - { - msg->key[n] = strdup(ASL_KEY_MSG); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - status = string_fetch_sid(s, pmsg->message, &(msg->val[n])); - n++; - } - - /* ReadUID */ - if (pmsg->ruid != -1) - { - msg->key[n] = strdup(ASL_KEY_READ_UID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%d", pmsg->ruid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; - } - - /* ReadGID */ - if (pmsg->rgid != -1) - { - msg->key[n] = strdup(ASL_KEY_READ_GID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%d", pmsg->rgid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; - } - - /* Message ID */ - msg->key[n] = strdup(ASL_KEY_MSG_ID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%llu", pmsg->msgid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + if (status == ASL_STATUS_OK) status = string_fetch_sid(s, sid, &val); - /* Key - Value List */ - for (i = 0; i < pmsg->kvcount; i++) - { - key = NULL; - status = string_fetch_sid(s, pmsg->kvlist[i++], &key); - if (status != ASL_STATUS_OK) - { - if (key != NULL) free(key); - continue; - } - - val = NULL; - status = string_fetch_sid(s, pmsg->kvlist[i], &val); - if (status != ASL_STATUS_OK) - { + if ((status == ASL_STATUS_OK) && (key != NULL)) asl_set(msg, key, val); if (key != NULL) free(key); if (val != NULL) free(val); - continue; + + n++; } - msg->key[n] = key; - msg->val[n] = val; - n++; + next = header_get_next(tmp); } *out = msg; return ASL_STATUS_OK; } -/* - * Finds string either in the string cache or in the database - */ -static uint32_t -store_string_find(asl_legacy1_t *s, uint32_t hash, const char *str, uint32_t *index) -{ - uint32_t i, status; - char *tmp; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (str == NULL) return ASL_STATUS_INVALID_ARG; - if (index == NULL) return ASL_STATUS_INVALID_ARG; - if (s->slotlist == NULL) return ASL_STATUS_FAILED; - - /* check the database */ - for (i = 0; i < s->slotlist_count; i++) - { - if ((s->slotlist[i].type != DB_TYPE_STRING) || (s->slotlist[i].hash != hash)) continue; - - /* read the whole string */ - tmp = NULL; - status = string_fetch_slot(s, s->slotlist[i].slot, &tmp); - if (status != ASL_STATUS_OK) return status; - if (tmp == NULL) return ASL_STATUS_FAILED; - - status = strcmp(tmp, str); - free(tmp); - if (status != 0) continue; - - /* Bingo! */ - *index = i; - return ASL_STATUS_OK; - } - - return ASL_STATUS_FAILED; -} - -/* - * Looks up a string ID number. - */ -static uint64_t -string_lookup(asl_legacy1_t *s, const char *str) -{ - uint32_t status, hash, index, slot, len; - uint64_t nsid, sid; - char *p; - uint8_t inls; - - if (s == NULL) return ASL_REF_NULL; - if (str == NULL) return ASL_REF_NULL; - - sid = ASL_REF_NULL; - index = ASL_INDEX_NULL; - slot = ASL_INDEX_NULL; - - len = strlen(str); - if (len < 8) - { - /* inline string */ - inls = len; - inls |= 0x80; - - nsid = 0; - p = (char *)&nsid; - memcpy(p, &inls, 1); - memcpy(p + 1, str, len); - sid = _asl_ntohq(nsid); - return sid; - } - - hash = asl_core_string_hash(str, len); - - /* check the database */ - status = store_string_find(s, hash, str, &index); - if (status == ASL_STATUS_OK) - { - if (index == ASL_INDEX_NULL) return ASL_REF_NULL; - return s->slotlist[index].xid; - } - - return ASL_REF_NULL; -} - uint32_t -asl_legacy1_fetch(asl_legacy1_t *s, uint64_t msgid, asl_msg_t **msg) +asl_legacy1_fetch(asl_legacy1_t *s, uint64_t msgid, aslmsg *out) { - uint32_t status, slot; - pmsg_t *pmsg; + uint32_t i, status; if (s == NULL) return ASL_STATUS_INVALID_STORE; if (msgid == ASL_REF_NULL) return ASL_STATUS_INVALID_ARG; + if (out == NULL) return ASL_STATUS_INVALID_ARG; - pmsg = NULL; - slot = ASL_INDEX_NULL; + i = slotlist_find(s, msgid, 0); + if (i == ASL_INDEX_NULL) return ASL_STATUS_INVALID_ID; - status = pmsg_fetch_by_id(s, msgid, &pmsg, &slot); + /* read the message */ + status = msg_fetch(s, s->slotlist[i].slot, out); if (status != ASL_STATUS_OK) return status; - if (pmsg == NULL) return ASL_STATUS_FAILED; - - status = msg_decode(s, pmsg, msg); - free_pmsg(pmsg); + if (*out == NULL) return ASL_STATUS_FAILED; return status; } -static uint32_t -query_to_pmsg(asl_legacy1_t *s, asl_msg_t *q, pmsg_t **p) -{ - pmsg_t *out; - uint32_t i, j; - uint64_t ksid, vsid; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (p == NULL) return ASL_STATUS_INVALID_ARG; - - if (q == NULL) return Q_NULL; - if (q->count == 0) return Q_NULL; - - *p = NULL; - - if (q->op != NULL) - { - for (i = 0; i < q->count; i++) if (q->op[i] != ASL_QUERY_OP_EQUAL) return Q_SLOW; - } - - out = (pmsg_t *)calloc(1, sizeof(pmsg_t)); - if (out == NULL) return ASL_STATUS_NO_MEMORY; - - for (i = 0; i < q->count; i++) - { - if (q->key[i] == NULL) continue; - - else if (!strcmp(q->key[i], ASL_KEY_TIME)) - { - if (out->kselect & PMSG_SEL_TIME) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_TIME; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_TIME; - out->time = asl_parse_time(q->val[i]); - } - } - else if (!strcmp(q->key[i], ASL_KEY_HOST)) - { - if (out->kselect & PMSG_SEL_HOST) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_HOST; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_HOST; - out->host = string_lookup(s, q->val[i]); - if (out->host == ASL_REF_NULL) - { - free_pmsg(out); - return Q_FAIL; - } - } - } - else if (!strcmp(q->key[i], ASL_KEY_SENDER)) - { - if (out->kselect & PMSG_SEL_SENDER) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_SENDER; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_SENDER; - out->sender = string_lookup(s, q->val[i]); - if (out->sender == ASL_REF_NULL) - { - free_pmsg(out); - return Q_FAIL; - } - } - } - else if (!strcmp(q->key[i], ASL_KEY_PID)) - { - if (out->kselect & PMSG_SEL_PID) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_PID; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_PID; - out->pid = atoi(q->val[i]); - } - } - else if (!strcmp(q->key[i], ASL_KEY_UID)) - { - if (out->kselect & PMSG_SEL_UID) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_UID; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_UID; - out->uid = atoi(q->val[i]); - } - } - else if (!strcmp(q->key[i], ASL_KEY_GID)) - { - if (out->kselect & PMSG_SEL_GID) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_GID; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_GID; - out->gid = atoi(q->val[i]); - } - } - else if (!strcmp(q->key[i], ASL_KEY_LEVEL)) - { - if (out->kselect & PMSG_SEL_LEVEL) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_LEVEL; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_LEVEL; - out->level = atoi(q->val[i]); - } - } - else if (!strcmp(q->key[i], ASL_KEY_MSG)) - { - if (out->kselect & PMSG_SEL_MESSAGE) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_MESSAGE; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_MESSAGE; - out->message = string_lookup(s, q->val[i]); - if (out->message == ASL_REF_NULL) - { - free_pmsg(out); - return Q_FAIL; - } - } - } - else if (!strcmp(q->key[i], ASL_KEY_FACILITY)) - { - if (out->kselect & PMSG_SEL_FACILITY) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_FACILITY; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_FACILITY; - out->facility = string_lookup(s, q->val[i]); - if (out->facility == ASL_REF_NULL) - { - free_pmsg(out); - return Q_FAIL; - } - } - } - else if (!strcmp(q->key[i], ASL_KEY_READ_UID)) - { - if (out->kselect & PMSG_SEL_RUID) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_RUID; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_RUID; - out->ruid = atoi(q->val[i]); - } - } - else if (!strcmp(q->key[i], ASL_KEY_READ_GID)) - { - if (out->kselect & PMSG_SEL_RGID) - { - free_pmsg(out); - return Q_SLOW; - } - - out->kselect |= PMSG_SEL_RGID; - if (q->val[i] != NULL) - { - out->vselect |= PMSG_SEL_RGID; - out->rgid = atoi(q->val[i]); - } - } - else - { - ksid = string_lookup(s, q->key[i]); - if (ksid == ASL_REF_NULL) - { - free_pmsg(out); - return Q_FAIL; - } - - for (j = 0; j < out->kvcount; j += 2) - { - if (out->kvlist[j] == ksid) - { - free_pmsg(out); - return Q_SLOW; - } - } - - vsid = ASL_REF_NULL; - if (q->val[i] != NULL) - { - vsid = string_lookup(s, q->val[i]); - if (ksid == ASL_REF_NULL) - { - free_pmsg(out); - return Q_FAIL; - } - } - - if (out->kvcount == 0) - { - out->kvlist = (uint64_t *)calloc(2, sizeof(uint64_t)); - } - else - { - out->kvlist = (uint64_t *)reallocf(out->kvlist, (out->kvcount + 2) * sizeof(uint64_t)); - } - - if (out->kvlist == NULL) - { - free_pmsg(out); - return ASL_STATUS_NO_MEMORY; - } - - out->kvlist[out->kvcount++] = ksid; - out->kvlist[out->kvcount++] = vsid; - } - } - - *p = out; - return Q_FAST; -} - -static uint32_t -msg_match(asl_legacy1_t *s, uint32_t qtype, pmsg_t *qp, asl_msg_t *q, uint32_t slot, pmsg_t **iopm, asl_msg_t **iomsg, asl_msg_list_t **res, uint32_t *didmatch) -{ - uint32_t status, what; - - *didmatch = 0; - - if (qtype == Q_FAIL) return ASL_STATUS_OK; - - if (qtype == Q_NULL) - { - if (*iopm == NULL) - { - status = pmsg_fetch(s, slot, PMSG_FETCH_ALL, iopm); - if (status != ASL_STATUS_OK) return status; - if (*iopm == NULL) return ASL_STATUS_FAILED; - } - } - else if (qtype == Q_FAST) - { - if (qp == NULL) return ASL_STATUS_INVALID_ARG; - - what = PMSG_FETCH_STD; - if (qp->kvcount > 0) what = PMSG_FETCH_ALL; - - if (*iopm == NULL) - { - status = pmsg_fetch(s, slot, what, iopm); - if (status != ASL_STATUS_OK) return status; - if (*iopm == NULL) return ASL_STATUS_FAILED; - } - - status = pmsg_match(s, qp, *iopm); - if (status == 1) - { - if ((what == PMSG_FETCH_STD) && ((*iopm)->next != 0) && ((*iopm)->kvcount == 0)) - { - status = pmsg_fetch(s, slot, PMSG_FETCH_KV, iopm); - if (status != ASL_STATUS_OK) return status; - if (*iopm == NULL) return ASL_STATUS_FAILED; - } - } - else return ASL_STATUS_OK; - } - else if (qtype == Q_SLOW) - { - if (*iomsg == NULL) - { - if (*iopm == NULL) - { - status = pmsg_fetch(s, slot, PMSG_FETCH_ALL, iopm); - if (status != ASL_STATUS_OK) return status; - if (*iopm == NULL) return ASL_STATUS_FAILED; - } - - status = msg_decode(s, *iopm, iomsg); - if (status == ASL_STATUS_INVALID_MESSAGE) return ASL_STATUS_OK; - if (status != ASL_STATUS_OK) return status; - if (*iomsg == NULL) return ASL_STATUS_FAILED; - } - - status = 0; - if (asl_msg_cmp(q, *iomsg) != 0) status = 1; - if (status == 0) return ASL_STATUS_OK; - } - - *didmatch = 1; - - if (res == NULL) return ASL_STATUS_OK; - - if (*iomsg == NULL) - { - status = msg_decode(s, *iopm, iomsg); - if (status == ASL_STATUS_INVALID_MESSAGE) - { - *didmatch = 0; - return ASL_STATUS_OK; - } - - if (status != ASL_STATUS_OK) return status; - } - - if ((*res)->count == 0) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *)); - else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, (1 + (*res)->count) * sizeof(asl_msg_t *)); - if ((*res)->msg == NULL) return ASL_STATUS_NO_MEMORY; - - (*res)->msg[(*res)->count++] = *iomsg; - - return ASL_STATUS_OK; -} - static uint32_t next_search_slot(asl_legacy1_t *s, uint32_t last_si, int32_t direction) { @@ -1576,73 +686,14 @@ next_search_slot(asl_legacy1_t *s, uint32_t last_si, int32_t direction) return ASL_INDEX_NULL; } -static uint32_t -query_list_to_pmsg_list(asl_legacy1_t *s, asl_msg_list_t *query, uint32_t *match, pmsg_t ***qp, uint32_t **qtype, uint32_t *count) -{ - pmsg_t **outp, *pm; - uint32_t i, j, *outt; - *match = 0; - *qp = NULL; - *qtype = 0; - *count = 0; - - if (query == NULL) return ASL_STATUS_OK; - if (match == NULL) return ASL_STATUS_INVALID_ARG; - if (qp == NULL) return ASL_STATUS_INVALID_ARG; - if (qtype == NULL) return ASL_STATUS_OK; - if (query->msg == NULL) return ASL_STATUS_OK; - if (query->count == 0) return ASL_STATUS_OK; - - outp = (pmsg_t **)calloc(query->count, sizeof(pmsg_t *)); - if (outp == NULL) return ASL_STATUS_NO_MEMORY; - - outt = (uint32_t *)calloc(query->count, sizeof(uint32_t)); - if (outt == NULL) - { - free(outp); - return ASL_STATUS_NO_MEMORY; - } - - *match = 1; - - for (i = 0; i < query->count; i++) - { - pm = NULL; - outt[i] = query_to_pmsg(s, query->msg[i], &pm); - if (outt[i] <= ASL_STATUS_FAILED) - { - if (pm != NULL) free_pmsg(pm); - for (j = 0; j < i; j++) free_pmsg(outp[j]); - free(outp); - free(outt); - return ASL_STATUS_NO_MEMORY; - } - - outp[i] = pm; - } - - *count = query->count; - *qp = outp; - *qtype = outt; - return ASL_STATUS_OK; -} - static void -match_worker_cleanup(pmsg_t **ql, uint32_t *qt, uint32_t n, asl_msg_list_t **res) +match_worker_cleanup(asl_msg_list_t **res) { uint32_t i; - if (ql != NULL) - { - for (i = 0; i < n; i++) free_pmsg(ql[i]); - free(ql); - } - - if (qt != NULL) free(qt); - if (res != NULL) { - for (i = 0; i < (*res)->count; i++) asl_free((*res)->msg[i]); + for (i = 0; i < (*res)->count; i++) asl_free((aslmsg)(*res)->msg[i]); free(*res); } } @@ -1658,11 +709,6 @@ match_worker_cleanup(pmsg_t **ql, uint32_t *qt, uint32_t n, asl_msg_list_t **res * If any query is NULL, set match flog off (skips matching below). * Else if all queries only check "standard" keys, set std flag to on. * - * If a query only tests equality, convert it to a pmsg_t. The conversion routine - * checks for string values that are NOT in the database. If a string is not found, - * the conversion fails and the query is markes as "never matches". Otherwise, - * the query is marked "fast". - * * If all queries are marked as "never matches", return NULL. * * match loop: @@ -1671,7 +717,6 @@ match_worker_cleanup(pmsg_t **ql, uint32_t *qt, uint32_t n, asl_msg_list_t **res * else for each query: * if query is NULL (shouldn't happen) decode record and add it to result. Return to match loop. * else if query never matches, ignore it. - * else if query is fast, use pmsg_match. If it succeeds, decode record and add it to result. Return to match loop. * else decode record and use asl_cmp. If it succeeds, add record to result. Return to match loop. * * return results. @@ -1679,10 +724,9 @@ match_worker_cleanup(pmsg_t **ql, uint32_t *qt, uint32_t n, asl_msg_list_t **res static uint32_t match_worker(asl_legacy1_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint64_t *last_id, uint64_t **idlist, uint32_t *idcount, uint64_t start_id, int32_t count, int32_t direction) { - uint32_t mx, si, slot, i, qcount, match, didmatch, status, *qtype; + uint32_t mx, si, slot, i, qcount, match, didmatch, status; uint64_t xid; - pmsg_t **qp, *iopmsg; - asl_msg_t *iomsg; + aslmsg msg; if (s == NULL) return ASL_STATUS_INVALID_STORE; if ((res == NULL) && (idlist == NULL)) return ASL_STATUS_INVALID_ARG; @@ -1707,8 +751,12 @@ match_worker(asl_legacy1_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint slot = s->slotlist[si].slot; - status = query_list_to_pmsg_list(s, query, &match, &qp, &qtype, &qcount); - if (status != ASL_STATUS_OK) return status; + match = 1; + qcount = 0; + + if (query == NULL) match = 0; + else if (query->count == 0) match = 0; + else qcount = query->count; /* * initialize result list if we've been asked to return messages @@ -1716,13 +764,11 @@ match_worker(asl_legacy1_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint if (res != NULL) { *res = (asl_msg_list_t *)calloc(1, sizeof(asl_msg_list_t)); - if (*res == NULL) - { - match_worker_cleanup(qp, qtype, qcount, NULL); - return ASL_STATUS_NO_MEMORY; - } + if (*res == NULL) return ASL_STATUS_NO_MEMORY; } + status = ASL_STATUS_OK; + /* * loop through records */ @@ -1737,79 +783,42 @@ match_worker(asl_legacy1_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint *last_id = xid; - iopmsg = NULL; - iomsg = NULL; + status = msg_fetch(s, slot, &msg); didmatch = 0; if (match == 0) { - status = msg_match(s, Q_NULL, NULL, NULL, slot, &iopmsg, &iomsg, res, &didmatch); - free_pmsg(iopmsg); - if (didmatch == 0) - { - asl_free(iomsg); - iomsg = NULL; - } - else + didmatch = 1; + } + else + { + for (i = 0; i < qcount; i++) { - if (idlist != NULL) - { - if (*idlist == NULL) *idlist = (uint64_t *)calloc(1, sizeof(uint64_t)); - else *idlist = (uint64_t *)reallocf(*idlist, (*idcount + 1) * sizeof(uint64_t)); - if (*idlist == NULL) status = ASL_STATUS_NO_MEMORY; - else (*idlist)[*idcount] = xid; - } - - (*idcount)++; + didmatch = asl_msg_cmp((aslmsg)(query->msg[i]), msg); + if (didmatch == 1) break; } + } - if (status != ASL_STATUS_OK) + if (didmatch == 1) + { + if ((*res)->count == 0) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *)); + else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, (1 + (*res)->count) * sizeof(asl_msg_t *)); + if ((*res)->msg == NULL) { - match_worker_cleanup(qp, qtype, qcount, res); - return status; + match_worker_cleanup(res); + return ASL_STATUS_NO_MEMORY; } + + (*res)->msg[(*res)->count++] = (asl_msg_t *)msg; } else { - for (i = 0; i < qcount; i++) - { - status = msg_match(s, qtype[i], qp[i], query->msg[i], slot, &iopmsg, &iomsg, res, &didmatch); - if (status != ASL_STATUS_OK) - { - free_pmsg(iopmsg); - asl_free(iomsg); - match_worker_cleanup(qp, qtype, qcount, res); - return status; - } - - if (didmatch == 1) - { - if (idlist != NULL) - { - if (*idlist == NULL) *idlist = (uint64_t *)calloc(1, sizeof(uint64_t)); - else *idlist = (uint64_t *)reallocf(*idlist, (*idcount + 1) * sizeof(uint64_t)); - if (*idlist == NULL) - { - match_worker_cleanup(qp, qtype, qcount, res); - return ASL_STATUS_NO_MEMORY; - } - - (*idlist)[*idcount] = xid; - } - - (*idcount)++; - break; - } - } - - free_pmsg(iopmsg); - if ((didmatch == 0) || (res == NULL)) asl_free(iomsg); + asl_free(msg); } si = next_search_slot(s, si, direction); } - match_worker_cleanup(qp, qtype, qcount, NULL); return status; } diff --git a/gen/asl_legacy1.h b/gen/asl_legacy1.h index 8b869e9..eff42d9 100644 --- a/gen/asl_legacy1.h +++ b/gen/asl_legacy1.h @@ -62,6 +62,7 @@ #include #include #include +#include typedef struct { @@ -78,9 +79,9 @@ typedef struct FILE *db; } asl_legacy1_t; -uint32_t asl_legacy1_open(const char *path, asl_legacy1_t **s); -uint32_t asl_legacy1_close(asl_legacy1_t *s); -uint32_t asl_legacy1_fetch(asl_legacy1_t *s, uint64_t msgid, aslmsg *msg); -uint32_t asl_legacy1_match(asl_legacy1_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction); +uint32_t asl_legacy1_open(const char *path, asl_legacy1_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_legacy1_close(asl_legacy1_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_legacy1_fetch(asl_legacy1_t *s, uint64_t msgid, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_legacy1_match(asl_legacy1_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); #endif /*__ASL_LEGACY1_H__*/ diff --git a/gen/asl_msg.c b/gen/asl_msg.c new file mode 100644 index 0000000..d824209 --- /dev/null +++ b/gen/asl_msg.c @@ -0,0 +1,3589 @@ +/* + * Copyright (c) 2009-2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "asl_msg.h" + +#define TOKEN_NULL 0 +#define TOKEN_OPEN 1 +#define TOKEN_CLOSE 2 +#define TOKEN_WORD 3 +#define TOKEN_INT 4 + +#define MFMT_RAW 0 +#define MFMT_STD 1 +#define MFMT_BSD 2 +#define MFMT_XML 3 +#define MFMT_STR 4 +#define MFMT_MSG 5 + +#define TFMT_SEC 0 +#define TFMT_UTC 1 +#define TFMT_LCL 2 + +#define XML_TAG_KEY 0 +#define XML_TAG_STRING 1 +#define XML_TAG_DATA 2 + +#define forever for(;;) + +#define streq(A, B) (strcmp(A, B) == 0) +#define streq_len(A, B, C) (strncmp(A, B, C) == 0) +#define strneq(A, B) (strcmp(A, B) != 0) +#define strcaseeq(A, B) (strcasecmp(A, B) == 0) +#define strcaseneq(A, B) (strcasecmp(A, B) != 0) + +#ifndef ASL_KEY_OPTION +#define ASL_KEY_OPTION "ASLOption" +#endif + +#ifndef ASL_QUERY_OP_FALSE +#define ASL_QUERY_OP_FALSE 0 +#endif + +#define AUX_0_TIME 0x00000001 +#define AUX_0_TIME_NSEC 0x00000002 +#define AUX_0_HOST 0x00000004 +#define AUX_0_SENDER 0x00000008 +#define AUX_0_FACILITY 0x00000010 +#define AUX_0_PID 0x00000020 +#define AUX_0_UID 0x00000040 +#define AUX_0_GID 0x00000080 +#define AUX_0_MSG 0x00000100 +#define AUX_0_OPTION 0x00000200 +#define AUX_0_LEVEL 0x00000400 + +/* character encoding lengths */ +static const uint8_t char_encode_len[128] = +{ + 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 +}; + +static const char *cvis_7_13 = "abtnvfr"; + +extern time_t asl_parse_time(const char *in); + +/* from asl_util.c */ +int asl_is_utf8(const char *str); +uint8_t *asl_b64_encode(const uint8_t *buf, size_t len); + +static const char *ASLStandardKey[] = +{ + ASL_KEY_TIME, + ASL_KEY_TIME_NSEC, + ASL_KEY_HOST, + ASL_KEY_SENDER, + ASL_KEY_FACILITY, + ASL_KEY_PID, + ASL_KEY_UID, + ASL_KEY_GID, + ASL_KEY_LEVEL, + ASL_KEY_MSG, + ASL_KEY_READ_UID, + ASL_KEY_READ_GID, + ASL_KEY_SESSION, + ASL_KEY_REF_PID, + ASL_KEY_REF_PROC, + ASL_KEY_MSG_ID, + ASL_KEY_EXPIRE_TIME, + ASL_KEY_OPTION +}; + +static const char *MTStandardKey[] = +{ + "com.apple.message.domain", + "com.apple.message.domain_scope", + "com.apple.message.result", + "com.apple.message.signature", + "com.apple.message.signature2", + "com.apple.message.signature3", + "com.apple.message.success", + "com.apple.message.uuid", + "com.apple.message.value", + "com.apple.message.value2", + "com.apple.message.value3", + "com.apple.message.value4", + "com.apple.message.value5" +}; + +static uint16_t +_asl_msg_std_key(const char *s, uint32_t len) +{ + if ((len > 18) && (streq_len(s, "com.apple.message.", 18))) + { + if (streq(s + 18, "domain")) return ASL_MT_KEY_DOMAIN; + else if (streq(s + 18, "domain_scope")) return ASL_MT_KEY_SCOPE; + else if (streq(s + 18, "result")) return ASL_MT_KEY_RESULT; + else if (streq(s + 18, "signature")) return ASL_MT_KEY_SIG; + else if (streq(s + 18, "signature2")) return ASL_MT_KEY_SIG2; + else if (streq(s + 18, "signature3")) return ASL_MT_KEY_SIG3; + else if (streq(s + 18, "success")) return ASL_MT_KEY_SUCCESS; + else if (streq(s + 18, "uuid")) return ASL_MT_KEY_UUID; + else if (streq(s + 18, "value")) return ASL_MT_KEY_VAL; + else if (streq(s + 18, "value2")) return ASL_MT_KEY_VAL2; + else if (streq(s + 18, "value3")) return ASL_MT_KEY_VAL3; + else if (streq(s + 18, "value4")) return ASL_MT_KEY_VAL4; + else if (streq(s + 18, "value5")) return ASL_MT_KEY_VAL5; + + return 0; + } + + switch (len) + { + case 3: + { + if streq(s, ASL_KEY_PID) return ASL_STD_KEY_PID; + else if streq(s, ASL_KEY_UID) return ASL_STD_KEY_UID; + else if streq(s, ASL_KEY_GID) return ASL_STD_KEY_GID; + } + case 4: + { + if streq(s, ASL_KEY_TIME) return ASL_STD_KEY_TIME; + else if streq(s, ASL_KEY_HOST) return ASL_STD_KEY_HOST; + } + case 5: + { + if streq(s, ASL_KEY_LEVEL) return ASL_STD_KEY_LEVEL; + } + case 6: + { + if streq(s, ASL_KEY_SENDER) return ASL_STD_KEY_SENDER; + else if streq(s, ASL_KEY_REF_PID) return ASL_STD_KEY_REF_PID; + } + case 7: + { + if streq(s, ASL_KEY_MSG) return ASL_STD_KEY_MESSAGE; + else if streq(s, ASL_KEY_SESSION) return ASL_STD_KEY_SESSION; + else if streq(s, ASL_KEY_READ_UID) return ASL_STD_KEY_READ_UID; + else if streq(s, ASL_KEY_READ_GID) return ASL_STD_KEY_READ_GID; + else if streq(s, ASL_KEY_REF_PROC) return ASL_STD_KEY_REF_PROC; + } + case 8: + { + if streq(s, ASL_KEY_FACILITY) return ASL_STD_KEY_FACILITY; + } + case 9: + { + if streq(s, ASL_KEY_OPTION) return ASL_STD_KEY_OPTION; + } + case 11: + { + if streq(s, ASL_KEY_TIME_NSEC) return ASL_STD_KEY_NANO; + } + case 12: + { + if streq(s, ASL_KEY_MSG_ID) return ASL_STD_KEY_MSG_ID; + } + case 13: + { + if streq(s, ASL_KEY_EXPIRE_TIME) return ASL_STD_KEY_EXPIRE; + } + default: + { + return 0; + } + } + + return 0; +} + +static asl_msg_t * +_asl_msg_make_page() +{ + asl_msg_t *out; + int i; + + out = calloc(1, sizeof(asl_msg_t)); + if (out == NULL) return NULL; + + for (i = 0; i < ASL_MSG_PAGE_SLOTS; i++) + { + out->key[i] = ASL_MSG_SLOT_FREE; + out->val[i] = ASL_MSG_SLOT_FREE; + } + + return out; +} + +static const char * +_asl_msg_slot_key(asl_msg_t *page, uint32_t slot) +{ + const char *out; + uint16_t x; + + if (page == NULL) return NULL; + if (slot >= ASL_MSG_PAGE_SLOTS) return NULL; + + if (page->key[slot] == ASL_MSG_SLOT_FREE) return NULL; + + switch (page->key[slot] & ASL_MSG_KV_MASK) + { + case ASL_MSG_KV_INLINE: + { + return page->data + page->key[slot]; + } + case ASL_MSG_KV_DICT: + { + if ((page->key[slot] > ASL_STD_KEY_BASE) && (page->key[slot] <= ASL_STD_KEY_LAST)) + { + x = page->key[slot] - ASL_STD_KEY_BASE - 1; + return ASLStandardKey[x]; + } + else if ((page->key[slot] > ASL_MT_KEY_BASE) && (page->key[slot] <= ASL_MT_KEY_LAST)) + { + x = page->key[slot] - ASL_MT_KEY_BASE - 1; + return MTStandardKey[x]; + } + + return NULL; + } + case ASL_MSG_KV_EXTERN: + { + x = page->key[slot] & ASL_MSG_OFFSET_MASK; + memcpy(&out, page->data + x, sizeof(char *)); + return out; + } + } + + return NULL; +} + +static const char * +_asl_msg_slot_val(asl_msg_t *page, uint32_t slot) +{ + const char *out; + uint16_t x, type; + + if (page == NULL) return NULL; + if (slot >= ASL_MSG_PAGE_SLOTS) return NULL; + + if (page->val[slot] == ASL_MSG_SLOT_FREE) return NULL; + + type = page->val[slot] & ASL_MSG_KV_MASK; + + if (type == ASL_MSG_KV_INLINE) + { + return page->data + page->val[slot]; + } + else if (type == ASL_MSG_KV_EXTERN) + { + x = page->val[slot] & ASL_MSG_OFFSET_MASK; + memcpy(&out, page->data + x, sizeof(char *)); + return out; + } + + return NULL; +} + +/* + * asl_new: create a new log message. + */ +asl_msg_t * +asl_msg_new(uint32_t type) +{ + asl_msg_t *out; + + out = _asl_msg_make_page(); + if (out == NULL) return NULL; + + out->type = type; + out->refcount = 1; + + return out; +} + +asl_msg_t * +asl_msg_retain(asl_msg_t *msg) +{ + int32_t new; + + if (msg == NULL) return NULL; + + new = OSAtomicIncrement32Barrier(&msg->refcount); + assert(new >= 1); + + return msg; +} + +static void +_asl_msg_free(asl_msg_t *page) +{ + uint32_t i; + char *p; + + if (page == NULL) return; + + for (i = 0; i < ASL_MSG_PAGE_SLOTS; i++) + { + if ((page->key[i] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) + { + memcpy(&p, page->data + (page->key[i] & ASL_MSG_OFFSET_MASK), sizeof(char *)); + free(p); + } + + if ((page->val[i] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) + { + memcpy(&p, page->data + (page->val[i] & ASL_MSG_OFFSET_MASK), sizeof(char *)); + free(p); + } + } + + free(page); +} + +void +asl_msg_release(asl_msg_t *msg) +{ + int32_t new; + asl_msg_t *next; + + if (msg == NULL) return; + + new = OSAtomicDecrement32Barrier(&msg->refcount); + assert(new >= 0); + + if (new > 0) return; + + while (msg != NULL) + { + next = msg->next; + _asl_msg_free(msg); + msg = next; + } +} + +static uint32_t +_asl_msg_index(asl_msg_t *msg, const char *key, uint32_t *oslot, asl_msg_t **opage) +{ + uint32_t i, len, slot; + uint16_t kx; + asl_msg_t *page; + const char *kp; + + if (msg == NULL) return IndexNull; + if (key == NULL) return IndexNull; + + i = 0; + slot = 0; + if (oslot != NULL) *oslot = slot; + + page = msg; + if (opage != NULL) *opage = page; + + len = strlen(key); + kx = _asl_msg_std_key(key, len); + + forever + { + if (page->key[slot] != ASL_MSG_SLOT_FREE) + { + if (kx != 0) + { + if (page->key[slot] == kx) return i; + } + else if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_DICT) + { + /* page->key[slot] is a dictionary key, but key is not (kx == 0) so skip this slot */ + } + else if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) + { + memcpy(&kp, page->data + (page->key[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *)); + if (streq(key, kp)) return i; + } + else + { + kp = page->data + page->key[slot]; + if (streq(key, kp)) return i; + } + } + + i++; + slot++; + if (oslot != NULL) *oslot = slot; + + if (slot >= ASL_MSG_PAGE_SLOTS) + { + if (page->next == NULL) return IndexNull; + + slot = 0; + if (oslot != NULL) *oslot = slot; + + page = page->next; + if (opage != NULL) *opage = page; + } + } + + return IndexNull; +} + +/* + * asl_msg_key: iterate over entries + * initial value of n should be 0 + * after that, the value of n should be previously returned value + * sets the pointers for the next key, value, and op in the msgionary + * returns IndexNull when there are no more entries + */ +static uint32_t +_asl_msg_fetch_internal(asl_msg_t *msg, uint32_t n, const char **keyout, const char **valout, uint32_t *opout, asl_msg_t **outpage, uint32_t *outslot) +{ + uint32_t slot; + asl_msg_t *page; + + if (msg == NULL) return IndexNull; + if (outpage != NULL) *outpage = NULL; + if (outslot != NULL) *outslot = IndexNull; + + slot = n; + page = msg; + + while (slot >= ASL_MSG_PAGE_SLOTS) + { + if (page->next == NULL) return IndexNull; + page = page->next; + slot -= ASL_MSG_PAGE_SLOTS; + } + + while (page->key[slot] == ASL_MSG_SLOT_FREE) + { + slot++; + n++; + + if (slot >= ASL_MSG_PAGE_SLOTS) + { + if (page->next == NULL) return IndexNull; + page = page->next; + slot = 0; + } + } + + n++; + + if (keyout != NULL) *keyout = _asl_msg_slot_key(page, slot); + if (valout != NULL) *valout = _asl_msg_slot_val(page, slot); + if (opout != NULL) *opout = page->op[slot]; + + if (outpage != NULL) *outpage = page; + if (outslot != NULL) *outslot = slot; + + return n; +} + +uint32_t +asl_msg_fetch(asl_msg_t *msg, uint32_t n, const char **keyout, const char **valout, uint32_t *opout) +{ + return _asl_msg_fetch_internal(msg, n, keyout, valout, opout, NULL, NULL); +} + +static int +_asl_msg_new_key_val_op(asl_msg_t *msg, const char *key, const char *val, uint32_t op) +{ + uint32_t slot, keylen, vallen, total; + uint16_t kx; + asl_msg_t *page, *last; + char *extkey, *extval; + + if (msg == NULL) return -1; + if (key == NULL) return -1; + + extkey = NULL; + extval = NULL; + + keylen = strlen(key); + kx = _asl_msg_std_key(key, keylen); + + if (kx == 0) keylen++; + else keylen = 0; + + total = keylen; + + vallen = 0; + if (val != NULL) + { + vallen = strlen(val) + 1; + total += vallen; + } + + /* check if one or both of key and value must be "external" (in its own malloced space) */ + if (keylen > ASL_MSG_PAGE_DATA_SIZE) + { + extkey = strdup(key); + keylen = sizeof(char *); + } + + if (vallen > ASL_MSG_PAGE_DATA_SIZE) + { + extval = strdup(val); + vallen = sizeof(char *); + } + + total = keylen + vallen; + if ((total > ASL_MSG_PAGE_DATA_SIZE) && (extval == NULL) && (keylen > 0)) + { + extval = strdup(val); + vallen = sizeof(char *); + total = keylen + vallen; + } + + if ((total > ASL_MSG_PAGE_DATA_SIZE) && (extkey == NULL)) + { + extkey = strdup(key); + keylen = sizeof(char *); + total = keylen + vallen; + } + + if (total > ASL_MSG_PAGE_DATA_SIZE) + { + /* can't happen, but... */ + if (extkey != NULL) free(extkey); + if (extval != NULL) free(extval); + return -1; + } + + /* find a page with space for the key and value and a free slot*/ + slot = 0; + last = msg; + + for (page = msg; page != NULL; page = page->next) + { + last = page; + + if (total <= (ASL_MSG_PAGE_DATA_SIZE - page->data_size)) + { + /* check for a free slot */ + for (slot = 0; (slot < ASL_MSG_PAGE_SLOTS) && (page->key[slot] != ASL_MSG_SLOT_FREE); slot++); + if (slot < ASL_MSG_PAGE_SLOTS) break; + } + } + + if (page == NULL) + { + /* allocate a new page and attach it */ + page = _asl_msg_make_page(); + if (page == NULL) + { + if (extkey != NULL) free(extkey); + if (extval != NULL) free(extval); + return -1; + } + + last->next = page; + slot = 0; + } + + /* copy key or external key pointer into page data */ + if (kx != 0) + { + page->key[slot] = kx; + } + else if (extkey == NULL) + { + page->key[slot] = page->data_size; + memcpy(page->data + page->data_size, key, keylen); + } + else + { + page->key[slot] = page->data_size | ASL_MSG_KV_EXTERN; + memcpy(page->data + page->data_size, &extkey, keylen); + } + + page->data_size += keylen; + + /* copy val or external val pointer into page data */ + page->val[slot] = ASL_MSG_SLOT_FREE; + + if (val != NULL) + { + if (extval == NULL) + { + page->val[slot] = page->data_size; + memcpy(page->data + page->data_size, val, vallen); + } + else + { + page->val[slot] = page->data_size | ASL_MSG_KV_EXTERN; + memcpy(page->data + page->data_size, &extval, vallen); + } + + page->data_size += vallen; + } + + /* set op */ + page->op[slot] = op; + + /* update page count */ + page->count++; + + return 0; +} + +/* + * Most of the code in asl_msg_set_key_val_op is concerned with trying to re-use + * space in an asl_msg_t page when given a new value for an existing key. + * If the key is new, we just call _asl_msg_new_key_val_op. + * + * Note that queries can have duplicate keys, so for ASL_TYPE_QUERY we just + * call through to _asl_msg_new_key_val_op. + */ +static int +_asl_msg_set_kvo(asl_msg_t *msg, const char *key, const char *val, uint32_t op) +{ + uint32_t i, slot, newexternal; + asl_msg_t *page; + uint32_t intvallen, extvallen, newvallen; + char *intval, *extval, *newval; + + if (msg == NULL) return -1; + if (key == NULL) return -1; + + slot = IndexNull; + page = NULL; + + if ((msg->type == ASL_TYPE_QUERY) || (IndexNull == _asl_msg_index(msg, key, &slot, &page))) + { + /* add key */ + return _asl_msg_new_key_val_op(msg, key, val, op); + } + + intval = NULL; + intvallen = 0; + + extval = NULL; + extvallen = 0; + + if (page->val[slot] != ASL_MSG_SLOT_FREE) + { + if ((page->val[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) + { + i = page->val[slot] & ASL_MSG_OFFSET_MASK; + memcpy(&extval, page->data + i, sizeof(char *)); + extvallen = sizeof(char *); + } + else + { + intval = page->data + page->val[slot]; + intvallen = strlen(intval) + 1; + } + } + + /* replace val and op for existing entry */ + + /* easy case - remove val */ + if (val == NULL) + { + if (extval != NULL) free(extval); + page->val[slot] = ASL_MSG_SLOT_FREE; + if (op != IndexNull) page->op[slot] = op; + return 0; + } + + /* trivial case - internal val doesn't change */ + if ((intval != NULL) && (streq(val, intval))) + { + if (op != IndexNull) page->op[slot] = op; + return 0; + } + + /* trivial case - external val doesn't change */ + if ((extval != NULL) && (streq(val, extval))) + { + if (op != IndexNull) page->op[slot] = op; + return 0; + } + + /* + * special case: we generally don't compress out holes in the data + * space, but if this is the last string in the currently used data space + * we can just back up the data_size and reset page->val[slot] + */ + i = page->val[slot] & ASL_MSG_OFFSET_MASK; + if ((intval != NULL) && ((i + intvallen) == page->data_size)) + { + page->val[slot] = ASL_MSG_SLOT_FREE; + page->data_size -= intvallen; + intval = NULL; + intvallen = 0; + } + else if ((extval != NULL) && ((i + extvallen) == page->data_size)) + { + page->val[slot] = ASL_MSG_SLOT_FREE; + page->data_size -= extvallen; + free(extval); + extval = NULL; + extvallen = 0; + } + + /* val changes - see if it needs to be external */ + newvallen = strlen(val) + 1; + newexternal = 0; + + if (newvallen > ASL_MSG_PAGE_DATA_SIZE) + { + newexternal = 1; + newvallen = sizeof(char *); + } + + /* check if there is room to change val in place */ + if (((extval != NULL) && (newvallen <= extvallen)) || ((extval == NULL) && (newvallen <= intvallen))) + { + if (extval != NULL) free(extval); + extval = NULL; + + /* we can re-use the space of the old value */ + i = page->val[slot] & ASL_MSG_OFFSET_MASK; + + if (newexternal == 1) + { + /* create an external val and copy in the new pointer */ + newval = strdup(val); + if (newval == NULL) return -1; + + page->val[slot] = i | ASL_MSG_KV_EXTERN; + memcpy(page->data + i, &newval, sizeof(char *)); + } + else + { + /* new internal value */ + page->val[slot] = i; + memcpy(page->data + i, val, newvallen); + } + + if (op != IndexNull) page->op[slot] = op; + return 0; + } + + /* we're done with the old value if it is external - free it now */ + if (extval != NULL) free(extval); + extval = NULL; + + if (newvallen <= (ASL_MSG_PAGE_DATA_SIZE - page->data_size)) + { + /* can't re-use the old space, but there's room on the page */ + i = page->data_size; + page->data_size += newvallen; + + if (newexternal == 1) + { + /* create an external val and copy in the new pointer */ + newval = strdup(val); + if (newval == NULL) return -1; + + page->val[slot] = i | ASL_MSG_KV_EXTERN; + memcpy(page->data + i, &newval, sizeof(char *)); + } + else + { + /* new internal value */ + page->val[slot] = i; + memcpy(page->data + i, val, newvallen); + } + + if (op != IndexNull) page->op[slot] = op; + return 0; + + } + + /* no room on this page - free up existing entry and treat this as a new entry */ + if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) + { + memcpy(&extval, page->data + (page->key[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *)); + free(extval); + } + + page->key[slot] = ASL_MSG_SLOT_FREE; + page->val[slot] = ASL_MSG_SLOT_FREE; + page->op[slot] = 0; + + return _asl_msg_new_key_val_op(msg, key, val, op); +} + +int +asl_msg_set_key_val_op(asl_msg_t *msg, const char *key, const char *val, uint32_t op) +{ + char *special, buf[512]; + uint32_t i, len; + int status; + + /* Special case handling */ + special = NULL; + + /* convert "Level" values to "0" through "7" */ + if (streq(key, ASL_KEY_LEVEL)) + { + if (val == NULL) val = "7"; + else if ((val[0] >= '0') && (val[0] <= '7') && (val[1] == '\0')) /* do nothing */; + else if (strcaseeq(val, ASL_STRING_EMERG)) val = "0"; + else if (strcaseeq(val, ASL_STRING_ALERT)) val = "1"; + else if (strcaseeq(val, ASL_STRING_CRIT)) val = "2"; + else if (strcaseeq(val, ASL_STRING_ERR)) val = "3"; + else if (strcaseeq(val, ASL_STRING_WARNING)) val = "4"; + else if (strcaseeq(val, ASL_STRING_NOTICE)) val = "5"; + else if (strcaseeq(val, ASL_STRING_INFO)) val = "6"; + else if (strcaseeq(val, ASL_STRING_DEBUG)) val = "7"; + else val = "7"; + } + + /* strip trailing newlines from "Message" values */ + if ((streq(key, ASL_KEY_MSG)) && (val != NULL)) + { + len = strlen(val); + i = len; + while ((i > 0) && (val[i - 1] == '\n')) i--; + if (i == 0) val = NULL; + else if (i < len) + { + /* use buf if it is big enough, else malloc a temporary buffer */ + if (i < sizeof(buf)) + { + memcpy(buf, val, i); + buf[i] = 0; + val = (const char *)buf; + } + else + { + special = malloc(i + 1); + if (special == NULL) return -1; + memcpy(special, val, i); + special[i] = 0; + val = (const char *)special; + } + } + } + + status = _asl_msg_set_kvo(msg, key, val, op); + + if (special != NULL) free(special); + return status; +} + +int +asl_msg_set_key_val(asl_msg_t *msg, const char *key, const char *val) +{ + return asl_msg_set_key_val_op(msg, key, val, 0); +} + +/* + * asl_msg_unset + * Frees external key and val strings, but does not try to reclaim data space. + */ +void +asl_msg_unset(asl_msg_t *msg, const char *key) +{ + uint32_t i, slot; + asl_msg_t *page; + char *ext; + + if (msg == NULL) return; + if (key == NULL) return; + + slot = IndexNull; + page = NULL; + + i = _asl_msg_index(msg, key, &slot, &page); + if (i == IndexNull) return; + + if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) + { + memcpy(&ext, page->data + (page->key[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *)); + free(ext); + } + + if ((page->val[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) + { + memcpy(&ext, page->data + (page->val[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *)); + free(ext); + } + + page->key[slot] = ASL_MSG_SLOT_FREE; + page->val[slot] = ASL_MSG_SLOT_FREE; + page->op[slot] = 0; + + page->count--; +} + +int +asl_msg_lookup(asl_msg_t *msg, const char *key, const char **valout, uint32_t *opout) +{ + uint32_t i, slot; + asl_msg_t *page; + + slot = IndexNull; + page = NULL; + + i = _asl_msg_index(msg, key, &slot, &page); + if (i == IndexNull) return -1; + + if (valout != NULL) *valout = _asl_msg_slot_val(page, slot); + if (opout != NULL) *opout = page->op[slot]; + + return 0; +} + +uint32_t +asl_msg_type(asl_msg_t *msg) +{ + if (msg == NULL) return 0; + return msg->type; +} + +uint32_t +asl_msg_count(asl_msg_t *msg) +{ + uint32_t total; + + total = 0; + + for (; msg != NULL; msg = msg->next) total += msg->count; + return total; +} + +/* + * Compare messages + */ +static int +_asl_msg_equal(asl_msg_t *a, asl_msg_t *b) +{ + uint32_t x, oa, ob; + const char *key, *va, *vb; + + if (asl_msg_count(a) != asl_msg_count(b)) return 0; + + key = NULL; + va = NULL; + oa = 0; + + + for (x = asl_msg_fetch(a, 0, &key, &va, &oa); x != IndexNull; x = asl_msg_fetch(a, x, &key, &va, &oa)) + { + if (asl_msg_lookup(b, key, &vb, &ob) != 0) return 0; + if (strcmp(va, vb)) return 0; + if ((a->type == ASL_TYPE_QUERY) && (oa != ob)) return 0; + } + + return 1; +} + +static int +_asl_isanumber(const char *s) +{ + int i; + + if (s == NULL) return 0; + + i = 0; + if ((s[0] == '-') || (s[0] == '+')) i = 1; + + if (s[i] == '\0') return 0; + + for (; s[i] != '\0'; i++) + { + if (!isdigit(s[i])) return 0; + } + + return 1; +} + +static int +_asl_msg_basic_test(uint32_t op, const char *q, const char *m, uint32_t n) +{ + int cmp; + uint32_t t; + int64_t nq, nm; + int rflags; + regex_t rex; + + t = op & ASL_QUERY_OP_TRUE; + + /* NULL value from query or message string fails */ + if ((q == NULL) || (m == NULL)) return (t & ASL_QUERY_OP_NOT_EQUAL); + + if (op & ASL_QUERY_OP_REGEX) + { + /* greater than or less than make no sense in substring search */ + if ((t == ASL_QUERY_OP_GREATER) || (t == ASL_QUERY_OP_LESS)) return 0; + + memset(&rex, 0, sizeof(regex_t)); + + rflags = REG_EXTENDED | REG_NOSUB; + if (op & ASL_QUERY_OP_CASEFOLD) rflags |= REG_ICASE; + + /* A bad reqular expression matches nothing */ + if (regcomp(&rex, q, rflags) != 0) return (t & ASL_QUERY_OP_NOT_EQUAL); + + cmp = regexec(&rex, m, 0, NULL, 0); + regfree(&rex); + + if (t == ASL_QUERY_OP_NOT_EQUAL) return (cmp != 0); + return (cmp == 0); + } + + if (op & ASL_QUERY_OP_NUMERIC) + { + if (_asl_isanumber(q) == 0) return (t == ASL_QUERY_OP_NOT_EQUAL); + if (_asl_isanumber(m) == 0) return (t == ASL_QUERY_OP_NOT_EQUAL); + + nq = atoll(q); + nm = atoll(m); + + switch (t) + { + case ASL_QUERY_OP_EQUAL: return (nm == nq); + case ASL_QUERY_OP_GREATER: return (nm > nq); + case ASL_QUERY_OP_GREATER_EQUAL: return (nm >= nq); + case ASL_QUERY_OP_LESS: return (nm < nq); + case ASL_QUERY_OP_LESS_EQUAL: return (nm <= nq); + case ASL_QUERY_OP_NOT_EQUAL: return (nm != nq); + default: return (t == ASL_QUERY_OP_NOT_EQUAL); + } + } + + cmp = 0; + if (op & ASL_QUERY_OP_CASEFOLD) + { + if (n == 0) cmp = strcasecmp(m, q); + else cmp = strncasecmp(m, q, n); + } + else + { + if (n == 0) cmp = strcmp(m, q); + else cmp = strncmp(m, q, n); + } + + switch (t) + { + case ASL_QUERY_OP_EQUAL: return (cmp == 0); + case ASL_QUERY_OP_GREATER: return (cmp > 0); + case ASL_QUERY_OP_GREATER_EQUAL: return (cmp >= 0); + case ASL_QUERY_OP_LESS: return (cmp < 0); + case ASL_QUERY_OP_LESS_EQUAL: return (cmp <= 0); + case ASL_QUERY_OP_NOT_EQUAL: return (cmp != 0); + } + + return (t == ASL_QUERY_OP_NOT_EQUAL); +} + +static int +_asl_msg_test_substring(uint32_t op, const char *q, const char *m) +{ + uint32_t t, i, d, lm, lq, match, newop; + + t = op & ASL_QUERY_OP_TRUE; + + lm = 0; + if (m != NULL) lm = strlen(m); + + lq = 0; + if (q != NULL) lq = strlen(q); + + /* NULL is a substring of any string */ + if (lq == 0) return (t & ASL_QUERY_OP_EQUAL); + + /* A long string is defined to be not equal to a short string */ + if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL); + + /* greater than or less than make no sense in substring search */ + if ((t == ASL_QUERY_OP_GREATER) || (t == ASL_QUERY_OP_LESS)) return 0; + + /* + * We scan the string doing an equality test. + * If the input test is equality, we stop as soon as we hit a match. + * Otherwise we keep scanning the whole message string. + */ + newop = op & 0xff0; + newop |= ASL_QUERY_OP_EQUAL; + + match = 0; + d = lm - lq; + for (i = 0; i <= d; i++) + { + if (_asl_msg_basic_test(newop, q, m + i, lq) != 0) + { + if (t & ASL_QUERY_OP_EQUAL) return 1; + match++; + } + } + + /* If the input test was for equality, no matches were found */ + if (t & ASL_QUERY_OP_EQUAL) return 0; + + /* The input test was for not equal. Return true if no matches were found */ + return (match == 0); +} + +static int +_asl_msg_test_prefix(uint32_t op, const char *q, const char *m) +{ + uint32_t lm, lq, t; + + t = op & ASL_QUERY_OP_TRUE; + + lm = 0; + if (m != NULL) lm = strlen(m); + + lq = 0; + if (q != NULL) lq = strlen(q); + + /* NULL is a prefix of any string */ + if (lq == 0) return (t & ASL_QUERY_OP_EQUAL); + + /* A long string is defined to be not equal to a short string */ + if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL); + + /* Compare two equal-length strings */ + return _asl_msg_basic_test(op, q, m, lq); +} + +static int +_asl_msg_test_suffix(uint32_t op, const char *q, const char *m) +{ + uint32_t lm, lq, d, t; + + t = op & ASL_QUERY_OP_TRUE; + + lm = 0; + if (m != NULL) lm = strlen(m); + + lq = 0; + if (q != NULL) lq = strlen(q); + + /* NULL is a suffix of any string */ + if (lq == 0) return (t & ASL_QUERY_OP_EQUAL); + + /* A long string is defined to be not equal to a short string */ + if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL); + + /* Compare two equal-length strings */ + d = lm - lq; + return _asl_msg_basic_test(op, q, m + d, lq); +} + +/* + * Splits out prefix, suffix, and substring tests. + * Sends the rest to _asl_msg_basic_test(). + */ +static int +_asl_msg_test_expression(uint32_t op, const char *q, const char *m) +{ + uint32_t t; + + t = op & ASL_QUERY_OP_TRUE; + if (t == ASL_QUERY_OP_TRUE) return 1; + + if (op & ASL_QUERY_OP_PREFIX) + { + if (op & ASL_QUERY_OP_SUFFIX) return _asl_msg_test_substring(op, q, m); + return _asl_msg_test_prefix(op, q, m); + } + if (op & ASL_QUERY_OP_SUFFIX) return _asl_msg_test_suffix(op, q, m); + + return _asl_msg_basic_test(op, q, m, 0); +} + +/* + * Special case for comparing time values. + * If both inputs are time strings, this compares the time + * value in seconds. Otherwise it just does normal matching. + */ +static int +_asl_msg_test_time_expression(uint32_t op, const char *q, const char *m) +{ + time_t tq, tm; + uint32_t t; + + if ((op & ASL_QUERY_OP_PREFIX) || (op & ASL_QUERY_OP_SUFFIX) || (op & ASL_QUERY_OP_REGEX)) return _asl_msg_test_expression(op, q, m); + if ((q == NULL) || (m == NULL)) return _asl_msg_test_expression(op, q, m); + + tq = asl_parse_time(q); + if (tq < 0) return _asl_msg_test_expression(op, q, m); + + tm = asl_parse_time(m); + if (tm < 0) return _asl_msg_test_expression(op, q, m); + + t = op & ASL_QUERY_OP_TRUE; + + switch (t) + { + case ASL_QUERY_OP_FALSE: + { + return 0; + } + case ASL_QUERY_OP_EQUAL: + { + if (tm == tq) return 1; + return 0; + } + case ASL_QUERY_OP_GREATER: + { + if (tm > tq) return 1; + return 0; + } + case ASL_QUERY_OP_GREATER_EQUAL: + { + if (tm >= tq) return 1; + return 0; + } + case ASL_QUERY_OP_LESS: + { + if (tm < tq) return 1; + return 0; + } + case ASL_QUERY_OP_LESS_EQUAL: + { + if (tm <= tq) return 1; + return 0; + } + case ASL_QUERY_OP_NOT_EQUAL: + { + if (tm != tq) return 1; + return 0; + } + case ASL_QUERY_OP_TRUE: + { + return 1; + } + } + + /* NOTREACHED */ + return 0; +} + +/* test a query against a message */ +static int +_asl_msg_test(asl_msg_t *q, asl_msg_t *m) +{ + uint32_t i, t, x, op; + int cmp; + const char *kq, *vq, *vm; + + /* + * Check each simple expression (key op val) separately. + * The query suceeds (returns 1) if all simple expressions + * succeed (i.e. AND the simple expressions). + */ + + kq = NULL; + vq = NULL; + op = 0; + + for (x = asl_msg_fetch(q, 0, &kq, &vq, &op); x != IndexNull; x = asl_msg_fetch(q, x, &kq, &vq, &op)) + { + /* Find query key in the message */ + vm = NULL; + i = asl_msg_lookup(m, kq, &vm, NULL); + + /* ASL_QUERY_OP_TRUE tests if key is present in the message */ + t = op & ASL_QUERY_OP_TRUE; + if (t == ASL_QUERY_OP_TRUE) + { + if (i != 0) return 0; + continue; + } + + /* ASL_QUERY_OP_FALSE tests if the key is NOT present in the message */ + if (t == ASL_QUERY_OP_FALSE) + { + if (i == 0) return 0; + continue; + } + + if (i != 0) + { + /* the message does NOT have query key - fail unless we are testing not equal */ + if (t == ASL_QUERY_OP_NOT_EQUAL) continue; + return 0; + } + + cmp = 1; + if (streq(kq, ASL_KEY_TIME)) + { + cmp = _asl_msg_test_time_expression(op, vq, vm); + } + else + { + cmp = _asl_msg_test_expression(op, vq, vm); + } + + if (cmp == 0) return 0; + } + + return 1; +} + +int +asl_msg_cmp(asl_msg_t *a, asl_msg_t *b) +{ + + if (a == NULL) return 0; + if (b == NULL) return 0; + + if (a->type == b->type) return _asl_msg_equal(a, b); + if (a->type == ASL_TYPE_QUERY) return _asl_msg_test(a, b); + return _asl_msg_test(b, a); +} + +static void +_asl_encode_char(char *buf, uint32_t *cursor, uint32_t c, uint32_t encode, uint32_t encode_space) +{ + char *p; + int meta; + + meta = 0; + + p = buf + *cursor; + + /* NUL is not allowed */ + if (c == 0) return; + + /* Meta chars get \M prefix */ + if (c >= 128) + { + /* except meta-space, which is \240 */ + if (c == 160) + { + *p++ = '\\'; + *p++ = '2'; + *p++ = '4'; + *p++ = '0'; + *p = '\0'; + *cursor = *cursor + 4; + return; + } + + *p++ = '\\'; + *p++ = 'M'; + *p = '\0'; + *cursor = *cursor + 2; + c &= 0x7f; + meta = 1; + } + + /* space is either ' ' or \s */ + if (c == 32) + { + if (encode_space == 0) + { + *p++ = ' '; + *p = '\0'; + *cursor = *cursor + 1; + return; + } + + *p++ = '\\'; + *p++ = 's'; + *p = '\0'; + *cursor = *cursor + 2; + return; + } + + /* \ is escaped */ + if ((meta == 0) && (c == 92)) + { + *p++ = '\\'; + *p++ = c; + *p = '\0'; + *cursor = *cursor + 2; + return; + } + + /* [ and ] are escaped in ASL encoding */ + if ((encode == ASL_ENCODE_ASL) && (meta == 0) && ((c == 91) || (c == 93))) + { + *p++ = '\\'; + *p++ = c; + *p = '\0'; + *cursor = *cursor + 2; + return; + } + + /* DEL is \^? */ + if (c == 127) + { + if (meta == 0) + { + *p++ = '\\'; + *cursor = *cursor + 1; + } + + *p++ = '^'; + *p++ = '?'; + *p = '\0'; + *cursor = *cursor + 2; + return; + } + + /* 33-126 are printable (add a '-' prefix for meta) */ + if ((c >= 33) && (c <= 126)) + { + if (meta == 1) + { + *p++ = '-'; + *cursor = *cursor + 1; + } + + *p++ = c; + *p = '\0'; + *cursor = *cursor + 1; + return; + } + + /* non-meta BEL, BS, HT, NL, VT, NP, CR (7-13) are \a, \b, \t, \n, \v, \f, and \r */ + if ((meta == 0) && (c >= 7) && (c <= 13)) + { + *p++ = '\\'; + *p++ = cvis_7_13[c - 7]; + *p = '\0'; + *cursor = *cursor + 2; + return; + } + + /* 0 - 31 are ^@ - ^_ (non-meta get a leading \) */ + if ((c >= 0) && (c <= 31)) + { + if (meta == 0) + { + *p++ = '\\'; + *cursor = *cursor + 1; + } + + *p++ = '^'; + *p++ = 64 + c; + *p = '\0'; + *cursor = *cursor + 2; + return; + } + + return; +} + +static uint32_t +_asl_append_string_length(const char *s, uint32_t encode, uint32_t escspace) +{ + uint32_t i, n, spextra, outlen; + uint8_t c; + + if (s == NULL) return 0; + + outlen = 0; + + if (encode == ASL_ENCODE_NONE) + { + /* no encoding - just need enough space for the string */ + return strlen(s); + } + else if (encode == ASL_ENCODE_SAFE) + { + /* minor encoding to reduce the likelyhood of spoof attacks */ + n = 0; + for (i = 0; s[i] != '\0'; i++) + { + n++; + c = s[i]; + if ((c == 10) || (c == 13) || (c == 8)) n++; + } + + return n; + } + + spextra = 0; + if (escspace != 0) spextra = 1; + + n = 0; + for (i = 0; s[i] != '\0'; i++) + { + c = s[i]; + + if (c >= 128) + { + n += 4; + } + else if ((c == 91) || (c == 93)) + { + if (encode == ASL_ENCODE_ASL) n += 2; + else n += 1; + } + else + { + n += char_encode_len[c]; + if (c == 32) n += spextra; + } + } + + return n; +} + + +/* + * Append a string using the requested encoding to a buffer. + */ +static void +_asl_append_string(char *buf, uint32_t bufsize, uint32_t *cursor, const char *s, uint32_t encode, uint32_t escspace) +{ + uint32_t i, n, spextra; + uint8_t c; + char *p; + + if (buf == NULL) return; + if (cursor == NULL) return; + if (s == NULL) return; + + if (encode == ASL_ENCODE_NONE) + { + /* no encoding - just use enough space and copy the string */ + + n = strlen(s); + if (n == 0) return; + + assert((*cursor + n) < bufsize); + + memcpy(buf + *cursor, s, n); + *cursor = *cursor + n; + + return; + } + else if (encode == ASL_ENCODE_SAFE) + { + /* + * Minor encoding to reduce the likelyhood of spoof attacks. + * + * - append a tab after newlines + * - translate \r to newline & append a tab + * - map backspace to ^H + * + * Note that there may be UTF-8 characters that could be used in a spoof + * attack that we don't check. Caveat Reador. + */ + n = 0; + for (i = 0; s[i] != '\0'; i++) + { + n++; + c = s[i]; + if ((c == 10) || (c == 13) || (c == 8)) n++; + } + + if (n == 0) return; + + assert((*cursor + n) < bufsize); + + p = buf + *cursor; + + for (i = 0; s[i] != '\0'; i++) + { + c = s[i]; + if ((c == 10) || (c == 13)) + { + *p++ = '\n'; + *p++ = '\t'; + *cursor = *cursor + 2; + } + else if (c == 8) + { + *p++ = '^'; + *p++ = 'H'; + *cursor = *cursor + 2; + } + else + { + *p++ = c; + *cursor = *cursor + 1; + } + } + + return; + } + + spextra = 0; + + if (escspace != 0) spextra = 1; + + n = 0; + for (i = 0; s[i] != '\0'; i++) + { + c = s[i]; + + if (c >= 128) + { + n += 4; + } + else if ((c == 91) || (c == 93)) + { + if (encode == ASL_ENCODE_ASL) n += 2; + else n += 1; + } + else + { + n += char_encode_len[c]; + if (c == 32) n += spextra; + } + } + + if (n == 0) return; + + assert((*cursor + n) < bufsize); + + for (i = 0; s[i] != '\0'; i++) + { + c = s[i]; + _asl_encode_char(buf, cursor, c, encode, escspace); + } +} + + +static uint32_t +_asl_append_xml_string_length(const char *s) +{ + uint32_t i, n; + uint8_t c; + + if (s == NULL) return 0; + + n = 0; + for (i = 0; s[i] != '\0'; i++) + { + c = s[i]; + + /* + * XML wants & < > " and ' + * We use &#xnn; for control chars. + * Everything else just gets printed "as is" (we know the input is UTF8) + */ + if (c == '&') n += 5; + else if (c == '<') n += 4; + else if (c == '>') n += 4; + else if (c == '"') n += 6; + else if (c == '\'') n += 6; + else if (iscntrl(c)) n += 6; + else n += 1; + } + + return n; +} + +static int +_asl_append_xml_string(char *buf, uint32_t bufsize, uint32_t *cursor, const char *s) +{ + uint32_t i, n; + uint8_t c; + char tmp[8], *p; + + if (buf == NULL) return -1; + if (cursor == NULL) return -1; + if (s == NULL) return -1; + + n = 0; + for (i = 0; s[i] != '\0'; i++) + { + c = s[i]; + + /* + * XML wants & < > " and ' + * We use &#xnn; for control chars. + * Everything else just gets printed "as is" (we know the input is UTF8) + */ + if (c == '&') n += 5; + else if (c == '<') n += 4; + else if (c == '>') n += 4; + else if (c == '"') n += 6; + else if (c == '\'') n += 6; + else if (iscntrl(c)) n += 6; + else n += 1; + } + + if (n == 0) return 0; + + assert((*cursor + n) < bufsize); + p = buf + *cursor; + + for (i = 0; s[i] != '\0'; i++) + { + c = s[i]; + + if (c == '&') + { + memcpy(p, "&", 5); + p += 5; + *cursor = *cursor + 5; + } + else if (c == '<') + { + memcpy(p, "<", 4); + p += 4; + *cursor = *cursor + 4; + } + else if (c == '>') + { + memcpy(p, ">", 4); + p += 4; + *cursor = *cursor + 4; + } + else if (c == '"') + { + memcpy(p, """, 6); + p += 6; + *cursor = *cursor + 6; + } + else if (c == '\'') + { + memcpy(p, "'", 6); + p += 6; + *cursor = *cursor + 6; + } + else if (iscntrl(c)) + { + snprintf(tmp, sizeof(tmp), "&#x%02hhx;", c); + memcpy(p, tmp, 6); + p += 6; + *cursor = *cursor + 6; + } + else + { + *p++ = c; + *cursor = *cursor + 1; + } + } + + return 0; +} + +static uint32_t +_asl_append_xml_tag_length(int tag, const char *s) +{ + uint32_t len, slen; + + len = 0; + + if (tag == XML_TAG_KEY) + { + len += 14; /* "\t\t" + "\n" */ + len += _asl_append_xml_string_length(s); + } + else if (tag == XML_TAG_STRING) + { + len += 20; /* "\t\t" + "\n" */ + len += _asl_append_xml_string_length(s); + } + else if (tag == XML_TAG_DATA) + { + len += 16; /* "\t\t" + "\n" */ + slen = strlen(s); + len += ((len + 2) / 3) * 4; + } + + return len; +} + +/* called from asl_format_message */ +static void +_asl_append_xml_tag(char *buf, uint32_t bufsize, uint32_t *cursor, int tag, const char *s) +{ + char *b64; + + if (buf == NULL) return; + if (cursor == NULL) return; + + if (tag == XML_TAG_KEY) + { + _asl_append_string(buf, bufsize, cursor, "\t\t", ASL_ENCODE_NONE, 0); + _asl_append_xml_string(buf, bufsize, cursor, s); + _asl_append_string(buf, bufsize, cursor, "\n", ASL_ENCODE_NONE, 0); + return; + } + else if (tag == XML_TAG_STRING) + { + _asl_append_string(buf, bufsize, cursor, "\t\t", ASL_ENCODE_NONE, 0); + _asl_append_xml_string(buf, bufsize, cursor, s); + _asl_append_string(buf, bufsize, cursor, "\n", ASL_ENCODE_NONE, 0); + return; + } + else if (tag == XML_TAG_DATA) + { + _asl_append_string(buf, bufsize, cursor, "\t\t", ASL_ENCODE_NONE, 0); + b64 = (char *)asl_b64_encode((uint8_t *)s, strlen(s)); + if (b64 != NULL) + { + _asl_append_string(buf, bufsize, cursor, b64, ASL_ENCODE_NONE, 0); + free(b64); + } + + _asl_append_string(buf, bufsize, cursor, "\n", ASL_ENCODE_NONE, 0); + return; + } +} + +static uint32_t +_asl_append_op_length(uint32_t op) +{ + uint32_t i; + + if (op == ASL_QUERY_OP_NULL) return 1; + + i = 0; + + if (op & ASL_QUERY_OP_CASEFOLD) i++; + if (op & ASL_QUERY_OP_REGEX) i++; + if (op & ASL_QUERY_OP_NUMERIC) i++; + if (op & ASL_QUERY_OP_PREFIX) i++; + if (op & ASL_QUERY_OP_SUFFIX) i++; + + switch (op & ASL_QUERY_OP_TRUE) + { + case ASL_QUERY_OP_EQUAL: + case ASL_QUERY_OP_GREATER: + case ASL_QUERY_OP_LESS: + case ASL_QUERY_OP_NOT_EQUAL: + case ASL_QUERY_OP_TRUE: + i++; + break; + case ASL_QUERY_OP_LESS_EQUAL: + case ASL_QUERY_OP_GREATER_EQUAL: + i += 2; + break; + default: + break; + } + + if (i == 0) return 1; + return i; +} + + +static void +_asl_append_op(char *buf, uint32_t bufsize, uint32_t *cursor, uint32_t op) +{ + char opstr[8]; + uint32_t i; + + if (buf == NULL) return; + if (cursor == NULL) return; + + if (op == ASL_QUERY_OP_NULL) + { + _asl_append_string(buf, bufsize, cursor, ".", ASL_ENCODE_NONE, 0); + return; + } + + i = 0; + if (op & ASL_QUERY_OP_CASEFOLD) opstr[i++] = 'C'; + + if (op & ASL_QUERY_OP_REGEX) opstr[i++] = 'R'; + + if (op & ASL_QUERY_OP_NUMERIC) opstr[i++] = 'N'; + + if (op & ASL_QUERY_OP_PREFIX) + { + if (op & ASL_QUERY_OP_SUFFIX) opstr[i++] = 'S'; + else opstr[i++] = 'A'; + } + if (op & ASL_QUERY_OP_SUFFIX) opstr[i++] = 'Z'; + + switch (op & ASL_QUERY_OP_TRUE) + { + case ASL_QUERY_OP_EQUAL: + opstr[i++] = '='; + break; + case ASL_QUERY_OP_GREATER: + opstr[i++] = '>'; + break; + case ASL_QUERY_OP_GREATER_EQUAL: + opstr[i++] = '>'; + opstr[i++] = '='; + break; + case ASL_QUERY_OP_LESS: + opstr[i++] = '<'; + break; + case ASL_QUERY_OP_LESS_EQUAL: + opstr[i++] = '<'; + opstr[i++] = '='; + break; + case ASL_QUERY_OP_NOT_EQUAL: + opstr[i++] = '!'; + break; + case ASL_QUERY_OP_TRUE: + opstr[i++] = 'T'; + break; + default: + break; + } + + if (i == 0) + { + _asl_append_string(buf, bufsize, cursor, ".", ASL_ENCODE_NONE, 0); + return; + } + + opstr[i] = '\0'; + _asl_append_string(buf, bufsize, cursor, opstr, ASL_ENCODE_NONE, 0); +} + +static char * +_asl_time_string(int fmt, const char *str) +{ + time_t tick; + struct tm *stm; + char *ltime; + char *out; + char ltbuf[32]; + out = NULL; + + tick = 0; + if (str != NULL) tick = asl_parse_time(str); + + if (fmt == TFMT_SEC) + { + asprintf(&out, "%lu", tick); + return out; + } + + if (fmt == TFMT_UTC) + { + stm = gmtime(&tick); + asprintf(&out, "%d.%02d.%02d %02d:%02d:%02d UTC", stm->tm_year + 1900, stm->tm_mon + 1, stm->tm_mday, stm->tm_hour, stm->tm_min, stm->tm_sec); + return out; + } + + if (fmt == TFMT_LCL) + { + ltime = ctime_r(&tick, ltbuf); + if (ltime == NULL) return NULL; + ltime[19] = '\0'; + asprintf(&out, "%s", ltime + 4); + return out; + } + + return NULL; +} + +/* called from asl_format_message */ +static char * +_asl_msg_to_string_time_fmt(asl_msg_t *msg, uint32_t *len, int tf) +{ + uint32_t i, x, count, bufsize, cursor; + char *buf, *timestr; + const char *key, *val; + + *len = 0; + + if (msg == NULL) return NULL; + + timestr = NULL; + buf = NULL; + + count = asl_msg_count(msg); + + if (count == 0) return NULL; + + key = NULL; + val = NULL; + + /* first pass: determine output string length */ + bufsize = 0; + i = 0; + + for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL)) + { + if (key == NULL) continue; + + if (i > 0) bufsize += 1; /* " " */ + + /* "[" */ + bufsize += 1; + + bufsize += _asl_append_string_length(key, ASL_ENCODE_ASL, 1); + + if ((tf != TFMT_SEC) && (!strcmp(key, ASL_KEY_TIME))) + { + timestr = _asl_time_string(tf, val); + if (timestr != NULL) + { + /* " " */ + bufsize += 1; + bufsize += _asl_append_string_length(timestr, ASL_ENCODE_ASL, 0); + } + } + else if (val != NULL) + { + /* " " */ + bufsize += 1; + bufsize += _asl_append_string_length(val, ASL_ENCODE_ASL, 0); + } + + /* "]" */ + bufsize += 1; + + i++; + } + + /* "\n\0" */ + bufsize += 2; + + /* allocate the output string */ + buf = malloc(bufsize); + if (buf == NULL) return NULL; + + cursor = 0; + i = 0; + + /* second pass: construct the output string */ + + for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL)) + { + if (key == NULL) continue; + + if (i > 0) + { + assert(cursor < bufsize); + buf[cursor++] = ' '; + } + + assert(cursor < bufsize); + buf[cursor++] = '['; + + _asl_append_string(buf, bufsize, &cursor, key, ASL_ENCODE_ASL, 1); + + if ((tf != TFMT_SEC) && (!strcmp(key, ASL_KEY_TIME))) + { + if (timestr != NULL) + { + assert(cursor < bufsize); + buf[cursor++] = ' '; + _asl_append_string(buf, bufsize, &cursor, timestr, ASL_ENCODE_ASL, 0); + free(timestr); + } + } + else if (val != NULL) + { + assert(cursor < bufsize); + buf[cursor++] = ' '; + _asl_append_string(buf, bufsize, &cursor, val, ASL_ENCODE_ASL, 0); + } + + assert(cursor < bufsize); + buf[cursor++] = ']'; + + i++; + } + + assert((cursor + 1) < bufsize); + buf[cursor++] = '\n'; + buf[cursor] = '\0'; + + *len = bufsize; + return buf; +} + +static uint32_t +_msg_length_helper(uint32_t *i, uint32_t type, const char *key, const char *val, uint32_t op) +{ + uint32_t outlen; + + outlen = 0; + + if (*i > 0) outlen = 1; /* " " */ + *i = *i + 1; + + /* "[" */ + outlen += 1; + + if (type == ASL_TYPE_QUERY) + { + outlen += _asl_append_op_length(op); + + /* " " */ + outlen += 1; + } + + outlen += _asl_append_string_length(key, ASL_ENCODE_ASL, 1); + + if (val != NULL) + { + /* " " */ + outlen += 1; + outlen += _asl_append_string_length(val, ASL_ENCODE_ASL, 0); + } + + /* "]" */ + outlen += 1; + + return outlen; +} + +__private_extern__ uint32_t +_asl_msg_string_length_aux(asl_msg_t *msg, asl_msg_aux_t *aux) +{ + uint32_t i, x, slot, op, outlen, auxbits, type; + char *s; + const char *key, *val; + asl_msg_t *page; + + s = NULL; + type = ASL_TYPE_MSG; + + outlen = 0; + if ((msg != NULL) && (msg->type == ASL_TYPE_QUERY)) + { + type = ASL_TYPE_QUERY; + outlen = 2; /* "Q " */ + if (asl_msg_count(msg) == 0) return outlen + 1; + } + + auxbits = 0; + + key = NULL; + val = NULL; + op = 0; + i = 0; + + /* process aux keys */ + if ((aux != NULL) && (aux->type == ASL_MSG_TYPE_AUX_0)) + { + if (aux->data.aux0->level != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_LEVEL, aux->data.aux0->level, op); + auxbits |= AUX_0_LEVEL; + } + + if (aux->data.aux0->time != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_TIME, aux->data.aux0->time, op); + auxbits |= AUX_0_TIME; + } + + if (aux->data.aux0->nano != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_TIME_NSEC, aux->data.aux0->nano, op); + auxbits |= AUX_0_TIME_NSEC; + } + + if (aux->data.aux0->host != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_HOST, aux->data.aux0->host, op); + auxbits |= AUX_0_HOST; + } + + if (aux->data.aux0->sender != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_SENDER, aux->data.aux0->sender, op); + auxbits |= AUX_0_SENDER; + } + + if (aux->data.aux0->facility != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_FACILITY, aux->data.aux0->facility, op); + auxbits |= AUX_0_FACILITY; + } + + if (aux->data.aux0->pid != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_PID, aux->data.aux0->pid, op); + auxbits |= AUX_0_PID; + } + + if (aux->data.aux0->uid != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_UID, aux->data.aux0->uid, op); + auxbits |= AUX_0_UID; + } + + if (aux->data.aux0->gid != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_GID, aux->data.aux0->gid, op); + auxbits |= AUX_0_GID; + } + + if (aux->data.aux0->message != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_MSG, aux->data.aux0->message, op); + auxbits |= AUX_0_MSG; + } + + if (aux->data.aux0->option != NULL) + { + outlen += _msg_length_helper(&i, type, ASL_KEY_OPTION, aux->data.aux0->option, op); + auxbits |= AUX_0_OPTION; + } + } + + page = NULL; + slot = IndexNull; + + for (x = _asl_msg_fetch_internal(msg, 0, &key, &val, &op, &page, &slot); x != IndexNull; x = _asl_msg_fetch_internal(msg, x, &key, &val, &op, &page, &slot)) + { + if ((key == NULL) || (page == NULL) || (slot == IndexNull)) continue; + + /* ignore in msg if an override value was supplied in aux */ + if ((page->key[slot] == ASL_STD_KEY_LEVEL) && (auxbits & AUX_0_LEVEL)) continue; + if ((page->key[slot] == ASL_STD_KEY_TIME) && (auxbits & AUX_0_TIME)) continue; + if ((page->key[slot] == ASL_STD_KEY_NANO) && (auxbits & AUX_0_TIME_NSEC)) continue; + if ((page->key[slot] == ASL_STD_KEY_HOST) && (auxbits & AUX_0_HOST)) continue; + if ((page->key[slot] == ASL_STD_KEY_SENDER) && (auxbits & AUX_0_SENDER)) continue; + if ((page->key[slot] == ASL_STD_KEY_FACILITY) && (auxbits & AUX_0_FACILITY)) continue; + if ((page->key[slot] == ASL_STD_KEY_PID) && (auxbits & AUX_0_PID)) continue; + if ((page->key[slot] == ASL_STD_KEY_UID) && (auxbits & AUX_0_UID)) continue; + if ((page->key[slot] == ASL_STD_KEY_GID) && (auxbits & AUX_0_GID)) continue; + if ((page->key[slot] == ASL_STD_KEY_MESSAGE) && (auxbits & AUX_0_MSG)) continue; + if ((page->key[slot] == ASL_STD_KEY_OPTION) && (auxbits & AUX_0_OPTION)) continue; + + outlen += _msg_length_helper(&i, type, key, val, op); + } + + if (outlen > 0) outlen++; /* trailing NUL */ + + return outlen; +} + +uint32_t +asl_msg_string_length(asl_msg_t *msg) +{ + return _asl_msg_string_length_aux(msg, NULL); +} + +static void +_msg_to_string_buffer_helper(uint32_t *i, uint32_t type, char *buf, uint32_t bufsize, uint32_t *cursor, const char *key, const char *val, uint32_t op) +{ + if (*i > 0) + { + assert(*cursor < bufsize); + buf[*cursor] = ' '; + *cursor = *cursor + 1; + } + + *i = *i + 1; + + assert(*cursor < bufsize); + buf[*cursor] = '['; + *cursor = *cursor + 1; + + if (type == ASL_TYPE_QUERY) + { + _asl_append_op(buf, bufsize, cursor, op); + + assert(*cursor < bufsize); + buf[*cursor] = ' '; + *cursor = *cursor + 1; + } + + _asl_append_string(buf, bufsize, cursor, key, ASL_ENCODE_ASL, 1); + + if (val != NULL) + { + assert(*cursor < bufsize); + buf[*cursor] = ' '; + *cursor = *cursor + 1; + + _asl_append_string(buf, bufsize, cursor, val, ASL_ENCODE_ASL, 0); + } + + assert(*cursor < bufsize); + buf[*cursor] = ']'; + *cursor = *cursor + 1; +} + +__private_extern__ uint32_t +_asl_msg_to_string_buffer_aux(asl_msg_t *msg, asl_msg_aux_t *aux, char *buf, uint32_t bufsize) +{ + uint32_t i, x, slot, op, cursor, auxbits, type; + char *s; + const char *key, *val; + asl_msg_t *page; + + cursor = 0; + + if (buf == NULL) return -1; + + s = NULL; + type = ASL_TYPE_MSG; + + if ((msg != NULL) && (msg->type == ASL_TYPE_QUERY)) + { + type = ASL_TYPE_QUERY; + assert((cursor + 1) < bufsize); + buf[cursor++] = 'Q'; + buf[cursor++] = ' '; + if (asl_msg_count(msg) == 0) + { + assert(cursor < bufsize); + buf[cursor] = '\0'; + return 0; + } + } + + auxbits = 0; + + key = NULL; + val = NULL; + op = 0; + i = 0; + + /* process aux keys */ + if ((aux != NULL) && (aux->type == ASL_MSG_TYPE_AUX_0)) + { + if (aux->data.aux0->level != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_LEVEL, aux->data.aux0->level, op); + auxbits |= AUX_0_LEVEL; + } + + if (aux->data.aux0->time != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_TIME, aux->data.aux0->time, op); + auxbits |= AUX_0_TIME; + } + + if (aux->data.aux0->nano != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_TIME_NSEC, aux->data.aux0->nano, op); + auxbits |= AUX_0_TIME_NSEC; + } + + if (aux->data.aux0->host != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_HOST, aux->data.aux0->host, op); + auxbits |= AUX_0_HOST; + } + + if (aux->data.aux0->sender != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_SENDER, aux->data.aux0->sender, op); + auxbits |= AUX_0_SENDER; + } + + if (aux->data.aux0->facility != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_FACILITY, aux->data.aux0->facility, op); + auxbits |= AUX_0_FACILITY; + } + + if (aux->data.aux0->pid != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_PID, aux->data.aux0->pid, op); + auxbits |= AUX_0_PID; + } + + if (aux->data.aux0->uid != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_UID, aux->data.aux0->uid, op); + auxbits |= AUX_0_UID; + } + + if (aux->data.aux0->gid != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_GID, aux->data.aux0->gid, op); + auxbits |= AUX_0_GID; + } + + if (aux->data.aux0->message != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_MSG, aux->data.aux0->message, op); + auxbits |= AUX_0_MSG; + } + + if (aux->data.aux0->option != NULL) + { + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, ASL_KEY_OPTION, aux->data.aux0->option, op); + auxbits |= AUX_0_OPTION; + } + } + + page = NULL; + slot = IndexNull; + + for (x = _asl_msg_fetch_internal(msg, 0, &key, &val, &op, &page, &slot); x != IndexNull; x = _asl_msg_fetch_internal(msg, x, &key, &val, &op, &page, &slot)) + { + if ((key == NULL) || (page == NULL) || (slot == IndexNull)) continue; + + /* ignore in msg if an override value was supplied in aux */ + if ((page->key[slot] == ASL_STD_KEY_LEVEL) && (auxbits & AUX_0_LEVEL)) continue; + if ((page->key[slot] == ASL_STD_KEY_TIME) && (auxbits & AUX_0_TIME)) continue; + if ((page->key[slot] == ASL_STD_KEY_NANO) && (auxbits & AUX_0_TIME_NSEC)) continue; + if ((page->key[slot] == ASL_STD_KEY_HOST) && (auxbits & AUX_0_HOST)) continue; + if ((page->key[slot] == ASL_STD_KEY_SENDER) && (auxbits & AUX_0_SENDER)) continue; + if ((page->key[slot] == ASL_STD_KEY_FACILITY) && (auxbits & AUX_0_FACILITY)) continue; + if ((page->key[slot] == ASL_STD_KEY_PID) && (auxbits & AUX_0_PID)) continue; + if ((page->key[slot] == ASL_STD_KEY_UID) && (auxbits & AUX_0_UID)) continue; + if ((page->key[slot] == ASL_STD_KEY_GID) && (auxbits & AUX_0_GID)) continue; + if ((page->key[slot] == ASL_STD_KEY_MESSAGE) && (auxbits & AUX_0_MSG)) continue; + if ((page->key[slot] == ASL_STD_KEY_OPTION) && (auxbits & AUX_0_OPTION)) continue; + + _msg_to_string_buffer_helper(&i, type, buf, bufsize, &cursor, key, val, op); + } + + assert(cursor < bufsize); + buf[cursor] = '\0'; + + return 0; +} + +uint32_t +asl_msg_to_string_buffer(asl_msg_t *msg, char *buf, uint32_t bufsize) +{ + return _asl_msg_to_string_buffer_aux(msg, NULL, buf, bufsize); +} + +char * +asl_msg_to_string(asl_msg_t *in, uint32_t *len) +{ + uint32_t status, outlen; + char *out; + + *len = 0; + + if (in == NULL) return NULL; + + out = NULL; + outlen = _asl_msg_string_length_aux(in, NULL); + if (outlen == 0) return NULL; + + out = malloc(outlen); + if (out == NULL) return NULL; + + status = _asl_msg_to_string_buffer_aux(in, NULL, out, outlen); + if (status != 0) + { + free(out); + return NULL; + } + + *len = outlen; + return out; +} + +static uint32_t +_asl_msg_op_from_string(char *o) +{ + uint32_t op, i; + + op = ASL_QUERY_OP_NULL; + + if (o == NULL) return op; + + for (i = 0; o[i] != '\0'; i++) + { + if (o[i] == '.') return ASL_QUERY_OP_NULL; + if (o[i] == 'C') op |= ASL_QUERY_OP_CASEFOLD; + if (o[i] == 'R') op |= ASL_QUERY_OP_REGEX; + if (o[i] == 'N') op |= ASL_QUERY_OP_NUMERIC; + if (o[i] == 'S') op |= ASL_QUERY_OP_SUBSTRING; + if (o[i] == 'A') op |= ASL_QUERY_OP_PREFIX; + if (o[i] == 'Z') op |= ASL_QUERY_OP_SUFFIX; + if (o[i] == '<') op |= ASL_QUERY_OP_LESS; + if (o[i] == '>') op |= ASL_QUERY_OP_GREATER; + if (o[i] == '=') op |= ASL_QUERY_OP_EQUAL; + if (o[i] == '!') op |= ASL_QUERY_OP_NOT_EQUAL; + if (o[i] == 'T') op |= ASL_QUERY_OP_TRUE; + } + + return op; +} + +static char * +_asl_msg_get_next_word(char **p, uint32_t *tt, uint32_t spacedel) +{ + char *str, *out, c, oval; + uint32_t i, len, n, outlen; + + *tt = TOKEN_NULL; + + if (p == NULL) return NULL; + if (*p == NULL) return NULL; + if (**p == '\0') return NULL; + + /* skip one space if it's there (word separator) */ + if (**p == ' ') (*p)++; + + /* skip leading white space */ + if (spacedel != 0) + { + while ((**p == ' ') || (**p == '\t')) (*p)++; + } + + if (**p == '\0') return NULL; + if (**p == '\n') return NULL; + + str = *p; + + /* opening [ */ + if (**p == '[') + { + *tt = TOKEN_OPEN; + + (*p)++; + out = malloc(2); + if (out == NULL) return NULL; + + out[0] = '['; + out[1] = '\0'; + return out; + } + + /* scan for token and calulate it's length (input and decoded output len) */ + len = 0; + outlen = 0; + + forever + { + c = str[len]; + + /* stop scanning when we hit a delimiter */ + if (((spacedel != 0) && (c == ' ')) || (c == ']') || (c == '\0')) break; + + if (c == '\\') + { + len++; + c = str[len]; + if ((c == 'a') || (c == 'b') || (c == 't') || (c == 'n') || (c == 'v') || (c == 'f') || (c == 'r') || (c == 's') || (c == '[') || (c == '\\') || (c == ']')) + { + } + else if (c == '^') + { + if (str[++len] == '\0') return NULL; + } + else if (c == 'M') + { + if (str[++len] == '\0') return NULL; + if (str[++len] == '\0') return NULL; + } + else if ((c >= '0') && (c <= '3')) + { + if (str[++len] == '\0') return NULL; + if (str[++len] == '\0') return NULL; + } + else + { + return NULL; + } + } + + len++; + outlen++; + } + + (*p) += len; + + if ((len == 0) && (**p == ']')) + { + *tt = TOKEN_CLOSE; + (*p)++; + out = malloc(2); + if (out == NULL) return NULL; + + out[0] = ']'; + out[1] = '\0'; + return out; + } + + *tt = TOKEN_INT; + + out = malloc(outlen + 1); + if (out == NULL) return NULL; + + n = 0; + for (i = 0; i < len; i++) + { + c = str[i]; + + if (c == '\\') + { + *tt = TOKEN_WORD; + + i++; + c = str[i]; + if (c == 'a') + { + out[n++] = '\a'; + } + else if (c == 'b') + { + out[n++] = '\b'; + } + else if (c == 't') + { + out[n++] = '\t'; + } + else if (c == 'n') + { + out[n++] = '\n'; + } + else if (c == 'v') + { + out[n++] = '\v'; + } + else if (c == 'f') + { + out[n++] = '\f'; + } + else if (c == 'r') + { + out[n++] = '\r'; + } + else if (c == 's') + { + out[n++] = ' '; + } + else if (c == '[') + { + out[n++] = '['; + } + else if (c == '\\') + { + out[n++] = '\\'; + } + else if (c == ']') + { + out[n++] = ']'; + } + else if (c == '^') + { + i++; + if (str[i] == '?') out[n++] = 127; + else out[n++] = str[i] - 64; + } + else if (c == 'M') + { + i++; + c = str[i]; + if (c == '^') + { + i++; + if (str[i] == '?') out[n++] = 255; + else out[n++] = str[i] + 64; + } + else if (c == '-') + { + i++; + out[n++] = str[i] + 128; + } + else + { + *tt = TOKEN_NULL; + free(out); + return NULL; + } + + } + else if ((c >= '0') && (c <= '3')) + { + oval = (c - '0') * 64; + + i++; + c = str[i]; + if ((c < '0') || (c > '7')) + { + *tt = TOKEN_NULL; + free(out); + return NULL; + } + + oval += ((c - '0') * 8); + + i++; + c = str[i]; + if ((c < '0') || (c > '7')) + { + *tt = TOKEN_NULL; + free(out); + return NULL; + } + + oval += (c - '0'); + + out[n++] = oval; + } + else + { + *tt = TOKEN_NULL; + free(out); + return NULL; + } + } + else + { + + if ((c < '0') || (c > '9')) *tt = TOKEN_WORD; + out[n++] = c; + } + } + + out[n] = '\0'; + + return out; +} + +asl_msg_t * +asl_msg_from_string(const char *buf) +{ + uint32_t tt, type, op; + char *k, *v, *o, *p; + asl_msg_t *out; + + if (buf == NULL) return NULL; + + type = ASL_TYPE_MSG; + p = (char *)buf; + + k = _asl_msg_get_next_word(&p, &tt, 1); + if (k == NULL) return NULL; + + if (streq(k, "Q")) + { + type = ASL_TYPE_QUERY; + free(k); + + k = _asl_msg_get_next_word(&p, &tt, 1); + } + else if (tt == TOKEN_INT) + { + /* Leading integer is a string length - skip it */ + free(k); + k = _asl_msg_get_next_word(&p, &tt, 1); + if (k == NULL) return NULL; + } + + out = asl_msg_new(ASL_TYPE_MSG); + if (out == NULL) return NULL; + + out->type = type; + + /* OPEN WORD [WORD [WORD]] CLOSE */ + while (k != NULL) + { + op = ASL_QUERY_OP_NULL; + + if (tt != TOKEN_OPEN) + { + asl_msg_release(out); + return NULL; + } + + free(k); + + /* get op for query type */ + if (type == ASL_TYPE_QUERY) + { + o = _asl_msg_get_next_word(&p, &tt, 1); + if ((o == NULL) || (tt != TOKEN_WORD)) + { + if (o != NULL) free(o); + asl_msg_release(out); + return NULL; + } + + op = _asl_msg_op_from_string(o); + free(o); + } + + k = _asl_msg_get_next_word(&p, &tt, 1); + if (tt == TOKEN_INT) tt = TOKEN_WORD; + if ((k == NULL) || (tt != TOKEN_WORD)) + { + if (k != NULL) free(k); + asl_msg_release(out); + return NULL; + } + + v = _asl_msg_get_next_word(&p, &tt, 0); + if (tt == TOKEN_INT) tt = TOKEN_WORD; + if (v == NULL) + { + asl_msg_set_key_val_op(out, k, NULL, op); + free(k); + break; + } + + if (tt == TOKEN_CLOSE) + { + asl_msg_set_key_val_op(out, k, NULL, op); + } + else if (tt == TOKEN_WORD) + { + asl_msg_set_key_val_op(out, k, v, op); + } + else + { + if (k != NULL) free(k); + if (v != NULL) free(v); + asl_msg_release(out); + return NULL; + } + + if (k != NULL) free(k); + if (v != NULL) free(v); + + if (tt != TOKEN_CLOSE) + { + k = _asl_msg_get_next_word(&p, &tt, 1); + if (k == NULL) break; + + if (tt != TOKEN_CLOSE) + { + asl_msg_release(out); + return NULL; + } + + free(k); + } + + k = _asl_msg_get_next_word(&p, &tt, 1); + if (k == NULL) break; + } + + return out; +} + +char * +asl_list_to_string(asl_search_result_t *list, uint32_t *outlen) +{ + uint32_t i, len, newlen; + char *msgbuf, *out; + + if (list == NULL) return NULL; + if (list->count == 0) return NULL; + if (list->msg == NULL) return NULL; + + out = NULL; + asprintf(&out, "%u\n", list->count); + if (out == NULL) return NULL; + *outlen = strlen(out) + 1; + + for (i = 0; i < list->count; i++) + { + len = 0; + msgbuf = asl_msg_to_string(list->msg[i], &len); + if (msgbuf == NULL) + { + free(out); + *outlen = 0; + return NULL; + } + + newlen = *outlen + len; + out = reallocf(out, newlen); + if (out == NULL) + { + *outlen = 0; + return NULL; + } + + memmove((out + *outlen - 1), msgbuf, len); + out[newlen - 2] = '\n'; + out[newlen - 1] = '\0'; + *outlen = newlen; + + free(msgbuf); + } + + return out; +} + +asl_search_result_t * +asl_list_from_string(const char *buf) +{ + uint32_t i, n; + const char *p; + asl_search_result_t *out; + asl_msg_t *m; + + if (buf == NULL) return NULL; + p = buf; + + n = atoi(buf); + if (n == 0) return NULL; + + out = (asl_search_result_t *)calloc(1, sizeof(asl_search_result_t)); + if (out == NULL) return NULL; + + out->msg = (asl_msg_t **)calloc(n, sizeof(asl_msg_t *)); + if (out->msg == NULL) + { + free(out); + return NULL; + } + + for (i = 0; i < n; i++) + { + p = strchr(p, '\n'); + if (p == NULL) + { + aslresponse_free((aslresponse)out); + return NULL; + } + + p++; + + m = asl_msg_from_string(p); + if (m == NULL) + { + aslresponse_free((aslresponse)out); + return NULL; + } + + out->msg[i] = (asl_msg_t *)m; + out->count += 1; + } + + return out; +} + +static const char * +_asl_level_string(int level) +{ + if (level == ASL_LEVEL_EMERG) return ASL_STRING_EMERG; + if (level == ASL_LEVEL_ALERT) return ASL_STRING_ALERT; + if (level == ASL_LEVEL_CRIT) return ASL_STRING_CRIT; + if (level == ASL_LEVEL_ERR) return ASL_STRING_ERR; + if (level == ASL_LEVEL_WARNING) return ASL_STRING_WARNING; + if (level == ASL_LEVEL_NOTICE) return ASL_STRING_NOTICE; + if (level == ASL_LEVEL_INFO) return ASL_STRING_INFO; + if (level == ASL_LEVEL_DEBUG) return ASL_STRING_DEBUG; + return "Unknown"; +} + +/* + * format a message for printing + * out parameter len returns string length including trailing NUL + */ +char * +asl_format_message(asl_msg_t *msg, const char *mfmt, const char *tfmt, uint32_t text_encoding, uint32_t *len) +{ + char *buf, *tstr, *k, c[2], skey[512]; + const char *hstr, *sstr, *pstr, *mstr, *lstr, *rprc, *rpid, *v, *key, *val; + int i, j, l, mf, tf, paren, oval, level; + uint32_t x, cursor, bufsize; + + buf = NULL; + *len = 0; + + if (msg == NULL) return NULL; + + mf = MFMT_RAW; + tf = TFMT_SEC; + + if (mfmt == NULL) mf = MFMT_RAW; + else if (!strcmp(mfmt, ASL_MSG_FMT_RAW)) mf = MFMT_RAW; + else if (!strcmp(mfmt, ASL_MSG_FMT_STD)) mf = MFMT_STD; + else if (!strcmp(mfmt, ASL_MSG_FMT_BSD)) mf = MFMT_BSD; + else if (!strcmp(mfmt, ASL_MSG_FMT_XML)) mf = MFMT_XML; + else if (!strcmp(mfmt, ASL_MSG_FMT_MSG)) mf = MFMT_MSG; + else mf = MFMT_STR; + + if (tfmt == NULL) tf = TFMT_SEC; + else if (!strcmp(tfmt, ASL_TIME_FMT_SEC)) tf = TFMT_SEC; + else if (!strcmp(tfmt, ASL_TIME_FMT_UTC)) tf = TFMT_UTC; + else if (!strcmp(tfmt, ASL_TIME_FMT_LCL)) tf = TFMT_LCL; + + if (mf == MFMT_RAW) + { + return _asl_msg_to_string_time_fmt(msg, len, tf); + } + + if (mf == MFMT_MSG) + { + mstr = NULL; + if (asl_msg_lookup(msg, ASL_KEY_MSG, &mstr, NULL) != 0) return NULL; + + bufsize = _asl_append_string_length(mstr, text_encoding, 0); + bufsize += 2; /* \n\0 */ + + buf = malloc(bufsize); + if (buf == NULL) return NULL; + + cursor = 0; + _asl_append_string(buf, bufsize, &cursor, mstr, text_encoding, 0); + + buf[cursor++] = '\n'; + buf[cursor] = '\0'; + + *len = bufsize; + return buf; + } + + if ((mf == MFMT_STD) || (mf == MFMT_BSD)) + { + /* BSD: Mth dd hh:mm:ss host sender[pid]: message */ + /* BSD: Mth dd hh:mm:ss host sender[pid] (refproc[refpid]): message */ + /* STD: Mth dd hh:mm:ss host sender[pid] : message */ + /* STD: Mth dd hh:mm:ss host sender[pid] (refproc[refpid]) : message */ + + v = NULL; + hstr = NULL; + sstr = NULL; + pstr = NULL; + mstr = NULL; + lstr = NULL; + rprc = NULL; + rpid = NULL; + + asl_msg_lookup(msg, ASL_KEY_TIME, &v, NULL); + tstr = _asl_time_string(tf, v); + + asl_msg_lookup(msg, ASL_KEY_HOST, &hstr, NULL); + asl_msg_lookup(msg, ASL_KEY_SENDER, &sstr, NULL); + asl_msg_lookup(msg, ASL_KEY_PID, &pstr, NULL); + asl_msg_lookup(msg, ASL_KEY_MSG, &mstr, NULL); + + asl_msg_lookup(msg, ASL_KEY_REF_PROC, &rprc, NULL); + asl_msg_lookup(msg, ASL_KEY_REF_PID, &rpid, NULL); + + level = 7; + + if (mf == MFMT_STD) + { + asl_msg_lookup(msg, ASL_KEY_LEVEL, &lstr, NULL); + if (lstr != NULL) level = atoi(lstr); + + lstr = _asl_level_string(level); + } + + if (hstr == NULL) hstr = "unknown"; + if (sstr == NULL) sstr = "unknown"; + + /* first pass: calculate output line length */ + bufsize = 0; + + if (tstr == NULL) bufsize++; + else bufsize += _asl_append_string_length(tstr, ASL_ENCODE_NONE, 0); + + /* " " */ + bufsize++; + + bufsize += _asl_append_string_length(hstr, text_encoding, 0); + + /* " " */ + bufsize++; + + bufsize += _asl_append_string_length(sstr, text_encoding, 0); + + if ((pstr != NULL) && (strcmp(pstr, "-1"))) + { + /* "[" + "]" */ + bufsize += 2; + bufsize += _asl_append_string_length(pstr, ASL_ENCODE_NONE, 0); + } + + if ((rprc != NULL) || (rpid != NULL)) bufsize += 3; /* " (" + ")" */ + + if (rprc != NULL) bufsize += _asl_append_string_length(rprc, text_encoding, 0); + if (rpid != NULL) + { + /* "[" + "]" */ + bufsize += 2; + bufsize += _asl_append_string_length(rpid, ASL_ENCODE_NONE, 0); + } + + if (mf == MFMT_STD) + { + /* " <" + ">" */ + bufsize += 3; + bufsize += _asl_append_string_length(lstr, ASL_ENCODE_NONE, 0); + } + + /* ": " */ + bufsize += 2; + + if (mstr != NULL) bufsize += _asl_append_string_length(mstr, text_encoding, 0); + + /* "\n\0" */ + bufsize += 2; + + /* second pass: construct the output line */ + + buf = malloc(bufsize); + if (buf == NULL) return NULL; + + cursor = 0; + + if (tstr == NULL) + { + buf[cursor++] = '0'; + } + else + { + _asl_append_string(buf, bufsize, &cursor, tstr, ASL_ENCODE_NONE, 0); + free(tstr); + } + + buf[cursor++] = ' '; + + _asl_append_string(buf, bufsize, &cursor, hstr, text_encoding, 0); + + buf[cursor++] = ' '; + + _asl_append_string(buf, bufsize, &cursor, sstr, text_encoding, 0); + + if ((pstr != NULL) && (strcmp(pstr, "-1"))) + { + buf[cursor++] = '['; + _asl_append_string(buf, bufsize, &cursor, pstr, ASL_ENCODE_NONE, 0); + buf[cursor++] = ']'; + } + + if ((rprc != NULL) || (rpid != NULL)) + { + buf[cursor++] = ' '; + buf[cursor++] = '('; + } + + if (rprc != NULL) _asl_append_string(buf, bufsize, &cursor, rprc, text_encoding, 0); + if (rpid != NULL) + { + buf[cursor++] = '['; + _asl_append_string(buf, bufsize, &cursor, rpid, ASL_ENCODE_NONE, 0); + buf[cursor++] = ']'; + } + + if ((rprc != NULL) || (rpid != NULL)) buf[cursor++] = ')'; + + if (mf == MFMT_STD) + { + buf[cursor++] = ' '; + buf[cursor++] = '<'; + _asl_append_string(buf, bufsize, &cursor, _asl_level_string(level), ASL_ENCODE_NONE, 0); + buf[cursor++] = '>'; + } + + buf[cursor++] = ':'; + buf[cursor++] = ' '; + + if (mstr != NULL) _asl_append_string(buf, bufsize, &cursor, mstr, text_encoding, 0); + + buf[cursor++] = '\n'; + buf[cursor++] = '\0'; + + *len = bufsize; + return buf; + } + + if (mf == MFMT_XML) + { + /* first pass: calculate output line length */ + tstr = NULL; + bufsize = 0; + + bufsize += 8; /* "\t\n" */ + + for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL)) + { + if (asl_is_utf8(key) == 1) + { + bufsize += _asl_append_xml_tag_length(XML_TAG_KEY, key); + if (!strcmp(key, ASL_KEY_TIME)) + { + tstr = _asl_time_string(tf, val); + bufsize += _asl_append_xml_tag_length(XML_TAG_STRING, tstr); + } + else + { + if (asl_is_utf8(val) == 1) bufsize += _asl_append_xml_tag_length(XML_TAG_STRING, val); + else bufsize += _asl_append_xml_tag_length(XML_TAG_DATA, val); + } + } + } + + bufsize += 10; /* "\t\n\0" */ + + /* second pass: construct the output line */ + + buf = malloc(bufsize); + if (buf == NULL) return NULL; + + cursor = 0; + + _asl_append_string(buf, bufsize, &cursor, "\t\n", ASL_ENCODE_NONE, 0); + + for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL)) + { + if (asl_is_utf8(key) == 1) + { + _asl_append_xml_tag(buf, bufsize, &cursor, XML_TAG_KEY, key); + if (!strcmp(key, ASL_KEY_TIME)) + { + _asl_append_xml_tag(buf, bufsize, &cursor, XML_TAG_STRING, tstr); + } + else + { + if (asl_is_utf8(val) == 1) _asl_append_xml_tag(buf, bufsize, &cursor, XML_TAG_STRING, val); + else _asl_append_xml_tag(buf, bufsize, &cursor, XML_TAG_DATA, val); + } + } + } + + _asl_append_string(buf, bufsize, &cursor, "\t\n", ASL_ENCODE_NONE, 0); + + buf[cursor] = '\0'; + + if (tstr != NULL) free(tstr); + + *len = bufsize; + return buf; + } + + /* custom format */ + + c[1] = '\0'; + + /* + * We need enough space to copy any keys found in mfmt. + * The key obviously can't be longer than strlen(mfmt), + * in fact, keys must be shorter, since there's at least a '$' + * in front of the key, so we allocate a buffer with strlen(mfmt). + * If strlen(mfmt) <= sizeof(skey), we use skey to avoid a malloc. + */ + + x = strlen(mfmt); + if (x <= sizeof(skey)) + { + k = skey; + } + else + { + k = malloc(x); + if (k == NULL) return NULL; + } + + /* first pass: calculate output line length */ + + tstr = NULL; + bufsize = 0; + + for (i = 0; mfmt[i] != '\0'; i++) + { + if (mfmt[i] == '$') + { + i++; + paren = 0; + + if (mfmt[i] == '(') + { + paren = 1; + i++; + } + + l = 0; + + for (j = i; mfmt[j] != '\0'; j++) + { + c[0] = '\0'; + if (mfmt[j] == '\\') c[0] = mfmt[++j]; + else if ((paren == 1) && (mfmt[j] ==')')) break; + else if (mfmt[j] != ' ') c[0] = mfmt[j]; + + if (c[0] == '\0') break; + + k[l] = c[0]; + k[l + 1] = '\0'; + l++; + } + + if (paren == 1) j++; + i = j; + if (l > 0) + { + v = NULL; + + if (asl_msg_lookup(msg, k, &v, NULL) == 0) + { + if (!strcmp(k, ASL_KEY_TIME)) + { + tstr = _asl_time_string(tf, v); + bufsize += _asl_append_string_length(tstr, ASL_ENCODE_NONE, 0); + } + else + { + bufsize += _asl_append_string_length(v, ASL_ENCODE_NONE, 0); + } + } + } + } + + if (mfmt[i] == '\\') + { + i++; + if (mfmt[i] == '$') bufsize++; + else if (mfmt[i] == 'e') bufsize += 2; + else if (mfmt[i] == 's') bufsize++; + else if (mfmt[i] == 'a') bufsize += 2; + else if (mfmt[i] == 'b') bufsize += 2; + else if (mfmt[i] == 'f') bufsize += 2; + else if (mfmt[i] == 'n') bufsize += 2; + else if (mfmt[i] == 'r') bufsize += 2; + else if (mfmt[i] == 't') bufsize += 2; + else if (mfmt[i] == 'v') bufsize += 2; + else if (mfmt[i] == '\'') bufsize += 2; + else if (mfmt[i] == '\\') bufsize += 2; + else if (isdigit(mfmt[i])) + { + oval = mfmt[i] - '0'; + if (isdigit(mfmt[i+1])) + { + i++; + oval = (oval * 8) + (mfmt[i] - '0'); + if (isdigit(mfmt[i+1])) + { + i++; + oval = (oval * 8) + (mfmt[i] - '0'); + } + } + + c[0] = oval; + bufsize += _asl_append_string_length(c, ASL_ENCODE_NONE, 0); + } + continue; + } + + if (mfmt[i] == '\0') break; + c[0] = mfmt[i]; + bufsize += _asl_append_string_length(c, ASL_ENCODE_NONE, 0); + } + + bufsize += 2; /* "\n\0" */ + + /* second pass: construct the output line */ + + buf = malloc(bufsize); + if (buf == NULL) return NULL; + + cursor = 0; + + for (i = 0; mfmt[i] != '\0'; i++) + { + if (mfmt[i] == '$') + { + i++; + paren = 0; + + if (mfmt[i] == '(') + { + paren = 1; + i++; + } + + l = 0; + + for (j = i; mfmt[j] != '\0'; j++) + { + c[0] = '\0'; + if (mfmt[j] == '\\') c[0] = mfmt[++j]; + else if ((paren == 1) && (mfmt[j] ==')')) break; + else if (mfmt[j] != ' ') c[0] = mfmt[j]; + + if (c[0] == '\0') break; + + k[l] = c[0]; + k[l + 1] = '\0'; + l++; + } + + if (paren == 1) j++; + i = j; + if (l > 0) + { + v = NULL; + + if (asl_msg_lookup(msg, k, &v, NULL) == 0) + { + if (!strcmp(k, ASL_KEY_TIME)) + { + _asl_append_string(buf, bufsize, &cursor, tstr, ASL_ENCODE_NONE, 0); + } + else + { + _asl_append_string(buf, bufsize, &cursor, v, ASL_ENCODE_NONE, 0); + } + } + } + } + + if (mfmt[i] == '\\') + { + i++; + if (mfmt[i] == '$') _asl_append_string(buf, bufsize, &cursor, "$", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == 'e') _asl_append_string(buf, bufsize, &cursor, "\e", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == 's') _asl_append_string(buf, bufsize, &cursor, " ", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == 'a') _asl_append_string(buf, bufsize, &cursor, "\a", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == 'b') _asl_append_string(buf, bufsize, &cursor, "\b", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == 'f') _asl_append_string(buf, bufsize, &cursor, "\f", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == 'n') _asl_append_string(buf, bufsize, &cursor, "\n", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == 'r') _asl_append_string(buf, bufsize, &cursor, "\r", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == 't') _asl_append_string(buf, bufsize, &cursor, "\t", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == 'v') _asl_append_string(buf, bufsize, &cursor, "\v", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == '\'') _asl_append_string(buf, bufsize, &cursor, "\'", ASL_ENCODE_NONE, 0); + else if (mfmt[i] == '\\') _asl_append_string(buf, bufsize, &cursor, "\\", ASL_ENCODE_NONE, 0); + else if (isdigit(mfmt[i])) + { + oval = mfmt[i] - '0'; + if (isdigit(mfmt[i+1])) + { + i++; + oval = (oval * 8) + (mfmt[i] - '0'); + if (isdigit(mfmt[i+1])) + { + i++; + oval = (oval * 8) + (mfmt[i] - '0'); + } + } + c[0] = oval; + _asl_append_string(buf, bufsize, &cursor, c, ASL_ENCODE_NONE, 0); + } + continue; + } + + if (mfmt[i] == '\0') break; + c[0] = mfmt[i]; + _asl_append_string(buf, bufsize, &cursor, c, ASL_ENCODE_NONE, 0); + } + + buf[cursor++] = '\n'; + buf[cursor] = '\0'; + + if (tstr != NULL) free(tstr); + if (k != skey) free(k); + + *len = bufsize; + return buf; +} + +/* + * OLD ASLMSG COMPATIBILITY + */ +const char * +asl_key(aslmsg msg, uint32_t n) +{ + uint32_t slot, i; + asl_msg_t *page; + + i = 0; + for (page = (asl_msg_t *)msg; page != NULL; page = page->next) + { + for (slot = 0; slot < ASL_MSG_PAGE_SLOTS; slot++) + { + if (page->key[slot] != ASL_MSG_SLOT_FREE) + { + if (i == n) return _asl_msg_slot_key(page, slot); + i++; + } + } + } + + return NULL; +} + +aslmsg +asl_new(uint32_t type) +{ + return (aslmsg)asl_msg_new(type); +} + +int +asl_set(aslmsg msg, const char *key, const char *value) +{ + return asl_msg_set_key_val_op((asl_msg_t *)msg, key, value, IndexNull); +} + +int +asl_set_query(aslmsg msg, const char *key, const char *value, uint32_t op) +{ + return asl_msg_set_key_val_op((asl_msg_t *)msg, key, value, op); +} + +int +asl_unset(aslmsg msg, const char *key) +{ + asl_msg_unset((asl_msg_t *)msg, key); + return 0; +} + +const char * +asl_get(aslmsg msg, const char *key) +{ + const char *val; + int status; + + val = NULL; + status = asl_msg_lookup((asl_msg_t *)msg, key, &val, NULL); + if (status != 0) return NULL; + return val; +} + +void +asl_free(aslmsg msg) +{ + asl_msg_release((asl_msg_t *)msg); +} + +/* aslresponse */ + +/* + * aslresponse_next: Iterate over responses returned from asl_search() + * a: a response returned from asl_search(); + * returns: The next log message (an aslmsg) or NULL on failure + */ +aslmsg +aslresponse_next(aslresponse r) +{ + asl_search_result_t *res; + asl_msg_t *m; + + res = (asl_search_result_t *)r; + if (res == NULL) return NULL; + + if (res->curr >= res->count) return NULL; + m = res->msg[res->curr]; + res->curr++; + + return (aslmsg)m; +} + +/* + * aslresponse_free: Free a response returned from asl_search() + * a: a response returned from asl_search() + */ +void +aslresponse_free(aslresponse r) +{ + asl_search_result_t *res; + uint32_t i; + + res = (asl_search_result_t *)r; + if (res == NULL) return; + + for (i = 0; i < res->count; i++) asl_msg_release(res->msg[i]); + free(res->msg); + free(res); +} diff --git a/gen/asl_msg.h b/gen/asl_msg.h new file mode 100644 index 0000000..c1876b2 --- /dev/null +++ b/gen/asl_msg.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2009-2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __ASL_MSG_H__ +#define __ASL_MSG_H__ + +#include + +#define IndexNull ((uint32_t)-1) + +#define ASL_MSG_PAGE_DATA_SIZE 800 +#define ASL_MSG_PAGE_SLOTS 24 + +#define ASL_MSG_OFFSET_MASK 0x3fff +#define ASL_MSG_KV_MASK 0xc000 +#define ASL_MSG_KV_INLINE 0x0000 +#define ASL_MSG_KV_DICT 0x8000 +#define ASL_MSG_KV_EXTERN 0x4000 + +#define ASL_MSG_SLOT_FREE 0xffff + +#define ASL_STD_KEY_BASE 0x8000 +#define ASL_STD_KEY_TIME 0x8001 +#define ASL_STD_KEY_NANO 0x8002 +#define ASL_STD_KEY_HOST 0x8003 +#define ASL_STD_KEY_SENDER 0x8004 +#define ASL_STD_KEY_FACILITY 0x8005 +#define ASL_STD_KEY_PID 0x8006 +#define ASL_STD_KEY_UID 0x8007 +#define ASL_STD_KEY_GID 0x8008 +#define ASL_STD_KEY_LEVEL 0x8009 +#define ASL_STD_KEY_MESSAGE 0x800a +#define ASL_STD_KEY_READ_UID 0x800b +#define ASL_STD_KEY_READ_GID 0x800c +#define ASL_STD_KEY_SESSION 0x800d +#define ASL_STD_KEY_REF_PID 0x800e +#define ASL_STD_KEY_REF_PROC 0x800f +#define ASL_STD_KEY_MSG_ID 0x8010 +#define ASL_STD_KEY_EXPIRE 0x8011 +#define ASL_STD_KEY_OPTION 0x8012 +#define ASL_STD_KEY_LAST ASL_STD_KEY_OPTION + +#define ASL_MT_KEY_BASE 0x8100 +#define ASL_MT_KEY_DOMAIN 0x8101 +#define ASL_MT_KEY_SCOPE 0x8102 +#define ASL_MT_KEY_RESULT 0x8103 +#define ASL_MT_KEY_SIG 0x8104 +#define ASL_MT_KEY_SIG2 0x8105 +#define ASL_MT_KEY_SIG3 0x8106 +#define ASL_MT_KEY_SUCCESS 0x8107 +#define ASL_MT_KEY_UUID 0x8108 +#define ASL_MT_KEY_VAL 0x8109 +#define ASL_MT_KEY_VAL2 0x810a +#define ASL_MT_KEY_VAL3 0x810b +#define ASL_MT_KEY_VAL4 0x810c +#define ASL_MT_KEY_VAL5 0x810d +#define ASL_MT_KEY_LAST ASL_MT_KEY_VAL5 + +#define ASL_PRIVATE_KEY_BASE 0x8200 + +#define ASL_MSG_TYPE_AUX_0 0 + +typedef struct +{ + const char *level; + const char *time; + const char *nano; + const char *host; + const char *sender; + const char *facility; + const char *pid; + const char *uid; + const char *gid; + const char *message; + const char *option; + const char *auxtitle; + const char *auxuti; + const char *auxurl; +} asl_msg_aux_0_t; + +typedef struct +{ + uint32_t type; + union + { + asl_msg_aux_0_t *aux0; + } data; +} asl_msg_aux_t; + +typedef struct asl_msg_s +{ + uint32_t type; + int32_t refcount; + uint32_t count; + uint32_t data_size; + void *aux; + struct asl_msg_s *next; + uint16_t key[ASL_MSG_PAGE_SLOTS]; + uint16_t val[ASL_MSG_PAGE_SLOTS]; + uint32_t op[ASL_MSG_PAGE_SLOTS]; + char data[ASL_MSG_PAGE_DATA_SIZE]; +} asl_msg_t; + +asl_msg_t *asl_msg_new(uint32_t type) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +asl_msg_t *asl_msg_retain(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +void asl_msg_release(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); + +int asl_msg_set_key_val(asl_msg_t *msg, const char *key, const char *val) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +int asl_msg_set_key_val_op(asl_msg_t *msg, const char *key, const char *val, uint32_t op) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +void asl_msg_unset(asl_msg_t *msg, const char *key) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); + +int asl_msg_lookup(asl_msg_t *msg, const char *key, const char **valout, uint32_t *opout) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +uint32_t asl_msg_fetch(asl_msg_t *msg, uint32_t n, const char **keyout, const char **valout, uint32_t *opout) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); + +uint32_t asl_msg_type(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +uint32_t asl_msg_count(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); + +#endif /* __ASL_MSG_H__ */ diff --git a/gen/asl_private.h b/gen/asl_private.h index a9c699b..a10cc64 100644 --- a/gen/asl_private.h +++ b/gen/asl_private.h @@ -1,33 +1,37 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 2007 Apple Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ + +#ifndef __ASL_PRIVATE_H__ +#define __ASL_PRIVATE_H__ + #include #include #include #include #include - -#define _PATH_ASL_OUT "/var/log/asl.log" +#include "asl_file.h" +#include "asl_msg.h" +#include #define ASL_QUERY_OP_NULL 0x00000 @@ -52,16 +56,17 @@ #define ASL_ENCODE_VIS 2 #define ASL_ENCODE_ASL 3 -#define ASL_KEY_REF_PID "RefPID" -#define ASL_KEY_REF_PROC "RefProc" -#define ASL_KEY_OPTION "ASLOption" - #define ASL_OPT_IGNORE "ignore" #define ASL_OPT_STORE "store" #define ASL_STORE_LOCATION_FILE 0 #define ASL_STORE_LOCATION_MEMORY 1 +#define ASL_OPT_SYSLOG_LEGACY 0x00010000 + +/* SPI to enable ASL filter tunneling using asl_set_filter() */ +#define ASL_FILTER_MASK_TUNNEL 0x100 + typedef struct __aslclient { uint32_t options; @@ -80,19 +85,12 @@ typedef struct __aslclient char **fd_mfmt; char **fd_tfmt; uint32_t *fd_encoding; + asl_file_t *aslfile; + uint64_t aslfileid; uint32_t reserved1; void *reserved2; } asl_client_t; -typedef struct __aslmsg -{ - uint32_t type; - uint32_t count; - char **key; - char **val; - uint32_t *op; -} asl_msg_t; - typedef struct __aslresponse { uint32_t count; @@ -100,13 +98,20 @@ typedef struct __aslresponse asl_msg_t **msg; } asl_search_result_t; - __BEGIN_DECLS -int asl_add_output(aslclient asl, int fd, const char *msg_fmt, const char *time_fmt, uint32_t text_encoding); -int asl_remove_output(aslclient asl, int fd); -char *asl_format_message(aslmsg msg, const char *msg_fmt, const char *time_fmt, uint32_t text_encoding, uint32_t *outlen); -int asl_store_location(); +int asl_add_output(aslclient asl, int fd, const char *msg_fmt, const char *time_fmt, uint32_t text_encoding) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int asl_remove_output(aslclient asl, int fd) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +char *asl_format_message(asl_msg_t *msg, const char *msg_fmt, const char *time_fmt, uint32_t text_encoding, uint32_t *outlen) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_msg_string_length(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +uint32_t asl_msg_to_string_buffer(asl_msg_t *msg, char *buf, uint32_t bufsize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +char *asl_msg_to_string(asl_msg_t *in, uint32_t *len) __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0); +asl_search_result_t *asl_list_from_string(const char *buf) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +char *asl_list_to_string(asl_search_result_t *, uint32_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int asl_store_location() __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +int asl_get_filter(aslclient asl, int *local, int *master, int *remote, int *active) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +char *asl_remote_notify_name() __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); __END_DECLS +#endif /* __ASL_PRIVATE_H__ */ diff --git a/gen/asl_store.c b/gen/asl_store.c index 97d1df9..d8a0499 100644 --- a/gen/asl_store.c +++ b/gen/asl_store.c @@ -1,23 +1,22 @@ /* - * Copyright (c) 2007-2009 Apple Inc. All rights reserved. + * Copyright (c) 2007-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 2007 Apple Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -40,6 +39,7 @@ extern time_t asl_parse_time(const char *str); extern uint64_t asl_file_cursor(asl_file_t *s); extern uint32_t asl_file_match_start(asl_file_t *s, uint64_t start_id, int32_t direction); extern uint32_t asl_file_match_next(asl_file_t *s, aslresponse query, asl_msg_t **msg, uint64_t *last_id, int32_t direction, int32_t ruid, int32_t rgid); +extern int asl_file_create(const char *path, uid_t uid, gid_t gid, mode_t mode); #define SECONDS_PER_DAY 86400 @@ -106,7 +106,7 @@ asl_store_open_write(const char *basedir, asl_store_t **s) memset(&sb, 0, sizeof(struct stat)); if (stat(basedir, &sb) != 0) return ASL_STATUS_INVALID_STORE; - if ((sb.st_mode & S_IFDIR) == 0) return ASL_STATUS_INVALID_STORE; + if (!S_ISDIR(sb.st_mode)) return ASL_STATUS_INVALID_STORE; path = NULL; asprintf(&path, "%s/%s", basedir, FILE_ASL_STORE_DATA); @@ -144,6 +144,9 @@ asl_store_open_write(const char *basedir, asl_store_t **s) fclose(sd); return ASL_STATUS_WRITE_FAILED; } + + /* flush data */ + fflush(sd); } else { @@ -201,7 +204,7 @@ asl_store_statistics(asl_store_t *s, aslmsg *msg) if (s == NULL) return ASL_STATUS_INVALID_STORE; if (msg == NULL) return ASL_STATUS_INVALID_ARG; - out = (aslmsg)calloc(1, sizeof(asl_msg_t)); + out = asl_new(ASL_TYPE_MSG); if (out == NULL) return ASL_STATUS_NO_MEMORY; /* does nothing for now */ @@ -222,7 +225,7 @@ asl_store_open_read(const char *basedir, asl_store_t **s) memset(&sb, 0, sizeof(struct stat)); if (stat(basedir, &sb) != 0) return ASL_STATUS_INVALID_STORE; - if ((sb.st_mode & S_IFDIR) == 0) return ASL_STATUS_INVALID_STORE; + if (!S_ISDIR(sb.st_mode)) return ASL_STATUS_INVALID_STORE; out = (asl_store_t *)calloc(1, sizeof(asl_store_t)); if (out == NULL) return ASL_STATUS_NO_MEMORY; @@ -249,7 +252,7 @@ asl_store_max_file_size(asl_store_t *s, size_t max) return ASL_STATUS_OK; } -void +__private_extern__ void asl_store_file_closeall(asl_store_t *s) { uint32_t i; @@ -357,12 +360,59 @@ asl_store_sweep_file_cache(asl_store_t *s) return ASL_STATUS_OK; } +static char * +asl_store_make_ug_path(const char *dir, const char *base, const char *ext, uid_t ruid, gid_t rgid, uid_t *u, gid_t *g, mode_t *m) +{ + char *path = NULL; + + *u = 0; + *g = 0; + *m = 0644; + + if (ruid == -1) + { + if (rgid == -1) + { + if (ext == NULL) asprintf(&path, "%s/%s", dir, base); + else asprintf(&path, "%s/%s.%s", dir, base, ext); + } + else + { + *g = rgid; + *m = 0600; + if (ext == NULL) asprintf(&path, "%s/%s.G%d", dir, base, *g); + else asprintf(&path, "%s/%s.G%d.%s", dir, base, *g, ext); + } + } + else + { + *u = ruid; + if (rgid == -1) + { + *m = 0600; + if (ext == NULL) asprintf(&path, "%s/%s.U%d", dir, base, *u); + else asprintf(&path, "%s/%s.U%d.%s", dir, base, *u, ext); + } + else + { + *g = rgid; + *m = 0600; + if (ext == NULL) asprintf(&path, "%s/%s.U%d.G%d", dir, base, *u, *g); + else asprintf(&path, "%s/%s.U%d.G%u.%s", dir, base, *u, *g, ext); + } + } + + return path; +} + static uint32_t asl_store_file_open_write(asl_store_t *s, char *tstring, int32_t ruid, int32_t rgid, time_t bb, asl_file_t **f, time_t now, uint32_t check_cache) { char *path; mode_t m; - int32_t i, x, u, g; + int32_t i, x; + uid_t u; + gid_t g; uint32_t status; asl_file_t *out; @@ -380,40 +430,10 @@ asl_store_file_open_write(asl_store_t *s, char *tstring, int32_t ruid, int32_t r } } - path = NULL; u = 0; g = 0; m = 0644; - - if (ruid == -1) - { - if (rgid == -1) - { - asprintf(&path, "%s/%s.asl", s->base_dir, tstring); - } - else - { - g = rgid; - m = 0640; - asprintf(&path, "%s/%s.G%d.asl", s->base_dir, tstring, g); - } - } - else - { - u = ruid; - if (rgid == -1) - { - m = 0600; - asprintf(&path, "%s/%s.U%d.asl", s->base_dir, tstring, u); - } - else - { - g = rgid; - m = 0640; - asprintf(&path, "%s/%s.U%d.G%u.asl", s->base_dir, tstring, u, g); - } - } - + path = asl_store_make_ug_path(s->base_dir, tstring, "asl", (uid_t)ruid, (gid_t)rgid, &u, &g, &m); if (path == NULL) return ASL_STATUS_NO_MEMORY; out = NULL; @@ -440,7 +460,7 @@ asl_store_file_open_write(asl_store_t *s, char *tstring, int32_t ruid, int32_t r return ASL_STATUS_OK; } -char * +__private_extern__ char * asl_store_file_path(asl_store_t *s, asl_file_t *f) { uint32_t i; @@ -459,7 +479,7 @@ asl_store_file_path(asl_store_t *s, asl_file_t *f) return NULL; } -void +__private_extern__ void asl_store_file_close(asl_store_t *s, asl_file_t *f) { uint32_t i; @@ -556,6 +576,9 @@ asl_store_save(asl_store_t *s, aslmsg msg) xid = asl_core_htonq(s->next_id); if (fwrite(&xid, sizeof(uint64_t), 1, s->storedata) != 1) return ASL_STATUS_WRITE_FAILED; + /* flush data */ + fflush(s->storedata); + xid = s->next_id; s->next_id++; @@ -567,7 +590,7 @@ asl_store_save(asl_store_t *s, aslmsg msg) if (bb == 1) { /* - * This supports 12 monthy "Best Before" buckets. + * This supports 12 monthly "Best Before" buckets. * We advance the actual expiry time to day zero of the following month. * mktime() is clever enough to know that you actually mean the last day * of the previous month. What we get back from localtime is the last @@ -655,6 +678,158 @@ asl_store_save(asl_store_t *s, aslmsg msg) return status; } +static uint32_t +asl_store_mkdir(asl_store_t *s, const char *dir, mode_t m) +{ + char *tstring = NULL; + int status; + struct stat sb; + + asprintf(&tstring, "%s/%s", s->base_dir, dir); + if (tstring == NULL) return ASL_STATUS_NO_MEMORY; + + memset(&sb, 0, sizeof(struct stat)); + status = stat(tstring, &sb); + + if (status == 0) + { + /* must be a directory */ + if (!S_ISDIR(sb.st_mode)) + { + free(tstring); + return ASL_STATUS_INVALID_STORE; + } + } + else + { + if (errno == ENOENT) + { + /* doesn't exist - create it */ + if (mkdir(tstring, m) != 0) + { + free(tstring); + return ASL_STATUS_WRITE_FAILED; + } + } + else + { + /* stat failed for some other reason */ + free(tstring); + return ASL_STATUS_FAILED; + } + } + + free(tstring); + return ASL_STATUS_OK; +} + +uint32_t +asl_store_open_aux(asl_store_t *s, aslmsg msg, int *out_fd, char **url) +{ + struct tm ctm; + time_t msg_time, bb; + char *path, *dir, *tstring; + const char *val; + uid_t ruid, u; + gid_t rgid, g; + mode_t m; + uint32_t status; + uint64_t fid; + int fd; + + if (s == NULL) return ASL_STATUS_INVALID_STORE; + if (msg == NULL) return ASL_STATUS_INVALID_ARG; + if (out_fd == NULL) return ASL_STATUS_INVALID_ARG; + if (url == NULL) return ASL_STATUS_INVALID_ARG; + + msg_time = time(NULL); + + val = asl_get(msg, ASL_KEY_READ_UID); + ruid = -1; + if (val != NULL) ruid = atoi(val); + + val = asl_get(msg, ASL_KEY_READ_GID); + rgid = -1; + if (val != NULL) rgid = atoi(val); + + bb = 0; + val = asl_get(msg, ASL_KEY_EXPIRE_TIME); + if (val != NULL) + { + bb = 1; + msg_time = asl_parse_time(val); + } + + if (localtime_r((const time_t *)&msg_time, &ctm) == NULL) return ASL_STATUS_FAILED; + + dir = NULL; + if (bb == 1) + { + /* + * This supports 12 monthly "Best Before" buckets. + * We advance the actual expiry time to day zero of the following month. + * mktime() is clever enough to know that you actually mean the last day + * of the previous month. What we get back from localtime is the last + * day of the month in which the message expires, which we use in the name. + */ + ctm.tm_sec = 0; + ctm.tm_min = 0; + ctm.tm_hour = 0; + ctm.tm_mday = 0; + ctm.tm_mon += 1; + + bb = mktime(&ctm); + + if (localtime_r((const time_t *)&bb, &ctm) == NULL) return ASL_STATUS_FAILED; + asprintf(&dir, "BB.AUX.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday); + } + else + { + asprintf(&dir, "AUX.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday); + } + + if (dir == NULL) return ASL_STATUS_NO_MEMORY; + + status = asl_store_mkdir(s, dir, 0755); + if (status != ASL_STATUS_OK) + { + free(dir); + return status; + } + + fid = s->next_id; + s->next_id++; + tstring = NULL; + + asprintf(&tstring, "%s/%llu", dir, fid); + free(dir); + if (tstring == NULL) return ASL_STATUS_NO_MEMORY; + + u = 0; + g = 0; + m = 0644; + path = asl_store_make_ug_path(s->base_dir, tstring, NULL, ruid, rgid, &u, &g, &m); + free(tstring); + if (path == NULL) return ASL_STATUS_NO_MEMORY; + + fd = asl_file_create(path, u, g, m); + if (fd < 0) + { + free(path); + *out_fd = -1; + return ASL_STATUS_WRITE_FAILED; + } + + /* URL is file:// */ + *url = NULL; + asprintf(url, "file://%s", path); + free(path); + + *out_fd = fd; + + return status; +} + uint32_t asl_store_match_timeout(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec) { diff --git a/gen/asl_store.h b/gen/asl_store.h index 9bca0df..b24a586 100644 --- a/gen/asl_store.h +++ b/gen/asl_store.h @@ -1,35 +1,35 @@ -#ifndef __ASL_STORE_H__ -#define __ASL_STORE_H__ - /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 2007 Apple Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ +#ifndef __ASL_STORE_H__ +#define __ASL_STORE_H__ + #include #include #include #include -#include +#include "asl_file.h" +#include #define PATH_ASL_STORE "/var/log/asl" #define PATH_ASL_ARCHIVE "/var/log/asl.archive" @@ -62,21 +62,23 @@ typedef struct size_t max_file_size; } asl_store_t; -uint32_t asl_store_open_write(const char *basedir, asl_store_t **s); -uint32_t asl_store_open_read(const char *basedir, asl_store_t **s); -uint32_t asl_store_close(asl_store_t *s); -uint32_t asl_store_statistics(asl_store_t *s, aslmsg *msg); +uint32_t asl_store_open_write(const char *basedir, asl_store_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_store_open_read(const char *basedir, asl_store_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_store_close(asl_store_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_store_statistics(asl_store_t *s, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +uint32_t asl_store_save(asl_store_t *s, aslmsg msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_store_save(asl_store_t *s, aslmsg msg); +uint32_t asl_store_match(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_store_match_timeout(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); -uint32_t asl_store_match(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction); -uint32_t asl_store_match_timeout(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec); +uint32_t asl_store_match_start(asl_store_t *s, uint64_t start_id, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_store_match_next(asl_store_t *s, aslresponse query, aslresponse *res, uint32_t count) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_store_match_start(asl_store_t *s, uint64_t start_id, int32_t direction); -uint32_t asl_store_match_next(asl_store_t *s, aslresponse query, aslresponse *res, uint32_t count); +uint32_t asl_store_max_file_size(asl_store_t *s, size_t max) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_store_signal_sweep(asl_store_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +uint32_t asl_store_sweep_file_cache(asl_store_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); -uint32_t asl_store_max_file_size(asl_store_t *s, size_t max); -uint32_t asl_store_signal_sweep(asl_store_t *s); -uint32_t asl_store_sweep_file_cache(asl_store_t *s); +uint32_t asl_store_open_aux(asl_store_t *s, aslmsg msg, int *fd, char **url) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); #endif __ASL_STORE_H__ diff --git a/gen/assert-fbsd.c b/gen/assert-fbsd.c index 2490831..2e1c0b1 100644 --- a/gen/assert-fbsd.c +++ b/gen/assert-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,15 +31,13 @@ static char sccsid[] = "@(#)assert.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/assert.c,v 1.7 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/assert.c,v 1.8 2007/01/09 00:27:53 imp Exp $"); #include -#include #include - -extern const char *__crashreporter_info__; -static const char badasprintf[] = - "Assertion failed and asprintf also failed to create full error string"; +#include +#include "CrashReporterClient.h" +#include "_simple.h" void __assert_rtn(func, file, line, failedexpr) @@ -51,27 +45,47 @@ __assert_rtn(func, file, line, failedexpr) int line; const char *failedexpr; { - char *str = NULL; - - if (func == NULL) { - (void)fprintf(stderr, + if (func == (const char *)-1L) { + /* 8462256: special case to replace __eprintf */ + _simple_dprintf(STDERR_FILENO, + "%s:%u: failed assertion `%s'\n", file, line, failedexpr); + if (!CRGetCrashLogMessage()) { + _SIMPLE_STRING s = _simple_salloc(); + if (s) { + _simple_sprintf(s, + "%s:%u: failed assertion `%s'\n", + file, line, failedexpr); + CRSetCrashLogMessage(_simple_string(s)); + } else + CRSetCrashLogMessage(failedexpr); + } + } else if (func == NULL) { + _simple_dprintf(STDERR_FILENO, "Assertion failed: (%s), file %s, line %d.\n", failedexpr, file, line); - if (!__crashreporter_info__) { - asprintf(&str, - "Assertion failed: (%s), file %s, line %d.\n", - failedexpr, file, line); - __crashreporter_info__ = str ? str : badasprintf; + if (!CRGetCrashLogMessage()) { + _SIMPLE_STRING s = _simple_salloc(); + if (s) { + _simple_sprintf(s, + "Assertion failed: (%s), file %s, line %d.\n", + failedexpr, file, line); + CRSetCrashLogMessage(_simple_string(s)); + } else + CRSetCrashLogMessage(failedexpr); } } else { - (void)fprintf(stderr, + _simple_dprintf(STDERR_FILENO, "Assertion failed: (%s), function %s, file %s, line %d.\n", failedexpr, func, file, line); - if (!__crashreporter_info__) { - asprintf(&str, - "Assertion failed: (%s), function %s, file %s, line %d.\n", - failedexpr, func, file, line); - __crashreporter_info__ = str ? str : badasprintf; + if (!CRGetCrashLogMessage()) { + _SIMPLE_STRING s = _simple_salloc(); + if (s) { + _simple_sprintf(s, + "Assertion failed: (%s), function %s, file %s, line %d.\n", + failedexpr, func, file, line); + CRSetCrashLogMessage(_simple_string(s)); + } else + CRSetCrashLogMessage(failedexpr); } } abort(); diff --git a/gen/assumes.c b/gen/assumes.c new file mode 100644 index 0000000..076e59c --- /dev/null +++ b/gen/assumes.c @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "assumes.h" + +/* TODO: Re-enable after deciding how best to interact with this symbol. */ +/* + * NOTE: 8006611: converted to using libCrashReporterClient.a, so shouldn't + * use __crashreporter_info__. + */ +#if 0 +static char __crashreporter_info_buff__[2048]; +const char *__crashreporter_info__ = &__crashreporter_info_buff__[0]; +asm (".desc __crashreporter_info__, 0x10"); +#endif + +#define osx_atomic_cmpxchg(p, o, n) __sync_bool_compare_and_swap((p), (o), (n)) + +static const char * +_osx_basename(const char *p) +{ + return ((strrchr(p, '/') ? : p - 1) + 1); +} + +static char * +_osx_get_build(void) +{ + static char s_build[16]; + static long s_once = 0; + if (osx_atomic_cmpxchg(&s_once, 0, 1)) { + int mib[] = { CTL_KERN, KERN_OSVERSION }; + size_t sz = sizeof(s_build); + + (void)sysctl(mib, 2, s_build, &sz, NULL, 0); + } + + return s_build; +} + +static void +_osx_get_image_uuid(void *hdr, uuid_t uuid) +{ +#if __LP64__ + struct mach_header_64 *_hdr = (struct mach_header_64 *)hdr; +#else + struct mach_header *_hdr = (struct mach_header *)hdr; +#endif /* __LP64__ */ + + size_t i = 0; + size_t next = sizeof(*_hdr); + struct load_command *cur = NULL; + for (i = 0; i < _hdr->ncmds; i++) { + cur = (struct load_command *)((uintptr_t)_hdr + next); + if (cur->cmd == LC_UUID) { + struct uuid_command *cmd = (struct uuid_command *)cur; + uuid_copy(uuid, cmd->uuid); + break; + } + next += cur->cmdsize; + } + + if (i == _hdr->ncmds) { + uuid_clear(uuid); + } +} + +void +_osx_assumes_log(uint64_t code) +{ + Dl_info info; + + const char *image_name = NULL; + uintptr_t offset = 0; + uuid_string_t uuid_str; + + void *arr[2]; + /* Get our caller's address so we can look it up with dladdr(3) and + * get info about the image. + */ + if (backtrace(arr, 2) == 2) { + /* dladdr(3) returns non-zero on success... for some reason. */ + if (dladdr(arr[1], &info)) { + uuid_t uuid; + _osx_get_image_uuid(info.dli_fbase, uuid); + + uuid_unparse(uuid, uuid_str); + image_name = _osx_basename(info.dli_fname); + + offset = arr[1] - info.dli_fbase; + } + } else { + uuid_t null_uuid; + uuid_string_t uuid_str; + + uuid_clear(null_uuid); + uuid_unparse(null_uuid, uuid_str); + + image_name = "unknown"; + } + + char name[256]; + (void)snprintf(name, sizeof(name), "com.apple.assumes.%s", image_name); + + char sig[64]; + (void)snprintf(sig, sizeof(sig), "%s:%lu", uuid_str, offset); + + char result[24]; + (void)snprintf(result, sizeof(result), "0x%llx", code); + + char *prefix = "Bug"; + char message[1024]; + (void)snprintf(message, sizeof(message), "%s: %s: %s + %lu [%s]: %s", prefix, _osx_get_build(), image_name, offset, uuid_str, result); + + aslmsg msg = asl_new(ASL_TYPE_MSG); + if (msg != NULL) { + /* MessageTracer messages aren't logged to the regular syslog store, so + * we pre-log the message without any MessageTracer attributes so that + * we can see it in our regular syslog. + */ + (void)asl_log(NULL, msg, ASL_LEVEL_ERR, "%s", message); + + (void)asl_set(msg, "com.apple.message.domain", name); + (void)asl_set(msg, "com.apple.message.signature", sig); + (void)asl_set(msg, "com.apple.message.value", result); + + (void)asl_log(NULL, msg, ASL_LEVEL_ERR, "%s", message); + asl_free(msg); + } +} + +/* For osx_assert(). We need to think more about how best to set the __crashreporter_info__ string. + * For example, calling into two functions will basically smash the register state at the time of + * the assertion failure, causing potentially valuable information to be lost. Also, just setting + * the __crashreporter_info__ to a static string only involves one instruction, whereas a function + * call involves... well, more. + */ +#if 0 +void +osx_hardware_trap(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + osx_hardware_trapv(fmt, ap); + + va_end(ap); +} + +void +osx_hardware_trapv(const char *fmt, va_list ap) +{ + (void)vsnprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__), fmt, ap); + fflush(NULL); + __builtin_trap(); +} +#endif diff --git a/gen/assumes.h b/gen/assumes.h new file mode 100644 index 0000000..4f266c4 --- /dev/null +++ b/gen/assumes.h @@ -0,0 +1,60 @@ +#ifndef __OSX_ASSUMES_H__ +#define __OSX_ASSUMES_H__ + +#include + +__BEGIN_DECLS + +#include +#include +#include +#include +#include +#include + +#if __GNUC__ +#define osx_fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l)) +#define osx_slowpath(x) ((typeof(x))__builtin_expect((long)(x), 0l)) +#define osx_constant(x) __builtin_constant_p((x)) + +#define __OSX_COMPILETIME_ASSERT__(e) ({ \ + char __compile_time_assert__[(e) ? 1 : -1]; \ + (void)__compile_time_assert__; \ +}) +#else +#define osx_fastpath(x) (x) +#define osx_slowpath(x) (x) +#define osx_constant(x) ((long)0) + +#define __OSX_COMPILETIME_ASSERT__(e) (e) +#endif /* __GNUC__ */ + +#define osx_assumes(e) ({ \ + typeof(e) _e = osx_fastpath(e); /* Force evaluation of 'e' */ \ + if (!_e) { \ + if (osx_constant(e)) { \ + __OSX_COMPILETIME_ASSERT__(e); \ + } \ + _osx_assumes_log((uintptr_t)_e); \ + } \ + _e; \ +}) + +#define osx_assumes_zero(e) ({ \ + typeof(e) _e = osx_slowpath(e); /* Force evaluation of 'e' */ \ + if (_e) { \ + if (osx_constant(e)) { \ + __OSX_COMPILETIME_ASSERT__(!e); \ + } \ + _osx_assumes_log((uintptr_t)_e); \ + } \ + _e; \ +}) + +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3) +extern void +_osx_assumes_log(uint64_t code); + +__END_DECLS + +#endif /* __OSX_ASSUMES_H__ */ diff --git a/gen/backtrace.c b/gen/backtrace.c index 2aaee08..c075de2 100644 --- a/gen/backtrace.c +++ b/gen/backtrace.c @@ -43,27 +43,39 @@ int backtrace(void** buffer, int size) { #if __LP64__ #define _BACKTRACE_FORMAT "%-4d%-35s 0x%016lx %s + %lu" -#define _BACKTRACE_FORMAT_SIZE 82 +#define _BACKTRACE_FORMAT_SIZE 83 /* %lu can take up to 20, does not include %s, includes NUL */ +#define _BACKTRACE_ADDRESS_LEN 18 /* 0x + 16 (no NUL) */ #else #define _BACKTRACE_FORMAT "%-4d%-35s 0x%08lx %s + %lu" -#define _BACKTRACE_FORMAT_SIZE 65 +#define _BACKTRACE_FORMAT_SIZE 65 /* %lu can take up to 10, does not include %s, includes NUL */ +#define _BACKTRACE_ADDRESS_LEN 10 /* 0x + 8 (no NUL) */ #endif - static int _backtrace_snprintf(char* buf, size_t size, int frame, const void* addr, const Dl_info* info) { - char symbuf[19]; + char symbuf[_BACKTRACE_ADDRESS_LEN + 1]; const char* image = "???"; - const char* symbol = symbuf; + const char* symbol = "0x0"; + uintptr_t symbol_offset = 0; if (info->dli_fname) { - image = strrchr(info->dli_fname, '/') + 1; - if (image == NULL) image = info->dli_fname; + const char *tmp = strrchr(info->dli_fname, '/'); + if(tmp == NULL) + image = info->dli_fname; + else + image = tmp + 1; } if (info->dli_sname) { symbol = info->dli_sname; + symbol_offset = (uintptr_t)addr - (uintptr_t)info->dli_saddr; + } else if(info->dli_fname) { + symbol = image; + symbol_offset = (uintptr_t)addr - (uintptr_t)info->dli_fbase; + } else if(0 < snprintf(symbuf, sizeof(symbuf), "0x%lx", (uintptr_t)info->dli_saddr)) { + symbol = symbuf; + symbol_offset = (uintptr_t)addr - (uintptr_t)info->dli_saddr; } else { - snprintf(symbuf, sizeof(symbuf), "0x%lx", (uintptr_t)info->dli_saddr); + symbol_offset = (uintptr_t)addr; } return snprintf(buf, size, @@ -72,7 +84,7 @@ static int _backtrace_snprintf(char* buf, size_t size, int frame, const void* ad image, (uintptr_t)addr, symbol, - (uintptr_t)addr - (uintptr_t)info->dli_saddr) + 1; + symbol_offset) + 1; } char** backtrace_symbols(void* const* buffer, int size) { @@ -80,7 +92,7 @@ char** backtrace_symbols(void* const* buffer, int size) { size_t total_bytes; char** result; char** ptrs; - intptr_t strs; + intptr_t strs, end; Dl_info* info = calloc(size, sizeof (Dl_info)); if (info == NULL) return NULL; @@ -94,8 +106,18 @@ char** backtrace_symbols(void* const* buffer, int size) { // Plus each symbol description for (i = 0 ; i < size; ++i) { dladdr(buffer[i], &info[i]); - total_bytes += _BACKTRACE_FORMAT_SIZE + 1; - if (info[i].dli_sname) total_bytes += strlen(info[i].dli_sname); + total_bytes += _BACKTRACE_FORMAT_SIZE; + if (info[i].dli_sname) { + total_bytes += strlen(info[i].dli_sname); + } else if(info[i].dli_fname) { + const char *tmp = strrchr(info->dli_fname, '/'); + if(tmp == NULL) + total_bytes += strlen(info->dli_fname); + else + total_bytes += strlen(tmp + 1); + } else { + total_bytes += _BACKTRACE_ADDRESS_LEN; + } } result = (char**)malloc(total_bytes); @@ -103,16 +125,24 @@ char** backtrace_symbols(void* const* buffer, int size) { free(info); return NULL; } + end = (intptr_t)result + total_bytes; // Fill in the array of pointers and append the strings for // each symbol description. ptrs = result; strs = ((intptr_t)result) + sizeof(char*) * size; - + for (i = 0; i < size; ++i) { + int chk = _backtrace_snprintf((char*)strs, end - (intptr_t)strs, i, buffer[i], &info[i]); + + if(chk < 0) { + free(info); + return NULL; + } + ptrs[i] = (char*)strs; - strs += _backtrace_snprintf((char*)strs, total_bytes, i, buffer[i], &info[i]); + strs += chk; } free(info); diff --git a/gen/closedir-fbsd.c b/gen/closedir-fbsd.c index 61753c2..10bfe5e 100644 --- a/gen/closedir-fbsd.c +++ b/gen/closedir-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)closedir.c 8.1 (Berkeley) 6/10/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/closedir.c,v 1.10 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/closedir.c,v 1.13 2007/12/03 14:33:50 des Exp $"); #include "namespace.h" #include @@ -58,7 +54,7 @@ closedir(dirp) int fd; if (__isthreaded) - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_lock(&dirp->dd_lock); #if !__DARWIN_UNIX03 _seekdir(dirp, dirp->dd_rewind); /* free seekdir storage */ #endif /* __DARWIN_UNIX03 */ @@ -68,8 +64,8 @@ closedir(dirp) free((void *)dirp->dd_buf); _reclaim_telldir(dirp); if (__isthreaded) { - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); - _pthread_mutex_destroy((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_unlock(&dirp->dd_lock); + _pthread_mutex_destroy(&dirp->dd_lock); } free((void *)dirp); return(_close(fd)); diff --git a/gen/compat.5 b/gen/compat.5 index 880265d..fbae912 100644 --- a/gen/compat.5 +++ b/gen/compat.5 @@ -1,4 +1,4 @@ -.Dd October 23, 2005 +.Dd June 30, 2010 .Os Darwin .Dt COMPAT 5 .Sh NAME @@ -17,7 +17,12 @@ .Sh DESCRIPTION Setting the environment variable .Ev COMMAND_MODE -to the value legacy causes utility programs to behave as closely to Mac OS X 10.3's utility programs as possible. When in this mode all of 10.3's flags are accepted, and in some cases extra flags are accepted, but no flags that were used in 10.3 will have been removed or changed in meaning. Any behavioral changes in this mode are documented in the LEGACY sections of the individual utilities. +to the value legacy causes utility programs to behave as closely to +Mac OS X 10.3's utility programs as possible. When in this mode all of 10.3's +flags are accepted, and in some cases extra flags are accepted, but no flags +that were used in 10.3 will have been removed or changed in meaning. Any +behavioral changes in this mode are documented in the LEGACY sections of the +individual utilities. .Pp Setting the environment variable .Ev COMMAND_MODE @@ -27,11 +32,16 @@ standards even if doing so would alter the behavior of flags used in 10.3. .Pp The value of .Ev COMMAND_MODE -is case insensitive and if it is unset or set to something other than legacy or unix2003 it behaves as if it were set to unix2003. -.Sh 32-BIT COMPILATION +is case insensitive and if it is unset or set to something other than legacy +or unix2003 it behaves as if it were set to unix2003. +.Sh COMPILATION Defining .Dv _NONSTD_SOURCE -causes library and kernel calls to behave as closely to Mac OS X 10.3's library and kernel calls as possible. Any behavioral changes in this mode are documented in the LEGACY sections of the individual function calls. +for i386 causes library and kernel calls to behave as closely to Mac +OS X 10.3's library and kernel calls as possible. Any behavioral changes are +documented in the LEGACY sections of the man pages for the individual function +calls. Defining this macro when compiling for any other architecture will +result in a compilation error. .Pp Defining .Dv _POSIX_C_SOURCE @@ -69,27 +79,100 @@ is either not specified or set to 10.5 or greater), then UNIX conformance will be on by default, and non-POSIX extensions will also be available (this is the equivalent of defining .Dv _DARWIN_C_SOURCE ) . -For version values less that 10.5, UNIX conformance will be off (the -equivalent of defining +For version values less that 10.5, UNIX conformance will be off when targeting +i386 (the equivalent of defining .Dv _NONSTD_SOURCE ) . -.Sh 64-BIT COMPILATION -When compiling for 64-bit architectures, the -.Dv __LP64__ -macro will be defined to 1, and UNIX conformance is always on (the -.Dv _DARWIN_FEATURE_UNIX_CONFORMANCE -macro will also be defined to the SUS conformance level). -Defining -.Dv _NONSTD_SOURCE -will cause a compilation error. +.Pp +In order to provide both legacy and conformance versions of functions, two +versions of affected functions are provided. Legacy variants have symbol names +with no suffix in order to maintain ABI compatibility. Conformance versions +have a $UNIX2003 suffix appended to their symbol name. These $UNIX2003 +suffixes are automatically appended by the compiler tool-chain and should not +be used directly. +.Pp +Platforms that were released after these updates only have conformance variants +available and do not have a $UNIX2003 suffix. +.Pp +.TS +center; +c s s s s +c c | c c c +c c | c c c +l c | c c c +l c | c c c +l c | c c c +l c | c c c +l c | c c c +l c | c c c +l c | c c c. +T{ +.Dv i386 +T} += +user defines deployment namespace conformance suffix + target +_ +T{ +.Em (none) +T} < 10.5 full 10.3 compatibility (none) +T{ +.Em (none) +T} >= 10.5 full SUSv3 conformance $UNIX2003 +T{ +.Em _NONSTD_SOURCE +T} (any) full 10.3 compatibility (none) +T{ +.Em _DARWIN_C_SOURCE +T} < 10.4 full 10.3 compatibility (none) +T{ +.Em _DARWIN_C_SOURCE +T} >= 10.4 full SUSv3 conformance $UNIX2003 +T{ +.Em _POSIX_C_SOURCE +T} < 10.4 strict 10.3 compatibility (none) +T{ +.Em _POSIX_C_SOURCE +T} >= 10.4 strict SUSv3 conformance $UNIX2003 +_ +.T& +c s s s s +c s s s s +c c | c c c +c c | c c c +l c | c c c +l c | c s s +l c | c c c +l c | c c c. +T{ +.Dv Newer Architectures +T} += +user defines deployment namespace conformance suffix + target +_ +T{ +.Em (none) +T} (any) full SUSv3 conformance (none) +T{ +.Em _NONSTD_SOURCE +T} (any) (error) +T{ +.Em _DARWIN_C_SOURCE +T} (any) full SUSv3 conformance (none) +T{ +.Em _POSIX_C_SOURCE +T} (any) strict SUSv3 conformance (none) +_ +.TE .Sh STANDARDS -With COMMAND_MODE set to unix2003 utility functions conform to +With COMMAND_MODE set to anything other than legacy, utility functions conform to .St -susv3 . .Pp With -.Dv _POSIX_C_SOURCE , -.Dv _DARWIN_C_SOURCE , +.Dv _POSIX_C_SOURCE or -.Dv __LP64__ , +.Dv _DARWIN_C_SOURCE +for i386, or when building for any other architecture, system and library calls conform to .St -susv3 . .Sh BUGS diff --git a/gen/crypt.c b/gen/crypt.c index 4c6b742..f1edfd9 100644 --- a/gen/crypt.c +++ b/gen/crypt.c @@ -131,11 +131,12 @@ #endif #ifndef BUILDING_VARIANT STATIC void init_des(), init_perm(), permute(); -#endif /* BUILDING_VARIANT */ -__private_extern__ int __crypt_des_cipher(), __crypt_des_setkey(); #ifdef DEBUG -STATIC prtab(); +#include +STATIC void prtab(); #endif +#endif /* BUILDING_VARIANT */ +__private_extern__ int __crypt_des_cipher(), __crypt_des_setkey(); /* ==================================== */ @@ -1023,7 +1024,7 @@ int encrypt(block, flag) #ifndef BUILDING_VARIANT #ifdef DEBUG -STATIC +STATIC void prtab(s, t, num_rows) char *s; unsigned char *t; diff --git a/gen/ctermid.3 b/gen/ctermid.3 index c51c8a9..2085245 100644 --- a/gen/ctermid.3 +++ b/gen/ctermid.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ctermid.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/ctermid.3,v 1.11 2003/09/08 19:57:14 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/ctermid.3,v 1.12 2007/01/09 00:27:53 imp Exp $ .\" .Dd June 4, 1993 .Dt CTERMID 3 diff --git a/gen/daemon-fbsd.c b/gen/daemon-fbsd.c index b85c24a..ea9a15f 100644 --- a/gen/daemon-fbsd.c +++ b/gen/daemon-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/daemon.c,v 1.6 2003/11/10 22:01:42 ghelmer Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/daemon.c,v 1.8 2007/01/09 00:27:53 imp Exp $"); #ifndef VARIANT_PRE1050 #include @@ -45,6 +41,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/daemon.c,v 1.6 2003/11/10 22:01:42 ghelmer #include #include #include +#include #include #include #include "un-namespace.h" diff --git a/gen/daemon.3 b/gen/daemon.3 index cd4931f..a2d9f2b 100644 --- a/gen/daemon.3 +++ b/gen/daemon.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)daemon.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/daemon.3,v 1.14 2003/11/10 22:04:51 ghelmer Exp $ +.\" $FreeBSD: src/lib/libc/gen/daemon.3,v 1.15 2007/01/09 00:27:53 imp Exp $ .\" .Dd June 9, 1993 .Dt DAEMON 3 diff --git a/gen/dirname-fbsd.c b/gen/dirname-fbsd.c index e1c575b..5164e18 100644 --- a/gen/dirname-fbsd.c +++ b/gen/dirname-fbsd.c @@ -1,37 +1,23 @@ +/* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */ + /* - * Copyright (c) 1997 Todd C. Miller - * All rights reserved. + * Copyright (c) 1997, 2004 Todd C. Miller * - * 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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 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. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#if 0 -#ifndef lint -static char rcsid[] = "$OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $"; -#endif /* not lint */ -#endif #include -__FBSDID("$FreeBSD: src/lib/libc/gen/dirname.c,v 1.7 2002/12/30 01:41:14 marcel Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/dirname.c,v 1.8 2008/11/03 05:19:45 delphij Exp $"); #include #include @@ -44,25 +30,26 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/dirname.c,v 1.7 2002/12/30 01:41:14 marcel #endif char * -dirname(path) - const char *path; +dirname(const char *path) { - static char *bname = NULL; + static char *dname = NULL; + size_t len; const char *endp; - if (bname == NULL) { - bname = (char *)malloc(MAXPATHLEN); - if (bname == NULL) + if (dname == NULL) { + dname = (char *)malloc(MAXPATHLEN); + if (dname == NULL) return(NULL); } /* Empty or NULL string gets treated as "." */ if (path == NULL || *path == '\0') { - (void)strcpy(bname, "."); - return(bname); + dname[0] = '.'; + dname[1] = '\0'; + return (dname); } - /* Strip trailing slashes */ + /* Strip any trailing slashes */ endp = path + strlen(path) - 1; while (endp > path && *endp == '/') endp--; @@ -73,19 +60,22 @@ dirname(path) /* Either the dir is "/" or there are no slashes */ if (endp == path) { - (void)strcpy(bname, *endp == '/' ? "/" : "."); - return(bname); + dname[0] = *endp == '/' ? '/' : '.'; + dname[1] = '\0'; + return (dname); } else { + /* Move forward past the separating slashes */ do { endp--; } while (endp > path && *endp == '/'); } - if (endp - path + 2 > MAXPATHLEN) { + len = endp - path + 1; + if (len >= MAXPATHLEN) { errno = ENAMETOOLONG; - return(NULL); + return (NULL); } - (void)strncpy(bname, path, endp - path + 1); - bname[endp - path + 1] = '\0'; - return(bname); + memcpy(dname, path, len); + dname[len] = '\0'; + return (dname); } diff --git a/gen/dirname.3 b/gen/dirname.3 index 2caa872..330b426 100644 --- a/gen/dirname.3 +++ b/gen/dirname.3 @@ -1,33 +1,22 @@ +.\" $OpenBSD: dirname.3,v 1.17 2007/05/31 19:19:28 jmc Exp $ .\" .\" Copyright (c) 1997 Todd C. Miller -.\" 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. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. .\" -.\" THIS SOFTWARE IS PROVIDED ``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 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. +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.\" $OpenBSD: dirname.3,v 1.9 2000/04/18 03:01:25 aaron Exp $ -.\" $FreeBSD: src/lib/libc/gen/dirname.3,v 1.8 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/dirname.3,v 1.10 2008/11/03 05:19:45 delphij Exp $ .\" -.Dd August 17, 1997 +.Dd October 12, 2006 .Dt DIRNAME 3 .Os .Sh NAME @@ -42,8 +31,7 @@ .Sh DESCRIPTION The .Fn dirname -function -is the converse of +function is the converse of .Xr basename 3 ; it returns a pointer to the parent directory of the pathname pointed to by .Fa path . @@ -60,31 +48,13 @@ characters, returns a pointer to the string .Qq \&. , signifying the current directory. -.Sh RETURN VALUES -On successful completion, -.Fn dirname -returns a pointer to the parent directory of -.Fa path . -.Pp -If -.Fn dirname -fails, a null pointer is returned and the global variable -.Va errno -is set to indicate the error. -.Sh ERRORS -The following error codes may be set in -.Va errno : -.Bl -tag -width Er -.It Bq Er ENAMETOOLONG -The path component to be returned was larger than -.Dv MAXPATHLEN . -.El -.Sh WARNINGS +.Sh IMPLEMENTATION NOTES The .Fn dirname function -returns a pointer to internal static storage space that will be overwritten -by subsequent calls (each function has its own separate storage). +returns a pointer to internal storage space allocated on the first call +that will be overwritten +by subsequent calls. .Pp Other vendor implementations of .Fn dirname @@ -104,6 +74,25 @@ this should be taken into account when writing code which calls this function. In legacy mode, .Fa path will not be changed. +.Sh RETURN VALUES +On successful completion, +.Fn dirname +returns a pointer to the parent directory of +.Fa path . +.Pp +If +.Fn dirname +fails, a null pointer is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The following error codes may be set in +.Va errno : +.Bl -tag -width Er +.It Bq Er ENAMETOOLONG +The path component to be returned was larger than +.Dv MAXPATHLEN . +.El .Sh SEE ALSO .Xr basename 1 , .Xr dirname 1 , @@ -122,4 +111,4 @@ function first appeared in and .Fx 4.2 . .Sh AUTHORS -.An "Todd C. Miller" Aq Todd.Miller@courtesan.com +.An "Todd C. Miller" diff --git a/gen/endutxent.3 b/gen/endutxent.3 index 84382a6..719b98f 100644 --- a/gen/endutxent.3 +++ b/gen/endutxent.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: endutxent.3,v 1.4 2004/05/04 02:38:35 atatat Exp $ +.\" $NetBSD: endutxent.3,v 1.5 2008/04/30 13:10:50 martin Exp $ .\" .\" Copyright (c) 2002 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -14,13 +14,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -187,11 +180,11 @@ the other fields with meaningful values are as follows: .El .Ss Other extensions to the standards The -.Fa ut_tv +.Fa ut_type value may also be OR-ed with the following masks: .Bl -tag -width XXXX -compact -offset indent .It Dv UTMPX_AUTOFILL_MASK -Depending on the +Depending on the main part of .Fa ut_type value, other fields are automatically filled in (as specified in the meaningful fields table above). diff --git a/gen/endutxent.3.orig b/gen/endutxent.3.orig new file mode 100644 index 0000000..06a4433 --- /dev/null +++ b/gen/endutxent.3.orig @@ -0,0 +1,202 @@ +.\" $NetBSD: endutxent.3,v 1.5 2008/04/30 13:10:50 martin Exp $ +.\" +.\" Copyright (c) 2002 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Thomas Klausner. +.\" +.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +.\" +.Dd September 26, 2002 +.Dt ENDUTXENT 3 +.Os +.Sh NAME +.Nm endutxent , +.Nm getutxent , +.Nm getutxid , +.Nm getutxline , +.Nm pututxline , +.Nm setutxent +.Nd user accounting database functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In utmpx.h +.Ft void +.Fn endutxent void +.Ft struct utmpx * +.Fn getutxent void +.Ft struct utmpx * +.Fn getutxid "const struct utmpx *" +.Ft struct utmpx * +.Fn getutxline "const struct utmpx *" +.Ft struct utmpx * +.Fn pututxline "const struct utmpx *" +.Ft void +.Fn setutxent void +.Sh DESCRIPTION +These functions provide access to the +.Xr utmpx 5 +user accounting database. +.Pp +.Fn getutxent +reads the next entry from the database; +if the database was not yet open, it also opens it. +.Fn setutxent +resets the database, so that the next +.Fn getutxent +call will get the first entry. +.Fn endutxent +closes the database. +.Pp +.Fn getutxid +returns the next entry of the type specified in its argument's +.Va ut_type +field, or +.Dv NULL +if none is found. +.Fn getutxline +returns the next +.Dv LOGIN_PROCESS +or +.Dv USER_PROCESS +entry which has the same name as specified in the +.Va ut_line +field, or +.Dv NULL +if no match is found. +.Pp +.Fn pututxline +adds the argument +.Xr utmpx 5 +entry line to the accounting database, replacing a previous entry for +the same user if it exists. +.Ss The utmpx structure +The +.Nm utmpx +structure has the following definition: +.Pp +.Bd -literal +struct utmpx { + char ut_name[_UTX_USERSIZE]; /* login name */ + char ut_id[_UTX_IDSIZE]; /* inittab id */ + char ut_line[_UTX_LINESIZE]; /* tty name */ + char ut_host[_UTX_HOSTSIZE]; /* host name */ + uint16_t ut_session; /* session id used for windowing */ + uint16_t ut_type; /* type of this entry */ + pid_t ut_pid; /* process id creating the entry */ + struct { + uint16_t e_termination; /* process termination signal */ + uint16_t e_exit; /* process exit status */ + } ut_exit; + struct sockaddr_storage ut_ss; /* address where entry was made from */ + struct timeval ut_tv; /* time entry was created */ + uint32_t ut_pad[10]; /* reserved for future use */ +}; +.Ed +.Pp +Valid entries for +.Fa ut_type +are: +.Bl -tag -width LOGIN_PROCESSXX -compact -offset indent +.It Dv BOOT_TIME +Time of a system boot. +.It Dv DEAD_PROCESS +A session leader exited. +.It Dv EMPTY +No valid user accounting information. +.It Dv INIT_PROCESS +A process spawned by +.Xr init 8 . +.It Dv LOGIN_PROCESS +The session leader of a logged-in user. +.It Dv NEW_TIME +Time after system clock change. +.It Dv OLD_TIME +Time before system clock change. +.It Dv RUN_LVL +Run level. +Provided for compatibility, not used on +.Nx . +.It Dv USER_PROCESS +A user process. +.El +.Sh RETURN VALUES +.Fn getutxent +returns the next entry, or +.Dv NULL +on failure (end of database or problems reading from the database). +.Fn getutxid +and +.Fn getutxline +return the matching structure on success, or +.Dv NULL +if no match was found. +.Fn pututxline +returns the structure that was successfully written, or +.Dv NULL . +.Sh SEE ALSO +.Xr logwtmpx 3 , +.Xr utmpx 5 +.Sh STANDARDS +The +.Fn endutxent , +.Fn getutxent , +.Fn getutxid , +.Fn getutxline , +.Fn pututxline , +.Fn setutxent +all conform to +.St -p1003.1-2001 +(XSI extension), and previously to +.St -xpg4.2 . +The fields +.Fa ut_user , +.Fa ut_id , +.Fa ut_line , +.Fa ut_pid , +.Fa ut_type , +and +.Fa ut_tv +conform to +.St -p1003.1-2001 +(XSI extension), and previously to +.St -xpg4.2 . +.\" .Fa ut_host , +.\" .Fa ut_session , +.\" .Fa ut_exit , +.\" and +.\" .Fa ut_ss +.\" are from +.\" SVR3/4? +.\" .Dv RUN_LVL +.\" is for compatibility with +.\" what exactly? +.\" .Sh HISTORY +.\" The +.\" .Nm utmpx , +.\" .Nm wtmpx , +.\" and +.\" .Nm lastlogx +.\" files first appeared in +.\" SVR3? 4? diff --git a/gen/err-fbsd.c b/gen/err-fbsd.c index 2ceded0..e6e03f6 100644 --- a/gen/err-fbsd.c +++ b/gen/err-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)err.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/err.c,v 1.13 2002/03/29 22:43:41 markm Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/err.c,v 1.15 2008/04/03 20:36:44 imp Exp $"); #include "namespace.h" #include @@ -87,10 +83,12 @@ __private_extern__ struct _e_err_exit _e_err_exit = {ERR_EXIT_UNDEF}; * (NUL isn't used) */ static unsigned char escape[256] = { - /* NUL SOH STX ETX EOT ENQ ACK BEL */ - 0 , 255, 255, 255, 255, 255, 255, 'a', + /* NUL */ + 0, /* Unused: strings can't contain nulls */ + /* SOH STX ETX EOT ENQ ACK BEL */ + 255, 255, 255, 255, 255, 255, 'a', /* BS HT NL VT NP CR SO SI */ - 'b', 't', 'n', 'v', 'f', 'r', 255, 255, + 'b', 0, 0, 'v', 'f', 'r', 255, 255, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ 255, 255, 255, 255, 255, 255, 255, 255, /* CAN EM SUB ESC FS GS RS US */ @@ -121,7 +119,7 @@ _e_visprintf(FILE * __restrict stream, const char * __restrict format, va_list a *tp++ = *fp; break; case 255: - sprintf(tp, "\\%03o", *fp); + sprintf((char *)tp, "\\%03o", *fp); tp += 4; break; default: @@ -205,11 +203,7 @@ errc(int eval, int code, const char *fmt, ...) } void -verrc(eval, code, fmt, ap) - int eval; - int code; - const char *fmt; - va_list ap; +verrc(int eval, int code, const char *fmt, va_list ap) { if (_e_err_file == 0) err_set_file((FILE *)0); @@ -239,10 +233,7 @@ errx(int eval, const char *fmt, ...) } void -verrx(eval, fmt, ap) - int eval; - const char *fmt; - va_list ap; +verrx(int eval, const char *fmt, va_list ap) { if (_e_err_file == 0) err_set_file((FILE *)0); @@ -272,9 +263,7 @@ _warn(const char *fmt, ...) } void -vwarn(fmt, ap) - const char *fmt; - va_list ap; +vwarn(const char *fmt, va_list ap) { vwarnc(errno, fmt, ap); } @@ -289,10 +278,7 @@ warnc(int code, const char *fmt, ...) } void -vwarnc(code, fmt, ap) - int code; - const char *fmt; - va_list ap; +vwarnc(int code, const char *fmt, va_list ap) { if (_e_err_file == 0) err_set_file((FILE *)0); @@ -314,9 +300,7 @@ warnx(const char *fmt, ...) } void -vwarnx(fmt, ap) - const char *fmt; - va_list ap; +vwarnx(const char *fmt, va_list ap) { if (_e_err_file == 0) err_set_file((FILE *)0); diff --git a/gen/err.3 b/gen/err.3 index 41f5d1c..a4c953f 100644 --- a/gen/err.3 +++ b/gen/err.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)err.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/err.3,v 1.20 2004/10/04 14:04:37 jkoshy Exp $ +.\" $FreeBSD: src/lib/libc/gen/err.3,v 1.24 2008/10/31 15:14:40 rwatson Exp $ .\" .Dd May 20, 2008 .Dt ERR 3 @@ -105,7 +101,7 @@ and a space are output. If the .Fa fmt argument is not NULL, the -.Xr printf 3 +.Xr printf 3 Ns -like formatted error message is output. The output is terminated by a newline character. .Pp @@ -121,7 +117,7 @@ and .Fn vwarnc functions append an error message obtained from .Xr strerror 3 -based on a code or the global variable +based on a supplied error code value or the global variable .Va errno , preceded by another colon and space unless the .Fa fmt @@ -207,15 +203,16 @@ or a null pointer Display the current errno information string and exit: .Bd -literal -offset indent if ((p = malloc(size)) == NULL) - err(1, NULL); + err(EX_OSERR, NULL); if ((fd = open(file_name, O_RDONLY, 0)) == -1) - err(1, "%s", file_name); + err(EX_NOINPUT, "%s", file_name); .Ed .Pp Display an error message and exit: .Bd -literal -offset indent if (tm.tm_hour < START_TIME) - errx(1, "too early, wait until %s", start_time_string); + errx(EX_DATAERR, "too early, wait until %s", + start_time_string); .Ed .Pp Warn of an error: @@ -224,7 +221,7 @@ if ((fd = open(raw_device, O_RDONLY, 0)) == -1) warnx("%s: %s: trying the block device", raw_device, strerror(errno)); if ((fd = open(block_device, O_RDONLY, 0)) == -1) - err(1, "%s", block_device); + err(EX_OSFILE, "%s", block_device); .Ed .Pp Warn of an error without using the global variable diff --git a/gen/errlst.c b/gen/errlst.c index 66916da..d0c2cd6 100644 --- a/gen/errlst.c +++ b/gen/errlst.c @@ -182,6 +182,8 @@ const char *const sys_errlist[] = { "STREAM ioctl timeout", /* 101 - ETIME */ "Operation not supported on socket", /* 102 - EOPNOTSUPP */ "Policy not found", /* 103 - ENOPOLICY */ + "State not recoverable", /* 104 - ENOTRECOVERABLE */ + "Previous owner died", /* 105 - EOWNERDEAD */ }; const int sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]); diff --git a/gen/errno_-fbsd.c b/gen/errno_-fbsd.c deleted file mode 120000 index f3e3eb4..0000000 --- a/gen/errno_-fbsd.c +++ /dev/null @@ -1 +0,0 @@ -./errno_.c \ No newline at end of file diff --git a/gen/exec-fbsd.c b/gen/exec-fbsd.c index 54a0548..86cf335 100644 --- a/gen/exec-fbsd.c +++ b/gen/exec-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/exec.c,v 1.22 2003/07/01 12:30:03 bde Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/exec.c,v 1.27 2009/12/05 18:55:16 ed Exp $"); #include "namespace.h" #include @@ -50,15 +46,19 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/exec.c,v 1.22 2003/07/01 12:30:03 bde Exp $ #include #include "un-namespace.h" +#include "libc_private.h" #include #define environ (*_NSGetEnviron()) +int +_execvpe(const char *name, char * const argv[], char * const envp[]); + int execl(const char *name, const char *arg, ...) { va_list ap; - char **argv; + const char **argv; int n; va_start(ap, arg); @@ -73,18 +73,19 @@ execl(const char *name, const char *arg, ...) } va_start(ap, arg); n = 1; - argv[0] = (char *)arg; + argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; va_end(ap); - return (_execve(name, argv, environ)); + return (_execve(name, __DECONST(char **, argv), environ)); } int execle(const char *name, const char *arg, ...) { va_list ap; - char **argv, **envp; + const char **argv; + char **envp; int n; va_start(ap, arg); @@ -99,19 +100,19 @@ execle(const char *name, const char *arg, ...) } va_start(ap, arg); n = 1; - argv[0] = (char *)arg; + argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; envp = va_arg(ap, char **); va_end(ap); - return (_execve(name, argv, envp)); + return (_execve(name, __DECONST(char **, argv), envp)); } int execlp(const char *name, const char *arg, ...) { va_list ap; - char **argv; + const char **argv; int n; va_start(ap, arg); @@ -126,11 +127,11 @@ execlp(const char *name, const char *arg, ...) } va_start(ap, arg); n = 1; - argv[0] = (char *)arg; + argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; va_end(ap); - return (execvp(name, argv)); + return (execvp(name, __DECONST(char **, argv))); } int @@ -145,33 +146,25 @@ execv(name, argv) int execvp(const char *name, char * const *argv) { - const char *path; - - /* Get the path we're searching. */ - if ((path = getenv("PATH")) == NULL) - path = _PATH_DEFPATH; - - return (execvP(name, path, argv)); + return (_execvpe(name, argv, environ)); } -int -execvP(name, path, argv) - const char *name; - const char *path; - char * const *argv; +static int +execvPe(const char *name, const char *path, char * const *argv, + char * const *envp) { - char **memp; - int cnt, lp, ln; - char *p; + const char **memp; + size_t cnt, lp, ln; int eacces, save_errno; - char *bp, *cur, buf[MAXPATHLEN]; + char *cur, buf[MAXPATHLEN]; + const char *p, *bp; struct stat sb; eacces = 0; /* If it's an absolute or relative path name, it's easy. */ if (index(name, '/')) { - bp = (char *)name; + bp = name; cur = NULL; goto retry; } @@ -218,7 +211,7 @@ execvP(name, path, argv) bcopy(name, buf + lp + 1, ln); buf[lp + ln + 1] = '\0'; -retry: (void)_execve(bp, argv, environ); +retry: (void)_execve(bp, argv, envp); switch (errno) { case E2BIG: goto done; @@ -237,7 +230,8 @@ retry: (void)_execve(bp, argv, environ); memp[0] = "sh"; memp[1] = bp; bcopy(argv + 1, memp + 2, cnt * sizeof(char *)); - (void)_execve(_PATH_BSHELL, memp, environ); + (void)_execve(_PATH_BSHELL, + __DECONST(char **, memp), envp); goto done; case ENOMEM: goto done; @@ -275,3 +269,21 @@ retry: (void)_execve(bp, argv, environ); done: return (-1); } + +int +execvP(const char *name, const char *path, char * const argv[]) +{ + return execvPe(name, path, argv, environ); +} + +__private_extern__ int +_execvpe(const char *name, char * const argv[], char * const envp[]) +{ + const char *path; + + /* Get the path we're searching. */ + if ((path = getenv("PATH")) == NULL) + path = _PATH_DEFPATH; + + return (execvPe(name, path, argv, envp)); +} diff --git a/gen/exec.3 b/gen/exec.3 index d0b11fa..2f49ef3 100644 --- a/gen/exec.3 +++ b/gen/exec.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)exec.3 8.3 (Berkeley) 1/24/94 -.\" $FreeBSD: src/lib/libc/gen/exec.3,v 1.23 2003/09/10 19:24:32 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/exec.3,v 1.28 2008/06/23 05:22:06 ed Exp $ .\" .Dd January 24, 1994 .Dt EXEC 3 @@ -173,7 +169,7 @@ and search path is the path specified in the environment by .Dq Ev PATH variable. -If this variable isn't specified, +If this variable is not specified, the default path is set according to the .Dv _PATH_DEFPATH definition in @@ -210,7 +206,7 @@ or according to whether at least one file with suitable execute permissions was found. .Pp -If the header of a file isn't recognized (the attempted +If the header of a file is not recognized (the attempted .Fn execve returned .Er ENOEXEC ) , @@ -229,34 +225,6 @@ will be set to indicate the error. .It Pa /bin/sh The shell. .El -.Sh ERRORS -The -.Fn execl , -.Fn execle , -.Fn execlp , -.Fn execvp , -and -.Fn execvP -functions -may fail and set -.Va errno -for any of the errors specified for the library functions -.Xr execve 2 -and -.Xr malloc 3 . -.Pp -The -.Fn execv -function may fail and set -.Va errno -for any of the errors specified for the library function -.Xr execve 2 . -.Sh SEE ALSO -.Xr sh 1 , -.Xr execve 2 , -.Xr fork 2 , -.Xr ptrace 2 , -.Xr environ 7 .Sh COMPATIBILITY Historically, the default path for the .Fn execlp @@ -277,11 +245,11 @@ by the .Tn POSIX standard. .Pp -Traditionally, the +Traditionally, the functions .Fn execlp and .Fn execvp -functions ignored all errors except for the ones described above and +ignored all errors except for the ones described above and .Er ETXTBSY , upon which they retried after sleeping for several seconds, and .Er ENOMEM @@ -313,6 +281,34 @@ and the unusual error .Er EIO . The behaviour was changed to match the behaviour of .Xr sh 1 . +.Sh ERRORS +The +.Fn execl , +.Fn execle , +.Fn execlp , +.Fn execvp , +and +.Fn execvP +functions +may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr execve 2 +and +.Xr malloc 3 . +.Pp +The +.Fn execv +function may fail and set +.Va errno +for any of the errors specified for the library function +.Xr execve 2 . +.Sh SEE ALSO +.Xr sh 1 , +.Xr execve 2 , +.Xr fork 2 , +.Xr ptrace 2 , +.Xr environ 7 .Sh STANDARDS The .Fn execl , diff --git a/gen/execinfo.h b/gen/execinfo.h index 6fc9759..259b92e 100644 --- a/gen/execinfo.h +++ b/gen/execinfo.h @@ -24,12 +24,13 @@ #define _EXECINFO_H_ 1 #include +#include __BEGIN_DECLS -int backtrace(void**,int); -char** backtrace_symbols(void* const*,int); -void backtrace_symbols_fd(void* const*,int,int); +int backtrace(void**,int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +char** backtrace_symbols(void* const*,int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +void backtrace_symbols_fd(void* const*,int,int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); __END_DECLS diff --git a/gen/fmtmsg-fbsd.c b/gen/fmtmsg-fbsd.c index 8e14941..e912693 100644 --- a/gen/fmtmsg-fbsd.c +++ b/gen/fmtmsg-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/fmtmsg.c,v 1.5 2003/05/01 19:03:13 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/fmtmsg.c,v 1.6 2009/11/08 14:02:54 brueffer Exp $"); #include #include @@ -179,7 +179,7 @@ printfmt(char *msgverb, long class, const char *label, int sev, size += strlen(sevname); if (text != MM_NULLTXT) size += strlen(text); - if (text != MM_NULLACT) + if (act != MM_NULLACT) size += strlen(act); if (tag != MM_NULLTAG) size += strlen(tag); diff --git a/gen/fnmatch-fbsd.c b/gen/fnmatch-fbsd.c index 96e35eb..51a1f97 100644 --- a/gen/fnmatch-fbsd.c +++ b/gen/fnmatch-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.16 2004/07/29 03:13:10 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.19 2010/04/16 22:29:24 jilles Exp $"); #include "xlocale_private.h" @@ -68,15 +64,16 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.16 2004/07/29 03:13:10 tjr Ex #define EOS '\0' -#if __DARWIN_UNIX03 #define RETURN_ERROR 2 /* neither 0 or FNM_NOMATCH */ -#endif /* __DARWIN_UNIX03 */ #define RANGE_MATCH 1 #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) +#define RECURSION_MAX 64 + __private_extern__ int rangematch(const char *, wchar_t, const char *, int, char **, char **, mbstate_t *, mbstate_t *, locale_t); -static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t, locale_t); +static int fnmatch1(const char *, const char *, const char *, int, mbstate_t, + mbstate_t, locale_t, int); int fnmatch(pattern, string, flags) @@ -84,24 +81,29 @@ fnmatch(pattern, string, flags) int flags; { static const mbstate_t initial; - - return (fnmatch1(pattern, string, flags, initial, initial, __current_locale())); +#if __DARWIN_UNIX03 + return (fnmatch1(pattern, string, string, flags, initial, initial, __current_locale(), RECURSION_MAX)); +#else /* !__DARWIN_UNIX03 */ + return (fnmatch1(pattern, string, string, flags, initial, initial, __current_locale(), RECURSION_MAX) != 0 ? FNM_NOMATCH : 0); +#endif /* __DARWIN_UNIX03 */ } static int -fnmatch1(pattern, string, flags, patmbs, strmbs, loc) - const char *pattern, *string; +fnmatch1(pattern, string, stringstart, flags, patmbs, strmbs, loc, recursion) + const char *pattern, *string, *stringstart; int flags; mbstate_t patmbs, strmbs; locale_t loc; + int recursion; { - const char *stringstart; char *newp, *news; char c; wchar_t pc, sc; size_t pclen, sclen; - for (stringstart = string;;) { + if (recursion-- <= 0) + return RETURN_ERROR; + for (;;) { pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX, &patmbs, loc); if (pclen == (size_t)-1 || pclen == (size_t)-2) #if __DARWIN_UNIX03 @@ -158,10 +160,11 @@ fnmatch1(pattern, string, flags, patmbs, strmbs, loc) } /* General case, use recursion. */ + int ret; while (sc != EOS) { - if (!fnmatch1(pattern, string, - flags & ~FNM_PERIOD, patmbs, strmbs, loc)) - return (0); + if ((ret = fnmatch1(pattern, string, stringstart, + flags, patmbs, strmbs, loc, recursion)) != FNM_NOMATCH) + return (ret); sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, &strmbs, loc); if (sclen == (size_t)-1 || @@ -278,7 +281,6 @@ rangematch(pattern, test, string, flags, newp, news, patmbs, strmbs, loc) } else if (*pattern == '\0') { return (RANGE_ERROR); } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { - pattern++; return (RANGE_NOMATCH); } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) pattern++; diff --git a/gen/fnmatch.3 b/gen/fnmatch.3 index 1b0d529..f3aa885 100644 --- a/gen/fnmatch.3 +++ b/gen/fnmatch.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fnmatch.3 8.3 (Berkeley) 4/28/95 -.\" $FreeBSD: src/lib/libc/gen/fnmatch.3,v 1.18 2004/07/18 06:56:40 tjr Exp $ +.\" $FreeBSD: src/lib/libc/gen/fnmatch.3,v 1.19 2007/01/09 00:27:53 imp Exp $ .\" .Dd July 18, 2004 .Dt FNMATCH 3 @@ -126,6 +122,17 @@ The function returns zero if .Fa string matches the pattern specified by +.Fa pattern . +It returns the value +.Dv FNM_NOMATCH +if no match is found. +Otherwise, another non-zero value is returned on error. +.Sh LEGACY RETURN VALUES +The +.Fn fnmatch +function returns zero if +.Fa string +matches the pattern specified by .Fa pattern ; otherwise, it returns the value .Dv FNM_NOMATCH . diff --git a/gen/ftok.3 b/gen/ftok.3 index a01b70d..88a3a23 100644 --- a/gen/ftok.3 +++ b/gen/ftok.3 @@ -23,8 +23,8 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/ftok.3,v 1.16 2004/07/02 23:52:10 ru Exp $ -.Dd June 24, 1994 +.\" $FreeBSD: src/lib/libc/gen/ftok.3,v 1.17 2009/07/13 12:53:43 trasz Exp $ +.Dd July 9, 2009 .Os .Dt FTOK 3 .Sh NAME @@ -40,7 +40,6 @@ The .Fn ftok function attempts to create a unique key suitable for use with the -.Xr msgget 3 , .Xr semget 2 , and .Xr shmget 2 @@ -72,7 +71,6 @@ is necessary. .Sh SEE ALSO .Xr semget 2 , .Xr shmget 2 , -.Xr msgget 3 , .Xr compat 5 .Sh HISTORY The diff --git a/gen/fts.c b/gen/fts.c index b06ef04..9b85488 100644 --- a/gen/fts.c +++ b/gen/fts.c @@ -134,7 +134,7 @@ __fts_open(argv, sp) { register FTSENT *p, *root; register int nitems; - FTSENT *parent, *tmp; + FTSENT *parent, *tmp = NULL; int len; /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ @@ -456,8 +456,6 @@ fts_read(sp) /* Move to the next node on this level. */ next: tmp = p; if (p = p->fts_link) { - free(tmp); - /* * If reached the top, return to the original directory, and * load the paths for the next root. @@ -468,6 +466,7 @@ next: tmp = p; return (NULL); } fts_load(sp, p); + free(tmp); return (sp->fts_cur = p); } @@ -476,8 +475,10 @@ next: tmp = p; * ignore. If followed, get a file descriptor so we can * get back if necessary. */ - if (p->fts_instr == FTS_SKIP) + if (p->fts_instr == FTS_SKIP) { + free(tmp); goto next; + } if (p->fts_instr == FTS_FOLLOW) { p->fts_info = fts_stat(sp, p, 1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) @@ -490,6 +491,7 @@ next: tmp = p; p->fts_instr = FTS_NOINSTR; } + free(tmp); name: t = sp->fts_path + NAPPEND(p->fts_parent); *t++ = '/'; memmove(t, p->fts_name, p->fts_namelen + 1); @@ -654,7 +656,7 @@ fts_build(sp, type) DIR *dirp; void *adjaddr; int cderrno, descend, len, level, maxlen, dostat, oflag, saved_errno; - char *cp; + char *cp = NULL; /* Set current node pointer. */ cur = sp->fts_cur; diff --git a/gen/get_compat.c b/gen/get_compat.c index e678699..bec0856 100644 --- a/gen/get_compat.c +++ b/gen/get_compat.c @@ -31,7 +31,6 @@ #include #include -static bool def_unix03 = false; /* Catastrophic errors only, including "out of memory" */ static bool parse_error = false; static bool bootstrapping = false; diff --git a/gen/getcap-fbsd.c b/gen/getcap-fbsd.c index ff74872..ea8425f 100644 --- a/gen/getcap-fbsd.c +++ b/gen/getcap-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)getcap.c 8.3 (Berkeley) 3/25/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/getcap.c,v 1.19 2003/01/02 10:19:43 thomas Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/getcap.c,v 1.23 2009/11/25 04:45:45 wollman Exp $"); #include "xlocale_private.h" @@ -195,7 +191,7 @@ getent(char **cap, u_int *len, char **db_array, int fd, const char *name, { DB *capdbp; char *r_end, *rp, **db_p; - int myfd, eof, foundit, retval, clen; + int myfd, eof, foundit, retval; char *record, *cbuf; int tc_not_resolved; char pbuf[_POSIX_PATH_MAX]; @@ -257,14 +253,16 @@ getent(char **cap, u_int *len, char **db_array, int fd, const char *name, return (retval); } /* save the data; close frees it */ - clen = strlen(record); - cbuf = malloc(clen + 1); - memcpy(cbuf, record, clen + 1); + cbuf = strdup(record); if (capdbp->close(capdbp) < 0) { free(cbuf); return (-2); } - *len = clen; + if (cbuf == NULL) { + errno = ENOMEM; + return (-2); + } + *len = strlen(cbuf); *cap = cbuf; return (retval); } else { @@ -651,7 +649,7 @@ int cgetnext(char **bp, char **db_array) { size_t len; - int done, hadreaderr, i, savederrno, status; + int done, hadreaderr, savederrno, status; char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; u_int dummy; locale_t loc = __current_locale(); @@ -663,7 +661,7 @@ cgetnext(char **bp, char **db_array) (void)cgetclose(); return (-1); } - for(;;) { + for (;;) { if (toprec && !gottoprec) { gottoprec = 1; line = toprec; @@ -714,7 +712,6 @@ cgetnext(char **bp, char **db_array) /* * Line points to a name line. */ - i = 0; done = 0; np = nbuf; for (;;) { diff --git a/gen/getcap-fbsd.c.orig b/gen/getcap-fbsd.c.orig new file mode 100644 index 0000000..649a9f4 --- /dev/null +++ b/gen/getcap-fbsd.c.orig @@ -0,0 +1,1055 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Casey Leedom of Lawrence Livermore National Laboratory. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getcap.c 8.3 (Berkeley) 3/25/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/getcap.c,v 1.23 2009/11/25 04:45:45 wollman Exp $"); + +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include + +#define BFRAG 1024 +#define BSIZE 1024 +#define ESC ('[' & 037) /* ASCII ESC */ +#define MAX_RECURSION 32 /* maximum getent recursion */ +#define SFRAG 100 /* cgetstr mallocs in SFRAG chunks */ + +#define RECOK (char)0 +#define TCERR (char)1 +#define SHADOW (char)2 + +static size_t topreclen; /* toprec length */ +static char *toprec; /* Additional record specified by cgetset() */ +static int gottoprec; /* Flag indicating retrieval of toprecord */ + +static int cdbget(DB *, char **, const char *); +static int getent(char **, u_int *, char **, int, const char *, int, char *); +static int nfcmp(char *, char *); + +/* + * Cgetset() allows the addition of a user specified buffer to be added + * to the database array, in effect "pushing" the buffer on top of the + * virtual database. 0 is returned on success, -1 on failure. + */ +int +cgetset(const char *ent) +{ + if (ent == NULL) { + if (toprec) + free(toprec); + toprec = NULL; + topreclen = 0; + return (0); + } + topreclen = strlen(ent); + if ((toprec = malloc (topreclen + 1)) == NULL) { + errno = ENOMEM; + return (-1); + } + gottoprec = 0; + (void)strcpy(toprec, ent); + return (0); +} + +/* + * Cgetcap searches the capability record buf for the capability cap with + * type `type'. A pointer to the value of cap is returned on success, NULL + * if the requested capability couldn't be found. + * + * Specifying a type of ':' means that nothing should follow cap (:cap:). + * In this case a pointer to the terminating ':' or NUL will be returned if + * cap is found. + * + * If (cap, '@') or (cap, terminator, '@') is found before (cap, terminator) + * return NULL. + */ +char * +cgetcap(char *buf, const char *cap, int type) +{ + char *bp; + const char *cp; + + bp = buf; + for (;;) { + /* + * Skip past the current capability field - it's either the + * name field if this is the first time through the loop, or + * the remainder of a field whose name failed to match cap. + */ + for (;;) + if (*bp == '\0') + return (NULL); + else + if (*bp++ == ':') + break; + + /* + * Try to match (cap, type) in buf. + */ + for (cp = cap; *cp == *bp && *bp != '\0'; cp++, bp++) + continue; + if (*cp != '\0') + continue; + if (*bp == '@') + return (NULL); + if (type == ':') { + if (*bp != '\0' && *bp != ':') + continue; + return(bp); + } + if (*bp != type) + continue; + bp++; + return (*bp == '@' ? NULL : bp); + } + /* NOTREACHED */ +} + +/* + * Cgetent extracts the capability record name from the NULL terminated file + * array db_array and returns a pointer to a malloc'd copy of it in buf. + * Buf must be retained through all subsequent calls to cgetcap, cgetnum, + * cgetflag, and cgetstr, but may then be free'd. 0 is returned on success, + * -1 if the requested record couldn't be found, -2 if a system error was + * encountered (couldn't open/read a file, etc.), and -3 if a potential + * reference loop is detected. + */ +int +cgetent(char **buf, char **db_array, const char *name) +{ + u_int dummy; + + return (getent(buf, &dummy, db_array, -1, name, 0, NULL)); +} + +/* + * Getent implements the functions of cgetent. If fd is non-negative, + * *db_array has already been opened and fd is the open file descriptor. We + * do this to save time and avoid using up file descriptors for tc= + * recursions. + * + * Getent returns the same success/failure codes as cgetent. On success, a + * pointer to a malloc'ed capability record with all tc= capabilities fully + * expanded and its length (not including trailing ASCII NUL) are left in + * *cap and *len. + * + * Basic algorithm: + * + Allocate memory incrementally as needed in chunks of size BFRAG + * for capability buffer. + * + Recurse for each tc=name and interpolate result. Stop when all + * names interpolated, a name can't be found, or depth exceeds + * MAX_RECURSION. + */ +static int +getent(char **cap, u_int *len, char **db_array, int fd, const char *name, + int depth, char *nfield) +{ + DB *capdbp; + char *r_end, *rp, **db_p; + int myfd, eof, foundit, retval; + char *record, *cbuf; + int tc_not_resolved; + char pbuf[_POSIX_PATH_MAX]; + + /* + * Return with ``loop detected'' error if we've recursed more than + * MAX_RECURSION times. + */ + if (depth > MAX_RECURSION) + return (-3); + + /* + * Check if we have a top record from cgetset(). + */ + if (depth == 0 && toprec != NULL && cgetmatch(toprec, name) == 0) { + if ((record = malloc (topreclen + BFRAG)) == NULL) { + errno = ENOMEM; + return (-2); + } + (void)strcpy(record, toprec); + myfd = 0; + db_p = db_array; + rp = record + topreclen + 1; + r_end = rp + BFRAG; + goto tc_exp; + } + /* + * Allocate first chunk of memory. + */ + if ((record = malloc(BFRAG)) == NULL) { + errno = ENOMEM; + return (-2); + } + r_end = record + BFRAG; + foundit = 0; + /* + * Loop through database array until finding the record. + */ + + for (db_p = db_array; *db_p != NULL; db_p++) { + eof = 0; + + /* + * Open database if not already open. + */ + + if (fd >= 0) { + (void)lseek(fd, (off_t)0, SEEK_SET); + myfd = 0; + } else { + (void)snprintf(pbuf, sizeof(pbuf), "%s.db", *db_p); + if ((capdbp = dbopen(pbuf, O_RDONLY, 0, DB_HASH, 0)) + != NULL) { + free(record); + retval = cdbget(capdbp, &record, name); + if (retval < 0) { + /* no record available */ + (void)capdbp->close(capdbp); + return (retval); + } + /* save the data; close frees it */ + cbuf = strdup(record); + if (capdbp->close(capdbp) < 0) { + free(cbuf); + return (-2); + } + if (cbuf == NULL) { + errno = ENOMEM; + return (-2); + } + *len = strlen(cbuf); + *cap = cbuf; + return (retval); + } else { + fd = _open(*db_p, O_RDONLY, 0); + if (fd < 0) + continue; + myfd = 1; + } + } + /* + * Find the requested capability record ... + */ + { + char buf[BUFSIZ]; + char *b_end, *bp; + int c; + + /* + * Loop invariants: + * There is always room for one more character in record. + * R_end always points just past end of record. + * Rp always points just past last character in record. + * B_end always points just past last character in buf. + * Bp always points at next character in buf. + */ + b_end = buf; + bp = buf; + for (;;) { + + /* + * Read in a line implementing (\, newline) + * line continuation. + */ + rp = record; + for (;;) { + if (bp >= b_end) { + int n; + + n = _read(fd, buf, sizeof(buf)); + if (n <= 0) { + if (myfd) + (void)_close(fd); + if (n < 0) { + free(record); + return (-2); + } else { + fd = -1; + eof = 1; + break; + } + } + b_end = buf+n; + bp = buf; + } + + c = *bp++; + if (c == '\n') { + if (rp > record && *(rp-1) == '\\') { + rp--; + continue; + } else + break; + } + *rp++ = c; + + /* + * Enforce loop invariant: if no room + * left in record buffer, try to get + * some more. + */ + if (rp >= r_end) { + u_int pos; + size_t newsize; + + pos = rp - record; + newsize = r_end - record + BFRAG; + record = reallocf(record, newsize); + if (record == NULL) { + errno = ENOMEM; + if (myfd) + (void)_close(fd); + return (-2); + } + r_end = record + newsize; + rp = record + pos; + } + } + /* loop invariant let's us do this */ + *rp++ = '\0'; + + /* + * If encountered eof check next file. + */ + if (eof) + break; + + /* + * Toss blank lines and comments. + */ + if (*record == '\0' || *record == '#') + continue; + + /* + * See if this is the record we want ... + */ + if (cgetmatch(record, name) == 0) { + if (nfield == NULL || !nfcmp(nfield, record)) { + foundit = 1; + break; /* found it! */ + } + } + } + } + if (foundit) + break; + } + + if (!foundit) { + free(record); + return (-1); + } + + /* + * Got the capability record, but now we have to expand all tc=name + * references in it ... + */ +tc_exp: { + char *newicap, *s; + int newilen; + u_int ilen; + int diff, iret, tclen; + char *icap, *scan, *tc, *tcstart, *tcend; + + /* + * Loop invariants: + * There is room for one more character in record. + * R_end points just past end of record. + * Rp points just past last character in record. + * Scan points at remainder of record that needs to be + * scanned for tc=name constructs. + */ + scan = record; + tc_not_resolved = 0; + for (;;) { + if ((tc = cgetcap(scan, "tc", '=')) == NULL) + break; + + /* + * Find end of tc=name and stomp on the trailing `:' + * (if present) so we can use it to call ourselves. + */ + s = tc; + for (;;) + if (*s == '\0') + break; + else + if (*s++ == ':') { + *(s - 1) = '\0'; + break; + } + tcstart = tc - 3; + tclen = s - tcstart; + tcend = s; + + iret = getent(&icap, &ilen, db_p, fd, tc, depth+1, + NULL); + newicap = icap; /* Put into a register. */ + newilen = ilen; + if (iret != 0) { + /* an error */ + if (iret < -1) { + if (myfd) + (void)_close(fd); + free(record); + return (iret); + } + if (iret == 1) + tc_not_resolved = 1; + /* couldn't resolve tc */ + if (iret == -1) { + *(s - 1) = ':'; + scan = s - 1; + tc_not_resolved = 1; + continue; + + } + } + /* not interested in name field of tc'ed record */ + s = newicap; + for (;;) + if (*s == '\0') + break; + else + if (*s++ == ':') + break; + newilen -= s - newicap; + newicap = s; + + /* make sure interpolated record is `:'-terminated */ + s += newilen; + if (*(s-1) != ':') { + *s = ':'; /* overwrite NUL with : */ + newilen++; + } + + /* + * Make sure there's enough room to insert the + * new record. + */ + diff = newilen - tclen; + if (diff >= r_end - rp) { + u_int pos, tcpos, tcposend; + size_t newsize; + + pos = rp - record; + newsize = r_end - record + diff + BFRAG; + tcpos = tcstart - record; + tcposend = tcend - record; + record = reallocf(record, newsize); + if (record == NULL) { + errno = ENOMEM; + if (myfd) + (void)_close(fd); + free(icap); + return (-2); + } + r_end = record + newsize; + rp = record + pos; + tcstart = record + tcpos; + tcend = record + tcposend; + } + + /* + * Insert tc'ed record into our record. + */ + s = tcstart + newilen; + bcopy(tcend, s, rp - tcend); + bcopy(newicap, tcstart, newilen); + rp += diff; + free(icap); + + /* + * Start scan on `:' so next cgetcap works properly + * (cgetcap always skips first field). + */ + scan = s-1; + } + + } + /* + * Close file (if we opened it), give back any extra memory, and + * return capability, length and success. + */ + if (myfd) + (void)_close(fd); + *len = rp - record - 1; /* don't count NUL */ + if (r_end > rp) + if ((record = + reallocf(record, (size_t)(rp - record))) == NULL) { + errno = ENOMEM; + return (-2); + } + + *cap = record; + if (tc_not_resolved) + return (1); + return (0); +} + +static int +cdbget(DB *capdbp, char **bp, const char *name) +{ + DBT key, data; + char *namebuf; + + namebuf = strdup(name); + if (namebuf == NULL) + return (-2); + key.data = namebuf; + key.size = strlen(namebuf); + + for (;;) { + /* Get the reference. */ + switch(capdbp->get(capdbp, &key, &data, 0)) { + case -1: + free(namebuf); + return (-2); + case 1: + free(namebuf); + return (-1); + } + + /* If not an index to another record, leave. */ + if (((char *)data.data)[0] != SHADOW) + break; + + key.data = (char *)data.data + 1; + key.size = data.size - 1; + } + + *bp = (char *)data.data + 1; + free(namebuf); + return (((char *)(data.data))[0] == TCERR ? 1 : 0); +} + +/* + * Cgetmatch will return 0 if name is one of the names of the capability + * record buf, -1 if not. + */ +int +cgetmatch(const char *buf, const char *name) +{ + const char *np, *bp; + + if (name == NULL || *name == '\0') + return -1; + + /* + * Start search at beginning of record. + */ + bp = buf; + for (;;) { + /* + * Try to match a record name. + */ + np = name; + for (;;) + if (*np == '\0') + if (*bp == '|' || *bp == ':' || *bp == '\0') + return (0); + else + break; + else + if (*bp++ != *np++) + break; + + /* + * Match failed, skip to next name in record. + */ + bp--; /* a '|' or ':' may have stopped the match */ + for (;;) + if (*bp == '\0' || *bp == ':') + return (-1); /* match failed totally */ + else + if (*bp++ == '|') + break; /* found next name */ + } +} + + + + + +int +cgetfirst(char **buf, char **db_array) +{ + (void)cgetclose(); + return (cgetnext(buf, db_array)); +} + +static FILE *pfp; +static int slash; +static char **dbp; + +int +cgetclose(void) +{ + if (pfp != NULL) { + (void)fclose(pfp); + pfp = NULL; + } + dbp = NULL; + gottoprec = 0; + slash = 0; + return(0); +} + +/* + * Cgetnext() gets either the first or next entry in the logical database + * specified by db_array. It returns 0 upon completion of the database, 1 + * upon returning an entry with more remaining, and -1 if an error occurs. + */ +int +cgetnext(char **bp, char **db_array) +{ + size_t len; + int done, hadreaderr, savederrno, status; + char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; + u_int dummy; + + if (dbp == NULL) + dbp = db_array; + + if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL) { + (void)cgetclose(); + return (-1); + } + for (;;) { + if (toprec && !gottoprec) { + gottoprec = 1; + line = toprec; + } else { + line = fgetln(pfp, &len); + if (line == NULL && pfp) { + hadreaderr = ferror(pfp); + if (hadreaderr) + savederrno = errno; + fclose(pfp); + pfp = NULL; + if (hadreaderr) { + cgetclose(); + errno = savederrno; + return (-1); + } else { + if (*++dbp == NULL) { + (void)cgetclose(); + return (0); + } else if ((pfp = + fopen(*dbp, "r")) == NULL) { + (void)cgetclose(); + return (-1); + } else + continue; + } + } else + line[len - 1] = '\0'; + if (len == 1) { + slash = 0; + continue; + } + if (isspace((unsigned char)*line) || + *line == ':' || *line == '#' || slash) { + if (line[len - 2] == '\\') + slash = 1; + else + slash = 0; + continue; + } + if (line[len - 2] == '\\') + slash = 1; + else + slash = 0; + } + + + /* + * Line points to a name line. + */ + done = 0; + np = nbuf; + for (;;) { + for (cp = line; *cp != '\0'; cp++) { + if (*cp == ':') { + *np++ = ':'; + done = 1; + break; + } + if (*cp == '\\') + break; + *np++ = *cp; + } + if (done) { + *np = '\0'; + break; + } else { /* name field extends beyond the line */ + line = fgetln(pfp, &len); + if (line == NULL && pfp) { + /* Name extends beyond the EOF! */ + hadreaderr = ferror(pfp); + if (hadreaderr) + savederrno = errno; + fclose(pfp); + pfp = NULL; + if (hadreaderr) { + cgetclose(); + errno = savederrno; + return (-1); + } else { + cgetclose(); + return (-1); + } + } else + line[len - 1] = '\0'; + } + } + rp = buf; + for(cp = nbuf; *cp != '\0'; cp++) + if (*cp == '|' || *cp == ':') + break; + else + *rp++ = *cp; + + *rp = '\0'; + /* + * XXX + * Last argument of getent here should be nbuf if we want true + * sequential access in the case of duplicates. + * With NULL, getent will return the first entry found + * rather than the duplicate entry record. This is a + * matter of semantics that should be resolved. + */ + status = getent(bp, &dummy, db_array, -1, buf, 0, NULL); + if (status == -2 || status == -3) + (void)cgetclose(); + + return (status + 1); + } + /* NOTREACHED */ +} + +/* + * Cgetstr retrieves the value of the string capability cap from the + * capability record pointed to by buf. A pointer to a decoded, NUL + * terminated, malloc'd copy of the string is returned in the char * + * pointed to by str. The length of the string not including the trailing + * NUL is returned on success, -1 if the requested string capability + * couldn't be found, -2 if a system error was encountered (storage + * allocation failure). + */ +int +cgetstr(char *buf, const char *cap, char **str) +{ + u_int m_room; + char *bp, *mp; + int len; + char *mem; + + /* + * Find string capability cap + */ + bp = cgetcap(buf, cap, '='); + if (bp == NULL) + return (-1); + + /* + * Conversion / storage allocation loop ... Allocate memory in + * chunks SFRAG in size. + */ + if ((mem = malloc(SFRAG)) == NULL) { + errno = ENOMEM; + return (-2); /* couldn't even allocate the first fragment */ + } + m_room = SFRAG; + mp = mem; + + while (*bp != ':' && *bp != '\0') { + /* + * Loop invariants: + * There is always room for one more character in mem. + * Mp always points just past last character in mem. + * Bp always points at next character in buf. + */ + if (*bp == '^') { + bp++; + if (*bp == ':' || *bp == '\0') + break; /* drop unfinished escape */ + if (*bp == '?') { + *mp++ = '\177'; + bp++; + } else + *mp++ = *bp++ & 037; + } else if (*bp == '\\') { + bp++; + if (*bp == ':' || *bp == '\0') + break; /* drop unfinished escape */ + if ('0' <= *bp && *bp <= '7') { + int n, i; + + n = 0; + i = 3; /* maximum of three octal digits */ + do { + n = n * 8 + (*bp++ - '0'); + } while (--i && '0' <= *bp && *bp <= '7'); + *mp++ = n; + } + else switch (*bp++) { + case 'b': case 'B': + *mp++ = '\b'; + break; + case 't': case 'T': + *mp++ = '\t'; + break; + case 'n': case 'N': + *mp++ = '\n'; + break; + case 'f': case 'F': + *mp++ = '\f'; + break; + case 'r': case 'R': + *mp++ = '\r'; + break; + case 'e': case 'E': + *mp++ = ESC; + break; + case 'c': case 'C': + *mp++ = ':'; + break; + default: + /* + * Catches '\', '^', and + * everything else. + */ + *mp++ = *(bp-1); + break; + } + } else + *mp++ = *bp++; + m_room--; + + /* + * Enforce loop invariant: if no room left in current + * buffer, try to get some more. + */ + if (m_room == 0) { + size_t size = mp - mem; + + if ((mem = reallocf(mem, size + SFRAG)) == NULL) + return (-2); + m_room = SFRAG; + mp = mem + size; + } + } + *mp++ = '\0'; /* loop invariant let's us do this */ + m_room--; + len = mp - mem - 1; + + /* + * Give back any extra memory and return value and success. + */ + if (m_room != 0) + if ((mem = reallocf(mem, (size_t)(mp - mem))) == NULL) + return (-2); + *str = mem; + return (len); +} + +/* + * Cgetustr retrieves the value of the string capability cap from the + * capability record pointed to by buf. The difference between cgetustr() + * and cgetstr() is that cgetustr does not decode escapes but rather treats + * all characters literally. A pointer to a NUL terminated malloc'd + * copy of the string is returned in the char pointed to by str. The + * length of the string not including the trailing NUL is returned on success, + * -1 if the requested string capability couldn't be found, -2 if a system + * error was encountered (storage allocation failure). + */ +int +cgetustr(char *buf, const char *cap, char **str) +{ + u_int m_room; + char *bp, *mp; + int len; + char *mem; + + /* + * Find string capability cap + */ + if ((bp = cgetcap(buf, cap, '=')) == NULL) + return (-1); + + /* + * Conversion / storage allocation loop ... Allocate memory in + * chunks SFRAG in size. + */ + if ((mem = malloc(SFRAG)) == NULL) { + errno = ENOMEM; + return (-2); /* couldn't even allocate the first fragment */ + } + m_room = SFRAG; + mp = mem; + + while (*bp != ':' && *bp != '\0') { + /* + * Loop invariants: + * There is always room for one more character in mem. + * Mp always points just past last character in mem. + * Bp always points at next character in buf. + */ + *mp++ = *bp++; + m_room--; + + /* + * Enforce loop invariant: if no room left in current + * buffer, try to get some more. + */ + if (m_room == 0) { + size_t size = mp - mem; + + if ((mem = reallocf(mem, size + SFRAG)) == NULL) + return (-2); + m_room = SFRAG; + mp = mem + size; + } + } + *mp++ = '\0'; /* loop invariant let's us do this */ + m_room--; + len = mp - mem - 1; + + /* + * Give back any extra memory and return value and success. + */ + if (m_room != 0) + if ((mem = reallocf(mem, (size_t)(mp - mem))) == NULL) + return (-2); + *str = mem; + return (len); +} + +/* + * Cgetnum retrieves the value of the numeric capability cap from the + * capability record pointed to by buf. The numeric value is returned in + * the long pointed to by num. 0 is returned on success, -1 if the requested + * numeric capability couldn't be found. + */ +int +cgetnum(char *buf, const char *cap, long *num) +{ + long n; + int base, digit; + char *bp; + + /* + * Find numeric capability cap + */ + bp = cgetcap(buf, cap, '#'); + if (bp == NULL) + return (-1); + + /* + * Look at value and determine numeric base: + * 0x... or 0X... hexadecimal, + * else 0... octal, + * else decimal. + */ + if (*bp == '0') { + bp++; + if (*bp == 'x' || *bp == 'X') { + bp++; + base = 16; + } else + base = 8; + } else + base = 10; + + /* + * Conversion loop ... + */ + n = 0; + for (;;) { + if ('0' <= *bp && *bp <= '9') + digit = *bp - '0'; + else if ('a' <= *bp && *bp <= 'f') + digit = 10 + *bp - 'a'; + else if ('A' <= *bp && *bp <= 'F') + digit = 10 + *bp - 'A'; + else + break; + + if (digit >= base) + break; + + n = n * base + digit; + bp++; + } + + /* + * Return value and success. + */ + *num = n; + return (0); +} + + +/* + * Compare name field of record. + */ +static int +nfcmp(char *nf, char *rec) +{ + char *cp, tmp; + int ret; + + for (cp = rec; *cp != ':'; cp++) + ; + + tmp = *(cp + 1); + *(cp + 1) = '\0'; + ret = strcmp(nf, rec); + *(cp + 1) = tmp; + + return (ret); +} diff --git a/gen/getcwd-fbsd.c b/gen/getcwd-fbsd.c index d4bee06..512b88c 100644 --- a/gen/getcwd-fbsd.c +++ b/gen/getcwd-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)getcwd.c 8.5 (Berkeley) 2/7/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/getcwd.c,v 1.25 2003/10/29 10:45:01 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/getcwd.c,v 1.29 2007/01/09 00:27:53 imp Exp $"); #include "namespace.h" #include @@ -180,8 +176,8 @@ __private_getcwd(pt, size, usegetpath) *bpt = '\0'; /* - * Allocate bytes MAXPATHLEN) for the string of "../"'s. - * Should always be enough (it's 340 levels). If it's not, allocate + * Allocate MAXPATHLEN bytes for the string of "../"'s. + * Should always be enough. If it's not, allocate * as necessary. Special case the first stat, it's ".", not "..". */ if ((up = malloc(upsize = MAXPATHLEN)) == NULL) @@ -226,7 +222,7 @@ __private_getcwd(pt, size, usegetpath) * as necessary. Max length is 3 for "../", the largest * possible component name, plus a trailing NUL. */ - if (bup + 3 + MAXNAMLEN + 1 >= eup) { + while (bup + 3 + MAXNAMLEN + 1 >= eup) { if ((up = reallocf(up, upsize *= 2)) == NULL) goto err; bup = up; @@ -280,7 +276,7 @@ __private_getcwd(pt, size, usegetpath) * Check for length of the current name, preceding slash, * leading slash. */ - if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { + while (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { size_t len, off; if (!ptsize) { diff --git a/gen/gethostname-fbsd.c b/gen/gethostname-fbsd.c index 16c64b2..031e2c8 100644 --- a/gen/gethostname-fbsd.c +++ b/gen/gethostname-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)gethostname.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/gethostname.c,v 1.5 2003/08/19 23:01:46 wollman Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/gethostname.c,v 1.8 2007/01/09 00:27:54 imp Exp $"); #include #include @@ -43,6 +39,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/gethostname.c,v 1.5 2003/08/19 23:01:46 wol #include #include +#include int gethostname(name, namelen) @@ -51,9 +48,6 @@ gethostname(name, namelen) { int mib[2]; - /* Kluge to avoid ABI breakage. */ - namelen = (int)namelen; - mib[0] = CTL_KERN; mib[1] = KERN_HOSTNAME; if (namelen < MAXHOSTNAMELEN + 1) { diff --git a/gen/gethostname.3 b/gen/gethostname.3 index c02b9b5..eed2346 100644 --- a/gen/gethostname.3 +++ b/gen/gethostname.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)gethostname.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/gethostname.3,v 1.16 2004/07/03 22:30:08 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/gethostname.3,v 1.17 2007/01/09 00:27:54 imp Exp $ .\" .Dd August 18, 2003 .Dt GETHOSTNAME 3 @@ -72,8 +68,8 @@ which has length This call is restricted to the super-user and is normally used only when the system is bootstrapped. .Pp -Host names are limited to -.Brq Dv HOST_NAME_MAX +Host names are limited in length to +.Brq Dv sysconf(_SC_HOST_NAME_MAX) characters, not including the trailing null, currently 255. .Sh RETURN VALUES .Rv -std @@ -105,7 +101,7 @@ The function conforms to .St -p1003.1-2001 . Callers should be aware that -.Brq Dv HOST_NAME_MAX +.Brq Dv sysconf(_SC_HOST_NAME_MAX) may be variable or infinite, but is guaranteed to be no less than .Brq Dv _POSIX_HOST_NAME_MAX . On older systems, this limit was defined in the non-standard header diff --git a/gen/getlastlogx.3 b/gen/getlastlogx.3 index 47ef108..8a70bcf 100644 --- a/gen/getlastlogx.3 +++ b/gen/getlastlogx.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: getlastlogx.3,v 1.1 2003/08/26 17:37:51 wiz Exp $ +.\" $NetBSD: getlastlogx.3,v 1.2 2008/04/30 13:10:50 martin Exp $ .\" .\" Copyright (c) 2003 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -14,13 +14,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED diff --git a/gen/getlastlogx.3.orig b/gen/getlastlogx.3.orig new file mode 100644 index 0000000..cb7404c --- /dev/null +++ b/gen/getlastlogx.3.orig @@ -0,0 +1,173 @@ +.\" $NetBSD: getlastlogx.3,v 1.2 2008/04/30 13:10:50 martin Exp $ +.\" +.\" Copyright (c) 2003 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Thomas Klausner. +.\" +.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +.\" +.Dd August 26, 2003 +.Dt GETLASTLOGX 3 +.Os +.Sh NAME +.Nm getlastlogx , +.Nm getutmp , +.Nm getutmpx , +.Nm updlastlogx , +.Nm updwtmpx , +.Nm utmpxname +.Nd user accounting database functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In utmpx.h +.Ft struct lastlogx * +.Fn getlastlogx "const char *fname" "uid_t uid" "struct lastlogx *ll" +.Ft void +.Fn getutmp "const struct utmpx *ux" "struct utmp *u" +.Ft void +.Fn getutmpx "const struct utmp *u" "struct utmpx *ux" +.Ft int +.Fn updlastlogx "const char *fname" "uid_t uid" "struct lastlogx *ll" +.Ft int +.Fn updwtmpx "const char *file" "const struct utmpx *utx" +.Ft int +.Fn utmpxname "const char *fname" +.Sh DESCRIPTION +The +.Fn getlastlogx +function looks up the entry for the user with user id +.Fa uid +in the +.Xr lastlogx 5 +file given by +.Fa fname +and returns it in +.Fa \&ll . +If the provided +.Fa \&ll +is +.Dv NULL , +the necessary space will be allocated by +.Fn getlastlogx +and should be +.Fn free Ns d +by the caller. +.Pp +The +.Fn getutmp +function fills out the entries in the struct utmp +.Fa u +with the data provided in the struct utmpx +.Fa ux . +.Fn getutmpx +does the opposite, filling out the entries in the struct utmpx +.Fa ux +with the data provided in the struct utmp +.Fa u , +and initializing all the unknown fields to 0. +The sole exception is the +.Fa ut_type +field, which will be initialized to +.Dv USER_PROCESS . +.Pp +The +.Fn updlastlogx +function tries to update the information for the user with the user id +.Fa uid +in the +.Xr lastlogx 5 +file given by +.Fa fname +with the data supplied in +.Fa \&ll . +A +.Ft struct lastlogx +is defined like this: +.Bd -literal +struct lastlogx { + struct timeval ll_tv; /* time entry was created */ + char ll_line[_UTX_LINESIZE]; /* tty name */ + char ll_host[_UTX_HOSTSIZE]; /* host name */ + struct sockaddr_storage ll_ss; /* address where entry was made from */ +}; +.Ed +All the fields should be filled out by the caller. +.Pp +The +.Fn updwtmpx +function updates the +.Xr wtmpx 5 +file +.Fa file +with the +.Xr utmpx 5 +entry +.Fa utx . +.Pp +The +.Fn utmpxname +function sets the default +.Xr utmpx 5 +database file name to +.Fa fname . +.Sh RETURN VALUES +.Fn getlastlogx +returns the found entry on success, or +.Dv NULL +if it could not open the database, could not find an entry matching +.Fa uid +in there, or could not allocate the necessary space (in case +.Fa \&ll +was +.Dv NULL ) . +.Pp +.Fn utmpxname +returns 1 on success, or 0 if the supplied file name was too long or +did not end with +.Sq x . +.Pp +.Fn updlastlogx +and +.Fn updwtmpx +return 0 on success, or \-1 in case the database or file respectively +could not be opened or the data not written into it. +.Sh SEE ALSO +.Xr endutxent 3 , +.Xr loginx 3 , +.Xr utmpx 5 +.Sh HISTORY +The functions +.Fn getutmp , +.Fn getutmpx , +.Fn updwtmpx , +and +.Fn utmpxname +first appeared in +.Tn Solaris . +.Nm getlastlogx +and +.Nm updlastlogx +first appeared in +.Nx 2.0 . diff --git a/gen/getlogin-fbsd.c b/gen/getlogin-fbsd.c index b639fe1..f60de8d 100644 --- a/gen/getlogin-fbsd.c +++ b/gen/getlogin-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)getlogin.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/getlogin.c,v 1.9 2003/10/29 10:45:01 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/getlogin.c,v 1.11 2009/12/05 19:04:21 ed Exp $"); #include #include diff --git a/gen/getmntinfo.3 b/gen/getmntinfo.3 index 19e757b..0c8283b 100644 --- a/gen/getmntinfo.3 +++ b/gen/getmntinfo.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,13 +26,14 @@ .\" SUCH DAMAGE. .\" .\" @(#)getmntinfo.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/getmntinfo.3,v 1.12 2002/12/19 09:40:21 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/getmntinfo.3,v 1.13 2007/01/09 00:27:54 imp Exp $ .\" -.Dd May 15, 2008 +.Dd May 4, 2010 .Dt GETMNTINFO 3 .Os .Sh NAME .Nm getmntinfo +.Nm getmntinfo64 .Nd get information about mounted file systems .Sh SYNOPSIS .In sys/param.h @@ -44,12 +41,10 @@ .In sys/mount.h .Ft int .Fn getmntinfo "struct statfs **mntbufp" "int flags" -#ifdef UNIFDEF_LEGACY_64_APIS .Sh TRANSITIIONAL SYNOPSIS (NOW DEPRECATED) .Ft int .br .Fn getmntinfo64 "struct statfs64 **mntbufp" "int flags" ; -#endif /* UNIFDEF_LEGACY_64_APIS */ .Sh DESCRIPTION The .Fn getmntinfo @@ -58,6 +53,12 @@ returns an array of .Ft statfs structures describing each currently mounted file system (see .Xr statfs 2 ) . +As +.Xr statfs 2 +indicates, the structure is defined differently depending on +whether the macro _DARWIN_FEATURE_64_BIT_INODE is defined (see +.Xr stat 2 +for more information on this macro). .Pp The .Fn getmntinfo @@ -66,33 +67,6 @@ passes its .Fa flags argument transparently to .Xr getfsstat 2 . -#ifdef UNIFDEF_LEGACY_64_APIS -.Pp -Like -.Xr getfsstat 2 , -when the macro -.Dv _DARWIN_FEATURE_64_BIT_INODE -is defined, the -.Ft ino_t -type will be 64-bits (force 64-bit inode mode by defining the -.Dv _DARWIN_USE_64_BIT_INODE -macro before including header files). -This will cause the symbol variant of -.Fn getmntinfo , -with the -.Fa $INODE64 -suffixes, to be automatically linked in. -In addition, the -.Ft statfs -structure will be the 64-bit inode version. -If -.Dv _DARWIN_USE_64_BIT_INODE -is not defined, both -.Fn getmntinfo -and the -.Ft statfs -structure will refer to the 32-bit inode versions. -#endif /* UNIFDEF_LEGACY_64_APIS */ .Sh RETURN VALUES On successful completion, .Fn getmntinfo @@ -117,7 +91,6 @@ routines .Xr getfsstat 2 or .Xr malloc 3 . -#ifdef UNIFDEF_LEGACY_64_APIS .Sh TRANSITIONAL DESCRIPTION (NOW DEPRECATED) The .Fn getmntinfo64 @@ -134,10 +107,10 @@ The structure used by this deprecated routine is the same as the .Ft statfs structure when 64-bit inodes are in effect. -#endif /* UNIFDEF_LEGACY_64_APIS */ .Sh SEE ALSO .Xr getfsstat 2 , .Xr mount 2 , +.Xr stat 2 , .Xr statfs 2 , .Xr mount 8 .Sh HISTORY @@ -148,29 +121,15 @@ function first appeared in .Sh BUGS The .Fn getmntinfo -#ifdef UNIFDEF_LEGACY_64_APIS -and -.Fn getmntinfo64 -functions write the array of structures to an internal static object -#else /* !UNIFDEF_LEGACY_64_APIS */ function writes the array of structures to an internal static object -#endif /* UNIFDEF_LEGACY_64_APIS */ and returns a pointer to that object. Subsequent calls to .Fn getmntinfo -#ifdef UNIFDEF_LEGACY_64_APIS -and -.Fn getmntinfo64 -#endif /* UNIFDEF_LEGACY_64_APIS */ will modify the same object. .Pp The memory allocated by .Fn getmntinfo -#ifdef UNIFDEF_LEGACY_64_APIS -and -.Fn getmntinfo64 -#endif /* UNIFDEF_LEGACY_64_APIS */ cannot be .Xr free 3 Ns 'd by the application. diff --git a/gen/getmntinfo64-fbsd.c b/gen/getmntinfo64-fbsd.c index 48717e1..f4f3a28 100644 --- a/gen/getmntinfo64-fbsd.c +++ b/gen/getmntinfo64-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)getmntinfo.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/getmntinfo.c,v 1.4 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/getmntinfo.c,v 1.5 2007/01/09 00:27:54 imp Exp $"); #include #include diff --git a/gen/getmntinfo64-fbsd.c.orig b/gen/getmntinfo64-fbsd.c.orig new file mode 100644 index 0000000..24b7886 --- /dev/null +++ b/gen/getmntinfo64-fbsd.c.orig @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getmntinfo.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/getmntinfo.c,v 1.5 2007/01/09 00:27:54 imp Exp $"); + +#include +#include +#include +#include + +/* + * Return information about mounted filesystems. + */ +int +getmntinfo(mntbufp, flags) + struct statfs **mntbufp; + int flags; +{ + static struct statfs *mntbuf; + static int mntsize; + static long bufsize; + + if (mntsize <= 0 && (mntsize = getfsstat(0, 0, MNT_NOWAIT)) < 0) + return (0); + if (bufsize > 0 && (mntsize = getfsstat(mntbuf, bufsize, flags)) < 0) + return (0); + while (bufsize <= mntsize * sizeof(struct statfs)) { + if (mntbuf) + free(mntbuf); + bufsize = (mntsize + 1) * sizeof(struct statfs); + if ((mntbuf = (struct statfs *)malloc(bufsize)) == 0) + return (0); + if ((mntsize = getfsstat(mntbuf, bufsize, flags)) < 0) + return (0); + } + *mntbufp = mntbuf; + return (mntsize); +} diff --git a/gen/isatty-fbsd.c b/gen/isatty-fbsd.c index 3610804..54a0fa0 100644 --- a/gen/isatty-fbsd.c +++ b/gen/isatty-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)isatty.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/isatty.c,v 1.5 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/isatty.c,v 1.6 2007/01/09 00:27:54 imp Exp $"); #include #include diff --git a/gen/lockf-fbsd.c b/gen/lockf-fbsd.c index daa89df..bc8de89 100644 --- a/gen/lockf-fbsd.c +++ b/gen/lockf-fbsd.c @@ -1,3 +1,4 @@ +/* $NetBSD: lockf.c,v 1.3 2008/04/28 20:22:59 martin Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. * All rights reserved. @@ -13,13 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -34,9 +28,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* $NetBSD: lockf.c,v 1.1 1997/12/20 20:23:18 kleink Exp $ */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/lockf.c,v 1.8 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/lockf.c,v 1.10 2009/03/04 01:01:26 delphij Exp $"); #ifdef VARIANT_CANCELABLE int __fcntl(int, int, void *); @@ -52,15 +45,11 @@ int __fcntl_nocancel(int, int, void *); #include "un-namespace.h" int -lockf(filedes, function, size) - int filedes; - int function; - off_t size; +lockf(int filedes, int function, off_t size) { struct flock fl; int cmd; - fl.l_start = 0; fl.l_len = size; fl.l_whence = SEEK_CUR; @@ -99,9 +88,9 @@ lockf(filedes, function, size) } #ifdef VARIANT_CANCELABLE - return (__fcntl(filedes, cmd, &fl)); + return (__fcntl(filedes, cmd, &fl)); #else /* !VARIANT_CANCELABLE */ - return (__fcntl_nocancel(filedes, cmd, &fl)); + return (__fcntl_nocancel(filedes, cmd, &fl)); #endif /* VARIANT_CANCELABLE */ } diff --git a/gen/lockf.3 b/gen/lockf.3 index f4cecd1..fc48307 100644 --- a/gen/lockf.3 +++ b/gen/lockf.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: lockf.3,v 1.2 1998/02/05 18:47:28 perry Exp $ +.\" $NetBSD: lockf.3,v 1.10 2008/04/30 13:10:50 martin Exp $ .\" .\" Copyright (c) 1997 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -14,13 +14,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -34,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/lockf.3,v 1.13 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/lockf.3,v 1.14 2009/03/04 01:01:26 delphij Exp $ .\" .Dd December 19, 1997 .Dt LOCKF 3 diff --git a/gen/magazine_malloc.c b/gen/magazine_malloc.c index a713e70..e6b6998 100644 --- a/gen/magazine_malloc.c +++ b/gen/magazine_malloc.c @@ -53,9 +53,25 @@ #include #include #include +#include + +#if defined(__i386__) || defined(__x86_64__) +#define __APPLE_API_PRIVATE +#include +#define _COMM_PAGE_VERSION_REQD 9 +#undef __APPLE_API_PRIVATE +#else #include +#endif + #include -#include /* for NSVersionOfLinkTimeLibrary() */ +#include /* for NSVersionOfLinkTimeLibrary() */ +#include /* for _dyld_get_image_slide() */ +#include /* for _NSGetMachExecuteHeader() */ +#include +#include + +#include /********************* DEFINITIONS ************************/ @@ -92,6 +108,10 @@ do { \ #define CACHE_ALIGN #endif +#if !__LP64__ +#define ASLR_INTERNAL 1 +#endif + /* * Access to global variables is slow, so optimise our handling of vm_page_size * and vm_page_shift. @@ -123,6 +143,7 @@ typedef unsigned int grain_t; // N.B. wide enough to index all free slots typedef int mag_index_t; #define CHECK_REGIONS (1 << 31) +#define DISABLE_ASLR (1 << 30) #define MAX_RECORDER_BUFFER 256 @@ -191,6 +212,17 @@ typedef int mag_index_t; #define NUM_TINY_CEIL_BLOCKS (1 << SHIFT_TINY_CEIL_BLOCKS) #define TINY_BLOCKS_ALIGN (SHIFT_TINY_CEIL_BLOCKS + SHIFT_TINY_QUANTUM) // 20 +#define TINY_ENTROPY_BITS 15 +#define TINY_ENTROPY_MASK ((1 << TINY_ENTROPY_BITS) - 1) + +/* + * Avoid having so much entropy that the end of a valid tiny allocation + * might overrun the end of the tiny region. + */ +#if TINY_ENTROPY_MASK + NUM_TINY_SLOTS > NUM_TINY_BLOCKS +#error Too many entropy bits for tiny region requested +#endif + /* * Enough room for the data, followed by the bit arrays (2-bits per block) * plus rounding to the nearest page. @@ -243,6 +275,7 @@ typedef struct region_trailer struct region_trailer *next; boolean_t recirc_suitable; boolean_t failedREUSE; + volatile int pinned_to_depot; unsigned bytes_used; mag_index_t mag_index; } region_trailer_t; @@ -345,6 +378,17 @@ typedef struct tiny_region #define NUM_SMALL_CEIL_BLOCKS (1 << SHIFT_SMALL_CEIL_BLOCKS) #define SMALL_BLOCKS_ALIGN (SHIFT_SMALL_CEIL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23 +#define SMALL_ENTROPY_BITS 13 +#define SMALL_ENTROPY_MASK ((1 << SMALL_ENTROPY_BITS) - 1) + +/* + * Avoid having so much entropy that the end of a valid small allocation + * might overrun the end of the small region. + */ +#if SMALL_ENTROPY_MASK + NUM_SMALL_SLOTS > NUM_SMALL_BLOCKS +#error Too many entropy bits for small region requested +#endif + #define SMALL_METADATA_SIZE (sizeof(region_trailer_t) + NUM_SMALL_BLOCKS * sizeof(msize_t)) #define SMALL_REGION_SIZE \ ((NUM_SMALL_BLOCKS * SMALL_QUANTUM + SMALL_METADATA_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1)) @@ -418,8 +462,6 @@ typedef struct small_region */ #define SMALL_PTR_SIZE(_p) (*SMALL_METADATA_FOR_PTR(_p) & ~SMALL_IS_FREE) -#define PROTECT_SMALL 0 // Should be 0: 1 is too slow for normal use - #define SMALL_CACHE 1 #if !SMALL_CACHE #warning SMALL_CACHE turned off @@ -473,6 +515,9 @@ typedef struct { #endif #define LARGE_CACHE_SIZE_ENTRY_LIMIT (LARGE_CACHE_SIZE_LIMIT/LARGE_ENTRY_CACHE_SIZE) +#define SZONE_FLOTSAM_THRESHOLD_LOW (1024 * 512) +#define SZONE_FLOTSAM_THRESHOLD_HIGH (1024 * 1024) + /******************************************************************************* * Definitions for region hash ******************************************************************************/ @@ -500,6 +545,8 @@ typedef struct region_hash_generation { typedef struct { // vm_allocate()'d, so the array of magazines is page-aligned to begin with. // Take magazine_lock first, Depot lock when needed for recirc, then szone->{tiny,small}_regions_lock when needed for alloc pthread_lock_t magazine_lock CACHE_ALIGN; + // Protection for the crtical section that does allocate_pages outside the magazine_lock + volatile boolean_t alloc_underway; // One element deep "death row", optimizes malloc/free/malloc for identical size. void *mag_last_free; // low SHIFT_{TINY,SMALL}_QUANTUM bits indicate the msize @@ -508,9 +555,10 @@ typedef struct { // vm_allocate()'d, so the array of magazines is page-aligned free_list_t *mag_free_list[256]; // assert( 256 >= MAX( NUM_TINY_SLOTS, NUM_SMALL_SLOTS_LARGEMEM )) unsigned mag_bitmap[8]; // assert( sizeof(mag_bitmap) << 3 >= sizeof(mag_free_list)/sizeof(free_list_t) ) - // the last free region in the last block is treated as a big block in use that is not accounted for + // the first and last free region in the last block are treated as big blocks in use that are not accounted for size_t mag_bytes_free_at_end; - region_t mag_last_region; // Valid iff mag_bytes_free_at_end > 0 + size_t mag_bytes_free_at_start; + region_t mag_last_region; // Valid iff mag_bytes_free_at_end || mag_bytes_free_at_start > 0 // bean counting ... unsigned mag_num_objects; @@ -525,9 +573,9 @@ typedef struct { // vm_allocate()'d, so the array of magazines is page-aligned region_trailer_t *lastNode; #if __LP64__ - uint64_t pad[49]; // So sizeof(magazine_t) is 2560 bytes. FIXME: assert this at compile time + uint64_t pad[48]; // So sizeof(magazine_t) is 2560 bytes. FIXME: assert this at compile time #else - uint32_t pad[45]; // So sizeof(magazine_t) is 1280 bytes. FIXME: assert this at compile time + uint32_t pad[12]; // So sizeof(magazine_t) is 1280 bytes. FIXME: assert this at compile time #endif } magazine_t; @@ -552,8 +600,10 @@ typedef struct { // vm_allocate()'d, so the array of magazines is page-aligned */ typedef struct szone_s { // vm_allocate()'d, so page-aligned to begin with. - malloc_zone_t basic_zone; - pthread_key_t cpu_id_key; + malloc_zone_t basic_zone; // first page will be given read-only protection + uint8_t pad[vm_page_size - sizeof(malloc_zone_t)]; + + pthread_key_t cpu_id_key; // remainder of structure is R/W (contains no function pointers) unsigned debug_flags; void *log_address; @@ -603,8 +653,9 @@ typedef struct szone_s { // vm_allocate()'d, so page-aligned to begin with. int large_entry_cache_newest; large_entry_t large_entry_cache[LARGE_ENTRY_CACHE_SIZE]; // "death row" for large malloc/free boolean_t large_legacy_reset_mprotect; - size_t large_entry_cache_hoard_bytes; - size_t large_entry_cache_hoard_lmit; + size_t large_entry_cache_reserve_bytes; + size_t large_entry_cache_reserve_limit; + size_t large_entry_cache_bytes; // total size of death row, bytes #endif /* flag and limits pertaining to altered malloc behavior for systems with @@ -623,6 +674,8 @@ typedef struct szone_s { // vm_allocate()'d, so page-aligned to begin with. /* The purgeable zone constructed by create_purgeable_zone() would like to hand off tiny and small * allocations to the default scalable zone. Record the latter as the "helper" zone here. */ struct szone_s *helper_zone; + + boolean_t flotsam_enabled; } szone_t; #define SZONE_PAGED_SIZE ((sizeof(szone_t) + vm_page_size - 1) & ~ (vm_page_size - 1)) @@ -639,6 +692,8 @@ static NOINLINE void szone_error(szone_t *szone, int is_corruption, const char * static void protect(void *address, size_t size, unsigned protection, unsigned debug_flags); static void *allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label); +static void *allocate_pages_securely(szone_t *szone, size_t size, unsigned char align, + int vm_page_label); static void deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags); #if TARGET_OS_EMBEDDED static int madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi, uintptr_t *last); @@ -689,15 +744,15 @@ static void tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr); static int tiny_free_detach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r); static size_t tiny_free_reattach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r); static void tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r); -static void tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node); -static void tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index); -static region_t tiny_find_msize_region(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize); +static region_t tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node); +static boolean_t tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index); +static region_t tiny_find_msize_region(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize); static boolean_t tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize); -static INLINE void tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region, +static INLINE boolean_t tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, msize_t msize) ALWAYSINLINE; static void *tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, - msize_t msize); + msize_t msize, void *fresh_region); static boolean_t tiny_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size); static boolean_t tiny_check_region(szone_t *szone, region_t region); static kern_return_t tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, @@ -707,7 +762,7 @@ static void *tiny_malloc_from_free_list(szone_t *szone, magazine_t *tiny_mag_pt static INLINE void *tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE; static INLINE void free_tiny(szone_t *szone, void *ptr, region_t tiny_region, size_t known_size) ALWAYSINLINE; static void print_tiny_free_list(szone_t *szone); -static void print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_end); +static void print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end); static boolean_t tiny_free_list_check(szone_t *szone, grain_t slot); static INLINE void small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize) ALWAYSINLINE; @@ -720,15 +775,15 @@ static INLINE region_t small_region_for_ptr_no_lock(szone_t *szone, const void * static void small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr); static int small_free_detach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r); static size_t small_free_reattach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r); -static void small_free_scan_depot_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r); -static void small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node); -static void small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index); -static region_t small_find_msize_region(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize); +static void small_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r); +static region_t small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node); +static boolean_t small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index); +static region_t small_find_msize_region(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize); static boolean_t small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize); -static INLINE void small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, region_t region, +static INLINE boolean_t small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, msize_t msize) ALWAYSINLINE; static void *small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, - msize_t msize); + msize_t msize, void *fresh_region); static boolean_t small_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size); static boolean_t small_check_region(szone_t *szone, region_t region); static kern_return_t small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, @@ -738,7 +793,7 @@ static void *small_malloc_from_free_list(szone_t *szone, magazine_t *small_mag_ static INLINE void *small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE; static INLINE void free_small(szone_t *szone, void *ptr, region_t small_region, size_t known_size) ALWAYSINLINE; static void print_small_free_list(szone_t *szone); -static void print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_end); +static void print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end); static boolean_t small_free_list_check(szone_t *szone, grain_t grain); #if DEBUG_MALLOC @@ -754,7 +809,8 @@ static large_entry_t *large_entries_grow_no_lock(szone_t *szone, vm_range_t *ran static vm_range_t large_entry_free_no_lock(szone_t *szone, large_entry_t *entry); static NOINLINE kern_return_t large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address, - unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder); + unsigned num_entries, memory_reader_t reader, + vm_range_recorder_t recorder); static void *large_malloc(szone_t *szone, size_t num_pages, unsigned char alignment, boolean_t cleared_requested); static NOINLINE void free_large(szone_t *szone, void *ptr); static INLINE int large_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE; @@ -822,6 +878,12 @@ static void *frozen_realloc(szone_t *zone, void *ptr, size_t new_size); static void frozen_free(szone_t *zone, void *ptr); static void frozen_destroy(szone_t *zone); +static volatile uintptr_t entropic_address = 0; +static volatile uintptr_t entropic_limit = 0; +#define ENTROPIC_KABILLION 0x10000000 /* 256Mb */ + +__private_extern__ uint64_t malloc_entropy[2]; + #define SZONE_LOCK(szone) \ do { \ LOCK(szone->large_szone_lock); \ @@ -879,8 +941,6 @@ szone_sleep(void) } #endif -extern const char *__crashreporter_info__; - // msg prints after fmt, ... static NOINLINE void szone_error(szone_t *szone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...) @@ -931,7 +991,7 @@ szone_error(szone_t *szone, int is_corruption, const char *msg, const void *ptr, // corruption flag is set, or if any error should abort. if ((is_corruption && (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_CORRUPTION)) || (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_ERROR)) { - __crashreporter_info__ = b ? _simple_string(b) : msg; + CRSetCrashLogMessage(b ? _simple_string(b) : msg); abort(); } else if (b) { _simple_sfree(b); @@ -944,14 +1004,14 @@ protect(void *address, size_t size, unsigned protection, unsigned debug_flags) kern_return_t err; if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_PRELUDE)) { - err = vm_protect(mach_task_self(), (vm_address_t)(uintptr_t)address - vm_page_size, vm_page_size, 0, protection); + err = mprotect((void *)((uintptr_t)address - vm_page_size), vm_page_size, protection); if (err) { malloc_printf("*** can't protect(%p) region for prelude guard page at %p\n", protection,(uintptr_t)address - (1 << vm_page_shift)); } } if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE)) { - err = vm_protect(mach_task_self(), (vm_address_t)(uintptr_t)address + size, vm_page_size, 0, protection); + err = mprotect((void *)((uintptr_t)address + size), vm_page_size, protection); if (err) { malloc_printf("*** can't protect(%p) region for postlude guard page at %p\n", protection, (uintptr_t)address + size); @@ -969,18 +1029,23 @@ allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_ boolean_t purgeable = debug_flags & SCALABLE_MALLOC_PURGEABLE; size_t allocation_size = round_page(size); size_t delta; - int flags = VM_MAKE_TAG(vm_page_label); + int alloc_flags = VM_MAKE_TAG(vm_page_label); if (align) add_guard_pages = 0; // too cumbersome to deal with that if (!allocation_size) allocation_size = 1 << vm_page_shift; if (add_guard_pages) allocation_size += 2 * (1 << vm_page_shift); if (align) allocation_size += (size_t)1 << align; - if (purgeable) flags |= VM_FLAGS_PURGABLE; + if (purgeable) alloc_flags |= VM_FLAGS_PURGABLE; if (allocation_size < size) // size_t arithmetic wrapped! return NULL; - vm_addr = mmap(0, allocation_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, flags, 0); + vm_addr = mmap(0 /* addr */, + allocation_size /* size */, + PROT_READ | PROT_WRITE /* prot */, + MAP_ANON | MAP_PRIVATE /* flags */, + alloc_flags /* fd being used to pass "purgeable" and "vm_page_label" */, + 0 /* offset */); if ((uintptr_t)vm_addr == -1) { szone_error(szone, 0, "can't allocate region", NULL, "*** mmap(size=%lu) failed (error code=%d)\n", allocation_size, errno); @@ -1004,7 +1069,78 @@ allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_ } if (add_guard_pages) { addr += (uintptr_t)1 << vm_page_shift; - protect((void *)addr, size, 0, debug_flags); + protect((void *)addr, size, PROT_NONE, debug_flags); + } + return (void *)addr; +} + +static void * +allocate_pages_securely(szone_t *szone, size_t size, unsigned char align, int vm_page_label) +{ + // align specifies a desired alignment (as a log) or 0 if no alignment requested + void *vm_addr; + uintptr_t addr, aligned_address; + size_t delta, allocation_size = MAX(round_page(size), vm_page_size); + int alloc_flags = VM_MAKE_TAG(vm_page_label); + + if (szone->debug_flags & DISABLE_ASLR) + return allocate_pages(szone, size, align, 0, vm_page_label); + + if (align) + allocation_size += (size_t)1 << align; + + if (allocation_size < size) // size_t arithmetic wrapped! + return NULL; + +retry: + vm_addr = mmap((void *)entropic_address /* kernel finds next available range at or above this address */, + allocation_size /* size */, + PROT_READ | PROT_WRITE /* prot */, + MAP_ANON | MAP_PRIVATE /* flags */, + alloc_flags /* fd being used to pass "vm_page_label" */, + 0 /* offset */); + if (MAP_FAILED == vm_addr) { + szone_error(szone, 0, "can't allocate region securely", NULL, "*** mmap(size=%lu) failed (error code=%d)\n", + size, errno); + return NULL; + } + addr = (uintptr_t)vm_addr; + + // Don't allow allocation to rise above entropic_limit (for tidiness). + if (addr + allocation_size > entropic_limit) { // Exhausted current range? + uintptr_t t = entropic_address; + uintptr_t u = t - ENTROPIC_KABILLION; + + if (u < t) { // provided we don't wrap, unmap and retry, in the expanded entropic range + munmap((void *)addr, allocation_size); + (void)__sync_bool_compare_and_swap(&entropic_address, t, u); // Just one reduction please + goto retry; + } + // fall through to use what we got + } + + if (addr < entropic_address) { // mmap wrapped to find this allocation, expand the entropic range + uintptr_t t = entropic_address; + uintptr_t u = t - ENTROPIC_KABILLION; + if (u < t) + (void)__sync_bool_compare_and_swap(&entropic_address, t, u); // Just one reduction please + // fall through to use what we got + } + + // unmap any excess address range used for alignment padding + if (align) { + aligned_address = (addr + ((uintptr_t)1 << align) - 1) & ~ (((uintptr_t)1 << align) - 1); + if (aligned_address != addr) { + delta = aligned_address - addr; + if (munmap((void *)addr, delta) == -1) + malloc_printf("*** munmap unaligned header failed with %d\n", errno); + addr = aligned_address; + allocation_size -= delta; + } + if (allocation_size > size) { + if (munmap((void *)(addr + size), allocation_size - size) == -1) + malloc_printf("*** munmap unaligned footer failed with %d\n", errno); + } } return (void *)addr; } @@ -1056,7 +1192,8 @@ madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi) #endif /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ #if DEBUG_MADVISE - szone_error(szone, 0, "madvise_free_range madvise(..., MADV_FREE_REUSABLE) failed", (void *)pgLo, "length=%d\n", len); + szone_error(szone, 0, "madvise_free_range madvise(..., MADV_FREE_REUSABLE) failed", + (void *)pgLo, "length=%d\n", len); #endif } } @@ -1081,17 +1218,11 @@ _szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void ** ((((uintptr_t)pthread_self()) >> vm_page_shift) * 2654435761UL) >> (32 - szone->num_tiny_magazines_mask_shift) #endif -#if defined(__i386__) || defined(__x86_64__) -#define __APPLE_API_PRIVATE -#include -#define _COMM_PAGE_VERSION_REQD 9 -#undef __APPLE_API_PRIVATE - +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) /* * These commpage routines provide fast access to the logical cpu number * of the calling processor assuming no pre-emption occurs. */ -#define CPU_NUMBER() (((int (*)()) _COMM_PAGE_CPU_NUMBER)()) /* Zero-based */ static INLINE mag_index_t mag_get_thread_index(szone_t *szone) @@ -1099,15 +1230,7 @@ mag_get_thread_index(szone_t *szone) if (!__is_threaded) return 0; else - return CPU_NUMBER() & (TINY_MAX_MAGAZINES - 1); -} - -#elif defined(__arm__) - -static INLINE mag_index_t -mag_get_thread_index(szone_t *szone) -{ - return 0; + return cpu_number() & (TINY_MAX_MAGAZINES - 1); } #else @@ -1288,7 +1411,7 @@ hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, si // at least 4 trailing zero bits. // // When an entry is added to the free list, a checksum of the previous and next -// pointers is calculated and written to the low four bits of the respective +// pointers is calculated and written to the high four bits of the respective // pointers. Upon detection of an invalid checksum, an error is logged and NULL // is returned. Since all code which un-checksums pointers checks for a NULL // return, a potentially crashing or malicious dereference is avoided at the @@ -1320,20 +1443,30 @@ static INLINE uintptr_t free_list_gen_checksum(uintptr_t ptr) return chk & (uintptr_t)0xF; } +#define NYBBLE 4 +#if __LP64__ +#define ANTI_NYBBLE (64 - NYBBLE) +#else +#define ANTI_NYBBLE (32 - NYBBLE) +#endif + static INLINE uintptr_t free_list_checksum_ptr(szone_t *szone, void *ptr) { uintptr_t p = (uintptr_t)ptr; - return p | free_list_gen_checksum(p ^ szone->cookie); + return (p >> NYBBLE) | (free_list_gen_checksum(p ^ szone->cookie) << ANTI_NYBBLE); // compiles to rotate instruction } static INLINE void * free_list_unchecksum_ptr(szone_t *szone, ptr_union *ptr) { ptr_union p; - p.u = (ptr->u >> 4) << 4; - - if ((ptr->u & (uintptr_t)0xF) != free_list_gen_checksum(p.u ^ szone->cookie)) + uintptr_t t = ptr->u; + + t = (t << NYBBLE) | (t >> ANTI_NYBBLE); // compiles to rotate instruction + p.u = t & ~(uintptr_t)0xF; + + if ((t & (uintptr_t)0xF) != free_list_gen_checksum(p.u ^ szone->cookie)) { free_list_checksum_botch(szone, (free_list_t *)ptr); return NULL; @@ -1341,6 +1474,9 @@ free_list_unchecksum_ptr(szone_t *szone, ptr_union *ptr) return p.p; } +#undef ANTI_NYBBLE +#undef NYBBLE + static unsigned free_list_count(szone_t *szone, free_list_t *ptr) { @@ -1880,6 +2016,18 @@ tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr) { uint32_t *last_header; msize_t last_msize, previous_msize, last_index; + // It is possible that the block prior to the last block in the region has + // been free'd, but was not coalesced with the free bytes at the end of the + // block, since we treat the bytes at the end of the region as "in use" in + // the meta headers. Attempt to coalesce the last block with the previous + // block, so we don't violate the "no consecutive free blocks" invariant. + // + // FIXME: Need to investigate how much work would be required to increase + // 'mag_bytes_free_at_end' when freeing the preceding block, rather + // than performing this workaround. + // + + if (tiny_mag_ptr->mag_bytes_free_at_end) { last_block = (void *) ((uintptr_t)TINY_REGION_END(tiny_mag_ptr->mag_last_region) - tiny_mag_ptr->mag_bytes_free_at_end); last_msize = TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_end); @@ -1899,16 +2047,6 @@ tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr) { if (last_index != (NUM_TINY_BLOCKS - 1)) BITARRAY_CLR(last_header, (last_index + 1)); - // It is possible that the block prior to the last block in the region has - // been free'd, but was not coalesced with the free bytes at the end of the - // block, since we treat the bytes at the end of the region as "in use" in - // the meta headers. Attempt to coalesce the last block with the previous - // block, so we don't violate the "no consecutive free blocks" invariant. - // - // FIXME: Need to investigate how much work would be required to increase - // 'mag_bytes_free_at_end' when freeing the preceding block, rather - // than performing this workaround. - // previous_block = tiny_previous_preceding_free(last_block, &previous_msize); if (previous_block) { set_tiny_meta_header_middle(last_block); @@ -1920,6 +2058,33 @@ tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr) { // splice last_block into the free list tiny_free_list_add_ptr(szone, tiny_mag_ptr, last_block, last_msize); tiny_mag_ptr->mag_bytes_free_at_end = 0; + } + +#if ASLR_INTERNAL + // Coalesce the big free block at start with any following free blocks + if (tiny_mag_ptr->mag_bytes_free_at_start) { + last_block = TINY_REGION_ADDRESS(tiny_mag_ptr->mag_last_region); + last_msize = TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_start); + + void *next_block = (void *) ((uintptr_t)last_block + tiny_mag_ptr->mag_bytes_free_at_start); + + // clear the in use bit we were using to mark the end of the big start block + set_tiny_meta_header_middle((uintptr_t)next_block - TINY_QUANTUM); + + // Coalesce the big start block with any following free blocks + if (tiny_meta_header_is_free(next_block)) { + msize_t next_msize = get_tiny_free_size(next_block); + set_tiny_meta_header_middle(next_block); + tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize); + last_msize += next_msize; + } + + // splice last_block into the free list + tiny_free_list_add_ptr(szone, tiny_mag_ptr, last_block, last_msize); + tiny_mag_ptr->mag_bytes_free_at_start = 0; + } +#endif + tiny_mag_ptr->mag_last_region = NULL; } @@ -1987,14 +2152,19 @@ tiny_free_reattach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r) return total_alloc; } -static void +typedef struct { + uint8_t pnum, size; +} tiny_pg_pair_t; + +static void NOINLINE /* want private stack frame for automatic array */ tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) { uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r); uintptr_t current = start; uintptr_t limit = (uintptr_t)TINY_REGION_END(r); boolean_t is_free; msize_t msize; - boolean_t did_advise = FALSE; + tiny_pg_pair_t advisory[((TINY_REGION_PAYLOAD_BYTES + vm_page_size - 1) >> vm_page_shift) >> 1]; // 256bytes stack allocated + int advisories = 0; // Scan the metadata identifying blocks which span one or more pages. Mark the pages MADV_FREE taking care to preserve free list // management data. @@ -2010,12 +2180,9 @@ tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) { uintptr_t pgHi = trunc_page(start + TINY_REGION_SIZE - sizeof(msize_t)); if (pgLo < pgHi) { -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, r, pgLo, pgHi, NULL); -#else - madvise_free_range(szone, r, pgLo, pgHi); -#endif - did_advise = TRUE; + advisory[advisories].pnum = (pgLo - start) >> vm_page_shift; + advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift; + advisories++; } break; } @@ -2031,32 +2198,48 @@ tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) { uintptr_t pgHi = trunc_page(current + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); if (pgLo < pgHi) { -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, r, pgLo, pgHi, NULL); -#else - madvise_free_range(szone, r, pgLo, pgHi); -#endif - did_advise = TRUE; + advisory[advisories].pnum = (pgLo - start) >> vm_page_shift; + advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift; + advisories++; } } current += TINY_BYTES_FOR_MSIZE(msize); } - if (did_advise) { - /* Move the node to the tail of the Deopt's recirculation list to delay its re-use. */ - region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(r); - recirc_list_extract(szone, depot_ptr, node); // excise node from list - recirc_list_splice_last(szone, depot_ptr, node); // connect to magazine as last node + if (advisories > 0) { + int i; + + // So long as the following hold for this region: + // (1) No malloc()'s are ever performed from the depot (hence free pages remain free,) + // (2) The region is not handed over to a per-CPU magazine (where malloc()'s could be performed), + // (3) The entire region is not mumap()'d (so the madvise's are applied to the intended addresses), + // then the madvise opportunities collected just above can be applied outside all locks. + // (1) is ensured by design, (2) and (3) are ensured by bumping the globally visible counter node->pinned_to_depot. + + OSAtomicIncrement32Barrier(&(REGION_TRAILER_FOR_TINY_REGION(r)->pinned_to_depot)); + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + for (i = 0; i < advisories; ++i) { + uintptr_t addr = (advisory[i].pnum << vm_page_shift) + start; + size_t size = advisory[i].size << vm_page_shift; + +#if TARGET_OS_EMBEDDED + madvise_free_range(szone, r, addr, addr + size, NULL); +#else + madvise_free_range(szone, r, addr, addr + size); +#endif + } + SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); + OSAtomicDecrement32Barrier(&(REGION_TRAILER_FOR_TINY_REGION(r)->pinned_to_depot)); } } -static void +static region_t tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node) { -#warning Tune Depot headroom if (0 < node->bytes_used || + 0 < node->pinned_to_depot || depot_ptr->recirculation_entries < (szone->num_tiny_magazines * 2)) { - return; + return NULL; } // disconnect node from Depot @@ -2072,31 +2255,24 @@ tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_ rgnhdl_t pSlot = hash_lookup_region_no_lock(szone->tiny_region_generation->hashed_regions, szone->tiny_region_generation->num_regions_allocated, szone->tiny_region_generation->num_regions_allocated_shift, sparse_region); + if (NULL == pSlot) { + szone_error(szone, 1, "tiny_free_try_depot_unmap_no_lock hash lookup failed:", NULL, "%p\n", sparse_region); + return NULL; + } *pSlot = HASHRING_REGION_DEALLOCATED; depot_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; -#if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1))) /* GCC 4.1 and forward supports atomic builtins */ __sync_fetch_and_add( &(szone->num_tiny_regions_dealloc), 1); // Atomically increment num_tiny_regions_dealloc -#else -#ifdef __LP64__ - OSAtomicIncrement64( (volatile int64_t *)&(szone->num_tiny_regions_dealloc) ); -#else - OSAtomicIncrement32( (volatile int32_t *)&(szone->num_tiny_regions_dealloc) ); -#endif -#endif - - // Transfer ownership of the region back to the OS - SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); // Avoid denial of service to Depot while in kernel - deallocate_pages(szone, sparse_region, TINY_REGION_SIZE, 0); - SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); - - MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region); // DTrace USDT Probe + // Caller will transfer ownership of the region back to the OS with no locks held + MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region, TINY_REGION_SIZE); // DTrace USDT Probe + return sparse_region; } else { szone_error(szone, 1, "tiny_free_try_depot_unmap_no_lock objects_in_use not zero:", NULL, "%d\n", objects_in_use); + return NULL; } } -static void +static boolean_t tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index) { // The entire magazine crossed the "emptiness threshold". Transfer a region @@ -2112,13 +2288,13 @@ tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index #if DEBUG_MALLOC malloc_printf("*** tiny_free_do_recirc_to_depot end of list\n"); #endif - return; + return TRUE; // Caller must SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); } region_t sparse_region = TINY_REGION_FOR_PTR(node); - // Deal with unclaimed memory -- mag_bytes_free_at_end - if (sparse_region == tiny_mag_ptr->mag_last_region && tiny_mag_ptr->mag_bytes_free_at_end) { + // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at_start + if (sparse_region == tiny_mag_ptr->mag_last_region && (tiny_mag_ptr->mag_bytes_free_at_end || tiny_mag_ptr->mag_bytes_free_at_start)) { tiny_finalize_region(szone, tiny_mag_ptr); } @@ -2134,6 +2310,7 @@ tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index // this will cause tiny_free_list_add_ptr called by tiny_free_reattach_region to use // the depot as its target magazine, rather than magazine formerly associated with sparse_region MAGAZINE_INDEX_FOR_TINY_REGION(sparse_region) = DEPOT_MAGAZINE_INDEX; + node->pinned_to_depot = 0; // Iterate the region putting its free entries on Depot's free list size_t bytes_inplay = tiny_free_reattach_region(szone, depot_ptr, sparse_region); @@ -2142,22 +2319,27 @@ tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index tiny_mag_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; tiny_mag_ptr->mag_num_objects -= objects_in_use; + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); // Unlock the originating magazine + depot_ptr->mag_num_bytes_in_objects += bytes_inplay; depot_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; depot_ptr->mag_num_objects += objects_in_use; - // connect to Depot as first (MRU) node - recirc_list_splice_first(szone, depot_ptr, node); + // connect to Depot as last node + recirc_list_splice_last(szone, depot_ptr, node); - MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe + MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (void *)sparse_region, TINY_REGION_SIZE, + (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe // Mark free'd dirty pages with MADV_FREE to reduce memory pressure tiny_free_scan_madvise_free(szone, depot_ptr, sparse_region); - // If the region is entirely empty vm_deallocate() it - tiny_free_try_depot_unmap_no_lock(szone, depot_ptr, node); - + // If the region is entirely empty vm_deallocate() it outside the depot lock + region_t r_dealloc = tiny_free_try_depot_unmap_no_lock(szone, depot_ptr, node); SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); + if (r_dealloc) + deallocate_pages(szone, r_dealloc, TINY_REGION_SIZE, 0); + return FALSE; // Caller need not unlock the originating magazine } static region_t @@ -2235,16 +2417,27 @@ tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - // Appropriate one of the Depot's regions that can satisfy requested msize. - region_t sparse_region = tiny_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize); - if (NULL == sparse_region) { // Depot empty? - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); + // Appropriate a Depot'd region that can satisfy requested msize. + region_trailer_t *node; + region_t sparse_region; + + while (1) { + sparse_region = tiny_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize); + if (NULL == sparse_region) { // Depot empty? + SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); return 0; - } + } - region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(sparse_region); + node = REGION_TRAILER_FOR_TINY_REGION(sparse_region); + if (0 >= node->pinned_to_depot) + break; + + SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); + pthread_yield_np(); + SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); + } - // disconnect node from Depot + // disconnect node from Depot recirc_list_extract(szone, depot_ptr, node); // Iterate the region pulling its free entries off the (locked) Depot's free list @@ -2252,6 +2445,7 @@ tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t // Transfer ownership of the region MAGAZINE_INDEX_FOR_TINY_REGION(sparse_region) = mag_index; + node->pinned_to_depot = 0; // Iterate the region putting its free entries on its new (locked) magazine's free list size_t bytes_inplay = tiny_free_reattach_region(szone, tiny_mag_ptr, sparse_region); @@ -2264,33 +2458,37 @@ tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t tiny_mag_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; tiny_mag_ptr->mag_num_objects += objects_in_use; - // connect to magazine as first node (it's maximally sparse at this moment) + // connect to magazine as first node recirc_list_splice_first(szone, tiny_mag_ptr, node); SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); -#if !TARGET_OS_EMBEDDED + // madvise() outside the Depot lock +#if TARGET_OS_EMBEDDED + if (node->failedREUSE) { +#else if (node->failedREUSE || -1 == madvise((void *)sparse_region, TINY_REGION_PAYLOAD_BYTES, MADV_FREE_REUSE)) { +#endif /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ #if DEBUG_MADVISE - szone_error(szone, 0, "tiny_get_region_from_depot madvise(..., MADV_FREE_REUSE) failed", sparse_region, "length=%d\n", TINY_REGION_PAYLOAD_BYTES); + szone_error(szone, 0, "tiny_get_region_from_depot madvise(..., MADV_FREE_REUSE) failed", + sparse_region, "length=%d\n", TINY_REGION_PAYLOAD_BYTES); #endif node->failedREUSE = TRUE; } -#endif - MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe + MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (void *)sparse_region, TINY_REGION_SIZE, + (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe return 1; } -#warning Tune K and f! #define K 1.5 // headroom measured in number of 1Mb regions #define DENSITY_THRESHOLD(a) \ ((a) - ((a) >> 2)) // "Emptiness" f = 0.25, so "Density" is (1 - f)*a. Generally: ((a) - ((a) >> -log2(f))) -static INLINE void +static INLINE boolean_t tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, msize_t msize) { @@ -2302,14 +2500,12 @@ tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_inde free_list_t *big_free_block; free_list_t *after_next_block; free_list_t *before_next_block; - boolean_t did_prepend = FALSE; - boolean_t did_append = FALSE; #if DEBUG_MALLOC if (LOG(szone,ptr)) { malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); } - if (! msize) { + if (!msize) { szone_error(szone, 1, "trying to free tiny block that is too small", ptr, "in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); } @@ -2323,7 +2519,6 @@ tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_inde malloc_printf("in tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); } #endif - did_prepend = TRUE; // clear the meta_header since this is no longer the start of a block set_tiny_meta_header_middle(ptr); @@ -2333,7 +2528,6 @@ tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_inde } // We try to coalesce with the next block if ((next_block < TINY_REGION_END(region)) && tiny_meta_header_is_free(next_block)) { - did_append = TRUE; next_msize = get_tiny_free_size(next_block); #if DEBUG_MALLOC if (LOG(szone, ptr) || LOG(szone, next_block)) { @@ -2376,16 +2570,15 @@ tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_inde set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards msize += next_msize; } -#if !TINY_CACHE + // The tiny cache already scribbles free blocks as they go through the - // cache, so we do not need to do it here. - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) + // cache whenever msize < TINY_QUANTUM , so we do not need to do it here. + if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize && (msize >= TINY_QUANTUM)) memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize)); -#endif tiny_free_list_add_ptr(szone, tiny_mag_ptr, ptr, msize); + tiny_free_ending: - // When in proper debug mode we write on the memory to help debug memory smashers tiny_mag_ptr->mag_num_objects--; // we use original_size and not msize to avoid double counting the coalesced blocks @@ -2417,84 +2610,67 @@ tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_inde size_t a = tiny_mag_ptr->num_bytes_in_magazine; // Total bytes allocated to this magazine size_t u = tiny_mag_ptr->mag_num_bytes_in_objects; // In use (malloc'd) from this magaqzine - if (a - u > ((3 * TINY_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) - tiny_free_do_recirc_to_depot(szone, tiny_mag_ptr, mag_index); + if (a - u > ((3 * TINY_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) { + return tiny_free_do_recirc_to_depot(szone, tiny_mag_ptr, mag_index); + } } else { #endif // Freed to Depot. N.B. Lock on tiny_magazines[DEPOT_MAGAZINE_INDEX] is already held + // Calcuate the first page in the coalesced block that would be safe to mark MADV_FREE uintptr_t safe_ptr = (uintptr_t)ptr + sizeof(free_list_t) + sizeof(msize_t); uintptr_t round_safe = round_page(safe_ptr); + // Calcuate the last page in the coalesced block that would be safe to mark MADV_FREE uintptr_t safe_extent = (uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t); uintptr_t trunc_extent = trunc_page(safe_extent); // The newly freed block may complete a span of bytes that cover a page. Mark it with MADV_FREE. - if (round_safe < trunc_extent) { // Safe area covers a page - if (did_prepend & did_append) { // Coalesced preceding with original_ptr *and* with following - uintptr_t trunc_safe_prev = trunc_page((uintptr_t)original_ptr - sizeof(msize_t)); - uintptr_t rnd_safe_follow = - round_page((uintptr_t)original_ptr + original_size + sizeof(free_list_t) + sizeof(msize_t)); - -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, region, MAX(round_safe, trunc_safe_prev), MIN(rnd_safe_follow, trunc_extent), &szone->last_tiny_advise); -#else - madvise_free_range(szone, region, MAX(round_safe, trunc_safe_prev), MIN(rnd_safe_follow, trunc_extent)); -#endif - } else if (did_prepend) { // Coalesced preceding with original_ptr - uintptr_t trunc_safe_prev = trunc_page((uintptr_t)original_ptr - sizeof(msize_t)); - -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, region, MAX(round_safe, trunc_safe_prev), trunc_extent, &szone->last_tiny_advise); -#else - madvise_free_range(szone, region, MAX(round_safe, trunc_safe_prev), trunc_extent); -#endif - } else if (did_append) { // Coalesced original_ptr with following - uintptr_t rnd_safe_follow = - round_page((uintptr_t)original_ptr + original_size + sizeof(free_list_t) + sizeof(msize_t)); - + if (round_safe < trunc_extent) { // Safe area covers a page (perhaps many) + uintptr_t lo = trunc_page((uintptr_t)original_ptr); + uintptr_t hi = round_page((uintptr_t)original_ptr + original_size); + + OSAtomicIncrement32Barrier(&(node->pinned_to_depot)); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); #if TARGET_OS_EMBEDDED - madvise_free_range(szone, region, round_safe, MIN(rnd_safe_follow, trunc_extent), &szone->last_tiny_advise); + madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi), &szone->last_tiny_advise); #else - madvise_free_range(szone, region, round_safe, MIN(rnd_safe_follow, trunc_extent)); + madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi)); #endif - } else { // Isolated free cannot exceed 496 bytes, thus round_safe == trunc_extent, and so never get here. - /* madvise_free_range(szone, region, round_safe, trunc_extent); */ - } - } + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + OSAtomicDecrement32Barrier(&(node->pinned_to_depot)); + } #if !TARGET_OS_EMBEDDED - if (0 < bytes_used) { + if (0 < bytes_used || 0 < node->pinned_to_depot) { /* Depot'd region is still live. Leave it in place on the Depot's recirculation list so as to avoid thrashing between the Depot's free list and a magazines's free list with detach_region/reattach_region */ } else { /* Depot'd region is just now empty. Consider return to OS. */ - region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(region); - magazine_t *depot_ptr = &(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); - tiny_free_try_depot_unmap_no_lock(szone, depot_ptr, node); // FIXME: depot_ptr is simply tiny_mag_ptr? + region_t r_dealloc = tiny_free_try_depot_unmap_no_lock(szone, tiny_mag_ptr, node); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + if (r_dealloc) + deallocate_pages(szone, r_dealloc, TINY_REGION_SIZE, 0); + return FALSE; // Caller need not unlock } } #endif + + return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr) } // Allocates from the last region or a freshly allocated region static void * -tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize) +tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, + msize_t msize, void * aligned_address) { - void *ptr, *aligned_address; + void *ptr; - // Deal with unclaimed memory -- mag_bytes_free_at_end - if (tiny_mag_ptr->mag_bytes_free_at_end) + // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at_start + if (tiny_mag_ptr->mag_bytes_free_at_end || tiny_mag_ptr->mag_bytes_free_at_start) tiny_finalize_region(szone, tiny_mag_ptr); - // time to create a new region - aligned_address = allocate_pages(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, 0, VM_MEMORY_MALLOC_TINY); - if (!aligned_address) // out of memory! - return NULL; - - MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index); // DTrace USDT Probe - // We set the unused bits of the header in the last pair to be all ones, and those of the inuse to zeroes. ((tiny_region_t)aligned_address)->pairs[CEIL_NUM_TINY_BLOCKS_WORDS-1].header = (NUM_TINY_BLOCKS & 31) ? (0xFFFFFFFFU << (NUM_TINY_BLOCKS & 31)) : 0; @@ -2531,11 +2707,7 @@ tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_in // Throw the switch to atomically advance to the next generation. szone->tiny_region_generation = szone->tiny_region_generation->nextgen; // Ensure everyone sees the advance. -#if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1))) /* GCC 4.1 and forward supports atomic builtins */ - __sync_synchronize(); -#else OSMemoryBarrier(); -#endif } // Tag the region at "aligned_address" as belonging to us, // and so put it under the protection of the magazine lock we are holding. @@ -2553,7 +2725,16 @@ tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_in tiny_mag_ptr->mag_last_region = aligned_address; BYTES_USED_FOR_TINY_REGION(aligned_address) = TINY_BYTES_FOR_MSIZE(msize); - ptr = aligned_address; +#if ASLR_INTERNAL + int offset_msize = malloc_entropy[0] & TINY_ENTROPY_MASK; +#if DEBUG_MALLOC + if (getenv("MallocASLRForce")) offset_msize = strtol(getenv("MallocASLRForce"), NULL, 0) & TINY_ENTROPY_MASK; + if (getenv("MallocASLRPrint")) malloc_printf("Region: %p offset: %d\n", aligned_address, offset_msize); +#endif +#else + int offset_msize = 0; +#endif + ptr = (void *)((uintptr_t) aligned_address + TINY_BYTES_FOR_MSIZE(offset_msize)); set_tiny_meta_header_in_use(ptr, msize); tiny_mag_ptr->mag_num_objects++; tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(msize); @@ -2561,10 +2742,20 @@ tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_in // We put a header on the last block so that it appears in use (for coalescing, etc...) set_tiny_meta_header_in_use_1((void *)((uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(msize))); - tiny_mag_ptr->mag_bytes_free_at_end = TINY_BYTES_FOR_MSIZE(NUM_TINY_BLOCKS - msize); + tiny_mag_ptr->mag_bytes_free_at_end = TINY_BYTES_FOR_MSIZE(NUM_TINY_BLOCKS - msize - offset_msize); - // connect to magazine as first node (it's maximally sparse at this moment) - recirc_list_splice_first(szone, tiny_mag_ptr, REGION_TRAILER_FOR_TINY_REGION(aligned_address)); +#if ASLR_INTERNAL + // Put a header on the previous block for same reason + tiny_mag_ptr->mag_bytes_free_at_start = TINY_BYTES_FOR_MSIZE(offset_msize); + if (offset_msize) { + set_tiny_meta_header_in_use_1((void *)((uintptr_t)ptr - TINY_QUANTUM)); + } +#else + tiny_mag_ptr->mag_bytes_free_at_start = 0; +#endif + + // connect to magazine as last node + recirc_list_splice_last(szone, tiny_mag_ptr, REGION_TRAILER_FOR_TINY_REGION(aligned_address)); #if DEBUG_MALLOC if (LOG(szone,ptr)) { @@ -2574,6 +2765,28 @@ tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_in return ptr; } +static INLINE void * +tiny_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) +{ + msize_t new_msize = TINY_MSIZE_FOR_BYTES(new_good_size); + msize_t mshrinkage = TINY_MSIZE_FOR_BYTES(old_size) - new_msize; + + if (mshrinkage) { + void *q = (void *)((uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(new_msize)); + magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, + REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)), + MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr))); + + // Mark q as block header and in-use, thus creating two blocks. + set_tiny_meta_header_in_use(q, mshrinkage); + tiny_mag_ptr->mag_num_objects++; + + SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr); + szone_free(szone, q); // avoid inlining free_tiny(szone, q, ...); + } + return ptr; +} + static INLINE boolean_t tiny_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) { @@ -2673,6 +2886,19 @@ tiny_check_region(szone_t *szone, region_t region) /* establish region limits */ start = (uintptr_t)TINY_REGION_ADDRESS(region); ptr = start; + if (region == tiny_mag_ptr->mag_last_region) { + ptr += tiny_mag_ptr->mag_bytes_free_at_start; + + /* + * Check the leading block's integrity here also. + */ + if (tiny_mag_ptr->mag_bytes_free_at_start) { + msize = get_tiny_meta_header((void *)(ptr - TINY_QUANTUM), &is_free); + if (is_free || (msize != 1)) { + malloc_printf("*** invariant broken for leader block %p - %d %d\n", ptr - TINY_QUANTUM, msize, is_free); + } + } + } region_end = (uintptr_t)TINY_REGION_END(region); /* @@ -2802,9 +3028,8 @@ tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t * msize_t msize; void *mapped_ptr; unsigned bit; - vm_address_t mag_last_free_ptr = 0; - msize_t mag_last_free_msize = 0; - + magazine_t *tiny_mag_base = NULL; + region_hash_generation_t *trg_ptr; err = reader(task, (vm_address_t)szone->tiny_region_generation, sizeof(region_hash_generation_t), (void **)&trg_ptr); if (err) return err; @@ -2813,6 +3038,13 @@ tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t * err = reader(task, (vm_address_t)trg_ptr->hashed_regions, sizeof(region_t) * num_regions, (void **)®ions); if (err) return err; + if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + // Map in all active magazines. Do this outside the iteration over regions. + err = reader(task, (vm_address_t)(szone->tiny_magazines), + szone->num_tiny_magazines*sizeof(magazine_t),(void **)&tiny_mag_base); + if (err) return err; + } + for (index = 0; index < num_regions; ++index) { region = regions[index]; if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { @@ -2829,28 +3061,43 @@ tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t * recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); } if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + void *mag_last_free; + vm_address_t mag_last_free_ptr = 0; + msize_t mag_last_free_msize = 0; + err = reader(task, range.address, range.size, (void **)&mapped_region); if (err) return err; mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(mapped_region); - magazine_t *tiny_mag_ptr; - err = reader(task, (vm_address_t)&(szone->tiny_magazines[mag_index]), sizeof(magazine_t), - (void **)&tiny_mag_ptr); - if (err) return err; - - void *mag_last_free = tiny_mag_ptr->mag_last_free; - if (mag_last_free) { - mag_last_free_ptr = (uintptr_t) mag_last_free & ~(TINY_QUANTUM - 1); - mag_last_free_msize = (uintptr_t) mag_last_free & (TINY_QUANTUM - 1); + magazine_t *tiny_mag_ptr = tiny_mag_base + mag_index; + + if (DEPOT_MAGAZINE_INDEX != mag_index) { + mag_last_free = tiny_mag_ptr->mag_last_free; + if (mag_last_free) { + mag_last_free_ptr = (uintptr_t) mag_last_free & ~(TINY_QUANTUM - 1); + mag_last_free_msize = (uintptr_t) mag_last_free & (TINY_QUANTUM - 1); + } + } else { + for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) { + if ((void *)range.address == (tiny_mag_base + mag_index)->mag_last_free_rgn) { + mag_last_free = (tiny_mag_base + mag_index)->mag_last_free; + if (mag_last_free) { + mag_last_free_ptr = (uintptr_t) mag_last_free & ~(TINY_QUANTUM - 1); + mag_last_free_msize = (uintptr_t) mag_last_free & (TINY_QUANTUM - 1); + } + } + } } block_header = (uint32_t *)(mapped_region + TINY_METADATA_START + sizeof(region_trailer_t)); in_use = TINY_INUSE_FOR_HEADER(block_header); block_index = 0; block_limit = NUM_TINY_BLOCKS; - if (region == tiny_mag_ptr->mag_last_region) + if (region == tiny_mag_ptr->mag_last_region) { + block_index += TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_start); block_limit -= TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_end); + } while (block_index < block_limit) { vm_size_t block_offset = TINY_BYTES_FOR_MSIZE(block_index); @@ -3037,6 +3284,25 @@ try_tiny_malloc_from_end: #endif goto return_tiny_alloc; } +#if ASLR_INTERNAL + // Try from start if nothing left at end + if (tiny_mag_ptr->mag_bytes_free_at_start >= TINY_BYTES_FOR_MSIZE(msize)) { + ptr = (free_list_t *)(TINY_REGION_ADDRESS(tiny_mag_ptr->mag_last_region) + + tiny_mag_ptr->mag_bytes_free_at_start - TINY_BYTES_FOR_MSIZE(msize)); + tiny_mag_ptr->mag_bytes_free_at_start -= TINY_BYTES_FOR_MSIZE(msize); + if (tiny_mag_ptr->mag_bytes_free_at_start) { + // let's add an in use block before ptr to serve as boundary + set_tiny_meta_header_in_use_1((unsigned char *)ptr - TINY_QUANTUM); + } + this_msize = msize; +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in tiny_malloc_from_free_list(), from start ptr=%p, msize=%d\n", ptr, msize); + } +#endif + goto return_tiny_alloc; + } +#endif return NULL; add_leftover_and_proceed: @@ -3111,6 +3377,7 @@ tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_reques if ((((uintptr_t)ptr) & (TINY_QUANTUM - 1)) == msize) { // we have a winner tiny_mag_ptr->mag_last_free = NULL; + tiny_mag_ptr->mag_last_free_rgn = NULL; SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); CHECK(szone, __PRETTY_FUNCTION__); ptr = (void *)((uintptr_t)ptr & ~ (TINY_QUANTUM - 1)); @@ -3126,17 +3393,7 @@ tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_reques } #endif /* TINY_CACHE */ - ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); - if (ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - - if (tiny_get_region_from_depot(szone, tiny_mag_ptr, mag_index, msize)) { + while (1) { ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); if (ptr) { SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); @@ -3146,13 +3403,59 @@ tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_reques } return ptr; } - } - ptr = tiny_malloc_from_region_no_lock(szone, tiny_mag_ptr, mag_index, msize); - // we don't clear because this freshly allocated space is pristine - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return ptr; + if (tiny_get_region_from_depot(szone, tiny_mag_ptr, mag_index, msize)) { + ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); + if (ptr) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + if (cleared_requested) { + memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); + } + return ptr; + } + } + + // The magazine is exhausted. A new region (heap) must be allocated to satisfy this call to malloc(). + // The allocation, an mmap() system call, will be performed outside the magazine spin locks by the first + // thread that suffers the exhaustion. That thread sets "alloc_underway" and enters a critical section. + // Threads arriving here later are excluded from the critical section, yield the CPU, and then retry the + // allocation. After some time the magazine is resupplied, the original thread leaves with its allocation, + // and retry-ing threads succeed in the code just above. + if (!tiny_mag_ptr->alloc_underway) { + void *fresh_region; + + // time to create a new region (do this outside the magazine lock) + tiny_mag_ptr->alloc_underway = TRUE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + fresh_region = allocate_pages_securely(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, VM_MEMORY_MALLOC_TINY); + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + + MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index, fresh_region, TINY_REGION_SIZE); // DTrace USDT Probe + + if (!fresh_region) { // out of memory! + tiny_mag_ptr->alloc_underway = FALSE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + return NULL; + } + + ptr = tiny_malloc_from_region_no_lock(szone, tiny_mag_ptr, mag_index, msize, fresh_region); + + // we don't clear because this freshly allocated space is pristine + tiny_mag_ptr->alloc_underway = FALSE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + return ptr; + } else { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + pthread_yield_np(); + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + } + } + /* NOTREACHED */ } static NOINLINE void @@ -3239,8 +3542,9 @@ free_tiny(szone_t *szone, void *ptr, region_t tiny_region, size_t known_size) SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); } - tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize); + if (tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize)) SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); } @@ -3272,12 +3576,12 @@ print_tiny_free_list(szone_t *szone) } static void -print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_end) +print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end) { unsigned counts[1024]; unsigned in_use = 0; uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(region); - uintptr_t current = start; + uintptr_t current = start + bytes_at_end; uintptr_t limit = (uintptr_t)TINY_REGION_END(region) - bytes_at_end; boolean_t is_free; msize_t msize; @@ -3332,8 +3636,8 @@ print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_end) _simple_sprintf(b, "Tiny region [%p-%p, %y] \t", (void *)start, TINY_REGION_END(region), (int)TINY_REGION_SIZE); _simple_sprintf(b, "Magazine=%d \t", MAGAZINE_INDEX_FOR_TINY_REGION(region)); _simple_sprintf(b, "Allocations in use=%d \t Bytes in use=%ly \t", in_use, BYTES_USED_FOR_TINY_REGION(region)); - if (bytes_at_end) - _simple_sprintf(b, "Untouched=%ly ", bytes_at_end); + if (bytes_at_end || bytes_at_start) + _simple_sprintf(b, "Untouched=%ly ", bytes_at_end + bytes_at_start); if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_TINY_REGION(region)) { _simple_sprintf(b, "Advised MADV_FREE=%ly", pgTot); } else { @@ -3537,9 +3841,6 @@ small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr) { void *last_block, *previous_block; msize_t last_msize, previous_msize, last_index; - last_block = SMALL_REGION_END(small_mag_ptr->mag_last_region) - small_mag_ptr->mag_bytes_free_at_end; - last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end); - // It is possible that the block prior to the last block in the region has // been free'd, but was not coalesced with the free bytes at the end of the // block, since we treat the bytes at the end of the region as "in use" in @@ -3555,6 +3856,10 @@ small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr) { // 'mag_bytes_free_at_end' when freeing the preceding block, rather // than performing this workaround. // + if (small_mag_ptr->mag_bytes_free_at_end) { + last_block = SMALL_REGION_END(small_mag_ptr->mag_last_region) - small_mag_ptr->mag_bytes_free_at_end; + last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end); + last_index = SMALL_META_INDEX_FOR_PTR(last_block); previous_msize = SMALL_PREVIOUS_MSIZE(last_block); @@ -3573,6 +3878,30 @@ small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr) { // splice last_block into the free list small_free_list_add_ptr(szone, small_mag_ptr, last_block, last_msize); small_mag_ptr->mag_bytes_free_at_end = 0; + } + +#if ASLR_INTERNAL + if (small_mag_ptr->mag_bytes_free_at_start) { + last_block = SMALL_REGION_ADDRESS(small_mag_ptr->mag_last_region); + last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start); + + void *next_block = (void *) ((uintptr_t)last_block + small_mag_ptr->mag_bytes_free_at_start); + if (SMALL_PTR_IS_FREE(next_block)) { + msize_t next_msize = SMALL_PTR_SIZE(next_block); + + small_meta_header_set_middle(SMALL_META_HEADER_FOR_PTR(next_block), SMALL_META_INDEX_FOR_PTR(next_block)); + small_free_list_remove_ptr(szone, small_mag_ptr, next_block, next_msize); + last_msize += next_msize; + } + + // splice last_block into the free list + small_free_list_add_ptr(szone, small_mag_ptr, last_block, last_msize); + small_mag_ptr->mag_bytes_free_at_start = 0; + } +#endif + + // TODO: Will we ever need to coalesce the blocks at the beginning and end when we finalize? + small_mag_ptr->mag_last_region = NULL; } @@ -3640,13 +3969,18 @@ small_free_reattach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r return total_alloc; } -static void -small_free_scan_depot_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) { +typedef struct { + uint16_t pnum, size; +} small_pg_pair_t; + +static void NOINLINE /* want private stack frame for automatic array */ +small_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) { uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r); uintptr_t current = start; uintptr_t limit = (uintptr_t)SMALL_REGION_END(r); msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(start); - boolean_t did_advise = FALSE; + small_pg_pair_t advisory[((SMALL_REGION_PAYLOAD_BYTES + vm_page_size - 1) >> vm_page_shift) >> 1]; // 4096bytes stack allocated + int advisories = 0; // Scan the metadata identifying blocks which span one or more pages. Mark the pages MADV_FREE taking care to preserve free list // management data. @@ -3659,25 +3993,22 @@ small_free_scan_depot_madvise_free(szone_t *szone, magazine_t *depot_ptr, region if (is_free && !msize && (current == start)) { #if DEBUG_MALLOC // first block is all free - malloc_printf("*** small_free_scan_depot_madvise_free first block is all free! %p: msize=%d is_free =%d\n", + malloc_printf("*** small_free_scan_madvise_free first block is all free! %p: msize=%d is_free =%d\n", (void *)current, msize, is_free); #endif uintptr_t pgLo = round_page(start + sizeof(free_list_t) + sizeof(msize_t)); uintptr_t pgHi = trunc_page(start + SMALL_REGION_SIZE - sizeof(msize_t)); if (pgLo < pgHi) { -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, r, pgLo, pgHi, NULL); -#else - madvise_free_range(szone, r, pgLo, pgHi); -#endif - did_advise = TRUE; + advisory[advisories].pnum = (pgLo - start) >> vm_page_shift; + advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift; + advisories++; } break; } if (!msize) { #if DEBUG_MALLOC - malloc_printf("*** small_free_scan_depot_madvise_free error with %p: msize=%d is_free =%d\n", + malloc_printf("*** small_free_scan_madvise_free error with %p: msize=%d is_free =%d\n", (void *)current, msize, is_free); #endif break; @@ -3687,35 +4018,44 @@ small_free_scan_depot_madvise_free(szone_t *szone, magazine_t *depot_ptr, region uintptr_t pgHi = trunc_page(current + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); if (pgLo < pgHi) { -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, r, pgLo, pgHi, NULL); -#else - madvise_free_range(szone, r, pgLo, pgHi); -#endif - did_advise = TRUE; + advisory[advisories].pnum = (pgLo - start) >> vm_page_shift; + advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift; + advisories++; } } current += SMALL_BYTES_FOR_MSIZE(msize); } - if (did_advise) { - /* Move the node to the tail of the Deopt's recirculation list to delay its re-use. */ - region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(r); - recirc_list_extract(szone, depot_ptr, node); // excise node from list - recirc_list_splice_last(szone, depot_ptr, node); // connect to magazine as last node + if (advisories > 0) { + int i; + + OSAtomicIncrement32Barrier(&(REGION_TRAILER_FOR_SMALL_REGION(r)->pinned_to_depot)); + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + for (i = 0; i < advisories; ++i) { + uintptr_t addr = (advisory[i].pnum << vm_page_shift) + start; + size_t size = advisory[i].size << vm_page_shift; + +#if TARGET_OS_EMBEDDED + madvise_free_range(szone, r, addr, addr + size, NULL); +#else + madvise_free_range(szone, r, addr, addr + size); +#endif + } + SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); + OSAtomicDecrement32Barrier(&(REGION_TRAILER_FOR_SMALL_REGION(r)->pinned_to_depot)); } } -static void +static region_t small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node) { -#warning Tune Depot headroom if (0 < node->bytes_used || + 0 < node->pinned_to_depot || depot_ptr->recirculation_entries < (szone->num_small_magazines * 2)) { - return; + return NULL; } - // disconnect node from Depot + // disconnect first node from Depot recirc_list_extract(szone, depot_ptr, node); // Iterate the region pulling its free entries off the (locked) Depot's free list @@ -3728,31 +4068,25 @@ small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region rgnhdl_t pSlot = hash_lookup_region_no_lock(szone->small_region_generation->hashed_regions, szone->small_region_generation->num_regions_allocated, szone->small_region_generation->num_regions_allocated_shift, sparse_region); + if (NULL == pSlot) { + szone_error(szone, 1, "small_free_try_depot_unmap_no_lock hash lookup failed:", NULL, "%p\n", sparse_region); + return NULL; + } *pSlot = HASHRING_REGION_DEALLOCATED; depot_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; -#if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1))) /* GCC 4.1 and forward supports atomic builtins */ __sync_fetch_and_add( &(szone->num_small_regions_dealloc), 1); // Atomically increment num_small_regions_dealloc -#else -#ifdef __LP64__ - OSAtomicIncrement64( (volatile int64_t *)&(szone->num_small_regions_dealloc) ); -#else - OSAtomicIncrement32( (volatile int32_t *)&(szone->num_small_regions_dealloc) ); -#endif -#endif - // Transfer ownership of the region back to the OS - SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); // Avoid denial of service to Depot while in kernel - deallocate_pages(szone, sparse_region, SMALL_REGION_SIZE, 0); - SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); - - MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region); // DTrace USDT Probe + // Caller will transfer ownership of the region back to the OS with no locks held + MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region, SMALL_REGION_SIZE); // DTrace USDT Probe + return sparse_region; } else { szone_error(szone, 1, "small_free_try_depot_unmap_no_lock objects_in_use not zero:", NULL, "%d\n", objects_in_use); + return NULL; } } -static void +static boolean_t small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index) { // The entire magazine crossed the "emptiness threshold". Transfer a region @@ -3768,17 +4102,17 @@ small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_ind #if DEBUG_MALLOC malloc_printf("*** small_free_do_recirc_to_depot end of list\n"); #endif - return; + return TRUE; // Caller must SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); } region_t sparse_region = SMALL_REGION_FOR_PTR(node); - // Deal with unclaimed memory -- mag_bytes_free_at_end - if (sparse_region == small_mag_ptr->mag_last_region && small_mag_ptr->mag_bytes_free_at_end) { + // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at start + if (sparse_region == small_mag_ptr->mag_last_region && (small_mag_ptr->mag_bytes_free_at_end || small_mag_ptr->mag_bytes_free_at_start)) { small_finalize_region(szone, small_mag_ptr); } - // disconnect first node from magazine + // disconnect "suitable" node from magazine recirc_list_extract(szone, small_mag_ptr, node); // Iterate the region pulling its free entries off its (locked) magazine's free list @@ -3790,6 +4124,7 @@ small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_ind // this will cause small_free_list_add_ptr called by small_free_reattach_region to use // the depot as its target magazine, rather than magazine formerly associated with sparse_region MAGAZINE_INDEX_FOR_SMALL_REGION(sparse_region) = DEPOT_MAGAZINE_INDEX; + node->pinned_to_depot = 0; // Iterate the region putting its free entries on Depot's free list size_t bytes_inplay = small_free_reattach_region(szone, depot_ptr, sparse_region); @@ -3798,22 +4133,27 @@ small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_ind small_mag_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; small_mag_ptr->mag_num_objects -= objects_in_use; + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); // Unlock the originating magazine + depot_ptr->mag_num_bytes_in_objects += bytes_inplay; depot_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; depot_ptr->mag_num_objects += objects_in_use; - // connect to Depot as first node - recirc_list_splice_first(szone, depot_ptr, node); + // connect to Depot as last node + recirc_list_splice_last(szone, depot_ptr, node); - MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe + MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (void *)sparse_region, SMALL_REGION_SIZE, + (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe // Mark free'd dirty pages with MADV_FREE to reduce memory pressure - small_free_scan_depot_madvise_free(szone, depot_ptr, sparse_region); + small_free_scan_madvise_free(szone, depot_ptr, sparse_region); - // If the region is entirely empty vm_deallocate() it - small_free_try_depot_unmap_no_lock(szone, depot_ptr, node); - + // If the region is entirely empty vm_deallocate() it outside the depot lock + region_t r_dealloc = small_free_try_depot_unmap_no_lock(szone, depot_ptr, node); SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); + if (r_dealloc) + deallocate_pages(szone, r_dealloc, SMALL_REGION_SIZE, 0); + return FALSE; // Caller need not unlock the originating magazine } static region_t @@ -3903,14 +4243,26 @@ small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - // Appropriate one of the Depot's regions that can satisfy requested msize. - region_t sparse_region = small_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize); - if (NULL == sparse_region) { // Depot empty? + // Appropriate a Depot'd region that can satisfy requested msize. + region_trailer_t *node; + region_t sparse_region; + + while (1) { + sparse_region = small_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize); + if (NULL == sparse_region) { // Depot empty? + SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); + return 0; + } + + node = REGION_TRAILER_FOR_SMALL_REGION(sparse_region); + if (0 >= node->pinned_to_depot) + break; + SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - return 0; + pthread_yield_np(); + SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); } - region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(sparse_region); // disconnect node from Depot recirc_list_extract(szone, depot_ptr, node); @@ -3919,6 +4271,7 @@ small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index // Transfer ownership of the region MAGAZINE_INDEX_FOR_SMALL_REGION(sparse_region) = mag_index; + node->pinned_to_depot = 0; // Iterate the region putting its free entries on its new (locked) magazine's free list size_t bytes_inplay = small_free_reattach_region(szone, small_mag_ptr, sparse_region); @@ -3931,33 +4284,37 @@ small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index small_mag_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; small_mag_ptr->mag_num_objects += objects_in_use; - // connect to magazine as first node (it's maximally sparse at this moment) + // connect to magazine as first node recirc_list_splice_first(szone, small_mag_ptr, node); SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); -#if !TARGET_OS_EMBEDDED + // madvise() outside the Depot lock +#if TARGET_OS_EMBEDDED + if (node->failedREUSE) { +#else if (node->failedREUSE || -1 == madvise((void *)sparse_region, SMALL_REGION_PAYLOAD_BYTES, MADV_FREE_REUSE)) { +#endif /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ #if DEBUG_MADVISE - szone_error(szone, 0, "small_get_region_from_depot madvise(..., MADV_FREE_REUSE) failed", sparse_region, "length=%d\n", SMALL_REGION_PAYLOAD_BYTES); + szone_error(szone, 0, "small_get_region_from_depot madvise(..., MADV_FREE_REUSE) failed", + sparse_region, "length=%d\n", SMALL_REGION_PAYLOAD_BYTES); #endif node->failedREUSE = TRUE; } -#endif - MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe + MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (void *)sparse_region, SMALL_REGION_SIZE, + (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe return 1; } -#warning Tune K and f! #define K 1.5 // headroom measured in number of 8Mb regions #define DENSITY_THRESHOLD(a) \ ((a) - ((a) >> 2)) // "Emptiness" f = 0.25, so "Density" is (1 - f)*a. Generally: ((a) - ((a) >> -log2(f))) -static INLINE void +static INLINE boolean_t small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, msize_t msize) { msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); @@ -3968,14 +4325,12 @@ small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_in msize_t next_index = index + msize; msize_t previous_msize, next_msize; void *previous; - boolean_t did_prepend = FALSE; - boolean_t did_append = FALSE; #if DEBUG_MALLOC if (LOG(szone,ptr)) { malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); } - if (! msize) { + if (!msize) { szone_error(szone, 1, "trying to free small block that is too small", ptr, "in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); } @@ -3987,7 +4342,6 @@ small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_in if (meta_headers[index - previous_msize] == (previous_msize | SMALL_IS_FREE)) { previous = (void *)((uintptr_t)ptr - SMALL_BYTES_FOR_MSIZE(previous_msize)); // previous is really to be coalesced - did_prepend = TRUE; #if DEBUG_MALLOC if (LOG(szone, ptr) || LOG(szone,previous)) { malloc_printf("in small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); @@ -4003,7 +4357,6 @@ small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_in // We try to coalesce with the next block if ((next_block < SMALL_REGION_END(region)) && (meta_headers[next_index] & SMALL_IS_FREE)) { // next block is free, we coalesce - did_append = TRUE; next_msize = meta_headers[next_index] & ~ SMALL_IS_FREE; #if DEBUG_MALLOC if (LOG(szone,ptr)) @@ -4053,88 +4406,68 @@ small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_in size_t a = small_mag_ptr->num_bytes_in_magazine; // Total bytes allocated to this magazine size_t u = small_mag_ptr->mag_num_bytes_in_objects; // In use (malloc'd) from this magaqzine - if (a - u > ((3 * SMALL_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) - small_free_do_recirc_to_depot(szone, small_mag_ptr, mag_index); + if (a - u > ((3 * SMALL_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) { + return small_free_do_recirc_to_depot(szone, small_mag_ptr, mag_index); + } } else { #endif // Freed to Depot. N.B. Lock on small_magazines[DEPOT_MAGAZINE_INDEX] is already held + // Calcuate the first page in the coalesced block that would be safe to mark MADV_FREE uintptr_t safe_ptr = (uintptr_t)ptr + sizeof(free_list_t) + sizeof(msize_t); uintptr_t round_safe = round_page(safe_ptr); + // Calcuate the last page in the coalesced block that would be safe to mark MADV_FREE uintptr_t safe_extent = (uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t); uintptr_t trunc_extent = trunc_page(safe_extent); - // The newly freed block may complete a span of bytes that cover a page. Mark it with MADV_FREE. + // The newly freed block may complete a span of bytes that cover one or more pages. Mark the span with MADV_FREE. if (round_safe < trunc_extent) { // Safe area covers a page (perhaps many) - if (did_prepend & did_append) { // Coalesced preceding with original_ptr *and* with following - uintptr_t trunc_safe_prev = trunc_page((uintptr_t)original_ptr - sizeof(msize_t)); - uintptr_t rnd_safe_follow = - round_page((uintptr_t)original_ptr + original_size + sizeof(free_list_t) + sizeof(msize_t)); - -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, region, MAX(round_safe, trunc_safe_prev), MIN(rnd_safe_follow, trunc_extent), &szone->last_small_advise); -#else - madvise_free_range(szone, region, MAX(round_safe, trunc_safe_prev), MIN(rnd_safe_follow, trunc_extent)); -#endif - } else if (did_prepend) { // Coalesced preceding with original_ptr - uintptr_t trunc_safe_prev = trunc_page((uintptr_t)original_ptr - sizeof(msize_t)); - -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, region, MAX(round_safe, trunc_safe_prev), trunc_extent, &szone->last_small_advise); -#else - madvise_free_range(szone, region, MAX(round_safe, trunc_safe_prev), trunc_extent); -#endif - } else if (did_append) { // Coalesced original_ptr with following - uintptr_t rnd_safe_follow = - round_page((uintptr_t)original_ptr + original_size + sizeof(free_list_t) + sizeof(msize_t)); - -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, region, round_safe, MIN(rnd_safe_follow, trunc_extent), &szone->last_small_advise); -#else - madvise_free_range(szone, region, round_safe, MIN(rnd_safe_follow, trunc_extent)); -#endif - } else // Isolated free + uintptr_t lo = trunc_page((uintptr_t)original_ptr); + uintptr_t hi = round_page((uintptr_t)original_ptr + original_size); + + OSAtomicIncrement32Barrier(&(node->pinned_to_depot)); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); #if TARGET_OS_EMBEDDED - madvise_free_range(szone, region, round_safe, trunc_extent, &szone->last_small_advise); + madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi), &szone->last_small_advise); #else - madvise_free_range(szone, region, round_safe, trunc_extent); + madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi)); #endif - } + SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); + OSAtomicDecrement32Barrier(&(node->pinned_to_depot)); + } #if !TARGET_OS_EMBEDDED - if (0 < bytes_used) { + if (0 < bytes_used || 0 < node->pinned_to_depot) { /* Depot'd region is still live. Leave it in place on the Depot's recirculation list so as to avoid thrashing between the Depot's free list and a magazines's free list with detach_region/reattach_region */ } else { /* Depot'd region is just now empty. Consider return to OS. */ - region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(region); - magazine_t *depot_ptr = &(szone->small_magazines[DEPOT_MAGAZINE_INDEX]); - small_free_try_depot_unmap_no_lock(szone, depot_ptr, node); + region_t r_dealloc = small_free_try_depot_unmap_no_lock(szone, small_mag_ptr, node); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + if (r_dealloc) + deallocate_pages(szone, r_dealloc, SMALL_REGION_SIZE, 0); + return FALSE; // Caller need not unlock } } #endif + + return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr) } // Allocates from the last region or a freshly allocated region static void * -small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize) +small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, + msize_t msize, void *aligned_address) { - void *ptr, *aligned_address; + void *ptr; - // Before anything we transform the mag_bytes_free_at_end - if any - to a regular free block + // Before anything we transform the mag_bytes_free_at_end or mag_bytes_free_at_start - if any - to a regular free block /* FIXME: last_block needs to be coalesced with previous entry if free, */ - if (small_mag_ptr->mag_bytes_free_at_end) + if (small_mag_ptr->mag_bytes_free_at_end || small_mag_ptr->mag_bytes_free_at_start) small_finalize_region(szone, small_mag_ptr); - // time to create a new region - aligned_address = allocate_pages(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, 0, VM_MEMORY_MALLOC_SMALL); - if (!aligned_address) - return NULL; - - MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index); // DTrace USDT Probe - // Here find the only place in smallville that (infrequently) takes the small_regions_lock. // Only one thread at a time should be permitted to assess the density of the hash // ring and adjust if needed. @@ -4165,11 +4498,7 @@ small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_ // Throw the switch to atomically advance to the next generation. szone->small_region_generation = szone->small_region_generation->nextgen; // Ensure everyone sees the advance. -#if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1))) /* GCC 4.1 and forward supports atomic builtins */ - __sync_synchronize(); -#else OSMemoryBarrier(); -#endif } // Tag the region at "aligned_address" as belonging to us, // and so put it under the protection of the magazine lock we are holding. @@ -4188,18 +4517,61 @@ small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_ small_mag_ptr->mag_last_region = aligned_address; BYTES_USED_FOR_SMALL_REGION(aligned_address) = SMALL_BYTES_FOR_MSIZE(msize); - ptr = aligned_address; - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), 0, msize); +#if ASLR_INTERNAL + int offset_msize = malloc_entropy[1] & SMALL_ENTROPY_MASK; +#if DEBUG_MALLOC + if (getenv("MallocASLRForce")) offset_msize = strtol(getenv("MallocASLRForce"), NULL, 0) & SMALL_ENTROPY_MASK; + if (getenv("MallocASLRPrint")) malloc_printf("Region: %p offset: %d\n", aligned_address, offset_msize); +#endif +#else + int offset_msize = 0; +#endif + ptr = (void *)((uintptr_t) aligned_address + SMALL_BYTES_FOR_MSIZE(offset_msize)); + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), offset_msize, msize); small_mag_ptr->mag_num_objects++; small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(msize); small_mag_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; - // add a big free block - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr) , msize, NUM_SMALL_BLOCKS - msize); - small_mag_ptr->mag_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(NUM_SMALL_BLOCKS - msize); + // add a big free block at the end + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), offset_msize + msize, NUM_SMALL_BLOCKS - msize - offset_msize); + small_mag_ptr->mag_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(NUM_SMALL_BLOCKS - msize - offset_msize); + +#if ASLR_INTERNAL + // add a big free block at the start + small_mag_ptr->mag_bytes_free_at_start = SMALL_BYTES_FOR_MSIZE(offset_msize); + if (offset_msize) { + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), 0, offset_msize); + } +#else + small_mag_ptr->mag_bytes_free_at_start = 0; +#endif + + // connect to magazine as last node + recirc_list_splice_last(szone, small_mag_ptr, REGION_TRAILER_FOR_SMALL_REGION(aligned_address)); + + return ptr; +} + +static INLINE void * +small_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) +{ + msize_t new_msize = SMALL_MSIZE_FOR_BYTES(new_good_size); + msize_t mshrinkage = SMALL_MSIZE_FOR_BYTES(old_size) - new_msize; + + if (mshrinkage) { + void *q = (void *)((uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(new_msize)); + magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, + REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)), + MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr))); + + // Mark q as block header and in-use, thus creating two blocks. + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), new_msize); + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), mshrinkage); + small_mag_ptr->mag_num_objects++; - // connect to magazine as first node (it's maximally sparse at this moment) - recirc_list_splice_first(szone, small_mag_ptr, REGION_TRAILER_FOR_SMALL_REGION(aligned_address)); + SZONE_MAGAZINE_PTR_UNLOCK(szone,small_mag_ptr); + szone_free(szone, q); // avoid inlining free_small(szone, q, ...); + } return ptr; } @@ -4277,7 +4649,7 @@ small_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t ne small_meta_header_set_in_use(meta_headers, index, new_msize); #if DEBUG_MALLOC if (LOG(szone,ptr)) { - malloc_printf("in szone_realloc(), ptr=%p, msize=%d\n", ptr, *SMALL_METADATA_FOR_PTR(ptr)); + malloc_printf("in small_try_realloc_in_place(), ptr=%p, msize=%d\n", ptr, *SMALL_METADATA_FOR_PTR(ptr)); } #endif small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(new_msize - old_msize); @@ -4321,8 +4693,10 @@ small_check_region(szone_t *szone, region_t region) // Assumes locked CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__); - if (region == small_mag_ptr->mag_last_region) + if (region == small_mag_ptr->mag_last_region) { + ptr += small_mag_ptr->mag_bytes_free_at_start; region_end -= small_mag_ptr->mag_bytes_free_at_end; + } while (ptr < region_end) { index = SMALL_META_INDEX_FOR_PTR(ptr); @@ -4399,9 +4773,8 @@ small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t unsigned block_limit; msize_t msize_and_free; msize_t msize; - vm_address_t mag_last_free_ptr = 0; - msize_t mag_last_free_msize = 0; - + magazine_t *small_mag_base = NULL; + region_hash_generation_t *srg_ptr; err = reader(task, (vm_address_t)szone->small_region_generation, sizeof(region_hash_generation_t), (void **)&srg_ptr); if (err) return err; @@ -4410,6 +4783,13 @@ small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t err = reader(task, (vm_address_t)srg_ptr->hashed_regions, sizeof(region_t) * num_regions, (void **)®ions); if (err) return err; + if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + // Map in all active magazines. Do this outside the iteration over regions. + err = reader(task, (vm_address_t)(szone->small_magazines), + szone->num_small_magazines*sizeof(magazine_t),(void **)&small_mag_base); + if (err) return err; + } + for (index = 0; index < num_regions; ++index) { region = regions[index]; if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { @@ -4426,27 +4806,42 @@ small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); } if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + void *mag_last_free; + vm_address_t mag_last_free_ptr = 0; + msize_t mag_last_free_msize = 0; + err = reader(task, range.address, range.size, (void **)&mapped_region); if (err) return err; mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(mapped_region); - magazine_t *small_mag_ptr; - err = reader(task, (vm_address_t)&(szone->small_magazines[mag_index]), sizeof(magazine_t), - (void **)&small_mag_ptr); - if (err) return err; - - void *mag_last_free = small_mag_ptr->mag_last_free; - if (mag_last_free) { - mag_last_free_ptr = (uintptr_t) mag_last_free & ~(SMALL_QUANTUM - 1); - mag_last_free_msize = (uintptr_t) mag_last_free & (SMALL_QUANTUM - 1); + magazine_t *small_mag_ptr = small_mag_base + mag_index; + + if (DEPOT_MAGAZINE_INDEX != mag_index) { + mag_last_free = small_mag_ptr->mag_last_free; + if (mag_last_free) { + mag_last_free_ptr = (uintptr_t) mag_last_free & ~(SMALL_QUANTUM - 1); + mag_last_free_msize = (uintptr_t) mag_last_free & (SMALL_QUANTUM - 1); + } + } else { + for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) { + if ((void *)range.address == (small_mag_base + mag_index)->mag_last_free_rgn) { + mag_last_free = (small_mag_base + mag_index)->mag_last_free; + if (mag_last_free) { + mag_last_free_ptr = (uintptr_t) mag_last_free & ~(SMALL_QUANTUM - 1); + mag_last_free_msize = (uintptr_t) mag_last_free & (SMALL_QUANTUM - 1); + } + } + } } block_header = (msize_t *)(mapped_region + SMALL_METADATA_START + sizeof(region_trailer_t)); block_index = 0; block_limit = NUM_SMALL_BLOCKS; - if (region == small_mag_ptr->mag_last_region) + if (region == small_mag_ptr->mag_last_region) { + block_index += SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start); block_limit -= SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end); + } while (block_index < block_limit) { msize_and_free = block_header[block_index]; msize = msize_and_free & ~ SMALL_IS_FREE; @@ -4614,6 +5009,20 @@ try_small_from_end: this_msize = msize; goto return_small_alloc; } +#if ASLR_INTERNAL + // Try from start if nothing left at end + if (small_mag_ptr->mag_bytes_free_at_start >= SMALL_BYTES_FOR_MSIZE(msize)) { + ptr = (free_list_t *)(SMALL_REGION_ADDRESS(small_mag_ptr->mag_last_region) + + small_mag_ptr->mag_bytes_free_at_start - SMALL_BYTES_FOR_MSIZE(msize)); + small_mag_ptr->mag_bytes_free_at_start -= SMALL_BYTES_FOR_MSIZE(msize); + if (small_mag_ptr->mag_bytes_free_at_start) { + // let's mark this block as in use to serve as boundary + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), 0, SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start)); + } + this_msize = msize; + goto return_small_alloc; + } +#endif return NULL; add_leftover_and_proceed: @@ -4673,6 +5082,7 @@ small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_reque if ((((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) == msize) { // we have a winner small_mag_ptr->mag_last_free = NULL; + small_mag_ptr->mag_last_free_rgn = NULL; SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); CHECK(szone, __PRETTY_FUNCTION__); ptr = (void *)((uintptr_t)ptr & ~ (SMALL_QUANTUM - 1)); @@ -4683,17 +5093,7 @@ small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_reque } #endif /* SMALL_CACHE */ - ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize); - if (ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - - if (small_get_region_from_depot(szone, small_mag_ptr, mag_index, msize)) { + while(1) { ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize); if (ptr) { SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); @@ -4703,13 +5103,59 @@ small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_reque } return ptr; } - } - ptr = small_malloc_from_region_no_lock(szone, small_mag_ptr, mag_index, msize); - // we don't clear because this freshly allocated space is pristine - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return ptr; + if (small_get_region_from_depot(szone, small_mag_ptr, mag_index, msize)) { + ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize); + if (ptr) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + if (cleared_requested) { + memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); + } + return ptr; + } + } + + // The magazine is exhausted. A new region (heap) must be allocated to satisfy this call to malloc(). + // The allocation, an mmap() system call, will be performed outside the magazine spin locks by the first + // thread that suffers the exhaustion. That thread sets "alloc_underway" and enters a critical section. + // Threads arriving here later are excluded from the critical section, yield the CPU, and then retry the + // allocation. After some time the magazine is resupplied, the original thread leaves with its allocation, + // and retry-ing threads succeed in the code just above. + if (!small_mag_ptr->alloc_underway) { + void *fresh_region; + + // time to create a new region (do this outside the magazine lock) + small_mag_ptr->alloc_underway = TRUE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + fresh_region = allocate_pages_securely(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, VM_MEMORY_MALLOC_SMALL); + SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); + + MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index, fresh_region, SMALL_REGION_SIZE); // DTrace USDT Probe + + if (!fresh_region) { // out of memory! + small_mag_ptr->alloc_underway = FALSE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + return NULL; + } + + ptr = small_malloc_from_region_no_lock(szone, small_mag_ptr, mag_index, msize, fresh_region); + + // we don't clear because this freshly allocated space is pristine + small_mag_ptr->alloc_underway = FALSE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + return ptr; + } else { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + pthread_yield_np(); + SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); + } + } + /* NOTREACHED */ } static NOINLINE void @@ -4788,8 +5234,9 @@ free_small(szone_t *szone, void *ptr, region_t small_region, size_t known_size) SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); } - small_free_no_lock(szone, small_mag_ptr, mag_index, small_region, ptr, msize); + if (small_free_no_lock(szone, small_mag_ptr, mag_index, small_region, ptr, msize)) SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); } @@ -4821,12 +5268,12 @@ print_small_free_list(szone_t *szone) } static void -print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_end) +print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end) { unsigned counts[1024]; unsigned in_use = 0; uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(region); - uintptr_t current = start; + uintptr_t current = start + bytes_at_start; uintptr_t limit = (uintptr_t)SMALL_REGION_END(region) - bytes_at_end; msize_t msize_and_free; msize_t msize; @@ -4858,7 +5305,7 @@ print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t by in_use++; } else { uintptr_t pgLo = round_page(current + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page(current + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); + uintptr_t pgHi = trunc_page(current + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); if (pgLo < pgHi) { pgTot += (pgHi - pgLo); @@ -4870,8 +5317,8 @@ print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t by _simple_sprintf(b, "Small region [%p-%p, %y] \t", (void *)start, SMALL_REGION_END(region), (int)SMALL_REGION_SIZE); _simple_sprintf(b, "Magazine=%d \t", MAGAZINE_INDEX_FOR_SMALL_REGION(region)); _simple_sprintf(b, "Allocations in use=%d \t Bytes in use=%ly \t", in_use, BYTES_USED_FOR_SMALL_REGION(region)); - if (bytes_at_end) - _simple_sprintf(b, "Untouched=%ly ", bytes_at_end); + if (bytes_at_end || bytes_at_start) + _simple_sprintf(b, "Untouched=%ly ", bytes_at_end + bytes_at_start); if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_SMALL_REGION(region)) { _simple_sprintf(b, "Advised MADV_FREE=%ly", pgTot); } else { @@ -5114,7 +5561,7 @@ large_entry_free_no_lock(szone_t *szone, large_entry_t *entry) range.size = entry->size; if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) { - protect((void *)range.address, range.size, VM_PROT_READ | VM_PROT_WRITE, szone->debug_flags); + protect((void *)range.address, range.size, PROT_READ | PROT_WRITE, szone->debug_flags); range.address -= vm_page_size; range.size += 2 * vm_page_size; } @@ -5203,16 +5650,19 @@ large_malloc(szone_t *szone, size_t num_pages, unsigned char alignment, while (1) { // Scan large_entry_cache for best fit, starting with most recent entry size_t this_size = szone->large_entry_cache[idx].size; + addr = (void *)szone->large_entry_cache[idx].address; + + if (0 == alignment || 0 == (((uintptr_t) addr) & (((uintptr_t) 1 << alignment) - 1))) { + if (size == this_size) { // size match! + best = idx; + best_size = this_size; + break; + } - if (size == this_size) { // size match! - best = idx; - best_size = this_size; - break; - } - - if (size <= this_size && this_size < best_size) { // improved fit? - best = idx; - best_size = this_size; + if (size <= this_size && this_size < best_size) { // improved fit? + best = idx; + best_size = this_size; + } } if (idx == stop_idx) // exhausted live ring? @@ -5288,7 +5738,14 @@ large_malloc(szone_t *szone, size_t num_pages, unsigned char alignment, szone->num_large_objects_in_use ++; szone->num_bytes_in_large_objects += best_size; if (!was_madvised_reusable) - szone->large_entry_cache_hoard_bytes -= best_size; + szone->large_entry_cache_reserve_bytes -= best_size; + + szone->large_entry_cache_bytes -= best_size; + + if (szone->flotsam_enabled && szone->large_entry_cache_bytes < SZONE_FLOTSAM_THRESHOLD_LOW) { + szone->flotsam_enabled = FALSE; + } + SZONE_UNLOCK(szone); if (range_to_deallocate.size) { @@ -5299,10 +5756,15 @@ large_malloc(szone_t *szone, size_t num_pages, unsigned char alignment, // Perform the madvise() outside the lock. // Typically the madvise() is successful and we'll quickly return from this routine. // In the unusual case of failure, reacquire the lock to unwind. +#if TARGET_OS_EMBEDDED + // Ok to do this madvise on embedded because we won't call MADV_FREE_REUSABLE on a large + // cache block twice without MADV_FREE_REUSE in between. +#endif if (was_madvised_reusable && -1 == madvise(addr, size, MADV_FREE_REUSE)) { /* -1 return: VM map entry change makes this unfit for reuse. */ #if DEBUG_MADVISE - szone_error(szone, 0, "large_malloc madvise(..., MADV_FREE_REUSE) failed", addr, "length=%d\n", size); + szone_error(szone, 0, "large_malloc madvise(..., MADV_FREE_REUSE) failed", + addr, "length=%d\n", size); #endif SZONE_LOCK(szone); @@ -5392,7 +5854,7 @@ free_large(szone_t *szone, void *ptr) int idx = szone->large_entry_cache_newest, stop_idx = szone->large_entry_cache_oldest; large_entry_t this_entry = *entry; // Make a local copy, "entry" is volatile when lock is let go. boolean_t reusable = TRUE; - boolean_t should_madvise = szone->large_entry_cache_hoard_bytes + this_entry.size > szone->large_entry_cache_hoard_lmit; + boolean_t should_madvise = szone->large_entry_cache_reserve_bytes + this_entry.size > szone->large_entry_cache_reserve_limit; // Already freed? // [Note that repeated entries in death-row risk vending the same entry subsequently @@ -5420,30 +5882,35 @@ free_large(szone_t *szone, void *ptr) int state = VM_PURGABLE_NONVOLATILE; // restore to default condition if (KERN_SUCCESS != vm_purgable_control(mach_task_self(), this_entry.address, VM_PURGABLE_SET_STATE, &state)) { - malloc_printf("*** can't vm_purgable_control(..., VM_PURGABLE_SET_STATE) for large freed block at %p\n", this_entry.address); + malloc_printf("*** can't vm_purgable_control(..., VM_PURGABLE_SET_STATE) for large freed block at %p\n", + this_entry.address); reusable = FALSE; } } if (szone->large_legacy_reset_mprotect) { // Linked for Leopard? // Accomodate Leopard apps that (illegally) mprotect() their own guard pages on large malloc'd allocations - kern_return_t err = vm_protect(mach_task_self(), (vm_address_t)(this_entry.address), this_entry.size, - 0, PROT_READ | PROT_WRITE); + int err = mprotect((void *)(this_entry.address), this_entry.size, PROT_READ | PROT_WRITE); if (err) { malloc_printf("*** can't reset protection for large freed block at %p\n", this_entry.address); reusable = FALSE; } } - // madvise(..., MADV_REUSABLE) death-row arrivals if hoarding would exceed large_entry_cache_hoard_lmit + // madvise(..., MADV_REUSABLE) death-row arrivals if hoarding would exceed large_entry_cache_reserve_limit if (should_madvise) { // Issue madvise to avoid paging out the dirtied free()'d pages in "entry" MAGMALLOC_MADVFREEREGION((void *)szone, (void *)0, (void *)(this_entry.address), this_entry.size); // DTrace USDT Probe +#if TARGET_OS_EMBEDDED + // Ok to do this madvise on embedded because we won't call MADV_FREE_REUSABLE on a large + // cache block twice without MADV_FREE_REUSE in between. +#endif if (-1 == madvise((void *)(this_entry.address), this_entry.size, MADV_FREE_REUSABLE)) { /* -1 return: VM map entry change makes this unfit for reuse. */ #if DEBUG_MADVISE - szone_error(szone, 0, "free_large madvise(..., MADV_FREE_REUSABLE) failed", (void *)this_entry.address, "length=%d\n", this_entry.size); + szone_error(szone, 0, "free_large madvise(..., MADV_FREE_REUSABLE) failed", + (void *)this_entry.address, "length=%d\n", this_entry.size); #endif reusable = FALSE; } @@ -5481,8 +5948,9 @@ free_large(szone_t *szone, void *ptr) // Drop this entry from the cache and deallocate the VM addr = szone->large_entry_cache[idx].address; adjsize = szone->large_entry_cache[idx].size; + szone->large_entry_cache_bytes -= adjsize; if (!szone->large_entry_cache[idx].did_madvise_reusable) - szone->large_entry_cache_hoard_bytes -= adjsize; + szone->large_entry_cache_reserve_bytes -= adjsize; } else { // Using an unoccupied cache slot addr = 0; @@ -5495,8 +5963,14 @@ free_large(szone_t *szone, void *ptr) entry->did_madvise_reusable = should_madvise; // Was madvise()'d above? if (!should_madvise) // Entered on death-row without madvise() => up the hoard total - szone->large_entry_cache_hoard_bytes += entry->size; + szone->large_entry_cache_reserve_bytes += entry->size; + szone->large_entry_cache_bytes += entry->size; + + if (!szone->flotsam_enabled && szone->large_entry_cache_bytes > SZONE_FLOTSAM_THRESHOLD_HIGH) { + szone->flotsam_enabled = TRUE; + } + szone->large_entry_cache[idx] = *entry; szone->large_entry_cache_newest = idx; @@ -5559,6 +6033,31 @@ free_large(szone_t *szone, void *ptr) } } +static INLINE void * +large_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) +{ + size_t shrinkage = old_size - new_good_size; + + if (shrinkage) { + SZONE_LOCK(szone); + /* contract existing large entry */ + large_entry_t *large_entry = large_entry_for_pointer_no_lock(szone, ptr); + if (!large_entry) { + szone_error(szone, 1, "large entry reallocated is not properly in table", ptr, NULL); + SZONE_UNLOCK(szone); + return ptr; + } + + large_entry->address = (vm_address_t)ptr; + large_entry->size = new_good_size; + szone->num_bytes_in_large_objects -= shrinkage; + SZONE_UNLOCK(szone); // we release the lock asap + + deallocate_pages(szone, (void *)((uintptr_t)ptr + new_good_size), shrinkage, 0); + } + return ptr; +} + static INLINE int large_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) { @@ -5696,8 +6195,7 @@ szone_free_definite_size(szone_t *szone, void *ptr, size_t size) szone_error(szone, 1, "Non-aligned pointer being freed (2)", ptr, NULL); return; } - if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && - (size <= szone->large_threshold)) { + if (size <= szone->large_threshold) { if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) { szone_error(szone, 1, "Pointer to metadata being freed (2)", ptr, NULL); return; @@ -5726,11 +6224,10 @@ szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_request if (!msize) msize = 1; ptr = tiny_malloc_should_clear(szone, msize, cleared_requested); - } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && - (size <= szone->large_threshold)) { + } else if (size <= szone->large_threshold) { // think small msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); - if (! msize) + if (!msize) msize = 1; ptr = small_malloc_should_clear(szone, msize, cleared_requested); } else { @@ -5856,10 +6353,19 @@ szone_size(szone_t *szone, const void *ptr) #if TINY_CACHE { mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); + if (DEPOT_MAGAZINE_INDEX != mag_index) { + magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~ (TINY_QUANTUM - 1))) - return 0; + if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~ (TINY_QUANTUM - 1))) + return 0; + } else { + for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) { + magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); + + if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~ (TINY_QUANTUM - 1))) + return 0; + } + } } #endif return TINY_BYTES_FOR_MSIZE(msize); @@ -5879,10 +6385,19 @@ szone_size(szone_t *szone, const void *ptr) #if SMALL_CACHE { mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); + if (DEPOT_MAGAZINE_INDEX != mag_index) { + magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~ (SMALL_QUANTUM - 1))) - return 0; + if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~ (SMALL_QUANTUM - 1))) + return 0; + } else { + for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) { + magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); + + if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~ (SMALL_QUANTUM - 1))) + return 0; + } + } } #endif return SMALL_BYTES_FOR_MSIZE(msize_and_free); @@ -5903,7 +6418,7 @@ szone_size(szone_t *szone, const void *ptr) static NOINLINE void * szone_realloc(szone_t *szone, void *ptr, size_t new_size) { - size_t old_size; + size_t old_size, new_good_size, valid_size; void *new_ptr; #if DEBUG_MALLOC @@ -5911,49 +6426,76 @@ szone_realloc(szone_t *szone, void *ptr, size_t new_size) malloc_printf("in szone_realloc for %p, %d\n", ptr, (unsigned)new_size); } #endif - if (!ptr) { - ptr = szone_malloc(szone, new_size); - return ptr; + if (NULL == ptr) { + // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. + return szone_malloc(szone, new_size); + } else if (0 == new_size) { + // If size is 0 and ptr is not a null pointer, the object pointed to is freed. + szone_free(szone, ptr); + // If size is 0, either a null pointer or a unique pointer that can be successfully passed + // to free() shall be returned. + return szone_malloc(szone, 1); } + old_size = szone_size(szone, ptr); if (!old_size) { szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL); return NULL; } - /* we never shrink an allocation */ - if (old_size >= new_size) + + new_good_size = szone_good_size(szone, new_size); + if (new_good_size == old_size) { // Existing allocation is best fit evar? return ptr; + } /* * If the new size suits the tiny allocator and the pointer being resized * belongs to a tiny region, try to reallocate in-place. */ - if ((new_size + TINY_QUANTUM - 1) <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) { - if (tiny_region_for_ptr_no_lock(szone, ptr) != NULL) { - if (tiny_try_realloc_in_place(szone, ptr, old_size, new_size)) { + if (new_good_size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) { + if (old_size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) { + if (new_good_size <= (old_size >> 1)) { + /* + * Serious shrinkage (more than half). free() the excess. + */ + return tiny_try_shrink_in_place(szone, ptr, old_size, new_good_size); + } else if (new_good_size <= old_size) { + /* + * new_good_size smaller than old_size but not by much (less than half). + * Avoid thrashing at the expense of some wasted storage. + */ + return ptr; + } else if (tiny_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { // try to grow the allocation return ptr; } } /* - * If the new size suits the small allocator and the pointer being resized + * Else if the new size suits the small allocator and the pointer being resized * belongs to a small region, and we're not protecting the small allocations * try to reallocate in-place. */ - } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && - ((new_size + SMALL_QUANTUM - 1) <= szone->large_threshold) && - (small_region_for_ptr_no_lock(szone, ptr) != NULL)) { - if (small_try_realloc_in_place(szone, ptr, old_size, new_size)) { + } else if (new_good_size <= szone->large_threshold) { + if ((NUM_TINY_SLOTS - 1) * TINY_QUANTUM < old_size && old_size <= szone->large_threshold) { + if (new_good_size <= (old_size >> 1)) { + return small_try_shrink_in_place(szone, ptr, old_size, new_good_size); + } else if (new_good_size <= old_size) { + return ptr; + } else if (small_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { return ptr; } - + } /* - * If the allocation's a large allocation, try to reallocate in-place there. + * Else if the allocation's a large allocation, try to reallocate in-place there. */ - } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && - !(szone->debug_flags & SCALABLE_MALLOC_PURGEABLE) && - (old_size > szone->large_threshold)) { - if (large_try_realloc_in_place(szone, ptr, old_size, new_size)) { + } else if (!(szone->debug_flags & SCALABLE_MALLOC_PURGEABLE) && // purgeable needs fresh allocation + (old_size > szone->large_threshold) && + (new_good_size > szone->large_threshold)) { + if (new_good_size <= (old_size >> 1)) { + return large_try_shrink_in_place(szone, ptr, old_size, new_good_size); + } else if (new_good_size <= old_size) { + return ptr; + } else if (large_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { return ptr; } } @@ -5961,6 +6503,12 @@ szone_realloc(szone_t *szone, void *ptr, size_t new_size) /* * Can't reallocate in place for whatever reason; allocate a new buffer and copy. */ + if (new_good_size <= (old_size >> 1)) { + /* Serious shrinkage (more than half). FALL THROUGH to alloc/copy/free. */ + } else if (new_good_size <= old_size) { + return ptr; + } + new_ptr = szone_malloc(szone, new_size); if (new_ptr == NULL) return NULL; @@ -5969,9 +6517,10 @@ szone_realloc(szone_t *szone, void *ptr, size_t new_size) * If the allocation's large enough, try to copy using VM. If that fails, or * if it's too small, just copy by hand. */ - if ((old_size < szone->vm_copy_threshold) || - vm_copy(mach_task_self(), (vm_address_t)ptr, old_size, (vm_address_t)new_ptr)) - memcpy(new_ptr, ptr, old_size); + valid_size = MIN(old_size, new_size); + if ((valid_size < szone->vm_copy_threshold) || + vm_copy(mach_task_self(), (vm_address_t)ptr, valid_size, (vm_address_t)new_ptr)) + memcpy(new_ptr, ptr, valid_size); szone_free(szone, ptr); #if DEBUG_MALLOC @@ -6052,7 +6601,7 @@ szone_memalign(szone_t *szone, size_t alignment, size_t size) } else if ((NUM_TINY_SLOTS - 1)*TINY_QUANTUM < size && alignment <= SMALL_QUANTUM) { return szone_malloc(szone, size); // Trivially satisfied by small or large - } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (span <= szone->large_threshold)) { + } else if (span <= szone->large_threshold) { if (size <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) { size = (NUM_TINY_SLOTS - 1)*TINY_QUANTUM + TINY_QUANTUM; // ensure block allocated by small does not have a tiny-possible size @@ -6212,7 +6761,11 @@ szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) if (is_free) break; // a double free; let the standard free deal with it - tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize); + if (!tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize)) { + // Arrange to re-acquire magazine lock + tiny_mag_ptr = NULL; + tiny_region = NULL; + } to_be_freed[cc] = NULL; } else { // No region in this zone claims ptr; let the standard free deal with it @@ -6243,14 +6796,35 @@ szone_destroy(szone_t *szone) large_entry_t *large; vm_range_t range_to_deallocate; - /* destroy large entries cache */ +#if LARGE_CACHE + SZONE_LOCK(szone); + + /* disable any memory pressure responder */ + szone->flotsam_enabled = FALSE; + + // stack allocated copy of the death-row cache int idx = szone->large_entry_cache_oldest, idx_max = szone->large_entry_cache_newest; + large_entry_t local_entry_cache[LARGE_ENTRY_CACHE_SIZE]; + + memcpy((void *)local_entry_cache, (void *)szone->large_entry_cache, sizeof(local_entry_cache)); + + szone->large_entry_cache_oldest = szone->large_entry_cache_newest = 0; + szone->large_entry_cache[0].address = 0x0; + szone->large_entry_cache[0].size = 0; + szone->large_entry_cache_bytes = 0; + szone->large_entry_cache_reserve_bytes = 0; + + SZONE_UNLOCK(szone); + + // deallocate the death-row cache outside the zone lock while (idx != idx_max) { - deallocate_pages(szone, (void *) szone->large_entry_cache[idx].address, szone->large_entry_cache[idx].size, 0); + deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); if (++idx == LARGE_ENTRY_CACHE_SIZE) idx = 0; } - if (0 != szone->large_entry_cache[idx].address && 0 != szone->large_entry_cache[idx].size) - deallocate_pages(szone, (void *) szone->large_entry_cache[idx].address, szone->large_entry_cache[idx].size, 0); + if (0 != local_entry_cache[idx].address && 0 != local_entry_cache[idx].size) { + deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); + } +#endif /* destroy large entries */ index = szone->num_large_entries; @@ -6292,14 +6866,13 @@ szone_destroy(szone_t *szone) (void)pthread_key_delete(szone->cpu_id_key); deallocate_pages(szone, (void *)&(szone->tiny_magazines[-1]), TINY_MAGAZINE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES); deallocate_pages(szone, (void *)&(szone->small_magazines[-1]), SMALL_MAGAZINE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES); - deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES); + deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0); } static NOINLINE size_t szone_good_size(szone_t *szone, size_t size) { msize_t msize; - int guard_small = (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL; // Find a good size for this tiny allocation. if (size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) { @@ -6310,7 +6883,7 @@ szone_good_size(szone_t *szone, size_t size) } // Find a good size for this small allocation. - if (!guard_small && (size <= szone->large_threshold)) { + if (size <= szone->large_threshold) { msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); if (!msize) msize = 1; @@ -6463,6 +7036,7 @@ scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) mag_index_t mag_index; for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { + s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; t += szone->tiny_magazines[mag_index].mag_num_objects; u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; @@ -6472,6 +7046,7 @@ scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) info[5] = u; for (t = 0, u = 0, mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { + s += szone->small_magazines[mag_index].mag_bytes_free_at_start; s += szone->small_magazines[mag_index].mag_bytes_free_at_end; t += szone->small_magazines[mag_index].mag_num_objects; u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; @@ -6523,7 +7098,10 @@ szone_print(szone_t *szone, boolean_t verbose) region = szone->tiny_region_generation->hashed_regions[index]; if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(region); - print_tiny_region(verbose, region, (region == szone->tiny_magazines[mag_index].mag_last_region) ? + print_tiny_region(verbose, region, + (region == szone->tiny_magazines[mag_index].mag_last_region) ? + szone->tiny_magazines[mag_index].mag_bytes_free_at_start : 0, + (region == szone->tiny_magazines[mag_index].mag_last_region) ? szone->tiny_magazines[mag_index].mag_bytes_free_at_end : 0); } } @@ -6540,6 +7118,8 @@ szone_print(szone_t *szone, boolean_t verbose) if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(region); print_small_region(szone, verbose, region, + (region == szone->small_magazines[mag_index].mag_last_region) ? + szone->small_magazines[mag_index].mag_bytes_free_at_start : 0, (region == szone->small_magazines[mag_index].mag_last_region) ? szone->small_magazines[mag_index].mag_bytes_free_at_end : 0); } @@ -6617,6 +7197,49 @@ szone_locked(szone_t *szone) return 0; } +static size_t +szone_pressure_relief(szone_t *szone, size_t goal) +{ +#if LARGE_CACHE + if (!szone->flotsam_enabled) + return 0; + + SZONE_LOCK(szone); + + // stack allocated copy of the death-row cache + int idx = szone->large_entry_cache_oldest, idx_max = szone->large_entry_cache_newest; + large_entry_t local_entry_cache[LARGE_ENTRY_CACHE_SIZE]; + + memcpy((void *)local_entry_cache, (void *)szone->large_entry_cache, sizeof(local_entry_cache)); + + szone->large_entry_cache_oldest = szone->large_entry_cache_newest = 0; + szone->large_entry_cache[0].address = 0x0; + szone->large_entry_cache[0].size = 0; + szone->large_entry_cache_bytes = 0; + szone->large_entry_cache_reserve_bytes = 0; + + szone->flotsam_enabled = FALSE; + + SZONE_UNLOCK(szone); + + // deallocate the death-row cache outside the zone lock + size_t total = 0; + while (idx != idx_max) { + deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); + total += local_entry_cache[idx].size; + if (++idx == LARGE_ENTRY_CACHE_SIZE) idx = 0; + } + if (0 != local_entry_cache[idx].address && 0 != local_entry_cache[idx].size) { + deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); + total += local_entry_cache[idx].size; + } + MAGMALLOC_PRESSURERELIEF((void *)szone, goal, total); // DTrace USDT Probe + return total; +#else + return 0; +#endif +} + boolean_t scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone) { @@ -6631,6 +7254,7 @@ scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsign mag_index_t mag_index; for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { + s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; t += szone->tiny_magazines[mag_index].mag_num_objects; u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; @@ -6650,6 +7274,7 @@ scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsign mag_index_t mag_index; for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { + s += szone->small_magazines[mag_index].mag_bytes_free_at_start; s += szone->small_magazines[mag_index].mag_bytes_free_at_end; t += szone->small_magazines[mag_index].mag_num_objects; u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; @@ -6686,12 +7311,14 @@ szone_statistics(szone_t *szone, malloc_statistics_t *stats) mag_index_t mag_index; for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { + s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; t += szone->tiny_magazines[mag_index].mag_num_objects; u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; } for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { + s += szone->small_magazines[mag_index].mag_bytes_free_at_start; s += szone->small_magazines[mag_index].mag_bytes_free_at_end; t += szone->small_magazines[mag_index].mag_num_objects; u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; @@ -6730,8 +7357,10 @@ void zeroify_scalable_zone(malloc_zone_t *zone) szone_t *szone = (szone_t *)zone; if (szone) { + mprotect(szone, sizeof(szone->basic_zone), PROT_READ | PROT_WRITE); szone->basic_zone.malloc = (void *)legacy_zeroing_large_malloc; szone->basic_zone.valloc = (void *)legacy_zeroing_large_valloc; + mprotect(szone, sizeof(szone->basic_zone), PROT_READ); } } @@ -6745,6 +7374,7 @@ static const struct malloc_introspection_t szone_introspect = { (void *)szone_force_unlock, (void *)szone_statistics, (void *)szone_locked, + NULL, NULL, NULL, NULL, /* Zone enumeration version 7 and forward. */ }; // marked as const to spare the DATA section malloc_zone_t * @@ -6752,8 +7382,6 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) { szone_t *szone; uint64_t hw_memsize = 0; - size_t uint64_t_size = sizeof(hw_memsize); - int err; /* * Sanity-check our build-time assumptions about the size of a page. @@ -6772,10 +7400,8 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) } #endif - /* get memory for the zone, which is now separate from any region. - add guard pages to prevent walking from any other vm allocations - to here and overwriting the function pointers in basic_zone. */ - szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, SCALABLE_MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC); + /* get memory for the zone. */ + szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC); if (!szone) return NULL; @@ -6810,8 +7436,15 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) * upon the amount of memory in the system. Switch to a larger number of * free list entries at 1GB. */ +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) + if ((hw_memsize = *(uint64_t *)(uintptr_t)_COMM_PAGE_MEMORY_SIZE) >= (1ULL << 30)) +#else + size_t uint64_t_size = sizeof(hw_memsize); + if (0 == sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0) && - hw_memsize >= (1ULL << 30)) { + hw_memsize >= (1ULL << 30)) +#endif + { szone->is_largemem = 1; szone->num_small_slots = NUM_SMALL_SLOTS_LARGEMEM; szone->large_threshold = LARGE_THRESHOLD_LARGEMEM; @@ -6823,7 +7456,8 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) szone->vm_copy_threshold = VM_COPY_THRESHOLD; } #if LARGE_CACHE - szone->large_entry_cache_hoard_lmit = hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%] + szone->large_entry_cache_reserve_limit = + hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%] /* Reset protection when returning a previous large allocation? */ int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System"); @@ -6834,13 +7468,36 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) #endif // Initialize the security token. -#if __LP64__ - szone->cookie = ((uintptr_t)arc4random() << 32) | (uintptr_t)arc4random(); + szone->cookie = (uintptr_t)malloc_entropy[0]; + + // Prepare ASLR +#if __i386__ || __LP64__ || TARGET_OS_EMBEDDED +#if __i386__ + uintptr_t stackbase = 0x8fe00000; + int entropic_bits = 3; +#elif __LP64__ + uintptr_t stackbase = USRSTACK64; + int entropic_bits = 16; +#else + uintptr_t stackbase = USRSTACK; + int entropic_bits = 3; +#endif + if (0 != _dyld_get_image_slide((const struct mach_header*)_NSGetMachExecuteHeader())) { + if (0 == entropic_address) { + uintptr_t t = stackbase - MAXSSIZ - ((uintptr_t) (malloc_entropy[1] & ((1 << entropic_bits) - 1)) << SMALL_BLOCKS_ALIGN); + (void)__sync_bool_compare_and_swap(&entropic_limit, 0, t); // Just one initialization please + (void)__sync_bool_compare_and_swap(&entropic_address, 0, t - ENTROPIC_KABILLION); // Just one initialization please + } + debug_flags &= ~DISABLE_ASLR; + } else { + debug_flags |= DISABLE_ASLR; + } + #else - szone->cookie = arc4random(); + debug_flags |= DISABLE_ASLR; #endif - szone->basic_zone.version = 6; + szone->basic_zone.version = 8; szone->basic_zone.size = (void *)szone_size; szone->basic_zone.malloc = (void *)szone_malloc; szone->basic_zone.calloc = (void *)szone_calloc; @@ -6853,6 +7510,12 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) szone->basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; szone->basic_zone.memalign = (void *)szone_memalign; szone->basic_zone.free_definite_size = (void *)szone_free_definite_size; + szone->basic_zone.pressure_relief = (void *)szone_pressure_relief; + + szone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */ + szone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */ + mprotect(szone, sizeof(szone->basic_zone), PROT_READ); /* Prevent overwriting the function pointers in basic_zone. */ + szone->debug_flags = debug_flags; LOCK_INIT(szone->large_szone_lock); @@ -6864,16 +7527,25 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) zeroify_scalable_zone((malloc_zone_t *)szone); #endif +#if defined(__i386__) || defined(__x86_64__) + szone->cpu_id_key = (pthread_key_t) -1; // Unused. _COMM_PAGE_CPU_NUMBER preferred. +#else + int err; if ((err = pthread_key_create(&(szone->cpu_id_key), NULL))) { malloc_printf("*** ERROR -pthread_key_create failure err=%d.\n", err); szone->cpu_id_key = (pthread_key_t) -1; } +#endif // Query the number of configured processors. // Uniprocessor case gets just one tiny and one small magazine (whose index is zero). This gives // the same behavior as the original scalable malloc. MP gets per-CPU magazines // that scale (way) better. +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) + int nproc = *(uint8_t *)(uintptr_t)_COMM_PAGE_NCPUS; +#else int nproc = sysconf(_SC_NPROCESSORS_CONF); +#endif szone->num_tiny_magazines = (nproc > 1) ? MIN(nproc, TINY_MAX_MAGAZINES) : 1; // FIXME vm_allocate() based on number of configured CPUs @@ -6960,12 +7632,8 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) static size_t purgeable_size(szone_t *szone, const void *ptr) { - size_t t = szone_size_try_large(szone, ptr); - - if (t) - return t; - else - return szone_size(szone->helper_zone, ptr); + // Only claim our large allocations, leave the shared tiny/small for the helper zone to claim. + return szone_size_try_large(szone, ptr); } static void * @@ -7042,10 +7710,61 @@ purgeable_free_definite_size(szone_t *szone, void *ptr, size_t size) static void * purgeable_realloc(szone_t *szone, void *ptr, size_t new_size) { - if (new_size <= szone->large_threshold) - return szone_realloc(szone->helper_zone, ptr, new_size); - else - return szone_realloc(szone, ptr, new_size); + size_t old_size; + + if (NULL == ptr) { + // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. + return purgeable_malloc(szone, new_size); + } else if (0 == new_size) { + // If size is 0 and ptr is not a null pointer, the object pointed to is freed. + purgeable_free(szone, ptr); + // If size is 0, either a null pointer or a unique pointer that can be successfully passed + // to free() shall be returned. + return purgeable_malloc(szone, 1); + } + + old_size = purgeable_size(szone, ptr); // Now ptr can be safely size()'d + if (!old_size) + old_size = szone_size(szone->helper_zone, ptr); + + if (!old_size) { + szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL); + return NULL; + } + + // Distinguish 4 cases: {oldsize, newsize} x { <= , > large_threshold } + // and deal with the allocation crossing from the purgeable zone to the helper zone and vice versa. + if (old_size <= szone->large_threshold) { + if (new_size <= szone->large_threshold) + return szone_realloc(szone->helper_zone, ptr, new_size); + else { + // allocation crosses from helper to purgeable zone + void * new_ptr = purgeable_malloc(szone, new_size); + if (new_ptr) { + memcpy(new_ptr, ptr, old_size); + szone_free_definite_size(szone->helper_zone, ptr, old_size); + } + return new_ptr; // in state VM_PURGABLE_NONVOLATILE + } + } else { + if (new_size <= szone->large_threshold) { + // allocation crosses from purgeable to helper zone + void * new_ptr = szone_malloc(szone->helper_zone, new_size); + if (new_ptr) { + memcpy(new_ptr, ptr, new_size); + purgeable_free_definite_size(szone, ptr, old_size); + } + return new_ptr; + } else { + void * new_ptr = purgeable_malloc(szone, new_size); + if (new_ptr) { + memcpy(new_ptr, ptr, MIN(old_size, new_size)); + purgeable_free_definite_size(szone, ptr, old_size); + } + return new_ptr; // in state VM_PURGABLE_NONVOLATILE + } + } + /* NOTREACHED */ } static void @@ -7068,7 +7787,7 @@ purgeable_destroy(szone_t *szone) deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0); /* Now destroy the separate szone region */ - deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES); + deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0); } static unsigned @@ -7171,6 +7890,12 @@ purgeable_locked(szone_t *szone) return 0; } +static size_t +purgeable_pressure_relief(szone_t *szone, size_t goal) +{ + return szone_pressure_relief(szone, goal) + szone_pressure_relief(szone->helper_zone, goal); +} + static const struct malloc_introspection_t purgeable_introspect = { (void *)purgeable_ptr_in_use_enumerator, (void *)purgeable_good_size, @@ -7181,17 +7906,17 @@ static const struct malloc_introspection_t purgeable_introspect = { (void *)purgeable_force_unlock, (void *)purgeable_statistics, (void *)purgeable_locked, + NULL, NULL, NULL, NULL, /* Zone enumeration version 7 and forward. */ }; // marked as const to spare the DATA section -malloc_zone_t * +__private_extern__ malloc_zone_t * create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, unsigned debug_flags) { szone_t *szone; + uint64_t hw_memsize = 0; - /* get memory for the zone, which is now separate from any region. - add guard pages to prevent walking from any other vm allocations - to here and overwriting the function pointers in basic_zone. */ - szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, SCALABLE_MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC); + /* get memory for the zone. */ + szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC); if (!szone) return NULL; @@ -7201,12 +7926,22 @@ create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, u szone->log_address = ~0; #endif +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) + hw_memsize = *(uint64_t *)(uintptr_t)_COMM_PAGE_MEMORY_SIZE; +#else + size_t uint64_t_size = sizeof(hw_memsize); + + sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0); +#endif /* Purgeable zone does not participate in the adaptive "largemem" sizing. */ szone->is_largemem = 0; szone->large_threshold = LARGE_THRESHOLD; szone->vm_copy_threshold = VM_COPY_THRESHOLD; #if LARGE_CACHE + szone->large_entry_cache_reserve_limit = + hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%] + /* Reset protection when returning a previous large allocation? */ int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System"); if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 112) /* CFSystemVersionSnowLeopard */) @@ -7215,7 +7950,7 @@ create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, u szone->large_legacy_reset_mprotect = FALSE; #endif - szone->basic_zone.version = 6; + szone->basic_zone.version = 8; szone->basic_zone.size = (void *)purgeable_size; szone->basic_zone.malloc = (void *)purgeable_malloc; szone->basic_zone.calloc = (void *)purgeable_calloc; @@ -7228,9 +7963,14 @@ create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, u szone->basic_zone.introspect = (struct malloc_introspection_t *)&purgeable_introspect; szone->basic_zone.memalign = (void *)purgeable_memalign; szone->basic_zone.free_definite_size = (void *)purgeable_free_definite_size; + szone->basic_zone.pressure_relief = (void *)purgeable_pressure_relief; + szone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */ + szone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */ + mprotect(szone, sizeof(szone->basic_zone), PROT_READ); /* Prevent overwriting the function pointers in basic_zone. */ + szone->debug_flags = debug_flags | SCALABLE_MALLOC_PURGEABLE; - + /* Purgeable zone does not support SCALABLE_MALLOC_ADD_GUARD_PAGES. */ if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) { _malloc_printf(ASL_LEVEL_INFO, "purgeable zone does not support guard pages\n"); @@ -7264,7 +8004,7 @@ legacy_valloc(szone_t *szone, size_t size) return ptr; } -malloc_zone_t * +__private_extern__ malloc_zone_t * create_legacy_scalable_zone(size_t initial_size, unsigned debug_flags) { malloc_zone_t *mzone = create_scalable_zone(initial_size, debug_flags); @@ -7278,8 +8018,10 @@ create_legacy_scalable_zone(size_t initial_size, unsigned debug_flags) szone->large_threshold = LARGE_THRESHOLD; szone->vm_copy_threshold = VM_COPY_THRESHOLD; + mprotect(szone, sizeof(szone->basic_zone), PROT_READ | PROT_WRITE); szone->basic_zone.valloc = (void *)legacy_valloc; szone->basic_zone.free_definite_size = NULL; + mprotect(szone, sizeof(szone->basic_zone), PROT_READ); return mzone; } diff --git a/gen/magmallocProvider.d b/gen/magmallocProvider.d index ef17b19..11b7add 100644 --- a/gen/magmallocProvider.d +++ b/gen/magmallocProvider.d @@ -1,10 +1,11 @@ provider magmalloc { probe refreshIndex(void *, int, int); - probe depotRegion(void *, int, int); - probe recircRegion(void *, int, int); - probe allocRegion(void *, int); - probe deallocRegion(void *, void *); + probe depotRegion(void *, int, void *, int, int); + probe recircRegion(void *, int, void *, int, int); + probe allocRegion(void *, int, void *, int); + probe deallocRegion(void *, void *, int); probe madvfreeRegion(void *, void *, void *, int); + probe pressureRelief(void *, int, int); probe mallocErrorBreak(); }; diff --git a/gen/malloc.3 b/gen/malloc.3 index a75512a..542d4cc 100644 --- a/gen/malloc.3 +++ b/gen/malloc.3 @@ -128,6 +128,8 @@ is zero and is not .Dv NULL , a new, minimum sized object is allocated and the original object is freed. +When extending a region allocated with calloc(3), realloc(3) does not guarantee +that the additional memory is also zero-filled. .Pp The .Fn reallocf diff --git a/gen/malloc.c b/gen/malloc.c index e89051b..497a9b5 100644 --- a/gen/malloc.c +++ b/gen/malloc.c @@ -23,6 +23,7 @@ #include #include "magmallocProvider.h" +#include /* for NSVersionOfLinkTimeLibrary() */ #import #import @@ -43,6 +44,7 @@ #import "stack_logging.h" #import "malloc_printf.h" #import "_simple.h" +#import "CrashReporterClient.h" /* * MALLOC_ABSOLUTE_MAX_SIZE - There are many instances of addition to a @@ -66,7 +68,9 @@ __private_extern__ pthread_lock_t _malloc_lock = 0; // initialized in __libc_ini /* The following variables are exported for the benefit of performance tools * * It should always be safe to first read malloc_num_zones, then read - * malloc_zones without taking the lock, if only iteration is required + * malloc_zones without taking the lock, if only iteration is required and + * provided that when malloc_destroy_zone is called all prior operations on that + * zone are complete and no further calls referencing that zone can be made. */ unsigned malloc_num_zones = 0; unsigned malloc_num_zones_allocated = 0; @@ -101,30 +105,105 @@ static const char Malloc_Facility[] = "com.apple.Libsystem.malloc"; #define MALLOC_LOCK() LOCK(_malloc_lock) #define MALLOC_UNLOCK() UNLOCK(_malloc_lock) +/* + * Counters that coordinate zone destruction (in malloc_zone_unregister) with + * find_registered_zone (here abbreviated as FRZ). + */ +static int counterAlice = 0, counterBob = 0; +static int *pFRZCounterLive= &counterAlice, *pFRZCounterDrain = &counterBob; + #define MALLOC_LOG_TYPE_ALLOCATE stack_logging_type_alloc #define MALLOC_LOG_TYPE_DEALLOCATE stack_logging_type_dealloc #define MALLOC_LOG_TYPE_HAS_ZONE stack_logging_flag_zone #define MALLOC_LOG_TYPE_CLEARED stack_logging_flag_cleared /********* Utilities ************/ +__private_extern__ uint64_t malloc_entropy[2] = {0, 0}; + +void __malloc_entropy_setup(const char *apple[]) __attribute__ ((visibility ("hidden"))); + +static int +__entropy_from_kernel(const char *str) +{ + unsigned long long val; + char tmp[20], *p; + int idx = 0; + + /* Skip over key to the first value */ + str = strchr(str, '='); + if (str == NULL) + return 0; + str++; + + while (str && idx < sizeof(malloc_entropy)/sizeof(malloc_entropy[0])) { + strlcpy(tmp, str, 20); + p = strchr(tmp, ','); + if (p) *p = '\0'; + val = strtoull(tmp, NULL, 0); + malloc_entropy[idx] = (uint64_t)val; + idx++; + if ((str = strchr(str, ',')) != NULL) + str++; + } + return idx; +} + +void +__malloc_entropy_setup(const char *apple[]) +{ + const char **p; + for (p = apple; p && *p; p++) { + if (strstr(*p, "malloc_entropy") == *p) { + if (sizeof(malloc_entropy)/sizeof(malloc_entropy[0]) == __entropy_from_kernel(*p)) + return; + else + break; + } + } + + malloc_entropy[0] = ((uint64_t)arc4random()) << 32 | ((uint64_t)arc4random()); + malloc_entropy[1] = ((uint64_t)arc4random()) << 32 | ((uint64_t)arc4random()); + return; +} static inline malloc_zone_t * find_registered_zone(const void *, size_t *) __attribute__((always_inline)); static inline malloc_zone_t * find_registered_zone(const void *ptr, size_t *returned_size) { // Returns a zone which contains ptr, else NULL - unsigned index; - malloc_zone_t **zones = malloc_zones; + + if (0 == malloc_num_zones) { + if (returned_size) *returned_size = 0; + return NULL; + } + + // The default zone is registered in malloc_zones[0]. There's no danger that it will ever be unregistered. + // So don't advance the FRZ counter yet. + malloc_zone_t *zone = malloc_zones[0]; + size_t size = zone->size(zone, ptr); + if (size) { // Claimed by this zone? + if (returned_size) *returned_size = size; + return zone; + } + + int *pFRZCounter = pFRZCounterLive; // Capture pointer to the counter of the moment + __sync_fetch_and_add(pFRZCounter, 1); // Advance this counter -- our thread is in FRZ - for (index = 0; index < malloc_num_zones; ++index, ++zones) { - malloc_zone_t *zone = *zones; - size_t size = zone->size(zone, ptr); + unsigned index; + unsigned limit = malloc_num_zones; + malloc_zone_t **zones = &malloc_zones[1]; + + for (index = 1; index < limit; ++index, ++zones) { + zone = *zones; + size = zone->size(zone, ptr); if (size) { // Claimed by this zone? if (returned_size) *returned_size = size; + __sync_fetch_and_sub(pFRZCounter, 1); // our thread is leaving FRZ return zone; } } // Unclaimed by any zone. if (returned_size) *returned_size = 0; + __sync_fetch_and_sub(pFRZCounter, 1); // our thread is leaving FRZ return NULL; } @@ -206,13 +285,13 @@ malloc_zone_register_while_locked(malloc_zone_t *zone) { /* If we don't need to reallocate zones, we need to briefly change the * page protection the malloc zones to allow writes */ protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); - vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ | VM_PROT_WRITE); + mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); } malloc_zones[malloc_num_zones++] = zone; /* Finally, now that the zone is registered, disallow write access to the * malloc_zones array */ - vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ); + mprotect(malloc_zones, protect_size, PROT_READ); //_malloc_printf(ASL_LEVEL_INFO, "Registered malloc_zone %p in malloc_zones %p [%u zones, %u bytes]\n", zone, malloc_zones, malloc_num_zones, protect_size); } @@ -232,14 +311,15 @@ _malloc_initialize(void) { if (n != 0) { // make the default first, for efficiency unsigned protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); malloc_zone_t *hold = malloc_zones[0]; + if(hold->zone_name && strcmp(hold->zone_name, "DefaultMallocZone") == 0) { - free((void *)hold->zone_name); - hold->zone_name = NULL; + malloc_set_zone_name(hold, NULL); } - vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ | VM_PROT_WRITE); + + mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); malloc_zones[0] = malloc_zones[n]; malloc_zones[n] = hold; - vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ); + mprotect(malloc_zones, protect_size, PROT_READ); } // _malloc_printf(ASL_LEVEL_INFO, "%d registered zones\n", malloc_num_zones); // _malloc_printf(ASL_LEVEL_INFO, "malloc_zones is at %p; malloc_num_zones is at %p\n", (unsigned)&malloc_zones, (unsigned)&malloc_num_zones); @@ -260,12 +340,39 @@ malloc_default_zone(void) { return inline_malloc_default_zone(); } +static inline malloc_zone_t *inline_malloc_default_scalable_zone(void) __attribute__((always_inline)); +static inline malloc_zone_t * +inline_malloc_default_scalable_zone(void) { + unsigned index; + + if (malloc_def_zone_state < 2) _malloc_initialize(); + // _malloc_printf(ASL_LEVEL_INFO, "In inline_malloc_default_scalable_zone with %d %d\n", malloc_num_zones, malloc_has_debug_zone); + + MALLOC_LOCK(); + for (index = 0; index < malloc_num_zones; ++index) { + malloc_zone_t *z = malloc_zones[index]; + + if(z->zone_name && strcmp(z->zone_name, "DefaultMallocZone") == 0) { + MALLOC_UNLOCK(); + return z; + } + } + MALLOC_UNLOCK(); + + malloc_printf("*** malloc_default_scalable_zone() failed to find 'DefaultMallocZone'\n"); + return NULL; // FIXME: abort() instead? +} + malloc_zone_t * malloc_default_purgeable_zone(void) { static malloc_zone_t *dpz; if (!dpz) { - malloc_zone_t *tmp = create_purgeable_zone(0, malloc_default_zone(), malloc_debug_flags); + // + // PR_7288598: Must pass a *scalable* zone (szone) as the helper for create_purgeable_zone(). + // Take care that the zone so obtained is not subject to interposing. + // + malloc_zone_t *tmp = create_purgeable_zone(0, inline_malloc_default_scalable_zone(), malloc_debug_flags); malloc_zone_register(tmp); malloc_set_zone_name(tmp, "DefaultPurgeableMallocZone"); if (!__sync_bool_compare_and_swap(&dpz, NULL, tmp)) @@ -297,7 +404,11 @@ set_flags_from_environment(void) { #if __LP64__ malloc_debug_flags = SCALABLE_MALLOC_ABORT_ON_CORRUPTION; // Set always on 64-bit processes #else - malloc_debug_flags = 0; + int libSystemVersion = NSVersionOfLinkTimeLibrary("System"); + if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 126) /* CFSystemVersionBarolo */) + malloc_debug_flags = 0; + else + malloc_debug_flags = SCALABLE_MALLOC_ABORT_ON_CORRUPTION; #endif stack_logging_enable_logging = 0; stack_logging_dontcompact = 0; @@ -332,7 +443,7 @@ set_flags_from_environment(void) { } } if (getenv("MallocGuardEdges")) { - malloc_debug_flags = SCALABLE_MALLOC_ADD_GUARD_PAGES; + malloc_debug_flags |= SCALABLE_MALLOC_ADD_GUARD_PAGES; _malloc_printf(ASL_LEVEL_INFO, "protecting edges\n"); if (getenv("MallocDoNotProtectPrelude")) { malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_PRELUDE; @@ -389,8 +500,11 @@ set_flags_from_environment(void) { #if __LP64__ /* initialization above forces SCALABLE_MALLOC_ABORT_ON_CORRUPTION of 64-bit processes */ #else - if (getenv("MallocCorruptionAbort")) { // Set from an environment variable in 32-bit processes - malloc_debug_flags |= SCALABLE_MALLOC_ABORT_ON_CORRUPTION; + flag = getenv("MallocCorruptionAbort"); + if (flag && (flag[0] == '0')) { // Set from an environment variable in 32-bit processes + malloc_debug_flags &= ~SCALABLE_MALLOC_ABORT_ON_CORRUPTION; + } else if (flag) { + malloc_debug_flags |= SCALABLE_MALLOC_ABORT_ON_CORRUPTION; } #endif flag = getenv("MallocCheckHeapStart"); @@ -481,13 +595,12 @@ malloc_create_legacy_default_zone(void) // malloc_zone_t *hold = malloc_zones[0]; if(hold->zone_name && strcmp(hold->zone_name, "DefaultMallocZone") == 0) { - free((void *)hold->zone_name); - hold->zone_name = NULL; + malloc_set_zone_name(hold, NULL); } malloc_set_zone_name(zone, "DefaultMallocZone"); unsigned protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); - vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ | VM_PROT_WRITE); + mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); // assert(zone == malloc_zones[malloc_num_zones - 1]; for (i = malloc_num_zones - 1; i > 0; --i) { @@ -495,12 +608,13 @@ malloc_create_legacy_default_zone(void) } malloc_zones[0] = zone; - vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ); + mprotect(malloc_zones, protect_size, PROT_READ); MALLOC_UNLOCK(); } void malloc_destroy_zone(malloc_zone_t *zone) { + malloc_set_zone_name(zone, NULL); // Deallocate zone name wherever it may reside PR_7701095 malloc_zone_unregister(zone); zone->destroy(zone); } @@ -510,15 +624,22 @@ __private_extern__ void __malloc_check_env_name(const char *name) { MALLOC_LOCK(); + /* + * + * + * 2. malloc will no longer take notice of *programmatic* changes to the MALLOC_* environment variables + * (i.e. calls to putenv() or setenv() that manipulate these environment variables.) + * + */ +#if 0 if(malloc_def_zone_state == 2 && strncmp(name, "Malloc", 6) == 0) malloc_def_zone_state = 1; +#endif MALLOC_UNLOCK(); } /********* Block creation and manipulation ************/ -extern const char *__crashreporter_info__; - static void internal_check(void) { static vm_address_t *frames = NULL; @@ -556,7 +677,7 @@ internal_check(void) { malloc_printf("*** Recommend using 'setenv MallocCheckHeapStart %d; setenv MallocCheckHeapEach %d' to narrow down failure\n", recomm_start, recomm_each); } if (malloc_check_abort) { - __crashreporter_info__ = b ? _simple_string(b) : "*** MallocCheckHeap: FAILED check"; + CRSetCrashLogMessage(b ? _simple_string(b) : "*** MallocCheckHeap: FAILED check"); abort(); } else if (b) _simple_sfree(b); @@ -584,7 +705,8 @@ malloc_zone_malloc(malloc_zone_t *zone, size_t size) { return NULL; } ptr = zone->malloc(zone, size); - if (malloc_logger) malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); + if (malloc_logger) + malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); return ptr; } @@ -598,7 +720,9 @@ malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) { return NULL; } ptr = zone->calloc(zone, num_items, size); - if (malloc_logger) malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE | MALLOC_LOG_TYPE_CLEARED, (uintptr_t)zone, (uintptr_t)(num_items * size), 0, (uintptr_t)ptr, 0); + if (malloc_logger) + malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE | MALLOC_LOG_TYPE_CLEARED, (uintptr_t)zone, (uintptr_t)(num_items * size), 0, + (uintptr_t)ptr, 0); return ptr; } @@ -612,7 +736,8 @@ malloc_zone_valloc(malloc_zone_t *zone, size_t size) { return NULL; } ptr = zone->valloc(zone, size); - if (malloc_logger) malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); + if (malloc_logger) + malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); return ptr; } @@ -626,13 +751,16 @@ malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) { return NULL; } new_ptr = zone->realloc(zone, ptr, size); - if (malloc_logger) malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, (uintptr_t)size, (uintptr_t)new_ptr, 0); + if (malloc_logger) + malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, (uintptr_t)size, + (uintptr_t)new_ptr, 0); return new_ptr; } void malloc_zone_free(malloc_zone_t *zone, void *ptr) { - if (malloc_logger) malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, 0, 0, 0); + if (malloc_logger) + malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, 0, 0, 0); if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } @@ -641,7 +769,8 @@ malloc_zone_free(malloc_zone_t *zone, void *ptr) { static void malloc_zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size) { - if (malloc_logger) malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, 0, 0, 0); + if (malloc_logger) + malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, 0, 0, 0); if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } @@ -674,7 +803,8 @@ malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) { return NULL; } ptr = zone->memalign(zone, alignment, size); - if (malloc_logger) malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); + if (malloc_logger) + malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); return ptr; } @@ -702,16 +832,28 @@ malloc_zone_unregister(malloc_zone_t *z) { // Modify the page to be allow write access, so that we can update the // malloc_zones array. size_t protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); - vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ | VM_PROT_WRITE); + mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); + + // If we found a match, replace it with the entry at the end of the list, shrink the list, + // and leave the end of the list intact to avoid racing with find_registered_zone(). - // If we found a match, swap it with the entry on the back of the list - // and null out the back of the list. malloc_zones[index] = malloc_zones[malloc_num_zones - 1]; - malloc_zones[malloc_num_zones - 1] = NULL; --malloc_num_zones; - vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ); + mprotect(malloc_zones, protect_size, PROT_READ); + + // Exchange the roles of the FRZ counters. The counter that has captured the number of threads presently + // executing *inside* find_regiatered_zone is swapped with the counter drained to zero last time through. + // The former is then allowed to drain to zero while this thread yields. + int *p = pFRZCounterLive; + pFRZCounterLive = pFRZCounterDrain; + pFRZCounterDrain = p; + __sync_synchronize(); // Full memory barrier + + while (0 != *pFRZCounterDrain) { pthread_yield_np(); } + MALLOC_UNLOCK(); + return; } MALLOC_UNLOCK(); @@ -721,13 +863,23 @@ malloc_zone_unregister(malloc_zone_t *z) { void malloc_set_zone_name(malloc_zone_t *z, const char *name) { char *newName; + + mprotect(z, sizeof(malloc_zone_t), PROT_READ | PROT_WRITE); if (z->zone_name) { free((char *)z->zone_name); z->zone_name = NULL; } - newName = malloc_zone_malloc(z, strlen(name) + 1); - strcpy(newName, name); - z->zone_name = (const char *)newName; + if (name) { + size_t buflen = strlen(name) + 1; + newName = malloc_zone_malloc(z, buflen); + if (newName) { + strlcpy(newName, name, buflen); + z->zone_name = (const char *)newName; + } else { + z->zone_name = NULL; + } + } + mprotect(z, sizeof(malloc_zone_t), PROT_READ); } const char * @@ -824,8 +976,16 @@ free(void *ptr) { malloc_printf("*** error for object %p: pointer being freed was not allocated\n" "*** set a breakpoint in malloc_error_break to debug\n", ptr); malloc_error_break(); - if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION|SCALABLE_MALLOC_ABORT_ON_ERROR))) - abort(); + if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION|SCALABLE_MALLOC_ABORT_ON_ERROR))) { + _SIMPLE_STRING b = _simple_salloc(); + if (b) { + _simple_sprintf(b, "*** error for object %p: pointer being freed was not allocated\n", ptr); + CRSetCrashLogMessage(_simple_string(b)); + } else { + CRSetCrashLogMessage("*** error: pointer being freed was not allocated\n"); + } + abort(); + } } else if (zone->version >= 6 && zone->free_definite_size) malloc_zone_free_definite_size(zone, ptr, size); else @@ -834,7 +994,7 @@ free(void *ptr) { void * realloc(void *in_ptr, size_t new_size) { - void *retval; + void *retval = NULL; void *old_ptr; malloc_zone_t *zone; size_t old_size = 0; @@ -852,13 +1012,23 @@ realloc(void *in_ptr, size_t new_size) { retval = malloc_zone_malloc(inline_malloc_default_zone(), new_size); } else { zone = find_registered_zone(old_ptr, &old_size); - if (zone && old_size >= new_size) - return old_ptr; - - if (!zone) - zone = inline_malloc_default_zone(); - - retval = malloc_zone_realloc(zone, old_ptr, new_size); + if (!zone) { + malloc_printf("*** error for object %p: pointer being realloc'd was not allocated\n" + "*** set a breakpoint in malloc_error_break to debug\n", old_ptr); + malloc_error_break(); + if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION|SCALABLE_MALLOC_ABORT_ON_ERROR))) { + _SIMPLE_STRING b = _simple_salloc(); + if (b) { + _simple_sprintf(b, "*** error for object %p: pointer being realloc'd was not allocated\n", old_ptr); + CRSetCrashLogMessage(_simple_string(b)); + } else { + CRSetCrashLogMessage("*** error: pointer being realloc'd was not allocated\n"); + } + abort(); + } + } else { + retval = malloc_zone_realloc(zone, old_ptr, new_size); + } } if (retval == NULL) { errno = ENOMEM; @@ -995,12 +1165,46 @@ malloc_make_nonpurgeable(void *ptr) { return 0; } +size_t malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal) +{ + if (!zone) { + unsigned index = 0; + size_t total = 0; + + // Take lock to defend against malloc_destroy_zone() + MALLOC_LOCK(); + while (index < malloc_num_zones) { + zone = malloc_zones[index++]; + if (zone->version < 8) + continue; + if (NULL == zone->pressure_relief) + continue; + if (0 == goal) /* Greedy */ + total += zone->pressure_relief(zone, 0); + else if (goal > total) + total += zone->pressure_relief(zone, goal - total); + else /* total >= goal */ + break; + } + MALLOC_UNLOCK(); + return total; + } else { + // Assumes zone is not destroyed for the duration of this call + if (zone->version < 8) + return 0; + if (NULL == zone->pressure_relief) + return 0; + return zone->pressure_relief(zone, goal); + } +} + /********* Batch methods ************/ unsigned malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested) { unsigned (*batch_malloc)(malloc_zone_t *, size_t, void **, unsigned) = zone-> batch_malloc; - if (! batch_malloc) return 0; + if (! batch_malloc) + return 0; if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } @@ -1171,10 +1375,10 @@ DefaultMallocError(int x) { if (b) { _simple_sprintf(b, "*** error %d", x); malloc_printf("%s\n", _simple_string(b)); - __crashreporter_info__ = _simple_string(b); + CRSetCrashLogMessage(_simple_string(b)); } else { _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error %d", x); - __crashreporter_info__ = "*** DefaultMallocError called"; + CRSetCrashLogMessage("*** DefaultMallocError called"); } abort(); #endif @@ -1249,6 +1453,62 @@ mstats(void) return(m); } +boolean_t +malloc_zone_enable_discharge_checking(malloc_zone_t *zone) +{ + if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields. + return FALSE; + if (NULL == zone->introspect->enable_discharge_checking) + return FALSE; + return zone->introspect->enable_discharge_checking(zone); +} + +void +malloc_zone_disable_discharge_checking(malloc_zone_t *zone) +{ + if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields. + return; + if (NULL == zone->introspect->disable_discharge_checking) + return; + zone->introspect->disable_discharge_checking(zone); +} + +void +malloc_zone_discharge(malloc_zone_t *zone, void *memory) +{ + if (NULL == zone) + zone = malloc_zone_from_ptr(memory); + if (NULL == zone) + return; + if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields. + return; + if (NULL == zone->introspect->discharge) + return; + zone->introspect->discharge(zone, memory); +} + +void +malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info)) +{ + if (!zone) { + unsigned index = 0; + while (index < malloc_num_zones) { + zone = malloc_zones[index++]; + if (zone->version < 7) + continue; + if (NULL == zone->introspect->enumerate_discharged_pointers) + continue; + zone->introspect->enumerate_discharged_pointers(zone, report_discharged); + } + } else { + if (zone->version < 7) + return; + if (NULL == zone->introspect->enumerate_discharged_pointers) + return; + zone->introspect->enumerate_discharged_pointers(zone, report_discharged); + } +} + /***************** OBSOLETE ENTRY POINTS ********************/ #if PHASE_OUT_OLD_MALLOC diff --git a/gen/malloc_zone_malloc.3 b/gen/malloc_zone_malloc.3 index 4f0006b..52d4c19 100644 --- a/gen/malloc_zone_malloc.3 +++ b/gen/malloc_zone_malloc.3 @@ -92,10 +92,11 @@ function creates a malloc zone, advising an initial allocation of .Fa start_size bytes, and specifying .Fa flags -that alter the standard behavior of the zone. The returned malloc zone can be used to provide custom allocation and deallocation behavior, and to retrieve additional information about the allocations in that zone. +At present there are no client settable flag values recognized by malloc_create_zone(), +the flags argument should always be passed as zero. .Pp The .Fn malloc_destroy_zone diff --git a/gen/nanosleep.c b/gen/nanosleep.c index fbab3c9..1b56056 100644 --- a/gen/nanosleep.c +++ b/gen/nanosleep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (c) 1999, 2003, 2006, 2007, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -26,15 +26,39 @@ #include #include #include +#include #if __DARWIN_UNIX03 #include "pthread_internals.h" #include -extern int __unix_conforming; -extern mach_port_t clock_port; +#ifndef BUILDING_VARIANT +semaphore_t clock_sem = MACH_PORT_NULL; +mach_port_t clock_port = MACH_PORT_NULL; + +void _init_clock_port() { + kern_return_t kr; + mach_port_t host = mach_host_self(); + + /* Get the clock service port for nanosleep */ + kr = host_get_clock_service(host, SYSTEM_CLOCK, &clock_port); + if (kr != KERN_SUCCESS) { + abort(); + } + + kr = semaphore_create(mach_task_self_, &clock_sem, SYNC_POLICY_FIFO, 0); + if (kr != KERN_SUCCESS) { + abort(); + } + mach_port_deallocate(mach_task_self(), host); +} +#else extern semaphore_t clock_sem; +extern mach_port_t clock_port; +#endif /* !BUILDING_VARIANT */ + +extern int __unix_conforming; #ifdef VARIANT_CANCELABLE extern void _pthread_testcancel(pthread_t thread, int isconforming); extern int __semwait_signal(int cond_sem, int mutex_sem, int timeout, int relative, __int64_t tv_sec, __int32_t tv_nsec); @@ -48,8 +72,8 @@ int nanosleep(const struct timespec *requested_time, struct timespec *remaining_time) { kern_return_t kret; int ret; - mach_timespec_t remain; mach_timespec_t current; + mach_timespec_t completion; if (__unix_conforming == 0) __unix_conforming = 1; @@ -65,9 +89,11 @@ nanosleep(const struct timespec *requested_time, struct timespec *remaining_time if (remaining_time != NULL) { - kret = clock_get_time(clock_port, ¤t); + /* once we add requested_time, this will be the completion time */ + kret = clock_get_time(clock_port, &completion); if (kret != KERN_SUCCESS) { fprintf(stderr, "clock_get_time() failed: %s\n", mach_error_string(kret)); + errno = EINVAL; return -1; } } @@ -77,16 +103,21 @@ nanosleep(const struct timespec *requested_time, struct timespec *remaining_time return 0; } else if (errno == EINTR) { if (remaining_time != NULL) { - ret = clock_get_time(clock_port, &remain); + ret = clock_get_time(clock_port, ¤t); if (ret != KERN_SUCCESS) { fprintf(stderr, "clock_get_time() failed: %s\n", mach_error_string(ret)); return -1; } /* This depends on the layout of a mach_timespec_t and timespec_t being equivalent */ - ADD_MACH_TIMESPEC(¤t, requested_time); - SUB_MACH_TIMESPEC(¤t, &remain); - remaining_time->tv_sec = current.tv_sec; - remaining_time->tv_nsec = current.tv_nsec; + ADD_MACH_TIMESPEC(&completion, requested_time); + /* We have to compare first, since mach_timespect_t contains unsigned integers */ + if(CMP_MACH_TIMESPEC(&completion, ¤t) > 0) { + SUB_MACH_TIMESPEC(&completion, ¤t); + remaining_time->tv_sec = completion.tv_sec; + remaining_time->tv_nsec = completion.tv_nsec; + } else { + bzero(remaining_time, sizeof(*remaining_time)); + } } } else { errno = EINVAL; diff --git a/gen/nftw.c b/gen/nftw.c index 5a06b98..a1a485a 100644 --- a/gen/nftw.c +++ b/gen/nftw.c @@ -46,7 +46,7 @@ both_ftw(const char *path, const char *paths[2]; struct FTW ftw; FTSENT *cur; - FTS *ftsp; + FTS *ftsp = NULL; int ftsflags, fnflag, error, postorder, sverrno; int cwd_fd = -1; /* cwd_fd != -1 means call chdir a lot */ @@ -64,7 +64,8 @@ both_ftw(const char *path, /* XXX - nfds is currently unused */ if (nfds < 1 || nfds > OPEN_MAX) { errno = EINVAL; - return (-1); + error = -1; + goto done; } ftsflags = FTS_COMFOLLOW; @@ -85,7 +86,8 @@ both_ftw(const char *path, if (ftwflags & FTW_CHDIR) { cwd_fd = open(".", O_RDONLY, 0); if (cwd_fd < 0) { - return -1; + error = -1; + goto done; } /* Prevent problems if fts ever starts using chdir when passed FTS_PHYSICAL */ @@ -102,16 +104,17 @@ both_ftw(const char *path, ENOTDIR, and EACCES */ { int rc = stat(path, &path_stat); - int e = errno; if (rc < 0 && (errno == ELOOP || errno == ENAMETOOLONG || errno == ENOENT || errno == ENOTDIR || errno == EACCES)) { - return -1; + error = -1; + goto done; } if (rc >= 0 && nfn) { if (!S_ISDIR(path_stat.st_mode)) { errno = ENOTDIR; - return -1; + error = -1; + goto done; } } } @@ -120,7 +123,8 @@ both_ftw(const char *path, paths[1] = NULL; ftsp = fts_open((char * const *)paths, ftsflags, NULL); if (ftsp == NULL) { - return (-1); + error = -1; + goto done; } error = 0; while ((cur = fts_read(ftsp)) != NULL) { @@ -211,6 +215,14 @@ both_ftw(const char *path, free(free_me); } if (rc < 0) { + if(cur->fts_pathlen == cur->fts_namelen && + fnflag == FTW_DNR) { + /* If cwd_fd is our last FD, fts_read will give us FTS_DNR + * and fts_path == fts_name == "." + * This check results in the correct errno being returned. + */ + errno = EMFILE; + } error = -1; goto done; } @@ -234,7 +246,10 @@ both_ftw(const char *path, } done: sverrno = errno; - (void) fts_close(ftsp); + if(ftsp != NULL) + (void) fts_close(ftsp); + if(cwd_fd >= 0) + (void) close(cwd_fd); errno = sverrno; return (error); } diff --git a/gen/nice-fbsd.c b/gen/nice-fbsd.c index 519ceb6..962eee1 100644 --- a/gen/nice-fbsd.c +++ b/gen/nice-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)nice.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/nice.c,v 1.3 2002/03/22 21:52:05 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/nice.c,v 1.4 2007/01/09 00:27:54 imp Exp $"); #include #include diff --git a/gen/opendir-fbsd.c b/gen/opendir-fbsd.c index 836600f..86c2e40 100644 --- a/gen/opendir-fbsd.c +++ b/gen/opendir-fbsd.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)opendir.c 8.8 (Berkeley) 5/1/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/opendir.c,v 1.22 2004/08/14 17:46:10 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/opendir.c,v 1.24 2008/04/16 18:40:52 delphij Exp $"); #include "namespace.h" #include @@ -56,17 +52,14 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/opendir.c,v 1.22 2004/08/14 17:46:10 stefan * Open a directory. */ DIR * -opendir(name) - const char *name; +opendir(const char *name) { return (__opendir2(name, DTF_HIDEW|DTF_NODUP)); } DIR * -__opendir2(name, flags) - const char *name; - int flags; +__opendir2(const char *name, int flags) { DIR *dirp; int fd; diff --git a/gen/pause-fbsd.c b/gen/pause-fbsd.c index 819dcaa..99576fd 100644 --- a/gen/pause-fbsd.c +++ b/gen/pause-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -42,7 +38,7 @@ static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93"; #endif /* VARIANT_CANCELABLE */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.8 2009/12/05 19:31:38 ed Exp $"); #include #include @@ -51,7 +47,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.6 2002/02/01 00:57:29 obrien Ex * Backwards compatible pause. */ int -__pause() +__pause(void) { sigset_t set; diff --git a/gen/pause-fbsd.c.orig b/gen/pause-fbsd.c.orig new file mode 100644 index 0000000..6f78fe9 --- /dev/null +++ b/gen/pause-fbsd.c.orig @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.8 2009/12/05 19:31:38 ed Exp $"); + +#include +#include + +/* + * Backwards compatible pause. + */ +int +__pause(void) +{ + return sigpause(sigblock(0L)); +} +__weak_reference(__pause, pause); +__weak_reference(__pause, _pause); diff --git a/gen/platfunc.c b/gen/platfunc.c new file mode 100644 index 0000000..0bb3bb1 --- /dev/null +++ b/gen/platfunc.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include +#include +#include + +#define PLAT_CAP_MASK (kHasMMX | kHasSSE | kHasSSE2 | kHasSSE3 | kCache32 | kCache64 | kCache128 | kFastThreadLocalStorage | kHasSupplementalSSE3 | k64Bit | kHasSSE4_1 | kHasSSE4_2 | kHasAES | kInOrderPipeline | kSlow | kUP) + +inline static int num_cpus(int capabilities) { + return (capabilities & kNumCPUs) >> kNumCPUsShift; +} + +/* TODO: If 8151810 is fixed (or full support for visibility("internal") is added), change this to visibility("internal") */ +void __attribute__((visibility("hidden"))) *find_platform_function(const platfunc_descriptor *descriptors[]) { + int cap = _get_cpu_capabilities(), + have_cpus = num_cpus(cap); + + for (int i = 0; descriptors[i] != 0; i++) { + int musthave_cpus = num_cpus(descriptors[i]->musthave), + canthave_cpus = num_cpus(descriptors[i]->canthave); + uint32_t musthave = descriptors[i]->musthave & PLAT_CAP_MASK, + canthave = descriptors[i]->canthave & PLAT_CAP_MASK; + /* First check that the CPU supports all the features that are in musthave */ + if ((musthave & cap) != musthave) + continue; + /* Now check that the CPU doesn't have any of the features that are in canthave */ + if ((canthave & cap) != 0) + continue; + /* Special case check for the number of CPUs. */ + /* TODO: Should there be a way to specify < or > num cpus? */ + if (musthave_cpus != 0 && have_cpus != musthave_cpus) + continue; + if (canthave_cpus != 0 && have_cpus == canthave_cpus) + continue; + /* otherwise, we have found our preferred implementation */ + return descriptors[i]->address; + } + + /* We didn't find an acceptable implementation. (bug in data structures!) */ + return NULL; +} + +#endif diff --git a/gen/platfunc.h b/gen/platfunc.h new file mode 100644 index 0000000..58c117c --- /dev/null +++ b/gen/platfunc.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2003-2010 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#if defined(__i386__) || defined(__x86_64__) + +#ifndef _I386_PLATFUNC_H +#define _I386_PLATFUNC_H + +#ifndef __ASSEMBLER__ +#include +#endif /* __ASSEMBLER__ */ + +// This is a shared macro which calls PLATFUNC_VARIANT_NAME which has different +// implementations in __ASSEMBLER__ and !__ASSEMBLER__ +#define PLATFUNC_DESCRIPTOR_NAME(name, variant) \ + PLATFUNC_VARIANT_NAME(platfunc_ ## name, variant) + +#ifdef __ASSEMBLER__ + +/* When trying to acquire a spinlock or mutex, we will spin in + * user mode for awhile, before entering the kernel to relinquish. + * MP_SPIN_TRIES is the initial value of _COMM_PAGE_SPIN_COUNT. + * The idea is that _COMM_PAGE_SPIN_COUNT will be adjusted up or + * down as the machine is plugged in/out, etc. + * At present spinlocks do not use _COMM_PAGE_SPIN_COUNT. + * They use MP_SPIN_TRIES directly. + */ +#define MP_SPIN_TRIES 1000 + +#define PLATFUNC_VARIANT_NAME(name, variant) _ ## name ## $VARIANT$ ## variant + +#if defined (__i386__) +#define PLATFUNC_DESCRIPTOR_FIELD_POINTER .long +#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) \ + .long PLATFUNC_DESCRIPTOR_NAME(name, variant) +#elif defined (__x86_64__) +#define PLATFUNC_DESCRIPTOR_FIELD_POINTER .quad +#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) \ + .quad PLATFUNC_DESCRIPTOR_NAME(name, variant) +#else +#error unsupported architecture +#endif + +#ifdef VARIANT_DYLD + +#define PLATFUNC_FUNCTION_START_GENERIC(name, variant, codetype, alignment) \ + PLATFUNC_FUNCTION_START(name, variant, codetype, alignment) \ + .globl _ ## name ;\ + _ ## name ## : + +#define PLATFUNC_DESCRIPTOR(name, variant, must, cant) + +#else /* VARIANT_DYLD */ + +#define PLATFUNC_FUNCTION_START_GENERIC PLATFUNC_FUNCTION_START + +#define PLATFUNC_DESCRIPTOR(name, variant, must, cant) \ + .const_data ;\ + .private_extern PLATFUNC_DESCRIPTOR_NAME(name, variant) ;\ + PLATFUNC_DESCRIPTOR_NAME(name, variant) ## : ;\ + PLATFUNC_DESCRIPTOR_FIELD_POINTER PLATFUNC_VARIANT_NAME(name, variant) ;\ + .long must ;\ + .long cant ;\ + .text + +#endif /* VARIANT_DYLD */ + +#define PLATFUNC_FUNCTION_START(name, variant, codetype, alignment) \ + .text ;\ + .align alignment, 0x90 ;\ + .private_extern PLATFUNC_VARIANT_NAME(name, variant) ;\ + PLATFUNC_VARIANT_NAME(name, variant) ## : + +#else /* __ASSEMBLER__ */ + +#define PLATFUNC_VARIANT_NAME(name, variant) name ## $VARIANT$ ## variant +#define PLATFUNC_DESCRIPTOR_PROTOTYPE(name, variant) extern const platfunc_descriptor PLATFUNC_DESCRIPTOR_NAME(name, variant); +#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) &PLATFUNC_DESCRIPTOR_NAME(name, variant) + +#define PLATFUNC_DESCRIPTOR(name, variant, must, cant) \ + extern void PLATFUNC_VARIANT_NAME(name, variant) (void); \ + const platfunc_descriptor PLATFUNC_DESCRIPTOR_NAME(name, variant) = { \ + .address = PLATFUNC_VARIANT_NAME(name, variant), \ + .musthave = must, \ + .canthave = cant \ + } + +/* + * Each potential platfunc routine is described by one of these. + * Note that the PLATFUNC_DESCRIPTOR macro (above), used in + * assembly language, must agree with this. + */ + +typedef struct platfunc_descriptor { + void *address; // address of code + uint32_t musthave; // _cpu_capability bits we must have + uint32_t canthave; // _cpu_capability bits we can't have +} platfunc_descriptor; + +void *find_platform_function(const platfunc_descriptor *descriptors[]); + +#endif /* __ASSEMBLER__ */ + +#endif /* _I386_PLATFUNC_H */ + +#endif /* __i386__ || __x86_64__ */ diff --git a/gen/popen-fbsd.c b/gen/popen-fbsd.c index 6de71b8..d4aea86 100644 --- a/gen/popen-fbsd.c +++ b/gen/popen-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -42,10 +38,11 @@ static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/popen.c,v 1.18 2003/01/04 00:15:15 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/popen.c,v 1.21 2009/05/27 19:28:04 ed Exp $"); #include "namespace.h" #include +#include #include #include #include /* fwide() */ @@ -64,9 +61,19 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/popen.c,v 1.18 2003/01/04 00:15:15 tjr Exp #include #define environ (*_NSGetEnviron()) +/* Our queue.h doesn't have SLIST_REMOVE_AFTER in it yet + * API: Add SLIST_REMOVE_AFTER to sys/queue.h (from FreeBSD) + */ +#ifndef SLIST_REMOVE_AFTER +#define SLIST_REMOVE_AFTER(elm, field) do { \ + SLIST_NEXT(elm, field) = \ + SLIST_NEXT(SLIST_NEXT(elm, field), field); \ +} while (0) +#endif + /* 3516149 - store file descriptor and use that to close to prevent blocking */ struct pid { - struct pid *next; + SLIST_ENTRY(pid) next; FILE *fp; int fd; pid_t pid; @@ -74,10 +81,10 @@ struct pid { #define pidlist __popen_pidlist #define pidlist_mutex __popen_pidlist_mutex #ifndef BUILDING_VARIANT -__private_extern__ struct pid *pidlist = NULL; +__private_extern__ SLIST_HEAD(, pid) pidlist = SLIST_HEAD_INITIALIZER(pidlist); __private_extern__ pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER; #else /* BUILDING_VARIANT */ -extern struct pid *pidlist; +extern SLIST_HEAD(, pid) pidlist; extern pthread_mutex_t pidlist_mutex; #endif /* !BUILDING_VARIANT */ @@ -166,9 +173,8 @@ popen(command, type) } (void)posix_spawn_file_actions_addclose(&file_actions, pdes[1]); } - for (p = pidlist; p; p = p->next) { + SLIST_FOREACH(p, &pidlist, next) (void)posix_spawn_file_actions_addclose(&file_actions, p->fd); - } argv[0] = "sh"; argv[1] = "-c"; @@ -200,8 +206,7 @@ popen(command, type) cur->fp = iop; cur->pid = pid; THREAD_LOCK(); - cur->next = pidlist; - pidlist = cur; + SLIST_INSERT_HEAD(&pidlist, cur, next); THREAD_UNLOCK(); fwide(iop, -1); /* byte stream */ return (iop); @@ -217,7 +222,7 @@ int pclose(iop) FILE *iop; { - struct pid *cur, *last; + struct pid *cur, *last = NULL; int pstat; pid_t pid; @@ -225,17 +230,19 @@ pclose(iop) * Find the appropriate file pointer and remove it from the list. */ THREAD_LOCK(); - for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next) + SLIST_FOREACH(cur, &pidlist, next) { if (cur->fp == iop) break; + last = cur; + } if (cur == NULL) { THREAD_UNLOCK(); return (-1); } if (last == NULL) - pidlist = cur->next; + SLIST_REMOVE_HEAD(&pidlist, next); else - last->next = cur->next; + SLIST_REMOVE_AFTER(last, next); THREAD_UNLOCK(); (void)fclose(iop); diff --git a/gen/psignal.3 b/gen/psignal.3 deleted file mode 120000 index 7550220..0000000 --- a/gen/psignal.3 +++ /dev/null @@ -1 +0,0 @@ -./psignal.3 \ No newline at end of file diff --git a/gen/psignal.3 b/gen/psignal.3 new file mode 100644 index 0000000..84976af --- /dev/null +++ b/gen/psignal.3 @@ -0,0 +1,122 @@ +.\" Copyright (c) 1983, 1991, 1993 +.\" The Regents of the University of California. 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. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. +.\" +.\" @(#)psignal.3 8.2 (Berkeley) 2/27/95 +.\" $FreeBSD: src/lib/libc/gen/psignal.3,v 1.17 2007/01/09 00:27:54 imp Exp $ +.\" +.Dd February 27, 1995 +.Dt PSIGNAL 3 +.Os +.Sh NAME +.Nm psignal , +.Nm strsignal , +.Nm sys_siglist , +.Nm sys_signame +.Nd system signal messages +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Ft void +.Fn psignal "unsigned sig" "const char *s" +.Vt extern const char * const sys_siglist[] ; +.Vt extern const char * const sys_signame[] ; +.In string.h +.Ft "char *" +.Fn strsignal "int sig" +.Sh DESCRIPTION +The +.Fn psignal +and +.Fn strsignal +functions locate the descriptive message +string for a signal number. +.Pp +The +.Fn strsignal +function accepts a signal number argument +.Fa sig +and returns a pointer to the corresponding message string. +.Pp +The +.Fn psignal +function accepts a signal number argument +.Fa sig +and writes it to the standard error. +If the argument +.Fa s +is +.Pf non- Dv NULL +and does not point to the null character, +.Fa s +is written to the standard error file descriptor +prior to the message string, +immediately followed by a colon and a space. +If the signal number is not recognized +.Pq Xr sigaction 2 , +the string +.Dq "Unknown signal +is produced. +.Pp +The message strings can be accessed directly +through the external array +.Va sys_siglist , +indexed by recognized signal numbers. +The external array +.Va sys_signame +is used similarly and +contains short, lower-case abbreviations for signals +which are useful for recognizing signal names +in user input. +The defined variable +.Dv NSIG +contains a count of the strings in +.Va sys_siglist +and +.Va sys_signame . +.Sh RETURN VALUES +.Fn strsignal +a pointer to the desired message or a NULL value indicating an error. This +string is not to be freed by the caller. Beginning with Mac OSX 10.7, this +string is unique to each thread. +.Sh ERRORS +.Fn strsignal +will fail and no additional memory will be allocated if +one of the following are true: +.Bl -tag -width Er +.It Bq Er ENOMEM +There was insufficient memory to allocate storage space for the return value in the running thread. +.El +.Sh SEE ALSO +.Xr sigaction 2 , +.Xr perror 3 , +.Xr strerror 3 +.Sh HISTORY +The +.Fn psignal +function appeared in +.Bx 4.2 . diff --git a/gen/rand48.3 b/gen/rand48.3 index 223b2a9..6bc96d6 100644 --- a/gen/rand48.3 +++ b/gen/rand48.3 @@ -10,7 +10,7 @@ .\" to anyone/anything when using this software. .\" .\" @(#)rand48.3 V1.0 MB 8 Oct 1993 -.\" $FreeBSD: src/lib/libc/gen/rand48.3,v 1.16 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/rand48.3,v 1.17 2005/01/20 09:17:02 ru Exp $ .\" .Dd October 8, 1993 .Dt RAND48 3 @@ -74,7 +74,7 @@ congruential algorithm working on integers 48 bits in size. The particular formula employed is r(n+1) = (a * r(n) + c) mod m. -The default value for the multiplicand `a' is 0xfdeece66d (25214903917). +The default value for the multiplicand `a' is 0x5deece66d (25214903917). The default value for the the addend `c' is 0xb (11). The modulo is always fixed at m = 2 ** 48. r(n) is called the seed of the random number generator. @@ -194,8 +194,8 @@ generator calls. .Pp For a more powerful random number generator, see .Xr random 3 . -.Sh AUTHORS -.An Martin Birgmeier .Sh SEE ALSO .Xr rand 3 , .Xr random 3 +.Sh AUTHORS +.An Martin Birgmeier diff --git a/gen/readdir-fbsd.c b/gen/readdir-fbsd.c index 6cf30d6..3875cef 100644 --- a/gen/readdir-fbsd.c +++ b/gen/readdir-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/readdir.c,v 1.11 2002/02/26 21:39:32 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/readdir.c,v 1.15 2008/05/05 14:05:23 kib Exp $"); #include "namespace.h" #include @@ -46,15 +42,16 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/readdir.c,v 1.11 2002/02/26 21:39:32 alfred #include #include "un-namespace.h" -#include "telldir.h" #include "libc_private.h" +#include "telldir.h" /* * get next entry in a directory. */ struct dirent * -_readdir_unlocked(dirp) +_readdir_unlocked(dirp, skip) DIR *dirp; + int skip; { struct dirent *dp; @@ -82,7 +79,7 @@ _readdir_unlocked(dirp) dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) return (NULL); dirp->dd_loc += dp->d_reclen; - if (dp->d_ino == 0) + if (dp->d_ino == 0 && skip) continue; if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) continue; @@ -97,12 +94,12 @@ readdir(dirp) struct dirent *dp; if (__isthreaded) { - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); - dp = _readdir_unlocked(dirp); - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_lock(&dirp->dd_lock); + dp = _readdir_unlocked(dirp, 1); + _pthread_mutex_unlock(&dirp->dd_lock); } else - dp = _readdir_unlocked(dirp); + dp = _readdir_unlocked(dirp, 1); return (dp); } @@ -118,12 +115,12 @@ readdir_r(dirp, entry, result) saved_errno = errno; errno = 0; if (__isthreaded) { - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); - if ((dp = _readdir_unlocked(dirp)) != NULL) + _pthread_mutex_lock(&dirp->dd_lock); + if ((dp = _readdir_unlocked(dirp, 1)) != NULL) memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_unlock(&dirp->dd_lock); } - else if ((dp = _readdir_unlocked(dirp)) != NULL) + else if ((dp = _readdir_unlocked(dirp, 1)) != NULL) memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); if (errno != 0) { diff --git a/gen/scandir-fbsd.c b/gen/scandir-fbsd.c index ab6657c..7f2b13d 100644 --- a/gen/scandir-fbsd.c +++ b/gen/scandir-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)scandir.c 8.3 (Berkeley) 1/2/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/scandir.c,v 1.7 2002/02/01 01:32:19 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/scandir.c,v 1.9 2008/03/16 19:08:53 das Exp $"); /* * Scan the directory dirname calling select to make a list of selected @@ -45,8 +41,6 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/scandir.c,v 1.7 2002/02/01 01:32:19 obrien */ #include "namespace.h" -#include -#include #include #include #include @@ -68,20 +62,13 @@ scandir(dirname, namelist, select, dcomp) { struct dirent *d, *p, **names = NULL; size_t nitems = 0; - struct stat stb; long arraysz; DIR *dirp; if ((dirp = opendir(dirname)) == NULL) return(-1); - if (_fstat(dirp->dd_fd, &stb) < 0) - goto fail; - /* - * estimate the array size by taking the size of the directory file - * and dividing it by a multiple of the minimum size entry. - */ - arraysz = (stb.st_size / 24); + arraysz = 32; /* initial estimate of the array size */ names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *)); if (names == NULL) goto fail; @@ -105,17 +92,16 @@ scandir(dirname, namelist, select, dcomp) * realloc the maximum size. */ if (nitems >= arraysz) { - const int inc = 10; /* increase by this much */ struct dirent **names2; names2 = (struct dirent **)realloc((char *)names, - (arraysz + inc) * sizeof(struct dirent *)); + (arraysz * 2) * sizeof(struct dirent *)); if (names2 == NULL) { free(p); goto fail; } names = names2; - arraysz += inc; + arraysz *= 2; } names[nitems++] = p; } diff --git a/gen/scandir.3 b/gen/scandir.3 index 5c429e0..7998581 100644 --- a/gen/scandir.3 +++ b/gen/scandir.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)scandir.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/scandir.3,v 1.8 2002/12/19 09:40:21 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/scandir.3,v 1.9 2007/01/09 00:27:55 imp Exp $ .\" .Dd May 20, 2008 .Dt SCANDIR 3 diff --git a/gen/scandir_b-fbsd.c b/gen/scandir_b-fbsd.c index 82b06a7..7cdea7b 100644 --- a/gen/scandir_b-fbsd.c +++ b/gen/scandir_b-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)scandir.c 8.3 (Berkeley) 1/2/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/scandir.c,v 1.7 2002/02/01 01:32:19 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/scandir.c,v 1.9 2008/03/16 19:08:53 das Exp $"); /* * Scan the directory dirname calling select to make a list of selected @@ -45,8 +41,6 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/scandir.c,v 1.7 2002/02/01 01:32:19 obrien */ #include "namespace.h" -#include -#include #include #include #include @@ -68,20 +62,13 @@ scandir_b(dirname, namelist, select, dcomp) { struct dirent *d, *p, **names = NULL; size_t nitems = 0; - struct stat stb; long arraysz; DIR *dirp; if ((dirp = opendir(dirname)) == NULL) return(-1); - if (_fstat(dirp->dd_fd, &stb) < 0) - goto fail; - /* - * estimate the array size by taking the size of the directory file - * and dividing it by a multiple of the minimum size entry. - */ - arraysz = (stb.st_size / 24); + arraysz = 32; /* initial estimate of the array size */ names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *)); if (names == NULL) goto fail; @@ -105,17 +92,16 @@ scandir_b(dirname, namelist, select, dcomp) * realloc the maximum size. */ if (nitems >= arraysz) { - const int inc = 10; /* increase by this much */ struct dirent **names2; names2 = (struct dirent **)realloc((char *)names, - (arraysz + inc) * sizeof(struct dirent *)); + (arraysz * 2) * sizeof(struct dirent *)); if (names2 == NULL) { free(p); goto fail; } names = names2; - arraysz += inc; + arraysz *= 2; } names[nitems++] = p; } diff --git a/gen/setmode-fbsd.c b/gen/setmode-fbsd.c index 6d06c82..53b79d2 100644 --- a/gen/setmode-fbsd.c +++ b/gen/setmode-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/setmode.c,v 1.9 2003/02/23 00:24:03 mikeh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/setmode.c,v 1.11 2007/01/09 00:27:55 imp Exp $"); #include "namespace.h" #include @@ -86,9 +82,7 @@ static void dumpmode(BITCMD *); * bits) followed by a '+' (set bits). */ mode_t -getmode(bbox, omode) - const void *bbox; - mode_t omode; +getmode(const void *bbox, mode_t omode) { const BITCMD *set; mode_t clrval, newmode, value; @@ -180,8 +174,7 @@ common: if (set->cmd2 & CMD2_CLR) { #endif /* !VARIANT_LEGACY */ void * -setmode(p) - const char *p; +setmode(const char *p) { int perm, who; char op, *ep; @@ -361,11 +354,7 @@ apply: if (!*p) } static BITCMD * -addcmd(set, op, who, oparg, mask) - BITCMD *set; - int oparg, who; - int op; - u_int mask; +addcmd(BITCMD *set, int op, int who, int oparg, u_int mask) { switch (op) { case '=': @@ -409,8 +398,7 @@ addcmd(set, op, who, oparg, mask) #ifdef SETMODE_DEBUG static void -dumpmode(set) - BITCMD *set; +dumpmode(BITCMD *set) { for (; set->cmd; ++set) (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n", @@ -431,8 +419,7 @@ dumpmode(set) * compacted, but it's not worth the effort. */ __private_extern__ void -compress_mode(set) - BITCMD *set; +compress_mode(BITCMD *set) { BITCMD *nset; int setbits, clrbits, Xbits, op; diff --git a/gen/setprogname-fbsd.c b/gen/setprogname-fbsd.c index 76559d4..2392a66 100644 --- a/gen/setprogname-fbsd.c +++ b/gen/setprogname-fbsd.c @@ -19,7 +19,7 @@ setprogname(const char *progname) p = strrchr(progname, '/'); if (p != NULL) - __progname = (char *)(p + 1); + __progname = (char *)(p = p + 1); else __progname = (char *)(p = progname); diff --git a/gen/siginterrupt.3 b/gen/siginterrupt.3 index 0b1f2d4..6e2fd5f 100644 --- a/gen/siginterrupt.3 +++ b/gen/siginterrupt.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)siginterrupt.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/siginterrupt.3,v 1.14 2002/12/19 09:40:21 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/siginterrupt.3,v 1.15 2007/01/09 00:27:55 imp Exp $ .\" .Dd June 4, 1993 .Dt SIGINTERRUPT 3 diff --git a/gen/siglist-fbsd.c b/gen/siglist-fbsd.c index 8452535..a222989 100644 --- a/gen/siglist-fbsd.c +++ b/gen/siglist-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,9 +31,8 @@ static char sccsid[] = "@(#)siglist.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/siglist.c,v 1.4 2002/09/07 08:14:19 jmallett Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/siglist.c,v 1.6 2007/01/20 08:24:01 maxim Exp $"); -#include #include const char *const sys_signame[NSIG] = { diff --git a/gen/signal-fbsd.c b/gen/signal-fbsd.c index f0764f7..a496863 100644 --- a/gen/signal-fbsd.c +++ b/gen/signal-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)signal.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/signal.c,v 1.3 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/signal.c,v 1.4 2007/01/09 00:27:55 imp Exp $"); /* * Almost backwards compatible signal. diff --git a/gen/signal.3 b/gen/signal.3 index dee3357..f18d1cf 100644 --- a/gen/signal.3 +++ b/gen/signal.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)signal.3 8.3 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/signal.3,v 1.38 2004/07/03 22:30:08 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/signal.3,v 1.43 2008/07/17 21:54:23 simon Exp $ .\" .Dd June 7, 2004 .Dt SIGNAL 3 @@ -42,14 +38,23 @@ .Lb libc .Sh SYNOPSIS .In signal.h -.\" The following is Quite Ugly, but syntactically correct. -.\" Don't try to -.\" fix it. -.Ft void \*(lp* -.Fn signal "int sig" "void \*(lp*func\*(rp\*(lpint\*(rp\*(rp\*(rp\*(lpint" +.\" XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX +.\" The prototype for signal(3) cannot be cleanly marked up in -mdoc +.\" without the following lower-level tweak. +.nr in-synopsis-section 0 .Pp +.Ft "void \*(lp*" Ns +.Fo signal +.Fa "int sig" +.Fa "void \*(lp*func\*(rp\*(lpint\*(rp" +.Fc Ns +.Ft "\*(rp\*(lpint\*(rp" ; +.Pp +.nr in-synopsis-section 1 +.\" XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX or in the equivalent but easier to read typedef'd version: .Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp" ; +.Pp .Ft sig_t .Fn signal "int sig" "sig_t func" .Sh DESCRIPTION @@ -172,10 +177,12 @@ func() remains installed after a signal has been delivered. For some system calls, if a signal is caught while the call is executing and the call is prematurely terminated, the call is automatically restarted. -(The handler is installed using the +Any handler installed with +.Xr signal 3 +will have the .Dv SA_RESTART -flag with -.Xr sigaction 2 . ) +flag set, meaning that any restartable system call will not return on +receipt of a signal. The affected system calls include .Xr read 2 , .Xr write 2 , @@ -243,7 +250,7 @@ is not a valid signal number. An attempt is made to ignore or supply a handler for .Dv SIGKILL or -.Ev SIGSTOP . +.Dv SIGSTOP . .El .Sh SEE ALSO .Xr kill 1 , @@ -259,8 +266,8 @@ or .Xr siginterrupt 3 , .Xr tty 4 .Sh HISTORY -This -.Fn signal +The +.Nm facility appeared in .Bx 4.0 . The option to avoid the creation of child zombies through ignoring diff --git a/gen/sleep-fbsd.c b/gen/sleep-fbsd.c index 773b54b..9d2095e 100644 --- a/gen/sleep-fbsd.c +++ b/gen/sleep-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/sleep.c,v 1.31 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/sleep.c,v 1.33 2009/12/05 19:31:38 ed Exp $"); #include "namespace.h" #include @@ -50,8 +46,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/sleep.c,v 1.31 2002/02/01 00:57:29 obrien E #include "un-namespace.h" unsigned int -__sleep(seconds) - unsigned int seconds; +__sleep(unsigned int seconds) { struct timespec time_to_sleep; struct timespec time_remaining; diff --git a/gen/sleep.3 b/gen/sleep.3 index 00cd85e..f540a15 100644 --- a/gen/sleep.3 +++ b/gen/sleep.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)sleep.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/sleep.3,v 1.16 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/sleep.3,v 1.17 2007/01/09 00:27:55 imp Exp $ .\" .Dd February 13, 1998 .Dt SLEEP 3 diff --git a/gen/stack_logging.c b/gen/stack_logging.c index f40e262..42953c8 100644 --- a/gen/stack_logging.c +++ b/gen/stack_logging.c @@ -32,11 +32,11 @@ #include #import #import +#import extern void spin_lock(int *); extern void spin_unlock(int *); extern void thread_stack_pcs(vm_address_t *, unsigned, unsigned *); -extern const char *__crashreporter_info__; static inline void *allocate_pages(unsigned) __attribute__((always_inline)); static inline void *allocate_pages(unsigned bytes) { @@ -44,7 +44,7 @@ static inline void *allocate_pages(unsigned bytes) { if (vm_allocate(mach_task_self(), (vm_address_t *)&address, bytes, VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)| TRUE)) { malloc_printf("*** out of memory while stack logging\n"); - __crashreporter_info__ = "*** out of memory while stack logging\n"; + CRSetCrashLogMessage("*** out of memory while stack logging\n"); abort(); } return (void *)address; @@ -158,7 +158,7 @@ void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsign arg1 *= arg2; arg2 = arg3; arg3 = 0; type &= ~stack_logging_flag_calloc; } if (type & stack_logging_flag_object) { - unsigned *class = (unsigned *)(long)arg1; + unsigned *class = (unsigned *)(uintptr_t)arg1; arg1 = arg2 + class[5]; // corresponds to the instance_size field arg2 = 0; arg3 = 0; type = stack_logging_type_alloc; } @@ -169,12 +169,12 @@ void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsign if (stack_logging_type_alloc) { if (!result) return; stack_logging_log_stack(stack_logging_type_alloc, 0, 0, 0, result, num_hot_to_skip+1); - stack_logging_log_stack(stack_logging_type_alloc, arg1, 0, 0, *((int *)(long)result), num_hot_to_skip+1); + stack_logging_log_stack(stack_logging_type_alloc, arg1, 0, 0, *((int *)(uintptr_t)result), num_hot_to_skip+1); return; } if (stack_logging_type_dealloc) { if (!arg1) return; - stack_logging_log_stack(stack_logging_type_dealloc, *((int *)(long)arg1), 0, 0, 0, num_hot_to_skip+1); + stack_logging_log_stack(stack_logging_type_dealloc, *((int *)(uintptr_t)arg1), 0, 0, 0, num_hot_to_skip+1); stack_logging_log_stack(stack_logging_type_dealloc, arg1, 0, 0, 0, num_hot_to_skip+1); return; } @@ -183,9 +183,9 @@ void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsign if (type == stack_logging_flag_set_handle_size) { if (!arg1) return; // Thanks to a horrible hack, arg3 contains the prvious handle value - if (arg3 == *((int *)(long)arg1)) return; + if (arg3 == *((int *)(uintptr_t)arg1)) return; stack_logging_log_stack(stack_logging_type_dealloc, arg3, 0, 0, 0, num_hot_to_skip+1); - stack_logging_log_stack(stack_logging_type_alloc, arg2, 0, 0, *((int *)(long)arg1), num_hot_to_skip+1); + stack_logging_log_stack(stack_logging_type_alloc, arg2, 0, 0, *((int *)(uintptr_t)arg1), num_hot_to_skip+1); return; } if (type == (stack_logging_type_dealloc|stack_logging_type_alloc)) { @@ -229,7 +229,7 @@ void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsign // printf("Before getting samples 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result); thread_stack_pcs((vm_address_t *)stack_entries, MAX_NUM_PC - 1, &count); // We put at the bottom of the stack a marker that denotes the thread (+1 for good measure...) - stack_entries[count++] = (int)(long)pthread_self() + 1; + stack_entries[count++] = (int)(uintptr_t)pthread_self() + 1; /* now let's unique the sample */ // printf("Uniquing 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result); rec->uniqued_stack = stack_logging_get_unique_stack(&stack_logging_the_record_list->uniquing_table, &stack_logging_the_record_list->uniquing_table_num_pages, stack_entries, count, num_hot_to_skip+2); // we additionally skip the warmest 2 entries that are an artefact of the code @@ -280,7 +280,7 @@ kern_return_t stack_logging_get_frames(task_t task, memory_reader_t reader, vm_a } index++; } - fprintf(stderr, "*** stack_logging: no record found for 0x%lx\n", (long)address); + fprintf(stderr, "*** stack_logging: no record found for %p\n", address); return 0; } diff --git a/gen/stack_logging.h b/gen/stack_logging.h index bfb89df..ff7079d 100644 --- a/gen/stack_logging.h +++ b/gen/stack_logging.h @@ -59,6 +59,8 @@ typedef struct { mach_vm_address_t address; } mach_stack_logging_record_t; +extern kern_return_t __mach_stack_logging_set_file_path(task_t task, char* file_path); + extern kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); /* Gets the last allocation record (malloc, realloc, or free) about address */ diff --git a/gen/stack_logging_disk.c b/gen/stack_logging_disk.c index aa0bf28..5a48ca3 100644 --- a/gen/stack_logging_disk.c +++ b/gen/stack_logging_disk.c @@ -187,9 +187,10 @@ static const char *stack_log_file_base_name = "stack-logs."; static const char *stack_log_file_suffix = ".index"; static const char *stack_log_link_suffix = ".link"; -static char stack_log_location[PATH_MAX]; -static char stack_log_reference_file[PATH_MAX]; -static char index_file_path[PATH_MAX]; +static void *stack_log_path_buffers = NULL; +static char *stack_log_location = NULL; +static char *stack_log_reference_file = NULL; +char *__stack_log_file_path__ = NULL; static int index_file_descriptor = -1; // for accessing remote log files @@ -387,7 +388,42 @@ append_int(char * filename, pid_t pid, size_t maxLength) } } -// If successful, returns path to log file that was created. Otherwise returns NULL. +/* + * Check various temporary directory options starting with _PATH_TMP and use confstr. + * Allocating and releasing target buffer is the caller's responsibility. + */ +static bool +get_writeable_temp_dir(char* target) +{ + if (!target) return false; + if (-1 != access(_PATH_TMP, W_OK)) { + strlcpy(target, _PATH_TMP, (size_t)PATH_MAX); + return true; + } + size_t n = confstr(_CS_DARWIN_USER_TEMP_DIR, target, (size_t) PATH_MAX); + if ((n > 0) && (n < PATH_MAX)) return true; + n = confstr(_CS_DARWIN_USER_CACHE_DIR, target, (size_t) PATH_MAX); + if ((n > 0) && (n < PATH_MAX)) return true; + /* No writeable tmp directory found. Maybe shd try /private/var/tmp for device here ... */ + *target = '\0'; + return false; +} + +/* + * If successful, returns path to log file that was created, otherwise NULL. + * + * The log could be in one of 3 places (in decreasing order of preference) + * + * 1) value of environment variable MallocStackLoggingDirectory + * 2) the temp directory /tmp for desktop apps and internal apps on devices, or + * 3) the sandbox location + tmp/ in case of 3rd party apps on the device. + * + * For 1 and 3, we create a .link file with the path of the file. We prefer to + * create this file in /tmp, but if we are unable to (device 3rd party case), + * we create it in the same location as the .index file and issue a message + * in syslog asking for it to be copied to /tmp to enable tools. + * + */ static char * create_log_file(void) { @@ -395,69 +431,110 @@ create_log_file(void) const char *progname = getprogname(); char *created_log_location = NULL; + if (stack_log_path_buffers == NULL) { + /* + * on first use, allocate buffers directly from the OS without + * using malloc + */ + + stack_log_path_buffers = allocate_pages((uint64_t)round_page(3*PATH_MAX)); + if (stack_log_path_buffers == NULL) { + _malloc_printf(ASL_LEVEL_INFO, "unable to allocate memory for path buffers\n"); + return NULL; + } + + stack_log_location = &((char *)stack_log_path_buffers)[0*PATH_MAX]; + stack_log_reference_file = &((char *)stack_log_path_buffers)[1*PATH_MAX]; + __stack_log_file_path__ = &((char *)stack_log_path_buffers)[2*PATH_MAX]; + } + // WARNING! use of snprintf can induce malloc() calls bool use_alternate_location = false; char *evn_log_directory = getenv("MallocStackLoggingDirectory"); + size_t stack_log_len; if (evn_log_directory && *evn_log_directory) { use_alternate_location = true; strlcpy(stack_log_location, evn_log_directory, (size_t)PATH_MAX); - size_t evn_log_len = strlen(stack_log_location); - // add the '/' only if it's not already there. - if (evn_log_directory[evn_log_len-1] != '/') { - strlcat(stack_log_location, "/", (size_t)PATH_MAX); + } + if (!use_alternate_location || (access(stack_log_location, W_OK) == -1)) { + if (!get_writeable_temp_dir(stack_log_location)) { + _malloc_printf(ASL_LEVEL_INFO, "No writeable tmp dir\n"); + return NULL; } - } else { - strlcpy(stack_log_location, _PATH_TMP, (size_t)PATH_MAX); + if (0 != strcmp(stack_log_location, _PATH_TMP)) + use_alternate_location = true; + } + stack_log_len = strlen(stack_log_location); + // add the '/' only if it's not already there. + if (stack_log_location[stack_log_len-1] != '/') { + strlcat(stack_log_location, "/", (size_t)PATH_MAX); + ++stack_log_len; } - strlcat(stack_log_location, stack_log_file_base_name, (size_t)PATH_MAX); - append_int(stack_log_location, pid, (size_t)PATH_MAX); + strlcpy(__stack_log_file_path__, stack_log_location, (size_t)PATH_MAX); + + strlcat(__stack_log_file_path__, stack_log_file_base_name, (size_t)PATH_MAX); + append_int(__stack_log_file_path__, pid, (size_t)PATH_MAX); if (progname && progname[0] != '\0') { - strlcat(stack_log_location, ".", (size_t)PATH_MAX); - strlcat(stack_log_location, progname, (size_t)PATH_MAX); + strlcat(__stack_log_file_path__, ".", (size_t)PATH_MAX); + strlcat(__stack_log_file_path__, progname, (size_t)PATH_MAX); + } + if (!use_alternate_location) strlcat(__stack_log_file_path__, ".XXXXXX", (size_t)PATH_MAX); + strlcat(__stack_log_file_path__, stack_log_file_suffix, (size_t)PATH_MAX); + + // Securely create the log file. + if ((index_file_descriptor = mkstemps(__stack_log_file_path__, (int)strlen(stack_log_file_suffix))) != -1) { + _malloc_printf(ASL_LEVEL_INFO, "stack logs being written into %s\n", __stack_log_file_path__); + created_log_location = __stack_log_file_path__; + } else { + _malloc_printf(ASL_LEVEL_INFO, "unable to create stack logs at %s\n", stack_log_location); + if (use_alternate_location) delete_logging_file(stack_log_reference_file); + stack_log_reference_file[0] = '\0'; + stack_log_location[0] = '\0'; + __stack_log_file_path__[0] = '\0'; + created_log_location = NULL; + return created_log_location; } - if (!use_alternate_location) strlcat(stack_log_location, ".XXXXXX", (size_t)PATH_MAX); - strlcat(stack_log_location, stack_log_file_suffix, (size_t)PATH_MAX); // in the case where the user has specified an alternate location, drop a reference file // in /tmp with the suffix 'stack_log_link_suffix' (".link") and save the path of the // stack logging file there. + bool use_alternate_link_location = false; if (use_alternate_location) { strlcpy(stack_log_reference_file, _PATH_TMP, (size_t)PATH_MAX); + if (access(stack_log_reference_file, W_OK) == -1) { + strlcpy(stack_log_reference_file, stack_log_location, (size_t)PATH_MAX); + use_alternate_link_location = true; + } strlcat(stack_log_reference_file, stack_log_file_base_name, (size_t)PATH_MAX); append_int(stack_log_reference_file, pid, (size_t)PATH_MAX); if (progname && progname[0] != '\0') { strlcat(stack_log_reference_file, ".", (size_t)PATH_MAX); strlcat(stack_log_reference_file, progname, (size_t)PATH_MAX); } + if (!use_alternate_link_location) + strlcat(stack_log_reference_file, ".XXXXXX", (size_t)PATH_MAX); strlcat(stack_log_reference_file, ".XXXXXX", (size_t)PATH_MAX); strlcat(stack_log_reference_file, stack_log_link_suffix, (size_t)PATH_MAX); int link_file_descriptor = mkstemps(stack_log_reference_file, (int)strlen(stack_log_link_suffix)); if (link_file_descriptor == -1) { - _malloc_printf(ASL_LEVEL_INFO, "unable to create stack reference file at %s\n", stack_log_location); - return NULL; + _malloc_printf(ASL_LEVEL_INFO, "unable to create stack reference file %s at %s\n", + stack_log_reference_file, stack_log_location); + } else { + ssize_t written = write(link_file_descriptor, __stack_log_file_path__, strlen(__stack_log_file_path__)); + if (written < (ssize_t)strlen(__stack_log_file_path__)) { + _malloc_printf(ASL_LEVEL_INFO, "unable to write to stack reference file %s at %s\n", + stack_log_reference_file, stack_log_location); + } else { + const char *description_string = "\n(This is a reference file to the stack logs at the path above.)\n"; + write(link_file_descriptor, description_string, strlen(description_string)); } - ssize_t written = write(link_file_descriptor, stack_log_location, strlen(stack_log_location)); - if (written < (ssize_t)strlen(stack_log_location)) { - _malloc_printf(ASL_LEVEL_INFO, "unable to write to stack reference file at %s\n", stack_log_location); - return NULL; } - const char *description_string = "\n(This is a reference file to the stack logs at the path above.)\n"; - write(link_file_descriptor, description_string, strlen(description_string)); close(link_file_descriptor); } - - // Securely create the log file. - if ((index_file_descriptor = mkstemps(stack_log_location, (int)strlen(stack_log_file_suffix))) != -1) { - _malloc_printf(ASL_LEVEL_INFO, "stack logs being written into %s\n", stack_log_location); - created_log_location = stack_log_location; - } else { - _malloc_printf(ASL_LEVEL_INFO, "unable to create stack logs at %s\n", stack_log_location); - if (use_alternate_location) delete_logging_file(stack_log_reference_file); - stack_log_reference_file[0] = '\0'; - stack_log_location[0] = '\0'; - created_log_location = NULL; + if (use_alternate_link_location) { + _malloc_printf(ASL_LEVEL_INFO, "Please issue: cp %s %s\n", stack_log_reference_file, _PATH_TMP); } return created_log_location; } @@ -520,12 +597,12 @@ delete_logging_file(char *log_location) static void delete_log_files(void) { - if (stack_log_location && stack_log_location[0]) { - if (delete_logging_file(stack_log_location) == 0) { - _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", stack_log_location); - index_file_path[0] = '\0'; + if (__stack_log_file_path__ && __stack_log_file_path__[0]) { + if (delete_logging_file(__stack_log_file_path__) == 0) { + _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", __stack_log_file_path__); + __stack_log_file_path__[0] = '\0'; } else { - _malloc_printf(ASL_LEVEL_INFO, "unable to delete stack logs from %s\n", stack_log_location); + _malloc_printf(ASL_LEVEL_INFO, "unable to delete stack logs from %s\n", __stack_log_file_path__); } } if (stack_log_reference_file && stack_log_reference_file[0]) { @@ -632,7 +709,7 @@ robust_write(int fd, const void *buf, size_t nbyte) { // descriptor was closed on us. We need to reopen it if (fd == index_file_descriptor) { - file_to_reopen = index_file_path; + file_to_reopen = __stack_log_file_path__; fd_to_reset = &index_file_descriptor; } else { // We don't know about this file. Return (and abort()). @@ -687,7 +764,8 @@ flush_data(void) while (remaining > 0) { written = robust_write(index_file_descriptor, p, remaining); if (written == -1) { - _malloc_printf(ASL_LEVEL_INFO, "Unable to write to stack logging file %s (%s)\n", index_file_path, strerror(errno)); + _malloc_printf(ASL_LEVEL_INFO, "Unable to write to stack logging file %s (%s)\n", + __stack_log_file_path__, strerror(errno)); disable_stack_logging(); return; } @@ -726,7 +804,7 @@ prepare_to_log_stacks(void) pre_write_buffers = (stack_buffer_shared_memory*)mmap(0, full_shared_mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, (off_t)0); close(shmid); - if (!pre_write_buffers) { + if (MAP_FAILED == pre_write_buffers) { _malloc_printf(ASL_LEVEL_INFO, "error mapping in shared memory for disk-based stack logging output buffers\n"); disable_stack_logging(); return; @@ -1045,7 +1123,7 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors) close(shmid); } - if (shmid < 0 || cache->shmem == NULL) { + if (shmid < 0 || cache->shmem == MAP_FAILED) { // failed to connect to the shared memory region; warn and continue. _malloc_printf(ASL_LEVEL_INFO, "warning: unable to connect to remote process' shared memory; allocation histories may not be up-to-date.\n"); } @@ -1087,7 +1165,7 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors) } // if a snapshot is necessary, memcpy from remote frozen process' memory - // note: there were two ways to do this – spin lock or suspend. suspend allows us to + // note: there were two ways to do this - spin lock or suspend. suspend allows us to // analyze processes even if they were artificially suspended. with a lock, there'd be // worry that the target was suspended with the lock taken. if (update_snapshot) { @@ -1206,8 +1284,10 @@ destroy_cache_for_file_streams(remote_task_file_streams *descriptors) // In the stack log analysis process, find the stack logging files for target process // by scanning the temporary directory for directory entries with names of the form "stack-logs.." // If we find such a directory then open the stack logging files in there. +// We might also have been passed the file path if the client first read it from __stack_log_file_path__ +// global variable in the target task, as will be needed if the .link cannot be put in /tmp. static void -open_log_files(pid_t pid, remote_task_file_streams *this_task_streams) +open_log_files(pid_t pid, char* file_path, remote_task_file_streams *this_task_streams) { DIR *dp; struct dirent *entry; @@ -1216,6 +1296,11 @@ open_log_files(pid_t pid, remote_task_file_streams *this_task_streams) reap_orphaned_log_files(false); // reap any left-over log files (for non-existant processes, but not for this analysis process) + if (file_path != NULL) { + this_task_streams->index_file_stream = fopen(file_path, "r"); + return; + } + if ((dp = opendir(_PATH_TMP)) == NULL) { return; } @@ -1242,7 +1327,7 @@ open_log_files(pid_t pid, remote_task_file_streams *this_task_streams) } static remote_task_file_streams* -retain_file_streams_for_task(task_t task) +retain_file_streams_for_task(task_t task, char* file_path) { if (task == MACH_PORT_NULL) return NULL; @@ -1283,7 +1368,7 @@ retain_file_streams_for_task(task_t task) remote_task_file_streams *this_task_streams = &remote_fds[next_remote_task_fd]; - open_log_files(pid, this_task_streams); + open_log_files(pid, file_path, this_task_streams); // check if opens failed if (this_task_streams->index_file_stream == NULL) { @@ -1333,10 +1418,25 @@ release_file_streams_for_task(task_t task) #pragma mark - extern +// +// The following is used by client tools like malloc_history and Instruments to pass along the path +// of the index file as read from the target task's __stack_log_file_path__ variable (set in this file) +// Eventually, at a suitable point, this additional argument should just be added to the other APIs below. +// +kern_return_t +__mach_stack_logging_set_file_path(task_t task, char* file_path) +{ + remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, file_path); + if (remote_fd == NULL) { + return KERN_FAILURE; + } + return KERN_SUCCESS; +} + kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count) { - remote_task_file_streams *remote_fd = retain_file_streams_for_task(task); + remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL); if (remote_fd == NULL) { return KERN_FAILURE; } @@ -1416,7 +1516,7 @@ __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_ kern_return_t __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context) { - remote_task_file_streams *remote_fd = retain_file_streams_for_task(task); + remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL); if (remote_fd == NULL) { return KERN_FAILURE; } @@ -1499,7 +1599,7 @@ __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, v kern_return_t __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count) { - remote_task_file_streams *remote_fd = retain_file_streams_for_task(task); + remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL); if (remote_fd == NULL) return KERN_FAILURE; __unwind_stack_from_table_index(&remote_fd->cache->uniquing_table, stack_identifier, stack_frames_buffer, count, max_stack_frames); @@ -1531,9 +1631,9 @@ main() fprintf(stderr, "sizeof stack_log_file_base_name: %lu\n", sizeof(stack_log_file_base_name)); total_globals += sizeof(stack_log_file_base_name); fprintf(stderr, "sizeof stack_log_file_suffix: %lu\n", sizeof(stack_log_file_suffix)); total_globals += sizeof(stack_log_file_suffix); fprintf(stderr, "sizeof stack_log_link_suffix: %lu\n", sizeof(stack_log_link_suffix)); total_globals += sizeof(stack_log_link_suffix); - fprintf(stderr, "sizeof stack_log_location: %lu\n", sizeof(stack_log_location)); total_globals += sizeof(stack_log_location); - fprintf(stderr, "sizeof stack_log_reference_file: %lu\n", sizeof(stack_log_reference_file)); total_globals += sizeof(stack_log_reference_file); - fprintf(stderr, "sizeof index_file_path: %lu\n", sizeof(index_file_path)); total_globals += sizeof(index_file_path); + fprintf(stderr, "sizeof stack_log_location: %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX; + fprintf(stderr, "sizeof stack_log_reference_file: %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX; + fprintf(stderr, "sizeof __stack_log_file_path__ (index_file_path): %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX; fprintf(stderr, "sizeof index_file_descriptor: %lu\n", sizeof(index_file_descriptor)); total_globals += sizeof(index_file_descriptor); fprintf(stderr, "sizeof remote_fds: %lu\n", sizeof(remote_fds)); total_globals += sizeof(remote_fds); fprintf(stderr, "sizeof next_remote_task_fd: %lu\n", sizeof(next_remote_task_fd)); total_globals += sizeof(next_remote_task_fd); diff --git a/gen/strtofflags.c b/gen/strtofflags.c index 50a3771..098bf6a 100644 --- a/gen/strtofflags.c +++ b/gen/strtofflags.c @@ -90,6 +90,7 @@ static struct { { "nodump", UF_NODUMP, 1 }, { "noopaque", UF_OPAQUE, 0 }, { "nohidden", UF_HIDDEN, 0 }, + { "nocompressed", UF_COMPRESSED, 0 }, }; #define longestflaglen 12 #define nmappings (sizeof(mapping) / sizeof(mapping[0])) diff --git a/gen/sysctl-fbsd.c b/gen/sysctl-fbsd.c deleted file mode 120000 index fac1fc6..0000000 --- a/gen/sysctl-fbsd.c +++ /dev/null @@ -1 +0,0 @@ -./sysctl.c \ No newline at end of file diff --git a/gen/sysctl-fbsd.c b/gen/sysctl-fbsd.c new file mode 100644 index 0000000..7205820 --- /dev/null +++ b/gen/sysctl-fbsd.c @@ -0,0 +1,209 @@ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)sysctl.c 8.2 (Berkeley) 1/4/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/sysctl.c,v 1.6 2007/01/09 00:27:55 imp Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen); + +int +sysctl(name, namelen, oldp, oldlenp, newp, newlen) + int *name; + u_int namelen; + void *oldp, *newp; + size_t *oldlenp, newlen; +{ + if (name[0] != CTL_USER) { + if (namelen == 2 && name[0] == CTL_KERN && name[1] == KERN_EXEC) { + /* + * 7723306: intercept kern.exec and fake a return of + * a dummy string ("/" in this case) + */ + if (newp != NULL) { + errno = EPERM; + return -1; + } + if (oldp == NULL) { + if (oldlenp != NULL) *oldlenp = 2; + return 0; + } + if (oldlenp == NULL) { + errno = EFAULT; + return -1; + } + if (*oldlenp < 2) { + errno = ENOMEM; + return -1; + } + memmove(oldp, "/", 2); + *oldlenp = 2; + return 0; + } + return (__sysctl(name, namelen, oldp, oldlenp, newp, newlen)); + } + + if (newp != NULL) { + errno = EPERM; + return (-1); + } + if (namelen != 2) { + errno = EINVAL; + return (-1); + } + + switch (name[1]) { + case USER_CS_PATH: + if (oldp && *oldlenp < sizeof(_PATH_STDPATH)) { + errno = ENOMEM; + return -1; + } + *oldlenp = sizeof(_PATH_STDPATH); + if (oldp != NULL) + memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH)); + return (0); + } + + if (oldp && *oldlenp < sizeof(int)) { + errno = ENOMEM; + return (-1); + } + *oldlenp = sizeof(int); + if (oldp == NULL) + return (0); + + switch (name[1]) { + case USER_BC_BASE_MAX: + *(int *)oldp = BC_BASE_MAX; + return (0); + case USER_BC_DIM_MAX: + *(int *)oldp = BC_DIM_MAX; + return (0); + case USER_BC_SCALE_MAX: + *(int *)oldp = BC_SCALE_MAX; + return (0); + case USER_BC_STRING_MAX: + *(int *)oldp = BC_STRING_MAX; + return (0); + case USER_COLL_WEIGHTS_MAX: + *(int *)oldp = COLL_WEIGHTS_MAX; + return (0); + case USER_EXPR_NEST_MAX: + *(int *)oldp = EXPR_NEST_MAX; + return (0); + case USER_LINE_MAX: + *(int *)oldp = LINE_MAX; + return (0); + case USER_RE_DUP_MAX: + *(int *)oldp = RE_DUP_MAX; + return (0); + case USER_POSIX2_VERSION: + *(int *)oldp = _POSIX2_VERSION; + return (0); + case USER_POSIX2_C_BIND: +#ifdef POSIX2_C_BIND + *(int *)oldp = 1; +#else + *(int *)oldp = 0; +#endif + return (0); + case USER_POSIX2_C_DEV: +#ifdef POSIX2_C_DEV + *(int *)oldp = 1; +#else + *(int *)oldp = 0; +#endif + return (0); + case USER_POSIX2_CHAR_TERM: +#ifdef POSIX2_CHAR_TERM + *(int *)oldp = 1; +#else + *(int *)oldp = 0; +#endif + return (0); + case USER_POSIX2_FORT_DEV: +#ifdef POSIX2_FORT_DEV + *(int *)oldp = 1; +#else + *(int *)oldp = 0; +#endif + return (0); + case USER_POSIX2_FORT_RUN: +#ifdef POSIX2_FORT_RUN + *(int *)oldp = 1; +#else + *(int *)oldp = 0; +#endif + return (0); + case USER_POSIX2_LOCALEDEF: +#ifdef POSIX2_LOCALEDEF + *(int *)oldp = 1; +#else + *(int *)oldp = 0; +#endif + return (0); + case USER_POSIX2_SW_DEV: +#ifdef POSIX2_SW_DEV + *(int *)oldp = 1; +#else + *(int *)oldp = 0; +#endif + return (0); + case USER_POSIX2_UPE: +#ifdef POSIX2_UPE + *(int *)oldp = 1; +#else + *(int *)oldp = 0; +#endif + return (0); + case USER_STREAM_MAX: + *(int *)oldp = FOPEN_MAX; + return (0); + case USER_TZNAME_MAX: + *(int *)oldp = NAME_MAX; + return (0); + default: + errno = EINVAL; + return (-1); + } + /* NOTREACHED */ +} diff --git a/gen/sysctl.3 b/gen/sysctl.3 index 584b45c..8c8e4bc 100644 --- a/gen/sysctl.3 +++ b/gen/sysctl.3 @@ -187,7 +187,7 @@ Note: Implementation of -- to print whatever data deemed necessary from the large .Vt kinfo_proc structure ( -.In sysctl.h +.In sys/sysctl.h ) -- is left as an exercise for the reader. .Pp The top level names are defined with a CTL_ prefix in @@ -288,7 +288,7 @@ privilege may change the value. .It Sy "Second level name Type Changeable" .It "HW_MACHINE string no" .It "HW_MODEL string no" -.It "HW_NCPU integer no" +.It "HW_NCPU integer no (DEPRECATED)" .It "HW_BYTEORDER integer no" .It "HW_PHYSMEM integer no" .It "HW_MEMSIZE integer no" @@ -305,8 +305,16 @@ privilege may change the value. The machine class. .It Li HW_MODEL The machine model -.It Li HW_NCPU -The number of cpus. +.It Li HW_NCPU (DEPRECATED) +The number of cpus. It is recommended that you use "hw.physicalcpu" "hw.physicalcpu_max" "hw.logicalcpu" or "hw.logicalcpu_max" instead. +.It Li "hw.physicalcpu" +The number of physical processors available in the current power management mode. +.It Li "hw.physicalcpu_max" +The maximum number of physical processors that could be available this boot. +.It Li "hw.logicalcpu" +The number of logical processors available in the current power management mode. +.It Li "hw.logicalcpu_max" +The maximum number of logical processors that could be available this boot. .It Li HW_BYTEORDER The byteorder (4,321, or 1,234). .It Li HW_PHYSMEM @@ -355,7 +363,7 @@ information. .It "KERN_OSREV integer no" .It "KERN_OSTYPE string no" .It "KERN_POSIX1 integer no" -.It "KERN_PROC struct proc no" +.It "KERN_PROC struct kinfo_proc no" .It "KERN_PROF node not applicable" .It "KERN_QUANTUM integer yes" .It "KERN_SAVED_IDS integer no" @@ -449,10 +457,8 @@ with which the system attempts to comply. .It Li KERN_PROC Return the entire process table, or a subset of it. -An array of pairs of -.Va struct proc -followed by corresponding -.Va struct eproc +An array of +.Va struct kinfo_proc structures is returned, whose size depends on the current number of such objects in the system. The third and fourth level names are as follows: diff --git a/gen/syslog.3 b/gen/syslog.3 index c2e4ced..bdce947 100644 --- a/gen/syslog.3 +++ b/gen/syslog.3 @@ -216,9 +216,8 @@ Messages generated by the kernel. These cannot be generated by any user processes. .It Dv LOG_LPR The line printer spooling system: -.Xr lpr 1 , -.Xr lpc 8 , -.Xr lpd 8 , +.Xr cups-lpd 8 , +.Xr cupsd 8 , etc. .It Dv LOG_MAIL The mail system. @@ -298,6 +297,7 @@ syslog(LOG_INFO|LOG_LOCAL2, "foobar error: %m"); .Pp These include files are necessary for all functions. .Sh SEE ALSO +.Xr asl 3 , .Xr logger 1 , .Xr compat 5 , .Xr syslogd 8 @@ -318,4 +318,6 @@ for later interpolation by .Pp Always use the proper secure idiom: .Pp -.Dl syslog(LOG_ERR, "%s", string); +.Bd -literal -offset indent -compact +syslog(LOG_ERR, "%s", string); +.Ed diff --git a/gen/syslog.c b/gen/syslog.c index 1ef8aa2..d63e509 100644 --- a/gen/syslog.c +++ b/gen/syslog.c @@ -1,26 +1,26 @@ /* - * Copyright (c) 1999-2008 Apple Inc. All rights reserved. + * Copyright (c) 1999-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ + /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. @@ -54,29 +54,13 @@ * SUCH DAMAGE. */ -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include -#include -#include -#include -#include +#include +#include #include -#include -#include +#include "asl_private.h" #ifdef __STDC__ #include @@ -84,49 +68,25 @@ #include #endif -#include - #define LOG_NO_NOTIFY 0x1000 -#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID +extern const char *asl_syslog_faciliy_num_to_name(int n); #ifdef BUILDING_VARIANT -__private_extern__ int _sl_LogStat; /* status bits, set by openlog() */ -__private_extern__ const char *_sl_LogTag; /* string to tag the entry with */ -__private_extern__ int _sl_LogFacility; /* default facility code */ -__private_extern__ int _sl_LogMask; /* local mask of priorities to be logged */ -__private_extern__ int _sl_MasterLogMask; /* master (remote control) mask of priorities to be logged */ -__private_extern__ int _sl_ProcLogMask; /* process-specific (remote control) mask of priorities to be logged */ -__private_extern__ int _sl_RCToken; /* for remote control change notification */ -__private_extern__ int _sl_NotifyToken; /* for remote control of priority filter */ -__private_extern__ int _sl_NotifyMaster; /* for remote control of priority filter */ -__private_extern__ int _sl_pid; /* pid */ +__private_extern__ pthread_mutex_t _sl_lock; +__private_extern__ aslclient _sl_asl; +__private_extern__ char *_sl_ident; +__private_extern__ int _sl_fac; +__private_extern__ int _sl_opts; +__private_extern__ int _sl_mask; #else /* !BUILDING_VARIANT */ -__private_extern__ int _sl_LogStat = 0; /* status bits, set by openlog() */ -__private_extern__ const char *_sl_LogTag = NULL; /* string to tag the entry with */ -__private_extern__ int _sl_LogFacility = LOG_USER; /* default facility code */ -__private_extern__ int _sl_LogMask = 0xff; /* mask of priorities to be logged */ -__private_extern__ int _sl_MasterLogMask = 0; /* master mask of priorities to be logged */ -__private_extern__ int _sl_ProcLogMask = 0; /* process-specific mask of priorities to be logged */ -__private_extern__ int _sl_RCToken = -1; /* for remote control change notification */ -__private_extern__ int _sl_NotifyToken = -1; /* for remote control of max logged priority */ -__private_extern__ int _sl_NotifyMaster = -1; /* for remote control of max logged priority */ -__private_extern__ int _sl_pid = -1; /* pid */ +__private_extern__ pthread_mutex_t _sl_lock = PTHREAD_MUTEX_INITIALIZER; +__private_extern__ aslclient _sl_asl = NULL; +__private_extern__ char *_sl_ident = NULL; +__private_extern__ int _sl_fac = 0; +__private_extern__ int _sl_opts = 0; +__private_extern__ int _sl_mask = 0; #endif /* BUILDING_VARIANT */ -__private_extern__ void _sl_init_notify(); - -#define ASL_SERVICE_NAME "com.apple.system.logger" -static mach_port_t asl_server_port = MACH_PORT_NULL; - -#define NOTIFY_SYSTEM_MASTER "com.apple.system.syslog.master" -#define NOTIFY_PREFIX_SYSTEM "com.apple.system.syslog" -#define NOTIFY_PREFIX_USER "user.syslog" -#define NOTIFY_STATE_OFFSET 1000 - -/* notify SPI */ -uint32_t notify_register_plain(const char *name, int *out_token); -const char *asl_syslog_faciliy_num_to_name(int); - /* * syslog, vsyslog -- * print message on log file; output is intended for syslogd(8). @@ -155,413 +115,93 @@ syslog(pri, fmt, va_alist) void vsyslog(int pri, const char *fmt, va_list ap) { - int status, i, saved_errno, filter, check, rc_filter; - time_t tick; - struct timeval tval; - uint32_t elen, count, outlen; - char *p, *str, *expanded, *err_str, hname[MAXHOSTNAMELEN+1]; - const char *val; - uint64_t cval; - int fd, mask, level, facility; - aslmsg msg; - kern_return_t kstatus; - caddr_t out; - - saved_errno = errno; - - if (_sl_pid == -1) _sl_pid = getpid(); - - /* Check for invalid bits. */ - if (pri & ~(LOG_PRIMASK | LOG_FACMASK)) - { - syslog(INTERNALLOG, "syslog: unknown facility/priority: %x", pri); - pri &= (LOG_PRIMASK | LOG_FACMASK); - } - - level = LOG_PRI(pri); - facility = pri & LOG_FACMASK; - - if (facility == 0) facility = _sl_LogFacility; - - _sl_init_notify(); - - /* initialize or re-check process-specific and master filters */ - if (_sl_RCToken >= 0) - { - check = 0; - status = notify_check(_sl_RCToken, &check); - if ((status == NOTIFY_STATUS_OK) && (check != 0)) - { - if (_sl_NotifyMaster >= 0) - { - cval = 0; - if (notify_get_state(_sl_NotifyMaster, &cval) == NOTIFY_STATUS_OK) _sl_MasterLogMask = cval; - } - - if (_sl_NotifyToken >= 0) - { - cval = 0; - if (notify_get_state(_sl_NotifyToken, &cval) == NOTIFY_STATUS_OK) _sl_ProcLogMask = cval; - } - } - } - - filter = _sl_LogMask; - rc_filter = 0; - - /* master filter overrides local filter */ - if (_sl_MasterLogMask != 0) - { - filter = _sl_MasterLogMask; - rc_filter = 1; - } - - /* process-specific filter overrides local and master */ - if (_sl_ProcLogMask != 0) - { - filter = _sl_ProcLogMask; - rc_filter = 1; - } - - mask = LOG_MASK(level); - if ((mask & filter) == 0) return; - - /* Build the message. */ - msg = asl_new(ASL_TYPE_MSG); - - if (_sl_LogTag == NULL) _sl_LogTag = *(*_NSGetArgv()); - if (_sl_LogTag != NULL) - { - asl_set(msg, ASL_KEY_SENDER, _sl_LogTag); - } - - str = (char *)asl_syslog_faciliy_num_to_name(facility); - if (str != NULL) asl_set(msg, ASL_KEY_FACILITY, str); - - str = NULL; - memset(&tval, 0, sizeof(struct timeval)); - - status = gettimeofday(&tval, NULL); - if (status == 0) - { - str = NULL; - asprintf(&str, "%lu", tval.tv_sec); - if (str != NULL) - { - asl_set(msg, ASL_KEY_TIME, str); - free(str); - } - - str = NULL; - asprintf(&str, "%lu", tval.tv_usec * 1000); - if (str != NULL) - { - asl_set(msg, ASL_KEY_TIME_NSEC, str); - free(str); - } - } - else - { - tick = time(NULL); - str = NULL; - asprintf(&str, "%lu", tick); - if (str != NULL) - { - asl_set(msg, ASL_KEY_TIME, str); - free(str); - } - } - - str = NULL; - asprintf(&str, "%u", _sl_pid); - if (str != NULL) - { - asl_set(msg, ASL_KEY_PID, str); - free(str); - } - - str = NULL; - asprintf(&str, "%d", getuid()); - if (str != NULL) - { - asl_set(msg, ASL_KEY_UID, str); - free(str); - } - - str = NULL; - asprintf(&str, "%u", getgid()); - if (str != NULL) - { - asl_set(msg, ASL_KEY_GID, str); - free(str); - } - - str = NULL; - asprintf(&str, "%u", level); - if (str != NULL) - { - asl_set(msg, ASL_KEY_LEVEL, str); - free(str); - } - - status = gethostname(hname, MAXHOSTNAMELEN); - if (status < 0) asl_set(msg, ASL_KEY_HOST, "localhost"); - else asl_set(msg, ASL_KEY_HOST, hname); - - /* check for %m */ - count = 0; - for (i = 0; fmt[i] != '\0'; i++) - { - if ((fmt[i] == '%') && (fmt[i+1] == 'm')) count++; - } - - expanded = NULL; - elen = 0; - err_str = NULL; - - /* deal with malloc failures gracefully */ - if (count > 0) - { - err_str = strdup(strerror(saved_errno)); - if (err_str == NULL) count = 0; - else - { - elen = strlen(err_str); - expanded = malloc(i + (count * elen)); - if (expanded == NULL) count = 0; - } - } + int fac; + aslmsg facmsg; + const char *facility; - if (expanded == NULL) expanded = (char *)fmt; - if (count > 0) + facmsg = NULL; + fac = pri & LOG_FACMASK; + if (fac != 0) { - p = expanded; - - for (i = 0; fmt[i] != '\0'; i++) + facility = asl_syslog_faciliy_num_to_name(fac); + if (facility != NULL) { - if ((fmt[i] == '%') && (fmt[i+1] == 'm')) - { - memcpy(p, err_str, elen); - p += elen; - i++; - } - else - { - *p++ = fmt[i]; - } + facmsg = asl_new(ASL_TYPE_MSG); + asl_set(facmsg, ASL_KEY_FACILITY, facility); } - - *p = '\0'; } - if (err_str != NULL) free(err_str); - - vasprintf(&str, expanded, ap); - if (count > 0) free(expanded); - - if (str != NULL) - { - asl_set(msg, ASL_KEY_MSG, str); - - /* Output to stderr if requested. */ - if (_sl_LogStat & LOG_PERROR) - { - p = NULL; - if (_sl_LogStat & LOG_PID) asprintf(&p, "%s[%u]: %s", (_sl_LogTag == NULL) ? "???" : _sl_LogTag, _sl_pid, str); - else asprintf(&p, "%s: %s", (_sl_LogTag == NULL) ? "???" : _sl_LogTag, str); - - if (p != NULL) - { - struct iovec iov[2]; - - iov[0].iov_base = p; - iov[0].iov_len = strlen(p); - iov[1].iov_base = "\n"; - iov[1].iov_len = 1; - writev(STDERR_FILENO, iov, 2); - free(p); - } - } - - free(str); - } - - /* Set "ASLOption store" if remote control is active */ - if (rc_filter != 0) - { - val = asl_get(msg, ASL_KEY_OPTION); - if (val == NULL) - { - asl_set(msg, ASL_KEY_OPTION, ASL_OPT_STORE); - } - else - { - str = NULL; - asprintf(&str, "%s %s", ASL_OPT_STORE, val); - if (str != NULL) - { - asl_set(msg, ASL_KEY_OPTION, str); - free(str); - str = NULL; - } - } - } - - /* send a mach message to syslogd */ - str = asl_format_message(msg, ASL_MSG_FMT_RAW, ASL_TIME_FMT_SEC, ASL_ENCODE_ASL, &count); - if (str != NULL) - { - outlen = count + 11; - kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&out, outlen + 1, TRUE); - if (kstatus == KERN_SUCCESS) - { - memset(out, 0, outlen + 1); - snprintf((char *)out, outlen, "%10u %s", count, str); - - status = 0; - if (asl_server_port == MACH_PORT_NULL) kstatus = bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &asl_server_port); - - if (kstatus == KERN_SUCCESS) kstatus = _asl_server_message(asl_server_port, (caddr_t)out, outlen + 1); - else vm_deallocate(mach_task_self(), (vm_address_t)out, outlen + 1); - - if (kstatus == KERN_SUCCESS) - { - free(str); - asl_free(msg); - return; - } - } - - free(str); - } - - /* - * Output the message to the console. - */ - if (_sl_LogStat & LOG_CONS && (fd = open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) - { - count = 0; - - p = asl_format_message(msg, ASL_MSG_FMT_STD, ASL_TIME_FMT_LCL, ASL_ENCODE_SAFE, &count); - if (p != NULL) - { - struct iovec iov; - - /* count includes trailing nul */ - iov.iov_len = count - 1; - iov.iov_base = p; - writev(fd, &iov, 1); - - free(p); - } - - close(fd); - } - - asl_free(msg); + asl_vlog(_sl_asl, facmsg, LOG_PRI(pri), fmt, ap); + if (facmsg != NULL) asl_free(facmsg); } #ifndef BUILDING_VARIANT -__private_extern__ void -_syslog_fork_child() -{ - _sl_RCToken = -1; - _sl_NotifyToken = -1; - _sl_NotifyMaster = -1; - - asl_server_port = MACH_PORT_NULL; - - _sl_pid = getpid(); -} - -__private_extern__ void -_sl_init_notify() +void +openlog(const char *ident, int opts, int logfac) { - int status; - char *notify_name; - uint32_t euid; + const char *facility; + uint32_t asl_opts; - if (_sl_LogStat & LOG_NO_NOTIFY) - { - _sl_RCToken = -2; - _sl_NotifyMaster = -2; - _sl_NotifyToken = -2; - return; - } - - if (_sl_RCToken == -1) - { - status = notify_register_check(NOTIFY_RC, &_sl_RCToken); - if (status != NOTIFY_STATUS_OK) _sl_RCToken = -2; - } + pthread_mutex_lock(&_sl_lock); - if (_sl_NotifyMaster == -1) - { - status = notify_register_plain(NOTIFY_SYSTEM_MASTER, &_sl_NotifyMaster); - if (status != NOTIFY_STATUS_OK) _sl_NotifyMaster = -2; - } + /* close existing aslclient */ + if (_sl_asl != NULL) asl_close(_sl_asl); + _sl_asl = NULL; - if (_sl_NotifyToken == -1) - { - _sl_NotifyToken = -2; + if (_sl_ident != NULL) free(_sl_ident); + _sl_ident = NULL; - euid = geteuid(); - notify_name = NULL; - if (euid == 0) asprintf(¬ify_name, "%s.%d", NOTIFY_PREFIX_SYSTEM, getpid()); - else asprintf(¬ify_name, "user.uid.%d.syslog.%d", euid, getpid()); + /* open with specified parameters */ - if (notify_name != NULL) - { - status = notify_register_plain(notify_name, &_sl_NotifyToken); - free(notify_name); - if (status != NOTIFY_STATUS_OK) _sl_NotifyToken = -2; - } - } -} + if (ident != NULL) _sl_ident = strdup(ident); + /* NB we allow the strdup to fail silently */ -void -openlog(const char *ident, int logstat, int logfac) -{ - kern_return_t kstatus; + _sl_fac = logfac; + facility = asl_syslog_faciliy_num_to_name(_sl_fac); - if (ident != NULL) _sl_LogTag = ident; + _sl_opts = opts; + asl_opts = ASL_OPT_SYSLOG_LEGACY; - _sl_LogStat = logstat; + if (_sl_opts & LOG_NO_NOTIFY) asl_opts |= ASL_OPT_NO_REMOTE; + if (_sl_opts & LOG_PERROR) asl_opts |= ASL_OPT_STDERR; - if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) _sl_LogFacility = logfac; + _sl_mask = ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG); - if (asl_server_port == MACH_PORT_NULL) - { - kstatus = bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &asl_server_port); - } + _sl_asl = asl_open(_sl_ident, facility, asl_opts); + asl_set_filter(_sl_asl, _sl_mask); - _sl_pid = getpid(); - _sl_init_notify(); + pthread_mutex_unlock(&_sl_lock); } void closelog() { - if (asl_server_port != MACH_PORT_NULL) mach_port_deallocate(mach_task_self(), asl_server_port); - asl_server_port = MACH_PORT_NULL; + pthread_mutex_lock(&_sl_lock); - if (_sl_NotifyToken != -1) notify_cancel(_sl_NotifyToken); - _sl_NotifyToken = -1; + if (_sl_asl != NULL) asl_close(_sl_asl); + _sl_asl = NULL; - if (_sl_NotifyMaster != -1) notify_cancel(_sl_NotifyMaster); - _sl_NotifyMaster = -1; + if (_sl_ident != NULL) free(_sl_ident); + _sl_ident = NULL; + + pthread_mutex_unlock(&_sl_lock); } /* setlogmask -- set the log mask level */ int -setlogmask(int pmask) +setlogmask(int mask) { - int omask; + int oldmask; + + pthread_mutex_lock(&_sl_lock); + + _sl_mask = mask; + oldmask = asl_set_filter(_sl_asl, mask); + + pthread_mutex_unlock(&_sl_lock); - omask = _sl_LogMask; - if (pmask != 0) _sl_LogMask = pmask; - return (omask); + return oldmask; } #endif /* !BUILDING_VARIANT */ diff --git a/gen/telldir-fbsd.c b/gen/telldir-fbsd.c index 6ed1288..355ed50 100644 --- a/gen/telldir-fbsd.c +++ b/gen/telldir-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/telldir.c,v 1.8 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/telldir.c,v 1.11 2008/05/05 14:05:23 kib Exp $"); #include "namespace.h" #include @@ -69,7 +65,7 @@ telldir(dirp) #if __DARWIN_UNIX03 if (__isthreaded) - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_lock(&dirp->dd_lock); LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { if ( #if __DARWIN_64_BIT_INO_T @@ -82,14 +78,14 @@ telldir(dirp) } if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) { if (__isthreaded) - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_unlock(&dirp->dd_lock); return (-1); } #else /* !__DARWIN_UNIX03 */ if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) return (-1); if (__isthreaded) - _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_lock(&dirp->dd_lock); #endif /* __DARWIN_UNIX03 */ lp->loc_index = dirp->dd_td->td_loccnt++; #if __DARWIN_64_BIT_INO_T @@ -103,7 +99,7 @@ telldir(dirp) found: #endif /* __DARWIN_UNIX03 */ if (__isthreaded) - _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + _pthread_mutex_unlock(&dirp->dd_lock); return (lp->loc_index); } @@ -141,7 +137,7 @@ _seekdir(dirp, loc) #endif /* __DARWIN_64_BIT_INO_T */ dirp->dd_loc = 0; while (dirp->dd_loc < lp->loc_loc) { - dp = _readdir_unlocked(dirp); + dp = _readdir_unlocked(dirp, 0); if (dp == NULL) break; } diff --git a/gen/telldir.h b/gen/telldir.h index 379cd09..c1f0ad0 100644 --- a/gen/telldir.h +++ b/gen/telldir.h @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/lib/libc/gen/telldir.h,v 1.2 2001/01/24 12:59:24 deischen Exp $ + * $FreeBSD: src/lib/libc/gen/telldir.h,v 1.3 2008/05/05 14:05:23 kib Exp $ */ #ifndef _TELLDIR_H_ @@ -69,7 +69,7 @@ struct _telldir { #if __DARWIN_64_BIT_INO_T size_t __getdirentries64(int fd, void *buf, size_t bufsize, __darwin_off_t *basep); #endif /* __DARWIN_64_BIT_INO_T */ -struct dirent *_readdir_unlocked(DIR *) __DARWIN_INODE64(_readdir_unlocked); +struct dirent *_readdir_unlocked(DIR *, int) __DARWIN_INODE64(_readdir_unlocked); void _reclaim_telldir(DIR *); void _seekdir(DIR *, long) __DARWIN_ALIAS_I(_seekdir); long telldir(DIR *) __DARWIN_ALIAS_I(telldir); diff --git a/gen/termios-fbsd.c b/gen/termios-fbsd.c index 4168a4e..ab540d6 100644 --- a/gen/termios-fbsd.c +++ b/gen/termios-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)termios.c 8.2 (Berkeley) 2/21/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/termios.c,v 1.13 2002/05/28 16:59:39 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/termios.c,v 1.16 2009/05/07 13:49:48 ed Exp $"); #if __DARWIN_UNIX03 #ifdef VARIANT_CANCELABLE @@ -118,6 +114,31 @@ tcgetpgrp(fd) return ((pid_t)s); } +#if 0 // Needs API review first +pid_t +tcgetsid(int fd) +{ + int s; + + if (_ioctl(fd, TIOCGSID, &s) < 0) + return ((pid_t)-1); + + return ((pid_t)s); +} + +int +tcsetsid(int fd, pid_t pid) +{ + + if (pid != getsid(0)) { + errno = EINVAL; + return (-1); + } + + return (_ioctl(fd, TIOCSCTTY, NULL)); +} +#endif + speed_t cfgetospeed(t) const struct termios *t; diff --git a/gen/time-fbsd.c b/gen/time-fbsd.c index 544440c..d77e38a 100644 --- a/gen/time-fbsd.c +++ b/gen/time-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)time.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/time.c,v 1.4 2003/07/19 02:53:46 wollman Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/time.c,v 1.5 2007/01/09 00:27:55 imp Exp $"); #include #include diff --git a/gen/time.3 b/gen/time.3 index ffebc88..e694537 100644 --- a/gen/time.3 +++ b/gen/time.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)time.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/time.3,v 1.13 2004/07/02 19:07:30 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/time.3,v 1.15 2007/01/09 00:27:55 imp Exp $ .\" .Dd July 18, 2003 .Dt TIME 3 @@ -78,6 +74,11 @@ The .Nm function conforms to .St -p1003.1-2001 . +.Sh HISTORY +A +.Fn time +function appeared in +.At v6 . .Sh BUGS Neither .St -isoC-99 @@ -98,8 +99,3 @@ standards (including older versions of did not set .No \&* Ns Va tloc in the error case. -.Sh HISTORY -A -.Fn time -function appeared in -.At v6 . diff --git a/gen/ttyname-fbsd.c b/gen/ttyname-fbsd.c index e7cdb62..aa5483a 100644 --- a/gen/ttyname-fbsd.c +++ b/gen/ttyname-fbsd.c @@ -54,7 +54,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/ttyname.c,v 1.16 2004/01/06 18:26:14 nectar #include "libc_private.h" #ifndef BUILDING_VARIANT -static char buf[sizeof(_PATH_DEV) + MAXNAMLEN]; +static pthread_once_t ttyname_buf_control = PTHREAD_ONCE_INIT; +static char *buf = NULL; static char *ttyname_threaded(int fd); static char *ttyname_unthreaded(int fd); @@ -114,7 +115,7 @@ ttyname_r(int fd, char *thrbuf, size_t len) } #endif /* __DARWIN_UNIX03 */ - strcpy(thrbuf, _PATH_DEV); + strlcpy(thrbuf, _PATH_DEV, len); if (devname_r(sb.st_rdev, S_IFCHR, thrbuf + strlen(thrbuf), len - strlen(thrbuf)) == NULL) #if __DARWIN_UNIX03 @@ -171,6 +172,12 @@ ttyname_threaded(int fd) #endif /* __DARWIN_UNIX03 */ } +static void +ttyname_buf_allocate(void) +{ + buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN); +} + static char * ttyname_unthreaded(int fd) { @@ -188,9 +195,15 @@ ttyname_unthreaded(int fd) return (NULL); } - strcpy(buf, _PATH_DEV); + if (pthread_once(&ttyname_buf_control, ttyname_buf_allocate) + || !buf) { + errno = ENOMEM; + return (NULL); + } + + strlcpy(buf, _PATH_DEV, sizeof(_PATH_DEV) + MAXNAMLEN); if (devname_r(sb.st_rdev, S_IFCHR, - buf + strlen(buf), sizeof(buf) - strlen(buf)) == NULL) { + buf + strlen(buf), sizeof(_PATH_DEV) + MAXNAMLEN - strlen(buf)) == NULL) { errno = ERANGE; return (NULL); } diff --git a/gen/ualarm.3 b/gen/ualarm.3 index ede1ea2..01a681f 100644 --- a/gen/ualarm.3 +++ b/gen/ualarm.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)ualarm.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/ualarm.3,v 1.19 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/ualarm.3,v 1.20 2007/01/09 00:27:56 imp Exp $ .\" .Dd April 19, 1994 .Dt UALARM 3 diff --git a/gen/unvis-fbsd.c b/gen/unvis-fbsd.c index 02984c0..da2efbf 100644 --- a/gen/unvis-fbsd.c +++ b/gen/unvis-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/unvis.c,v 1.9 2004/08/02 08:46:23 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/unvis.c,v 1.10 2007/01/09 00:27:56 imp Exp $"); #include "xlocale_private.h" diff --git a/gen/usleep-fbsd.c b/gen/usleep-fbsd.c index 5ad2cd2..fc8054b 100644 --- a/gen/usleep-fbsd.c +++ b/gen/usleep-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/usleep.c,v 1.28 2002/12/29 00:59:09 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/usleep.c,v 1.31 2009/12/05 19:31:38 ed Exp $"); #include "namespace.h" #include @@ -48,8 +44,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/usleep.c,v 1.28 2002/12/29 00:59:09 mike Ex #include "un-namespace.h" int -usleep(useconds) - useconds_t useconds; +usleep(useconds_t useconds) { struct timespec time_to_sleep; diff --git a/gen/usleep.3 b/gen/usleep.3 index acee9a3..e99b773 100644 --- a/gen/usleep.3 +++ b/gen/usleep.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)usleep.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/usleep.3,v 1.18 2002/12/29 00:59:09 mike Exp $ +.\" $FreeBSD: src/lib/libc/gen/usleep.3,v 1.19 2007/01/09 00:27:56 imp Exp $ .\" .Dd February 13, 1998 .Dt USLEEP 3 diff --git a/gen/utime.3 b/gen/utime.3 index 92e8467..c96ab2e 100644 --- a/gen/utime.3 +++ b/gen/utime.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)utime.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/utime.3,v 1.11 2002/08/24 00:39:43 mike Exp $ +.\" $FreeBSD: src/lib/libc/gen/utime.3,v 1.14 2007/01/09 00:27:56 imp Exp $ .\" .Dd June 4, 1993 .Dt UTIME 3 @@ -56,7 +52,13 @@ This interface is obsoleted by The .Fn utime function sets the access and modification times of the named file, -based on the structures in the argument array +based on the +.Va actime +and +.Va modtime +fields of the +.Vt "struct utimbuf" +pointed at by .Fa times . .Pp If the times are specified (the @@ -81,13 +83,13 @@ for any of the errors specified for the library function .Sh SEE ALSO .Xr stat 2 , .Xr utimes 2 -.Sh HISTORY -A -.Fn utime -function appeared in -.At v7 . .Sh STANDARDS The .Fn utime function conforms to .St -p1003.1-88 . +.Sh HISTORY +A +.Fn utime +function appeared in +.At v7 . diff --git a/gen/utmpx-darwin.c b/gen/utmpx-darwin.c index 914cca7..ec2f733 100644 --- a/gen/utmpx-darwin.c +++ b/gen/utmpx-darwin.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005-2008 Apple Inc. All rights reserved. + * Copyright (c) 2005-2009 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -39,6 +39,7 @@ #endif /* UTMP_COMPAT */ #include #include +#include #include #include #include @@ -57,9 +58,9 @@ #include #endif /* UTMP_COMPAT */ +__private_extern__ const char __utx_magic__[UTMPX_MAGIC] = __UTX_MAGIC__; + extern const char _utmpx_vers[]; /* in utmpx.c */ -extern char *asl_list_to_string(asl_search_result_t *, uint32_t *); -extern asl_search_result_t *asl_list_from_string(const char *); static void msg2lastlogx(const aslmsg, struct lastlogx *); static void msg2utmpx(const aslmsg, struct utmpx *); @@ -76,6 +77,7 @@ static int pw_size = 0; /* indirection causes argument to be substituted before stringification */ #define STR(x) __STRING(x) +#ifdef UTMP_COMPAT static char * _pwnam_r(const char *user, struct passwd *pw) { @@ -97,6 +99,7 @@ _pwnam_r(const char *user, struct passwd *pw) } return buf; } +#endif static char * _pwuid_r(uid_t uid, struct passwd *pw) @@ -165,7 +168,7 @@ getlastlogxbyname(const char *user, struct lastlogx *lx) asl_set_query(m, FACILITY, LASTLOG_FACILITY, ASL_QUERY_OP_EQUAL); asl_set_query(m, "ut_user", user, ASL_QUERY_OP_EQUAL); - qm[0] = m; + qm[0] = (asl_msg_t *)m; query.count = 1; query.msg = qm; @@ -243,7 +246,7 @@ static void utmpx2msg(const struct utmpx *u, aslmsg m) { char buf[_UTX_HOSTSIZE + 1]; /* the largest string in struct utmpx */ - char *cp; + const char *cp; #define ISET(e) { snprintf(buf, sizeof(buf), "%d", u->e); \ asl_set(m, #e, buf); } #define LSET(e) { snprintf(buf, sizeof(buf), "%ld", u->e); \ @@ -255,7 +258,7 @@ utmpx2msg(const struct utmpx *u, aslmsg m) } SSET(ut_user); - cp = u->ut_id + sizeof(u->ut_id); + cp = (char *)u->ut_id + sizeof(u->ut_id); while(--cp >= u->ut_id && isprint(*cp)) {} if(cp < u->ut_id) { SSET(ut_id); @@ -489,7 +492,7 @@ static struct { static struct { int fd; int dir; - char file[MAXPATHLEN]; + char *file; off_t off; size_t count; #ifdef __LP64__ @@ -540,21 +543,27 @@ wtmpxname(const char *fname) } len = strlen(fname); - if (len >= sizeof(wtmp_file.file)) + if (len >= MAXPATHLEN) return 0; /* must end in x! */ if (fname[len - 1] != 'x') return 0; - (void)strlcpy(wtmp_file.file, fname, sizeof(wtmp_file.file)); - if (wtmp_func.which == WTMP_ASL) end_asl(); else if (wtmp_file.fd >= 0) { close(wtmp_file.fd); wtmp_file.fd = -1; } + + if (wtmp_file.file) + free(wtmp_file.file); + + wtmp_file.file = strdup(fname); + if (wtmp_file.file == NULL) + return 0; + wtmp_func.which = WTMP_FILE; wtmp_func.end = end_file; wtmp_func.get = get_file; @@ -746,8 +755,8 @@ set_asl(int forward) asl_set_query(q0, FACILITY, UTMPX_FACILITY, ASL_QUERY_OP_EQUAL); asl_set_query(q1, FACILITY, LASTLOG_FACILITY, ASL_QUERY_OP_EQUAL); - m[0] = q0; - m[1] = q1; + m[0] = (asl_msg_t *)q0; + m[1] = (asl_msg_t *)q1; query.count = 2; query.msg = m; @@ -1145,3 +1154,43 @@ _write_wtmp(const struct utmp *u) (void) close(fd); } #endif /* UTMP_COMPAT */ + +/* + * thread aware SPI + */ +utmpx_t +_openutx(const char *name) +{ + struct _utmpx *U; + + if ((U = calloc(1, sizeof(struct _utmpx))) == NULL) + return NULL; + memcpy(U->magic, __utx_magic__, UTMPX_MAGIC); + U->utmpx_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + if (__utmpxname(U, name) == 0) { + if (!U->utfile_system) + free(U->utfile); + free(U); + errno = EINVAL; + return NULL; + } + return (utmpx_t)U; +} + +int +_closeutx(utmpx_t u) +{ + struct _utmpx *U = (struct _utmpx *)u; + + if (!U || memcmp(U->magic, __utx_magic__, UTMPX_MAGIC) != 0) { + errno = EINVAL; + return -1; + } + UTMPX_LOCK(U); + __endutxent(U); + if (!U->utfile_system) + free(U->utfile); + UTMPX_UNLOCK(U); + free(U); + return 0; +} diff --git a/gen/utmpx-darwin.h b/gen/utmpx-darwin.h index a150547..14804e4 100644 --- a/gen/utmpx-darwin.h +++ b/gen/utmpx-darwin.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005, 2009 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,6 +22,10 @@ * @APPLE_LICENSE_HEADER_END@ */ #include +#include +#include +#include +#include #ifdef UTMP_COMPAT #define UTMP_COMPAT_UTMP0 0x01 @@ -33,12 +37,31 @@ #define LASTLOG_FACILITY "com.apple.system.lastlog" #define UTMPX_FACILITY "com.apple.system.utmpx" -#define UTMPX_LOCK if (__is_threaded) pthread_mutex_lock(&utmpx_mutex) -#define UTMPX_UNLOCK if (__is_threaded) pthread_mutex_unlock(&utmpx_mutex) +#define UTMPX_LOCK(x) if (__is_threaded) pthread_mutex_lock(&(x)->utmpx_mutex) +#define UTMPX_UNLOCK(x) if (__is_threaded) pthread_mutex_unlock(&(x)->utmpx_mutex) +#define UTMPX_MAGIC 8 +#define __UTX_MAGIC__ { 'u', 't', 'x', 0, 'v', 1, 0, 0 } + +#define TEST_UTMPX_T(x,y) { \ + if (!(y)) \ + LIBC_ABORT("%s: NULL utmpx_t", (x)); \ + if (memcmp((y)->magic, __utx_magic__, UTMPX_MAGIC) != 0) \ + LIBC_ABORT("%s: magic mismatch", (x)); \ + } -extern int utfile_system; /* are we using _PATH_UTMPX? */ extern int __is_threaded; -extern pthread_mutex_t utmpx_mutex; + +struct _utmpx { + char magic[UTMPX_MAGIC]; + struct utmpx ut; + pthread_mutex_t utmpx_mutex; + char *utfile; + FILE *fp; + unsigned int utfile_system :1; /* are we using _PATH_UTMPX? */ + unsigned int readonly :1; +}; +extern struct _utmpx __utx__; /* the default struct _utmpx */ +extern const char __utx_magic__[]; /* size of UTMPX_MAGIC */ #ifdef __LP64__ #define __need_struct_timeval32 @@ -75,9 +98,11 @@ struct utmpx32 { }; #endif /* __LP64__ */ -void _endutxent(void); -void _setutxent(void); -struct utmpx *_pututxline(const struct utmpx *); +void __endutxent(struct _utmpx *); +struct utmpx *__getutxent(struct _utmpx *); +void __setutxent(struct _utmpx *); +struct utmpx *__pututxline(struct _utmpx *, const struct utmpx *); +int __utmpxname(struct _utmpx *, const char *); #ifdef __LP64__ void _utmpx32_64(const struct utmpx32 *, struct utmpx *); void _utmpx64_32(const struct utmpx *, struct utmpx32 *); diff --git a/gen/utmpx-nbsd.c b/gen/utmpx-nbsd.c index 8a4c3b2..0eda3d4 100644 --- a/gen/utmpx-nbsd.c +++ b/gen/utmpx-nbsd.c @@ -1,4 +1,4 @@ -/* $NetBSD: utmpx.c,v 1.21 2003/09/06 16:42:10 wiz Exp $ */ +/* $NetBSD: utmpx.c,v 1.25 2008/04/28 20:22:59 martin Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -15,13 +15,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -38,7 +31,7 @@ #include #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: utmpx.c,v 1.21 2003/09/06 16:42:10 wiz Exp $"); +__RCSID("$NetBSD: utmpx.c,v 1.25 2008/04/28 20:22:59 martin Exp $"); #endif /* LIBC_SCCS and not lint */ #include "namespace.h" @@ -54,94 +47,117 @@ __RCSID("$NetBSD: utmpx.c,v 1.21 2003/09/06 16:42:10 wiz Exp $"); #include #include #include -#ifdef LEGACY_UTMP_APIS +#ifdef UNIFDEF_LEGACY_UTMP_APIS #include -#endif /* LEGACY_UTMP_APIS */ +#endif /* UNIFDEF_LEGACY_UTMP_APIS */ #include #include #include #include #include -static FILE *fp; -static int readonly = 0; -static struct utmpx ut; -static char utfile[MAXPATHLEN] = _PATH_UTMPX; -__private_extern__ int utfile_system = 1; /* are we using _PATH_UTMPX? */ -__private_extern__ pthread_mutex_t utmpx_mutex = PTHREAD_MUTEX_INITIALIZER; +/* This is the default struct _utmpx shared by the POSIX APIs */ +__private_extern__ +struct _utmpx __utx__ = { + __UTX_MAGIC__, /* magic */ + {}, /* ut */ + PTHREAD_MUTEX_INITIALIZER, /* utmpx_mutex */ + _PATH_UTMPX, /* utfile */ + NULL, /* fp */ + 1, /* utfile_system */ + 0, /* readonly */ +}; -static struct utmpx *_getutxid(const struct utmpx *); +static struct utmpx *__getutxid(struct _utmpx *, const struct utmpx *); __private_extern__ const char _utmpx_vers[] = "utmpx-1.00"; __private_extern__ void -_setutxent() +__setutxent(struct _utmpx *U) { - (void)memset(&ut, 0, sizeof(ut)); - if (fp == NULL) + (void)memset(&U->ut, 0, sizeof(U->ut)); + if (U->fp == NULL) return; #ifdef __LP64__ - (void)fseeko(fp, (off_t)sizeof(struct utmpx32), SEEK_SET); + (void)fseeko(U->fp, (off_t)sizeof(struct utmpx32), SEEK_SET); #else /* __LP64__ */ - (void)fseeko(fp, (off_t)sizeof(ut), SEEK_SET); + (void)fseeko(U->fp, (off_t)sizeof(U->ut), SEEK_SET); #endif /* __LP64__ */ } +void +_setutxent(struct _utmpx *U) +{ + + TEST_UTMPX_T("_setutxent", U); + UTMPX_LOCK(U); + __setutxent(U); + UTMPX_UNLOCK(U); +} + void setutxent() { - UTMPX_LOCK; - _setutxent(); - UTMPX_UNLOCK; + _setutxent(&__utx__); } __private_extern__ void -_endutxent() +__endutxent(struct _utmpx *U) { - - (void)memset(&ut, 0, sizeof(ut)); - if (fp != NULL) { - (void)fclose(fp); - fp = NULL; - readonly = 0; + (void)memset(&U->ut, 0, sizeof(U->ut)); + if (U->fp != NULL) { + int saveerrno = errno; + (void)fclose(U->fp); + errno = saveerrno; + U->fp = NULL; + U->readonly = 0; } } +void +_endutxent(struct _utmpx *U) +{ + TEST_UTMPX_T("_endutxent", U); + UTMPX_LOCK(U); + __endutxent(U); + UTMPX_UNLOCK(U); +} + + void endutxent() { - UTMPX_LOCK; - _endutxent(); - UTMPX_UNLOCK; + _endutxent(&__utx__); } -static struct utmpx * -_getutxent() +__private_extern__ struct utmpx * +__getutxent(struct _utmpx *U) { + int saveerrno; #ifdef __LP64__ struct utmpx32 ut32; #endif /* __LP64__ */ - if (fp == NULL) { + if (U->fp == NULL) { struct stat st; - if ((fp = fopen(utfile, "r+")) == NULL) - if ((fp = fopen(utfile, "w+")) == NULL) { - if ((fp = fopen(utfile, "r")) == NULL) + if ((U->fp = fopen(U->utfile, "r+")) == NULL) + if ((U->fp = fopen(U->utfile, "w+")) == NULL) { + if ((U->fp = fopen(U->utfile, "r")) == NULL) goto fail; else - readonly = 1; + U->readonly = 1; } - fcntl(fileno(fp), F_SETFD, 1); /* set close-on-exec flag */ + fcntl(fileno(U->fp), F_SETFD, 1); /* set close-on-exec flag */ /* get file size in order to check if new file */ - if (fstat(fileno(fp), &st) == -1) + if (fstat(fileno(U->fp), &st) == -1) goto failclose; if (st.st_size == 0) { @@ -150,95 +166,116 @@ _getutxent() (void)memset(&ut32, 0, sizeof(ut32)); ut32.ut_type = SIGNATURE; (void)memcpy(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers)); - if (fwrite(&ut32, sizeof(ut32), 1, fp) != 1) + if (fwrite(&ut32, sizeof(ut32), 1, U->fp) != 1) #else /* __LP64__ */ - (void)memset(&ut, 0, sizeof(ut)); - ut.ut_type = SIGNATURE; - (void)memcpy(ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)); - if (fwrite(&ut, sizeof(ut), 1, fp) != 1) + (void)memset(&U->ut, 0, sizeof(U->ut)); + U->ut.ut_type = SIGNATURE; + (void)memcpy(U->ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)); + if (fwrite(&U->ut, sizeof(U->ut), 1, U->fp) != 1) #endif /* __LP64__ */ goto failclose; } else { /* old file, read signature record */ #ifdef __LP64__ - if (fread(&ut32, sizeof(ut32), 1, fp) != 1) + if (fread(&ut32, sizeof(ut32), 1, U->fp) != 1) #else /* __LP64__ */ - if (fread(&ut, sizeof(ut), 1, fp) != 1) + if (fread(&U->ut, sizeof(U->ut), 1, U->fp) != 1) #endif /* __LP64__ */ goto failclose; #ifdef __LP64__ if (memcmp(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 || ut32.ut_type != SIGNATURE) #else /* __LP64__ */ - if (memcmp(ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 || - ut.ut_type != SIGNATURE) + if (memcmp(U->ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 || + U->ut.ut_type != SIGNATURE) #endif /* __LP64__ */ + { + errno = EINVAL; goto failclose; + } } } #ifdef __LP64__ - if (fread(&ut32, sizeof(ut32), 1, fp) != 1) + if (fread(&ut32, sizeof(ut32), 1, U->fp) != 1) #else /* __LP64__ */ - if (fread(&ut, sizeof(ut), 1, fp) != 1) + if (fread(&U->ut, sizeof(U->ut), 1, U->fp) != 1) #endif /* __LP64__ */ goto fail; #ifdef __LP64__ - _utmpx32_64(&ut32, &ut); + _utmpx32_64(&ut32, &U->ut); #endif /* __LP64__ */ - return &ut; + return &U->ut; failclose: - (void)fclose(fp); - fp = NULL; + saveerrno = errno; + (void)fclose(U->fp); + errno = saveerrno; + U->fp = NULL; fail: - (void)memset(&ut, 0, sizeof(ut)); + (void)memset(&U->ut, 0, sizeof(U->ut)); return NULL; } struct utmpx * -getutxent() +_getutxent(struct _utmpx *U) { struct utmpx *ret; - UTMPX_LOCK; - ret = _getutxent(); - UTMPX_UNLOCK; + + TEST_UTMPX_T("_getutxent", U); + UTMPX_LOCK(U); + ret = __getutxent(U); + UTMPX_UNLOCK(U); return ret; } + struct utmpx * -getutxid(const struct utmpx *utx) +getutxent() +{ + return _getutxent(&__utx__); +} + + +struct utmpx * +_getutxid(struct _utmpx *U, const struct utmpx *utx) { struct utmpx temp; const struct utmpx *ux; struct utmpx *ret; - _DIAGASSERT(utx != NULL); - if (utx->ut_type == EMPTY) return NULL; - UTMPX_LOCK; + TEST_UTMPX_T("_getutxid", U); + UTMPX_LOCK(U); /* make a copy as needed, and auto-fill if requested */ ux = _utmpx_working_copy(utx, &temp, 1); if (!ux) { - UTMPX_UNLOCK; + UTMPX_UNLOCK(U); return NULL; } - ret = _getutxid(ux); - UTMPX_UNLOCK; + ret = __getutxid(U, ux); + UTMPX_UNLOCK(U); return ret; } +struct utmpx * +getutxid(const struct utmpx *utx) +{ + return _getutxid(&__utx__, utx); +} + + static struct utmpx * -_getutxid(const struct utmpx *utx) +__getutxid(struct _utmpx *U, const struct utmpx *utx) { do { - if (ut.ut_type == EMPTY) + if (U->ut.ut_type == EMPTY) continue; switch (utx->ut_type) { case EMPTY: @@ -247,21 +284,21 @@ _getutxid(const struct utmpx *utx) case BOOT_TIME: case OLD_TIME: case NEW_TIME: - if (ut.ut_type == utx->ut_type) - return &ut; + if (U->ut.ut_type == utx->ut_type) + return &U->ut; break; case INIT_PROCESS: case LOGIN_PROCESS: case USER_PROCESS: case DEAD_PROCESS: - switch (ut.ut_type) { + switch (U->ut.ut_type) { case INIT_PROCESS: case LOGIN_PROCESS: case USER_PROCESS: case DEAD_PROCESS: - if (memcmp(ut.ut_id, utx->ut_id, - sizeof(ut.ut_id)) == 0) - return &ut; + if (memcmp(U->ut.ut_id, utx->ut_id, + sizeof(U->ut.ut_id)) == 0) + return &U->ut; break; default: break; @@ -270,64 +307,83 @@ _getutxid(const struct utmpx *utx) default: return NULL; } - } while (_getutxent() != NULL); + } while (__getutxent(U) != NULL); return NULL; } -struct utmpx * -getutxline(const struct utmpx *utx) +static struct utmpx * +__getutxline(struct _utmpx *U, const struct utmpx *utx) { - - _DIAGASSERT(utx != NULL); - - UTMPX_LOCK; do { - switch (ut.ut_type) { + switch (U->ut.ut_type) { case EMPTY: break; case LOGIN_PROCESS: case USER_PROCESS: - if (strncmp(ut.ut_line, utx->ut_line, - sizeof(ut.ut_line)) == 0) { - UTMPX_UNLOCK; - return &ut; - } + if (strncmp(U->ut.ut_line, utx->ut_line, + sizeof(U->ut.ut_line)) == 0) + return &U->ut; break; default: break; } - } while (_getutxent() != NULL); - UTMPX_UNLOCK; + } while (__getutxent(U) != NULL); return NULL; } struct utmpx * -pututxline(const struct utmpx *utx) +_getutxline(struct _utmpx *U, const struct utmpx *utx) { - struct utmpx *ux; + struct utmpx *ret; + + TEST_UTMPX_T("_getutxline", U); + UTMPX_LOCK(U); + ret = __getutxline(U, utx); + UTMPX_UNLOCK(U); + return ret; +} - _DIAGASSERT(utx != NULL); + +struct utmpx * +getutxline(const struct utmpx *utx) +{ + return _getutxline(&__utx__, utx); +} + + +struct utmpx * +_pututxline(struct _utmpx *U, const struct utmpx *utx) +{ + struct utmpx *ux; if (utx == NULL) { errno = EINVAL; return NULL; } - UTMPX_LOCK; - if ((ux = _pututxline(utx)) != NULL && utfile_system) { + TEST_UTMPX_T("_pututxline", U); + UTMPX_LOCK(U); + if ((ux = __pututxline(&__utx__, utx)) != NULL && __utx__.utfile_system) { _utmpx_asl(ux); /* the equivalent of wtmpx and lastlogx */ #ifdef UTMP_COMPAT _write_utmp_compat(ux); #endif /* UTMP_COMPAT */ } - UTMPX_UNLOCK; + UTMPX_UNLOCK(U); return ux; } + +struct utmpx * +pututxline(const struct utmpx *utx) +{ + return _pututxline(&__utx__, utx); +} + __private_extern__ struct utmpx * -_pututxline(const struct utmpx *utx) +__pututxline(struct _utmpx *U, const struct utmpx *utx) { struct utmpx temp, *u = NULL, *x; const struct utmpx *ux; @@ -338,15 +394,15 @@ _pututxline(const struct utmpx *utx) #define gotlock (fl.l_start >= 0) fl.l_start = -1; /* also means we haven't locked */ - if (utfile_system) - if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) { + if (U->utfile_system) + if ((U->fp != NULL && U->readonly) || (U->fp == NULL && geteuid() != 0)) { errno = EPERM; return NULL; } - if (fp == NULL) { - (void)_getutxent(); - if (fp == NULL || readonly) { + if (U->fp == NULL) { + (void)__getutxent(U); + if (U->fp == NULL || U->readonly) { errno = EPERM; return NULL; } @@ -357,9 +413,9 @@ _pututxline(const struct utmpx *utx) if (!ux) return NULL; - if ((x = _getutxid(ux)) == NULL) { - _setutxent(); - if ((x = _getutxid(ux)) == NULL) { + if ((x = __getutxid(U, ux)) == NULL) { + __setutxent(U); + if ((x = __getutxid(U, ux)) == NULL) { /* * utx->ut_type has any original mask bits, while * ux->ut_type has those mask bits removed. If we @@ -376,14 +432,14 @@ _pututxline(const struct utmpx *utx) * Replace lockf() with fcntl() and a fixed start * value. We should already be at EOF. */ - if ((fl.l_start = lseek(fileno(fp), 0, SEEK_CUR)) < 0) + if ((fl.l_start = lseek(fileno(U->fp), 0, SEEK_CUR)) < 0) return NULL; fl.l_len = 0; fl.l_whence = SEEK_SET; fl.l_type = F_WRLCK; - if (fcntl(fileno(fp), F_SETLKW, &fl) == -1) + if (fcntl(fileno(U->fp), F_SETLKW, &fl) == -1) return NULL; - if (fseeko(fp, (off_t)0, SEEK_END) == -1) + if (fseeko(U->fp, (off_t)0, SEEK_END) == -1) goto fail; } } @@ -404,31 +460,31 @@ _pututxline(const struct utmpx *utx) } /* we are not appending */ #ifdef __LP64__ - if (fseeko(fp, -(off_t)sizeof(ut32), SEEK_CUR) == -1) + if (fseeko(U->fp, -(off_t)sizeof(ut32), SEEK_CUR) == -1) #else /* __LP64__ */ - if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1) + if (fseeko(U->fp, -(off_t)sizeof(U->ut), SEEK_CUR) == -1) #endif /* __LP64__ */ return NULL; } #ifdef __LP64__ _utmpx64_32(ux, &ut32); - if (fwrite(&ut32, sizeof (ut32), 1, fp) != 1) + if (fwrite(&ut32, sizeof (ut32), 1, U->fp) != 1) #else /* __LP64__ */ - if (fwrite(ux, sizeof (*ux), 1, fp) != 1) + if (fwrite(ux, sizeof (*ux), 1, U->fp) != 1) #endif /* __LP64__ */ goto fail; - if (fflush(fp) == -1) + if (fflush(U->fp) == -1) goto fail; - u = memcpy(&ut, ux, sizeof(ut)); + u = memcpy(&U->ut, ux, sizeof(U->ut)); notify_post(UTMPX_CHANGE_NOTIFICATION); fail: if (gotlock) { int save = errno; fl.l_type = F_UNLCK; - if (fcntl(fileno(fp), F_SETLK, &fl) == -1) + if (fcntl(fileno(U->fp), F_SETLK, &fl) == -1) return NULL; errno = save; } @@ -439,41 +495,59 @@ fail: /* * The following are extensions and not part of the X/Open spec. */ -int -utmpxname(const char *fname) +__private_extern__ int +__utmpxname(struct _utmpx *U, const char *fname) { size_t len; - UTMPX_LOCK; if (fname == NULL) { - strcpy(utfile, _PATH_UTMPX); - utfile_system = 1; - _endutxent(); - UTMPX_UNLOCK; + if(!U->utfile_system) + free(U->utfile); + U->utfile = _PATH_UTMPX; + U->utfile_system = 1; + __endutxent(U); return 1; } len = strlen(fname); - if (len >= sizeof(utfile)) { - UTMPX_UNLOCK; + if (len >= MAXPATHLEN) return 0; - } /* must end in x! */ - if (fname[len - 1] != 'x') { - UTMPX_UNLOCK; + if (fname[len - 1] != 'x') + return 0; + + if (U->utfile_system) + U->utfile = NULL; + U->utfile_system = 0; + if ((U->utfile = reallocf(U->utfile, len + 1)) == NULL) return 0; - } - (void)strlcpy(utfile, fname, sizeof(utfile)); - _endutxent(); - utfile_system = 0; - UTMPX_UNLOCK; + (void)strcpy(U->utfile, fname); + __endutxent(U); return 1; } -#ifdef LEGACY_UTMP_APIS +int +_utmpxname(struct _utmpx *U, const char *fname) +{ + int ret; + + TEST_UTMPX_T("_utmpxname", U); + UTMPX_LOCK(U); + ret = __utmpxname(U, fname); + UTMPX_UNLOCK(U); + return ret; +} + +int +utmpxname(const char *fname) +{ + return _utmpxname(&__utx__, fname); +} + +#ifdef UNIFDEF_LEGACY_UTMP_APIS void getutmp(const struct utmpx *ux, struct utmp *u) { @@ -501,4 +575,4 @@ getutmpx(const struct utmp *u, struct utmpx *ux) ux->ut_pid = getpid(); ux->ut_type = USER_PROCESS; } -#endif /* LEGACY_UTMP_APIS */ +#endif /* UNIFDEF_LEGACY_UTMP_APIS */ diff --git a/gen/utmpx.5 b/gen/utmpx.5 index 5e7d31a..6068b09 100644 --- a/gen/utmpx.5 +++ b/gen/utmpx.5 @@ -1,4 +1,4 @@ -.\" $NetBSD: utmpx.5,v 1.2 2003/04/16 13:35:24 wiz Exp $ +.\" $NetBSD: utmpx.5,v 1.7 2008/04/30 13:10:57 martin Exp $ .\" .\" Copyright (c) 2002 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -14,13 +14,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -34,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd Dec 26, 2005 +.Dd January 31, 2007 .Dt UTMPX 5 .Os .Sh NAME @@ -43,6 +36,17 @@ .Sh SYNOPSIS .In utmpx.h .Sh DESCRIPTION +In contrast to +.Pa utmp +and +.Pa wtmp , +the extended databases in +.Pa utmpx +and +.Pa wtmpx +reserve more space for logging hostnames, and also +information on a process' ID, termination signal and exit status. +.Pp The .Aq Pa utmpx.h header defines the structures and functions for logging user. diff --git a/gen/utmpx_thread.h b/gen/utmpx_thread.h new file mode 100644 index 0000000..3534c0f --- /dev/null +++ b/gen/utmpx_thread.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * "Portions Copyright (c) 2004 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 1.0 (the 'License'). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Thread-aware utmpx SPI + */ +#ifndef _UTMPX_THREAD_H_ +#define _UTMPX_THREAD_H_ + +#include + +struct _utmpx; /* forward reference */ +typedef struct _utmpx *utmpx_t; + +__BEGIN_DECLS +int _closeutx(utmpx_t); +void _endutxent(utmpx_t); +struct utmpx *_getutxent(utmpx_t); +struct utmpx *_getutxid(utmpx_t, const struct utmpx *); +struct utmpx *_getutxline(utmpx_t, const struct utmpx *); +utmpx_t _openutx(const char *); +struct utmpx *_pututxline(utmpx_t, const struct utmpx *); +void _setutxent(utmpx_t); +int _utmpxname(utmpx_t, const char *); +__END_DECLS + +#endif /* !_UTMPX_THREAD_H_ */ diff --git a/gen/vis-fbsd.c b/gen/vis-fbsd.c index 7eb50b7..3a4b67c 100644 --- a/gen/vis-fbsd.c +++ b/gen/vis-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)vis.c 8.1 (Berkeley) 7/19/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/vis.c,v 1.13 2003/10/30 12:41:50 phk Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/vis.c,v 1.14 2007/01/09 00:27:56 imp Exp $"); #include "xlocale_private.h" diff --git a/gen/wait-fbsd.c b/gen/wait-fbsd.c index d1c0f4d..8bf2b1e 100644 --- a/gen/wait-fbsd.c +++ b/gen/wait-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)wait.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/wait.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/wait.c,v 1.7 2007/01/09 00:27:56 imp Exp $"); #include "namespace.h" #include diff --git a/gen/waitpid-fbsd.c b/gen/waitpid-fbsd.c index 3679eb8..d81530f 100644 --- a/gen/waitpid-fbsd.c +++ b/gen/waitpid-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)waitpid.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/waitpid.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/waitpid.c,v 1.7 2007/01/09 00:27:56 imp Exp $"); #include "namespace.h" #include diff --git a/gen/wordexp.c b/gen/wordexp.c index 4c4baa7..467603d 100644 --- a/gen/wordexp.c +++ b/gen/wordexp.c @@ -45,7 +45,7 @@ static regex_t re_cmd, re_goodchars, re_subcmd_syntax_err_kludge, re_quoted_stri /* Similar to popen, but captures stderr for you. Doesn't interoperate with pclose. Call wait4 on your own */ -pid_t popen_oe(char *cmd, FILE **out, FILE **err) { +static pid_t popen_oe(char *cmd, FILE **out, FILE **err) { int out_pipe[2], err_pipe[2]; char *argv[4]; pid_t pid; @@ -105,7 +105,7 @@ pid_t popen_oe(char *cmd, FILE **out, FILE **err) { return pid; } -void re_init(void) { +static void re_init(void) { int rc = regcomp(&re_cmd, "(^|[^\\])(`|\\$\\([^(])", REG_EXTENDED|REG_NOSUB); /* XXX I'm not sure the { } stuff is correct, it may be overly restrictave */ diff --git a/gmon/gmon.c b/gmon/gmon.c index bd5d9f4..20ce855 100644 --- a/gmon/gmon.c +++ b/gmon/gmon.c @@ -376,7 +376,7 @@ char *highpc) if(!init) add_profil(m->sbuf + sizeof(gmonhdr_t), m->ssiz - sizeof(gmonhdr_t), - (long)m->lowpc, m->scale); + (uintptr_t)m->lowpc, m->scale); } } @@ -424,7 +424,7 @@ const char *filename) mon_t *m; uint32_t image_count; intptr_t image_header; - char *image_name; + const char *image_name; moncontrol(0); m = mon; @@ -673,7 +673,7 @@ char *selfpc) ((uintptr_t)frompcindex - (uintptr_t)m->lowpc); } frompcindex = - &m->froms[((long)frompcindex) / (HASHFRACTION * sizeof(*m->froms))]; + &m->froms[((uintptr_t)frompcindex) / (HASHFRACTION * sizeof(*m->froms))]; toindex = *frompcindex; if(toindex == 0){ /* diff --git a/i386/gen/Makefile.inc b/i386/gen/Makefile.inc index e9bbd61..f759c80 100644 --- a/i386/gen/Makefile.inc +++ b/i386/gen/Makefile.inc @@ -1,4 +1,5 @@ .PATH: ${.CURDIR}/i386/gen + MDSRCS+= _ctx_start.S \ _setcontext.S \ getcontext.S \ @@ -8,10 +9,16 @@ MDSRCS+= _ctx_start.S \ mcount.s \ setcontext.c \ setjmperr.c \ - swapcontext.c + swapcontext.c \ + cpu_number.s .for _src in makecontext.c setcontext.c swapcontext.c CFLAGS-${_src} += -fomit-frame-pointer # -pg and -fomit-frame-pointer don't work together, so just use -g ${_src:R}.po: ${_src} _STANDARD_DEBUG .endfor + +CFLAGS += -I${.CURDIR}/i386/gen + +DYLDSRCS += icacheinval.s \ + cpu_number.s diff --git a/i386/gen/cpu_number.s b/i386/gen/cpu_number.s new file mode 100644 index 0000000..d9381c9 --- /dev/null +++ b/i386/gen/cpu_number.s @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include +#include + +/* + * These platfunc routines provide fast access to the logical cpu number + * of the calling processor assuming no pre-emption occurs. This number + * is encoded in the bottom 12-bits of the limit field of the IDTR (the + * Interrupt Descriptor Table Register). The SIDT instruction is used in + * userspace to read this register and thus to gain access to the cpu number. + * The IDTR is loaded by the kernel for each processor at startup - see + * osfmk/i386/mp_desc.c. + */ + +/* return logical cpu number in %eax */ + + .align 4 + .private_extern _cpu_number +_cpu_number: + push %ebp + mov %esp,%ebp + sub $8, %esp // space to read IDTR + + sidt (%esp) // store limit:base on stack + movw (%esp), %ax // get limit + and $0xfff, %eax // mask off lower 12 bits to return + + mov %ebp,%esp + pop %ebp + ret diff --git a/i386/gen/getmcontext.c b/i386/gen/getmcontext.c index 7ce8a54..a64da4c 100644 --- a/i386/gen/getmcontext.c +++ b/i386/gen/getmcontext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * diff --git a/i386/gen/icacheinval.s b/i386/gen/icacheinval.s index dbbb42d..ca4b958 100644 --- a/i386/gen/icacheinval.s +++ b/i386/gen/icacheinval.s @@ -31,15 +31,28 @@ /* void sys_icache_invalidate(addr_t start, int length) */ -.globl _sys_icache_invalidate + .globl _sys_icache_invalidate _sys_icache_invalidate: - movl $(_COMM_PAGE_FLUSH_ICACHE), %eax - jmpl *%eax + // This is a NOP on intel processors, since the intent of the API + // is to make data executable, and Intel L1Is are coherent with L1D. + ret /* void sys_dcache_flush(addr_t start, int length) */ -.globl _sys_dcache_flush + .globl _sys_dcache_flush _sys_dcache_flush: - movl $(_COMM_PAGE_FLUSH_DCACHE), %eax - jmpl *%eax + movl 8(%esp),%ecx // get length + movl 4(%esp),%edx // get ptr + testl %ecx,%ecx // length 0? + jz 2f // yes + mfence // ensure previous stores make it to memory + clflush -1(%edx,%ecx) // make sure last line is flushed +1: + clflush (%edx) // flush a line + addl $64,%edx + subl $64,%ecx + ja 1b + mfence // make sure memory is updated before we return +2: + ret diff --git a/i386/pthreads/Makefile.inc b/i386/pthreads/Makefile.inc index 81bf856..7fd652c 100644 --- a/i386/pthreads/Makefile.inc +++ b/i386/pthreads/Makefile.inc @@ -2,9 +2,16 @@ MDSRCS += \ init_cpu_capabilities.c \ get_cpu_capabilities.s \ + preempt.s \ pthread_mutex_lock.s \ pthread_set_self.s \ pthread_self.s \ pthread_getspecific.s \ start_wqthread.s \ thread_start.s + +DYLDSRCS += \ + preempt.s \ + pthread_set_self.s \ + pthread_self.s \ + pthread_getspecific.s diff --git a/i386/pthreads/preempt.s b/i386/pthreads/preempt.s new file mode 100644 index 0000000..e0bd2e1 --- /dev/null +++ b/i386/pthreads/preempt.s @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* Subroutine to make a preempt syscall. Called when we notice %ebx is + * nonzero after returning from a PFZ subroutine. + * When we enter kernel: + * %edx = return address + * %ecx = stack ptr + * Destroys %eax, %ecx, and %edx. + */ + .align 4 + .private_extern _preempt +_preempt: + popl %edx // get return address + movl %esp,%ecx // save stack ptr here + movl $(-58),%eax /* 58 = pfz_exit */ + xorl %ebx,%ebx // clear "preemption pending" flag + sysenter + + +/* Subroutine to back off if we cannot get the spinlock. Called + * after a few attempts inline in the PFZ subroutines. This code is + * not in the PFZ. + * %edi = ptr to queue head structure + * %ebx = preemption flag (nonzero if preemption pending) + * Destroys %eax. + */ + + .align 4 + .private_extern _backoff +_backoff: + testl %ebx,%ebx // does kernel want to preempt us? + jz 1f // no + xorl %ebx,%ebx // yes, clear flag + pushl %edx // preserve regs used by preempt syscall + pushl %ecx + call _preempt + popl %ecx + popl %edx +1: + pause // SMT-friendly backoff + cmpl $0,8(%edi) // sniff the lockword + jnz 1b // loop if still taken + ret // lockword is free, so reenter PFZ diff --git a/i386/pthreads/pthread_getspecific.s b/i386/pthreads/pthread_getspecific.s index 52c40bf..187aae7 100644 --- a/i386/pthreads/pthread_getspecific.s +++ b/i386/pthreads/pthread_getspecific.s @@ -28,5 +28,5 @@ .globl _pthread_getspecific _pthread_getspecific: movl 4(%esp),%eax - movl %gs:_PTHREAD_TSD_OFFSET(,%eax,4),%eax + movl %gs:(,%eax,4),%eax ret diff --git a/i386/pthreads/pthread_mutex_lock.s b/i386/pthreads/pthread_mutex_lock.s index 287be1d..d9684aa 100644 --- a/i386/pthreads/pthread_mutex_lock.s +++ b/i386/pthreads/pthread_mutex_lock.s @@ -28,5 +28,33 @@ .align 2 .globl __commpage_pthread_mutex_lock __commpage_pthread_mutex_lock: - movl $(_COMM_PAGE_MUTEX_LOCK), %eax - jmpl *%eax + pushl %ebp // set up frame for backtrace + movl %esp,%ebp + pushl %esi + pushl %edi + pushl %ebx + xorl %ebx,%ebx // clear "preemption pending" flag + movl 20(%esp),%edi // %edi == ptr to LVAL/UVAL structure + lea 20(%esp),%esi // %esi == ptr to argument list + movl _COMM_PAGE_SPIN_COUNT, %edx + movl 16(%esi),%ecx // get mask (ie, PTHRW_EBIT etc) +1: + testl 0(%edi),%ecx // is mutex available? + jz 2f // yes, it is available + pause + decl %edx // decrement max spin count + jnz 1b // keep spinning +2: + movl $(_COMM_PAGE_PFZ_MUTEX_LOCK), %ecx + call *%ecx + testl %ebx,%ebx // pending preemption? + jz 3f + pushl %eax // save return value across sysenter + call _preempt + popl %eax +3: + popl %ebx + popl %edi + popl %esi + popl %ebp + ret diff --git a/i386/pthreads/pthread_self.s b/i386/pthreads/pthread_self.s index 5f9083c..929231c 100644 --- a/i386/pthreads/pthread_self.s +++ b/i386/pthreads/pthread_self.s @@ -27,5 +27,5 @@ .align 2, 0x90 .globl _pthread_self _pthread_self: - movl %gs:_PTHREAD_TSD_OFFSET,%eax + movl %gs:0,%eax ret diff --git a/i386/string/Makefile.inc b/i386/string/Makefile.inc index 54d64df..36d022d 100644 --- a/i386/string/Makefile.inc +++ b/i386/string/Makefile.inc @@ -5,11 +5,22 @@ # # .PATH: ${.CURDIR}/i386/string -MDSRCS += bcopy.s \ - bzero.s \ +MDSRCS += \ + bcopy.c \ + bcopy_scalar.s \ + bcopy_sse2.s \ + bcopy_sse3x.s \ + bcopy_sse42.s \ + bzero.c \ + bzero_scalar.s \ + bzero_sse2.s \ + bzero_sse42.s \ + __bzero.s \ + longcopy_sse3x.s \ + memset_pattern_sse2.s \ ffs.s \ - memcpy.s \ - memmove.s \ + memcpy.c \ + memmove.c \ strlcat.s \ strlcpy.s \ strlen.s \ @@ -21,3 +32,13 @@ MDSRCS += bcopy.s \ memset.s SUPPRESSSRCS += bcmp.c + +DYLDSRCS += \ + __bzero.s \ + bcopy_scalar.s \ + bzero_scalar.s \ + ffs.s \ + memcmp.s \ + memset_pattern_sse2.s \ + strcmp.s \ + strlen.s diff --git a/i386/string/__bzero.s b/i386/string/__bzero.s new file mode 100644 index 0000000..c16f31a --- /dev/null +++ b/i386/string/__bzero.s @@ -0,0 +1,3 @@ + .globl ___bzero +___bzero: + jmp _bzero diff --git a/i386/string/bcopy.c b/i386/string/bcopy.c new file mode 100644 index 0000000..61c33bf --- /dev/null +++ b/i386/string/bcopy.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse42); +PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse3x); +PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse2); +PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, scalar); + +static const platfunc_descriptor *bcopy_platfunc_descriptors[] = { + PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse42), + PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse3x), + PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse2), + PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, scalar), + 0 +}; + +void *bcopy_chooser() __asm__("_bcopy"); +void *bcopy_chooser() { + __asm__(".desc _bcopy, 0x100"); + return find_platform_function((const platfunc_descriptor **) bcopy_platfunc_descriptors); +} diff --git a/i386/string/bcopy_scalar.s b/i386/string/bcopy_scalar.s new file mode 100644 index 0000000..d6708d7 --- /dev/null +++ b/i386/string/bcopy_scalar.s @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from locore.s. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 +#include +#include +#include + + /* + * (ov)bcopy (src,dst,cnt) + * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800 + */ + +PLATFUNC_FUNCTION_START_GENERIC(bcopy, scalar, 32, 5) + pushl %ebp /* set up a frame for backtraces */ + movl %esp,%ebp + pushl %esi + pushl %edi + movl 8(%ebp),%esi + movl 12(%ebp),%edi + jmp 1f + +PLATFUNC_FUNCTION_START_GENERIC(memcpy, scalar, 32, 0) +PLATFUNC_FUNCTION_START_GENERIC(memmove, scalar, 32, 0) + pushl %ebp /* set up a frame for backtraces */ + movl %esp,%ebp + pushl %esi + pushl %edi + movl 8(%ebp),%edi + movl 12(%ebp),%esi + movl %edi,%eax +1: + movl 16(%ebp),%ecx + movl %edi,%edx + subl %esi,%edx + cmpl %ecx,%edx /* overlapping? */ + jb 2f + cld /* nope, copy forwards. */ + movl %ecx,%edx + shrl $2,%ecx /* copy by words */ + rep + movsl + movl %edx,%ecx + andl $3,%ecx /* any bytes left? */ + rep + movsb + popl %edi + popl %esi + popl %ebp + ret +2: + addl %ecx,%edi /* copy backwards. */ + addl %ecx,%esi + std + movl %ecx,%edx + andl $3,%ecx /* any fractional bytes? */ + decl %edi + decl %esi + rep + movsb + movl %edx,%ecx /* copy remainder by words */ + shrl $2,%ecx + subl $3,%esi + subl $3,%edi + rep + movsl + popl %edi + popl %esi + popl %ebp + cld + ret + +PLATFUNC_DESCRIPTOR(bcopy,scalar,0,0) +PLATFUNC_DESCRIPTOR(memcpy,scalar,0,0) +PLATFUNC_DESCRIPTOR(memmove,scalar,0,0) diff --git a/i386/string/bcopy_sse2.s b/i386/string/bcopy_sse2.s new file mode 100644 index 0000000..4987c5e --- /dev/null +++ b/i386/string/bcopy_sse2.s @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* + * The bcopy/memcpy loops, tuned for Pentium-M class processors with SSE2 + * and 64-byte cache lines, such as Core and Core 2. + * + * The following #defines are tightly coupled to the u-architecture: + */ + +#define kShort 80 // too short to bother with SSE (must be >=80) +#define kVeryLong (500*1024) // large enough for non-temporal stores (must be >= 8192) +#define kBigChunk (256*1024) // outer loop chunk size for kVeryLong sized operands +#define kFastUCode (16*1024) // cutoff for microcode fastpath for "rep/movsl" + + +// void bcopy(const void *src, void *dst, size_t len); + +PLATFUNC_FUNCTION_START(bcopy, sse2, 32, 5) + pushl %ebp // set up a frame for backtraces + movl %esp,%ebp + pushl %esi + pushl %edi + movl 8(%ebp),%esi // get source ptr + movl 12(%ebp),%edi // get dest ptr + jmp Ljoin + +// +// void *memcpy(void *dst, const void *src, size_t len); +// void *memmove(void *dst, const void *src, size_t len); +// + +PLATFUNC_FUNCTION_START(memcpy, sse2, 32, 0) // void *memcpy(void *dst, const void *src, size_t len) +PLATFUNC_FUNCTION_START(memmove, sse2, 32, 0) // void *memmove(void *dst, const void *src, size_t len) +Lmemcpy_sse2: + pushl %ebp // set up a frame for backtraces + movl %esp,%ebp + pushl %esi + pushl %edi + movl 8(%ebp),%edi // get dest ptr + movl 12(%ebp),%esi // get source ptr + +Ljoin: // here from bcopy() with esi and edi loaded + movl 16(%ebp),%ecx // get length + movl %edi,%edx + subl %esi,%edx // (dest - source) + cmpl %ecx,%edx // must move in reverse if (dest - source) < length + jb LReverseIsland +Lrejoin: // here from very-long-operand copies + cmpl $(kShort),%ecx // long enough to bother with SSE? + ja LNotShort // yes + +// Handle short forward copies. As the most common case, this is the fall-through path. +// ecx = length (<= kShort) +// esi = source ptr +// edi = dest ptr + +Lshort: + movl %ecx,%edx // copy length + shrl $2,%ecx // get #doublewords + jz LLeftovers +2: // loop copying doublewords + movl (%esi),%eax + addl $4,%esi + movl %eax,(%edi) + addl $4,%edi + dec %ecx + jnz 2b +LLeftovers: // handle leftover bytes (0..3) in last word + andl $3,%edx // any leftover bytes? + jz 5f +4: // loop copying bytes + movb (%esi),%al + inc %esi +movb %al,(%edi) + inc %edi + dec %edx + jnz 4b +5: + movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove + popl %edi + popl %esi + popl %ebp + ret + + +LReverseIsland: // keep the "jb" above a short branch... + jmp LReverse // ...because reverse moves are uncommon + + +// Handle forward moves that are long enough to justify use of SSE3. +// First, 16-byte align the destination. +// ecx = length (> kShort) +// esi = source ptr +// edi = dest ptr + +LNotShort: + cmpl $(kVeryLong),%ecx // long enough to justify heavyweight loops? + movl %edi,%edx // copy destination + jae LVeryLong // use very-long-operand path + negl %edx + andl $15,%edx // get #bytes to align destination + jz LDestAligned // already aligned + subl %edx,%ecx // decrement length +1: // loop copying 1..15 bytes + movb (%esi),%al + inc %esi + movb %al,(%edi) + inc %edi + dec %edx + jnz 1b + +// Destination is now aligned. Prepare for forward loops over 64-byte chunks. +// Since kShort>=80 and we've moved at most 15 bytes already, there is at least one chunk. + +LDestAligned: + movl %ecx,%edx // copy length + movl %ecx,%eax // twice + andl $63,%ecx // get remaining bytes for Lshort + andl $-64,%edx // get number of bytes we will copy in inner loop + addl %edx,%esi // point to 1st byte not copied + addl %edx,%edi + negl %edx // now generate offset to 1st byte to be copied + testl $15,%esi // is source aligned too? + jnz LUnalignedLoop // no + + cmpl $(kFastUCode),%eax // long enough for the fastpath in microcode? + jb LAlignedLoop // no, use SSE + cld // we'll move forward + movl %eax,%ecx // copy length again + shrl $2,%ecx // compute #words to move + addl %edx,%esi // restore ptrs to 1st byte of source and dest + addl %edx,%edi + rep // the u-code will optimize this + movsl + movl %eax,%edx // original length + jmp LLeftovers // handle 0..3 leftover bytes + + +// Forward aligned loop for medium length operands (kShort < n < kVeryLong). + + .align 4,0x90 // 16-byte align inner loops +LAlignedLoop: // loop over 64-byte chunks + movdqa (%esi,%edx),%xmm0 + movdqa 16(%esi,%edx),%xmm1 + movdqa 32(%esi,%edx),%xmm2 + movdqa 48(%esi,%edx),%xmm3 + + movdqa %xmm0,(%edi,%edx) + movdqa %xmm1,16(%edi,%edx) + movdqa %xmm2,32(%edi,%edx) + movdqa %xmm3,48(%edi,%edx) + + addl $64,%edx + jnz LAlignedLoop + + jmp Lshort // copy remaining 0..15 bytes and done + + +// Forward unaligned loop for medium length operands (kShort < n < kVeryLong). +// Note that LDDQU==MOVDQU on these machines, ie we don't care when we cross +// source cache lines. + + .align 4,0x90 // 16-byte align inner loops +LUnalignedLoop: // loop over 64-byte chunks + movdqu (%esi,%edx),%xmm0 // the loads are unaligned + movdqu 16(%esi,%edx),%xmm1 + movdqu 32(%esi,%edx),%xmm2 + movdqu 48(%esi,%edx),%xmm3 + + movdqa %xmm0,(%edi,%edx) // we can use aligned stores + movdqa %xmm1,16(%edi,%edx) + movdqa %xmm2,32(%edi,%edx) + movdqa %xmm3,48(%edi,%edx) + + addl $64,%edx + jnz LUnalignedLoop + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Very long forward moves. These are at least several pages, so we loop over big +// chunks of memory (kBigChunk in size.) We first prefetch the chunk, and then copy +// it using non-temporal stores. Hopefully all the reads occur in the prefetch loop, +// so the copy loop reads from L2 and writes directly to memory (with write combining.) +// This minimizes bus turnaround and maintains good DRAM page locality. +// Note that for this scheme to work, kVeryLong must be a large fraction of L2 cache +// size. Otherwise, it is counter-productive to bypass L2 on the stores. +// ecx = length (>= kVeryLong bytes) +// edi = dest (aligned) +// esi = source + +LVeryLong: + pushl %ebx // we'll need to use this + movl %edi,%ebx // copy dest ptr + negl %ebx + andl $63,%ebx // get #bytes to cache line align destination + jz LBigChunkLoop // already aligned + +// Cache line align destination, so temporal stores in copy loops work right. + + pushl %ecx // save total length remaining + pushl %ebx // arg3 - #bytes to align destination (1..63) + pushl %esi // arg2 - source + pushl %edi // arg1 - dest + call Lmemcpy_sse2 // align the destination + movl 12(%esp),%ecx // recover total length + addl $16,%esp + addl %ebx,%esi // adjust ptrs and lengths past copy + addl %ebx,%edi + subl %ebx,%ecx + +// Loop over big chunks. +// ecx = length remaining (>= 4096) +// edi = dest (64-byte aligned) +// esi = source (may be unaligned) + +LBigChunkLoop: + movl $(kBigChunk),%edx // assume we can do a full chunk + cmpl %edx,%ecx // do we have a full chunk left to do? + cmovbl %ecx,%edx // if not, only move what we have left + andl $-4096,%edx // we work in page multiples + xor %eax,%eax // initialize chunk offset + jmp LTouchLoop + +// Because the source may be unaligned, we use byte loads to touch. +// ecx = length remaining (including this chunk) +// edi = ptr to start of dest chunk +// esi = ptr to start of source chunk +// edx = chunk length (multiples of pages) +// ebx = scratch reg used to read a byte of each cache line +// eax = chunk offset + + .align 4,0x90 // 16-byte align inner loops +LTouchLoop: + movzb (%esi,%eax),%ebx // touch line 0, 2, 4, or 6 of page + movzb 1*64(%esi,%eax),%ebx // touch line 1, 3, 5, or 7 + movzb 8*64(%esi,%eax),%ebx // touch line 8, 10, 12, or 14 + movzb 9*64(%esi,%eax),%ebx // etc + + movzb 16*64(%esi,%eax),%ebx + movzb 17*64(%esi,%eax),%ebx + movzb 24*64(%esi,%eax),%ebx + movzb 25*64(%esi,%eax),%ebx + + movzb 32*64(%esi,%eax),%ebx + movzb 33*64(%esi,%eax),%ebx + movzb 40*64(%esi,%eax),%ebx + movzb 41*64(%esi,%eax),%ebx + + movzb 48*64(%esi,%eax),%ebx + movzb 49*64(%esi,%eax),%ebx + movzb 56*64(%esi,%eax),%ebx + movzb 57*64(%esi,%eax),%ebx + + subl $-128,%eax // next slice of page (adding 128 w 8-bit immediate) + testl $512,%eax // done with this page? + jz LTouchLoop // no, next of four slices + addl $(4096-512),%eax // move on to next page + cmpl %eax,%edx // done with this chunk? + jnz LTouchLoop // no, do next page + +// The chunk has been pre-fetched, now copy it using non-temporal stores. +// There are two copy loops, depending on whether the source is 16-byte aligned +// or not. + + addl %edx,%esi // increment ptrs by chunk length + addl %edx,%edi + subl %edx,%ecx // adjust remaining length + negl %edx // prepare loop index (counts up to 0) + testl $15,%esi // is source 16-byte aligned? + jnz LVeryLongUnaligned // source is not aligned + jmp LVeryLongAligned + + .align 4,0x90 // 16-byte align inner loops +LVeryLongAligned: // aligned loop over 128-bytes + movdqa (%esi,%edx),%xmm0 + movdqa 16(%esi,%edx),%xmm1 + movdqa 32(%esi,%edx),%xmm2 + movdqa 48(%esi,%edx),%xmm3 + movdqa 64(%esi,%edx),%xmm4 + movdqa 80(%esi,%edx),%xmm5 + movdqa 96(%esi,%edx),%xmm6 + movdqa 112(%esi,%edx),%xmm7 + + movntdq %xmm0,(%edi,%edx) + movntdq %xmm1,16(%edi,%edx) + movntdq %xmm2,32(%edi,%edx) + movntdq %xmm3,48(%edi,%edx) + movntdq %xmm4,64(%edi,%edx) + movntdq %xmm5,80(%edi,%edx) + movntdq %xmm6,96(%edi,%edx) + movntdq %xmm7,112(%edi,%edx) + + subl $-128,%edx // add 128 with an 8-bit immediate + jnz LVeryLongAligned + jmp LVeryLongChunkEnd + + .align 4,0x90 // 16-byte align inner loops +LVeryLongUnaligned: // unaligned loop over 128-bytes + movdqu (%esi,%edx),%xmm0 + movdqu 16(%esi,%edx),%xmm1 + movdqu 32(%esi,%edx),%xmm2 + movdqu 48(%esi,%edx),%xmm3 + movdqu 64(%esi,%edx),%xmm4 + movdqu 80(%esi,%edx),%xmm5 + movdqu 96(%esi,%edx),%xmm6 + movdqu 112(%esi,%edx),%xmm7 + + movntdq %xmm0,(%edi,%edx) + movntdq %xmm1,16(%edi,%edx) + movntdq %xmm2,32(%edi,%edx) + movntdq %xmm3,48(%edi,%edx) + movntdq %xmm4,64(%edi,%edx) + movntdq %xmm5,80(%edi,%edx) + movntdq %xmm6,96(%edi,%edx) + movntdq %xmm7,112(%edi,%edx) + + subl $-128,%edx // add 128 with an 8-bit immediate + jnz LVeryLongUnaligned + +LVeryLongChunkEnd: + cmpl $4096,%ecx // at least another page to go? + jae LBigChunkLoop // yes + + sfence // required by non-temporal stores + popl %ebx + jmp Lrejoin // handle remaining (0..4095) bytes + + +// Reverse moves. +// ecx = length +// esi = source ptr +// edi = dest ptr + +LReverse: + addl %ecx,%esi // point to end of strings + addl %ecx,%edi + cmpl $(kShort),%ecx // long enough to bother with SSE? + ja LReverseNotShort // yes + +// Handle reverse short copies. +// ecx = length +// esi = one byte past end of source +// edi = one byte past end of dest + +LReverseShort: + movl %ecx,%edx // copy length + shrl $2,%ecx // #words + jz 3f +1: + subl $4,%esi + movl (%esi),%eax + subl $4,%edi + movl %eax,(%edi) + dec %ecx + jnz 1b +3: + andl $3,%edx // bytes? + jz 5f +4: + dec %esi + movb (%esi),%al + dec %edi + movb %al,(%edi) + dec %edx + jnz 4b +5: + movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove + popl %edi + popl %esi + popl %ebp + ret + +// Handle a reverse move long enough to justify using SSE. +// ecx = length +// esi = one byte past end of source +// edi = one byte past end of dest + +LReverseNotShort: + movl %edi,%edx // copy destination + andl $15,%edx // get #bytes to align destination + je LReverseDestAligned // already aligned + subl %edx,%ecx // adjust length +1: // loop copying 1..15 bytes + dec %esi + movb (%esi),%al + dec %edi + movb %al,(%edi) + dec %edx + jnz 1b + +// Destination is now aligned. Prepare for reverse loops. + +LReverseDestAligned: + movl %ecx,%edx // copy length + andl $63,%ecx // get remaining bytes for Lshort + andl $-64,%edx // get number of bytes we will copy in inner loop + subl %edx,%esi // point to endpoint of copy + subl %edx,%edi + testl $15,%esi // is source aligned too? + jnz LReverseUnalignedLoop // no + jmp LReverseAlignedLoop // use aligned loop + + .align 4,0x90 // 16-byte align inner loops +LReverseAlignedLoop: // loop over 64-byte chunks + movdqa -16(%esi,%edx),%xmm0 + movdqa -32(%esi,%edx),%xmm1 + movdqa -48(%esi,%edx),%xmm2 + movdqa -64(%esi,%edx),%xmm3 + + movdqa %xmm0,-16(%edi,%edx) + movdqa %xmm1,-32(%edi,%edx) + movdqa %xmm2,-48(%edi,%edx) + movdqa %xmm3,-64(%edi,%edx) + + subl $64,%edx + jne LReverseAlignedLoop + + jmp LReverseShort // copy remaining 0..63 bytes and done + + +// Reverse, unaligned loop. LDDQU==MOVDQU on these machines. + + .align 4,0x90 // 16-byte align inner loops +LReverseUnalignedLoop: // loop over 64-byte chunks + movdqu -16(%esi,%edx),%xmm0 + movdqu -32(%esi,%edx),%xmm1 + movdqu -48(%esi,%edx),%xmm2 + movdqu -64(%esi,%edx),%xmm3 + + movdqa %xmm0,-16(%edi,%edx) + movdqa %xmm1,-32(%edi,%edx) + movdqa %xmm2,-48(%edi,%edx) + movdqa %xmm3,-64(%edi,%edx) + + subl $64,%edx + jne LReverseUnalignedLoop + + jmp LReverseShort // copy remaining 0..63 bytes and done + +PLATFUNC_DESCRIPTOR(bcopy,sse2,kHasSSE2|kCache64,kHasSupplementalSSE3) +PLATFUNC_DESCRIPTOR(memcpy,sse2,kHasSSE2|kCache64,kHasSupplementalSSE3) +PLATFUNC_DESCRIPTOR(memmove,sse2,kHasSSE2|kCache64,kHasSupplementalSSE3) diff --git a/i386/string/bcopy_sse3x.s b/i386/string/bcopy_sse3x.s new file mode 100644 index 0000000..85aa85a --- /dev/null +++ b/i386/string/bcopy_sse3x.s @@ -0,0 +1,806 @@ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* + * The bcopy/memcpy loops, tuned for Pentium-M class processors with + * Supplemental SSE3 and 64-byte cache lines. + * + * The following #defines are tightly coupled to the u-architecture: + */ + +#define kShort 80 // too short to bother with SSE (must be >=80) +#define kVeryLong (500*1024) // large enough for non-temporal stores (must be >= 8192) +#define kFastUCode ((16*1024)-15) // cutoff for microcode fastpath for "rep/movsl" + +// void bcopy(const void *src, void *dst, size_t len); + +PLATFUNC_FUNCTION_START(bcopy, sse3x, 32, 5) + pushl %ebp // set up a frame for backtraces + movl %esp,%ebp + pushl %esi + pushl %edi + pushl %ebx + movl 8(%ebp),%esi // get source ptr + movl 12(%ebp),%edi // get dest ptr + movl 16(%ebp),%ecx // get length + movl %edi,%edx + subl %esi,%edx // (dest - source) + cmpl %ecx,%edx // must move in reverse if (dest - source) < length + jb LReverseIsland + cmpl $(kShort),%ecx // long enough to bother with SSE? + jbe Lshort // no + jmp LNotShort + +// +// void *memcpy(void *dst, const void *src, size_t len); +// void *memmove(void *dst, const void *src, size_t len); +// + +PLATFUNC_FUNCTION_START(memcpy, sse3x, 32, 0) // void *memcpy(void *dst, const void *src, size_t len) +PLATFUNC_FUNCTION_START(memmove, sse3x, 32, 0) // void *memmove(void *dst, const void *src, size_t len) + pushl %ebp // set up a frame for backtraces + movl %esp,%ebp + pushl %esi + pushl %edi + pushl %ebx + movl 8(%ebp),%edi // get dest ptr + movl 12(%ebp),%esi // get source ptr + movl 16(%ebp),%ecx // get length + movl %edi,%edx + subl %esi,%edx // (dest - source) + cmpl %ecx,%edx // must move in reverse if (dest - source) < length + jb LReverseIsland + cmpl $(kShort),%ecx // long enough to bother with SSE? + ja LNotShort // yes + +// Handle short forward copies. As the most common case, this is the fall-through path. +// ecx = length (<= kShort) +// esi = source ptr +// edi = dest ptr + +Lshort: + movl %ecx,%edx // copy length + shrl $2,%ecx // get #doublewords + jz LLeftovers +2: // loop copying doublewords + movl (%esi),%eax + addl $4,%esi + movl %eax,(%edi) + addl $4,%edi + dec %ecx + jnz 2b +LLeftovers: // handle leftover bytes (0..3) in last word + andl $3,%edx // any leftover bytes? + jz Lexit +4: // loop copying bytes + movb (%esi),%al + inc %esi + movb %al,(%edi) + inc %edi + dec %edx + jnz 4b +Lexit: + movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove + popl %ebx + popl %edi + popl %esi + popl %ebp + ret + + +LReverseIsland: // keep the "jb" above a short branch... + jmp LReverse // ...because reverse moves are uncommon + + +// Handle forward moves that are long enough to justify use of SSE3. +// First, 16-byte align the destination. +// ecx = length (> kShort) +// esi = source ptr +// edi = dest ptr + +LNotShort: + cmpl $(kVeryLong),%ecx // long enough to justify heavyweight loops? + movl %edi,%edx // copy destination + jae LVeryLong // use very-long-operand path + negl %edx + andl $15,%edx // get #bytes to align destination + jz LDestAligned // already aligned + subl %edx,%ecx // decrement length +1: // loop copying 1..15 bytes + movb (%esi),%al + inc %esi + movb %al,(%edi) + inc %edi + dec %edx + jnz 1b + +// Destination is now aligned. Dispatch to one of sixteen loops over 64-byte chunks, +// based on the alignment of the source. All vector loads and stores are aligned. +// Even though this means we have to shift and repack vectors, doing so is much faster +// than unaligned loads. Since kShort>=80 and we've moved at most 15 bytes already, +// there is at least one chunk. When we enter the copy loops, the following registers +// are set up: +// ecx = residual length (0..63) +// edx = -(length to move), a multiple of 64 +// esi = ptr to 1st source byte not to move (unaligned) +// edi = ptr to 1st dest byte not to move (aligned) + +LDestAligned: + movl %ecx,%edx // copy length + movl %esi,%eax // copy source address + andl $63,%ecx // get remaining bytes for Lshort + andl $-64,%edx // get number of bytes we will copy in inner loop + andl $15,%eax // mask to low 4 bits of source address + addl %edx,%esi // point to 1st byte not copied + addl %edx,%edi + negl %edx // now generate offset to 1st byte to be copied + call 1f +1: + popl %ebx + movl (LTable-1b)(%ebx,%eax,4), %eax // load jump table entry address, relative to LZero + leal (LTable-1b)(%ebx,%eax,1), %eax + jmp *%eax + + .align 2 +LTable: // table of copy loop addresses + .long LMod0 -LTable + .long LMod1 -LTable + .long LMod2 -LTable + .long LMod3 -LTable + .long LMod4 -LTable + .long LMod5 -LTable + .long LMod6 -LTable + .long LMod7 -LTable + .long LMod8 -LTable + .long LMod9 -LTable + .long LMod10 -LTable + .long LMod11 -LTable + .long LMod12 -LTable + .long LMod13 -LTable + .long LMod14 -LTable + .long LMod15 -LTable + + +// Very long forward moves. These are at least several pages. They are special cased +// and aggressively optimized, not so much because they are common or useful, but +// because they are subject to benchmark. There isn't enough room for them in the +// area reserved on the platfunc for bcopy, so we put them elsewhere. We call +// the longcopy routine using the normal ABI. + +LVeryLong: + pushl %ecx // length (>= kVeryLong) + pushl %esi // source ptr + pushl %edi // dest ptr + call _longcopy + addl $12,%esp // pop off our parameters + jmp Lexit + + +// On Pentium-M, the microcode for "rep/movsl" is faster than SSE for 8-byte +// aligned operands from about 32KB up to kVeryLong for the hot cache case, and from +// about 256 bytes up to kVeryLong for cold caches. This is because the microcode +// avoids having to read destination cache lines that will be completely overwritten. +// The cutoff we use (ie, kFastUCode) must somehow balance the two cases, since +// we do not know if the destination is in cache or not. + +Lfastpath: + addl %edx,%esi // restore ptrs to 1st byte of source and dest + addl %edx,%edi + negl %edx // make length positive + orl %edx,%ecx // restore total #bytes remaining to move + cld // we'll move forward + movl %ecx,%edx // copy total length to move + shrl $2,%ecx // compute #words to move + rep // the u-code will optimize this + movsl + jmp LLeftovers // handle 0..3 leftover bytes + + +// Forward loop for medium length operands in which low four bits of %esi == 0000 + +LMod0: + cmpl $(-kFastUCode),%edx // %edx == -length, where (length < kVeryLong) + jle Lfastpath // long enough for fastpath in microcode + jmp 1f + .align 4,0x90 // 16-byte align inner loops +1: // loop over 64-byte chunks + movdqa (%esi,%edx),%xmm0 + movdqa 16(%esi,%edx),%xmm1 + movdqa 32(%esi,%edx),%xmm2 + movdqa 48(%esi,%edx),%xmm3 + + movdqa %xmm0,(%edi,%edx) + movdqa %xmm1,16(%edi,%edx) + movdqa %xmm2,32(%edi,%edx) + movdqa %xmm3,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 0001 + +LMod1: + movdqa -1(%esi,%edx),%xmm0 // prime the loop by loading 1st quadword +1: // loop over 64-byte chunks + movdqa 15(%esi,%edx),%xmm1 + movdqa 31(%esi,%edx),%xmm2 + movdqa 47(%esi,%edx),%xmm3 + movdqa 63(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $1,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $1,%xmm2,%xmm3 + palignr $1,%xmm1,%xmm2 + palignr $1,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 0010 + +LMod2: + movdqa -2(%esi,%edx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 14(%esi,%edx),%xmm1 + movdqa 30(%esi,%edx),%xmm2 + movdqa 46(%esi,%edx),%xmm3 + movdqa 62(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $2,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $2,%xmm2,%xmm3 + palignr $2,%xmm1,%xmm2 + palignr $2,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 0011 + +LMod3: + movdqa -3(%esi,%edx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 13(%esi,%edx),%xmm1 + movdqa 29(%esi,%edx),%xmm2 + movdqa 45(%esi,%edx),%xmm3 + movdqa 61(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $3,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $3,%xmm2,%xmm3 + palignr $3,%xmm1,%xmm2 + palignr $3,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 0100 +// We use the float single data type in order to use "movss" to merge vectors. + +LMod4: + movaps -4(%esi,%edx),%xmm0 // 4-byte aligned: prime the loop + jmp 1f + .align 4,0x90 +1: // loop over 64-byte chunks + movaps 12(%esi,%edx),%xmm1 + movaps 28(%esi,%edx),%xmm2 + movss %xmm1,%xmm0 // copy low 4 bytes of source into destination + pshufd $(0x39),%xmm0,%xmm0 // rotate right 4 bytes (mask -- 00 11 10 01) + movaps 44(%esi,%edx),%xmm3 + movss %xmm2,%xmm1 + pshufd $(0x39),%xmm1,%xmm1 + movaps 60(%esi,%edx),%xmm4 + movss %xmm3,%xmm2 + pshufd $(0x39),%xmm2,%xmm2 + + movaps %xmm0,(%edi,%edx) + movss %xmm4,%xmm3 + pshufd $(0x39),%xmm3,%xmm3 + movaps %xmm1,16(%edi,%edx) + movaps %xmm2,32(%edi,%edx) + movaps %xmm4,%xmm0 + movaps %xmm3,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 0101 + +LMod5: + movdqa -5(%esi,%edx),%xmm0// prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 11(%esi,%edx),%xmm1 + movdqa 27(%esi,%edx),%xmm2 + movdqa 43(%esi,%edx),%xmm3 + movdqa 59(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $5,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $5,%xmm2,%xmm3 + palignr $5,%xmm1,%xmm2 + palignr $5,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 0110 + +LMod6: + movdqa -6(%esi,%edx),%xmm0// prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 10(%esi,%edx),%xmm1 + movdqa 26(%esi,%edx),%xmm2 + movdqa 42(%esi,%edx),%xmm3 + movdqa 58(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $6,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $6,%xmm2,%xmm3 + palignr $6,%xmm1,%xmm2 + palignr $6,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 0111 + +LMod7: + movdqa -7(%esi,%edx),%xmm0// prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 9(%esi,%edx),%xmm1 + movdqa 25(%esi,%edx),%xmm2 + movdqa 41(%esi,%edx),%xmm3 + movdqa 57(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $7,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $7,%xmm2,%xmm3 + palignr $7,%xmm1,%xmm2 + palignr $7,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 1000 +// We use the float double data type in order to use "shufpd" to shift by 8 bytes. + +LMod8: + cmpl $(-kFastUCode),%edx// %edx == -length, where (length < kVeryLong) + jle Lfastpath // long enough for fastpath in microcode + movapd -8(%esi,%edx),%xmm0// 8-byte aligned: prime the loop + jmp 1f + .align 4,0x90 +1: // loop over 64-byte chunks + movapd 8(%esi,%edx),%xmm1 + movapd 24(%esi,%edx),%xmm2 + shufpd $01,%xmm1,%xmm0 // %xmm0 <- shr( %xmm0 || %xmm1, 8 bytes) + movapd 40(%esi,%edx),%xmm3 + shufpd $01,%xmm2,%xmm1 + movapd 56(%esi,%edx),%xmm4 + shufpd $01,%xmm3,%xmm2 + + movapd %xmm0,(%edi,%edx) + shufpd $01,%xmm4,%xmm3 + movapd %xmm1,16(%edi,%edx) + movapd %xmm2,32(%edi,%edx) + movapd %xmm4,%xmm0 + movapd %xmm3,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 1001 + +LMod9: + movdqa -9(%esi,%edx),%xmm0// prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 7(%esi,%edx),%xmm1 + movdqa 23(%esi,%edx),%xmm2 + movdqa 39(%esi,%edx),%xmm3 + movdqa 55(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $9,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $9,%xmm2,%xmm3 + palignr $9,%xmm1,%xmm2 + palignr $9,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 1010 + +LMod10: + movdqa -10(%esi,%edx),%xmm0// prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 6(%esi,%edx),%xmm1 + movdqa 22(%esi,%edx),%xmm2 + movdqa 38(%esi,%edx),%xmm3 + movdqa 54(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $10,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $10,%xmm2,%xmm3 + palignr $10,%xmm1,%xmm2 + palignr $10,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 1011 + +LMod11: + movdqa -11(%esi,%edx),%xmm0// prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 5(%esi,%edx),%xmm1 + movdqa 21(%esi,%edx),%xmm2 + movdqa 37(%esi,%edx),%xmm3 + movdqa 53(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $11,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $11,%xmm2,%xmm3 + palignr $11,%xmm1,%xmm2 + palignr $11,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 1100 +// We use the float single data type in order to use "movss" to merge vectors. + +LMod12: + movss (%esi,%edx),%xmm0// prefetch 1st four bytes of source, right justified + jmp 1f + .align 4,0x90 +1: // loop over 64-byte chunks + pshufd $(0x93),4(%esi,%edx),%xmm1 // load and rotate right 12 bytes (mask -- 10 01 00 11) + pshufd $(0x93),20(%esi,%edx),%xmm2 + pshufd $(0x93),36(%esi,%edx),%xmm3 + pshufd $(0x93),52(%esi,%edx),%xmm4 + + movaps %xmm4,%xmm5 + movss %xmm3,%xmm4 // copy low 4 bytes of source into destination + movss %xmm2,%xmm3 + movss %xmm1,%xmm2 + movss %xmm0,%xmm1 + + movaps %xmm1,(%edi,%edx) + movaps %xmm2,16(%edi,%edx) + movaps %xmm5,%xmm0 + movaps %xmm3,32(%edi,%edx) + movaps %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 1101 + +LMod13: + movdqa -13(%esi,%edx),%xmm0// prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 3(%esi,%edx),%xmm1 + movdqa 19(%esi,%edx),%xmm2 + movdqa 35(%esi,%edx),%xmm3 + movdqa 51(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $13,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $13,%xmm2,%xmm3 + palignr $13,%xmm1,%xmm2 + palignr $13,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 1110 + +LMod14: + movdqa -14(%esi,%edx),%xmm0// prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 2(%esi,%edx),%xmm1 + movdqa 18(%esi,%edx),%xmm2 + movdqa 34(%esi,%edx),%xmm3 + movdqa 50(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $14,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $14,%xmm2,%xmm3 + palignr $14,%xmm1,%xmm2 + palignr $14,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %esi == 1111 + +LMod15: + movdqa -15(%esi,%edx),%xmm0// prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 1(%esi,%edx),%xmm1 + movdqa 17(%esi,%edx),%xmm2 + movdqa 33(%esi,%edx),%xmm3 + movdqa 49(%esi,%edx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $15,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $15,%xmm2,%xmm3 + palignr $15,%xmm1,%xmm2 + palignr $15,%xmm5,%xmm1 + + movdqa %xmm1,(%edi,%edx) + movdqa %xmm2,16(%edi,%edx) + movdqa %xmm3,32(%edi,%edx) + movdqa %xmm4,48(%edi,%edx) + + addl $64,%edx + jnz 1b + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Reverse moves. These are not optimized as aggressively as their forward +// counterparts, as they are only used with destructive overlap. +// ecx = length +// esi = source ptr +// edi = dest ptr + +LReverse: + addl %ecx,%esi // point to end of strings + addl %ecx,%edi + cmpl $(kShort),%ecx // long enough to bother with SSE? + ja LReverseNotShort // yes + +// Handle reverse short copies. +// ecx = length +// esi = one byte past end of source +// edi = one byte past end of dest + +LReverseShort: + movl %ecx,%edx // copy length + shrl $2,%ecx // #words + jz 3f +1: + subl $4,%esi + movl (%esi),%eax + subl $4,%edi + movl %eax,(%edi) + dec %ecx + jnz 1b +3: + andl $3,%edx // bytes? + jz 5f +4: + dec %esi + movb (%esi),%al + dec %edi + movb %al,(%edi) + dec %edx + jnz 4b +5: + movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove + popl %ebx + popl %edi + popl %esi + popl %ebp + ret + +// Handle a reverse move long enough to justify using SSE. +// ecx = length +// esi = one byte past end of source +// edi = one byte past end of dest + +LReverseNotShort: + movl %edi,%edx // copy destination + andl $15,%edx // get #bytes to align destination + je LReverseDestAligned // already aligned + subl %edx,%ecx // adjust length +1: // loop copying 1..15 bytes + dec %esi + movb (%esi),%al + dec %edi + movb %al,(%edi) + dec %edx + jnz 1b + +// Destination is now aligned. Prepare for reverse loops. + +LReverseDestAligned: + movl %ecx,%edx // copy length + andl $63,%ecx // get remaining bytes for Lshort + andl $-64,%edx // get number of bytes we will copy in inner loop + subl %edx,%esi // point to endpoint of copy + subl %edx,%edi + testl $15,%esi // is source aligned too? + jnz LReverseUnalignedLoop // no + +LReverseAlignedLoop: // loop over 64-byte chunks + movdqa -16(%esi,%edx),%xmm0 + movdqa -32(%esi,%edx),%xmm1 + movdqa -48(%esi,%edx),%xmm2 + movdqa -64(%esi,%edx),%xmm3 + + movdqa %xmm0,-16(%edi,%edx) + movdqa %xmm1,-32(%edi,%edx) + movdqa %xmm2,-48(%edi,%edx) + movdqa %xmm3,-64(%edi,%edx) + + subl $64,%edx + jne LReverseAlignedLoop + + jmp LReverseShort // copy remaining 0..63 bytes and done + + +// Reverse, unaligned loop. LDDQU==MOVDQU on these machines. + +LReverseUnalignedLoop: // loop over 64-byte chunks + movdqu -16(%esi,%edx),%xmm0 + movdqu -32(%esi,%edx),%xmm1 + movdqu -48(%esi,%edx),%xmm2 + movdqu -64(%esi,%edx),%xmm3 + + movdqa %xmm0,-16(%edi,%edx) + movdqa %xmm1,-32(%edi,%edx) + movdqa %xmm2,-48(%edi,%edx) + movdqa %xmm3,-64(%edi,%edx) + + subl $64,%edx + jne LReverseUnalignedLoop + + jmp LReverseShort // copy remaining 0..63 bytes and done + +PLATFUNC_DESCRIPTOR(bcopy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) +PLATFUNC_DESCRIPTOR(memcpy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) +PLATFUNC_DESCRIPTOR(memmove,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) diff --git a/i386/string/bcopy_sse42.s b/i386/string/bcopy_sse42.s new file mode 100644 index 0000000..14146ee --- /dev/null +++ b/i386/string/bcopy_sse42.s @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* + * The bcopy/memcpy loops, tuned for Nehalem. + * + * The following #defines are tightly coupled to the u-architecture: + */ + +#define kShort 80 // too short to bother with SSE (must be >=80) + + +// void bcopy(const void *src, void *dst, size_t len); + +PLATFUNC_FUNCTION_START(bcopy, sse42, 32, 5) + pushl %ebp // set up a frame for backtraces + movl %esp,%ebp + pushl %esi + pushl %edi + movl 8(%ebp),%esi // get source ptr + movl 12(%ebp),%edi // get dest ptr + movl 16(%ebp),%ecx // get length + movl %edi,%edx + subl %esi,%edx // (dest - source) + cmpl %ecx,%edx // must move in reverse if (dest - source) < length + jb LReverseIsland + cmpl $(kShort),%ecx // long enough to bother with SSE? + jbe Lshort // no + jmp LNotShort + +// +// void *memcpy(void *dst, const void *src, size_t len); +// void *memmove(void *dst, const void *src, size_t len); +// + +PLATFUNC_FUNCTION_START(memcpy, sse42, 32, 0) // void *memcpy(void *dst, const void *src, size_t len) +PLATFUNC_FUNCTION_START(memmove, sse42, 32, 0) // void *memmove(void *dst, const void *src, size_t len) + pushl %ebp // set up a frame for backtraces + movl %esp,%ebp + pushl %esi + pushl %edi + movl 8(%ebp),%edi // get dest ptr + movl 12(%ebp),%esi // get source ptr + movl 16(%ebp),%ecx // get length + movl %edi,%edx + subl %esi,%edx // (dest - source) + cmpl %ecx,%edx // must move in reverse if (dest - source) < length + jb LReverseIsland + cmpl $(kShort),%ecx // long enough to bother with SSE? + ja LNotShort // yes + +// Handle short forward copies. As the most common case, this is the fall-through path. +// ecx = length (<= kShort) +// esi = source ptr +// edi = dest ptr + +Lshort: + movl %ecx,%edx // copy length + shrl $2,%ecx // get #doublewords + jz 3f +2: // loop copying doublewords + movl (%esi),%eax + addl $4,%esi + movl %eax,(%edi) + addl $4,%edi + dec %ecx + jnz 2b +3: // handle leftover bytes (0..3) in last word + andl $3,%edx // any leftover bytes? + jz Lexit +4: // loop copying bytes + movb (%esi),%al + inc %esi + movb %al,(%edi) + inc %edi + dec %edx + jnz 4b +Lexit: + movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove + popl %edi + popl %esi + popl %ebp + ret + + +LReverseIsland: // keep the "jb" above a short branch... + jmp LReverse // ...because reverse moves are uncommon + + +// Handle forward moves that are long enough to justify use of SSE. +// First, 16-byte align the destination. +// ecx = length (> kShort) +// esi = source ptr +// edi = dest ptr + +LNotShort: + movl %edi,%edx // copy destination + negl %edx + andl $15,%edx // get #bytes to align destination + jz LDestAligned // already aligned + subl %edx,%ecx // decrement length +1: // loop copying 1..15 bytes + movb (%esi),%al + inc %esi + movb %al,(%edi) + inc %edi + dec %edx + jnz 1b + +// Destination is now aligned. Nehalem does a great job with unaligned SSE loads, +// so we use MOVDQU rather than aligned loads and shifts. Since kShort>=80, we +// know there is at least one 64-byte chunk to move. +// When we enter the copy loops, the following registers are set up: +// ecx = residual length (0..63) +// edx = -(length to move), a multiple of 64 +// esi = ptr to 1st source byte not to move (unaligned) +// edi = ptr to 1st dest byte not to move (aligned) + +LDestAligned: + movl %ecx,%edx // copy length + andl $63,%ecx // get remaining bytes for Lshort + andl $-64,%edx // get number of bytes we will copy in inner loop + addl %edx,%esi // point to 1st byte not copied + addl %edx,%edi + negl %edx // now generate offset to 1st byte to be copied + testl $15,%esi // source also aligned? + jnz LUnalignedLoop + jmp LAlignedLoop + + +// Forward loop for aligned operands. + + .align 4,0x90 // 16-byte align inner loops +LAlignedLoop: // loop over 64-byte chunks + movdqa (%esi,%edx),%xmm0 + movdqa 16(%esi,%edx),%xmm1 + movdqa 32(%esi,%edx),%xmm2 + movdqa 48(%esi,%edx),%xmm3 + + movdqa %xmm0,(%edi,%edx) + movdqa %xmm1,16(%edi,%edx) + movdqa %xmm2,32(%edi,%edx) + movdqa %xmm3,48(%edi,%edx) + + addl $64,%edx + jnz LAlignedLoop + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Forward loop for unaligned operands. + + .align 4,0x90 // 16-byte align inner loops +LUnalignedLoop: // loop over 64-byte chunks + movdqu (%esi,%edx),%xmm0 + movdqu 16(%esi,%edx),%xmm1 + movdqu 32(%esi,%edx),%xmm2 + movdqu 48(%esi,%edx),%xmm3 + + movdqa %xmm0,(%edi,%edx) + movdqa %xmm1,16(%edi,%edx) + movdqa %xmm2,32(%edi,%edx) + movdqa %xmm3,48(%edi,%edx) + + addl $64,%edx + jnz LUnalignedLoop + + jmp Lshort // copy remaining 0..63 bytes and done + + +// Reverse moves. They are only used with destructive overlap. +// ecx = length +// esi = source ptr +// edi = dest ptr + +LReverse: + addl %ecx,%esi // point to end of strings + addl %ecx,%edi + cmpl $(kShort),%ecx // long enough to bother with SSE? + ja LReverseNotShort // yes + +// Handle reverse short copies. +// ecx = length +// esi = one byte past end of source +// edi = one byte past end of dest + +LReverseShort: + movl %ecx,%edx // copy length + shrl $2,%ecx // #words + jz 3f +1: + subl $4,%esi + movl (%esi),%eax + subl $4,%edi + movl %eax,(%edi) + dec %ecx + jnz 1b +3: + andl $3,%edx // bytes? + jz 5f +4: + dec %esi + movb (%esi),%al + dec %edi + movb %al,(%edi) + dec %edx + jnz 4b +5: + movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove + popl %edi + popl %esi + popl %ebp + ret + +// Handle a reverse move long enough to justify using SSE. +// ecx = length +// esi = one byte past end of source +// edi = one byte past end of dest + +LReverseNotShort: + movl %edi,%edx // copy destination + andl $15,%edx // get #bytes to align destination + je LReverseDestAligned // already aligned + subl %edx,%ecx // adjust length +1: // loop copying 1..15 bytes + dec %esi + movb (%esi),%al + dec %edi + movb %al,(%edi) + dec %edx + jnz 1b + +// Destination is now aligned. Prepare for reverse loops. + +LReverseDestAligned: + movl %ecx,%edx // copy length + andl $63,%ecx // get remaining bytes for Lshort + andl $-64,%edx // get number of bytes we will copy in inner loop + subl %edx,%esi // point to endpoint of copy + subl %edx,%edi + testl $15,%esi // is source aligned too? + jnz LReverseUnalignedLoop // no + +LReverseAlignedLoop: // loop over 64-byte chunks + movdqa -16(%esi,%edx),%xmm0 + movdqa -32(%esi,%edx),%xmm1 + movdqa -48(%esi,%edx),%xmm2 + movdqa -64(%esi,%edx),%xmm3 + + movdqa %xmm0,-16(%edi,%edx) + movdqa %xmm1,-32(%edi,%edx) + movdqa %xmm2,-48(%edi,%edx) + movdqa %xmm3,-64(%edi,%edx) + + subl $64,%edx + jne LReverseAlignedLoop + + jmp LReverseShort // copy remaining 0..63 bytes and done + + +// Reverse, unaligned loop. LDDQU==MOVDQU on these machines. + +LReverseUnalignedLoop: // loop over 64-byte chunks + movdqu -16(%esi,%edx),%xmm0 + movdqu -32(%esi,%edx),%xmm1 + movdqu -48(%esi,%edx),%xmm2 + movdqu -64(%esi,%edx),%xmm3 + + movdqa %xmm0,-16(%edi,%edx) + movdqa %xmm1,-32(%edi,%edx) + movdqa %xmm2,-48(%edi,%edx) + movdqa %xmm3,-64(%edi,%edx) + + subl $64,%edx + jne LReverseUnalignedLoop + + jmp LReverseShort // copy remaining 0..63 bytes and done + + +PLATFUNC_DESCRIPTOR(bcopy,sse42,kHasSSE4_2,0) +PLATFUNC_DESCRIPTOR(memcpy,sse42,kHasSSE4_2,0) +PLATFUNC_DESCRIPTOR(memmove,sse42,kHasSSE4_2,0) diff --git a/i386/string/bzero.c b/i386/string/bzero.c new file mode 100644 index 0000000..69d51df --- /dev/null +++ b/i386/string/bzero.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse42) +PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse2) +PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, scalar) + +static const platfunc_descriptor *bzero_platfunc_descriptors[] = { + PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse42), + PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse2), + PLATFUNC_DESCRIPTOR_REFERENCE(bzero, scalar), + 0 +}; + +void *bzero_chooser() __asm__("_bzero"); +void *bzero_chooser() { + __asm__(".desc _bzero, 0x100"); + return find_platform_function((const platfunc_descriptor **) bzero_platfunc_descriptors); +} diff --git a/i386/string/bzero_scalar.s b/i386/string/bzero_scalar.s new file mode 100644 index 0000000..74adf99 --- /dev/null +++ b/i386/string/bzero_scalar.s @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1993 Winning Strategies, Inc. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Winning Strategies, Inc. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 +#include +#include + +/* + * bzero (void *b, size_t len) + * write len zero bytes to the string b. + * + * Written by: + * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc. + */ + +PLATFUNC_FUNCTION_START_GENERIC(bzero, scalar, 32, 4) + pushl %ebp /* set up a frame for backtraces */ + movl %esp,%ebp + pushl %edi + pushl %ebx + movl 8(%ebp),%edi + movl 12(%ebp),%ecx + + cld /* set fill direction forward */ + xorl %eax,%eax /* set fill data to 0 */ + + /* + * if the string is too short, it's really not worth the overhead + * of aligning to word boundries, etc. So we jump to a plain + * unaligned set. + */ + cmpl $0x0f,%ecx + jbe L1 + + movl %edi,%edx /* compute misalignment */ + negl %edx + andl $3,%edx + movl %ecx,%ebx + subl %edx,%ebx + + movl %edx,%ecx /* zero until word aligned */ + rep + stosb + + movl %ebx,%ecx /* zero by words */ + shrl $2,%ecx + rep + stosl + + movl %ebx,%ecx + andl $3,%ecx /* zero remainder by bytes */ +L1: rep + stosb + + popl %ebx + popl %edi + popl %ebp + ret + +PLATFUNC_DESCRIPTOR(bzero,scalar,0,0) diff --git a/i386/string/bzero_sse2.s b/i386/string/bzero_sse2.s new file mode 100644 index 0000000..6d03019 --- /dev/null +++ b/i386/string/bzero_sse2.s @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* + * Bzero, tuned for Pentium-M class processors with SSE2 + * and 64-byte cache lines. + * + * This routine is also used for memset(p,0,n), which is a common case + * since gcc sometimes silently maps bzero() into memset(). As a result, + * we always load the original ptr into %eax before returning. + */ + +#define kShort 80 // too short to bother with SSE (must be >=80) +#define kVeryLong (1024*1024) + +// void bzero(void *b, size_t len); + +PLATFUNC_FUNCTION_START(bzero, sse2, 32, 5) + pushl %ebp // set up a frame for backtraces + movl %esp,%ebp + pushl %edi + movl 8(%ebp),%edi // get ptr + movl 12(%ebp),%edx // get length + + xorl %eax,%eax // set fill data to 0 + cmpl $(kShort),%edx // long enough for SSE? + jg LNotShort // yes + +// Here for short operands or the end of long ones. +// %edx = length +// %edi = ptr +// %eax = zero + +Lshort: + cmpl $16,%edx // long enough to word align? + jge 3f // yes + test %edx,%edx // length==0? + jz 6f +1: + movb %al,(%edi) // zero a byte + inc %edi + dec %edx + jnz 1b + jmp 6f +2: + movb %al,(%edi) // zero a byte + inc %edi + dec %edx +3: + test $3,%edi // is ptr doubleword aligned? + jnz 2b // no + movl %edx,%ecx // copy length + shrl $2,%edx // #doublewords to store +4: + movl %eax,(%edi) // zero an aligned doubleword + addl $4,%edi + dec %edx + jnz 4b + andl $3,%ecx // mask down to #bytes at end (0..3) + jz 6f // none +5: + movb %al,(%edi) // zero a byte + inc %edi + dec %ecx + jnz 5b +6: + movl 8(%ebp),%eax // get return value in case this was a call of memset() + popl %edi + popl %ebp + ret + + +// We will be using SSE, so align ptr. + +LNotShort: + movl %edi,%ecx + negl %ecx + andl $15,%ecx // mask down to #bytes to 16-byte align + jz LDestAligned // already aligned + subl %ecx,%edx // decrement length +0: // loop storing bytes to align the ptr + movb %al,(%edi) // pack in a byte + inc %edi + dec %ecx + jnz 0b + +// Destination is now 16-byte aligned. Prepare to loop over 64-byte chunks. +// %edx = length +// %edi = ptr +// %eax = zero + +LDestAligned: + movl %edx,%ecx + andl $63,%edx // mask down to residual length (0..63) + andl $-64,%ecx // get #bytes we will zero in this loop + pxor %xmm0,%xmm0 // zero an SSE register + addl %ecx,%edi // increment ptr by length to move + cmpl $(kVeryLong),%ecx // long enough to justify non-temporal stores? + jae LVeryLong // yes + negl %ecx // negate length to move + jmp 1f + +// Loop over 64-byte chunks, storing into cache. + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movdqa %xmm0,(%edi,%ecx) + movdqa %xmm0,16(%edi,%ecx) + movdqa %xmm0,32(%edi,%ecx) + movdqa %xmm0,48(%edi,%ecx) + addl $64,%ecx + jne 1b + + jmp Lshort + +// Very long operands: use non-temporal stores to bypass cache. + +LVeryLong: + negl %ecx // negate length to move + jmp 1f + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movntdq %xmm0,(%edi,%ecx) + movntdq %xmm0,16(%edi,%ecx) + movntdq %xmm0,32(%edi,%ecx) + movntdq %xmm0,48(%edi,%ecx) + addl $64,%ecx + jne 1b + + sfence // required by non-temporal stores + jmp Lshort + +PLATFUNC_DESCRIPTOR(bzero,sse2,kHasSSE2,kHasSSE4_2) diff --git a/i386/string/bzero_sse42.s b/i386/string/bzero_sse42.s new file mode 100644 index 0000000..24073c4 --- /dev/null +++ b/i386/string/bzero_sse42.s @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* + * Bzero, tuned for processors with SSE4.2 and 64-byte cache lines, ie Nehalem. + * We don't actually use SSE4.2, but rather use it to identify Nehalem. + * + * We do not use nontemporal operations, but use MOVDQA in preference to REP/STOS. + * + * This routine is also used for memset(p,0,n), which is a common case + * since gcc sometimes silently maps bzero() into memset(). As a result, + * we always load the original ptr into %eax before returning. + */ + +#define kShort 80 // too short to bother with SSE (must be >=80) + + +PLATFUNC_FUNCTION_START(bzero, sse42, 32, 5) + pushl %ebp // set up a frame for backtraces + movl %esp,%ebp + pushl %edi + movl 8(%ebp),%edi // get ptr + movl 12(%ebp),%edx // get length + + xorl %eax,%eax // set fill data to 0 + cmpl $(kShort),%edx // long enough for SSE? + jg LNotShort // yes + +// Here for short operands or the end of long ones. +// %edx = length +// %edi = ptr +// %eax = zero + +Lshort: + cmpl $12,%edx // long enough to word align? + jge 3f // yes + test %edx,%edx // length==0? + jz 6f +1: + movb %al,(%edi) // zero a byte + inc %edi + dec %edx + jnz 1b + jmp 6f +2: + movb %al,(%edi) // zero a byte + inc %edi + dec %edx +3: + test $3,%edi // is ptr doubleword aligned? + jnz 2b // no + movl %edx,%ecx // copy length + shrl $2,%edx // #doublewords to store +4: + movl %eax,(%edi) // zero an aligned doubleword + addl $4,%edi + dec %edx + jnz 4b + andl $3,%ecx // mask down to #bytes at end (0..3) + jz 6f // none +5: + movb %al,(%edi) // zero a byte + inc %edi + dec %ecx + jnz 5b +6: + movl 8(%ebp),%eax // get return value in case this was a call of memset() + popl %edi + popl %ebp + ret + + +// We will be using SSE, so align ptr. +// %edx = length +// %edi = ptr +// %eax = zero + +LNotShort: + testl $3,%edi // 4-byte aligned? + jz 2f // yes + movb %al,(%edi) // zero another byte + incl %edi + decl %edx + jmp LNotShort +1: // zero doublewords until 16-byte aligned + movl %eax,(%edi) + addl $4,%edi + subl $4,%edx +2: + testl $15,%edi // 16-byte aligned? + jnz 1b // no + + +// Destination is now 16-byte aligned. Prepare to loop over 64-byte chunks. +// %edx = length +// %edi = ptr +// %eax = zero + +LDestAligned: + movl %edx,%ecx + andl $63,%edx // mask down to residual length (0..63) + andl $-64,%ecx // get #bytes we will zero in this loop + pxor %xmm0,%xmm0 // zero an SSE register + addl %ecx,%edi // increment ptr by length to move + negl %ecx // negate length to move + jmp 1f + +// Loop over 64-byte chunks, storing into cache. + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movdqa %xmm0,(%edi,%ecx) + movdqa %xmm0,16(%edi,%ecx) + movdqa %xmm0,32(%edi,%ecx) + movdqa %xmm0,48(%edi,%ecx) + addl $64,%ecx + jne 1b + + jmp Lshort + + + +PLATFUNC_DESCRIPTOR(bzero,sse42,kHasSSE4_2,0) diff --git a/i386/string/longcopy_sse3x.s b/i386/string/longcopy_sse3x.s new file mode 100644 index 0000000..aed3bc3 --- /dev/null +++ b/i386/string/longcopy_sse3x.s @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + + +/* + * The bcopy/memcpy loops for very long operands, tuned for Pentium-M + * class processors with Supplemental SSE3 and 64-byte cache lines. + * + * The following #defines are tightly coupled to the u-architecture: + */ + +#define kBigChunk (256*1024) // outer loop chunk size for kVeryLong sized operands + + +// Very long forward moves. These are at least several pages, so we loop over big +// chunks of memory (kBigChunk in size.) We first prefetch the chunk, and then copy +// it using non-temporal stores. Hopefully all the reads occur in the prefetch loop, +// so the copy loop reads from L2 and writes directly to memory (with write combining.) +// This minimizes bus turnaround and maintains good DRAM page locality. +// Note that for this scheme to work, kVeryLong must be a large fraction of L2 cache +// size. Otherwise, it is counter-productive to bypass L2 on the stores. +// +// We are called from the platfunc bcopy loops when they encounter very long +// operands, with the standard ABI. +// +// void longcopy(const void *dest, void *sou, size_t len) + +// void longcopy(const void *dest, void *sou, size_t len) + + .text + .private_extern _longcopy + + .align 5 +_longcopy: + pushl %ebp // set up a frame for backtraces + movl %esp,%ebp + pushl %esi + pushl %edi + pushl %ebx // we'll need to use this too + movl 8(%ebp),%edi // get dest ptr + movl 12(%ebp),%esi // get source ptr + movl 16(%ebp),%ecx // get length + movl %edi,%ebx // copy dest ptr + negl %ebx + andl $63,%ebx // get #bytes to cache line align destination + jz LBigChunkLoop // already aligned + +// Cache line align destination, so temporal stores in copy loops work right. + + pushl %ebx // arg3 - #bytes to align destination (1..63) + pushl %esi // arg2 - source + pushl %edi // arg1 - dest + call _memcpy // align the destination + addl $12,%esp + movl 8(%ebp),%edi // recover dest ptr + movl 12(%ebp),%esi // recover source ptr + movl 16(%ebp),%ecx // recover length + addl %ebx,%esi // adjust ptrs and lengths past copy + addl %ebx,%edi + subl %ebx,%ecx + +// Loop over big chunks. +// ecx = length remaining (>= 4096) +// edi = dest (64-byte aligned) +// esi = source (may be unaligned) + +LBigChunkLoop: + movl $(kBigChunk),%edx // assume we can do a full chunk + cmpl %edx,%ecx // do we have a full chunk left to do? + cmovbl %ecx,%edx // if not, only move what we have left + andl $-4096,%edx // we work in page multiples + xor %eax,%eax // initialize chunk offset + jmp LTouchLoop + +// Touch in the next chunk. We try to keep the prefetch unit in "kick-start" mode, +// by touching two adjacent cache lines every 8 lines of each page, in four slices. +// Because the source may be unaligned, we use byte loads to touch. +// ecx = length remaining (including this chunk) +// edi = ptr to start of dest chunk +// esi = ptr to start of source chunk +// edx = chunk length (multiples of pages) +// ebx = scratch reg used to read a byte of each cache line +// eax = chunk offset + + .align 4,0x90 // 16-byte align inner loops +LTouchLoop: + movzb (%esi,%eax),%ebx // touch line 0, 2, 4, or 6 of page + movzb 1*64(%esi,%eax),%ebx // touch line 1, 3, 5, or 7 + movzb 8*64(%esi,%eax),%ebx // touch line 8, 10, 12, or 14 + movzb 9*64(%esi,%eax),%ebx // etc + + movzb 16*64(%esi,%eax),%ebx + movzb 17*64(%esi,%eax),%ebx + movzb 24*64(%esi,%eax),%ebx + movzb 25*64(%esi,%eax),%ebx + + movzb 32*64(%esi,%eax),%ebx + movzb 33*64(%esi,%eax),%ebx + movzb 40*64(%esi,%eax),%ebx + movzb 41*64(%esi,%eax),%ebx + + movzb 48*64(%esi,%eax),%ebx + movzb 49*64(%esi,%eax),%ebx + movzb 56*64(%esi,%eax),%ebx + movzb 57*64(%esi,%eax),%ebx + + subl $-128,%eax // next slice of page (adding 128 w 8-bit immediate) + testl $512,%eax // done with this page? + jz LTouchLoop // no, next of four slices + addl $(4096-512),%eax // move on to next page + cmpl %eax,%edx // done with this chunk? + jnz LTouchLoop // no, do next page + +// The chunk has been pre-fetched, now copy it using non-temporal stores. +// There are two copy loops, depending on whether the source is 16-byte aligned +// or not. + + addl %edx,%esi // increment ptrs by chunk length + addl %edx,%edi + subl %edx,%ecx // adjust remaining length + negl %edx // prepare loop index (counts up to 0) + testl $15,%esi // is source 16-byte aligned? + jnz LVeryLongUnaligned // source is not aligned + jmp LVeryLongAligned + + .align 4,0x90 // 16-byte align inner loops +LVeryLongAligned: // aligned loop over 128-bytes + movdqa (%esi,%edx),%xmm0 + movdqa 16(%esi,%edx),%xmm1 + movdqa 32(%esi,%edx),%xmm2 + movdqa 48(%esi,%edx),%xmm3 + movdqa 64(%esi,%edx),%xmm4 + movdqa 80(%esi,%edx),%xmm5 + movdqa 96(%esi,%edx),%xmm6 + movdqa 112(%esi,%edx),%xmm7 + + movntdq %xmm0,(%edi,%edx) + movntdq %xmm1,16(%edi,%edx) + movntdq %xmm2,32(%edi,%edx) + movntdq %xmm3,48(%edi,%edx) + movntdq %xmm4,64(%edi,%edx) + movntdq %xmm5,80(%edi,%edx) + movntdq %xmm6,96(%edi,%edx) + movntdq %xmm7,112(%edi,%edx) + + subl $-128,%edx // add 128 with an 8-bit immediate + jnz LVeryLongAligned + jmp LVeryLongChunkEnd + + .align 4,0x90 // 16-byte align inner loops +LVeryLongUnaligned: // unaligned loop over 128-bytes + movdqu (%esi,%edx),%xmm0 + movdqu 16(%esi,%edx),%xmm1 + movdqu 32(%esi,%edx),%xmm2 + movdqu 48(%esi,%edx),%xmm3 + movdqu 64(%esi,%edx),%xmm4 + movdqu 80(%esi,%edx),%xmm5 + movdqu 96(%esi,%edx),%xmm6 + movdqu 112(%esi,%edx),%xmm7 + + movntdq %xmm0,(%edi,%edx) + movntdq %xmm1,16(%edi,%edx) + movntdq %xmm2,32(%edi,%edx) + movntdq %xmm3,48(%edi,%edx) + movntdq %xmm4,64(%edi,%edx) + movntdq %xmm5,80(%edi,%edx) + movntdq %xmm6,96(%edi,%edx) + movntdq %xmm7,112(%edi,%edx) + + subl $-128,%edx // add 128 with an 8-bit immediate + jnz LVeryLongUnaligned + +LVeryLongChunkEnd: + cmpl $4096,%ecx // at least another page to go? + jae LBigChunkLoop // yes + +// Done. Call memcpy() again to handle the 0-4095 bytes at the end. + + sfence // required by non-temporal stores + testl %ecx,%ecx // anything left to copy? + jz 1f + pushl %ecx // arg3 - #bytes to align destination (1..63) + pushl %esi // arg2 - source + pushl %edi // arg1 - dest + call _memcpy // align the destination + addl $12,%esp // pop off arguments +1: + popl %ebx + popl %edi + popl %esi + popl %ebp + ret diff --git a/i386/string/memcpy.c b/i386/string/memcpy.c new file mode 100644 index 0000000..20c4719 --- /dev/null +++ b/i386/string/memcpy.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse42) +PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse3x) +PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse2) +PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, scalar) + +static const platfunc_descriptor *memcpy_platfunc_descriptors[] = { + PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse42), + PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse3x), + PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse2), + PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, scalar), + 0 +}; + +void *memcpy_chooser() __asm__("_memcpy"); +void *memcpy_chooser() { + __asm__(".desc _memcpy, 0x100"); + return find_platform_function((const platfunc_descriptor **) memcpy_platfunc_descriptors); +} diff --git a/i386/string/memcpy.s b/i386/string/memcpy.s deleted file mode 100644 index 8160b02..0000000 --- a/i386/string/memcpy.s +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: libc/i386/ansi/memcpy.c - * Author: Bruce Martin, NeXT Computer, Inc. - * - * HISTORY - * 24-Nov-92 Derek B Clegg (dclegg@next.com) - * Created for m98k. - */ -#define MEMCOPY -#include "bcopy.s" diff --git a/i386/string/memmove.c b/i386/string/memmove.c new file mode 100644 index 0000000..a79d916 --- /dev/null +++ b/i386/string/memmove.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse42) +PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse3x) +PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse2) +PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, scalar) + +static const platfunc_descriptor *memmove_platfunc_descriptors[] = { + PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse42), + PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse3x), + PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse2), + PLATFUNC_DESCRIPTOR_REFERENCE(memmove, scalar), + 0 +}; + +void *memmove_chooser() __asm__("_memmove"); +void *memmove_chooser() { + __asm__(".desc _memmove, 0x100"); + return find_platform_function((const platfunc_descriptor **) memmove_platfunc_descriptors); +} diff --git a/i386/string/memmove.s b/i386/string/memmove.s deleted file mode 100644 index 50fd4e2..0000000 --- a/i386/string/memmove.s +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: libc/i386/ansi/memmove.c - * Author: Bruce Martin, NeXT Computer, Inc. - * - * HISTORY - * 24-Nov-92 Derek B Clegg (dclegg@next.com) - * Created for m98k. - */ -#define MEMMOVE -#include "bcopy.s" diff --git a/i386/string/memset.s b/i386/string/memset.s index a0adaa2..b8cdd81 100644 --- a/i386/string/memset.s +++ b/i386/string/memset.s @@ -31,7 +31,7 @@ * void memset_pattern16(void *b, const void *c16, size_t len); * * Calls of memset() with c==0 are routed to the bzero() routine. Most of the - * others go to _COMM_PAGE_MEMSET_PATTERN, which is entered as follows: + * others go to _memset_pattern, which is entered as follows: * %edi = ptr to memory to set (aligned) * %edx = length (which can be short, though we bias in favor of long operands) * %xmm0 = the pattern to store @@ -54,9 +54,8 @@ _memset: // void *memset(void *b, int c, size_t len); andl $0xFF,%eax // (c==0) ? jnz LNonzero // not a bzero - movl $(_COMM_PAGE_BZERO),%eax// map memset(p,0,n) into bzero(p,n) movl %edx,8(%esp) // put count where bzero() expects it - jmp *%eax // enter commpage + jmp _bzero // enter _bzero // Handle memset of a nonzero value. @@ -135,8 +134,7 @@ LCallCommpage: dec %ecx jnz 1b 2: // ptr aligned, length long enough to justify - movl $(_COMM_PAGE_MEMSET_PATTERN),%eax - call *%eax // call commpage to do the heavy lifting + call _memset_pattern // call commpage to do the heavy lifting movl 12(%esp),%eax // get return value (ie, original ptr) popl %esi popl %edi @@ -234,8 +232,7 @@ LAlignPtr: // NB: can drop down to here! // Ptr is aligned if practical, we're ready to call commpage to do the heavy lifting. LReady: - movl $(_COMM_PAGE_MEMSET_PATTERN),%eax - call *%eax // call commpage to do the heavy lifting + call _memset_pattern // call commpage to do the heavy lifting popl %esi popl %edi ret diff --git a/i386/string/memset_pattern_sse2.s b/i386/string/memset_pattern_sse2.s new file mode 100644 index 0000000..135517d --- /dev/null +++ b/i386/string/memset_pattern_sse2.s @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* The common path for nonzero memset and the memset_pattern routines, + * tuned for Pentium-M class processors with SSE2 and 64-byte cache lines. + * This is used by the following functions: + * + * void *memset(void *b, int c, size_t len); // when c!=0 + * void memset_pattern4(void *b, const void *c4, size_t len); + * void memset_pattern8(void *b, const void *c8, size_t len); + * void memset_pattern16(void *b, const void *c16, size_t len); + * + * Note bzero() and memset() of 0 are handled separately. + */ + +#define kShort 63 +#define kVeryLong (1024*1024) + +// Initial entry from Libc with parameters passed in registers. Although we +// correctly handle misaligned ptrs and short operands, they are inefficient. +// Therefore our caller should filter out short operands and exploit local +// knowledge (ie, original pattern length) to align the ptr if possible. +// When called, we expect: +// %edi = ptr to memory to set (not necessarily aligned) +// %edx = length (may be short or even 0) +// %xmm0 = the pattern to store +// Return conditions: +// %eax, %edi, %esi, %ecx, and %edx all trashed + + .align 5 + .private_extern _memset_pattern +_memset_pattern: + cmpl $(kShort),%edx // long enough to bother aligning? + ja LNotShort // yes + jmp LShort // no + +// Here for short operands or the end of long ones. +// %edx = length +// %edi = ptr (may not be not aligned) +// %xmm0 = pattern + +LUnalignedStore16: + movdqu %xmm0,(%edi) // stuff in another 16 bytes + subl $16,%edx + addl $16,%edi +LShort: + cmpl $16,%edx // room for another vector? + jge LUnalignedStore16 // yes +LLessThan16: // here at end of copy with < 16 bytes remaining + test $8,%dl // 8-byte store required? + jz 2f // no + movq %xmm0,(%edi) // pack in 8 low bytes + psrldq $8,%xmm0 // then shift vector down 8 bytes + addl $8,%edi +2: + test $4,%dl // 4-byte store required? + jz 3f // no + movd %xmm0,(%edi) // pack in 4 low bytes + psrldq $4,%xmm0 // then shift vector down 4 bytes + addl $4,%edi +3: + andl $3,%edx // more to go? + jz 5f // no + movd %xmm0,%eax // move remainders out into %eax +4: // loop on up to three bytes + movb %al,(%edi) // pack in next byte + shrl $8,%eax // shift next byte into position + inc %edi + dec %edx + jnz 4b +5: ret + +// Long enough to justify aligning ptr. Note that we have to rotate the +// pattern to account for any alignment. We do this by doing two unaligned +// stores, and then an aligned load from the middle of the two stores. +// This will stall on store forwarding alignment mismatch, and the unaligned +// stores can be pretty slow too, but the alternatives aren't any better. +// Fortunately, in most cases our caller has already aligned the ptr. +// %edx = length (> kShort) +// %edi = ptr (may not be aligned) +// %xmm0 = pattern + +LNotShort: + movl %edi,%ecx // copy dest ptr + negl %ecx + andl $15,%ecx // mask down to #bytes to 16-byte align + jz LAligned // skip if already aligned + movdqu %xmm0,(%edi) // store 16 unaligned bytes + movdqu %xmm0,16(%edi) // and 16 more, to be sure we have an aligned chunk + addl %ecx,%edi // now point to the aligned chunk + subl %ecx,%edx // adjust remaining count + movdqa (%edi),%xmm0 // get the rotated pattern (probably stalling) + addl $16,%edi // skip past the aligned chunk + subl $16,%edx + +// Set up for 64-byte loops. +// %edx = length remaining +// %edi = ptr (aligned) +// %xmm0 = rotated pattern + +LAligned: + movl %edx,%ecx // copy length remaining + andl $63,%edx // mask down to residual length (0..63) + andl $-64,%ecx // %ecx <- #bytes we will zero in by-64 loop + jz LNoMoreChunks // no 64-byte chunks + addl %ecx,%edi // increment ptr by length to move + cmpl $(kVeryLong),%ecx // long enough to justify non-temporal stores? + jge LVeryLong // yes + negl %ecx // negate length to move + jmp 1f + +// Loop over 64-byte chunks, storing into cache. + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movdqa %xmm0,(%edi,%ecx) + movdqa %xmm0,16(%edi,%ecx) + movdqa %xmm0,32(%edi,%ecx) + movdqa %xmm0,48(%edi,%ecx) + addl $64,%ecx + jne 1b + + jmp LNoMoreChunks + +// Very long operands: use non-temporal stores to bypass cache. + +LVeryLong: + negl %ecx // negate length to move + jmp 1f + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movntdq %xmm0,(%edi,%ecx) + movntdq %xmm0,16(%edi,%ecx) + movntdq %xmm0,32(%edi,%ecx) + movntdq %xmm0,48(%edi,%ecx) + addl $64,%ecx + jne 1b + + sfence // required by non-temporal stores + jmp LNoMoreChunks + +// Handle leftovers: loop by 16. +// %edx = length remaining (<64) +// %edi = ptr (aligned) +// %xmm0 = rotated pattern + +LLoopBy16: + movdqa %xmm0,(%edi) // pack in 16 more bytes + subl $16,%edx // decrement count + addl $16,%edi // increment ptr +LNoMoreChunks: + cmpl $16,%edx // more to go? + jge LLoopBy16 // yes + jmp LLessThan16 // handle up to 15 remaining bytes diff --git a/i386/string/strncpy.s b/i386/string/strncpy.s index ddc53b9..69edfd9 100644 --- a/i386/string/strncpy.s +++ b/i386/string/strncpy.s @@ -179,8 +179,7 @@ LFound0: LZeroBuffer: pushl %ecx // remaining buffer size pushl %edi // ptr to 1st unstored byte - movl $(_COMM_PAGE_BZERO),%eax - call *%eax + call _bzero addl $8,%esp // pop off the arguments LDone: diff --git a/i386/sys/Makefile.inc b/i386/sys/Makefile.inc index df13f6f..7a83351 100644 --- a/i386/sys/Makefile.inc +++ b/i386/sys/Makefile.inc @@ -3,9 +3,18 @@ AINC+= -I${.CURDIR}/i386/sys MDSRCS+= OSAtomic.s \ - i386_gettimeofday.s \ + atomic.c \ + i386_gettimeofday_asm.s \ + mach_absolute_time.c \ + mach_absolute_time_asm.s \ _setjmp.s \ setjmp.s \ - _sigtramp.s + _sigtramp.s \ + spinlocks_asm.s \ + spinlocks.s -MDCOPYFILES+= ${.CURDIR}/Platforms/${RC_TARGET_CONFIG}/i386/libc.syscall.i386 +DYLDSRCS += \ + OSAtomic.s \ + i386_gettimeofday_asm.s \ + mach_absolute_time_asm.s \ + spinlocks_asm.s diff --git a/i386/sys/OSAtomic.s b/i386/sys/OSAtomic.s index 3524074..49834ce 100644 --- a/i386/sys/OSAtomic.s +++ b/i386/sys/OSAtomic.s @@ -23,204 +23,283 @@ */ #include +#include -#define DECLARE(x) \ -.align 2, 0x90 ; \ -.globl x ; \ -.globl x ## Barrier ; \ -x: ; \ -x ## Barrier: - -.text - -DECLARE(_OSAtomicAnd32) - movl 8(%esp), %ecx - movl (%ecx), %eax -1: - movl 4(%esp), %edx - andl %eax, %edx - call *_COMM_PAGE_COMPARE_AND_SWAP32 - jnz 1b - movl %edx, %eax +#define ATOMIC_UP 0 +#define ATOMIC_MP 1 +#define ATOMIC_RET_ORIG 0 +#define ATOMIC_RET_NEW 1 + +// compare and exchange 32-bit +// xchg32 +.macro xchg32 + .if $2 == ATOMIC_MP + lock + .endif + cmpxchgl $0, ($1) +.endm + +// compare and exchange 64-bit +// xchg64 +.macro xchg64 + .if $1 == ATOMIC_MP + lock + .endif + cmpxchg8b ($0) +.endm + + +// int32_t OSAtomicAdd32(int32_t theAmount, volatile int32_t *theValue); +#define ATOMIC_ARITHMETIC(instr, orig, mp) \ + movl 8(%esp), %ecx /* load 2nd arg ptr into ecx */ ;\ + movl (%ecx), %eax /* load contents of ecx into eax */ ;\ +1: movl 4(%esp), %edx /* load 1st arg into edx */ ;\ + instr %eax, %edx /* do the operation */ ;\ + xchg32 %edx, %ecx, mp /* old in %eax, new in %edx, exchange into %ecx */ ;\ + jnz 1b /* go back if we failed to exchange */ ;\ + .if orig == ATOMIC_RET_NEW ;\ + movl %edx, %eax /* return new value */ ;\ + .endif + +// bool OSAtomicTestAndSet(uint32_t n, volatile void *theAddress); +#define ATOMIC_BIT_OP(instr, mp) \ + movl 4(%esp), %eax ;\ + movl 8(%esp), %edx ;\ + shldl $3,%edx,%ecx /* save top 3 bits of address in %ecx */ ;\ + shll $3,%edx ;\ + xorl $7,%eax /* bit position is numbered big endian so convert to little endian */ ;\ + addl %eax,%edx /* generate bit address */ ;\ + adcl $0,%ecx /* handle carry out of lower half of address */ ;\ + movl %edx,%eax /* copy lower half of bit address */ ;\ + andl $31,%eax /* keep bit offset in range 0..31 */ ;\ + xorl %eax,%edx /* 4-byte align address */ ;\ + shrdl $3,%ecx,%edx /* restore 32-bit byte address in %edx */ ;\ + .if mp == ATOMIC_MP ;\ + lock ;\ + .endif ;\ + instr %eax, (%edx) ;\ + setc %al ;\ + movzbl %al,%eax // widen in case caller assumes we return an int + +// int64_t OSAtomicAdd64(int64_t theAmount, volatile int64_t *theValue); +#define ATOMIC_ADD64(mp) \ + pushl %ebx ;\ + pushl %esi ;\ + movl 20(%esp), %esi ;\ + movl 0(%esi), %eax ;\ + movl 4(%esi), %edx ;\ +1: movl 12(%esp), %ebx ;\ + movl 16(%esp), %ecx ;\ + addl %eax, %ebx ;\ + adcl %edx, %ecx ;\ + xchg64 %esi, mp ;\ + jnz 1b ;\ + movl %ebx, %eax ;\ + movl %ecx, %edx ;\ + popl %esi ;\ + popl %ebx + + .text + +PLATFUNC_FUNCTION_START(OSAtomicAnd32, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicAnd32Barrier, up, 32, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_UP) + ret + +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Barrier, mp, 32, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_MP) + ret + +PLATFUNC_FUNCTION_START(OSAtomicOr32, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicOr32Barrier, up, 32, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_UP) + ret + +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Barrier, mp, 32, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_MP) ret -DECLARE(_OSAtomicOr32) - movl 8(%esp), %ecx - movl (%ecx), %eax -1: - movl 4(%esp), %edx - orl %eax, %edx - call *_COMM_PAGE_COMPARE_AND_SWAP32 - jnz 1b - movl %edx, %eax +PLATFUNC_FUNCTION_START(OSAtomicXor32, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicXor32Barrier, up, 32, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_UP) ret -DECLARE(_OSAtomicXor32) - movl 8(%esp), %ecx - movl (%ecx), %eax -1: - movl 4(%esp), %edx - xorl %eax, %edx - call *_COMM_PAGE_COMPARE_AND_SWAP32 - jnz 1b - movl %edx, %eax +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Barrier, mp, 32, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_MP) ret -DECLARE(_OSAtomicAnd32Orig) - movl 8(%esp), %ecx - movl (%ecx), %eax -1: - movl 4(%esp), %edx - andl %eax, %edx - call *_COMM_PAGE_COMPARE_AND_SWAP32 - jnz 1b +PLATFUNC_FUNCTION_START(OSAtomicAnd32Orig, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicAnd32OrigBarrier, up, 32, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_UP) ret -DECLARE(_OSAtomicOr32Orig) - movl 8(%esp), %ecx - movl (%ecx), %eax -1: - movl 4(%esp), %edx - orl %eax, %edx - call *_COMM_PAGE_COMPARE_AND_SWAP32 - jnz 1b +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Orig, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32OrigBarrier, mp, 32, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_MP) ret -DECLARE(_OSAtomicXor32Orig) - movl 8(%esp), %ecx - movl (%ecx), %eax -1: - movl 4(%esp), %edx - xorl %eax, %edx - call *_COMM_PAGE_COMPARE_AND_SWAP32 - jnz 1b +PLATFUNC_FUNCTION_START(OSAtomicOr32Orig, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicOr32OrigBarrier, up, 32, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_UP) ret -DECLARE(_OSAtomicCompareAndSwapPtr) -DECLARE(_OSAtomicCompareAndSwapInt) -DECLARE(_OSAtomicCompareAndSwapLong) -DECLARE(_OSAtomicCompareAndSwap32) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp), %ecx - call *_COMM_PAGE_COMPARE_AND_SWAP32 +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Orig, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32OrigBarrier, mp, 32, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_MP) + ret + +PLATFUNC_FUNCTION_START(OSAtomicXor32Orig, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicXor32OrigBarrier, up, 32, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_UP) + ret + +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Orig, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32OrigBarrier, mp, 32, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_MP) + ret + +// bool OSAtomicCompareAndSwapInt(int oldValue, int newValue, volatile int *theValue); +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtr, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtrBarrier, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapInt, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapIntBarrier, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLong, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLongBarrier, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32Barrier, up, 32, 2) + movl 4(%esp), %eax + movl 8(%esp), %edx + movl 12(%esp), %ecx + xchg32 %edx, %ecx, ATOMIC_UP sete %al movzbl %al,%eax // widen in case caller assumes we return an int ret -DECLARE(_OSAtomicCompareAndSwap64) - pushl %ebx +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtr, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtrBarrier, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapInt, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapIntBarrier, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLong, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLongBarrier, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32Barrier, mp, 32, 2) + movl 4(%esp), %eax + movl 8(%esp), %edx + movl 12(%esp), %ecx + xchg32 %edx, %ecx, ATOMIC_MP + sete %al + movzbl %al,%eax // widen in case caller assumes we return an int + ret + +// bool OSAtomicCompareAndSwap64(int64_t oldValue, int64_t newValue, volatile int64_t *theValue); +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64Barrier, up, 32, 2) + pushl %ebx // push out spare stuff for space pushl %esi - movl 12(%esp), %eax + movl 12(%esp), %eax // load in 1st 64-bit parameter movl 16(%esp), %edx - movl 20(%esp), %ebx + movl 20(%esp), %ebx // load in 2nd 64-bit parameter movl 24(%esp), %ecx - movl 28(%esp), %esi - call *_COMM_PAGE_COMPARE_AND_SWAP64 + movl 28(%esp), %esi // laod in destination address + xchg64 %esi, ATOMIC_UP // compare and swap 64-bit sete %al movzbl %al,%eax // widen in case caller assumes we return an int popl %esi popl %ebx ret -DECLARE(_OSAtomicAdd32) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl %eax, %ecx - call *_COMM_PAGE_ATOMIC_ADD32 - addl %ecx, %eax - ret - -DECLARE(_OSAtomicAdd64) - pushl %ebx +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64Barrier, mp, 32, 2) + pushl %ebx // push out spare stuff for space pushl %esi - movl 20(%esp), %esi - movl 0(%esi), %eax - movl 4(%esi), %edx -1: movl 12(%esp), %ebx - movl 16(%esp), %ecx - addl %eax, %ebx - adcl %edx, %ecx - call *_COMM_PAGE_COMPARE_AND_SWAP64 - jnz 1b - movl %ebx, %eax - movl %ecx, %edx + movl 12(%esp), %eax // load in 1st 64-bit parameter + movl 16(%esp), %edx + movl 20(%esp), %ebx // load in 2nd 64-bit parameter + movl 24(%esp), %ecx + movl 28(%esp), %esi // laod in destination address + xchg64 %esi, ATOMIC_MP // compare and swap 64-bit + sete %al + movzbl %al,%eax // widen in case caller assumes we return an int popl %esi - popl %ebx + popl %ebx ret -DECLARE(_OSAtomicTestAndSet) +PLATFUNC_FUNCTION_START(OSAtomicAdd32, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicAdd32Barrier, up, 32, 2) movl 4(%esp), %eax movl 8(%esp), %edx movl %eax, %ecx - andl $-8, %ecx - notl %eax - andl $7, %eax - orl %ecx, %eax - call *_COMM_PAGE_BTS - setc %al - movzbl %al,%eax // widen in case caller assumes we return an int + xaddl %eax, (%edx) + addl %ecx, %eax ret -DECLARE(_OSAtomicTestAndClear) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32Barrier, mp, 32, 2) movl 4(%esp), %eax movl 8(%esp), %edx movl %eax, %ecx - andl $-8, %ecx - notl %eax - andl $7, %eax - orl %ecx, %eax - call *_COMM_PAGE_BTC - setc %al - movzbl %al,%eax // widen in case caller assumes we return an int + lock + xaddl %eax, (%edx) + addl %ecx, %eax ret - .align 2, 0x90 - .globl _OSSpinLockTry - .globl __spin_lock_try -_OSSpinLockTry: -__spin_lock_try: - movl $(_COMM_PAGE_SPINLOCK_TRY), %eax - jmpl *%eax - - .align 2, 0x90 - .globl _OSSpinLockLock - .globl _spin_lock - .globl __spin_lock -_OSSpinLockLock: -_spin_lock: -__spin_lock: - movl $(_COMM_PAGE_SPINLOCK_LOCK), %eax - jmpl *%eax - - .align 2, 0x90 - .globl _OSSpinLockUnlock - .globl _spin_unlock - .globl __spin_unlock -_OSSpinLockUnlock: -_spin_unlock: -__spin_unlock: - movl 4(%esp), %eax - movl $0, (%eax) +PLATFUNC_FUNCTION_START(OSAtomicAdd64, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicAdd64Barrier, up, 32, 2) + ATOMIC_ADD64(ATOMIC_UP) ret - .align 2, 0x90 - .globl _OSMemoryBarrier -_OSMemoryBarrier: - movl $(_COMM_PAGE_MEMORY_BARRIER), %eax - jmpl *%eax +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64Barrier, mp, 32, 2) + ATOMIC_ADD64(ATOMIC_MP) + ret -/* - * typedef volatile struct { - * void *opaque1; <-- ptr to 1st queue element or null - * long opaque2; <-- generation count - * } OSQueueHead; - * - * void OSAtomicEnqueue( OSQueueHead *list, void *new, size_t offset); - */ - .align 2 - .globl _OSAtomicEnqueue -_OSAtomicEnqueue: +PLATFUNC_FUNCTION_START(OSAtomicTestAndSet, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicTestAndSetBarrier, up, 32, 2) + ATOMIC_BIT_OP(btsl, ATOMIC_UP) + ret + +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSet, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSetBarrier, mp, 32, 2) + ATOMIC_BIT_OP(btsl, ATOMIC_MP) + ret + +PLATFUNC_FUNCTION_START(OSAtomicTestAndClear, up, 32, 2) +PLATFUNC_FUNCTION_START(OSAtomicTestAndClearBarrier, up, 32, 2) + ATOMIC_BIT_OP(btrl, ATOMIC_UP) + ret + +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClear, mp, 32, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClearBarrier, mp, 32, 2) + ATOMIC_BIT_OP(btrl, ATOMIC_MP) + ret + +// OSMemoryBarrier() +// These are used both in 32 and 64-bit mode. We use a fence even on UP +// machines, so this function can be used with nontemporal stores. + +PLATFUNC_FUNCTION_START_GENERIC(OSMemoryBarrier, all, 32, 4) + lock + addl $0,(%esp) + ret +PLATFUNC_DESCRIPTOR(OSMemoryBarrier,all,0,kHasSSE2); + +PLATFUNC_FUNCTION_START(OSMemoryBarrier, sse2, 32, 4) + mfence + ret +PLATFUNC_DESCRIPTOR(OSMemoryBarrier,sse2,kHasSSE2,0); + + /* + * typedef volatile struct { + * void *opaque1; <-- ptr to 1st queue element or null + * long opaque2; <-- generation count + * } OSQueueHead; + * + * void OSAtomicEnqueue( OSQueueHead *list, void *new, size_t offset); + */ +PLATFUNC_FUNCTION_START(OSAtomicEnqueue, up, 32, 2) pushl %edi pushl %esi pushl %ebx @@ -229,23 +308,37 @@ _OSAtomicEnqueue: movl 24(%esp),%esi // %esi == offset movl (%edi),%eax // %eax == ptr to 1st element in Q movl 4(%edi),%edx // %edx == current generation count -1: - movl %eax,(%ebx,%esi)// link to old list head from new element +1: movl %eax,(%ebx,%esi)// link to old list head from new element movl %edx,%ecx incl %ecx // increment generation count - lock // always lock for now... - cmpxchg8b (%edi) // ...push on new element + xchg64 %edi, ATOMIC_UP // ...push on new element jnz 1b popl %ebx popl %esi popl %edi ret - - + +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicEnqueue, mp, 32, 2) + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%edi // %edi == ptr to list head + movl 20(%esp),%ebx // %ebx == new + movl 24(%esp),%esi // %esi == offset + movl (%edi),%eax // %eax == ptr to 1st element in Q + movl 4(%edi),%edx // %edx == current generation count +1: movl %eax,(%ebx,%esi)// link to old list head from new element + movl %edx,%ecx + incl %ecx // increment generation count + xchg64 %edi, ATOMIC_MP // ...push on new element + jnz 1b + popl %ebx + popl %esi + popl %edi + ret + /* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */ - .align 2 - .globl _OSAtomicDequeue -_OSAtomicDequeue: +PLATFUNC_FUNCTION_START(OSAtomicDequeue, up, 32, 2) pushl %edi pushl %esi pushl %ebx @@ -253,18 +346,89 @@ _OSAtomicDequeue: movl 20(%esp),%esi // %esi == offset movl (%edi),%eax // %eax == ptr to 1st element in Q movl 4(%edi),%edx // %edx == current generation count -1: - testl %eax,%eax // list empty? +1: testl %eax,%eax // list empty? jz 2f // yes movl (%eax,%esi),%ebx // point to 2nd in Q movl %edx,%ecx incl %ecx // increment generation count - lock // always lock for now... - cmpxchg8b (%edi) // ...pop off 1st element + xchg64 %edi, ATOMIC_UP // ...pop off 1st element jnz 1b -2: - popl %ebx +2: popl %ebx + popl %esi + popl %edi + ret // ptr to 1st element in Q still in %eax + +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicDequeue, mp, 32, 2) + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%edi // %edi == ptr to list head + movl 20(%esp),%esi // %esi == offset + movl (%edi),%eax // %eax == ptr to 1st element in Q + movl 4(%edi),%edx // %edx == current generation count +1: testl %eax,%eax // list empty? + jz 2f // yes + movl (%eax,%esi),%ebx // point to 2nd in Q + movl %edx,%ecx + incl %ecx // increment generation count + xchg64 %edi, ATOMIC_MP // ...pop off 1st element + jnz 1b +2: popl %ebx + popl %esi + popl %edi + ret // ptr to 1st element in Q still in %eax + +/* + * typedef volatile struct { + * void *opaque1; <-- ptr to first queue element or null + * void *opaque2; <-- ptr to last queue element or null + * int opaque3; <-- spinlock + * } OSFifoQueueHead; + * + * void OSAtomicFifoEnqueue( OSFifoQueueHead *list, void *new, size_t offset); + */ + .align 2 + .globl _OSAtomicFifoEnqueue +_OSAtomicFifoEnqueue: + pushl %edi + pushl %esi + pushl %ebx + xorl %ebx,%ebx // clear "preemption pending" flag + movl 16(%esp),%edi // %edi == ptr to list head + movl 20(%esp),%esi // %esi == new + movl 24(%esp),%edx // %edx == offset + movl $(_COMM_PAGE_PFZ_ENQUEUE), %ecx + call *%ecx + testl %ebx,%ebx // pending preemption? + jz 1f + call _preempt +1: popl %ebx + popl %esi + popl %edi + ret + +/* void* OSAtomicFifoDequeue( OSFifoQueueHead *list, size_t offset); */ + .align 2 + .globl _OSAtomicFifoDequeue +_OSAtomicFifoDequeue: + pushl %edi + pushl %esi + pushl %ebx + xorl %ebx,%ebx // clear "preemption pending" flag + movl 16(%esp),%edi // %edi == ptr to list head + movl 20(%esp),%edx // %edx == offset + movl $(_COMM_PAGE_PFZ_DEQUEUE), %ecx + call *%ecx + testl %ebx,%ebx // pending preemption? + jz 1f + pushl %eax // save return value across sysenter + call _preempt + popl %eax +1: popl %ebx popl %esi popl %edi ret // ptr to 1st element in Q still in %eax +// Local Variables: +// tab-width: 8 +// End: diff --git a/i386/sys/_setjmp.s b/i386/sys/_setjmp.s index 0390560..5828337 100644 --- a/i386/sys/_setjmp.s +++ b/i386/sys/_setjmp.s @@ -63,8 +63,6 @@ #define JB_FS 64 #define JB_GS 68 -#define SAVE_SEG_REGS 1 - LEAF(__setjmp, 0) movl 4(%esp), %ecx // jmp_buf (struct sigcontext *) @@ -80,38 +78,21 @@ LEAF(__setjmp, 0) movl (%esp), %eax movl %eax, JB_EIP(%ecx) // ESP is set to the frame return address plus 4 - movl %esp, %eax - addl $4, %eax + leal 4(%esp), %eax movl %eax, JB_ESP(%ecx) -#if SAVE_SEG_REGS - // segment registers - mov %ss, JB_SS(%ecx) - mov %cs, JB_CS(%ecx) - mov %ds, JB_DS(%ecx) - mov %es, JB_ES(%ecx) - mov %fs, JB_FS(%ecx) - mov %gs, JB_GS(%ecx) -#endif - - // save eflags - you can't use movl - pushf - popl %eax - movl %eax, JB_EFLAGS(%ecx) - // return 0 xorl %eax, %eax ret LEAF(__longjmp, 0) - fninit // reset FP coprocessor - + fninit // Clear all FP exceptions movl 4(%esp), %ecx // jmp_buf (struct sigcontext *) movl 8(%esp), %eax // return value testl %eax, %eax jnz 1f - incl %eax + incl %eax // general registers 1: movl JB_EBX(%ecx), %ebx @@ -119,21 +100,9 @@ LEAF(__longjmp, 0) movl JB_EDI(%ecx), %edi movl JB_EBP(%ecx), %ebp movl JB_ESP(%ecx), %esp + fldcw JB_FPCW(%ecx) // Restore FP control word ldmxcsr JB_MXCSR(%ecx) // Restore the MXCSR -#if SAVE_SEG_REGS - // segment registers - mov JB_SS(%ecx), %ss - // mov JB_CS(%ecx), %cs // can't set cs? - mov JB_DS(%ecx), %ds - mov JB_ES(%ecx), %es - mov JB_FS(%ecx), %fs - mov JB_GS(%ecx), %gs -#endif - - // eflags - pushl JB_EFLAGS(%ecx) - popf - + cld // Make sure DF is reset jmp *JB_EIP(%ecx) diff --git a/i386/sys/_sigtramp.s b/i386/sys/_sigtramp.s index a8d2613..5143286 100644 --- a/i386/sys/_sigtramp.s +++ b/i386/sys/_sigtramp.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007, 2011 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -68,6 +68,7 @@ _sigtramp( .text .align 4,0x90 __sigtramp: +Lstart: /* Although this routine does not need any stack frame, various parts of the OS can't analyse the stack without them. */ pushl %ebp @@ -91,9 +92,7 @@ __sigtramp: movl %esi, 8(%esp) movl %eax, 4(%esp) movl %edx, (%esp) -Lcall_start: call *%ecx -Lcall_end: #if defined(__DYNAMIC__) decl ___in_sigtramp-"L00000000001$pb"(%ebx) #endif @@ -101,6 +100,7 @@ Lcall_end: movl $ UC_FLAVOR, 8(%esp) movl $ SYS_sigreturn, %eax int $0x80 +Lend: /* DWARF unwind table #defines. */ #define DW_CFA_advance_loc_4 0x44 @@ -160,8 +160,8 @@ EH_frame1: .long L$set$0 # Length of Common Information Entry LSCIE1: .long 0 # CIE Identifier Tag - .byte 0x3 # CIE Version - .ascii "zR\0" # CIE Augmentation + .byte 0x1 # CIE Version + .ascii "zRS\0" # CIE Augmentation .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor .byte 0x7c # sleb128 -4; CIE Data Alignment Factor .byte 0x8 # CIE RA Column @@ -172,6 +172,8 @@ LSCIE1: .byte 0x4 # uleb128 0x4 .byte DW_CFA_offset(8) .byte 0x1 # uleb128 0x1 + .byte DW_CFA_offset(8) // double DW_CFA_offset (eip, -4) tells linker to not make compact unwind + .byte 0x1 # uleb128 0x1 .align 2 LECIE1: .globl _sigtramp.eh @@ -181,8 +183,8 @@ LSFDE1: .long L$set$1 # FDE Length LASFDE1: .long LASFDE1-EH_frame1 # FDE CIE offset - .long Lcall_start-. # FDE initial location - .set L$set$2,Lcall_end-Lcall_start + .long Lstart-. # FDE initial location + .set L$set$2,Lend-Lstart .long L$set$2 # FDE address range .byte 0x0 # uleb128 0x0; Augmentation size diff --git a/i386/sys/atomic.c b/i386/sys/atomic.c new file mode 100644 index 0000000..8ff5ff0 --- /dev/null +++ b/i386/sys/atomic.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +#define RESOLVER_UP_MP(symbol) \ + PLATFUNC_DESCRIPTOR(symbol, up, kUP, 0); \ + PLATFUNC_DESCRIPTOR(symbol, mp, 0, kUP); \ + static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \ + PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \ + PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \ + 0 \ + }; \ + void* symbol ## _chooser() __asm__("_" #symbol); \ + void* symbol ## _chooser() { \ + __asm__(".symbol_resolver _" #symbol); \ + return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \ + } + +RESOLVER_UP_MP(OSAtomicAnd32) +RESOLVER_UP_MP(OSAtomicAnd32Barrier) +RESOLVER_UP_MP(OSAtomicOr32) +RESOLVER_UP_MP(OSAtomicOr32Barrier) +RESOLVER_UP_MP(OSAtomicXor32) +RESOLVER_UP_MP(OSAtomicXor32Barrier) +RESOLVER_UP_MP(OSAtomicAnd32Orig) +RESOLVER_UP_MP(OSAtomicAnd32OrigBarrier) +RESOLVER_UP_MP(OSAtomicOr32Orig) +RESOLVER_UP_MP(OSAtomicOr32OrigBarrier) +RESOLVER_UP_MP(OSAtomicXor32Orig) +RESOLVER_UP_MP(OSAtomicXor32OrigBarrier) +RESOLVER_UP_MP(OSAtomicCompareAndSwapPtr) +RESOLVER_UP_MP(OSAtomicCompareAndSwapPtrBarrier) +RESOLVER_UP_MP(OSAtomicCompareAndSwapInt) +RESOLVER_UP_MP(OSAtomicCompareAndSwapIntBarrier) +RESOLVER_UP_MP(OSAtomicCompareAndSwapLong) +RESOLVER_UP_MP(OSAtomicCompareAndSwapLongBarrier) +RESOLVER_UP_MP(OSAtomicCompareAndSwap32) +RESOLVER_UP_MP(OSAtomicCompareAndSwap32Barrier) +RESOLVER_UP_MP(OSAtomicCompareAndSwap64) +RESOLVER_UP_MP(OSAtomicCompareAndSwap64Barrier) +RESOLVER_UP_MP(OSAtomicAdd32) +RESOLVER_UP_MP(OSAtomicAdd32Barrier) +RESOLVER_UP_MP(OSAtomicAdd64) +RESOLVER_UP_MP(OSAtomicAdd64Barrier) +RESOLVER_UP_MP(OSAtomicTestAndSet) +RESOLVER_UP_MP(OSAtomicTestAndSetBarrier) +RESOLVER_UP_MP(OSAtomicTestAndClear) +RESOLVER_UP_MP(OSAtomicTestAndClearBarrier) +RESOLVER_UP_MP(OSAtomicEnqueue) +RESOLVER_UP_MP(OSAtomicDequeue) + +PLATFUNC_DESCRIPTOR_PROTOTYPE(OSMemoryBarrier, all) +PLATFUNC_DESCRIPTOR_PROTOTYPE(OSMemoryBarrier, sse2) + +static const platfunc_descriptor *OSMemoryBarrier_platfunc_descriptors[] = { + PLATFUNC_DESCRIPTOR_REFERENCE(OSMemoryBarrier, sse2), + PLATFUNC_DESCRIPTOR_REFERENCE(OSMemoryBarrier, all), + 0 +}; + +void *OSMemoryBarrier_chooser() __asm__("_OSMemoryBarrier"); +void *OSMemoryBarrier_chooser() { + __asm__(".symbol_resolver _OSMemoryBarrier"); + return find_platform_function((const platfunc_descriptor **) OSMemoryBarrier_platfunc_descriptors); +} diff --git a/i386/sys/i386_gettimeofday_asm.s b/i386/sys/i386_gettimeofday_asm.s new file mode 100644 index 0000000..c798528 --- /dev/null +++ b/i386/sys/i386_gettimeofday_asm.s @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2003-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include +#include + +#define NSEC_PER_SEC 1000*1000*1000 +#define NSEC_PER_USEC 1000 + + .align 4 + .private_extern ___commpage_gettimeofday +___commpage_gettimeofday: + push %ebp + mov %esp,%ebp + push %esi + push %ebx + +0: + movl _COMM_PAGE_GTOD_GENERATION,%esi /* get generation (0 if disabled) */ + testl %esi,%esi /* disabled? */ + jz 4f + + call _mach_absolute_time_direct + + sub _COMM_PAGE_GTOD_NS_BASE,%eax + sbb _COMM_PAGE_GTOD_NS_BASE+4,%edx + mov _COMM_PAGE_GTOD_SEC_BASE,%ebx /* load all the data before checking generation */ + mov $ NSEC_PER_SEC,%ecx + + cmpl _COMM_PAGE_GTOD_GENERATION,%esi /* has time data changed out from under us? */ + jne 0b + + div %ecx + add %eax,%ebx + + mov $ NSEC_PER_USEC,%ecx + mov %edx,%eax + xor %edx,%edx + div %ecx + + mov 8(%ebp),%ecx + mov %ebx,(%ecx) + mov %eax,4(%ecx) + xor %eax,%eax + +3: + pop %ebx + pop %esi + pop %ebp + ret +4: /* fail */ + movl $1,%eax + jmp 3b diff --git a/i386/sys/mach_absolute_time.c b/i386/sys/mach_absolute_time.c new file mode 100644 index 0000000..d78ebf9 --- /dev/null +++ b/i386/sys/mach_absolute_time.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +PLATFUNC_DESCRIPTOR_PROTOTYPE(mach_absolute_time,fast) +PLATFUNC_DESCRIPTOR_PROTOTYPE(mach_absolute_time,slow) + +static const platfunc_descriptor *mach_absolute_time_platfunc_descriptors[] = { + PLATFUNC_DESCRIPTOR_REFERENCE(mach_absolute_time,fast), + PLATFUNC_DESCRIPTOR_REFERENCE(mach_absolute_time,slow), + 0 +}; + +void *mach_absolute_time_chooser() __asm__("_mach_absolute_time"); +void *mach_absolute_time_chooser() { + __asm__(".desc _mach_absolute_time, 0x100"); + return find_platform_function((const platfunc_descriptor **) mach_absolute_time_platfunc_descriptors); +} diff --git a/i386/sys/mach_absolute_time_asm.s b/i386/sys/mach_absolute_time_asm.s new file mode 100644 index 0000000..4d3bc25 --- /dev/null +++ b/i386/sys/mach_absolute_time_asm.s @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2003-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include +#include + +#if defined(VARIANT_DYLD) +/* For dyld, we need to decide upon call whether to jump to fast or slow */ + .globl _mach_absolute_time + .align 2, 0x90 +_mach_absolute_time: + movl _COMM_PAGE_CPU_CAPABILITIES, %eax + andl $(kSlow), %eax + jnz PLATFUNC_VARIANT_NAME(mach_absolute_time, slow) + jmp PLATFUNC_VARIANT_NAME(mach_absolute_time, fast) +#endif + +/* return mach_absolute_time in %edx:%eax */ + +PLATFUNC_FUNCTION_START(mach_absolute_time, fast, 32, 4) + .private_extern _mach_absolute_time_direct +_mach_absolute_time_direct: + pushl %ebp + movl %esp,%ebp + pushl %esi + pushl %ebx + +0: + movl _COMM_PAGE_NT_GENERATION,%esi /* get generation (0 if being changed) */ + testl %esi,%esi /* if being updated, loop until stable */ + jz 0b + + lfence + rdtsc /* get TSC in %edx:%eax */ + lfence + + subl _COMM_PAGE_NT_TSC_BASE,%eax + sbbl _COMM_PAGE_NT_TSC_BASE+4,%edx + + movl _COMM_PAGE_NT_SCALE,%ecx + + movl %edx,%ebx + mull %ecx + movl %ebx,%eax + movl %edx,%ebx + mull %ecx + addl %ebx,%eax + adcl $0,%edx + + addl _COMM_PAGE_NT_NS_BASE,%eax + adcl _COMM_PAGE_NT_NS_BASE+4,%edx + + cmpl _COMM_PAGE_NT_GENERATION,%esi /* have the parameters changed? */ + jne 0b /* yes, loop until stable */ + + popl %ebx + popl %esi + popl %ebp + ret +PLATFUNC_DESCRIPTOR(mach_absolute_time,fast,0,kSlow) + + +/* mach_absolute_time routine for machines slower than ~1Gz (SLOW_TSC_THRESHOLD) */ +PLATFUNC_FUNCTION_START(mach_absolute_time, slow, 32, 4) + push %ebp + mov %esp,%ebp + push %esi + push %edi + push %ebx + +0: + movl _COMM_PAGE_NT_GENERATION,%esi + testl %esi,%esi /* if generation is 0, data being changed */ + jz 0b /* so loop until stable */ + + lfence + rdtsc /* get TSC in %edx:%eax */ + lfence + subl _COMM_PAGE_NT_TSC_BASE,%eax + sbbl _COMM_PAGE_NT_TSC_BASE+4,%edx + + pushl %esi /* save generation */ + /* + * Do the math to convert tsc ticks to nanoseconds. We first + * do long multiply of 1 billion times the tsc. Then we do + * long division by the tsc frequency + */ + mov $1000000000, %ecx /* number of nanoseconds in a second */ + mov %edx, %ebx + mul %ecx + mov %edx, %edi + mov %eax, %esi + mov %ebx, %eax + mul %ecx + add %edi, %eax + adc $0, %edx /* result in edx:eax:esi */ + mov %eax, %edi + mov _COMM_PAGE_NT_SHIFT,%ecx /* overloaded as the low 32 tscFreq */ + xor %eax, %eax + xchg %edx, %eax + div %ecx + xor %eax, %eax + mov %edi, %eax + div %ecx + mov %eax, %ebx + mov %esi, %eax + div %ecx + mov %ebx, %edx /* result in edx:eax */ + popl %esi /* recover generation */ + + add _COMM_PAGE_NT_NS_BASE,%eax + adc _COMM_PAGE_NT_NS_BASE+4,%edx + + cmpl _COMM_PAGE_NT_GENERATION,%esi /* have the parameters changed? */ + jne 0b /* yes, loop until stable */ + + pop %ebx + pop %edi + pop %esi + pop %ebp + ret /* result in edx:eax */ +PLATFUNC_DESCRIPTOR(mach_absolute_time,slow,kSlow,0) diff --git a/i386/sys/spinlocks.c b/i386/sys/spinlocks.c new file mode 100644 index 0000000..8bc85a8 --- /dev/null +++ b/i386/sys/spinlocks.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +#define RESOLVER_UP_MP(symbol) \ + PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, up); \ + PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, mp); \ + static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \ + PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \ + PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \ + 0 \ + }; \ + void* symbol ## _chooser() __asm__("_" #symbol); \ + void* symbol ## _chooser() { \ + __asm__(".symbol_resolver _" #symbol); \ + return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \ + } + +RESOLVER_UP_MP(OSSpinLockTry) +RESOLVER_UP_MP(_spin_lock_try) +RESOLVER_UP_MP(OSSpinLockLock) +RESOLVER_UP_MP(_spin_lock) +RESOLVER_UP_MP(spin_lock) diff --git a/i386/sys/spinlocks_asm.s b/i386/sys/spinlocks_asm.s new file mode 100644 index 0000000..0c0eb18 --- /dev/null +++ b/i386/sys/spinlocks_asm.s @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2003-2009 Apple, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include + + +PLATFUNC_FUNCTION_START(OSSpinLockTry, up, 32, 4) +PLATFUNC_FUNCTION_START(_spin_lock_try, up, 32, 4) + movl 4(%esp), %ecx + xorl %eax, %eax + orl $-1, %edx + cmpxchgl %edx, (%ecx) + setz %dl + movzbl %dl, %eax + ret +PLATFUNC_DESCRIPTOR(OSSpinLockTry,up,kUP,0) +PLATFUNC_DESCRIPTOR(_spin_lock_try,up,kUP,0) + +PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockTry, mp, 32, 4) +PLATFUNC_FUNCTION_START_GENERIC(_spin_lock_try, mp, 32, 4) + movl 4(%esp), %ecx + xorl %eax, %eax + orl $-1, %edx + lock + cmpxchgl %edx, (%ecx) + setz %dl + movzbl %dl, %eax + ret +PLATFUNC_DESCRIPTOR(OSSpinLockTry,mp,0,kUP) +PLATFUNC_DESCRIPTOR(_spin_lock_try,mp,0,kUP) + + +PLATFUNC_FUNCTION_START(spin_lock, up, 32, 4) +PLATFUNC_FUNCTION_START(OSSpinLockLock, up, 32, 4) +PLATFUNC_FUNCTION_START(_spin_lock, up, 32, 4) +Lspin_lock_up: + movl 4(%esp), %ecx + xorl %eax, %eax + orl $-1, %edx + cmpxchgl %edx, (%ecx) + jnz 1f + ret +1: + /* failed to get lock so relinquish the processor immediately on UP */ + pushl $1 /* 1 ms */ + pushl $1 /* SWITCH_OPTION_DEPRESS */ + pushl $0 /* THREAD_NULL */ + pushl $0 /* push dummy stack ret addr */ + movl $-61,%eax /* SYSCALL_THREAD_SWITCH */ + int $(MACH_INT) + addl $16, %esp /* adjust stack*/ + jmp Lspin_lock_up +PLATFUNC_DESCRIPTOR(spin_lock,up,kUP,0) +PLATFUNC_DESCRIPTOR(OSSpinLockLock,up,kUP,0) +PLATFUNC_DESCRIPTOR(_spin_lock,up,kUP,0) + +PLATFUNC_FUNCTION_START_GENERIC(spin_lock, mp, 32, 4) +PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockLock, mp, 32, 4) +PLATFUNC_FUNCTION_START_GENERIC(_spin_lock, mp, 32, 4) +Lspin_lock_mp: + movl 4(%esp), %ecx + xorl %eax, %eax +0: + orl $-1, %edx + lock + cmpxchgl %edx, (%ecx) + jnz 1f + ret +1: + xorl %eax, %eax + movl $(MP_SPIN_TRIES), %edx +2: + pause + cmpl %eax, (%ecx) + jz 0b /* favor success and slow down spin loop */ + decl %edx + jnz 2b + /* failed to get lock after spinning so relinquish */ + pushl $1 /* 1 ms */ + pushl $1 /* SWITCH_OPTION_DEPRESS */ + pushl $0 /* THREAD_NULL */ + pushl $0 /* push dummy stack ret addr */ + movl $-61,%eax /* SYSCALL_THREAD_SWITCH */ + int $(MACH_INT) + addl $16, %esp /* adjust stack*/ + jmp Lspin_lock_mp +PLATFUNC_DESCRIPTOR(spin_lock,mp,0,kUP) +PLATFUNC_DESCRIPTOR(OSSpinLockLock,mp,0,kUP) +PLATFUNC_DESCRIPTOR(_spin_lock,mp,0,kUP) + + .align 2, 0x90 + .globl _OSSpinLockUnlock + .globl _spin_unlock + .globl __spin_unlock +_OSSpinLockUnlock: +_spin_unlock: +__spin_unlock: + movl 4(%esp), %eax + movl $0, (%eax) + ret + diff --git a/sys/sigsuspend.c b/include/CrashReporterClient.h similarity index 57% rename from sys/sigsuspend.c rename to include/CrashReporterClient.h index fcaab4c..68593ae 100644 --- a/sys/sigsuspend.c +++ b/include/CrashReporterClient.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,30 +20,25 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* @(#)sigsuspend.c 1.0 9/22/95 (c) 1995 NeXT */ - -#include -#include - -#ifdef VARIANT_CANCELABLE -int __sigsuspend (const sigset_t); -#else /* !VARIANT_CANCELABLE */ -int __sigsuspend_nocancel(const sigset_t); -#endif /* VARIANT_CANCELABLE */ - -int -sigsuspend (const sigset_t *sigmask_p) -{ - sigset_t mask; - - if (sigmask_p) - mask = *sigmask_p; - else - sigemptyset(&mask); -#ifdef VARIANT_CANCELABLE - return __sigsuspend(mask); -#else /* !VARIANT_CANCELABLE */ - return __sigsuspend_nocancel(mask); -#endif /* VARIANT_CANCELABLE */ -} +/*********************************************************************** + * Not to be installed in /usr/local/include + ***********************************************************************/ + +#ifndef _LIBC_CRASHREPORTERCLIENT_H +#define _LIBC_CRASHREPORTERCLIENT_H + +#ifdef LIBC_NO_LIBCRASHREPORTERCLIENT + +/* Fake the CrashReporterClient API */ +#define CRGetCrashLogMessage() 0 +#define CRSetCrashLogMessage(x) /* nothing */ + +#else /* !LIBC_NO_LIBCRASHREPORTERCLIENT */ + +/* Include the real CrashReporterClient.h */ +#include_next + +#endif /* !LIBC_NO_LIBCRASHREPORTERCLIENT */ + +#endif /* _LIBC_CRASHREPORTERCLIENT_H */ diff --git a/include/FreeBSD/nl_types.h b/include/FreeBSD/nl_types.h new file mode 100644 index 0000000..100d570 --- /dev/null +++ b/include/FreeBSD/nl_types.h @@ -0,0 +1,105 @@ +/* $NetBSD: nl_types.h,v 1.9 2000/10/03 19:53:32 sommerfeld Exp $ */ + +/*- + * Copyright (c) 1996 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by J.T. Conklin. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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: src/include/nl_types.h,v 1.11 2005/02/27 16:20:53 phantom Exp $ + */ + +#ifndef _NL_TYPES_H_ +#define _NL_TYPES_H_ + +#include +#include + +#ifdef _NLS_PRIVATE +/* + * MESSAGE CATALOG FILE FORMAT. + * + * The NetBSD/FreeBSD message catalog format is similar to the format used by + * Svr4 systems. The differences are: + * * fixed byte order (big endian) + * * fixed data field sizes + * + * A message catalog contains four data types: a catalog header, one + * or more set headers, one or more message headers, and one or more + * text strings. + */ + +#define _NLS_MAGIC 0xff88ff89 + +struct _nls_cat_hdr { + int32_t __magic; + int32_t __nsets; + int32_t __mem; + int32_t __msg_hdr_offset; + int32_t __msg_txt_offset; +} ; + +struct _nls_set_hdr { + int32_t __setno; /* set number: 0 < x <= NL_SETMAX */ + int32_t __nmsgs; /* number of messages in the set */ + int32_t __index; /* index of first msg_hdr in msg_hdr table */ +} ; + +struct _nls_msg_hdr { + int32_t __msgno; /* msg number: 0 < x <= NL_MSGMAX */ + int32_t __msglen; + int32_t __offset; +} ; + +#endif /* _NLS_PRIVATE */ + +#define NL_SETD 0 +#define NL_CAT_LOCALE 1 + +typedef struct __nl_cat_d { + void *__data; + int __size; +} *nl_catd; + +#ifndef _NL_ITEM_DECLARED +typedef __nl_item nl_item; +#define _NL_ITEM_DECLARED +#endif + +__BEGIN_DECLS +nl_catd catopen(const char *, int); +char *catgets(nl_catd, int, int, const char *) + __attribute__((__format_arg__(4))); +int catclose(nl_catd); +__END_DECLS + +#endif /* _NL_TYPES_H_ */ diff --git a/include/FreeBSD/nl_types.h.patch b/include/FreeBSD/nl_types.h.patch new file mode 100644 index 0000000..c411b64 --- /dev/null +++ b/include/FreeBSD/nl_types.h.patch @@ -0,0 +1,32 @@ +--- nl_types.h.orig 2010-10-29 00:51:39.000000000 -0700 ++++ nl_types.h 2010-10-29 00:53:25.000000000 -0700 +@@ -43,6 +43,7 @@ + + #include + #include ++#include <_types.h> + + #ifdef _NLS_PRIVATE + /* +@@ -82,7 +83,7 @@ + + #endif /* _NLS_PRIVATE */ + +-#define NL_SETD 0 ++#define NL_SETD 1 + #define NL_CAT_LOCALE 1 + + typedef struct __nl_cat_d { +@@ -90,9 +91,9 @@ + int __size; + } *nl_catd; + +-#ifndef _NL_ITEM_DECLARED +-typedef __nl_item nl_item; +-#define _NL_ITEM_DECLARED ++#ifndef _NL_ITEM ++typedef __darwin_nl_item nl_item; ++#define _NL_ITEM + #endif + + __BEGIN_DECLS diff --git a/include/Makefile.inc b/include/Makefile.inc index bf3db86..83d8b47 100644 --- a/include/Makefile.inc +++ b/include/Makefile.inc @@ -31,7 +31,6 @@ INC_INSTHDRS += NSSystemDirectories.h \ err.h \ errno.h \ fcntl.h \ - float.h \ fmtmsg.h \ fnmatch.h \ fsproperties.h \ @@ -70,10 +69,10 @@ INC_INSTHDRS += NSSystemDirectories.h \ spawn.h \ stab.h \ standards.h \ - stdarg.h \ stdbool.h \ stddef.h \ stdio.h \ + stdint.h \ stdlib.h \ strhash.h \ string.h \ @@ -93,7 +92,6 @@ INC_INSTHDRS += NSSystemDirectories.h \ util.h \ utime.h \ utmpx.h \ - varargs.h \ vis.h \ wchar.h \ wctype.h \ @@ -121,3 +119,8 @@ LOCALHDRS += ${.CURDIR}/include/spawn_private.h .include "Makefile.nbsd_begin" NBSDHDRS = utmpx.h .include "Makefile.nbsd_end" + +.include "Makefile.fbsd_begin" +FBSDHDRS= nl_types.h +.include "Makefile.fbsd_end" + diff --git a/include/NSSystemDirectories.h b/include/NSSystemDirectories.h index fc3c1f3..b678106 100644 --- a/include/NSSystemDirectories.h +++ b/include/NSSystemDirectories.h @@ -65,7 +65,7 @@ typedef enum { NSDocumentationDirectory = 8, // documentation (Library/Documentation) NSDocumentDirectory = 9, // documents (Documents) NSCoreServiceDirectory = 10, // location of core services (System/Library/CoreServices) - NSAutosavedInformationDirectory = 11, // location of user's directory for use with autosaving (~/Documents/Autosaved) + NSAutosavedInformationDirectory = 11, // location of user's directory for use with autosaving (Library/Autosave Information) NSDesktopDirectory = 12, // location of user's Desktop (Desktop) NSCachesDirectory = 13, // location of discardable cache files (Library/Caches) NSApplicationSupportDirectory = 14, // location of application support files (plug-ins, etc) (Library/Application Support) diff --git a/include/NetBSD/utmpx.h.patch b/include/NetBSD/utmpx.h.patch index bed5c0c..3006f1c 100644 --- a/include/NetBSD/utmpx.h.patch +++ b/include/NetBSD/utmpx.h.patch @@ -1,5 +1,7 @@ ---- utmpx.h.orig 2008-07-17 11:34:24.000000000 -0700 -+++ utmpx.h 2008-07-17 11:57:27.000000000 -0700 +Index: utmpx.h +=================================================================== +--- utmpx.h (revision 59377) ++++ utmpx.h (working copy) @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. @@ -26,15 +28,17 @@ /* $NetBSD: utmpx.h,v 1.11 2003/08/26 16:48:32 wiz Exp $ */ /*- -@@ -38,28 +60,32 @@ +@@ -38,28 +60,34 @@ #ifndef _UTMPX_H_ #define _UTMPX_H_ --#include ++#include <_types.h> ++#include + #include -#include -#include -+#include <_types.h> - #include +-#include ++#include +#ifndef _PID_T +#define _PID_T @@ -73,7 +77,7 @@ #define EMPTY 0 #define RUN_LVL 1 #define BOOT_TIME 2 -@@ -70,74 +96,87 @@ +@@ -70,75 +98,88 @@ #define USER_PROCESS 7 #define DEAD_PROCESS 8 @@ -83,14 +87,14 @@ #define SIGNATURE 10 -#endif +#define SHUTDOWN_TIME 11 -+ + +#define UTMPX_AUTOFILL_MASK 0x8000 +#define UTMPX_DEAD_IF_CORRESPONDING_MASK 0x4000 + +/* notify(3) change notification name */ +#define UTMPX_CHANGE_NOTIFICATION "com.apple.system.utmpx" +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ - ++ /* * The following structure describes the fields of the utmpx entries - * stored in _PATH_UTMPX or _PATH_WTMPX. This is not the format the @@ -145,7 +149,8 @@ -struct utmpx *getutxid __P((const struct utmpx *)); -struct utmpx *getutxline __P((const struct utmpx *)); -struct utmpx *pututxline __P((const struct utmpx *)); -- ++void endutxent(void); + -#if defined(_NETBSD_SOURCE) -int updwtmpx __P((const char *, const struct utmpx *)); -int lastlogxname __P((const char *)); @@ -160,32 +165,29 @@ -struct utmp; -void getutmp __P((const struct utmpx *, struct utmp *)); -void getutmpx __P((const struct utmp *, struct utmpx *)); -- --int utmpxname __P((const char *)); -+void endutxent(void); - --#endif /* _NETBSD_SOURCE */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -+void endutxent_wtmp(void); ++void endutxent_wtmp(void) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +struct lastlogx * -+ getlastlogx(uid_t, struct lastlogx *); ++ getlastlogx(uid_t, struct lastlogx *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +struct lastlogx * -+ getlastlogxbyname(const char*, struct lastlogx *); ++ getlastlogxbyname(const char*, struct lastlogx *)__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +#ifdef UNIFDEF_LEGACY_UTMP_APIS +struct utmp; /* forward reference */ -+void getutmp(const struct utmpx *, struct utmp *); -+void getutmpx(const struct utmp *, struct utmpx *); ++void getutmp(const struct utmpx *, struct utmp *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); ++void getutmpx(const struct utmp *, struct utmpx *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +#endif /* UNIFDEF_LEGACY_UTMP_APIS */ +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ -+ + +-int utmpxname __P((const char *)); +struct utmpx * + getutxent(void); -+ + +-#endif /* _NETBSD_SOURCE */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +struct utmpx * -+ getutxent_wtmp(void); ++ getutxent_wtmp(void) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ -+ + +struct utmpx * + getutxid(const struct utmpx *); +struct utmpx * @@ -195,10 +197,11 @@ +void setutxent(void); + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -+void setutxent_wtmp(int); -+int utmpxname(const char *); -+int wtmpxname(const char *); ++void setutxent_wtmp(int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); ++int utmpxname(const char *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); ++int wtmpxname(const char *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ - ++ __END_DECLS + #endif /* !_UTMPX_H_ */ diff --git a/include/asl.h b/include/asl.h index 3d9c63f..1761e9b 100644 --- a/include/asl.h +++ b/include/asl.h @@ -1,23 +1,22 @@ /* - * Copyright (c) 2004 - 2007 Apple Inc. All rights reserved. + * Copyright (c) 2004-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 2004 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -28,6 +27,7 @@ #include #include #include +#include typedef struct __aslclient *aslclient; typedef struct __aslmsg *aslmsg; @@ -119,13 +119,19 @@ typedef struct __aslresponse *aslresponse; #define ASL_KEY_GID "GID" /* GID that sent the log message (set by the server). */ #define ASL_KEY_LEVEL "Level" /* Log level number encoded as a string. See levels above. */ #define ASL_KEY_MSG "Message" /* Message text. */ -#define ASL_KEY_READ_UID "ReadUID" /* User read access (-1 is any group). */ +#define ASL_KEY_READ_UID "ReadUID" /* User read access (-1 is any user). */ #define ASL_KEY_READ_GID "ReadGID" /* Group read access (-1 is any group). */ #define ASL_KEY_EXPIRE_TIME "ASLExpireTime" /* Expiration time for messages with long TTL. */ #define ASL_KEY_MSG_ID "ASLMessageID" /* 64-bit message ID number (set by the server). */ #define ASL_KEY_SESSION "Session" /* Session (set by the launchd). */ #define ASL_KEY_REF_PID "RefPID" /* Reference PID for messages proxied by launchd */ #define ASL_KEY_REF_PROC "RefProc" /* Reference process for messages proxied by launchd */ +#define ASL_KEY_AUX_TITLE "ASLAuxTitle" /* Auxiliary title string */ +#define ASL_KEY_AUX_UTI "ASLAuxUTI" /* Auxiliary Uniform Type ID */ +#define ASL_KEY_AUX_URL "ASLAuxURL" /* Auxiliary Uniform Resource Locator */ +#define ASL_KEY_AUX_DATA "ASLAuxData" /* Auxiliary in-line data */ +#define ASL_KEY_OPTION "ASLOption" /* Internal */ +#define ASL_KEY_SENDER_INSTANCE "SenderInstance" /* Sender instance UUID. */ /*! @/defineblock */ /*! @defineblock aslmsg Types @@ -412,6 +418,93 @@ aslmsg aslresponse_next(aslresponse r); */ void aslresponse_free(aslresponse r); +/*! + * Creates an auxiliary file that may be used to save arbitrary data. The ASL message msg + * will be saved at the time that the auxiliary file is closed with asl_close_auxiliary_file(). + * The log entry will include any keys and values found in msg, and it will include the title + * and Uniform Type Identifier specified. If NULL is supplied as a value for the uti parameter, + * the type "public.data" is used. Console.app will display a hyperlink to the file. + * Output parameter out_fd will contain a readable and writable file descriptor for the new + * auxiliary file. + * + * By default, the file will be world-readable. If the message contains a ReadUID and/or a + * ReadGID key, then the values for those keys will determine read access to the file. + * + * The file will be deleted at the same time that the message expires from the ASL data store. + * The aslmanager utility manages message expiry. If msg contains a value for ASLExpireTime, + * then the message and the file will not be deleted before that time. The value may be in + * seconds after the Epoch, or it may be ctime() format, e.g "Thu Jun 24 18:22:48 2010". + * + * @param msg + * (input) An aslmsg + * @param tite + * (input) A title string for the file + * @param uti + * (input) Uniform Type Identifier for the file + * @param out_fd + * (output) A writable file descriptor + * @result Returns 0 for success, non-zero for failure + */ +int asl_create_auxiliary_file(aslmsg msg, const char *title, const char *uti, int *out_fd) +__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0); + +/*! + * Close an auxiliary file opened by asl_create_auxiliary_file() when writing is complete. + * syslogd will log the message provided to asl_create_auxiliary_file() when this routine + * is called. + * + * @param fd + * (input) The file descriptor + * @result Returns 0 for success, non-zero for failure + */ +int asl_close_auxiliary_file(int fd) +__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0); + +/*! + * Sends an ASL message to syslogd along with a title string, Uniform Resource Locator, + * and Uniform Type Identifier specified. Console.app will hyperlink the title string to + * the specified URL. If NULL is supplied as a value for the uti parameter, the default + * type "public.data" is used. + * + * @param msg + * (input) An aslmsg + * @param title + * (input) A title string for the file + * @param uti + * (input) Uniform Type Identifier for the file + * @param url + * (input) Uniform Type Locator + * @result Returns 0 for success, non-zero for failure + */ +int asl_log_auxiliary_location(aslmsg msg, const char *title, const char *uti, const char *url) +__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0); + +/*! + * Creates an aslclient for logging to a file descriptor. The file must be opened for read and + * write access. This routine may be used in conjunction with asl_create_auxiliary_file() to + * save ASL format log messages to an auxiliary file. + * + * The file will be truncated if it is not empty. When logging to the auxiliary file is complete, + * aslclient should be closed using asl_close(). The file should be closed using + * asl_close_auxiliary_file() if it was returned by asl_create_auxiliary_file(), or close() + * otherwise. + * + * The returned aslclient is thread-safe. + * + * Note that per-message read access controls (ReadUID and ReadGID) and message expire + * times (ASLExpireTime) keys have no effect for messages written to this file. + * + * @param fd + * (input) A file descriptor + * @param ident + * (input) Sender name + * @param facility + * (input) Facility name + * @result An aslclient + */ +aslclient asl_open_from_file(int fd, const char *ident, const char *facility) +__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0); + __END_DECLS #endif /* __ASL_H__ */ diff --git a/include/assert.h b/include/assert.h index 1bfea51..a585ff1 100644 --- a/include/assert.h +++ b/include/assert.h @@ -74,11 +74,19 @@ __END_DECLS __BEGIN_DECLS void __assert_rtn(const char *, const char *, int, const char *) __dead2; +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) < 1070) void __eprintf(const char *, const char *, unsigned, const char *) __dead2; +#endif __END_DECLS +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) < 1070) #define __assert(e, file, line) \ __eprintf ("%s:%u: failed assertion `%s'\n", file, line, e) +#else +/* 8462256: modified __assert_rtn() replaces deprecated __eprintf() */ +#define __assert(e, file, line) \ + __assert_rtn ((const char *)-1L, file, line, e) +#endif #if __DARWIN_UNIX03 #define assert(e) \ diff --git a/include/dirent.h b/include/dirent.h index 917cb23..0d76134 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -124,7 +124,7 @@ int getdirentries(int, char *, int, long *) */ __asm("_getdirentries_is_not_available_when_64_bit_inodes_are_in_effect") #else /* !__DARWIN_64_BIT_INO_T */ - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_6,__IPHONE_2_0,__IPHONE_2_0) + __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_6, __IPHONE_2_0,__IPHONE_2_0) #endif /* __DARWIN_64_BIT_INO_T */ //Begin-Libc #endif /* !__LIBC__ */ @@ -167,7 +167,7 @@ int scandir(const char *, struct dirent ***, int (*)(struct dirent *), int (*)(const void *, const void *)) __DARWIN_INODE64(scandir); #ifdef __BLOCKS__ int scandir_b(const char *, struct dirent ***, - int (^)(struct dirent *), int (^)(const void *, const void *)) __DARWIN_INODE64(scandir_b); + int (^)(struct dirent *), int (^)(const void *, const void *)) __DARWIN_INODE64(scandir_b) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ #endif /* not POSIX */ //Begin-Libc diff --git a/include/err.h b/include/err.h index ae92c29..4383e2d 100644 --- a/include/err.h +++ b/include/err.h @@ -67,24 +67,25 @@ */ #include #include <_types.h> +#include __BEGIN_DECLS -void err(int, const char *, ...) __DARWIN_LDBL_COMPAT(err) __dead2; -void verr(int, const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(verr) __dead2; -void errc(int, int, const char *, ...) __DARWIN_LDBL_COMPAT(errc) __dead2; -void verrc(int, int, const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(verrc) __dead2; -void errx(int, const char *, ...) __DARWIN_LDBL_COMPAT(errx) __dead2; -void verrx(int, const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(verrx) __dead2; -void warn(const char *, ...) __DARWIN_LDBL_COMPAT(warn); -void vwarn(const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(vwarn); -void warnc(int, const char *, ...) __DARWIN_LDBL_COMPAT(warnc); -void vwarnc(int, const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(vwarnc); -void warnx(const char *, ...) __DARWIN_LDBL_COMPAT(warnx); -void vwarnx(const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(vwarnx); +void err(int, const char *, ...) __DARWIN_LDBL_COMPAT(err) __dead2 __printflike(2, 3); +void verr(int, const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(verr) __dead2 __printflike(2, 0); +void errc(int, int, const char *, ...) __DARWIN_LDBL_COMPAT(errc) __dead2 __printflike(3, 4); +void verrc(int, int, const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(verrc) __dead2 __printflike(3, 0); +void errx(int, const char *, ...) __DARWIN_LDBL_COMPAT(errx) __dead2 __printflike(2, 3); +void verrx(int, const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(verrx) __dead2 __printflike(2, 0); +void warn(const char *, ...) __DARWIN_LDBL_COMPAT(warn) __printflike(1, 2); +void vwarn(const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(vwarn) __printflike(1, 0); +void warnc(int, const char *, ...) __DARWIN_LDBL_COMPAT(warnc) __printflike(2, 3); +void vwarnc(int, const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(vwarnc) __printflike(2, 0); +void warnx(const char *, ...) __DARWIN_LDBL_COMPAT(warnx) __printflike(1, 2); +void vwarnx(const char *, __darwin_va_list) __DARWIN_LDBL_COMPAT(vwarnx) __printflike(1, 0); void err_set_file(void *); void err_set_exit(void (*)(int)); #ifdef __BLOCKS__ -void err_set_exit_b(void (^)(int)); +void err_set_exit_b(void (^)(int)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ __END_DECLS diff --git a/include/float.h b/include/float.h deleted file mode 100644 index 84fd005..0000000 --- a/include/float.h +++ /dev/null @@ -1,281 +0,0 @@ -/* This file exists soley to keep Metrowerks' compilers happy. The version - used by GCC can be found in /usr/lib/gcc, although it's - not very informative. */ - -#ifndef _FLOAT_H_ - -#if defined(__GNUC__) -#include_next - -#elif defined(__MWERKS__) -#define _FLOAT_H_ - -/* APPLE LOCAL begin MW compatibility */ -/* Define various characteristics of floating-point types, if needed. */ -#ifndef __FLT_RADIX__ -#define __FLT_RADIX__ 2 -#endif -#ifndef __FLT_MANT_DIG__ -#define __FLT_MANT_DIG__ 24 -#endif -#ifndef __FLT_DIG__ -#define __FLT_DIG__ 6 -#endif -#ifndef __FLT_EPSILON__ -#define __FLT_EPSILON__ 1.19209290e-07F -#endif -#ifndef __FLT_MIN__ -#define __FLT_MIN__ 1.17549435e-38F -#endif -#ifndef __FLT_MAX__ -#define __FLT_MAX__ 3.40282347e+38F -#endif -#ifndef __FLT_MIN_EXP__ -#define __FLT_MIN_EXP__ (-125) -#endif -#ifndef __FLT_MIN_10_EXP__ -#define __FLT_MIN_10_EXP__ (-37) -#endif -#ifndef __FLT_MAX_EXP__ -#define __FLT_MAX_EXP__ 128 -#endif -#ifndef __FLT_MAX_10_EXP__ -#define __FLT_MAX_10_EXP__ 38 -#endif -#ifndef __DBL_MANT_DIG__ -#define __DBL_MANT_DIG__ 53 -#endif -#ifndef __DBL_DIG__ -#define __DBL_DIG__ 15 -#endif -#ifndef __DBL_EPSILON__ -#define __DBL_EPSILON__ 2.2204460492503131e-16 -#endif -#ifndef __DBL_MIN__ -#define __DBL_MIN__ 2.2250738585072014e-308 -#endif -#ifndef __DBL_MAX__ -#define __DBL_MAX__ 1.7976931348623157e+308 -#endif -#ifndef __DBL_MIN_EXP__ -#define __DBL_MIN_EXP__ (-1021) -#endif -#ifndef __DBL_MIN_10_EXP__ -#define __DBL_MIN_10_EXP__ (-307) -#endif -#ifndef __DBL_MAX_EXP__ -#define __DBL_MAX_EXP__ 1024 -#endif -#ifndef __DBL_MAX_10_EXP__ -#define __DBL_MAX_10_EXP__ 308 -#endif -#ifndef __LDBL_MANT_DIG__ -#define __LDBL_MANT_DIG__ 53 -#endif -#ifndef __LDBL_DIG__ -#define __LDBL_DIG__ 15 -#endif -#ifndef __LDBL_EPSILON__ -#define __LDBL_EPSILON__ 2.2204460492503131e-16 -#endif -#ifndef __LDBL_MIN__ -#define __LDBL_MIN__ 2.2250738585072014e-308 -#endif -#ifndef __LDBL_MAX__ -#define __LDBL_MAX__ 1.7976931348623157e+308 -#endif -#ifndef __LDBL_MIN_EXP__ -#define __LDBL_MIN_EXP__ (-1021) -#endif -#ifndef __LDBL_MIN_10_EXP__ -#define __LDBL_MIN_10_EXP__ (-307) -#endif -#ifndef __LDBL_MAX_EXP__ -#define __LDBL_MAX_EXP__ 1024 -#endif -#ifndef __LDBL_MAX_10_EXP__ -#define __LDBL_MAX_10_EXP__ 308 -#endif -/* APPLE LOCAl end MW compatibility */ - -/* Copyright (C) 2002 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you include this header file into source - files compiled by GCC, this header file does not by itself cause - the resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. */ - -/* - * ISO C Standard: 5.2.4.2.2 Characteristics of floating types - */ - - -/* Radix of exponent representation, b. */ -#undef FLT_RADIX -#define FLT_RADIX __FLT_RADIX__ - -/* Number of base-FLT_RADIX digits in the significand, p. */ -#undef FLT_MANT_DIG -#undef DBL_MANT_DIG -#undef LDBL_MANT_DIG -#define FLT_MANT_DIG __FLT_MANT_DIG__ -#define DBL_MANT_DIG __DBL_MANT_DIG__ -#define LDBL_MANT_DIG __LDBL_MANT_DIG__ - -/* Number of decimal digits, q, such that any floating-point number with q - decimal digits can be rounded into a floating-point number with p radix b - digits and back again without change to the q decimal digits, - - p * log10(b) if b is a power of 10 - floor((p - 1) * log10(b)) otherwise -*/ -#undef FLT_DIG -#undef DBL_DIG -#undef LDBL_DIG -#define FLT_DIG __FLT_DIG__ -#define DBL_DIG __DBL_DIG__ -#define LDBL_DIG __LDBL_DIG__ - -/* Minimum int x such that FLT_RADIX**(x-1) is a normalized float, emin */ -#undef FLT_MIN_EXP -#undef DBL_MIN_EXP -#undef LDBL_MIN_EXP -#define FLT_MIN_EXP __FLT_MIN_EXP__ -#define DBL_MIN_EXP __DBL_MIN_EXP__ -#define LDBL_MIN_EXP __LDBL_MIN_EXP__ - -/* Minimum negative integer such that 10 raised to that power is in the - range of normalized floating-point numbers, - - ceil(log10(b) * (emin - 1)) -*/ -#undef FLT_MIN_10_EXP -#undef DBL_MIN_10_EXP -#undef LDBL_MIN_10_EXP -#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__ -#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__ -#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ - -/* Maximum int x such that FLT_RADIX**(x-1) is a representable float, emax. */ -#undef FLT_MAX_EXP -#undef DBL_MAX_EXP -#undef LDBL_MAX_EXP -#define FLT_MAX_EXP __FLT_MAX_EXP__ -#define DBL_MAX_EXP __DBL_MAX_EXP__ -#define LDBL_MAX_EXP __LDBL_MAX_EXP__ - -/* Maximum integer such that 10 raised to that power is in the range of - representable finite floating-point numbers, - - floor(log10((1 - b**-p) * b**emax)) -*/ -#undef FLT_MAX_10_EXP -#undef DBL_MAX_10_EXP -#undef LDBL_MAX_10_EXP -#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__ -#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__ -#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ - -/* Maximum representable finite floating-point number, - - (1 - b**-p) * b**emax -*/ -#undef FLT_MAX -#undef DBL_MAX -#undef LDBL_MAX -#define FLT_MAX __FLT_MAX__ -#define DBL_MAX __DBL_MAX__ -#define LDBL_MAX __LDBL_MAX__ - -/* The difference between 1 and the least value greater than 1 that is - representable in the given floating point type, b**1-p. */ -#undef FLT_EPSILON -#undef DBL_EPSILON -#undef LDBL_EPSILON -#define FLT_EPSILON __FLT_EPSILON__ -#define DBL_EPSILON __DBL_EPSILON__ -#define LDBL_EPSILON __LDBL_EPSILON__ - -/* Minimum normalized positive floating-point number, b**(emin - 1). */ -#undef FLT_MIN -#undef DBL_MIN -#undef LDBL_MIN -#define FLT_MIN __FLT_MIN__ -#define DBL_MIN __DBL_MIN__ -#define LDBL_MIN __LDBL_MIN__ - -/* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown. */ -/* ??? This is supposed to change with calls to fesetround in . */ -#undef FLT_ROUNDS -#define FLT_ROUNDS 1 - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -/* The floating-point expression evaluation method. - -1 indeterminate - 0 evaluate all operations and constants just to the range and - precision of the type - 1 evaluate operations and constants of type float and double - to the range and precision of the double type, evaluate - long double operations and constants to the range and - precision of the long double type - 2 evaluate all operations and constants to the range and - precision of the long double type - - ??? This ought to change with the setting of the fp control word; - the value provided by the compiler assumes the widest setting. */ -#undef FLT_EVAL_METHOD -#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ - -/* Number of decimal digits, n, such that any floating-point number in the - widest supported floating type with pmax radix b digits can be rounded - to a floating-point number with n decimal digits and back again without - change to the value, - - pmax * log10(b) if b is a power of 10 - ceil(1 + pmax * log10(b)) otherwise -*/ -#undef DECIMAL_DIG -#define DECIMAL_DIG __DECIMAL_DIG__ - -#endif /* C99 */ - -#ifdef __cplusplus -extern "C" { -#endif -extern int __fegetfltrounds( void ); -#ifdef __cplusplus -} -#endif -#undef FLT_ROUNDS -#define FLT_ROUNDS (__fegetfltrounds ()) -/* End of GNU CC file */ - -/* APPLE LOCAL begin CW compatibility */ -/* CodeWarrior defines the following on its own. */ -#undef DECIMAL_DIG -/* APPLE LOCAL end CW compatibility */ - -#else -#error This file is only for Metrowerks compatibilty. -#endif - -#endif /* _FLOAT_H_ */ diff --git a/include/fsproperties.h b/include/fsproperties.h index bef75c4..7e90bd9 100644 --- a/include/fsproperties.h +++ b/include/fsproperties.h @@ -49,5 +49,8 @@ #define kFSVerificationArgumentsKey "FSVerificationArguments" #define kFSVerificationExecutableKey "FSVerificationExecutable" #define kFSSubTypeKey "FSSubType" +#define kFSXMLOutputArgumentKey "FSXMLOutputArgument" + +#define kFSCoreStorageEncryptNameKey "FSCoreStorageEncryptionName" #endif /* _FSPROPERTIES_H_ */ diff --git a/include/fts.h b/include/fts.h index fa9d08f..f04d5ff 100644 --- a/include/fts.h +++ b/include/fts.h @@ -165,6 +165,7 @@ typedef struct _ftsent { } FTSENT; #include +#include __BEGIN_DECLS //Begin-Libc @@ -201,7 +202,7 @@ FTS *fts_open(char * const *, int, #ifndef LIBC_ALIAS_FTS_OPEN_B //End-Libc FTS *fts_open_b(char * const *, int, - int (^)(const FTSENT **, const FTSENT **)) __DARWIN_INODE64(fts_open_b); + int (^)(const FTSENT **, const FTSENT **)) __DARWIN_INODE64(fts_open_b) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); //Begin-Libc #else /* LIBC_ALIAS_FTS_OPEN */ FTS *fts_open_b(char * const *, int, diff --git a/include/glob.h b/include/glob.h index 784f242..878720b 100644 --- a/include/glob.h +++ b/include/glob.h @@ -41,6 +41,8 @@ #define _GLOB_H_ #include <_types.h> +#include +#include #ifndef _SIZE_T #define _SIZE_T @@ -135,7 +137,7 @@ int glob(const char * __restrict, int, int (*)(const char *, int), #ifndef LIBC_ALIAS_GLOB_B //End-Libc int glob_b(const char * __restrict, int, int (^)(const char *, int), - glob_t * __restrict) __DARWIN_INODE64(glob_b); + glob_t * __restrict) __DARWIN_INODE64(glob_b) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); //Begin-Libc #else /* LIBC_ALIAS_GLOB_B */ int glob_b(const char * __restrict, int, int (^)(const char *, int), diff --git a/include/inttypes.h b/include/inttypes.h index 4f9dd8d..1beb2c0 100644 --- a/include/inttypes.h +++ b/include/inttypes.h @@ -28,11 +28,8 @@ * and their ilk. */ -/* "C++ implementations should define these macros only when - * __STDC_FORMAT_MACROS is defined before is included." - */ -#if (!defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)) && !defined(__STDC_FORMAT_MACROS_DEFINED) -#define __STDC_FORMAT_MACROS_DEFINED +#if !defined(_INTTYPES_H_) +#define _INTTYPES_H_ # undef __PRI_8_LENGTH_MODIFIER__ # undef __PRI_64_LENGTH_MODIFIER__ @@ -245,11 +242,6 @@ # define SCNuMAX __SCN_MAX_LENGTH_MODIFIER__ "u" # define SCNxMAX __SCN_MAX_LENGTH_MODIFIER__ "x" -#endif /* if C++, then __STDC_FORMAT_MACROS enables the above macros */ - -#if !defined(_INTTYPES_H_) -#define _INTTYPES_H_ - #include /* For __BEGIN_DECLS and __END_DECLS */ #include <_types.h> /* For __darwin_wchar_t */ #include diff --git a/include/langinfo.h b/include/langinfo.h index 27ba0a5..117402b 100644 --- a/include/langinfo.h +++ b/include/langinfo.h @@ -102,7 +102,7 @@ typedef __darwin_nl_item nl_item; #define YESEXPR 52 /* affirmative response expression */ #define NOEXPR 53 /* negative response expression */ -#if !defined(_ANSI_SOURCE) +#if (__DARWIN_C_LEVEL > __DARWIN_C_ANSI && __DARWIN_C_LEVEL < 200112L) || __DARWIN_C_LEVEL == __DARWIN_C_FULL #define YESSTR 54 /* affirmative response for yes/no queries */ #define NOSTR 55 /* negative response for yes/no queries */ #endif diff --git a/include/libc.h b/include/libc.h index db1c3ee..7880986 100644 --- a/include/libc.h +++ b/include/libc.h @@ -28,7 +28,6 @@ #define _LIBC_H #include -#include #include #ifdef __STRICT_BSD__ diff --git a/include/libkern/OSAtomic.h b/include/libkern/OSAtomic.h index 9f2dba4..6a62bd3 100644 --- a/include/libkern/OSAtomic.h +++ b/include/libkern/OSAtomic.h @@ -29,119 +29,472 @@ #include #include -/* These are the preferred versions of the atomic and synchronization operations. +#include + +/*! @header + * These are the preferred versions of the atomic and synchronization operations. * Their implementation is customized at boot time for the platform, including * late-breaking errata fixes as necessary. They are thread safe. * - * WARNING: all addresses passed to these functions must be "naturally aligned", ie - * int32_t's must be 32-bit aligned (low 2 bits of address zero), and int64_t's - * must be 64-bit aligned (low 3 bits of address zero.) + * WARNING: all addresses passed to these functions must be "naturally aligned", + * i.e. * int32_t pointers must be 32-bit aligned (low 2 bits of + * address are zeroes), and int64_t pointers must be 64-bit aligned + * (low 3 bits of address are zeroes.) + * + * Note that some versions of the atomic functions incorporate memory barriers + * and some do not. Barriers strictly order memory access on weakly-ordered + * architectures such as PPC. All loads and stores that appear (in sequential + * program order) before the barrier are guaranteed to complete before any + * load or store that appears after the barrier. * - * Note that some versions of the atomic functions incorporate memory barriers, - * and some do not. Barriers strictly order memory access on a weakly-ordered - * architecture such as PPC. All loads and stores executed in sequential program - * order before the barrier will complete before any load or store executed after - * the barrier. On a uniprocessor, the barrier operation is typically a nop. - * On a multiprocessor, the barrier can be quite expensive on some platforms, - * eg PPC. + * On a uniprocessor system, the barrier operation is typically a no-op. On a + * multiprocessor system, the barrier can be quite expensive on some platforms, + * such as PPC. * - * Most code will want to use the barrier functions to insure that memory shared - * between threads is properly synchronized. For example, if you want to initialize + * Most code should use the barrier functions to ensure that memory shared between + * threads is properly synchronized. For example, if you want to initialize * a shared data structure and then atomically increment a variable to indicate - * that the initialization is complete, then you must use OSAtomicIncrement32Barrier() - * to ensure that the stores to your data structure complete before the atomic add. - * Likewise, the consumer of that data structure must use OSAtomicDecrement32Barrier(), + * that the initialization is complete, you must use {@link OSAtomicIncrement32Barrier} + * to ensure that the stores to your data structure complete before the atomic + * increment. + * + * Likewise, the consumer of that data structure must use {@link OSAtomicDecrement32Barrier}, * in order to ensure that their loads of the structure are not executed before * the atomic decrement. On the other hand, if you are simply incrementing a global - * counter, then it is safe and potentially faster to use OSAtomicIncrement32(). + * counter, then it is safe and potentially faster to use {@link OSAtomicIncrement32}. * * If you are unsure which version to use, prefer the barrier variants as they are * safer. * * The spinlock and queue operations always incorporate a barrier. + * + * For the kernel-space version of this header, see + * {@link //apple_ref/doc/header/OSAtomic.h OSAtomic.h (Kernel Framework)} + * + * @apiuid //apple_ref/doc/header/user_space_OSAtomic.h */ __BEGIN_DECLS -/* Arithmetic functions. They return the new value. +/*! @group Arithmetic functions + All functions in this group return the new value. + */ + +/*! @abstract Atomically adds two 32-bit values. + @discussion + This function adds the value given by __theAmount to the + value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the new value. */ int32_t OSAtomicAdd32( int32_t __theAmount, volatile int32_t *__theValue ); + + +/*! @abstract Atomically adds two 32-bit values. + @discussion + This function adds the value given by __theAmount to the + value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicAdd32} + except that it also introduces a barrier. + @result Returns the new value. + */ int32_t OSAtomicAdd32Barrier( int32_t __theAmount, volatile int32_t *__theValue ); + +/*! @abstract Atomically increments a 32-bit value. + */ __inline static int32_t OSAtomicIncrement32( volatile int32_t *__theValue ) { return OSAtomicAdd32( 1, __theValue); } + + +/*! @abstract Atomically increments a 32-bit value with a barrier. + @discussion + This function is equivalent to {@link OSAtomicIncrement32} + except that it also introduces a barrier. + @result Returns the new value. + */ __inline static int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue ) { return OSAtomicAdd32Barrier( 1, __theValue); } +/*! @abstract Atomically decrements a 32-bit value. */ __inline static int32_t OSAtomicDecrement32( volatile int32_t *__theValue ) { return OSAtomicAdd32( -1, __theValue); } + +/*! @abstract Atomically increments a 32-bit value with a barrier. + @discussion + This function is equivalent to {@link OSAtomicDecrement32} + except that it also introduces a barrier. + @result Returns the new value. + */ __inline static int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue ) { return OSAtomicAdd32Barrier( -1, __theValue); } + #if defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) || defined(__arm__) +/*! @abstract Atomically adds two 64-bit values. + @discussion + This function adds the value given by __theAmount to the + value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + */ int64_t OSAtomicAdd64( int64_t __theAmount, volatile int64_t *__theValue ); -int64_t OSAtomicAdd64Barrier( int64_t __theAmount, volatile int64_t *__theValue ); + +/*! @abstract Atomically adds two 64-bit values with a barrier. + @discussion + This function adds the value given by __theAmount to the + value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicAdd64} + except that it also introduces a barrier. + @result Returns the new value. + */ +int64_t OSAtomicAdd64Barrier( int64_t __theAmount, volatile int64_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2); + + +/*! @abstract Atomically increments a 64-bit value. */ __inline static int64_t OSAtomicIncrement64( volatile int64_t *__theValue ) { return OSAtomicAdd64( 1, __theValue); } + +/*! @abstract Atomically increments a 64-bit value with a barrier. + @discussion + This function is equivalent to {@link OSAtomicIncrement64} + except that it also introduces a barrier. + @result Returns the new value. + */ __inline static int64_t OSAtomicIncrement64Barrier( volatile int64_t *__theValue ) { return OSAtomicAdd64Barrier( 1, __theValue); } + +/*! @abstract Atomically decrements a 64-bit value. + @discussion + This function is equivalent to {@link OSAtomicIncrement64} + except that it also introduces a barrier. + @result Returns the new value. + */ __inline static int64_t OSAtomicDecrement64( volatile int64_t *__theValue ) { return OSAtomicAdd64( -1, __theValue); } + + +/*! @abstract Atomically decrements a 64-bit value with a barrier. + @discussion + This function is equivalent to {@link OSAtomicDecrement64} + except that it also introduces a barrier. + @result Returns the new value. + */ __inline static int64_t OSAtomicDecrement64Barrier( volatile int64_t *__theValue ) { return OSAtomicAdd64Barrier( -1, __theValue); } + #endif /* defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) || defined(__arm__) */ -/* Boolean functions (and, or, xor.) These come in four versions for each operation: - * with and without barriers, and returning the old or new value of the operation. - * The "Orig" versions return the original value, ie before the operation, the non-Orig +/*! @group Boolean functions (AND, OR, XOR) + * + * @discussion Functions in this group come in four variants for each operation: + * with and without barriers, and functions that return the original value or + * the result value of the operation. + * + * The "Orig" versions return the original value, (before the operation); the non-Orig * versions return the value after the operation. All are layered on top of - * compare-and-swap. + * {@link OSAtomicCompareAndSwap32} and similar. + */ + +/*! @abstract Atomic bitwise OR of two 32-bit values. + @discussion + This function performs the bitwise OR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the new value. */ int32_t OSAtomicOr32( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise OR of two 32-bit values with barrier. + @discussion + This function performs the bitwise OR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicOr32} + except that it also introduces a barrier. + @result Returns the new value. + */ int32_t OSAtomicOr32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); -int32_t OSAtomicOr32Orig( uint32_t __theMask, volatile uint32_t *__theValue ); -int32_t OSAtomicOr32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ); + +/*! @abstract Atomic bitwise OR of two 32-bit values returning original. + @discussion + This function performs the bitwise OR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the original value referenced by __theValue. + */ +int32_t OSAtomicOr32Orig( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); + + +/*! @abstract Atomic bitwise OR of two 32-bit values returning original with barrier. + @discussion + This function performs the bitwise OR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicOr32Orig} + except that it also introduces a barrier. + @result Returns the original value referenced by __theValue. + */ +int32_t OSAtomicOr32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); + + + + +/*! @abstract Atomic bitwise AND of two 32-bit values. + @discussion + This function performs the bitwise AND of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the new value. + */ int32_t OSAtomicAnd32( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise AND of two 32-bit values with barrier. + @discussion + This function performs the bitwise AND of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicAnd32} + except that it also introduces a barrier. + @result Returns the new value. + */ int32_t OSAtomicAnd32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); -int32_t OSAtomicAnd32Orig( uint32_t __theMask, volatile uint32_t *__theValue ); -int32_t OSAtomicAnd32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ); + +/*! @abstract Atomic bitwise AND of two 32-bit values returning original. + @discussion + This function performs the bitwise AND of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the original value referenced by __theValue. + */ +int32_t OSAtomicAnd32Orig( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); + + +/*! @abstract Atomic bitwise AND of two 32-bit values returning original with barrier. + @discussion + This function performs the bitwise AND of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicAnd32Orig} + except that it also introduces a barrier. + @result Returns the original value referenced by __theValue. + */ +int32_t OSAtomicAnd32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); + + + + +/*! @abstract Atomic bitwise XOR of two 32-bit values. + @discussion + This function performs the bitwise XOR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the new value. + */ int32_t OSAtomicXor32( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise XOR of two 32-bit values with barrier. + @discussion + This function performs the bitwise XOR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicXor32} + except that it also introduces a barrier. + @result Returns the new value. + */ int32_t OSAtomicXor32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); -int32_t OSAtomicXor32Orig( uint32_t __theMask, volatile uint32_t *__theValue ); -int32_t OSAtomicXor32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise XOR of two 32-bit values returning original. + @discussion + This function performs the bitwise XOR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the original value referenced by __theValue. + */ +int32_t OSAtomicXor32Orig( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); + + +/*! @abstract Atomic bitwise XOR of two 32-bit values returning original with barrier. + @discussion + This function performs the bitwise XOR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicXor32Orig} + except that it also introduces a barrier. + @result Returns the original value referenced by __theValue. + */ +int32_t OSAtomicXor32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); -/* Compare and swap. They return true if the swap occured. There are several versions, - * depending on data type and whether or not a barrier is used. +/*! @group Compare and swap + * Functions in this group return true if the swap occured. There are several versions, + * depending on data type and on whether or not a barrier is used. + */ + + +/*! @abstract Compare and swap for 32-bit values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + @result Returns TRUE on a match, FALSE otherwise. */ bool OSAtomicCompareAndSwap32( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue ); + + +/*! @abstract Compare and swap for 32-bit values with barrier. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwap32} + except that it also introduces a barrier. + @result Returns TRUE on a match, FALSE otherwise. + */ bool OSAtomicCompareAndSwap32Barrier( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue ); -bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ); -bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue ); -bool OSAtomicCompareAndSwapInt( int __oldValue, int __newValue, volatile int *__theValue ); -bool OSAtomicCompareAndSwapIntBarrier( int __oldValue, int __newValue, volatile int *__theValue ); -bool OSAtomicCompareAndSwapLong( long __oldValue, long __newValue, volatile long *__theValue ); -bool OSAtomicCompareAndSwapLongBarrier( long __oldValue, long __newValue, volatile long *__theValue ); + + +/*! @abstract Compare and swap pointers. + @discussion + This function compares the pointer stored in __oldValue to the pointer + in the memory location referenced by __theValue. If the pointers + match, this function stores the pointer from __newValue into + that memory location atomically. + @result Returns TRUE on a match, FALSE otherwise. + */ +bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + + +/*! @abstract Compare and swap pointers with barrier. + @discussion + This function compares the pointer stored in __oldValue to the pointer + in the memory location referenced by __theValue. If the pointers + match, this function stores the pointer from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwapPtr} + except that it also introduces a barrier. + @result Returns TRUE on a match, FALSE otherwise. + */ +bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + + +/*! @abstract Compare and swap for int values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwap32}. + @result Returns TRUE on a match, FALSE otherwise. + */ +bool OSAtomicCompareAndSwapInt( int __oldValue, int __newValue, volatile int *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + + +/*! @abstract Compare and swap for int values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwapInt} + except that it also introduces a barrier. + + This function is equivalent to {@link OSAtomicCompareAndSwap32Barrier}. + @result Returns TRUE on a match, FALSE otherwise. + */ +bool OSAtomicCompareAndSwapIntBarrier( int __oldValue, int __newValue, volatile int *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + + +/*! @abstract Compare and swap for long values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures, + or {@link OSAtomicCompareAndSwap64} on 64-bit architectures. + @result Returns TRUE on a match, FALSE otherwise. + */ +bool OSAtomicCompareAndSwapLong( long __oldValue, long __newValue, volatile long *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + + +/*! @abstract Compare and swap for long values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwapLong} + except that it also introduces a barrier. + + This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures, + or {@link OSAtomicCompareAndSwap64} on 64-bit architectures. + @result Returns TRUE on a match, FALSE otherwise. + */ +bool OSAtomicCompareAndSwapLongBarrier( long __oldValue, long __newValue, volatile long *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + #if defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) || defined(__arm__) +/*! @abstract Compare and swap for uint64_t values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + @result Returns TRUE on a match, FALSE otherwise. + */ bool OSAtomicCompareAndSwap64( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ); -bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ); + + +/*! @abstract Compare and swap for uint64_t values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwap64} + except that it also introduces a barrier. + @result Returns TRUE on a match, FALSE otherwise. + */ +bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2); #endif /* defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) || defined(__arm__) */ @@ -149,40 +502,130 @@ bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, /* Test and set. They return the original value of the bit, and operate on bit (0x80>>(n&7)) * in byte ((char*)theAddress + (n>>3)). */ +/*! @abstract Atomic test and set + @discussion + This function tests a bit in the value referenced by __theAddress + and if it is not set, sets it. The bit is chosen by the value of __n. + The bits are numbered in order beginning with bit 1 as the lowest order bit. + + For example, if __theAddress points to a 64-bit value, + to compare the value of the highest bit, you would specify 64 for + __n. + @result + Returns the original value of the bit being tested. + */ bool OSAtomicTestAndSet( uint32_t __n, volatile void *__theAddress ); + + +/*! @abstract Atomic test and set with barrier + @discussion + This function tests a bit in the value referenced by __theAddress + and if it is not set, sets it. The bit is chosen by the value of __n. + The bits are numbered in order beginning with bit 1 as the lowest order bit. + + For example, if __theAddress points to a 64-bit value, + to compare the value of the highest bit, you would specify 64 for + __n. + + This function is equivalent to {@link OSAtomicTestAndSet} + except that it also introduces a barrier. + @result + Returns the original value of the bit being tested. + */ + bool OSAtomicTestAndSetBarrier( uint32_t __n, volatile void *__theAddress ); + + + +/*! @abstract Atomic test and clear + @discussion + This function tests a bit in the value referenced by __theAddress + and if it is not cleared, clears it. The bit is chosen by the value of __n. + The bits are numbered in order beginning with bit 1 as the lowest order bit. + + For example, if __theAddress points to a 64-bit value, + to compare the value of the highest bit, you would specify 64 for + __n. + @result + Returns the original value of the bit being tested. + */ bool OSAtomicTestAndClear( uint32_t __n, volatile void *__theAddress ); + + +/*! @abstract Atomic test and clear + @discussion + This function tests a bit in the value referenced by __theAddress + and if it is not cleared, clears it. The bit is chosen by the value of __n. + The bits are numbered in order beginning with bit 1 as the lowest order bit. + + For example, if __theAddress points to a 64-bit value, + to compare the value of the highest bit, you would specify 64 for + __n. + + This function is equivalent to {@link OSAtomicTestAndSet} + except that it also introduces a barrier. + @result + Returns the original value of the bit being tested. + */ bool OSAtomicTestAndClearBarrier( uint32_t __n, volatile void *__theAddress ); -/* Spinlocks. These use memory barriers as required to synchronize access to shared - * memory protected by the lock. The lock operation spins, but employs various strategies - * to back off if the lock is held, making it immune to most priority-inversion livelocks. - * The try operation immediately returns false if the lock was held, true if it took the - * lock. The convention is that unlocked is zero, locked is nonzero. +/*! @group Spinlocks + * These spinlocks use memory barriers as required to synchronize access to shared + * memory protected by the lock. + */ + +/*! @abstract The default value for an OSSpinLock. + @discussion + The convention is that unlocked is zero, locked is nonzero. */ #define OS_SPINLOCK_INIT 0 + +/*! @abstract Data type for a spinlock. + @discussion + You should always initialize a spinlock to {@link OS_SPINLOCK_INIT} before + using it. + */ typedef int32_t OSSpinLock; + +/*! @abstract Locks a spinlock if it would not block + @result + Returns false if the lock was already held by another thread, + true if it took the lock successfully. + */ bool OSSpinLockTry( volatile OSSpinLock *__lock ); + + +/*! @abstract Locks a spinlock + @discussion + Although the lock operation spins, it employs various strategies + to back off if the lock is held, making it immune to most priority-inversion + livelocks. + */ void OSSpinLockLock( volatile OSSpinLock *__lock ); + + +/*! @abstract Unlocks a spinlock */ void OSSpinLockUnlock( volatile OSSpinLock *__lock ); -/* Lockless atomic enqueue and dequeue. These routines manipulate singly - * linked LIFO lists. Ie, a dequeue will return the most recently enqueued - * element, or NULL if the list is empty. The "offset" parameter is the offset - * in bytes of the link field within the data structure being queued. The - * link field should be a pointer type. Memory barriers are incorporated as - * needed to permit thread-safe access to the queue element. +/*! @group Lockless atomic enqueue and dequeue + * These routines manipulate singly-linked LIFO lists. + */ + +/*! @abstract The data structure for a queue head. + @discussion + You should always initialize a queue head structure with the + initialization vector {@link OS_ATOMIC_QUEUE_INIT} before use. */ #if defined(__x86_64__) typedef volatile struct { void *opaque1; long opaque2; -} OSQueueHead __attribute__ ((aligned (16))); +} __attribute__ ((aligned (16))) OSQueueHead; #else @@ -193,16 +636,133 @@ typedef volatile struct { #endif +/*! @abstract The initialization vector for a queue head. */ #define OS_ATOMIC_QUEUE_INIT { NULL, 0 } -void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset); -void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset); +/*! @abstract Enqueue an item onto a list. + @discussion + Memory barriers are incorporated as needed to permit thread-safe access + to the queue element. + @param __list + The list on which you want to enqueue the item. + @param __new + The item to add. + @param __offset + The "offset" parameter is the offset (in bytes) of the link field + from the beginning of the data structure being queued (__new). + The link field should be a pointer type. + The __offset value needs to be same for all enqueuing and + dequeuing operations on the same queue, even if different structure types + are enqueued on that queue. The use of offsetset(), defined in + stddef.h is the common way to specify the __offset + value. + */ +void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0); + + +/*! @abstract Dequeue an item from a list. + @discussion + Memory barriers are incorporated as needed to permit thread-safe access + to the queue element. + @param __list + The list on which you want to enqueue the item. + @param __offset + The "offset" parameter is the offset (in bytes) of the link field + from the beginning of the data structure being queued (__new). + The link field should be a pointer type. + The __offset value needs to be same for all enqueuing and + dequeuing operations on the same queue, even if different structure types + are enqueued on that queue. The use of offsetset(), defined in + stddef.h is the common way to specify the __offset + value. + @result + Returns the most recently enqueued element, or NULL if the + list is empty. + */ +void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0); +#if defined(__x86_64__) || defined(__i386__) -/* Memory barrier. It is both a read and write barrier. +/*! @group Lockless atomic fifo enqueue and dequeue + * These routines manipulate singly-linked FIFO lists. */ -void OSMemoryBarrier( void ); +/*! @abstract The data structure for a fifo queue head. + @discussion + You should always initialize a fifo queue head structure with the + initialization vector {@link OS_ATOMIC_FIFO_QUEUE_INIT} before use. + */ +#if defined(__x86_64__) + +typedef volatile struct { + void *opaque1; + void *opaque2; + int opaque3; +} __attribute__ ((aligned (16))) OSFifoQueueHead; + +#else + +typedef volatile struct { + void *opaque1; + void *opaque2; + int opaque3; +} OSFifoQueueHead; + +#endif + +/*! @abstract The initialization vector for a fifo queue head. */ +#define OS_ATOMIC_FIFO_QUEUE_INIT { NULL, NULL, 0 } + +/*! @abstract Enqueue an item onto a list. + @discussion + Memory barriers are incorporated as needed to permit thread-safe access + to the queue element. + @param __list + The list on which you want to enqueue the item. + @param __new + The item to add. + @param __offset + The "offset" parameter is the offset (in bytes) of the link field + from the beginning of the data structure being queued (__new). + The link field should be a pointer type. + The __offset value needs to be same for all enqueuing and + dequeuing operations on the same queue, even if different structure types + are enqueued on that queue. The use of offsetset(), defined in + stddef.h is the common way to specify the __offset + value. + */ +void OSAtomicFifoEnqueue( OSFifoQueueHead *__list, void *__new, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + +/*! @abstract Dequeue an item from a list. + @discussion + Memory barriers are incorporated as needed to permit thread-safe access + to the queue element. + @param __list + The list on which you want to enqueue the item. + @param __offset + The "offset" parameter is the offset (in bytes) of the link field + from the beginning of the data structure being queued (__new). + The link field should be a pointer type. + The __offset value needs to be same for all enqueuing and + dequeuing operations on the same queue, even if different structure types + are enqueued on that queue. The use of offsetset(), defined in + stddef.h is the common way to specify the __offset + value. + @result + Returns the oldest enqueued element, or NULL if the + list is empty. + */ +void* OSAtomicFifoDequeue( OSFifoQueueHead *__list, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + +#endif /* __i386__ || __x86_64__ */ + +/*! @group Memory barriers */ + +/*! @abstract Memory barrier. + @discussion + This function serves as both a read and write barrier. + */ +void OSMemoryBarrier( void ); __END_DECLS diff --git a/include/libkern/OSCacheControl.h b/include/libkern/OSCacheControl.h index 771a704..ca8df01 100644 --- a/include/libkern/OSCacheControl.h +++ b/include/libkern/OSCacheControl.h @@ -27,6 +27,7 @@ #include #include #include +#include __BEGIN_DECLS @@ -57,7 +58,7 @@ int sys_cache_control( int function, void *start, size_t len); void sys_icache_invalidate( void *start, size_t len); /* equivalent to sys_cache_control(kCacheFunctionFlushDcache): */ -void sys_dcache_flush( void *start, size_t len); +void sys_dcache_flush( void *start, size_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); __END_DECLS diff --git a/include/libkern/OSThermalNotification.h b/include/libkern/OSThermalNotification.h index ab61e5a..02b2823 100644 --- a/include/libkern/OSThermalNotification.h +++ b/include/libkern/OSThermalNotification.h @@ -25,6 +25,7 @@ #define _OSTHERMALNOTIFICATION_H_ #include +#include /* ** OSThermalNotification.h @@ -40,16 +41,35 @@ __BEGIN_DECLS typedef enum { OSThermalNotificationLevelAny = -1, OSThermalNotificationLevelNormal = 0, - OSThermalNotificationLevel70PercentTorch = 1, - OSThermalNotificationLevel70PercentBacklight = 3, - OSThermalNotificationLevel50PercentTorch = 3, - OSThermalNotificationLevel50PercentBacklight = 5, - OSThermalNotificationLevelDisableTorch = 5, - OSThermalNotificationLevel25PercentBacklight = 7, - OSThermalNotificationLevelAppTerminate = 12, - OSThermalNotificationLevelDeviceRestart = 16 } OSThermalNotificationLevel; +extern OSThermalNotificationLevel _OSThermalNotificationLevelForBehavior(int) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_4_2); +extern void _OSThermalNotificationSetLevelForBehavior(int, int) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_4_2); + +enum { + kOSThermalMitigationNone, + kOSThermalMitigation70PercentTorch, + kOSThermalMitigation70PercentBacklight, + kOSThermalMitigation50PercentTorch, + kOSThermalMitigation50PercentBacklight, + kOSThermalMitigationDisableTorch, + kOSThermalMitigation25PercentBacklight, + kOSThermalMitigationDisableMapsHalo, + kOSThermalMitigationAppTerminate, + kOSThermalMitigationDeviceRestart, + kOSThermalMitigationCount +}; + +#define OSThermalNotificationLevel70PercentTorch _OSThermalNotificationLevelForBehavior(kOSThermalMitigation70PercentTorch) +#define OSThermalNotificationLevel70PercentBacklight _OSThermalNotificationLevelForBehavior(kOSThermalMitigation70PercentBacklight) +#define OSThermalNotificationLevel50PercentTorch _OSThermalNotificationLevelForBehavior(kOSThermalMitigation50PercentTorch) +#define OSThermalNotificationLevel50PercentBacklight _OSThermalNotificationLevelForBehavior(kOSThermalMitigation50PercentBacklight) +#define OSThermalNotificationLevelDisableTorch _OSThermalNotificationLevelForBehavior(kOSThermalMitigationDisableTorch) +#define OSThermalNotificationLevel25PercentBacklight _OSThermalNotificationLevelForBehavior(kOSThermalMitigation25PercentBacklight) +#define OSThermalNotificationLevelDisableMapsHalo _OSThermalNotificationLevelForBehavior(kOSThermalMitigationDisableMapsHalo) +#define OSThermalNotificationLevelAppTerminate _OSThermalNotificationLevelForBehavior(kOSThermalMitigationAppTerminate) +#define OSThermalNotificationLevelDeviceRestart _OSThermalNotificationLevelForBehavior(kOSThermalMitigationDeviceRestart) + /* Backwards compatibility */ #define OSThermalNotificationLevelWarning OSThermalNotificationLevel70PercentBacklight #define OSThermalNotificationLevelUrgent OSThermalNotificationLevelAppTerminate @@ -59,13 +79,13 @@ typedef enum { ** Simple polling interface to detect current thermal level */ -OSThermalNotificationLevel OSThermalNotificationCurrentLevel(void); +extern OSThermalNotificationLevel OSThermalNotificationCurrentLevel(void) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_2_0); /* ** External notify(3) string for manual notification setup */ -extern const char *kOSThermalNotificationName; +extern const char * const kOSThermalNotificationName __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_2_0); __END_DECLS diff --git a/include/limits.h b/include/limits.h index 49d0502..968de19 100644 --- a/include/limits.h +++ b/include/limits.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 2004-2007, 2009 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -64,15 +64,7 @@ #include #include -#if !defined(_ANSI_SOURCE) -#define _POSIX_AIO_LISTIO_MAX 2 -#define _POSIX_AIO_MAX 1 -#define _POSIX_DELAYTIMER_MAX 32 -#define _POSIX_HOST_NAME_MAX 255 -#define _POSIX_LOGIN_NAME_MAX 9 -#define _POSIX_MQ_OPEN_MAX 8 -#define _POSIX_MQ_PRIO_MAX 32 - +#if __DARWIN_C_LEVEL > __DARWIN_C_ANSI #define _POSIX_ARG_MAX 4096 #define _POSIX_CHILD_MAX 25 #define _POSIX_LINK_MAX 8 @@ -87,42 +79,70 @@ #define _POSIX_STREAM_MAX 8 #define _POSIX_TZNAME_MAX 6 -#define _POSIX_RE_DUP_MAX 255 +#define _POSIX2_BC_BASE_MAX 99 +#define _POSIX2_BC_DIM_MAX 2048 +#define _POSIX2_BC_SCALE_MAX 99 +#define _POSIX2_BC_STRING_MAX 1000 +#define _POSIX2_EQUIV_CLASS_MAX 2 +#define _POSIX2_EXPR_NEST_MAX 32 +#define _POSIX2_LINE_MAX 2048 +#define _POSIX2_RE_DUP_MAX 255 +#endif /* __DARWIN_C_LEVEL > __DARWIN_C_ANSI */ + +#if __DARWIN_C_LEVEL >= 199309L +#define _POSIX_AIO_LISTIO_MAX 2 +#define _POSIX_AIO_MAX 1 +#define _POSIX_DELAYTIMER_MAX 32 +#define _POSIX_MQ_OPEN_MAX 8 +#define _POSIX_MQ_PRIO_MAX 32 #define _POSIX_RTSIG_MAX 8 #define _POSIX_SEM_NSEMS_MAX 256 #define _POSIX_SEM_VALUE_MAX 32767 #define _POSIX_SIGQUEUE_MAX 32 -#define _POSIX_SS_REPL_MAX 4 -#define _POSIX_SYMLINK_MAX 255 -#define _POSIX_SYMLOOP_MAX 8 +#define _POSIX_TIMER_MAX 32 +#endif /* __DARWIN_C_LEVEL >= 199309L */ + +#if __DARWIN_C_LEVEL >= 199506L #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 #define _POSIX_THREAD_KEYS_MAX 128 #define _POSIX_THREAD_THREADS_MAX 64 -#define _POSIX_TIMER_MAX 32 +#endif /* __DARWIN_C_LEVEL >= 199506L */ + +#if __DARWIN_C_LEVEL >= 200112 +#define _POSIX_HOST_NAME_MAX 255 +#define _POSIX_LOGIN_NAME_MAX 9 +#define _POSIX_SS_REPL_MAX 4 +#define _POSIX_SYMLINK_MAX 255 +#define _POSIX_SYMLOOP_MAX 8 #define _POSIX_TRACE_EVENT_NAME_MAX 30 #define _POSIX_TRACE_NAME_MAX 8 #define _POSIX_TRACE_SYS_MAX 8 #define _POSIX_TRACE_USER_EVENT_MAX 32 #define _POSIX_TTY_NAME_MAX 9 - -#define _POSIX2_BC_BASE_MAX 99 -#define _POSIX2_BC_DIM_MAX 2048 -#define _POSIX2_BC_SCALE_MAX 99 -#define _POSIX2_BC_STRING_MAX 1000 #define _POSIX2_CHARCLASS_NAME_MAX 14 #define _POSIX2_COLL_WEIGHTS_MAX 2 -#define _POSIX2_EQUIV_CLASS_MAX 2 -#define _POSIX2_EXPR_NEST_MAX 32 -#define _POSIX2_LINE_MAX 2048 -#define _POSIX2_RE_DUP_MAX 255 -#define PTHREAD_STACK_MIN 8192 +#define _POSIX_RE_DUP_MAX _POSIX2_RE_DUP_MAX +#endif /* __DARWIN_C_LEVEL >= 200112 */ + +#if __DARWIN_C_LEVEL >= 200809L #define PTHREAD_DESTRUCTOR_ITERATIONS 4 #define PTHREAD_KEYS_MAX 512 +#define PTHREAD_STACK_MIN 8192 +#endif /* __DARWIN_C_LEVEL >= 200809L */ -#if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define OFF_MIN LLONG_MIN /* min value for an off_t */ +#define OFF_MAX LLONG_MAX /* max value for an off_t */ +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +/* Actually for XSI Visible */ +#if __DARWIN_C_LEVEL > __DARWIN_C_ANSI + +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L #define PASS_MAX 128 -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ +#endif #define NL_ARGMAX 9 #define NL_LANGMAX 14 @@ -136,9 +156,8 @@ #define _XOPEN_NAME_MAX 255 #define _XOPEN_PATH_MAX 1024 -#endif /* _ANSI_SOURCE */ +#endif /* __DARWIN_C_LEVEL > __DARWIN_C_ANSI */ /* NZERO to be defined here. TBD. See also sys/param.h */ #endif /* !_LIMITS_H_ */ - diff --git a/include/malloc/malloc.h b/include/malloc/malloc.h index ec9fcf1..53e555f 100644 --- a/include/malloc/malloc.h +++ b/include/malloc/malloc.h @@ -27,6 +27,7 @@ #include #include #include +#include __BEGIN_DECLS /********* Type definitions ************/ @@ -52,11 +53,14 @@ typedef struct _malloc_zone_t { struct malloc_introspection_t *introspect; unsigned version; - /* aligned memory allocation. The callback may be NULL. */ - void *(*memalign)(struct _malloc_zone_t *zone, size_t alignment, size_t size); + /* aligned memory allocation. The callback may be NULL. Present in version >= 5. */ + void *(*memalign)(struct _malloc_zone_t *zone, size_t alignment, size_t size); - /* free a pointer known to be in zone and known to have the given size. The callback may be NULL. */ + /* free a pointer known to be in zone and known to have the given size. The callback may be NULL. Present in version >= 6.*/ void (*free_definite_size)(struct _malloc_zone_t *zone, void *ptr, size_t size); + + /* Empty out caches in the face of memory pressure. The callback may be NULL. Present in version >= 8. */ + size_t (*pressure_relief)(struct _malloc_zone_t *zone, size_t goal); } malloc_zone_t; /********* Creation and destruction ************/ @@ -97,12 +101,12 @@ extern size_t malloc_size(const void *ptr); extern size_t malloc_good_size(size_t size); /* Returns number of bytes greater than or equal to size that can be allocated without padding */ -extern void *malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size); +extern void *malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); /* * Allocates a new pointer of size size whose address is an exact multiple of alignment. - * alignment must be a power of two and at least as large as sizeof(void *). - * zone must be non-NULL. - */ + * alignment must be a power of two and at least as large as sizeof(void *). + * zone must be non-NULL. + */ /********* Batch methods ************/ @@ -114,13 +118,13 @@ extern void malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsi /********* Functions for libcache ************/ -extern malloc_zone_t *malloc_default_purgeable_zone(void); +extern malloc_zone_t *malloc_default_purgeable_zone(void) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); /* Returns a pointer to the default purgeable_zone. */ -extern void malloc_make_purgeable(void *ptr); +extern void malloc_make_purgeable(void *ptr) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); /* Make an allocation from the purgeable zone purgeable if possible. */ -extern int malloc_make_nonpurgeable(void *ptr); +extern int malloc_make_nonpurgeable(void *ptr) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); /* Makes an allocation from the purgeable zone nonpurgeable. * Returns zero if the contents were not purged since the last * call to malloc_make_purgeable, else returns non-zero. */ @@ -143,6 +147,14 @@ extern void malloc_set_zone_name(malloc_zone_t *zone, const char *name); extern const char *malloc_get_zone_name(malloc_zone_t *zone); /* Returns the name of a zone */ +size_t malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); + /* malloc_zone_pressure_relief() advises the malloc subsystem that the process is under memory pressure and + * that the subsystem should make its best effort towards releasing (i.e. munmap()-ing) "goal" bytes from "zone". + * If "goal" is passed as zero, the malloc subsystem will attempt to achieve maximal pressure relief in "zone". + * If "zone" is passed as NULL, all zones are examined for pressure relief opportunities. + * malloc_zone_pressure_relief() returns the number of bytes released. + */ + typedef struct { vm_address_t address; vm_size_t size; @@ -176,7 +188,17 @@ typedef struct malloc_introspection_t { void (*force_lock)(malloc_zone_t *zone); /* Forces locking zone */ void (*force_unlock)(malloc_zone_t *zone); /* Forces unlocking zone */ void (*statistics)(malloc_zone_t *zone, malloc_statistics_t *stats); /* Fills statistics */ - boolean_t (*zone_locked)(malloc_zone_t *zone); /* Are any zone locks held */ + boolean_t (*zone_locked)(malloc_zone_t *zone); /* Are any zone locks held */ + + /* Discharge checking. Present in version >= 7. */ + boolean_t (*enable_discharge_checking)(malloc_zone_t *zone); + void (*disable_discharge_checking)(malloc_zone_t *zone); + void (*discharge)(malloc_zone_t *zone, void *memory); +#ifdef __BLOCKS__ + void (*enumerate_discharged_pointers)(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info)); +#else + void *enumerate_unavailable_without_blocks; +#endif /* __BLOCKS__ */ } malloc_introspection_t; extern void malloc_printf(const char *format, ...); @@ -221,6 +243,26 @@ struct mstats { extern struct mstats mstats(void); +extern boolean_t malloc_zone_enable_discharge_checking(malloc_zone_t *zone) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +/* Increment the discharge checking enabled counter for a zone. Returns true if the zone supports checking, false if it does not. */ + +extern void malloc_zone_disable_discharge_checking(malloc_zone_t *zone) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +/* Decrement the discharge checking enabled counter for a zone. */ + +extern void malloc_zone_discharge(malloc_zone_t *zone, void *memory) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +/* Register memory that the programmer expects to be freed soon. + zone may be NULL in which case the zone is determined using malloc_zone_from_ptr(). + If discharge checking is off for the zone this function is a no-op. */ + +#ifdef __BLOCKS__ +extern void malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info)) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +/* Calls report_discharged for each block that was registered using malloc_zone_discharge() but has not yet been freed. + info is used to provide zone defined information about the memory block. + If zone is NULL then the enumeration covers all zones. */ +#else +extern void malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +#endif /* __BLOCKS__ */ + __END_DECLS #endif /* _MALLOC_MALLOC_H_ */ diff --git a/include/nl_types.h b/include/nl_types.h index fe180d9..db74be9 100644 --- a/include/nl_types.h +++ b/include/nl_types.h @@ -1,56 +1,106 @@ -/* $FreeBSD: src/include/nl_types.h,v 1.7 1999/08/27 23:44:51 peter Exp $ */ - -/*********************************************************** -Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that Alfalfa's name not be used in -advertising or publicity pertaining to distribution of the software -without specific, written prior permission. - -ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -If you make any modifications, bugfixes or other changes to this software -we'd appreciate it if you could send a copy to us so we can keep things -up-to-date. Many thanks. - Kee Hinckley - Alfalfa Software, Inc. - 267 Allston St., #3 - Cambridge, MA 02139 USA - nazgul@alfalfa.com - -******************************************************************/ +/* $NetBSD: nl_types.h,v 1.9 2000/10/03 19:53:32 sommerfeld Exp $ */ + +/*- + * Copyright (c) 1996 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by J.T. Conklin. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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: src/include/nl_types.h,v 1.11 2005/02/27 16:20:53 phantom Exp $ + */ #ifndef _NL_TYPES_H_ #define _NL_TYPES_H_ + #include +#include #include <_types.h> +#ifdef _NLS_PRIVATE +/* + * MESSAGE CATALOG FILE FORMAT. + * + * The NetBSD/FreeBSD message catalog format is similar to the format used by + * Svr4 systems. The differences are: + * * fixed byte order (big endian) + * * fixed data field sizes + * + * A message catalog contains four data types: a catalog header, one + * or more set headers, one or more message headers, and one or more + * text strings. + */ + +#define _NLS_MAGIC 0xff88ff89 + +struct _nls_cat_hdr { + int32_t __magic; + int32_t __nsets; + int32_t __mem; + int32_t __msg_hdr_offset; + int32_t __msg_txt_offset; +} ; + +struct _nls_set_hdr { + int32_t __setno; /* set number: 0 < x <= NL_SETMAX */ + int32_t __nmsgs; /* number of messages in the set */ + int32_t __index; /* index of first msg_hdr in msg_hdr table */ +} ; + +struct _nls_msg_hdr { + int32_t __msgno; /* msg number: 0 < x <= NL_MSGMAX */ + int32_t __msglen; + int32_t __offset; +} ; + +#endif /* _NLS_PRIVATE */ + #define NL_SETD 1 #define NL_CAT_LOCALE 1 +typedef struct __nl_cat_d { + void *__data; + int __size; +} *nl_catd; + #ifndef _NL_ITEM -typedef __darwin_nl_item nl_item; +typedef __darwin_nl_item nl_item; #define _NL_ITEM #endif -typedef void *nl_catd; - __BEGIN_DECLS -extern nl_catd catopen(const char *, int); -extern char *catgets(nl_catd, int, int, const char *); -extern int catclose(nl_catd); +nl_catd catopen(const char *, int); +char *catgets(nl_catd, int, int, const char *) + __attribute__((__format_arg__(4))); +int catclose(nl_catd); __END_DECLS #endif /* _NL_TYPES_H_ */ diff --git a/include/protocols/Makefile.inc b/include/protocols/Makefile.inc index b7ea0cb..5158f77 100644 --- a/include/protocols/Makefile.inc +++ b/include/protocols/Makefile.inc @@ -1,5 +1,4 @@ -PROTO_INSTHDRS += dumprestore.h \ - routed.h \ +PROTO_INSTHDRS += routed.h \ rwhod.h \ talkd.h \ timed.h diff --git a/include/protocols/dumprestore.h b/include/protocols/dumprestore.h deleted file mode 100644 index 65e4ca4..0000000 --- a/include/protocols/dumprestore.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2000, 2006, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * @(#)dumprestore.h 8.2 (Berkeley) 1/21/94 - */ - -#ifndef _DUMPRESTORE_H_ -#define _DUMPRESTORE_H_ - -/* - * TP_BSIZE is the size of file blocks on the dump tapes. - * Note that TP_BSIZE must be a multiple of DEV_BSIZE. - * - * NTREC is the number of TP_BSIZE blocks that are written - * in each tape record. HIGHDENSITYTREC is the number of - * TP_BSIZE blocks that are written in each tape record on - * 6250 BPI or higher density tapes. - * - * TP_NINDIR is the number of indirect pointers in a TS_INODE - * or TS_ADDR record. Note that it must be a power of two. - */ -#define TP_BSIZE 1024 -#define NTREC 10 -#define HIGHDENSITYTREC 32 -#define TP_NINDIR (TP_BSIZE/2) -#define LBLSIZE 16 -#define NAMELEN 64 - -#define OFS_MAGIC (int)60011 -#define NFS_MAGIC (int)60012 -#define CHECKSUM (int)84446 - -union u_spcl { - char dummy[TP_BSIZE]; - struct s_spcl { -#ifdef __LP64__ - int c_type; /* record type (see below) */ - int c_date; /* date of this dump */ - int c_ddate; /* date of previous dump */ - int c_volume; /* dump volume number */ -#else /* !__LP64__ */ - long c_type; /* record type (see below) */ - time_t c_date; /* date of this dump */ - time_t c_ddate; /* date of previous dump */ - long c_volume; /* dump volume number */ -#endif /* __LP64__ */ - daddr_t c_tapea; /* logical block of this record */ - unsigned int c_inumber; /* number of inode; truncation can occur for 64-bit ino_t */ -#ifdef __LP64__ - int c_magic; /* magic number (see above) */ - int c_checksum; /* record checksum */ -#else /* !__LP64__ */ - long c_magic; /* magic number (see above) */ - long c_checksum; /* record checksum */ -#endif /* __LP64__ */ - struct dinode c_dinode; /* ownership and mode of inode */ -#ifdef __LP64__ - int c_count; /* number of valid c_addr entries */ -#else /* !__LP64__ */ - long c_count; /* number of valid c_addr entries */ -#endif /* __LP64__ */ - char c_addr[TP_NINDIR]; /* 1 => data; 0 => hole in inode */ - char c_label[LBLSIZE]; /* dump label */ -#ifdef __LP64__ - int c_level; /* level of this dump */ -#else /* !__LP64__ */ - long c_level; /* level of this dump */ -#endif /* __LP64__ */ - char c_filesys[NAMELEN]; /* name of dumpped file system */ - char c_dev[NAMELEN]; /* name of dumpped device */ - char c_host[NAMELEN]; /* name of dumpped host */ -#ifdef __LP64__ - int c_flags; /* additional information */ - int c_firstrec; /* first record on volume */ - int c_spare[32]; /* reserved for future uses */ -#else /* !__LP64__ */ - long c_flags; /* additional information */ - long c_firstrec; /* first record on volume */ - long c_spare[32]; /* reserved for future uses */ -#endif /* __LP64__ */ - } s_spcl; -}; - -/* - * special record types - */ -#define TS_TAPE 1 /* dump tape header */ -#define TS_INODE 2 /* beginning of file record */ -#define TS_ADDR 4 /* continuation of file record */ -#define TS_BITS 3 /* map of inodes on tape */ -#define TS_CLRI 6 /* map of inodes deleted since last dump */ -#define TS_END 5 /* end of volume marker */ - -/* - * flag values - */ -#define DR_NEWHEADER 0x0001 /* new format tape header */ -#define DR_NEWINODEFMT 0x0002 /* new format inodes on tape */ - -#define DUMPOUTFMT "%-16s %c %s" /* for printf */ - /* name, level, ctime(date) */ -#define DUMPINFMT "%16s %c %[^\n]\n" /* inverse for scanf */ - -#endif /* !_DUMPRESTORE_H_ */ diff --git a/include/rune.h b/include/rune.h index dccfda0..4ecb003 100644 --- a/include/rune.h +++ b/include/rune.h @@ -41,7 +41,7 @@ #include #include -#include +#include /*--------------------------- DEPRECIATED ------------------------------- * This interface is depreciated and will eventually be removed. The ISO C99 @@ -60,14 +60,14 @@ #define sputrune(c, s, n, r) (*__sputrune)((c), (s), (n), (r)) __BEGIN_DECLS -char *mbrune(const char *, rune_t) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4; -char *mbrrune(const char *, rune_t) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4; -char *mbmb(const char *, char *) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4; -long fgetrune(FILE *) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4; -int fputrune(rune_t, FILE *) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4; -int fungetrune(rune_t, FILE *) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4; -int setrunelocale(char *) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4; -void setinvalidrune(rune_t) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4; +char *mbrune(const char *, rune_t) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_4, __IPHONE_NA, __IPHONE_NA); +char *mbrrune(const char *, rune_t) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_4, __IPHONE_NA, __IPHONE_NA); +char *mbmb(const char *, char *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_4, __IPHONE_NA, __IPHONE_NA); +long fgetrune(FILE *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_4, __IPHONE_NA, __IPHONE_NA); +int fputrune(rune_t, FILE *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_4, __IPHONE_NA, __IPHONE_NA); +int fungetrune(rune_t, FILE *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_4, __IPHONE_NA, __IPHONE_NA); +int setrunelocale(char *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_4, __IPHONE_NA, __IPHONE_NA); +void setinvalidrune(rune_t) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_4, __IPHONE_NA, __IPHONE_NA); __END_DECLS #endif /*! _RUNE_H_ */ diff --git a/include/secure/_stdio.h b/include/secure/_stdio.h index 9d1b163..e04c9c5 100644 --- a/include/secure/_stdio.h +++ b/include/secure/_stdio.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -34,8 +34,11 @@ #undef sprintf #undef vsprintf + +#if __DARWIN_C_LEVEL >= 200112L #undef snprintf #undef vsnprintf +#endif /* sprintf, vsprintf, snprintf, vsnprintf */ @@ -50,6 +53,7 @@ extern int __snprintf_chk (char * __restrict, size_t, int, size_t, const char * __restrict, ...) __DARWIN_LDBL_COMPAT (__snprintf_chk); +#if __DARWIN_C_LEVEL >= 200112L #define snprintf(str, len, ...) \ __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__) @@ -66,7 +70,7 @@ extern int __vsnprintf_chk (char * __restrict, size_t, int, size_t, #define vsnprintf(str, len, format, ap) \ __builtin___vsnprintf_chk (str, len, 0, __darwin_obsz(str), format, ap) - +#endif #endif diff --git a/include/secure/_string.h b/include/secure/_string.h index e4d45cb..cba7db4 100644 --- a/include/secure/_string.h +++ b/include/secure/_string.h @@ -33,19 +33,22 @@ #if _USE_FORTIFY_LEVEL > 0 -/* memcpy, mempcpy, memmove, memset, strcpy, stpcpy, strncpy, strcat - and strncat */ +/* memcpy, mempcpy, memmove, memset, strcpy, stpcpy, strncpy, stpncpy, + strcat, and strncat */ #undef memcpy #undef memmove #undef memset #undef strcpy -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#if __DARWIN_C_LEVEL >= 200809L #undef stpcpy -#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +#undef stpncpy +#endif #undef strncpy #undef strcat +#if ! (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 32000) #undef strncat +#endif #define memcpy(dest, src, len) \ ((__darwin_obsz0 (dest) != (size_t) -1) \ @@ -91,7 +94,7 @@ __inline_strcpy_chk (char *__restrict __dest, const char *__restrict __src) return __builtin___strcpy_chk (__dest, __src, __darwin_obsz(__dest)); } -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#if __DARWIN_C_LEVEL >= 200809L #define stpcpy(dest, src) \ ((__darwin_obsz0 (dest) != (size_t) -1) \ ? __builtin___stpcpy_chk (dest, src, __darwin_obsz (dest)) \ @@ -102,7 +105,19 @@ __inline_stpcpy_chk (char *__dest, const char *__src) { return __builtin___stpcpy_chk (__dest, __src, __darwin_obsz(__dest)); } -#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +#define stpncpy(dest, src, len) \ + ((__darwin_obsz0 (dest) != (size_t) -1) \ + ? __builtin___stpncpy_chk (dest, src, len, __darwin_obsz (dest)) \ + : __inline_stpncpy_chk (dest, src, len)) + +static __inline char * +__inline_stpncpy_chk (char *__restrict __dest, const char *__restrict __src, + size_t __len) +{ + return __builtin___stpncpy_chk (__dest, __src, __len, __darwin_obsz(__dest)); +} +#endif #define strncpy(dest, src, len) \ ((__darwin_obsz0 (dest) != (size_t) -1) \ @@ -127,6 +142,7 @@ __inline_strcat_chk (char *__restrict __dest, const char *__restrict __src) return __builtin___strcat_chk (__dest, __src, __darwin_obsz(__dest)); } +#if ! (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 32000) #define strncat(dest, src, len) \ ((__darwin_obsz0 (dest) != (size_t) -1) \ ? __builtin___strncat_chk (dest, src, len, __darwin_obsz (dest)) \ @@ -138,6 +154,7 @@ __inline_strncat_chk (char *__restrict __dest, const char *__restrict __src, { return __builtin___strncat_chk (__dest, __src, __len, __darwin_obsz(__dest)); } +#endif #endif #endif diff --git a/include/spawn.h b/include/spawn.h index c7cd7c6..5553b63 100644 --- a/include/spawn.h +++ b/include/spawn.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2009 Apple Inc. All rights reserved. + * Copyright (c) 2006, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -33,6 +33,8 @@ #include <_types.h> #include /* shared types */ +#include + /* * [SPN] Inclusion of the header may make visible symbols defined * in the , , and headers. @@ -69,36 +71,36 @@ int posix_spawn(pid_t * __restrict, const char * __restrict, const posix_spawn_file_actions_t *, const posix_spawnattr_t * __restrict, char *const __argv[ __restrict], - char *const __envp[ __restrict]); + char *const __envp[ __restrict]) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawnp(pid_t * __restrict, const char * __restrict, const posix_spawn_file_actions_t *, const posix_spawnattr_t * __restrict, char *const __argv[ __restrict], - char *const __envp[ __restrict]); -int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int); + char *const __envp[ __restrict]) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, - int); + int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawn_file_actions_addopen( posix_spawn_file_actions_t * __restrict, int, - const char * __restrict, int, mode_t); -int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *); -int posix_spawn_file_actions_init(posix_spawn_file_actions_t *); -int posix_spawnattr_destroy(posix_spawnattr_t *); + const char * __restrict, int, mode_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int posix_spawn_file_actions_init(posix_spawn_file_actions_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int posix_spawnattr_destroy(posix_spawnattr_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict, - sigset_t * __restrict); + sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawnattr_getflags(const posix_spawnattr_t * __restrict, - short * __restrict); + short * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict, - pid_t * __restrict); + pid_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict, - sigset_t * __restrict); -int posix_spawnattr_init(posix_spawnattr_t *); + sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int posix_spawnattr_init(posix_spawnattr_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict, - const sigset_t * __restrict); -int posix_spawnattr_setflags(posix_spawnattr_t *, short); -int posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t); + const sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int posix_spawnattr_setflags(posix_spawnattr_t *, short) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict, - const sigset_t * __restrict); + const sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); #if 0 /* _POSIX_PRIORITY_SCHEDULING [PS] : not supported */ int posix_spawnattr_setschedparam(posix_spawnattr_t * __restrict, @@ -128,16 +130,19 @@ typedef __darwin_size_t size_t; __BEGIN_DECLS int posix_spawnattr_getbinpref_np(const posix_spawnattr_t * __restrict, - size_t, cpu_type_t *__restrict, size_t *__restrict); + size_t, cpu_type_t *__restrict, size_t *__restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawnattr_setauditsessionport_np(posix_spawnattr_t *__restrict, - mach_port_t); + mach_port_t) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); int posix_spawnattr_setbinpref_np(posix_spawnattr_t * __restrict, - size_t, cpu_type_t *__restrict, size_t *__restrict); + size_t, cpu_type_t *__restrict, size_t *__restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawnattr_setexceptionports_np(posix_spawnattr_t *__restrict, exception_mask_t, mach_port_t, - exception_behavior_t, thread_state_flavor_t); + exception_behavior_t, thread_state_flavor_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int posix_spawnattr_setspecialport_np(posix_spawnattr_t *__restrict, - mach_port_t, int); + mach_port_t, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int posix_spawn_file_actions_addinherit_np(posix_spawn_file_actions_t *, + int) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); + __END_DECLS #endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ diff --git a/include/spawn_private.h b/include/spawn_private.h index 6bf5d42..174b595 100644 --- a/include/spawn_private.h +++ b/include/spawn_private.h @@ -25,8 +25,10 @@ #define _SPAWN_PRIVATE_H_ #include +#include +#include -int posix_spawnattr_getpcontrol_np(const posix_spawnattr_t * __restrict, int * __restrict); -int posix_spawnattr_setpcontrol_np(posix_spawnattr_t *, const int); +int posix_spawnattr_getpcontrol_np(const posix_spawnattr_t * __restrict, int * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +int posix_spawnattr_setpcontrol_np(posix_spawnattr_t *, const int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* !defined _SPAWN_PRIVATE_H_*/ diff --git a/include/standards.h b/include/standards.h index 0c18101..6693238 100644 --- a/include/standards.h +++ b/include/standards.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -29,11 +29,6 @@ #include -#if defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE) -# ifndef __STRICT_ANSI__ -# define __STRICT_ANSI__ -# endif -# undef __STRICT_BSD__ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ +#warning "The use of is deprecated, and it will be removed in a future release." #endif /* _STANDARDS_H */ diff --git a/include/stdarg.h b/include/stdarg.h deleted file mode 100644 index 7585995..0000000 --- a/include/stdarg.h +++ /dev/null @@ -1,9 +0,0 @@ -/* This file is public domain. */ -/* GCC uses its own copy of this header */ -#if defined(__GNUC__) -#include_next -#elif defined(__MWERKS__) -#include "mw_stdarg.h" -#else -#error "This header only supports __MWERKS__." -#endif diff --git a/include/stdbool.h b/include/stdbool.h index 994cee8..5f01433 100644 --- a/include/stdbool.h +++ b/include/stdbool.h @@ -38,8 +38,8 @@ typedef int _Bool; #endif -#define false (bool)0 -#define true (bool)1 +#define false 0 +#define true 1 #endif /* !__cplusplus */ diff --git a/include/stddef.h b/include/stddef.h index 78095de..2559fe2 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -109,12 +109,12 @@ typedef __darwin_wint_t wint_t; #ifdef __STDDEF_H__ #if defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 5 || __GNUC__ > 3) -#ifndef __offsetof /* Deprecated: for source compatability only */ +#ifndef __offsetof /* Deprecated: for source compatibility only */ #define __offsetof(type, field) __builtin_offsetof(type, field) #endif #define offsetof(type, field) __builtin_offsetof(type, field) #else /* ! (gcc >= 3.5) */ -#ifndef __offsetof /* Deprecated: for source compatability only */ +#ifndef __offsetof /* Deprecated: for source compatibility only */ #define __offsetof(type, field) ((size_t)(&((type *)0)->field)) #endif #define offsetof(type, field) ((size_t)(&((type *)0)->field)) diff --git a/include/stdint.h b/include/stdint.h new file mode 100644 index 0000000..a9e312d --- /dev/null +++ b/include/stdint.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2000-2010 Apple Inc. + * All rights reserved. + */ + +#ifndef _STDINT_H_ +#define _STDINT_H_ + +#if __LP64__ +#define __WORDSIZE 64 +#else +#define __WORDSIZE 32 +#endif + +/* from ISO/IEC 988:1999 spec */ + +/* 7.18.1.1 Exact-width integer types */ +#ifndef _INT8_T +#define _INT8_T +typedef signed char int8_t; +#endif /*_INT8_T */ + +#ifndef _INT16_T +#define _INT16_T +typedef short int16_t; +#endif /* _INT16_T */ + +#ifndef _INT32_T +#define _INT32_T +typedef int int32_t; +#endif /* _INT32_T */ + +#ifndef _INT64_T +#define _INT64_T +typedef long long int64_t; +#endif /* _INT64_T */ + +#ifndef _UINT8_T +#define _UINT8_T +typedef unsigned char uint8_t; +#endif /*_UINT8_T */ + +#ifndef _UINT16_T +#define _UINT16_T +typedef unsigned short uint16_t; +#endif /* _UINT16_T */ + +#ifndef _UINT32_T +#define _UINT32_T +typedef unsigned int uint32_t; +#endif /* _UINT32_T */ + +#ifndef _UINT64_T +#define _UINT64_T +typedef unsigned long long uint64_t; +#endif /* _UINT64_T */ + +/* 7.18.1.2 Minimum-width integer types */ +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + + +/* 7.18.1.3 Fastest-width integer types */ +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + + +/* 7.18.1.4 Integer types capable of holding object pointers */ + +#ifndef _INTPTR_T +#define _INTPTR_T +typedef long intptr_t; +#endif /* _INTPTR_T */ + +#ifndef _UINTPTR_T +#define _UINTPTR_T +typedef unsigned long uintptr_t; +#endif /* _UINTPTR_T */ + + +/* 7.18.1.5 Greatest-width integer types */ +#ifndef _INTMAX_T +#define _INTMAX_T +#ifdef __INTMAX_TYPE__ +typedef __INTMAX_TYPE__ intmax_t; +#else /* __INTMAX_TYPE__ */ +typedef long long intmax_t; +#endif /* __INTMAX_TYPE__ */ +#endif /* _INTMAX_T */ + +#ifndef _UINTMAX_T +#define _UINTMAX_T +#ifdef __UINTMAX_TYPE__ +typedef __UINTMAX_TYPE__ uintmax_t; +#else /* __UINTMAX_TYPE__ */ +typedef unsigned long long uintmax_t; +#endif /* __UINTMAX_TYPE__ */ +#endif /* _UINTMAX_T */ + +/* 7.18.2 Limits of specified-width integer types: + * These #defines specify the minimum and maximum limits + * of each of the types declared above. + */ + + +/* 7.18.2.1 Limits of exact-width integer types */ +#define INT8_MAX 127 +#define INT16_MAX 32767 +#define INT32_MAX 2147483647 +#define INT64_MAX 9223372036854775807LL + +#define INT8_MIN -128 +#define INT16_MIN -32768 + /* + Note: the literal "most negative int" cannot be written in C -- + the rules in the standard (section 6.4.4.1 in C99) will give it + an unsigned type, so INT32_MIN (and the most negative member of + any larger signed type) must be written via a constant expression. + */ +#define INT32_MIN (-INT32_MAX-1) +#define INT64_MIN (-INT64_MAX-1) + +#define UINT8_MAX 255 +#define UINT16_MAX 65535 +#define UINT32_MAX 4294967295U +#define UINT64_MAX 18446744073709551615ULL + +/* 7.18.2.2 Limits of minimum-width integer types */ +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +/* 7.18.2.3 Limits of fastest minimum-width integer types */ +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST64_MIN INT64_MIN + +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MAX INT64_MAX + +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +/* 7.18.2.4 Limits of integer types capable of holding object pointers */ + +#if __WORDSIZE == 64 +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#else +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#endif + +#if __WORDSIZE == 64 +#define UINTPTR_MAX UINT64_MAX +#else +#define UINTPTR_MAX UINT32_MAX +#endif + +/* 7.18.2.5 Limits of greatest-width integer types */ +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX + +#define UINTMAX_MAX UINT64_MAX + +/* 7.18.3 "Other" */ +#if __WORDSIZE == 64 +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX +#else +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX +#endif + +/* We have no sig_atomic_t yet, so no SIG_ATOMIC_{MIN,MAX}. + Should end up being {-127,127} or {0,255} ... or bigger. + My bet would be on one of {U}INT32_{MIN,MAX}. */ + +#if __WORDSIZE == 64 +#define SIZE_MAX UINT64_MAX +#else +#define SIZE_MAX UINT32_MAX +#endif + +#ifndef WCHAR_MAX +# ifdef __WCHAR_MAX__ +# define WCHAR_MAX __WCHAR_MAX__ +# else +# define WCHAR_MAX 0x7fffffff +# endif +#endif + +/* WCHAR_MIN should be 0 if wchar_t is an unsigned type and + (-WCHAR_MAX-1) if wchar_t is a signed type. Unfortunately, + it turns out that -fshort-wchar changes the signedness of + the type. */ +#ifndef WCHAR_MIN +# if WCHAR_MAX == 0xffff +# define WCHAR_MIN 0 +# else +# define WCHAR_MIN (-WCHAR_MAX-1) +# endif +#endif + +#define WINT_MIN INT32_MIN +#define WINT_MAX INT32_MAX + +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +/* 7.18.4 Macros for integer constants */ +#define INT8_C(v) (v) +#define INT16_C(v) (v) +#define INT32_C(v) (v) +#define INT64_C(v) (v ## LL) + +#define UINT8_C(v) (v ## U) +#define UINT16_C(v) (v ## U) +#define UINT32_C(v) (v ## U) +#define UINT64_C(v) (v ## ULL) + +#define INTMAX_C(v) (v ## LL) +#define UINTMAX_C(v) (v ## ULL) + +#endif /* _STDINT_H_ */ diff --git a/include/stdio.h b/include/stdio.h index 455960c..3608903 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2005, 2007, 2009 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2005, 2007, 2009, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -61,6 +61,9 @@ #ifndef _STDIO_H_ #define _STDIO_H_ +#include +#include + #include <_types.h> #ifndef _VA_LIST @@ -70,11 +73,6 @@ typedef __darwin_va_list va_list; #endif -#ifndef _OFF_T -#define _OFF_T -typedef __darwin_off_t off_t; -#endif - #ifndef _SIZE_T #define _SIZE_T typedef __darwin_size_t size_t; @@ -163,13 +161,9 @@ typedef struct __sFILE { } FILE; __BEGIN_DECLS -#if __DARWIN_UNIX03 extern FILE *__stdinp; extern FILE *__stdoutp; extern FILE *__stderrp; -#else /* !__DARWIN_UNIX03 */ -extern FILE __sF[]; -#endif /* __DARWIN_UNIX03 */ __END_DECLS #define __SLBF 0x0001 /* line buffered */ @@ -206,11 +200,6 @@ __END_DECLS #define BUFSIZ 1024 /* size of buffer used by setbuf */ #define EOF (-1) -/* - * FOPEN_MAX is a minimum maximum, and is the number of streams that - * stdio can provide without attempting to allocate further resources - * (which could fail). Do not use this for anything. - */ /* must be == _POSIX_STREAM_MAX */ #define FOPEN_MAX 20 /* must be <= OPEN_MAX */ #define FILENAME_MAX 1024 /* must be <= PATH_MAX */ @@ -232,19 +221,20 @@ __END_DECLS #define SEEK_END 2 /* set file offset to EOF plus offset */ #endif -#if __DARWIN_UNIX03 #define stdin __stdinp #define stdout __stdoutp #define stderr __stderrp -#else /* !__DARWIN_UNIX03 */ -#define stdin (&__sF[0]) -#define stdout (&__sF[1]) -#define stderr (&__sF[2]) -#endif /* __DARWIN_UNIX03 */ -/* - * Functions defined in ANSI C standard. - */ +#ifdef _DARWIN_UNLIMITED_STREAMS +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 +#error "_DARWIN_UNLIMITED_STREAMS specified, but -miphoneos-version-min version does not support it." +#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6 +#error "_DARWIN_UNLIMITED_STREAMS specified, but -mmacosx-version-min version does not support it." +#endif +#endif + +/* ANSI-C */ + __BEGIN_DECLS void clearerr(FILE *); int fclose(FILE *); @@ -254,20 +244,20 @@ int fflush(FILE *); int fgetc(FILE *); int fgetpos(FILE * __restrict, fpos_t *); char *fgets(char * __restrict, int, FILE *); -#if defined(__DARWIN_10_6_AND_LATER) && (defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE)) -FILE *fopen(const char * __restrict, const char * __restrict) __DARWIN_EXTSN(fopen); -#else /* < 10.6 || !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ +#if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) +FILE *fopen(const char * __restrict, const char * __restrict) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(fopen)); +#else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ //Begin-Libc #ifndef LIBC_ALIAS_FOPEN //End-Libc -FILE *fopen(const char * __restrict, const char * __restrict) __DARWIN_10_6_AND_LATER_ALIAS(__DARWIN_ALIAS(fopen)); +FILE *fopen(const char * __restrict, const char * __restrict) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen)); //Begin-Libc #else /* LIBC_ALIAS_FOPEN */ FILE *fopen(const char * __restrict, const char * __restrict) LIBC_ALIAS(fopen); #endif /* !LIBC_ALIAS_FOPEN */ //End-Libc -#endif /* >= 10.6 &&_(DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ -int fprintf(FILE * __restrict, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(fprintf); +#endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ +int fprintf(FILE * __restrict, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(fprintf) __printflike(2, 3); int fputc(int, FILE *); //Begin-Libc #ifndef LIBC_ALIAS_FPUTS @@ -283,14 +273,14 @@ size_t fread(void * __restrict, size_t, size_t, FILE * __restrict); #ifndef LIBC_ALIAS_FREOPEN //End-Libc FILE *freopen(const char * __restrict, const char * __restrict, - FILE * __restrict) __DARWIN_ALIAS(freopen); + FILE * __restrict) __DARWIN_ALIAS(freopen); //Begin-Libc #else /* LIBC_ALIAS_FREOPEN */ FILE *freopen(const char * __restrict, const char * __restrict, - FILE * __restrict) LIBC_ALIAS(freopen); + FILE * __restrict) LIBC_ALIAS(freopen); #endif /* !LIBC_ALIAS_FREOPEN */ //End-Libc -int fscanf(FILE * __restrict, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(fscanf); +int fscanf(FILE * __restrict, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(fscanf) __scanflike(2, 3); int fseek(FILE *, long, int); int fsetpos(FILE *, const fpos_t *); long ftell(FILE *); @@ -306,140 +296,99 @@ size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict) LIBC_ int getc(FILE *); int getchar(void); char *gets(char *); -#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) -extern __const int sys_nerr; /* perror(3) external variables */ -extern __const char *__const sys_errlist[]; -#endif void perror(const char *); -int printf(const char * __restrict, ...) __DARWIN_LDBL_COMPAT(printf); +int printf(const char * __restrict, ...) __DARWIN_LDBL_COMPAT(printf) __printflike(1, 2); int putc(int, FILE *); int putchar(int); int puts(const char *); int remove(const char *); int rename (const char *, const char *); void rewind(FILE *); -int scanf(const char * __restrict, ...) __DARWIN_LDBL_COMPAT(scanf); +int scanf(const char * __restrict, ...) __DARWIN_LDBL_COMPAT(scanf) __scanflike(1, 2); void setbuf(FILE * __restrict, char * __restrict); int setvbuf(FILE * __restrict, char * __restrict, int, size_t); -int sprintf(char * __restrict, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(sprintf); -int sscanf(const char * __restrict, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(sscanf); +int sprintf(char * __restrict, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(sprintf) __printflike(2, 3); +int sscanf(const char * __restrict, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(sscanf) __scanflike(2, 3); FILE *tmpfile(void); char *tmpnam(char *); int ungetc(int, FILE *); -int vfprintf(FILE * __restrict, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vfprintf); -int vprintf(const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vprintf); -int vsprintf(char * __restrict, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vsprintf); -#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) -int asprintf(char **, const char *, ...) __DARWIN_LDBL_COMPAT(asprintf); -int vasprintf(char **, const char *, va_list) __DARWIN_LDBL_COMPAT(vasprintf); -#endif +int vfprintf(FILE * __restrict, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vfprintf) __printflike(2, 0); +int vprintf(const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vprintf) __printflike(1, 0); +int vsprintf(char * __restrict, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vsprintf) __printflike(2, 0); __END_DECLS -/* - * Functions defined in POSIX 1003.1. + + +/* Additional functionality provided by: + * POSIX.1-1988 */ -#ifndef _ANSI_SOURCE + +#if __DARWIN_C_LEVEL >= 198808L #define L_ctermid 1024 /* size for ctermid(); PATH_MAX */ __BEGIN_DECLS +#ifndef __CTERMID_DEFINED +/* Multiply defined in stdio.h and unistd.h by SUS */ +#define __CTERMID_DEFINED 1 char *ctermid(char *); -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -char *ctermid_r(char *); -#endif /* not POSIX */ -#if defined(__DARWIN_10_6_AND_LATER) && (defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE)) -FILE *fdopen(int, const char *) __DARWIN_EXTSN(fdopen); -#else /* < 10.6 || !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ +#endif + +#if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) +FILE *fdopen(int, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(fdopen)); +#else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ //Begin-Libc #ifndef LIBC_ALIAS_FDOPEN //End-Libc -FILE *fdopen(int, const char *) __DARWIN_10_6_AND_LATER_ALIAS(__DARWIN_ALIAS(fdopen)); +FILE *fdopen(int, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fdopen)); //Begin-Libc #else /* LIBC_ALIAS_FDOPEN */ FILE *fdopen(int, const char *) LIBC_ALIAS(fdopen); #endif /* !LIBC_ALIAS_FDOPEN */ //End-Libc -#endif /* >= 10.6 &&_(DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -char *fgetln(FILE *, size_t *); -#endif /* not POSIX */ +#endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ int fileno(FILE *); -void flockfile(FILE *); -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -__const char - *fmtcheck(const char *, const char *); -int fpurge(FILE *); -#endif /* not POSIX */ -int fseeko(FILE *, off_t, int); -off_t ftello(FILE *); -int ftrylockfile(FILE *); -void funlockfile(FILE *); -int getc_unlocked(FILE *); -int getchar_unlocked(void); -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -int getw(FILE *); -#endif /* not POSIX */ +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 198808L */ + + +/* Additional functionality provided by: + * POSIX.2-1992 C Language Binding Option + */ + +#if __DARWIN_C_LEVEL >= 199209L +__BEGIN_DECLS int pclose(FILE *); -#if defined(__DARWIN_10_6_AND_LATER) && (defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE)) -FILE *popen(const char *, const char *) __DARWIN_EXTSN(popen); -#else /* < 10.6 || !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ +#if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) +FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(popen)); +#else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ //Begin-Libc #ifndef LIBC_ALIAS_POPEN //End-Libc -FILE *popen(const char *, const char *) __DARWIN_10_6_AND_LATER_ALIAS(__DARWIN_ALIAS(popen)); +FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(popen)); //Begin-Libc #else /* LIBC_ALIAS_POPEN */ FILE *popen(const char *, const char *) LIBC_ALIAS(popen); #endif /* !LIBC_ALIAS_POPEN */ //End-Libc -#endif /* >= 10.6 &&_(DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ -int putc_unlocked(int, FILE *); -int putchar_unlocked(int); -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -int putw(int, FILE *); -void setbuffer(FILE *, char *, int); -int setlinebuf(FILE *); -#endif /* not POSIX */ -int snprintf(char * __restrict, size_t, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(snprintf); -//Begin-Libc -#ifndef LIBC_ALIAS_TEMPNAM -//End-Libc -char *tempnam(const char *, const char *) __DARWIN_ALIAS(tempnam); -//Begin-Libc -#else /* LIBC_ALIAS_TEMPNAM */ -char *tempnam(const char *, const char *) LIBC_ALIAS(tempnam); -#endif /* !LIBC_ALIAS_TEMPNAM */ -//End-Libc -int vfscanf(FILE * __restrict, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vfscanf); -int vscanf(const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vscanf); -int vsnprintf(char * __restrict, size_t, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vsnprintf); -int vsscanf(const char * __restrict, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vsscanf); -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -FILE *zopen(const char *, const char *, int); -#endif /* not POSIX */ +#endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ __END_DECLS +#endif /* __DARWIN_C_LEVEL >= 199209L */ -/* - * Stdio function-access interface. - */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -__BEGIN_DECLS -FILE *funopen(const void *, - int (*)(void *, char *, int), - int (*)(void *, const char *, int), - fpos_t (*)(void *, fpos_t, int), - int (*)(void *)); -__END_DECLS -#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) -#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) -#endif /* not POSIX */ -#endif /* not ANSI */ -/* - * Functions internal to the implementation. + + +/* Additional functionality provided by: + * POSIX.1c-1995, + * POSIX.1i-1995, + * and the omnibus ISO/IEC 9945-1: 1996 */ + +#if __DARWIN_C_LEVEL >= 199506L + +/* Functions internal to the implementation. */ __BEGIN_DECLS int __srget(FILE *); -int __svfscanf(FILE *, const char *, va_list) __DARWIN_LDBL_COMPAT(__svfscanf); +int __svfscanf(FILE *, const char *, va_list) __DARWIN_LDBL_COMPAT(__svfscanf) __scanflike(2, 0); int __swbuf(int, FILE *); __END_DECLS @@ -474,13 +423,31 @@ static __inline int __sputc(int _c, FILE *_p) { #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) #define __sfileno(p) ((p)->_file) -#ifndef _ANSI_SOURCE -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define feof_unlocked(p) __sfeof(p) -#define ferror_unlocked(p) __sferror(p) -#define clearerr_unlocked(p) __sclearerr(p) -#define fileno_unlocked(p) __sfileno(p) -#endif /* not POSIX */ +__BEGIN_DECLS +void flockfile(FILE *); +int ftrylockfile(FILE *); +void funlockfile(FILE *); +int getc_unlocked(FILE *); +int getchar_unlocked(void); +int putc_unlocked(int, FILE *); +int putchar_unlocked(int); + +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +int getw(FILE *); +int putw(int, FILE *); +#endif + +//Begin-Libc +#ifndef LIBC_ALIAS_TEMPNAM +//End-Libc +char *tempnam(const char *, const char *) __DARWIN_ALIAS(tempnam); +//Begin-Libc +#else /* LIBC_ALIAS_TEMPNAM */ +char *tempnam(const char *, const char *) LIBC_ALIAS(tempnam); +#endif /* !LIBC_ALIAS_TEMPNAM */ +//End-Libc +__END_DECLS #ifndef lint #define getc_unlocked(fp) __sgetc(fp) @@ -489,7 +456,96 @@ static __inline int __sputc(int _c, FILE *_p) { #define getchar_unlocked() getc_unlocked(stdin) #define putchar_unlocked(x) putc_unlocked(x, stdout) -#endif /* not ANSI */ +#endif /* __DARWIN_C_LEVEL >= 199506L */ + + + +/* Additional functionality provided by: + * POSIX.1-2001 + * ISO C99 + */ + +#if __DARWIN_C_LEVEL >= 200112L +#ifndef _OFF_T +#define _OFF_T +typedef __darwin_off_t off_t; +#endif + +__BEGIN_DECLS +int fseeko(FILE *, off_t, int); +off_t ftello(FILE *); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200112L */ + +#if __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) +__BEGIN_DECLS +int snprintf(char * __restrict, size_t, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(snprintf) __printflike(3, 4); +int vfscanf(FILE * __restrict, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vfscanf) __scanflike(2, 0); +int vscanf(const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vscanf) __scanflike(1, 0); +int vsnprintf(char * __restrict, size_t, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vsnprintf) __printflike(3, 0); +int vsscanf(const char * __restrict, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vsscanf) __scanflike(2, 0); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) */ + + + +/* Additional functionality provided by: + * POSIX.1-2008 + */ + +#if __DARWIN_C_LEVEL >= 200809L +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __darwin_ssize_t ssize_t; +#endif + +__BEGIN_DECLS +int dprintf(int, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(dprintf) __printflike(2, 3) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +int vdprintf(int, const char * __restrict, va_list) __DARWIN_LDBL_COMPAT(vdprintf) __printflike(2, 0) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +ssize_t getdelim(char ** __restrict, size_t * __restrict, int, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200809L */ + + + +/* Darwin extensions */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +__BEGIN_DECLS +extern __const int sys_nerr; /* perror(3) external variables */ +extern __const char *__const sys_errlist[]; + +int asprintf(char **, const char *, ...) __DARWIN_LDBL_COMPAT(asprintf) __printflike(2, 3); +char *ctermid_r(char *); +char *fgetln(FILE *, size_t *); +__const char *fmtcheck(const char *, const char *); +int fpurge(FILE *); +void setbuffer(FILE *, char *, int); +int setlinebuf(FILE *); +int vasprintf(char **, const char *, va_list) __DARWIN_LDBL_COMPAT(vasprintf) __printflike(2, 0); +FILE *zopen(const char *, const char *, int); + + +/* + * Stdio function-access interface. + */ +FILE *funopen(const void *, + int (*)(void *, char *, int), + int (*)(void *, const char *, int), + fpos_t (*)(void *, fpos_t, int), + int (*)(void *)); +__END_DECLS +#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) +#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) + +#define feof_unlocked(p) __sfeof(p) +#define ferror_unlocked(p) __sferror(p) +#define clearerr_unlocked(p) __sclearerr(p) +#define fileno_unlocked(p) __sfileno(p) + +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + #ifdef _USE_EXTENDED_LOCALES_ #include diff --git a/include/stdlib.h b/include/stdlib.h index c7fa049..2405804 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -178,7 +178,7 @@ void *malloc(size_t); int mblen(const char *, size_t); size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t); int mbtowc(wchar_t * __restrict, const char * __restrict, size_t); -int posix_memalign(void **, size_t, size_t); +int posix_memalign(void **, size_t, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); int rand(void); @@ -330,12 +330,15 @@ typedef __darwin_mode_t mode_t; u_int32_t arc4random(void); -void arc4random_addrandom(unsigned char *dat, int datlen); +void arc4random_addrandom(unsigned char * /*dat*/, int /*datlen*/); +void arc4random_buf(void * /*buf*/, size_t /*nbytes*/) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); void arc4random_stir(void); +u_int32_t + arc4random_uniform(u_int32_t /*upper_bound*/) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); #ifdef __BLOCKS__ -int atexit_b(void (^)(void)); +int atexit_b(void (^)(void)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); void *bsearch_b(const void *, const void *, size_t, - size_t, int (^)(const void *, const void *)); + size_t, int (^)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ /* getcap(3) functions */ @@ -350,7 +353,7 @@ int cgetset(const char *); int cgetstr(char *, const char *, char **); int cgetustr(char *, const char *, char **); -int daemon(int, int) __DARWIN_1050(daemon) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_5,__IPHONE_2_0,__IPHONE_2_0); +int daemon(int, int) __DARWIN_1050(daemon) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_5, __IPHONE_2_0, __IPHONE_2_0); char *devname(dev_t, mode_t); char *devname_r(dev_t, mode_t, char *buf, int len); char *getbsize(int *, long *); @@ -362,25 +365,25 @@ int heapsort(void *, size_t, size_t, int (*)(const void *, const void *)); #ifdef __BLOCKS__ int heapsort_b(void *, size_t, size_t, - int (^)(const void *, const void *)); + int (^)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ int mergesort(void *, size_t, size_t, int (*)(const void *, const void *)); #ifdef __BLOCKS__ int mergesort_b(void *, size_t, size_t, - int (^)(const void *, const void *)); + int (^)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ void psort(void *, size_t, size_t, - int (*)(const void *, const void *)); + int (*)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #ifdef __BLOCKS__ void psort_b(void *, size_t, size_t, - int (^)(const void *, const void *)); + int (^)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ void psort_r(void *, size_t, size_t, void *, - int (*)(void *, const void *, const void *)); + int (*)(void *, const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #ifdef __BLOCKS__ void qsort_b(void *, size_t, size_t, - int (^)(const void *, const void *)); + int (^)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ void qsort_r(void *, size_t, size_t, void *, int (*)(void *, const void *, const void *)); diff --git a/include/string.h b/include/string.h index 2db632d..f56f382 100644 --- a/include/string.h +++ b/include/string.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2007 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2007, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -57,25 +57,24 @@ #ifndef _STRING_H_ #define _STRING_H_ + #include <_types.h> +#include +#include + #ifndef _SIZE_T #define _SIZE_T typedef __darwin_size_t size_t; #endif -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) /* For swab */ -#ifndef _SSIZE_T -#define _SSIZE_T -typedef __darwin_ssize_t ssize_t; -#endif -#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ - #ifndef NULL #define NULL __DARWIN_NULL #endif /* ! NULL */ -#include + + +/* ANSI-C */ __BEGIN_DECLS void *memchr(const void *, int, size_t); @@ -83,10 +82,6 @@ int memcmp(const void *, const void *, size_t); void *memcpy(void *, const void *, size_t); void *memmove(void *, const void *, size_t); void *memset(void *, int, size_t); -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -char *stpcpy(char *, const char *); -char *strcasestr(const char *, const char *); -#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ char *strcat(char *, const char *); char *strchr(const char *, int); int strcmp(const char *, const char *); @@ -102,51 +97,98 @@ char *strerror(int) __DARWIN_ALIAS(strerror); char *strerror(int) LIBC_ALIAS(strerror); #endif /* !LIBC_ALIAS_STRERROR */ //End-Libc -int strerror_r(int, char *, size_t); size_t strlen(const char *); char *strncat(char *, const char *, size_t); int strncmp(const char *, const char *, size_t); char *strncpy(char *, const char *, size_t); -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -char *strnstr(const char *, const char *, size_t); -#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ char *strpbrk(const char *, const char *); char *strrchr(const char *, int); size_t strspn(const char *, const char *); char *strstr(const char *, const char *); char *strtok(char *, const char *); size_t strxfrm(char *, const char *, size_t); +__END_DECLS -/* Nonstandard routines */ -#ifndef _ANSI_SOURCE -void *memccpy(void *, const void *, int, size_t); + + +/* Additional functionality provided by: + * POSIX.1c-1995, + * POSIX.1i-1995, + * and the omnibus ISO/IEC 9945-1: 1996 + */ + +#if __DARWIN_C_LEVEL >= 199506L +__BEGIN_DECLS char *strtok_r(char *, const char *, char **); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 199506L */ + + + +/* Additional functionality provided by: + * POSIX.1-2001 + */ + +#if __DARWIN_C_LEVEL >= 200112L +__BEGIN_DECLS +int strerror_r(int, char *, size_t); char *strdup(const char *); -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -int bcmp(const void *, const void *, size_t); -void bcopy(const void *, void *, size_t); -void bzero(void *, size_t); -int ffs(int); -int ffsl(long); -int fls(int); -int flsl(long); -char *index(const char *, int); -void memset_pattern4(void *, const void *, size_t); -void memset_pattern8(void *, const void *, size_t); -void memset_pattern16(void *, const void *, size_t); -char *rindex(const char *, int); -int strcasecmp(const char *, const char *); +void *memccpy(void *, const void *, int, size_t); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200112L */ + + + +/* Additional functionality provided by: + * POSIX.1-2008 + */ + +#if __DARWIN_C_LEVEL >= 200809L +__BEGIN_DECLS +char *stpcpy(char *, const char *); +char *stpncpy(char *, const char *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +char *strndup(const char *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +size_t strnlen(const char *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +char *strsignal(int sig); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200809L */ + + + +/* Darwin extensions */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __darwin_ssize_t ssize_t; +#endif + +__BEGIN_DECLS +void *memmem(const void *, size_t, const void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +void memset_pattern4(void *, const void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); +void memset_pattern8(void *, const void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); +void memset_pattern16(void *, const void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); + +char *strcasestr(const char *, const char *); +char *strnstr(const char *, const char *, size_t); size_t strlcat(char *, const char *, size_t); size_t strlcpy(char *, const char *, size_t); void strmode(int, char *); -int strncasecmp(const char *, const char *, size_t); char *strsep(char **, const char *); -char *strsignal(int sig); + +/* SUS places swab() in unistd.h. It is listed here for source compatibility */ void swab(const void * __restrict, void * __restrict, ssize_t); -#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ -#endif /* !_ANSI_SOURCE */ __END_DECLS +/* Some functions historically defined in string.h were placed in strings.h + * by SUS. We are using "strings.h" instead of to avoid an issue + * where /Developer/Headers/FlatCarbon/Strings.h could be included instead on + * case-insensitive file systems. + */ +#include "strings.h" +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + + #ifdef _USE_EXTENDED_LOCALES_ #include #endif /* _USE_EXTENDED_LOCALES_ */ diff --git a/include/strings.h b/include/strings.h index f8aba3d..47308ae 100644 --- a/include/strings.h +++ b/include/strings.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2007 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2007, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -55,31 +55,44 @@ * @(#)strings.h 8.1 (Berkeley) 6/2/93 */ -#include - -#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) - -#include - -#else +#ifndef _STRINGS_H_ +#define _STRINGS_H_ #include <_types.h> +#include +#include + #ifndef _SIZE_T #define _SIZE_T typedef __darwin_size_t size_t; #endif __BEGIN_DECLS -int bcmp(const void *, const void *, size_t); -void bcopy(const void *, void *, size_t); -void bzero(void *, size_t); -int ffs(int); -char *index(const char *, int); -char *rindex(const char *, int); -int strcasecmp(const char *, const char *); -int strncasecmp(const char *, const char *, size_t); +/* Removed in Issue 7 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L +int bcmp(const void *, const void *, size_t) __POSIX_C_DEPRECATED(200112L); +void bcopy(const void *, void *, size_t) __POSIX_C_DEPRECATED(200112L); +void bzero(void *, size_t) __POSIX_C_DEPRECATED(200112L); +char *index(const char *, int) __POSIX_C_DEPRECATED(200112L); +char *rindex(const char *, int) __POSIX_C_DEPRECATED(200112L); +#endif + +int ffs(int); +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); +__END_DECLS + +/* Darwin extensions */ +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +__BEGIN_DECLS +int ffsl(long) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int fls(int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int flsl(long) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); __END_DECLS -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ +#include +#endif + +#endif /* _STRINGS_H_ */ diff --git a/include/sys/acl.h b/include/sys/acl.h index 7224b56..f3b26f6 100644 --- a/include/sys/acl.h +++ b/include/sys/acl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,8 +23,37 @@ #ifndef _SYS_ACL_H #define _SYS_ACL_H +#include #include +#define __DARWIN_ACL_READ_DATA (1<<1) +#define __DARWIN_ACL_LIST_DIRECTORY __DARWIN_ACL_READ_DATA +#define __DARWIN_ACL_WRITE_DATA (1<<2) +#define __DARWIN_ACL_ADD_FILE __DARWIN_ACL_WRITE_DATA +#define __DARWIN_ACL_EXECUTE (1<<3) +#define __DARWIN_ACL_SEARCH __DARWIN_ACL_EXECUTE +#define __DARWIN_ACL_DELETE (1<<4) +#define __DARWIN_ACL_APPEND_DATA (1<<5) +#define __DARWIN_ACL_ADD_SUBDIRECTORY __DARWIN_ACL_APPEND_DATA +#define __DARWIN_ACL_DELETE_CHILD (1<<6) +#define __DARWIN_ACL_READ_ATTRIBUTES (1<<7) +#define __DARWIN_ACL_WRITE_ATTRIBUTES (1<<8) +#define __DARWIN_ACL_READ_EXTATTRIBUTES (1<<9) +#define __DARWIN_ACL_WRITE_EXTATTRIBUTES (1<<10) +#define __DARWIN_ACL_READ_SECURITY (1<<11) +#define __DARWIN_ACL_WRITE_SECURITY (1<<12) +#define __DARWIN_ACL_CHANGE_OWNER (1<<13) + +#define __DARWIN_ACL_EXTENDED_ALLOW 1 +#define __DARWIN_ACL_EXTENDED_DENY 2 + +#define __DARWIN_ACL_ENTRY_INHERITED (1<<4) +#define __DARWIN_ACL_ENTRY_FILE_INHERIT (1<<5) +#define __DARWIN_ACL_ENTRY_DIRECTORY_INHERIT (1<<6) +#define __DARWIN_ACL_ENTRY_LIMIT_INHERIT (1<<7) +#define __DARWIN_ACL_ENTRY_ONLY_INHERIT (1<<8) +#define __DARWIN_ACL_FLAG_NO_INHERIT (1<<17) + /* * Implementation constants. * @@ -36,30 +65,30 @@ /* 23.2.2 Individual object access permissions - nonstandard */ typedef enum { - ACL_READ_DATA = KAUTH_VNODE_READ_DATA, - ACL_LIST_DIRECTORY = KAUTH_VNODE_LIST_DIRECTORY, - ACL_WRITE_DATA = KAUTH_VNODE_WRITE_DATA, - ACL_ADD_FILE = KAUTH_VNODE_ADD_FILE, - ACL_EXECUTE = KAUTH_VNODE_EXECUTE, - ACL_SEARCH = KAUTH_VNODE_SEARCH, - ACL_DELETE = KAUTH_VNODE_DELETE, - ACL_APPEND_DATA = KAUTH_VNODE_APPEND_DATA, - ACL_ADD_SUBDIRECTORY = KAUTH_VNODE_ADD_SUBDIRECTORY, - ACL_DELETE_CHILD = KAUTH_VNODE_DELETE_CHILD, - ACL_READ_ATTRIBUTES = KAUTH_VNODE_READ_ATTRIBUTES, - ACL_WRITE_ATTRIBUTES = KAUTH_VNODE_WRITE_ATTRIBUTES, - ACL_READ_EXTATTRIBUTES = KAUTH_VNODE_READ_EXTATTRIBUTES, - ACL_WRITE_EXTATTRIBUTES = KAUTH_VNODE_WRITE_EXTATTRIBUTES, - ACL_READ_SECURITY = KAUTH_VNODE_READ_SECURITY, - ACL_WRITE_SECURITY = KAUTH_VNODE_WRITE_SECURITY, - ACL_CHANGE_OWNER = KAUTH_VNODE_CHANGE_OWNER + ACL_READ_DATA = __DARWIN_ACL_READ_DATA, + ACL_LIST_DIRECTORY = __DARWIN_ACL_LIST_DIRECTORY, + ACL_WRITE_DATA = __DARWIN_ACL_WRITE_DATA, + ACL_ADD_FILE = __DARWIN_ACL_ADD_FILE, + ACL_EXECUTE = __DARWIN_ACL_EXECUTE, + ACL_SEARCH = __DARWIN_ACL_SEARCH, + ACL_DELETE = __DARWIN_ACL_DELETE, + ACL_APPEND_DATA = __DARWIN_ACL_APPEND_DATA, + ACL_ADD_SUBDIRECTORY = __DARWIN_ACL_ADD_SUBDIRECTORY, + ACL_DELETE_CHILD = __DARWIN_ACL_DELETE_CHILD, + ACL_READ_ATTRIBUTES = __DARWIN_ACL_READ_ATTRIBUTES, + ACL_WRITE_ATTRIBUTES = __DARWIN_ACL_WRITE_ATTRIBUTES, + ACL_READ_EXTATTRIBUTES = __DARWIN_ACL_READ_EXTATTRIBUTES, + ACL_WRITE_EXTATTRIBUTES = __DARWIN_ACL_WRITE_EXTATTRIBUTES, + ACL_READ_SECURITY = __DARWIN_ACL_READ_SECURITY, + ACL_WRITE_SECURITY = __DARWIN_ACL_WRITE_SECURITY, + ACL_CHANGE_OWNER = __DARWIN_ACL_CHANGE_OWNER, } acl_perm_t; /* 23.2.5 ACL entry tag type bits - nonstandard */ typedef enum { ACL_UNDEFINED_TAG = 0, - ACL_EXTENDED_ALLOW = KAUTH_ACE_PERMIT, - ACL_EXTENDED_DENY = KAUTH_ACE_DENY + ACL_EXTENDED_ALLOW = __DARWIN_ACL_EXTENDED_ALLOW, + ACL_EXTENDED_DENY = __DARWIN_ACL_EXTENDED_DENY } acl_tag_t; /* 23.2.6 Individual ACL types */ @@ -89,11 +118,12 @@ typedef enum { /* nonstandard ACL / entry flags */ typedef enum { ACL_FLAG_DEFER_INHERIT = (1 << 0), /* tentative */ - ACL_ENTRY_INHERITED = KAUTH_ACE_INHERITED, - ACL_ENTRY_FILE_INHERIT = KAUTH_ACE_FILE_INHERIT, - ACL_ENTRY_DIRECTORY_INHERIT = KAUTH_ACE_DIRECTORY_INHERIT, - ACL_ENTRY_LIMIT_INHERIT = KAUTH_ACE_LIMIT_INHERIT, - ACL_ENTRY_ONLY_INHERIT = KAUTH_ACE_ONLY_INHERIT + ACL_FLAG_NO_INHERIT = __DARWIN_ACL_FLAG_NO_INHERIT, + ACL_ENTRY_INHERITED = __DARWIN_ACL_ENTRY_INHERITED, + ACL_ENTRY_FILE_INHERIT = __DARWIN_ACL_ENTRY_FILE_INHERIT, + ACL_ENTRY_DIRECTORY_INHERIT = __DARWIN_ACL_ENTRY_DIRECTORY_INHERIT, + ACL_ENTRY_LIMIT_INHERIT = __DARWIN_ACL_ENTRY_LIMIT_INHERIT, + ACL_ENTRY_ONLY_INHERIT = __DARWIN_ACL_ENTRY_ONLY_INHERIT } acl_flag_t; /* "External" ACL types */ @@ -108,6 +138,8 @@ typedef struct _acl_entry *acl_entry_t; typedef struct _acl_permset *acl_permset_t; typedef struct _acl_flagset *acl_flagset_t; +typedef u_int64_t acl_permset_mask_t; + __BEGIN_DECLS /* 23.1.6.1 ACL Storage Management */ extern acl_t acl_dup(acl_t acl); @@ -134,6 +166,11 @@ extern int acl_get_perm_np(acl_permset_t permset_d, acl_perm_t perm); extern int acl_get_permset(acl_entry_t entry_d, acl_permset_t *permset_p); extern int acl_set_permset(acl_entry_t entry_d, acl_permset_t permset_d); +/* nonstandard - manipulate permissions within an ACL entry using bitmasks */ +extern int acl_maximal_permset_mask_np(acl_permset_mask_t * mask_p) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +extern int acl_get_permset_mask_np(acl_entry_t entry_d, acl_permset_mask_t * mask_p) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +extern int acl_set_permset_mask_np(acl_entry_t entry_d, acl_permset_mask_t mask) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); + /* nonstandard - manipulate flags on ACLs and entries */ extern int acl_add_flag_np(acl_flagset_t flagset_d, acl_flag_t flag); extern int acl_clear_flags_np(acl_flagset_t flagset_d); diff --git a/include/ucontext.h b/include/ucontext.h index 82254a8..b99a6c7 100644 --- a/include/ucontext.h +++ b/include/ucontext.h @@ -42,15 +42,16 @@ __END_DECLS //End-Libc #ifdef _XOPEN_SOURCE #include +#include __BEGIN_DECLS -int getcontext(ucontext_t *); -void makecontext(ucontext_t *, void (*)(), int, ...); -int setcontext(const ucontext_t *); -int swapcontext(ucontext_t * __restrict, const ucontext_t * __restrict); +int getcontext(ucontext_t *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0); +void makecontext(ucontext_t *, void (*)(), int, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0); +int setcontext(const ucontext_t *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0); +int swapcontext(ucontext_t * __restrict, const ucontext_t * __restrict) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0); __END_DECLS #else /* !_XOPEN_SOURCE */ -#error ucontext routines are deprecated, and require _XOPEN_SOURCE to be defined +#error The deprecated ucontext routines require _XOPEN_SOURCE to be defined #endif /* _XOPEN_SOURCE */ //Begin-Libc #endif /* __LIBC__ */ diff --git a/include/unistd.h b/include/unistd.h index d086ae8..1cd221c 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2002-2006, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2002-2006, 2008-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -70,13 +70,7 @@ #include <_types.h> #include - -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#ifndef _DEV_T -#define _DEV_T -typedef __darwin_dev_t dev_t; -#endif -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ +#include #ifndef _GID_T #define _GID_T @@ -88,13 +82,6 @@ typedef __darwin_gid_t gid_t; typedef __darwin_intptr_t intptr_t; #endif -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#ifndef _MODE_T -#define _MODE_T -typedef __darwin_mode_t mode_t; -#endif -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ - #ifndef _OFF_T #define _OFF_T typedef __darwin_off_t off_t; @@ -127,20 +114,14 @@ typedef __darwin_uid_t uid_t; /* user id */ typedef __darwin_useconds_t useconds_t; #endif -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#ifndef _UUID_T -#define _UUID_T -typedef __darwin_uuid_t uuid_t; -#endif /* _UUID_T */ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ +#ifndef NULL +#define NULL __DARWIN_NULL +#endif /* ! NULL */ #define STDIN_FILENO 0 /* standard input file descriptor */ #define STDOUT_FILENO 1 /* standard output file descriptor */ #define STDERR_FILENO 2 /* standard error file descriptor */ -#ifndef NULL -#define NULL __DARWIN_NULL -#endif /* ! NULL */ /* Version test macros */ /* _POSIX_VERSION and _POSIX2_VERSION from sys/unistd.h */ @@ -200,6 +181,7 @@ typedef __darwin_uuid_t uuid_t; #define _POSIX_VDISABLE 0xff /* same as sys/termios.h */ #endif /* _POSIX_VDISABLE */ +#if __DARWIN_C_LEVEL >= 199209L #define _POSIX2_C_BIND 200112L #define _POSIX2_C_DEV 200112L /* c99 command */ #define _POSIX2_CHAR_TERM 200112L @@ -214,31 +196,62 @@ typedef __darwin_uuid_t uuid_t; #define _POSIX2_PBS_TRACK (-1) #define _POSIX2_SW_DEV 200112L #define _POSIX2_UPE 200112L /* XXXX no fc, newgrp, tabs */ +#endif /* __DARWIN_C_LEVEL */ -#define _V6_ILP32_OFF32 (-1) -#define _V6_ILP32_OFFBIG (1) -#define _V6_LP64_OFF64 (-1) -#define _V6_LPBIG_OFFBIG (-1) +#define __ILP32_OFF32 (-1) +#define __ILP32_OFFBIG (-1) +#define __LP64_OFF64 (-1) +#define __LPBIG_OFFBIG (-1) -#define _XBS5_ILP32_OFF32 _V6_ILP32_OFF32 /* legacy */ -#define _XBS5_ILP32_OFFBIG _V6_ILP32_OFFBIG /* legacy */ -#define _XBS5_LP64_OFF64 _V6_LP64_OFF64 /* legacy */ -#define _XBS5_LPBIG_OFFBIG _V6_LPBIG_OFFBIG /* legacy */ +#ifdef __LP64__ +#undef __LP64_OFF64 +#define __LP64_OFF64 (1) +#undef __LPBIG_OFFBIG +#define __LPBIG_OFFBIG (1) +#else +#undef __ILP32_OFFBIG +#define __ILP32_OFFBIG (1) +#endif +#if __DARWIN_C_LEVEL >= 200112L +#define _POSIX_V6_ILP32_OFF32 __ILP32_OFF32 +#define _POSIX_V6_ILP32_OFFBIG __ILP32_OFFBIG +#define _POSIX_V6_LP64_OFF64 __LP64_OFF64 +#define _POSIX_V6_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL >= 200112L */ + +#if __DARWIN_C_LEVEL >= 200809L +#define _POSIX_V7_ILP32_OFF32 __ILP32_OFF32 +#define _POSIX_V7_ILP32_OFFBIG __ILP32_OFFBIG +#define _POSIX_V7_LP64_OFF64 __LP64_OFF64 +#define _POSIX_V7_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL >= 200809L */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define _V6_ILP32_OFF32 __ILP32_OFF32 +#define _V6_ILP32_OFFBIG __ILP32_OFFBIG +#define _V6_LP64_OFF64 __LP64_OFF64 +#define _V6_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 7 */ +#define _XBS5_ILP32_OFF32 __ILP32_OFF32 +#define _XBS5_ILP32_OFFBIG __ILP32_OFFBIG +#define _XBS5_LP64_OFF64 __LP64_OFF64 +#define _XBS5_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL < 200809L */ + +#if __DARWIN_C_LEVEL >= 199506L /* This really should be XSI */ #define _XOPEN_CRYPT (1) #define _XOPEN_ENH_I18N (1) /* XXX required */ #define _XOPEN_LEGACY (-1) /* no ftime gcvt, wcswcs */ #define _XOPEN_REALTIME (-1) /* no q'ed signals, mq_* */ #define _XOPEN_REALTIME_THREADS (-1) /* no posix_spawn, et. al. */ #define _XOPEN_SHM (1) -#define _XOPEN_STREAMS (-1) +#define _XOPEN_STREAMS (-1) /* Issue 6 */ #define _XOPEN_UNIX (1) - - -#define F_ULOCK 0 /* unlock locked section */ -#define F_LOCK 1 /* lock a section for exclusive use */ -#define F_TLOCK 2 /* test and lock a section for exclusive use */ -#define F_TEST 3 /* test a section for locks by other procs */ +#endif /* XSI */ /* configurable system variables */ #define _SC_ARG_MAX 1 @@ -268,6 +281,8 @@ typedef __darwin_uuid_t uuid_t; #define _SC_2_UPE 25 #define _SC_STREAM_MAX 26 #define _SC_TZNAME_MAX 27 + +#if __DARWIN_C_LEVEL >= 199309L #define _SC_ASYNCHRONOUS_IO 28 #define _SC_PAGESIZE 29 #define _SC_MEMLOCK 30 @@ -293,10 +308,14 @@ typedef __darwin_uuid_t uuid_t; #define _SC_SEM_VALUE_MAX 50 #define _SC_SIGQUEUE_MAX 51 #define _SC_TIMER_MAX 52 -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#endif /* __DARWIN_C_LEVEL >= 199309L */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL #define _SC_NPROCESSORS_CONF 57 #define _SC_NPROCESSORS_ONLN 58 -#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#if __DARWIN_C_LEVEL >= 200112L #define _SC_2_PBS 59 #define _SC_2_PBS_ACCOUNTING 60 #define _SC_2_PBS_CHECKPOINT 61 @@ -348,33 +367,52 @@ typedef __darwin_uuid_t uuid_t; #define _SC_IPV6 118 #define _SC_RAW_SOCKETS 119 #define _SC_SYMLOOP_MAX 120 +#endif /* __DARWIN_C_LEVEL >= 200112L */ + +#if __DARWIN_C_LEVEL >= 199506L /* Really XSI */ #define _SC_ATEXIT_MAX 107 #define _SC_IOV_MAX 56 #define _SC_PAGE_SIZE _SC_PAGESIZE #define _SC_XOPEN_CRYPT 108 #define _SC_XOPEN_ENH_I18N 109 -#define _SC_XOPEN_LEGACY 110 -#define _SC_XOPEN_REALTIME 111 -#define _SC_XOPEN_REALTIME_THREADS 112 +#define _SC_XOPEN_LEGACY 110 /* Issue 6 */ +#define _SC_XOPEN_REALTIME 111 /* Issue 6 */ +#define _SC_XOPEN_REALTIME_THREADS 112 /* Issue 6 */ #define _SC_XOPEN_SHM 113 -#define _SC_XOPEN_STREAMS 114 +#define _SC_XOPEN_STREAMS 114 /* Issue 6 */ #define _SC_XOPEN_UNIX 115 #define _SC_XOPEN_VERSION 116 #define _SC_XOPEN_XCU_VERSION 121 +#endif /* XSI */ + +#if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 7 */ #define _SC_XBS5_ILP32_OFF32 122 #define _SC_XBS5_ILP32_OFFBIG 123 #define _SC_XBS5_LP64_OFF64 124 #define _SC_XBS5_LPBIG_OFFBIG 125 +#endif /* __DARWIN_C_LEVEL <= 200809L */ + +#if __DARWIN_C_LEVEL >= 200112L #define _SC_SS_REPL_MAX 126 #define _SC_TRACE_EVENT_NAME_MAX 127 #define _SC_TRACE_NAME_MAX 128 #define _SC_TRACE_SYS_MAX 129 #define _SC_TRACE_USER_EVENT_MAX 130 +#endif + +#if __DARWIN_C_LEVEL < 200112L || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 6 */ #define _SC_PASS_MAX 131 +#endif -#ifndef _CS_PATH /* XXX temporary #ifdef'ed for */ +#if __DARWIN_C_LEVEL >= 199209L +#ifndef _CS_PATH /* Defined in */ #define _CS_PATH 1 #endif +#endif + +#if __DARWIN_C_LEVEL >= 200112 #define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 2 #define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 3 #define _CS_POSIX_V6_ILP32_OFF32_LIBS 4 @@ -388,8 +426,10 @@ typedef __darwin_uuid_t uuid_t; #define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 12 #define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 13 #define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 14 +#endif -/* reserved for compatibility with Issue 5 */ +#if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 7 */ #define _CS_XBS5_ILP32_OFF32_CFLAGS 20 #define _CS_XBS5_ILP32_OFF32_LDFLAGS 21 #define _CS_XBS5_ILP32_OFF32_LIBS 22 @@ -406,19 +446,33 @@ typedef __darwin_uuid_t uuid_t; #define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 33 #define _CS_XBS5_LPBIG_OFFBIG_LIBS 34 #define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 35 +#endif +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL #define _CS_DARWIN_USER_DIR 65536 #define _CS_DARWIN_USER_TEMP_DIR 65537 #define _CS_DARWIN_USER_CACHE_DIR 65538 +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ -__BEGIN_DECLS +#ifdef _DARWIN_UNLIMITED_GETGROUPS +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 +#error "_DARWIN_UNLIMITED_GETGROUPS specified, but -miphoneos-version-min version does not support it." +#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6 +#error "_DARWIN_UNLIMITED_GETGROUPS specified, but -mmacosx-version-min version does not support it." +#endif +#endif + +/* POSIX.1-1990 */ + +__BEGIN_DECLS void _exit(int) __dead2; int access(const char *, int); unsigned int alarm(unsigned int); int chdir(const char *); int chown(const char *, uid_t, gid_t); + //Begin-Libc #ifndef LIBC_ALIAS_CLOSE //End-Libc @@ -428,65 +482,126 @@ int close(int) __DARWIN_ALIAS_C(close); int close(int) LIBC_ALIAS_C(close); #endif /* !LIBC_ALIAS_CLOSE */ //End-Libc -//Begin-Libc -#ifndef LIBC_ALIAS_CONFSTR -//End-Libc -size_t confstr(int, char *, size_t) __DARWIN_ALIAS(confstr); -//Begin-Libc -#else /* LIBC_ALIAS_CONFSTR */ -size_t confstr(int, char *, size_t) LIBC_ALIAS(confstr); -#endif /* !LIBC_ALIAS_CONFSTR */ -//End-Libc -char *crypt(const char *, const char *); -char *ctermid(char *); + int dup(int); int dup2(int, int); -#if __DARWIN_UNIX03 -//Begin-Libc -#ifndef LIBC_ALIAS_ENCRYPT -//End-Libc -void encrypt(char *, int) __DARWIN_ALIAS(encrypt); -//Begin-Libc -#else /* LIBC_ALIAS_ENCRYPT */ -void encrypt(char *, int) LIBC_ALIAS(encrypt); -#endif /* !LIBC_ALIAS_ENCRYPT */ -//End-Libc -#else /* !__DARWIN_UNIX03 */ -int encrypt(char *, int); -#endif /* __DARWIN_UNIX03 */ int execl(const char *, const char *, ...); int execle(const char *, const char *, ...); int execlp(const char *, const char *, ...); int execv(const char *, char * const *); int execve(const char *, char * const *, char * const *); int execvp(const char *, char * const *); -int fchown(int, uid_t, gid_t); -int fchdir(int); pid_t fork(void); long fpathconf(int, int); -//Begin-Libc -#ifndef LIBC_ALIAS_FSYNC -//End-Libc -int fsync(int) __DARWIN_ALIAS_C(fsync); -//Begin-Libc -#else /* LIBC_ALIAS_FSYNC */ -int fsync(int) LIBC_ALIAS_C(fsync); -#endif /* !LIBC_ALIAS_FSYNC */ -//End-Libc -int ftruncate(int, off_t); char *getcwd(char *, size_t); gid_t getegid(void); uid_t geteuid(void); gid_t getgid(void); #if defined(_DARWIN_UNLIMITED_GETGROUPS) || defined(_DARWIN_C_SOURCE) -int getgroups(int, gid_t []) __DARWIN_EXTSN(getgroups); +int getgroups(int, gid_t []) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(getgroups)); #else /* !_DARWIN_UNLIMITED_GETGROUPS && !_DARWIN_C_SOURCE */ int getgroups(int, gid_t []); #endif /* _DARWIN_UNLIMITED_GETGROUPS || _DARWIN_C_SOURCE */ -long gethostid(void); -int gethostname(char *, size_t); char *getlogin(void); -int getlogin_r(char *, size_t); +pid_t getpgrp(void); +pid_t getpid(void); +pid_t getppid(void); +uid_t getuid(void); +int isatty(int); +int link(const char *, const char *); +off_t lseek(int, off_t, int); +long pathconf(const char *, int); + +//Begin-Libc +#ifndef LIBC_ALIAS_PAUSE +//End-Libc +int pause(void) __DARWIN_ALIAS_C(pause); +//Begin-Libc +#else /* LIBC_ALIAS_PAUSE */ +int pause(void) LIBC_ALIAS_C(pause); +#endif /* !LIBC_ALIAS_PAUSE */ +//End-Libc + +int pipe(int [2]); + +//Begin-Libc +#ifndef LIBC_ALIAS_READ +//End-Libc +ssize_t read(int, void *, size_t) __DARWIN_ALIAS_C(read); +//Begin-Libc +#else /* LIBC_ALIAS_READ */ +ssize_t read(int, void *, size_t) LIBC_ALIAS_C(read); +#endif /* !LIBC_ALIAS_READ */ +//End-Libc + +int rmdir(const char *); +int setgid(gid_t); +int setpgid(pid_t, pid_t); +pid_t setsid(void); +int setuid(uid_t); + +//Begin-Libc +#ifndef LIBC_ALIAS_SLEEP +//End-Libc +unsigned int + sleep(unsigned int) __DARWIN_ALIAS_C(sleep); +//Begin-Libc +#else /* LIBC_ALIAS_SLEEP */ +unsigned int + sleep(unsigned int) LIBC_ALIAS_C(sleep); +#endif /* !LIBC_ALIAS_SLEEP */ +//End-Libc + +long sysconf(int); +pid_t tcgetpgrp(int); +int tcsetpgrp(int, pid_t); +char *ttyname(int); + +#if __DARWIN_UNIX03 +//Begin-Libc +#ifndef LIBC_ALIAS_TTYNAME_R +//End-Libc +int ttyname_r(int, char *, size_t) __DARWIN_ALIAS(ttyname_r); +//Begin-Libc +#else /* LIBC_ALIAS_TTYNAME_R */ +int ttyname_r(int, char *, size_t) LIBC_ALIAS(ttyname_r); +#endif /* !LIBC_ALIAS_TTYNAME_R */ +//End-Libc +#else /* !__DARWIN_UNIX03 */ +char *ttyname_r(int, char *, size_t); +#endif /* __DARWIN_UNIX03 */ + +int unlink(const char *); + +//Begin-Libc +#ifndef LIBC_ALIAS_WRITE +//End-Libc +ssize_t write(int, const void *, size_t) __DARWIN_ALIAS_C(write); +//Begin-Libc +#else /* LIBC_ALIAS_WRITE */ +ssize_t write(int, const void *, size_t) LIBC_ALIAS_C(write); +#endif /* !LIBC_ALIAS_WRITE */ +//End-Libc +__END_DECLS + + + +/* Additional functionality provided by: + * POSIX.2-1992 C Language Binding Option + */ + +#if __DARWIN_C_LEVEL >= 199209L +__BEGIN_DECLS +//Begin-Libc +#ifndef LIBC_ALIAS_CONFSTR +//End-Libc +size_t confstr(int, char *, size_t) __DARWIN_ALIAS(confstr); +//Begin-Libc +#else /* LIBC_ALIAS_CONFSTR */ +size_t confstr(int, char *, size_t) LIBC_ALIAS(confstr); +#endif /* !LIBC_ALIAS_CONFSTR */ +//End-Libc + //Begin-Libc #ifndef LIBC_ALIAS_GETOPT //End-Libc @@ -496,14 +611,72 @@ int getopt(int, char * const [], const char *) __DARWIN_ALIAS(getopt); int getopt(int, char * const [], const char *) LIBC_ALIAS(getopt); #endif /* !LIBC_ALIAS_GETOPT */ //End-Libc + +extern char *optarg; /* getopt(3) external variables */ +extern int optind, opterr, optopt; +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 199209L */ + + + +/* Additional functionality provided by: + * POSIX.1c-1995, + * POSIX.1i-1995, + * and the omnibus ISO/IEC 9945-1: 1996 + */ + +#if __DARWIN_C_LEVEL >= 199506L + /* These F_* are really XSI or Issue 6 */ +#define F_ULOCK 0 /* unlock locked section */ +#define F_LOCK 1 /* lock a section for exclusive use */ +#define F_TLOCK 2 /* test and lock a section for exclusive use */ +#define F_TEST 3 /* test a section for locks by other procs */ + + __BEGIN_DECLS + +/* Begin XSI */ +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +void *brk(const void *); +int chroot(const char *) __POSIX_C_DEPRECATED(199506L); +#endif + +char *crypt(const char *, const char *); +#ifndef __CTERMID_DEFINED +/* Multiply defined in stdio.h and unistd.h by SUS */ +#define __CTERMID_DEFINED 1 +char *ctermid(char *); +#endif +#if __DARWIN_UNIX03 +//Begin-Libc +#ifndef LIBC_ALIAS_ENCRYPT +//End-Libc +void encrypt(char *, int) __DARWIN_ALIAS(encrypt); +//Begin-Libc +#else /* LIBC_ALIAS_ENCRYPT */ +void encrypt(char *, int) LIBC_ALIAS(encrypt); +#endif /* !LIBC_ALIAS_ENCRYPT */ +//End-Libc +#else /* !__DARWIN_UNIX03 */ +int encrypt(char *, int); +#endif /* __DARWIN_UNIX03 */ +int fchdir(int); +long gethostid(void); pid_t getpgid(pid_t); -pid_t getpgrp(void); -pid_t getpid(void); -pid_t getppid(void); pid_t getsid(pid_t); -uid_t getuid(void); -char *getwd(char *); /* obsoleted by getcwd() */ -int isatty(int); + +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +int getdtablesize(void) __POSIX_C_DEPRECATED(199506L); +int getpagesize(void) __pure2 __POSIX_C_DEPRECATED(199506L); +char *getpass(const char *) __POSIX_C_DEPRECATED(199506L); +#endif + +/* Removed in Issue 7 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L +char *getwd(char *) __POSIX_C_DEPRECATED(200112L); /* obsoleted by getcwd() */ +#endif + //Begin-Libc #ifndef LIBC_ALIAS_LCHOWN //End-Libc @@ -513,7 +686,7 @@ int lchown(const char *, uid_t, gid_t) __DARWIN_ALIAS(lchown); int lchown(const char *, uid_t, gid_t) LIBC_ALIAS(lchown); #endif /* !LIBC_ALIAS_LCHOWN */ //End-Libc -int link(const char *, const char *); + //Begin-Libc #ifndef LIBC_ALIAS_LOCKF //End-Libc @@ -523,7 +696,7 @@ int lockf(int, int, off_t) __DARWIN_ALIAS_C(lockf); int lockf(int, int, off_t) LIBC_ALIAS_C(lockf); #endif /* !LIBC_ALIAS_LOCKF */ //End-Libc -off_t lseek(int, off_t, int); + //Begin-Libc #ifndef LIBC_ALIAS_NICE //End-Libc @@ -533,17 +706,7 @@ int nice(int) __DARWIN_ALIAS(nice); int nice(int) LIBC_ALIAS(nice); #endif /* !LIBC_ALIAS_NICE */ //End-Libc -long pathconf(const char *, int); -//Begin-Libc -#ifndef LIBC_ALIAS_PAUSE -//End-Libc -int pause(void) __DARWIN_ALIAS_C(pause); -//Begin-Libc -#else /* LIBC_ALIAS_PAUSE */ -int pause(void) LIBC_ALIAS_C(pause); -#endif /* !LIBC_ALIAS_PAUSE */ -//End-Libc -int pipe(int [2]); + //Begin-Libc #ifndef LIBC_ALIAS_PREAD //End-Libc @@ -553,6 +716,7 @@ ssize_t pread(int, void *, size_t, off_t) __DARWIN_ALIAS_C(pread); ssize_t pread(int, void *, size_t, off_t) LIBC_ALIAS_C(pread); #endif /* !LIBC_ALIAS_PREAD */ //End-Libc + //Begin-Libc #ifndef LIBC_ALIAS_PWRITE //End-Libc @@ -562,21 +726,14 @@ ssize_t pwrite(int, const void *, size_t, off_t) __DARWIN_ALIAS_C(pwrite); ssize_t pwrite(int, const void *, size_t, off_t) LIBC_ALIAS_C(pwrite); #endif /* !LIBC_ALIAS_PWRITE */ //End-Libc -//Begin-Libc -#ifndef LIBC_ALIAS_READ -//End-Libc -ssize_t read(int, void *, size_t) __DARWIN_ALIAS_C(read); -//Begin-Libc -#else /* LIBC_ALIAS_READ */ -ssize_t read(int, void *, size_t) LIBC_ALIAS_C(read); -#endif /* !LIBC_ALIAS_READ */ -//End-Libc -ssize_t readlink(const char * __restrict, char * __restrict, size_t); -int rmdir(const char *); -int setegid(gid_t); -int seteuid(uid_t); -int setgid(gid_t); -int setpgid(pid_t, pid_t); + +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +/* Note that Issue 5 changed the argument as intprt_t, + * but we keep it as int for binary compatability. */ +void *sbrk(int); +#endif + #if __DARWIN_UNIX03 //Begin-Libc #ifndef LIBC_ALIAS_SETPGRP @@ -590,6 +747,7 @@ pid_t setpgrp(void) LIBC_ALIAS(setpgrp); #else /* !__DARWIN_UNIX03 */ int setpgrp(pid_t pid, pid_t pgrp); /* obsoleted by setpgid() */ #endif /* __DARWIN_UNIX03 */ + //Begin-Libc #ifndef LIBC_ALIAS_SETREGID //End-Libc @@ -599,6 +757,7 @@ int setregid(gid_t, gid_t) __DARWIN_ALIAS(setregid); int setregid(gid_t, gid_t) LIBC_ALIAS(setregid); #endif /* !LIBC_ALIAS_SETREGID */ //End-Libc + //Begin-Libc #ifndef LIBC_ALIAS_SETREUID //End-Libc @@ -608,43 +767,11 @@ int setreuid(uid_t, uid_t) __DARWIN_ALIAS(setreuid); int setreuid(uid_t, uid_t) LIBC_ALIAS(setreuid); #endif /* !LIBC_ALIAS_SETREUID */ //End-Libc -pid_t setsid(void); -int setuid(uid_t); -//Begin-Libc -#ifndef LIBC_ALIAS_SLEEP -//End-Libc -unsigned int - sleep(unsigned int) __DARWIN_ALIAS_C(sleep); -//Begin-Libc -#else /* LIBC_ALIAS_SLEEP */ -unsigned int - sleep(unsigned int) LIBC_ALIAS_C(sleep); -#endif /* !LIBC_ALIAS_SLEEP */ -//End-Libc + void swab(const void * __restrict, void * __restrict, ssize_t); -int symlink(const char *, const char *); void sync(void); -long sysconf(int); -pid_t tcgetpgrp(int); -int tcsetpgrp(int, pid_t); int truncate(const char *, off_t); -char *ttyname(int); -#if __DARWIN_UNIX03 -//Begin-Libc -#ifndef LIBC_ALIAS_TTYNAME_R -//End-Libc -int ttyname_r(int, char *, size_t) __DARWIN_ALIAS(ttyname_r); -//Begin-Libc -#else /* LIBC_ALIAS_TTYNAME_R */ -int ttyname_r(int, char *, size_t) LIBC_ALIAS(ttyname_r); -#endif /* !LIBC_ALIAS_TTYNAME_R */ -//End-Libc -#else /* !__DARWIN_UNIX03 */ -char *ttyname_r(int, char *, size_t); -#endif /* __DARWIN_UNIX03 */ -useconds_t - ualarm(useconds_t, useconds_t); -int unlink(const char *); +useconds_t ualarm(useconds_t, useconds_t); //Begin-Libc #ifndef LIBC_ALIAS_USLEEP //End-Libc @@ -655,42 +782,77 @@ int usleep(useconds_t) LIBC_ALIAS_C(usleep); #endif /* !LIBC_ALIAS_USLEEP */ //End-Libc pid_t vfork(void); +/* End XSI */ + //Begin-Libc -#ifndef LIBC_ALIAS_WRITE +#ifndef LIBC_ALIAS_FSYNC //End-Libc -ssize_t write(int, const void *, size_t) __DARWIN_ALIAS_C(write); +int fsync(int) __DARWIN_ALIAS_C(fsync); //Begin-Libc -#else /* LIBC_ALIAS_WRITE */ -ssize_t write(int, const void *, size_t) LIBC_ALIAS_C(write); -#endif /* !LIBC_ALIAS_WRITE */ +#else /* LIBC_ALIAS_FSYNC */ +int fsync(int) LIBC_ALIAS_C(fsync); +#endif /* !LIBC_ALIAS_FSYNC */ //End-Libc -extern char *optarg; /* getopt(3) external variables */ -extern int optind, opterr, optopt; +int ftruncate(int, off_t); +int getlogin_r(char *, size_t); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 199506L */ + + + +/* Additional functionality provided by: + * POSIX.1-2001 + * ISO C99 + */ + +#if __DARWIN_C_LEVEL >= 200112L +__BEGIN_DECLS +int fchown(int, uid_t, gid_t); +int gethostname(char *, size_t); +ssize_t readlink(const char * __restrict, char * __restrict, size_t); +int setegid(gid_t); +int seteuid(uid_t); +int symlink(const char *, const char *); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200112L */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) + + +/* Darwin extensions */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL #include +#ifndef _DEV_T +#define _DEV_T +typedef __darwin_dev_t dev_t; +#endif + +#ifndef _MODE_T +#define _MODE_T +typedef __darwin_mode_t mode_t; +#endif + +#ifndef _UUID_T +#define _UUID_T +typedef __darwin_uuid_t uuid_t; +#endif /* _UUID_T */ + +__BEGIN_DECLS void _Exit(int) __dead2; int accessx_np(const struct accessx_descriptor *, size_t, int *, uid_t); int acct(const char *); int add_profil(char *, size_t, unsigned long, unsigned int); -void *brk(const void *); -int chroot(const char *); void endusershell(void); int execvP(const char *, const char *, char * const *); char *fflagstostr(unsigned long); -int getdtablesize(void); int getdomainname(char *, int); int getgrouplist(const char *, int, int *, int *); -int gethostuuid(uuid_t, const struct timespec *); +int gethostuuid(uuid_t, const struct timespec *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); mode_t getmode(const void *, mode_t); -int getpagesize(void) __pure2; -char *getpass(const char *); int getpeereid(int, uid_t *, gid_t *); -int getpgid(pid_t _pid); int getsgroups_np(int *, uuid_t); -int getsid(pid_t _pid); char *getusershell(void); int getwgroups_np(int *, uuid_t); int initgroups(const char *, int); @@ -714,7 +876,6 @@ int revoke(const char *); int rresvport(int *); int rresvport_af(int *, int); int ruserok(const char *, int, const char *, const char *); -void *sbrk(int); int setdomainname(const char *, int); int setgroups(int, const gid_t *); void sethostid(long); @@ -736,7 +897,7 @@ int setlogin(const char *); //Begin-Libc #ifndef LIBC_ALIAS_SETMODE //End-Libc -void *setmode(const char *) __DARWIN_ALIAS(setmode); +void *setmode(const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(setmode)); //Begin-Libc #else /* LIBC_ALIAS_SETMODE */ void *setmode(const char *) LIBC_ALIAS(setmode); @@ -760,8 +921,8 @@ int getsubopt(char **, char * const *, char **); /* HFS & HFS Plus semantics system calls go here */ #ifdef __LP64__ -int fgetattrlist(int,void*,void*,size_t,unsigned int); -int fsetattrlist(int,void*,void*,size_t,unsigned int); +int fgetattrlist(int,void*,void*,size_t,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +int fsetattrlist(int,void*,void*,size_t,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); //Begin-Libc #ifndef LIBC_ALIAS_GETATTRLIST //End-Libc @@ -784,8 +945,8 @@ int exchangedata(const char*,const char*,unsigned int); int getdirentriesattr(int,void*,void*,size_t,unsigned int*,unsigned int*,unsigned int*,unsigned int); #else /* __LP64__ */ -int fgetattrlist(int,void*,void*,size_t,unsigned long); -int fsetattrlist(int,void*,void*,size_t,unsigned long); +int fgetattrlist(int,void*,void*,size_t,unsigned long) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +int fsetattrlist(int,void*,void*,size_t,unsigned long) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); //Begin-Libc #ifndef LIBC_ALIAS_GETATTRLIST //End-Libc @@ -814,11 +975,11 @@ struct searchstate; int searchfs(const char *, struct fssearchblock *, unsigned long *, unsigned int, unsigned int, struct searchstate *); int fsctl(const char *,unsigned long,void*,unsigned int); -int ffsctl(int,unsigned long,void*,unsigned int); +int ffsctl(int,unsigned long,void*,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); extern int optreset; -#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ __END_DECLS +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ -#endif /* !_UNISTD_H_ */ +#endif /* _UNISTD_H_ */ diff --git a/include/utmpx.h b/include/utmpx.h index d902550..616b4c0 100644 --- a/include/utmpx.h +++ b/include/utmpx.h @@ -62,6 +62,8 @@ #include <_types.h> #include +#include +#include #ifndef _PID_T #define _PID_T @@ -144,15 +146,15 @@ __BEGIN_DECLS void endutxent(void); #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -void endutxent_wtmp(void); +void endutxent_wtmp(void) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); struct lastlogx * - getlastlogx(uid_t, struct lastlogx *); + getlastlogx(uid_t, struct lastlogx *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); struct lastlogx * - getlastlogxbyname(const char*, struct lastlogx *); + getlastlogxbyname(const char*, struct lastlogx *)__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); #ifdef UNIFDEF_LEGACY_UTMP_APIS struct utmp; /* forward reference */ -void getutmp(const struct utmpx *, struct utmp *); -void getutmpx(const struct utmp *, struct utmpx *); +void getutmp(const struct utmpx *, struct utmp *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +void getutmpx(const struct utmp *, struct utmpx *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); #endif /* UNIFDEF_LEGACY_UTMP_APIS */ #endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ @@ -161,7 +163,7 @@ struct utmpx * #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) struct utmpx * - getutxent_wtmp(void); + getutxent_wtmp(void) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); #endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ struct utmpx * @@ -173,9 +175,9 @@ struct utmpx * void setutxent(void); #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -void setutxent_wtmp(int); -int utmpxname(const char *); -int wtmpxname(const char *); +void setutxent_wtmp(int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int utmpxname(const char *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int wtmpxname(const char *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); #endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ __END_DECLS diff --git a/include/varargs.h b/include/varargs.h deleted file mode 100644 index 7a17e63..0000000 --- a/include/varargs.h +++ /dev/null @@ -1,9 +0,0 @@ -/* This file is public domain. */ -/* GCC uses its own copy of this header */ -#if defined(__GNUC__) -#include_next -#elif defined(__MWERKS__) -#include "mw_varargs.h" -#else -#error "This header only supports __MWERKS__." -#endif diff --git a/include/wchar.h b/include/wchar.h index 0c5fc1e..fe527fd 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -68,6 +68,8 @@ #define _WCHAR_H_ #include <_types.h> +#include +#include #ifndef NULL #define NULL __DARWIN_NULL @@ -113,6 +115,8 @@ typedef __darwin_wchar_t wchar_t; #include #include <_wctype.h> + +/* Initially added in Issue 4 */ __BEGIN_DECLS wint_t btowc(int); wint_t fgetwc(FILE *); @@ -184,8 +188,19 @@ wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t); wchar_t *wmemset(wchar_t *, wchar_t, size_t); int wprintf(const wchar_t * __restrict, ...) __DARWIN_LDBL_COMPAT(wprintf); int wscanf(const wchar_t * __restrict, ...) __DARWIN_LDBL_COMPAT(wscanf); +int wcswidth(const wchar_t *, size_t); +int wcwidth(wchar_t); +__END_DECLS + + + +/* Additional functionality provided by: + * POSIX.1-2001 + * ISO C99 + */ -#if !defined(_ANSI_SOURCE) +#if __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) +__BEGIN_DECLS int vfwscanf(FILE * __restrict, const wchar_t * __restrict, __darwin_va_list) __DARWIN_LDBL_COMPAT(vfwscanf); int vswscanf(const wchar_t * __restrict, const wchar_t * __restrict, @@ -200,24 +215,47 @@ long long unsigned long long wcstoull(const wchar_t * __restrict, wchar_t ** __restrict, int); #endif /* !__DARWIN_NO_LONG_LONG */ -int wcswidth(const wchar_t *, size_t); -int wcwidth(wchar_t); -#endif /* !defined(_ANSI_SOURCE) */ +__END_DECLS +#endif + -#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) -size_t mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, - size_t, mbstate_t * __restrict); + +/* Additional functionality provided by: + * POSIX.1-2008 + */ + +#if __DARWIN_C_LEVEL >= 200809L +__BEGIN_DECLS +size_t mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, + size_t, mbstate_t * __restrict); +wchar_t *wcpcpy(wchar_t * __restrict, const wchar_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +wchar_t *wcpncpy(wchar_t * __restrict, const wchar_t * __restrict, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +wchar_t *wcsdup(const wchar_t *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +int wcscasecmp(const wchar_t *, const wchar_t *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +int wcsncasecmp(const wchar_t *, const wchar_t *, size_t n) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +size_t wcsnlen(const wchar_t *, size_t) __pure __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +size_t wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, + size_t, mbstate_t * __restrict); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200809L */ + + + +/* Darwin extensions */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +__BEGIN_DECLS +wchar_t *fgetwln(FILE * __restrict, size_t *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); size_t wcslcat(wchar_t *, const wchar_t *, size_t); size_t wcslcpy(wchar_t *, const wchar_t *, size_t); -size_t wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, - size_t, mbstate_t * __restrict); -#endif /* !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) */ +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + /* Poison the following routines if -fshort-wchar is set */ #if !defined(__cplusplus) && defined(__WCHAR_MAX__) && __WCHAR_MAX__ <= 0xffffU -#pragma GCC poison fgetws fputwc fputws fwprintf fwscanf mbrtowc mbsnrtowcs mbsrtowcs putwc putwchar swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf vwprintf vwscanf wcrtomb wcscat wcschr wcscmp wcscoll wcscpy wcscspn wcsftime wcsftime wcslcat wcslcpy wcslen wcsncat wcsncmp wcsncpy wcsnrtombs wcspbrk wcsrchr wcsrtombs wcsspn wcsstr wcstod wcstof wcstok wcstol wcstold wcstoll wcstoul wcstoull wcswidth wcsxfrm wcwidth wmemchr wmemcmp wmemcpy wmemmove wmemset wprintf wscanf +#pragma GCC poison fgetwln fgetws fputwc fputws fwprintf fwscanf mbrtowc mbsnrtowcs mbsrtowcs putwc putwchar swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf vwprintf vwscanf wcrtomb wcscat wcschr wcscmp wcscoll wcscpy wcscspn wcsftime wcsftime wcslcat wcslcpy wcslen wcsncat wcsncmp wcsncpy wcsnrtombs wcspbrk wcsrchr wcsrtombs wcsspn wcsstr wcstod wcstof wcstok wcstol wcstold wcstoll wcstoul wcstoull wcswidth wcsxfrm wcwidth wmemchr wmemcmp wmemcpy wmemmove wmemset wprintf wscanf #endif -__END_DECLS #ifdef _USE_EXTENDED_LOCALES_ #include diff --git a/include/xlocale/_stdio.h b/include/xlocale/_stdio.h index c5d4d3f..f9fdf86 100644 --- a/include/xlocale/_stdio.h +++ b/include/xlocale/_stdio.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009 Apple Inc. All rights reserved. + * Copyright (c) 2005, 2009, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -25,40 +25,55 @@ #define _XLOCALE__STDIO_H_ __BEGIN_DECLS -int asprintf_l(char **, locale_t, const char *, ...) - __DARWIN_LDBL_COMPAT2(asprintf_l) __printflike(3, 4); + int fprintf_l(FILE * __restrict, locale_t, const char * __restrict, ...) - __DARWIN_LDBL_COMPAT2(fprintf_l) __printflike(3, 4); + __DARWIN_LDBL_COMPAT2(fprintf_l) __printflike(3, 4); int fscanf_l(FILE * __restrict, locale_t, const char * __restrict, ...) - __DARWIN_LDBL_COMPAT2(fscanf_l) __scanflike(3, 4); + __DARWIN_LDBL_COMPAT2(fscanf_l) __scanflike(3, 4); int printf_l(locale_t, const char * __restrict, ...) - __DARWIN_LDBL_COMPAT2(printf_l) __printflike(2, 3); + __DARWIN_LDBL_COMPAT2(printf_l) __printflike(2, 3); int scanf_l(locale_t, const char * __restrict, ...) - __DARWIN_LDBL_COMPAT2(scanf_l) __scanflike(2, 3); -int snprintf_l(char * __restrict, size_t, locale_t, - const char * __restrict, ...) - __DARWIN_LDBL_COMPAT2(snprintf_l) __printflike(4, 5); + __DARWIN_LDBL_COMPAT2(scanf_l) __scanflike(2, 3); int sprintf_l(char * __restrict, locale_t, const char * __restrict, ...) - __DARWIN_LDBL_COMPAT2(sprintf_l) __printflike(3, 4); -int sscanf_l(const char * __restrict, locale_t, const char * __restrict, - ...) __DARWIN_LDBL_COMPAT2(sscanf_l) __scanflike(3, 4); -int vasprintf_l(char **, locale_t, const char *, va_list) - __DARWIN_LDBL_COMPAT2(vasprintf_l) __printflike(3, 0); -int vfprintf_l(FILE * __restrict, locale_t, const char * __restrict, - va_list) __DARWIN_LDBL_COMPAT2(vfprintf_l) __printflike(3, 0); -int vfscanf_l(FILE * __restrict, locale_t, const char * __restrict, - va_list) __DARWIN_LDBL_COMPAT2(vfscanf_l) __scanflike(3, 0); + __DARWIN_LDBL_COMPAT2(sprintf_l) __printflike(3, 4); +int sscanf_l(const char * __restrict, locale_t, const char * __restrict, ...) + __DARWIN_LDBL_COMPAT2(sscanf_l) __scanflike(3, 4); +int vfprintf_l(FILE * __restrict, locale_t, const char * __restrict, va_list) + __DARWIN_LDBL_COMPAT2(vfprintf_l) __printflike(3, 0); int vprintf_l(locale_t, const char * __restrict, va_list) - __DARWIN_LDBL_COMPAT2(vprintf_l) __printflike(2, 0); + __DARWIN_LDBL_COMPAT2(vprintf_l) __printflike(2, 0); +int vsprintf_l(char * __restrict, locale_t, const char * __restrict, va_list) + __DARWIN_LDBL_COMPAT2(vsprintf_l) __printflike(3, 0); + +#if __DARWIN_C_LEVEL >= 200112L +int snprintf_l(char * __restrict, size_t, locale_t, const char * __restrict, ...) + __DARWIN_LDBL_COMPAT2(snprintf_l) __printflike(4, 5); +int vfscanf_l(FILE * __restrict, locale_t, const char * __restrict, va_list) + __DARWIN_LDBL_COMPAT2(vfscanf_l) __scanflike(3, 0); int vscanf_l(locale_t, const char * __restrict, va_list) - __DARWIN_LDBL_COMPAT2(vscanf_l) __scanflike(2, 0); -int vsnprintf_l(char * __restrict, size_t, locale_t, - const char * __restrict, va_list) - __DARWIN_LDBL_COMPAT2(vsnprintf_l) __printflike(4, 0); -int vsprintf_l(char * __restrict, locale_t, const char * __restrict, - va_list) __DARWIN_LDBL_COMPAT2(vsprintf_l) __printflike(3, 0); -int vsscanf_l(const char * __restrict, locale_t, const char * __restrict, - va_list) __DARWIN_LDBL_COMPAT2(vsscanf_l) __scanflike(3, 0); + __DARWIN_LDBL_COMPAT2(vscanf_l) __scanflike(2, 0); +int vsnprintf_l(char * __restrict, size_t, locale_t, const char * __restrict, va_list) + __DARWIN_LDBL_COMPAT2(vsnprintf_l) __printflike(4, 0); +int vsscanf_l(const char * __restrict, locale_t, const char * __restrict, va_list) + __DARWIN_LDBL_COMPAT2(vsscanf_l) __scanflike(3, 0); +#endif + +#if __DARWIN_C_LEVEL >= 200809L +int dprintf_l(int, locale_t, const char * __restrict, ...) + __DARWIN_LDBL_COMPAT2(dprintf_l) __printflike(3, 4) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +int vdprintf_l(int, locale_t, const char * __restrict, va_list) + __DARWIN_LDBL_COMPAT2(vdprintf_l) __printflike(3, 0) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +#endif + + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +int asprintf_l(char **, locale_t, const char *, ...) + __DARWIN_LDBL_COMPAT2(asprintf_l) __printflike(3, 4); +int vasprintf_l(char **, locale_t, const char *, va_list) + __DARWIN_LDBL_COMPAT2(vasprintf_l) __printflike(3, 0); +#endif + __END_DECLS + #endif /* _XLOCALE__STDIO_H_ */ diff --git a/include/xlocale/_wchar.h b/include/xlocale/_wchar.h index 5318f3b..c3c8974 100644 --- a/include/xlocale/_wchar.h +++ b/include/xlocale/_wchar.h @@ -24,6 +24,7 @@ #ifndef _XLOCALE__WCHAR_H_ #define _XLOCALE__WCHAR_H_ +/* Initially added in Issue 4 */ __BEGIN_DECLS wint_t btowc_l(int, locale_t); wint_t fgetwc_l(FILE *, locale_t); @@ -41,8 +42,6 @@ size_t mbrlen_l(const char * __restrict, size_t, mbstate_t * __restrict, size_t mbrtowc_l(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict, locale_t); int mbsinit_l(const mbstate_t *, locale_t); -size_t mbsnrtowcs_l(wchar_t * __restrict, const char ** __restrict, size_t, - size_t, mbstate_t * __restrict, locale_t); size_t mbsrtowcs_l(wchar_t * __restrict, const char ** __restrict, size_t, mbstate_t * __restrict, locale_t); wint_t putwc_l(wchar_t, FILE *, locale_t); @@ -56,18 +55,11 @@ int swscanf_l(const wchar_t * __restrict, locale_t, wint_t ungetwc_l(wint_t, FILE *, locale_t); int vfwprintf_l(FILE * __restrict, locale_t, const wchar_t * __restrict, __darwin_va_list) __DARWIN_LDBL_COMPAT2(vfwprintf_l); -int vfwscanf_l(FILE * __restrict, locale_t, const wchar_t * __restrict, - __darwin_va_list) __DARWIN_LDBL_COMPAT2(vfwscanf_l); int vswprintf_l(wchar_t * __restrict, size_t n, locale_t, const wchar_t * __restrict, __darwin_va_list) __DARWIN_LDBL_COMPAT2(vswprintf_l); -int vswscanf_l(const wchar_t * __restrict, locale_t, - const wchar_t * __restrict, __darwin_va_list) - __DARWIN_LDBL_COMPAT2(vswscanf_l); int vwprintf_l(locale_t, const wchar_t * __restrict, __darwin_va_list) __DARWIN_LDBL_COMPAT2(vwprintf_l); -int vwscanf_l(locale_t, const wchar_t * __restrict, __darwin_va_list) - __DARWIN_LDBL_COMPAT2(vwscanf_l); size_t wcrtomb_l(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); int wcscoll_l(const wchar_t *, const wchar_t *, locale_t); @@ -84,26 +76,14 @@ size_t wcsftime_l(wchar_t * __restrict, size_t, const wchar_t * __restrict, LIBC_ALIAS(wcsftime_l); #endif /* !LIBC_ALIAS_WCSFTIME_L */ //End-Libc -size_t wcsnrtombs_l(char * __restrict, const wchar_t ** __restrict, size_t, - size_t, mbstate_t * __restrict, locale_t); size_t wcsrtombs_l(char * __restrict, const wchar_t ** __restrict, size_t, mbstate_t * __restrict, locale_t); double wcstod_l(const wchar_t * __restrict, wchar_t ** __restrict, locale_t); -float wcstof_l(const wchar_t * __restrict, wchar_t ** __restrict, locale_t); long wcstol_l(const wchar_t * __restrict, wchar_t ** __restrict, int, locale_t); -long double - wcstold_l(const wchar_t * __restrict, wchar_t ** __restrict, locale_t) - __DARWIN_LDBL_COMPAT2(wcstold_l); -long long - wcstoll_l(const wchar_t * __restrict, wchar_t ** __restrict, int, - locale_t); unsigned long wcstoul_l(const wchar_t * __restrict, wchar_t ** __restrict, int, locale_t); -unsigned long long - wcstoull_l(const wchar_t * __restrict, wchar_t ** __restrict, int, - locale_t); int wcswidth_l(const wchar_t *, size_t, locale_t); size_t wcsxfrm_l(wchar_t * __restrict, const wchar_t * __restrict, size_t, locale_t); @@ -113,11 +93,70 @@ int wprintf_l(locale_t, const wchar_t * __restrict, ...) __DARWIN_LDBL_COMPAT2(wprintf_l); int wscanf_l(locale_t, const wchar_t * __restrict, ...) __DARWIN_LDBL_COMPAT2(wscanf_l); +__END_DECLS + + + +/* Additional functionality provided by: + * POSIX.1-2001 + */ + +#if __DARWIN_C_LEVEL >= 200112L +__BEGIN_DECLS +int vfwscanf_l(FILE * __restrict, locale_t, const wchar_t * __restrict, + __darwin_va_list) __DARWIN_LDBL_COMPAT2(vfwscanf_l); +int vswscanf_l(const wchar_t * __restrict, locale_t, + const wchar_t * __restrict, __darwin_va_list) + __DARWIN_LDBL_COMPAT2(vswscanf_l); +int vwscanf_l(locale_t, const wchar_t * __restrict, __darwin_va_list) + __DARWIN_LDBL_COMPAT2(vwscanf_l); +float wcstof_l(const wchar_t * __restrict, wchar_t ** __restrict, locale_t); +long double + wcstold_l(const wchar_t * __restrict, wchar_t ** __restrict, locale_t) + __DARWIN_LDBL_COMPAT2(wcstold_l); +#if !__DARWIN_NO_LONG_LONG +long long + wcstoll_l(const wchar_t * __restrict, wchar_t ** __restrict, int, + locale_t); +unsigned long long + wcstoull_l(const wchar_t * __restrict, wchar_t ** __restrict, int, + locale_t); +#endif /* !__DARWIN_NO_LONG_LONG */ +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200112L */ + + + +/* Additional functionality provided by: + * POSIX.1-2008 + */ + +#if __DARWIN_C_LEVEL >= 200809L +__BEGIN_DECLS +size_t mbsnrtowcs_l(wchar_t * __restrict, const char ** __restrict, size_t, + size_t, mbstate_t * __restrict, locale_t); +int wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t n, locale_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +size_t wcsnrtombs_l(char * __restrict, const wchar_t ** __restrict, size_t, + size_t, mbstate_t * __restrict, locale_t); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200809L */ + + + +/* Darwin extensions */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +__BEGIN_DECLS +wchar_t *fgetwln_l(FILE * __restrict, size_t *, locale_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + + /* Poison the following routines if -fshort-wchar is set */ #if !defined(__cplusplus) && defined(__WCHAR_MAX__) && __WCHAR_MAX__ <= 0xffffU -#pragma GCC poison fgetws_l fputwc_l fputws_l fwprintf_l fwscanf_l mbrtowc_l mbsnrtowcs_l mbsrtowcs_l putwc_l putwchar_l swprintf_l swscanf_l vfwprintf_l vfwscanf_l vswprintf_l vswscanf_l vwprintf_l vwscanf_l wcrtomb_l wcscoll_l wcsftime_l wcsftime_l wcsnrtombs_l wcsrtombs_l wcstod_l wcstof_l wcstol_l wcstold_l wcstoll_l wcstoul_l wcstoull_l wcswidth_l wcsxfrm_l wcwidth_l wprintf_l wscanf_l +#pragma GCC poison fgetwln_l fgetws_l fputwc_l fputws_l fwprintf_l fwscanf_l mbrtowc_l mbsnrtowcs_l mbsrtowcs_l putwc_l putwchar_l swprintf_l swscanf_l vfwprintf_l vfwscanf_l vswprintf_l vswscanf_l vwprintf_l vwscanf_l wcrtomb_l wcscoll_l wcsftime_l wcsftime_l wcsnrtombs_l wcsrtombs_l wcstod_l wcstof_l wcstol_l wcstold_l wcstoll_l wcstoul_l wcstoull_l wcswidth_l wcsxfrm_l wcwidth_l wprintf_l wscanf_l #endif -__END_DECLS #endif /* _XLOCALE__WCHAR_H_ */ diff --git a/interposable.list b/interposable.list new file mode 100644 index 0000000..f9ec86a --- /dev/null +++ b/interposable.list @@ -0,0 +1,33 @@ +_malloc_printf +__malloc_fork_prepare +__malloc_fork_parent +__malloc_fork_child +_vfree +_malloc +_free +_realloc +_calloc +_malloc_size +_malloc_good_size +_malloc_zone_valloc +_valloc +_malloc_create_zone +_malloc_default_zone +_malloc_destroy_zone +_malloc_get_all_zones +_malloc_get_zone_name +_malloc_zone_calloc +_malloc_zone_check +_malloc_zone_free +_malloc_zone_from_ptr +_malloc_zone_log +_malloc_zone_malloc +_malloc_zone_memalign +_posix_memalign +_malloc_zone_print +_malloc_zone_print_ptr_info +_malloc_zone_realloc +_malloc_zone_register +_malloc_zone_unregister +_malloc_zone_batch_malloc +_malloc_zone_batch_free diff --git a/locale/FreeBSD/ascii.c b/locale/FreeBSD/ascii.c new file mode 100644 index 0000000..7006e01 --- /dev/null +++ b/locale/FreeBSD/ascii.c @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 +__FBSDID("$FreeBSD: src/lib/libc/locale/ascii.c,v 1.1 2008/01/21 23:48:12 ache Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _ascii_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _ascii_mbsinit(const mbstate_t *); +static size_t _ascii_mbsnrtowcs(wchar_t * __restrict dst, + const char ** __restrict src, size_t nms, size_t len, + mbstate_t * __restrict ps __unused); +static size_t _ascii_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); +static size_t _ascii_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict); + +int +_ascii_init(_RuneLocale *rl) +{ + + __mbrtowc = _ascii_mbrtowc; + __mbsinit = _ascii_mbsinit; + __mbsnrtowcs = _ascii_mbsnrtowcs; + __wcrtomb = _ascii_wcrtomb; + __wcsnrtombs = _ascii_wcsnrtombs; + _CurrentRuneLocale = rl; + __mb_cur_max = 1; + __mb_sb_limit = 128; + return(0); +} + +static int +_ascii_mbsinit(const mbstate_t *ps __unused) +{ + + /* + * Encoding is not state dependent - we are always in the + * initial state. + */ + return (1); +} + +static size_t +_ascii_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps __unused) +{ + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (0); + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + if (*s & 0x80) { + errno = EILSEQ; + return ((size_t)-1); + } + if (pwc != NULL) + *pwc = (unsigned char)*s; + return (*s == '\0' ? 0 : 1); +} + +static size_t +_ascii_wcrtomb(char * __restrict s, wchar_t wc, + mbstate_t * __restrict ps __unused) +{ + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc < 0 || wc > 127) { + errno = EILSEQ; + return ((size_t)-1); + } + *s = (unsigned char)wc; + return (1); +} + +static size_t +_ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps __unused) +{ + const char *s; + size_t nchr; + + if (dst == NULL) { + for (s = *src; nms > 0 && *s != '\0'; s++, nms--) { + if (*s & 0x80) { + errno = EILSEQ; + return ((size_t)-1); + } + } + return (s - *src); + } + + s = *src; + nchr = 0; + while (len-- > 0 && nms-- > 0) { + if (*s & 0x80) { + errno = EILSEQ; + return ((size_t)-1); + } + if ((*dst++ = (unsigned char)*s++) == L'\0') { + *src = NULL; + return (nchr); + } + nchr++; + } + *src = s; + return (nchr); +} + +static size_t +_ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, + size_t nwc, size_t len, mbstate_t * __restrict ps __unused) +{ + const wchar_t *s; + size_t nchr; + + if (dst == NULL) { + for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) { + if (*s < 0 || *s > 127) { + errno = EILSEQ; + return ((size_t)-1); + } + } + return (s - *src); + } + + s = *src; + nchr = 0; + while (len-- > 0 && nwc-- > 0) { + if (*s < 0 || *s > 127) { + errno = EILSEQ; + return ((size_t)-1); + } + if ((*dst++ = *s++) == '\0') { + *src = NULL; + return (nchr); + } + nchr++; + } + *src = s; + return (nchr); +} + diff --git a/locale/FreeBSD/ascii.c.patch b/locale/FreeBSD/ascii.c.patch new file mode 100644 index 0000000..aa45979 --- /dev/null +++ b/locale/FreeBSD/ascii.c.patch @@ -0,0 +1,89 @@ +Index: ascii.c +=================================================================== +--- ascii.c (revision 47445) ++++ ascii.c (working copy) +@@ -45,33 +45,32 @@ + #include "mblocal.h" + + static size_t _ascii_mbrtowc(wchar_t * __restrict, const char * __restrict, +- size_t, mbstate_t * __restrict); +-static int _ascii_mbsinit(const mbstate_t *); ++ size_t, mbstate_t * __restrict, locale_t); ++static int _ascii_mbsinit(const mbstate_t *, locale_t); + static size_t _ascii_mbsnrtowcs(wchar_t * __restrict dst, + const char ** __restrict src, size_t nms, size_t len, +- mbstate_t * __restrict ps __unused); ++ mbstate_t * __restrict ps __unused, locale_t); + static size_t _ascii_wcrtomb(char * __restrict, wchar_t, +- mbstate_t * __restrict); ++ mbstate_t * __restrict, locale_t); + static size_t _ascii_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, +- size_t, size_t, mbstate_t * __restrict); ++ size_t, size_t, mbstate_t * __restrict, locale_t); + +-int +-_ascii_init(_RuneLocale *rl) ++__private_extern__ int ++_ascii_init(struct __xlocale_st_runelocale *xrl) + { + +- __mbrtowc = _ascii_mbrtowc; +- __mbsinit = _ascii_mbsinit; +- __mbsnrtowcs = _ascii_mbsnrtowcs; +- __wcrtomb = _ascii_wcrtomb; +- __wcsnrtombs = _ascii_wcsnrtombs; +- _CurrentRuneLocale = rl; +- __mb_cur_max = 1; +- __mb_sb_limit = 128; ++ xrl->__mbrtowc = _ascii_mbrtowc; ++ xrl->__mbsinit = _ascii_mbsinit; ++ xrl->__mbsnrtowcs = _ascii_mbsnrtowcs; ++ xrl->__wcrtomb = _ascii_wcrtomb; ++ xrl->__wcsnrtombs = _ascii_wcsnrtombs; ++ xrl->__mb_cur_max = 1; ++ xrl->__mb_sb_limit = 128; + return(0); + } + + static int +-_ascii_mbsinit(const mbstate_t *ps __unused) ++_ascii_mbsinit(const mbstate_t *ps __unused, locale_t loc __unused) + { + + /* +@@ -83,7 +82,7 @@ + + static size_t + _ascii_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, +- mbstate_t * __restrict ps __unused) ++ mbstate_t * __restrict ps __unused, locale_t loc __unused) + { + + if (s == NULL) +@@ -103,7 +102,7 @@ + + static size_t + _ascii_wcrtomb(char * __restrict s, wchar_t wc, +- mbstate_t * __restrict ps __unused) ++ mbstate_t * __restrict ps __unused, locale_t loc __unused) + { + + if (s == NULL) +@@ -119,7 +118,7 @@ + + static size_t + _ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, +- size_t nms, size_t len, mbstate_t * __restrict ps __unused) ++ size_t nms, size_t len, mbstate_t * __restrict ps __unused, locale_t loc __unused) + { + const char *s; + size_t nchr; +@@ -153,7 +152,7 @@ + + static size_t + _ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, +- size_t nwc, size_t len, mbstate_t * __restrict ps __unused) ++ size_t nwc, size_t len, mbstate_t * __restrict ps __unused, locale_t loc __unused) + { + const wchar_t *s; + size_t nchr; diff --git a/locale/FreeBSD/big5.c b/locale/FreeBSD/big5.c index 26000a8..ef2fd4e 100644 --- a/locale/FreeBSD/big5.c +++ b/locale/FreeBSD/big5.c @@ -38,9 +38,10 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)big5.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/locale/big5.c,v 1.16 2004/05/17 11:16:14 tjr Exp $"); +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/big5.c,v 1.18 2007/10/13 16:28:21 ache Exp $"); +#include #include #include #include @@ -48,11 +49,13 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/big5.c,v 1.16 2004/05/17 11:16:14 tjr Ex #include #include "mblocal.h" -int _BIG5_init(_RuneLocale *); -size_t _BIG5_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict); -int _BIG5_mbsinit(const mbstate_t *); -size_t _BIG5_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); +extern int __mb_sb_limit; + +static size_t _BIG5_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _BIG5_mbsinit(const mbstate_t *); +static size_t _BIG5_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); typedef struct { wchar_t ch; @@ -67,10 +70,11 @@ _BIG5_init(_RuneLocale *rl) __mbsinit = _BIG5_mbsinit; _CurrentRuneLocale = rl; __mb_cur_max = 2; + __mb_sb_limit = 128; return (0); } -int +static int _BIG5_mbsinit(const mbstate_t *ps) { @@ -85,7 +89,7 @@ _big5_check(u_int c) return ((c >= 0xa1 && c <= 0xfe) ? 2 : 1); } -size_t +static size_t _BIG5_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { @@ -146,7 +150,7 @@ _BIG5_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } } -size_t +static size_t _BIG5_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _BIG5State *bs; diff --git a/locale/FreeBSD/big5.c.patch b/locale/FreeBSD/big5.c.patch index 1c249bf..96c1988 100644 --- a/locale/FreeBSD/big5.c.patch +++ b/locale/FreeBSD/big5.c.patch @@ -1,28 +1,28 @@ ---- big5.c.orig Thu Nov 25 11:38:16 2004 -+++ big5.c Fri Feb 18 15:48:14 2005 -@@ -41,6 +41,8 @@ - #include - __FBSDID("$FreeBSD: src/lib/libc/locale/big5.c,v 1.16 2004/05/17 11:16:14 tjr Exp $"); +--- big5.c.orig 2009-11-09 15:24:27.000000000 -0800 ++++ big5.c 2009-11-09 18:41:35.000000000 -0800 +@@ -41,6 +41,8 @@ static char sccsid[] = "@(#)big5.c 8.1 ( + #include + __FBSDID("$FreeBSD: src/lib/libc/locale/big5.c,v 1.18 2007/10/13 16:28:21 ache Exp $"); +#include "xlocale_private.h" + + #include #include #include - #include -@@ -48,30 +50,29 @@ +@@ -49,33 +51,30 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include #include "mblocal.h" --int _BIG5_init(_RuneLocale *); --size_t _BIG5_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -- mbstate_t * __restrict); --int _BIG5_mbsinit(const mbstate_t *); --size_t _BIG5_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); -+__private_extern__ int _BIG5_init(struct __xlocale_st_runelocale *); -+static size_t _BIG5_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -+ mbstate_t * __restrict, locale_t); +-extern int __mb_sb_limit; +- + static size_t _BIG5_mbrtowc(wchar_t * __restrict, const char * __restrict, +- size_t, mbstate_t * __restrict); +-static int _BIG5_mbsinit(const mbstate_t *); ++ size_t, mbstate_t * __restrict, locale_t); +static int _BIG5_mbsinit(const mbstate_t *, locale_t); -+static size_t _BIG5_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); + static size_t _BIG5_wcrtomb(char * __restrict, wchar_t, +- mbstate_t * __restrict); ++ mbstate_t * __restrict, locale_t); typedef struct { wchar_t ch; @@ -39,40 +39,36 @@ - __mbsinit = _BIG5_mbsinit; - _CurrentRuneLocale = rl; - __mb_cur_max = 2; +- __mb_sb_limit = 128; + xrl->__mbrtowc = _BIG5_mbrtowc; + xrl->__wcrtomb = _BIG5_wcrtomb; + xrl->__mbsinit = _BIG5_mbsinit; + xrl->__mb_cur_max = 2; ++ xrl->__mb_sb_limit = 128; return (0); } --int + static int -_BIG5_mbsinit(const mbstate_t *ps) -+static int -+_BIG5_mbsinit(const mbstate_t *ps, locale_t loc) ++_BIG5_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _BIG5State *)ps)->ch == 0); -@@ -85,9 +86,9 @@ - return ((c >= 0xa1 && c <= 0xfe) ? 2 : 1); - } +@@ -91,7 +90,7 @@ _big5_check(u_int c) --size_t -+static size_t + static size_t _BIG5_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps) -+ mbstate_t * __restrict ps, locale_t loc) ++ mbstate_t * __restrict ps, locale_t loc __unused) { _BIG5State *bs; wchar_t wc; -@@ -146,8 +147,8 @@ - } +@@ -151,7 +150,7 @@ _BIG5_mbrtowc(wchar_t * __restrict pwc, } --size_t + static size_t -_BIG5_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) -+static size_t -+_BIG5_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) ++_BIG5_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc __unused) { _BIG5State *bs; diff --git a/locale/FreeBSD/btowc.3.patch b/locale/FreeBSD/btowc.3.patch index 66f6c85..039e86e 100644 --- a/locale/FreeBSD/btowc.3.patch +++ b/locale/FreeBSD/btowc.3.patch @@ -1,5 +1,5 @@ ---- btowc.3 2003-05-20 15:21:44.000000000 -0700 -+++ btowc.3.edit 2006-07-12 11:14:18.000000000 -0700 +--- btowc.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ btowc.3 2009-11-09 15:05:25.000000000 -0800 @@ -29,16 +29,35 @@ .Os .Sh NAME @@ -39,7 +39,7 @@ .Sh DESCRIPTION The .Fn btowc -@@ -59,10 +78,29 @@ +@@ -59,10 +78,29 @@ or not able to be represented as a singl .Fn wctob returns .Dv WEOF . diff --git a/locale/FreeBSD/btowc.c.patch b/locale/FreeBSD/btowc.c.patch index 3dc8fcc..b9a02cd 100644 --- a/locale/FreeBSD/btowc.c.patch +++ b/locale/FreeBSD/btowc.c.patch @@ -1,5 +1,5 @@ ---- btowc.c.orig Thu Nov 25 11:38:16 2004 -+++ btowc.c Fri Feb 18 15:58:50 2005 +--- btowc.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ btowc.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,18 +27,21 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/btowc.c,v 1.4 2004/05/12 14:26:54 tjr Exp $"); @@ -23,7 +23,7 @@ if (c == EOF) return (WEOF); /* -@@ -47,7 +50,13 @@ +@@ -47,7 +50,13 @@ btowc(int c) * counts. */ cc = (char)c; @@ -31,10 +31,10 @@ + if (loc->__lc_ctype->__mbrtowc(&wc, &cc, 1, &mbs, loc) > 1) return (WEOF); return (wc); -+} + } + +wint_t +btowc(int c) +{ + return btowc_l(c, __current_locale()); - } ++} diff --git a/locale/FreeBSD/collate.c b/locale/FreeBSD/collate.c index e56dd1a..184fac6 100644 --- a/locale/FreeBSD/collate.c +++ b/locale/FreeBSD/collate.c @@ -26,7 +26,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.33 2004/09/22 16:56:48 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.35 2005/02/27 20:31:13 ru Exp $"); #include "namespace.h" #include @@ -99,7 +99,7 @@ __collate_load_tables(const char *encoding) chains = -1; if (strcmp(strbuf, COLLATE_VERSION) == 0) chains = 0; - else if (strcmp(strbuf, COLLATE_VERSION1_1) == 0) + else if (strcmp(strbuf, COLLATE_VERSION1_2) == 0) chains = 1; if (chains < 0) { (void)fclose(fp); @@ -172,10 +172,21 @@ __collate_load_tables(const char *encoding) if (__collate_char_pri_table_ptr != NULL) free(__collate_char_pri_table_ptr); __collate_char_pri_table_ptr = TMP_char_pri_table; + for (i = 0; i < UCHAR_MAX + 1; i++) { + __collate_char_pri_table[i].prim = + ntohl(__collate_char_pri_table[i].prim); + __collate_char_pri_table[i].sec = + ntohl(__collate_char_pri_table[i].sec); + } if (__collate_chain_pri_table != NULL) free(__collate_chain_pri_table); __collate_chain_pri_table = TMP_chain_pri_table; - + for (i = 0; i < chains; i++) { + __collate_chain_pri_table[i].prim = + ntohl(__collate_chain_pri_table[i].prim); + __collate_chain_pri_table[i].sec = + ntohl(__collate_chain_pri_table[i].sec); + } __collate_substitute_nontrivial = 0; for (i = 0; i < UCHAR_MAX + 1; i++) { if (__collate_substitute_table[i][0] != i || @@ -190,8 +201,7 @@ __collate_load_tables(const char *encoding) } u_char * -__collate_substitute(s) - const u_char *s; +__collate_substitute(const u_char *s) { int dest_len, len, nlen; int delta = strlen(s); @@ -218,9 +228,7 @@ __collate_substitute(s) } void -__collate_lookup(t, len, prim, sec) - const u_char *t; - int *len, *prim, *sec; +__collate_lookup(const u_char *t, int *len, int *prim, int *sec) { struct __collate_st_chain_pri *p2; @@ -240,8 +248,7 @@ __collate_lookup(t, len, prim, sec) } u_char * -__collate_strdup(s) - u_char *s; +__collate_strdup(u_char *s) { u_char *t = strdup(s); diff --git a/locale/FreeBSD/collate.c.patch b/locale/FreeBSD/collate.c.patch index d831b23..8a08e16 100644 --- a/locale/FreeBSD/collate.c.patch +++ b/locale/FreeBSD/collate.c.patch @@ -1,8 +1,8 @@ ---- collate.c.orig 2004-11-25 11:38:16.000000000 -0800 -+++ collate.c 2005-10-20 01:00:19.000000000 -0700 +--- collate.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ collate.c 2009-11-09 15:20:20.000000000 -0800 @@ -28,14 +28,26 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.33 2004/09/22 16:56:48 stefanf Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.35 2005/02/27 20:31:13 ru Exp $"); +#include "xlocale_private.h" +/* assumes the locale_t variable is named loc */ @@ -27,7 +27,7 @@ #include "un-namespace.h" #include "collate.h" -@@ -44,36 +56,50 @@ +@@ -44,36 +56,50 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include "libc_private.h" @@ -94,18 +94,18 @@ return (_LDP_CACHE); } -@@ -97,9 +123,7 @@ +@@ -97,9 +123,7 @@ __collate_load_tables(const char *encodi return (_LDP_ERROR); } chains = -1; - if (strcmp(strbuf, COLLATE_VERSION) == 0) - chains = 0; -- else if (strcmp(strbuf, COLLATE_VERSION1_1) == 0) +- else if (strcmp(strbuf, COLLATE_VERSION1_2) == 0) + if (strcmp(strbuf, COLLATE_VERSION1_1A) == 0) chains = 1; if (chains < 0) { (void)fclose(fp); -@@ -107,13 +131,21 @@ +@@ -107,13 +131,21 @@ __collate_load_tables(const char *encodi return (_LDP_ERROR); } if (chains) { @@ -129,17 +129,23 @@ (void)fclose(fp); errno = EFTYPE; return (_LDP_ERROR); -@@ -121,136 +153,446 @@ +@@ -121,143 +153,446 @@ __collate_load_tables(const char *encodi } else chains = TABLE_SIZE; - if ((TMP_substitute_table = - malloc(sizeof(__collate_substitute_table))) == NULL) { -- saverr = errno; -- (void)fclose(fp); -- errno = saverr; -- return (_LDP_ERROR); -- } ++ i = sizeof(struct __xlocale_st_collate) ++ + sizeof(struct __collate_st_chain_pri) * chains ++ + sizeof(struct __collate_st_large_char_pri) * info.large_pri_count; ++ for(z = 0; z < info.directive_count; z++) ++ i += sizeof(struct __collate_st_subst) * info.subst_count[z]; ++ if ((TMP = (struct __xlocale_st_collate *)malloc(i)) == NULL) { + saverr = errno; + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } - if ((TMP_char_pri_table = - malloc(sizeof(__collate_char_pri_table))) == NULL) { - saverr = errno; @@ -150,19 +156,13 @@ - } - if ((TMP_chain_pri_table = - malloc(sizeof(*__collate_chain_pri_table) * chains)) == NULL) { -+ i = sizeof(struct __xlocale_st_collate) -+ + sizeof(struct __collate_st_chain_pri) * chains -+ + sizeof(struct __collate_st_large_char_pri) * info.large_pri_count; -+ for(z = 0; z < info.directive_count; z++) -+ i += sizeof(struct __collate_st_subst) * info.subst_count[z]; -+ if ((TMP = (struct __xlocale_st_collate *)malloc(i)) == NULL) { - saverr = errno; +- saverr = errno; - free(TMP_substitute_table); - free(TMP_char_pri_table); - (void)fclose(fp); - errno = saverr; - return (_LDP_ERROR); - } +- (void)fclose(fp); +- errno = saverr; +- return (_LDP_ERROR); +- } + TMP->__refcount = 2; /* one for the locale, one for the cache */ + TMP->__free_extra = NULL; @@ -196,10 +196,21 @@ - if (__collate_char_pri_table_ptr != NULL) - free(__collate_char_pri_table_ptr); - __collate_char_pri_table_ptr = TMP_char_pri_table; +- for (i = 0; i < UCHAR_MAX + 1; i++) { +- __collate_char_pri_table[i].prim = +- ntohl(__collate_char_pri_table[i].prim); +- __collate_char_pri_table[i].sec = +- ntohl(__collate_char_pri_table[i].sec); +- } - if (__collate_chain_pri_table != NULL) - free(__collate_chain_pri_table); - __collate_chain_pri_table = TMP_chain_pri_table; -- +- for (i = 0; i < chains; i++) { +- __collate_chain_pri_table[i].prim = +- ntohl(__collate_chain_pri_table[i].prim); +- __collate_chain_pri_table[i].sec = +- ntohl(__collate_chain_pri_table[i].sec); +- } - __collate_substitute_nontrivial = 0; - for (i = 0; i < UCHAR_MAX + 1; i++) { - if (__collate_substitute_table[i][0] != i || @@ -283,8 +294,7 @@ } -u_char * --__collate_substitute(s) -- const u_char *s; +-__collate_substitute(const u_char *s) +static int +__collate_wcsnlen(const wchar_t *s, int len) +{ @@ -373,9 +383,7 @@ } -void --__collate_lookup(t, len, prim, sec) -- const u_char *t; -- int *len, *prim, *sec; +-__collate_lookup(const u_char *t, int *len, int *prim, int *sec) +static struct __collate_st_chain_pri * +chainsearch(const wchar_t *key, int *len, locale_t loc) +{ @@ -500,9 +508,11 @@ + if (p >= 0) { + *len = l; + *pri = p; -+ return; -+ } -+ } + return; + } + } +- *prim = __collate_char_pri_table[*t].prim; +- *sec = __collate_char_pri_table[*t].sec; + if (*t <= UCHAR_MAX) { + *pri = __collate_char_pri_table[*t].pri[which]; + return; @@ -512,21 +522,15 @@ + match = largesearch(*t, loc); + if (match) { + *pri = match->pri.pri[which]; - return; - } - } -- *prim = __collate_char_pri_table[*t].prim; -- *sec = __collate_char_pri_table[*t].sec; ++ return; ++ } ++ } + *pri = (l = __collate_info->undef_pri[which]) >= 0 ? l : *t - l; - } - --u_char * --__collate_strdup(s) -- u_char *s; ++} ++ +__private_extern__ wchar_t * +__collate_mbstowcs(const char *s, locale_t loc) - { -- u_char *t = strdup(s); ++{ + static const mbstate_t initial; + mbstate_t st; + size_t len; @@ -542,17 +546,20 @@ + st = initial; + mbsrtowcs_l(wcs, &s, len, &st, loc); + wcs[len] = 0; - -- if (t == NULL) -+ return (wcs); -+} + ++ return (wcs); + } + +-u_char * +-__collate_strdup(u_char *s) +__private_extern__ wchar_t * +__collate_wcsdup(const wchar_t *s) -+{ + { +- u_char *t = strdup(s); + size_t len = wcslen(s) + 1; + wchar_t *wcs; -+ + +- if (t == NULL) + if ((wcs = (wchar_t *)malloc(len * sizeof(wchar_t))) == NULL) __collate_err(EX_OSERR, __func__); - return (t); @@ -651,7 +658,7 @@ __collate_err(int ex, const char *f) { const char *s; -@@ -268,24 +610,345 @@ +@@ -275,24 +610,345 @@ __collate_err(int ex, const char *f) exit(ex); } diff --git a/locale/FreeBSD/collate.h b/locale/FreeBSD/collate.h index 4d55f9c..a8d2176 100644 --- a/locale/FreeBSD/collate.h +++ b/locale/FreeBSD/collate.h @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/lib/libc/locale/collate.h,v 1.14 2002/08/30 20:26:02 ache Exp $ + * $FreeBSD: src/lib/libc/locale/collate.h,v 1.15 2005/02/27 20:31:13 ru Exp $ */ #ifndef _COLLATE_H_ @@ -37,7 +37,7 @@ #define STR_LEN 10 #define TABLE_SIZE 100 #define COLLATE_VERSION "1.0\n" -#define COLLATE_VERSION1_1 "1.1\n" +#define COLLATE_VERSION1_2 "1.2\n" struct __collate_st_char_pri { int prim, sec; diff --git a/locale/FreeBSD/collate.h.patch b/locale/FreeBSD/collate.h.patch index cbdb83f..342a518 100644 --- a/locale/FreeBSD/collate.h.patch +++ b/locale/FreeBSD/collate.h.patch @@ -1,6 +1,6 @@ ---- collate.h.orig 2003-05-20 15:21:44.000000000 -0700 -+++ collate.h 2005-10-20 00:05:25.000000000 -0700 -@@ -31,36 +31,88 @@ +--- collate.h.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ collate.h 2009-11-09 15:21:14.000000000 -0800 +@@ -31,36 +31,90 @@ #define _COLLATE_H_ #include @@ -12,8 +12,10 @@ #define STR_LEN 10 #define TABLE_SIZE 100 #define COLLATE_VERSION "1.0\n" - #define COLLATE_VERSION1_1 "1.1\n" ++#define COLLATE_VERSION1_1 "1.1\n" +#define COLLATE_VERSION1_1A "1.1A\n" + #define COLLATE_VERSION1_2 "1.2\n" + +/* see discussion in string/FreeBSD/strxfrm for this value */ +#define COLLATE_MAX_PRIORITY ((1 << 24) - 1) + @@ -43,7 +45,7 @@ + __int32_t chain_count; + __int32_t large_pri_count; +}; - ++ struct __collate_st_char_pri { - int prim, sec; + __int32_t pri[COLL_WEIGHTS_MAX]; diff --git a/locale/FreeBSD/collcmp.c b/locale/FreeBSD/collcmp.c index 8cbd213..dde67a4 100644 --- a/locale/FreeBSD/collcmp.c +++ b/locale/FreeBSD/collcmp.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.17 2003/08/03 19:28:23 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.18 2005/02/27 14:54:23 phantom Exp $"); #include #include "collate.h" @@ -34,8 +34,7 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.17 2003/08/03 19:28:23 ach * Compare two characters using collate */ -int __collate_range_cmp(c1, c2) - int c1, c2; +int __collate_range_cmp(int c1, int c2) { static char s1[2], s2[2]; diff --git a/locale/FreeBSD/collcmp.c.patch b/locale/FreeBSD/collcmp.c.patch index a39ad68..d985e29 100644 --- a/locale/FreeBSD/collcmp.c.patch +++ b/locale/FreeBSD/collcmp.c.patch @@ -1,8 +1,8 @@ ---- collcmp.c.orig 2004-11-25 11:38:16.000000000 -0800 -+++ collcmp.c 2005-03-30 08:36:37.000000000 -0800 -@@ -27,19 +27,22 @@ +--- collcmp.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ collcmp.c 2009-11-09 15:23:31.000000000 -0800 +@@ -27,18 +27,20 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.17 2003/08/03 19:28:23 ache Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.18 2005/02/27 14:54:23 phantom Exp $"); -#include +#include @@ -13,12 +13,9 @@ * Compare two characters using collate */ --int __collate_range_cmp(c1, c2) -- int c1, c2; +-int __collate_range_cmp(int c1, int c2) +__private_extern__ int -+__collate_range_cmp(c1, c2, loc) -+ wchar_t c1, c2; -+ locale_t loc; ++__collate_range_cmp(wchar_t c1, wchar_t c2, locale_t loc) { - static char s1[2], s2[2]; + static wchar_t s1[2], s2[2]; diff --git a/locale/FreeBSD/ctype.3 b/locale/FreeBSD/ctype.3 index ab99375..f3bbaa1 100644 --- a/locale/FreeBSD/ctype.3 +++ b/locale/FreeBSD/ctype.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ctype.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/ctype.3,v 1.15 2004/06/30 20:09:08 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/ctype.3,v 1.18 2009/09/04 07:44:58 des Exp $ .\" .Dd March 30, 2004 .Dt CTYPE 3 diff --git a/locale/FreeBSD/ctype.3.patch b/locale/FreeBSD/ctype.3.patch index e78e876..d43340c 100644 --- a/locale/FreeBSD/ctype.3.patch +++ b/locale/FreeBSD/ctype.3.patch @@ -1,6 +1,6 @@ ---- ctype.3.orig Fri Mar 11 18:02:47 2005 -+++ ctype.3 Fri Mar 11 18:03:52 2005 -@@ -115,6 +115,12 @@ +--- ctype.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ ctype.3 2009-11-09 15:05:26.000000000 -0800 +@@ -111,6 +111,12 @@ They are available as macros, defined in .In ctype.h , or as true functions in the C library. See the specific manual pages for more information. @@ -13,7 +13,7 @@ .Sh SEE ALSO .Xr digittoint 3 , .Xr isalnum 3 , -@@ -138,7 +144,8 @@ +@@ -134,7 +140,8 @@ See the specific manual pages for more i .Xr tolower 3 , .Xr toupper 3 , .Xr wctype 3 , diff --git a/locale/FreeBSD/digittoint.3 b/locale/FreeBSD/digittoint.3 index 9f49a46..e3a71dd 100644 --- a/locale/FreeBSD/digittoint.3 +++ b/locale/FreeBSD/digittoint.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)digittoint.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/digittoint.3,v 1.3 2004/03/30 07:19:35 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/digittoint.3,v 1.6 2009/09/04 07:44:58 des Exp $ .\" .Dd April 6, 2001 .Dt DIGITTOINT 3 diff --git a/locale/FreeBSD/digittoint.3.patch b/locale/FreeBSD/digittoint.3.patch index 5ba211e..3bb6a14 100644 --- a/locale/FreeBSD/digittoint.3.patch +++ b/locale/FreeBSD/digittoint.3.patch @@ -1,6 +1,6 @@ ---- digittoint.3 2004-11-25 11:38:16.000000000 -0800 -+++ digittoint.3.edit 2006-08-11 15:23:25.000000000 -0700 -@@ -36,20 +36,38 @@ +--- digittoint.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ digittoint.3 2009-11-09 15:05:26.000000000 -0800 +@@ -32,20 +32,38 @@ .Dt DIGITTOINT 3 .Os .Sh NAME @@ -41,7 +41,7 @@ .Sh RETURN VALUES The .Fn digittoint -@@ -60,4 +78,5 @@ +@@ -56,4 +74,5 @@ the function will return 0. .Sh SEE ALSO .Xr ctype 3 , .Xr isdigit 3 , diff --git a/locale/FreeBSD/euc.5 b/locale/FreeBSD/euc.5 index 3a4a689..03619e7 100644 --- a/locale/FreeBSD/euc.5 +++ b/locale/FreeBSD/euc.5 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)euc.4 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/euc.5,v 1.12 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/euc.5,v 1.13 2007/01/09 00:28:00 imp Exp $ .\" .Dd November 8, 2003 .Dt EUC 5 diff --git a/locale/FreeBSD/euc.c b/locale/FreeBSD/euc.c index 3811156..6ae525a 100644 --- a/locale/FreeBSD/euc.c +++ b/locale/FreeBSD/euc.c @@ -39,7 +39,7 @@ static char sccsid[] = "@(#)euc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/euc.c,v 1.20 2004/06/23 07:01:43 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/euc.c,v 1.22 2007/10/13 16:28:21 ache Exp $"); #include #include @@ -49,11 +49,13 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/euc.c,v 1.20 2004/06/23 07:01:43 tjr Exp #include #include "mblocal.h" -int _EUC_init(_RuneLocale *); -size_t _EUC_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict); -int _EUC_mbsinit(const mbstate_t *); -size_t _EUC_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); +extern int __mb_sb_limit; + +static size_t _EUC_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _EUC_mbsinit(const mbstate_t *); +static size_t _EUC_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); typedef struct { int count[4]; @@ -116,10 +118,11 @@ _EUC_init(_RuneLocale *rl) __mbrtowc = _EUC_mbrtowc; __wcrtomb = _EUC_wcrtomb; __mbsinit = _EUC_mbsinit; + __mb_sb_limit = 256; return (0); } -int +static int _EUC_mbsinit(const mbstate_t *ps) { @@ -136,11 +139,12 @@ _EUC_mbsinit(const mbstate_t *ps) static __inline int _euc_set(u_int c) { + c &= 0xff; return ((c & 0x80) ? c == _SS3 ? 3 : c == _SS2 ? 2 : 1 : 0); } -size_t +static size_t _EUC_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { @@ -213,7 +217,7 @@ _EUC_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, return (wc == L'\0' ? 0 : s - os); } -size_t +static size_t _EUC_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _EucState *es; diff --git a/locale/FreeBSD/euc.c.patch b/locale/FreeBSD/euc.c.patch index 1bdf016..816b75b 100644 --- a/locale/FreeBSD/euc.c.patch +++ b/locale/FreeBSD/euc.c.patch @@ -1,33 +1,32 @@ ---- euc.c.orig Thu Nov 25 11:38:16 2004 -+++ euc.c Fri Feb 18 15:30:38 2005 -@@ -41,6 +41,8 @@ +--- euc.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ euc.c 2009-11-09 15:44:21.000000000 -0800 +@@ -41,6 +41,8 @@ static char sccsid[] = "@(#)euc.c 8.1 (B #include - __FBSDID("$FreeBSD: src/lib/libc/locale/euc.c,v 1.20 2004/06/23 07:01:43 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/euc.c,v 1.22 2007/10/13 16:28:21 ache Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -49,11 +51,12 @@ +@@ -49,13 +51,11 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include #include "mblocal.h" --int _EUC_init(_RuneLocale *); --size_t _EUC_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -- mbstate_t * __restrict); --int _EUC_mbsinit(const mbstate_t *); --size_t _EUC_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); -+__private_extern__ int _EUC_init(struct __xlocale_st_runelocale *); -+static size_t _EUC_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -+ mbstate_t * __restrict, locale_t); +-extern int __mb_sb_limit; +- + static size_t _EUC_mbrtowc(wchar_t * __restrict, const char * __restrict, +- size_t, mbstate_t * __restrict); +-static int _EUC_mbsinit(const mbstate_t *); ++ size_t, mbstate_t * __restrict, locale_t); +static int _EUC_mbsinit(const mbstate_t *, locale_t); -+static size_t _EUC_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, -+ locale_t); + static size_t _EUC_wcrtomb(char * __restrict, wchar_t, +- mbstate_t * __restrict); ++ mbstate_t * __restrict, locale_t); typedef struct { int count[4]; -@@ -67,12 +70,20 @@ +@@ -69,12 +69,20 @@ typedef struct { int want; } _EucState; @@ -50,7 +49,7 @@ if (rl->__variable == NULL) return (EFTYPE); -@@ -111,23 +122,21 @@ +@@ -113,24 +121,22 @@ _EUC_init(_RuneLocale *rl) } rl->__variable = ei; rl->__variable_len = sizeof(_EucInfo); @@ -59,18 +58,19 @@ - __mbrtowc = _EUC_mbrtowc; - __wcrtomb = _EUC_wcrtomb; - __mbsinit = _EUC_mbsinit; -+ xrl->__mb_cur_max = new__mb_cur_max; -+ xrl->__mbrtowc = _EUC_mbrtowc; -+ xrl->__wcrtomb = _EUC_wcrtomb; -+ xrl->__mbsinit = _EUC_mbsinit; -+ xrl->__free_extra = (__free_extra_t)_EUC_free_extra; +- __mb_sb_limit = 256; ++ xrl->__mb_cur_max = new__mb_cur_max; ++ xrl->__mbrtowc = _EUC_mbrtowc; ++ xrl->__wcrtomb = _EUC_wcrtomb; ++ xrl->__mbsinit = _EUC_mbsinit; ++ xrl->__mb_sb_limit = 256; ++ xrl->__free_extra = (__free_extra_t)_EUC_free_extra; return (0); } --int + static int -_EUC_mbsinit(const mbstate_t *ps) -+static int -+_EUC_mbsinit(const mbstate_t *ps, locale_t loc) ++_EUC_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _EucState *)ps)->want == 0); @@ -81,12 +81,9 @@ #define _SS2 0x008e #define _SS3 0x008f -@@ -140,18 +149,20 @@ - return ((c & 0x80) ? c == _SS3 ? 3 : c == _SS2 ? 2 : 1 : 0); - } +@@ -146,16 +152,18 @@ _euc_set(u_int c) --size_t -+static size_t + static size_t _EUC_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps) + mbstate_t * __restrict ps, locale_t loc) @@ -105,15 +102,12 @@ es->set > 3) { errno = EINVAL; return ((size_t)-1); -@@ -213,12 +224,14 @@ - return (wc == L'\0' ? 0 : s - os); +@@ -218,11 +226,12 @@ _EUC_mbrtowc(wchar_t * __restrict pwc, c } --size_t + static size_t -_EUC_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) -+static size_t -+_EUC_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, -+ locale_t loc) ++_EUC_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) { _EucState *es; wchar_t m, nm; diff --git a/locale/FreeBSD/fix_grouping.c.patch b/locale/FreeBSD/fix_grouping.c.patch index 96e6e3e..43adfce 100644 --- a/locale/FreeBSD/fix_grouping.c.patch +++ b/locale/FreeBSD/fix_grouping.c.patch @@ -1,6 +1,6 @@ ---- fix_grouping.c.orig 2004-11-25 11:38:16.000000000 -0800 -+++ fix_grouping.c 2004-12-07 18:11:15.000000000 -0800 -@@ -31,7 +31,8 @@ +--- fix_grouping.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ fix_grouping.c 2009-11-09 15:05:25.000000000 -0800 +@@ -31,7 +31,8 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include #include @@ -10,7 +10,7 @@ /* * Internal helper used to convert grouping sequences from string -@@ -84,3 +85,14 @@ +@@ -84,3 +85,14 @@ __fix_locale_grouping_str(const char *st *dst = '\0'; return str; } diff --git a/locale/FreeBSD/gb18030.c b/locale/FreeBSD/gb18030.c index 192b0f6..67f2b0e 100644 --- a/locale/FreeBSD/gb18030.c +++ b/locale/FreeBSD/gb18030.c @@ -30,7 +30,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/gb18030.c,v 1.6 2004/05/12 14:09:04 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/gb18030.c,v 1.8 2007/10/13 16:28:21 ache Exp $"); #include #include @@ -39,11 +39,13 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/gb18030.c,v 1.6 2004/05/12 14:09:04 tjr #include #include "mblocal.h" -int _GB18030_init(_RuneLocale *); -size_t _GB18030_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict); -int _GB18030_mbsinit(const mbstate_t *); -size_t _GB18030_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); +extern int __mb_sb_limit; + +static size_t _GB18030_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _GB18030_mbsinit(const mbstate_t *); +static size_t _GB18030_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); typedef struct { int count; @@ -59,18 +61,19 @@ _GB18030_init(_RuneLocale *rl) __mbsinit = _GB18030_mbsinit; _CurrentRuneLocale = rl; __mb_cur_max = 4; + __mb_sb_limit = 128; return (0); } -int +static int _GB18030_mbsinit(const mbstate_t *ps) { return (ps == NULL || ((const _GB18030State *)ps)->count == 0); } -size_t +static size_t _GB18030_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { @@ -154,7 +157,7 @@ ilseq: return ((size_t)-1); } -size_t +static size_t _GB18030_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _GB18030State *gs; diff --git a/locale/FreeBSD/gb18030.c.patch b/locale/FreeBSD/gb18030.c.patch index de83cc1..10f81f8 100644 --- a/locale/FreeBSD/gb18030.c.patch +++ b/locale/FreeBSD/gb18030.c.patch @@ -1,30 +1,29 @@ ---- gb18030.c.orig Thu Nov 25 11:38:16 2004 -+++ gb18030.c Fri Feb 18 15:43:22 2005 +--- gb18030.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ gb18030.c 2009-11-09 15:50:31.000000000 -0800 @@ -32,6 +32,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/gb18030.c,v 1.6 2004/05/12 14:09:04 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/gb18030.c,v 1.8 2007/10/13 16:28:21 ache Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -39,40 +41,41 @@ +@@ -39,35 +41,34 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include #include "mblocal.h" --int _GB18030_init(_RuneLocale *); --size_t _GB18030_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -- mbstate_t * __restrict); --int _GB18030_mbsinit(const mbstate_t *); --size_t _GB18030_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); +-extern int __mb_sb_limit; +#define GB18030_MB_CUR_MAX 4 -+ -+__private_extern__ int _GB18030_init(struct __xlocale_st_runelocale *); -+static size_t _GB18030_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -+ mbstate_t * __restrict, locale_t); + + static size_t _GB18030_mbrtowc(wchar_t * __restrict, const char * __restrict, +- size_t, mbstate_t * __restrict); +-static int _GB18030_mbsinit(const mbstate_t *); ++ size_t, mbstate_t * __restrict, locale_t); +static int _GB18030_mbsinit(const mbstate_t *, locale_t); -+static size_t _GB18030_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); + static size_t _GB18030_wcrtomb(char * __restrict, wchar_t, +- mbstate_t * __restrict); ++ mbstate_t * __restrict, locale_t); typedef struct { int count; @@ -42,32 +41,32 @@ - __mbsinit = _GB18030_mbsinit; - _CurrentRuneLocale = rl; - __mb_cur_max = 4; +- __mb_sb_limit = 128; + xrl->__mbrtowc = _GB18030_mbrtowc; + xrl->__wcrtomb = _GB18030_wcrtomb; + xrl->__mbsinit = _GB18030_mbsinit; + xrl->__mb_cur_max = GB18030_MB_CUR_MAX; ++ xrl->__mb_sb_limit = 128; return (0); } --int + static int -_GB18030_mbsinit(const mbstate_t *ps) -+static int -+_GB18030_mbsinit(const mbstate_t *ps, locale_t loc) ++_GB18030_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _GB18030State *)ps)->count == 0); - } +@@ -75,7 +76,7 @@ _GB18030_mbsinit(const mbstate_t *ps) --size_t -+static size_t + static size_t _GB18030_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, - size_t n, mbstate_t * __restrict ps) -+ size_t n, mbstate_t * __restrict ps, locale_t loc) ++ size_t n, mbstate_t * __restrict ps, locale_t loc __unused) { _GB18030State *gs; wchar_t wch; -@@ -92,7 +95,7 @@ +@@ -95,7 +96,7 @@ _GB18030_mbrtowc(wchar_t * __restrict pw pwc = NULL; } @@ -76,14 +75,12 @@ memcpy(gs->bytes + gs->count, s, ncopy); ocount = gs->count; gs->count += ncopy; -@@ -154,8 +157,8 @@ - return ((size_t)-1); +@@ -158,7 +159,7 @@ ilseq: } --size_t + static size_t -_GB18030_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) -+static size_t -+_GB18030_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) ++_GB18030_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc __unused) { _GB18030State *gs; size_t len; diff --git a/locale/FreeBSD/gb2312.c b/locale/FreeBSD/gb2312.c index 4cf94b7..5f47bd0 100644 --- a/locale/FreeBSD/gb2312.c +++ b/locale/FreeBSD/gb2312.c @@ -26,7 +26,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/gb2312.c,v 1.8 2004/05/12 14:09:04 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/gb2312.c,v 1.10 2007/10/13 16:28:21 ache Exp $"); #include #include @@ -35,11 +35,13 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/gb2312.c,v 1.8 2004/05/12 14:09:04 tjr E #include #include "mblocal.h" -int _GB2312_init(_RuneLocale *); -size_t _GB2312_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict); -int _GB2312_mbsinit(const mbstate_t *); -size_t _GB2312_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); +extern int __mb_sb_limit; + +static size_t _GB2312_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _GB2312_mbsinit(const mbstate_t *); +static size_t _GB2312_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); typedef struct { int count; @@ -55,10 +57,11 @@ _GB2312_init(_RuneLocale *rl) __wcrtomb = _GB2312_wcrtomb; __mbsinit = _GB2312_mbsinit; __mb_cur_max = 2; + __mb_sb_limit = 128; return (0); } -int +static int _GB2312_mbsinit(const mbstate_t *ps) { @@ -88,7 +91,7 @@ _GB2312_check(const char *str, size_t n) return (1); } -size_t +static size_t _GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { @@ -129,7 +132,7 @@ _GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, return (wc == L'\0' ? 0 : len - ocount); } -size_t +static size_t _GB2312_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _GB2312State *gs; diff --git a/locale/FreeBSD/gb2312.c.patch b/locale/FreeBSD/gb2312.c.patch index 796dbf6..7912ed0 100644 --- a/locale/FreeBSD/gb2312.c.patch +++ b/locale/FreeBSD/gb2312.c.patch @@ -1,31 +1,30 @@ ---- gb2312.c.orig Thu Nov 25 11:38:17 2004 -+++ gb2312.c Fri Feb 18 15:45:33 2005 +--- gb2312.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ gb2312.c 2009-11-09 16:10:25.000000000 -0800 @@ -28,6 +28,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/gb2312.c,v 1.8 2004/05/12 14:09:04 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/gb2312.c,v 1.10 2007/10/13 16:28:21 ache Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -35,31 +37,32 @@ +@@ -35,34 +37,32 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include #include "mblocal.h" --int _GB2312_init(_RuneLocale *); --size_t _GB2312_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -- mbstate_t * __restrict); --int _GB2312_mbsinit(const mbstate_t *); --size_t _GB2312_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); +-extern int __mb_sb_limit; +#define GB2312_MB_CUR_MAX 2 -+ -+__private_extern__ int _GB2312_init(struct __xlocale_st_runelocale *); -+static size_t _GB2312_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -+ mbstate_t * __restrict, locale_t); -+static int _GB2312_mbsinit(const mbstate_t *, locale_t); -+static size_t _GB2312_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); + static size_t _GB2312_mbrtowc(wchar_t * __restrict, const char * __restrict, +- size_t, mbstate_t * __restrict); +-static int _GB2312_mbsinit(const mbstate_t *); ++ size_t, mbstate_t * __restrict, locale_t); ++static int _GB2312_mbsinit(const mbstate_t *, locale_t); + static size_t _GB2312_wcrtomb(char * __restrict, wchar_t, +- mbstate_t * __restrict); +- ++ mbstate_t * __restrict, locale_t); typedef struct { int count; u_char bytes[2]; @@ -42,33 +41,31 @@ - __wcrtomb = _GB2312_wcrtomb; - __mbsinit = _GB2312_mbsinit; - __mb_cur_max = 2; +- __mb_sb_limit = 128; + xrl->__mbrtowc = _GB2312_mbrtowc; + xrl->__wcrtomb = _GB2312_wcrtomb; + xrl->__mbsinit = _GB2312_mbsinit; + xrl->__mb_cur_max = GB2312_MB_CUR_MAX; ++ xrl->__mb_sb_limit = 128; return (0); } --int + static int -_GB2312_mbsinit(const mbstate_t *ps) -+static int -+_GB2312_mbsinit(const mbstate_t *ps, locale_t loc) ++_GB2312_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _GB2312State *)ps)->count == 0); -@@ -88,9 +91,9 @@ - return (1); - } +@@ -93,7 +93,7 @@ _GB2312_check(const char *str, size_t n) --size_t -+static size_t + static size_t _GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps) -+ mbstate_t * __restrict ps, locale_t loc) ++ mbstate_t * __restrict ps, locale_t loc __unused) { _GB2312State *gs; wchar_t wc; -@@ -110,7 +113,7 @@ +@@ -113,7 +113,7 @@ _GB2312_mbrtowc(wchar_t * __restrict pwc pwc = NULL; } @@ -77,14 +74,12 @@ memcpy(gs->bytes + gs->count, s, ncopy); ocount = gs->count; gs->count += ncopy; -@@ -129,8 +132,8 @@ - return (wc == L'\0' ? 0 : len - ocount); +@@ -133,7 +133,7 @@ _GB2312_mbrtowc(wchar_t * __restrict pwc } --size_t + static size_t -_GB2312_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) -+static size_t -+_GB2312_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) ++_GB2312_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc __unused) { _GB2312State *gs; diff --git a/locale/FreeBSD/gbk.c b/locale/FreeBSD/gbk.c index 6adcc41..3b30f10 100644 --- a/locale/FreeBSD/gbk.c +++ b/locale/FreeBSD/gbk.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,9 +31,10 @@ * SUCH DAMAGE. */ -#include -__FBSDID("$FreeBSD: src/lib/libc/locale/gbk.c,v 1.11 2004/05/17 11:16:14 tjr Exp $"); +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/gbk.c,v 1.14 2007/10/13 16:28:21 ache Exp $"); +#include #include #include #include @@ -45,11 +42,13 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/gbk.c,v 1.11 2004/05/17 11:16:14 tjr Exp #include #include "mblocal.h" -int _GBK_init(_RuneLocale *); -size_t _GBK_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict); -int _GBK_mbsinit(const mbstate_t *); -size_t _GBK_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); +extern int __mb_sb_limit; + +static size_t _GBK_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _GBK_mbsinit(const mbstate_t *); +static size_t _GBK_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); typedef struct { wchar_t ch; @@ -64,10 +63,11 @@ _GBK_init(_RuneLocale *rl) __mbsinit = _GBK_mbsinit; _CurrentRuneLocale = rl; __mb_cur_max = 2; + __mb_sb_limit = 128; return (0); } -int +static int _GBK_mbsinit(const mbstate_t *ps) { @@ -82,7 +82,7 @@ _gbk_check(u_int c) return ((c >= 0x81 && c <= 0xfe) ? 2 : 1); } -size_t +static size_t _GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { @@ -143,7 +143,7 @@ _GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } } -size_t +static size_t _GBK_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _GBKState *gs; diff --git a/locale/FreeBSD/gbk.c.patch b/locale/FreeBSD/gbk.c.patch index 71081d5..df89765 100644 --- a/locale/FreeBSD/gbk.c.patch +++ b/locale/FreeBSD/gbk.c.patch @@ -1,28 +1,28 @@ ---- gbk.c.orig Thu Nov 25 11:38:17 2004 -+++ gbk.c Fri Feb 18 15:46:58 2005 -@@ -38,6 +38,8 @@ - #include - __FBSDID("$FreeBSD: src/lib/libc/locale/gbk.c,v 1.11 2004/05/17 11:16:14 tjr Exp $"); +--- gbk.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ gbk.c 2009-11-09 16:27:30.000000000 -0800 +@@ -34,6 +34,8 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/locale/gbk.c,v 1.14 2007/10/13 16:28:21 ache Exp $"); +#include "xlocale_private.h" + + #include #include #include - #include -@@ -45,30 +47,29 @@ +@@ -42,33 +44,30 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include #include "mblocal.h" --int _GBK_init(_RuneLocale *); --size_t _GBK_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -- mbstate_t * __restrict); --int _GBK_mbsinit(const mbstate_t *); --size_t _GBK_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); -+__private_extern__ int _GBK_init(struct __xlocale_st_runelocale *); -+static size_t _GBK_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -+ mbstate_t * __restrict, locale_t); +-extern int __mb_sb_limit; +- + static size_t _GBK_mbrtowc(wchar_t * __restrict, const char * __restrict, +- size_t, mbstate_t * __restrict); +-static int _GBK_mbsinit(const mbstate_t *); ++ size_t, mbstate_t * __restrict, locale_t); +static int _GBK_mbsinit(const mbstate_t *, locale_t); -+static size_t _GBK_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); + static size_t _GBK_wcrtomb(char * __restrict, wchar_t, +- mbstate_t * __restrict); ++ mbstate_t * __restrict, locale_t); typedef struct { wchar_t ch; @@ -39,40 +39,36 @@ - __mbsinit = _GBK_mbsinit; - _CurrentRuneLocale = rl; - __mb_cur_max = 2; +- __mb_sb_limit = 128; + xrl->__mbrtowc = _GBK_mbrtowc; + xrl->__wcrtomb = _GBK_wcrtomb; + xrl->__mbsinit = _GBK_mbsinit; + xrl->__mb_cur_max = 2; ++ xrl->__mb_sb_limit = 128; return (0); } --int + static int -_GBK_mbsinit(const mbstate_t *ps) -+static int -+_GBK_mbsinit(const mbstate_t *ps, locale_t loc) ++_GBK_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _GBKState *)ps)->ch == 0); -@@ -82,9 +83,9 @@ - return ((c >= 0x81 && c <= 0xfe) ? 2 : 1); - } +@@ -84,7 +83,7 @@ _gbk_check(u_int c) --size_t -+static size_t + static size_t _GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps) -+ mbstate_t * __restrict ps, locale_t loc) ++ mbstate_t * __restrict ps, locale_t loc __unused) { _GBKState *gs; wchar_t wc; -@@ -143,8 +144,8 @@ - } +@@ -144,7 +143,7 @@ _GBK_mbrtowc(wchar_t * __restrict pwc, c } --size_t + static size_t -_GBK_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) -+static size_t -+_GBK_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) ++_GBK_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc __unused) { _GBKState *gs; diff --git a/locale/FreeBSD/isalnum.3 b/locale/FreeBSD/isalnum.3 index 72c1137..85fb66b 100644 --- a/locale/FreeBSD/isalnum.3 +++ b/locale/FreeBSD/isalnum.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isalnum.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isalnum.3,v 1.19 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isalnum.3,v 1.24 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISALNUM 3 .Os .Sh NAME @@ -56,15 +52,11 @@ function tests for any character for which or .Xr isdigit 3 is true. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): .Pp @@ -103,7 +95,6 @@ function should be used instead. .Xr isalpha 3 , .Xr isdigit 3 , .Xr iswalnum 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/FreeBSD/isalnum.3.patch b/locale/FreeBSD/isalnum.3.patch index 2a53f70..0bb3f5a 100644 --- a/locale/FreeBSD/isalnum.3.patch +++ b/locale/FreeBSD/isalnum.3.patch @@ -1,23 +1,15 @@ ---- isalnum.3 2004-11-25 11:38:17.000000000 -0800 -+++ isalnum.3.edit 2006-08-09 13:19:45.000000000 -0700 -@@ -59,14 +59,14 @@ - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char - or the value of +--- isalnum.3.bsdnew 2009-11-10 13:13:10.000000000 -0800 ++++ isalnum.3 2009-11-10 13:22:59.000000000 -0800 +@@ -58,7 +58,7 @@ or the value of .Dv EOF . + .Pp In the ASCII character set, this includes the following characters -(with their numeric values shown in octal): +(preceded by their numeric values, in octal): .Pp .Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ .It "\&060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3'' \t064\ ``4''" -@@ -100,6 +100,7 @@ +@@ -92,6 +92,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , diff --git a/locale/FreeBSD/isalpha.3 b/locale/FreeBSD/isalpha.3 index 08ba88e..7369cb5 100644 --- a/locale/FreeBSD/isalpha.3 +++ b/locale/FreeBSD/isalpha.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isalpha.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isalpha.3,v 1.18 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isalpha.3,v 1.23 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISALPHA 3 .Os .Sh NAME @@ -56,15 +52,11 @@ function tests for any character for which or .Xr islower 3 is true. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): .Pp @@ -101,7 +93,6 @@ function should be used instead. .Xr islower 3 , .Xr isupper 3 , .Xr iswalpha 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/FreeBSD/isalpha.3.patch b/locale/FreeBSD/isalpha.3.patch index ccdc0d8..9263ce3 100644 --- a/locale/FreeBSD/isalpha.3.patch +++ b/locale/FreeBSD/isalpha.3.patch @@ -1,23 +1,15 @@ ---- isalpha.3 2004-11-25 11:38:17.000000000 -0800 -+++ isalpha.3.edit 2006-08-09 13:21:04.000000000 -0700 -@@ -59,14 +59,14 @@ - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char - or the value of +--- isalpha.3.bsdnew 2009-11-10 13:13:10.000000000 -0800 ++++ isalpha.3 2009-11-10 13:24:18.000000000 -0800 +@@ -58,7 +58,7 @@ or the value of .Dv EOF . + .Pp In the ASCII character set, this includes the following characters -(with their numeric values shown in octal): +(preceded by their numeric values, in octal): .Pp .Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ .It "\&101\ ``A'' \t102\ ``B'' \t103\ ``C'' \t104\ ``D'' \t105\ ``E''" -@@ -98,6 +98,7 @@ +@@ -90,6 +90,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , diff --git a/locale/FreeBSD/isascii.3 b/locale/FreeBSD/isascii.3 index b930401..6a0c4ea 100644 --- a/locale/FreeBSD/isascii.3 +++ b/locale/FreeBSD/isascii.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)isascii.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/locale/isascii.3,v 1.13 2002/10/06 10:15:38 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isascii.3,v 1.16 2009/09/04 07:44:58 des Exp $ .\" .Dd October 6, 2002 .Dt ISASCII 3 diff --git a/locale/FreeBSD/isblank.3 b/locale/FreeBSD/isblank.3 index 50c4f58..bdba080 100644 --- a/locale/FreeBSD/isblank.3 +++ b/locale/FreeBSD/isblank.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isblank.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isblank.3,v 1.19 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isblank.3,v 1.26 2009/11/11 11:31:02 roam Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISBLANK 3 .Os .Sh NAME @@ -54,18 +50,18 @@ For any locale, this includes the following standard characters: .It "\&``\et''\t`` ''" .El .Pp -In the "C" locale +In the "C" locale, a successful .Fn isblank -successful test is limited to this characters only. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +test is limited to these characters only. +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Sh RETURN VALUES +The +.Fn isblank +function returns zero if the character tests false and +returns non-zero if the character tests true. .Sh COMPATIBILITY The .Bx 4.4 @@ -76,15 +72,9 @@ and may not be supported in future releases. The .Fn iswblank function should be used instead. -.Sh RETURN VALUES -The -.Fn isblank -function returns zero if the character tests false and -returns non-zero if the character tests true. .Sh SEE ALSO .Xr ctype 3 , .Xr iswblank 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/FreeBSD/isblank.3.patch b/locale/FreeBSD/isblank.3.patch index 7d5bc4d..1da0af0 100644 --- a/locale/FreeBSD/isblank.3.patch +++ b/locale/FreeBSD/isblank.3.patch @@ -1,27 +1,10 @@ ---- isblank.3 2004-11-25 11:38:17.000000000 -0800 -+++ isblank.3.edit 2006-08-09 13:23:09.000000000 -0700 -@@ -54,13 +54,13 @@ - .It "\&``\et''\t`` ''" - .El - .Pp --In the "C" locale -+In the "C" locale, - .Fn isblank --successful test is limited to this characters only. -+successful test is limited to these characters only. - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char -@@ -83,6 +83,7 @@ - returns non-zero if the character tests true. +--- isblank.3.orig 2009-11-30 16:10:19.000000000 -0800 ++++ isblank.3 2009-11-30 16:10:19.000000000 -0800 +@@ -74,6 +74,7 @@ The + function should be used instead. .Sh SEE ALSO .Xr ctype 3 , +.Xr isalnum_l 3 , .Xr iswblank 3 , - .Xr multibyte 3 , .Xr ascii 7 + .Sh STANDARDS diff --git a/locale/FreeBSD/iscntrl.3 b/locale/FreeBSD/iscntrl.3 index f2582bc..b12e912 100644 --- a/locale/FreeBSD/iscntrl.3 +++ b/locale/FreeBSD/iscntrl.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)iscntrl.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/iscntrl.3,v 1.17 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/iscntrl.3,v 1.22 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISCNTRL 3 .Os .Sh NAME @@ -52,15 +48,11 @@ The .Fn iscntrl function tests for any control character. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): .Pp @@ -91,7 +83,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr iswcntrl 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/FreeBSD/iscntrl.3.patch b/locale/FreeBSD/iscntrl.3.patch index 06d84fd..cbb58e0 100644 --- a/locale/FreeBSD/iscntrl.3.patch +++ b/locale/FreeBSD/iscntrl.3.patch @@ -1,27 +1,19 @@ ---- iscntrl.3 2004-11-25 11:38:17.000000000 -0800 -+++ iscntrl.3.edit 2006-08-09 13:23:23.000000000 -0700 -@@ -55,14 +55,14 @@ - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char - or the value of +--- iscntrl.3.bsdnew 2009-11-10 13:13:10.000000000 -0800 ++++ iscntrl.3 2009-11-10 13:33:05.000000000 -0800 +@@ -54,7 +54,7 @@ or the value of .Dv EOF . + .Pp In the ASCII character set, this includes the following characters -(with their numeric values shown in octal): +(preceded by their numeric values, in octal): .Pp .Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ .It "\&000\ NUL \t001\ SOH \t002\ STX \t003\ ETX \t004\ EOT" -@@ -90,6 +90,7 @@ +@@ -82,6 +82,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , +.Xr isalnum_l 3 , .Xr iswcntrl 3 , - .Xr multibyte 3 , .Xr ascii 7 + .Sh STANDARDS diff --git a/locale/FreeBSD/isdigit.3 b/locale/FreeBSD/isdigit.3 index 1c8bea8..587df33 100644 --- a/locale/FreeBSD/isdigit.3 +++ b/locale/FreeBSD/isdigit.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isdigit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isdigit.3,v 1.19 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isdigit.3,v 1.25 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd May 4, 2007 .Dt ISDIGIT 3 .Os .Sh NAME @@ -68,13 +64,8 @@ function behaves similarly to but may recognize additional characters, depending on the current locale setting. .Pp -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . .Sh RETURN VALUES @@ -83,7 +74,7 @@ The and .Fn isnumber functions return zero if the character tests false and -returns non-zero if the character tests true. +return non-zero if the character tests true. .Sh COMPATIBILITY The .Bx 4.4 diff --git a/locale/FreeBSD/isdigit.3.patch b/locale/FreeBSD/isdigit.3.patch index 3545a7c..0ddb02e 100644 --- a/locale/FreeBSD/isdigit.3.patch +++ b/locale/FreeBSD/isdigit.3.patch @@ -1,24 +1,6 @@ ---- isdigit.3 2004-11-25 11:38:17.000000000 -0800 -+++ isdigit.3.edit 2006-08-09 13:23:40.000000000 -0700 -@@ -71,7 +71,7 @@ - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char -@@ -83,7 +83,7 @@ - and - .Fn isnumber - functions return zero if the character tests false and --returns non-zero if the character tests true. -+return non-zero if the character tests true. - .Sh COMPATIBILITY - The - .Bx 4.4 -@@ -96,6 +96,7 @@ +--- isdigit.3.bsdnew 2009-11-10 13:13:10.000000000 -0800 ++++ isdigit.3 2009-11-10 13:34:59.000000000 -0800 +@@ -87,6 +87,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , diff --git a/locale/FreeBSD/isgraph.3 b/locale/FreeBSD/isgraph.3 index a4b3ba3..bc2ada6 100644 --- a/locale/FreeBSD/isgraph.3 +++ b/locale/FreeBSD/isgraph.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isgraph.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/locale/isgraph.3,v 1.19 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isgraph.3,v 1.25 2009/11/13 09:03:50 roam Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISGRAPH 3 .Os .Sh NAME @@ -54,16 +50,12 @@ The function tests for any printing character except space .Pq Ql "\ " and other -locale specific space-like characters. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +locale-specific space-like characters. +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): .Pp @@ -106,7 +98,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr iswgraph 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/FreeBSD/isgraph.3.patch b/locale/FreeBSD/isgraph.3.patch index 1acc762..99180c0 100644 --- a/locale/FreeBSD/isgraph.3.patch +++ b/locale/FreeBSD/isgraph.3.patch @@ -1,32 +1,19 @@ ---- isgraph.3 2004-11-25 11:38:17.000000000 -0800 -+++ isgraph.3.edit 2006-08-09 13:23:59.000000000 -0700 -@@ -54,18 +54,18 @@ - function tests for any printing character except space - .Pq Ql "\ " - and other --locale specific space-like characters. -+locale-specific, space-like characters. - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char - or the value of +--- isgraph.3.orig 2009-11-30 16:10:19.000000000 -0800 ++++ isgraph.3 2009-11-30 16:11:41.000000000 -0800 +@@ -57,7 +57,7 @@ or the value of .Dv EOF . + .Pp In the ASCII character set, this includes the following characters -(with their numeric values shown in octal): +(preceded by their numeric values, in octal): .Pp .Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ .It "\&041\ ``!'' \t042\ ``""'' \t043\ ``#'' \t044\ ``$'' \t045\ ``%''" -@@ -105,6 +105,7 @@ +@@ -97,6 +97,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , +.Xr isalnum_l 3 , .Xr iswgraph 3 , - .Xr multibyte 3 , .Xr ascii 7 + .Sh STANDARDS diff --git a/locale/FreeBSD/isideogram.3 b/locale/FreeBSD/isideogram.3 index e4fe16b..35d6718 100644 --- a/locale/FreeBSD/isideogram.3 +++ b/locale/FreeBSD/isideogram.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/isideogram.3,v 1.2 2004/07/04 20:55:48 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isideogram.3,v 1.4 2009/09/04 07:44:58 des Exp $ .\" .Dd March 30, 2004 .Dt ISIDEOGRAM 3 diff --git a/locale/FreeBSD/isideogram.3.patch b/locale/FreeBSD/isideogram.3.patch index cb0f91e..9d5ebc4 100644 --- a/locale/FreeBSD/isideogram.3.patch +++ b/locale/FreeBSD/isideogram.3.patch @@ -1,6 +1,6 @@ ---- isideogram.3.orig Fri Mar 11 19:25:22 2005 -+++ isideogram.3 Fri Mar 11 19:26:54 2005 -@@ -49,7 +49,8 @@ +--- isideogram.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ isideogram.3 2009-11-09 15:05:26.000000000 -0800 +@@ -49,7 +49,8 @@ returns non-zero if the character tests .Sh SEE ALSO .Xr ctype 3 , .Xr isphonogram 3 , diff --git a/locale/FreeBSD/islower.3 b/locale/FreeBSD/islower.3 index 156e38d..889ece1 100644 --- a/locale/FreeBSD/islower.3 +++ b/locale/FreeBSD/islower.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)islower.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/islower.3,v 1.17 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/islower.3,v 1.22 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISLOWER 3 .Os .Sh NAME @@ -52,15 +48,11 @@ The .Fn islower function tests for any lower-case letters. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): .Pp @@ -90,7 +82,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr iswlower 3 , -.Xr multibyte 3 , .Xr tolower 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/FreeBSD/islower.3.patch b/locale/FreeBSD/islower.3.patch index 4198265..102cc14 100644 --- a/locale/FreeBSD/islower.3.patch +++ b/locale/FreeBSD/islower.3.patch @@ -1,10 +1,10 @@ ---- islower.3 2004-11-25 11:38:17.000000000 -0800 -+++ islower.3.edit 2006-08-09 13:24:14.000000000 -0700 -@@ -89,6 +89,7 @@ +--- islower.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ islower.3 2009-11-09 15:05:26.000000000 -0800 +@@ -81,6 +81,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , +.Xr isalnum_l 3 , .Xr iswlower 3 , - .Xr multibyte 3 , .Xr tolower 3 , + .Xr ascii 7 diff --git a/locale/FreeBSD/isphonogram.3 b/locale/FreeBSD/isphonogram.3 index 66bd006..57a575a 100644 --- a/locale/FreeBSD/isphonogram.3 +++ b/locale/FreeBSD/isphonogram.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/isphonogram.3,v 1.1 2004/03/30 07:23:54 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isphonogram.3,v 1.3 2009/09/04 07:44:58 des Exp $ .\" .Dd March 30, 2004 .Dt ISPHONOGRAM 3 diff --git a/locale/FreeBSD/isphonogram.3.patch b/locale/FreeBSD/isphonogram.3.patch index ed26476..10bff7a 100644 --- a/locale/FreeBSD/isphonogram.3.patch +++ b/locale/FreeBSD/isphonogram.3.patch @@ -1,6 +1,6 @@ ---- isphonogram.3.orig Fri Mar 11 19:25:22 2005 -+++ isphonogram.3 Fri Mar 11 19:26:47 2005 -@@ -49,7 +49,8 @@ +--- isphonogram.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ isphonogram.3 2009-11-09 15:05:26.000000000 -0800 +@@ -49,7 +49,8 @@ returns non-zero if the character tests .Sh SEE ALSO .Xr ctype 3 , .Xr isideogram 3 , diff --git a/locale/FreeBSD/isprint.3 b/locale/FreeBSD/isprint.3 index 60a289f..70c1807 100644 --- a/locale/FreeBSD/isprint.3 +++ b/locale/FreeBSD/isprint.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isprint.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isprint.3,v 1.20 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isprint.3,v 1.26 2009/11/13 09:07:33 roam Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISPRINT 3 .Os .Sh NAME @@ -51,17 +47,13 @@ .Sh DESCRIPTION The .Fn isprint -function tests for any printing character including space +function tests for any printing character, including space .Pq Ql "\ " . -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): .Pp @@ -104,7 +96,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr iswprint 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/FreeBSD/isprint.3.patch b/locale/FreeBSD/isprint.3.patch index 9a24905..4e71b97 100644 --- a/locale/FreeBSD/isprint.3.patch +++ b/locale/FreeBSD/isprint.3.patch @@ -1,33 +1,19 @@ ---- isprint.3 2004-11-25 11:38:17.000000000 -0800 -+++ isprint.3.edit 2006-08-09 13:24:27.000000000 -0700 -@@ -51,19 +51,19 @@ - .Sh DESCRIPTION - The - .Fn isprint --function tests for any printing character including space -+function tests for any printing character, including space - .Pq Ql "\ " . - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char - or the value of +--- isprint.3.orig 2009-11-30 16:10:19.000000000 -0800 ++++ isprint.3 2009-11-30 16:10:29.000000000 -0800 +@@ -55,7 +55,7 @@ or the value of .Dv EOF . + .Pp In the ASCII character set, this includes the following characters -(with their numeric values shown in octal): +(preceded by their numeric values, in octal): .Pp .Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ .It "\&040\ sp \t041\ ``!'' \t042\ ``""'' \t043\ ``#'' \t044\ ``$''" -@@ -103,6 +103,7 @@ +@@ -95,6 +95,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , +.Xr isalnum_l 3 , .Xr iswprint 3 , - .Xr multibyte 3 , .Xr ascii 7 + .Sh STANDARDS diff --git a/locale/FreeBSD/ispunct.3 b/locale/FreeBSD/ispunct.3 index 420882c..1b47166 100644 --- a/locale/FreeBSD/ispunct.3 +++ b/locale/FreeBSD/ispunct.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)ispunct.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/ispunct.3,v 1.18 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/ispunct.3,v 1.23 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISPUNCT 3 .Os .Sh NAME @@ -57,15 +53,11 @@ or a character for which .Xr isalnum 3 is true. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): .Pp @@ -96,7 +88,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr iswpunct 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/FreeBSD/ispunct.3.patch b/locale/FreeBSD/ispunct.3.patch index 95393d0..d59803f 100644 --- a/locale/FreeBSD/ispunct.3.patch +++ b/locale/FreeBSD/ispunct.3.patch @@ -1,6 +1,6 @@ ---- ispunct.3 2004-11-25 11:38:17.000000000 -0800 -+++ ispunct.3.edit 2006-08-09 13:24:42.000000000 -0700 -@@ -51,7 +51,7 @@ +--- ispunct.3.bsdnew 2009-11-10 13:13:10.000000000 -0800 ++++ ispunct.3 2009-11-10 13:17:02.000000000 -0800 +@@ -47,7 +47,7 @@ .Sh DESCRIPTION The .Fn ispunct @@ -9,28 +9,20 @@ .Pq Ql "\ " or a character for which -@@ -60,14 +60,14 @@ - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char - or the value of +@@ -59,7 +59,7 @@ or the value of .Dv EOF . + .Pp In the ASCII character set, this includes the following characters -(with their numeric values shown in octal): +(preceded by their numeric values, in octal): .Pp .Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ .It "\&041\ ``!'' \t042\ ``""'' \t043\ ``#'' \t044\ ``$'' \t045\ ``%''" -@@ -95,6 +95,7 @@ +@@ -87,6 +87,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , +.Xr isalnum_l 3 , .Xr iswpunct 3 , - .Xr multibyte 3 , .Xr ascii 7 + .Sh STANDARDS diff --git a/locale/FreeBSD/isrune.3 b/locale/FreeBSD/isrune.3 index 2b1f64f..e474f3e 100644 --- a/locale/FreeBSD/isrune.3 +++ b/locale/FreeBSD/isrune.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/isrune.3,v 1.1 2004/03/30 07:23:54 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isrune.3,v 1.3 2009/09/04 07:44:58 des Exp $ .\" .Dd March 30, 2004 .Dt ISRUNE 3 diff --git a/locale/FreeBSD/isrune.3.patch b/locale/FreeBSD/isrune.3.patch index 62b0500..b268fac 100644 --- a/locale/FreeBSD/isrune.3.patch +++ b/locale/FreeBSD/isrune.3.patch @@ -1,6 +1,6 @@ ---- isrune.3.orig Fri Mar 11 19:25:22 2005 -+++ isrune.3 Fri Mar 11 19:26:33 2005 -@@ -55,7 +55,8 @@ +--- isrune.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ isrune.3 2009-11-09 15:05:26.000000000 -0800 +@@ -55,7 +55,8 @@ returns non-zero if the character tests .Xr ctype 3 , .Xr isascii 3 , .Xr iswrune 3 , diff --git a/locale/FreeBSD/isspace.3 b/locale/FreeBSD/isspace.3 index ab5a771..46588ec 100644 --- a/locale/FreeBSD/isspace.3 +++ b/locale/FreeBSD/isspace.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isspace.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isspace.3,v 1.17 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isspace.3,v 1.22 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISSPACE 3 .Os .Sh NAME @@ -61,13 +57,8 @@ For any locale, this includes the following standard characters: In the "C" locale .Fn isspace successful test is limited to this characters only. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . .Sh RETURN VALUES diff --git a/locale/FreeBSD/isspace.3.patch b/locale/FreeBSD/isspace.3.patch index ede5cfb..d1a8f9a 100644 --- a/locale/FreeBSD/isspace.3.patch +++ b/locale/FreeBSD/isspace.3.patch @@ -1,6 +1,6 @@ ---- isspace.3 2004-11-25 11:38:17.000000000 -0800 -+++ isspace.3.edit 2006-08-09 13:24:59.000000000 -0700 -@@ -58,13 +58,13 @@ +--- isspace.3.bsdnew 2009-11-10 13:13:10.000000000 -0800 ++++ isspace.3 2009-11-10 13:45:41.000000000 -0800 +@@ -54,9 +54,9 @@ For any locale, this includes the follow .It "\&``\et''\t``\en''\t``\ev''\t``\ef''\t``\er''\t`` ''" .El .Pp @@ -9,15 +9,10 @@ .Fn isspace -successful test is limited to this characters only. +successful test is limited to these characters only. - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char -@@ -87,6 +87,7 @@ + The value of the argument must be representable as an + .Vt "unsigned char" + or the value of +@@ -78,6 +78,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , diff --git a/locale/FreeBSD/isspecial.3 b/locale/FreeBSD/isspecial.3 index 57eefc8..f356b4a 100644 --- a/locale/FreeBSD/isspecial.3 +++ b/locale/FreeBSD/isspecial.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/isspecial.3,v 1.1 2004/03/30 07:23:54 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isspecial.3,v 1.3 2009/09/04 07:44:58 des Exp $ .\" .Dd March 30, 2004 .Dt ISSPECIAL 3 diff --git a/locale/FreeBSD/isspecial.3.patch b/locale/FreeBSD/isspecial.3.patch index 79d27e2..d427920 100644 --- a/locale/FreeBSD/isspecial.3.patch +++ b/locale/FreeBSD/isspecial.3.patch @@ -1,6 +1,6 @@ ---- isspecial.3.orig Fri Mar 11 19:25:22 2005 -+++ isspecial.3 Fri Mar 11 19:26:16 2005 -@@ -48,7 +48,8 @@ +--- isspecial.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ isspecial.3 2009-11-09 15:05:26.000000000 -0800 +@@ -48,7 +48,8 @@ function returns zero if the character t returns non-zero if the character tests true. .Sh SEE ALSO .Xr ctype 3 , diff --git a/locale/FreeBSD/isupper.3 b/locale/FreeBSD/isupper.3 index c533b97..3d84bef 100644 --- a/locale/FreeBSD/isupper.3 +++ b/locale/FreeBSD/isupper.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isupper.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isupper.3,v 1.18 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isupper.3,v 1.23 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISUPPER 3 .Os .Sh NAME @@ -52,15 +48,11 @@ The .Fn isupper function tests for any upper-case letter. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): .Pp @@ -90,7 +82,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr iswupper 3 , -.Xr multibyte 3 , .Xr toupper 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/FreeBSD/isupper.3.patch b/locale/FreeBSD/isupper.3.patch index 6c8b17c..3cd6e29 100644 --- a/locale/FreeBSD/isupper.3.patch +++ b/locale/FreeBSD/isupper.3.patch @@ -1,27 +1,19 @@ ---- isupper.3 2004-11-25 11:38:17.000000000 -0800 -+++ isupper.3.edit 2006-08-09 13:25:22.000000000 -0700 -@@ -55,14 +55,14 @@ - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char - or the value of +--- isupper.3.bsdnew 2009-11-10 13:13:10.000000000 -0800 ++++ isupper.3 2009-11-10 13:48:09.000000000 -0800 +@@ -54,7 +54,7 @@ or the value of .Dv EOF . + .Pp In the ASCII character set, this includes the following characters -(with their numeric values shown in octal): +(preceded by their numeric values, in octal): .Pp .Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ .It "\&101\ ``A'' \t102\ ``B'' \t103\ ``C'' \t104\ ``D'' \t105\ ``E''" -@@ -89,6 +89,7 @@ +@@ -81,6 +81,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , +.Xr isalnum_l 3 , .Xr iswupper 3 , - .Xr multibyte 3 , .Xr toupper 3 , + .Xr ascii 7 diff --git a/locale/FreeBSD/iswalnum.3 b/locale/FreeBSD/iswalnum.3 index 4aafb25..f50a1b5 100644 --- a/locale/FreeBSD/iswalnum.3 +++ b/locale/FreeBSD/iswalnum.3 @@ -15,10 +15,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -36,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)isalnum.3 5.2 (Berkeley) 6/29/91 -.\" $FreeBSD: src/lib/libc/locale/iswalnum.3,v 1.5 2002/11/29 17:35:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/iswalnum.3,v 1.6 2007/01/09 00:28:00 imp Exp $ .\" .Dd October 3, 2002 .Dt ISWALNUM 3 diff --git a/locale/FreeBSD/iswalnum.3.patch b/locale/FreeBSD/iswalnum.3.patch index 8740bbe..bedec9e 100644 --- a/locale/FreeBSD/iswalnum.3.patch +++ b/locale/FreeBSD/iswalnum.3.patch @@ -1,6 +1,6 @@ ---- iswalnum.3 2003-05-20 15:21:44.000000000 -0700 -+++ iswalnum.3.edit 2006-08-09 13:28:43.000000000 -0700 -@@ -111,9 +111,15 @@ +--- iswalnum.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ iswalnum.3 2009-11-09 15:05:26.000000000 -0800 +@@ -107,9 +107,15 @@ for use with wide characters or .Vt wint_t ) . See the description for the similarly-named single byte classification @@ -17,7 +17,7 @@ .Sh RETURN VALUES The functions return zero if the character tests false and return non-zero if the character tests true. -@@ -136,6 +142,7 @@ +@@ -132,6 +138,7 @@ return non-zero if the character tests t .Xr isspace 3 , .Xr isspecial 3 , .Xr isupper 3 , @@ -25,7 +25,7 @@ .Xr isxdigit 3 , .Xr wctype 3 .Sh STANDARDS -@@ -147,7 +154,7 @@ +@@ -143,7 +150,7 @@ except .Fn iswideogram , .Fn iswnumber , .Fn iswphonogram , diff --git a/locale/FreeBSD/isxdigit.3 b/locale/FreeBSD/isxdigit.3 index 5c932cb..7315a65 100644 --- a/locale/FreeBSD/isxdigit.3 +++ b/locale/FreeBSD/isxdigit.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isxdigit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isxdigit.3,v 1.20 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isxdigit.3,v 1.25 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISXDIGIT 3 .Os .Sh NAME @@ -71,13 +67,8 @@ function behaves similarly to but may recognize additional characters, depending on the current locale setting. .Pp -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . .Sh RETURN VALUES @@ -98,7 +89,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr iswxdigit 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/FreeBSD/isxdigit.3.patch b/locale/FreeBSD/isxdigit.3.patch index f1cc5cb..4c5e7f0 100644 --- a/locale/FreeBSD/isxdigit.3.patch +++ b/locale/FreeBSD/isxdigit.3.patch @@ -1,19 +1,10 @@ ---- isxdigit.3 2004-11-25 11:38:17.000000000 -0800 -+++ isxdigit.3.edit 2006-08-09 13:29:19.000000000 -0700 -@@ -74,7 +74,7 @@ - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char -@@ -97,6 +97,7 @@ +--- isxdigit.3.bsdnew 2009-11-10 13:13:11.000000000 -0800 ++++ isxdigit.3 2009-11-10 13:48:37.000000000 -0800 +@@ -88,6 +88,7 @@ The function should be used instead. .Sh SEE ALSO .Xr ctype 3 , +.Xr isalnum_l 3 , .Xr iswxdigit 3 , - .Xr multibyte 3 , .Xr ascii 7 + .Sh STANDARDS diff --git a/locale/FreeBSD/ldpart.c.patch b/locale/FreeBSD/ldpart.c.patch index 4f2ad77..ddfe6ea 100644 --- a/locale/FreeBSD/ldpart.c.patch +++ b/locale/FreeBSD/ldpart.c.patch @@ -1,5 +1,5 @@ ---- ldpart.c.orig 2008-06-03 18:15:42.000000000 -0700 -+++ ldpart.c 2008-06-18 13:23:20.000000000 -0700 +--- ldpart.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ ldpart.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,6 +27,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/ldpart.c,v 1.15 2004/04/25 19:56:50 ache Exp $"); diff --git a/locale/FreeBSD/ldpart.h.patch b/locale/FreeBSD/ldpart.h.patch index 108e1d9..e15d894 100644 --- a/locale/FreeBSD/ldpart.h.patch +++ b/locale/FreeBSD/ldpart.h.patch @@ -1,5 +1,5 @@ ---- ldpart.h.orig 2004-11-25 11:38:17.000000000 -0800 -+++ ldpart.h 2005-02-13 19:02:54.000000000 -0800 +--- ldpart.h.orig 2009-11-09 15:05:25.000000000 -0800 ++++ ldpart.h 2009-11-09 15:05:25.000000000 -0800 @@ -33,7 +33,7 @@ #define _LDP_ERROR (-1) #define _LDP_CACHE 1 diff --git a/locale/FreeBSD/lmessages.c.patch b/locale/FreeBSD/lmessages.c.patch index fc26ef6..459c0ee 100644 --- a/locale/FreeBSD/lmessages.c.patch +++ b/locale/FreeBSD/lmessages.c.patch @@ -1,5 +1,5 @@ ---- lmessages.c.orig 2004-11-25 11:38:17.000000000 -0800 -+++ lmessages.c 2005-02-17 10:13:34.000000000 -0800 +--- lmessages.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ lmessages.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,7 +27,10 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/lmessages.c,v 1.14 2003/06/26 10:46:16 phantom Exp $"); @@ -11,7 +11,7 @@ #include "ldpart.h" #include "lmessages.h" -@@ -45,47 +48,76 @@ +@@ -45,47 +48,76 @@ static const struct lc_messages_T _C_mes "no" /* nostr */ }; diff --git a/locale/FreeBSD/lmessages.h.patch b/locale/FreeBSD/lmessages.h.patch index 8f2832c..601ac82 100644 --- a/locale/FreeBSD/lmessages.h.patch +++ b/locale/FreeBSD/lmessages.h.patch @@ -1,5 +1,5 @@ ---- lmessages.h.orig 2003-05-20 15:21:44.000000000 -0700 -+++ lmessages.h 2005-02-19 14:39:44.000000000 -0800 +--- lmessages.h.orig 2009-11-09 15:05:25.000000000 -0800 ++++ lmessages.h 2009-11-09 15:05:25.000000000 -0800 @@ -29,6 +29,8 @@ #ifndef _LMESSAGES_H_ #define _LMESSAGES_H_ @@ -9,7 +9,7 @@ struct lc_messages_T { const char *yesexpr; const char *noexpr; -@@ -36,7 +38,7 @@ +@@ -36,7 +38,7 @@ struct lc_messages_T { const char *nostr; }; diff --git a/locale/FreeBSD/lmonetary.c.patch b/locale/FreeBSD/lmonetary.c.patch index 9f3b3b3..4014d5b 100644 --- a/locale/FreeBSD/lmonetary.c.patch +++ b/locale/FreeBSD/lmonetary.c.patch @@ -1,5 +1,5 @@ ---- lmonetary.c.orig 2004-11-25 11:38:17.000000000 -0800 -+++ lmonetary.c 2005-03-16 23:05:30.000000000 -0800 +--- lmonetary.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ lmonetary.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,14 +27,16 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/lmonetary.c,v 1.19 2003/06/26 10:46:16 phantom Exp $"); @@ -18,7 +18,7 @@ extern const char * __fix_locale_grouping_str(const char *); #define LCMONETARY_SIZE_FULL (sizeof(struct lc_monetary_T) / sizeof(char *)) -@@ -50,7 +52,7 @@ +@@ -50,7 +52,7 @@ static const struct lc_monetary_T _C_mon empty, /* currency_symbol */ empty, /* mon_decimal_point */ empty, /* mon_thousands_sep */ @@ -27,7 +27,7 @@ empty, /* positive_sign */ empty, /* negative_sign */ numempty, /* int_frac_digits */ -@@ -69,10 +71,6 @@ +@@ -69,10 +71,6 @@ static const struct lc_monetary_T _C_mon numempty /* int_n_sign_posn */ }; @@ -38,7 +38,7 @@ static char cnv(const char *str) { -@@ -83,23 +81,57 @@ +@@ -83,23 +81,57 @@ cnv(const char *str) return ((char)i); } @@ -106,7 +106,7 @@ M_ASSIGN_CHAR(int_frac_digits); M_ASSIGN_CHAR(frac_digits); -@@ -117,9 +149,9 @@ +@@ -117,9 +149,9 @@ __monetary_load_locale(const char *name) */ #define M_ASSIGN_ICHAR(NAME) \ do { \ @@ -119,7 +119,7 @@ else \ M_ASSIGN_CHAR(int_##NAME); \ } while (0) -@@ -130,21 +162,27 @@ +@@ -130,21 +162,27 @@ __monetary_load_locale(const char *name) M_ASSIGN_ICHAR(n_sep_by_space); M_ASSIGN_ICHAR(p_sign_posn); M_ASSIGN_ICHAR(n_sign_posn); @@ -151,7 +151,7 @@ printf( "int_curr_symbol = %s\n" "currency_symbol = %s\n" "mon_decimal_point = %s\n" -@@ -166,27 +204,27 @@ +@@ -166,27 +204,27 @@ printf( "int_curr_symbol = %s\n" "int_n_sep_by_space = %d\n" "int_p_sign_posn = %d\n" "int_n_sign_posn = %d\n", diff --git a/locale/FreeBSD/lmonetary.h.patch b/locale/FreeBSD/lmonetary.h.patch index 8d62098..826c1be 100644 --- a/locale/FreeBSD/lmonetary.h.patch +++ b/locale/FreeBSD/lmonetary.h.patch @@ -1,5 +1,5 @@ ---- lmonetary.h.orig 2003-05-20 15:21:44.000000000 -0700 -+++ lmonetary.h 2005-02-19 14:41:58.000000000 -0800 +--- lmonetary.h.orig 2009-11-09 15:05:25.000000000 -0800 ++++ lmonetary.h 2009-11-09 15:05:25.000000000 -0800 @@ -29,6 +29,8 @@ #ifndef _LMONETARY_H_ #define _LMONETARY_H_ @@ -9,7 +9,7 @@ struct lc_monetary_T { const char *int_curr_symbol; const char *currency_symbol; -@@ -53,7 +55,7 @@ +@@ -53,7 +55,7 @@ struct lc_monetary_T { const char *int_n_sign_posn; }; diff --git a/locale/FreeBSD/lnumeric.c.patch b/locale/FreeBSD/lnumeric.c.patch index 70f5ccf..50a02e5 100644 --- a/locale/FreeBSD/lnumeric.c.patch +++ b/locale/FreeBSD/lnumeric.c.patch @@ -1,5 +1,5 @@ ---- lnumeric.c.orig 2004-11-25 11:38:17.000000000 -0800 -+++ lnumeric.c 2005-03-16 23:06:13.000000000 -0800 +--- lnumeric.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ lnumeric.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,67 +27,103 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/lnumeric.c,v 1.16 2003/06/26 10:46:16 phantom Exp $"); diff --git a/locale/FreeBSD/lnumeric.h.patch b/locale/FreeBSD/lnumeric.h.patch index 0f2fcc1..7635d21 100644 --- a/locale/FreeBSD/lnumeric.h.patch +++ b/locale/FreeBSD/lnumeric.h.patch @@ -1,5 +1,5 @@ ---- lnumeric.h.orig 2003-05-20 15:21:44.000000000 -0700 -+++ lnumeric.h 2005-02-19 14:44:29.000000000 -0800 +--- lnumeric.h.orig 2009-11-09 15:05:25.000000000 -0800 ++++ lnumeric.h 2009-11-09 15:05:25.000000000 -0800 @@ -29,13 +29,15 @@ #ifndef _LNUMERIC_H_ #define _LNUMERIC_H_ diff --git a/locale/FreeBSD/localeconv.3 b/locale/FreeBSD/localeconv.3 index c73d59e..092f670 100644 --- a/locale/FreeBSD/localeconv.3 +++ b/locale/FreeBSD/localeconv.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" .\" From @(#)setlocale.3 8.1 (Berkeley) 6/9/93 .\" From FreeBSD: src/lib/libc/locale/setlocale.3,v 1.28 2003/11/15 02:26:04 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/localeconv.3,v 1.2 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/localeconv.3,v 1.3 2007/01/09 00:28:00 imp Exp $ .\" .Dd November 21, 2003 .Dt LOCALECONV 3 diff --git a/locale/FreeBSD/localeconv.3.patch b/locale/FreeBSD/localeconv.3.patch index 0e0a41b..6a8e459 100644 --- a/locale/FreeBSD/localeconv.3.patch +++ b/locale/FreeBSD/localeconv.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/localeconv.3 2004-11-25 11:38:18.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/localeconv.3.edit 2006-06-29 11:04:42.000000000 -0700 -@@ -40,14 +40,22 @@ +--- localeconv.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ localeconv.3 2009-11-09 15:05:26.000000000 -0800 +@@ -36,14 +36,22 @@ .Dt LOCALECONV 3 .Os .Sh NAME @@ -25,7 +25,7 @@ .Sh DESCRIPTION The .Fn localeconv -@@ -201,6 +209,14 @@ +@@ -197,6 +205,14 @@ a value that is not in the current local A .Dv CHAR_MAX result similarly denotes an unavailable value. @@ -40,7 +40,7 @@ .Sh RETURN VALUES The .Fn localeconv -@@ -213,7 +229,8 @@ +@@ -209,7 +225,8 @@ or No errors are defined. .Sh SEE ALSO .Xr setlocale 3 , diff --git a/locale/FreeBSD/localeconv.c b/locale/FreeBSD/localeconv.c index 1420aa8..919fd02 100644 --- a/locale/FreeBSD/localeconv.c +++ b/locale/FreeBSD/localeconv.c @@ -11,10 +11,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -36,7 +32,7 @@ static char sccsid[] = "@(#)localeconv.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.13 2003/06/26 10:46:16 phantom Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.14 2007/12/12 07:43:23 phantom Exp $"); #include diff --git a/locale/FreeBSD/localeconv.c.patch b/locale/FreeBSD/localeconv.c.patch index 14a89ed..393277f 100644 --- a/locale/FreeBSD/localeconv.c.patch +++ b/locale/FreeBSD/localeconv.c.patch @@ -1,8 +1,8 @@ ---- localeconv.c.orig 2008-10-09 11:37:42.000000000 -0700 -+++ localeconv.c 2008-10-10 01:37:33.000000000 -0700 -@@ -38,11 +38,71 @@ static char sccsid[] = "@(#)localeconv.c +--- localeconv.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ localeconv.c 2009-11-09 15:05:26.000000000 -0800 +@@ -34,11 +34,71 @@ static char sccsid[] = "@(#)localeconv.c #include - __FBSDID("$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.13 2003/06/26 10:46:16 phantom Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.14 2007/12/12 07:43:23 phantom Exp $"); +#include "xlocale_private.h" + @@ -72,7 +72,7 @@ /* * The localeconv() function constructs a struct lconv from the current * monetary and numeric locales. -@@ -52,25 +112,28 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ +@@ -48,25 +108,28 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ * lconv structure are computed only when the monetary or numeric * locale has been changed. */ @@ -109,7 +109,7 @@ M_ASSIGN_STR(int_curr_symbol); M_ASSIGN_STR(currency_symbol); M_ASSIGN_STR(mon_decimal_point); -@@ -92,21 +155,45 @@ localeconv() +@@ -88,21 +151,45 @@ localeconv() M_ASSIGN_CHAR(int_n_sep_by_space); M_ASSIGN_CHAR(int_p_sign_posn); M_ASSIGN_CHAR(int_n_sign_posn); diff --git a/locale/FreeBSD/mblen.3 b/locale/FreeBSD/mblen.3 index fbe01a9..adfd58a 100644 --- a/locale/FreeBSD/mblen.3 +++ b/locale/FreeBSD/mblen.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/mblen.3,v 1.5 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/mblen.3,v 1.6 2007/01/09 00:28:00 imp Exp $ .\" .Dd April 11, 2004 .Dt MBLEN 3 diff --git a/locale/FreeBSD/mblen.3.patch b/locale/FreeBSD/mblen.3.patch index 89464dd..193f576 100644 --- a/locale/FreeBSD/mblen.3.patch +++ b/locale/FreeBSD/mblen.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/mblen.3 2004-11-25 11:38:18.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/mblen.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -41,33 +41,53 @@ +--- mblen.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mblen.3 2009-11-09 15:05:26.000000000 -0800 +@@ -37,33 +37,53 @@ .Dt MBLEN 3 .Os .Sh NAME @@ -63,7 +63,7 @@ is .Dv NULL , the -@@ -76,14 +96,14 @@ +@@ -72,14 +92,14 @@ function returns nonzero if shift states zero otherwise. .Pp Otherwise, if @@ -81,7 +81,7 @@ or returns \-1 if no multibyte character could be recognized or converted. In this case, -@@ -102,7 +122,8 @@ +@@ -98,7 +118,8 @@ The internal conversion state is not val .Sh SEE ALSO .Xr mbrlen 3 , .Xr mbtowc 3 , diff --git a/locale/FreeBSD/mblen.c.patch b/locale/FreeBSD/mblen.c.patch index 6dc72fc..5d8f912 100644 --- a/locale/FreeBSD/mblen.c.patch +++ b/locale/FreeBSD/mblen.c.patch @@ -1,5 +1,5 @@ ---- mblen.c.orig Thu Nov 25 11:38:18 2004 -+++ mblen.c Fri Feb 18 16:55:20 2005 +--- mblen.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mblen.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,24 +27,32 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/mblen.c,v 1.9 2004/07/29 06:18:40 tjr Exp $"); @@ -30,10 +30,10 @@ if (rval == (size_t)-1 || rval == (size_t)-2) return (-1); return ((int)rval); -+} + } + +int +mblen(const char *s, size_t n) +{ + return mblen_l(s, n, __current_locale()); - } ++} diff --git a/locale/FreeBSD/mblocal.h b/locale/FreeBSD/mblocal.h index 4158f07..c1a716d 100644 --- a/locale/FreeBSD/mblocal.h +++ b/locale/FreeBSD/mblocal.h @@ -23,12 +23,27 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/lib/libc/locale/mblocal.h,v 1.4 2004/10/17 06:51:50 tjr Exp $ + * $FreeBSD: src/lib/libc/locale/mblocal.h,v 1.7 2008/01/21 23:48:12 ache Exp $ */ #ifndef _MBLOCAL_H_ #define _MBLOCAL_H_ +#include + +/* + * Rune initialization function prototypes. + */ +int _none_init(_RuneLocale *); +int _ascii_init(_RuneLocale *); +int _UTF8_init(_RuneLocale *); +int _EUC_init(_RuneLocale *); +int _GB18030_init(_RuneLocale *); +int _GB2312_init(_RuneLocale *); +int _GBK_init(_RuneLocale *); +int _BIG5_init(_RuneLocale *); +int _MSKanji_init(_RuneLocale *); + /* * Conversion function pointers for current encoding. */ @@ -41,19 +56,6 @@ extern size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict); extern size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); -/* - * Conversion functions for "NONE"/C/POSIX encoding. - */ -extern size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, - size_t, mbstate_t * __restrict); -extern int _none_mbsinit(const mbstate_t *); -extern size_t _none_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, - size_t, size_t, mbstate_t * __restrict); -extern size_t _none_wcrtomb(char * __restrict, wchar_t, - mbstate_t * __restrict); -extern size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, - size_t, size_t, mbstate_t * __restrict); - extern size_t __mbsnrtowcs_std(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); extern size_t __wcsnrtombs_std(char * __restrict, const wchar_t ** __restrict, diff --git a/locale/FreeBSD/mblocal.h.patch b/locale/FreeBSD/mblocal.h.patch index 4dc9632..ed7ca59 100644 --- a/locale/FreeBSD/mblocal.h.patch +++ b/locale/FreeBSD/mblocal.h.patch @@ -1,9 +1,30 @@ ---- mblocal.h.orig 2004-11-25 11:38:18.000000000 -0800 -+++ mblocal.h 2005-02-18 18:25:53.000000000 -0800 -@@ -30,33 +30,21 @@ - #define _MBLOCAL_H_ - +--- mblocal.h.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mblocal.h 2009-11-09 19:00:41.000000000 -0800 +@@ -34,31 +34,31 @@ /* + * Rune initialization function prototypes. + */ +-int _none_init(_RuneLocale *); +-int _ascii_init(_RuneLocale *); +-int _UTF8_init(_RuneLocale *); +-int _EUC_init(_RuneLocale *); +-int _GB18030_init(_RuneLocale *); +-int _GB2312_init(_RuneLocale *); +-int _GBK_init(_RuneLocale *); +-int _BIG5_init(_RuneLocale *); +-int _MSKanji_init(_RuneLocale *); ++__private_extern__ int _none_init(struct __xlocale_st_runelocale *); ++__private_extern__ int _ascii_init(struct __xlocale_st_runelocale *); ++__private_extern__ int _UTF2_init(struct __xlocale_st_runelocale *); ++__private_extern__ int _UTF8_init(struct __xlocale_st_runelocale *); ++__private_extern__ int _EUC_init(struct __xlocale_st_runelocale *); ++__private_extern__ int _GB18030_init(struct __xlocale_st_runelocale *); ++__private_extern__ int _GB2312_init(struct __xlocale_st_runelocale *); ++__private_extern__ int _GBK_init(struct __xlocale_st_runelocale *); ++__private_extern__ int _BIG5_init(struct __xlocale_st_runelocale *); ++__private_extern__ int _MSKanji_init(struct __xlocale_st_runelocale *); + +-/* - * Conversion function pointers for current encoding. - */ -extern size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, @@ -14,24 +35,16 @@ -extern size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict); -extern size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, - size_t, size_t, mbstate_t * __restrict); -- --/* - * Conversion functions for "NONE"/C/POSIX encoding. - */ - extern size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, -- size_t, mbstate_t * __restrict); --extern int _none_mbsinit(const mbstate_t *); -+ size_t, mbstate_t * __restrict, locale_t); -+extern int _none_mbsinit(const mbstate_t *, locale_t); - extern size_t _none_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, -- size_t, size_t, mbstate_t * __restrict); -+ size_t, size_t, mbstate_t * __restrict, locale_t); - extern size_t _none_wcrtomb(char * __restrict, wchar_t, -- mbstate_t * __restrict); -+ mbstate_t * __restrict, locale_t); - extern size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, -- size_t, size_t, mbstate_t * __restrict); -+ size_t, size_t, mbstate_t * __restrict, locale_t); ++__private_extern__ size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, ++ size_t, mbstate_t * __restrict, locale_t); ++__private_extern__ int _none_mbsinit(const mbstate_t *, locale_t); ++__private_extern__ size_t _none_mbsnrtowcs(wchar_t * __restrict dst, ++ const char ** __restrict src, size_t nms, size_t len, ++ mbstate_t * __restrict ps __unused, locale_t); ++__private_extern__ size_t _none_wcrtomb(char * __restrict, wchar_t, ++ mbstate_t * __restrict, locale_t); ++__private_extern__ size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, ++ size_t, size_t, mbstate_t * __restrict, locale_t); extern size_t __mbsnrtowcs_std(wchar_t * __restrict, const char ** __restrict, - size_t, size_t, mbstate_t * __restrict); diff --git a/locale/FreeBSD/mbrlen.3.patch b/locale/FreeBSD/mbrlen.3.patch index 2ff046c..8bfba2d 100644 --- a/locale/FreeBSD/mbrlen.3.patch +++ b/locale/FreeBSD/mbrlen.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/mbrlen.3 2004-11-25 11:38:18.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/mbrlen.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- mbrlen.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbrlen.3 2009-11-09 15:05:25.000000000 -0800 @@ -28,21 +28,35 @@ .Dt MBRLEN 3 .Os @@ -40,7 +40,7 @@ to determine the number of bytes needed to complete the next multibyte character. .Pp -@@ -63,7 +77,7 @@ +@@ -63,7 +77,7 @@ It is equivalent to: .Pp .Dl "mbrtowc(NULL, s, n, ps);" .Pp @@ -49,7 +49,7 @@ .Fa ps is a .Dv NULL -@@ -72,6 +86,14 @@ +@@ -72,6 +86,14 @@ pointer, uses its own static, internal .Vt mbstate_t object to keep track of the shift state. @@ -64,7 +64,7 @@ .Sh RETURN VALUES The .Fn mbrlen -@@ -137,7 +159,8 @@ +@@ -137,7 +159,8 @@ The conversion state is invalid. .Sh SEE ALSO .Xr mblen 3 , .Xr mbrtowc 3 , diff --git a/locale/FreeBSD/mbrlen.c.patch b/locale/FreeBSD/mbrlen.c.patch index aa3e99c..24365a7 100644 --- a/locale/FreeBSD/mbrlen.c.patch +++ b/locale/FreeBSD/mbrlen.c.patch @@ -1,5 +1,5 @@ ---- mbrlen.c.orig Thu Nov 25 11:38:18 2004 -+++ mbrlen.c Fri Feb 18 16:54:36 2005 +--- mbrlen.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbrlen.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,15 +27,23 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/mbrlen.c,v 1.4 2004/05/12 14:26:54 tjr Exp $"); diff --git a/locale/FreeBSD/mbrtowc.3.patch b/locale/FreeBSD/mbrtowc.3.patch index 9c95d87..1b42524 100644 --- a/locale/FreeBSD/mbrtowc.3.patch +++ b/locale/FreeBSD/mbrtowc.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/mbrtowc.3 2004-11-25 11:38:18.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/mbrtowc.3.edit 2006-06-29 11:10:29.000000000 -0700 +--- mbrtowc.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbrtowc.3 2009-11-09 15:05:25.000000000 -0800 @@ -28,7 +28,8 @@ .Dt MBRTOWC 3 .Os @@ -43,7 +43,7 @@ to determine the number of bytes needed to complete the next multibyte character. If a character can be completed, and -@@ -65,14 +78,14 @@ +@@ -65,14 +78,14 @@ is .Fn mbrtowc behaves as if .Fa pwc @@ -62,7 +62,7 @@ .Pp The .Vt mbstate_t -@@ -86,6 +99,14 @@ +@@ -86,6 +99,14 @@ uses an internal, static .Vt mbstate_t object, which is initialized to the initial conversion state at program startup. @@ -77,7 +77,7 @@ .Sh RETURN VALUES The .Fn mbrtowc -@@ -131,7 +152,8 @@ +@@ -131,7 +152,8 @@ The conversion state is invalid. .Xr mbtowc 3 , .Xr multibyte 3 , .Xr setlocale 3 , diff --git a/locale/FreeBSD/mbrtowc.c.patch b/locale/FreeBSD/mbrtowc.c.patch index ca343a5..85053f4 100644 --- a/locale/FreeBSD/mbrtowc.c.patch +++ b/locale/FreeBSD/mbrtowc.c.patch @@ -1,5 +1,5 @@ ---- mbrtowc.c.orig 2004-11-25 11:38:18.000000000 -0800 -+++ mbrtowc.c 2005-02-18 18:21:18.000000000 -0800 +--- mbrtowc.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbrtowc.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,16 +27,24 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/mbrtowc.c,v 1.7 2004/05/12 14:09:04 tjr Exp $"); diff --git a/locale/FreeBSD/mbsinit.3.patch b/locale/FreeBSD/mbsinit.3.patch index 6ec480c..4d83a50 100644 --- a/locale/FreeBSD/mbsinit.3.patch +++ b/locale/FreeBSD/mbsinit.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/mbsinit.3 2004-11-25 11:38:18.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/mbsinit.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- mbsinit.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbsinit.3 2009-11-09 15:05:25.000000000 -0800 @@ -28,7 +28,8 @@ .Dt MBSINIT 3 .Os @@ -21,7 +21,7 @@ .Sh DESCRIPTION The .Fn mbsinit -@@ -44,6 +49,14 @@ +@@ -44,6 +49,14 @@ function determines whether the object pointed to by .Fa ps describes an initial conversion state. @@ -36,7 +36,7 @@ .Sh RETURN VALUES The .Fn mbsinit -@@ -51,15 +64,16 @@ +@@ -51,15 +64,16 @@ function returns non-zero if .Fa ps is .Dv NULL diff --git a/locale/FreeBSD/mbsinit.c.patch b/locale/FreeBSD/mbsinit.c.patch index 709f68e..7635c85 100644 --- a/locale/FreeBSD/mbsinit.c.patch +++ b/locale/FreeBSD/mbsinit.c.patch @@ -1,5 +1,5 @@ ---- mbsinit.c.orig Thu Nov 25 11:38:18 2004 -+++ mbsinit.c Fri Feb 18 16:12:33 2005 +--- mbsinit.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbsinit.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,12 +27,21 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/mbsinit.c,v 1.3 2004/05/12 14:09:04 tjr Exp $"); diff --git a/locale/FreeBSD/mbsnrtowcs.c.patch b/locale/FreeBSD/mbsnrtowcs.c.patch index 9e29260..9b03c7c 100644 --- a/locale/FreeBSD/mbsnrtowcs.c.patch +++ b/locale/FreeBSD/mbsnrtowcs.c.patch @@ -1,5 +1,5 @@ ---- mbsnrtowcs.c.orig Thu Nov 25 11:38:18 2004 -+++ mbsnrtowcs.c Fri Feb 18 16:57:14 2005 +--- mbsnrtowcs.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbsnrtowcs.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,6 +27,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/mbsnrtowcs.c,v 1.1 2004/07/21 10:54:57 tjr Exp $"); @@ -9,7 +9,7 @@ #include #include #include -@@ -34,31 +36,40 @@ +@@ -34,31 +36,40 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include "mblocal.h" size_t @@ -58,7 +58,7 @@ /* Invalid sequence - mbrtowc() sets errno. */ return ((size_t)-1); else if (nb == 0 || nb == (size_t)-2) -@@ -71,7 +82,7 @@ +@@ -71,7 +82,7 @@ __mbsnrtowcs_std(wchar_t * __restrict ds } while (len-- > 0) { diff --git a/locale/FreeBSD/mbsrtowcs.3 b/locale/FreeBSD/mbsrtowcs.3 index 05f2e1a..dce9c78 100644 --- a/locale/FreeBSD/mbsrtowcs.3 +++ b/locale/FreeBSD/mbsrtowcs.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/mbsrtowcs.3,v 1.5 2004/07/21 10:54:57 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/mbsrtowcs.3,v 1.6 2005/01/11 20:50:49 ru Exp $ .Dd July 21, 2004 .Dt MBSRTOWCS 3 .Os @@ -95,7 +95,7 @@ function behaves identically to .Fn mbsrtowcs , except that conversion stops after reading at most .Fa nms -bytes from the buffer pointed to by +bytes from the buffer pointed to by .Fa src . .Sh RETURN VALUES The diff --git a/locale/FreeBSD/mbsrtowcs.3.patch b/locale/FreeBSD/mbsrtowcs.3.patch index 1ad0752..ad11bb0 100644 --- a/locale/FreeBSD/mbsrtowcs.3.patch +++ b/locale/FreeBSD/mbsrtowcs.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/mbsrtowcs.3 2004-11-25 11:38:18.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/mbsrtowcs.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- mbsrtowcs.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbsrtowcs.3 2009-11-09 15:05:26.000000000 -0800 @@ -27,29 +27,55 @@ .Dt MBSRTOWCS 3 .Os @@ -65,9 +65,9 @@ .Fa len of them in the .Vt wchar_t -@@ -97,6 +123,18 @@ +@@ -97,6 +123,18 @@ except that conversion stops after readi .Fa nms - bytes from the buffer pointed to by + bytes from the buffer pointed to by .Fa src . +.Pp +While the @@ -84,7 +84,7 @@ .Sh RETURN VALUES The .Fn mbsrtowcs -@@ -123,7 +161,8 @@ +@@ -123,7 +161,8 @@ The conversion state is invalid. .Xr mbrtowc 3 , .Xr mbstowcs 3 , .Xr multibyte 3 , diff --git a/locale/FreeBSD/mbsrtowcs.c.patch b/locale/FreeBSD/mbsrtowcs.c.patch index f1cde86..47831aa 100644 --- a/locale/FreeBSD/mbsrtowcs.c.patch +++ b/locale/FreeBSD/mbsrtowcs.c.patch @@ -1,5 +1,5 @@ ---- mbsrtowcs.c.orig 2004-11-25 11:38:18.000000000 -0800 -+++ mbsrtowcs.c 2005-02-18 18:28:00.000000000 -0800 +--- mbsrtowcs.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbsrtowcs.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,6 +27,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/mbsrtowcs.c,v 1.6 2004/07/21 10:54:57 tjr Exp $"); @@ -9,7 +9,7 @@ #include #include #include -@@ -34,12 +36,18 @@ +@@ -34,12 +36,18 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include "mblocal.h" size_t diff --git a/locale/FreeBSD/mbstowcs.3 b/locale/FreeBSD/mbstowcs.3 index 634d972..f710b8b 100644 --- a/locale/FreeBSD/mbstowcs.3 +++ b/locale/FreeBSD/mbstowcs.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/mbstowcs.3,v 1.4 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/mbstowcs.3,v 1.5 2007/01/09 00:28:00 imp Exp $ .\" .Dd April 8, 2004 .Dt MBSTOWCS 3 diff --git a/locale/FreeBSD/mbstowcs.3.patch b/locale/FreeBSD/mbstowcs.3.patch index 871a5a5..075f58b 100644 --- a/locale/FreeBSD/mbstowcs.3.patch +++ b/locale/FreeBSD/mbstowcs.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/mbstowcs.3 2004-11-25 11:38:18.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/mbstowcs.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -41,7 +41,8 @@ +--- mbstowcs.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbstowcs.3 2009-11-09 15:05:26.000000000 -0800 +@@ -37,7 +37,8 @@ .Dt MBSTOWCS 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nd convert a character string to a wide-character string .Sh LIBRARY .Lb libc -@@ -49,21 +50,39 @@ +@@ -45,21 +46,39 @@ .In stdlib.h .Ft size_t .Fo mbstowcs @@ -57,7 +57,7 @@ .Sh RETURN VALUES The .Fn mbstowcs -@@ -83,7 +102,8 @@ +@@ -79,7 +98,8 @@ The conversion state is invalid. .Sh SEE ALSO .Xr mbsrtowcs 3 , .Xr mbtowc 3 , diff --git a/locale/FreeBSD/mbstowcs.c b/locale/FreeBSD/mbstowcs.c index ab2e849..2de8792 100644 --- a/locale/FreeBSD/mbstowcs.c +++ b/locale/FreeBSD/mbstowcs.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/mbstowcs.c,v 1.11 2004/07/21 10:54:57 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/mbstowcs.c,v 1.12 2009/01/15 18:53:52 rdivacky Exp $"); #include #include @@ -37,7 +37,9 @@ mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n) { static const mbstate_t initial; mbstate_t mbs; + const char *sp; mbs = initial; - return (__mbsnrtowcs(pwcs, &s, SIZE_T_MAX, n, &mbs)); + sp = s; + return (__mbsnrtowcs(pwcs, &sp, SIZE_T_MAX, n, &mbs)); } diff --git a/locale/FreeBSD/mbstowcs.c.patch b/locale/FreeBSD/mbstowcs.c.patch index e6f86ce..f0834b0 100644 --- a/locale/FreeBSD/mbstowcs.c.patch +++ b/locale/FreeBSD/mbstowcs.c.patch @@ -1,8 +1,8 @@ ---- mbstowcs.c.orig Thu Nov 25 11:38:18 2004 -+++ mbstowcs.c Fri Feb 18 17:02:15 2005 -@@ -27,17 +27,27 @@ +--- mbstowcs.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ mbstowcs.c 2009-11-09 16:20:59.000000000 -0800 +@@ -27,19 +27,29 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/mbstowcs.c,v 1.11 2004/07/21 10:54:57 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/mbstowcs.c,v 1.12 2009/01/15 18:53:52 rdivacky Exp $"); +#include "xlocale_private.h" + @@ -18,11 +18,13 @@ { static const mbstate_t initial; mbstate_t mbs; + const char *sp; + NORMALIZE_LOCALE(loc); mbs = initial; -- return (__mbsnrtowcs(pwcs, &s, SIZE_T_MAX, n, &mbs)); -+ return (loc->__lc_ctype->__mbsnrtowcs(pwcs, &s, SIZE_T_MAX, n, &mbs, loc)); + sp = s; +- return (__mbsnrtowcs(pwcs, &sp, SIZE_T_MAX, n, &mbs)); ++ return (loc->__lc_ctype->__mbsnrtowcs(pwcs, &sp, SIZE_T_MAX, n, &mbs, loc)); +} + +size_t diff --git a/locale/FreeBSD/mbtowc.3 b/locale/FreeBSD/mbtowc.3 index c4bea65..9481c63 100644 --- a/locale/FreeBSD/mbtowc.3 +++ b/locale/FreeBSD/mbtowc.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/mbtowc.3,v 1.4 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/mbtowc.3,v 1.5 2007/01/09 00:28:00 imp Exp $ .\" .Dd April 11, 2004 .Dt MBTOWC 3 diff --git a/locale/FreeBSD/mbtowc.3.patch b/locale/FreeBSD/mbtowc.3.patch index 6c38fdc..8bfdf86 100644 --- a/locale/FreeBSD/mbtowc.3.patch +++ b/locale/FreeBSD/mbtowc.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/mbtowc.3 2004-11-25 11:38:18.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/mbtowc.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -41,7 +41,8 @@ +--- mbtowc.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbtowc.3 2009-11-09 15:05:26.000000000 -0800 +@@ -37,7 +37,8 @@ .Dt MBTOWC 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nd convert a character to a wide-character code .Sh LIBRARY .Lb libc -@@ -49,30 +50,48 @@ +@@ -45,30 +46,48 @@ .In stdlib.h .Ft int .Fo mbtowc @@ -67,7 +67,7 @@ is .Dv NULL , the -@@ -81,14 +100,14 @@ +@@ -77,14 +96,14 @@ function returns nonzero if shift states zero otherwise. .Pp Otherwise, if @@ -85,7 +85,7 @@ or returns \-1 if no multibyte character could be recognized or converted. In this case, -@@ -110,7 +129,8 @@ +@@ -106,7 +125,8 @@ The internal conversion state is invalid .Xr mbrtowc 3 , .Xr mbstowcs 3 , .Xr multibyte 3 , diff --git a/locale/FreeBSD/mbtowc.c.patch b/locale/FreeBSD/mbtowc.c.patch index 8c9b7ee..daa1b84 100644 --- a/locale/FreeBSD/mbtowc.c.patch +++ b/locale/FreeBSD/mbtowc.c.patch @@ -1,5 +1,5 @@ ---- mbtowc.c.orig Thu Nov 25 11:38:18 2004 -+++ mbtowc.c Fri Feb 18 17:12:35 2005 +--- mbtowc.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mbtowc.c 2009-11-09 15:05:25.000000000 -0800 @@ -27,24 +27,33 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/mbtowc.c,v 1.11 2004/07/29 06:18:40 tjr Exp $"); @@ -31,10 +31,10 @@ if (rval == (size_t)-1 || rval == (size_t)-2) return (-1); return ((int)rval); -+} + } + +int +mbtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n) +{ + return mbtowc_l(pwc, s, n, __current_locale()); - } ++} diff --git a/locale/FreeBSD/mskanji.c b/locale/FreeBSD/mskanji.c index c84661a..609004d 100644 --- a/locale/FreeBSD/mskanji.c +++ b/locale/FreeBSD/mskanji.c @@ -36,9 +36,10 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)mskanji.c 1.0 (Phase One) 5/5/95"; #endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/locale/mskanji.c,v 1.16 2004/05/14 15:40:47 tjr Exp $"); +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mskanji.c,v 1.18 2007/10/13 16:28:22 ache Exp $"); +#include #include #include #include @@ -46,11 +47,13 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/mskanji.c,v 1.16 2004/05/14 15:40:47 tjr #include #include "mblocal.h" -int _MSKanji_init(_RuneLocale *); -size_t _MSKanji_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict); -int _MSKanji_mbsinit(const mbstate_t *); -size_t _MSKanji_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); +extern int __mb_sb_limit; + +static size_t _MSKanji_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _MSKanji_mbsinit(const mbstate_t *); +static size_t _MSKanji_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); typedef struct { wchar_t ch; @@ -65,17 +68,18 @@ _MSKanji_init(_RuneLocale *rl) __mbsinit = _MSKanji_mbsinit; _CurrentRuneLocale = rl; __mb_cur_max = 2; + __mb_sb_limit = 256; return (0); } -int +static int _MSKanji_mbsinit(const mbstate_t *ps) { return (ps == NULL || ((const _MSKanjiState *)ps)->ch == 0); } -size_t +static size_t _MSKanji_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { @@ -133,7 +137,7 @@ _MSKanji_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } } -size_t +static size_t _MSKanji_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _MSKanjiState *ms; diff --git a/locale/FreeBSD/mskanji.c.patch b/locale/FreeBSD/mskanji.c.patch index 998d30d..1399fa9 100644 --- a/locale/FreeBSD/mskanji.c.patch +++ b/locale/FreeBSD/mskanji.c.patch @@ -1,33 +1,28 @@ ---- mskanji.c.orig Thu Nov 25 11:38:18 2004 -+++ mskanji.c Fri Feb 18 15:49:37 2005 -@@ -36,9 +36,12 @@ - #if defined(LIBC_SCCS) && !defined(lint) - static char sccsid[] = "@(#)mskanji.c 1.0 (Phase One) 5/5/95"; - #endif /* LIBC_SCCS and not lint */ --#include -+#include - __FBSDID("$FreeBSD: src/lib/libc/locale/mskanji.c,v 1.16 2004/05/14 15:40:47 tjr Exp $"); +--- mskanji.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ mskanji.c 2009-11-09 16:30:02.000000000 -0800 +@@ -39,6 +39,8 @@ static char sccsid[] = "@(#)mskanji.c 1. + #include + __FBSDID("$FreeBSD: src/lib/libc/locale/mskanji.c,v 1.18 2007/10/13 16:28:22 ache Exp $"); +#include "xlocale_private.h" + -+#include + #include #include #include - #include -@@ -46,38 +49,37 @@ +@@ -47,33 +49,30 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include #include "mblocal.h" --int _MSKanji_init(_RuneLocale *); --size_t _MSKanji_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -- mbstate_t * __restrict); --int _MSKanji_mbsinit(const mbstate_t *); --size_t _MSKanji_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); -+__private_extern__ int _MSKanji_init(struct __xlocale_st_runelocale *); -+static size_t _MSKanji_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -+ mbstate_t * __restrict, locale_t); +-extern int __mb_sb_limit; +- + static size_t _MSKanji_mbrtowc(wchar_t * __restrict, const char * __restrict, +- size_t, mbstate_t * __restrict); +-static int _MSKanji_mbsinit(const mbstate_t *); ++ size_t, mbstate_t * __restrict, locale_t); +static int _MSKanji_mbsinit(const mbstate_t *, locale_t); -+static size_t _MSKanji_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); + static size_t _MSKanji_wcrtomb(char * __restrict, wchar_t, +- mbstate_t * __restrict); ++ mbstate_t * __restrict, locale_t); typedef struct { wchar_t ch; @@ -44,38 +39,36 @@ - __mbsinit = _MSKanji_mbsinit; - _CurrentRuneLocale = rl; - __mb_cur_max = 2; +- __mb_sb_limit = 256; + xrl->__mbrtowc = _MSKanji_mbrtowc; + xrl->__wcrtomb = _MSKanji_wcrtomb; + xrl->__mbsinit = _MSKanji_mbsinit; + xrl->__mb_cur_max = 2; ++ xrl->__mb_sb_limit = 256; return (0); } --int + static int -_MSKanji_mbsinit(const mbstate_t *ps) -+static int -+_MSKanji_mbsinit(const mbstate_t *ps, locale_t loc) ++_MSKanji_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _MSKanjiState *)ps)->ch == 0); - } +@@ -81,7 +80,7 @@ _MSKanji_mbsinit(const mbstate_t *ps) --size_t -+static size_t + static size_t _MSKanji_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps) -+ mbstate_t * __restrict ps, locale_t loc) ++ mbstate_t * __restrict ps, locale_t loc __unused) { _MSKanjiState *ms; wchar_t wc; -@@ -133,8 +135,8 @@ - } +@@ -138,7 +137,7 @@ _MSKanji_mbrtowc(wchar_t * __restrict pw } --size_t + static size_t -_MSKanji_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) -+static size_t -+_MSKanji_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) ++_MSKanji_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc __unused) { _MSKanjiState *ms; int len, i; diff --git a/locale/FreeBSD/multibyte.3 b/locale/FreeBSD/multibyte.3 index 34e269d..de7099c 100644 --- a/locale/FreeBSD/multibyte.3 +++ b/locale/FreeBSD/multibyte.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)multibyte.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/multibyte.3,v 1.27 2004/10/17 02:29:15 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/multibyte.3,v 1.28 2007/01/09 00:28:00 imp Exp $ .\" .Dd April 8, 2004 .Dt MULTIBYTE 3 diff --git a/locale/FreeBSD/nextwctype.3 b/locale/FreeBSD/nextwctype.3 index 2af8289..aa6ba68 100644 --- a/locale/FreeBSD/nextwctype.3 +++ b/locale/FreeBSD/nextwctype.3 @@ -23,9 +23,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/nextwctype.3,v 1.1 2004/07/08 06:43:37 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/nextwctype.3,v 1.3 2005/07/21 10:27:45 tjr Exp $ .\" -.Dd July 8, 2004 +.Dd July 21, 2005 .Dt NEXTWCTYPE 3 .Os .Sh NAME @@ -36,9 +36,7 @@ .Sh SYNOPSIS .In wctype.h .Ft wint_t -.Fo nextwctype -.Fa "wint_t ch" "wctype_t wct" -.Fc +.Fn nextwctype "wint_t ch" "wctype_t wct" .Sh DESCRIPTION The .Fn nextwctype @@ -53,6 +51,17 @@ is \-1, the search begins at the first member of .Sh RETURN VALUES The .Fn nextwctype -functions returns the next character, or \-1 if there are no more. +function returns the next character, or \-1 if there are no more. +.Sh COMPATIBILITY +This function is a non-standard +.Fx +extension and should not be used where the standard +.Fn iswctype +function would suffice. .Sh SEE ALSO .Xr wctype 3 +.Sh HISTORY +The +.Fn nextwctype +function appeared in +.Fx 5.4 . diff --git a/locale/FreeBSD/nextwctype.3.patch b/locale/FreeBSD/nextwctype.3.patch index a5aa26e..82fac93 100644 --- a/locale/FreeBSD/nextwctype.3.patch +++ b/locale/FreeBSD/nextwctype.3.patch @@ -1,5 +1,5 @@ ---- nextwctype.3.orig Fri Mar 11 19:44:47 2005 -+++ nextwctype.3 Fri Mar 11 19:53:29 2005 +--- nextwctype.3.orig 2009-11-10 13:13:11.000000000 -0800 ++++ nextwctype.3 2009-11-10 14:53:56.000000000 -0800 @@ -29,7 +29,8 @@ .Dt NEXTWCTYPE 3 .Os @@ -10,19 +10,17 @@ .Nd "iterate through character classes" .Sh LIBRARY .Lb libc -@@ -39,6 +40,11 @@ - .Fo nextwctype - .Fa "wint_t ch" "wctype_t wct" - .Fc +@@ -37,6 +38,9 @@ + .In wctype.h + .Ft wint_t + .Fn nextwctype "wint_t ch" "wctype_t wct" +.In xlocale.h +.Ft wint_t -+.Fo nextwctype_l -+.Fa "wint_t ch" "wctype_t wct" "locale_t loc" -+.Fc ++.Fn nextwctype_l "wint_t ch" "wctype_t wct" "locale_t loc" .Sh DESCRIPTION The .Fn nextwctype -@@ -50,9 +56,18 @@ +@@ -48,6 +52,14 @@ If .Fa ch is \-1, the search begins at the first member of .Fa wct . @@ -30,15 +28,20 @@ +While the +.Fn nextwctype +function uses the current locale, the -+.Fn nextwctype_l ++ .Fn nextwctype_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. .Sh RETURN VALUES The .Fn nextwctype - functions returns the next character, or \-1 if there are no more. +@@ -59,7 +71,8 @@ extension and should not be used where t + .Fn iswctype + function would suffice. .Sh SEE ALSO -.Xr wctype 3 +.Xr wctype 3 , +.Xr xlocale 3 + .Sh HISTORY + The + .Fn nextwctype diff --git a/locale/FreeBSD/nextwctype.c.patch b/locale/FreeBSD/nextwctype.c.patch index 7d6e2e0..4fb3399 100644 --- a/locale/FreeBSD/nextwctype.c.patch +++ b/locale/FreeBSD/nextwctype.c.patch @@ -1,5 +1,5 @@ ---- nextwctype.c.orig 2004-11-25 11:38:19.000000000 -0800 -+++ nextwctype.c 2005-02-19 03:44:49.000000000 -0800 +--- nextwctype.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ nextwctype.c 2009-11-09 15:05:26.000000000 -0800 @@ -27,28 +27,32 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/nextwctype.c,v 1.1 2004/07/08 06:43:37 tjr Exp $"); @@ -36,7 +36,7 @@ if (rr->__ranges != NULL && wc < rr->__ranges[0].__min) { wc = rr->__ranges[0].__min; noinc = 1; -@@ -88,3 +92,9 @@ +@@ -88,3 +92,9 @@ found: } return (-1); } diff --git a/locale/FreeBSD/nl_langinfo.3 b/locale/FreeBSD/nl_langinfo.3 index 3fc47e0..1185739 100644 --- a/locale/FreeBSD/nl_langinfo.3 +++ b/locale/FreeBSD/nl_langinfo.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/nl_langinfo.3,v 1.5 2003/09/08 19:57:14 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/nl_langinfo.3,v 1.7 2009/11/16 14:33:31 brueffer Exp $ .\" .Dd May 3, 2001 .Dt NL_LANGINFO 3 @@ -53,18 +53,7 @@ with a category corresponding to the category of or to the category .Dv LC_ALL , -may overwrite buffer pointed by the return value. -.Sh EXAMPLES -For example: -.Pp -.Dl nl_langinfo(ABDAY_1) -.Pp -would return a pointer to the string -.Qq Li Dom -if the identified language was -Portuguese, and -.Qq Li Sun -if the identified language was English. +may overwrite the buffer pointed to by the return value. .Sh RETURN VALUES In a locale where langinfo data is not defined, .Fn nl_langinfo @@ -76,6 +65,17 @@ In all locales, returns a pointer to an empty string if .Fa item contains an invalid setting. +.Sh EXAMPLES +For example: +.Pp +.Dl nl_langinfo(ABDAY_1) +.Pp +would return a pointer to the string +.Qq Li Dom +if the identified language was +Portuguese, and +.Qq Li Sun +if the identified language was English. .Sh SEE ALSO .Xr setlocale 3 .Sh STANDARDS diff --git a/locale/FreeBSD/nl_langinfo.3.patch b/locale/FreeBSD/nl_langinfo.3.patch index 9f9e3e0..d10c7b3 100644 --- a/locale/FreeBSD/nl_langinfo.3.patch +++ b/locale/FreeBSD/nl_langinfo.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/nl_langinfo.3 2004-11-25 11:38:19.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/nl_langinfo.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- nl_langinfo.3.orig 2009-11-30 16:10:29.000000000 -0800 ++++ nl_langinfo.3 2009-11-30 16:10:30.000000000 -0800 @@ -28,14 +28,24 @@ .Dt NL_LANGINFO 3 .Os @@ -27,16 +27,7 @@ .Sh DESCRIPTION The .Fn nl_langinfo -@@ -53,7 +63,7 @@ - or to the - category - .Dv LC_ALL , --may overwrite buffer pointed by the return value. -+may overwrite the buffer pointed to by the return value. - .Sh EXAMPLES - For example: - .Pp -@@ -65,6 +75,14 @@ +@@ -76,8 +86,17 @@ if the identified language was Portuguese, and .Qq Li Sun if the identified language was English. @@ -48,12 +39,6 @@ +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. - .Sh RETURN VALUES - In a locale where langinfo data is not defined, - .Fn nl_langinfo -@@ -77,7 +95,8 @@ - .Fa item - contains an invalid setting. .Sh SEE ALSO -.Xr setlocale 3 +.Xr setlocale 3 , diff --git a/locale/FreeBSD/nl_langinfo.c.patch b/locale/FreeBSD/nl_langinfo.c.patch index ed9a909..7e05fb5 100644 --- a/locale/FreeBSD/nl_langinfo.c.patch +++ b/locale/FreeBSD/nl_langinfo.c.patch @@ -1,5 +1,5 @@ ---- nl_langinfo.c.orig 2008-01-15 11:30:57.000000000 -0800 -+++ nl_langinfo.c 2008-01-17 23:58:24.000000000 -0800 +--- nl_langinfo.c.orig 2009-11-09 18:47:29.000000000 -0800 ++++ nl_langinfo.c 2009-11-09 18:47:34.000000000 -0800 @@ -27,6 +27,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/nl_langinfo.c,v 1.17 2003/06/26 10:46:16 phantom Exp $"); @@ -9,7 +9,7 @@ #include #include #include -@@ -36,62 +38,66 @@ +@@ -36,62 +38,66 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include "lnumeric.h" #include "lmessages.h" #include "lmonetary.h" @@ -90,7 +90,7 @@ break; case ERA: /* XXX: need to be implemented */ -@@ -114,16 +120,16 @@ +@@ -114,16 +120,16 @@ nl_langinfo(nl_item item) ret = ""; break; case RADIXCHAR: @@ -111,7 +111,7 @@ break; /* * YESSTR and NOSTR items marked with LEGACY are available, but not -@@ -131,25 +137,25 @@ +@@ -131,25 +137,25 @@ nl_langinfo(nl_item item) * they're subject to remove in future specification editions. */ case YESSTR: /* LEGACY */ @@ -143,7 +143,7 @@ psn = '.'; } else psn = pos ? '-' : '+'; -@@ -166,10 +172,19 @@ +@@ -166,10 +172,19 @@ nl_langinfo(nl_item item) } break; case D_MD_ORDER: /* FreeBSD local extension */ diff --git a/locale/FreeBSD/none.c b/locale/FreeBSD/none.c index 0514bc4..cc94e47 100644 --- a/locale/FreeBSD/none.c +++ b/locale/FreeBSD/none.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -39,7 +35,7 @@ static char sccsid[] = "@(#)none.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.12 2004/07/21 10:54:57 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.15 2007/10/13 16:28:22 ache Exp $"); #include #include @@ -51,16 +47,21 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.12 2004/07/21 10:54:57 tjr Ex #include #include "mblocal.h" -int _none_init(_RuneLocale *); -size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict); -int _none_mbsinit(const mbstate_t *); -size_t _none_mbsnrtowcs(wchar_t * __restrict dst, - const char ** __restrict src, size_t nms, size_t len, - mbstate_t * __restrict ps __unused); -size_t _none_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); -size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, - size_t, size_t, mbstate_t * __restrict); +static size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _none_mbsinit(const mbstate_t *); +static size_t _none_mbsnrtowcs(wchar_t * __restrict dst, + const char ** __restrict src, size_t nms, size_t len, + mbstate_t * __restrict ps __unused); +static size_t _none_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); +static size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict); + +/* setup defaults */ + +int __mb_cur_max = 1; +int __mb_sb_limit = 256; /* Expected to be <= _CACHED_RUNES */ int _none_init(_RuneLocale *rl) @@ -73,10 +74,11 @@ _none_init(_RuneLocale *rl) __wcsnrtombs = _none_wcsnrtombs; _CurrentRuneLocale = rl; __mb_cur_max = 1; + __mb_sb_limit = 256; return(0); } -int +static int _none_mbsinit(const mbstate_t *ps __unused) { @@ -87,7 +89,7 @@ _none_mbsinit(const mbstate_t *ps __unused) return (1); } -size_t +static size_t _none_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps __unused) { @@ -103,7 +105,7 @@ _none_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, return (*s == '\0' ? 0 : 1); } -size_t +static size_t _none_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps __unused) { @@ -119,7 +121,7 @@ _none_wcrtomb(char * __restrict s, wchar_t wc, return (1); } -size_t +static size_t _none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps __unused) { @@ -144,7 +146,7 @@ _none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, return (nchr); } -size_t +static size_t _none_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps __unused) { @@ -177,3 +179,16 @@ _none_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, *src = s; return (nchr); } + +/* setup defaults */ + +size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t, + mbstate_t * __restrict) = _none_mbrtowc; +int (*__mbsinit)(const mbstate_t *) = _none_mbsinit; +size_t (*__mbsnrtowcs)(wchar_t * __restrict, const char ** __restrict, + size_t, size_t, mbstate_t * __restrict) = _none_mbsnrtowcs; +size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict) = + _none_wcrtomb; +size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict) = _none_wcsnrtombs; + diff --git a/locale/FreeBSD/none.c.patch b/locale/FreeBSD/none.c.patch index 51e2b8b..405e5fd 100644 --- a/locale/FreeBSD/none.c.patch +++ b/locale/FreeBSD/none.c.patch @@ -1,37 +1,33 @@ ---- none.c.orig Fri Feb 18 15:34:30 2005 -+++ none.c Fri Feb 18 15:37:15 2005 -@@ -41,6 +41,8 @@ +--- none.c.orig 2009-11-09 18:24:17.000000000 -0800 ++++ none.c 2009-11-10 11:08:33.000000000 -0800 +@@ -37,6 +37,8 @@ static char sccsid[] = "@(#)none.c 8.1 ( #include - __FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.12 2004/07/21 10:54:57 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.15 2007/10/13 16:28:22 ache Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -51,33 +53,32 @@ +@@ -47,39 +49,27 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include #include "mblocal.h" --int _none_init(_RuneLocale *); --size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -- mbstate_t * __restrict); --int _none_mbsinit(const mbstate_t *); --size_t _none_mbsnrtowcs(wchar_t * __restrict dst, -+__private_extern__ int _none_init(struct __xlocale_st_runelocale *); -+__private_extern__ size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -+ mbstate_t * __restrict, locale_t); -+__private_extern__ int _none_mbsinit(const mbstate_t *, locale_t); -+__private_extern__ size_t _none_mbsnrtowcs(wchar_t * __restrict dst, - const char ** __restrict src, size_t nms, size_t len, -- mbstate_t * __restrict ps __unused); --size_t _none_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); --size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, -- size_t, size_t, mbstate_t * __restrict); -+ mbstate_t * __restrict ps __unused, locale_t); -+__private_extern__ size_t _none_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); -+__private_extern__ size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, -+ size_t, size_t, mbstate_t * __restrict, locale_t); +-static size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, +- size_t, mbstate_t * __restrict); +-static int _none_mbsinit(const mbstate_t *); +-static size_t _none_mbsnrtowcs(wchar_t * __restrict dst, +- const char ** __restrict src, size_t nms, size_t len, +- mbstate_t * __restrict ps __unused); +-static size_t _none_wcrtomb(char * __restrict, wchar_t, +- mbstate_t * __restrict); +-static size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, +- size_t, size_t, mbstate_t * __restrict); +- + /* setup defaults */ + + int __mb_cur_max = 1; + int __mb_sb_limit = 256; /* Expected to be <= _CACHED_RUNES */ -int -_none_init(_RuneLocale *rl) @@ -46,67 +42,86 @@ - __wcsnrtombs = _none_wcsnrtombs; - _CurrentRuneLocale = rl; - __mb_cur_max = 1; +- __mb_sb_limit = 256; + xrl->__mbrtowc = _none_mbrtowc; + xrl->__mbsinit = _none_mbsinit; + xrl->__mbsnrtowcs = _none_mbsnrtowcs; + xrl->__wcrtomb = _none_wcrtomb; + xrl->__wcsnrtombs = _none_wcsnrtombs; + xrl->__mb_cur_max = 1; ++ xrl->__mb_sb_limit = 256; return(0); } --int +-static int -_none_mbsinit(const mbstate_t *ps __unused) +__private_extern__ int -+_none_mbsinit(const mbstate_t *ps __unused, locale_t loc) ++_none_mbsinit(const mbstate_t *ps __unused, locale_t loc __unused) { /* -@@ -87,9 +88,9 @@ +@@ -89,9 +79,9 @@ _none_mbsinit(const mbstate_t *ps __unus return (1); } --size_t +-static size_t +__private_extern__ size_t _none_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps __unused) -+ mbstate_t * __restrict ps __unused, locale_t loc) ++ mbstate_t * __restrict ps __unused, locale_t loc __unused) { if (s == NULL) -@@ -103,9 +104,9 @@ +@@ -105,9 +95,9 @@ _none_mbrtowc(wchar_t * __restrict pwc, return (*s == '\0' ? 0 : 1); } --size_t +-static size_t +__private_extern__ size_t _none_wcrtomb(char * __restrict s, wchar_t wc, - mbstate_t * __restrict ps __unused) -+ mbstate_t * __restrict ps __unused, locale_t loc) ++ mbstate_t * __restrict ps __unused, locale_t loc __unused) { if (s == NULL) -@@ -119,9 +120,9 @@ +@@ -121,9 +111,9 @@ _none_wcrtomb(char * __restrict s, wchar return (1); } --size_t +-static size_t +__private_extern__ size_t _none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, - size_t nms, size_t len, mbstate_t * __restrict ps __unused) -+ size_t nms, size_t len, mbstate_t * __restrict ps __unused, locale_t loc) ++ size_t nms, size_t len, mbstate_t * __restrict ps __unused, locale_t loc __unused) { const char *s; size_t nchr; -@@ -144,9 +145,9 @@ +@@ -146,9 +136,9 @@ _none_mbsnrtowcs(wchar_t * __restrict ds return (nchr); } --size_t +-static size_t +__private_extern__ size_t _none_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, - size_t nwc, size_t len, mbstate_t * __restrict ps __unused) -+ size_t nwc, size_t len, mbstate_t * __restrict ps __unused, locale_t loc) ++ size_t nwc, size_t len, mbstate_t * __restrict ps __unused, locale_t loc __unused) { const wchar_t *s; size_t nchr; +@@ -179,16 +169,3 @@ _none_wcsnrtombs(char * __restrict dst, + *src = s; + return (nchr); + } +- +-/* setup defaults */ +- +-size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t, +- mbstate_t * __restrict) = _none_mbrtowc; +-int (*__mbsinit)(const mbstate_t *) = _none_mbsinit; +-size_t (*__mbsnrtowcs)(wchar_t * __restrict, const char ** __restrict, +- size_t, size_t, mbstate_t * __restrict) = _none_mbsnrtowcs; +-size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict) = +- _none_wcrtomb; +-size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, +- size_t, size_t, mbstate_t * __restrict) = _none_wcsnrtombs; +- diff --git a/locale/FreeBSD/rune.c.patch b/locale/FreeBSD/rune.c.patch index 7d81d4b..402153d 100644 --- a/locale/FreeBSD/rune.c.patch +++ b/locale/FreeBSD/rune.c.patch @@ -1,6 +1,8 @@ ---- rune.c.orig 2004-11-25 11:38:19.000000000 -0800 -+++ rune.c 2005-04-12 17:18:12.000000000 -0700 -@@ -34,28 +34,98 @@ +Index: rune.c +=================================================================== +--- rune.c (revision 59751) ++++ rune.c (working copy) +@@ -34,28 +34,100 @@ * SUCH DAMAGE. */ @@ -16,8 +18,10 @@ #include "namespace.h" #include #include -+#endif /* !RUNEOFF32 */ #include ++#else ++#include "runetype.h" ++#endif /* !RUNEOFF32 */ #include +#ifndef RUNEOFF32 #include @@ -101,7 +105,7 @@ void *lastp; _RuneLocale *rl; _RuneEntry *rr; -@@ -65,13 +135,20 @@ +@@ -65,13 +137,20 @@ if (_fstat(fileno(fp), &sb) < 0) return (NULL); @@ -124,7 +128,7 @@ errno = 0; rewind(fp); /* Someone might have read the magic number once already */ -@@ -82,26 +159,43 @@ +@@ -82,26 +161,43 @@ return (NULL); } @@ -172,7 +176,7 @@ rl->__runetype_ext.__nranges = ntohl(rl->__runetype_ext.__nranges); rl->__maplower_ext.__nranges = ntohl(rl->__maplower_ext.__nranges); rl->__mapupper_ext.__nranges = ntohl(rl->__mapupper_ext.__nranges); -@@ -111,7 +205,54 @@ +@@ -111,7 +207,54 @@ rl->__maplower[x] = ntohl(rl->__maplower[x]); rl->__mapupper[x] = ntohl(rl->__mapupper[x]); } @@ -227,7 +231,7 @@ rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable; rl->__variable = rl->__runetype_ext.__ranges + rl->__runetype_ext.__nranges; -@@ -142,8 +283,10 @@ +@@ -142,8 +285,10 @@ for (x = 0; x < rl->__runetype_ext.__nranges; ++x) { rr = rl->__runetype_ext.__ranges; @@ -238,7 +242,7 @@ if ((rr[x].__map = ntohl(rr[x].__map)) == 0) { int len = rr[x].__max - rr[x].__min + 1; rr[x].__types = rl->__variable; -@@ -153,12 +296,15 @@ +@@ -153,12 +298,15 @@ errno = EFTYPE; return (NULL); } @@ -254,7 +258,7 @@ for (x = 0; x < rl->__maplower_ext.__nranges; ++x) { rr = rl->__maplower_ext.__ranges; -@@ -174,6 +320,22 @@ +@@ -174,6 +322,22 @@ rr[x].__max = ntohl(rr[x].__max); rr[x].__map = ntohl(rr[x].__map); } @@ -277,7 +281,7 @@ if (((char *)rl->__variable) + rl->__variable_len > (char *)lastp) { free(data); errno = EFTYPE; -@@ -195,5 +357,7 @@ +@@ -195,5 +359,7 @@ if (!rl->__mapupper_ext.__nranges) rl->__mapupper_ext.__ranges = 0; diff --git a/locale/FreeBSD/runetype.c b/locale/FreeBSD/runetype.c index 2536c55..bb1bbc4 100644 --- a/locale/FreeBSD/runetype.c +++ b/locale/FreeBSD/runetype.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,14 +31,14 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/runetype.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/runetype.c,v 1.14 2007/01/09 00:28:00 imp Exp $"); +#include #include #include unsigned long -___runetype(c) - __ct_rune_t c; +___runetype(__ct_rune_t c) { size_t lim; _RuneRange *rr = &_CurrentRuneLocale->__runetype_ext; diff --git a/locale/FreeBSD/runetype.c.patch b/locale/FreeBSD/runetype.c.patch index d9a6109..ef76217 100644 --- a/locale/FreeBSD/runetype.c.patch +++ b/locale/FreeBSD/runetype.c.patch @@ -1,19 +1,18 @@ ---- runetype.c.orig 2004-11-25 11:38:19.000000000 -0800 -+++ runetype.c 2005-02-16 22:43:53.000000000 -0800 -@@ -37,20 +37,25 @@ +--- runetype.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ runetype.c 2009-11-09 16:54:21.000000000 -0800 +@@ -33,20 +33,24 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/runetype.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/runetype.c,v 1.14 2007/01/09 00:28:00 imp Exp $"); +#include "xlocale_private.h" + + #include #include #include unsigned long --___runetype(c) -+___runetype_l(c, loc) - __ct_rune_t c; -+ locale_t loc; +-___runetype(__ct_rune_t c) ++___runetype_l(__ct_rune_t c, locale_t loc) { size_t lim; - _RuneRange *rr = &_CurrentRuneLocale->__runetype_ext; @@ -28,14 +27,13 @@ /* Binary search -- see bsearch.c for explanation. */ base = rr->__ranges; for (lim = rr->__nranges; lim != 0; lim >>= 1) { -@@ -68,3 +73,10 @@ +@@ -64,3 +68,9 @@ ___runetype(__ct_rune_t c) return(0L); } + +unsigned long -+___runetype(c) -+ __ct_rune_t c; ++___runetype(__ct_rune_t c) +{ + return ___runetype_l(c, __current_locale()); +} diff --git a/locale/FreeBSD/setlocale.3 b/locale/FreeBSD/setlocale.3 index b09dbb5..1048ce9 100644 --- a/locale/FreeBSD/setlocale.3 +++ b/locale/FreeBSD/setlocale.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setlocale.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/locale/setlocale.3,v 1.33 2004/10/17 06:51:50 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/setlocale.3,v 1.35 2007/01/09 00:28:00 imp Exp $ .\" .Dd November 21, 2003 .Dt SETLOCALE 3 @@ -143,8 +139,6 @@ if the given combination of and .Fa locale makes no sense. -.Sh ERRORS -No errors are defined. .Sh FILES .Bl -tag -width /usr/share/locale/locale/category -compact .It Pa $PATH_LOCALE/ Ns Em locale/category @@ -154,6 +148,8 @@ locale file for the locale and the category .Em category . .El +.Sh ERRORS +No errors are defined. .Sh SEE ALSO .Xr colldef 1 , .Xr mklocale 1 , diff --git a/locale/FreeBSD/setlocale.3.patch b/locale/FreeBSD/setlocale.3.patch index 97ed7a9..195cf81 100644 --- a/locale/FreeBSD/setlocale.3.patch +++ b/locale/FreeBSD/setlocale.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/setlocale.3 2004-11-25 11:38:19.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/setlocale.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -46,7 +46,10 @@ +--- setlocale.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ setlocale.3 2009-11-09 15:05:26.000000000 -0800 +@@ -42,7 +42,10 @@ .Sh SYNOPSIS .In locale.h .Ft char * @@ -12,7 +12,7 @@ .Sh DESCRIPTION The .Fn setlocale -@@ -105,14 +108,14 @@ +@@ -101,14 +104,14 @@ Set a locale for formatting dates and ti function. .El .Pp diff --git a/locale/FreeBSD/setlocale.c b/locale/FreeBSD/setlocale.c index e42f53a..9874849 100644 --- a/locale/FreeBSD/setlocale.c +++ b/locale/FreeBSD/setlocale.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -39,7 +35,7 @@ static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.50 2004/01/31 19:15:32 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.51 2007/01/09 00:28:00 imp Exp $"); #include #include diff --git a/locale/FreeBSD/setlocale.c.patch b/locale/FreeBSD/setlocale.c.patch index 55446f1..b782cac 100644 --- a/locale/FreeBSD/setlocale.c.patch +++ b/locale/FreeBSD/setlocale.c.patch @@ -1,15 +1,15 @@ ---- setlocale.c.orig 2008-01-24 17:13:46.000000000 -0800 -+++ setlocale.c 2008-02-17 13:23:02.000000000 -0800 -@@ -41,6 +41,8 @@ static char sccsid[] = "@(#)setlocale.c +--- setlocale.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ setlocale.c 2009-11-09 15:05:26.000000000 -0800 +@@ -37,6 +37,8 @@ static char sccsid[] = "@(#)setlocale.c #include - __FBSDID("$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.50 2004/01/31 19:15:32 ache Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.51 2007/01/09 00:28:00 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -56,7 +58,7 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ +@@ -52,7 +54,7 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include "lmessages.h" /* for __messages_load_locale() */ #include "setlocale.h" #include "ldpart.h" @@ -18,7 +18,7 @@ /* * Category names for getenv() -@@ -99,15 +101,18 @@ static char current_locale_string[_LC_LA +@@ -95,15 +97,18 @@ static char current_locale_string[_LC_LA static char *currentlocale(void); static char *loadlocale(int); @@ -39,7 +39,7 @@ if (category < LC_ALL || category >= _LC_LAST) { errno = EINVAL; -@@ -118,6 +123,7 @@ setlocale(category, locale) +@@ -114,6 +119,7 @@ setlocale(category, locale) return (category != LC_ALL ? current_categories[category] : currentlocale()); @@ -47,7 +47,7 @@ /* * Default to the current locale for everything. */ -@@ -133,7 +139,7 @@ setlocale(category, locale) +@@ -129,7 +135,7 @@ setlocale(category, locale) env = __get_locale_env(i); if (strlen(env) > ENCODING_LEN) { errno = EINVAL; @@ -56,7 +56,7 @@ } (void)strcpy(new_categories[i], env); } -@@ -141,21 +147,21 @@ setlocale(category, locale) +@@ -137,21 +143,21 @@ setlocale(category, locale) env = __get_locale_env(category); if (strlen(env) > ENCODING_LEN) { errno = EINVAL; @@ -81,7 +81,7 @@ } for (i = 1; i < _LC_LAST; ++i) (void)strcpy(new_categories[i], locale); -@@ -164,14 +170,14 @@ setlocale(category, locale) +@@ -160,14 +166,14 @@ setlocale(category, locale) ; if (!r[1]) { errno = EINVAL; @@ -98,7 +98,7 @@ } (void)strlcpy(new_categories[i], locale, len + 1); -@@ -191,8 +197,11 @@ setlocale(category, locale) +@@ -187,8 +193,11 @@ setlocale(category, locale) } if (category != LC_ALL) @@ -111,7 +111,7 @@ for (i = 1; i < _LC_LAST; ++i) { (void)strcpy(saved_categories[i], current_categories[i]); if (loadlocale(i) == NULL) { -@@ -205,11 +214,15 @@ setlocale(category, locale) +@@ -201,11 +210,15 @@ setlocale(category, locale) (void)loadlocale(j); } } @@ -129,7 +129,7 @@ } static char * -@@ -237,7 +250,7 @@ loadlocale(category) +@@ -233,7 +246,7 @@ loadlocale(category) { char *new = new_categories[category]; char *old = current_categories[category]; @@ -138,7 +138,7 @@ int saved_errno; if ((new[0] == '.' && -@@ -280,15 +293,26 @@ loadlocale(category) +@@ -276,15 +289,26 @@ loadlocale(category) if (strcmp(new, old) == 0) return (old); @@ -167,7 +167,7 @@ __get_locale_env(category) int category; { -@@ -315,7 +339,7 @@ __get_locale_env(category) +@@ -311,7 +335,7 @@ __get_locale_env(category) /* * Detect locale storage location and store its value to _PathLocale variable */ diff --git a/locale/FreeBSD/setlocale.h.patch b/locale/FreeBSD/setlocale.h.patch index 565fbed..95bb91f 100644 --- a/locale/FreeBSD/setlocale.h.patch +++ b/locale/FreeBSD/setlocale.h.patch @@ -1,5 +1,5 @@ ---- setlocale.h.orig 2004-11-25 11:38:19.000000000 -0800 -+++ setlocale.h 2005-02-19 14:45:55.000000000 -0800 +--- setlocale.h.orig 2009-11-09 15:05:25.000000000 -0800 ++++ setlocale.h 2009-11-09 15:05:26.000000000 -0800 @@ -29,12 +29,14 @@ #ifndef _SETLOCALE_H_ #define _SETLOCALE_H_ diff --git a/locale/FreeBSD/setrunelocale.c b/locale/FreeBSD/setrunelocale.c index 7ef9f4b..bf2b6d9 100644 --- a/locale/FreeBSD/setrunelocale.c +++ b/locale/FreeBSD/setrunelocale.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.44 2004/10/18 02:06:18 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.51 2008/01/23 03:05:35 ache Exp $"); #include #include @@ -49,14 +45,8 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.44 2004/10/18 02:06: #include "mblocal.h" #include "setlocale.h" -extern int _none_init(_RuneLocale *); -extern int _UTF8_init(_RuneLocale *); -extern int _EUC_init(_RuneLocale *); -extern int _GB18030_init(_RuneLocale *); -extern int _GB2312_init(_RuneLocale *); -extern int _GBK_init(_RuneLocale *); -extern int _BIG5_init(_RuneLocale *); -extern int _MSKanji_init(_RuneLocale *); +extern int __mb_sb_limit; + extern _RuneLocale *_Read_RuneMagi(FILE *); static int __setrunelocale(const char *); @@ -68,9 +58,20 @@ __setrunelocale(const char *encoding) char name[PATH_MAX]; _RuneLocale *rl; int saverr, ret; + size_t (*old__mbrtowc)(wchar_t * __restrict, + const char * __restrict, size_t, mbstate_t * __restrict); + size_t (*old__wcrtomb)(char * __restrict, wchar_t, + mbstate_t * __restrict); + int (*old__mbsinit)(const mbstate_t *); + size_t (*old__mbsnrtowcs)(wchar_t * __restrict, + const char ** __restrict, size_t, size_t, mbstate_t * __restrict); + size_t (*old__wcsnrtombs)(char * __restrict, + const wchar_t ** __restrict, size_t, size_t, + mbstate_t * __restrict); static char ctype_encoding[ENCODING_LEN + 1]; static _RuneLocale *CachedRuneLocale; static int Cached__mb_cur_max; + static int Cached__mb_sb_limit; static size_t (*Cached__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static size_t (*Cached__wcrtomb)(char * __restrict, wchar_t, @@ -86,13 +87,7 @@ __setrunelocale(const char *encoding) * The "C" and "POSIX" locale are always here. */ if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { - _CurrentRuneLocale = &_DefaultRuneLocale; - __mb_cur_max = 1; - __mbrtowc = _none_mbrtowc; - __mbsinit = _none_mbsinit; - __mbsnrtowcs = _none_mbsnrtowcs; - __wcrtomb = _none_wcrtomb; - __wcsnrtombs = _none_wcsnrtombs; + (void) _none_init(&_DefaultRuneLocale); return (0); } @@ -103,6 +98,7 @@ __setrunelocale(const char *encoding) strcmp(encoding, ctype_encoding) == 0) { _CurrentRuneLocale = CachedRuneLocale; __mb_cur_max = Cached__mb_cur_max; + __mb_sb_limit = Cached__mb_sb_limit; __mbrtowc = Cached__mbrtowc; __mbsinit = Cached__mbsinit; __mbsnrtowcs = Cached__mbsnrtowcs; @@ -131,20 +127,29 @@ __setrunelocale(const char *encoding) } (void)fclose(fp); + old__mbrtowc = __mbrtowc; + old__mbsinit = __mbsinit; + old__mbsnrtowcs = __mbsnrtowcs; + old__wcrtomb = __wcrtomb; + old__wcsnrtombs = __wcsnrtombs; + __mbrtowc = NULL; __mbsinit = NULL; __mbsnrtowcs = __mbsnrtowcs_std; __wcrtomb = NULL; __wcsnrtombs = __wcsnrtombs_std; + rl->__sputrune = NULL; rl->__sgetrune = NULL; if (strcmp(rl->__encoding, "NONE") == 0) ret = _none_init(rl); + else if (strcmp(rl->__encoding, "ASCII") == 0) + ret = _ascii_init(rl); else if (strcmp(rl->__encoding, "UTF-8") == 0) ret = _UTF8_init(rl); else if (strcmp(rl->__encoding, "EUC") == 0) ret = _EUC_init(rl); - else if (strcmp(rl->__encoding, "GB18030") == 0) + else if (strcmp(rl->__encoding, "GB18030") == 0) ret = _GB18030_init(rl); else if (strcmp(rl->__encoding, "GB2312") == 0) ret = _GB2312_init(rl); @@ -156,6 +161,7 @@ __setrunelocale(const char *encoding) ret = _MSKanji_init(rl); else ret = EFTYPE; + if (ret == 0) { if (CachedRuneLocale != NULL) { /* See euc.c */ @@ -165,14 +171,21 @@ __setrunelocale(const char *encoding) } CachedRuneLocale = _CurrentRuneLocale; Cached__mb_cur_max = __mb_cur_max; + Cached__mb_sb_limit = __mb_sb_limit; Cached__mbrtowc = __mbrtowc; Cached__mbsinit = __mbsinit; Cached__mbsnrtowcs = __mbsnrtowcs; Cached__wcrtomb = __wcrtomb; Cached__wcsnrtombs = __wcsnrtombs; (void)strcpy(ctype_encoding, encoding); - } else + } else { + __mbrtowc = old__mbrtowc; + __mbsinit = old__mbsinit; + __mbsnrtowcs = old__mbsnrtowcs; + __wcrtomb = old__wcrtomb; + __wcsnrtombs = old__wcsnrtombs; free(rl); + } return (ret); } diff --git a/locale/FreeBSD/setrunelocale.c.patch b/locale/FreeBSD/setrunelocale.c.patch index fef06f7..ed607d0 100644 --- a/locale/FreeBSD/setrunelocale.c.patch +++ b/locale/FreeBSD/setrunelocale.c.patch @@ -1,45 +1,29 @@ ---- setrunelocale.c.orig 2008-05-12 17:37:36.000000000 -0700 -+++ setrunelocale.c 2008-05-13 00:32:37.000000000 -0700 -@@ -37,6 +37,8 @@ +--- setrunelocale.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ setrunelocale.c 2009-11-09 17:20:45.000000000 -0800 +@@ -33,6 +33,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.44 2004/10/18 02:06:18 ache Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.51 2008/01/23 03:05:35 ache Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -49,67 +51,66 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ +@@ -45,67 +47,60 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include "mblocal.h" #include "setlocale.h" --extern int _none_init(_RuneLocale *); --extern int _UTF8_init(_RuneLocale *); --extern int _EUC_init(_RuneLocale *); --extern int _GB18030_init(_RuneLocale *); --extern int _GB2312_init(_RuneLocale *); --extern int _GBK_init(_RuneLocale *); --extern int _BIG5_init(_RuneLocale *); --extern int _MSKanji_init(_RuneLocale *); --extern _RuneLocale *_Read_RuneMagi(FILE *); +-extern int __mb_sb_limit; - --static int __setrunelocale(const char *); -+extern int _none_init(struct __xlocale_st_runelocale *); -+extern int _UTF8_init(struct __xlocale_st_runelocale *); -+extern int _EUC_init(struct __xlocale_st_runelocale *); -+extern int _GB18030_init(struct __xlocale_st_runelocale *); -+extern int _GB2312_init(struct __xlocale_st_runelocale *); -+extern int _GBK_init(struct __xlocale_st_runelocale *); -+extern int _BIG5_init(struct __xlocale_st_runelocale *); -+extern int _MSKanji_init(struct __xlocale_st_runelocale *); -+extern int _UTF2_init(struct __xlocale_st_runelocale *); /* deprecated */ +-extern _RuneLocale *_Read_RuneMagi(FILE *); +extern struct __xlocale_st_runelocale *_Read_RuneMagi(FILE *); -+ -+#ifdef LEGACY_RUNE_APIS + +-static int __setrunelocale(const char *); ++#ifdef UNIFDEF_LEGACY_RUNE_APIS +/* depreciated interfaces */ +rune_t sgetrune(const char *, size_t, char const **); +int sputrune(rune_t, char *, size_t, char **); -+#endif /* LEGACY_RUNE_APIS */ ++#endif /* UNIFDEF_LEGACY_RUNE_APIS */ -static int -__setrunelocale(const char *encoding) @@ -51,9 +35,20 @@ + struct __xlocale_st_runelocale *xrl; _RuneLocale *rl; int saverr, ret; +- size_t (*old__mbrtowc)(wchar_t * __restrict, +- const char * __restrict, size_t, mbstate_t * __restrict); +- size_t (*old__wcrtomb)(char * __restrict, wchar_t, +- mbstate_t * __restrict); +- int (*old__mbsinit)(const mbstate_t *); +- size_t (*old__mbsnrtowcs)(wchar_t * __restrict, +- const char ** __restrict, size_t, size_t, mbstate_t * __restrict); +- size_t (*old__wcsnrtombs)(char * __restrict, +- const wchar_t ** __restrict, size_t, size_t, +- mbstate_t * __restrict); - static char ctype_encoding[ENCODING_LEN + 1]; - static _RuneLocale *CachedRuneLocale; - static int Cached__mb_cur_max; +- static int Cached__mb_sb_limit; - static size_t (*Cached__mbrtowc)(wchar_t * __restrict, - const char * __restrict, size_t, mbstate_t * __restrict); - static size_t (*Cached__wcrtomb)(char * __restrict, wchar_t, @@ -66,25 +61,21 @@ - mbstate_t * __restrict); + static struct __xlocale_st_runelocale *CachedRuneLocale; + extern int __mb_cur_max; ++ extern int __mb_sb_limit; + static pthread_lock_t cache_lock = LOCK_INITIALIZER; /* * The "C" and "POSIX" locale are always here. */ if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { -- _CurrentRuneLocale = &_DefaultRuneLocale; -- __mb_cur_max = 1; -- __mbrtowc = _none_mbrtowc; -- __mbsinit = _none_mbsinit; -- __mbsnrtowcs = _none_mbsnrtowcs; -- __wcrtomb = _none_wcrtomb; -- __wcsnrtombs = _none_wcsnrtombs; +- (void) _none_init(&_DefaultRuneLocale); + XL_RELEASE(loc->__lc_ctype); + loc->__lc_ctype = &_DefaultRuneXLocale; + /* no need to retain _DefaultRuneXLocale */ + if (loc == &__global_locale) { + _CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale; + __mb_cur_max = loc->__lc_ctype->__mb_cur_max; ++ __mb_sb_limit = loc->__lc_ctype->__mb_sb_limit; + } return (0); } @@ -97,6 +88,7 @@ - strcmp(encoding, ctype_encoding) == 0) { - _CurrentRuneLocale = CachedRuneLocale; - __mb_cur_max = Cached__mb_cur_max; +- __mb_sb_limit = Cached__mb_sb_limit; - __mbrtowc = Cached__mbrtowc; - __mbsinit = Cached__mbsinit; - __mbsnrtowcs = Cached__mbsnrtowcs; @@ -109,6 +101,7 @@ + if (loc == &__global_locale) { + _CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale; + __mb_cur_max = loc->__lc_ctype->__mb_cur_max; ++ __mb_sb_limit = loc->__lc_ctype->__mb_sb_limit; + } + UNLOCK(cache_lock); return (0); @@ -117,7 +110,7 @@ /* * Slurp the locale file into the cache. -@@ -124,63 +125,86 @@ __setrunelocale(const char *encoding) +@@ -120,80 +115,90 @@ __setrunelocale(const char *encoding) if ((fp = fopen(name, "r")) == NULL) return (errno == 0 ? ENOENT : errno); @@ -129,11 +122,18 @@ } (void)fclose(fp); +- old__mbrtowc = __mbrtowc; +- old__mbsinit = __mbsinit; +- old__mbsnrtowcs = __mbsnrtowcs; +- old__wcrtomb = __wcrtomb; +- old__wcsnrtombs = __wcsnrtombs; +- - __mbrtowc = NULL; - __mbsinit = NULL; - __mbsnrtowcs = __mbsnrtowcs_std; - __wcrtomb = NULL; - __wcsnrtombs = __wcsnrtombs_std; +- + xrl->__mbrtowc = NULL; + xrl->__mbsinit = NULL; + xrl->__mbsnrtowcs = __mbsnrtowcs_std; @@ -142,25 +142,28 @@ + + rl = &xrl->_CurrentRuneLocale; + -+#ifdef LEGACY_RUNE_APIS ++#ifdef UNIFDEF_LEGACY_RUNE_APIS + /* provide backwards compatibility (depreciated interface) */ + rl->__sputrune = sputrune; + rl->__sgetrune = sgetrune; -+#else /* LEGACY_RUNE_APIS */ ++#else /* UNIFDEF_LEGACY_RUNE_APIS */ rl->__sputrune = NULL; rl->__sgetrune = NULL; -+#endif /* LEGACY_RUNE_APIS */ ++#endif /* UNIFDEF_LEGACY_RUNE_APIS */ + if (strcmp(rl->__encoding, "NONE") == 0) - ret = _none_init(rl); + ret = _none_init(xrl); + else if (strcmp(rl->__encoding, "ASCII") == 0) +- ret = _ascii_init(rl); ++ ret = _ascii_init(xrl); else if (strcmp(rl->__encoding, "UTF-8") == 0) - ret = _UTF8_init(rl); + ret = _UTF8_init(xrl); else if (strcmp(rl->__encoding, "EUC") == 0) - ret = _EUC_init(rl); + ret = _EUC_init(xrl); - else if (strcmp(rl->__encoding, "GB18030") == 0) + else if (strcmp(rl->__encoding, "GB18030") == 0) - ret = _GB18030_init(rl); + ret = _GB18030_init(xrl); else if (strcmp(rl->__encoding, "GB2312") == 0) @@ -179,6 +182,7 @@ + ret = _UTF2_init(xrl); else ret = EFTYPE; + if (ret == 0) { - if (CachedRuneLocale != NULL) { - /* See euc.c */ @@ -191,28 +195,37 @@ + if (loc == &__global_locale) { + _CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale; + __mb_cur_max = loc->__lc_ctype->__mb_cur_max; ++ __mb_sb_limit = loc->__lc_ctype->__mb_sb_limit; } - CachedRuneLocale = _CurrentRuneLocale; - Cached__mb_cur_max = __mb_cur_max; +- Cached__mb_sb_limit = __mb_sb_limit; - Cached__mbrtowc = __mbrtowc; - Cached__mbsinit = __mbsinit; - Cached__mbsnrtowcs = __mbsnrtowcs; - Cached__wcrtomb = __wcrtomb; - Cached__wcsnrtombs = __wcsnrtombs; - (void)strcpy(ctype_encoding, encoding); +- } else { +- __mbrtowc = old__mbrtowc; +- __mbsinit = old__mbsinit; +- __mbsnrtowcs = old__mbsnrtowcs; +- __wcrtomb = old__wcrtomb; +- __wcsnrtombs = old__wcsnrtombs; +- free(rl); +- } + LOCK(cache_lock); + XL_RELEASE(CachedRuneLocale); + CachedRuneLocale = xrl; + XL_RETAIN(CachedRuneLocale); + UNLOCK(cache_lock); - } else -- free(rl); ++ } else + XL_RELEASE(xrl); return (ret); } -+#ifdef LEGACY_RUNE_APIS ++#ifdef UNIFDEF_LEGACY_RUNE_APIS int -__wrap_setrunelocale(const char *locale) +setrunelocale(const char *encoding) @@ -224,7 +237,7 @@ + XL_UNLOCK(&__global_locale); + return ret; +} -+#endif /* LEGACY_RUNE_APIS */ ++#endif /* UNIFDEF_LEGACY_RUNE_APIS */ + +__private_extern__ int +__wrap_setrunelocale(const char *locale, locale_t loc) diff --git a/locale/FreeBSD/table.c b/locale/FreeBSD/table.c index 84b5490..874f415 100644 --- a/locale/FreeBSD/table.c +++ b/locale/FreeBSD/table.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)table.c 8.1 (Berkeley) 6/27/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/table.c,v 1.26 2004/10/17 06:51:50 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/table.c,v 1.28 2007/01/09 00:28:00 imp Exp $"); #include #include @@ -251,13 +247,3 @@ _RuneLocale _DefaultRuneLocale = { _RuneLocale *_CurrentRuneLocale = &_DefaultRuneLocale; -int __mb_cur_max = 1; -size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict) = _none_mbrtowc; -int (*__mbsinit)(const mbstate_t *) = _none_mbsinit; -size_t (*__mbsnrtowcs)(wchar_t * __restrict, const char ** __restrict, - size_t, size_t, mbstate_t * __restrict) = _none_mbsnrtowcs; -size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict) = - _none_wcrtomb; -size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, - size_t, size_t, mbstate_t * __restrict) = _none_wcsnrtombs; diff --git a/locale/FreeBSD/table.c.patch b/locale/FreeBSD/table.c.patch index 81a3492..d7238e3 100644 --- a/locale/FreeBSD/table.c.patch +++ b/locale/FreeBSD/table.c.patch @@ -1,8 +1,8 @@ ---- table.c.orig 2004-11-25 11:38:19.000000000 -0800 -+++ table.c 2005-03-30 16:33:51.000000000 -0800 -@@ -40,13 +40,16 @@ +--- table.c.orig 2010-06-21 14:25:20.000000000 -0700 ++++ table.c 2010-06-21 14:25:34.000000000 -0700 +@@ -36,13 +36,16 @@ static char sccsid[] = "@(#)table.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/locale/table.c,v 1.26 2004/10/17 06:51:50 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/table.c,v 1.28 2007/01/09 00:28:00 imp Exp $"); +#include "xlocale_private.h" + @@ -11,23 +11,25 @@ #include #include "mblocal.h" -+/* _DefaultRuneLocale is depreciated; _DefaultRuneXLocale is used instead */ - _RuneLocale _DefaultRuneLocale = { +-_RuneLocale _DefaultRuneLocale = { - _RUNE_MAGIC_1, ++/* _DefaultRuneLocale is depreciated; _DefaultRuneXLocale is used instead */ ++_RuneLocale _DefaultRuneLocale __attribute__((section("__DATA,__constrw"))) = { + _RUNE_MAGIC_A, "NONE", NULL, NULL, -@@ -249,15 +252,222 @@ +@@ -245,5 +248,221 @@ _RuneLocale _DefaultRuneLocale = { }, }; -_RuneLocale *_CurrentRuneLocale = &_DefaultRuneLocale; -+__private_extern__ struct __xlocale_st_runelocale _DefaultRuneXLocale = { ++__private_extern__ struct __xlocale_st_runelocale _DefaultRuneXLocale __attribute__((section("__DATA,__constrw"))) = { + 0, + XPERMANENT, + "C", + 1, ++ 256, + _none_mbrtowc, + _none_mbsinit, + _none_mbsnrtowcs, @@ -238,16 +240,5 @@ + }, + }, +}; -+ -+_RuneLocale *_CurrentRuneLocale = &_DefaultRuneXLocale._CurrentRuneLocale; - int __mb_cur_max = 1; --size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t, -- mbstate_t * __restrict) = _none_mbrtowc; --int (*__mbsinit)(const mbstate_t *) = _none_mbsinit; --size_t (*__mbsnrtowcs)(wchar_t * __restrict, const char ** __restrict, -- size_t, size_t, mbstate_t * __restrict) = _none_mbsnrtowcs; --size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict) = -- _none_wcrtomb; --size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, -- size_t, size_t, mbstate_t * __restrict) = _none_wcsnrtombs; ++_RuneLocale *_CurrentRuneLocale = &_DefaultRuneXLocale._CurrentRuneLocale; diff --git a/locale/FreeBSD/toascii.3 b/locale/FreeBSD/toascii.3 index b1a2425..7c37d11 100644 --- a/locale/FreeBSD/toascii.3 +++ b/locale/FreeBSD/toascii.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)toascii.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/toascii.3,v 1.7 2002/01/09 13:43:31 nik Exp $ +.\" $FreeBSD: src/lib/libc/locale/toascii.3,v 1.10 2009/09/04 07:44:58 des Exp $ .\" .Dd June 4, 1993 .Dt TOASCII 3 diff --git a/locale/FreeBSD/tolower.3 b/locale/FreeBSD/tolower.3 index d3535c8..29515bb 100644 --- a/locale/FreeBSD/tolower.3 +++ b/locale/FreeBSD/tolower.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)tolower.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/tolower.3,v 1.16 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/tolower.3,v 1.21 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt TOLOWER 3 .Os .Sh NAME @@ -53,13 +49,8 @@ The .Fn tolower function converts an upper-case letter to the corresponding lower-case letter. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . .Sh RETURN VALUES @@ -80,7 +71,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr islower 3 , -.Xr multibyte 3 , .Xr towlower 3 .Sh STANDARDS The diff --git a/locale/FreeBSD/tolower.3.patch b/locale/FreeBSD/tolower.3.patch index 1e3b08c..b5cc733 100644 --- a/locale/FreeBSD/tolower.3.patch +++ b/locale/FreeBSD/tolower.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/tolower.3 2004-11-25 11:38:19.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/tolower.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -40,14 +40,24 @@ +--- tolower.3.bsdnew 2009-11-10 13:13:11.000000000 -0800 ++++ tolower.3 2009-11-10 13:51:11.000000000 -0800 +@@ -36,14 +36,24 @@ .Dt TOLOWER 3 .Os .Sh NAME @@ -27,15 +27,8 @@ .Sh DESCRIPTION The .Fn tolower -@@ -56,17 +66,25 @@ - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char +@@ -53,11 +63,19 @@ The argument must be representable as an + .Vt "unsigned char" or the value of .Dv EOF . +.Pp @@ -55,10 +48,10 @@ .Sh COMPATIBILITY The .Bx 4.4 -@@ -81,7 +99,8 @@ +@@ -71,7 +89,8 @@ function should be used instead. + .Sh SEE ALSO .Xr ctype 3 , .Xr islower 3 , - .Xr multibyte 3 , -.Xr towlower 3 +.Xr towlower 3 , +.Xr xlocale 3 diff --git a/locale/FreeBSD/tolower.c b/locale/FreeBSD/tolower.c index 24694e7..968cb5a 100644 --- a/locale/FreeBSD/tolower.c +++ b/locale/FreeBSD/tolower.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,8 +31,9 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/tolower.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/tolower.c,v 1.13 2007/01/09 00:28:01 imp Exp $"); +#include #include #include diff --git a/locale/FreeBSD/tolower.c.patch b/locale/FreeBSD/tolower.c.patch index c829c4d..b40e942 100644 --- a/locale/FreeBSD/tolower.c.patch +++ b/locale/FreeBSD/tolower.c.patch @@ -1,11 +1,13 @@ ---- tolower.c.orig 2004-11-25 11:38:19.000000000 -0800 -+++ tolower.c 2005-02-17 16:43:19.000000000 -0800 -@@ -37,20 +37,32 @@ - #include - __FBSDID("$FreeBSD: src/lib/libc/locale/tolower.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); +--- tolower.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ tolower.c 2009-11-09 17:31:29.000000000 -0800 +@@ -32,22 +32,34 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/locale/tolower.c,v 1.13 2007/01/09 00:28:01 imp Exp $"); ++ +#include "xlocale_private.h" -+ + + #include #include #include @@ -35,7 +37,7 @@ /* Binary search -- see bsearch.c for explanation. */ base = rr->__ranges; for (lim = rr->__nranges; lim != 0; lim >>= 1) { -@@ -65,3 +77,10 @@ +@@ -62,3 +74,10 @@ ___tolower(c) return(c); } diff --git a/locale/FreeBSD/toupper.3 b/locale/FreeBSD/toupper.3 index 64b6ac3..cf23d15 100644 --- a/locale/FreeBSD/toupper.3 +++ b/locale/FreeBSD/toupper.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)toupper.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/toupper.3,v 1.16 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/toupper.3,v 1.21 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt TOUPPER 3 .Os .Sh NAME @@ -53,13 +49,8 @@ The .Fn toupper function converts a lower-case letter to the corresponding upper-case letter. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . .Sh RETURN VALUES @@ -80,7 +71,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr isupper 3 , -.Xr multibyte 3 , .Xr towupper 3 .Sh STANDARDS The diff --git a/locale/FreeBSD/toupper.3.patch b/locale/FreeBSD/toupper.3.patch index d0d2531..c469626 100644 --- a/locale/FreeBSD/toupper.3.patch +++ b/locale/FreeBSD/toupper.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/toupper.3 2004-11-25 11:38:20.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/toupper.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -40,14 +40,24 @@ +--- toupper.3.bsdnew 2009-11-10 13:13:11.000000000 -0800 ++++ toupper.3 2009-11-10 13:52:49.000000000 -0800 +@@ -36,14 +36,24 @@ .Dt TOUPPER 3 .Os .Sh NAME @@ -27,15 +27,8 @@ .Sh DESCRIPTION The .Fn toupper -@@ -56,17 +66,25 @@ - For single C - .Va char Ns s - locales (see --.Xr multibyte 3 ) -+.Xr multibyte 3 ) , - the value of the argument is - representable as an - .Li unsigned char +@@ -53,11 +63,19 @@ The argument must be representable as an + .Vt "unsigned char" or the value of .Dv EOF . +.Pp @@ -55,10 +48,10 @@ .Sh COMPATIBILITY The .Bx 4.4 -@@ -81,7 +99,8 @@ +@@ -71,7 +89,8 @@ function should be used instead. + .Sh SEE ALSO .Xr ctype 3 , .Xr isupper 3 , - .Xr multibyte 3 , -.Xr towupper 3 +.Xr towupper 3 , +.Xr xlocale 3 diff --git a/locale/FreeBSD/toupper.c b/locale/FreeBSD/toupper.c index bb7f36a..e160b39 100644 --- a/locale/FreeBSD/toupper.c +++ b/locale/FreeBSD/toupper.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,8 +31,9 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/toupper.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/toupper.c,v 1.13 2007/01/09 00:28:01 imp Exp $"); +#include #include #include diff --git a/locale/FreeBSD/toupper.c.patch b/locale/FreeBSD/toupper.c.patch index e59a7d7..aea5ad9 100644 --- a/locale/FreeBSD/toupper.c.patch +++ b/locale/FreeBSD/toupper.c.patch @@ -1,11 +1,13 @@ ---- toupper.c.orig 2005-02-17 16:40:25.000000000 -0800 -+++ toupper.c 2005-02-17 16:42:30.000000000 -0800 -@@ -37,20 +37,32 @@ - #include - __FBSDID("$FreeBSD: src/lib/libc/locale/toupper.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); +--- toupper.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ toupper.c 2009-11-09 17:30:20.000000000 -0800 +@@ -32,22 +32,34 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/locale/toupper.c,v 1.13 2007/01/09 00:28:01 imp Exp $"); ++ +#include "xlocale_private.h" -+ + + #include #include #include @@ -35,7 +37,7 @@ /* Binary search -- see bsearch.c for explanation. */ base = rr->__ranges; for (lim = rr->__nranges; lim != 0; lim >>= 1) { -@@ -65,3 +77,10 @@ +@@ -62,3 +74,10 @@ ___toupper(c) return(c); } diff --git a/locale/FreeBSD/towlower.3 b/locale/FreeBSD/towlower.3 index 6bdd3c8..b6968b7 100644 --- a/locale/FreeBSD/towlower.3 +++ b/locale/FreeBSD/towlower.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)tolower.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/towlower.3,v 1.5 2002/11/29 17:35:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/towlower.3,v 1.6 2007/01/09 00:28:01 imp Exp $ .\" .Dd October 3, 2002 .Dt TOWLOWER 3 diff --git a/locale/FreeBSD/towlower.3.patch b/locale/FreeBSD/towlower.3.patch index dbb16e9..ecd8b5e 100644 --- a/locale/FreeBSD/towlower.3.patch +++ b/locale/FreeBSD/towlower.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/towlower.3 2003-05-20 15:21:44.000000000 -0700 -+++ _SB/Libc/locale/FreeBSD/towlower.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -40,29 +40,48 @@ +--- towlower.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ towlower.3 2009-11-09 15:05:26.000000000 -0800 +@@ -36,29 +36,48 @@ .Dt TOWLOWER 3 .Os .Sh NAME diff --git a/locale/FreeBSD/towupper.3 b/locale/FreeBSD/towupper.3 index c771998..1d3763b 100644 --- a/locale/FreeBSD/towupper.3 +++ b/locale/FreeBSD/towupper.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)toupper.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/towupper.3,v 1.2 2002/11/29 17:35:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/towupper.3,v 1.3 2007/01/09 00:28:01 imp Exp $ .\" .Dd October 3, 2002 .Dt TOWUPPER 3 diff --git a/locale/FreeBSD/towupper.3.patch b/locale/FreeBSD/towupper.3.patch index 8882d1a..77cbd8e 100644 --- a/locale/FreeBSD/towupper.3.patch +++ b/locale/FreeBSD/towupper.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/towupper.3 2003-05-20 15:21:44.000000000 -0700 -+++ _SB/Libc/locale/FreeBSD/towupper.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -40,29 +40,48 @@ +--- towupper.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ towupper.3 2009-11-09 15:05:26.000000000 -0800 +@@ -36,29 +36,48 @@ .Dt TOWUPPER 3 .Os .Sh NAME diff --git a/locale/FreeBSD/utf2.c.patch b/locale/FreeBSD/utf2.c.patch index dc4b7a0..ab2535e 100644 --- a/locale/FreeBSD/utf2.c.patch +++ b/locale/FreeBSD/utf2.c.patch @@ -1,39 +1,40 @@ ---- utf2.c.orig Fri Feb 18 15:49:55 2005 -+++ utf2.c Fri Feb 18 15:52:07 2005 -@@ -25,8 +25,11 @@ - */ - +--- utf2.c.bsdnew 2009-11-09 17:38:09.000000000 -0800 ++++ utf2.c 2009-11-09 17:41:17.000000000 -0800 +@@ -27,6 +27,8 @@ #include -+/* dumb down UTF-8 to do UTF2 */ - __FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.11 2004/07/27 06:29:48 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.16 2007/10/15 09:51:30 ache Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -35,54 +38,55 @@ +@@ -35,62 +37,61 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include #include "mblocal.h" --size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -- mbstate_t * __restrict); --int _UTF8_mbsinit(const mbstate_t *); --size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, -- size_t, size_t, mbstate_t * __restrict); --size_t _UTF8_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); --size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, -- size_t, size_t, mbstate_t * __restrict); +-extern int __mb_sb_limit; +#define UTF2_MB_CUR_MAX 3 -+ -+static size_t _UTF2_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -+ mbstate_t * __restrict, locale_t); + +-static size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, +- size_t, mbstate_t * __restrict); +-static int _UTF8_mbsinit(const mbstate_t *); +-static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, ++static size_t _UTF2_mbrtowc(wchar_t * __restrict, const char * __restrict, ++ size_t, mbstate_t * __restrict, locale_t); +static int _UTF2_mbsinit(const mbstate_t *, locale_t); -+static size_t _UTF2_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, -+ size_t, size_t, mbstate_t * __restrict, locale_t); -+static size_t _UTF2_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); ++static size_t _UTF2_mbsnrtowcs(wchar_t * __restrict, + const char ** __restrict, size_t, size_t, +- mbstate_t * __restrict); +-static size_t _UTF8_wcrtomb(char * __restrict, wchar_t, +- mbstate_t * __restrict); +-static size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, +- size_t, size_t, mbstate_t * __restrict); ++ mbstate_t * __restrict, locale_t); ++static size_t _UTF2_wcrtomb(char * __restrict, wchar_t, ++ mbstate_t * __restrict, locale_t); +static size_t _UTF2_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, -+ size_t, size_t, mbstate_t * __restrict, locale_t); ++ size_t, size_t, mbstate_t * __restrict, locale_t); typedef struct { wchar_t ch; @@ -61,13 +62,19 @@ + xrl->__mbsnrtowcs = _UTF2_mbsnrtowcs; + xrl->__wcsnrtombs = _UTF2_wcsnrtombs; + xrl->__mb_cur_max = UTF2_MB_CUR_MAX; + /* + * UCS-4 encoding used as the internal representation, so + * slots 0x0080-0x00FF are occuped and must be excluded + * from the single byte ctype by setting the limit. + */ +- __mb_sb_limit = 128; ++ xrl->__mb_sb_limit = 128; return (0); } --int + static int -_UTF8_mbsinit(const mbstate_t *ps) -+static int +_UTF2_mbsinit(const mbstate_t *ps, locale_t loc) { @@ -75,10 +82,9 @@ + return (ps == NULL || ((const _UTF2State *)ps)->want == 0); } --size_t + static size_t -_UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps) -+static size_t +_UTF2_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t loc) { @@ -90,12 +96,9 @@ - us = (_UTF8State *)ps; + us = (_UTF2State *)ps; -- if (us->want < 0 || us->want > 6) { -+ if (us->want < 0 || us->want > 3) { + if (us->want < 0 || us->want > 6) { errno = EINVAL; - return ((size_t)-1); - } -@@ -130,21 +134,9 @@ +@@ -140,21 +141,9 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, mask = 0x0f; want = 3; lbound = 0x800; @@ -107,7 +110,7 @@ - mask = 0x03; - want = 5; - lbound = 0x200000; -- } else if ((ch & 0xfc) == 0xfc) { +- } else if ((ch & 0xfe) == 0xfc) { - mask = 0x01; - want = 6; - lbound = 0x4000000; @@ -118,14 +121,12 @@ */ errno = EILSEQ; return ((size_t)-1); -@@ -194,17 +186,17 @@ - return (wch == L'\0' ? 0 : want); +@@ -205,16 +194,16 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, } --size_t + static size_t -_UTF8_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, - size_t nms, size_t len, mbstate_t * __restrict ps) -+static size_t +_UTF2_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc) { @@ -141,7 +142,7 @@ s = *src; nchr = 0; -@@ -226,7 +218,7 @@ +@@ -236,7 +225,7 @@ _UTF8_mbsnrtowcs(wchar_t * __restrict ds * excluding NUL. */ nb = 1; @@ -150,7 +151,7 @@ (size_t)-1) /* Invalid sequence - mbrtowc() sets errno. */ return ((size_t)-1); -@@ -256,7 +248,7 @@ +@@ -266,7 +255,7 @@ _UTF8_mbsnrtowcs(wchar_t * __restrict ds */ *dst = (wchar_t)*s; nb = 1; @@ -159,13 +160,11 @@ (size_t)-1) { *src = s; return ((size_t)-1); -@@ -276,14 +268,14 @@ - return (nchr); +@@ -287,13 +276,13 @@ _UTF8_mbsnrtowcs(wchar_t * __restrict ds } --size_t + static size_t -_UTF8_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) -+static size_t +_UTF2_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) { - _UTF8State *us; @@ -178,7 +177,7 @@ if (us->want != 0) { errno = EINVAL; -@@ -315,15 +307,6 @@ +@@ -325,15 +314,6 @@ _UTF8_wcrtomb(char * __restrict s, wchar } else if ((wc & ~0xffff) == 0) { lead = 0xe0; len = 3; @@ -194,14 +193,12 @@ } else { errno = EILSEQ; return ((size_t)-1); -@@ -344,17 +327,17 @@ - return (len); +@@ -355,16 +335,16 @@ _UTF8_wcrtomb(char * __restrict s, wchar } --size_t + static size_t -_UTF8_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, - size_t nwc, size_t len, mbstate_t * __restrict ps) -+static size_t +_UTF2_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, + size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc) { @@ -217,7 +214,7 @@ if (us->want != 0) { errno = EINVAL; -@@ -369,7 +352,7 @@ +@@ -379,7 +359,7 @@ _UTF8_wcsnrtombs(char * __restrict dst, if (0 <= *s && *s < 0x80) /* Fast path for plain ASCII characters. */ nb = 1; @@ -226,24 +223,24 @@ (size_t)-1) /* Invalid character - wcrtomb() sets errno. */ return ((size_t)-1); -@@ -386,9 +369,9 @@ +@@ -396,9 +376,9 @@ _UTF8_wcsnrtombs(char * __restrict dst, /* Fast path for plain ASCII characters. */ nb = 1; *dst = *s; - } else if (len > (size_t)MB_CUR_MAX) { + } else if (len > (size_t)UTF2_MB_CUR_MAX) { /* Enough space to translate in-place. */ -- if ((nb = (int)_UTF8_wcrtomb(dst, *s, ps)) < 0) { -+ if ((nb = (int)_UTF2_wcrtomb(dst, *s, ps, loc)) < 0) { +- if ((nb = _UTF8_wcrtomb(dst, *s, ps)) == (size_t)-1) { ++ if ((nb = _UTF2_wcrtomb(dst, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } -@@ -396,7 +379,7 @@ +@@ -406,7 +386,7 @@ _UTF8_wcsnrtombs(char * __restrict dst, /* * May not be enough space; use temp. buffer. */ -- if ((nb = (int)_UTF8_wcrtomb(buf, *s, ps)) < 0) { -+ if ((nb = (int)_UTF2_wcrtomb(buf, *s, ps, loc)) < 0) { +- if ((nb = _UTF8_wcrtomb(buf, *s, ps)) == (size_t)-1) { ++ if ((nb = _UTF2_wcrtomb(buf, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } diff --git a/locale/FreeBSD/utf8.5 b/locale/FreeBSD/utf8.5 index e89f5e5..e5c3b61 100644 --- a/locale/FreeBSD/utf8.5 +++ b/locale/FreeBSD/utf8.5 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)utf2.4 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/utf8.5,v 1.6 2004/10/17 02:29:15 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/utf8.5,v 1.7 2007/01/09 00:28:01 imp Exp $ .\" .Dd April 7, 2004 .Dt UTF8 5 diff --git a/locale/FreeBSD/utf8.c b/locale/FreeBSD/utf8.c index 26f89f7..9a9ffa9 100644 --- a/locale/FreeBSD/utf8.c +++ b/locale/FreeBSD/utf8.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.11 2004/07/27 06:29:48 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.16 2007/10/15 09:51:30 ache Exp $"); #include #include @@ -35,14 +35,18 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.11 2004/07/27 06:29:48 tjr Ex #include #include "mblocal.h" -size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict); -int _UTF8_mbsinit(const mbstate_t *); -size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, - size_t, size_t, mbstate_t * __restrict); -size_t _UTF8_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); -size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, - size_t, size_t, mbstate_t * __restrict); +extern int __mb_sb_limit; + +static size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _UTF8_mbsinit(const mbstate_t *); +static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, + const char ** __restrict, size_t, size_t, + mbstate_t * __restrict); +static size_t _UTF8_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); +static size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict); typedef struct { wchar_t ch; @@ -61,18 +65,24 @@ _UTF8_init(_RuneLocale *rl) __wcsnrtombs = _UTF8_wcsnrtombs; _CurrentRuneLocale = rl; __mb_cur_max = 6; + /* + * UCS-4 encoding used as the internal representation, so + * slots 0x0080-0x00FF are occuped and must be excluded + * from the single byte ctype by setting the limit. + */ + __mb_sb_limit = 128; return (0); } -int +static int _UTF8_mbsinit(const mbstate_t *ps) { return (ps == NULL || ((const _UTF8State *)ps)->want == 0); } -size_t +static size_t _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { @@ -138,7 +148,7 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mask = 0x03; want = 5; lbound = 0x200000; - } else if ((ch & 0xfc) == 0xfc) { + } else if ((ch & 0xfe) == 0xfc) { mask = 0x01; want = 6; lbound = 0x4000000; @@ -194,7 +204,7 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, return (wch == L'\0' ? 0 : want); } -size_t +static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { @@ -276,7 +286,7 @@ _UTF8_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, return (nchr); } -size_t +static size_t _UTF8_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _UTF8State *us; @@ -344,7 +354,7 @@ _UTF8_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) return (len); } -size_t +static size_t _UTF8_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { @@ -388,7 +398,7 @@ _UTF8_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, *dst = *s; } else if (len > (size_t)MB_CUR_MAX) { /* Enough space to translate in-place. */ - if ((nb = (int)_UTF8_wcrtomb(dst, *s, ps)) < 0) { + if ((nb = _UTF8_wcrtomb(dst, *s, ps)) == (size_t)-1) { *src = s; return ((size_t)-1); } @@ -396,7 +406,7 @@ _UTF8_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, /* * May not be enough space; use temp. buffer. */ - if ((nb = (int)_UTF8_wcrtomb(buf, *s, ps)) < 0) { + if ((nb = _UTF8_wcrtomb(buf, *s, ps)) == (size_t)-1) { *src = s; return ((size_t)-1); } diff --git a/locale/FreeBSD/utf8.c.patch b/locale/FreeBSD/utf8.c.patch index 2aa8c40..9427108 100644 --- a/locale/FreeBSD/utf8.c.patch +++ b/locale/FreeBSD/utf8.c.patch @@ -1,40 +1,40 @@ ---- utf8.c.orig Thu Nov 25 11:38:20 2004 -+++ utf8.c Fri Feb 18 15:40:44 2005 +--- utf8.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ utf8.c 2009-11-09 17:35:23.000000000 -0800 @@ -27,6 +27,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.11 2004/07/27 06:29:48 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.16 2007/10/15 09:51:30 ache Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -35,14 +37,16 @@ +@@ -35,18 +37,18 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include #include "mblocal.h" --size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -- mbstate_t * __restrict); --int _UTF8_mbsinit(const mbstate_t *); --size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, -- size_t, size_t, mbstate_t * __restrict); --size_t _UTF8_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); --size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, -- size_t, size_t, mbstate_t * __restrict); +-extern int __mb_sb_limit; +#define UTF8_MB_CUR_MAX 6 -+ -+static size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, -+ mbstate_t * __restrict, locale_t); + + static size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, +- size_t, mbstate_t * __restrict); +-static int _UTF8_mbsinit(const mbstate_t *); ++ size_t, mbstate_t * __restrict, locale_t); +static int _UTF8_mbsinit(const mbstate_t *, locale_t); -+static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, -+ size_t, size_t, mbstate_t * __restrict, locale_t); -+static size_t _UTF8_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); -+static size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, -+ size_t, size_t, mbstate_t * __restrict, locale_t); + static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, + const char ** __restrict, size_t, size_t, +- mbstate_t * __restrict); ++ mbstate_t * __restrict, locale_t); + static size_t _UTF8_wcrtomb(char * __restrict, wchar_t, +- mbstate_t * __restrict); ++ mbstate_t * __restrict, locale_t); + static size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, +- size_t, size_t, mbstate_t * __restrict); ++ size_t, size_t, mbstate_t * __restrict, locale_t); typedef struct { wchar_t ch; -@@ -50,31 +54,30 @@ +@@ -54,29 +56,28 @@ typedef struct { wchar_t lbound; } _UTF8State; @@ -57,40 +57,42 @@ + xrl->__mbsnrtowcs = _UTF8_mbsnrtowcs; + xrl->__wcsnrtombs = _UTF8_wcsnrtombs; + xrl->__mb_cur_max = UTF8_MB_CUR_MAX; + /* + * UCS-4 encoding used as the internal representation, so + * slots 0x0080-0x00FF are occuped and must be excluded + * from the single byte ctype by setting the limit. + */ +- __mb_sb_limit = 128; ++ xrl->__mb_sb_limit = 128; return (0); } --int + static int -_UTF8_mbsinit(const mbstate_t *ps) -+static int +_UTF8_mbsinit(const mbstate_t *ps, locale_t loc) { return (ps == NULL || ((const _UTF8State *)ps)->want == 0); - } +@@ -84,7 +85,7 @@ _UTF8_mbsinit(const mbstate_t *ps) --size_t -+static size_t + static size_t _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps) + mbstate_t * __restrict ps, locale_t loc) { _UTF8State *us; int ch, i, mask, want; -@@ -194,9 +197,9 @@ - return (wch == L'\0' ? 0 : want); - } +@@ -206,7 +207,7 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, --size_t -+static size_t + static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, - size_t nms, size_t len, mbstate_t * __restrict ps) + size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc) { _UTF8State *us; const char *s; -@@ -226,7 +229,7 @@ +@@ -236,7 +237,7 @@ _UTF8_mbsnrtowcs(wchar_t * __restrict ds * excluding NUL. */ nb = 1; @@ -99,7 +101,7 @@ (size_t)-1) /* Invalid sequence - mbrtowc() sets errno. */ return ((size_t)-1); -@@ -256,7 +259,7 @@ +@@ -266,7 +267,7 @@ _UTF8_mbsnrtowcs(wchar_t * __restrict ds */ *dst = (wchar_t)*s; nb = 1; @@ -108,30 +110,25 @@ (size_t)-1) { *src = s; return ((size_t)-1); -@@ -276,8 +279,8 @@ - return (nchr); +@@ -287,7 +288,7 @@ _UTF8_mbsnrtowcs(wchar_t * __restrict ds } --size_t + static size_t -_UTF8_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) -+static size_t +_UTF8_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) { _UTF8State *us; unsigned char lead; -@@ -344,9 +347,9 @@ - return (len); - } +@@ -356,7 +357,7 @@ _UTF8_wcrtomb(char * __restrict s, wchar --size_t -+static size_t + static size_t _UTF8_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, - size_t nwc, size_t len, mbstate_t * __restrict ps) + size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc) { _UTF8State *us; char buf[MB_LEN_MAX]; -@@ -369,7 +372,7 @@ +@@ -379,7 +380,7 @@ _UTF8_wcsnrtombs(char * __restrict dst, if (0 <= *s && *s < 0x80) /* Fast path for plain ASCII characters. */ nb = 1; @@ -140,24 +137,24 @@ (size_t)-1) /* Invalid character - wcrtomb() sets errno. */ return ((size_t)-1); -@@ -386,9 +389,9 @@ +@@ -396,9 +397,9 @@ _UTF8_wcsnrtombs(char * __restrict dst, /* Fast path for plain ASCII characters. */ nb = 1; *dst = *s; - } else if (len > (size_t)MB_CUR_MAX) { + } else if (len > (size_t)UTF8_MB_CUR_MAX) { /* Enough space to translate in-place. */ -- if ((nb = (int)_UTF8_wcrtomb(dst, *s, ps)) < 0) { -+ if ((nb = (int)_UTF8_wcrtomb(dst, *s, ps, loc)) < 0) { +- if ((nb = _UTF8_wcrtomb(dst, *s, ps)) == (size_t)-1) { ++ if ((nb = _UTF8_wcrtomb(dst, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } -@@ -396,7 +399,7 @@ +@@ -406,7 +407,7 @@ _UTF8_wcsnrtombs(char * __restrict dst, /* * May not be enough space; use temp. buffer. */ -- if ((nb = (int)_UTF8_wcrtomb(buf, *s, ps)) < 0) { -+ if ((nb = (int)_UTF8_wcrtomb(buf, *s, ps, loc)) < 0) { +- if ((nb = _UTF8_wcrtomb(buf, *s, ps)) == (size_t)-1) { ++ if ((nb = _UTF8_wcrtomb(buf, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } diff --git a/locale/FreeBSD/wcrtomb.3.patch b/locale/FreeBSD/wcrtomb.3.patch index af52731..9042c9e 100644 --- a/locale/FreeBSD/wcrtomb.3.patch +++ b/locale/FreeBSD/wcrtomb.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/wcrtomb.3 2004-11-25 11:38:20.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/wcrtomb.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- wcrtomb.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcrtomb.3 2009-11-09 15:05:26.000000000 -0800 @@ -28,14 +28,28 @@ .Dt WCRTOMB 3 .Os @@ -31,7 +31,7 @@ .Sh DESCRIPTION The .Fn wcrtomb -@@ -44,10 +58,10 @@ +@@ -44,10 +58,10 @@ wide character .Fa wc , including any necessary shift sequences, to the character array @@ -45,7 +45,7 @@ .Pp If .Fa s -@@ -58,7 +72,7 @@ +@@ -58,7 +72,7 @@ behaves as if .Fa s pointed to an internal buffer and .Fa wc @@ -54,7 +54,7 @@ .Pp The .Ft mbstate_t -@@ -72,6 +86,14 @@ +@@ -72,6 +86,14 @@ uses an internal, static .Vt mbstate_t object, which is initialized to the initial conversion state at program startup. @@ -69,7 +69,7 @@ .Sh RETURN VALUES The .Fn wcrtomb -@@ -97,7 +119,8 @@ +@@ -97,7 +119,8 @@ The conversion state is invalid. .Xr mbrtowc 3 , .Xr multibyte 3 , .Xr setlocale 3 , diff --git a/locale/FreeBSD/wcrtomb.c.patch b/locale/FreeBSD/wcrtomb.c.patch index 365a10f..0de3d6d 100644 --- a/locale/FreeBSD/wcrtomb.c.patch +++ b/locale/FreeBSD/wcrtomb.c.patch @@ -1,5 +1,5 @@ ---- wcrtomb.c.orig 2004-11-25 11:38:20.000000000 -0800 -+++ wcrtomb.c 2005-02-18 18:30:14.000000000 -0800 +--- wcrtomb.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcrtomb.c 2009-11-09 15:05:26.000000000 -0800 @@ -27,15 +27,23 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wcrtomb.c,v 1.8 2004/05/12 14:09:04 tjr Exp $"); diff --git a/locale/FreeBSD/wcsftime.3.patch b/locale/FreeBSD/wcsftime.3.patch index 76b959d..7a7d808 100644 --- a/locale/FreeBSD/wcsftime.3.patch +++ b/locale/FreeBSD/wcsftime.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/wcsftime.3 2003-05-20 15:21:44.000000000 -0700 -+++ _SB/Libc/locale/FreeBSD/wcsftime.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- wcsftime.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcsftime.3 2009-11-09 15:05:26.000000000 -0800 @@ -28,7 +28,8 @@ .Dt WCSFTIME 3 .Os diff --git a/locale/FreeBSD/wcsftime.c b/locale/FreeBSD/wcsftime.c index 2598043..40f3c6c 100644 --- a/locale/FreeBSD/wcsftime.c +++ b/locale/FreeBSD/wcsftime.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcsftime.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcsftime.c,v 1.6 2009/01/15 20:45:59 rdivacky Exp $"); #include #include @@ -52,7 +52,9 @@ wcsftime(wchar_t * __restrict wcs, size_t maxsize, { static const mbstate_t initial; mbstate_t mbs; - char *dst, *dstp, *sformat; + char *dst, *sformat; + const char *dstp; + const wchar_t *formatp; size_t n, sflen; int sverrno; @@ -63,13 +65,14 @@ wcsftime(wchar_t * __restrict wcs, size_t maxsize, * for strftime(), which only handles single-byte characters. */ mbs = initial; - sflen = wcsrtombs(NULL, &format, 0, &mbs); + formatp = format; + sflen = wcsrtombs(NULL, &formatp, 0, &mbs); if (sflen == (size_t)-1) goto error; if ((sformat = malloc(sflen + 1)) == NULL) goto error; mbs = initial; - wcsrtombs(sformat, &format, sflen + 1, &mbs); + wcsrtombs(sformat, &formatp, sflen + 1, &mbs); /* * Allocate memory for longest multibyte sequence that will fit @@ -88,7 +91,7 @@ wcsftime(wchar_t * __restrict wcs, size_t maxsize, goto error; dstp = dst; mbs = initial; - n = mbsrtowcs(wcs, (const char **)&dstp, maxsize, &mbs); + n = mbsrtowcs(wcs, &dstp, maxsize, &mbs); if (n == (size_t)-2 || n == (size_t)-1 || dstp != NULL) goto error; diff --git a/locale/FreeBSD/wcsftime.c.patch b/locale/FreeBSD/wcsftime.c.patch index 72fdc6b..02c81ea 100644 --- a/locale/FreeBSD/wcsftime.c.patch +++ b/locale/FreeBSD/wcsftime.c.patch @@ -1,15 +1,15 @@ ---- wcsftime.c.orig 2004-11-25 11:38:20.000000000 -0800 -+++ wcsftime.c 2005-02-24 00:53:36.000000000 -0800 +--- wcsftime.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ wcsftime.c 2009-11-09 17:45:28.000000000 -0800 @@ -27,6 +27,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/wcsftime.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wcsftime.c,v 1.6 2009/01/15 20:45:59 rdivacky Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -47,8 +49,9 @@ +@@ -47,8 +49,9 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ * format specifications in the format string. */ size_t @@ -21,7 +21,7 @@ { static const mbstate_t initial; mbstate_t mbs; -@@ -56,6 +59,7 @@ +@@ -58,6 +61,7 @@ wcsftime(wchar_t * __restrict wcs, size_ size_t n, sflen; int sverrno; @@ -29,23 +29,23 @@ sformat = dst = NULL; /* -@@ -63,13 +67,13 @@ - * for strftime(), which only handles single-byte characters. +@@ -66,13 +70,13 @@ wcsftime(wchar_t * __restrict wcs, size_ */ mbs = initial; -- sflen = wcsrtombs(NULL, &format, 0, &mbs); -+ sflen = wcsrtombs_l(NULL, &format, 0, &mbs, loc); + formatp = format; +- sflen = wcsrtombs(NULL, &formatp, 0, &mbs); ++ sflen = wcsrtombs_l(NULL, &formatp, 0, &mbs, loc); if (sflen == (size_t)-1) goto error; if ((sformat = malloc(sflen + 1)) == NULL) goto error; mbs = initial; -- wcsrtombs(sformat, &format, sflen + 1, &mbs); -+ wcsrtombs_l(sformat, &format, sflen + 1, &mbs, loc); +- wcsrtombs(sformat, &formatp, sflen + 1, &mbs); ++ wcsrtombs_l(sformat, &formatp, sflen + 1, &mbs, loc); /* * Allocate memory for longest multibyte sequence that will fit -@@ -77,18 +81,18 @@ +@@ -80,18 +84,18 @@ wcsftime(wchar_t * __restrict wcs, size_ * Then, copy and convert the result back into wide characters in * the caller's buffer. */ @@ -63,12 +63,12 @@ goto error; dstp = dst; mbs = initial; -- n = mbsrtowcs(wcs, (const char **)&dstp, maxsize, &mbs); -+ n = mbsrtowcs_l(wcs, (const char **)&dstp, maxsize, &mbs, loc); +- n = mbsrtowcs(wcs, &dstp, maxsize, &mbs); ++ n = mbsrtowcs_l(wcs, &dstp, maxsize, &mbs, loc); if (n == (size_t)-2 || n == (size_t)-1 || dstp != NULL) goto error; -@@ -103,3 +107,10 @@ +@@ -106,3 +110,10 @@ error: errno = sverrno; return (0); } diff --git a/locale/FreeBSD/wcsnrtombs.c b/locale/FreeBSD/wcsnrtombs.c index 6de6ff9..89cd9b7 100644 --- a/locale/FreeBSD/wcsnrtombs.c +++ b/locale/FreeBSD/wcsnrtombs.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcsnrtombs.c,v 1.2 2004/07/22 02:57:29 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcsnrtombs.c,v 1.3 2005/02/12 08:45:12 stefanf Exp $"); #include #include @@ -73,7 +73,7 @@ __wcsnrtombs_std(char * __restrict dst, const wchar_t ** __restrict src, while (len > 0 && nwc-- > 0) { if (len > (size_t)MB_CUR_MAX) { /* Enough space to translate in-place. */ - if ((nb = (int)__wcrtomb(dst, *s, ps)) < 0) { + if ((nb = __wcrtomb(dst, *s, ps)) == (size_t)-1) { *src = s; return ((size_t)-1); } @@ -86,7 +86,7 @@ __wcsnrtombs_std(char * __restrict dst, const wchar_t ** __restrict src, * character is too long for the buffer. */ mbsbak = *ps; - if ((nb = (int)__wcrtomb(buf, *s, ps)) < 0) { + if ((nb = __wcrtomb(buf, *s, ps)) == (size_t)-1) { *src = s; return ((size_t)-1); } diff --git a/locale/FreeBSD/wcsnrtombs.c.patch b/locale/FreeBSD/wcsnrtombs.c.patch index dc39a61..e4ba34b 100644 --- a/locale/FreeBSD/wcsnrtombs.c.patch +++ b/locale/FreeBSD/wcsnrtombs.c.patch @@ -1,15 +1,15 @@ ---- wcsnrtombs.c.orig 2004-11-25 11:38:20.000000000 -0800 -+++ wcsnrtombs.c 2005-02-18 18:38:25.000000000 -0800 +--- wcsnrtombs.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ wcsnrtombs.c 2009-11-09 17:47:14.000000000 -0800 @@ -27,6 +27,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/wcsnrtombs.c,v 1.2 2004/07/22 02:57:29 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wcsnrtombs.c,v 1.3 2005/02/12 08:45:12 stefanf Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -34,32 +36,41 @@ +@@ -34,32 +36,41 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include "mblocal.h" size_t @@ -59,24 +59,24 @@ /* Invalid character - wcrtomb() sets errno. */ return ((size_t)-1); else if (*s == L'\0') -@@ -71,9 +82,9 @@ +@@ -71,9 +82,9 @@ __wcsnrtombs_std(char * __restrict dst, } while (len > 0 && nwc-- > 0) { - if (len > (size_t)MB_CUR_MAX) { + if (len > (size_t)mb_cur_max) { /* Enough space to translate in-place. */ -- if ((nb = (int)__wcrtomb(dst, *s, ps)) < 0) { -+ if ((nb = (int)__wcrtomb(dst, *s, ps, loc)) < 0) { +- if ((nb = __wcrtomb(dst, *s, ps)) == (size_t)-1) { ++ if ((nb = __wcrtomb(dst, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } -@@ -86,7 +97,7 @@ +@@ -86,7 +97,7 @@ __wcsnrtombs_std(char * __restrict dst, * character is too long for the buffer. */ mbsbak = *ps; -- if ((nb = (int)__wcrtomb(buf, *s, ps)) < 0) { -+ if ((nb = (int)__wcrtomb(buf, *s, ps, loc)) < 0) { +- if ((nb = __wcrtomb(buf, *s, ps)) == (size_t)-1) { ++ if ((nb = __wcrtomb(buf, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } diff --git a/locale/FreeBSD/wcsrtombs.3.patch b/locale/FreeBSD/wcsrtombs.3.patch index 09fbb4b..6cd7335 100644 --- a/locale/FreeBSD/wcsrtombs.3.patch +++ b/locale/FreeBSD/wcsrtombs.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/wcsrtombs.3 2004-11-25 11:38:20.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/wcsrtombs.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- wcsrtombs.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcsrtombs.3 2009-11-09 15:05:26.000000000 -0800 @@ -28,30 +28,57 @@ .Dt WCSRTOMBS 3 .Os @@ -68,7 +68,7 @@ .Fa dst . No more than .Fa len -@@ -97,15 +124,28 @@ +@@ -97,15 +124,28 @@ except that conversion stops after readi .Fa nwc characters from the buffer pointed to by .Fa src . @@ -99,7 +99,7 @@ .Po Vt size_t Pc Ns \-1 . .Sh ERRORS The -@@ -122,7 +162,8 @@ +@@ -122,7 +162,8 @@ The conversion state is invalid. .Sh SEE ALSO .Xr mbsrtowcs 3 , .Xr wcrtomb 3 , diff --git a/locale/FreeBSD/wcsrtombs.c.patch b/locale/FreeBSD/wcsrtombs.c.patch index 03a28ec..ff0e290 100644 --- a/locale/FreeBSD/wcsrtombs.c.patch +++ b/locale/FreeBSD/wcsrtombs.c.patch @@ -1,5 +1,5 @@ ---- wcsrtombs.c.orig 2004-11-25 11:38:20.000000000 -0800 -+++ wcsrtombs.c 2005-02-18 18:36:45.000000000 -0800 +--- wcsrtombs.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcsrtombs.c 2009-11-09 15:05:26.000000000 -0800 @@ -27,6 +27,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wcsrtombs.c,v 1.6 2004/07/21 10:54:57 tjr Exp $"); @@ -9,7 +9,7 @@ #include #include #include -@@ -34,12 +36,18 @@ +@@ -34,12 +36,18 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ #include "mblocal.h" size_t diff --git a/locale/FreeBSD/wcstod.3.patch b/locale/FreeBSD/wcstod.3.patch index 9be640f..2b7bdca 100644 --- a/locale/FreeBSD/wcstod.3.patch +++ b/locale/FreeBSD/wcstod.3.patch @@ -1,5 +1,5 @@ ---- wcstod.3 2004-11-25 11:38:20.000000000 -0800 -+++ wcstod.3.edit 2006-08-09 13:29:59.000000000 -0700 +--- wcstod.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstod.3 2009-11-09 15:05:26.000000000 -0800 @@ -28,40 +28,57 @@ .Dt WCSTOD 3 .Os diff --git a/locale/FreeBSD/wcstod.c.patch b/locale/FreeBSD/wcstod.c.patch index 5082777..9cab53b 100644 --- a/locale/FreeBSD/wcstod.c.patch +++ b/locale/FreeBSD/wcstod.c.patch @@ -1,5 +1,5 @@ ---- wcstod.c.orig 2008-10-09 11:50:53.000000000 -0700 -+++ wcstod.c 2008-10-29 00:50:24.000000000 -0700 +--- wcstod.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstod.c 2009-11-09 15:05:26.000000000 -0800 @@ -27,9 +27,31 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wcstod.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); diff --git a/locale/FreeBSD/wcstof.c.patch b/locale/FreeBSD/wcstof.c.patch index ffc6ef6..5ed6b1d 100644 --- a/locale/FreeBSD/wcstof.c.patch +++ b/locale/FreeBSD/wcstof.c.patch @@ -1,5 +1,5 @@ ---- wcstof.c.orig 2008-10-09 11:50:52.000000000 -0700 -+++ wcstof.c 2008-10-29 00:51:43.000000000 -0700 +--- wcstof.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstof.c 2009-11-09 15:05:26.000000000 -0800 @@ -27,44 +27,67 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wcstof.c,v 1.3 2004/04/07 09:47:56 tjr Exp $"); diff --git a/locale/FreeBSD/wcstoimax.c b/locale/FreeBSD/wcstoimax.c index 09e7817..53d52a9 100644 --- a/locale/FreeBSD/wcstoimax.c +++ b/locale/FreeBSD/wcstoimax.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "from @(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoimax.c,v 1.8 2002/09/06 11:23:59 tjr Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoimax.c,v 1.2 2003/01/01 18:48:43 schweikh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoimax.c,v 1.3 2007/01/09 00:28:01 imp Exp $"); #include #include diff --git a/locale/FreeBSD/wcstoimax.c.patch b/locale/FreeBSD/wcstoimax.c.patch index f89ef5e..d904bca 100644 --- a/locale/FreeBSD/wcstoimax.c.patch +++ b/locale/FreeBSD/wcstoimax.c.patch @@ -1,15 +1,15 @@ ---- wcstoimax.c.orig 2003-05-20 15:21:45.000000000 -0700 -+++ wcstoimax.c 2005-02-23 16:06:32.000000000 -0800 -@@ -40,6 +40,8 @@ +--- wcstoimax.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstoimax.c 2009-11-09 15:05:26.000000000 -0800 +@@ -36,6 +36,8 @@ __FBSDID("FreeBSD: src/lib/libc/stdlib/s #endif - __FBSDID("$FreeBSD: src/lib/libc/locale/wcstoimax.c,v 1.2 2003/01/01 18:48:43 schweikh Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wcstoimax.c,v 1.3 2007/01/09 00:28:01 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -50,8 +52,8 @@ +@@ -46,8 +48,8 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ * Convert a wide character string to an intmax_t integer. */ intmax_t @@ -20,7 +20,7 @@ { const wchar_t *s; uintmax_t acc; -@@ -59,13 +61,14 @@ +@@ -55,13 +57,14 @@ wcstoimax(const wchar_t * __restrict npt uintmax_t cutoff; int neg, any, cutlim; @@ -36,7 +36,7 @@ if (c == L'-') { neg = 1; c = *s++; -@@ -92,8 +95,8 @@ +@@ -88,8 +91,8 @@ wcstoimax(const wchar_t * __restrict npt cutoff /= base; for ( ; ; c = *s++) { #ifdef notyet @@ -47,7 +47,7 @@ else #endif if (c >= L'0' && c <= L'9') -@@ -126,3 +129,10 @@ +@@ -122,3 +125,10 @@ noconv: *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); } diff --git a/locale/FreeBSD/wcstol.3.patch b/locale/FreeBSD/wcstol.3.patch index b1607bd..2bd8b79 100644 --- a/locale/FreeBSD/wcstol.3.patch +++ b/locale/FreeBSD/wcstol.3.patch @@ -1,5 +1,5 @@ ---- wcstol.3 2003-05-20 15:21:45.000000000 -0700 -+++ wcstol.3.edit 2006-07-12 11:29:16.000000000 -0700 +--- wcstol.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstol.3 2009-11-09 15:05:26.000000000 -0800 @@ -28,15 +28,18 @@ .Dt WCSTOL 3 .Os @@ -24,7 +24,7 @@ or .Vt uintmax_t integer -@@ -45,25 +48,50 @@ +@@ -45,25 +48,50 @@ integer .Sh SYNOPSIS .In wchar.h .Ft long @@ -83,7 +83,7 @@ and .Fn wcstoumax functions are wide-character versions of the -@@ -71,23 +99,42 @@ +@@ -71,23 +99,42 @@ functions are wide-character versions of .Fn strtoul , .Fn strtoll , .Fn strtoull , diff --git a/locale/FreeBSD/wcstol.c b/locale/FreeBSD/wcstol.c index ae51c2e..7c2afbd 100644 --- a/locale/FreeBSD/wcstol.c +++ b/locale/FreeBSD/wcstol.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -32,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstol.c,v 1.1 2002/09/08 13:27:26 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstol.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); #include #include diff --git a/locale/FreeBSD/wcstol.c.patch b/locale/FreeBSD/wcstol.c.patch index 2a3c6be..57ca1e1 100644 --- a/locale/FreeBSD/wcstol.c.patch +++ b/locale/FreeBSD/wcstol.c.patch @@ -1,15 +1,15 @@ ---- wcstol.c.orig Tue May 20 15:21:45 2003 -+++ wcstol.c Fri Feb 18 14:50:27 2005 -@@ -34,6 +34,8 @@ +--- wcstol.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstol.c 2009-11-09 15:05:26.000000000 -0800 +@@ -30,6 +30,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/wcstol.c,v 1.1 2002/09/08 13:27:26 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wcstol.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -44,7 +46,8 @@ +@@ -40,7 +42,8 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ * Convert a string to a long integer. */ long @@ -19,7 +19,7 @@ { const wchar_t *s; unsigned long acc; -@@ -52,13 +55,14 @@ +@@ -48,13 +51,14 @@ wcstol(const wchar_t * __restrict nptr, unsigned long cutoff; int neg, any, cutlim; @@ -35,7 +35,7 @@ if (c == '-') { neg = 1; c = *s++; -@@ -85,8 +89,8 @@ +@@ -81,8 +85,8 @@ wcstol(const wchar_t * __restrict nptr, cutoff /= base; for ( ; ; c = *s++) { #ifdef notyet @@ -46,14 +46,13 @@ else #endif if (c >= L'0' && c <= L'9') -@@ -118,4 +122,10 @@ - if (endptr != NULL) +@@ -115,3 +119,9 @@ noconv: *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); -+} + } + +long +wcstol(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) +{ + return wcstol_l(nptr, endptr, base, __current_locale()); - } ++} diff --git a/locale/FreeBSD/wcstold.c.patch b/locale/FreeBSD/wcstold.c.patch index d97758e..36fee1e 100644 --- a/locale/FreeBSD/wcstold.c.patch +++ b/locale/FreeBSD/wcstold.c.patch @@ -1,5 +1,5 @@ ---- wcstold.c.orig 2008-10-09 11:50:53.000000000 -0700 -+++ wcstold.c 2008-10-29 00:51:34.000000000 -0700 +--- wcstold.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstold.c 2009-11-09 15:05:26.000000000 -0800 @@ -27,44 +27,67 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wcstold.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); diff --git a/locale/FreeBSD/wcstoll.c b/locale/FreeBSD/wcstoll.c index a48056c..9a019ff 100644 --- a/locale/FreeBSD/wcstoll.c +++ b/locale/FreeBSD/wcstoll.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.19 2002/09/06 11:23:59 tjr Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoll.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoll.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); #include #include diff --git a/locale/FreeBSD/wcstoll.c.patch b/locale/FreeBSD/wcstoll.c.patch index 00deccc..867219a 100644 --- a/locale/FreeBSD/wcstoll.c.patch +++ b/locale/FreeBSD/wcstoll.c.patch @@ -1,15 +1,15 @@ ---- wcstoll.c.orig Tue May 20 15:21:45 2003 -+++ wcstoll.c Fri Feb 18 14:54:25 2005 -@@ -40,6 +40,8 @@ +--- wcstoll.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstoll.c 2009-11-09 15:05:26.000000000 -0800 +@@ -36,6 +36,8 @@ __FBSDID("FreeBSD: src/lib/libc/stdlib/s #endif - __FBSDID("$FreeBSD: src/lib/libc/locale/wcstoll.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wcstoll.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -50,7 +52,8 @@ +@@ -46,7 +48,8 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ * Convert a wide character string to a long long integer. */ long long @@ -19,7 +19,7 @@ { const wchar_t *s; unsigned long long acc; -@@ -58,13 +61,14 @@ +@@ -54,13 +57,14 @@ wcstoll(const wchar_t * __restrict nptr, unsigned long long cutoff; int neg, any, cutlim; @@ -35,7 +35,7 @@ if (c == L'-') { neg = 1; c = *s++; -@@ -91,8 +95,8 @@ +@@ -87,8 +91,8 @@ wcstoll(const wchar_t * __restrict nptr, cutoff /= base; for ( ; ; c = *s++) { #ifdef notyet @@ -46,14 +46,13 @@ else #endif if (c >= L'0' && c <= L'9') -@@ -124,4 +128,10 @@ - if (endptr != NULL) +@@ -121,3 +125,9 @@ noconv: *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); -+} + } + +long long +wcstoll(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) +{ + return wcstoll_l(nptr, endptr, base, __current_locale()); - } ++} diff --git a/locale/FreeBSD/wcstombs.3 b/locale/FreeBSD/wcstombs.3 index ee995bb..2ef8f27 100644 --- a/locale/FreeBSD/wcstombs.3 +++ b/locale/FreeBSD/wcstombs.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/wcstombs.3,v 1.4 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/wcstombs.3,v 1.5 2007/01/09 00:28:01 imp Exp $ .\" .Dd April 8, 2004 .Dt WCSTOMBS 3 diff --git a/locale/FreeBSD/wcstombs.3.patch b/locale/FreeBSD/wcstombs.3.patch index 0e57b66..3a606bb 100644 --- a/locale/FreeBSD/wcstombs.3.patch +++ b/locale/FreeBSD/wcstombs.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/wcstombs.3 2004-11-25 11:38:20.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/wcstombs.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -41,7 +41,8 @@ +--- wcstombs.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstombs.3 2009-11-09 15:05:26.000000000 -0800 +@@ -37,7 +37,8 @@ .Dt WCSTOMBS 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nd convert a wide-character string to a character string .Sh LIBRARY .Lb libc -@@ -49,28 +50,47 @@ +@@ -45,28 +46,47 @@ .In stdlib.h .Ft size_t .Fo wcstombs @@ -66,7 +66,7 @@ .Po Vt size_t Pc Ns \-1 . .Sh ERRORS The -@@ -86,7 +106,8 @@ +@@ -82,7 +102,8 @@ The conversion state is invalid. .Xr mbstowcs 3 , .Xr multibyte 3 , .Xr wcsrtombs 3 , diff --git a/locale/FreeBSD/wcstombs.c b/locale/FreeBSD/wcstombs.c index b798c9e..c7d5b67 100644 --- a/locale/FreeBSD/wcstombs.c +++ b/locale/FreeBSD/wcstombs.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstombs.c,v 1.10 2004/07/21 10:54:57 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstombs.c,v 1.11 2009/01/15 18:53:52 rdivacky Exp $"); #include #include @@ -37,7 +37,9 @@ wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n) { static const mbstate_t initial; mbstate_t mbs; + const wchar_t *pwcsp; mbs = initial; - return (__wcsnrtombs(s, &pwcs, SIZE_T_MAX, n, &mbs)); + pwcsp = pwcs; + return (__wcsnrtombs(s, &pwcsp, SIZE_T_MAX, n, &mbs)); } diff --git a/locale/FreeBSD/wcstombs.c.patch b/locale/FreeBSD/wcstombs.c.patch index a2d1bc1..749f439 100644 --- a/locale/FreeBSD/wcstombs.c.patch +++ b/locale/FreeBSD/wcstombs.c.patch @@ -1,8 +1,8 @@ ---- wcstombs.c.orig Thu Nov 25 11:38:20 2004 -+++ wcstombs.c Fri Feb 18 17:17:37 2005 -@@ -27,17 +27,27 @@ +--- wcstombs.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ wcstombs.c 2009-11-09 17:49:26.000000000 -0800 +@@ -27,19 +27,29 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/wcstombs.c,v 1.10 2004/07/21 10:54:57 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wcstombs.c,v 1.11 2009/01/15 18:53:52 rdivacky Exp $"); +#include "xlocale_private.h" + @@ -18,11 +18,13 @@ { static const mbstate_t initial; mbstate_t mbs; + const wchar_t *pwcsp; + NORMALIZE_LOCALE(loc); mbs = initial; -- return (__wcsnrtombs(s, &pwcs, SIZE_T_MAX, n, &mbs)); -+ return (loc->__lc_ctype->__wcsnrtombs(s, &pwcs, SIZE_T_MAX, n, &mbs, loc)); + pwcsp = pwcs; +- return (__wcsnrtombs(s, &pwcsp, SIZE_T_MAX, n, &mbs)); ++ return (loc->__lc_ctype->__wcsnrtombs(s, &pwcsp, SIZE_T_MAX, n, &mbs, loc)); +} + +size_t diff --git a/locale/FreeBSD/wcstoul.c b/locale/FreeBSD/wcstoul.c index f3b8b49..5a5d643 100644 --- a/locale/FreeBSD/wcstoul.c +++ b/locale/FreeBSD/wcstoul.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -32,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoul.c,v 1.1 2002/09/08 13:27:26 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoul.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); #include #include diff --git a/locale/FreeBSD/wcstoul.c.patch b/locale/FreeBSD/wcstoul.c.patch index 9b2594d..44bbe1d 100644 --- a/locale/FreeBSD/wcstoul.c.patch +++ b/locale/FreeBSD/wcstoul.c.patch @@ -1,15 +1,15 @@ ---- wcstoul.c.orig Tue May 20 15:21:45 2003 -+++ wcstoul.c Fri Feb 18 14:56:18 2005 -@@ -34,6 +34,8 @@ +--- wcstoul.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstoul.c 2009-11-09 15:05:26.000000000 -0800 +@@ -30,6 +30,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/wcstoul.c,v 1.1 2002/09/08 13:27:26 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wcstoul.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -44,7 +46,8 @@ +@@ -40,7 +42,8 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ * Convert a wide character string to an unsigned long integer. */ unsigned long @@ -19,7 +19,7 @@ { const wchar_t *s; unsigned long acc; -@@ -52,13 +55,14 @@ +@@ -48,13 +51,14 @@ wcstoul(const wchar_t * __restrict nptr, unsigned long cutoff; int neg, any, cutlim; @@ -35,7 +35,7 @@ if (c == L'-') { neg = 1; c = *s++; -@@ -83,8 +87,8 @@ +@@ -79,8 +83,8 @@ wcstoul(const wchar_t * __restrict nptr, cutlim = ULONG_MAX % base; for ( ; ; c = *s++) { #ifdef notyet @@ -46,14 +46,13 @@ else #endif if (c >= L'0' && c <= L'9') -@@ -116,4 +120,10 @@ - if (endptr != NULL) +@@ -113,3 +117,9 @@ noconv: *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); -+} + } + +unsigned long +wcstoul(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) +{ + return wcstoul_l(nptr, endptr, base, __current_locale()); - } ++} diff --git a/locale/FreeBSD/wcstoull.c b/locale/FreeBSD/wcstoull.c index fd9558b..9700cde 100644 --- a/locale/FreeBSD/wcstoull.c +++ b/locale/FreeBSD/wcstoull.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.18 2002/09/06 11:23:59 tjr Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoull.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoull.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); #include #include diff --git a/locale/FreeBSD/wcstoull.c.patch b/locale/FreeBSD/wcstoull.c.patch index 2b5c765..5ec05f8 100644 --- a/locale/FreeBSD/wcstoull.c.patch +++ b/locale/FreeBSD/wcstoull.c.patch @@ -1,15 +1,15 @@ ---- wcstoull.c.orig Tue May 20 15:21:45 2003 -+++ wcstoull.c Fri Feb 18 14:58:24 2005 -@@ -40,6 +40,8 @@ +--- wcstoull.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstoull.c 2009-11-09 15:05:26.000000000 -0800 +@@ -36,6 +36,8 @@ __FBSDID("FreeBSD: src/lib/libc/stdlib/s #endif - __FBSDID("$FreeBSD: src/lib/libc/locale/wcstoull.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wcstoull.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -50,8 +52,8 @@ +@@ -46,8 +48,8 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ * Convert a wide character string to an unsigned long long integer. */ unsigned long long @@ -20,7 +20,7 @@ { const wchar_t *s; unsigned long long acc; -@@ -59,13 +61,14 @@ +@@ -55,13 +57,14 @@ wcstoull(const wchar_t * __restrict nptr unsigned long long cutoff; int neg, any, cutlim; @@ -36,7 +36,7 @@ if (c == L'-') { neg = 1; c = *s++; -@@ -90,8 +93,8 @@ +@@ -86,8 +89,8 @@ wcstoull(const wchar_t * __restrict nptr cutlim = ULLONG_MAX % base; for ( ; ; c = *s++) { #ifdef notyet @@ -47,15 +47,14 @@ else #endif if (c >= L'0' && c <= L'9') -@@ -123,4 +126,11 @@ - if (endptr != NULL) +@@ -120,3 +123,10 @@ noconv: *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); -+} + } + +unsigned long long +wcstoull(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base) +{ + return wcstoull_l(nptr, endptr, base, __current_locale()); - } ++} diff --git a/locale/FreeBSD/wcstoumax.c b/locale/FreeBSD/wcstoumax.c index 01e25d5..765bbfb 100644 --- a/locale/FreeBSD/wcstoumax.c +++ b/locale/FreeBSD/wcstoumax.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "from @(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoumax.c,v 1.8 2002/09/06 11:23:59 tjr Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoumax.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoumax.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); #include #include diff --git a/locale/FreeBSD/wcstoumax.c.patch b/locale/FreeBSD/wcstoumax.c.patch index d285d22..d79d57c 100644 --- a/locale/FreeBSD/wcstoumax.c.patch +++ b/locale/FreeBSD/wcstoumax.c.patch @@ -1,15 +1,15 @@ ---- wcstoumax.c.orig 2003-05-20 15:21:45.000000000 -0700 -+++ wcstoumax.c 2005-02-23 16:08:34.000000000 -0800 -@@ -40,6 +40,8 @@ +--- wcstoumax.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcstoumax.c 2009-11-09 15:05:26.000000000 -0800 +@@ -36,6 +36,8 @@ __FBSDID("FreeBSD: src/lib/libc/stdlib/s #endif - __FBSDID("$FreeBSD: src/lib/libc/locale/wcstoumax.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wcstoumax.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -50,8 +52,8 @@ +@@ -46,8 +48,8 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/ * Convert a wide character string to a uintmax_t integer. */ uintmax_t @@ -20,7 +20,7 @@ { const wchar_t *s; uintmax_t acc; -@@ -59,13 +61,14 @@ +@@ -55,13 +57,14 @@ wcstoumax(const wchar_t * __restrict npt uintmax_t cutoff; int neg, any, cutlim; @@ -36,7 +36,7 @@ if (c == L'-') { neg = 1; c = *s++; -@@ -90,8 +93,8 @@ +@@ -86,8 +89,8 @@ wcstoumax(const wchar_t * __restrict npt cutlim = UINTMAX_MAX % base; for ( ; ; c = *s++) { #ifdef notyet @@ -47,7 +47,7 @@ else #endif if (c >= L'0' && c <= L'9') -@@ -124,3 +127,10 @@ +@@ -120,3 +123,10 @@ noconv: *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); } diff --git a/locale/FreeBSD/wctob.c.patch b/locale/FreeBSD/wctob.c.patch index ea6ed62..485409f 100644 --- a/locale/FreeBSD/wctob.c.patch +++ b/locale/FreeBSD/wctob.c.patch @@ -1,5 +1,5 @@ ---- wctob.c.orig 2004-11-25 11:38:20.000000000 -0800 -+++ wctob.c 2005-02-18 18:16:08.000000000 -0800 +--- wctob.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wctob.c 2009-11-09 15:05:26.000000000 -0800 @@ -27,19 +27,28 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wctob.c,v 1.4 2004/05/12 14:26:54 tjr Exp $"); diff --git a/locale/FreeBSD/wctomb.3 b/locale/FreeBSD/wctomb.3 index b7de6e5..1ecc876 100644 --- a/locale/FreeBSD/wctomb.3 +++ b/locale/FreeBSD/wctomb.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/wctomb.3,v 1.3 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/wctomb.3,v 1.4 2007/01/09 00:28:01 imp Exp $ .\" .Dd April 8, 2004 .Dt WCTOMB 3 diff --git a/locale/FreeBSD/wctomb.3.patch b/locale/FreeBSD/wctomb.3.patch index 36d28db..e35da9f 100644 --- a/locale/FreeBSD/wctomb.3.patch +++ b/locale/FreeBSD/wctomb.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/locale/FreeBSD/wctomb.3 2004-11-25 11:38:20.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/wctomb.3.edit 2006-06-28 16:55:51.000000000 -0700 -@@ -41,37 +41,56 @@ +--- wctomb.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wctomb.3 2009-11-09 15:05:26.000000000 -0800 +@@ -37,37 +37,56 @@ .Dt WCTOMB 3 .Os .Sh NAME @@ -69,7 +69,7 @@ is .Dv NULL , the -@@ -79,12 +98,12 @@ +@@ -75,12 +94,12 @@ the function returns nonzero if shift states are supported, zero otherwise. If @@ -84,7 +84,7 @@ or \-1 if no multibyte character could be recognized or converted. In this case, -@@ -104,7 +123,8 @@ +@@ -100,7 +119,8 @@ The internal conversion state is invalid .Xr mbtowc 3 , .Xr wcrtomb 3 , .Xr wcstombs 3 , diff --git a/locale/FreeBSD/wctomb.c.patch b/locale/FreeBSD/wctomb.c.patch index a7a16c6..425812b 100644 --- a/locale/FreeBSD/wctomb.c.patch +++ b/locale/FreeBSD/wctomb.c.patch @@ -1,5 +1,5 @@ ---- wctomb.c.orig 2004-11-25 11:38:20.000000000 -0800 -+++ wctomb.c 2005-02-18 18:40:43.000000000 -0800 +--- wctomb.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wctomb.c 2009-11-09 15:05:26.000000000 -0800 @@ -27,23 +27,31 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wctomb.c,v 1.8 2004/07/29 06:18:40 tjr Exp $"); diff --git a/locale/FreeBSD/wctrans.3.patch b/locale/FreeBSD/wctrans.3.patch index fc1e9e9..b294abb 100644 --- a/locale/FreeBSD/wctrans.3.patch +++ b/locale/FreeBSD/wctrans.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/wctrans.3 2003-05-20 15:21:45.000000000 -0700 -+++ _SB/Libc/locale/FreeBSD/wctrans.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- wctrans.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wctrans.3 2009-11-09 15:05:26.000000000 -0800 @@ -28,21 +28,42 @@ .Dt WCTRANS 3 .Os @@ -47,7 +47,7 @@ which represents the requested wide character mapping operation and may be used as the second argument for calls to .Fn towctrans . -@@ -55,9 +76,21 @@ +@@ -55,9 +76,21 @@ The following character mapping names ar The .Fn towctrans function transliterates the wide character @@ -70,7 +70,7 @@ .Sh RETURN VALUES The .Fn towctrans -@@ -105,7 +138,8 @@ +@@ -105,7 +138,8 @@ The requested mapping name is invalid. .Sh SEE ALSO .Xr tolower 3 , .Xr toupper 3 , diff --git a/locale/FreeBSD/wctrans.c.patch b/locale/FreeBSD/wctrans.c.patch index 15075f5..90808c4 100644 --- a/locale/FreeBSD/wctrans.c.patch +++ b/locale/FreeBSD/wctrans.c.patch @@ -1,5 +1,5 @@ ---- wctrans.c.orig 2004-11-25 11:38:20.000000000 -0800 -+++ wctrans.c 2005-02-19 14:30:32.000000000 -0800 +--- wctrans.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wctrans.c 2009-11-09 15:05:26.000000000 -0800 @@ -27,6 +27,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wctrans.c,v 1.3 2003/11/01 08:20:58 tjr Exp $"); @@ -9,7 +9,7 @@ #include #include #include -@@ -38,15 +40,16 @@ +@@ -38,15 +40,16 @@ enum { }; wint_t @@ -29,7 +29,7 @@ break; case _WCT_ERROR: default: -@@ -57,6 +60,12 @@ +@@ -57,6 +60,12 @@ towctrans(wint_t wc, wctrans_t desc) return (wc); } @@ -42,7 +42,7 @@ wctrans_t wctrans(const char *charclass) { -@@ -78,3 +87,14 @@ +@@ -78,3 +87,14 @@ wctrans(const char *charclass) errno = EINVAL; return (ccls[i].trans); } diff --git a/locale/FreeBSD/wctype.3 b/locale/FreeBSD/wctype.3 index 30409f3..16c3de9 100644 --- a/locale/FreeBSD/wctype.3 +++ b/locale/FreeBSD/wctype.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/wctype.3,v 1.5 2004/03/27 08:59:21 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/wctype.3,v 1.7 2006/10/13 16:11:12 ru Exp $ .\" .Dd March 27, 2004 .Dt WCTYPE 3 @@ -94,7 +94,8 @@ myiswalpha(wint_t wc) } .Ed .Sh SEE ALSO -.Xr ctype 3 +.Xr ctype 3 , +.Xr nextwctype 3 .Sh STANDARDS The .Fn iswctype @@ -104,7 +105,7 @@ functions conform to .St -p1003.1-2001 . The .Dq Li ideogram , -.Dq Li phonogram +.Dq Li phonogram , .Dq Li special , and .Dq Li rune diff --git a/locale/FreeBSD/wctype.3.patch b/locale/FreeBSD/wctype.3.patch index 86d78c6..07e69d2 100644 --- a/locale/FreeBSD/wctype.3.patch +++ b/locale/FreeBSD/wctype.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/wctype.3 2004-11-25 11:38:20.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/wctype.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- wctype.3.bsdnew 2009-11-10 13:13:11.000000000 -0800 ++++ wctype.3 2009-11-10 14:11:00.000000000 -0800 @@ -28,21 +28,42 @@ .Dt WCTYPE 3 .Os @@ -47,7 +47,7 @@ which represents the requested wide character class and may be used as the second argument for calls to .Fn iswctype . -@@ -60,6 +81,18 @@ +@@ -60,6 +81,18 @@ function checks whether the wide charact .Fa wc is in the character class .Fa charclass . @@ -66,7 +66,7 @@ .Sh RETURN VALUES The .Fn iswctype -@@ -75,7 +108,7 @@ +@@ -75,7 +108,7 @@ The .Fn wctype function returns 0 if .Fa property @@ -75,12 +75,12 @@ .Vt wctype_t that can be used in subsequent calls to .Fn iswctype . -@@ -94,7 +127,8 @@ - } +@@ -95,7 +128,8 @@ myiswalpha(wint_t wc) .Ed .Sh SEE ALSO --.Xr ctype 3 -+.Xr ctype 3 , + .Xr ctype 3 , +-.Xr nextwctype 3 ++.Xr nextwctype 3 , +.Xr xlocale 3 .Sh STANDARDS The diff --git a/locale/FreeBSD/wctype.c b/locale/FreeBSD/wctype.c index a0e21bc..2db1c9b 100644 --- a/locale/FreeBSD/wctype.c +++ b/locale/FreeBSD/wctype.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wctype.c,v 1.3 2004/03/27 08:59:21 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wctype.c,v 1.4 2008/03/17 18:22:23 antoine Exp $"); #include #include @@ -42,7 +42,7 @@ iswctype(wint_t wc, wctype_t charclass) wctype_t wctype(const char *property) { - struct { + static const struct { const char *name; wctype_t mask; } props[] = { diff --git a/locale/FreeBSD/wctype.c.patch b/locale/FreeBSD/wctype.c.patch index 46623d0..f9c75ab 100644 --- a/locale/FreeBSD/wctype.c.patch +++ b/locale/FreeBSD/wctype.c.patch @@ -1,16 +1,15 @@ ---- wctype.c.orig 2005-10-17 23:42:33.000000000 -0700 -+++ wctype.c 2005-10-17 23:44:47.000000000 -0700 -@@ -27,48 +27,63 @@ +--- wctype.c.bsdnew 2009-11-09 15:05:25.000000000 -0800 ++++ wctype.c 2009-11-09 17:53:01.000000000 -0800 +@@ -27,21 +27,17 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/wctype.c,v 1.3 2004/03/27 08:59:21 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wctype.c,v 1.4 2008/03/17 18:22:23 antoine Exp $"); +#include "xlocale_private.h" + #include #include #include -+#include - +- -#undef iswctype -int -iswctype(wint_t wc, wctype_t charclass) @@ -18,59 +17,17 @@ - - return (__istype(wc, charclass)); -} -+static struct { -+ const char *name; -+ wctype_t mask; -+} props[] = { -+ { "alnum", _CTYPE_A|_CTYPE_D }, -+ { "alpha", _CTYPE_A }, -+ { "blank", _CTYPE_B }, -+ { "cntrl", _CTYPE_C }, -+ { "digit", _CTYPE_D }, -+ { "graph", _CTYPE_G }, -+ { "lower", _CTYPE_L }, -+ { "print", _CTYPE_R }, -+ { "punct", _CTYPE_P }, -+ { "space", _CTYPE_S }, -+ { "upper", _CTYPE_U }, -+ { "xdigit", _CTYPE_X }, -+ { "ideogram", _CTYPE_I }, /* BSD extension */ -+ { "special", _CTYPE_T }, /* BSD extension */ -+ { "phonogram", _CTYPE_Q }, /* BSD extension */ -+ { "rune", 0xFFFFFFF0L }, /* BSD extension */ -+ { NULL, 0UL }, /* Default */ -+}; ++#include wctype_t -wctype(const char *property) +wctype_l(const char *property, locale_t loc) { -- struct { -- const char *name; -- wctype_t mask; -- } props[] = { -- { "alnum", _CTYPE_A|_CTYPE_D }, -- { "alpha", _CTYPE_A }, -- { "blank", _CTYPE_B }, -- { "cntrl", _CTYPE_C }, -- { "digit", _CTYPE_D }, -- { "graph", _CTYPE_G }, -- { "lower", _CTYPE_L }, -- { "print", _CTYPE_R }, -- { "punct", _CTYPE_P }, -- { "space", _CTYPE_S }, -- { "upper", _CTYPE_U }, -- { "xdigit", _CTYPE_X }, -- { "ideogram", _CTYPE_I }, /* BSD extension */ -- { "special", _CTYPE_T }, /* BSD extension */ -- { "phonogram", _CTYPE_Q }, /* BSD extension */ -- { "rune", 0xFFFFFF00L }, /* BSD extension */ -- { NULL, 0UL }, /* Default */ -- }; - int i; + _RuneLocale *rl; - - i = 0; + static const struct { + const char *name; + wctype_t mask; +@@ -70,5 +66,23 @@ wctype(const char *property) while (props[i].name != NULL && strcmp(props[i].name, property) != 0) i++; diff --git a/locale/FreeBSD/wcwidth.3.patch b/locale/FreeBSD/wcwidth.3.patch index 7c7b829..bc9dfc2 100644 --- a/locale/FreeBSD/wcwidth.3.patch +++ b/locale/FreeBSD/wcwidth.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/locale/FreeBSD/wcwidth.3 2004-11-25 11:38:21.000000000 -0800 -+++ _SB/Libc/locale/FreeBSD/wcwidth.3.edit 2006-06-28 16:55:51.000000000 -0700 +--- wcwidth.3.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcwidth.3 2009-11-09 15:05:26.000000000 -0800 @@ -28,20 +28,38 @@ .Dt WCWIDTH 3 .Os @@ -41,7 +41,7 @@ .Sh RETURN VALUES The .Fn wcwidth -@@ -50,8 +68,8 @@ +@@ -50,8 +68,8 @@ function returns 0 if the argument is a null wide character (L'\e0'), \-1 if .Fa wc @@ -52,7 +52,7 @@ character occupies. .Sh EXAMPLES This code fragment reads text from standard input and -@@ -79,7 +97,8 @@ +@@ -79,7 +97,8 @@ while ((ch = getwchar()) != WEOF) { .Ed .Sh SEE ALSO .Xr iswprint 3 , diff --git a/locale/FreeBSD/wcwidth.c b/locale/FreeBSD/wcwidth.c index 288a60d..587862e 100644 --- a/locale/FreeBSD/wcwidth.c +++ b/locale/FreeBSD/wcwidth.c @@ -18,10 +18,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcwidth.c,v 1.7 2004/08/12 12:19:11 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcwidth.c,v 1.8 2007/01/09 00:28:01 imp Exp $"); #include diff --git a/locale/FreeBSD/wcwidth.c.patch b/locale/FreeBSD/wcwidth.c.patch index 72de1ff..4f5e296 100644 --- a/locale/FreeBSD/wcwidth.c.patch +++ b/locale/FreeBSD/wcwidth.c.patch @@ -1,15 +1,15 @@ ---- wcwidth.c.orig 2004-11-25 11:38:21.000000000 -0800 -+++ wcwidth.c 2005-02-24 00:37:25.000000000 -0800 -@@ -42,6 +42,8 @@ +--- wcwidth.c.orig 2009-11-09 15:05:25.000000000 -0800 ++++ wcwidth.c 2009-11-09 15:05:26.000000000 -0800 +@@ -38,6 +38,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/locale/wcwidth.c,v 1.7 2004/08/12 12:19:11 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/locale/wcwidth.c,v 1.8 2007/01/09 00:28:01 imp Exp $"); +#include "xlocale_private.h" + #include #undef wcwidth -@@ -50,5 +52,13 @@ +@@ -46,5 +48,13 @@ int wcwidth(wchar_t wc) { diff --git a/locale/Makefile.inc b/locale/Makefile.inc index 767f796..56fcfd4 100644 --- a/locale/Makefile.inc +++ b/locale/Makefile.inc @@ -18,7 +18,7 @@ CFLAGS-${_src} += -D__FBSDID=__RCSID MISRCS += isctype.c iswctype.c xlocale.c .include "Makefile.fbsd_begin" -FBSDMISRCS= big5.c btowc.c collate.c collcmp.c euc.c fix_grouping.c \ +FBSDMISRCS= ascii.c big5.c btowc.c collate.c collcmp.c euc.c fix_grouping.c \ gb18030.c gb2312.c gbk.c \ ldpart.c lmessages.c lmonetary.c lnumeric.c localeconv.c \ mblen.c mbrlen.c mbrtowc.c mbsinit.c mbsnrtowcs.c mbsrtowcs.c \ @@ -80,9 +80,10 @@ ARCH32 = i386 ARCH32 = $(_ARCH:C/64$//) .endif ${_cwd}/rune32.h: ${_cwd}/rune-fbsd.c - ${HOSTCC} -arch ${ARCH32} -D_LIBC_NO_FEATURE_VERIFICATION -I${.CURDIR}/include -DRUNEOFF32 -o ${_cwd}/rune32 ${.ALLSRC} + ${CP} ${.CURDIR}/include/runetype.h ${_cwd} + ${HOSTCC} -arch ${ARCH32} -D_LIBC_NO_FEATURE_VERIFICATION -DRUNEOFF32 -o ${_cwd}/rune32 ${.ALLSRC} ${_cwd}/rune32 > ${.TARGET} - ${RM} ${_cwd}/rune32 + ${RM} ${_cwd}/rune32 ${_cwd}/runetype.h AUTOPATCHHDRS+= ${_cwd}/rune32.h .endfor # _cwd diff --git a/locale/ascii-fbsd.c b/locale/ascii-fbsd.c new file mode 100644 index 0000000..e2b2b83 --- /dev/null +++ b/locale/ascii-fbsd.c @@ -0,0 +1,186 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 +__FBSDID("$FreeBSD: src/lib/libc/locale/ascii.c,v 1.1 2008/01/21 23:48:12 ache Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _ascii_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t); +static int _ascii_mbsinit(const mbstate_t *, locale_t); +static size_t _ascii_mbsnrtowcs(wchar_t * __restrict dst, + const char ** __restrict src, size_t nms, size_t len, + mbstate_t * __restrict ps __unused, locale_t); +static size_t _ascii_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); +static size_t _ascii_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict, locale_t); + +__private_extern__ int +_ascii_init(struct __xlocale_st_runelocale *xrl) +{ + + xrl->__mbrtowc = _ascii_mbrtowc; + xrl->__mbsinit = _ascii_mbsinit; + xrl->__mbsnrtowcs = _ascii_mbsnrtowcs; + xrl->__wcrtomb = _ascii_wcrtomb; + xrl->__wcsnrtombs = _ascii_wcsnrtombs; + xrl->__mb_cur_max = 1; + xrl->__mb_sb_limit = 128; + return(0); +} + +static int +_ascii_mbsinit(const mbstate_t *ps __unused, locale_t loc __unused) +{ + + /* + * Encoding is not state dependent - we are always in the + * initial state. + */ + return (1); +} + +static size_t +_ascii_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps __unused, locale_t loc __unused) +{ + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (0); + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + if (*s & 0x80) { + errno = EILSEQ; + return ((size_t)-1); + } + if (pwc != NULL) + *pwc = (unsigned char)*s; + return (*s == '\0' ? 0 : 1); +} + +static size_t +_ascii_wcrtomb(char * __restrict s, wchar_t wc, + mbstate_t * __restrict ps __unused, locale_t loc __unused) +{ + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc < 0 || wc > 127) { + errno = EILSEQ; + return ((size_t)-1); + } + *s = (unsigned char)wc; + return (1); +} + +static size_t +_ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps __unused, locale_t loc __unused) +{ + const char *s; + size_t nchr; + + if (dst == NULL) { + for (s = *src; nms > 0 && *s != '\0'; s++, nms--) { + if (*s & 0x80) { + errno = EILSEQ; + return ((size_t)-1); + } + } + return (s - *src); + } + + s = *src; + nchr = 0; + while (len-- > 0 && nms-- > 0) { + if (*s & 0x80) { + errno = EILSEQ; + return ((size_t)-1); + } + if ((*dst++ = (unsigned char)*s++) == L'\0') { + *src = NULL; + return (nchr); + } + nchr++; + } + *src = s; + return (nchr); +} + +static size_t +_ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, + size_t nwc, size_t len, mbstate_t * __restrict ps __unused, locale_t loc __unused) +{ + const wchar_t *s; + size_t nchr; + + if (dst == NULL) { + for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) { + if (*s < 0 || *s > 127) { + errno = EILSEQ; + return ((size_t)-1); + } + } + return (s - *src); + } + + s = *src; + nchr = 0; + while (len-- > 0 && nwc-- > 0) { + if (*s < 0 || *s > 127) { + errno = EILSEQ; + return ((size_t)-1); + } + if ((*dst++ = *s++) == '\0') { + *src = NULL; + return (nchr); + } + nchr++; + } + *src = s; + return (nchr); +} + diff --git a/locale/big5-fbsd.c b/locale/big5-fbsd.c index d4d4142..12c88ba 100644 --- a/locale/big5-fbsd.c +++ b/locale/big5-fbsd.c @@ -38,11 +38,12 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)big5.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/locale/big5.c,v 1.16 2004/05/17 11:16:14 tjr Exp $"); +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/big5.c,v 1.18 2007/10/13 16:28:21 ache Exp $"); #include "xlocale_private.h" +#include #include #include #include @@ -50,11 +51,11 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/big5.c,v 1.16 2004/05/17 11:16:14 tjr Ex #include #include "mblocal.h" -__private_extern__ int _BIG5_init(struct __xlocale_st_runelocale *); -static size_t _BIG5_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict, locale_t); +static size_t _BIG5_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t); static int _BIG5_mbsinit(const mbstate_t *, locale_t); -static size_t _BIG5_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); +static size_t _BIG5_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); typedef struct { wchar_t ch; @@ -68,11 +69,12 @@ _BIG5_init(struct __xlocale_st_runelocale *xrl) xrl->__wcrtomb = _BIG5_wcrtomb; xrl->__mbsinit = _BIG5_mbsinit; xrl->__mb_cur_max = 2; + xrl->__mb_sb_limit = 128; return (0); } static int -_BIG5_mbsinit(const mbstate_t *ps, locale_t loc) +_BIG5_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _BIG5State *)ps)->ch == 0); @@ -88,7 +90,7 @@ _big5_check(u_int c) static size_t _BIG5_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps, locale_t loc) + mbstate_t * __restrict ps, locale_t loc __unused) { _BIG5State *bs; wchar_t wc; @@ -148,7 +150,7 @@ _BIG5_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } static size_t -_BIG5_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +_BIG5_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc __unused) { _BIG5State *bs; diff --git a/locale/collate-fbsd.c b/locale/collate-fbsd.c index e40350b..e48d7ca 100644 --- a/locale/collate-fbsd.c +++ b/locale/collate-fbsd.c @@ -26,7 +26,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.33 2004/09/22 16:56:48 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.35 2005/02/27 20:31:13 ru Exp $"); #include "xlocale_private.h" /* assumes the locale_t variable is named loc */ diff --git a/locale/collate.h b/locale/collate.h index 494e231..f50baba 100644 --- a/locale/collate.h +++ b/locale/collate.h @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/lib/libc/locale/collate.h,v 1.14 2002/08/30 20:26:02 ache Exp $ + * $FreeBSD: src/lib/libc/locale/collate.h,v 1.15 2005/02/27 20:31:13 ru Exp $ */ #ifndef _COLLATE_H_ @@ -41,6 +41,8 @@ #define COLLATE_VERSION "1.0\n" #define COLLATE_VERSION1_1 "1.1\n" #define COLLATE_VERSION1_1A "1.1A\n" +#define COLLATE_VERSION1_2 "1.2\n" + /* see discussion in string/FreeBSD/strxfrm for this value */ #define COLLATE_MAX_PRIORITY ((1 << 24) - 1) diff --git a/locale/collcmp-fbsd.c b/locale/collcmp-fbsd.c index ee6a383..7f135bc 100644 --- a/locale/collcmp-fbsd.c +++ b/locale/collcmp-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.17 2003/08/03 19:28:23 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.18 2005/02/27 14:54:23 phantom Exp $"); #include #include @@ -36,9 +36,7 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.17 2003/08/03 19:28:23 ach */ __private_extern__ int -__collate_range_cmp(c1, c2, loc) - wchar_t c1, c2; - locale_t loc; +__collate_range_cmp(wchar_t c1, wchar_t c2, locale_t loc) { static wchar_t s1[2], s2[2]; diff --git a/locale/ctype.3 b/locale/ctype.3 index eb1a4d7..aa91313 100644 --- a/locale/ctype.3 +++ b/locale/ctype.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ctype.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/ctype.3,v 1.15 2004/06/30 20:09:08 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/ctype.3,v 1.18 2009/09/04 07:44:58 des Exp $ .\" .Dd March 30, 2004 .Dt CTYPE 3 diff --git a/locale/digittoint.3 b/locale/digittoint.3 index eecd289..3e86f72 100644 --- a/locale/digittoint.3 +++ b/locale/digittoint.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)digittoint.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/digittoint.3,v 1.3 2004/03/30 07:19:35 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/digittoint.3,v 1.6 2009/09/04 07:44:58 des Exp $ .\" .Dd April 6, 2001 .Dt DIGITTOINT 3 diff --git a/locale/euc-fbsd.c b/locale/euc-fbsd.c index 0ce9bcc..1b60aa3 100644 --- a/locale/euc-fbsd.c +++ b/locale/euc-fbsd.c @@ -39,7 +39,7 @@ static char sccsid[] = "@(#)euc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/euc.c,v 1.20 2004/06/23 07:01:43 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/euc.c,v 1.22 2007/10/13 16:28:21 ache Exp $"); #include "xlocale_private.h" @@ -51,12 +51,11 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/euc.c,v 1.20 2004/06/23 07:01:43 tjr Exp #include #include "mblocal.h" -__private_extern__ int _EUC_init(struct __xlocale_st_runelocale *); -static size_t _EUC_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict, locale_t); +static size_t _EUC_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t); static int _EUC_mbsinit(const mbstate_t *, locale_t); -static size_t _EUC_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, - locale_t); +static size_t _EUC_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); typedef struct { int count[4]; @@ -122,16 +121,17 @@ _EUC_init(struct __xlocale_st_runelocale *xrl) } rl->__variable = ei; rl->__variable_len = sizeof(_EucInfo); - xrl->__mb_cur_max = new__mb_cur_max; - xrl->__mbrtowc = _EUC_mbrtowc; - xrl->__wcrtomb = _EUC_wcrtomb; - xrl->__mbsinit = _EUC_mbsinit; - xrl->__free_extra = (__free_extra_t)_EUC_free_extra; + xrl->__mb_cur_max = new__mb_cur_max; + xrl->__mbrtowc = _EUC_mbrtowc; + xrl->__wcrtomb = _EUC_wcrtomb; + xrl->__mbsinit = _EUC_mbsinit; + xrl->__mb_sb_limit = 256; + xrl->__free_extra = (__free_extra_t)_EUC_free_extra; return (0); } static int -_EUC_mbsinit(const mbstate_t *ps, locale_t loc) +_EUC_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _EucState *)ps)->want == 0); @@ -145,6 +145,7 @@ _EUC_mbsinit(const mbstate_t *ps, locale_t loc) static __inline int _euc_set(u_int c) { + c &= 0xff; return ((c & 0x80) ? c == _SS3 ? 3 : c == _SS2 ? 2 : 1 : 0); } @@ -225,8 +226,7 @@ _EUC_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } static size_t -_EUC_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, - locale_t loc) +_EUC_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) { _EucState *es; wchar_t m, nm; diff --git a/locale/gb18030-fbsd.c b/locale/gb18030-fbsd.c index b154c4c..c63d050 100644 --- a/locale/gb18030-fbsd.c +++ b/locale/gb18030-fbsd.c @@ -30,7 +30,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/gb18030.c,v 1.6 2004/05/12 14:09:04 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/gb18030.c,v 1.8 2007/10/13 16:28:21 ache Exp $"); #include "xlocale_private.h" @@ -43,11 +43,11 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/gb18030.c,v 1.6 2004/05/12 14:09:04 tjr #define GB18030_MB_CUR_MAX 4 -__private_extern__ int _GB18030_init(struct __xlocale_st_runelocale *); -static size_t _GB18030_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict, locale_t); +static size_t _GB18030_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t); static int _GB18030_mbsinit(const mbstate_t *, locale_t); -static size_t _GB18030_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); +static size_t _GB18030_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); typedef struct { int count; @@ -62,12 +62,13 @@ _GB18030_init(struct __xlocale_st_runelocale *xrl) xrl->__wcrtomb = _GB18030_wcrtomb; xrl->__mbsinit = _GB18030_mbsinit; xrl->__mb_cur_max = GB18030_MB_CUR_MAX; + xrl->__mb_sb_limit = 128; return (0); } static int -_GB18030_mbsinit(const mbstate_t *ps, locale_t loc) +_GB18030_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _GB18030State *)ps)->count == 0); @@ -75,7 +76,7 @@ _GB18030_mbsinit(const mbstate_t *ps, locale_t loc) static size_t _GB18030_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, - size_t n, mbstate_t * __restrict ps, locale_t loc) + size_t n, mbstate_t * __restrict ps, locale_t loc __unused) { _GB18030State *gs; wchar_t wch; @@ -158,7 +159,7 @@ ilseq: } static size_t -_GB18030_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +_GB18030_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc __unused) { _GB18030State *gs; size_t len; diff --git a/locale/gb2312-fbsd.c b/locale/gb2312-fbsd.c index a632e07..a84b1cf 100644 --- a/locale/gb2312-fbsd.c +++ b/locale/gb2312-fbsd.c @@ -26,7 +26,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/gb2312.c,v 1.8 2004/05/12 14:09:04 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/gb2312.c,v 1.10 2007/10/13 16:28:21 ache Exp $"); #include "xlocale_private.h" @@ -39,12 +39,11 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/gb2312.c,v 1.8 2004/05/12 14:09:04 tjr E #define GB2312_MB_CUR_MAX 2 -__private_extern__ int _GB2312_init(struct __xlocale_st_runelocale *); -static size_t _GB2312_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict, locale_t); +static size_t _GB2312_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t); static int _GB2312_mbsinit(const mbstate_t *, locale_t); -static size_t _GB2312_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); - +static size_t _GB2312_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); typedef struct { int count; u_char bytes[2]; @@ -58,11 +57,12 @@ _GB2312_init(struct __xlocale_st_runelocale *xrl) xrl->__wcrtomb = _GB2312_wcrtomb; xrl->__mbsinit = _GB2312_mbsinit; xrl->__mb_cur_max = GB2312_MB_CUR_MAX; + xrl->__mb_sb_limit = 128; return (0); } static int -_GB2312_mbsinit(const mbstate_t *ps, locale_t loc) +_GB2312_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _GB2312State *)ps)->count == 0); @@ -93,7 +93,7 @@ _GB2312_check(const char *str, size_t n) static size_t _GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps, locale_t loc) + mbstate_t * __restrict ps, locale_t loc __unused) { _GB2312State *gs; wchar_t wc; @@ -133,7 +133,7 @@ _GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } static size_t -_GB2312_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +_GB2312_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc __unused) { _GB2312State *gs; diff --git a/locale/gbk-fbsd.c b/locale/gbk-fbsd.c index a919137..c38338b 100644 --- a/locale/gbk-fbsd.c +++ b/locale/gbk-fbsd.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,11 +31,12 @@ * SUCH DAMAGE. */ -#include -__FBSDID("$FreeBSD: src/lib/libc/locale/gbk.c,v 1.11 2004/05/17 11:16:14 tjr Exp $"); +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/gbk.c,v 1.14 2007/10/13 16:28:21 ache Exp $"); #include "xlocale_private.h" +#include #include #include #include @@ -47,11 +44,11 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/gbk.c,v 1.11 2004/05/17 11:16:14 tjr Exp #include #include "mblocal.h" -__private_extern__ int _GBK_init(struct __xlocale_st_runelocale *); -static size_t _GBK_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict, locale_t); +static size_t _GBK_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t); static int _GBK_mbsinit(const mbstate_t *, locale_t); -static size_t _GBK_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); +static size_t _GBK_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); typedef struct { wchar_t ch; @@ -65,11 +62,12 @@ _GBK_init(struct __xlocale_st_runelocale *xrl) xrl->__wcrtomb = _GBK_wcrtomb; xrl->__mbsinit = _GBK_mbsinit; xrl->__mb_cur_max = 2; + xrl->__mb_sb_limit = 128; return (0); } static int -_GBK_mbsinit(const mbstate_t *ps, locale_t loc) +_GBK_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _GBKState *)ps)->ch == 0); @@ -85,7 +83,7 @@ _gbk_check(u_int c) static size_t _GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps, locale_t loc) + mbstate_t * __restrict ps, locale_t loc __unused) { _GBKState *gs; wchar_t wc; @@ -145,7 +143,7 @@ _GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } static size_t -_GBK_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +_GBK_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc __unused) { _GBKState *gs; diff --git a/locale/isalnum.3 b/locale/isalnum.3 index 3739051..961b9b3 100644 --- a/locale/isalnum.3 +++ b/locale/isalnum.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isalnum.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isalnum.3,v 1.19 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isalnum.3,v 1.24 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISALNUM 3 .Os .Sh NAME @@ -56,15 +52,11 @@ function tests for any character for which or .Xr isdigit 3 is true. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (preceded by their numeric values, in octal): .Pp @@ -104,7 +96,6 @@ function should be used instead. .Xr isalpha 3 , .Xr isdigit 3 , .Xr iswalnum 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/isalpha.3 b/locale/isalpha.3 index eb95363..3d9ad13 100644 --- a/locale/isalpha.3 +++ b/locale/isalpha.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isalpha.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isalpha.3,v 1.18 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isalpha.3,v 1.23 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISALPHA 3 .Os .Sh NAME @@ -56,15 +52,11 @@ function tests for any character for which or .Xr islower 3 is true. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (preceded by their numeric values, in octal): .Pp @@ -102,7 +94,6 @@ function should be used instead. .Xr islower 3 , .Xr isupper 3 , .Xr iswalpha 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/isblank.3 b/locale/isblank.3 index ead0706..5a4aef2 100644 --- a/locale/isblank.3 +++ b/locale/isblank.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isblank.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isblank.3,v 1.19 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isblank.3,v 1.26 2009/11/11 11:31:02 roam Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISBLANK 3 .Os .Sh NAME @@ -54,18 +50,18 @@ For any locale, this includes the following standard characters: .It "\&``\et''\t`` ''" .El .Pp -In the "C" locale, +In the "C" locale, a successful .Fn isblank -successful test is limited to these characters only. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +test is limited to these characters only. +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Sh RETURN VALUES +The +.Fn isblank +function returns zero if the character tests false and +returns non-zero if the character tests true. .Sh COMPATIBILITY The .Bx 4.4 @@ -76,16 +72,10 @@ and may not be supported in future releases. The .Fn iswblank function should be used instead. -.Sh RETURN VALUES -The -.Fn isblank -function returns zero if the character tests false and -returns non-zero if the character tests true. .Sh SEE ALSO .Xr ctype 3 , .Xr isalnum_l 3 , .Xr iswblank 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/iscntrl.3 b/locale/iscntrl.3 index 886980d..bb7045d 100644 --- a/locale/iscntrl.3 +++ b/locale/iscntrl.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)iscntrl.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/iscntrl.3,v 1.17 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/iscntrl.3,v 1.22 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISCNTRL 3 .Os .Sh NAME @@ -52,15 +48,11 @@ The .Fn iscntrl function tests for any control character. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (preceded by their numeric values, in octal): .Pp @@ -92,7 +84,6 @@ function should be used instead. .Xr ctype 3 , .Xr isalnum_l 3 , .Xr iswcntrl 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/isdigit.3 b/locale/isdigit.3 index b6e2b59..0fffb88 100644 --- a/locale/isdigit.3 +++ b/locale/isdigit.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isdigit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isdigit.3,v 1.19 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isdigit.3,v 1.25 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd May 4, 2007 .Dt ISDIGIT 3 .Os .Sh NAME @@ -68,13 +64,8 @@ function behaves similarly to but may recognize additional characters, depending on the current locale setting. .Pp -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . .Sh RETURN VALUES diff --git a/locale/isgraph.3 b/locale/isgraph.3 index de81a2b..f20973f 100644 --- a/locale/isgraph.3 +++ b/locale/isgraph.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isgraph.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/locale/isgraph.3,v 1.19 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isgraph.3,v 1.25 2009/11/13 09:03:50 roam Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISGRAPH 3 .Os .Sh NAME @@ -54,16 +50,12 @@ The function tests for any printing character except space .Pq Ql "\ " and other -locale-specific, space-like characters. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +locale-specific space-like characters. +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (preceded by their numeric values, in octal): .Pp @@ -107,7 +99,6 @@ function should be used instead. .Xr ctype 3 , .Xr isalnum_l 3 , .Xr iswgraph 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/isideogram.3 b/locale/isideogram.3 index e94bfd0..9ee26b5 100644 --- a/locale/isideogram.3 +++ b/locale/isideogram.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/isideogram.3,v 1.2 2004/07/04 20:55:48 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isideogram.3,v 1.4 2009/09/04 07:44:58 des Exp $ .\" .Dd March 30, 2004 .Dt ISIDEOGRAM 3 diff --git a/locale/islower.3 b/locale/islower.3 index 328ac0e..066d7d6 100644 --- a/locale/islower.3 +++ b/locale/islower.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)islower.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/islower.3,v 1.17 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/islower.3,v 1.22 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISLOWER 3 .Os .Sh NAME @@ -52,15 +48,11 @@ The .Fn islower function tests for any lower-case letters. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): .Pp @@ -91,7 +83,6 @@ function should be used instead. .Xr ctype 3 , .Xr isalnum_l 3 , .Xr iswlower 3 , -.Xr multibyte 3 , .Xr tolower 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/isphonogram.3 b/locale/isphonogram.3 index 203925e..39db048 100644 --- a/locale/isphonogram.3 +++ b/locale/isphonogram.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/isphonogram.3,v 1.1 2004/03/30 07:23:54 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isphonogram.3,v 1.3 2009/09/04 07:44:58 des Exp $ .\" .Dd March 30, 2004 .Dt ISPHONOGRAM 3 diff --git a/locale/isprint.3 b/locale/isprint.3 index 642643c..25ae0b5 100644 --- a/locale/isprint.3 +++ b/locale/isprint.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isprint.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isprint.3,v 1.20 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isprint.3,v 1.26 2009/11/13 09:07:33 roam Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISPRINT 3 .Os .Sh NAME @@ -53,15 +49,11 @@ The .Fn isprint function tests for any printing character, including space .Pq Ql "\ " . -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (preceded by their numeric values, in octal): .Pp @@ -105,7 +97,6 @@ function should be used instead. .Xr ctype 3 , .Xr isalnum_l 3 , .Xr iswprint 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/ispunct.3 b/locale/ispunct.3 index 89d780c..b4fcfa3 100644 --- a/locale/ispunct.3 +++ b/locale/ispunct.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)ispunct.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/ispunct.3,v 1.18 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/ispunct.3,v 1.23 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISPUNCT 3 .Os .Sh NAME @@ -57,15 +53,11 @@ or a character for which .Xr isalnum 3 is true. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (preceded by their numeric values, in octal): .Pp @@ -97,7 +89,6 @@ function should be used instead. .Xr ctype 3 , .Xr isalnum_l 3 , .Xr iswpunct 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/isrune.3 b/locale/isrune.3 index 2bda5c4..a98a159 100644 --- a/locale/isrune.3 +++ b/locale/isrune.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/isrune.3,v 1.1 2004/03/30 07:23:54 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isrune.3,v 1.3 2009/09/04 07:44:58 des Exp $ .\" .Dd March 30, 2004 .Dt ISRUNE 3 diff --git a/locale/isspace.3 b/locale/isspace.3 index 5255105..f6fa79a 100644 --- a/locale/isspace.3 +++ b/locale/isspace.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isspace.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isspace.3,v 1.17 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isspace.3,v 1.22 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISSPACE 3 .Os .Sh NAME @@ -61,13 +57,8 @@ For any locale, this includes the following standard characters: In the "C" locale, .Fn isspace successful test is limited to these characters only. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . .Sh RETURN VALUES diff --git a/locale/isspecial.3 b/locale/isspecial.3 index 579ca92..0a0ab37 100644 --- a/locale/isspecial.3 +++ b/locale/isspecial.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/isspecial.3,v 1.1 2004/03/30 07:23:54 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isspecial.3,v 1.3 2009/09/04 07:44:58 des Exp $ .\" .Dd March 30, 2004 .Dt ISSPECIAL 3 diff --git a/locale/isupper.3 b/locale/isupper.3 index acf7c13..c3274c6 100644 --- a/locale/isupper.3 +++ b/locale/isupper.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isupper.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isupper.3,v 1.18 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isupper.3,v 1.23 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISUPPER 3 .Os .Sh NAME @@ -52,15 +48,11 @@ The .Fn isupper function tests for any upper-case letter. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . +.Pp In the ASCII character set, this includes the following characters (preceded by their numeric values, in octal): .Pp @@ -91,7 +83,6 @@ function should be used instead. .Xr ctype 3 , .Xr isalnum_l 3 , .Xr iswupper 3 , -.Xr multibyte 3 , .Xr toupper 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/iswalnum.3 b/locale/iswalnum.3 index 987804e..d501ea9 100644 --- a/locale/iswalnum.3 +++ b/locale/iswalnum.3 @@ -15,10 +15,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -36,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)isalnum.3 5.2 (Berkeley) 6/29/91 -.\" $FreeBSD: src/lib/libc/locale/iswalnum.3,v 1.5 2002/11/29 17:35:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/iswalnum.3,v 1.6 2007/01/09 00:28:00 imp Exp $ .\" .Dd October 3, 2002 .Dt ISWALNUM 3 diff --git a/locale/isxdigit.3 b/locale/isxdigit.3 index 0dadcba..b1c2faa 100644 --- a/locale/isxdigit.3 +++ b/locale/isxdigit.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isxdigit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isxdigit.3,v 1.20 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/isxdigit.3,v 1.25 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt ISXDIGIT 3 .Os .Sh NAME @@ -71,13 +67,8 @@ function behaves similarly to but may recognize additional characters, depending on the current locale setting. .Pp -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The value of the argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . .Sh RETURN VALUES @@ -99,7 +90,6 @@ function should be used instead. .Xr ctype 3 , .Xr isalnum_l 3 , .Xr iswxdigit 3 , -.Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS The diff --git a/locale/localeconv-fbsd.c b/locale/localeconv-fbsd.c index 2d5a3d5..11afdb5 100644 --- a/locale/localeconv-fbsd.c +++ b/locale/localeconv-fbsd.c @@ -11,10 +11,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -36,7 +32,7 @@ static char sccsid[] = "@(#)localeconv.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.13 2003/06/26 10:46:16 phantom Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.14 2007/12/12 07:43:23 phantom Exp $"); #include "xlocale_private.h" diff --git a/locale/localeconv.3 b/locale/localeconv.3 index dba0aeb..01df550 100644 --- a/locale/localeconv.3 +++ b/locale/localeconv.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" .\" From @(#)setlocale.3 8.1 (Berkeley) 6/9/93 .\" From FreeBSD: src/lib/libc/locale/setlocale.3,v 1.28 2003/11/15 02:26:04 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/localeconv.3,v 1.2 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/localeconv.3,v 1.3 2007/01/09 00:28:00 imp Exp $ .\" .Dd November 21, 2003 .Dt LOCALECONV 3 diff --git a/locale/mblen.3 b/locale/mblen.3 index d6fa0de..c3530e1 100644 --- a/locale/mblen.3 +++ b/locale/mblen.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/mblen.3,v 1.5 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/mblen.3,v 1.6 2007/01/09 00:28:00 imp Exp $ .\" .Dd April 11, 2004 .Dt MBLEN 3 diff --git a/locale/mblocal.h b/locale/mblocal.h index 53d9464..f5d3fc1 100644 --- a/locale/mblocal.h +++ b/locale/mblocal.h @@ -23,24 +23,38 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/lib/libc/locale/mblocal.h,v 1.4 2004/10/17 06:51:50 tjr Exp $ + * $FreeBSD: src/lib/libc/locale/mblocal.h,v 1.7 2008/01/21 23:48:12 ache Exp $ */ #ifndef _MBLOCAL_H_ #define _MBLOCAL_H_ +#include + /* - * Conversion functions for "NONE"/C/POSIX encoding. + * Rune initialization function prototypes. */ -extern size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, - size_t, mbstate_t * __restrict, locale_t); -extern int _none_mbsinit(const mbstate_t *, locale_t); -extern size_t _none_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, - size_t, size_t, mbstate_t * __restrict, locale_t); -extern size_t _none_wcrtomb(char * __restrict, wchar_t, - mbstate_t * __restrict, locale_t); -extern size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, - size_t, size_t, mbstate_t * __restrict, locale_t); +__private_extern__ int _none_init(struct __xlocale_st_runelocale *); +__private_extern__ int _ascii_init(struct __xlocale_st_runelocale *); +__private_extern__ int _UTF2_init(struct __xlocale_st_runelocale *); +__private_extern__ int _UTF8_init(struct __xlocale_st_runelocale *); +__private_extern__ int _EUC_init(struct __xlocale_st_runelocale *); +__private_extern__ int _GB18030_init(struct __xlocale_st_runelocale *); +__private_extern__ int _GB2312_init(struct __xlocale_st_runelocale *); +__private_extern__ int _GBK_init(struct __xlocale_st_runelocale *); +__private_extern__ int _BIG5_init(struct __xlocale_st_runelocale *); +__private_extern__ int _MSKanji_init(struct __xlocale_st_runelocale *); + +__private_extern__ size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t); +__private_extern__ int _none_mbsinit(const mbstate_t *, locale_t); +__private_extern__ size_t _none_mbsnrtowcs(wchar_t * __restrict dst, + const char ** __restrict src, size_t nms, size_t len, + mbstate_t * __restrict ps __unused, locale_t); +__private_extern__ size_t _none_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); +__private_extern__ size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict, locale_t); extern size_t __mbsnrtowcs_std(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict, locale_t); diff --git a/locale/mbsrtowcs.3 b/locale/mbsrtowcs.3 index cd22deb..ff6e699 100644 --- a/locale/mbsrtowcs.3 +++ b/locale/mbsrtowcs.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/mbsrtowcs.3,v 1.5 2004/07/21 10:54:57 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/mbsrtowcs.3,v 1.6 2005/01/11 20:50:49 ru Exp $ .Dd July 21, 2004 .Dt MBSRTOWCS 3 .Os @@ -121,7 +121,7 @@ function behaves identically to .Fn mbsrtowcs , except that conversion stops after reading at most .Fa nms -bytes from the buffer pointed to by +bytes from the buffer pointed to by .Fa src . .Pp While the diff --git a/locale/mbstowcs-fbsd.c b/locale/mbstowcs-fbsd.c index 73b0392..80bc4fe 100644 --- a/locale/mbstowcs-fbsd.c +++ b/locale/mbstowcs-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/mbstowcs.c,v 1.11 2004/07/21 10:54:57 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/mbstowcs.c,v 1.12 2009/01/15 18:53:52 rdivacky Exp $"); #include "xlocale_private.h" @@ -40,10 +40,12 @@ mbstowcs_l(wchar_t * __restrict pwcs, const char * __restrict s, size_t n, { static const mbstate_t initial; mbstate_t mbs; + const char *sp; NORMALIZE_LOCALE(loc); mbs = initial; - return (loc->__lc_ctype->__mbsnrtowcs(pwcs, &s, SIZE_T_MAX, n, &mbs, loc)); + sp = s; + return (loc->__lc_ctype->__mbsnrtowcs(pwcs, &sp, SIZE_T_MAX, n, &mbs, loc)); } size_t diff --git a/locale/mbstowcs.3 b/locale/mbstowcs.3 index 1517a9c..9e52e79 100644 --- a/locale/mbstowcs.3 +++ b/locale/mbstowcs.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/mbstowcs.3,v 1.4 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/mbstowcs.3,v 1.5 2007/01/09 00:28:00 imp Exp $ .\" .Dd April 8, 2004 .Dt MBSTOWCS 3 diff --git a/locale/mbtowc.3 b/locale/mbtowc.3 index ff6f3b3..b4ec676 100644 --- a/locale/mbtowc.3 +++ b/locale/mbtowc.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/mbtowc.3,v 1.4 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/mbtowc.3,v 1.5 2007/01/09 00:28:00 imp Exp $ .\" .Dd April 11, 2004 .Dt MBTOWC 3 diff --git a/locale/mskanji-fbsd.c b/locale/mskanji-fbsd.c index 1fb7232..3bf9a4d 100644 --- a/locale/mskanji-fbsd.c +++ b/locale/mskanji-fbsd.c @@ -37,11 +37,11 @@ static char sccsid[] = "@(#)mskanji.c 1.0 (Phase One) 5/5/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/mskanji.c,v 1.16 2004/05/14 15:40:47 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/mskanji.c,v 1.18 2007/10/13 16:28:22 ache Exp $"); #include "xlocale_private.h" -#include +#include #include #include #include @@ -49,11 +49,11 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/mskanji.c,v 1.16 2004/05/14 15:40:47 tjr #include #include "mblocal.h" -__private_extern__ int _MSKanji_init(struct __xlocale_st_runelocale *); -static size_t _MSKanji_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict, locale_t); +static size_t _MSKanji_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t); static int _MSKanji_mbsinit(const mbstate_t *, locale_t); -static size_t _MSKanji_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); +static size_t _MSKanji_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); typedef struct { wchar_t ch; @@ -67,11 +67,12 @@ _MSKanji_init(struct __xlocale_st_runelocale *xrl) xrl->__wcrtomb = _MSKanji_wcrtomb; xrl->__mbsinit = _MSKanji_mbsinit; xrl->__mb_cur_max = 2; + xrl->__mb_sb_limit = 256; return (0); } static int -_MSKanji_mbsinit(const mbstate_t *ps, locale_t loc) +_MSKanji_mbsinit(const mbstate_t *ps, locale_t loc __unused) { return (ps == NULL || ((const _MSKanjiState *)ps)->ch == 0); @@ -79,7 +80,7 @@ _MSKanji_mbsinit(const mbstate_t *ps, locale_t loc) static size_t _MSKanji_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps, locale_t loc) + mbstate_t * __restrict ps, locale_t loc __unused) { _MSKanjiState *ms; wchar_t wc; @@ -136,7 +137,7 @@ _MSKanji_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } static size_t -_MSKanji_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +_MSKanji_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc __unused) { _MSKanjiState *ms; int len, i; diff --git a/locale/nextwctype.3 b/locale/nextwctype.3 index 59e80fd..d2b959f 100644 --- a/locale/nextwctype.3 +++ b/locale/nextwctype.3 @@ -23,9 +23,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/nextwctype.3,v 1.1 2004/07/08 06:43:37 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/nextwctype.3,v 1.3 2005/07/21 10:27:45 tjr Exp $ .\" -.Dd July 8, 2004 +.Dd July 21, 2005 .Dt NEXTWCTYPE 3 .Os .Sh NAME @@ -37,14 +37,10 @@ .Sh SYNOPSIS .In wctype.h .Ft wint_t -.Fo nextwctype -.Fa "wint_t ch" "wctype_t wct" -.Fc +.Fn nextwctype "wint_t ch" "wctype_t wct" .In xlocale.h .Ft wint_t -.Fo nextwctype_l -.Fa "wint_t ch" "wctype_t wct" "locale_t loc" -.Fc +.Fn nextwctype_l "wint_t ch" "wctype_t wct" "locale_t loc" .Sh DESCRIPTION The .Fn nextwctype @@ -60,14 +56,25 @@ is \-1, the search begins at the first member of While the .Fn nextwctype function uses the current locale, the -.Fn nextwctype_l + .Fn nextwctype_l function may be passed a locale directly. See .Xr xlocale 3 for more information. .Sh RETURN VALUES The .Fn nextwctype -functions returns the next character, or \-1 if there are no more. +function returns the next character, or \-1 if there are no more. +.Sh COMPATIBILITY +This function is a non-standard +.Fx +extension and should not be used where the standard +.Fn iswctype +function would suffice. .Sh SEE ALSO .Xr wctype 3 , .Xr xlocale 3 +.Sh HISTORY +The +.Fn nextwctype +function appeared in +.Fx 5.4 . diff --git a/locale/nl_langinfo.3 b/locale/nl_langinfo.3 index 13125b2..3d846de 100644 --- a/locale/nl_langinfo.3 +++ b/locale/nl_langinfo.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/nl_langinfo.3,v 1.5 2003/09/08 19:57:14 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/nl_langinfo.3,v 1.7 2009/11/16 14:33:31 brueffer Exp $ .\" .Dd May 3, 2001 .Dt NL_LANGINFO 3 @@ -64,6 +64,17 @@ or to the category .Dv LC_ALL , may overwrite the buffer pointed to by the return value. +.Sh RETURN VALUES +In a locale where langinfo data is not defined, +.Fn nl_langinfo +returns a pointer to the corresponding string in the +.Tn POSIX +locale. +In all locales, +.Fn nl_langinfo +returns a pointer to an empty string if +.Fa item +contains an invalid setting. .Sh EXAMPLES For example: .Pp @@ -83,17 +94,6 @@ function uses the current locale, the function may be passed a locale directly. See .Xr xlocale 3 for more information. -.Sh RETURN VALUES -In a locale where langinfo data is not defined, -.Fn nl_langinfo -returns a pointer to the corresponding string in the -.Tn POSIX -locale. -In all locales, -.Fn nl_langinfo -returns a pointer to an empty string if -.Fa item -contains an invalid setting. .Sh SEE ALSO .Xr setlocale 3 , .Xr xlocale 3 diff --git a/locale/none-fbsd.c b/locale/none-fbsd.c index baad0c9..c3c75cf 100644 --- a/locale/none-fbsd.c +++ b/locale/none-fbsd.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -39,7 +35,7 @@ static char sccsid[] = "@(#)none.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.12 2004/07/21 10:54:57 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.15 2007/10/13 16:28:22 ache Exp $"); #include "xlocale_private.h" @@ -53,16 +49,10 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.12 2004/07/21 10:54:57 tjr Ex #include #include "mblocal.h" -__private_extern__ int _none_init(struct __xlocale_st_runelocale *); -__private_extern__ size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict, locale_t); -__private_extern__ int _none_mbsinit(const mbstate_t *, locale_t); -__private_extern__ size_t _none_mbsnrtowcs(wchar_t * __restrict dst, - const char ** __restrict src, size_t nms, size_t len, - mbstate_t * __restrict ps __unused, locale_t); -__private_extern__ size_t _none_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); -__private_extern__ size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, - size_t, size_t, mbstate_t * __restrict, locale_t); +/* setup defaults */ + +int __mb_cur_max = 1; +int __mb_sb_limit = 256; /* Expected to be <= _CACHED_RUNES */ __private_extern__ int _none_init(struct __xlocale_st_runelocale *xrl) @@ -74,11 +64,12 @@ _none_init(struct __xlocale_st_runelocale *xrl) xrl->__wcrtomb = _none_wcrtomb; xrl->__wcsnrtombs = _none_wcsnrtombs; xrl->__mb_cur_max = 1; + xrl->__mb_sb_limit = 256; return(0); } __private_extern__ int -_none_mbsinit(const mbstate_t *ps __unused, locale_t loc) +_none_mbsinit(const mbstate_t *ps __unused, locale_t loc __unused) { /* @@ -90,7 +81,7 @@ _none_mbsinit(const mbstate_t *ps __unused, locale_t loc) __private_extern__ size_t _none_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, - mbstate_t * __restrict ps __unused, locale_t loc) + mbstate_t * __restrict ps __unused, locale_t loc __unused) { if (s == NULL) @@ -106,7 +97,7 @@ _none_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, __private_extern__ size_t _none_wcrtomb(char * __restrict s, wchar_t wc, - mbstate_t * __restrict ps __unused, locale_t loc) + mbstate_t * __restrict ps __unused, locale_t loc __unused) { if (s == NULL) @@ -122,7 +113,7 @@ _none_wcrtomb(char * __restrict s, wchar_t wc, __private_extern__ size_t _none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, - size_t nms, size_t len, mbstate_t * __restrict ps __unused, locale_t loc) + size_t nms, size_t len, mbstate_t * __restrict ps __unused, locale_t loc __unused) { const char *s; size_t nchr; @@ -147,7 +138,7 @@ _none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, __private_extern__ size_t _none_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, - size_t nwc, size_t len, mbstate_t * __restrict ps __unused, locale_t loc) + size_t nwc, size_t len, mbstate_t * __restrict ps __unused, locale_t loc __unused) { const wchar_t *s; size_t nchr; diff --git a/locale/rune-fbsd.c b/locale/rune-fbsd.c index 34293fe..5963761 100644 --- a/locale/rune-fbsd.c +++ b/locale/rune-fbsd.c @@ -46,8 +46,10 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/rune.c,v 1.12 2004/07/29 06:16:19 tjr Ex #include "namespace.h" #include #include -#endif /* !RUNEOFF32 */ #include +#else +#include "runetype.h" +#endif /* !RUNEOFF32 */ #include #ifndef RUNEOFF32 #include diff --git a/locale/runetype-fbsd.c b/locale/runetype-fbsd.c index 1a9db15..6ffcf72 100644 --- a/locale/runetype-fbsd.c +++ b/locale/runetype-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,17 +31,16 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/runetype.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/runetype.c,v 1.14 2007/01/09 00:28:00 imp Exp $"); #include "xlocale_private.h" +#include #include #include unsigned long -___runetype_l(c, loc) - __ct_rune_t c; - locale_t loc; +___runetype_l(__ct_rune_t c, locale_t loc) { size_t lim; _RuneRange *rr; @@ -75,8 +70,7 @@ ___runetype_l(c, loc) } unsigned long -___runetype(c) - __ct_rune_t c; +___runetype(__ct_rune_t c) { return ___runetype_l(c, __current_locale()); } diff --git a/locale/setlocale-fbsd.c b/locale/setlocale-fbsd.c index 61909b9..9729e54 100644 --- a/locale/setlocale-fbsd.c +++ b/locale/setlocale-fbsd.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -39,7 +35,7 @@ static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.50 2004/01/31 19:15:32 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.51 2007/01/09 00:28:00 imp Exp $"); #include "xlocale_private.h" diff --git a/locale/setlocale.3 b/locale/setlocale.3 index dcbd333..6d3be03 100644 --- a/locale/setlocale.3 +++ b/locale/setlocale.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setlocale.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/locale/setlocale.3,v 1.33 2004/10/17 06:51:50 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/setlocale.3,v 1.35 2007/01/09 00:28:00 imp Exp $ .\" .Dd November 21, 2003 .Dt SETLOCALE 3 @@ -146,8 +142,6 @@ if the given combination of and .Fa locale makes no sense. -.Sh ERRORS -No errors are defined. .Sh FILES .Bl -tag -width /usr/share/locale/locale/category -compact .It Pa $PATH_LOCALE/ Ns Em locale/category @@ -157,6 +151,8 @@ locale file for the locale and the category .Em category . .El +.Sh ERRORS +No errors are defined. .Sh SEE ALSO .Xr colldef 1 , .Xr mklocale 1 , diff --git a/locale/setrunelocale-fbsd.c b/locale/setrunelocale-fbsd.c index ec7bbb1..fbb2275 100644 --- a/locale/setrunelocale-fbsd.c +++ b/locale/setrunelocale-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.44 2004/10/18 02:06:18 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.51 2008/01/23 03:05:35 ache Exp $"); #include "xlocale_private.h" @@ -51,22 +47,13 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.44 2004/10/18 02:06: #include "mblocal.h" #include "setlocale.h" -extern int _none_init(struct __xlocale_st_runelocale *); -extern int _UTF8_init(struct __xlocale_st_runelocale *); -extern int _EUC_init(struct __xlocale_st_runelocale *); -extern int _GB18030_init(struct __xlocale_st_runelocale *); -extern int _GB2312_init(struct __xlocale_st_runelocale *); -extern int _GBK_init(struct __xlocale_st_runelocale *); -extern int _BIG5_init(struct __xlocale_st_runelocale *); -extern int _MSKanji_init(struct __xlocale_st_runelocale *); -extern int _UTF2_init(struct __xlocale_st_runelocale *); /* deprecated */ extern struct __xlocale_st_runelocale *_Read_RuneMagi(FILE *); -#ifdef LEGACY_RUNE_APIS +#ifdef UNIFDEF_LEGACY_RUNE_APIS /* depreciated interfaces */ rune_t sgetrune(const char *, size_t, char const **); int sputrune(rune_t, char *, size_t, char **); -#endif /* LEGACY_RUNE_APIS */ +#endif /* UNIFDEF_LEGACY_RUNE_APIS */ __private_extern__ int __setrunelocale(const char *encoding, locale_t loc) @@ -78,6 +65,7 @@ __setrunelocale(const char *encoding, locale_t loc) int saverr, ret; static struct __xlocale_st_runelocale *CachedRuneLocale; extern int __mb_cur_max; + extern int __mb_sb_limit; static pthread_lock_t cache_lock = LOCK_INITIALIZER; /* @@ -90,6 +78,7 @@ __setrunelocale(const char *encoding, locale_t loc) if (loc == &__global_locale) { _CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale; __mb_cur_max = loc->__lc_ctype->__mb_cur_max; + __mb_sb_limit = loc->__lc_ctype->__mb_sb_limit; } return (0); } @@ -106,6 +95,7 @@ __setrunelocale(const char *encoding, locale_t loc) if (loc == &__global_locale) { _CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale; __mb_cur_max = loc->__lc_ctype->__mb_cur_max; + __mb_sb_limit = loc->__lc_ctype->__mb_sb_limit; } UNLOCK(cache_lock); return (0); @@ -140,22 +130,24 @@ __setrunelocale(const char *encoding, locale_t loc) rl = &xrl->_CurrentRuneLocale; -#ifdef LEGACY_RUNE_APIS +#ifdef UNIFDEF_LEGACY_RUNE_APIS /* provide backwards compatibility (depreciated interface) */ rl->__sputrune = sputrune; rl->__sgetrune = sgetrune; -#else /* LEGACY_RUNE_APIS */ +#else /* UNIFDEF_LEGACY_RUNE_APIS */ rl->__sputrune = NULL; rl->__sgetrune = NULL; -#endif /* LEGACY_RUNE_APIS */ +#endif /* UNIFDEF_LEGACY_RUNE_APIS */ if (strcmp(rl->__encoding, "NONE") == 0) ret = _none_init(xrl); + else if (strcmp(rl->__encoding, "ASCII") == 0) + ret = _ascii_init(xrl); else if (strcmp(rl->__encoding, "UTF-8") == 0) ret = _UTF8_init(xrl); else if (strcmp(rl->__encoding, "EUC") == 0) ret = _EUC_init(xrl); - else if (strcmp(rl->__encoding, "GB18030") == 0) + else if (strcmp(rl->__encoding, "GB18030") == 0) ret = _GB18030_init(xrl); else if (strcmp(rl->__encoding, "GB2312") == 0) ret = _GB2312_init(xrl); @@ -169,6 +161,7 @@ __setrunelocale(const char *encoding, locale_t loc) ret = _UTF2_init(xrl); else ret = EFTYPE; + if (ret == 0) { (void)strcpy(xrl->__ctype_encoding, encoding); XL_RELEASE(loc->__lc_ctype); @@ -176,6 +169,7 @@ __setrunelocale(const char *encoding, locale_t loc) if (loc == &__global_locale) { _CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale; __mb_cur_max = loc->__lc_ctype->__mb_cur_max; + __mb_sb_limit = loc->__lc_ctype->__mb_sb_limit; } LOCK(cache_lock); XL_RELEASE(CachedRuneLocale); @@ -188,7 +182,7 @@ __setrunelocale(const char *encoding, locale_t loc) return (ret); } -#ifdef LEGACY_RUNE_APIS +#ifdef UNIFDEF_LEGACY_RUNE_APIS int setrunelocale(const char *encoding) { @@ -199,7 +193,7 @@ setrunelocale(const char *encoding) XL_UNLOCK(&__global_locale); return ret; } -#endif /* LEGACY_RUNE_APIS */ +#endif /* UNIFDEF_LEGACY_RUNE_APIS */ __private_extern__ int __wrap_setrunelocale(const char *locale, locale_t loc) diff --git a/locale/table-fbsd.c b/locale/table-fbsd.c index d2c3c44..667b846 100644 --- a/locale/table-fbsd.c +++ b/locale/table-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)table.c 8.1 (Berkeley) 6/27/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/table.c,v 1.26 2004/10/17 06:51:50 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/table.c,v 1.28 2007/01/09 00:28:00 imp Exp $"); #include "xlocale_private.h" @@ -48,7 +44,7 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/table.c,v 1.26 2004/10/17 06:51:50 tjr E #include "mblocal.h" /* _DefaultRuneLocale is depreciated; _DefaultRuneXLocale is used instead */ -_RuneLocale _DefaultRuneLocale = { +_RuneLocale _DefaultRuneLocale __attribute__((section("__DATA,__constrw"))) = { _RUNE_MAGIC_A, "NONE", NULL, @@ -252,11 +248,12 @@ _RuneLocale _DefaultRuneLocale = { }, }; -__private_extern__ struct __xlocale_st_runelocale _DefaultRuneXLocale = { +__private_extern__ struct __xlocale_st_runelocale _DefaultRuneXLocale __attribute__((section("__DATA,__constrw"))) = { 0, XPERMANENT, "C", 1, + 256, _none_mbrtowc, _none_mbsinit, _none_mbsnrtowcs, @@ -469,5 +466,3 @@ __private_extern__ struct __xlocale_st_runelocale _DefaultRuneXLocale = { }; _RuneLocale *_CurrentRuneLocale = &_DefaultRuneXLocale._CurrentRuneLocale; - -int __mb_cur_max = 1; diff --git a/locale/tolower-fbsd.c b/locale/tolower-fbsd.c index 4785d18..298b321 100644 --- a/locale/tolower-fbsd.c +++ b/locale/tolower-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,10 +31,11 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/tolower.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); - +__FBSDID("$FreeBSD: src/lib/libc/locale/tolower.c,v 1.13 2007/01/09 00:28:01 imp Exp $"); + #include "xlocale_private.h" +#include #include #include diff --git a/locale/tolower.3 b/locale/tolower.3 index 1121caf..0ac4aba 100644 --- a/locale/tolower.3 +++ b/locale/tolower.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)tolower.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/tolower.3,v 1.16 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/tolower.3,v 1.21 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt TOLOWER 3 .Os .Sh NAME @@ -63,13 +59,8 @@ The .Fn tolower function converts an upper-case letter to the corresponding lower-case letter. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . .Pp @@ -98,7 +89,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr islower 3 , -.Xr multibyte 3 , .Xr towlower 3 , .Xr xlocale 3 .Sh STANDARDS diff --git a/locale/toupper-fbsd.c b/locale/toupper-fbsd.c index a19ce98..d02ddd6 100644 --- a/locale/toupper-fbsd.c +++ b/locale/toupper-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,10 +31,11 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/toupper.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); - +__FBSDID("$FreeBSD: src/lib/libc/locale/toupper.c,v 1.13 2007/01/09 00:28:01 imp Exp $"); + #include "xlocale_private.h" +#include #include #include diff --git a/locale/toupper.3 b/locale/toupper.3 index 12b67bb..5b196a9 100644 --- a/locale/toupper.3 +++ b/locale/toupper.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)toupper.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/toupper.3,v 1.16 2004/08/21 07:37:08 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/toupper.3,v 1.21 2009/09/04 07:44:58 des Exp $ .\" -.Dd August 21, 2004 +.Dd July 17, 2005 .Dt TOUPPER 3 .Os .Sh NAME @@ -63,13 +59,8 @@ The .Fn toupper function converts a lower-case letter to the corresponding upper-case letter. -For single C -.Va char Ns s -locales (see -.Xr multibyte 3 ) , -the value of the argument is -representable as an -.Li unsigned char +The argument must be representable as an +.Vt "unsigned char" or the value of .Dv EOF . .Pp @@ -98,7 +89,6 @@ function should be used instead. .Sh SEE ALSO .Xr ctype 3 , .Xr isupper 3 , -.Xr multibyte 3 , .Xr towupper 3 , .Xr xlocale 3 .Sh STANDARDS diff --git a/locale/towlower.3 b/locale/towlower.3 index b4e25e3..248d5b1 100644 --- a/locale/towlower.3 +++ b/locale/towlower.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)tolower.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/towlower.3,v 1.5 2002/11/29 17:35:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/towlower.3,v 1.6 2007/01/09 00:28:01 imp Exp $ .\" .Dd October 3, 2002 .Dt TOWLOWER 3 diff --git a/locale/towupper.3 b/locale/towupper.3 index 87a85df..5df8bb0 100644 --- a/locale/towupper.3 +++ b/locale/towupper.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)toupper.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/towupper.3,v 1.2 2002/11/29 17:35:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/towupper.3,v 1.3 2007/01/09 00:28:01 imp Exp $ .\" .Dd October 3, 2002 .Dt TOWUPPER 3 diff --git a/locale/utf2-fbsd.c b/locale/utf2-fbsd.c index 53fa1f5..0e00131 100644 --- a/locale/utf2-fbsd.c +++ b/locale/utf2-fbsd.c @@ -25,8 +25,7 @@ */ #include -/* dumb down UTF-8 to do UTF2 */ -__FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.11 2004/07/27 06:29:48 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.16 2007/10/15 09:51:30 ache Exp $"); #include "xlocale_private.h" @@ -40,14 +39,16 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.11 2004/07/27 06:29:48 tjr Ex #define UTF2_MB_CUR_MAX 3 -static size_t _UTF2_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict, locale_t); +static size_t _UTF2_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t); static int _UTF2_mbsinit(const mbstate_t *, locale_t); -static size_t _UTF2_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, - size_t, size_t, mbstate_t * __restrict, locale_t); -static size_t _UTF2_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); +static size_t _UTF2_mbsnrtowcs(wchar_t * __restrict, + const char ** __restrict, size_t, size_t, + mbstate_t * __restrict, locale_t); +static size_t _UTF2_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); static size_t _UTF2_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, - size_t, size_t, mbstate_t * __restrict, locale_t); + size_t, size_t, mbstate_t * __restrict, locale_t); typedef struct { wchar_t ch; @@ -65,6 +66,12 @@ _UTF2_init(struct __xlocale_st_runelocale *xrl) xrl->__mbsnrtowcs = _UTF2_mbsnrtowcs; xrl->__wcsnrtombs = _UTF2_wcsnrtombs; xrl->__mb_cur_max = UTF2_MB_CUR_MAX; + /* + * UCS-4 encoding used as the internal representation, so + * slots 0x0080-0x00FF are occuped and must be excluded + * from the single byte ctype by setting the limit. + */ + xrl->__mb_sb_limit = 128; return (0); } @@ -86,7 +93,7 @@ _UTF2_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, us = (_UTF2State *)ps; - if (us->want < 0 || us->want > 3) { + if (us->want < 0 || us->want > 6) { errno = EINVAL; return ((size_t)-1); } @@ -371,7 +378,7 @@ _UTF2_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, *dst = *s; } else if (len > (size_t)UTF2_MB_CUR_MAX) { /* Enough space to translate in-place. */ - if ((nb = (int)_UTF2_wcrtomb(dst, *s, ps, loc)) < 0) { + if ((nb = _UTF2_wcrtomb(dst, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } @@ -379,7 +386,7 @@ _UTF2_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, /* * May not be enough space; use temp. buffer. */ - if ((nb = (int)_UTF2_wcrtomb(buf, *s, ps, loc)) < 0) { + if ((nb = _UTF2_wcrtomb(buf, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } diff --git a/locale/utf8-fbsd.c b/locale/utf8-fbsd.c index cd5d052..97515df 100644 --- a/locale/utf8-fbsd.c +++ b/locale/utf8-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.11 2004/07/27 06:29:48 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.16 2007/10/15 09:51:30 ache Exp $"); #include "xlocale_private.h" @@ -39,14 +39,16 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.11 2004/07/27 06:29:48 tjr Ex #define UTF8_MB_CUR_MAX 6 -static size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, - mbstate_t * __restrict, locale_t); +static size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t); static int _UTF8_mbsinit(const mbstate_t *, locale_t); -static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, - size_t, size_t, mbstate_t * __restrict, locale_t); -static size_t _UTF8_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); +static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, + const char ** __restrict, size_t, size_t, + mbstate_t * __restrict, locale_t); +static size_t _UTF8_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); static size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, - size_t, size_t, mbstate_t * __restrict, locale_t); + size_t, size_t, mbstate_t * __restrict, locale_t); typedef struct { wchar_t ch; @@ -64,6 +66,12 @@ _UTF8_init(struct __xlocale_st_runelocale *xrl) xrl->__mbsnrtowcs = _UTF8_mbsnrtowcs; xrl->__wcsnrtombs = _UTF8_wcsnrtombs; xrl->__mb_cur_max = UTF8_MB_CUR_MAX; + /* + * UCS-4 encoding used as the internal representation, so + * slots 0x0080-0x00FF are occuped and must be excluded + * from the single byte ctype by setting the limit. + */ + xrl->__mb_sb_limit = 128; return (0); } @@ -141,7 +149,7 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mask = 0x03; want = 5; lbound = 0x200000; - } else if ((ch & 0xfc) == 0xfc) { + } else if ((ch & 0xfe) == 0xfc) { mask = 0x01; want = 6; lbound = 0x4000000; @@ -391,7 +399,7 @@ _UTF8_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, *dst = *s; } else if (len > (size_t)UTF8_MB_CUR_MAX) { /* Enough space to translate in-place. */ - if ((nb = (int)_UTF8_wcrtomb(dst, *s, ps, loc)) < 0) { + if ((nb = _UTF8_wcrtomb(dst, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } @@ -399,7 +407,7 @@ _UTF8_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, /* * May not be enough space; use temp. buffer. */ - if ((nb = (int)_UTF8_wcrtomb(buf, *s, ps, loc)) < 0) { + if ((nb = _UTF8_wcrtomb(buf, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } diff --git a/locale/wcsftime-fbsd.c b/locale/wcsftime-fbsd.c index bf413e1..ddf989a 100644 --- a/locale/wcsftime-fbsd.c +++ b/locale/wcsftime-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcsftime.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcsftime.c,v 1.6 2009/01/15 20:45:59 rdivacky Exp $"); #include "xlocale_private.h" @@ -55,7 +55,9 @@ wcsftime_l(wchar_t * __restrict wcs, size_t maxsize, { static const mbstate_t initial; mbstate_t mbs; - char *dst, *dstp, *sformat; + char *dst, *sformat; + const char *dstp; + const wchar_t *formatp; size_t n, sflen; int sverrno; @@ -67,13 +69,14 @@ wcsftime_l(wchar_t * __restrict wcs, size_t maxsize, * for strftime(), which only handles single-byte characters. */ mbs = initial; - sflen = wcsrtombs_l(NULL, &format, 0, &mbs, loc); + formatp = format; + sflen = wcsrtombs_l(NULL, &formatp, 0, &mbs, loc); if (sflen == (size_t)-1) goto error; if ((sformat = malloc(sflen + 1)) == NULL) goto error; mbs = initial; - wcsrtombs_l(sformat, &format, sflen + 1, &mbs, loc); + wcsrtombs_l(sformat, &formatp, sflen + 1, &mbs, loc); /* * Allocate memory for longest multibyte sequence that will fit @@ -92,7 +95,7 @@ wcsftime_l(wchar_t * __restrict wcs, size_t maxsize, goto error; dstp = dst; mbs = initial; - n = mbsrtowcs_l(wcs, (const char **)&dstp, maxsize, &mbs, loc); + n = mbsrtowcs_l(wcs, &dstp, maxsize, &mbs, loc); if (n == (size_t)-2 || n == (size_t)-1 || dstp != NULL) goto error; diff --git a/locale/wcsnrtombs-fbsd.c b/locale/wcsnrtombs-fbsd.c index 7c58c2f..adc29a1 100644 --- a/locale/wcsnrtombs-fbsd.c +++ b/locale/wcsnrtombs-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcsnrtombs.c,v 1.2 2004/07/22 02:57:29 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcsnrtombs.c,v 1.3 2005/02/12 08:45:12 stefanf Exp $"); #include "xlocale_private.h" @@ -84,7 +84,7 @@ __wcsnrtombs_std(char * __restrict dst, const wchar_t ** __restrict src, while (len > 0 && nwc-- > 0) { if (len > (size_t)mb_cur_max) { /* Enough space to translate in-place. */ - if ((nb = (int)__wcrtomb(dst, *s, ps, loc)) < 0) { + if ((nb = __wcrtomb(dst, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } @@ -97,7 +97,7 @@ __wcsnrtombs_std(char * __restrict dst, const wchar_t ** __restrict src, * character is too long for the buffer. */ mbsbak = *ps; - if ((nb = (int)__wcrtomb(buf, *s, ps, loc)) < 0) { + if ((nb = __wcrtomb(buf, *s, ps, loc)) == (size_t)-1) { *src = s; return ((size_t)-1); } diff --git a/locale/wcstoimax-fbsd.c b/locale/wcstoimax-fbsd.c index b46c8d3..9c3dc3d 100644 --- a/locale/wcstoimax-fbsd.c +++ b/locale/wcstoimax-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "from @(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoimax.c,v 1.8 2002/09/06 11:23:59 tjr Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoimax.c,v 1.2 2003/01/01 18:48:43 schweikh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoimax.c,v 1.3 2007/01/09 00:28:01 imp Exp $"); #include "xlocale_private.h" diff --git a/locale/wcstol-fbsd.c b/locale/wcstol-fbsd.c index 2aadd10..2509e55 100644 --- a/locale/wcstol-fbsd.c +++ b/locale/wcstol-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -32,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstol.c,v 1.1 2002/09/08 13:27:26 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstol.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); #include "xlocale_private.h" diff --git a/locale/wcstoll-fbsd.c b/locale/wcstoll-fbsd.c index f2b9f00..af50ca8 100644 --- a/locale/wcstoll-fbsd.c +++ b/locale/wcstoll-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.19 2002/09/06 11:23:59 tjr Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoll.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoll.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); #include "xlocale_private.h" diff --git a/locale/wcstombs-fbsd.c b/locale/wcstombs-fbsd.c index 034b64f..a6d9ae3 100644 --- a/locale/wcstombs-fbsd.c +++ b/locale/wcstombs-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstombs.c,v 1.10 2004/07/21 10:54:57 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstombs.c,v 1.11 2009/01/15 18:53:52 rdivacky Exp $"); #include "xlocale_private.h" @@ -40,10 +40,12 @@ wcstombs_l(char * __restrict s, const wchar_t * __restrict pwcs, size_t n, { static const mbstate_t initial; mbstate_t mbs; + const wchar_t *pwcsp; NORMALIZE_LOCALE(loc); mbs = initial; - return (loc->__lc_ctype->__wcsnrtombs(s, &pwcs, SIZE_T_MAX, n, &mbs, loc)); + pwcsp = pwcs; + return (loc->__lc_ctype->__wcsnrtombs(s, &pwcsp, SIZE_T_MAX, n, &mbs, loc)); } size_t diff --git a/locale/wcstombs.3 b/locale/wcstombs.3 index b197803..24c4b61 100644 --- a/locale/wcstombs.3 +++ b/locale/wcstombs.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/wcstombs.3,v 1.4 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/wcstombs.3,v 1.5 2007/01/09 00:28:01 imp Exp $ .\" .Dd April 8, 2004 .Dt WCSTOMBS 3 diff --git a/locale/wcstoul-fbsd.c b/locale/wcstoul-fbsd.c index 270ad7c..1cad0f6 100644 --- a/locale/wcstoul-fbsd.c +++ b/locale/wcstoul-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -32,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoul.c,v 1.1 2002/09/08 13:27:26 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoul.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); #include "xlocale_private.h" diff --git a/locale/wcstoull-fbsd.c b/locale/wcstoull-fbsd.c index c20ffac..474480e 100644 --- a/locale/wcstoull-fbsd.c +++ b/locale/wcstoull-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.18 2002/09/06 11:23:59 tjr Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoull.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoull.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); #include "xlocale_private.h" diff --git a/locale/wcstoumax-fbsd.c b/locale/wcstoumax-fbsd.c index d8c75a4..1b447b8 100644 --- a/locale/wcstoumax-fbsd.c +++ b/locale/wcstoumax-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "from @(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoumax.c,v 1.8 2002/09/06 11:23:59 tjr Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoumax.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoumax.c,v 1.2 2007/01/09 00:28:01 imp Exp $"); #include "xlocale_private.h" diff --git a/locale/wctomb.3 b/locale/wctomb.3 index 0efbc55..33f6e37 100644 --- a/locale/wctomb.3 +++ b/locale/wctomb.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp -.\" $FreeBSD: src/lib/libc/locale/wctomb.3,v 1.3 2004/07/05 06:36:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/wctomb.3,v 1.4 2007/01/09 00:28:01 imp Exp $ .\" .Dd April 8, 2004 .Dt WCTOMB 3 diff --git a/locale/wctype-fbsd.c b/locale/wctype-fbsd.c index 0ed47b8..f94c133 100644 --- a/locale/wctype-fbsd.c +++ b/locale/wctype-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wctype.c,v 1.3 2004/03/27 08:59:21 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wctype.c,v 1.4 2008/03/17 18:22:23 antoine Exp $"); #include "xlocale_private.h" @@ -34,34 +34,33 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/wctype.c,v 1.3 2004/03/27 08:59:21 tjr E #include #include -static struct { - const char *name; - wctype_t mask; -} props[] = { - { "alnum", _CTYPE_A|_CTYPE_D }, - { "alpha", _CTYPE_A }, - { "blank", _CTYPE_B }, - { "cntrl", _CTYPE_C }, - { "digit", _CTYPE_D }, - { "graph", _CTYPE_G }, - { "lower", _CTYPE_L }, - { "print", _CTYPE_R }, - { "punct", _CTYPE_P }, - { "space", _CTYPE_S }, - { "upper", _CTYPE_U }, - { "xdigit", _CTYPE_X }, - { "ideogram", _CTYPE_I }, /* BSD extension */ - { "special", _CTYPE_T }, /* BSD extension */ - { "phonogram", _CTYPE_Q }, /* BSD extension */ - { "rune", 0xFFFFFFF0L }, /* BSD extension */ - { NULL, 0UL }, /* Default */ -}; - wctype_t wctype_l(const char *property, locale_t loc) { - int i; _RuneLocale *rl; + static const struct { + const char *name; + wctype_t mask; + } props[] = { + { "alnum", _CTYPE_A|_CTYPE_D }, + { "alpha", _CTYPE_A }, + { "blank", _CTYPE_B }, + { "cntrl", _CTYPE_C }, + { "digit", _CTYPE_D }, + { "graph", _CTYPE_G }, + { "lower", _CTYPE_L }, + { "print", _CTYPE_R }, + { "punct", _CTYPE_P }, + { "space", _CTYPE_S }, + { "upper", _CTYPE_U }, + { "xdigit", _CTYPE_X }, + { "ideogram", _CTYPE_I }, /* BSD extension */ + { "special", _CTYPE_T }, /* BSD extension */ + { "phonogram", _CTYPE_Q }, /* BSD extension */ + { "rune", 0xFFFFFF00L }, /* BSD extension */ + { NULL, 0UL }, /* Default */ + }; + int i; i = 0; while (props[i].name != NULL && strcmp(props[i].name, property) != 0) diff --git a/locale/wctype.3 b/locale/wctype.3 index 6608fe2..5175972 100644 --- a/locale/wctype.3 +++ b/locale/wctype.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/wctype.3,v 1.5 2004/03/27 08:59:21 tjr Exp $ +.\" $FreeBSD: src/lib/libc/locale/wctype.3,v 1.7 2006/10/13 16:11:12 ru Exp $ .\" .Dd March 27, 2004 .Dt WCTYPE 3 @@ -128,6 +128,7 @@ myiswalpha(wint_t wc) .Ed .Sh SEE ALSO .Xr ctype 3 , +.Xr nextwctype 3 , .Xr xlocale 3 .Sh STANDARDS The @@ -138,7 +139,7 @@ functions conform to .St -p1003.1-2001 . The .Dq Li ideogram , -.Dq Li phonogram +.Dq Li phonogram , .Dq Li special , and .Dq Li rune diff --git a/locale/wcwidth-fbsd.c b/locale/wcwidth-fbsd.c index ad9fe56..ae533e7 100644 --- a/locale/wcwidth-fbsd.c +++ b/locale/wcwidth-fbsd.c @@ -18,10 +18,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/wcwidth.c,v 1.7 2004/08/12 12:19:11 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcwidth.c,v 1.8 2007/01/09 00:28:01 imp Exp $"); #include "xlocale_private.h" diff --git a/locale/xlocale.c b/locale/xlocale.c index a43e1cd..c0fa5af 100644 --- a/locale/xlocale.c +++ b/locale/xlocale.c @@ -358,7 +358,7 @@ __numeric_ctype(locale_t loc) loc->__numeric_fp_cvt = LC_NUMERIC_FP_SAME_LOCALE; return loc; } else { - loc->__lc_numeric_loc = newlocale(LC_CTYPE_MASK, numeric, &__c_locale); + loc->__lc_numeric_loc = newlocale(LC_CTYPE_MASK, numeric, (locale_t)&__c_locale); if (loc->__lc_numeric_loc) { loc->__numeric_fp_cvt = LC_NUMERIC_FP_USE_LOCALE; return loc->__lc_numeric_loc; diff --git a/locale/xlocale_private.h b/locale/xlocale_private.h index d08328c..53c5c27 100644 --- a/locale/xlocale_private.h +++ b/locale/xlocale_private.h @@ -71,6 +71,7 @@ struct __xlocale_st_runelocale { __STRUCT_COMMON char __ctype_encoding[ENCODING_LEN + 1]; int __mb_cur_max; + int __mb_sb_limit; size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t, __darwin_mbstate_t * __restrict, struct _xlocale *); int (*__mbsinit)(const __darwin_mbstate_t *, struct _xlocale *); diff --git a/net/FreeBSD/inet.3 b/net/FreeBSD/inet.3 index e1b0c1a..1211e53 100644 --- a/net/FreeBSD/inet.3 +++ b/net/FreeBSD/inet.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)inet.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/net/inet.3,v 1.29 2004/07/02 23:52:11 ru Exp $ +.\" $FreeBSD: src/lib/libc/net/inet.3,v 1.36 2007/06/14 07:13:28 delphij Exp $ .\" -.Dd June 14, 2004 +.Dd June 14, 2007 .Dt INET 3 .Os .Sh NAME @@ -40,6 +36,7 @@ .Nm inet_addr , .Nm inet_network , .Nm inet_ntoa , +.Nm inet_ntoa_r , .Nm inet_ntop , .Nm inet_pton , .Nm inet_makeaddr , @@ -61,6 +58,12 @@ .Fn inet_network "const char *cp" .Ft char * .Fn inet_ntoa "struct in_addr in" +.Ft char * +.Fo inet_ntoa_r +.Fa "struct in_addr in" +.Fa "char *buf" +.Fa "socklen_t size" +.Fc .Ft const char * .Fo inet_ntop .Fa "int af" @@ -94,7 +97,7 @@ as held in a character string) to network format (usually a .Ft struct in_addr or some other internal binary representation, in network byte order). It returns 1 if the address was valid for the specified address family, or -0 if the address wasn't parseable in the specified address family, or -1 +0 if the address was not parseable in the specified address family, or -1 if some system error occurred (in which case .Va errno will have been set). @@ -130,6 +133,11 @@ The .Fa size argument specifies the size, in bytes, of the buffer .Fa *dst . +.Dv INET_ADDRSTRLEN +and +.Dv INET6_ADDRSTRLEN +define the maximum size required to convert an address of the respective +type. It returns NULL if a system error occurs (in which case, .Va errno will have been set), or it returns a pointer to the destination string. @@ -146,6 +154,10 @@ string representing the address in .Ql .\& notation. The routine +.Fn inet_ntoa_r +is the reentrant version of +.Fn inet_ntoa . +The routine .Fn inet_makeaddr takes an Internet network number and a local network address and constructs an Internet address @@ -216,19 +228,6 @@ may be decimal, octal, or hexadecimal, as specified in the C language (i.e., a leading 0x or 0X implies hexadecimal; otherwise, a leading 0 implies octal; otherwise, the number is interpreted as decimal). -.Pp -The -.Fn inet_aton -and -.Fn inet_ntoa -functions are semi-deprecated in favor of the -.Xr addr2ascii 3 -family. -However, since those functions are not yet widely implemented, -portable programs cannot rely on their presence and will continue -to use the -.Xr inet 3 -functions for some time. .Sh DIAGNOSTICS The constant .Dv INADDR_NONE @@ -254,9 +253,10 @@ or family address. .El .Sh SEE ALSO -.Xr addr2ascii 3 , .Xr byteorder 3 , +.Xr getaddrinfo 3 , .Xr gethostbyname 3 , +.Xr getnameinfo 3 , .Xr getnetent 3 , .Xr inet_net 3 , .Xr hosts 5 , @@ -299,5 +299,7 @@ The string returned by .Fn inet_ntoa resides in a static memory area. .Pp -Inet_addr should return a +The +.Fn inet_addr +function should return a .Fa struct in_addr . diff --git a/net/FreeBSD/inet.3.patch b/net/FreeBSD/inet.3.patch index a5f9c04..8f84aa0 100644 --- a/net/FreeBSD/inet.3.patch +++ b/net/FreeBSD/inet.3.patch @@ -1,6 +1,6 @@ ---- inet.3 2004-11-25 11:38:29.000000000 -0800 -+++ inet.3.edit 2006-07-12 11:23:50.000000000 -0700 -@@ -36,50 +36,67 @@ +--- inet.3.bsdnew 2009-11-10 16:23:10.000000000 -0800 ++++ inet.3 2009-11-10 16:35:18.000000000 -0800 +@@ -32,32 +32,51 @@ .Dt INET 3 .Os .Sh NAME @@ -12,6 +12,7 @@ +.Nm inet_netof , .Nm inet_network , .Nm inet_ntoa , + .Nm inet_ntoa_r , .Nm inet_ntop , -.Nm inet_pton , -.Nm inet_makeaddr , @@ -36,8 +37,7 @@ +.Fa "const char *cp" +.Fa "struct in_addr *pin" +.Fc - .Ft in_addr_t --.Fn inet_addr "const char *cp" ++.Ft in_addr_t +.Fo inet_lnaof +.Fa "struct in_addr in" +.Fc @@ -47,11 +47,12 @@ +.Fa "in_addr_t lna" +.Fc .Ft in_addr_t --.Fn inet_network "const char *cp" +-.Fn inet_addr "const char *cp" +.Fo inet_netof +.Fa "struct in_addr in" +.Fc -+.Ft in_addr_t + .Ft in_addr_t +-.Fn inet_network "const char *cp" +.Fo inet_network +.Fa "const char *cp" +.Fc @@ -60,13 +61,10 @@ +.Fo inet_ntoa +.Fa "struct in_addr in" +.Fc - .Ft const char * - .Fo inet_ntop - .Fa "int af" --.Fa "const void * restrict src" --.Fa "char * restrict dst" -+.Fa "const void *restrict src" -+.Fa "char *restrict dst" + .Ft char * + .Fo inet_ntoa_r + .Fa "struct in_addr in" +@@ -72,13 +91,11 @@ .Fa "socklen_t size" .Fc .Ft int @@ -79,18 +77,13 @@ -.Fn inet_netof "struct in_addr in" +.Fo inet_pton +.Fa "int af" -+.Fa "const char *restrict src" -+.Fa "void *restrict dst" ++.Fa "const char * restrict src" ++.Fa "void * restrict dst" +.Fc .Sh DESCRIPTION The routines .Fn inet_aton , --.Fn inet_addr -+.Fn inet_addr , - and - .Fn inet_network - interpret character strings representing -@@ -242,9 +259,6 @@ +@@ -241,9 +258,6 @@ The .Fn inet_ntop call fails if: .Bl -tag -width Er @@ -100,7 +93,7 @@ .It Bq Er EAFNOSUPPORT .Fa *src was not an -@@ -252,13 +266,24 @@ +@@ -251,7 +265,17 @@ was not an or .Dv AF_INET6 family address. @@ -116,12 +109,5 @@ +.Pp +These include files are necessary for all functions. .Sh SEE ALSO - .Xr addr2ascii 3 , .Xr byteorder 3 , - .Xr gethostbyname 3 , - .Xr getnetent 3 , - .Xr inet_net 3 , -+.Xr compat 5 , - .Xr hosts 5 , - .Xr networks 5 - .Rs + .Xr getaddrinfo 3 , diff --git a/net/FreeBSD/inet_net_pton.c b/net/FreeBSD/inet_net_pton.c index 5c6598b..1169e1e 100644 --- a/net/FreeBSD/inet_net_pton.c +++ b/net/FreeBSD/inet_net_pton.c @@ -16,10 +16,10 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.1 2005/04/27 05:00:53 sra Exp $"; +static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.2 2008/08/26 04:42:43 marka Exp $"; #endif #include -__FBSDID("$FreeBSD: src/lib/libc/inet/inet_net_pton.c,v 1.3 2007/06/03 17:20:26 ume Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/inet/inet_net_pton.c,v 1.4 2008/12/14 19:39:53 ume Exp $"); #include "port_before.h" @@ -135,11 +135,11 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { assert(n >= 0 && n <= 9); bits *= 10; bits += n; + if (bits > 32) + goto enoent; } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); if (ch != '\0') goto enoent; - if (bits > 32) - goto emsgsize; } /* Firey death and destruction unless we prefetched EOS. */ diff --git a/net/FreeBSD/inet_net_pton.c.patch b/net/FreeBSD/inet_net_pton.c.patch index 2982459..3e4dfbb 100644 --- a/net/FreeBSD/inet_net_pton.c.patch +++ b/net/FreeBSD/inet_net_pton.c.patch @@ -1,27 +1,13 @@ ---- inet_net_pton.c.orig 2008-09-01 22:59:17.000000000 -0700 -+++ inet_net_pton.c 2008-09-01 23:00:34.000000000 -0700 +--- inet_net_pton.c.bsdnew 2009-11-10 16:23:10.000000000 -0800 ++++ inet_net_pton.c 2009-11-10 16:23:10.000000000 -0800 @@ -18,6 +18,10 @@ #if defined(LIBC_SCCS) && !defined(lint) - static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.1 2005/04/27 05:00:53 sra Exp $"; + static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.2 2008/08/26 04:42:43 marka Exp $"; #endif + +/* the algorithms only can deal with ASCII, so we optimize for it */ +#define USE_ASCII + #include - __FBSDID("$FreeBSD: src/lib/libc/inet/inet_net_pton.c,v 1.3 2007/06/03 17:20:26 ume Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/inet/inet_net_pton.c,v 1.4 2008/12/14 19:39:53 ume Exp $"); -@@ -135,11 +139,11 @@ inet_net_pton_ipv4(const char *src, u_ch - assert(n >= 0 && n <= 9); - bits *= 10; - bits += n; -+ if (bits > 32) -+ goto emsgsize; - } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); - if (ch != '\0') - goto enoent; -- if (bits > 32) -- goto emsgsize; - } - - /* Firey death and destruction unless we prefetched EOS. */ diff --git a/net/FreeBSD/linkaddr.3 b/net/FreeBSD/linkaddr.3 index 5008a85..17ddfaa 100644 --- a/net/FreeBSD/linkaddr.3 +++ b/net/FreeBSD/linkaddr.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,9 +29,9 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)linkaddr.3 8.1 (Berkeley) 7/28/93 -.\" $FreeBSD: src/lib/libc/net/linkaddr.3,v 1.14 2004/07/03 22:30:08 ru Exp $ +.\" $FreeBSD: src/lib/libc/net/linkaddr.3,v 1.16 2007/02/28 21:18:38 bms Exp $ .\" -.Dd June 17, 1996 +.Dd February 28, 2007 .Dt LINK_ADDR 3 .Os .Sh NAME @@ -96,11 +92,6 @@ Thus .Li le0:8.0.9.13.d.30 represents an ethernet address to be transmitted on the first Lance ethernet interface. -.Pp -The direct use of these functions is deprecated in favor of the -.Xr addr2ascii 3 -interface; however, portable programs cannot rely on the latter as it is -not yet widely implemented. .Sh RETURN VALUES The .Fn link_ntoa @@ -113,8 +104,7 @@ has no return value. (See .Sx BUGS . ) .Sh SEE ALSO -.Xr addr2ascii 3 -.\" .Xr iso 4 +.Xr getnameinfo 3 .Sh HISTORY The .Fn link_addr diff --git a/net/FreeBSD/sourcefilter.3 b/net/FreeBSD/sourcefilter.3 new file mode 100644 index 0000000..1739db5 --- /dev/null +++ b/net/FreeBSD/sourcefilter.3 @@ -0,0 +1,240 @@ +.\" Copyright (c) 2007-2009 Bruce Simpson. +.\" 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: src/lib/libc/net/sourcefilter.3,v 1.2 2009/03/04 01:59:14 bms Exp $ +.\" +.Dd February 13, 2009 +.Dt SOURCEFILTER 3 +.Os +.Sh NAME +.Nm sourcefilter +.Nd advanced multicast group membership API +.Sh SYNOPSIS +.In sys/socket.h +.In netinet/in.h +.Ft int +.Fo getipv4sourcefilter +.Fa "int s" +.Fa "struct in_addr interface" +.Fa "struct in_addr group" +.Fa "uint32_t *fmode" +.Fa "uint32_t *numsrc" +.Fa "struct in_addr *slist" +.Fc +.Ft int +.Fo getsourcefilter +.Fa "int s" +.Fa "uint32_t interface" +.Fa "struct sockaddr *group" +.Fa "socklen_t grouplen" +.Fa "uint32_t *fmode" +.Fa "uint32_t *numsrc" +.Fa "struct sockaddr_storage *slist" +.Fc +.Ft int +.Fo setipv4sourcefilter +.Fa "int s" +.Fa "struct in_addr interface" +.Fa "struct in_addr group" +.Fa "uint32_t fmode" +.Fa "uint32_t numsrc" +.Fa "struct in_addr *slist" +.Fc +.Ft int +.Fo setsourcefilter +.Fa "int s" +.Fa "uint32_t interface" +.Fa "struct sockaddr *group" +.Fa "socklen_t grouplen" +.Fa "uint32_t fmode" +.Fa "uint32_t numsrc" +.Fa "struct sockaddr_storage *slist" +.Fc +.Sh DESCRIPTION +The +.Nm +functions implement the advanced, full-state multicast API +defined in RFC 3678. +An application may use these functions to atomically set and +retrieve the multicast source address filters associated with a socket +.Fa s +and a multicast +.Fa group . +.Pp +The functions +.Fn getipv4sourcefilter +and +.Fn getsourcefilter +allow an application to discover the filter mode, and +source filter entries, +for an existing group membership. +.Pp +The kernel will always return the number of source filter +entries on the socket for that group in +.Fa *numsrc . +If the +.Fa *numsrc +argument is non-zero, the kernel will attempt to return up to +.Fa *numsrc +filter entries in the array pointed to by +.Fa slist . +The +.Fa *numsrc +argument may be set to 0, in which case the +.Fa slist +argument will be ignored. +.Pp +For the +.Fn setipv4sourcefilter +and +.Fn setsourcefilter +functions, +the +.Fa fmode +argument may be used to place the socket into inclusive or exclusive +group membership modes, by using the +.Dv MCAST_INCLUDE +or +.Dv MCAST_EXCLUDE +constants respectively. +The +.Fa numsrc +argument specifies the number of source entries in the +.Fa slist +array. +If the +.Fa numsrc +argument has a value of 0, +all source filters will be removed from the socket. +Removing all source filters from a membership which is in the +.Dv MCAST_INCLUDE +filter mode will cause the group to be left on that socket. +.Pp +The protocol-independent function +.Fn setsourcefilter +allows an application to join a multicast group on an interface +which may not have an assigned protocol address, +by passing its index for the +.Fa interface +argument. +.Pp +Any changes made by these functions +will be communicated to IGMPv3 and/or MLDv2 routers +on the local network as appropriate. +If no IGMPv3 or MLDv2 routers are present, changes in the source filter +lists made by these functions will not cause +state changes to be transmitted, with the exception of any +change which causes a group to be joined or left. +The kernel will continue to maintain the source filter state +regardless of the IGMP or MLD version in use on the link. +.Sh IMPLEMENTATION NOTES +The IPv4 specific versions of these functions are implemented in terms +of the protocol-independent functions. +Application writers are encouraged to use the protocol-independent functions +for efficiency, and forwards compatibility with IPv6 networks. +.Pp +For the protocol-independent functions +.Fn getsourcefilter +and +.Fn setsourcefilter , +the argument +.Fa grouplen +argument specifies the size of the structure pointed to by +.Fa group . +This is required in order to differentiate between different +address families. +.Pp +Currently +.Fx +does not support source address selection for the IPv4 +protocol family, therefore the use of multicast APIs with +an unnumbered IPv4 interface is +.Em not recommended. +In all cases, the first assigned IPv4 address on the interface +will be used as the source address of IGMP control traffic. +If this address is removed or changed, the results are undefined. +.Sh RETURN VALUES +.Rv -std getsourcefilter getipv4sourcefilter setsourcefilter setipv4sourcefilter +.Sh ERRORS +The +.Nm +functions may fail because of: +.Bl -tag -width Er +.It Bq Er EADDRNOTAVAIL +The network interface which the +.Dv interface +argument refers to was not configured in the system, +or the system is not a member of the +.Dv group . +.It Bq Er EAFNOSUPPORT +The +.Dv group +and/or one or more of the +.Dv slist +arguments were of an address family unsupported by the system, +or the address family of the +.Dv group +and +.Dv slist +arguments were not identical. +.It Bq Er EINVAL +The +.Dv group +argument does not contain a multicast address. +The +.Dv fmode +argument is invalid; it must be set to either +.Dv MCAST_INCLUDE +or +.Dv MCAST_EXCLUDE . +The +.Dv numsrc +or +.Dv slist +arguments do not specify a source list. +.It Bq Er ENOMEM +Insufficient memory was available to carry out the requested +operation. +.El +.Sh SEE ALSO +.Xr ip 4 , +.Xr ip6 4 , +.Xr multicast 4, +.Xr ifmcstat 8 +.Rs +.%A D. Thaler +.%A B. Fenner +.%A B. Quinn +.%T "Socket Interface Extensions for Multicast Source Filters" +.%N RFC 3678 +.%D Jan 2004 +.Re +.Sh HISTORY +The +.Nm +functions first appeared in +.Fx 7.0 . +.Sh AUTHORS +Bruce M. Simpson +.Aq bms@FreeBSD.org diff --git a/net/FreeBSD/sourcefilter.3.patch b/net/FreeBSD/sourcefilter.3.patch new file mode 100644 index 0000000..9afa891 --- /dev/null +++ b/net/FreeBSD/sourcefilter.3.patch @@ -0,0 +1,13 @@ +--- sourcefilter.3.orig 2010-05-19 12:42:53.000000000 -0700 ++++ sourcefilter.3 2010-05-19 12:43:19.000000000 -0700 +@@ -219,9 +219,7 @@ operation. + .El + .Sh SEE ALSO + .Xr ip 4 , +-.Xr ip6 4 , +-.Xr multicast 4, +-.Xr ifmcstat 8 ++.Xr ip6 4 + .Rs + .%A D. Thaler + .%A B. Fenner diff --git a/net/FreeBSD/sourcefilter.c b/net/FreeBSD/sourcefilter.c new file mode 100644 index 0000000..c3d07c6 --- /dev/null +++ b/net/FreeBSD/sourcefilter.c @@ -0,0 +1,402 @@ +/*- + * Copyright (c) 2007-2009 Bruce Simpson. + * 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 +__FBSDID("$FreeBSD: src/lib/libc/net/sourcefilter.c,v 1.5 2009/04/29 09:58:31 bms Exp $"); + +#include "namespace.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "un-namespace.h" + +/* + * Advanced (Full-state) multicast group membership APIs [RFC3678] + * Currently this module assumes IPv4 support (INET) in the base system. + */ +#ifndef INET +#define INET +#endif + +union sockunion { + struct sockaddr_storage ss; + struct sockaddr sa; + struct sockaddr_dl sdl; +#ifdef INET + struct sockaddr_in sin; +#endif +#ifdef INET6 + struct sockaddr_in6 sin6; +#endif +}; +typedef union sockunion sockunion_t; + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/* + * Internal: Map an IPv4 unicast address to an interface index. + * This is quite inefficient so it is recommended applications use + * the newer, more portable, protocol independent API. + */ +static uint32_t +__inaddr_to_index(in_addr_t ifaddr) +{ + struct ifaddrs *ifa; + struct ifaddrs *ifaddrs; + char *ifname; + int ifindex; + sockunion_t *psu; + + if (getifaddrs(&ifaddrs) < 0) + return (0); + + ifindex = 0; + ifname = NULL; + + /* + * Pass #1: Find the ifaddr entry corresponding to the + * supplied IPv4 address. We should really use the ifindex + * consistently for matches, however it is not available to + * us on this pass. + */ + for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { + psu = (sockunion_t *)ifa->ifa_addr; + if (psu && psu->ss.ss_family == AF_INET && + psu->sin.sin_addr.s_addr == ifaddr) { + ifname = ifa->ifa_name; + break; + } + } + if (ifname == NULL) + goto out; + + /* + * Pass #2: Find the index of the interface matching the name + * we obtained from looking up the IPv4 ifaddr in pass #1. + * There must be a better way of doing this. + */ + for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { + psu = (sockunion_t *)ifa->ifa_addr; + if (psu && psu->ss.ss_family == AF_LINK && + strcmp(ifa->ifa_name, ifname) == 0) { + ifindex = psu->sdl.sdl_index; + break; + } + } + assert(ifindex != 0); + +out: + freeifaddrs(ifaddrs); + return (ifindex); +} + +/* + * Set IPv4 source filter list in use on socket. + * + * Stubbed to setsourcefilter(). Performs conversion of structures which + * may be inefficient; applications are encouraged to use the + * protocol-independent API. + */ +int +setipv4sourcefilter(int s, struct in_addr interface, struct in_addr group, + uint32_t fmode, uint32_t numsrc, struct in_addr *slist) +{ +#ifdef INET + sockunion_t tmpgroup; + struct in_addr *pina; + sockunion_t *psu, *tmpslist; + int err; + size_t i; + uint32_t ifindex; + + assert(s != -1); + + tmpslist = NULL; + + if (!IN_MULTICAST(ntohl(group.s_addr)) || + (fmode != MCAST_INCLUDE && fmode != MCAST_EXCLUDE)) { + errno = EINVAL; + return (-1); + } + + ifindex = __inaddr_to_index(interface.s_addr); + if (ifindex == 0) { + errno = EADDRNOTAVAIL; + return (-1); + } + + memset(&tmpgroup, 0, sizeof(sockunion_t)); + tmpgroup.sin.sin_family = AF_INET; + tmpgroup.sin.sin_len = sizeof(struct sockaddr_in); + tmpgroup.sin.sin_addr = group; + + if (numsrc != 0 || slist != NULL) { + tmpslist = calloc(numsrc, sizeof(sockunion_t)); + if (tmpslist == NULL) { + errno = ENOMEM; + return (-1); + } + + pina = slist; + psu = tmpslist; + for (i = 0; i < numsrc; i++, pina++, psu++) { + psu->sin.sin_family = AF_INET; + psu->sin.sin_len = sizeof(struct sockaddr_in); + psu->sin.sin_addr = *pina; + } + } + + err = setsourcefilter(s, ifindex, (struct sockaddr *)&tmpgroup, + sizeof(struct sockaddr_in), fmode, numsrc, + (struct sockaddr_storage *)tmpslist); + + if (tmpslist != NULL) + free(tmpslist); + + return (err); +#else /* !INET */ + return (EAFNOSUPPORT); +#endif /* INET */ +} + +/* + * Get IPv4 source filter list in use on socket. + * + * Stubbed to getsourcefilter(). Performs conversion of structures which + * may be inefficient; applications are encouraged to use the + * protocol-independent API. + * An slist of NULL may be used for guessing the required buffer size. + */ +int +getipv4sourcefilter(int s, struct in_addr interface, struct in_addr group, + uint32_t *fmode, uint32_t *numsrc, struct in_addr *slist) +{ + sockunion_t *psu, *tmpslist; + sockunion_t tmpgroup; + struct in_addr *pina; + int err; + size_t i; + uint32_t ifindex, onumsrc; + + assert(s != -1); + assert(fmode != NULL); + assert(numsrc != NULL); + + onumsrc = *numsrc; + *numsrc = 0; + tmpslist = NULL; + + if (!IN_MULTICAST(ntohl(group.s_addr)) || + (onumsrc != 0 && slist == NULL)) { + errno = EINVAL; + return (-1); + } + + ifindex = __inaddr_to_index(interface.s_addr); + if (ifindex == 0) { + errno = EADDRNOTAVAIL; + return (-1); + } + + memset(&tmpgroup, 0, sizeof(sockunion_t)); + tmpgroup.sin.sin_family = AF_INET; + tmpgroup.sin.sin_len = sizeof(struct sockaddr_in); + tmpgroup.sin.sin_addr = group; + + if (onumsrc != 0 || slist != NULL) { + tmpslist = calloc(onumsrc, sizeof(sockunion_t)); + if (tmpslist == NULL) { + errno = ENOMEM; + return (-1); + } + } + + err = getsourcefilter(s, ifindex, (struct sockaddr *)&tmpgroup, + sizeof(struct sockaddr_in), fmode, numsrc, + (struct sockaddr_storage *)tmpslist); + + if (tmpslist != NULL && *numsrc != 0) { + pina = slist; + psu = tmpslist; + for (i = 0; i < MIN(onumsrc, *numsrc); i++, psu++) { + if (psu->ss.ss_family != AF_INET) + continue; + *pina++ = psu->sin.sin_addr; + } + free(tmpslist); + } + + return (err); +} + +/* + * Set protocol-independent source filter list in use on socket. + */ +int +setsourcefilter(int s, uint32_t interface, struct sockaddr *group, + socklen_t grouplen, uint32_t fmode, uint32_t numsrc, + struct sockaddr_storage *slist) +{ + struct __msfilterreq msfr; + sockunion_t *psu; + int level, optname; + + if (fmode != MCAST_INCLUDE && fmode != MCAST_EXCLUDE) { + errno = EINVAL; + return (-1); + } + + psu = (sockunion_t *)group; + switch (psu->ss.ss_family) { +#ifdef INET + case AF_INET: + if ((grouplen != sizeof(struct sockaddr_in) || + !IN_MULTICAST(ntohl(psu->sin.sin_addr.s_addr)))) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IP; + optname = IP_MSFILTER; + break; +#endif +#ifdef INET6 + case AF_INET6: + if (grouplen != sizeof(struct sockaddr_in6) || + !IN6_IS_ADDR_MULTICAST(&psu->sin6.sin6_addr)) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IPV6; + optname = IPV6_MSFILTER; + break; +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + } + + memset(&msfr, 0, sizeof(msfr)); + msfr.msfr_ifindex = interface; + msfr.msfr_fmode = fmode; + msfr.msfr_nsrcs = numsrc; + memcpy(&msfr.msfr_group, &psu->ss, psu->ss.ss_len); + msfr.msfr_srcs = slist; /* pointer */ + + return (_setsockopt(s, level, optname, &msfr, sizeof(msfr))); +} + +/* + * Get protocol-independent source filter list in use on socket. + * An slist of NULL may be used for guessing the required buffer size. + */ +int +getsourcefilter(int s, uint32_t interface, struct sockaddr *group, + socklen_t grouplen, uint32_t *fmode, uint32_t *numsrc, + struct sockaddr_storage *slist) +{ + struct __msfilterreq msfr; + sockunion_t *psu; + int err, level, nsrcs, optlen, optname; + + if (interface == 0 || group == NULL || numsrc == NULL || + fmode == NULL) { + errno = EINVAL; + return (-1); + } + + nsrcs = *numsrc; + *numsrc = 0; + *fmode = 0; + + psu = (sockunion_t *)group; + switch (psu->ss.ss_family) { +#ifdef INET + case AF_INET: + if ((grouplen != sizeof(struct sockaddr_in) || + !IN_MULTICAST(ntohl(psu->sin.sin_addr.s_addr)))) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IP; + optname = IP_MSFILTER; + break; +#endif +#ifdef INET6 + case AF_INET6: + if (grouplen != sizeof(struct sockaddr_in6) || + !IN6_IS_ADDR_MULTICAST(&psu->sin6.sin6_addr)) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IPV6; + optname = IPV6_MSFILTER; + break; +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + break; + } + + optlen = sizeof(struct __msfilterreq); + memset(&msfr, 0, optlen); + msfr.msfr_ifindex = interface; + msfr.msfr_fmode = 0; + msfr.msfr_nsrcs = nsrcs; + memcpy(&msfr.msfr_group, &psu->ss, psu->ss.ss_len); + + /* + * msfr_srcs is a pointer to a vector of sockaddr_storage. It + * may be NULL. The kernel will always return the total number + * of filter entries for the group in msfr.msfr_nsrcs. + */ + msfr.msfr_srcs = slist; + err = _getsockopt(s, level, optname, &msfr, &optlen); + if (err == 0) { + *numsrc = msfr.msfr_nsrcs; + *fmode = msfr.msfr_fmode; + } + + return (err); +} diff --git a/net/FreeBSD/sourcefilter.c.patch b/net/FreeBSD/sourcefilter.c.patch new file mode 100644 index 0000000..0eeba36 --- /dev/null +++ b/net/FreeBSD/sourcefilter.c.patch @@ -0,0 +1,23 @@ +--- sourcefilter.c.orig 2010-06-29 16:12:54.000000000 -0700 ++++ sourcefilter.c 2010-06-29 17:55:54.000000000 -0700 +@@ -27,6 +27,9 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/net/sourcefilter.c,v 1.5 2009/04/29 09:58:31 bms Exp $"); + ++/* 8120237: enable INET6 */ ++#define __APPLE_USE_RFC_3542 ++ + #include "namespace.h" + + #include +@@ -56,6 +59,10 @@ __FBSDID("$FreeBSD: src/lib/libc/net/sou + #ifndef INET + #define INET + #endif ++/* 8120237: enable INET6 */ ++#ifndef INET6 ++#define INET6 ++#endif + + union sockunion { + struct sockaddr_storage ss; diff --git a/net/Makefile.inc b/net/Makefile.inc index 9717198..021f62c 100644 --- a/net/Makefile.inc +++ b/net/Makefile.inc @@ -12,7 +12,7 @@ CWD := ${.CURDIR}/net FBSDMISRCS= addr2ascii.c ascii2addr.c inet_addr.c inet_lnaof.c \ inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \ inet_netof.c inet_network.c inet_ntoa.c linkaddr.c nsap_addr.c \ - recv.c send.c sockatmark.c + recv.c send.c sockatmark.c sourcefilter.c .include "Makefile.fbsd_end" LEGACYSRCS+= recv.c send.c @@ -26,7 +26,7 @@ CFLAGS-send-fbsd.c += -DLIBC_ALIAS_SEND .if ${LIB} == "c" MAN3+= byteorder.3 ethers.3 rcmdsh.3 .include "Makefile.fbsd_begin" -FBSDMAN3= addr2ascii.3 inet.3 inet_net.3 linkaddr.3 sockatmark.3 +FBSDMAN3= addr2ascii.3 inet.3 inet_net.3 linkaddr.3 sockatmark.3 sourcefilter.3 .include "Makefile.fbsd_end" MLINKS+= addr2ascii.3 ascii2addr.3 @@ -60,4 +60,10 @@ MLINKS+= inet_net.3 inet_net_ntop.3 \ MLINKS+= linkaddr.3 link_addr.3 \ linkaddr.3 link_ntoa.3 + +MLINKS+= sourcefilter.3 getsourcefilter.3 \ + sourcefilter.3 getipv4sourcefilter.3 \ + sourcefilter.3 setsourcefilter.3 \ + sourcefilter.3 setipv4sourcefilter.3 + .endif diff --git a/net/ethers.3 b/net/ethers.3 index 36a8268..fd38d87 100644 --- a/net/ethers.3 +++ b/net/ethers.3 @@ -181,7 +181,7 @@ maps in addition to the data in the .Pa /etc/ethers file. .Sh SEE ALSO -.Xr yp 4 , +.Xr yp 8 , .Xr ethers 5 .Sh BUGS The diff --git a/net/inet.3 b/net/inet.3 index b15ab01..a679b74 100644 --- a/net/inet.3 +++ b/net/inet.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)inet.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/net/inet.3,v 1.29 2004/07/02 23:52:11 ru Exp $ +.\" $FreeBSD: src/lib/libc/net/inet.3,v 1.36 2007/06/14 07:13:28 delphij Exp $ .\" -.Dd June 14, 2004 +.Dd June 14, 2007 .Dt INET 3 .Os .Sh NAME @@ -43,6 +39,7 @@ .Nm inet_netof , .Nm inet_network , .Nm inet_ntoa , +.Nm inet_ntoa_r , .Nm inet_ntop , .Nm inet_pton .Nd Internet address manipulation routines @@ -80,23 +77,29 @@ .Fo inet_ntoa .Fa "struct in_addr in" .Fc +.Ft char * +.Fo inet_ntoa_r +.Fa "struct in_addr in" +.Fa "char *buf" +.Fa "socklen_t size" +.Fc .Ft const char * .Fo inet_ntop .Fa "int af" -.Fa "const void *restrict src" -.Fa "char *restrict dst" +.Fa "const void * restrict src" +.Fa "char * restrict dst" .Fa "socklen_t size" .Fc .Ft int .Fo inet_pton .Fa "int af" -.Fa "const char *restrict src" -.Fa "void *restrict dst" +.Fa "const char * restrict src" +.Fa "void * restrict dst" .Fc .Sh DESCRIPTION The routines .Fn inet_aton , -.Fn inet_addr , +.Fn inet_addr and .Fn inet_network interpret character strings representing @@ -111,7 +114,7 @@ as held in a character string) to network format (usually a .Ft struct in_addr or some other internal binary representation, in network byte order). It returns 1 if the address was valid for the specified address family, or -0 if the address wasn't parseable in the specified address family, or -1 +0 if the address was not parseable in the specified address family, or -1 if some system error occurred (in which case .Va errno will have been set). @@ -147,6 +150,11 @@ The .Fa size argument specifies the size, in bytes, of the buffer .Fa *dst . +.Dv INET_ADDRSTRLEN +and +.Dv INET6_ADDRSTRLEN +define the maximum size required to convert an address of the respective +type. It returns NULL if a system error occurs (in which case, .Va errno will have been set), or it returns a pointer to the destination string. @@ -163,6 +171,10 @@ string representing the address in .Ql .\& notation. The routine +.Fn inet_ntoa_r +is the reentrant version of +.Fn inet_ntoa . +The routine .Fn inet_makeaddr takes an Internet network number and a local network address and constructs an Internet address @@ -233,19 +245,6 @@ may be decimal, octal, or hexadecimal, as specified in the C language (i.e., a leading 0x or 0X implies hexadecimal; otherwise, a leading 0 implies octal; otherwise, the number is interpreted as decimal). -.Pp -The -.Fn inet_aton -and -.Fn inet_ntoa -functions are semi-deprecated in favor of the -.Xr addr2ascii 3 -family. -However, since those functions are not yet widely implemented, -portable programs cannot rely on their presence and will continue -to use the -.Xr inet 3 -functions for some time. .Sh DIAGNOSTICS The constant .Dv INADDR_NONE @@ -278,12 +277,12 @@ was not large enough to store the presentation form of the address. .Pp These include files are necessary for all functions. .Sh SEE ALSO -.Xr addr2ascii 3 , .Xr byteorder 3 , +.Xr getaddrinfo 3 , .Xr gethostbyname 3 , +.Xr getnameinfo 3 , .Xr getnetent 3 , .Xr inet_net 3 , -.Xr compat 5 , .Xr hosts 5 , .Xr networks 5 .Rs @@ -324,5 +323,7 @@ The string returned by .Fn inet_ntoa resides in a static memory area. .Pp -Inet_addr should return a +The +.Fn inet_addr +function should return a .Fa struct in_addr . diff --git a/net/inet_net_pton-fbsd.c b/net/inet_net_pton-fbsd.c index 153d5bf..4493011 100644 --- a/net/inet_net_pton-fbsd.c +++ b/net/inet_net_pton-fbsd.c @@ -16,14 +16,14 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.1 2005/04/27 05:00:53 sra Exp $"; +static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.2 2008/08/26 04:42:43 marka Exp $"; #endif /* the algorithms only can deal with ASCII, so we optimize for it */ #define USE_ASCII #include -__FBSDID("$FreeBSD: src/lib/libc/inet/inet_net_pton.c,v 1.3 2007/06/03 17:20:26 ume Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/inet/inet_net_pton.c,v 1.4 2008/12/14 19:39:53 ume Exp $"); #include "port_before.h" @@ -140,7 +140,7 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { bits *= 10; bits += n; if (bits > 32) - goto emsgsize; + goto enoent; } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); if (ch != '\0') goto enoent; diff --git a/net/sourcefilter-fbsd.c b/net/sourcefilter-fbsd.c new file mode 100644 index 0000000..a5a3cca --- /dev/null +++ b/net/sourcefilter-fbsd.c @@ -0,0 +1,409 @@ +/*- + * Copyright (c) 2007-2009 Bruce Simpson. + * 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 +__FBSDID("$FreeBSD: src/lib/libc/net/sourcefilter.c,v 1.5 2009/04/29 09:58:31 bms Exp $"); + +/* 8120237: enable INET6 */ +#define __APPLE_USE_RFC_3542 + +#include "namespace.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "un-namespace.h" + +/* + * Advanced (Full-state) multicast group membership APIs [RFC3678] + * Currently this module assumes IPv4 support (INET) in the base system. + */ +#ifndef INET +#define INET +#endif +/* 8120237: enable INET6 */ +#ifndef INET6 +#define INET6 +#endif + +union sockunion { + struct sockaddr_storage ss; + struct sockaddr sa; + struct sockaddr_dl sdl; +#ifdef INET + struct sockaddr_in sin; +#endif +#ifdef INET6 + struct sockaddr_in6 sin6; +#endif +}; +typedef union sockunion sockunion_t; + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/* + * Internal: Map an IPv4 unicast address to an interface index. + * This is quite inefficient so it is recommended applications use + * the newer, more portable, protocol independent API. + */ +static uint32_t +__inaddr_to_index(in_addr_t ifaddr) +{ + struct ifaddrs *ifa; + struct ifaddrs *ifaddrs; + char *ifname; + int ifindex; + sockunion_t *psu; + + if (getifaddrs(&ifaddrs) < 0) + return (0); + + ifindex = 0; + ifname = NULL; + + /* + * Pass #1: Find the ifaddr entry corresponding to the + * supplied IPv4 address. We should really use the ifindex + * consistently for matches, however it is not available to + * us on this pass. + */ + for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { + psu = (sockunion_t *)ifa->ifa_addr; + if (psu && psu->ss.ss_family == AF_INET && + psu->sin.sin_addr.s_addr == ifaddr) { + ifname = ifa->ifa_name; + break; + } + } + if (ifname == NULL) + goto out; + + /* + * Pass #2: Find the index of the interface matching the name + * we obtained from looking up the IPv4 ifaddr in pass #1. + * There must be a better way of doing this. + */ + for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { + psu = (sockunion_t *)ifa->ifa_addr; + if (psu && psu->ss.ss_family == AF_LINK && + strcmp(ifa->ifa_name, ifname) == 0) { + ifindex = psu->sdl.sdl_index; + break; + } + } + assert(ifindex != 0); + +out: + freeifaddrs(ifaddrs); + return (ifindex); +} + +/* + * Set IPv4 source filter list in use on socket. + * + * Stubbed to setsourcefilter(). Performs conversion of structures which + * may be inefficient; applications are encouraged to use the + * protocol-independent API. + */ +int +setipv4sourcefilter(int s, struct in_addr interface, struct in_addr group, + uint32_t fmode, uint32_t numsrc, struct in_addr *slist) +{ +#ifdef INET + sockunion_t tmpgroup; + struct in_addr *pina; + sockunion_t *psu, *tmpslist; + int err; + size_t i; + uint32_t ifindex; + + assert(s != -1); + + tmpslist = NULL; + + if (!IN_MULTICAST(ntohl(group.s_addr)) || + (fmode != MCAST_INCLUDE && fmode != MCAST_EXCLUDE)) { + errno = EINVAL; + return (-1); + } + + ifindex = __inaddr_to_index(interface.s_addr); + if (ifindex == 0) { + errno = EADDRNOTAVAIL; + return (-1); + } + + memset(&tmpgroup, 0, sizeof(sockunion_t)); + tmpgroup.sin.sin_family = AF_INET; + tmpgroup.sin.sin_len = sizeof(struct sockaddr_in); + tmpgroup.sin.sin_addr = group; + + if (numsrc != 0 || slist != NULL) { + tmpslist = calloc(numsrc, sizeof(sockunion_t)); + if (tmpslist == NULL) { + errno = ENOMEM; + return (-1); + } + + pina = slist; + psu = tmpslist; + for (i = 0; i < numsrc; i++, pina++, psu++) { + psu->sin.sin_family = AF_INET; + psu->sin.sin_len = sizeof(struct sockaddr_in); + psu->sin.sin_addr = *pina; + } + } + + err = setsourcefilter(s, ifindex, (struct sockaddr *)&tmpgroup, + sizeof(struct sockaddr_in), fmode, numsrc, + (struct sockaddr_storage *)tmpslist); + + if (tmpslist != NULL) + free(tmpslist); + + return (err); +#else /* !INET */ + return (EAFNOSUPPORT); +#endif /* INET */ +} + +/* + * Get IPv4 source filter list in use on socket. + * + * Stubbed to getsourcefilter(). Performs conversion of structures which + * may be inefficient; applications are encouraged to use the + * protocol-independent API. + * An slist of NULL may be used for guessing the required buffer size. + */ +int +getipv4sourcefilter(int s, struct in_addr interface, struct in_addr group, + uint32_t *fmode, uint32_t *numsrc, struct in_addr *slist) +{ + sockunion_t *psu, *tmpslist; + sockunion_t tmpgroup; + struct in_addr *pina; + int err; + size_t i; + uint32_t ifindex, onumsrc; + + assert(s != -1); + assert(fmode != NULL); + assert(numsrc != NULL); + + onumsrc = *numsrc; + *numsrc = 0; + tmpslist = NULL; + + if (!IN_MULTICAST(ntohl(group.s_addr)) || + (onumsrc != 0 && slist == NULL)) { + errno = EINVAL; + return (-1); + } + + ifindex = __inaddr_to_index(interface.s_addr); + if (ifindex == 0) { + errno = EADDRNOTAVAIL; + return (-1); + } + + memset(&tmpgroup, 0, sizeof(sockunion_t)); + tmpgroup.sin.sin_family = AF_INET; + tmpgroup.sin.sin_len = sizeof(struct sockaddr_in); + tmpgroup.sin.sin_addr = group; + + if (onumsrc != 0 || slist != NULL) { + tmpslist = calloc(onumsrc, sizeof(sockunion_t)); + if (tmpslist == NULL) { + errno = ENOMEM; + return (-1); + } + } + + err = getsourcefilter(s, ifindex, (struct sockaddr *)&tmpgroup, + sizeof(struct sockaddr_in), fmode, numsrc, + (struct sockaddr_storage *)tmpslist); + + if (tmpslist != NULL && *numsrc != 0) { + pina = slist; + psu = tmpslist; + for (i = 0; i < MIN(onumsrc, *numsrc); i++, psu++) { + if (psu->ss.ss_family != AF_INET) + continue; + *pina++ = psu->sin.sin_addr; + } + free(tmpslist); + } + + return (err); +} + +/* + * Set protocol-independent source filter list in use on socket. + */ +int +setsourcefilter(int s, uint32_t interface, struct sockaddr *group, + socklen_t grouplen, uint32_t fmode, uint32_t numsrc, + struct sockaddr_storage *slist) +{ + struct __msfilterreq msfr; + sockunion_t *psu; + int level, optname; + + if (fmode != MCAST_INCLUDE && fmode != MCAST_EXCLUDE) { + errno = EINVAL; + return (-1); + } + + psu = (sockunion_t *)group; + switch (psu->ss.ss_family) { +#ifdef INET + case AF_INET: + if ((grouplen != sizeof(struct sockaddr_in) || + !IN_MULTICAST(ntohl(psu->sin.sin_addr.s_addr)))) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IP; + optname = IP_MSFILTER; + break; +#endif +#ifdef INET6 + case AF_INET6: + if (grouplen != sizeof(struct sockaddr_in6) || + !IN6_IS_ADDR_MULTICAST(&psu->sin6.sin6_addr)) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IPV6; + optname = IPV6_MSFILTER; + break; +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + } + + memset(&msfr, 0, sizeof(msfr)); + msfr.msfr_ifindex = interface; + msfr.msfr_fmode = fmode; + msfr.msfr_nsrcs = numsrc; + memcpy(&msfr.msfr_group, &psu->ss, psu->ss.ss_len); + msfr.msfr_srcs = slist; /* pointer */ + + return (_setsockopt(s, level, optname, &msfr, sizeof(msfr))); +} + +/* + * Get protocol-independent source filter list in use on socket. + * An slist of NULL may be used for guessing the required buffer size. + */ +int +getsourcefilter(int s, uint32_t interface, struct sockaddr *group, + socklen_t grouplen, uint32_t *fmode, uint32_t *numsrc, + struct sockaddr_storage *slist) +{ + struct __msfilterreq msfr; + sockunion_t *psu; + int err, level, nsrcs, optlen, optname; + + if (interface == 0 || group == NULL || numsrc == NULL || + fmode == NULL) { + errno = EINVAL; + return (-1); + } + + nsrcs = *numsrc; + *numsrc = 0; + *fmode = 0; + + psu = (sockunion_t *)group; + switch (psu->ss.ss_family) { +#ifdef INET + case AF_INET: + if ((grouplen != sizeof(struct sockaddr_in) || + !IN_MULTICAST(ntohl(psu->sin.sin_addr.s_addr)))) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IP; + optname = IP_MSFILTER; + break; +#endif +#ifdef INET6 + case AF_INET6: + if (grouplen != sizeof(struct sockaddr_in6) || + !IN6_IS_ADDR_MULTICAST(&psu->sin6.sin6_addr)) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IPV6; + optname = IPV6_MSFILTER; + break; +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + break; + } + + optlen = sizeof(struct __msfilterreq); + memset(&msfr, 0, optlen); + msfr.msfr_ifindex = interface; + msfr.msfr_fmode = 0; + msfr.msfr_nsrcs = nsrcs; + memcpy(&msfr.msfr_group, &psu->ss, psu->ss.ss_len); + + /* + * msfr_srcs is a pointer to a vector of sockaddr_storage. It + * may be NULL. The kernel will always return the total number + * of filter entries for the group in msfr.msfr_nsrcs. + */ + msfr.msfr_srcs = slist; + err = _getsockopt(s, level, optname, &msfr, &optlen); + if (err == 0) { + *numsrc = msfr.msfr_nsrcs; + *fmode = msfr.msfr_fmode; + } + + return (err); +} diff --git a/net/sourcefilter.3 b/net/sourcefilter.3 new file mode 100644 index 0000000..081dfa3 --- /dev/null +++ b/net/sourcefilter.3 @@ -0,0 +1,238 @@ +.\" Copyright (c) 2007-2009 Bruce Simpson. +.\" 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: src/lib/libc/net/sourcefilter.3,v 1.2 2009/03/04 01:59:14 bms Exp $ +.\" +.Dd February 13, 2009 +.Dt SOURCEFILTER 3 +.Os +.Sh NAME +.Nm sourcefilter +.Nd advanced multicast group membership API +.Sh SYNOPSIS +.In sys/socket.h +.In netinet/in.h +.Ft int +.Fo getipv4sourcefilter +.Fa "int s" +.Fa "struct in_addr interface" +.Fa "struct in_addr group" +.Fa "uint32_t *fmode" +.Fa "uint32_t *numsrc" +.Fa "struct in_addr *slist" +.Fc +.Ft int +.Fo getsourcefilter +.Fa "int s" +.Fa "uint32_t interface" +.Fa "struct sockaddr *group" +.Fa "socklen_t grouplen" +.Fa "uint32_t *fmode" +.Fa "uint32_t *numsrc" +.Fa "struct sockaddr_storage *slist" +.Fc +.Ft int +.Fo setipv4sourcefilter +.Fa "int s" +.Fa "struct in_addr interface" +.Fa "struct in_addr group" +.Fa "uint32_t fmode" +.Fa "uint32_t numsrc" +.Fa "struct in_addr *slist" +.Fc +.Ft int +.Fo setsourcefilter +.Fa "int s" +.Fa "uint32_t interface" +.Fa "struct sockaddr *group" +.Fa "socklen_t grouplen" +.Fa "uint32_t fmode" +.Fa "uint32_t numsrc" +.Fa "struct sockaddr_storage *slist" +.Fc +.Sh DESCRIPTION +The +.Nm +functions implement the advanced, full-state multicast API +defined in RFC 3678. +An application may use these functions to atomically set and +retrieve the multicast source address filters associated with a socket +.Fa s +and a multicast +.Fa group . +.Pp +The functions +.Fn getipv4sourcefilter +and +.Fn getsourcefilter +allow an application to discover the filter mode, and +source filter entries, +for an existing group membership. +.Pp +The kernel will always return the number of source filter +entries on the socket for that group in +.Fa *numsrc . +If the +.Fa *numsrc +argument is non-zero, the kernel will attempt to return up to +.Fa *numsrc +filter entries in the array pointed to by +.Fa slist . +The +.Fa *numsrc +argument may be set to 0, in which case the +.Fa slist +argument will be ignored. +.Pp +For the +.Fn setipv4sourcefilter +and +.Fn setsourcefilter +functions, +the +.Fa fmode +argument may be used to place the socket into inclusive or exclusive +group membership modes, by using the +.Dv MCAST_INCLUDE +or +.Dv MCAST_EXCLUDE +constants respectively. +The +.Fa numsrc +argument specifies the number of source entries in the +.Fa slist +array. +If the +.Fa numsrc +argument has a value of 0, +all source filters will be removed from the socket. +Removing all source filters from a membership which is in the +.Dv MCAST_INCLUDE +filter mode will cause the group to be left on that socket. +.Pp +The protocol-independent function +.Fn setsourcefilter +allows an application to join a multicast group on an interface +which may not have an assigned protocol address, +by passing its index for the +.Fa interface +argument. +.Pp +Any changes made by these functions +will be communicated to IGMPv3 and/or MLDv2 routers +on the local network as appropriate. +If no IGMPv3 or MLDv2 routers are present, changes in the source filter +lists made by these functions will not cause +state changes to be transmitted, with the exception of any +change which causes a group to be joined or left. +The kernel will continue to maintain the source filter state +regardless of the IGMP or MLD version in use on the link. +.Sh IMPLEMENTATION NOTES +The IPv4 specific versions of these functions are implemented in terms +of the protocol-independent functions. +Application writers are encouraged to use the protocol-independent functions +for efficiency, and forwards compatibility with IPv6 networks. +.Pp +For the protocol-independent functions +.Fn getsourcefilter +and +.Fn setsourcefilter , +the argument +.Fa grouplen +argument specifies the size of the structure pointed to by +.Fa group . +This is required in order to differentiate between different +address families. +.Pp +Currently +.Fx +does not support source address selection for the IPv4 +protocol family, therefore the use of multicast APIs with +an unnumbered IPv4 interface is +.Em not recommended. +In all cases, the first assigned IPv4 address on the interface +will be used as the source address of IGMP control traffic. +If this address is removed or changed, the results are undefined. +.Sh RETURN VALUES +.Rv -std getsourcefilter getipv4sourcefilter setsourcefilter setipv4sourcefilter +.Sh ERRORS +The +.Nm +functions may fail because of: +.Bl -tag -width Er +.It Bq Er EADDRNOTAVAIL +The network interface which the +.Dv interface +argument refers to was not configured in the system, +or the system is not a member of the +.Dv group . +.It Bq Er EAFNOSUPPORT +The +.Dv group +and/or one or more of the +.Dv slist +arguments were of an address family unsupported by the system, +or the address family of the +.Dv group +and +.Dv slist +arguments were not identical. +.It Bq Er EINVAL +The +.Dv group +argument does not contain a multicast address. +The +.Dv fmode +argument is invalid; it must be set to either +.Dv MCAST_INCLUDE +or +.Dv MCAST_EXCLUDE . +The +.Dv numsrc +or +.Dv slist +arguments do not specify a source list. +.It Bq Er ENOMEM +Insufficient memory was available to carry out the requested +operation. +.El +.Sh SEE ALSO +.Xr ip 4 , +.Xr ip6 4 +.Rs +.%A D. Thaler +.%A B. Fenner +.%A B. Quinn +.%T "Socket Interface Extensions for Multicast Source Filters" +.%N RFC 3678 +.%D Jan 2004 +.Re +.Sh HISTORY +The +.Nm +functions first appeared in +.Fx 7.0 . +.Sh AUTHORS +Bruce M. Simpson +.Aq bms@FreeBSD.org diff --git a/nls/FreeBSD/catclose.3 b/nls/FreeBSD/catclose.3 index 7ac7172..cf238b5 100644 --- a/nls/FreeBSD/catclose.3 +++ b/nls/FreeBSD/catclose.3 @@ -26,8 +26,8 @@ .\" (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: src/lib/libc/nls/catclose.3,v 1.14 2001/10/01 16:08:56 ru Exp $ -.Dd May 29, 1994 +.\" $FreeBSD: src/lib/libc/nls/catclose.3,v 1.15 2005/02/27 16:30:16 phantom Exp $ +.Dd February 12, 2005 .Dt CATCLOSE 3 .Os .Sh NAME @@ -61,4 +61,4 @@ argument. The .Fn catclose function conforms to -.St -xpg4 . +.St -p1003.1-2001 . diff --git a/nls/FreeBSD/catgets.3 b/nls/FreeBSD/catgets.3 index 905e2cb..ba23033 100644 --- a/nls/FreeBSD/catgets.3 +++ b/nls/FreeBSD/catgets.3 @@ -26,8 +26,8 @@ .\" (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: src/lib/libc/nls/catgets.3,v 1.11 2001/10/01 16:08:56 ru Exp $ -.Dd May 29, 1994 +.\" $FreeBSD: src/lib/libc/nls/catgets.3,v 1.13 2005/06/15 19:04:04 ru Exp $ +.Dd February 12, 2005 .Dt CATGETS 3 .Os .Sh NAME @@ -58,6 +58,19 @@ If the specified message was retrieved successfully, returns a pointer to an internal buffer containing the message string; otherwise it returns .Fa s . +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa catd +argument is not a valid message catalog descriptor. +.It Bq Er EBADMSG +The message identified by +.Fa set_id +and +.Fa msg_id +is not in the message catalog. +.El .Sh SEE ALSO .Xr gencat 1 , .Xr catclose 3 , @@ -66,4 +79,4 @@ otherwise it returns The .Fn catgets function conforms to -.St -xpg4 . +.St -p1003.1-2001 . diff --git a/nls/FreeBSD/catopen.3 b/nls/FreeBSD/catopen.3 index ad75519..dad21ae 100644 --- a/nls/FreeBSD/catopen.3 +++ b/nls/FreeBSD/catopen.3 @@ -26,8 +26,8 @@ .\" (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: src/lib/libc/nls/catopen.3,v 1.16 2001/10/01 16:08:56 ru Exp $ -.Dd May 29, 1994 +.\" $FreeBSD: src/lib/libc/nls/catopen.3,v 1.17 2005/02/27 16:30:16 phantom Exp $ +.Dd February 12, 2005 .Dt CATOPEN 3 .Os .Sh NAME @@ -135,7 +135,7 @@ is set to indicate the error. .It Bq Er EINVAL Argument .Fa name -does not point to a valid message catalog. +does not point to a valid message catalog, or catalog is corrupt. .It Bq Er ENAMETOOLONG An entire path to the message catalog exceeded 1024 characters. .It Bq Er ENOENT @@ -154,4 +154,4 @@ Insufficient memory is available. The .Fn catopen function conforms to -.St -xpg4 . +.St -p1003.1-2001 . diff --git a/nls/FreeBSD/msgcat.c b/nls/FreeBSD/msgcat.c index 9b61cc9..0ce69e0 100644 --- a/nls/FreeBSD/msgcat.c +++ b/nls/FreeBSD/msgcat.c @@ -31,7 +31,7 @@ up-to-date. Many thanks. ******************************************************************/ #include -__FBSDID("$FreeBSD: src/lib/libc/nls/msgcat.c,v 1.48 2003/10/29 10:45:01 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/nls/msgcat.c,v 1.49 2005/02/01 16:04:55 phantom Exp $"); /* * We need a better way of handling errors than printing text. I need @@ -64,14 +64,12 @@ __FBSDID("$FreeBSD: src/lib/libc/nls/msgcat.c,v 1.48 2003/10/29 10:45:01 tjr Exp #define NLERR ((nl_catd) -1) #define NLRETERR(errc) { errno = errc; return (NLERR); } -static nl_catd loadCat(); -static int loadSet(); -static void __nls_free_resources(); +static nl_catd loadCat(__const char *); +static int loadSet(MCCatT *, MCSetT *); +static void __nls_free_resources(MCCatT *, int); nl_catd -catopen(name, type) - __const char *name; - int type; +catopen(__const char *name, int type) { int spcleft, saverr; char path[PATH_MAX]; @@ -158,7 +156,7 @@ catopen(name, type) (pathP - path) - 1; if (strlcpy(pathP, tmpptr, spcleft) >= spcleft) { - too_long: + too_long: free(plang); free(base); NLRETERR(ENAMETOOLONG); @@ -240,9 +238,7 @@ catopen(name, type) } static MCSetT * -MCGetSet(cat, setId) - MCCatT *cat; - int setId; +MCGetSet(MCCatT *cat, int setId) { MCSetT *set; long lo, hi, cur, dir; @@ -256,9 +252,7 @@ MCGetSet(cat, setId) } static MCMsgT * -MCGetMsg(set, msgId) - MCSetT *set; - int msgId; +MCGetMsg(MCSetT *set, int msgId) { MCMsgT *msg; long lo, hi, cur, dir; @@ -270,11 +264,7 @@ MCGetMsg(set, msgId) } char * -catgets(catd, setId, msgId, dflt) - nl_catd catd; - int setId; - int msgId; - __const char *dflt; +catgets(nl_catd catd, int setId, int msgId, __const char *dflt) { MCMsgT *msg; MCCatT *cat = (MCCatT *)catd; @@ -291,8 +281,7 @@ catgets(catd, setId, msgId, dflt) } int -catclose(catd) - nl_catd catd; +catclose(nl_catd catd) { MCCatT *cat = (MCCatT *)catd; @@ -300,10 +289,8 @@ catclose(catd) errno = EBADF; return (-1); } -#if 0 - if (cat->loadType != MCLoadAll) -#endif - (void)fclose(cat->fp); + + (void)fclose(cat->fp); __nls_free_resources(cat, cat->numSets); free(cat); return (0); @@ -333,9 +320,7 @@ static char *_errowner = "Message Catalog System"; } static void -__nls_free_resources(cat, i) - MCCatT *cat; - int i; +__nls_free_resources(MCCatT *cat, int i) { MCSetT *set; int j; @@ -351,8 +336,7 @@ __nls_free_resources(cat, i) } static nl_catd -loadCat(catpath) - __const char *catpath; +loadCat(__const char *catpath) { MCHeaderT header; MCCatT *cat; @@ -363,7 +347,6 @@ loadCat(catpath) if ((cat = (MCCatT *)malloc(sizeof(MCCatT))) == NULL) return (NLERR); - cat->loadType = MCLoadBySet; if ((cat->fp = fopen(catpath, "r")) == NULL) { saverr = errno; @@ -417,36 +400,15 @@ loadCat(catpath) nextSet = set->nextSet; continue; } -#if 0 - if (cat->loadType == MCLoadAll) { - int res; - - if ((res = loadSet(cat, set)) <= 0) { - saverr = errno; - __nls_free_resources(cat, i); - errno = saverr; - if (res < 0) - NOSPACE(); - CORRUPT(); - } - } else -#endif - set->invalid = TRUE; + set->invalid = TRUE; nextSet = set->nextSet; } -#if 0 - if (cat->loadType == MCLoadAll) { - (void)fclose(cat->fp); - cat->fp = NULL; - } -#endif + return ((nl_catd) cat); } static int -loadSet(cat, set) - MCCatT *cat; - MCSetT *set; +loadSet(MCCatT *cat, MCSetT *set) { MCMsgT *msg; int i; diff --git a/nls/FreeBSD/msgcat.c.patch b/nls/FreeBSD/msgcat.c.patch index e267fae..f62f2d7 100644 --- a/nls/FreeBSD/msgcat.c.patch +++ b/nls/FreeBSD/msgcat.c.patch @@ -1,6 +1,6 @@ ---- msgcat.c.orig 2007-02-07 01:54:34.000000000 -0800 -+++ msgcat.c 2007-02-07 02:03:33.000000000 -0800 -@@ -45,16 +45,22 @@ +--- msgcat.c.orig 2009-12-05 13:47:14.000000000 -0800 ++++ msgcat.c 2009-12-05 13:49:56.000000000 -0800 +@@ -45,16 +45,22 @@ __FBSDID("$FreeBSD: src/lib/libc/nls/msg #include #include #include @@ -25,7 +25,7 @@ #define _DEFAULT_NLS_PATH "/usr/share/nls/%L/%N.cat:/usr/share/nls/%N/%L:/usr/local/share/nls/%L/%N.cat:/usr/local/share/nls/%N/%L" -@@ -87,7 +93,7 @@ +@@ -85,7 +91,7 @@ catopen(__const char *name, int type) return (loadCat(name)); if (type == NL_CAT_LOCALE) @@ -34,7 +34,7 @@ else lang = getenv("LANG"); -@@ -210,21 +216,21 @@ +@@ -208,21 +214,21 @@ catopen(__const char *name, int type) #define LOOKUP(PARENT, CHILD, ID, NUM, SET) { \ lo = 0; \ @@ -62,14 +62,8 @@ dir = 1; \ } else { \ hi = cur; \ -@@ -240,32 +246,28 @@ - } - - static MCSetT * --MCGetSet(cat, setId) -- MCCatT *cat; -- int setId; -+MCGetSet(MCCatT *cat, int setId) +@@ -241,11 +247,11 @@ static MCSetT * + MCGetSet(MCCatT *cat, int setId) { MCSetT *set; - long lo, hi, cur, dir; @@ -82,13 +76,8 @@ if (set->invalid && loadSet(cat, set) <= 0) return (NULL); return (set); - } - - static MCMsgT * --MCGetMsg(set, msgId) -- MCSetT *set; -- int msgId; -+MCGetMsg(MCSetT *set, int msgId) +@@ -255,11 +261,11 @@ static MCMsgT * + MCGetMsg(MCSetT *set, int msgId) { MCMsgT *msg; - long lo, hi, cur, dir; @@ -101,7 +90,7 @@ return (msg); } -@@ -357,7 +359,7 @@ +@@ -341,7 +347,7 @@ loadCat(__const char *catpath) MCHeaderT header; MCCatT *cat; MCSetT *set; @@ -110,7 +99,7 @@ off_t nextSet; int saverr; -@@ -377,27 +379,30 @@ +@@ -360,27 +366,30 @@ loadCat(__const char *catpath) strncmp(header.magic, MCMagic, MCMagicLen) != 0) CORRUPT(); @@ -150,7 +139,7 @@ for (i = 0; i < cat->numSets; ++i) { if (fseeko(cat->fp, nextSet, SEEK_SET) == -1) { __nls_free_resources(cat, i); -@@ -414,7 +419,7 @@ +@@ -397,11 +406,11 @@ loadCat(__const char *catpath) /* if it's invalid, skip over it (and backup 'i') */ if (set->invalid) { --i; @@ -158,17 +147,13 @@ + nextSet = ntohll(set->nextSet); continue; } - #if 0 -@@ -432,7 +437,7 @@ - } else - #endif - set->invalid = TRUE; + set->invalid = TRUE; - nextSet = set->nextSet; + nextSet = ntohll(set->nextSet); } - #if 0 - if (cat->loadType == MCLoadAll) { -@@ -453,11 +458,11 @@ + + return ((nl_catd) cat); +@@ -415,11 +424,11 @@ loadSet(MCCatT *cat, MCSetT *set) int saverr; /* Get the data */ @@ -183,7 +168,7 @@ saverr = errno; free(set->data.str); errno = saverr; -@@ -465,13 +470,13 @@ +@@ -427,13 +436,13 @@ loadSet(MCCatT *cat, MCSetT *set) } /* Get the messages */ @@ -199,7 +184,7 @@ NULL) { saverr = errno; free(set->data.str); -@@ -479,7 +484,7 @@ +@@ -441,7 +450,7 @@ loadSet(MCCatT *cat, MCSetT *set) return (-1); } @@ -208,7 +193,7 @@ msg = set->u.msgs + i; if (fread(msg, sizeof(*msg), 1, cat->fp) != 1) { saverr = errno; -@@ -492,7 +497,7 @@ +@@ -454,7 +463,7 @@ loadSet(MCCatT *cat, MCSetT *set) --i; continue; } diff --git a/nls/FreeBSD/msgcat.h b/nls/FreeBSD/msgcat.h index df2bf5a..0a8b788 100644 --- a/nls/FreeBSD/msgcat.h +++ b/nls/FreeBSD/msgcat.h @@ -1,4 +1,4 @@ -/* $FreeBSD: src/lib/libc/nls/msgcat.h,v 1.8 2000/09/03 21:05:10 ache Exp $ */ +/* $FreeBSD: src/lib/libc/nls/msgcat.h,v 1.9 2005/02/01 16:04:55 phantom Exp $ */ #ifndef _MSGCAT_H_ #define _MSGCAT_H_ @@ -36,27 +36,20 @@ up-to-date. Many thanks. ******************************************************************/ - -#include - /* - * On disk data structures + * Magic definitions */ -/* For or'd constants */ -#define MCMakeId(s,m) (unsigned long) ( ((unsigned short)s << (sizeof(short)*8)) \ - | (unsigned short)m ) -#define MCSetId(id) (unsigned int) ( id >> (sizeof(short) * 8) ) -#define MCMsgId(id) (unsigned int) ( (id << (sizeof(short) * 8)) \ - >> (sizeof(short) * 8) ) #define MCMagicLen 8 #define MCMagic "*nazgul*" -#define MCLastMsg 0 -#define MCLastSet 0 #define MCMajorVer 1L #define MCMinorVer 0 +/* For or'd constants */ +#define MCMakeId(s,m) (unsigned long) ( ((unsigned short)s << (sizeof(short)*8)) \ + | (unsigned short)m ) + /* * Critical note here. Sets and Messages *MUST* be stored in ascending * order. There are stored that way (by specification) in the original @@ -84,11 +77,6 @@ up-to-date. Many thanks. * no guarantee that this will all work. */ -/* These should be publicly available */ - -#define MCLoadBySet 0 /* Load entire sets as they are used */ -#define MCLoadAll 1 /* Load entire DB on catopen */ - /* * MCOffsetT - Union to handle both disk and runtime pointers */ @@ -129,7 +117,6 @@ typedef struct _MCSetT { * MCCatT - Runtime catalog pointer */ typedef struct { - long loadType; /* How to load the messages (see MSLoadType) */ FILE *fp; /* File descriptor of catalog (if load-on-demand) */ long numSets; /* Number of sets */ MCSetT *sets; /* Pointer to the sets */ diff --git a/nls/FreeBSD/msgcat.h.patch b/nls/FreeBSD/msgcat.h.patch index 8b40fef..31303e4 100644 --- a/nls/FreeBSD/msgcat.h.patch +++ b/nls/FreeBSD/msgcat.h.patch @@ -1,24 +1,23 @@ ---- msgcat.h.orig 2007-02-07 11:30:18.000000000 -0800 -+++ msgcat.h 2007-02-07 11:57:46.000000000 -0800 -@@ -44,7 +44,7 @@ - */ +--- msgcat.h.orig 2009-11-23 18:16:18.000000000 -0800 ++++ msgcat.h 2009-12-05 13:58:11.000000000 -0800 +@@ -43,13 +43,14 @@ up-to-date. Many thanks. + #define MCMagicLen 8 + #define MCMagic "*nazgul*" + +-#define MCMajorVer 1L ++#define MCMajorVer 1 + #define MCMinorVer 0 /* For or'd constants */ -#define MCMakeId(s,m) (unsigned long) ( ((unsigned short)s << (sizeof(short)*8)) \ +#define MCMakeId(s,m) (u_int32_t) ( ((unsigned short)s << (sizeof(short)*8)) \ | (unsigned short)m ) - #define MCSetId(id) (unsigned int) ( id >> (sizeof(short) * 8) ) - #define MCMsgId(id) (unsigned int) ( (id << (sizeof(short) * 8)) \ -@@ -54,7 +54,7 @@ - #define MCLastMsg 0 - #define MCLastSet 0 - --#define MCMajorVer 1L -+#define MCMajorVer 1 - #define MCMinorVer 0 ++ /* -@@ -100,38 +100,44 @@ + * Critical note here. Sets and Messages *MUST* be stored in ascending + * order. There are stored that way (by specification) in the original +@@ -88,37 +89,43 @@ typedef union { struct _MCSetT *set; } MCOffsetT; @@ -63,15 +62,13 @@ * MCCatT - Runtime catalog pointer */ typedef struct { -- long loadType; /* How to load the messages (see MSLoadType) */ -+ int32_t loadType; /* How to load the messages (see MSLoadType) */ FILE *fp; /* File descriptor of catalog (if load-on-demand) */ - long numSets; /* Number of sets */ + int32_t numSets; /* Number of sets */ MCSetT *sets; /* Pointer to the sets */ off_t firstSet; /* Offset of first set on disk */ } MCCatT; -@@ -141,10 +147,10 @@ +@@ -128,10 +135,10 @@ typedef struct { */ typedef struct { char magic[MCMagicLen]; /* Magic cookie "*nazgul*" */ diff --git a/nls/msgcat-fbsd.c b/nls/msgcat-fbsd.c index c647da6..f65dd93 100644 --- a/nls/msgcat-fbsd.c +++ b/nls/msgcat-fbsd.c @@ -31,7 +31,7 @@ up-to-date. Many thanks. ******************************************************************/ #include -__FBSDID("$FreeBSD: src/lib/libc/nls/msgcat.c,v 1.48 2003/10/29 10:45:01 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/nls/msgcat.c,v 1.49 2005/02/01 16:04:55 phantom Exp $"); /* * We need a better way of handling errors than printing text. I need @@ -70,14 +70,12 @@ __FBSDID("$FreeBSD: src/lib/libc/nls/msgcat.c,v 1.48 2003/10/29 10:45:01 tjr Exp #define NLERR ((nl_catd) -1) #define NLRETERR(errc) { errno = errc; return (NLERR); } -static nl_catd loadCat(); -static int loadSet(); -static void __nls_free_resources(); +static nl_catd loadCat(__const char *); +static int loadSet(MCCatT *, MCSetT *); +static void __nls_free_resources(MCCatT *, int); nl_catd -catopen(name, type) - __const char *name; - int type; +catopen(__const char *name, int type) { int spcleft, saverr; char path[PATH_MAX]; @@ -164,7 +162,7 @@ catopen(name, type) (pathP - path) - 1; if (strlcpy(pathP, tmpptr, spcleft) >= spcleft) { - too_long: + too_long: free(plang); free(base); NLRETERR(ENAMETOOLONG); @@ -272,11 +270,7 @@ MCGetMsg(MCSetT *set, int msgId) } char * -catgets(catd, setId, msgId, dflt) - nl_catd catd; - int setId; - int msgId; - __const char *dflt; +catgets(nl_catd catd, int setId, int msgId, __const char *dflt) { MCMsgT *msg; MCCatT *cat = (MCCatT *)catd; @@ -293,8 +287,7 @@ catgets(catd, setId, msgId, dflt) } int -catclose(catd) - nl_catd catd; +catclose(nl_catd catd) { MCCatT *cat = (MCCatT *)catd; @@ -302,10 +295,8 @@ catclose(catd) errno = EBADF; return (-1); } -#if 0 - if (cat->loadType != MCLoadAll) -#endif - (void)fclose(cat->fp); + + (void)fclose(cat->fp); __nls_free_resources(cat, cat->numSets); free(cat); return (0); @@ -335,9 +326,7 @@ static char *_errowner = "Message Catalog System"; } static void -__nls_free_resources(cat, i) - MCCatT *cat; - int i; +__nls_free_resources(MCCatT *cat, int i) { MCSetT *set; int j; @@ -353,8 +342,7 @@ __nls_free_resources(cat, i) } static nl_catd -loadCat(catpath) - __const char *catpath; +loadCat(__const char *catpath) { MCHeaderT header; MCCatT *cat; @@ -365,7 +353,6 @@ loadCat(catpath) if ((cat = (MCCatT *)malloc(sizeof(MCCatT))) == NULL) return (NLERR); - cat->loadType = MCLoadBySet; if ((cat->fp = fopen(catpath, "r")) == NULL) { saverr = errno; @@ -422,36 +409,15 @@ loadCat(catpath) nextSet = ntohll(set->nextSet); continue; } -#if 0 - if (cat->loadType == MCLoadAll) { - int res; - - if ((res = loadSet(cat, set)) <= 0) { - saverr = errno; - __nls_free_resources(cat, i); - errno = saverr; - if (res < 0) - NOSPACE(); - CORRUPT(); - } - } else -#endif - set->invalid = TRUE; + set->invalid = TRUE; nextSet = ntohll(set->nextSet); } -#if 0 - if (cat->loadType == MCLoadAll) { - (void)fclose(cat->fp); - cat->fp = NULL; - } -#endif + return ((nl_catd) cat); } static int -loadSet(cat, set) - MCCatT *cat; - MCSetT *set; +loadSet(MCCatT *cat, MCSetT *set) { MCMsgT *msg; int i; diff --git a/nls/msgcat.h b/nls/msgcat.h index 51b009a..1e9f1a0 100644 --- a/nls/msgcat.h +++ b/nls/msgcat.h @@ -1,4 +1,4 @@ -/* $FreeBSD: src/lib/libc/nls/msgcat.h,v 1.8 2000/09/03 21:05:10 ache Exp $ */ +/* $FreeBSD: src/lib/libc/nls/msgcat.h,v 1.9 2005/02/01 16:04:55 phantom Exp $ */ #ifndef _MSGCAT_H_ #define _MSGCAT_H_ @@ -36,27 +36,21 @@ up-to-date. Many thanks. ******************************************************************/ - -#include - /* - * On disk data structures + * Magic definitions */ -/* For or'd constants */ -#define MCMakeId(s,m) (u_int32_t) ( ((unsigned short)s << (sizeof(short)*8)) \ - | (unsigned short)m ) -#define MCSetId(id) (unsigned int) ( id >> (sizeof(short) * 8) ) -#define MCMsgId(id) (unsigned int) ( (id << (sizeof(short) * 8)) \ - >> (sizeof(short) * 8) ) #define MCMagicLen 8 #define MCMagic "*nazgul*" -#define MCLastMsg 0 -#define MCLastSet 0 #define MCMajorVer 1 #define MCMinorVer 0 +/* For or'd constants */ +#define MCMakeId(s,m) (u_int32_t) ( ((unsigned short)s << (sizeof(short)*8)) \ + | (unsigned short)m ) + + /* * Critical note here. Sets and Messages *MUST* be stored in ascending * order. There are stored that way (by specification) in the original @@ -84,11 +78,6 @@ up-to-date. Many thanks. * no guarantee that this will all work. */ -/* These should be publicly available */ - -#define MCLoadBySet 0 /* Load entire sets as they are used */ -#define MCLoadAll 1 /* Load entire DB on catopen */ - /* * MCOffsetT - Union to handle both disk and runtime pointers */ @@ -135,7 +124,6 @@ typedef struct _MCSetT { * MCCatT - Runtime catalog pointer */ typedef struct { - int32_t loadType; /* How to load the messages (see MSLoadType) */ FILE *fp; /* File descriptor of catalog (if load-on-demand) */ int32_t numSets; /* Number of sets */ MCSetT *sets; /* Pointer to the sets */ diff --git a/posix1e/Makefile.inc b/posix1e/Makefile.inc index dea2441..da2d99a 100644 --- a/posix1e/Makefile.inc +++ b/posix1e/Makefile.inc @@ -15,6 +15,7 @@ MAN3 += acl.3 \ acl_clear_flags_np.3 \ acl_clear_perms.3 \ acl_copy_entry.3 \ + acl_copy_ext.3 \ acl_create_entry.3 \ acl_delete_entry.3 \ acl_delete_flag_np.3 \ @@ -26,6 +27,7 @@ MAN3 += acl.3 \ acl_get_entry.3 \ acl_get_flagset_np.3 \ acl_get_permset.3 \ + acl_get_permset_mask_np.3 \ acl_get_perm_np.3 \ acl_get_qualifier.3 \ acl_get_tag_type.3 \ @@ -38,6 +40,13 @@ MAN3 += acl.3 \ acl_to_text.3 \ acl_valid.3 +MLINKS+= acl.3 posix1e.3 + +MLINKS+= acl_copy_ext.3 acl_copy_ext_native.3 \ + acl_copy_ext.3 acl_copy_int.3 \ + acl_copy_ext.3 acl_copy_int_native.3 \ + acl_copy_ext.3 acl_size.3 + MLINKS+= acl_create_entry.3 acl_create_entry_np.3 #MLINKS+= acl_delete.3 acl_delete_fd_np.3 \ @@ -49,6 +58,9 @@ MLINKS+= acl_get.3 acl_get_fd.3 \ acl_get.3 acl_get_file.3 \ acl_get.3 acl_get_link_np.3 +MLINKS+= acl_get_permset_mask_np.3 acl_set_permset_mask_np.3 \ + acl_get_permset_mask_np.3 acl_maximal_permset_mask_np.3 + MLINKS+= acl_set.3 acl_set_fd.3 \ acl_set.3 acl_set_fd_np.3 \ acl_set.3 acl_set_file.3 \ diff --git a/posix1e/acl.3 b/posix1e/acl.3 index 8086084..039669a 100644 --- a/posix1e/acl.3 +++ b/posix1e/acl.3 @@ -75,14 +75,6 @@ and may be used to copy the contents of an ACL entry. This function is described in .Xr acl_create_entry 3 , and may be used to create an empty entry in an ACL. -.It Xo -.Fn acl_delete_fd_np , -.Fn acl_delete_file_np , -.Fn acl_delete_link_np -.Xc -These functions are described in -.Xr acl_delete 3 , -and may be used to delete ACLs from file system objects. .It Fn acl_delete_entry This function is described in .Xr acl_delete_entry 3 , @@ -170,9 +162,6 @@ and may be used to validate an ACL as correct POSIX.1e-semantics, or as appropriate for a particular file system object regardless of semantics. .El .Pp -Documentation of the internal kernel interfaces backing these calls may -be found in -.Xr acl 9 . The syscalls between the internal interfaces and the public library routines may change over time, and as such are not documented. They are not intended to be called directly without going through the @@ -203,7 +192,6 @@ library. .Xr acl_to_text 3 , .Xr acl_valid 3 , .Xr posix1e 3 -.\".Xr acl 9 .Sh UNSUPPORTED FUNCTIONS .Xr acl_calc_mask 3 , .Fn acl_delete_def_file diff --git a/posix1e/acl.c b/posix1e/acl.c index 8d05348..8314de7 100644 --- a/posix1e/acl.c +++ b/posix1e/acl.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -52,7 +53,8 @@ acl_free(void *obj) * Without tracking the addresses of text buffers and qualifiers, * we can't validate the obj argument here at all. */ - free(obj); + if(obj != _FILESEC_REMOVE_ACL) + free(obj); return(0); } diff --git a/posix1e/acl_copy_ext.3 b/posix1e/acl_copy_ext.3 new file mode 100644 index 0000000..9ac17fe --- /dev/null +++ b/posix1e/acl_copy_ext.3 @@ -0,0 +1,174 @@ +.Dd February 3, 2011 +.Dt ACL_COPY_EXT 3 +.Sh NAME +.Nm acl_copy_ext , +.Nm acl_copy_ext_native , +.Nm acl_copy_int , +.Nm acl_copy_int_native, +.Nm acl_size +.Nd convert an ACL to and from an external representation +.Sh SYNOPSIS +.In sys/types.h +.In sys/acl.h +.Ft ssize_t +.Fo acl_copy_ext +.Fa "void *buf" +.Fa "acl_t acl" +.Fa "ssize_t size" +.Fc +.Ft ssize_t +.Fo acl_copy_ext_native +.Fa "void *buf" +.Fa "acl_t acl" +.Fa "ssize_t size" +.Fc +.Ft acl_t +.Fo acl_copy_int +.Fa "const void *buf" +.Fc +.Ft acl_t +.Fo acl_copy_int_native +.Fa "const void *buf" +.Fc +.Ft ssize_t +.Fo acl_size +.Fa "acl_t acl" +.Fc +.Sh DESCRIPTION +The +.Fn acl_copy_ext +and +.Fn acl_copy_ext_native +functions convert the ACL given by the argument +.Fa acl +into a binary external representation that can be saved to a file, +passed to another program, etc. +This external representation is written to the buffer pointed to by the argument +.Fa buf , +which is assumed to have at least the number of contiguous bytes passed in the +.Fa size +argument. +The number of bytes actually written is returned. +.Pp +The +.Fn acl_copy_ext +function writes data in big-endian byte-order, and so is portable across +machines with different byte-order. +To the contrary, the +.Fn acl_copy_ext_native +function uses the machine's native byte-order, and so is only portable to +machines of like byte-order. +.Pp +The +.Fn acl_copy_int +and +.Fn acl_copy_int_native +functions do the reverse conversion; the ACL represented by the external +representation passed in the argument +.Fa buf , +is returned. +The +.Fn acl_copy_int +function expects an external representation in big-endian byte-order (as +returned by +.Fn acl_copy_ext ) , +while +.Fn acl_copy_int_native +expects an external representation in native byte-order (as returned by +.Fn acl_copy_ext_native ) . +.Pp +The +.Fn acl_size +function returns the corresponding external representation size, in bytes, for +the given ACL passed in the argument +.Fa acl . +This size can be used to allocate sufficient memory for the buffer in +subsequent calls to +.Fn acl_copy_ext +and +.Fn acl_copy_ext_native . +.Sh RETURN VALUES +Upon successful completion, the +.Fn acl_copy_ext +and +.Fn acl_copy_ext_native +functions shall return the number of bytes actually written to the buffer. +Otherwise, a value of +.Va -1 +shall be returned and +.Va errno +shall be set to indicate the error. +.Pp +Upon successful completion, the +.Fn acl_copy_int +and +.Fn acl_copy_int_native +functions shall return the ACL represented by the external representation +passed in the buffer. +Otherwise, a value of +.Va (acl_t)NULL +shall be returned and +.Va errno +shall be set to indicate the error. +.Pp +Upon successful completion, the +.Fn acl_size +function shall return the size of the external representation. +Otherwise, a value of +.Va -1 +shall be returned and +.Va errno +shall be set to indicate the error. +.Sh ERRORS +The +.Fn acl_copy_ext +and +.Fn acl_copy_ext_native +functions fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +Argument +.Fa acl +does not point to a valid ACL. +.It Bq Er ERANGE +The given buffer is too small to contain the converted external representation. +.El +.Pp +The +.Fn acl_copy_int +and +.Fn acl_copy_int_native +functions fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The buffer does not contain a valid external representation. +.El +.Pp +The +.Fn acl_size +function fails if: +.Bl -tag -width Er +.It Bq Er EINVAL +Argument +.Fa acl +does not point to a valid ACL. +.El +.Sh NOTE +While the external representation may use pre-existing data structures, +no assumptions on the internal structure should be made. +.Pp +The +.Xr acl_to_text 3 +and +.Xr acl_from_text 3 +functions also convert to and from a different external representation, +a human-readable string. +Neither of these representations are cross-platform, lacking a cross-platform +standard. +.Sh SEE ALSO +.Xr acl 3 , +.Xr acl_from_text 3 , +.Xr acl_to_text 3 +.Sh AUTHORS +.An Michael Smith +.An Robert N M Watson diff --git a/posix1e/acl_create_entry.3 b/posix1e/acl_create_entry.3 index 1a4a932..60e34ff 100644 --- a/posix1e/acl_create_entry.3 +++ b/posix1e/acl_create_entry.3 @@ -48,6 +48,9 @@ function is a POSIX.1e call that creates a new ACL entry in the ACL pointed to by .Fa acl_p . +The function will return in +.Fa entry_p +a descriptor for this ACL entry. .Pp The .Fn acl_create_entry_np diff --git a/posix1e/acl_entry.c b/posix1e/acl_entry.c index a7d2278..a690c00 100644 --- a/posix1e/acl_entry.c +++ b/posix1e/acl_entry.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004, 2011 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -30,6 +30,13 @@ #include "aclvar.h" +#if __DARWIN_ACL_EXTENDED_ALLOW != KAUTH_ACE_PERMIT +# error __DARWIN_ACL_EXTENDED_ALLOW != KAUTH_ACE_PERMIT +#endif +#if __DARWIN_ACL_EXTENDED_DENY != KAUTH_ACE_DENY +# error __DARWIN_ACL_EXTENDED_DENY != KAUTH_ACE_DENY +#endif + int acl_copy_entry(acl_entry_t dest, acl_entry_t src) { @@ -69,6 +76,7 @@ acl_create_entry_np(acl_t *acl_p, acl_entry_t *entry_p, int index) ap->a_entries++; /* initialise new entry */ + memset(&ap->a_ace[index], 0, sizeof(ap->a_ace[index])); ap->a_ace[index].ae_magic = _ACL_ENTRY_MAGIC; ap->a_ace[index].ae_tag = ACL_UNDEFINED_TAG; diff --git a/posix1e/acl_flag.c b/posix1e/acl_flag.c index 72f7d64..190bed9 100644 --- a/posix1e/acl_flag.c +++ b/posix1e/acl_flag.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -30,6 +30,25 @@ #include "aclvar.h" +#if __DARWIN_ACL_ENTRY_INHERITED != KAUTH_ACE_INHERITED +# error __DARWIN_ACL_ENTRY_INHERITED != KAUTH_ACE_INHERITED +#endif +#if __DARWIN_ACL_ENTRY_FILE_INHERIT != KAUTH_ACE_FILE_INHERIT +# error __DARWIN_ACL_ENTRY_FILE_INHERIT != KAUTH_ACE_FILE_INHERIT +#endif +#if __DARWIN_ACL_ENTRY_DIRECTORY_INHERIT != KAUTH_ACE_DIRECTORY_INHERIT +# error __DARWIN_ACL_ENTRY_DIRECTORY_INHERIT != KAUTH_ACE_DIRECTORY_INHERIT +#endif +#if __DARWIN_ACL_ENTRY_LIMIT_INHERIT != KAUTH_ACE_LIMIT_INHERIT +# error __DARWIN_ACL_ENTRY_LIMIT_INHERIT != KAUTH_ACE_LIMIT_INHERIT +#endif +#if __DARWIN_ACL_ENTRY_ONLY_INHERIT != KAUTH_ACE_ONLY_INHERIT +# error __DARWIN_ACL_ENTRY_ONLY_INHERIT != KAUTH_ACE_ONLY_INHERIT +#endif +#if __DARWIN_ACL_FLAG_NO_INHERIT != KAUTH_ACL_NO_INHERIT +# error __DARWIN_ACL_FLAG_NO_INHERIT != KAUTH_ACL_NO_INHERIT +#endif + int acl_add_flag_np(acl_flagset_t flags, acl_flag_t flag) { diff --git a/posix1e/acl_get_permset_mask_np.3 b/posix1e/acl_get_permset_mask_np.3 new file mode 100644 index 0000000..a47ac7c --- /dev/null +++ b/posix1e/acl_get_permset_mask_np.3 @@ -0,0 +1,93 @@ +.Dd August 24, 2010 +.Os Darwin +.Dt ACL_PERMSET_MASK 3 +.Sh NAME +.Nm acl_permset_mask +.Nd Manipulate ACL permissions using bitmasks +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/acl.h +.Ft int +.Fn acl_maximal_permset_mask_np "acl_permset_mask_t * mask_p" +.Ft int +.Fn acl_get_permset_mask_np "acl_entry_t entry_d" "acl_permset_mask_t * mask_p" +.Ft int +.Fn acl_set_permset_mask_np "acl_entry_t entry_d" "acl_permset_mask_t mask" +.Sh DESCRIPTION +The +.Fa acl_permset_mask_t +functions are a Darwin extension to the POSIX.1e ACL standard which allow +manipulation of permissions in an +.Fa acl_entry_t +using a bitmask of type +.Fa acl_permset_mask_t +rather than a constructed acl_permset_t (as done by +.Xr acl_get_permset 3 +and +.Xr acl_set_permset 3 ) . +.Pp +.Fa acl_permset_mask_t +values may be constructed using bitwise operations over +.Fa acl_perm_t +values. +.Pp +.Fn acl_maximal_permset_mask_np +sets the value pointed to by +.Fa mask_p +to a bitmask of all valid +.Fa acl_perm_t +values. +.Pp +.Fn acl_get_permset_mask_np +returns via +.Fa mask_p +a bitmask of permissions set on the ACL entry +.Fa entry_d . +.Pp +.Fn acl_set_permset_mask_np +sets the permissions of ACL entry +.Fa entry_d +to match the permission bitmask provided by +.Fa mask . +.Sh RETURN VALUES +.Rv -std acl_maximal_permset_mask_np +.Pp +.Rv -std acl_get_permset_mask_np +.Pp +.Rv -std acl_set_permset_mask_np +.Sh ERRORS +The +.Fn acl_get_permset_mask_np +function fails if: +.Bl -tag -width Er +.It Bq Er EINVAL +Argument +.Fa entry_d +is not a valid descriptor for an ACL entry. +.El +.Pp +The +.Fn acl_set_permset_mask_np +function fails if: +.Bl -tag -width Er +.It Bq Er EINVAL +Argument +.Fa entry_d +is not a valid descriptor for an ACL entry. +.It Bq Er EINVAL +Argument +.Fa mask +is not a valid bitmask of ACL permissions. +.El +.Sh SEE ALSO +.Xr acl 3 , +.Xr acl_add_perm 3 , +.Xr acl_clear_perms 3 , +.Xr acl_delete_perm 3 , +.Xr acl_get_permset 3 , +.Xr acl_set_permset 3 , +.Xr posix1e 3 +.Sh AUTHORS +.An Jeremy Huddleston diff --git a/posix1e/acl_perm.c b/posix1e/acl_perm.c index e344ca8..579915d 100644 --- a/posix1e/acl_perm.c +++ b/posix1e/acl_perm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004-2010 Apple, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -30,6 +30,58 @@ #include "aclvar.h" +#if __DARWIN_ACL_READ_DATA != KAUTH_VNODE_READ_DATA +# error __DARWIN_ACL_READ_DATA != KAUTH_VNODE_READ_DATA +#endif +#if __DARWIN_ACL_LIST_DIRECTORY != KAUTH_VNODE_LIST_DIRECTORY +# error __DARWIN_ACL_LIST_DIRECTORY != KAUTH_VNODE_LIST_DIRECTORY +#endif +#if __DARWIN_ACL_WRITE_DATA != KAUTH_VNODE_WRITE_DATA +# error __DARWIN_ACL_WRITE_DATA != KAUTH_VNODE_WRITE_DATA +#endif +#if __DARWIN_ACL_ADD_FILE != KAUTH_VNODE_ADD_FILE +# error __DARWIN_ACL_ADD_FILE != KAUTH_VNODE_ADD_FILE +#endif +#if __DARWIN_ACL_EXECUTE != KAUTH_VNODE_EXECUTE +# error __DARWIN_ACL_EXECUTE != KAUTH_VNODE_EXECUTE +#endif +#if __DARWIN_ACL_SEARCH != KAUTH_VNODE_SEARCH +# error __DARWIN_ACL_SEARCH != KAUTH_VNODE_SEARCH +#endif +#if __DARWIN_ACL_DELETE != KAUTH_VNODE_DELETE +# error __DARWIN_ACL_DELETE != KAUTH_VNODE_DELETE +#endif +#if __DARWIN_ACL_APPEND_DATA != KAUTH_VNODE_APPEND_DATA +# error __DARWIN_ACL_APPEND_DATA != KAUTH_VNODE_APPEND_DATA +#endif +#if __DARWIN_ACL_ADD_SUBDIRECTORY != KAUTH_VNODE_ADD_SUBDIRECTORY +# error __DARWIN_ACL_ADD_SUBDIRECTORY != KAUTH_VNODE_ADD_SUBDIRECTORY +#endif +#if __DARWIN_ACL_DELETE_CHILD != KAUTH_VNODE_DELETE_CHILD +# error __DARWIN_ACL_DELETE_CHILD != KAUTH_VNODE_DELETE_CHILD +#endif +#if __DARWIN_ACL_READ_ATTRIBUTES != KAUTH_VNODE_READ_ATTRIBUTES +# error __DARWIN_ACL_READ_ATTRIBUTES != KAUTH_VNODE_READ_ATTRIBUTES +#endif +#if __DARWIN_ACL_WRITE_ATTRIBUTES != KAUTH_VNODE_WRITE_ATTRIBUTES +# error __DARWIN_ACL_WRITE_ATTRIBUTES != KAUTH_VNODE_WRITE_ATTRIBUTES +#endif +#if __DARWIN_ACL_READ_EXTATTRIBUTES != KAUTH_VNODE_READ_EXTATTRIBUTES +# error __DARWIN_ACL_READ_EXTATTRIBUTES != KAUTH_VNODE_READ_EXTATTRIBUTES +#endif +#if __DARWIN_ACL_WRITE_EXTATTRIBUTES != KAUTH_VNODE_WRITE_EXTATTRIBUTES +# error __DARWIN_ACL_WRITE_EXTATTRIBUTES != KAUTH_VNODE_WRITE_EXTATTRIBUTES +#endif +#if __DARWIN_ACL_READ_SECURITY != KAUTH_VNODE_READ_SECURITY +# error __DARWIN_ACL_READ_SECURITY != KAUTH_VNODE_READ_SECURITY +#endif +#if __DARWIN_ACL_WRITE_SECURITY != KAUTH_VNODE_WRITE_SECURITY +# error __DARWIN_ACL_WRITE_SECURITY != KAUTH_VNODE_WRITE_SECURITY +#endif +#if __DARWIN_ACL_CHANGE_OWNER != KAUTH_VNODE_CHANGE_OWNER +# error __DARWIN_ACL_CHANGE_OWNER != KAUTH_VNODE_CHANGE_OWNER +#endif + int acl_add_perm(acl_permset_t permset, acl_perm_t perm) { @@ -84,3 +136,30 @@ acl_set_permset(acl_entry_t entry, acl_permset_t permset) entry->ae_perms = permset->ap_perms; return(0); } + +int +acl_maximal_permset_mask_np(acl_permset_mask_t * mask_p) +{ + /* Bitwise or of all possible acl_perm_t values */ + *mask_p = _ACL_PERMS_MASK; + return (0); +} + +int +acl_get_permset_mask_np(acl_entry_t entry, acl_permset_mask_t * mask_p) +{ + _ACL_VALIDATE_ENTRY(entry); + + *mask_p = (acl_permset_mask_t)entry->ae_perms; + return (0); +} + +int +acl_set_permset_mask_np(acl_entry_t entry, acl_permset_mask_t mask) +{ + _ACL_VALIDATE_ENTRY(entry); + _ACL_VALIDATE_PERM(mask); + + entry->ae_perms = mask; + return (0); +} diff --git a/posix1e/acl_translate.c b/posix1e/acl_translate.c index c62d3a2..41bbe21 100644 --- a/posix1e/acl_translate.c +++ b/posix1e/acl_translate.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004, 2010, 2011 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -24,11 +24,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -62,9 +64,17 @@ acl_copy_ext(void *buf, acl_t acl, ssize_t size) errno = ERANGE; return(-1); } + + bzero(ext, reqsize); + ext->fsec_magic = OSSwapHostToBigInt32(KAUTH_FILESEC_MAGIC); + + /* special case for _FILESEC_REMOVE_ACL */ + if (acl == (acl_t)_FILESEC_REMOVE_ACL) { + ext->fsec_entrycount = OSSwapHostToBigInt32(KAUTH_FILESEC_NOACL); + return(reqsize); + } /* export the header */ - ext->fsec_magic = OSSwapHostToBigInt32(KAUTH_FILESEC_MAGIC); ext->fsec_entrycount = OSSwapHostToBigInt32(acl->a_entries); ext->fsec_flags = OSSwapHostToBigInt32(acl->a_flags); @@ -98,12 +108,19 @@ acl_copy_ext_native(void *buf, acl_t acl, ssize_t size) errno = ERANGE; return(-1); } + + bzero(ext, reqsize); + ext->fsec_magic = KAUTH_FILESEC_MAGIC; + + /* special case for _FILESEC_REMOVE_ACL */ + if (acl == (acl_t)_FILESEC_REMOVE_ACL) { + ext->fsec_entrycount = KAUTH_FILESEC_NOACL; + return(reqsize); + } /* export the header */ - ext->fsec_magic = KAUTH_FILESEC_MAGIC; ext->fsec_entrycount = acl->a_entries; ext->fsec_flags = acl->a_flags; - /* XXX owner? */ /* copy ACEs */ for (i = 0; i < acl->a_entries; i++) { @@ -224,6 +241,7 @@ static struct { {ACL_ENTRY_DIRECTORY_INHERIT, "directory_inherit", ACL_TYPE_DIR}, {ACL_ENTRY_LIMIT_INHERIT, "limit_inherit", ACL_TYPE_FILE | ACL_TYPE_DIR}, {ACL_ENTRY_ONLY_INHERIT, "only_inherit", ACL_TYPE_DIR}, + {ACL_FLAG_NO_INHERIT, "no_inherit", ACL_TYPE_ACL}, {0, NULL, 0} }; @@ -628,20 +646,25 @@ acl_to_text(acl_t acl, ssize_t *len_p) if (((uu = (uuid_t *) acl_get_qualifier(entry)) == NULL) || (acl_get_tag_type(entry, &tag) != 0) || (acl_get_flagset_np(entry, &flags) != 0) - || (acl_get_permset(entry, &perms) != 0) - || ((str = uuid_to_name(uu, &id, &isgid)) == NULL)) { + || (acl_get_permset(entry, &perms) != 0)) { if (uu != NULL) acl_free(uu); continue; } uuid_unparse_upper(*uu, uu_str); - valid = raosnprintf(&buf, &bufsize, len_p, "\n%s:%s:%s:%d:%s", - isgid ? "group" : "user", - uu_str, - str, - id, - (tag == ACL_EXTENDED_ALLOW) ? "allow" : "deny"); + if ((str = uuid_to_name(uu, &id, &isgid)) != NULL) { + valid = raosnprintf(&buf, &bufsize, len_p, "\n%s:%s:%s:%d:%s", + isgid ? "group" : "user", + uu_str, + str, + id, + (tag == ACL_EXTENDED_ALLOW) ? "allow" : "deny"); + } else { + valid = raosnprintf(&buf, &bufsize, len_p, "\nuser:%s:::%s", + uu_str, + (tag == ACL_EXTENDED_ALLOW) ? "allow" : "deny"); + } free(str); acl_free(uu); @@ -690,6 +713,10 @@ err_nomem: ssize_t acl_size(acl_t acl) { + /* special case for _FILESEC_REMOVE_ACL */ + if (acl == (acl_t)_FILESEC_REMOVE_ACL) + return KAUTH_FILESEC_SIZE(0); + _ACL_VALIDATE_ACL(acl); return(KAUTH_FILESEC_SIZE(acl->a_entries)); diff --git a/posix1e/aclvar.h b/posix1e/aclvar.h index 0a9426a..33c432b 100644 --- a/posix1e/aclvar.h +++ b/posix1e/aclvar.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2008 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004, 2008, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -67,10 +67,20 @@ struct _acl_permset { /* * Argument validation. */ +/* + * Because of the use of special values for structure pointer (like + * _FILESEC_REMOVE_ACL), dereferences causes crashes. Rather than try to + * enumerate all such special values, we will assume there are a small + * number of these values, centered about zero, so we can just check the + * values are in this range. We have to do the check for both ACLs and + * ACEs, because the API uses the same routines on ACLs and ACEs. + */ + +#define _ACL_SPECIAL_RANGE 16 -#define _ACL_VALID_ENTRY(_e) ((_e)->ae_magic == _ACL_ENTRY_MAGIC) +#define _ACL_VALID_ENTRY(_e) ((((intptr_t)(_e)) > _ACL_SPECIAL_RANGE || ((intptr_t)(_e)) < -(_ACL_SPECIAL_RANGE)) && (_e)->ae_magic == _ACL_ENTRY_MAGIC) -#define _ACL_VALID_ACL(_a) ((_a)->a_magic == _ACL_ACL_MAGIC) +#define _ACL_VALID_ACL(_a) ((((intptr_t)(_a)) > _ACL_SPECIAL_RANGE || ((intptr_t)(_a)) < -(_ACL_SPECIAL_RANGE)) && (_a)->a_magic == _ACL_ACL_MAGIC) #define _ACL_ENTRY_CONTAINED(_a, _e) \ ((_e) >= &(_a)->a_ace[0]) && ((_e) < &(_a)->a_ace[ACL_MAX_ENTRIES]) diff --git a/ppc/sys/Makefile.inc b/ppc/sys/Makefile.inc index 2cb77d1..48349ed 100644 --- a/ppc/sys/Makefile.inc +++ b/ppc/sys/Makefile.inc @@ -8,5 +8,3 @@ MDSRCS+= OSAtomic.s \ _setjmp.s \ setjmp.s \ _sigtramp.s - -MDCOPYFILES+= ${.CURDIR}/Platforms/${RC_TARGET_CONFIG}/ppc/libc.syscall.ppc diff --git a/ppc/sys/_sigtramp.s b/ppc/sys/_sigtramp.s index cd2dfc6..92be538 100644 --- a/ppc/sys/_sigtramp.s +++ b/ppc/sys/_sigtramp.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007, 2011 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -255,7 +255,7 @@ EH_frame1: LSCIE1: .long 0 ; CIE Identifier Tag .byte 0x3 ; CIE Version - .ascii "zR\0" ; CIE Augmentation + .ascii "zRS\0" ; CIE Augmentation ;; Both these alignment values are unused. .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor diff --git a/ppc64/sys/Makefile.inc b/ppc64/sys/Makefile.inc index 3d9776b..c5574a4 100644 --- a/ppc64/sys/Makefile.inc +++ b/ppc64/sys/Makefile.inc @@ -8,5 +8,3 @@ MDSRCS+= OSAtomic.s \ _setjmp.s \ setjmp.s \ _sigtramp.s - -MDCOPYFILES+= ${.CURDIR}/Platforms/${RC_TARGET_CONFIG}/ppc64/libc.syscall.ppc64 diff --git a/pthreads/Makefile.inc b/pthreads/Makefile.inc index f1ed664..5ba231c 100644 --- a/pthreads/Makefile.inc +++ b/pthreads/Makefile.inc @@ -7,6 +7,8 @@ CFLAGS += -I${.CURDIR}/pthreads MISRCS += pthread_cancelable.c pthread_cond.c pthread_tsd.c pthread.c \ pthread_mutex.c thread_setup.c stack.s pthread_rwlock.c +DYLDSRCS += pthread.c pthread_mutex.c pthread_tsd.c + .ifdef FEATURE_PLOCKSTAT ${SYMROOTINC}/plockstat.h: ${.CURDIR}/pthreads/plockstat.d ${MKDIR} ${SYMROOTINC} @@ -17,7 +19,7 @@ ${_src:R}.${OBJSUFFIX}: ${SYMROOTINC}/plockstat.h .endfor .endif # FEATURE_PLOCKSTAT -PTHREADS_INSTHDRS += pthread.h pthread_impl.h sched.h +PTHREADS_INSTHDRS += pthread.h pthread_spis.h pthread_impl.h sched.h PTHREADS_INSTHDRS := ${PTHREADS_INSTHDRS:S/^/${.CURDIR}\/pthreads\//} INSTHDRS += ${PTHREADS_INSTHDRS} diff --git a/pthreads/pthread.c b/pthreads/pthread.c index 5e9aefb..ef4527e 100644 --- a/pthreads/pthread.c +++ b/pthreads/pthread.c @@ -61,8 +61,10 @@ #include #include #include +#include #include #include +#include #define __APPLE_API_PRIVATE #include #include @@ -88,7 +90,6 @@ extern void mig_init(int); static int _pthread_create_pthread_onstack(pthread_attr_t *attrs, void **stack, pthread_t *thread); static kern_return_t _pthread_free_pthread_onstack(pthread_t t, int freestruct, int termthread); static void _pthread_struct_init(pthread_t t, const pthread_attr_t *attrs, void * stack, size_t stacksize, int kernalloc, int nozero); -static void _pthread_tsd_reinit(pthread_t t); static int _new_pthread_create_suspended(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), @@ -145,7 +146,7 @@ __private_extern__ void _spin_lock_retry(pthread_lock_t *lock) } while(!_spin_lock_try(lock)); } -extern mach_port_t thread_recycle_port; +static mach_port_t thread_recycle_port = MACH_PORT_NULL; /* These are used to keep track of a semaphore pool shared by mutexes and condition ** variables. @@ -163,24 +164,29 @@ static int pthread_concurrency; static OSSpinLock __workqueue_list_lock = OS_SPINLOCK_INIT; -static void _pthread_exit(pthread_t self, void *value_ptr); +static void _pthread_exit(pthread_t self, void *value_ptr) __dead2; static void _pthread_setcancelstate_exit(pthread_t self, void *value_ptr, int conforming); static pthread_attr_t _pthread_attr_default = {0}; static void _pthread_workq_init(pthread_workqueue_t wq, const pthread_workqueue_attr_t * attr); static int kernel_workq_setup = 0; static volatile int32_t kernel_workq_count = 0; -static volatile unsigned int user_workq_count = 0; +static volatile unsigned int user_workq_count = 0; /* number of outstanding workqueues */ +static volatile unsigned int user_workitem_count = 0; /* number of outstanding workitems */ #define KERNEL_WORKQ_ELEM_MAX 64 /* Max number of elements in the kerrel */ static int wqreadyprio = 0; /* current highest prio queue ready with items */ -static int __pthread_workqueue_affinity = 1; /* 0 means no affinity */ __private_extern__ struct __pthread_workitem_pool __pthread_workitem_pool_head = TAILQ_HEAD_INITIALIZER(__pthread_workitem_pool_head); __private_extern__ struct __pthread_workqueue_pool __pthread_workqueue_pool_head = TAILQ_HEAD_INITIALIZER(__pthread_workqueue_pool_head); +static struct _pthread_workitem * __workqueue_pool_ptr; +static size_t __workqueue_pool_size = 0; +static int __workqueue_nitems = 0; + struct _pthread_workqueue_head __pthread_workq0_head; struct _pthread_workqueue_head __pthread_workq1_head; struct _pthread_workqueue_head __pthread_workq2_head; -pthread_workqueue_head_t __pthread_wq_head_tbl[WQ_NUM_PRIO_QS] = {&__pthread_workq0_head, &__pthread_workq1_head, &__pthread_workq2_head}; +struct _pthread_workqueue_head __pthread_workq3_head; +pthread_workqueue_head_t __pthread_wq_head_tbl[WORKQ_NUM_PRIOQUEUE] = {&__pthread_workq0_head, &__pthread_workq1_head, &__pthread_workq2_head, &__pthread_workq3_head}; static void workqueue_list_lock(void); static void workqueue_list_unlock(void); @@ -193,10 +199,12 @@ extern void start_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, extern void thread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int flags); static pthread_workitem_t alloc_workitem(void); static void free_workitem(pthread_workitem_t); +static void grow_workitem(void); static pthread_workqueue_t alloc_workqueue(void); static void free_workqueue(pthread_workqueue_t); static int _pthread_work_internal_init(void); static void workqueue_exit(pthread_t self, pthread_workqueue_t workq, pthread_workitem_t item); +void _pthread_fork_child_postinit(); void pthread_workqueue_atfork_prepare(void); void pthread_workqueue_atfork_parent(void); @@ -234,7 +242,7 @@ void _pthread_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthr static int pthread_setschedparam_internal(pthread_t, mach_port_t, int, const struct sched_param *); extern pthread_t __bsdthread_create(void *(*func)(void *), void * func_arg, void * stack, pthread_t thread, unsigned int flags); -extern int __bsdthread_register(void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), void (*)(pthread_t, mach_port_t, void *, pthread_workitem_t, int), int,void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), void (*)(pthread_t, mach_port_t, void *, pthread_workitem_t, int),__uint64_t); +extern int __bsdthread_register(void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), void (*)(pthread_t, mach_port_t, void *, pthread_workitem_t, int), int,void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), int32_t *,__uint64_t); extern int __bsdthread_terminate(void * freeaddr, size_t freesize, mach_port_t kport, mach_port_t joinsem); extern __uint64_t __thread_selfid( void ); extern int __pthread_canceled(int); @@ -365,7 +373,6 @@ _pthread_free_pthread_onstack(pthread_t t, int freestruct, int termthread) kern_return_t res = 0; vm_address_t freeaddr; size_t freesize; - task_t self = mach_task_self(); int thread_count; mach_port_t kport; semaphore_t joinsem = SEMAPHORE_NULL; @@ -820,13 +827,16 @@ static void _pthread_body(pthread_t self) { _pthread_set_self(self); +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) + if( (self->thread_id = __thread_selfid()) == (__uint64_t)-1) + printf("Failed to set thread_id in _pthread_body\n"); +#endif _pthread_exit(self, (self->fun)(self->arg)); } void _pthread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int pflags) { - int ret; #if WQ_DEBUG pthread_t pself; #endif @@ -916,7 +926,7 @@ _pthread_create(pthread_t t, t->policy = attrs->policy; t->param = attrs->param; t->freeStackOnExit = attrs->freeStackOnExit; - t->mutexes = (struct _pthread_mutex *)NULL; + t->cancel_error = 0; t->sig = _PTHREAD_SIG; t->reply_port = MACH_PORT_NULL; t->cthread_self = NULL; @@ -936,7 +946,7 @@ _pthread_create(pthread_t t, void _pthread_struct_init(pthread_t t, const pthread_attr_t *attrs, void * stack, size_t stacksize, int kernalloc, int nozero) { - mach_vm_offset_t stackaddr = (mach_vm_offset_t)(long)stack; + mach_vm_offset_t stackaddr = (mach_vm_offset_t)(uintptr_t)stack; if (nozero == 0) { memset(t, 0, sizeof(*t)); @@ -946,13 +956,13 @@ _pthread_struct_init(pthread_t t, const pthread_attr_t *attrs, void * stack, siz t->schedset = attrs->schedset; t->tsd[0] = t; if (kernalloc != 0) { - stackaddr = (mach_vm_offset_t)(long)t; + stackaddr = (mach_vm_offset_t)(uintptr_t)t; /* if allocated from kernel set values appropriately */ t->stacksize = stacksize; - t->stackaddr = (void *)(long)stackaddr; + t->stackaddr = (void *)(uintptr_t)stackaddr; t->freeStackOnExit = 1; - t->freeaddr = (void *)(long)(stackaddr - stacksize - vm_page_size); + t->freeaddr = (void *)(uintptr_t)(stackaddr - stacksize - vm_page_size); t->freesize = pthreadsize + stacksize + vm_page_size; } else { t->stacksize = attrs->stacksize; @@ -963,7 +973,7 @@ _pthread_struct_init(pthread_t t, const pthread_attr_t *attrs, void * stack, siz t->inherit = attrs->inherit; t->policy = attrs->policy; t->param = attrs->param; - t->mutexes = (struct _pthread_mutex *)NULL; + t->cancel_error = 0; t->sig = _PTHREAD_SIG; t->reply_port = MACH_PORT_NULL; t->cthread_self = NULL; @@ -979,13 +989,6 @@ _pthread_struct_init(pthread_t t, const pthread_attr_t *attrs, void * stack, siz t->max_tsd_key = 0; } -static void -_pthread_tsd_reinit(pthread_t t) -{ - bzero(&t->tsd[1], (_INTERNAL_POSIX_THREAD_KEYS_END-1) * sizeof(void *)); -} - - /* Need to deprecate this in future */ int _pthread_is_threaded(void) @@ -1047,12 +1050,8 @@ pthread_t pthread_from_mach_thread_np(mach_port_t kernel_thread) size_t pthread_get_stacksize_np(pthread_t t) { - int ret,nestingDepth=0; + int ret; size_t size = 0; - vm_address_t address=0; - vm_size_t region_size=0; - struct vm_region_submap_info_64 info; - mach_msg_type_number_t count; if (t == NULL) return(ESRCH); @@ -1084,7 +1083,7 @@ pthread_get_stackaddr_np(pthread_t t) void * addr = NULL; if (t == NULL) - return((void *)(long)ESRCH); + return((void *)(uintptr_t)ESRCH); if(t == pthread_self() || t == &_thread) //since the main thread will not get deallocated from underneath us return t->stackaddr; @@ -1093,7 +1092,7 @@ pthread_get_stackaddr_np(pthread_t t) if ((ret = _pthread_find_thread(t)) != 0) { UNLOCK(_pthread_list_lock); - return((void *)(long)ret); + return((void *)(uintptr_t)ret); } addr = t->stackaddr; UNLOCK(_pthread_list_lock); @@ -1171,14 +1170,16 @@ int pthread_setname_np(const char *threadname) { int rval; - size_t len; + int len; rval = 0; len = strlen(threadname); - rval = sysctlbyname("kern.threadname", NULL, 0, threadname, len); + + /* protytype is in pthread_internals.h */ + rval = proc_setthreadname((void *)threadname, len); if(rval == 0) { - strlcpy((pthread_self())->pthread_name, threadname, len+1); + strlcpy((pthread_self())->pthread_name, threadname, MAXTHREADNAMESIZE); } return rval; @@ -1309,7 +1310,7 @@ _new_pthread_create_suspended(pthread_t *thread, __kdebug_trace(0x9000008, t, 0, 0, 1, 0); #endif if(t->freeStackOnExit) - vm_deallocate(self, (mach_vm_address_t)(long)t, pthreadsize); + vm_deallocate(self, (mach_vm_address_t)(uintptr_t)t, pthreadsize); else free(t); } else if (t->childrun == 0) { @@ -1345,7 +1346,7 @@ _new_pthread_create_suspended(pthread_t *thread, #if PTH_TRACE __kdebug_trace(0x9000008, t, pthreadsize, 0, 2, 0); #endif - vm_deallocate(self, (mach_vm_address_t)(long)t, pthreadsize); + vm_deallocate(self, (mach_vm_address_t)(uintptr_t)t, pthreadsize); } else if (t->childrun == 0) { TAILQ_INSERT_TAIL(&__pthread_head, t, plist); _pthread_count++; @@ -1921,16 +1922,21 @@ pthread_equal(pthread_t t1, return (t1 == t2); } -__private_extern__ void +// Force LLVM not to optimise this to a call to __pthread_set_self, if it does +// then _pthread_set_self won't be bound when secondary threads try and start up. +void __attribute__((noinline)) _pthread_set_self(pthread_t p) { - extern void __pthread_set_self(pthread_t); + extern void __pthread_set_self(void *); + if (p == 0) { - bzero(&_thread, sizeof(struct _pthread)); + if (_thread.tsd[0] != 0) { + bzero(&_thread, sizeof(struct _pthread)); + } p = &_thread; } p->tsd[0] = p; - __pthread_set_self(p); + __pthread_set_self(&p->tsd[0]); } void @@ -2022,7 +2028,7 @@ pthread_setconcurrency(int new_level) /* * Perform package initialization - called automatically when application starts */ -__private_extern__ int +int pthread_init(void) { pthread_attr_t *attrs; @@ -2082,6 +2088,7 @@ pthread_init(void) workq_targetconc[WORKQ_HIGH_PRIOQUEUE] = ncpus; workq_targetconc[WORKQ_DEFAULT_PRIOQUEUE] = ncpus; workq_targetconc[WORKQ_LOW_PRIOQUEUE] = ncpus; + workq_targetconc[WORKQ_BG_PRIOQUEUE] = ncpus; mach_port_deallocate(mach_task_self(), host); @@ -2104,21 +2111,22 @@ pthread_init(void) /* We ignore the return result here. The ObjC runtime will just have to deal. */ } #endif - + //added so that thread_recycle_port is initialized on new launch. + _pthread_fork_child_postinit(); mig_init(1); /* enable multi-threaded mig interfaces */ if (__oldstyle == 0) { #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread)), _pthread_start, &workq_targetconc[0], (__uint64_t)(&thread->tsd[__PTK_LIBDISPATCH_KEY0]) - (__uint64_t)thread); + __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread)), _pthread_start, &workq_targetconc[0], (uintptr_t)(&thread->tsd[__PTK_LIBDISPATCH_KEY0]) - (uintptr_t)(&thread->tsd[0])); #else - __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread)), NULL, &workq_targetconc[0], (__uint64_t)&thread->tsd[__PTK_LIBDISPATCH_KEY0] - (__uint64_t)thread); + __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread)), NULL, &workq_targetconc[0], (uintptr_t)&thread->tsd[__PTK_LIBDISPATCH_KEY0] - (uintptr_t)thread); #endif } #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) if( (thread->thread_id = __thread_selfid()) == (__uint64_t)-1) printf("Failed to set thread_id in pthread_init\n"); - return 0; #endif + return 0; } int sched_yield(void) @@ -2128,8 +2136,12 @@ int sched_yield(void) } /* This used to be the "magic" that gets the initialization routine called when the application starts */ -static int _do_nothing(void) { return 0; } -int (*_cthread_init_routine)(void) = _do_nothing; +/* + * (These has been moved to setenv.c, so we can use it to fix a less than 10.5 + * crt1.o issue) + * static int _do_nothing(void) { return 0; } + * int (*_cthread_init_routine)(void) = _do_nothing; + */ /* Get a semaphore from the pool, growing it if necessary */ @@ -2186,6 +2198,15 @@ __private_extern__ void _pthread_fork_child(pthread_t p) { #endif } +void _pthread_fork_child_postinit() { + kern_return_t kr; + + kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &thread_recycle_port); + if (kr != KERN_SUCCESS) { + abort(); + } +} + /* * Query/update the cancelability 'state' of a thread */ @@ -2239,7 +2260,7 @@ int _pthread_join_cleanup(pthread_t thread, void ** value_ptr, int conforming) { kern_return_t res; - int detached = 0, ret; + int ret; #if PTH_TRACE __kdebug_trace(0x9000028, thread, 0, 0, 1, 0); @@ -2288,7 +2309,7 @@ _pthread_join_cleanup(pthread_t thread, void ** value_ptr, int conforming) #if PTH_TRACE __kdebug_trace(0x9000028, thread, 0, 0, 2, 0); #endif - vm_deallocate(mach_task_self(), (mach_vm_address_t)(long)thread, pthreadsize); + vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)thread, pthreadsize); } else { thread->sig = _PTHREAD_NO_SIG; #if PTH_TRACE @@ -2390,6 +2411,7 @@ int error = 0; case WORKQ_HIGH_PRIOQUEUE: case WORKQ_DEFAULT_PRIOQUEUE: case WORKQ_LOW_PRIOQUEUE: + case WORKQ_BG_PRIOQUEUE: attr->queueprio = qprio; break; default: @@ -2510,31 +2532,47 @@ _pthread_work_internal_init(void) { int i, error; pthread_workqueue_head_t headp; - pthread_workitem_t witemp; pthread_workqueue_t wq; +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) + pthread_t self = pthread_self(); +#endif if (kernel_workq_setup == 0) { #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread)),NULL,NULL, NULL); + __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread)), _pthread_start, &workq_targetconc[0], (uintptr_t)(&self->tsd[__PTK_LIBDISPATCH_KEY0]) - (uintptr_t)(&self->tsd[0])); #else - __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread)),NULL,NULL, NULL); + __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread)),NULL,NULL,0); #endif _pthread_wq_attr_default.queueprio = WORKQ_DEFAULT_PRIOQUEUE; _pthread_wq_attr_default.sig = PTHREAD_WORKQUEUE_ATTR_SIG; - for( i = 0; i< WQ_NUM_PRIO_QS; i++) { + for( i = 0; i< WORKQ_NUM_PRIOQUEUE; i++) { headp = __pthread_wq_head_tbl[i]; TAILQ_INIT(&headp->wqhead); headp->next_workq = 0; } - /* create work item and workqueue pools */ - witemp = (struct _pthread_workitem *)malloc(sizeof(struct _pthread_workitem) * WORKITEM_POOL_SIZE); - bzero(witemp, (sizeof(struct _pthread_workitem) * WORKITEM_POOL_SIZE)); - for (i = 0; i < WORKITEM_POOL_SIZE; i++) { - TAILQ_INSERT_TAIL(&__pthread_workitem_pool_head, &witemp[i], item_entry); - } + __workqueue_pool_ptr = NULL; + __workqueue_pool_size = round_page(sizeof(struct _pthread_workitem) * WORKITEM_POOL_SIZE); + + __workqueue_pool_ptr = (struct _pthread_workitem *)mmap(NULL, __workqueue_pool_size, + PROT_READ|PROT_WRITE, + MAP_ANON | MAP_PRIVATE, + 0, + 0); + + if (__workqueue_pool_ptr == MAP_FAILED) { + /* Not expected to fail, if it does, always malloc for work items */ + __workqueue_nitems = WORKITEM_POOL_SIZE; + __workqueue_pool_ptr = NULL; + } else + __workqueue_nitems = 0; + + /* sets up the workitem pool */ + grow_workitem(); + + /* since the size is less than a page, leaving this in malloc pool */ wq = (struct _pthread_workqueue *)malloc(sizeof(struct _pthread_workqueue) * WORKQUEUE_POOL_SIZE); bzero(wq, (sizeof(struct _pthread_workqueue) * WORKQUEUE_POOL_SIZE)); for (i = 0; i < WORKQUEUE_POOL_SIZE; i++) { @@ -2544,7 +2582,9 @@ _pthread_work_internal_init(void) if (error = __workq_open()) { TAILQ_INIT(&__pthread_workitem_pool_head); TAILQ_INIT(&__pthread_workqueue_pool_head); - free(witemp); + if (__workqueue_pool_ptr != NULL) { + munmap((void *)__workqueue_pool_ptr, __workqueue_pool_size); + } free(wq); return(ENOMEM); } @@ -2561,14 +2601,25 @@ alloc_workitem(void) pthread_workitem_t witem; if (TAILQ_EMPTY(&__pthread_workitem_pool_head)) { - workqueue_list_unlock(); - witem = malloc(sizeof(struct _pthread_workitem)); - witem->gencount = 0; - workqueue_list_lock(); - } else { - witem = TAILQ_FIRST(&__pthread_workitem_pool_head); - TAILQ_REMOVE(&__pthread_workitem_pool_head, witem, item_entry); + /* the chunk size is set so some multiple of it is pool size */ + if (__workqueue_nitems < WORKITEM_POOL_SIZE) { + grow_workitem(); + } else { + workqueue_list_unlock(); + witem = malloc(sizeof(struct _pthread_workitem)); + workqueue_list_lock(); + witem->fromcache = 0; + goto out; + } } + witem = TAILQ_FIRST(&__pthread_workitem_pool_head); + TAILQ_REMOVE(&__pthread_workitem_pool_head, witem, item_entry); + witem->fromcache = 1; +out: + witem->flags = 0; + witem->item_entry.tqe_next = 0; + witem->item_entry.tqe_prev = 0; + user_workitem_count++; return(witem); } @@ -2576,8 +2627,27 @@ alloc_workitem(void) static void free_workitem(pthread_workitem_t witem) { - witem->gencount++; - TAILQ_INSERT_TAIL(&__pthread_workitem_pool_head, witem, item_entry); + user_workitem_count--; + witem->flags = 0; + if (witem->fromcache != 0) + TAILQ_INSERT_TAIL(&__pthread_workitem_pool_head, witem, item_entry); + else + free(witem); +} + +static void +grow_workitem(void) +{ + pthread_workitem_t witemp; + int i; + + witemp = &__workqueue_pool_ptr[__workqueue_nitems]; + bzero(witemp, (sizeof(struct _pthread_workitem) * WORKITEM_CHUNK_SIZE)); + for (i = 0; i < WORKITEM_CHUNK_SIZE; i++) { + witemp[i].fromcache = 1; + TAILQ_INSERT_TAIL(&__pthread_workitem_pool_head, &witemp[i], item_entry); + } + __workqueue_nitems += WORKITEM_CHUNK_SIZE; } /* This routine is called with list lock held */ @@ -2655,7 +2725,7 @@ pick_nextworkqueue_droplock() loop: while (kernel_workq_count < KERNEL_WORKQ_ELEM_MAX) { found = 0; - for (i = 0; i < WQ_NUM_PRIO_QS; i++) { + for (i = 0; i < WORKQ_NUM_PRIOQUEUE; i++) { wqreadyprio = i; /* because there is nothing else higher to run */ headp = __pthread_wq_head_tbl[i]; @@ -2776,7 +2846,6 @@ post_nextworkitem(pthread_workqueue_t workq) #if WQ_LISTTRACE __kdebug_trace(0x90080a8, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0); #endif - witem->flags = 0; free_workitem(witem); #if WQ_TRACE __kdebug_trace(0x9000064, 4, workq->barrier_count, 0, 0, 0); @@ -2805,7 +2874,6 @@ post_nextworkitem(pthread_workqueue_t workq) __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 0xff, 0); #endif } - witem->flags = 0; free_workitem(witem); workq->flags |= PTHREAD_WORKQ_DESTROYED; #if WQ_TRACE @@ -2989,7 +3057,6 @@ _pthread_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthread_w static void workqueue_exit(pthread_t self, pthread_workqueue_t workq, pthread_workitem_t item) { - pthread_attr_t *attrs = &_pthread_attr_default; pthread_workitem_t baritem; pthread_workqueue_head_t headp; void (*func)(pthread_workqueue_t, void *); @@ -3001,7 +3068,6 @@ workqueue_exit(pthread_t self, pthread_workqueue_t workq, pthread_workitem_t ite #if WQ_TRACE __kdebug_trace(0x9000070, self, 1, item->func_arg, workq->kq_count, 0); #endif - item->flags = 0; free_workitem(item); if ((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == PTHREAD_WORKQ_BARRIER_ON) { @@ -3027,7 +3093,6 @@ workqueue_exit(pthread_t self, pthread_workqueue_t workq, pthread_workitem_t ite #if WQ_LISTTRACE __kdebug_trace(0x90080a8, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0); #endif - baritem->flags = 0; free_workitem(baritem); workq->flags &= ~PTHREAD_WORKQ_BARRIER_ON; #if WQ_TRACE @@ -3147,10 +3212,7 @@ pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(v witem = alloc_workitem(); witem->func = workitem_func; witem->func_arg = workitem_arg; - witem->flags = 0; witem->workq = workq; - witem->item_entry.tqe_next = 0; - witem->item_entry.tqe_prev = 0; /* alloc workitem can drop the lock, check the state */ if ((workq->flags & (PTHREAD_WORKQ_IN_TERMINATE | PTHREAD_WORKQ_DESTROYED)) != 0) { @@ -3163,7 +3225,7 @@ pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(v if (itemhandlep != NULL) *itemhandlep = (pthread_workitem_handle_t *)witem; if (gencountp != NULL) - *gencountp = witem->gencount; + *gencountp = 0; #if WQ_TRACE __kdebug_trace(0x9008090, witem, witem->func, witem->func_arg, workq, 0); #endif @@ -3183,8 +3245,6 @@ pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(v int pthread_workqueue_getovercommit_np(pthread_workqueue_t workq, unsigned int *ocommp) { - pthread_workitem_t witem; - if (valid_workq(workq) == 0) { return(EINVAL); } @@ -3195,13 +3255,6 @@ pthread_workqueue_getovercommit_np(pthread_workqueue_t workq, unsigned int *oco } -/* DEPRECATED -int pthread_workqueue_removeitem_np(pthread_workqueue_t workq, pthread_workitem_handle_t itemhandle, unsigned int gencount) -int pthread_workqueue_addbarrier_np(pthread_workqueue_t workq, void (* callback_func)(pthread_workqueue_t, void *), void * callback_arg, pthread_workitem_handle_t *itemhandlep, unsigned int *gencountp) -int pthread_workqueue_suspend_np(pthread_workqueue_t workq) -int pthread_workqueue_resume_np(pthread_workqueue_t workq) -*/ - #else /* !BUILDING_VARIANT ] [ */ extern int __unix_conforming; extern int _pthread_count; @@ -3220,8 +3273,7 @@ __posix_join_cleanup(void *arg) int already_exited, res; void * dummy; semaphore_t death; - mach_port_t joinport; - int newstyle = 0; + int newstyle; LOCK(thread->lock); already_exited = (thread->detached & _PTHREAD_EXITED); diff --git a/pthreads/pthread.h b/pthreads/pthread.h index be3bb91..132d42e 100644 --- a/pthreads/pthread.h +++ b/pthreads/pthread.h @@ -144,6 +144,7 @@ typedef __darwin_sigset_t sigset_t; */ #include +#include __BEGIN_DECLS /* @@ -222,6 +223,11 @@ __BEGIN_DECLS #define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {0}} +#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER {_PTHREAD_ERRORCHECK_MUTEX_SIG_init, {0}} +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER {_PTHREAD_RECURSIVE_MUTEX_SIG_init, {0}} +#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ + /* * Condition variable attributes */ @@ -472,13 +478,20 @@ void pthread_testcancel(void) __DARWIN_ALIAS(pthread_testcancel); /* returns non-zero if pthread_create or cthread_fork have been called */ int pthread_is_threaded_np(void); -#if defined(__i386__) || defined(__x86_64__) -int pthread_threadid_np(pthread_t,__uint64_t*); -#endif +int pthread_threadid_np(pthread_t,__uint64_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); + +int pthread_rwlock_longrdlock_np(pthread_rwlock_t *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); +int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); +int pthread_rwlock_downgrade_np(pthread_rwlock_t *); +int pthread_rwlock_upgrade_np(pthread_rwlock_t *); +int pthread_rwlock_tryupgrade_np(pthread_rwlock_t *); +int pthread_rwlock_held_np(pthread_rwlock_t *); +int pthread_rwlock_rdheld_np(pthread_rwlock_t *); +int pthread_rwlock_wrheld_np(pthread_rwlock_t *); /*SPI to set and get pthread name*/ -int pthread_getname_np(pthread_t,char*,size_t); -int pthread_setname_np(const char*); +int pthread_getname_np(pthread_t,char*,size_t) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +int pthread_setname_np(const char*) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); /* returns non-zero if the current thread is the main thread */ int pthread_main_np(void); @@ -502,7 +515,7 @@ int pthread_create_suspended_np(pthread_t *, void *); int pthread_kill(pthread_t, int); -pthread_t pthread_from_mach_thread_np(mach_port_t); +pthread_t pthread_from_mach_thread_np(mach_port_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); //Begin-Libc #ifndef LIBC_ALIAS_PTHREAD_SIGMASK diff --git a/pthreads/pthread_cond.c b/pthreads/pthread_cond.c index 73b1d75..b0e881f 100644 --- a/pthreads/pthread_cond.c +++ b/pthreads/pthread_cond.c @@ -58,53 +58,50 @@ #define PLOCKSTAT_MUTEX_RELEASE(x, y) #endif /* PLOCKSTAT */ - extern int __semwait_signal(int, int, int, int, int64_t, int32_t); extern int _pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *, int); extern int __unix_conforming; +extern int usenew_mtximpl; #ifdef PR_5243343 /* 5243343 - temporary hack to detect if we are running the conformance test */ extern int PR_5243343_flag; #endif /* PR_5243343 */ -#if defined(__i386__) || defined(__x86_64__) -__private_extern__ int __new_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime, int isRelative, int isconforming); -extern int _new_pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *, int); -extern int _new_pthread_cond_destroy(pthread_cond_t *); -extern int _new_pthread_cond_destroy_locked(pthread_cond_t *); -int _new_pthread_cond_broadcast(pthread_cond_t *cond); -int _new_pthread_cond_signal_thread_np(pthread_cond_t *cond, pthread_t thread); -int _new_pthread_cond_signal(pthread_cond_t *cond); -int _new_pthread_cond_timedwait_relative_np(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime); -int _new_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); -int _new_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime); -static void _new_cond_cleanup(void *arg); -static void _new_cond_dropwait(npthread_cond_t * cond); - +__private_extern__ int _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime, int isRelative, int isconforming); +#ifndef BUILDING_VARIANT +static void cond_cleanup(void *arg); +static void cond_dropwait(npthread_cond_t * cond, int error, uint32_t updateval); +static void __pthread_cond_set_signature(npthread_cond_t * cond); +static int _pthread_cond_destroy_locked(pthread_cond_t *cond); +#endif #if defined(__LP64__) -#define COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt) \ +#define COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt) \ { \ if (cond->misalign != 0) { \ c_lseqcnt = &cond->c_seq[1]; \ - c_useqcnt = &cond->c_seq[2]; \ + c_sseqcnt = &cond->c_seq[2]; \ + c_useqcnt = &cond->c_seq[0]; \ } else { \ /* aligned */ \ c_lseqcnt = &cond->c_seq[0]; \ - c_useqcnt = &cond->c_seq[1]; \ + c_sseqcnt = &cond->c_seq[1]; \ + c_useqcnt = &cond->c_seq[2]; \ } \ } #else /* __LP64__ */ -#define COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt) \ +#define COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt) \ { \ if (cond->misalign != 0) { \ c_lseqcnt = &cond->c_seq[1]; \ - c_useqcnt = &cond->c_seq[2]; \ + c_sseqcnt = &cond->c_seq[2]; \ + c_useqcnt = &cond->c_seq[0]; \ } else { \ /* aligned */ \ c_lseqcnt = &cond->c_seq[0]; \ - c_useqcnt = &cond->c_seq[1]; \ + c_sseqcnt = &cond->c_seq[1]; \ + c_useqcnt = &cond->c_seq[2]; \ } \ } #endif /* __LP64__ */ @@ -127,488 +124,14 @@ int __kdebug_trace(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); #define _KSYN_TRACE_UM_CVWAIT 0x9000070 #define _KSYN_TRACE_UM_CVSIG 0x9000074 #define _KSYN_TRACE_UM_CVBRD 0x9000078 +#define _KSYN_TRACE_UM_CDROPWT 0x90000a0 +#define _KSYN_TRACE_UM_CVCLRPRE 0x90000a4 #endif /* _KSYN_TRACE_ */ -#endif /* __i386__ || __x86_64__ */ #ifndef BUILDING_VARIANT /* [ */ -/* - * Destroy a condition variable. - */ -int -pthread_cond_destroy(pthread_cond_t *cond) -{ - int ret; - int sig = cond->sig; - - /* to provide backwards compat for apps using united condtn vars */ - if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init)) - return(EINVAL); - - LOCK(cond->lock); - if (cond->sig == _PTHREAD_COND_SIG) - { -#if defined(__i386__) || defined(__x86_64__) - if (cond->pshared == PTHREAD_PROCESS_SHARED) { - ret = _new_pthread_cond_destroy_locked(cond); - UNLOCK(cond->lock); - return(ret); - } -#endif /* __i386__ || __x86_64__ */ - if (cond->busy == (pthread_mutex_t *)NULL) - { - cond->sig = _PTHREAD_NO_SIG; - ret = 0; - } else - ret = EBUSY; - } else - ret = EINVAL; /* Not an initialized condition variable structure */ - UNLOCK(cond->lock); - return (ret); -} - - -/* - * Signal a condition variable, waking up all threads waiting for it. - */ -int -pthread_cond_broadcast(pthread_cond_t *cond) -{ - kern_return_t kern_res; - semaphore_t sem; - int sig = cond->sig; - - /* to provide backwards compat for apps using united condtn vars */ - if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init)) - return(EINVAL); - - LOCK(cond->lock); - if (cond->sig != _PTHREAD_COND_SIG) - { - int res; - - if (cond->sig == _PTHREAD_COND_SIG_init) - { - _pthread_cond_init(cond, NULL, 0); - res = 0; - } else - res = EINVAL; /* Not a condition variable */ - UNLOCK(cond->lock); - return (res); - } -#if defined(__i386__) || defined(__x86_64__) - else if (cond->pshared == PTHREAD_PROCESS_SHARED) { - UNLOCK(cond->lock); - return(_new_pthread_cond_broadcast(cond)); - } -#endif /* __i386__ || __x86_64__ */ - else if ((sem = cond->sem) == SEMAPHORE_NULL) - { - /* Avoid kernel call since there are no waiters... */ - UNLOCK(cond->lock); - return (0); - } - cond->sigspending++; - UNLOCK(cond->lock); - - PTHREAD_MACH_CALL(semaphore_signal_all(sem), kern_res); - - LOCK(cond->lock); - cond->sigspending--; - if (cond->waiters == 0 && cond->sigspending == 0) - { - cond->sem = SEMAPHORE_NULL; - restore_sem_to_pool(sem); - } - UNLOCK(cond->lock); - if (kern_res != KERN_SUCCESS) - return (EINVAL); - return (0); -} - -/* - * Signal a condition variable, waking a specified thread. - */ -int -pthread_cond_signal_thread_np(pthread_cond_t *cond, pthread_t thread) -{ - kern_return_t kern_res; - semaphore_t sem; - int sig = cond->sig; - - /* to provide backwards compat for apps using united condtn vars */ - - if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init)) - return(EINVAL); - LOCK(cond->lock); - if (cond->sig != _PTHREAD_COND_SIG) - { - int ret; - - if (cond->sig == _PTHREAD_COND_SIG_init) - { - _pthread_cond_init(cond, NULL, 0); - ret = 0; - } else - ret = EINVAL; /* Not a condition variable */ - UNLOCK(cond->lock); - return (ret); - } -#if defined(__i386__) || defined(__x86_64__) - else if (cond->pshared == PTHREAD_PROCESS_SHARED) { - UNLOCK(cond->lock); - return(_new_pthread_cond_signal_thread_np(cond, thread)); - } -#endif /* __i386__ || __x86_64__ */ - else if ((sem = cond->sem) == SEMAPHORE_NULL) - { - /* Avoid kernel call since there are not enough waiters... */ - UNLOCK(cond->lock); - return (0); - } - cond->sigspending++; - UNLOCK(cond->lock); - - if (thread == (pthread_t)NULL) - { - kern_res = semaphore_signal_thread(sem, THREAD_NULL); - if (kern_res == KERN_NOT_WAITING) - kern_res = KERN_SUCCESS; - } - else if (thread->sig == _PTHREAD_SIG) - { - PTHREAD_MACH_CALL(semaphore_signal_thread( - sem, pthread_mach_thread_np(thread)), kern_res); - } - else - kern_res = KERN_FAILURE; - - LOCK(cond->lock); - cond->sigspending--; - if (cond->waiters == 0 && cond->sigspending == 0) - { - cond->sem = SEMAPHORE_NULL; - restore_sem_to_pool(sem); - } - UNLOCK(cond->lock); - if (kern_res != KERN_SUCCESS) - return (EINVAL); - return (0); -} - -/* - * Signal a condition variable, waking only one thread. - */ -int -pthread_cond_signal(pthread_cond_t *cond) -{ - return pthread_cond_signal_thread_np(cond, NULL); -} - -/* - * Manage a list of condition variables associated with a mutex - */ - -static void -_pthread_cond_add(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - pthread_cond_t *c; - LOCK(mutex->lock); - if ((c = mutex->busy) != (pthread_cond_t *)NULL) - { - c->prev = cond; - } - cond->next = c; - cond->prev = (pthread_cond_t *)NULL; - mutex->busy = cond; - UNLOCK(mutex->lock); - if (cond->sem == SEMAPHORE_NULL) - cond->sem = new_sem_from_pool(); -} - -static void -_pthread_cond_remove(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - pthread_cond_t *n, *p; - - LOCK(mutex->lock); - if ((n = cond->next) != (pthread_cond_t *)NULL) - { - n->prev = cond->prev; - } - if ((p = cond->prev) != (pthread_cond_t *)NULL) - { - p->next = cond->next; - } - else - { /* This is the first in the list */ - mutex->busy = n; - } - UNLOCK(mutex->lock); - if (cond->sigspending == 0) - { - restore_sem_to_pool(cond->sem); - cond->sem = SEMAPHORE_NULL; - } -} - -static void -cond_cleanup(void *arg) -{ - pthread_cond_t *cond = (pthread_cond_t *)arg; - pthread_mutex_t *mutex; -// 4597450: begin - pthread_t thread = pthread_self(); - int thcanceled = 0; - - LOCK(thread->lock); - thcanceled = (thread->detached & _PTHREAD_WASCANCEL); - UNLOCK(thread->lock); - - if (thcanceled == 0) - return; - -// 4597450: end - LOCK(cond->lock); - mutex = cond->busy; - cond->waiters--; - if (cond->waiters == 0) { - _pthread_cond_remove(cond, mutex); - cond->busy = (pthread_mutex_t *)NULL; - } - UNLOCK(cond->lock); - - /* - ** Can't do anything if this fails -- we're on the way out - */ - (void)pthread_mutex_lock(mutex); -} - -/* - * Suspend waiting for a condition variable. - * Note: we have to keep a list of condition variables which are using - * this same mutex variable so we can detect invalid 'destroy' sequences. - * If isconforming < 0, we skip the _pthread_testcancel(), but keep the - * remaining conforming behavior.. - */ -__private_extern__ int -_pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *abstime, - int isRelative, - int isconforming) -{ - int res; - kern_return_t kern_res = KERN_SUCCESS; - int wait_res = 0; - pthread_mutex_t *busy; - mach_timespec_t then = {0, 0}; - struct timespec cthen = {0,0}; - int sig = cond->sig; - int msig = mutex->sig; -extern void _pthread_testcancel(pthread_t thread, int isconforming); - - /* to provide backwards compat for apps using united condtn vars */ - if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init)) - return(EINVAL); - - if (isconforming) { - if((msig != _PTHREAD_MUTEX_SIG) && (msig != _PTHREAD_MUTEX_SIG_init)) - return(EINVAL); - if (isconforming > 0) - _pthread_testcancel(pthread_self(), 1); - } - LOCK(cond->lock); - if (cond->sig != _PTHREAD_COND_SIG) - { - if (cond->sig != _PTHREAD_COND_SIG_init) - { - UNLOCK(cond->lock); - return (EINVAL); /* Not a condition variable */ - } - _pthread_cond_init(cond, NULL, 0); - } -#if defined(__i386__) || defined(__x86_64__) - else if (cond->pshared == PTHREAD_PROCESS_SHARED) { - UNLOCK(cond->lock); - return(__new_pthread_cond_wait(cond, mutex, abstime, isRelative, isconforming)); - } -#endif /* __i386__ || __x86_64__ */ - - if (abstime) { - if (!isconforming) - { - if (isRelative == 0) { - struct timespec now; - struct timeval tv; - gettimeofday(&tv, NULL); - TIMEVAL_TO_TIMESPEC(&tv, &now); - - /* Compute relative time to sleep */ - then.tv_nsec = abstime->tv_nsec - now.tv_nsec; - then.tv_sec = abstime->tv_sec - now.tv_sec; - if (then.tv_nsec < 0) - { - then.tv_nsec += NSEC_PER_SEC; - then.tv_sec--; - } - if (((int)then.tv_sec < 0) || - ((then.tv_sec == 0) && (then.tv_nsec == 0))) - { - UNLOCK(cond->lock); - return ETIMEDOUT; - } - } else { - then.tv_sec = abstime->tv_sec; - then.tv_nsec = abstime->tv_nsec; - } - if (then.tv_nsec >= NSEC_PER_SEC) { - UNLOCK(cond->lock); - return EINVAL; - } - } else { - if (isRelative == 0) { - /* preflight the checks for failures */ - struct timespec now; - struct timeval tv; - gettimeofday(&tv, NULL); - TIMEVAL_TO_TIMESPEC(&tv, &now); - - /* Compute relative time to sleep */ - then.tv_nsec = abstime->tv_nsec - now.tv_nsec; - then.tv_sec = abstime->tv_sec - now.tv_sec; - if (then.tv_nsec < 0) - { - then.tv_nsec += NSEC_PER_SEC; - then.tv_sec--; - } - if (((int)then.tv_sec < 0) || - ((then.tv_sec == 0) && (then.tv_nsec == 0))) - { - UNLOCK(cond->lock); - return ETIMEDOUT; - } - if (then.tv_nsec >= NSEC_PER_SEC) { - UNLOCK(cond->lock); - return EINVAL; - } - } - /* we can cleanup this code and pass the calculated time - * to the kernel. But kernel is going to do the same. TILL - * we change the kernel do this anyway - */ - cthen.tv_sec = abstime->tv_sec; - cthen.tv_nsec = abstime->tv_nsec; - if ((cthen.tv_sec < 0) || (cthen.tv_nsec < 0)) { - UNLOCK(cond->lock); - return EINVAL; - } - if (cthen.tv_nsec >= NSEC_PER_SEC) { - UNLOCK(cond->lock); - return EINVAL; - } - } - } - - if (++cond->waiters == 1) - { - _pthread_cond_add(cond, mutex); - cond->busy = mutex; - } - else if ((busy = cond->busy) != mutex) - { - /* Must always specify the same mutex! */ - cond->waiters--; - UNLOCK(cond->lock); - return (EINVAL); - } - UNLOCK(cond->lock); - - LOCK(mutex->lock); - if (--mutex->mtxopts.options.lock_count == 0) - { - PLOCKSTAT_MUTEX_RELEASE(mutex, (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE)? 1:0); - - if (mutex->sem == SEMAPHORE_NULL) - mutex->sem = new_sem_from_pool(); - mutex->owner = _PTHREAD_MUTEX_OWNER_SWITCHING; - UNLOCK(mutex->lock); - - if (!isconforming) { - if (abstime) { - kern_res = semaphore_timedwait_signal(cond->sem, mutex->sem, then); - } else { - PTHREAD_MACH_CALL(semaphore_wait_signal(cond->sem, mutex->sem), kern_res); - } - } else { - pthread_cleanup_push(cond_cleanup, (void *)cond); - wait_res = __semwait_signal(cond->sem, mutex->sem, abstime != NULL, isRelative, - (int64_t)cthen.tv_sec, (int32_t)cthen.tv_nsec); - pthread_cleanup_pop(0); - } - } else { - PLOCKSTAT_MUTEX_RELEASE(mutex, (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE)? 1:0); - UNLOCK(mutex->lock); - if (!isconforming) { - if (abstime) { - kern_res = semaphore_timedwait(cond->sem, then); - } else { - PTHREAD_MACH_CALL(semaphore_wait(cond->sem), kern_res); - } - } else { - pthread_cleanup_push(cond_cleanup, (void *)cond); - wait_res = __semwait_signal(cond->sem, 0, abstime != NULL, isRelative, - (int64_t)cthen.tv_sec, (int32_t)cthen.tv_nsec); - pthread_cleanup_pop(0); - } - - } - - LOCK(cond->lock); - cond->waiters--; - if (cond->waiters == 0) - { - _pthread_cond_remove(cond, mutex); - cond->busy = (pthread_mutex_t *)NULL; - } - UNLOCK(cond->lock); - if ((res = pthread_mutex_lock(mutex)) != 0) - return (res); - - if (!isconforming) { - /* KERN_ABORTED can be treated as a spurious wakeup */ - if ((kern_res == KERN_SUCCESS) || (kern_res == KERN_ABORTED)) - return (0); - else if (kern_res == KERN_OPERATION_TIMED_OUT) - return (ETIMEDOUT); - return (EINVAL); - } else { - if (wait_res < 0) { - if (errno == ETIMEDOUT) { - return ETIMEDOUT; - } else if (errno == EINTR) { - /* - ** EINTR can be treated as a spurious wakeup unless we were canceled. - */ - return 0; - } - return EINVAL; - } - return 0; - } -} - - -int -pthread_cond_timedwait_relative_np(pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *abstime) -{ - return (_pthread_cond_wait(cond, mutex, abstime, 1, 0)); -} - int pthread_condattr_init(pthread_condattr_t *attr) { @@ -639,27 +162,6 @@ pthread_condattr_getpshared(const pthread_condattr_t *attr, } -__private_extern__ int -_pthread_cond_init(pthread_cond_t *cond, - const pthread_condattr_t *attr, - int conforming) -{ - cond->next = (pthread_cond_t *)NULL; - cond->prev = (pthread_cond_t *)NULL; - cond->busy = (pthread_mutex_t *)NULL; - cond->waiters = 0; - cond->sigspending = 0; - if (conforming) { - if (attr) - cond->pshared = attr->pshared; - else - cond->pshared = _PTHREAD_DEFAULT_PSHARED; - } else - cond->pshared = _PTHREAD_DEFAULT_PSHARED; - cond->sem = SEMAPHORE_NULL; - cond->sig = _PTHREAD_COND_SIG; - return (0); -} /* temp home till pshared is fixed correctly */ @@ -670,19 +172,14 @@ pthread_condattr_setpshared(pthread_condattr_t * attr, int pshared) if (attr->sig == _PTHREAD_COND_ATTR_SIG) { #if __DARWIN_UNIX03 -#ifdef PR_5243343 - if (( pshared == PTHREAD_PROCESS_PRIVATE) || (pshared == PTHREAD_PROCESS_SHARED && PR_5243343_flag)) -#else /* !PR_5243343 */ if (( pshared == PTHREAD_PROCESS_PRIVATE) || (pshared == PTHREAD_PROCESS_SHARED)) -#endif /* PR_5243343 */ #else /* __DARWIN_UNIX03 */ if ( pshared == PTHREAD_PROCESS_PRIVATE) #endif /* __DARWIN_UNIX03 */ { - attr->pshared = pshared; + attr->pshared = pshared; return (0); - } else - { + } else { return (EINVAL); /* Invalid parameter */ } } else @@ -692,10 +189,8 @@ pthread_condattr_setpshared(pthread_condattr_t * attr, int pshared) } -#if defined(__i386__) || defined(__x86_64__) - __private_extern__ int -_new_pthread_cond_init(pthread_cond_t *ocond, +_pthread_cond_init(pthread_cond_t *ocond, const pthread_condattr_t *attr, int conforming) { @@ -705,12 +200,14 @@ _new_pthread_cond_init(pthread_cond_t *ocond, cond->c_seq[0] = 0; cond->c_seq[1] = 0; cond->c_seq[2] = 0; - cond->rfu = 0; + if (((uintptr_t)cond & 0x07) != 0) { cond->misalign = 1; + cond->c_seq[2] = PTH_RWS_CV_CBIT; } else { cond->misalign = 0; + cond->c_seq[1] = PTH_RWS_CV_CBIT; /* set Sword to 0c */ } if (conforming) { if (attr) @@ -719,49 +216,65 @@ _new_pthread_cond_init(pthread_cond_t *ocond, cond->pshared = _PTHREAD_DEFAULT_PSHARED; } else cond->pshared = _PTHREAD_DEFAULT_PSHARED; - cond->sig = _PTHREAD_COND_SIG; + /* + * For the new style mutex, interlocks are not held all the time. + * We needed the signature to be set in the end. And we need + * to protect against the code getting reorganized by compiler. + * cond->sig = _PTHREAD_COND_SIG; + */ + __pthread_cond_set_signature(cond); return (0); } int -_new_pthread_cond_destroy(pthread_cond_t * ocond) +pthread_cond_destroy(pthread_cond_t * ocond) { npthread_cond_t *cond = (npthread_cond_t *)ocond; int ret; + /* to provide backwards compat for apps using united condtn vars */ + if((cond->sig != _PTHREAD_COND_SIG) && (cond->sig != _PTHREAD_COND_SIG_init)) + return(EINVAL); + LOCK(cond->lock); - ret = _new_pthread_cond_destroy_locked(ocond); + ret = _pthread_cond_destroy_locked(ocond); UNLOCK(cond->lock); return(ret); } -int -_new_pthread_cond_destroy_locked(pthread_cond_t * ocond) +static int +_pthread_cond_destroy_locked(pthread_cond_t * ocond) { npthread_cond_t *cond = (npthread_cond_t *)ocond; int ret; - int sig = cond->sig; - uint32_t * c_lseqcnt; - uint32_t * c_useqcnt; - uint32_t lgenval , ugenval; - - /* to provide backwards compat for apps using united condtn vars */ - if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init)) - return(EINVAL); + volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt; + uint32_t lcntval , ucntval, scntval; + uint64_t oldval64, newval64; +retry: if (cond->sig == _PTHREAD_COND_SIG) { - COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt); -retry: - lgenval = *c_lseqcnt; - ugenval = *c_useqcnt; - if (lgenval == ugenval) - { + COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt); + lcntval = *c_lseqcnt; + ucntval = *c_useqcnt; + scntval = *c_sseqcnt; + + if ((lcntval & PTHRW_COUNT_MASK) == (scntval & PTHRW_COUNT_MASK)) { + /* validate it is not busy */ + oldval64 = (((uint64_t)scntval) << 32); + oldval64 |= lcntval; + newval64 = oldval64; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) + goto retry; cond->sig = _PTHREAD_NO_SIG; ret = 0; } else ret = EBUSY; + } else if (cond->sig == _PTHREAD_COND_SIG_init) { + cond->sig = _PTHREAD_NO_SIG; + ret = 0; } else ret = EINVAL; /* Not an initialized condition variable structure */ return (ret); @@ -771,18 +284,18 @@ retry: * Signal a condition variable, waking up all threads waiting for it. */ int -_new_pthread_cond_broadcast(pthread_cond_t *ocond) +pthread_cond_broadcast(pthread_cond_t *ocond) { npthread_cond_t * cond = (npthread_cond_t *)ocond; int sig = cond->sig; - npthread_mutex_t * mutex; - uint32_t lgenval, ugenval, mgen, ugen, flags, mtxgen, mtxugen, notify; - int diffgen, retval, dropcount, mutexrefs; - uint64_t oldval64, newval64; - uint32_t * c_lseqcnt; - uint32_t * c_useqcnt; + uint32_t flags, updateval; + uint32_t lcntval , ucntval, scntval; + uint64_t oldval64, newval64, mugen, cvlsgen, cvudgen, mtid=0; + int diffgen, error = 0; + volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt; uint32_t * pmtx = NULL; - + uint32_t nlval, ulval; + int needclearpre = 0, retry_count = 0; /* to provide backwards compat for apps using united condtn vars */ if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init)) @@ -790,17 +303,17 @@ _new_pthread_cond_broadcast(pthread_cond_t *ocond) if (sig != _PTHREAD_COND_SIG) { - int res; - LOCK(cond->lock); if (cond->sig == _PTHREAD_COND_SIG_init) { - _new_pthread_cond_init(ocond, NULL, 0); - res = 0; + _pthread_cond_init(ocond, NULL, 0); + /* just inited nothing to post */ + UNLOCK(cond->lock); + return (0); } else if (cond->sig != _PTHREAD_COND_SIG) { - res = EINVAL; /* Not a condition variable */ + /* Not a condition variable */ UNLOCK(cond->lock); - return (res); + return (EINVAL); } UNLOCK(cond->lock); } @@ -809,108 +322,167 @@ _new_pthread_cond_broadcast(pthread_cond_t *ocond) (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_START, (uint32_t)cond, 0, 0, 0, 0); #endif - COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt); + COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt); retry: - lgenval = *c_lseqcnt; - ugenval = *c_useqcnt; - diffgen = lgenval - ugenval; /* pendig waiters */ + lcntval = *c_lseqcnt; + ucntval = *c_useqcnt; + scntval = *c_sseqcnt; + +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, scntval, 0); +#endif - if (diffgen <= 0) { - return(0); + if (((lcntval & PTHRW_COUNT_MASK) == (scntval & PTHRW_COUNT_MASK)) || + ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK))) { + /* validate it is spurious and return */ + oldval64 = (((uint64_t)scntval) << 32); + oldval64 |= lcntval; + newval64 = oldval64; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) + goto retry; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_END, (uint32_t)cond, 0, 0, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, 0xf1f1f1f1, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_END, (uint32_t)cond, scntval, 0, 0xf1f1f1f1, 0); #endif + return(0); } - - mutex = cond->busy; - - if (OSAtomicCompareAndSwap32(ugenval, ugenval+diffgen, (volatile int *)c_useqcnt) != TRUE) - goto retry; -#ifdef COND_MTX_WAITQUEUEMOVE + if (is_seqhigher((ucntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK)) || is_seqhigher((scntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) { + /* since ucntval may be newer, just redo */ + retry_count++; + if (retry_count > 8192) { + return(EAGAIN); + } else { + sched_yield(); + goto retry; + } + } - if ((mutex != NULL) && cond->pshared != PTHREAD_PROCESS_SHARED) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, 1, diffgen, 0, 0); -#endif - (void)__mtx_holdlock(mutex, diffgen, &flags, &pmtx, &mgen, &ugen); - mutexrefs = 1; + if (is_seqlower(ucntval & PTHRW_COUNT_MASK, scntval & PTHRW_COUNT_MASK) != 0) { + /* If U < S, set U = S+diff due to intr's TO, etc */ + ulval = (scntval & PTHRW_COUNT_MASK); } else { - if (cond->pshared != PTHREAD_PROCESS_SHARED) - flags = _PTHREAD_MTX_OPT_NOHOLD; - else - flags = _PTHREAD_MTX_OPT_NOHOLD | _PTHREAD_MTX_OPT_PSHARED; - mgen = ugen = 0; - mutexrefs = 0; - pmtx = NULL; + /* If U >= S, set U = U+diff due to intr's TO, etc */ + ulval = (ucntval & PTHRW_COUNT_MASK); } -#else /* COND_MTX_WAITQUEUEMOVE */ +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, lcntval, ucntval, scntval, diffgen, 0); +#endif - if (cond->pshared != PTHREAD_PROCESS_SHARED) - flags = _PTHREAD_MTX_OPT_NOHOLD; - else - flags = _PTHREAD_MTX_OPT_NOHOLD | _PTHREAD_MTX_OPT_PSHARED; + diffgen = diff_genseq((lcntval & PTHRW_COUNT_MASK), (ulval & PTHRW_COUNT_MASK)); + + /* set U = L */ + ulval = (lcntval & PTHRW_COUNT_MASK); + if (OSAtomicCompareAndSwap32(ucntval, ulval, (volatile int32_t *)c_useqcnt) != TRUE) { + goto retry; + } + + flags = 0; + if (cond->pshared == PTHREAD_PROCESS_SHARED) + flags |= _PTHREAD_MTX_OPT_PSHARED; pmtx = NULL; - mgen = ugen = 0; - mutexrefs = 0; -#endif /* COND_MTX_WAITQUEUEMOVE */ #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, 3, diffgen, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, 3, diffgen, flags, 0); #endif - retval = __psynch_cvbroad(ocond, lgenval, diffgen, (pthread_mutex_t *)pmtx, mgen, ugen , (uint64_t)0, flags); + nlval = lcntval; + + /* pass old u val so kernel will know the diffgen */ + mugen = 0; + cvlsgen = ((uint64_t)scntval << 32) | nlval; + cvudgen = ((uint64_t)ucntval << 32) | diffgen; + + updateval = __psynch_cvbroad(ocond, cvlsgen, cvudgen, flags, (pthread_mutex_t *)pmtx, mugen, mtid); + + if (updateval != (uint32_t)-1) { + + /* if kernel granted woke some threads, updatwe S for them as they will not access cv on their way out */ + /* Were any threads woken or bits to be set? */ + if (updateval != 0) { +retry2: + needclearpre = 0; + lcntval = *c_lseqcnt; + ucntval = *c_useqcnt; + scntval = *c_sseqcnt; + /* update scntval with number of expected returns and bits */ + nlval = (scntval & PTHRW_COUNT_MASK) + (updateval & PTHRW_COUNT_MASK); + /* set bits */ + nlval |= ((scntval & PTH_RWS_CV_BITSALL) | (updateval & PTH_RWS_CV_BITSALL)); -#ifdef COND_MTX_WAITQUEUEMOVE - if ((retval != -1) && (retval != 0)) { - if ((mutexrefs != 0) && (retval <= PTHRW_MAX_READERS/2)) { - dropcount = (retval); #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, 2, dropcount, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, 0x25, lcntval, scntval, updateval, 0); #endif - retval = __mtx_droplock(mutex, dropcount, &flags, &pmtx, &mtxgen, &mtxugen, ¬ify); - } - } -#endif /* COND_MTX_WAITQUEUEMOVE */ + /* if L==S and c&p bits are set, needs clearpre */ + if (((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK)) + && ((nlval & PTH_RWS_CV_BITSALL) == PTH_RWS_CV_BITSALL)) { + /* reset p bit but retain c bit on the sword */ + nlval &= PTH_RWS_CV_RESET_PBIT; + needclearpre = 1; + } - oldval64 = (((uint64_t)(ugenval+diffgen)) << 32); - oldval64 |= lgenval; - newval64 = 0; + oldval64 = (((uint64_t)scntval) << 32); + oldval64 |= lcntval; + newval64 = (((uint64_t)nlval) << 32); + newval64 |= lcntval; + +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, 0x25, nlval, scntval, updateval, 0); +#endif - OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt); + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) + goto retry2; + + /* if L == S, then reset associated mutex */ + if ((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK)) { + cond->busy = (npthread_mutex_t *)NULL; + } + + if (needclearpre != 0) { + (void)__psynch_cvclrprepost(ocond, lcntval, ucntval, nlval, 0, lcntval, flags); + } + } + + } + error = 0; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_END, (uint32_t)cond, 0, 0, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_END, (uint32_t)cond, 0, error, 0, 0); #endif - return(0); + return(error); } /* * Signal a condition variable, waking a specified thread. */ + int -_new_pthread_cond_signal_thread_np(pthread_cond_t *ocond, pthread_t thread) +pthread_cond_signal_thread_np(pthread_cond_t *ocond, pthread_t thread) { npthread_cond_t * cond = (npthread_cond_t *)ocond; int sig = cond->sig; - npthread_mutex_t * mutex; - int retval, dropcount; - uint32_t lgenval, ugenval, diffgen, mgen, ugen, flags, mtxgen, mtxugen, notify; - uint32_t * c_lseqcnt; - uint32_t * c_useqcnt; - uint64_t oldval64, newval64; - int mutexrefs; - uint32_t * pmtx = NULL; + uint32_t flags, updateval; + uint32_t lcntval , ucntval, scntval; + uint32_t nlval, ulval=0; + volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt; + uint64_t oldval64, newval64, mugen, cvlsgen, mtid = 0; + int needclearpre = 0, retry_count = 0; + int error; /* to provide backwards compat for apps using united condtn vars */ if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init)) return(EINVAL); + if (cond->sig != _PTHREAD_COND_SIG) { LOCK(cond->lock); if (cond->sig != _PTHREAD_COND_SIG) { if (cond->sig == _PTHREAD_COND_SIG_init) { - _new_pthread_cond_init(ocond, NULL, 0); + _pthread_cond_init(ocond, NULL, 0); + /* just inited, nothing to post yet */ + UNLOCK(cond->lock); + return(0); } else { UNLOCK(cond->lock); return(EINVAL); @@ -922,86 +494,143 @@ _new_pthread_cond_signal_thread_np(pthread_cond_t *ocond, pthread_t thread) #if _KSYN_TRACE_ (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_START, (uint32_t)cond, 0, 0, 0, 0); #endif - COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt); + COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt); retry: - lgenval = *c_lseqcnt; - ugenval = *c_useqcnt; - diffgen = lgenval - ugenval; /* pendig waiters */ - if (diffgen <= 0) { + lcntval = *c_lseqcnt; + ucntval = *c_useqcnt; + scntval = *c_sseqcnt; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_END, (uint32_t)cond, 0, 0, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, scntval, 0); #endif - return(0); - } - - mutex = cond->busy; - if (OSAtomicCompareAndSwap32(ugenval, ugenval+1, (volatile int *)c_useqcnt) != TRUE) - goto retry; + if (((lcntval & PTHRW_COUNT_MASK) == (scntval & PTHRW_COUNT_MASK)) || + ((thread == 0) && ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK)))) { + /* If L <= S+U, it is spurious broadcasr */ + /* validate it is spurious and return */ + oldval64 = (((uint64_t)scntval) << 32); + oldval64 |= lcntval; + newval64 = oldval64; -#ifdef COND_MTX_WAITQUEUEMOVE - if ((mutex != NULL) && (cond->pshared != PTHREAD_PROCESS_SHARED)) { + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) + goto retry; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, 1, 0, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, 0xf1f1f1f1, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_END, (uint32_t)cond, scntval, 0, 0xf1f1f1f1, 0); #endif - (void)__mtx_holdlock(mutex, 1, &flags, &pmtx, &mgen, &ugen); - mutexrefs = 1; - } else { - if (cond->pshared != PTHREAD_PROCESS_SHARED) - flags = _PTHREAD_MTX_OPT_NOHOLD; - else - flags = _PTHREAD_MTX_OPT_NOHOLD | _PTHREAD_MTX_OPT_PSHARED; - mgen = ugen = 0; - mutexrefs = 0; + return(0); } -#else /* COND_MTX_WAITQUEUEMOVE */ - if (cond->pshared != PTHREAD_PROCESS_SHARED) - flags = _PTHREAD_MTX_OPT_NOHOLD; - else - flags = _PTHREAD_MTX_OPT_NOHOLD | _PTHREAD_MTX_OPT_PSHARED; - mgen = ugen = 0; - mutexrefs = 0; - -#endif /* COND_MTX_WAITQUEUEMOVE */ + + if (((thread == 0) && (is_seqhigher((ucntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK)))) || is_seqhigher((scntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) { + /* since ucntval may be newer, just redo */ + retry_count++; + if (retry_count > 8192) { + return(EAGAIN); + } else { + sched_yield(); + goto retry; + } + } + + if (thread == 0) { + /* + * skip manipulating U count as ESRCH from kernel cannot be handled properly. + * S count will cover the imbalance and next signal without thread or broadcast + * will correct it. But we need to send the right U to kernel so it will use + * that to look for the appropriate sequenc. So the ulval is computed anyway. + */ + + if (is_seqlower(ucntval & PTHRW_COUNT_MASK, scntval & PTHRW_COUNT_MASK) != 0) { + /* If U < S, set U = S+1 due to intr's TO, etc */ + ulval = (scntval & PTHRW_COUNT_MASK) + PTHRW_INC; + } else { + /* If U >= S, set U = U+1 due to intr's TO, etc */ + ulval = (ucntval & PTHRW_COUNT_MASK) + PTHRW_INC; + } + + if (OSAtomicCompareAndSwap32(ucntval, ulval, (volatile int32_t *)c_useqcnt) != TRUE) { + goto retry; + } + } + + flags = 0; + if (cond->pshared == PTHREAD_PROCESS_SHARED) + flags |= _PTHREAD_MTX_OPT_PSHARED; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, 3, lgenval, ugenval+1, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, 3, nlval, ulval, 0); #endif - retval = __psynch_cvsignal(ocond, lgenval, ugenval+1,(pthread_mutex_t *)mutex, mgen, ugen, pthread_mach_thread_np(thread), flags); + nlval = lcntval; + /* pass old u val so kernel will know the diffgen */ + mugen = 0; + cvlsgen = ((uint64_t)scntval << 32) | nlval; + + updateval = __psynch_cvsignal(ocond, cvlsgen, ucntval, pthread_mach_thread_np(thread), (pthread_mutex_t *)0, mugen, mtid, flags); + + + if (updateval != (uint32_t)-1) { + + /* if kernel granted woke some threads, updatwe S for them as they will not access cv on their way out */ + /* Were any threads woken or bits to be set? */ + if (updateval != 0) { +retry2: + lcntval = *c_lseqcnt; + ucntval = *c_useqcnt; + scntval = *c_sseqcnt; + /* update scntval with number of expected returns and bits */ + nlval = (scntval & PTHRW_COUNT_MASK) + (updateval & PTHRW_COUNT_MASK); + /* set bits */ + nlval |= ((scntval & PTH_RWS_CV_BITSALL) | (updateval & PTH_RWS_CV_BITSALL)); -#ifdef COND_MTX_WAITQUEUEMOVE - if ((retval != -1) && (retval != 0) && (mutexrefs != 0)) { - dropcount = retval; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, 4, dropcount, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, 0x25, 0, 0, updateval, 0); #endif - retval = __mtx_droplock(mutex, dropcount, &flags, &pmtx, &mtxgen, &mtxugen, ¬ify); - } -#endif /* COND_MTX_WAITQUEUEMOVE */ + /* if L==S and c&p bits are set, needs clearpre */ + if (((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK)) + && ((nlval & PTH_RWS_CV_BITSALL) == PTH_RWS_CV_BITSALL)) { + /* reset p bit but retain c bit on the sword */ + nlval &= PTH_RWS_CV_RESET_PBIT; + needclearpre = 1; + } else + needclearpre = 0; + + oldval64 = (((uint64_t)scntval) << 32); + oldval64 |= lcntval; + newval64 = (((uint64_t)nlval) << 32); + newval64 |= lcntval; - if (lgenval == ugenval+1){ - oldval64 = (((uint64_t)(ugenval+1)) << 32); - oldval64 |= lgenval; - newval64 = 0; - OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt); #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, 5, 0, 0, 0); +(void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, 0x25, nlval, ulval, updateval, 0); #endif + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) + goto retry2; + + /* if L == S, then reset associated mutex */ + if ((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK)) { + cond->busy = (npthread_mutex_t *)NULL; + } + + if (needclearpre != 0) { + (void)__psynch_cvclrprepost(ocond, lcntval, ucntval, nlval, 0, lcntval, flags); + } + } } - + + error = 0; + #if _KSYN_TRACE_ (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_END, (uint32_t)cond, 0, 0, 0, 0); #endif - return (0); + return (error); } /* * Signal a condition variable, waking only one thread. */ int -_new_pthread_cond_signal(pthread_cond_t *cond) +pthread_cond_signal(pthread_cond_t *cond) { - return _new_pthread_cond_signal_thread_np(cond, NULL); + return pthread_cond_signal_thread_np(cond, NULL); } /* @@ -1017,7 +646,7 @@ _new_pthread_cond_signal(pthread_cond_t *cond) * remaining conforming behavior.. */ __private_extern__ int -__new_pthread_cond_wait(pthread_cond_t *ocond, +_pthread_cond_wait(pthread_cond_t *ocond, pthread_mutex_t *omutex, const struct timespec *abstime, int isRelative, @@ -1030,13 +659,14 @@ __new_pthread_cond_wait(pthread_cond_t *ocond, struct timespec cthen = {0,0}; int sig = cond->sig; int msig = mutex->sig; - int firstfit = 0; npthread_mutex_t * pmtx; - uint32_t mtxgen, mtxugen, flags, updateval, notify; - uint32_t lgenval, ugenval; - uint32_t * c_lseqcnt; - uint32_t * c_useqcnt; + uint32_t mtxgen, mtxugen, flags=0, updateval; + uint32_t lcntval , ucntval, scntval; + uint32_t nlval, ulval, savebits; + volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt; + uint64_t oldval64, newval64, mugen, cvlsgen; uint32_t * npmtx = NULL; + int error, local_error; extern void _pthread_testcancel(pthread_t thread, int isconforming); @@ -1045,30 +675,36 @@ extern void _pthread_testcancel(pthread_t thread, int isconforming); return(EINVAL); if (isconforming) { - if((msig != _PTHREAD_MUTEX_SIG) && (msig != _PTHREAD_MUTEX_SIG_init)) + if((msig != _PTHREAD_MUTEX_SIG) && ((msig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) return(EINVAL); if (isconforming > 0) _pthread_testcancel(pthread_self(), 1); } + if (cond->sig != _PTHREAD_COND_SIG) { LOCK(cond->lock); - if (cond->sig != _PTHREAD_COND_SIG_init) - { + if (cond->sig != _PTHREAD_COND_SIG) { + if (cond->sig == _PTHREAD_COND_SIG_init) { + _pthread_cond_init(ocond, NULL, 0); + } else { UNLOCK(cond->lock); - return (EINVAL); /* Not a condition variable */ + return(EINVAL); + } } - _new_pthread_cond_init(ocond, NULL, 0); UNLOCK(cond->lock); } #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_START, (uint32_t)cond, 0, 0, (uint32_t)abstime, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_START, (uint32_t)cond, isRelative, 0, (uint32_t)abstime, 0); #endif - COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt); + COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt); /* send relative time to kernel */ if (abstime) { +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_START, 0x11111111, abstime->tv_nsec, abstime->tv_sec, 0, 0); +#endif if (isRelative == 0) { struct timespec now; struct timeval tv; @@ -1086,24 +722,24 @@ extern void _pthread_testcancel(pthread_t thread, int isconforming); if (((int)then.tv_sec < 0) || ((then.tv_sec == 0) && (then.tv_nsec == 0))) { - UNLOCK(cond->lock); return ETIMEDOUT; } if (isconforming != 0) { cthen.tv_sec = abstime->tv_sec; cthen.tv_nsec = abstime->tv_nsec; if ((cthen.tv_sec < 0) || (cthen.tv_nsec < 0)) { - UNLOCK(cond->lock); return EINVAL; } if (cthen.tv_nsec >= NSEC_PER_SEC) { - UNLOCK(cond->lock); return EINVAL; } } } else { then.tv_sec = abstime->tv_sec; then.tv_nsec = abstime->tv_nsec; + if ((then.tv_sec == 0) && (then.tv_nsec == 0)) { + return ETIMEDOUT; + } } if(isconforming && ((then.tv_sec < 0) || (then.tv_nsec < 0))) { return EINVAL; @@ -1113,94 +749,97 @@ extern void _pthread_testcancel(pthread_t thread, int isconforming); } } - cond->busy = mutex; + if ((cond->busy != (npthread_mutex_t *)NULL) && (cond->busy != mutex)) + return (EINVAL); + pmtx = mutex; +retry: + lcntval = *c_lseqcnt; + ucntval = *c_useqcnt; + scntval = *c_sseqcnt; - ugenval = *c_useqcnt; - lgenval = OSAtomicIncrement32((volatile int32_t *)c_lseqcnt); - + oldval64 = (((uint64_t)scntval) << 32); + oldval64 |= lcntval; + + /* remove c and p bits on S word */ + savebits = scntval & PTH_RWS_CV_BITSALL; + ulval = (scntval & PTHRW_COUNT_MASK); + nlval = lcntval + PTHRW_INC; + newval64 = (((uint64_t)ulval) << 32); + newval64 |= nlval; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) + goto retry; + + cond->busy = mutex; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 1, lgenval, ugenval, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, scntval, 0); #endif - notify = 0; - retval = __mtx_droplock(pmtx, 1, &flags, &npmtx, &mtxgen, &mtxugen, ¬ify); + retval = __mtx_droplock(pmtx, PTHRW_INC, &flags, &npmtx, &mtxgen, &mtxugen); + + /* TBD: cases are for normal (non owner for recursive mutex; error checking)*/ if (retval != 0) return(EINVAL); - if ((notify & 1) == 0) { + if ((flags & _PTHREAD_MTX_OPT_NOTIFY) == 0) { npmtx = NULL; - } - if ((notify & 0xc0000000) != 0) - then.tv_nsec |= (notify & 0xc0000000); + mugen = 0; + } else + mugen = ((uint64_t)mtxugen << 32) | mtxgen; + flags &= ~_PTHREAD_MTX_OPT_MUTEX; /* reset the mutex bit as this is cvar */ #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 3, (uint32_t)mutex, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 3, (uint32_t)mutex, flags, 0); #endif + + cvlsgen = ((uint64_t)(ulval | savebits)<< 32) | nlval; + if (isconforming) { - pthread_cleanup_push(_new_cond_cleanup, (void *)cond); - updateval = __psynch_cvwait(ocond, lgenval, ugenval, (pthread_mutex_t *)npmtx, mtxgen, mtxugen, (uint64_t)then.tv_sec, (uint64_t)then.tv_nsec); + pthread_cleanup_push(cond_cleanup, (void *)cond); + updateval = __psynch_cvwait(ocond, cvlsgen, ucntval, (pthread_mutex_t *)npmtx, mugen, flags, (int64_t)then.tv_sec, (int32_t)then.tv_nsec); pthread_cleanup_pop(0); } else { - updateval = __psynch_cvwait(ocond, lgenval, ugenval, (pthread_mutex_t *)npmtx, mtxgen, mtxugen, (uint64_t)then.tv_sec, (uint64_t)then.tv_nsec); + updateval = __psynch_cvwait(ocond, cvlsgen, ucntval, (pthread_mutex_t *)npmtx, mugen, flags, (int64_t)then.tv_sec, (int32_t)then.tv_nsec); } retval = 0; -#ifdef COND_MTX_WAITQUEUEMOVE - /* Needs to handle timedout */ if (updateval == (uint32_t)-1) { - retval = errno; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 4, retval, 0, 0); -#endif - /* add unlock ref to show one less waiter */ - _new_cond_dropwait(cond); - - pthread_mutex_lock(omutex); - - } else if ((updateval & PTHRW_MTX_NONE) != 0) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 5, updateval, 0, 0); -#endif - pthread_mutex_lock(omutex); - } else { - /* on successful return mutex held */ - /* returns 0 on succesful update */ -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 6, updateval, 0, 0); -#endif - firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT); - if (__mtx_updatebits( mutex, updateval, firstfit, 1) == 1) { - /* not expected to be here */ - LIBC_ABORT("CONDWAIT mutex acquire mishap"); - } - if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) - mutex->mtxopts.options.lock_count++; - } -#else /* COND_MTX_WAITQUEUEMOVE */ - if (updateval == (uint32_t)-1) { - if (errno == ETIMEDOUT) { + local_error = errno; + error = local_error & 0xff; + if (error == ETIMEDOUT) { retval = ETIMEDOUT; - } else if (errno == EINTR) { + } else if (error == EINTR) { /* ** EINTR can be treated as a spurious wakeup unless we were canceled. */ retval = 0; } else retval = EINVAL; +//#if _KSYN_TRACE_ +// (void)__kdebug_trace(0x9000070 | 0, (uint32_t)cond, 0xf1f1f2f2, local_error, error, 0); +//#endif /* add unlock ref to show one less waiter */ - _new_cond_dropwait(cond); - } else + cond_dropwait(cond, local_error, 0); + } else { +//#if _KSYN_TRACE_ +// (void)__kdebug_trace(0x9000070 | 0, (uint32_t)cond, 0xf3f3f4f4, updateval, 0, 0); +//#endif + /* succesful wait */ + if (updateval != 0) { + /* the return due to prepost and might have bit states */ + /* update S and return for prepo if needed */ + cond_dropwait(cond, 0, updateval); + } retval = 0; + } #if _KSYN_TRACE_ (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 4, retval, 0, 0); #endif - pthread_mutex_lock(omutex); - -#endif /* COND_MTX_WAITQUEUEMOVE */ + pthread_mutex_lock(omutex); #if _KSYN_TRACE_ (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_END, (uint32_t)cond, 0, 0, retval, 0); @@ -1208,8 +847,20 @@ extern void _pthread_testcancel(pthread_t thread, int isconforming); return(retval); } +/* + * For the new style mutex, interlocks are not held all the time. + * We needed the signature to be set in the end. And we need + * to protect against the code getting reorganized by compiler. + */ +static void +__pthread_cond_set_signature(npthread_cond_t * cond) +{ + cond->sig = _PTHREAD_COND_SIG; +} + + static void -_new_cond_cleanup(void *arg) +cond_cleanup(void *arg) { npthread_cond_t *cond = (npthread_cond_t *)arg; pthread_mutex_t *mutex; @@ -1226,27 +877,30 @@ _new_cond_cleanup(void *arg) return; // 4597450: end - mutex = cond->busy; + mutex = (pthread_mutex_t *) cond->busy; /* add unlock ref to show one less waiter */ - _new_cond_dropwait(cond); + cond_dropwait(cond, thread->cancel_error, 0); /* ** Can't do anything if this fails -- we're on the way out */ if (mutex != NULL) (void)pthread_mutex_lock(mutex); - } +#define ECVCERORR 256 +#define ECVPERORR 512 + void -_new_cond_dropwait(npthread_cond_t * cond) +cond_dropwait(npthread_cond_t * cond, int error, uint32_t updateval) { int sig = cond->sig; - int retval; - uint32_t lgenval, ugenval, diffgen, mgen, ugen, flags; - uint32_t * c_lseqcnt; - uint32_t * c_useqcnt; + pthread_cond_t * ocond = (pthread_cond_t *)cond; + int needclearpre = 0; + uint32_t diffgen, nlval, ulval, flags; + uint32_t lcntval , ucntval, scntval, lval; + volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt; uint64_t oldval64, newval64; /* to provide backwards compat for apps using united condtn vars */ @@ -1254,77 +908,108 @@ _new_cond_dropwait(npthread_cond_t * cond) if (sig != _PTHREAD_COND_SIG) return; + COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt); + + if (error != 0) { + lval = PTHRW_INC; + if ((error & ECVCERORR) != 0) + lval |= PTH_RWS_CV_CBIT; + if ((error & ECVPERORR) != 0) + lval |= PTH_RWS_CV_PBIT; + } else { + lval = updateval; + } #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_START, (uint32_t)cond, 0, 0, 0xee, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_START, (uint32_t)cond, error, updateval, 0xee, 0); #endif - COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt); retry: - lgenval = *c_lseqcnt; - ugenval = *c_useqcnt; - diffgen = lgenval - ugenval; /* pending waiters */ + lcntval = *c_lseqcnt; + ucntval = *c_useqcnt; + scntval = *c_sseqcnt; + diffgen = diff_genseq((lcntval & PTHRW_COUNT_MASK), (scntval & PTHRW_COUNT_MASK)); /* pendig waiters */ +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, (uint32_t)cond, lcntval, scntval, diffgen, 0); +#endif if (diffgen <= 0) { + /* TBD: Assert, should not be the case */ + /* validate it is spurious and return */ + oldval64 = (((uint64_t)scntval) << 32); + oldval64 |= lcntval; + newval64 = oldval64; + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) + goto retry; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_END, (uint32_t)cond, 1, 0, 0xee, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_END, (uint32_t)cond, 0, 0, 0, 0); #endif return; } - - if (OSAtomicCompareAndSwap32(ugenval, ugenval+1, (volatile int *)c_useqcnt) != TRUE) - goto retry; - if (lgenval == ugenval+1) { - /* last one */ - /* send last drop notify to erase pre post */ - flags = _PTHREAD_MTX_OPT_LASTDROP; + /* update S by one */ + oldval64 = (((uint64_t)scntval) << 32); + oldval64 |= lcntval; + + /* update scntval with number of expected returns and bits */ + ulval = (scntval & PTHRW_COUNT_MASK) + (lval & PTHRW_COUNT_MASK); + /* set bits */ + ulval |= ((scntval & PTH_RWS_CV_BITSALL) | (lval & PTH_RWS_CV_BITSALL)); + + nlval = lcntval; + + needclearpre = 0; + + /* If L==S, need to return to kernel */ + if ((nlval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) { + if ((ulval & PTH_RWS_CV_BITSALL) == PTH_RWS_CV_BITSALL) { + /* reset p bit but retain c bit on the sword */ + needclearpre = 1; + ulval &= PTH_RWS_CV_RESET_PBIT; + } + } - if (cond->pshared == PTHREAD_PROCESS_SHARED) - flags |= _PTHREAD_MTX_OPT_PSHARED; - mgen = ugen = 0; + newval64 = (((uint64_t)ulval) << 32); + newval64 |= nlval; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, 1, 0, 0xee, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, (uint32_t)cond, 0xffff, nlval, ulval, 0); #endif - retval = __psynch_cvsignal((pthread_cond_t *)cond, lgenval, ugenval+1,(pthread_mutex_t *)NULL, mgen, ugen, MACH_PORT_NULL, flags); + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) + goto retry; + +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, (uint32_t)cond, 2, 0, 0xee, 0); +#endif + if ((nlval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) { + /* last usage remove the mutex */ + cond->busy = NULL; + } - oldval64 = (((uint64_t)(ugenval+1)) << 32); - oldval64 |= lgenval; - newval64 = 0; - OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt); +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, nlval, ucntval, ulval, PTHRW_INC, 0); +#endif + if (needclearpre != 0) { + flags = 0; + if (cond->pshared == PTHREAD_PROCESS_SHARED) + flags |= _PTHREAD_MTX_OPT_PSHARED; + /* reset prepost */ + (void)__psynch_cvclrprepost(ocond, nlval, ucntval, ulval, 0, nlval, flags); } - #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_END, (uint32_t)cond, 2, 0, 0xee, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_END, nlval, ucntval, ulval, PTHRW_INC, 0); #endif return; } int -_new_pthread_cond_timedwait_relative_np(pthread_cond_t *cond, +pthread_cond_timedwait_relative_np(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) { - return (__new_pthread_cond_wait(cond, mutex, abstime, 1, 0)); -} - - -int -_new_pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex) -{ - return(__new_pthread_cond_wait(cond, mutex, 0, 0, 1)); + return (_pthread_cond_wait(cond, mutex, abstime, 1, 0)); } -int -_new_pthread_cond_timedwait(pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *abstime) -{ - return(__new_pthread_cond_wait(cond, mutex, abstime, 0, 1)); -} -#endif /* __i386__ || __x86_64__ */ #else /* !BUILDING_VARIANT */ @@ -1356,13 +1041,9 @@ pthread_cond_init(pthread_cond_t *cond, conforming = 0; #endif /* __DARWIN_UNIX03 */ + /* lock is same offset in both structures */ LOCK_INIT(cond->lock); -#if defined(__i386__) || defined(__x86_64__) - if ((attr != NULL) && (attr->pshared == PTHREAD_PROCESS_SHARED)) { - return(_new_pthread_cond_init(cond, attr, conforming)); - } -#endif /* __i386__ || __x86_64__ */ - + return (_pthread_cond_init(cond, attr, conforming)); } diff --git a/pthreads/pthread_impl.h b/pthreads/pthread_impl.h index 72969ae..887b56d 100644 --- a/pthreads/pthread_impl.h +++ b/pthreads/pthread_impl.h @@ -35,9 +35,15 @@ * [Internal] data structure signatures */ #define _PTHREAD_MUTEX_SIG_init 0x32AAABA7 + +#define _PTHREAD_ERRORCHECK_MUTEX_SIG_init 0x32AAABA1 +#define _PTHREAD_RECURSIVE_MUTEX_SIG_init 0x32AAABA2 +#define _PTHREAD_FIRSTFIT_MUTEX_SIG_init 0x32AAABA3 + #define _PTHREAD_COND_SIG_init 0x3CB0B1BB #define _PTHREAD_ONCE_SIG_init 0x30B1BCBA #define _PTHREAD_RWLOCK_SIG_init 0x2DA8B3B4 + /* * POSIX scheduling policies */ diff --git a/pthreads/pthread_internals.h b/pthreads/pthread_internals.h index 9262443..a74a94c 100644 --- a/pthreads/pthread_internals.h +++ b/pthreads/pthread_internals.h @@ -78,6 +78,10 @@ typedef struct _pthread_attr_t pthread_attr_t; #include "pthread_spinlock.h" /* spinlock definitions. */ TAILQ_HEAD(__pthread_list, _pthread); + +extern int __pthread_lock_debug; +extern int __pthread_lock_old; + extern struct __pthread_list __pthread_head; /* head of list of open files */ extern pthread_lock_t _pthread_list_lock; extern size_t pthreadsize; @@ -113,7 +117,10 @@ typedef struct _pthread int pad0; /* for backwards compatibility */ #endif struct sched_param param; - struct _pthread_mutex *mutexes; + uint32_t cancel_error; +#if defined(__LP64__) + uint32_t cancel_pad; /* pad value for alignment */ +#endif struct _pthread *joiner; #if !defined(__LP64__) int pad1; /* for backwards compatibility */ @@ -152,12 +159,6 @@ typedef struct _pthread uint64_t thread_id; } *pthread_t; -/* - * This will cause a compile-time failure if someone moved the tsd field - * and we need to change _PTHREAD_TSD_OFFSET in pthread_machdep.h - */ -typedef char _need_to_change_PTHREAD_TSD_OFFSET[(_PTHREAD_TSD_OFFSET == offsetof(struct _pthread, tsd[0])) ? 0 : -1] ; - /* * Thread attributes */ @@ -213,15 +214,19 @@ struct _pthread_mutex_options { policy:3, hold:2, misalign:1, /* 8 byte aligned? */ - rfu:4, + notify:1, /* CV notify field for kernel */ + mutex:1, /* used in clrprepo that it is a mutex */ + rfu:2, lock_count:16; }; #define _PTHREAD_MTX_OPT_PSHARED 0x010 -#define _PTHREAD_MTX_OPT_HOLD 0x200 -#define _PTHREAD_MTX_OPT_NOHOLD 0x400 -#define _PTHREAD_MTX_OPT_LASTDROP (_PTHREAD_MTX_OPT_NOHOLD | _PTHREAD_MTX_OPT_HOLD) +#define _PTHREAD_MTX_OPT_HOLD 0x200 /* current owner of the mutex */ +#define _PTHREAD_MTX_OPT_NOMTX 0x400 /* no mutex refs held */ + +#define _PTHREAD_MTX_OPT_NOTIFY 0x1000 /* notify to drop mutex handling in cvwait */ +#define _PTHREAD_MTX_OPT_MUTEX 0x2000 /* this is a mutex type */ #define _PTHREAD_MUTEX_T @@ -344,6 +349,9 @@ typedef struct { int pshared; } pthread_rwlock_t; +#define PTHRW_RFU_64BIT 124 /* 31 * sizeof(uint32_t) */ +#define PTHRW_RFU_32BIT 72 /* 18 * sizeof(uint32_t) */ + #define _PTHREAD_RWLOCK_T typedef struct { long sig; @@ -357,15 +365,15 @@ typedef struct { pthread_t rw_owner; int reserv; #endif /* __LP64__ */ - volatile uint32_t * rw_lseqaddr; - volatile uint32_t * rw_wcaddr; - volatile uint32_t * rw_useqaddr; + volatile uint32_t * rw_lcntaddr; + volatile uint32_t * rw_seqaddr; + volatile uint32_t * rw_ucntaddr; uint32_t rw_flags; int misalign; #if defined(__LP64__) - uint32_t rfu[31]; + char rfu[PTHRW_RFU_64BIT]; #else /* __LP64__ */ - uint32_t rfu[18]; + char rfu[PTHRW_RFU_32BIT]; #endif /* __LP64__ */ int pshared; } npthread_rwlock_t; @@ -374,25 +382,54 @@ typedef struct { #define PTHRW_KERN_PROCESS_SHARED 0x10 #define PTHRW_KERN_PROCESS_PRIVATE 0x20 #define PTHRW_KERN_PROCESS_FLAGS_MASK 0x30 +#define _PTHREAD_RWLOCK_UPGRADE_TRY 0x10000 + +/* New model bits on Lword */ +#define PTH_RWL_KBIT 0x01 /* users cannot acquire in user mode */ +#define PTH_RWL_EBIT 0x02 /* exclusive lock in progress */ +#define PTH_RWL_WBIT 0x04 /* write waiters pending in kernel */ +#define PTH_RWL_PBIT 0x04 /* prepost (cv) pending in kernel */ +#define PTH_RWL_YBIT 0x08 /* yielding write waiters pending in kernel */ +#define PTH_RWL_RETRYBIT 0x08 /* mutex retry wait */ +#define PTH_RWL_LBIT 0x10 /* long read in progress */ +#define PTH_RWL_MTXNONE 0x10 /* indicates the cvwait does not have mutex held */ +#define PTH_RWL_UBIT 0x20 /* upgrade request pending */ +#define PTH_RWL_MTX_WAIT 0x20 /* in cvar in mutex wait */ +#define PTH_RWL_RBIT 0x40 /* reader pending in kernel(not used) */ +#define PTH_RWL_MBIT 0x40 /* overlapping grants from kernel */ +#define PTH_RWL_TRYLKBIT 0x40 /* sets try lock attempt */ +#define PTH_RWL_IBIT 0x80 /* lock reset, held untill first succeesful unlock */ + +/* UBIT values for mutex, cvar */ +#define PTH_RWU_SBIT 0x01 +#define PTH_RWU_BBIT 0x02 + +#define PTHRW_RWL_INIT PTH_RWL_IBIT /* reset on the lock bits (U)*/ +#define PTHRW_RWLOCK_INIT (PTH_RWL_IBIT | PTH_RWL_RBIT) /* reset on the lock bits (U)*/ +#define PTH_RWLOCK_RESET_RBIT 0xffffffbf -#define PTHRW_EBIT 0x01 -#define PTHRW_LBIT 0x02 -#define PTHRW_YBIT 0x04 -#define PTHRW_WBIT 0x08 -#define PTHRW_UBIT 0x10 -#define PTHRW_RETRYBIT 0x20 -#define PTHRW_SHADOW_W 0x20 /* same as 0x20, shadow W bit for rwlock */ +#define PTHRW_INC 0x100 +#define PTHRW_BIT_MASK 0x000000ff -#define PTHRW_TRYLKBIT 0x40 -#define PTHRW_RW_HUNLOCK 0x40 /* readers responsible for handling unlock */ +#define PTHRW_UN_BIT_MASK 0x000000bf /* remove overlap bit */ -#define PTHRW_MTX_NONE 0x80 -#define PTHRW_RW_INIT 0x80 /* reset on the lock bits */ -#define PTHRW_RW_SPURIOUS 0x80 /* same as 0x80, spurious rwlock unlock ret from kernel */ -#define PTHRW_INC 0x100 -#define PTHRW_BIT_MASK 0x000000ff -#define PTHRW_UN_BIT_MASK 0x000000df /* remove shadow bit */ +/* New model bits on Sword */ +#define PTH_RWS_SBIT 0x01 /* kernel transition seq not set yet*/ +#define PTH_RWS_IBIT 0x02 /* Sequence is not set on return from kernel */ + +#define PTH_RWS_CV_CBIT PTH_RWS_SBIT /* kernel has cleared all info w.r.s.t CV */ +#define PTH_RWS_CV_PBIT PTH_RWS_IBIT /* kernel has prepost/fake structs only,no waiters */ +#define PTH_RWS_CV_BITSALL (PTH_RWS_CV_CBIT | PTH_RWS_CV_PBIT) +#define PTH_RWS_CV_MBIT PTH_RWL_MBIT /* to indicate prepost return from kernel */ +#define PTH_RWS_CV_RESET_PBIT 0xfffffffd + +#define PTH_RWS_WSVBIT 0x04 /* save W bit */ +#define PTH_RWS_USVBIT 0x08 /* save U bit */ +#define PTH_RWS_YSVBIT 0x10 /* save Y bit */ +#define PTHRW_RWS_INIT PTH_RWS_SBIT /* reset on the lock bits (U)*/ +#define PTHRW_RWS_SAVEMASK (PTH_RWS_WSVBIT|PTH_RWS_USVBIT|PTH_RWS_YSVBIT) /*save bits mask*/ +#define PTHRW_SW_Reset_BIT_MASK 0x000000fe /* remove S bit and get rest of the bits */ #define PTHRW_COUNT_SHIFT 8 #define PTHRW_COUNT_MASK 0xffffff00 @@ -401,30 +438,60 @@ typedef struct { #define PTHREAD_MTX_TID_SWITCHING (uint64_t)-1 -#define is_rw_ewubit_set(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT)) != 0) -#define is_rw_lbit_set(x) (((x) & PTHRW_LBIT) != 0) -#define is_rw_lybit_set(x) (((x) & (PTHRW_LBIT | PTHRW_YBIT)) != 0) -#define is_rw_ebit_set(x) (((x) & PTHRW_EBIT) != 0) -#define is_rw_ebit_clear(x) (((x) & PTHRW_EBIT) == 0) -#define is_rw_uebit_set(x) (((x) & (PTHRW_EBIT | PTHRW_UBIT)) != 0) -#define is_rw_ewuybit_set(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT | PTHRW_YBIT)) != 0) -#define is_rw_ewuybit_clear(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT | PTHRW_YBIT)) == 0) -#define is_rw_ewubit_set(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT)) != 0) -#define is_rw_ewubit_clear(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT)) == 0) +/* new L word defns */ +#define can_rwl_readinuser(x) ((((x) & (PTH_RWL_UBIT | PTH_RWL_WBIT | PTH_RWL_KBIT)) == 0)||(((x) & PTH_RWL_LBIT) != 0)) +#define can_rwl_longreadinuser(x) (((x) & (PTH_RWL_UBIT | PTH_RWL_WBIT | PTH_RWL_KBIT | PTH_RWL_YBIT)) == 0) +#define is_rwl_ebit_set(x) (((x) & PTH_RWL_EBIT) != 0) +#define is_rwl_eubit_set(x) (((x) & (PTH_RWL_EBIT | PTH_RWL_UBIT)) != 0) +#define is_rwl_wbit_set(x) (((x) & PTH_RWL_WBIT) != 0) +#define is_rwl_lbit_set(x) (((x) & PTH_RWL_LBIT) != 0) +#define is_rwl_ebit_clear(x) (((x) & PTH_RWL_EBIT) == 0) +#define is_rwl_lbit_clear(x) (((x) & PTH_RWL_LBIT) == 0) +#define is_rwl_readoverlap(x) (((x) & PTH_RWL_MBIT) != 0) + +/* S word checks */ +#define is_rws_setseq(x) (((x) & PTH_RWS_SBIT)) +#define is_rws_setunlockinit(x) (((x) & PTH_RWS_IBIT)) /* is x lower than Y */ -#define is_seqlower(x, y) ((x < y) || ((x - y) > (PTHRW_MAX_READERS/2))) +static inline int is_seqlower(uint32_t x, uint32_t y) { + if (x < y) { + if ((y-x) < (PTHRW_MAX_READERS/2)) + return(1); + } else { + if ((x-y) > (PTHRW_MAX_READERS/2)) + return(1); + } + return(0); +} + /* is x lower than or eq Y */ -#define is_seqlower_eq(x, y) ((x <= y) || ((x - y) > (PTHRW_MAX_READERS/2))) +static inline int is_seqlower_eq(uint32_t x, uint32_t y) { + if (x==y) + return(1); + else + return(is_seqlower(x,y)); +} /* is x greater than Y */ -#define is_seqhigher(x, y) ((x > y) || ((y - x) > (PTHRW_MAX_READERS/2))) +static inline int is_seqhigher(uint32_t x, uint32_t y) { + if (x > y) { + if ((x-y) < (PTHRW_MAX_READERS/2)) + return(1); + } else { + if ((y-x) > (PTHRW_MAX_READERS/2)) + return(1); + } + return(0); +} static inline int diff_genseq(uint32_t x, uint32_t y) { - if (x > y) { + if (x == y) { + return(0); + } else if (x > y) { return(x-y); } else { - return((PTHRW_MAX_READERS - y) + x +1); + return((PTHRW_MAX_READERS - y) + x + PTHRW_INC); } } @@ -444,7 +511,7 @@ typedef struct _pthread_workitem { void * func_arg; struct _pthread_workqueue * workq; unsigned int flags; - unsigned int gencount; + unsigned int fromcache; /* padding for 64bit */ } * pthread_workitem_t; #define PTH_WQITEM_INKERNEL_QUEUE 1 @@ -457,12 +524,16 @@ typedef struct _pthread_workitem { #define PTH_WQITEM_APPLIED 0x80 #define PTH_WQITEM_KERN_COUNT 0x100 -#define WORKITEM_POOL_SIZE 1000 +/* try to fit these within multiple of pages (8 pages for now) */ +#define WORKITEM_POOL_SIZE 680 +/* ensure some multiple of the chunk is the pool size */ +#define WORKITEM_CHUNK_SIZE 40 + +#define WORKITEM_STARTPOOL_SIZE WORKITEM_CHUNK_SIZE + TAILQ_HEAD(__pthread_workitem_pool, _pthread_workitem); extern struct __pthread_workitem_pool __pthread_workitem_pool_head; /* head list of workitem pool */ -#define WQ_NUM_PRIO_QS 3 /* WORKQ_HIGH/DEFAULT/LOW_PRIOQUEUE */ - #define _PTHREAD_WORKQUEUE_HEAD_T typedef struct _pthread_workqueue_head { TAILQ_HEAD(, _pthread_workqueue) wqhead; @@ -470,6 +541,7 @@ typedef struct _pthread_workqueue_head { } * pthread_workqueue_head_t; +/* sized to be 128 bytes both in 32 and 64bit archs */ #define _PTHREAD_WORKQUEUE_T typedef struct _pthread_workqueue { unsigned int sig; /* Unique signature for this structure */ @@ -489,9 +561,7 @@ typedef struct _pthread_workqueue { void * term_callarg; pthread_workqueue_head_t headp; int overcommit; -#if defined(__ppc64__) || defined(__x86_64__) - unsigned int rev2[2]; -#else +#if !defined(__LP64__) unsigned int rev2[12]; #endif } * pthread_workqueue_t; @@ -504,11 +574,11 @@ typedef struct _pthread_workqueue { #define PTHREAD_WORKQ_REQUEUED 0x20 #define PTHREAD_WORKQ_SUSPEND 0x40 -#define WORKQUEUE_POOL_SIZE 100 +#define WORKQUEUE_POOL_SIZE 16 TAILQ_HEAD(__pthread_workqueue_pool, _pthread_workqueue); extern struct __pthread_workqueue_pool __pthread_workqueue_pool_head; /* head list of workqueue pool */ -#include "pthread.h" +#include "pthread_spis.h" #if defined(__i386__) || defined(__ppc64__) || defined(__x86_64__) || (defined(__arm__) && (defined(_ARM_ARCH_7) || !defined(_ARM_ARCH_6) || !defined(__thumb__))) /* @@ -518,17 +588,17 @@ extern struct __pthread_workqueue_pool __pthread_workqueue_pool_head; /* inline static pthread_t __attribute__((__pure__)) _pthread_self_direct(void) { - pthread_t ret; + pthread_t ret; + #if defined(__i386__) || defined(__x86_64__) - asm("mov %%gs:%P1, %0" : "=r" (ret) : "i" (offsetof(struct _pthread, tsd[0]))); + ret = _pthread_getspecific_direct(0); #elif defined(__ppc64__) register const pthread_t __pthread_self asm ("r13"); ret = __pthread_self; #elif defined(__arm__) && defined(_ARM_ARCH_6) - __asm__ ("mrc p15, 0, %0, c13, c0, 3" : "=r"(ret)); + ret = _pthread_getspecific_direct(0); #elif defined(__arm__) && !defined(_ARM_ARCH_6) - register const pthread_t __pthread_self asm ("r9"); - ret = __pthread_self; + ret = _pthread_getspecific_direct(0); #endif return ret; } @@ -546,6 +616,11 @@ _pthread_self_direct(void) #define _PTHREAD_MUTEX_ATTR_SIG 0x4D545841 /* 'MTXA' */ #define _PTHREAD_MUTEX_SIG 0x4D555458 /* 'MUTX' */ #define _PTHREAD_MUTEX_SIG_init 0x32AAABA7 /* [almost] ~'MUTX' */ +#define _PTHREAD_ERRORCHECK_MUTEX_SIG_init 0x32AAABA1 +#define _PTHREAD_RECURSIVE_MUTEX_SIG_init 0x32AAABA2 +#define _PTHREAD_FIRSTFIT_MUTEX_SIG_init 0x32AAABA3 +#define _PTHREAD_MUTEX_SIG_init_MASK 0xfffffff0 +#define _PTHREAD_MUTEX_SIG_CMP 0x32AAABA0 #define _PTHREAD_COND_ATTR_SIG 0x434E4441 /* 'CNDA' */ #define _PTHREAD_COND_SIG 0x434F4E44 /* 'COND' */ #define _PTHREAD_COND_SIG_init 0x3CB0B1BB /* [almost] ~'COND' */ @@ -594,17 +669,18 @@ extern void _pthread_setup(pthread_t th, void (*f)(pthread_t), void *sp, int sus extern void _pthread_tsd_cleanup(pthread_t self); -#if defined(__i386__) || defined(__x86_64__) -__private_extern__ void __mtx_holdlock(npthread_mutex_t *mutex, uint32_t diff, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp); -__private_extern__ int __mtx_droplock(npthread_mutex_t *mutex, int count, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp, uint32_t * notifyp); -__private_extern__ int __mtx_updatebits(npthread_mutex_t *mutex, uint32_t updateval, int firstfiti, int fromcond); +__private_extern__ void __mtx_holdlock(npthread_mutex_t *mutex, uint32_t diff, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp, uint64_t *tidp); +__private_extern__ int __mtx_droplock(npthread_mutex_t *mutex, uint32_t diff, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp); +__private_extern__ int __mtx_updatebits(npthread_mutex_t *mutex, uint32_t updateval, int firstfiti, int fromcond, uint64_t selfid); /* syscall interfaces */ extern uint32_t __psynch_mutexwait(pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags); extern uint32_t __psynch_mutexdrop(pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags); -extern int __psynch_cvbroad(pthread_cond_t * cv, uint32_t cvgen, uint32_t diffgen, pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags); -extern int __psynch_cvsignal(pthread_cond_t * cv, uint32_t cvgen, uint32_t cvugen, pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, int thread_port, uint32_t flags); -extern uint32_t __psynch_cvwait(pthread_cond_t * cv, uint32_t cvgen, uint32_t cvugen, pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t sec, uint64_t usec); + +extern uint32_t __psynch_cvbroad(pthread_cond_t * cv, uint64_t cvlsgen, uint64_t cvudgen, uint32_t flags, pthread_mutex_t * mutex, uint64_t mugen, uint64_t tid); +extern uint32_t __psynch_cvsignal(pthread_cond_t * cv, uint64_t cvlsgen, uint32_t cvugen, int thread_port, pthread_mutex_t * mutex, uint64_t mugen, uint64_t tid, uint32_t flags); +extern uint32_t __psynch_cvwait(pthread_cond_t * cv, uint64_t cvlsgen, uint32_t cvugen, pthread_mutex_t * mutex, uint64_t mugen, uint32_t flags, int64_t sec, uint32_t nsec); +extern uint32_t __psynch_cvclrprepost(void * cv, uint32_t cvgen, uint32_t cvugen, uint32_t cvsgen, uint32_t prepocnt, uint32_t preposeq, uint32_t flags); extern uint32_t __psynch_rw_longrdlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); extern uint32_t __psynch_rw_yieldwrlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); extern int __psynch_rw_downgrade(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); @@ -613,12 +689,12 @@ extern uint32_t __psynch_rw_rdlock(pthread_rwlock_t * rwlock, uint32_t lgenval, extern uint32_t __psynch_rw_wrlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); extern uint32_t __psynch_rw_unlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); extern uint32_t __psynch_rw_unlock2(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); -#endif /* __i386__ || __x86_64__ */ __private_extern__ semaphore_t new_sem_from_pool(void); __private_extern__ void restore_sem_to_pool(semaphore_t); __private_extern__ void _pthread_atfork_queue_init(void); int _pthread_lookup_thread(pthread_t thread, mach_port_t * port, int only_joinable); int _pthread_join_cleanup(pthread_t thread, void ** value_ptr, int conforming); +__private_extern__ int proc_setthreadname(void * buffer, int buffersize); #endif /* _POSIX_PTHREAD_INTERNALS_H */ diff --git a/pthreads/pthread_machdep.h b/pthreads/pthread_machdep.h index 819df97..4e4d71b 100644 --- a/pthreads/pthread_machdep.h +++ b/pthreads/pthread_machdep.h @@ -49,18 +49,13 @@ #ifndef _POSIX_PTHREAD_MACHDEP_H #define _POSIX_PTHREAD_MACHDEP_H -#ifdef __LP64__ -#define _PTHREAD_TSD_OFFSET 0x60 -#else -#define _PTHREAD_TSD_OFFSET 0x48 -#endif /* __LP64__ */ - #ifndef __ASSEMBLER__ #include #ifdef __arm__ #include #endif +#include /* ** Define macros for inline pthread_getspecific() usage. @@ -76,6 +71,8 @@ #define _PTHREAD_TSD_SLOT_DYLD_2 2 #define _PTHREAD_TSD_SLOT_DYLD_3 3 #define _PTHREAD_TSD_RESERVED_SLOT_COUNT 4 +/* To mirror the usage by dyld for Unwind_SjLj */ +#define _PTHREAD_TSD_SLOT_DYLD_8 8 /* Keys 10 - 29 are for Libc/Libsystem internal ussage */ /* used as __pthread_tsd_first + Num */ @@ -85,6 +82,8 @@ #define __PTK_LIBC_GMTIME_KEY 13 #define __PTK_LIBC_GDTOA_BIGINT_KEY 14 #define __PTK_LIBC_PARSEFLOAT_KEY 15 +/* for usage by dyld */ +#define __PTK_LIBC_DYLD_Unwind_SjLj_Key 18 /* Keys 20-25 for libdispactch usage */ #define __PTK_LIBDISPATCH_KEY0 20 @@ -159,17 +158,35 @@ /* Keys 80-89 for Garbage Collection */ -#define __PTK_FRAMEWORK_GC_KEY0 80 -#define __PTK_FRAMEWORK_GC_KEY1 81 -#define __PTK_FRAMEWORK_GC_KEY2 82 -#define __PTK_FRAMEWORK_GC_KEY3 83 -#define __PTK_FRAMEWORK_GC_KEY4 84 -#define __PTK_FRAMEWORK_GC_KEY5 85 -#define __PTK_FRAMEWORK_GC_KEY6 86 -#define __PTK_FRAMEWORK_GC_KEY7 87 -#define __PTK_FRAMEWORK_GC_KEY8 88 -#define __PTK_FRAMEWORK_GC_KEY9 89 +#define __PTK_FRAMEWORK_OLDGC_KEY0 80 +#define __PTK_FRAMEWORK_OLDGC_KEY1 81 +#define __PTK_FRAMEWORK_OLDGC_KEY2 82 +#define __PTK_FRAMEWORK_OLDGC_KEY3 83 +#define __PTK_FRAMEWORK_OLDGC_KEY4 84 +#define __PTK_FRAMEWORK_OLDGC_KEY5 85 +#define __PTK_FRAMEWORK_OLDGC_KEY6 86 +#define __PTK_FRAMEWORK_OLDGC_KEY7 87 +#define __PTK_FRAMEWORK_OLDGC_KEY8 88 +#define __PTK_FRAMEWORK_OLDGC_KEY9 89 + +/* Keys 90-94 for JavaScriptCore Collection */ +#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY0 90 +#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY1 91 +#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY2 92 +#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY3 93 +#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 94 +/* Keys 110-119 for Garbage Collection */ +#define __PTK_FRAMEWORK_GC_KEY0 110 +#define __PTK_FRAMEWORK_GC_KEY1 111 +#define __PTK_FRAMEWORK_GC_KEY2 112 +#define __PTK_FRAMEWORK_GC_KEY3 113 +#define __PTK_FRAMEWORK_GC_KEY4 114 +#define __PTK_FRAMEWORK_GC_KEY5 115 +#define __PTK_FRAMEWORK_GC_KEY6 116 +#define __PTK_FRAMEWORK_GC_KEY7 117 +#define __PTK_FRAMEWORK_GC_KEY8 118 +#define __PTK_FRAMEWORK_GC_KEY9 119 /* ** Define macros for inline pthread_getspecific() usage. @@ -192,6 +209,21 @@ int pthread_key_init_np(int, void (*)(void *)); typedef int pthread_lock_t; +#if TARGET_IPHONE_SIMULATOR + +/* Similator will use the host implementation, so bypass the macro that is in the target code */ + +inline static int +_pthread_has_direct_tsd(void) +{ + return 0; +} + +#define _pthread_getspecific_direct(key) pthread_getspecific(key) +#define _pthread_setspecific_direct(key, val) pthread_setspecific(key, val) + +#else /* TARGET_IPHONE_SIMULATOR */ + inline static int _pthread_has_direct_tsd(void) { @@ -202,8 +234,6 @@ _pthread_has_direct_tsd(void) } else { return 0; } -#elif defined(__arm__) && defined(__thumb__) && defined(_ARM_ARCH_6) && !defined(_ARM_ARCH_7) - return 0; #else return 1; #endif @@ -214,36 +244,65 @@ inline static void * _pthread_getspecific_direct(unsigned long slot) { void *ret; + #if defined(__i386__) || defined(__x86_64__) -#if defined(__OPTIMIZE__) - asm volatile("mov %%gs:%P1, %0" : "=r" (ret) : "i" (slot * sizeof(void *) + _PTHREAD_TSD_OFFSET)); -#else - asm("mov %%gs:%P2(,%1,%P3), %0" : "=r" (ret) : "r" (slot), "i" (_PTHREAD_TSD_OFFSET), "i" (sizeof (void *))); -#endif -#elif defined(__ppc__) - void **__pthread_tsd; - asm volatile("mfspr %0, 259" : "=r" (__pthread_tsd)); - ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; -#elif defined(__ppc64__) - register void **__pthread_tsd asm ("r13"); - ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; + asm("mov %%gs:%1, %0" : "=r" (ret) : "m" (*(void **)(slot * sizeof(void *)))); +#elif defined(__ppc64__) || defined(__ppc__) + ret = pthread_getspecific(slot); #elif defined(__arm__) && defined(_ARM_ARCH_6) && !defined(_ARM_ARCH_7) && defined(__thumb__) && !defined(__OPTIMIZE__) ret = pthread_getspecific(slot); #elif defined(__arm__) && defined(_ARM_ARCH_6) void **__pthread_tsd; - __asm__ ("mrc p15, 0, %0, c13, c0, 3" : "=r"(__pthread_tsd)); - ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; + __asm__ ( + "mrc p15, 0, %0, c13, c0, 3\n" + "bic %0, %0, #3\n" + : "=r"(__pthread_tsd)); + ret = __pthread_tsd[slot]; #elif defined(__arm__) && !defined(_ARM_ARCH_6) register void **__pthread_tsd asm ("r9"); - ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; + ret = __pthread_tsd[slot]; #else #error no pthread_getspecific_direct implementation for this arch #endif return ret; } +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) +/* To be used with static constant keys only */ +inline static int +_pthread_setspecific_direct(unsigned long slot, void * val) +{ + +#if defined(__i386__) +#if defined(__PIC__) + asm("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val)); +#else + asm("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "ri" (val)); +#endif +#elif defined(__x86_64__) + /* PIC is free and cannot be disabled, even with: gcc -mdynamic-no-pic ... */ + asm("movq %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val)); +#elif defined(__arm__) && defined(_ARM_ARCH_6) + void **__pthread_tsd; + __asm__ ( + "mrc p15, 0, %0, c13, c0, 3\n" + "bic %0, %0, #3\n" + : "=r"(__pthread_tsd)); + __pthread_tsd[slot] = val; +#elif defined(__arm__) && !defined(_ARM_ARCH_6) + register void **__pthread_tsd asm ("r9"); + __pthread_tsd[slot] = val; +#endif + return(0); +} +#elif defined(__ppc__) || defined(__ppc64__) /* To be used with static constant keys only */ #define _pthread_setspecific_direct(key, val) pthread_setspecific(key, val) +#else +#error no pthread_setspecific_direct implementation for this arch +#endif + +#endif /* TARGET_IPHONE_SIMULATOR */ #define LOCK_INIT(l) ((l) = 0) #define LOCK_INITIALIZER 0 diff --git a/pthreads/pthread_mutex.c b/pthreads/pthread_mutex.c index 94db1f6..53465b5 100644 --- a/pthreads/pthread_mutex.c +++ b/pthreads/pthread_mutex.c @@ -66,21 +66,26 @@ extern int __unix_conforming; extern int __unix_conforming; -int _pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); -#if defined(__i386__) || defined(__x86_64__) +#ifndef BUILDING_VARIANT +__private_extern__ int usenew_mtximpl = 1; +static void __pthread_mutex_set_signature(npthread_mutex_t * mutex); +int __mtx_markprepost(npthread_mutex_t *mutex, uint32_t oupdateval, int firstfit); +static int _pthread_mutex_destroy_locked(pthread_mutex_t *omutex); +#else /* BUILDING_VARIANT */ +extern int usenew_mtximpl; +#endif /* BUILDING_VARIANT */ + + +#ifdef NOTNEEDED #define USE_COMPAGE 1 +extern int _commpage_pthread_mutex_lock(uint32_t * lvalp, int flags, uint64_t mtid, uint32_t mask, uint64_t * tidp, int *sysret); +#endif #include -extern int _commpage_pthread_mutex_lock(uint32_t * lvalp, int flags, uint64_t mtid, uint32_t mask, uint64_t * tidp, int *sysret); +int _pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr, uint32_t static_type); -int _new_pthread_mutex_destroy(pthread_mutex_t *mutex); -int _new_pthread_mutex_destroy_locked(pthread_mutex_t *mutex); -int _new_pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); -int _new_pthread_mutex_lock(pthread_mutex_t *omutex); -int _new_pthread_mutex_trylock(pthread_mutex_t *omutex); -int _new_pthread_mutex_unlock(pthread_mutex_t *omutex); #if defined(__LP64__) #define MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr) \ @@ -121,11 +126,10 @@ int __kdebug_trace(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); #define _KSYN_TRACE_UM_MHOLD 0x9000068 #define _KSYN_TRACE_UM_MDROP 0x900006c #define _KSYN_TRACE_UM_MUBITS 0x900007c +#define _KSYN_TRACE_UM_MARKPP 0x90000a8 #endif /* _KSYN_TRACE_ */ -#endif /* __i386__ || __x86_64__ */ - #ifndef BUILDING_VARIANT /* [ */ #define BLOCK_FAIL_PLOCKSTAT 0 @@ -145,82 +149,6 @@ __private_extern__ void _plockstat_never_fired(void) PLOCKSTAT_MUTEX_SPUN(NULL, 0, 0); } -/* - * Destroy a mutex variable. - */ -int -pthread_mutex_destroy(pthread_mutex_t *mutex) -{ - int res; - - LOCK(mutex->lock); - if (mutex->sig == _PTHREAD_MUTEX_SIG) - { - -#if defined(__i386__) || defined(__x86_64__) - if(mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED){ - - res = _new_pthread_mutex_destroy_locked(mutex); - UNLOCK(mutex->lock); - return(res); - } -#endif /* __i386__ || __x86_64__ */ - - if (mutex->owner == (pthread_t)NULL && - mutex->busy == (pthread_cond_t *)NULL) - { - mutex->sig = _PTHREAD_NO_SIG; - res = 0; - } - else - res = EBUSY; - } else - res = EINVAL; - UNLOCK(mutex->lock); - return (res); -} - -/* - * Initialize a mutex variable, possibly with additional attributes. - */ -int -_pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) -{ - if (attr) - { - if (attr->sig != _PTHREAD_MUTEX_ATTR_SIG) - return (EINVAL); -#if defined(__i386__) || defined(__x86_64__) - if (attr->pshared == PTHREAD_PROCESS_SHARED) { - return(_new_pthread_mutex_init(mutex, attr)); - } else -#endif /* __i386__ || __x86_64__ */ - { - mutex->prioceiling = attr->prioceiling; - mutex->mtxopts.options.protocol = attr->protocol; - mutex->mtxopts.options.policy = attr->policy; - mutex->mtxopts.options.type = attr->type; - mutex->mtxopts.options.pshared = attr->pshared; - } - } else { - mutex->prioceiling = _PTHREAD_DEFAULT_PRIOCEILING; - mutex->mtxopts.options.protocol = _PTHREAD_DEFAULT_PROTOCOL; - mutex->mtxopts.options.policy = _PTHREAD_MUTEX_POLICY_FAIRSHARE; - mutex->mtxopts.options.type = PTHREAD_MUTEX_DEFAULT; - mutex->mtxopts.options.pshared = _PTHREAD_DEFAULT_PSHARED; - } - mutex->mtxopts.options.lock_count = 0; - mutex->owner = (pthread_t)NULL; - mutex->next = (pthread_mutex_t *)NULL; - mutex->prev = (pthread_mutex_t *)NULL; - mutex->busy = (pthread_cond_t *)NULL; - mutex->waiters = 0; - mutex->sem = SEMAPHORE_NULL; - mutex->order = SEMAPHORE_NULL; - mutex->prioceiling = 0; - mutex->sig = _PTHREAD_MUTEX_SIG; - return (0); -} /* * Initialize a mutex variable, possibly with additional attributes. @@ -236,276 +164,7 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) return EBUSY; #endif LOCK_INIT(mutex->lock); - return (_pthread_mutex_init(mutex, attr)); -} - -/* - * Lock a mutex. - * TODO: Priority inheritance stuff - */ -int -pthread_mutex_lock(pthread_mutex_t *mutex) -{ - kern_return_t kern_res; - pthread_t self; - int sig = mutex->sig; - - /* To provide backwards compat for apps using mutex incorrectly */ - if ((sig != _PTHREAD_MUTEX_SIG) && (sig != _PTHREAD_MUTEX_SIG_init)) { - PLOCKSTAT_MUTEX_ERROR(mutex, EINVAL); - return(EINVAL); - } - - LOCK(mutex->lock); - if (mutex->sig != _PTHREAD_MUTEX_SIG) - { - if (mutex->sig != _PTHREAD_MUTEX_SIG_init) - { - UNLOCK(mutex->lock); - PLOCKSTAT_MUTEX_ERROR(mutex, EINVAL); - return (EINVAL); - } - _pthread_mutex_init(mutex, NULL); - self = _PTHREAD_MUTEX_OWNER_SELF; - } -#if defined(__i386__) || defined(__x86_64__) - else if(mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED){ - UNLOCK(mutex->lock); - return(_new_pthread_mutex_lock(mutex)); - } -#endif /* __i386__ || __x86_64__ */ - else if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) - { - self = pthread_self(); - if (mutex->owner == self) - { - int res; - - if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) - { - if (mutex->mtxopts.options.lock_count < USHRT_MAX) - { - mutex->mtxopts.options.lock_count++; - PLOCKSTAT_MUTEX_ACQUIRE(mutex, 1, 0); - res = 0; - } else { - res = EAGAIN; - PLOCKSTAT_MUTEX_ERROR(mutex, res); - } - } else { /* PTHREAD_MUTEX_ERRORCHECK */ - res = EDEADLK; - PLOCKSTAT_MUTEX_ERROR(mutex, res); - } - UNLOCK(mutex->lock); - return (res); - } - } else - self = _PTHREAD_MUTEX_OWNER_SELF; - - if (mutex->owner != (pthread_t)NULL) { - if (mutex->waiters || mutex->owner != _PTHREAD_MUTEX_OWNER_SWITCHING) - { - semaphore_t sem, order; - - if (++mutex->waiters == 1) - { - mutex->sem = sem = new_sem_from_pool(); - mutex->order = order = new_sem_from_pool(); - } - else - { - sem = mutex->sem; - order = mutex->order; - do { - PTHREAD_MACH_CALL(semaphore_wait(order), kern_res); - } while (kern_res == KERN_ABORTED); - } - UNLOCK(mutex->lock); - - PLOCKSTAT_MUTEX_BLOCK(mutex); - PTHREAD_MACH_CALL(semaphore_wait_signal(sem, order), kern_res); - while (kern_res == KERN_ABORTED) - { - PTHREAD_MACH_CALL(semaphore_wait(sem), kern_res); - } - - PLOCKSTAT_MUTEX_BLOCKED(mutex, BLOCK_SUCCESS_PLOCKSTAT); - - LOCK(mutex->lock); - if (--mutex->waiters == 0) - { - PTHREAD_MACH_CALL(semaphore_wait(order), kern_res); - mutex->sem = mutex->order = SEMAPHORE_NULL; - restore_sem_to_pool(order); - restore_sem_to_pool(sem); - } - } - else if (mutex->owner == _PTHREAD_MUTEX_OWNER_SWITCHING) - { - semaphore_t sem = mutex->sem; - do { - PTHREAD_MACH_CALL(semaphore_wait(sem), kern_res); - } while (kern_res == KERN_ABORTED); - mutex->sem = SEMAPHORE_NULL; - restore_sem_to_pool(sem); - } - } - - mutex->mtxopts.options.lock_count = 1; - mutex->owner = self; - UNLOCK(mutex->lock); - PLOCKSTAT_MUTEX_ACQUIRE(mutex, 0, 0); - return (0); -} - -/* - * Attempt to lock a mutex, but don't block if this isn't possible. - */ -int -pthread_mutex_trylock(pthread_mutex_t *mutex) -{ - kern_return_t kern_res; - pthread_t self; - - LOCK(mutex->lock); - if (mutex->sig != _PTHREAD_MUTEX_SIG) - { - if (mutex->sig != _PTHREAD_MUTEX_SIG_init) - { - PLOCKSTAT_MUTEX_ERROR(mutex, EINVAL); - UNLOCK(mutex->lock); - return (EINVAL); - } - _pthread_mutex_init(mutex, NULL); - self = _PTHREAD_MUTEX_OWNER_SELF; - } -#if defined(__i386__) || defined(__x86_64__) - else if(mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED){ - UNLOCK(mutex->lock); - return(_new_pthread_mutex_trylock(mutex)); - } -#endif /* __i386__ || __x86_64__ */ - else if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) - { - self = pthread_self(); - if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) - { - if (mutex->owner == self) - { - int res; - - if (mutex->mtxopts.options.lock_count < USHRT_MAX) - { - mutex->mtxopts.options.lock_count++; - PLOCKSTAT_MUTEX_ACQUIRE(mutex, 1, 0); - res = 0; - } else { - res = EAGAIN; - PLOCKSTAT_MUTEX_ERROR(mutex, res); - } - UNLOCK(mutex->lock); - return (res); - } - } - } else - self = _PTHREAD_MUTEX_OWNER_SELF; - - if (mutex->owner != (pthread_t)NULL) - { - if (mutex->waiters || mutex->owner != _PTHREAD_MUTEX_OWNER_SWITCHING) - { - PLOCKSTAT_MUTEX_ERROR(mutex, EBUSY); - UNLOCK(mutex->lock); - return (EBUSY); - } - else if (mutex->owner == _PTHREAD_MUTEX_OWNER_SWITCHING) - { - semaphore_t sem = mutex->sem; - - do { - PTHREAD_MACH_CALL(semaphore_wait(sem), kern_res); - } while (kern_res == KERN_ABORTED); - restore_sem_to_pool(sem); - mutex->sem = SEMAPHORE_NULL; - } - } - - mutex->mtxopts.options.lock_count = 1; - mutex->owner = self; - UNLOCK(mutex->lock); - PLOCKSTAT_MUTEX_ACQUIRE(mutex, 0, 0); - return (0); -} - -/* - * Unlock a mutex. - * TODO: Priority inheritance stuff - */ -int -pthread_mutex_unlock(pthread_mutex_t *mutex) -{ - kern_return_t kern_res; - int waiters; - int sig = mutex->sig; - - - /* To provide backwards compat for apps using mutex incorrectly */ - - if ((sig != _PTHREAD_MUTEX_SIG) && (sig != _PTHREAD_MUTEX_SIG_init)) { - PLOCKSTAT_MUTEX_ERROR(mutex, EINVAL); - return(EINVAL); - } - LOCK(mutex->lock); - if (mutex->sig != _PTHREAD_MUTEX_SIG) - { - if (mutex->sig != _PTHREAD_MUTEX_SIG_init) - { - PLOCKSTAT_MUTEX_ERROR(mutex, EINVAL); - UNLOCK(mutex->lock); - return (EINVAL); - } - _pthread_mutex_init(mutex, NULL); - } -#if defined(__i386__) || defined(__x86_64__) - else if(mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED){ - UNLOCK(mutex->lock); - return(_new_pthread_mutex_unlock(mutex)); - } -#endif /* __i386__ || __x86_64__ */ - else if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) - { - pthread_t self = pthread_self(); - if (mutex->owner != self) - { - PLOCKSTAT_MUTEX_ERROR(mutex, EPERM); - UNLOCK(mutex->lock); - return EPERM; - } else if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE && - --mutex->mtxopts.options.lock_count) - { - PLOCKSTAT_MUTEX_RELEASE(mutex, 1); - UNLOCK(mutex->lock); - return(0); - } - } - - mutex->mtxopts.options.lock_count = 0; - - waiters = mutex->waiters; - if (waiters) - { - mutex->owner = _PTHREAD_MUTEX_OWNER_SWITCHING; - PLOCKSTAT_MUTEX_RELEASE(mutex, 0); - UNLOCK(mutex->lock); - PTHREAD_MACH_CALL(semaphore_signal(mutex->sem), kern_res); - } - else - { - mutex->owner = (pthread_t)NULL; - PLOCKSTAT_MUTEX_RELEASE(mutex, 0); - UNLOCK(mutex->lock); - } - return (0); + return (_pthread_mutex_init(mutex, attr, 0x7)); } /* @@ -692,19 +351,23 @@ pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, } } -#ifdef NOTYET int pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *attr, int policy) { if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) { - if ((policy == _PTHREAD_MUTEX_POLICY_FAIRSHARE) || - (policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT) || + if ( + (policy == _PTHREAD_MUTEX_POLICY_FAIRSHARE) || + (policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT) +#if NOTYET + || (policy == _PTHREAD_MUTEX_POLICY_REALTIME) || (policy == _PTHREAD_MUTEX_POLICY_ADAPTIVE) || (policy == _PTHREAD_MUTEX_POLICY_PRIPROTECT) || - (policy == _PTHREAD_MUTEX_POLICY_PRIINHERIT)) + (policy == _PTHREAD_MUTEX_POLICY_PRIINHERIT) +#endif /* NOTYET */ + ) { attr->policy = policy; return (0); @@ -717,7 +380,6 @@ pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *attr, return (EINVAL); /* Not an initialized 'attribute' structure */ } } -#endif /* NOTYET */ /* * Set the mutex 'type' value in a mutex attribute structure. @@ -787,19 +449,14 @@ pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) { #if __DARWIN_UNIX03 -#ifdef PR_5243343 - if (( pshared == PTHREAD_PROCESS_PRIVATE) || (pshared == PTHREAD_PROCESS_SHARED && PR_5243343_flag)) -#else /* !PR_5243343 */ if (( pshared == PTHREAD_PROCESS_PRIVATE) || (pshared == PTHREAD_PROCESS_SHARED)) -#endif /* PR_5243343 */ #else /* __DARWIN_UNIX03 */ if ( pshared == PTHREAD_PROCESS_PRIVATE) #endif /* __DARWIN_UNIX03 */ - { + { attr->pshared = pshared; return (0); - } else - { + } else { return (EINVAL); /* Invalid parameter */ } } else @@ -808,130 +465,39 @@ pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) } } -#if defined(__i386__) || defined(__x86_64__) - -/* - * Acquire lock seq for condition var signalling/broadcast - */ -__private_extern__ void -__mtx_holdlock(npthread_mutex_t * mutex, uint32_t diff, uint32_t * flagp, uint32_t **pmtxp, uint32_t * mgenp, uint32_t * ugenp) -{ - uint32_t mgen, ugen, ngen; - int hold = 0; - int firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT); - uint32_t * lseqaddr; - uint32_t * useqaddr; - - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MHOLD | DBG_FUNC_START, (uint32_t)mutex, diff, firstfit, 0, 0); -#endif - if (mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED) { - /* no holds for shared mutexes */ - hold = 2; - mgen = 0; - ugen = 0; - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - goto out; - } else { - lseqaddr = mutex->m_lseqaddr; - useqaddr = mutex->m_useqaddr; - } - -retry: - mgen = *lseqaddr; - ugen = *useqaddr; - /* no need to do extra wrap */ - ngen = mgen + (PTHRW_INC * diff); - hold = 0; - - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MHOLD | DBG_FUNC_NONE, (uint32_t)mutex, 0, mgen, ngen, 0); -#endif - /* can we acquire the lock ? */ - if ((mgen & PTHRW_EBIT) == 0) { - /* if it is firstfit, no need to hold till the cvar returns */ - if (firstfit == 0) { - ngen |= PTHRW_EBIT; - hold = 1; - } -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MHOLD | DBG_FUNC_NONE, (uint32_t)mutex, 1, mgen, ngen, 0); -#endif - } - - /* update lockseq */ - if (OSAtomicCompareAndSwap32(mgen, ngen, (volatile int32_t *)lseqaddr) != TRUE) - goto retry; - if (hold == 1) { - mutex->m_tid = PTHREAD_MTX_TID_SWITCHING ; - } -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MHOLD | DBG_FUNC_NONE, (uint32_t)mutex, 2, hold, 0, 0); -#endif - -out: - if (flagp != NULL) { - if (hold == 1) { - *flagp = (mutex->mtxopts.value | _PTHREAD_MTX_OPT_HOLD); - } else if (hold == 2) { - *flagp = (mutex->mtxopts.value | _PTHREAD_MTX_OPT_NOHOLD); - } else { - *flagp = mutex->mtxopts.value; - } - } - if (mgenp != NULL) - *mgenp = mgen; - if (ugenp != NULL) - *ugenp = ugen; - if (pmtxp != NULL) - *pmtxp = lseqaddr; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MHOLD | DBG_FUNC_END, (uint32_t)mutex, hold, 0, 0, 0); -#endif -} - - /* * Drop the mutex unlock references(from cond wait or mutex_unlock(). - * mgenp and ugenp valid only if notifyp is set * */ __private_extern__ int -__mtx_droplock(npthread_mutex_t * mutex, int count, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp, uint32_t *notifyp) +__mtx_droplock(npthread_mutex_t * mutex, uint32_t diffgen, uint32_t * flagsp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp) { - int oldval, newval, lockval, unlockval; - uint64_t oldtid; - pthread_t self = pthread_self(); - uint32_t notify = 0; - uint64_t oldval64, newval64; - uint32_t * lseqaddr; - uint32_t * useqaddr; + pthread_t self; + uint64_t selfid, resettid; int firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT); + uint32_t lgenval, ugenval, nlval, ulval, morewaiters=0, flags; + volatile uint32_t * lseqaddr, *useqaddr; + uint64_t oldval64, newval64; + int numwaiters=0, clearprepost = 0; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_START, (uint32_t)mutex, count, 0, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_START, (uint32_t)mutex, diffgen, 0, 0, 0); #endif - if (mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED) { - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - } else { - lseqaddr = mutex->m_lseqaddr; - useqaddr = mutex->m_useqaddr; - } - - if (flagp != NULL) - *flagp = mutex->mtxopts.value; - - if (firstfit != 0) - notify |= 0x80000000; - if (mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED) - notify |= 0x40000000; + MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); + + flags = mutex->mtxopts.value; + flags &= ~_PTHREAD_MTX_OPT_NOTIFY; /* no notification by default */ + + if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) { - if (mutex->m_tid != (uint64_t)((uintptr_t)self)) + self = pthread_self(); + (void) pthread_threadid_np(self, &selfid); + + if (mutex->m_tid != selfid) { + //LIBC_ABORT("dropping recur or error mutex not owned by the thread\n"); PLOCKSTAT_MUTEX_ERROR((pthread_mutex_t *)mutex, EPERM); return(EPERM); } else if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE && @@ -943,167 +509,192 @@ __mtx_droplock(npthread_mutex_t * mutex, int count, uint32_t * flagp, uint32_t * } - if (mutex->m_tid != (uint64_t)((uintptr_t)self)) - return(EINVAL); - - -ml0: - oldval = *useqaddr; - unlockval = oldval + (PTHRW_INC * count); - lockval = *lseqaddr; - +retry: + lgenval = *lseqaddr; + ugenval = *useqaddr; + + numwaiters = diff_genseq((lgenval & PTHRW_COUNT_MASK),(ugenval & PTHRW_COUNT_MASK)); /* pendig waiters */ + + if (numwaiters == 0) { + /* spurious unlocks, do not touch tid */ + oldval64 = (((uint64_t)ugenval) << 32); + oldval64 |= lgenval; + if ((firstfit != 0) && ((lgenval & PTH_RWL_PBIT) != 0)) { + clearprepost = 1; + lgenval &= ~PTH_RWL_PBIT; + newval64 = (((uint64_t)ugenval) << 32); + newval64 |= lgenval; + } else + newval64 = oldval64; + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) + goto retry; + /* validated L & U to be same, this is spurious unlock */ + flags &= ~_PTHREAD_MTX_OPT_NOTIFY; + if (clearprepost == 1) + __psynch_cvclrprepost(mutex, lgenval, ugenval, 0, 0, lgenval, (flags | _PTHREAD_MTX_OPT_MUTEX)); + + goto out; + } + if (numwaiters < diffgen) { #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, 10, lockval, oldval, 0); -#endif -#if 1 - if (lockval == oldval) - LIBC_ABORT("same unlock and lockseq \n"); + (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, numwaiters, lgenval, ugenval, 0); #endif - - if ((lockval & PTHRW_COUNT_MASK) == unlockval) { - oldtid = mutex->m_tid; - - mutex->m_tid = 0; - - oldval64 = (((uint64_t)oldval) << 32); - oldval64 |= lockval; - - newval64 = 0; + /* cannot drop more than existing number of waiters */ + diffgen = numwaiters; + } - if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, 1, 0, 0, 0); -#endif - goto out; - } else { - mutex->m_tid = oldtid; - /* fall thru for kernel call */ - goto ml0; + oldval64 = (((uint64_t)ugenval) << 32); + oldval64 |= lgenval; + ulval = ugenval + diffgen; + nlval = lgenval; + + if ((lgenval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) { + /* do not reset Ibit, just K&E */ + nlval &= ~(PTH_RWL_KBIT | PTH_RWL_EBIT); + flags &= ~_PTHREAD_MTX_OPT_NOTIFY; + if ((firstfit != 0) && ((lgenval & PTH_RWL_PBIT) != 0)) { + clearprepost = 1; + nlval &= ~PTH_RWL_PBIT; } - } + } else { + /* need to signal others waiting for mutex */ + morewaiters = 1; + flags |= _PTHREAD_MTX_OPT_NOTIFY; + } - if (firstfit != 0) { - /* reset ebit along with unlock */ - newval = (lockval & ~PTHRW_EBIT); + if (((nlval & PTH_RWL_EBIT) != 0) && (firstfit != 0)) { + nlval &= ~PTH_RWL_EBIT; /* reset Ebit so another can acquire meanwhile */ + } - lockval = newval; - oldval64 = (((uint64_t)oldval) << 32); - oldval64 |= lockval; + newval64 = (((uint64_t)ulval) << 32); + newval64 |= nlval; - newval64 = (((uint64_t)unlockval) << 32); - newval64 |= newval; + resettid = mutex->m_tid; + + if ((lgenval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) + mutex->m_tid = 0; + else if (firstfit == 0) + mutex->m_tid = PTHREAD_MTX_TID_SWITCHING; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) { + mutex->m_tid = resettid; + goto retry; + } - if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) { - goto ml0; - } - lockval = newval; - } else { - /* fairshare , just update and go to kernel */ - if (OSAtomicCompareAndSwap32(oldval, unlockval, (volatile int32_t *)useqaddr) != TRUE) - goto ml0; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, 2, oldval, unlockval, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, 2, nlval, ulval, 0); #endif - } - - notify |= 1; - if (notifyp != 0) { - if (mgenp != NULL) - *mgenp = lockval; - if (ugenp != NULL) - *ugenp = unlockval; - if (pmtxp != NULL) - *pmtxp = lseqaddr; - *notifyp = notify; + if (clearprepost != 0) { + __psynch_cvclrprepost(mutex, nlval, ulval, 0, 0, nlval, (flags | _PTHREAD_MTX_OPT_MUTEX)); } + + if (mgenp != NULL) + *mgenp = nlval; + if (ugenp != NULL) + *ugenp = ulval; +#if USE_COMPAGE + if (pmtxp != NULL) + *pmtxp = lseqaddr; +#else + if (pmtxp != NULL) + *pmtxp = (uint32_t *)mutex; +#endif + out: - if (notifyp != 0) { - *notifyp = notify; - } + if (flagsp != NULL) + *flagsp = flags; + #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_END, (uint32_t)mutex, flags, 0, 0, 0); #endif return(0); } int -__mtx_updatebits(npthread_mutex_t *mutex, uint32_t oupdateval, int firstfit, int fromcond) +__mtx_updatebits(npthread_mutex_t *mutex, uint32_t oupdateval, int firstfit, int fromcond, uint64_t selfid) { - uint32_t lgenval, newval, bits; - int isebit = 0; uint32_t updateval = oupdateval; +#if !USE_COMPAGE pthread_mutex_t * omutex = (pthread_mutex_t *)mutex; - uint32_t * lseqaddr; - uint32_t * useqaddr; +#endif + int isebit = 0; + uint32_t lgenval, ugenval, nval, uval, bits; + volatile uint32_t * lseqaddr, *useqaddr; + uint64_t oldval64, newval64; + + MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - if (mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED) { - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - } else { - lseqaddr = mutex->m_lseqaddr; - useqaddr = mutex->m_useqaddr; - } #if _KSYN_TRACE_ (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_START, (uint32_t)mutex, oupdateval, firstfit, fromcond, 0); #endif retry: lgenval = *lseqaddr; + ugenval = *useqaddr; bits = updateval & PTHRW_BIT_MASK; - if (lgenval == updateval) - goto out; - #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 1, lgenval, updateval, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 1, lgenval, ugenval, 0); #endif - if ((lgenval & PTHRW_BIT_MASK) == bits) - goto out; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, bits, 0); -#endif - /* firsfit might not have EBIT */ - if (firstfit != 0) { - lgenval &= ~PTHRW_EBIT; /* see whether EBIT is set */ - if ((lgenval & PTHRW_EBIT) != 0) - isebit = 1; + + if ((updateval & PTH_RWL_MTX_WAIT) != 0) { + lgenval = (updateval & PTHRW_COUNT_MASK) | (lgenval & PTHRW_BIT_MASK); + if (fromcond == 0) { + /* if from mutex_lock(), it will handle the rewind */ + return(1); + } + /* go block in the kernel with same lgenval as returned */ + goto ml1; + } else { + /* firsfit might not have EBIT */ + if (firstfit != 0) { + if ((lgenval & PTH_RWL_EBIT) != 0) + isebit = 1; + else + isebit = 0; + } else if ((lgenval & (PTH_RWL_KBIT|PTH_RWL_EBIT)) == (PTH_RWL_KBIT|PTH_RWL_EBIT)) { + /* fairshare mutex and the bits are already set, just update tid */ + goto out; + } } - if ((lgenval & PTHRW_COUNT_MASK) == (updateval & PTHRW_COUNT_MASK)) { + /* either firstfist or no E bit set */ + /* update the bits */ + oldval64 = (((uint64_t)ugenval) << 32); + oldval64 |= lgenval; + uval = ugenval; + nval = lgenval | (PTH_RWL_KBIT|PTH_RWL_EBIT); + newval64 = (((uint64_t)uval) << 32); + newval64 |= nval; + + /* set s and b bit */ + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) { #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 3, lgenval, updateval, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 2, nval, uval, 0); #endif - updateval |= PTHRW_EBIT; /* just in case.. */ - if (OSAtomicCompareAndSwap32(lgenval, updateval, (volatile int32_t *)lseqaddr) != TRUE) { - if (firstfit == 0) - goto retry; + if ((firstfit != 0) && (isebit != 0)) goto handleffit; - } - /* update succesfully */ - goto out; - } - - if (((lgenval & PTHRW_WBIT) != 0) && ((updateval & PTHRW_WBIT) == 0)) { - newval = lgenval | (bits | PTHRW_WBIT | PTHRW_EBIT); - } else { - newval = lgenval | (bits | PTHRW_EBIT); + goto out; + } else { + if (firstfit == 0) + goto retry; + else + goto handleffit; } - + #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 4, lgenval, newval, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 4, nval, uval, 0); #endif - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) != TRUE) { - if (firstfit == 0) - goto retry; - goto handleffit; - } + out: /* succesful bits updation */ - mutex->m_tid = (uint64_t)((uintptr_t)pthread_self()); + mutex->m_tid = selfid; #if _KSYN_TRACE_ (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0); #endif @@ -1111,66 +702,144 @@ out: handleffit: /* firstfit failure */ - newval = *lseqaddr; - if ((newval & PTHRW_EBIT) == 0) + lgenval = *lseqaddr; + ugenval = *useqaddr; + if ((lgenval & PTH_RWL_EBIT) == 0) goto retry; - if (((lgenval & PTHRW_COUNT_MASK) == (newval & PTHRW_COUNT_MASK)) && (isebit == 1)) { - if (fromcond == 0) - return(1); - else { - /* called from condition variable code block again */ + + if (fromcond == 0) + return(1); + else { + /* called from condition variable code block again */ ml1: #if USE_COMPAGE /* [ */ - updateval = __psynch_mutexwait((pthread_mutex_t *)lseqaddr, newval | PTHRW_RETRYBIT, *useqaddr, (uint64_t)0, - mutex->mtxopts.value); + updateval = __psynch_mutexwait((pthread_mutex_t *)lseqaddr, lgenval | PTH_RWL_RETRYBIT, ugenval, mutex->m_tid, + mutex->mtxopts.value); #else /* USECOMPAGE ][ */ - updateval = __psynch_mutexwait(omutex, newval | PTHRW_RETRYBIT, *useqaddr, (uint64_t)0, + updateval = __psynch_mutexwait(omutex, lgenval | PTH_RWL_RETRYBIT, ugenval, mutex->m_tid, + mutex->mtxopts.value); #endif /* USE_COMPAGE ] */ - if (updateval == (uint32_t)-1) { - goto ml1; - } - - goto retry; + if (updateval == (uint32_t)-1) { + goto ml1; } + + /* now update the bits */ + goto retry; } - /* seqcount changed, retry */ + /* cannot reach */ goto retry; } + int -_new_pthread_mutex_lock(pthread_mutex_t *omutex) +__mtx_markprepost(npthread_mutex_t *mutex, uint32_t oupdateval, int firstfit) +{ + uint32_t updateval = oupdateval; + int clearprepost = 0; + uint32_t lgenval, ugenval,flags; + volatile uint32_t * lseqaddr, *useqaddr; + uint64_t oldval64, newval64; + + MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); + +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_START, (uint32_t)mutex, oupdateval, firstfit, 0, 0); +#endif + +retry: + + + + if ((firstfit != 0) && ((updateval & PTH_RWL_PBIT) != 0)) { + flags = mutex->mtxopts.value; + + lgenval = *lseqaddr; + ugenval = *useqaddr; + +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_NONE, (uint32_t)mutex, 1, lgenval, ugenval, 0); +#endif + /* update the bits */ + oldval64 = (((uint64_t)ugenval) << 32); + oldval64 |= lgenval; + + if ((lgenval & PTHRW_COUNT_MASK) == (ugenval & PTHRW_COUNT_MASK)) { + clearprepost = 1; + lgenval &= ~PTH_RWL_PBIT; + + } else { + lgenval |= PTH_RWL_PBIT; + } + newval64 = (((uint64_t)ugenval) << 32); + newval64 |= lgenval; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) { +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0); +#endif + + if (clearprepost != 0) + __psynch_cvclrprepost(mutex, lgenval, ugenval, 0, 0, lgenval, (flags | _PTHREAD_MTX_OPT_MUTEX)); + + } else { + goto retry; + } + +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0); +#endif + } + return(0); +} + +/* + * For the new style mutex, interlocks are not held all the time. + * We needed the signature to be set in the end. And we need + * to protect against the code getting reorganized by compiler. + */ +static void +__pthread_mutex_set_signature(npthread_mutex_t * mutex) +{ + mutex->sig = _PTHREAD_MUTEX_SIG; +} + +int +pthread_mutex_lock(pthread_mutex_t *omutex) { pthread_t self; + uint64_t selfid; npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; int sig = mutex->sig; +#if NEVERINCOMPAGE || !USE_COMPAGE + //uint32_t oldval, newval; +#endif int retval; - uint32_t oldval, newval, uval, updateval; - int gotlock = 0; - int firstfit = 0; - int retrybit = 0; - uint32_t * lseqaddr; - uint32_t * useqaddr; - int updatebitsonly = 0; + int gotlock = 0, firstfit = 0; + uint32_t updateval, lgenval, ugenval, nval, uval; + volatile uint32_t * lseqaddr, *useqaddr; + uint64_t oldval64, newval64; #if USE_COMPAGE - uint64_t mytid; int sysret = 0; uint32_t mask; #else - + int retrybit = 0; #endif /* To provide backwards compat for apps using mutex incorrectly */ - if ((sig != _PTHREAD_MUTEX_SIG) && (sig != _PTHREAD_MUTEX_SIG_init)) { + if ((sig != _PTHREAD_MUTEX_SIG) && ((sig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) { PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); return(EINVAL); } - if (sig != _PTHREAD_MUTEX_SIG) { + if (mutex->sig != _PTHREAD_MUTEX_SIG) { LOCK(mutex->lock); - if ((sig != _PTHREAD_MUTEX_SIG) && (sig == _PTHREAD_MUTEX_SIG_init)) { - /* static initializer, init the mutex */ - _new_pthread_mutex_init(omutex, NULL); - self = _PTHREAD_MUTEX_OWNER_SELF; - } else { + if ((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK) == _PTHREAD_MUTEX_SIG_CMP) { + /* static initializer, init the mutex */ + if(retval = _pthread_mutex_init(omutex, NULL, (mutex->sig & 0xf)) != 0){ + UNLOCK(mutex->lock); + PLOCKSTAT_MUTEX_ERROR(omutex, retval); + return(retval); + } + } else if (mutex->sig != _PTHREAD_MUTEX_SIG) { UNLOCK(mutex->lock); PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); return(EINVAL); @@ -1181,16 +850,13 @@ _new_pthread_mutex_lock(pthread_mutex_t *omutex) #if _KSYN_TRACE_ (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_START, (uint32_t)mutex, 0, 0, 0, 0); #endif - if (mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED) { - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - } else { - lseqaddr = mutex->m_lseqaddr; - useqaddr = mutex->m_useqaddr; - } + MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); self = pthread_self(); + (void) pthread_threadid_np(self, &selfid); + if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) { - if (mutex->m_tid == (uint64_t)((uintptr_t)self)) { + if (mutex->m_tid == selfid) { if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) { if (mutex->mtxopts.options.lock_count < USHRT_MAX) @@ -1209,24 +875,23 @@ _new_pthread_mutex_lock(pthread_mutex_t *omutex) return (retval); } } + #if _KSYN_TRACE_ (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 1, 0, 0, 0); #endif -loop: -#if USE_COMPAGE /* [ */ - mytid = (uint64_t)((uintptr_t)pthread_self()); +#if USE_COMPAGE /* [ */ ml0: - mask = PTHRW_EBIT; - retval = _commpage_pthread_mutex_lock(lseqaddr, mutex->mtxopts.value, mytid, mask, &mutex->m_tid, &sysret); + mask = PTH_RWL_EBIT; + retval = _commpage_pthread_mutex_lock(lseqaddr, mutex->mtxopts.value, selfid, mask, &mutex->m_tid, &sysret); if (retval == 0) { gotlock = 1; } else if (retval == 1) { gotlock = 1; updateval = sysret; /* returns 0 on succesful update */ - if (__mtx_updatebits( mutex, updateval, firstfit, 0) == 1) { + if (__mtx_updatebits( mutex, updateval, firstfit, 0, selfid) == 1) { /* could not acquire, may be locked in ffit case */ #if USE_COMPAGE LIBC_ABORT("comapge implementatin looping in libc \n"); @@ -1245,57 +910,65 @@ ml0: } #endif else { - LIBC_ABORT("comapge implementatin bombed \n"); + LIBC_ABORT("comapge implementation bombed \n"); } #else /* USECOMPAGE ][ */ - oldval = *lseqaddr; - uval = *useqaddr; - newval = oldval + PTHRW_INC; +retry: + lgenval = *lseqaddr; + ugenval = *useqaddr; - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, oldval, uval, 0); +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0); +#endif /* _KSYN_TRACE_ */ - if((oldval & PTHRW_EBIT) == 0) { + if((lgenval & PTH_RWL_EBIT) == 0) { gotlock = 1; - newval |= PTHRW_EBIT; } else { gotlock = 0; - newval |= PTHRW_WBIT; } - - if (OSAtomicCompareAndSwap32(oldval, newval, (volatile int32_t *)lseqaddr) == TRUE) { - if (gotlock != 0) - mutex->m_tid = (uint64_t)((uintptr_t)self); + + oldval64 = (((uint64_t)ugenval) << 32); + oldval64 |= lgenval; + uval = ugenval; + nval = (lgenval + PTHRW_INC) | (PTH_RWL_EBIT|PTH_RWL_KBIT); + newval64 = (((uint64_t)uval) << 32); + newval64 |= nval; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) { #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, oldval, newval, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, nval, uval, 0); #endif + if (gotlock != 0) { + mutex->m_tid = selfid; + goto out; + } } else - goto loop; + goto retry; retrybit = 0; if (gotlock == 0) { #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 3, 0, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 3, nval, uval, 0); #endif firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT); ml1: - updateval = __psynch_mutexwait(omutex, newval | retrybit, uval, (uint64_t)0, + updateval = __psynch_mutexwait(omutex, nval | retrybit, uval, mutex->m_tid, mutex->mtxopts.value); +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 4, updateval, 0, 0); +#endif if (updateval == (uint32_t)-1) { - updatebitsonly = 0; goto ml1; } -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 4, updateval, 0, 0); -#endif - /* returns 0 on succesful update */ - if (__mtx_updatebits( mutex, updateval, firstfit, 0) == 1) { + /* returns 0 on succesful update; in firstfit it may fail with 1 */ + if (__mtx_updatebits( mutex, PTHRW_INC | (PTH_RWL_KBIT | PTH_RWL_EBIT), firstfit, 0, selfid) == 1) { /* could not acquire, may be locked in ffit case */ - retrybit = PTHRW_RETRYBIT; + retrybit = PTH_RWL_RETRYBIT; #if USE_COMPAGE LIBC_ABORT("comapge implementatin looping in libc \n"); @@ -1305,8 +978,9 @@ ml1: } #endif /* USE_COMPAGE ] */ +out: if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) - mutex->mtxopts.options.lock_count++; + mutex->mtxopts.options.lock_count = 1; #if _KSYN_TRACE_ (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0); @@ -1318,29 +992,34 @@ ml1: * Attempt to lock a mutex, but don't block if this isn't possible. */ int -_new_pthread_mutex_trylock(pthread_mutex_t *omutex) +pthread_mutex_trylock(pthread_mutex_t *omutex) { npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; int sig = mutex->sig; - uint32_t oldval, newval; int error = 0; pthread_t self; - uint32_t * lseqaddr; - uint32_t * useqaddr; + uint64_t selfid; + int gotlock = 0; + uint32_t lgenval, ugenval, nval, uval; + volatile uint32_t * lseqaddr, *useqaddr; + uint64_t oldval64, newval64; /* To provide backwards compat for apps using mutex incorrectly */ - if ((sig != _PTHREAD_MUTEX_SIG) && (sig != _PTHREAD_MUTEX_SIG_init)) { + if ((sig != _PTHREAD_MUTEX_SIG) && ((sig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) { PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); return(EINVAL); } - if (sig != _PTHREAD_MUTEX_SIG) { + if ((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK) == _PTHREAD_MUTEX_SIG_CMP) { LOCK(mutex->lock); - if ((sig != _PTHREAD_MUTEX_SIG) && (sig == _PTHREAD_MUTEX_SIG_init)) { + if (mutex->sig == _PTHREAD_MUTEX_SIG_init) { /* static initializer, init the mutex */ - _new_pthread_mutex_init(omutex, NULL); - self = _PTHREAD_MUTEX_OWNER_SELF; - } else { + if((error = _pthread_mutex_init(omutex, NULL, (mutex->sig & 0xf))) != 0){ + UNLOCK(mutex->lock); + PLOCKSTAT_MUTEX_ERROR(omutex, error); + return(error); + } + } else if (mutex->sig != _PTHREAD_MUTEX_SIG) { UNLOCK(mutex->lock); PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); return(EINVAL); @@ -1348,16 +1027,13 @@ _new_pthread_mutex_trylock(pthread_mutex_t *omutex) UNLOCK(mutex->lock); } - if (mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED) { - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - } else { - lseqaddr = mutex->m_lseqaddr; - useqaddr = mutex->m_useqaddr; - } + MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); self = pthread_self(); + (void) pthread_threadid_np(self, &selfid); + if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) { - if (mutex->m_tid == (uint64_t)((uintptr_t)self)) { + if (mutex->m_tid == selfid) { if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) { if (mutex->mtxopts.options.lock_count < USHRT_MAX) @@ -1376,26 +1052,53 @@ _new_pthread_mutex_trylock(pthread_mutex_t *omutex) return (error); } } -retry: - oldval = *lseqaddr; +retry: + lgenval = *lseqaddr; + ugenval = *useqaddr; + +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0); +#endif /* _KSYN_TRACE_ */ + - if ((oldval & PTHRW_EBIT) != 0) { - newval = oldval | PTHRW_TRYLKBIT; - if (OSAtomicCompareAndSwap32(oldval, newval, (volatile int32_t *)lseqaddr) == TRUE) { - error = EBUSY; - } else - goto retry; + oldval64 = (((uint64_t)ugenval) << 32); + oldval64 |= lgenval; + uval = ugenval; + + /* if we can acquire go ahead otherwise ensure it is still busy */ + if((lgenval & PTH_RWL_EBIT) == 0) { + gotlock = 1; + nval = (lgenval + PTHRW_INC) | (PTH_RWL_EBIT|PTH_RWL_KBIT); } else { - newval = (oldval + PTHRW_INC)| PTHRW_EBIT; - if ((OSAtomicCompareAndSwap32(oldval, newval, (volatile int32_t *)lseqaddr) == TRUE)) { - mutex->m_tid = (uint64_t)((uintptr_t)self); - if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) - mutex->mtxopts.options.lock_count++; - } else - goto retry; + nval = (lgenval | PTH_RWL_TRYLKBIT); + gotlock = 0; } + + newval64 = (((uint64_t)uval) << 32); + newval64 |= nval; + + /* set s and b bit */ + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) { +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, nval, uval, 0); +#endif + if (gotlock != 0) { + mutex->m_tid = selfid; + if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) + mutex->mtxopts.options.lock_count = 1; + PLOCKSTAT_MUTEX_ACQUIRE(omutex, 1, 0); + } else { + error = EBUSY; + PLOCKSTAT_MUTEX_ERROR(omutex, error); + } + } else + goto retry; - return(error); + +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_END, (uint32_t)mutex, 0xfafafafa, 0, error, 0); +#endif + return (error); } /* @@ -1403,64 +1106,82 @@ retry: * TODO: Priority inheritance stuff */ int -_new_pthread_mutex_unlock(pthread_mutex_t *omutex) +pthread_mutex_unlock(pthread_mutex_t *omutex) { npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; int retval; - uint32_t mtxgen, mtxugen, flags, notify; + uint32_t mtxgen, mtxugen, flags, notify, updateval; int sig = mutex->sig; - pthread_t self = pthread_self(); - uint32_t * lseqaddr; - uint32_t * useqaddr; + pthread_t self; + uint64_t selfid; + volatile uint32_t * lseqaddr, *useqaddr; + int firstfit = 0; /* To provide backwards compat for apps using mutex incorrectly */ #if _KSYN_TRACE_ (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_START, (uint32_t)mutex, 0, 0, 0, 0); #endif - if ((sig != _PTHREAD_MUTEX_SIG) && (sig != _PTHREAD_MUTEX_SIG_init)) { + if ((sig != _PTHREAD_MUTEX_SIG) && ((sig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) { PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); return(EINVAL); } - if (sig != _PTHREAD_MUTEX_SIG) { + + if (mutex->sig != _PTHREAD_MUTEX_SIG) { LOCK(mutex->lock); - if ((sig != _PTHREAD_MUTEX_SIG) && (sig == _PTHREAD_MUTEX_SIG_init)) { + if ((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK) == _PTHREAD_MUTEX_SIG_CMP) { /* static initializer, init the mutex */ - _new_pthread_mutex_init(omutex, NULL); - self = _PTHREAD_MUTEX_OWNER_SELF; - } else { + if((retval = _pthread_mutex_init(omutex, NULL, (mutex->sig & 0xf))) != 0){ + UNLOCK(mutex->lock); + PLOCKSTAT_MUTEX_ERROR(omutex, retval); + return(retval); + } + } else if (mutex->sig != _PTHREAD_MUTEX_SIG) { UNLOCK(mutex->lock); PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); return(EINVAL); } UNLOCK(mutex->lock); } - - if (mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED) { - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - } else { - lseqaddr = mutex->m_lseqaddr; - useqaddr = mutex->m_useqaddr; - } + + MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); + notify = 0; - retval = __mtx_droplock(mutex, 1, &flags, NULL, &mtxgen, &mtxugen, ¬ify); + retval = __mtx_droplock(mutex, PTHRW_INC, &flags, NULL, &mtxgen, &mtxugen); if (retval != 0) return(retval); - if ((notify & 1) != 0) { + if ((flags & _PTHREAD_MTX_OPT_NOTIFY) != 0) { + firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT); + + self = pthread_self(); + (void) pthread_threadid_np(self, &selfid); + #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_NONE, (uint32_t)mutex, 1, 0, 0, 0); + (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_NONE, (uint32_t)mutex, 1, mtxgen, mtxugen, 0); #endif #if USE_COMPAGE /* [ */ - if ( __psynch_mutexdrop((pthread_mutex_t *)lseqaddr, mtxgen, mtxugen, (uint64_t)0, flags)== (uint32_t)-1) + if ((updateval = __psynch_mutexdrop((pthread_mutex_t *)lseqaddr, mtxgen, mtxugen, mutex->m_tid, flags)) == (uint32_t)-1) #else /* USECOMPAGE ][ */ - if ( __psynch_mutexdrop(omutex, mtxgen, mtxugen, (uint64_t)0, flags)== (uint32_t)-1) + if ((updateval = __psynch_mutexdrop(omutex, mtxgen, mtxugen, mutex->m_tid, flags))== (uint32_t)-1) #endif /* USE_COMPAGE ] */ { - if (errno == EINTR) + retval = errno; +#if _KSYN_TRACE_ + (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_END, (uint32_t)mutex, retval, 0, 0, 0); +#endif + if (retval == 0) return(0); - else - return(errno); + else if (errno == EINTR) + return(0); + else { + LIBC_ABORT("__p_mutexdrop failed with error %d\n", retval); + return(retval); + } + } else if (firstfit == 1) { + if ((updateval & PTH_RWL_PBIT) != 0) { + __mtx_markprepost(mutex, updateval, firstfit); + } } } #if _KSYN_TRACE_ @@ -1474,7 +1195,7 @@ _new_pthread_mutex_unlock(pthread_mutex_t *omutex) * Initialize a mutex variable, possibly with additional attributes. */ int -_new_pthread_mutex_init(pthread_mutex_t *omutex, const pthread_mutexattr_t *attr) +_pthread_mutex_init(pthread_mutex_t *omutex, const pthread_mutexattr_t *attr, uint32_t static_type) { npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; @@ -1488,13 +1209,35 @@ _new_pthread_mutex_init(pthread_mutex_t *omutex, const pthread_mutexattr_t *attr mutex->mtxopts.options.type = attr->type; mutex->mtxopts.options.pshared = attr->pshared; } else { + switch(static_type) { + case 1: + mutex->mtxopts.options.type = PTHREAD_MUTEX_ERRORCHECK; + break; + case 2: + mutex->mtxopts.options.type = PTHREAD_MUTEX_RECURSIVE; + break; + case 3: + /* firstfit fall thru */ + case 7: + mutex->mtxopts.options.type = PTHREAD_MUTEX_DEFAULT; + break; + default: + return(EINVAL); + } + mutex->prioceiling = _PTHREAD_DEFAULT_PRIOCEILING; mutex->mtxopts.options.protocol = _PTHREAD_DEFAULT_PROTOCOL; - mutex->mtxopts.options.policy = _PTHREAD_MUTEX_POLICY_FAIRSHARE; - mutex->mtxopts.options.type = PTHREAD_MUTEX_DEFAULT; + if (static_type != 3) + mutex->mtxopts.options.policy = _PTHREAD_MUTEX_POLICY_FAIRSHARE; + else + mutex->mtxopts.options.policy = _PTHREAD_MUTEX_POLICY_FIRSTFIT; mutex->mtxopts.options.pshared = _PTHREAD_DEFAULT_PSHARED; } + mutex->mtxopts.options.notify = 0; + mutex->mtxopts.options.rfu = 0; + mutex->mtxopts.options.hold = 0; + mutex->mtxopts.options.mutex = 1; mutex->mtxopts.options.lock_count = 0; /* address 8byte aligned? */ if (((uintptr_t)mutex & 0x07) != 0) { @@ -1524,64 +1267,66 @@ _new_pthread_mutex_init(pthread_mutex_t *omutex, const pthread_mutexattr_t *attr mutex->m_seq[2] = 0; mutex->prioceiling = 0; mutex->priority = 0; - mutex->sig = _PTHREAD_MUTEX_SIG; + /* + * For the new style mutex, interlocks are not held all the time. + * We needed the signature to be set in the end. And we need + * to protect against the code getting reorganized by compiler. + * mutex->sig = _PTHREAD_MUTEX_SIG; + */ + __pthread_mutex_set_signature(mutex); return (0); } - /* * Destroy a mutex variable. */ int -_new_pthread_mutex_destroy(pthread_mutex_t *omutex) +pthread_mutex_destroy(pthread_mutex_t *omutex) { int res; npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; LOCK(mutex->lock); - res = _new_pthread_mutex_destroy_locked(omutex); + res = _pthread_mutex_destroy_locked(omutex); UNLOCK(mutex->lock); return(res); } -int -_new_pthread_mutex_destroy_locked(pthread_mutex_t *omutex) +static int +_pthread_mutex_destroy_locked(pthread_mutex_t *omutex) { int res; npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; - uint32_t lgenval; - uint32_t * lseqaddr; - uint32_t * useqaddr; + uint32_t lgenval, ugenval; + volatile uint32_t * lseqaddr, *useqaddr; if (mutex->sig == _PTHREAD_MUTEX_SIG) { - if (mutex->mtxopts.options.pshared == PTHREAD_PROCESS_SHARED) { - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - } else { - lseqaddr = mutex->m_lseqaddr; - useqaddr = mutex->m_useqaddr; - } + MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); lgenval = *(lseqaddr); + ugenval = *(useqaddr); if ((mutex->m_tid == (uint64_t)0) && - ((lgenval & PTHRW_COUNT_MASK) == 0)) + ((lgenval & PTHRW_COUNT_MASK) == (ugenval & PTHRW_COUNT_MASK))) { mutex->sig = _PTHREAD_NO_SIG; res = 0; } else res = EBUSY; - } else + } else if((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK )== _PTHREAD_MUTEX_SIG_CMP) { + mutex->sig = _PTHREAD_NO_SIG; + res = 0; + } else res = EINVAL; return (res); } -#endif /* __i386__ || __x86_64__ */ #endif /* !BUILDING_VARIANT ] */ diff --git a/pthreads/pthread_rwlock.c b/pthreads/pthread_rwlock.c index 0da20d5..3920969 100644 --- a/pthreads/pthread_rwlock.c +++ b/pthreads/pthread_rwlock.c @@ -79,58 +79,54 @@ extern int __unix_conforming; /* maximum number of times a read lock may be obtained */ #define MAX_READ_LOCKS (INT_MAX - 1) -#if defined(__i386__) || defined(__x86_64__) #ifndef BUILDING_VARIANT /* [ */ -int usenew_impl = 0; +__private_extern__ int usenew_impl = 1; #else /* BUILDING_VARIANT */ extern int usenew_impl; #endif /* BUILDING_VARIANT */ +extern int PR_5243343_flag; #if defined(__LP64__) -#define RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr) \ +#define RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr) \ { \ if (rwlock->misalign != 0) { \ - lseqaddr = &rwlock->rw_seq[1]; \ - wcaddr = &rwlock->rw_seq[2]; \ - useqaddr = &rwlock->rw_seq[3]; \ + lcntaddr = &rwlock->rw_seq[1]; \ + seqaddr = &rwlock->rw_seq[2]; \ + ucntaddr = &rwlock->rw_seq[3]; \ } else { \ - lseqaddr = &rwlock->rw_seq[0]; \ - wcaddr = &rwlock->rw_seq[1]; \ - useqaddr = &rwlock->rw_seq[2]; \ + lcntaddr = &rwlock->rw_seq[0]; \ + seqaddr = &rwlock->rw_seq[1]; \ + ucntaddr = &rwlock->rw_seq[2]; \ } \ } #else /* __LP64__ */ -#define RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr) \ +#define RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr) \ { \ if (rwlock->misalign != 0) { \ - lseqaddr = &rwlock->rw_seq[0]; \ - wcaddr = &rwlock->rw_seq[1]; \ - useqaddr = &rwlock->rw_seq[2]; \ - }else { \ - lseqaddr = &rwlock->rw_seq[1]; \ - wcaddr = &rwlock->rw_seq[2]; \ - useqaddr = &rwlock->rw_seq[3]; \ + lcntaddr = &rwlock->rw_seq[1]; \ + seqaddr = &rwlock->rw_seq[2]; \ + ucntaddr = &rwlock->rw_seq[3]; \ + } else { \ + lcntaddr = &rwlock->rw_seq[0]; \ + seqaddr = &rwlock->rw_seq[1]; \ + ucntaddr = &rwlock->rw_seq[2]; \ } \ } #endif /* __LP64__ */ -int _new_pthread_rwlock_destroy(pthread_rwlock_t *rwlock); -int _new_pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); -int _new_pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); -int _new_pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); -int _new_pthread_rwlock_longrdlock_np(pthread_rwlock_t *rwlock); -int _new_pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); -int _new_pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); -int _new_pthread_rwlock_yieldwrlock_np(pthread_rwlock_t *rwlock); -int _new_pthread_rwlock_unlock(pthread_rwlock_t *rwlock); -int _new_pthread_rwlock_downgrade_np(pthread_rwlock_t *rwlock); -int _new_pthread_rwlock_upgrade_np(pthread_rwlock_t *rwlock); +__private_extern__ int __pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); + #define _KSYN_TRACE_ 0 #if _KSYN_TRACE_ +#include +#ifndef BUILDING_VARIANT /* [ */ +static void set_enable(int); +#endif /* !BUILDING_VARIANT ] */ + /* The Function qualifiers */ #define DBG_FUNC_START 1 #define DBG_FUNC_END 2 @@ -145,21 +141,17 @@ int __kdebug_trace(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); #define _KSYN_TRACE_RW_UNACT2 0x9008090 #define _KSYN_TRACE_RW_UNACTK 0x9008094 #define _KSYN_TRACE_RW_UNACTE 0x9008098 +#define _KSYN_TRACE_RW_UNACTR 0x900809c +#define _KSYN_TRACE_RW_TOOMANY 0x90080a0 +#define _KSYN_TRACE_RW_TRYWRLOCK 0x90080a4 +#define _KSYN_TRACE_RW_TRYRDLOCK 0x90080a8 #endif /* _KSYN_TRACE_ */ -#endif /* __i386__ || __x86_64__ */ - -#ifndef BUILDING_VARIANT /* [ */ -#if defined(__i386__) || defined(__x86_64__) -static int rwlock_unlock_action_onread(pthread_rwlock_t * rwlock, uint32_t updateval); -static int rwlock_unlock_action1(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t updateval); -static int rwlock_unlock_action2(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t updateval); -static uint32_t modbits(uint32_t lgenval, uint32_t updateval); -static int rwlock_unlock_action_k(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t updateval); -static int rwlock_exclusive_lockreturn(pthread_rwlock_t * rwlock, uint32_t updateval); -static int rw_diffgenseq(uint32_t x, uint32_t y); -#endif /* __i386__ || __x86_64__ */ +__private_extern__ void rwlock_action_onreturn(pthread_rwlock_t * rwlock, uint32_t updateval); +__private_extern__ int rw_diffgenseq(uint32_t x, uint32_t y); +#ifndef BUILDING_VARIANT /* [ */ +static uint32_t modbits(uint32_t lgenval, uint32_t updateval, uint32_t savebits); int pthread_rwlockattr_init(pthread_rwlockattr_t *attr) @@ -216,81 +208,14 @@ pthread_rwlockattr_setpshared(pthread_rwlockattr_t * attr, int pshared) } -#if defined(__i386__) || defined(__x86_64__) /* [ */ -int -_new_pthread_rwlock_destroy(pthread_rwlock_t *orwlock) +__private_extern__ int +__pthread_rwlock_init(pthread_rwlock_t * orwlock, const pthread_rwlockattr_t *attr) { npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; -#if __DARWIN_UNIX03 - uint32_t rw_lseqcnt, rw_useqcnt; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; -#endif /* __DARWIN_UNIX03 */ - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - return(EINVAL); - } else { -#if __DARWIN_UNIX03 - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); - } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } - - rw_lseqcnt = *lseqaddr; - rw_useqcnt = *useqaddr; - - if((rw_lseqcnt & PTHRW_COUNT_MASK) != rw_useqcnt) - return(EBUSY); - -#endif /* __DARWIN_UNIX03 */ - //bzero(rwlock, sizeof(npthread_rwlock_t)); - rwlock->sig = _PTHREAD_NO_SIG; - return(0); - } -} - -int -_new_pthread_rwlock_init(pthread_rwlock_t * orwlock, const pthread_rwlockattr_t *attr) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; -#if __DARWIN_UNIX03 - uint32_t rw_lseqcnt, rw_useqcnt; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; -#endif /* __DARWIN_UNIX03 */ - -#if __DARWIN_UNIX03 - if (attr && (attr->sig != _PTHREAD_RWLOCK_ATTR_SIG)) { - return(EINVAL); - } - - /* if already inited check whether it is in use, then return EBUSY */ - if (rwlock->sig == _PTHREAD_RWLOCK_SIG) { - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); - } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } - rw_lseqcnt = *lseqaddr; - rw_useqcnt = *useqaddr; - - if ((rw_lseqcnt & PTHRW_COUNT_MASK) != rw_useqcnt) - return(EBUSY); - - } -#endif /* __DARWIN_UNIX03 */ - - /* initialize the lock */ - bzero(rwlock, sizeof(pthread_rwlock_t)); - if ((attr != NULL) && (attr->pshared == PTHREAD_PROCESS_SHARED)) { rwlock->pshared = PTHREAD_PROCESS_SHARED; rwlock->rw_flags = PTHRW_KERN_PROCESS_SHARED; - } else { rwlock->pshared = _PTHREAD_DEFAULT_PSHARED; rwlock->rw_flags = PTHRW_KERN_PROCESS_PRIVATE; @@ -299,294 +224,291 @@ _new_pthread_rwlock_init(pthread_rwlock_t * orwlock, const pthread_rwlockattr_t if (((uintptr_t)rwlock & 0x07) != 0) { rwlock->misalign = 1; #if defined(__LP64__) - rwlock->rw_lseqaddr = &rwlock->rw_seq[1]; - rwlock->rw_wcaddr = &rwlock->rw_seq[2]; - rwlock->rw_useqaddr = &rwlock->rw_seq[3]; - rwlock->rw_seq[1]= PTHRW_RW_INIT; + rwlock->rw_lcntaddr = &rwlock->rw_seq[1]; + rwlock->rw_seqaddr = &rwlock->rw_seq[2]; + rwlock->rw_ucntaddr = &rwlock->rw_seq[3]; + rwlock->rw_seq[1]= PTHRW_RWLOCK_INIT; + rwlock->rw_seq[2]= PTHRW_RWS_INIT; + rwlock->rw_seq[3]= 0; #else /* __LP64__ */ - rwlock->rw_lseqaddr = &rwlock->rw_seq[0]; - rwlock->rw_wcaddr = &rwlock->rw_seq[1]; - rwlock->rw_useqaddr = &rwlock->rw_seq[2]; - rwlock->rw_seq[0]= PTHRW_RW_INIT; + rwlock->rw_lcntaddr = &rwlock->rw_seq[1]; + rwlock->rw_seqaddr = &rwlock->rw_seq[2]; + rwlock->rw_ucntaddr = &rwlock->rw_seq[3]; + rwlock->rw_seq[1]= PTHRW_RWLOCK_INIT; + rwlock->rw_seq[2]= PTHRW_RWS_INIT; + rwlock->rw_seq[3]= 0; #endif /* __LP64__ */ } else { rwlock->misalign = 0; #if defined(__LP64__) - rwlock->rw_lseqaddr = &rwlock->rw_seq[0]; - rwlock->rw_wcaddr = &rwlock->rw_seq[1]; - rwlock->rw_useqaddr = &rwlock->rw_seq[2]; - rwlock->rw_seq[0]= PTHRW_RW_INIT; + rwlock->rw_lcntaddr = &rwlock->rw_seq[0]; + rwlock->rw_seqaddr = &rwlock->rw_seq[1]; + rwlock->rw_ucntaddr = &rwlock->rw_seq[2]; + rwlock->rw_seq[0]= PTHRW_RWLOCK_INIT; + rwlock->rw_seq[1]= PTHRW_RWS_INIT; + rwlock->rw_seq[2]= 0; #else /* __LP64__ */ - rwlock->rw_lseqaddr = &rwlock->rw_seq[1]; - rwlock->rw_wcaddr = &rwlock->rw_seq[2]; - rwlock->rw_useqaddr = &rwlock->rw_seq[3]; - rwlock->rw_seq[1]= PTHRW_RW_INIT; + rwlock->rw_lcntaddr = &rwlock->rw_seq[0]; + rwlock->rw_seqaddr = &rwlock->rw_seq[1]; + rwlock->rw_ucntaddr = &rwlock->rw_seq[2]; + rwlock->rw_seq[0]= PTHRW_RWLOCK_INIT; + rwlock->rw_seq[1]= PTHRW_RWS_INIT; + rwlock->rw_seq[2]= 0; #endif /* __LP64__ */ } + + rwlock->reserv = 0; + rwlock->rw_owner = NULL; +#if defined(__LP64__) + memset(rwlock->rfu, 0, PTHRW_RFU_64BIT); +#else + memset(rwlock->rfu, 0, PTHRW_RFU_32BIT); +#endif + rwlock->sig = _PTHREAD_RWLOCK_SIG; return(0); } -int -_new_pthread_rwlock_rdlock(pthread_rwlock_t * orwlock) +#if _KSYN_TRACE_ +static void +set_enable(int val) { -#if __DARWIN_UNIX03 - pthread_t self; -#endif /* __DARWIN_UNIX03 */ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t lgenval, ugenval, rw_wc, newval, updateval; - int error = 0, ret; - uint64_t oldval64, newval64; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; + int mib[6]; + size_t needed = 0; + + mib[0] = CTL_KERN; + mib[1] = KERN_KDEBUG; + mib[2] = KERN_KDENABLE; + mib[3] = val; + mib[4] = 0; + mib[5] = 0; + /* best effort to stop the trace */ + (void)sysctl(mib, 4, NULL, &needed, NULL, 0); +} +#endif + +static uint32_t +modbits(uint32_t lgenval, uint32_t updateval, uint32_t savebits) +{ + uint32_t lval = lgenval & PTHRW_BIT_MASK; + uint32_t uval = updateval & PTHRW_BIT_MASK; + uint32_t rval, nlval; + + nlval = (lval | uval) & ~(PTH_RWL_MBIT); - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); - return(error); - } - } else { - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); + /* reconcile bits on the lock with what kernel needs to set */ + if ((uval & PTH_RWL_LBIT) != 0) + nlval &= ~PTH_RWL_KBIT; + else if (((uval & PTH_RWL_KBIT) == 0) && ((lval & PTH_RWL_WBIT) == 0)) + nlval &= ~PTH_RWL_KBIT; + + if (savebits !=0 ) { + if (((savebits & PTH_RWS_WSVBIT) != 0) && ((nlval & PTH_RWL_WBIT) == 0) && + ((nlval & PTH_RWL_EBIT) == 0)) { + if ((nlval & PTH_RWL_LBIT) == 0) + nlval |= (PTH_RWL_WBIT | PTH_RWL_KBIT); + else + nlval |= PTH_RWL_WBIT; + } + if (((savebits & PTH_RWS_YSVBIT) != 0) && ((nlval & PTH_RWL_YBIT) == 0) && + ((nlval & PTH_RWL_EBIT) == 0)) { + nlval |= PTH_RWL_YBIT; + } + if (((savebits & PTH_RWS_USVBIT) != 0) && ((nlval & PTH_RWL_EBIT) == 0)) { + if ((nlval & PTH_RWL_LBIT) == 0) + nlval |= (PTH_RWL_UBIT | PTH_RWL_KBIT); + else + nlval |= PTH_RWL_UBIT; } } + rval = (lgenval & PTHRW_COUNT_MASK) | nlval; + return(rval); +} + + +__private_extern__ void +rwlock_action_onreturn(pthread_rwlock_t * orwlock, uint32_t updateval) +{ + + npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; + uint32_t lcntval, rw_seq, newval = 0, newsval, lval, uval; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + uint64_t oldval64, newval64; + int setbits = 0; + int overlap = 0; + uint32_t savebits = 0; + int isoverlap = 0; + /* TBD: restore U bit */ if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } -loop: - lgenval = *lseqaddr; - ugenval = *useqaddr; - rw_wc = *wcaddr; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_START, (uint32_t)rwlock, lgenval, newval, rw_wc, 0); -#endif - - if (is_rw_lbit_set(lgenval)) - goto gotlock; - if(is_rw_ewubit_clear(lgenval)) - goto gotlock; - -#if __DARWIN_UNIX03 - if (is_rw_ebit_set(lgenval)) { - self = pthread_self(); - if(rwlock->rw_owner == self) { - error = EDEADLK; - goto out; - } + lcntaddr = rwlock->rw_lcntaddr; + seqaddr = rwlock->rw_seqaddr; } -#endif /* __DARWIN_UNIX03 */ - - /* mean Lbit is set and R bit not set; block in kernel */ - newval = (lgenval + PTHRW_INC); - - oldval64 = (((uint64_t)rw_wc) << 32); - oldval64 |= lgenval; - - newval64 = (((uint64_t)(rw_wc + 1)) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) - goto loop; - - /* give writers priority over readers */ - PLOCKSTAT_RW_BLOCK(orwlock, READ_LOCK_PLOCKSTAT); #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lgenval, newval, rw_wc+1, 0); + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_START, updateval, 0, 0, 0, 0); #endif -retry: - updateval = __psynch_rw_rdlock(orwlock, (newval & ~PTHRW_RW_INIT), ugenval, rw_wc, rwlock->rw_flags); - - if (updateval == (uint32_t)-1) { - error = errno; - } else - error = 0; - - if (error == EINTR) - goto retry; - - OSAtomicDecrement32((volatile int32_t *)wcaddr); - - + isoverlap = updateval & PTH_RWL_MBIT; - if (error == 0) { - if ((updateval & PTHRW_RW_HUNLOCK) != 0) { - ret = rwlock_unlock_action_onread(orwlock, (updateval & ~PTHRW_RW_HUNLOCK)); - if (ret != 0) { - LIBC_ABORT("rdlock_unlock handling failed"); - } +loop: + setbits = 0; + lcntval = *lcntaddr; + rw_seq = *seqaddr; + savebits = 0; + + if (isoverlap != 0) { + /* overlap return, just increment and inspect bits */ + setbits = 1; + overlap = 1; + /* set s word, increment by specified value */ + newsval = rw_seq + (updateval & PTHRW_COUNT_MASK); + if ((newsval & PTHRW_RWS_SAVEMASK) != 0) { + savebits = newsval & PTHRW_RWS_SAVEMASK; + newsval &= ~PTHRW_RWS_SAVEMASK; } - PLOCKSTAT_RW_BLOCKED(orwlock, READ_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); - PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); - return(0); } else { - PLOCKSTAT_RW_BLOCKED(orwlock, READ_LOCK_PLOCKSTAT, BLOCK_FAIL_PLOCKSTAT); - goto out; - } - /* Not reached */ - -gotlock: - /* check for max readers */ - ugenval = *useqaddr; - if (rw_diffgenseq(lgenval, ugenval) >= PTHRW_MAX_READERS) { - error = EAGAIN; - goto out; + /* normal return */ + if (is_rws_setunlockinit(rw_seq) != 0) { + setbits = 1; + /* set s word to passed in value */ + newsval = (rw_seq & PTHRW_COUNT_MASK) + (updateval & PTHRW_COUNT_MASK); + if ((rw_seq & PTHRW_RWS_SAVEMASK) != 0) { + savebits = rw_seq & PTHRW_RWS_SAVEMASK; + newsval &= ~PTHRW_RWS_SAVEMASK; + } + } else { + newval = lcntval; + newsval = rw_seq; + } } - - newval = (lgenval + PTHRW_INC); + if (setbits != 0) { + newval = modbits(lcntval, updateval, savebits); #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lgenval, newval, 0); + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_NONE, rw_seq, newsval, 0xeeeeeeee, updateval, 0); + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_NONE, lcntval, newval, 0xeeeeeeee, updateval, 0); #endif + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) == TRUE) { - PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, 0, 0, 0); -#endif - return(0); - } else - goto loop; -out: - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) + goto loop; + /* Check for consistency */ + lval = lcntval & PTHRW_BIT_MASK; + uval = updateval & PTHRW_BIT_MASK; + } + #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_END, rw_seq, newsval, 0xffffffff, 0, 0); #endif - return(error); + return; } - -int -_new_pthread_rwlock_tryrdlock(pthread_rwlock_t * orwlock) +/* returns are not bit shifted */ +__private_extern__ int +rw_diffgenseq(uint32_t x, uint32_t y) { - uint32_t lgenval, newval, ugenval; - int error = 0; - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - /* check for static initialization */ - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); - return(error); - } - } else { - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); + uint32_t lx = (x & PTHRW_COUNT_MASK); + uint32_t ly = (y &PTHRW_COUNT_MASK); + + if (lx > ly) { + return(lx-ly); } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; + return((PTHRW_MAX_READERS - y) + lx + PTHRW_INC); } -loop: - lgenval = *lseqaddr; - if (is_rw_lbit_set(lgenval)) - goto gotlock; - if (is_rw_ewubit_clear(lgenval)) - goto gotlock; - - - error = EBUSY; - goto out; - -gotlock: - ugenval = *useqaddr; - if (rw_diffgenseq(lgenval, ugenval) >= PTHRW_MAX_READERS) { - error = EAGAIN; - goto out; - } - - newval = (lgenval + PTHRW_INC); - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) == TRUE) { - PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); - return(0); - } else - goto loop; -out: - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); - return(error); } #ifdef NOTYET -/*****************************************************************************/ -/* TBD need to add towards MAX_READERS */ +/********************************************************** */ +static int pthread_rwlock_upgrade_internal(pthread_rwlock_t * orwlock, int trylock); + int -_new_pthread_rwlock_longrdlock_np(pthread_rwlock_t * orwlock) +pthread_rwlock_longrdlock_np(pthread_rwlock_t * orwlock) { pthread_t self; - uint32_t lgenval, ugenval, rw_wc, newval, updateval; - int error = 0, ret; + uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; + int error = 0, retry_count = 0; npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; uint64_t oldval64, newval64; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + uint64_t myid = 0; if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + LOCK(rwlock->lock); if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); return(error); } - } else { + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL); return(EINVAL); } + UNLOCK(rwlock->lock); } if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } loop: + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; - lgenval = *lseqaddr; - ugenval = *useqaddr; - rw_wc = *wcaddr; - - if (is_rw_ewuybit_clear(lgenval)) + if (can_rwl_longreadinuser(lcntval)) goto gotlock; - - /* if w bit is set ensure there is no deadlock */ - if (is_rw_ebit_set(lgenval)) { + +#if __DARWIN_UNIX03 + if (is_rwl_ebit_set(lcntval)) { self = pthread_self(); if(rwlock->rw_owner == self) { error = EDEADLK; goto out; } } +#endif /* __DARWIN_UNIX03 */ - newval = (lgenval + PTHRW_INC); + /* need to block in kernel */ + newval = (lcntval + PTHRW_INC); + + newsval = rw_seq; + if (is_rws_setseq(rw_seq)) { + newsval &= PTHRW_SW_Reset_BIT_MASK; + newsval |= (newval & PTHRW_COUNT_MASK); + } + /* update lock seq and block in kernel */ - oldval64 = (((uint64_t)rw_wc) << 32); - oldval64 |= lgenval; + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; - newval64 = (((uint64_t)(rw_wc + 1)) << 32); + newval64 = (((uint64_t)(newsval)) << 32); newval64 |= newval; - if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) goto loop; kblock: - updateval = __psynch_rw_longrdlock(orwlock, newval, ugenval, (rw_wc+1), rwlock->rw_flags); + updateval = __psynch_rw_longrdlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags); if (updateval == (uint32_t)-1) { error = errno; } else @@ -595,33 +517,56 @@ kblock: if (error == EINTR) goto kblock; - OSAtomicDecrement32((volatile int32_t *)wcaddr); if (error == 0) { - - if ((updateval & PTHRW_RW_HUNLOCK) != 0) { - ret = rwlock_unlock_action_onread(orwlock, (updateval & ~PTHRW_RW_HUNLOCK)); - if (ret != 0) { - LIBC_ABORT("rdlock_unlock handling failed"); - } - } - - error = FALSE; - while (error == FALSE) { - lgenval = *lseqaddr; - newval = lgenval | PTHRW_LBIT; - error = OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr); + rwlock_action_onreturn(orwlock, updateval); + if ( is_rwl_lbit_clear(updateval)) { +#if _KSYN_TRACE_ + set_enable(2); +#endif /* _KSYN_TRACE_ */ + (void)pthread_threadid_np(pthread_self(), &myid); + LIBC_ABORT("yieldwrlock from kernel without EBit %x: tid %x\n", updateval, (uint32_t)myid); + /* kernel cannot wakeup without granting E bit */ } - goto successout; - } else + } else { +#if _KSYN_TRACE_ + set_enable(2); +#endif /* _KSYN_TRACE_ */ + (void)pthread_threadid_np(pthread_self(), &myid); + LIBC_ABORT("yieldwrlock from kernel with unknown error %x: tid %x\n", updateval, (uint32_t)myid); goto out; - goto successout; + } gotlock: - newval = ((lgenval + PTHRW_INC)| PTHRW_LBIT); - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) != TRUE) - goto loop; + if (rw_diffgenseq(lcntval, ucntval) >= PTHRW_MAX_READERS) { + /* since ucntval may be newer, just redo */ + retry_count++; + if (retry_count > 1024) { + +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_TOOMANY | DBG_FUNC_NONE, (uint32_t)rwlock, 0XEEEEEEEE, lcntval, ucntval, 0); +#endif + error = EAGAIN; + goto out; + } else { + sched_yield(); + goto loop; + } + } + + /* Need to update L and S word */ + newval = (lcntval + PTHRW_INC) | PTH_RWL_LBIT; + newsval = (rw_seq + PTHRW_INC); + + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) + goto loop; + successout: PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); return(0); @@ -629,1981 +574,1307 @@ out: PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); return(error); } -/**************************************************************/ -#endif /* NOTYET */ int -_new_pthread_rwlock_trywrlock(pthread_rwlock_t * orwlock) +pthread_rwlock_yieldwrlock_np(pthread_rwlock_t * orwlock) { + uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; int error = 0; - uint32_t lgenval, newval; #if __DARWIN_UNIX03 pthread_t self = pthread_self(); #endif /* __DARWIN_UNIX03 */ npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; + uint64_t oldval64, newval64; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + uint64_t myid = 0; if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - /* check for static initialization */ + LOCK(rwlock->lock); if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); return(error); } - } else { + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); return(EINVAL); } + UNLOCK(rwlock->lock); } - + if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } - lgenval = PTHRW_RW_INIT; - newval = PTHRW_RW_INIT | PTHRW_INC | PTHRW_EBIT; - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) == TRUE) { -#if __DARWIN_UNIX03 - rwlock->rw_owner = self; -#endif /* __DARWIN_UNIX03 */ - PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT); - return(0); - } - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EBUSY); - return(EBUSY); -} +loop: + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; -int -_new_pthread_rwlock_wrlock(pthread_rwlock_t * orwlock) -{ - uint32_t lgenval, newval, ugenval, updateval, rw_wc; - int error = 0; -#if __DARWIN_UNIX03 - pthread_t self = pthread_self(); -#endif /* __DARWIN_UNIX03 */ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint64_t oldval64, newval64; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - /* check for static initialization */ - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); - return(error); - } - } else { - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } - } - - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); - } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0); -#endif -loop: - lgenval = *lseqaddr; - ugenval = *useqaddr; - rw_wc = *wcaddr; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lgenval, ugenval, rw_wc, 0); -#endif #if __DARWIN_UNIX03 - if (is_rw_ebit_set(lgenval)) { - if(rwlock->rw_owner == self) { + if (is_rwl_ebit_set(lcntval)) { + if (rwlock->rw_owner == self) { error = EDEADLK; goto out; } } #endif /* __DARWIN_UNIX03 */ - if (lgenval == PTHRW_RW_INIT) { - newval = ( PTHRW_RW_INIT | PTHRW_INC | PTHRW_EBIT); - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) == TRUE) { + if (lcntval == PTHRW_RWL_INIT) { + /* if we can acquire set L and S word */ + lcntval = PTHRW_RWL_INIT; + newval = PTHRW_RWL_INIT | PTHRW_INC | PTH_RWL_KBIT| PTH_RWL_EBIT; + newsval = rw_seq + PTHRW_INC; + + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) == TRUE) { goto gotit; - } + } else + goto loop; } - newval = (lgenval + PTHRW_INC) | PTHRW_WBIT | PTHRW_SHADOW_W; + newval = (lcntval + PTHRW_INC)| PTH_RWL_YBIT; + + newsval = rw_seq; + if (is_rws_setseq(rw_seq)) { + newsval &= PTHRW_SW_Reset_BIT_MASK; + newsval |= (newval & PTHRW_COUNT_MASK); + } - /* update lock seq and block in kernel */ - oldval64 = (((uint64_t)rw_wc) << 32); - oldval64 |= lgenval; + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; - newval64 = (((uint64_t)(rw_wc + 1)) << 32); + newval64 = (((uint64_t)(newsval)) << 32); newval64 |= newval; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lgenval, newval, 0); -#endif - if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) goto loop; - -retry: + PLOCKSTAT_RW_BLOCK(orwlock, WRITE_LOCK_PLOCKSTAT); -retry1: - updateval = __psynch_rw_wrlock(orwlock, newval, ugenval, (rw_wc+1), rwlock->rw_flags); +retry: + updateval = __psynch_rw_yieldwrlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags); if (updateval == (uint32_t)-1) { error = errno; } else error = 0; - if (error == EINTR) { - goto retry1; - } + if (error == EINTR) + goto retry; + -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x33333333, newval, updateval, 0); -#endif PLOCKSTAT_RW_BLOCKED(orwlock, WRITE_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); if (error != 0) { - OSAtomicDecrement32((volatile int32_t *)wcaddr); - goto out; - } - - if (is_rw_ebit_clear(updateval)) { - /* kernel cannot wakeup without granting E bit */ - abort(); +#if _KSYN_TRACE_ + set_enable(2); +#endif /* _KSYN_TRACE_ */ + (void)pthread_threadid_np(pthread_self(), &myid); + LIBC_ABORT("yieldwrlock from kernel with unknown error %x: tid %x\n", updateval, (uint32_t)myid); } - error = rwlock_exclusive_lockreturn(orwlock, updateval); - if (error == EAGAIN) - goto retry; - OSAtomicDecrement32((volatile int32_t *)wcaddr); +out: if (error == 0) { gotit: + rwlock_action_onreturn(orwlock, updateval); + if ( is_rwl_ebit_clear(updateval)) { +#if _KSYN_TRACE_ + set_enable(2); +#endif /* _KSYN_TRACE_ */ + (void)pthread_threadid_np(pthread_self(), &myid); + LIBC_ABORT("yieldwrlock from kernel without EBit %x: tid %x\n", updateval, (uint32_t)myid); + } #if __DARWIN_UNIX03 rwlock->rw_owner = self; #endif /* __DARWIN_UNIX03 */ PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT); -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); -#endif return(0); - } -out: - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); -#endif - return(error); + } else { + PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); + return(error); + } } - - -#ifdef NOTYET -/*****************************************************************************/ int -_new_pthread_rwlock_yieldwrlock_np(pthread_rwlock_t * orwlock) +pthread_rwlock_downgrade_np(pthread_rwlock_t * orwlock) { - uint32_t lgenval, newval, ugenval, updateval, rw_wc; - int error = 0; + uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; + int error = 0, haswbit = 0, hasubit = 0, hasybit = 0; #if __DARWIN_UNIX03 pthread_t self = pthread_self(); #endif /* __DARWIN_UNIX03 */ npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; uint64_t oldval64, newval64; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + uint64_t myid = 0; if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - /* check for static initialization */ + LOCK(rwlock->lock); if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); return(error); } - } else { - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL); return(EINVAL); } + UNLOCK(rwlock->lock); } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; + } + +loop: + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; + + + /* if not holding exclusive lock, return */ + if ((is_rwl_ebit_set(lcntval )== 0) || (rwlock->rw_owner != self)) { + return(EINVAL); } - lgenval = *lseqaddr; - ugenval = *useqaddr; - rw_wc = *wcaddr; + /* no other waiters and be granted in user space? ? */ + if ((lcntval & PTHRW_COUNT_MASK) == (ucntval + PTHRW_INC)) { +#if 0 + /* should have no write waiters pending */ + if (is_rwl_wbit_set(lcntval) != 0) { +#if _KSYN_TRACE_ + set_enable(2); +#endif /* _KSYN_TRACE_ */ + (void)pthread_threadid_np(pthread_self(), &myid); + LIBC_ABORT("downgrade in user mode but W bit set %x: tid %x\n", lcntval, (uint32_t)myid); + } +#endif + /* preserve count and remove ke bits */ + newval = lcntval & ~(PTH_RWL_EBIT | PTH_RWL_KBIT); + /* if we can acquire set L and S word */ + newsval = rw_seq; + + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) == TRUE) { #if __DARWIN_UNIX03 - if (is_rw_ebit_set(lgenval)) { - if (rwlock->rw_owner == self) { - error = EDEADLK; - goto out; + rwlock->rw_owner = (pthread_t)0; +#endif /* __DARWIN_UNIX03 */ + return(0); + } else + goto loop; + } else { + + haswbit = lcntval & PTH_RWL_WBIT; + hasubit = lcntval & PTH_RWL_UBIT; + hasybit = lcntval & PTH_RWL_YBIT; + + /* reset all bits and set k */ + newval = (lcntval & PTHRW_COUNT_MASK) | PTH_RWL_KBIT; + /* set I bit on S word */ + newsval = rw_seq | PTH_RWS_IBIT; + if (haswbit != 0) + newsval |= PTH_RWS_WSVBIT; + if (hasubit != 0) + newsval |= PTH_RWS_USVBIT; + if (hasybit != 0) + newsval |= PTH_RWS_YSVBIT; + + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) + goto loop; + +#if __DARWIN_UNIX03 + rwlock->rw_owner = 0; +#endif /* __DARWIN_UNIX03 */ + +retry: + updateval = __psynch_rw_downgrade(orwlock, newval, ucntval, newsval, rwlock->rw_flags); + if (updateval == (uint32_t)-1) { + error = errno; + } else + error = 0; + + /* TBD: what to do with the error, EINTR ?? */ + if (error == EINTR) + goto retry; + + if (error == 0) { + rwlock_action_onreturn(orwlock, updateval); + return(0); + } else { +#if _KSYN_TRACE_ + set_enable(1); +#endif /* _KSYN_TRACE_ */ + (void)pthread_threadid_np(pthread_self(), &myid); + LIBC_ABORT("downgrade from kernel with unknown error %x with tid %x\n", updateval, (uint32_t)myid); } + /* Not reached */ } + return(EINVAL); +} + +int +pthread_rwlock_upgrade_np(pthread_rwlock_t * orwlock) +{ + return(pthread_rwlock_upgrade_internal(orwlock, 0)); +} + +int +pthread_rwlock_tryupgrade_np(pthread_rwlock_t *orwlock) +{ + return(pthread_rwlock_upgrade_internal(orwlock, 1)); +} + +static int +pthread_rwlock_upgrade_internal(pthread_rwlock_t * orwlock, int trylock) +{ + uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; + int error = 0, flags ; +#if __DARWIN_UNIX03 + pthread_t self = pthread_self(); #endif /* __DARWIN_UNIX03 */ + npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; + uint64_t oldval64, newval64; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + uint64_t myid = 0; - if (lgenval == PTHRW_RW_INIT) { - newval = PTHRW_RW_INIT | PTHRW_INC | PTHRW_EBIT; - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) == TRUE) { - goto gotit; + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + /* check for static initialization */ + LOCK(rwlock->lock); + if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); + return(error); + } + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); + return(EINVAL); } + UNLOCK(rwlock->lock); + } + if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); + } else { + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; + } + +loop: + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; + + if (is_rwl_eubit_set(lcntval) !=0) { + return(EBUSY); } - newval = (lgenval + PTHRW_INC); - if ((lgenval & PTHRW_WBIT) == 0) - newval |= PTHRW_YBIT; + /* set U and K bit and go to kernel */ + newval = (lcntval | (PTH_RWL_UBIT | PTH_RWL_KBIT)); + newsval = rw_seq; +#if 0 + if (is_rws_setseq(rw_seq)) { + newsval &= PTHRW_SW_Reset_BIT_MASK; + newsval |= (newval & PTHRW_COUNT_MASK); + } +#endif + + /* update lock seq and block in kernel */ - oldval64 = (((uint64_t)rw_wc) << 32); - oldval64 |= lgenval; + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; - newval64 = (((uint64_t)(rw_wc + 1)) << 32); + newval64 = (((uint64_t)(newsval)) << 32); newval64 |= newval; - if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) - PLOCKSTAT_RW_BLOCK(orwlock, WRITE_LOCK_PLOCKSTAT); + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) + goto loop; + flags = rwlock->rw_flags; + if (trylock != 0) { + flags |= _PTHREAD_RWLOCK_UPGRADE_TRY; + } retry: - updateval = __psynch_rw_yieldwrlock(orwlock, newval, ugenval, (rw_wc+1), rwlock->rw_flags); + updateval = __psynch_rw_upgrade(orwlock, newval, ucntval, newsval, rwlock->rw_flags); if (updateval == (uint32_t)-1) { error = errno; } else error = 0; - + if (error == EINTR) goto retry; - - - PLOCKSTAT_RW_BLOCKED(orwlock, WRITE_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); - if (error != 0) { - OSAtomicDecrement32((volatile int32_t *)wcaddr); - goto out; - } - - if (is_rw_ebit_clear(updateval)) { - /* kernel cannot wakeup without granting E bit */ - abort(); - } - - error = rwlock_exclusive_lockreturn(orwlock, updateval); - if (error == EAGAIN) - goto retry; - - OSAtomicDecrement32((volatile int32_t *)wcaddr); + + if (error == 0) { - gotit: + rwlock_action_onreturn(orwlock, updateval); + if ( is_rwl_ebit_clear(updateval)) { +#if _KSYN_TRACE_ + set_enable(2); +#endif /* _KSYN_TRACE_ */ + (void)pthread_threadid_np(pthread_self(), &myid); + LIBC_ABORT("upgrade from kernel without EBit %x: tid %x\n", updateval, (uint32_t)myid); + } #if __DARWIN_UNIX03 rwlock->rw_owner = self; #endif /* __DARWIN_UNIX03 */ - PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT); return(0); } else { - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); + if (trylock != 0) { + return (EBUSY); + } } - return(error); -out: - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); - return(error); + + return(error); } -/**************************************************************/ -#endif /* NOTYET */ -int -_new_pthread_rwlock_unlock(pthread_rwlock_t * orwlock) +/* Returns true if the rwlock is held for reading by any thread or held for writing by the current thread */ +int +pthread_rwlock_held_np(pthread_rwlock_t * orwlock) { - uint32_t lgenval, ugenval, rw_wc, newval, nlval, ulval; + uint32_t lcntval, ucntval, rw_seq; int error = 0; - int wrlock = 0, kern_trans; - uint32_t updateval, bits, newbits; - uint32_t isupgrade = 0; npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - int retry_count = 0, retry_count1 = 0; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; - pthread_t self = NULL; - uint64_t threadid = 0; - int ubitchanged = 0, initbitset = 0, num; - + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - /* check for static initialization */ + LOCK(rwlock->lock); if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { - PLOCKSTAT_RW_ERROR(orwlock, wrlock, error); - return(error); + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); + return(0); } - } else { - PLOCKSTAT_RW_ERROR(orwlock, wrlock, EINVAL); - return(EINVAL); + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); + return(-1); } + UNLOCK(rwlock->lock); } if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } + + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0); -#endif -loop: - lgenval = *lseqaddr; - ugenval = *useqaddr; - rw_wc = *wcaddr; + if ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK)) + return(0); + return(1); +} -loop1: - if ((lgenval & PTHRW_COUNT_MASK) == (ugenval & PTHRW_COUNT_MASK)) { - retry_count++; - sched_yield(); - if (retry_count < 1024) - goto loop; - error = EINVAL; - goto out; - } - retry_count = 0; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lgenval, ugenval, 0); - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, rw_wc, 0, 0); -#endif - if (is_rw_ebit_set(lgenval)) { - wrlock = 1; -#if __DARWIN_UNIX03 - rwlock->rw_owner = (pthread_t)0; -#endif /* __DARWIN_UNIX03 */ - } +/* Returns true if the rwlock is held for reading by any thread */ +int +pthread_rwlock_rdheld_np(pthread_rwlock_t * orwlock) +{ + uint32_t lcntval, ucntval, rw_seq; + int error = 0; + npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - /* last unlock ? */ - if((lgenval & PTHRW_COUNT_MASK) == (ugenval + PTHRW_INC)) { - if (OSAtomicCompareAndSwap32(ugenval, 0, (volatile int32_t *)useqaddr) != TRUE) { - goto loop; - } - if (OSAtomicCompareAndSwap32(lgenval, PTHRW_RW_INIT, (volatile int32_t *)lseqaddr) != TRUE) { - if (OSAtomicCompareAndSwap32(0, ugenval, (volatile int32_t *)useqaddr) != TRUE) { -lp1: - ulval = *useqaddr; - nlval = ugenval+ulval; - if (OSAtomicCompareAndSwap32(ulval, nlval, (volatile int32_t *)useqaddr) != TRUE) - goto lp1; + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + LOCK(rwlock->lock); + if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); + return(0); } - - goto loop; + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); + return(-1); } - - goto succout; - } - - /* do we need kernel trans? */ - -lp11: - nlval = lgenval & PTHRW_COUNT_MASK; - if (ubitchanged == 0) - ulval = (ugenval + PTHRW_INC) & PTHRW_COUNT_MASK; - else - ulval = ugenval & PTHRW_COUNT_MASK; - - num = rw_diffgenseq(nlval, ulval); - kern_trans = ( num == (rw_wc << PTHRW_COUNT_SHIFT)); - /* if three more waiters than needed for kernel tras*/ - if ((ubitchanged ==0) && (kern_trans == 0) && (num < (rw_wc << PTHRW_COUNT_SHIFT))) { - retry_count1++; - sched_yield(); - if (retry_count1 < 1024) - goto loop; - } - retry_count1 = 0; - - if (ubitchanged == 0) { - if (OSAtomicCompareAndSwap32(ugenval, ugenval+PTHRW_INC, (volatile int32_t *)useqaddr) != TRUE) - goto loop; - ubitchanged = 1; + UNLOCK(rwlock->lock); } - if (kern_trans == 0) { - goto succout; - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 1, ugenval+PTHRW_INC, 0); -#endif - initbitset = 0; - bits = lgenval & PTHRW_BIT_MASK; - newbits = bits; - /* if this is first unlock to kernel, notify kernel of init status */ - if ((bits & PTHRW_RW_INIT) != 0) { - /* reset the initbit if present */ - newbits &= ~PTHRW_RW_INIT; - initbitset = PTHRW_RW_INIT; - } - if (((bits & PTHRW_EBIT) != 0) && ((bits & PTHRW_WBIT) == 0)) { - /* reset E bit is no U bit is set */ - newbits &= ~PTHRW_EBIT; - } - /* clear shadow bit, as W is going to be sent to kernel */ - if ((bits & PTHRW_WBIT) != 0) { - newbits &= ~PTHRW_SHADOW_W; - } - - /* reset L bit */ - if (bits & PTHRW_LBIT) - newbits &= ~PTHRW_LBIT; - if (bits & PTHRW_UBIT) { - /* reset U and set E bit */ - newbits &= ~PTHRW_LBIT; - newbits |= PTHRW_EBIT; - isupgrade = PTHRW_UBIT; - } - - /* updates bits on the L */ - newval = (lgenval & PTHRW_COUNT_MASK) | newbits; - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) != TRUE) { - /* reread the value */ - lgenval = *lseqaddr; - ugenval = *useqaddr; - rw_wc = *wcaddr; - /* since lgen changed check for trans again */ - goto lp11; - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 2, newval, 0); -#endif - - /* send upgrade bit to kernel */ - newval |= (isupgrade | initbitset); - updateval = __psynch_rw_unlock(orwlock, newval, ugenval+PTHRW_INC, rw_wc, rwlock->rw_flags); - if (updateval == (uint32_t)-1) { - error = errno; - } else - error = 0; - - if(error != 0) { - /* not sure what is the scenario */ - if(error != EINTR) - goto out; - } - - /* - * If the unlock is spurious return. Also if the - * exclusive lock is being granted, let that thread - * manage the status bits, otherwise stale bits exclusive - * bit can be set, if that thread had already unlocked. - */ - if ((updateval & (PTHRW_RW_SPURIOUS | PTHRW_EBIT)) != 0) { - goto succout; + if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); + } else { + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } -lp2: - lgenval = *lseqaddr; - + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 3, lgenval, 0); -#endif - /* if the kernel antcipated seq and one on the lock are same, set the one from kernel */ - if ((lgenval & PTHRW_COUNT_MASK) == (updateval & PTHRW_COUNT_MASK)) { - if (OSAtomicCompareAndSwap32(lgenval, updateval, (volatile int32_t *)lseqaddr) != TRUE) - goto lp2; - goto succout; - } - - /* state bits are same? */ - if ((lgenval & PTHRW_BIT_MASK) == (updateval & PTHRW_BIT_MASK)) { - /* nothing to do */ - goto succout; + if ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK)) + return(0); + + if (is_rwl_ebit_set(lcntval) !=0) { + return(0); } - - newval = ((lgenval & PTHRW_UN_BIT_MASK) << PTHRW_COUNT_SHIFT) | (updateval & PTHRW_BIT_MASK); - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 4, newval, 0); -#endif - /* high bits are state on the lock; lowbits are one kernel need to set */ - switch (newval) { - /* W States */ - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action_k(orwlock, lgenval, updateval); - //goto ktrans; - } - break; - - - /* L states */ - case ((PTHRW_LBIT << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - - /* Y states */ - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action_k(orwlock, lgenval, updateval); - //goto ktrans; - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action_k(orwlock, lgenval, updateval); - //goto ktrans; - } - break; - - /* YU states */ - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action_k(orwlock, lgenval, updateval); - //goto ktrans; - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action_k(orwlock, lgenval, updateval); - //goto ktrans; - } - break; - - /* E states */ - case ((PTHRW_EBIT << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - - /* WE states */ - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - - /* WL states */ - case (((PTHRW_WBIT | PTHRW_LBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_LBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_LBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - - default: - /* illegal states */ - self = pthread_self(); - threadid = self->thread_id; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 6, lgenval, 0); - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 7, updateval, 0); -#endif - LIBC_ABORT("incorect state on return 0x%x: lgenval 0x%x, updateval 0x%x; threadid (0x%x)\n", newval, lgenval, updateval, (uint32_t)threadid); - - }; - - if (error != 0) - goto lp2; -succout: - PLOCKSTAT_RW_RELEASE(orwlock, wrlock); -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); -#endif - return(0); -out: - PLOCKSTAT_RW_ERROR(orwlock, wrlock, error); -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); -#endif - return(error); + return(1); } -#ifdef NOTYET -/*****************************************************************************/ -int -_new_pthread_rwlock_downgrade_np(pthread_rwlock_t * orwlock) +/* Returns true if the rwlock is held for writing by the current thread */ +int +pthread_rwlock_wrheld_np(pthread_rwlock_t * orwlock) { - uint32_t lgenval, newval, ugenval, rw_wc; - int error = 0; + uint32_t lcntval, ucntval, rw_seq; pthread_t self = pthread_self(); npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; - + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + int error = 0; if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - /* check for static initialization */ + LOCK(rwlock->lock); if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { - return(error); + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); + return(0); } - } else { - return(EINVAL); + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); + return(-1); } + UNLOCK(rwlock->lock); } + if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } - -loop: - lgenval = *lseqaddr; - ugenval = *useqaddr; - rw_wc = *wcaddr; - - if ((is_rw_ebit_set(lgenval )) && (rwlock->rw_owner != self)) { - return(EINVAL); + + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; + + if ((is_rwl_ebit_set(lcntval)) && (rwlock->rw_owner == self)) { + return(1); } - - if ((lgenval & PTHRW_COUNT_MASK) != ugenval) { - - newval = lgenval & ~PTHRW_EBIT; - - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) == TRUE) { + return(0); +} +/******************************************************/ +#endif /* NOTYET */ + + +#endif /* !BUILDING_VARIANT ] */ + +int +pthread_rwlock_destroy(pthread_rwlock_t *orwlock) +{ + npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; #if __DARWIN_UNIX03 - rwlock->rw_owner = 0; + uint32_t rw_lcnt, rw_ucnt; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; #endif /* __DARWIN_UNIX03 */ - if (rw_wc != 0) { - error = __psynch_rw_downgrade(orwlock, newval, ugenval, rw_wc, rwlock->rw_flags); - - } - return(0); + + if (rwlock->sig != _PTHREAD_RWLOCK_SIG && rwlock->sig != _PTHREAD_RWLOCK_SIG_init) + return(EINVAL); + if (rwlock->sig == _PTHREAD_RWLOCK_SIG) { +#if __DARWIN_UNIX03 + if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); } else { - goto loop; + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } - } - return(EINVAL); + + rw_lcnt = *lcntaddr; + rw_ucnt = *ucntaddr; + + if((rw_lcnt & PTHRW_COUNT_MASK) != rw_ucnt) + return(EBUSY); + +#endif /* __DARWIN_UNIX03 */ + //bzero(rwlock, sizeof(npthread_rwlock_t)); + rwlock->sig = _PTHREAD_NO_SIG; + return(0); + } else if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { + rwlock->sig = _PTHREAD_NO_SIG; + return(0); + } else + return(EINVAL); } int -_new_pthread_rwlock_upgrade_np(pthread_rwlock_t * orwlock) +pthread_rwlock_init(pthread_rwlock_t * orwlock, const pthread_rwlockattr_t *attr) { - uint32_t lgenval, newval, ugenval, ulval, updateval, rw_wc; - int error = 0, kern_trans; - pthread_t self = pthread_self(); npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint64_t oldval64, newval64; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - /* check for static initialization */ - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { - return(error); - } - } else { - return(EINVAL); - } - } - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); - } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } -loop: - lgenval = *lseqaddr; - ugenval = *useqaddr; - rw_wc = *wcaddr; +#if __DARWIN_UNIX03 + uint32_t rw_lcnt, rw_ucnt; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; +#endif /* __DARWIN_UNIX03 */ - if (is_rw_uebit_set(lgenval)) { +#if __DARWIN_UNIX03 + if (attr && (attr->sig != _PTHREAD_RWLOCK_ATTR_SIG)) { return(EINVAL); - } - if ((lgenval & PTHRW_COUNT_MASK) == ugenval) - return(EINVAL); - - if (lgenval > ugenval) - ulval = (lgenval & PTHRW_COUNT_MASK) - (ugenval & PTHRW_COUNT_MASK); - else - ulval = (ugenval & PTHRW_COUNT_MASK) - (lgenval & PTHRW_COUNT_MASK); - - - newval = lgenval | PTHRW_UBIT; - - kern_trans = 1; - if (rw_wc != 0) { - if (ulval == ((rw_wc - 1) << PTHRW_COUNT_SHIFT)) - kern_trans = 0; - } else if (ulval == 1) - kern_trans = 0; - - if (kern_trans == 0) { - newval = ((lgenval | PTHRW_EBIT) & ~PTHRW_LBIT); - } else { - newval = lgenval | PTHRW_UBIT; - } - if (kern_trans == 0) { - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) != TRUE) - goto loop; - - } else { - newval = (lgenval + PTHRW_INC); - - oldval64 = (((uint64_t)rw_wc) << 32); - oldval64 |= lgenval; - - newval64 = (((uint64_t)(rw_wc + 1)) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) - goto loop; - /* kern_trans == 1 */ - retry: - updateval = __psynch_rw_upgrade(orwlock, newval, ugenval, rw_wc+1, rwlock->rw_flags); - if (updateval == (uint32_t)-1) { - error = errno; - } else - error = 0; - - if (error == EINTR) - goto retry; - - if (error != 0) { - OSAtomicDecrement32((volatile int32_t *)wcaddr); - goto out; - } - - if (is_rw_ebit_set(updateval)) { - /* kernel cannot wakeup without granting E bit */ - abort(); + if (rwlock->sig == _PTHREAD_RWLOCK_SIG) { + if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); + } else { + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } - error = rwlock_exclusive_lockreturn(orwlock, updateval); - if (error == EAGAIN) - goto retry; + rw_lcnt = *lcntaddr; + rw_ucnt = *ucntaddr; - OSAtomicDecrement32((volatile int32_t *)wcaddr); + if ((rw_lcnt & PTHRW_COUNT_MASK) != rw_ucnt) + return(EBUSY); } - if (error == 0) { - rwlock->rw_owner = self; - PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT); - return(0); - } +#endif + LOCK_INIT(rwlock->lock); + return(__pthread_rwlock_init(orwlock, attr)); -out: - return(error); } int -pthread_rwlock_tryupgrade_np(pthread_rwlock_t *orwlock) +pthread_rwlock_rdlock(pthread_rwlock_t * orwlock) { - pthread_t self = pthread_self(); - uint32_t lgenval, newval, ugenval, ulval, rw_wc; - int error = 0, kern_trans; +#if __DARWIN_UNIX03 + pthread_t self; +#endif /* __DARWIN_UNIX03 */ npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; + uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; + int error = 0, retry_count = 0; + uint64_t oldval64, newval64; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + uint64_t myid = 0; if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + LOCK(rwlock->lock); if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); return(error); } - } else { + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL); return(EINVAL); } + UNLOCK(rwlock->lock); } + if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0); +#endif loop: - lgenval = *lseqaddr; - ugenval = *useqaddr; - rw_wc = *wcaddr; + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lcntval, (ucntval | 0xee), rw_seq, 0); +#endif - if (is_rw_uebit_set(lgenval)) { - return(EBUSY); + /* if l bit is on or u and k bit is clear, acquire lock in userland */ + if (can_rwl_readinuser(lcntval)) + goto gotlock; + +#if __DARWIN_UNIX03 + if (is_rwl_ebit_set(lcntval)) { + self = pthread_self(); + if(rwlock->rw_owner == self) { + error = EDEADLK; + goto out; + } } +#endif /* __DARWIN_UNIX03 */ - if ((lgenval & PTHRW_COUNT_MASK) == ugenval) - return(EINVAL); + + /* Need to block in kernel , remove Rbit */ + newval = (lcntval + PTHRW_INC) & PTH_RWLOCK_RESET_RBIT; - if (lgenval > ugenval) - ulval = (lgenval & PTHRW_COUNT_MASK) - (ugenval & PTHRW_COUNT_MASK); - else - ulval = (ugenval & PTHRW_COUNT_MASK) - (lgenval & PTHRW_COUNT_MASK); + newsval = rw_seq; + if (is_rws_setseq(rw_seq)) { + newsval &= PTHRW_SW_Reset_BIT_MASK; + newsval |= (newval & PTHRW_COUNT_MASK); + } + + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; - newval = lgenval | PTHRW_UBIT; + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) + goto loop; + + /* give writers priority over readers */ + PLOCKSTAT_RW_BLOCK(orwlock, READ_LOCK_PLOCKSTAT); + +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lcntval, newval, newsval, 0); +#endif + +retry: + updateval = __psynch_rw_rdlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags); - kern_trans = 1; - if (rw_wc != 0) { - /* there is only one reader thread */ - if (ulval == (rw_wc - 1)) - kern_trans = 0; - } else if (ulval == 1) - kern_trans = 0; + if (updateval == (uint32_t)-1) { + error = errno; + } else + error = 0; - if (kern_trans == 0) { - newval = (lgenval | PTHRW_EBIT) & ~PTHRW_LBIT; - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) != TRUE) - goto loop; - - rwlock->rw_owner = self; - PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT); - return(0); - } - return(EBUSY); -} + if (error == EINTR) + goto retry; -/* Returns true if the rwlock is held for reading by any thread or held for writing by the current thread */ -int -pthread_rwlock_held_np(pthread_rwlock_t * orwlock) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t lgenval, ugenval; - int error = 0; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { - return(0); - } - } else { - return(-1); - } - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); - } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } - - lgenval = *lseqaddr; - ugenval = *useqaddr; - - if ((lgenval & PTHRW_COUNT_MASK) == (ugenval & PTHRW_COUNT_MASK)) + if (error == 0) { + rwlock_action_onreturn(orwlock, updateval); + PLOCKSTAT_RW_BLOCKED(orwlock, READ_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); + PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); return(0); - - return(1); -} - -/* Returns true if the rwlock is held for reading by any thread */ -int -pthread_rwlock_rdheld_np(pthread_rwlock_t * orwlock) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t lgenval; - int error = 0; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { - return(0); - } - } else { - return(-1); - } - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } - - lgenval = *lseqaddr; - - if (is_rw_ebit_set(lgenval)) { - return(0); + PLOCKSTAT_RW_BLOCKED(orwlock, READ_LOCK_PLOCKSTAT, BLOCK_FAIL_PLOCKSTAT); +#if _KSYN_TRACE_ + set_enable(1); +#endif /* _KSYN_TRACE_ */ + (void)pthread_threadid_np(pthread_self(), &myid); + LIBC_ABORT("rdlock from kernel with unknown error %x with tid %x\n", updateval, (uint32_t)myid); + goto out; } - return(0); -} - -/* Returns true if the rwlock is held for writing by the current thread */ -int -pthread_rwlock_wrheld_np(pthread_rwlock_t * orwlock) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - pthread_t self; - uint32_t lgenval; - int error = 0; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; + /* Not reached */ - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = pthread_rwlock_init(orwlock, NULL)) != 0) { - return(0); - } +gotlock: + if (rw_diffgenseq(lcntval, ucntval) >= PTHRW_MAX_READERS) { + /* since ucntval may be newer, just redo */ + retry_count++; + if (retry_count > 1024) { + +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_TOOMANY | DBG_FUNC_NONE, (uint32_t)rwlock, 0XEEEEEEEE, lcntval, ucntval, 0); +#endif + error = EAGAIN; + goto out; } else { - return(-1); + sched_yield(); + goto loop; } } - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); - } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } - - self = pthread_self(); - - lgenval = *lseqaddr; - if ((is_rw_ebit_set(lgenval)) && (rwlock->rw_owner == self)) { - return(1); - } - return(0); -} -/**************************************************************/ -#endif /* NOTYET */ - -static int -rwlock_unlock_action_onread(pthread_rwlock_t * orwlock, uint32_t updateval) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - int error = 0; - uint32_t lgenval, newval; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; - pthread_t self; - uint64_t threadid; - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); - } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } - - lgenval = *lseqaddr; + /* Need to update L (remove R bit) and S word */ + newval = (lcntval + PTHRW_INC) & PTH_RWLOCK_RESET_RBIT; + newsval = (rw_seq + PTHRW_INC); -lp2: - lgenval = *lseqaddr; + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) + goto loop; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 3, lgenval, 0); -#endif - /* if the kernel antcipated seq and one on the lock are same, set the one from kernel */ - if ((lgenval & PTHRW_COUNT_MASK) == (updateval & PTHRW_COUNT_MASK)) { - if (OSAtomicCompareAndSwap32(lgenval, updateval, (volatile int32_t *)lseqaddr) != TRUE) - goto lp2; - goto succout; - } - - /* state bits are same? */ - if ((lgenval & PTHRW_BIT_MASK) == (updateval & PTHRW_BIT_MASK)) { - /* nothing to do */ - goto succout; - } - - newval = ((lgenval & PTHRW_UN_BIT_MASK) << PTHRW_COUNT_SHIFT) | (updateval & PTHRW_BIT_MASK); - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 4, newval, 0); -#endif - /* high bits are state on the lock; lowbits are one kernel need to set */ - switch (newval) { - /* W States */ - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action_k(orwlock, lgenval, updateval); - //goto ktrans; - } - break; - - - /* L states */ - case ((PTHRW_LBIT << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - - /* Y states */ - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action_k(orwlock, lgenval, updateval); - //goto ktrans; - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action_k(orwlock, lgenval, updateval); - //goto ktrans; - } - break; - - /* YU states */ - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action_k(orwlock, lgenval, updateval); - //goto ktrans; - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action_k(orwlock, lgenval, updateval); - //goto ktrans; - } - break; - - /* E states */ - case ((PTHRW_EBIT << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - - /* WE states */ - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action2(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - - /* WL states */ - case (((PTHRW_WBIT | PTHRW_LBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_LBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_LBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_LBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - - default: - /* illegal states */ - self = pthread_self(); - threadid = self->thread_id; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 6, lgenval, 0); - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 7, updateval, 0); + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lcntval, newval, 0); #endif - LIBC_ABORT("incorect state on return 0x%x: lgenval 0x%x, updateval 0x%x; threadid (0x%x)\n", newval, lgenval, updateval, (uint32_t)threadid); - }; - - if (error != 0) - goto lp2; -succout: + PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_NONE, lgenval, newval, 0, 0, 0); + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, 0, 0, 0); #endif return(0); -} - - -static uint32_t -modbits(uint32_t lgenval, uint32_t updateval) -{ - uint32_t lval = lgenval & PTHRW_BIT_MASK; - uint32_t uval = updateval & PTHRW_BIT_MASK; - uint32_t rval, nlval; - - nlval = (lval | uval); - if ((uval & PTHRW_EBIT) == 0) - nlval &= ~PTHRW_EBIT; - if ((nlval & (PTHRW_WBIT | PTHRW_YBIT)) == (PTHRW_WBIT | PTHRW_YBIT)) - nlval &= ~PTHRW_YBIT; - /* no new writers and kernel resets w bit, reset W bit on the lock */ - if (((nlval & (PTHRW_WBIT | PTHRW_SHADOW_W)) == PTHRW_WBIT) && ((updateval & PTHRW_WBIT) == 0)) - nlval &= ~PTHRW_WBIT; - - rval = (lgenval & PTHRW_COUNT_MASK) | nlval; - return(rval); -} - -static int -rwlock_unlock_action1(pthread_rwlock_t * orwlock, uint32_t lgenval, uint32_t updateval) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - int error = 0; - uint32_t newval; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); - } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } - - newval = modbits(lgenval, updateval); - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) != TRUE) - error = EINVAL; +out: + PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_NONE, lgenval, newval, 0, 0, 0); + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); #endif return(error); } -static int -rwlock_unlock_action2(pthread_rwlock_t * orwlock, uint32_t lgenval, uint32_t updateval) +int +pthread_rwlock_tryrdlock(pthread_rwlock_t * orwlock) { npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t newval; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; + uint32_t lcntval, ucntval, rw_seq, newval, newsval; + int error = 0, retry_count = 0; + uint64_t oldval64, newval64; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); - } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } - - newval = modbits(lgenval, updateval); - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) == TRUE) { - /* roundtrip kernel */ - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT2 | DBG_FUNC_NONE, lgenval, newval, 0, 0, 0); -#endif - (void) __psynch_rw_unlock2(orwlock, lgenval, *useqaddr, *wcaddr, rwlock->rw_flags); - return(0); + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + LOCK(rwlock->lock); + if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); + return(error); + } + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL); + return(EINVAL); + } + UNLOCK(rwlock->lock); } -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT2 | DBG_FUNC_NONE, 0xffffffff, 0, 0, 0, 0); -#endif - - return(EINVAL); -} - -/* This is used when an exclusive write lock of any kind is being granted. For unlock thread, it needs to try to set the bit, if not move on */ -static int -rwlock_unlock_action_k(pthread_rwlock_t * orwlock, uint32_t lgenval, uint32_t updateval) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t newval; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } - newval = modbits(lgenval, updateval); -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACTK | DBG_FUNC_NONE, lgenval, updateval, newval, 0, 0); -#endif - /* try to set, if not not a prolem as the thread taking exclusive will take care of the discrepency */ - - if (OSAtomicCompareAndSwap32(lgenval, newval, (volatile int32_t *)lseqaddr) == TRUE) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACTK | DBG_FUNC_NONE, 0x55555555, lgenval, newval, 0, 0); -#endif - - } else { +loop: + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACTK | DBG_FUNC_NONE, 0xAAAAAAAA, lgenval, newval, 0, 0); + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_TRYRDLOCK | DBG_FUNC_START, (uint32_t)rwlock, lcntval, ucntval, rw_seq, 0); #endif - } - - return(0); -} - -static int -rwlock_exclusive_lockreturn(pthread_rwlock_t * orwlock, uint32_t updateval) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t lgenval, newval; - volatile uint32_t * lseqaddr, *useqaddr, *wcaddr; - pthread_t self; - uint64_t threadid; - - int error = 0; - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lseqaddr, useqaddr, wcaddr); - } else { - lseqaddr = rwlock->rw_lseqaddr; - useqaddr = rwlock->rw_useqaddr; - wcaddr = rwlock->rw_wcaddr; - } - -lp2: - lgenval = *lseqaddr; - - /* if the kernel antcipated seq and one on the lock are same, set the one from kernel */ - if ((lgenval & PTHRW_COUNT_MASK) == (updateval & PTHRW_COUNT_MASK)) { - if (OSAtomicCompareAndSwap32(lgenval, updateval, (volatile int32_t *)lseqaddr) != TRUE) - goto lp2; - goto out; - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACTE | DBG_FUNC_NONE, lgenval, updateval, 1, 0, 0); -#endif - /* state bits are same? */ - if ((lgenval & PTHRW_BIT_MASK) == (updateval & PTHRW_BIT_MASK)) { - /* nothing to do */ - goto out; - } - + /* if l bit is on or u and k bit is clear, acquire lock in userland */ + if (can_rwl_readinuser(lcntval)) + goto gotlock; - newval = ((lgenval & PTHRW_UN_BIT_MASK) << PTHRW_COUNT_SHIFT) | (updateval & PTHRW_BIT_MASK); + error = EBUSY; + goto out; +gotlock: + if (rw_diffgenseq(lcntval, ucntval) >= PTHRW_MAX_READERS) { + /* since ucntval may be newer, just redo */ + retry_count++; + if (retry_count > 1024) { + #if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACTE | DBG_FUNC_NONE, newval, 0, 2, 0, 0); + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_TOOMANY | DBG_FUNC_NONE, (uint32_t)rwlock, 0XEEEEEEEE, lcntval, ucntval, 0); #endif - /* high bits are state on the lock; lowbits are one kernel need to set */ - switch (newval) { - /* W States */ - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case ((PTHRW_WBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { error = EAGAIN; - } - break; - - - /* All L states illegal here */ - - /* Y states */ - case (PTHRW_YBIT << PTHRW_COUNT_SHIFT) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = EAGAIN; - } - break; - case ((PTHRW_YBIT << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = EAGAIN; - } - break; - - /* YU states */ - case ((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = EAGAIN; - } - break; - - case (((PTHRW_YBIT | PTHRW_UBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = EAGAIN; - } - break; - - /* E states */ - case ((PTHRW_EBIT << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - - /* WE states */ - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_WBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - case (((PTHRW_WBIT | PTHRW_EBIT) << PTHRW_COUNT_SHIFT) | (PTHRW_YBIT | PTHRW_EBIT)) : { - error = rwlock_unlock_action1(orwlock, lgenval, updateval); - } - break; - - /* All WL states are illegal*/ - - default: - /* illegal states */ - self = pthread_self(); - threadid = self->thread_id; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACTE | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 6, lgenval, 0); - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACTE | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, 7, updateval, 0); -#endif - LIBC_ABORT("rwlock_exclusive_lockreturn: incorect state on return 0x%x: lgenval 0x%x, updateval 0x%x; threadid (0x%x)\n", newval, lgenval, updateval, (uint32_t)threadid); - }; - - if (error == EINVAL) - goto lp2; -out: -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACTE | DBG_FUNC_NONE, error, 0, 0xffffffff, 0, 0); -#endif - return(error); -} - -/* returns are not bit shifted */ -static int -rw_diffgenseq(uint32_t x, uint32_t y) -{ - uint32_t lx = (x & PTHRW_COUNT_MASK); - uint32_t ly = (y &PTHRW_COUNT_MASK); - - if (lx > ly) { - return(lx-ly); - } else { - return((PTHRW_MAX_READERS - y) + lx + PTHRW_INC); - } - -} - -#endif /* i386 || x86_64 ] */ - - -#endif /* !BUILDING_VARIANT ] */ - -int -pthread_rwlock_destroy(pthread_rwlock_t *rwlock) -{ -#if defined(__i386__) || defined(__x86_64__) || defined(__DARWIN_UNIX03) - int ret; -#endif /* __i386__ || __x86_64__ */ - - -#if defined(__i386__) || defined(__x86_64__) - if ((usenew_impl != 0)) { - return(_new_pthread_rwlock_destroy(rwlock)); - } -#endif /* __i386__ || __x86_64__ */ - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - return(EINVAL); - } -#if defined(__i386__) || defined(__x86_64__) - else if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - ret = _new_pthread_rwlock_destroy(rwlock); - return(ret); - } -#endif /* __i386__ || __x86_64__ */ - else { -#if __DARWIN_UNIX03 - /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) - return(ret); - - if (rwlock->state != 0) { - pthread_mutex_unlock(&rwlock->lock); - return(EBUSY); - } - pthread_mutex_unlock(&rwlock->lock); -#endif /* __DARWIN_UNIX03 */ - - pthread_mutex_destroy(&rwlock->lock); - pthread_cond_destroy(&rwlock->read_signal); - pthread_cond_destroy(&rwlock->write_signal); - rwlock->sig = _PTHREAD_NO_SIG; - return(0); - } -} - -int -pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) -{ - int ret; - -#if defined(__i386__) || defined(__x86_64__) - if ((usenew_impl != 0)) { - return(_new_pthread_rwlock_init(rwlock, attr)); - } -#endif /* __i386__ || __x86_64__ */ - -#if __DARWIN_UNIX03 - if (attr && (attr->sig != _PTHREAD_RWLOCK_ATTR_SIG)) { - return(EINVAL); - } -#endif /* __DARWIN_UNIX03 */ - -#if defined(__i386__) || defined(__x86_64__) - if ((attr != NULL) && (attr->pshared == PTHREAD_PROCESS_SHARED)) { - ret = _new_pthread_rwlock_init(rwlock, attr); - return(ret); - } -#endif /* __i386__ || __x86_64__ */ - -#if __DARWIN_UNIX03 - /* if already inited check whether it is in use, then return EBUSY */ - if ((rwlock->sig == _PTHREAD_RWLOCK_SIG) && (rwlock->state !=0 )) { - return(EBUSY); - } -#endif /* __DARWIN_UNIX03 */ - - /* initialize the lock */ - if ((ret = pthread_mutex_init(&rwlock->lock, NULL)) != 0) - return(ret); - else { - /* initialize the read condition signal */ - ret = pthread_cond_init(&rwlock->read_signal, NULL); - - if (ret != 0) { - pthread_mutex_destroy(&rwlock->lock); - return(ret); + goto out; } else { - /* initialize the write condition signal */ - ret = pthread_cond_init(&rwlock->write_signal, NULL); - - if (ret != 0) { - pthread_cond_destroy(&rwlock->read_signal); - pthread_mutex_destroy(&rwlock->lock); - return(ret); - } else { - /* success */ - rwlock->state = 0; - rwlock->owner = (pthread_t)0; - rwlock->blocked_writers = 0; - if (attr) - rwlock->pshared = attr->pshared; - else - rwlock->pshared = _PTHREAD_DEFAULT_PSHARED; - - rwlock->sig = _PTHREAD_RWLOCK_SIG; - return(0); - } - } - } -} - -int -pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) -{ - int ret; -#if __DARWIN_UNIX03 - pthread_t self = pthread_self(); -#endif - -#if defined(__i386__) || defined(__x86_64__) - if ((usenew_impl != 0)) { - return(_new_pthread_rwlock_rdlock(rwlock)); - } -#endif /* __i386__ || __x86_64__ */ - - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((ret = pthread_rwlock_init(rwlock, NULL)) != 0) { - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); - return(ret); - } - } - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } -#if defined(__i386__) || defined(__x86_64__) - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - ret = _new_pthread_rwlock_rdlock(rwlock); - return(ret); - } -#endif /* __i386__ || __x86_64__ */ - /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) { - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); - return(ret); - } - -#if __DARWIN_UNIX03 - if ((rwlock->state < 0) && (rwlock->owner == self)) { - pthread_mutex_unlock(&rwlock->lock); - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, EDEADLK); - return(EDEADLK); - } -#endif /* __DARWIN_UNIX03 */ - -#if __DARWIN_UNIX03 - while (rwlock->blocked_writers || ((rwlock->state < 0) && (rwlock->owner != self))) -#else /* __DARWIN_UNIX03 */ - while (rwlock->blocked_writers || rwlock->state < 0) - -#endif /* __DARWIN_UNIX03 */ - { - /* give writers priority over readers */ - PLOCKSTAT_RW_BLOCK(rwlock, READ_LOCK_PLOCKSTAT); - ret = pthread_cond_wait(&rwlock->read_signal, &rwlock->lock); - - if (ret != 0) { - /* can't do a whole lot if this fails */ - pthread_mutex_unlock(&rwlock->lock); - PLOCKSTAT_RW_BLOCKED(rwlock, READ_LOCK_PLOCKSTAT, BLOCK_FAIL_PLOCKSTAT); - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); - return(ret); + sched_yield(); + goto loop; } - - PLOCKSTAT_RW_BLOCKED(rwlock, READ_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); } + + /* Need to update L(remove Rbit ) and S word */ + newval = (lcntval + PTHRW_INC) & PTH_RWLOCK_RESET_RBIT; + newsval = (rw_seq + PTHRW_INC); - /* check lock count */ - if (rwlock->state == MAX_READ_LOCKS) { - ret = EAGAIN; - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); - } - else { - ++rwlock->state; /* indicate we are locked for reading */ - PLOCKSTAT_RW_ACQUIRE(rwlock, READ_LOCK_PLOCKSTAT); - } + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) + goto loop; - /* - * Something is really wrong if this call fails. Returning - * error won't do because we've already obtained the read - * lock. Decrementing 'state' is no good because we probably - * don't have the monitor lock. - */ - pthread_mutex_unlock(&rwlock->lock); +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_TRYRDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lcntval, newval, 0); +#endif + + PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); + return(0); - return(ret); +out: + PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_TRYRDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, error, 0, 0); +#endif + return(error); } int -pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) +pthread_rwlock_trywrlock(pthread_rwlock_t * orwlock) { - int ret; - -#if defined(__i386__) || defined(__x86_64__) - if ((usenew_impl != 0)) { - return(_new_pthread_rwlock_tryrdlock(rwlock)); - } -#endif /* __i386__ || __x86_64__ */ - - /* check for static initialization */ - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((ret = pthread_rwlock_init(rwlock, NULL)) != 0) { - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); - return(ret); - } - } - +#if __DARWIN_UNIX03 + pthread_t self = pthread_self(); +#endif /* __DARWIN_UNIX03 */ + npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; + uint32_t lcntval, rw_seq, newval, newsval; + int error = 0, gotlock = 0; + uint64_t oldval64, newval64; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); + LOCK(rwlock->lock); + if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); + return(error); + } + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); + return(EINVAL); + } + UNLOCK(rwlock->lock); } -#if defined(__i386__) || defined(__x86_64__) + if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - ret = _new_pthread_rwlock_tryrdlock(rwlock); - return(ret); + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); + } else { + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } -#endif /* __i386__ || __x86_64__ */ - /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) { - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); - return(ret); - } +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_TRYWRLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0); +#endif +loop: + lcntval = *lcntaddr; + rw_seq = *seqaddr; + + /* can we acquire in userland? */ + if ((lcntval & PTH_RWL_RBIT) != 0) { + newval = ((lcntval + PTHRW_INC) & PTHRW_COUNT_MASK) | PTH_RWL_IBIT | PTH_RWL_KBIT| PTH_RWL_EBIT; + newsval = rw_seq + PTHRW_INC; + gotlock = 1; + } else + gotlock = 0; - /* give writers priority over readers */ - if (rwlock->blocked_writers || rwlock->state < 0) { - ret = EBUSY; - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); - } - else if (rwlock->state == MAX_READ_LOCKS) { - ret = EAGAIN; /* too many read locks acquired */ - PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); - } - else { - ++rwlock->state; /* indicate we are locked for reading */ - PLOCKSTAT_RW_ACQUIRE(rwlock, READ_LOCK_PLOCKSTAT); - } - /* see the comment on this in pthread_rwlock_rdlock */ - pthread_mutex_unlock(&rwlock->lock); + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + + if (gotlock != 0) { + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; + } else + newval64 = oldval64; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) { + goto loop; + } + if (gotlock == 1) { +#if __DARWIN_UNIX03 + rwlock->rw_owner = self; +#endif /* __DARWIN_UNIX03 */ + PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT); +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_TRYWRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0, 0, 0, 0); +#endif + return(0); + } else { +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_TRYWRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, EBUSY, 0, 0); +#endif - return(ret); + PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EBUSY); + return(EBUSY); + } } int -pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) +pthread_rwlock_wrlock(pthread_rwlock_t * orwlock) { - int ret; #if __DARWIN_UNIX03 pthread_t self = pthread_self(); #endif /* __DARWIN_UNIX03 */ - -#if defined(__i386__) || defined(__x86_64__) - if ((usenew_impl != 0)) { - return(_new_pthread_rwlock_trywrlock(rwlock)); + npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; + uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; + int error = 0, gotlock = 0; + uint64_t oldval64, newval64; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + uint64_t myid = 0; + + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + LOCK(rwlock->lock); + if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); + return(error); + } + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); + return(EINVAL); + } + UNLOCK(rwlock->lock); + } + + if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); + } else { + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } -#endif /* __i386__ || __x86_64__ */ + +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0); +#endif +loop: + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; + +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lcntval, ucntval, rw_seq, 0); +#endif - /* check for static initialization */ - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((ret = pthread_rwlock_init(rwlock, NULL)) != 0) { - PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, ret); - return(ret); +#if __DARWIN_UNIX03 + if (is_rwl_ebit_set(lcntval)) { + if(rwlock->rw_owner == self) { + error = EDEADLK; + goto out; } } +#endif /* __DARWIN_UNIX03 */ - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } + + if ((lcntval & PTH_RWL_RBIT) != 0) { + /* lock is restart state, writer can acquire the lock */ + newval = ((lcntval + PTHRW_INC) & PTHRW_COUNT_MASK) | PTH_RWL_IBIT | PTH_RWL_KBIT| PTH_RWL_EBIT; -#if defined(__i386__) || defined(__x86_64__) - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - ret = _new_pthread_rwlock_trywrlock(rwlock); - return(ret); - } -#endif /* __i386__ || __x86_64__ */ + newsval = rw_seq + PTHRW_INC; + gotlock = 1; + + } else { + if (is_rwl_lbit_set(lcntval)) + newval = (lcntval + PTHRW_INC)| PTH_RWL_WBIT; + else + newval = (lcntval + PTHRW_INC) | PTH_RWL_KBIT| PTH_RWL_WBIT; - /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) { - PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, ret); - return(ret); + newsval = rw_seq; + if (is_rws_setseq(rw_seq)) { + newsval &= PTHRW_SW_Reset_BIT_MASK; + newsval |= (newval & PTHRW_COUNT_MASK); + } + gotlock = 0; } + /* update lock seq */ + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; + +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lcntval, newval, 0); +#endif + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) + goto loop; + + /* lock acquired in userland itself? */ + if (gotlock != 0) + goto gotit; + + /* unable to acquire in userland, transition to kernel */ + + PLOCKSTAT_RW_BLOCK(orwlock, WRITE_LOCK_PLOCKSTAT); +retry: + updateval = __psynch_rw_wrlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags); + if (updateval == (uint32_t)-1) { + error = errno; + } else + error = 0; + + if (error == EINTR) { + goto retry; + } - if (rwlock->state != 0) { - ret = EBUSY; - PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, ret); + if (error != 0) { +#if _KSYN_TRACE_ + set_enable(2); +#endif /* _KSYN_TRACE_ */ + (void)pthread_threadid_np(pthread_self(), &myid); + LIBC_ABORT("wrlock from kernel with unknown error %x: tid %x\n", updateval, (uint32_t)myid); } - else { - /* indicate we are locked for writing */ - rwlock->state = -1; + +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x33333333, newval, updateval, 0); +#endif + PLOCKSTAT_RW_BLOCKED(orwlock, WRITE_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); + if (error == 0) { + rwlock_action_onreturn(orwlock, updateval); +gotit: #if __DARWIN_UNIX03 - rwlock->owner = self; + rwlock->rw_owner = self; #endif /* __DARWIN_UNIX03 */ - PLOCKSTAT_RW_ACQUIRE(rwlock, WRITE_LOCK_PLOCKSTAT); - } - - /* see the comment on this in pthread_rwlock_rdlock */ - pthread_mutex_unlock(&rwlock->lock); - - return(ret); + PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT); +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); +#endif + return(0); + } +#if __DARWIN_UNIX03 +out: +#endif /* __DARWIN_UNIX03 */ + PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); +#endif + return(error); } + int -pthread_rwlock_unlock(pthread_rwlock_t *rwlock) +pthread_rwlock_unlock(pthread_rwlock_t * orwlock) { - int ret; - int writer = (rwlock < 0) ? 1:0; - -#if defined(__i386__) || defined(__x86_64__) - if ((usenew_impl != 0)) { - return(_new_pthread_rwlock_unlock(rwlock)); - } -#endif /* __i386__ || __x86_64__ */ - + npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; + uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval, ulval; + int error = 0, wrlock = 0, haswbit = 0, hasubit = 0, hasybit = 0; + uint64_t oldval64, newval64; + volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; + uint64_t myid = 0; + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - PLOCKSTAT_RW_ERROR(rwlock, writer, EINVAL); - return(EINVAL); + LOCK(rwlock->lock); + if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { + if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, wrlock, error); + return(error); + } + } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ + UNLOCK(rwlock->lock); + PLOCKSTAT_RW_ERROR(orwlock, wrlock, EINVAL); + return(EINVAL); + } + UNLOCK(rwlock->lock); } - -#if defined(__i386__) || defined(__x86_64__) + if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - ret = _new_pthread_rwlock_unlock(rwlock); - return(ret); + RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); + } else { + lcntaddr = rwlock->rw_lcntaddr; + ucntaddr = rwlock->rw_ucntaddr; + seqaddr = rwlock->rw_seqaddr; } -#endif /* __i386__ || __x86_64__ */ + +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0); +#endif +loop: + lcntval = *lcntaddr; + ucntval = *ucntaddr; + rw_seq = *seqaddr; + + +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x51515151, lcntval, ucntval, 0); + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x51515151, rw_seq, 0, 0); +#endif + /* check for spurious unlocks */ + if ((lcntval & PTH_RWL_RBIT) != 0) { + newval = lcntval ; + newsval = rw_seq; - /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) { - PLOCKSTAT_RW_ERROR(rwlock, writer, ret); - return(ret); + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) == TRUE) { + /* spurious unlock, return */ + error = EINVAL; +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x1a1b1c1d, lcntval, ucntval, 0); +#endif + goto succout; + } else + goto loop; } - if (rwlock->state > 0) { - if (--rwlock->state == 0 && rwlock->blocked_writers) - ret = pthread_cond_signal(&rwlock->write_signal); - } else if (rwlock->state < 0) { - rwlock->state = 0; + if (is_rwl_ebit_set(lcntval)) { + wrlock = 1; #if __DARWIN_UNIX03 - rwlock->owner = (pthread_t)0; + rwlock->rw_owner = (pthread_t)0; #endif /* __DARWIN_UNIX03 */ + } + + /* update U */ + + ulval = (ucntval + PTHRW_INC); - if (rwlock->blocked_writers) - ret = pthread_cond_signal(&rwlock->write_signal); - else - ret = pthread_cond_broadcast(&rwlock->read_signal); - } else - ret = EINVAL; + if (OSAtomicCompareAndSwap32(ucntval, ulval, (volatile int32_t *)ucntaddr) != TRUE) + goto loop; + +lp11: + /* just validate the l and S values */ + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; - if (ret == 0) { - PLOCKSTAT_RW_RELEASE(rwlock, writer); - } else { - PLOCKSTAT_RW_ERROR(rwlock, writer, ret); + newval64 = oldval64; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) { + lcntval = *lcntaddr; + rw_seq = *seqaddr; + goto lp11; } - /* see the comment on this in pthread_rwlock_rdlock */ - pthread_mutex_unlock(&rwlock->lock); +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xd1d2d3d4, lcntval, rw_seq, 0); + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xd1d2d3d4, ulval, 0, 0); +#endif - return(ret); -} + /* last unlock, note U is already updated ? */ + if((lcntval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) { -int -pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) -{ - int ret; -#if __DARWIN_UNIX03 - pthread_t self = pthread_self(); -#endif /* __DARWIN_UNIX03 */ +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xbbbbbbbb, lcntval, ucntval, 0); +#endif + /* Set L with R and init bits and set S to L */ + newval = (lcntval & PTHRW_COUNT_MASK)| PTHRW_RWLOCK_INIT; + newsval = (lcntval & PTHRW_COUNT_MASK)| PTHRW_RWS_INIT; -#if defined(__i386__) || defined(__x86_64__) - if ((usenew_impl != 0)) { - return(_new_pthread_rwlock_wrlock(rwlock)); - } -#endif /* __i386__ || __x86_64__ */ + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; - /* check for static initialization */ - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((ret = pthread_rwlock_init(rwlock, NULL)) != 0) { - PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, ret); - return(ret); - } - } + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) { +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xcccccccc, 0, 0, 0); +#endif + lcntval = *lcntaddr; + rw_seq = *seqaddr; + goto lp11; + } +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xdddddddd, lcntval, ucntval, 0); +#endif + goto succout; } -#if defined(__i386__) || defined(__x86_64__) - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - ret = _new_pthread_rwlock_wrlock(rwlock); - return(ret); + /* if it is not exclusive or no Writer/yield pending, skip */ + if ((lcntval & (PTH_RWL_EBIT | PTH_RWL_WBIT | PTH_RWL_YBIT | PTH_RWL_KBIT)) == 0) { + goto succout; } -#endif /* __i386__ || __x86_64__ */ + /* kernel transition needed? */ + /* U+1 == S? */ + if ((ulval + PTHRW_INC) != (rw_seq & PTHRW_COUNT_MASK)) { + if ((lcntval & PTH_RWL_UBIT) != 0) { + /* if U bit is set U + 2 == S ? */ + if ((ulval + PTHRW_INC + PTHRW_INC) != (rw_seq & PTHRW_COUNT_MASK)) + goto succout; + } else + goto succout; + } + + haswbit = lcntval & PTH_RWL_WBIT; + hasubit = lcntval & PTH_RWL_UBIT; + hasybit = lcntval & PTH_RWL_YBIT; + + /* reset all bits and set k */ + newval = (lcntval & PTHRW_COUNT_MASK) | PTH_RWL_KBIT; + /* set I bit on S word */ + newsval = rw_seq | PTH_RWS_IBIT; + if (haswbit != 0) + newsval |= PTH_RWS_WSVBIT; + if (hasubit != 0) + newsval |= PTH_RWS_USVBIT; + if (hasybit != 0) + newsval |= PTH_RWS_YSVBIT; + + oldval64 = (((uint64_t)rw_seq) << 32); + oldval64 |= lcntval; + + newval64 = (((uint64_t)newsval) << 32); + newval64 |= newval; + + if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) + goto lp11; - /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) { - PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, ret); - return(ret); - } +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555511, 1, ulval, 0); +#endif + updateval = __psynch_rw_unlock(orwlock, lcntval, ulval, newsval, rwlock->rw_flags); + if (updateval == (uint32_t)-1) { + error = errno; + } else + error = 0; + + if(error != 0) { -#if __DARWIN_UNIX03 - if ((rwlock->state < 0) && (rwlock->owner == self)) { - pthread_mutex_unlock(&rwlock->lock); - PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, EDEADLK); - return(EDEADLK); - } -#endif /* __DARWIN_UNIX03 */ - while (rwlock->state != 0) { - ++rwlock->blocked_writers; - - PLOCKSTAT_RW_BLOCK(rwlock, WRITE_LOCK_PLOCKSTAT); - ret = pthread_cond_wait(&rwlock->write_signal, &rwlock->lock); - - if (ret != 0) { - --rwlock->blocked_writers; - pthread_mutex_unlock(&rwlock->lock); - PLOCKSTAT_RW_BLOCKED(rwlock, WRITE_LOCK_PLOCKSTAT, BLOCK_FAIL_PLOCKSTAT); - PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, ret); - return(ret); + /* not sure what is the scenario */ + if(error != EINTR) { +#if _KSYN_TRACE_ + set_enable(4); +#endif /* _KSYN_TRACE_ */ + (void)pthread_threadid_np(pthread_self(), &myid); + LIBC_ABORT("rwunlock from kernel with unknown error %x: tid %x\n", error, (uint32_t)myid); + goto succout; } - - PLOCKSTAT_RW_BLOCKED(rwlock, WRITE_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); - - --rwlock->blocked_writers; + error = 0; } + +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555522, 3, lcntval, 0); +#endif - /* indicate we are locked for writing */ - rwlock->state = -1; -#if __DARWIN_UNIX03 - rwlock->owner = self; -#endif /* __DARWIN_UNIX03 */ - PLOCKSTAT_RW_ACQUIRE(rwlock, WRITE_LOCK_PLOCKSTAT); - - /* see the comment on this in pthread_rwlock_rdlock */ - pthread_mutex_unlock(&rwlock->lock); - - return(ret); +succout: + PLOCKSTAT_RW_RELEASE(orwlock, wrlock); +#if _KSYN_TRACE_ + if (__pthread_lock_debug != 0) + (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); +#endif + return(0); } diff --git a/pthreads/pthread_spis.h b/pthreads/pthread_spis.h new file mode 100644 index 0000000..a9b3659 --- /dev/null +++ b/pthreads/pthread_spis.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2000-2011 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +/* + * MkLinux + */ + +/* + * Extension SPIs. + */ + +#ifndef _PTHREAD_SPIS_H +#define _PTHREAD_SPIS_H + + +#include + +__BEGIN_DECLS + +#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) +/* firstfit */ +#define PTHREAD_FIRSTFIT_MUTEX_INITIALIZER {_PTHREAD_FIRSTFIT_MUTEX_SIG_init, {0}} +/* + * Mutex attributes + */ +#define _PTHREAD_MUTEX_POLICY_NONE 0 +#define _PTHREAD_MUTEX_POLICY_FAIRSHARE 1 +#define _PTHREAD_MUTEX_POLICY_FIRSTFIT 2 + +/* sets the mutex policy attributes */ +int pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *, int ); + +#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ + +__END_DECLS + +#endif /* _PTHREAD_SPIS_H */ diff --git a/pthreads/pthread_workqueue.h b/pthreads/pthread_workqueue.h index c3b5f97..f8c3158 100644 --- a/pthreads/pthread_workqueue.h +++ b/pthreads/pthread_workqueue.h @@ -27,7 +27,7 @@ #include #include - +#include #define __PTHREAD_WORKQ_SIZE__ 128 #define __PTHREAD_WORKQ_ATTR_SIZE__ 60 @@ -42,35 +42,36 @@ typedef struct { unsigned int sig; char opaque[__PTHREAD_WORKQ_ATTR_SIZE__]; } typedef void * pthread_workitem_handle_t; /* Kernel expected target concurrency of the workqueue clients for the three priority queues */ -#define WORKQ_HIGH_PRIOQUEUE 0 -#define WORKQ_DEFAULT_PRIOQUEUE 1 -#define WORKQ_LOW_PRIOQUEUE 2 +#define WORKQ_HIGH_PRIOQUEUE 0 /* high priority queue */ +#define WORKQ_DEFAULT_PRIOQUEUE 1 /* default priority queue */ +#define WORKQ_LOW_PRIOQUEUE 2 /* low priority queue */ +#define WORKQ_BG_PRIOQUEUE 3 /* background priority queue */ -#define WORKQ_NUM_PRIOQUEUE 3 +#define WORKQ_NUM_PRIOQUEUE 4 extern __int32_t workq_targetconc[WORKQ_NUM_PRIOQUEUE]; __BEGIN_DECLS -int pthread_workqueue_init_np(void); -int pthread_workqueue_attr_init_np(pthread_workqueue_attr_t * attr); -int pthread_workqueue_attr_destroy_np(pthread_workqueue_attr_t * attr); -int pthread_workqueue_attr_getqueuepriority_np(const pthread_workqueue_attr_t * attr, int * qprio); +int pthread_workqueue_init_np(void) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int pthread_workqueue_attr_init_np(pthread_workqueue_attr_t * attr) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int pthread_workqueue_attr_destroy_np(pthread_workqueue_attr_t * attr) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int pthread_workqueue_attr_getqueuepriority_np(const pthread_workqueue_attr_t * attr, int * qprio) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); /* WORKQ_HIGH/DEFAULT/LOW_PRIOQUEUE are the only valid values */ -int pthread_workqueue_attr_setqueuepriority_np(pthread_workqueue_attr_t * attr, int qprio); -int pthread_workqueue_attr_getovercommit_np(const pthread_workqueue_attr_t * attr, int * ocommp); -int pthread_workqueue_attr_setovercommit_np(pthread_workqueue_attr_t * attr, int ocomm); +int pthread_workqueue_attr_setqueuepriority_np(pthread_workqueue_attr_t * attr, int qprio) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int pthread_workqueue_attr_getovercommit_np(const pthread_workqueue_attr_t * attr, int * ocommp) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +int pthread_workqueue_attr_setovercommit_np(pthread_workqueue_attr_t * attr, int ocomm) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); -int pthread_workqueue_create_np(pthread_workqueue_t * workqp, const pthread_workqueue_attr_t * attr); -int pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp); +int pthread_workqueue_create_np(pthread_workqueue_t * workqp, const pthread_workqueue_attr_t * attr) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); /* If the queue value is WORKQ_NUM_PRIOQUEUE, the request for concurrency is for all queues */ -int pthread_workqueue_requestconcurrency_np(int queue, int concurrency); -int pthread_workqueue_getovercommit_np(pthread_workqueue_t workq, unsigned int *ocommp); +int pthread_workqueue_requestconcurrency_np(int queue, int concurrency) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +int pthread_workqueue_getovercommit_np(pthread_workqueue_t workq, unsigned int *ocommp) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); /* * If the arg is non zero, it enables kill on current thread. * If the arg of zero, it disables kill on current thread. */ -int __pthread_workqueue_setkill(int); +int __pthread_workqueue_setkill(int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); __END_DECLS #endif /* _POSIX_PTHREAD_WORKQUEUE_H */ diff --git a/regex/FreeBSD/cname.h b/regex/FreeBSD/cname.h index 4f0d583..19b4ddb 100644 --- a/regex/FreeBSD/cname.h +++ b/regex/FreeBSD/cname.h @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ * SUCH DAMAGE. * * @(#)cname.h 8.3 (Berkeley) 3/20/94 - * $FreeBSD: src/lib/libc/regex/cname.h,v 1.3 2002/03/22 23:41:56 obrien Exp $ + * $FreeBSD: src/lib/libc/regex/cname.h,v 1.4 2007/01/09 00:28:04 imp Exp $ */ /* character-name table */ diff --git a/regex/FreeBSD/cname.h.patch b/regex/FreeBSD/cname.h.patch new file mode 100644 index 0000000..2e6b31f --- /dev/null +++ b/regex/FreeBSD/cname.h.patch @@ -0,0 +1,13 @@ +--- cname.h.orig 2010-05-05 14:45:26.000000000 -0700 ++++ cname.h 2010-05-05 14:45:56.000000000 -0700 +@@ -39,8 +39,8 @@ + */ + + /* character-name table */ +-static struct cname { +- char *name; ++static const struct cname { ++ const char *name; + char code; + } cnames[] = { + {"NUL", '\0'}, diff --git a/regex/FreeBSD/engine.c b/regex/FreeBSD/engine.c index 6ab6732..feae5c5 100644 --- a/regex/FreeBSD/engine.c +++ b/regex/FreeBSD/engine.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/regex/engine.c,v 1.14 2004/07/12 07:35:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/regex/engine.c,v 1.23 2009/09/16 06:32:23 dds Exp $"); /* * The matching engine and friends. This file is #included by regexec.c @@ -86,11 +82,11 @@ struct match { struct re_guts *g; int eflags; regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ - char *offp; /* offsets work from here */ - char *beginp; /* start of string -- virtual NUL precedes */ - char *endp; /* end of string -- virtual NUL here */ - char *coldp; /* can be no match starting before here */ - char **lastpos; /* [nplus+1] */ + const char *offp; /* offsets work from here */ + const char *beginp; /* start of string -- virtual NUL precedes */ + const char *endp; /* end of string -- virtual NUL here */ + const char *coldp; /* can be no match starting before here */ + const char **lastpos; /* [nplus+1] */ STATEVARS; states st; /* current states */ states fresh; /* states for a fresh start */ @@ -105,12 +101,13 @@ extern "C" { #endif /* === engine.c === */ -static int matcher(struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags); -static char *dissect(struct match *m, char *start, char *stop, sopno startst, sopno stopst); -static char *backref(struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev); -static char *fast(struct match *m, char *start, char *stop, sopno startst, sopno stopst); -static char *slow(struct match *m, char *start, char *stop, sopno startst, sopno stopst); +static int matcher(struct re_guts *g, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); +static const char *dissect(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); +static const char *backref(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst, sopno lev, int); +static const char *fast(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); +static const char *slow(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); static states step(struct re_guts *g, sopno start, sopno stop, states bef, wint_t ch, states aft); +#define MAX_RECURSION 100 #define BOL (OUT-1) #define EOL (BOL-1) #define BOLEOL (BOL-2) @@ -120,13 +117,13 @@ static states step(struct re_guts *g, sopno start, sopno stop, states bef, wint_ #define BADCHAR (BOL-6) #define NONCHAR(c) ((c) <= OUT) #ifdef REDEBUG -static void print(struct match *m, char *caption, states st, int ch, FILE *d); +static void print(struct match *m, const char *caption, states st, int ch, FILE *d); #endif #ifdef REDEBUG -static void at(struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst); +static void at(struct match *m, const char *title, const char *start, const char *stop, sopno startst, sopno stopst); #endif #ifdef REDEBUG -static char *pchar(int ch); +static const char *pchar(int ch); #endif #ifdef __cplusplus @@ -146,31 +143,30 @@ static char *pchar(int ch); /* - matcher - the actual matching engine - == static int matcher(struct re_guts *g, char *string, \ + == static int matcher(struct re_guts *g, const char *string, \ == size_t nmatch, regmatch_t pmatch[], int eflags); */ static int /* 0 success, REG_NOMATCH failure */ -matcher(g, string, nmatch, pmatch, eflags) -struct re_guts *g; -char *string; -size_t nmatch; -regmatch_t pmatch[]; -int eflags; +matcher(struct re_guts *g, + const char *string, + size_t nmatch, + regmatch_t pmatch[], + int eflags) { - char *endp; + const char *endp; int i; struct match mv; struct match *m = &mv; - char *dp; + const char *dp; const sopno gf = g->firststate+1; /* +1 for OEND */ const sopno gl = g->laststate; - char *start; - char *stop; + const char *start; + const char *stop; /* Boyer-Moore algorithms variables */ - char *pp; + const char *pp; int cj, mj; - char *mustfirst; - char *mustlast; + const char *mustfirst; + const char *mustlast; int *matchjump; int *charjump; @@ -251,10 +247,16 @@ int eflags; if (g->moffset > -1) start = ((dp - g->moffset) < start) ? start : dp - g->moffset; + SP("mloop", m->st, *start); + /* this loop does only one repetition except for backrefs */ for (;;) { endp = fast(m, start, stop, gf, gl); if (endp == NULL) { /* a miss */ + if (m->pmatch != NULL) + free((char *)m->pmatch); + if (m->lastpos != NULL) + free((char *)m->lastpos); STATETEARDOWN(m); return(REG_NOMATCH); } @@ -290,15 +292,15 @@ int eflags; dp = dissect(m, m->coldp, endp, gf, gl); } else { if (g->nplus > 0 && m->lastpos == NULL) - m->lastpos = (char **)malloc((g->nplus+1) * - sizeof(char *)); + m->lastpos = malloc((g->nplus+1) * + sizeof(const char *)); if (g->nplus > 0 && m->lastpos == NULL) { free(m->pmatch); STATETEARDOWN(m); return(REG_ESPACE); } NOTE("backref dissect"); - dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); + dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0); } if (dp != NULL) break; @@ -321,7 +323,7 @@ int eflags; } #endif NOTE("backoff dissect"); - dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); + dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0); } assert(dp == NULL || dp == endp); if (dp != NULL) /* found a shorter one */ @@ -331,7 +333,7 @@ int eflags; NOTE("false alarm"); /* recycle starting later */ start = m->coldp + XMBRTOWC(NULL, m->coldp, - m->endp - m->coldp, &m->mbs, 0); + stop - m->coldp, &m->mbs, 0); assert(start <= stop); } @@ -361,30 +363,29 @@ int eflags; /* - dissect - figure out what matched what, no back references - == static char *dissect(struct match *m, char *start, \ - == char *stop, sopno startst, sopno stopst); + == static const char *dissect(struct match *m, const char *start, \ + == const char *stop, sopno startst, sopno stopst); */ -static char * /* == stop (success) always */ -dissect(m, start, stop, startst, stopst) -struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; +static const char * /* == stop (success) always */ +dissect(struct match *m, + const char *start, + const char *stop, + sopno startst, + sopno stopst) { int i; sopno ss; /* start sop of current subRE */ sopno es; /* end sop of current subRE */ - char *sp; /* start of string matched by it */ - char *stp; /* string matched by it cannot pass here */ - char *rest; /* start of rest of string */ - char *tail; /* string unmatched by rest of RE */ + const char *sp; /* start of string matched by it */ + const char *stp; /* string matched by it cannot pass here */ + const char *rest; /* start of rest of string */ + const char *tail; /* string unmatched by rest of RE */ sopno ssub; /* start sop of subsubRE */ sopno esub; /* end sop of subsubRE */ - char *ssp; /* start of string matched by subsubRE */ - char *sep; /* end of string matched by subsubRE */ - char *oldssp; /* previous ssp */ - char *dp; + const char *ssp; /* start of string matched by subsubRE */ + const char *sep; /* end of string matched by subsubRE */ + const char *oldssp; /* previous ssp */ + const char *dp; AT("diss", start, stop, startst, stopst); sp = start; @@ -549,25 +550,25 @@ sopno stopst; /* - backref - figure out what matched what, figuring in back references - == static char *backref(struct match *m, char *start, \ - == char *stop, sopno startst, sopno stopst, sopno lev); + == static const char *backref(struct match *m, const char *start, \ + == const char *stop, sopno startst, sopno stopst, sopno lev); */ -static char * /* == stop (success) or NULL (failure) */ -backref(m, start, stop, startst, stopst, lev) -struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; -sopno lev; /* PLUS nesting level */ +static const char * /* == stop (success) or NULL (failure) */ +backref(struct match *m, + const char *start, + const char *stop, + sopno startst, + sopno stopst, + sopno lev, /* PLUS nesting level */ + int rec) { int i; sopno ss; /* start sop of current subRE */ - char *sp; /* start of string matched by it */ + const char *sp; /* start of string matched by it */ sopno ssub; /* start sop of subsubRE */ sopno esub; /* end sop of subsubRE */ - char *ssp; /* start of string matched by subsubRE */ - char *dp; + const char *ssp; /* start of string matched by subsubRE */ + const char *dp; size_t len; int hard; sop s; @@ -674,6 +675,8 @@ sopno lev; /* PLUS nesting level */ return(NULL); assert(m->pmatch[i].rm_so != -1); len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so; + if (len == 0 && rec++ > MAX_RECURSION) + return(NULL); assert(stop - m->beginp >= len); if (sp > stop - len) return(NULL); /* not enough left to match */ @@ -682,28 +685,28 @@ sopno lev; /* PLUS nesting level */ return(NULL); while (m->g->strip[ss] != SOP(O_BACK, i)) ss++; - return(backref(m, sp+len, stop, ss+1, stopst, lev)); + return(backref(m, sp+len, stop, ss+1, stopst, lev, rec)); break; case OQUEST_: /* to null or not */ - dp = backref(m, sp, stop, ss+1, stopst, lev); + dp = backref(m, sp, stop, ss+1, stopst, lev, rec); if (dp != NULL) return(dp); /* not */ - return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev)); + return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev, rec)); break; case OPLUS_: assert(m->lastpos != NULL); assert(lev+1 <= m->g->nplus); m->lastpos[lev+1] = sp; - return(backref(m, sp, stop, ss+1, stopst, lev+1)); + return(backref(m, sp, stop, ss+1, stopst, lev+1, rec)); break; case O_PLUS: if (sp == m->lastpos[lev]) /* last pass matched null */ - return(backref(m, sp, stop, ss+1, stopst, lev-1)); + return(backref(m, sp, stop, ss+1, stopst, lev-1, rec)); /* try another pass */ m->lastpos[lev] = sp; - dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev); + dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev, rec); if (dp == NULL) - return(backref(m, sp, stop, ss+1, stopst, lev-1)); + return(backref(m, sp, stop, ss+1, stopst, lev-1, rec)); else return(dp); break; @@ -712,7 +715,7 @@ sopno lev; /* PLUS nesting level */ esub = ss + OPND(s) - 1; assert(OP(m->g->strip[esub]) == OOR1); for (;;) { /* find first matching branch */ - dp = backref(m, sp, stop, ssub, esub, lev); + dp = backref(m, sp, stop, ssub, esub, lev, rec); if (dp != NULL) return(dp); /* that one missed, try next one */ @@ -733,7 +736,7 @@ sopno lev; /* PLUS nesting level */ assert(0 < i && i <= m->g->nsub); offsave = m->pmatch[i].rm_so; m->pmatch[i].rm_so = sp - m->offp; - dp = backref(m, sp, stop, ss+1, stopst, lev); + dp = backref(m, sp, stop, ss+1, stopst, lev, rec); if (dp != NULL) return(dp); m->pmatch[i].rm_so = offsave; @@ -744,7 +747,7 @@ sopno lev; /* PLUS nesting level */ assert(0 < i && i <= m->g->nsub); offsave = m->pmatch[i].rm_eo; m->pmatch[i].rm_eo = sp - m->offp; - dp = backref(m, sp, stop, ss+1, stopst, lev); + dp = backref(m, sp, stop, ss+1, stopst, lev, rec); if (dp != NULL) return(dp); m->pmatch[i].rm_eo = offsave; @@ -763,30 +766,30 @@ sopno lev; /* PLUS nesting level */ /* - fast - step through the string at top speed - == static char *fast(struct match *m, char *start, \ - == char *stop, sopno startst, sopno stopst); + == static const char *fast(struct match *m, const char *start, \ + == const char *stop, sopno startst, sopno stopst); */ -static char * /* where tentative match ended, or NULL */ -fast(m, start, stop, startst, stopst) -struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; +static const char * /* where tentative match ended, or NULL */ +fast( struct match *m, + const char *start, + const char *stop, + sopno startst, + sopno stopst) { states st = m->st; states fresh = m->fresh; states tmp = m->tmp; - char *p = start; + const char *p = start; wint_t c; wint_t lastc; /* previous c */ wint_t flagch; int i; - char *coldp; /* last p after which no match was underway */ + const char *coldp; /* last p after which no match was underway */ size_t clen; CLEAR(st); SET1(st, startst); + SP("fast", st, *p); st = step(m->g, startst, stopst, st, NOTHING, st); ASSIGN(fresh, st); SP("start", st, *p); @@ -804,9 +807,10 @@ sopno stopst; for (;;) { /* next character */ lastc = c; - if (p == m->endp) + if (p == m->endp) { + clen = 0; c = OUT; - else + } else clen = XMBRTOWC(&c, p, m->endp - p, &m->mbs, BADCHAR); if (EQ(st, fresh)) coldp = p; @@ -845,7 +849,7 @@ sopno stopst; } /* are we done? */ - if (ISSET(st, stopst) || p == stop) + if (ISSET(st, stopst) || p == stop || clen > stop - p) break; /* NOTE BREAK OUT */ /* no, we must deal with this character */ @@ -861,33 +865,32 @@ sopno stopst; assert(coldp != NULL); m->coldp = coldp; if (ISSET(st, stopst)) - return(p+XMBRTOWC(NULL, p, m->endp - p, &m->mbs, 0)); + return(p+XMBRTOWC(NULL, p, stop - p, &m->mbs, 0)); else return(NULL); } /* - slow - step through the string more deliberately - == static char *slow(struct match *m, char *start, \ - == char *stop, sopno startst, sopno stopst); + == static const char *slow(struct match *m, const char *start, \ + == const char *stop, sopno startst, sopno stopst); */ -static char * /* where it ended */ -slow(m, start, stop, startst, stopst) -struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; +static const char * /* where it ended */ +slow( struct match *m, + const char *start, + const char *stop, + sopno startst, + sopno stopst) { states st = m->st; states empty = m->empty; states tmp = m->tmp; - char *p = start; + const char *p = start; wint_t c; wint_t lastc; /* previous c */ wint_t flagch; int i; - char *matchp; /* last p at which a match ended */ + const char *matchp; /* last p at which a match ended */ size_t clen; AT("slow", start, stop, startst, stopst); @@ -951,7 +954,7 @@ sopno stopst; /* are we done? */ if (ISSET(st, stopst)) matchp = p; - if (EQ(st, empty) || p == stop) + if (EQ(st, empty) || p == stop || clen > stop - p) break; /* NOTE BREAK OUT */ /* no, we must deal with this character */ @@ -982,13 +985,12 @@ sopno stopst; == #define NONCHAR(c) ((c) <= OUT) */ static states -step(g, start, stop, bef, ch, aft) -struct re_guts *g; -sopno start; /* start state within strip */ -sopno stop; /* state after stop state within strip */ -states bef; /* states reachable before */ -wint_t ch; /* character or NONCHAR code */ -states aft; /* states already known reachable after */ +step(struct re_guts *g, + sopno start, /* start state within strip */ + sopno stop, /* state after stop state within strip */ + states bef, /* states reachable before */ + wint_t ch, /* character or NONCHAR code */ + states aft) /* states already known reachable after */ { cset *cs; sop s; @@ -1073,7 +1075,7 @@ states aft; /* states already known reachable after */ OP(s = g->strip[pc+look]) != O_CH; look += OPND(s)) assert(OP(s) == OOR2); - FWD(aft, aft, look); + FWD(aft, aft, look + 1); } break; case OOR2: /* propagate OCH_'s marking */ @@ -1099,17 +1101,16 @@ states aft; /* states already known reachable after */ /* - print - print a set of states == #ifdef REDEBUG - == static void print(struct match *m, char *caption, states st, \ + == static void print(struct match *m, const char *caption, states st, \ == int ch, FILE *d); == #endif */ static void -print(m, caption, st, ch, d) -struct match *m; -char *caption; -states st; -int ch; -FILE *d; +print(struct match *m, + const char *caption, + states st, + int ch, + FILE *d) { struct re_guts *g = m->g; int i; @@ -1132,18 +1133,17 @@ FILE *d; /* - at - print current situation == #ifdef REDEBUG - == static void at(struct match *m, char *title, char *start, char *stop, \ - == sopno startst, sopno stopst); + == static void at(struct match *m, const char *title, const char *start, \ + == const char *stop, sopno startst, sopno stopst); == #endif */ static void -at(m, title, start, stop, startst, stopst) -struct match *m; -char *title; -char *start; -char *stop; -sopno startst; -sopno stopst; +at( struct match *m, + const char *title, + const char *start, + const char *stop, + sopno startst, + sopno stopst) { if (!(m->eflags®_TRACE)) return; @@ -1158,7 +1158,7 @@ sopno stopst; /* - pchar - make a character printable == #ifdef REDEBUG - == static char *pchar(int ch); + == static const char *pchar(int ch); == #endif * * Is this identical to regchar() over in debug.c? Well, yes. But a @@ -1166,9 +1166,8 @@ sopno stopst; * a matching debug.o, and this is convenient. It all disappears in * the non-debug compilation anyway, so it doesn't matter much. */ -static char * /* -> representation */ -pchar(ch) -int ch; +static const char * /* -> representation */ +pchar(int ch) { static char pbuf[10]; diff --git a/regex/FreeBSD/engine.c.patch b/regex/FreeBSD/engine.c.patch index b40e6d0..ebf6da2 100644 --- a/regex/FreeBSD/engine.c.patch +++ b/regex/FreeBSD/engine.c.patch @@ -1,6 +1,6 @@ ---- engine.c.orig 2004-11-25 11:38:32.000000000 -0800 -+++ engine.c 2005-04-18 16:52:09.000000000 -0700 -@@ -270,7 +270,7 @@ int eflags; +--- engine.c.bsdnew 2009-11-11 11:29:04.000000000 -0800 ++++ engine.c 2009-11-11 11:30:28.000000000 -0800 +@@ -272,7 +272,7 @@ matcher(struct re_guts *g, break; assert(m->coldp < m->endp); m->coldp += XMBRTOWC(NULL, m->coldp, @@ -9,16 +9,16 @@ } if (nmatch == 1 && !g->backrefs) break; /* no further info needed */ -@@ -331,7 +331,7 @@ int eflags; +@@ -333,7 +333,7 @@ matcher(struct re_guts *g, NOTE("false alarm"); /* recycle starting later */ start = m->coldp + XMBRTOWC(NULL, m->coldp, -- m->endp - m->coldp, &m->mbs, 0); -+ m->endp - m->coldp, &m->mbs, 0, g->loc); +- stop - m->coldp, &m->mbs, 0); ++ stop - m->coldp, &m->mbs, 0, g->loc); assert(start <= stop); } -@@ -409,7 +409,7 @@ sopno stopst; +@@ -410,7 +410,7 @@ dissect(struct match *m, assert(nope); break; case OCHAR: @@ -27,7 +27,7 @@ break; case OBOL: case OEOL: -@@ -418,7 +418,7 @@ sopno stopst; +@@ -419,7 +419,7 @@ dissect(struct match *m, break; case OANY: case OANYOF: @@ -36,7 +36,7 @@ break; case OBACK_: case O_BACK: -@@ -479,6 +479,10 @@ sopno stopst; +@@ -480,6 +480,10 @@ dissect(struct match *m, sep = ssp; ssp = oldssp; } @@ -47,7 +47,7 @@ assert(sep == rest); /* must exhaust substring */ assert(slow(m, ssp, sep, ssub, esub) == rest); dp = dissect(m, ssp, sep, ssub, esub); -@@ -531,6 +535,14 @@ sopno stopst; +@@ -532,6 +536,14 @@ dissect(struct match *m, i = OPND(m->g->strip[ss]); assert(0 < i && i <= m->g->nsub); m->pmatch[i].rm_so = sp - m->offp; @@ -62,7 +62,7 @@ break; case ORPAREN: i = OPND(m->g->strip[ss]); -@@ -585,14 +597,14 @@ sopno lev; /* PLUS nesting level */ +@@ -586,14 +598,14 @@ backref(struct match *m, case OCHAR: if (sp == stop) return(NULL); @@ -79,7 +79,7 @@ if (wc == BADCHAR) return (NULL); break; -@@ -600,8 +612,8 @@ sopno lev; /* PLUS nesting level */ +@@ -601,8 +613,8 @@ backref(struct match *m, if (sp == stop) return (NULL); cs = &m->g->sets[OPND(s)]; @@ -90,7 +90,7 @@ return(NULL); break; case OBOL: -@@ -625,8 +637,8 @@ sopno lev; /* PLUS nesting level */ +@@ -626,8 +638,8 @@ backref(struct match *m, (sp < m->endp && *(sp-1) == '\n' && (m->g->cflags®_NEWLINE)) || (sp > m->beginp && @@ -101,7 +101,7 @@ { /* yes */ } else return(NULL); -@@ -635,8 +647,8 @@ sopno lev; /* PLUS nesting level */ +@@ -636,8 +648,8 @@ backref(struct match *m, if (( (sp == m->endp && !(m->eflags®_NOTEOL)) || (sp < m->endp && *sp == '\n' && (m->g->cflags®_NEWLINE)) || @@ -112,16 +112,16 @@ { /* yes */ } else return(NULL); -@@ -807,7 +819,7 @@ sopno stopst; - if (p == m->endp) +@@ -811,7 +823,7 @@ fast( struct match *m, + clen = 0; c = OUT; - else + } else - clen = XMBRTOWC(&c, p, m->endp - p, &m->mbs, BADCHAR); + clen = XMBRTOWC(&c, p, m->endp - p, &m->mbs, BADCHAR, m->g->loc); if (EQ(st, fresh)) coldp = p; -@@ -831,12 +843,12 @@ sopno stopst; +@@ -835,12 +847,12 @@ fast( struct match *m, } /* how about a word boundary? */ @@ -138,16 +138,16 @@ flagch = EOW; } if (flagch == BOW || flagch == EOW) { -@@ -861,7 +873,7 @@ sopno stopst; +@@ -865,7 +877,7 @@ fast( struct match *m, assert(coldp != NULL); m->coldp = coldp; if (ISSET(st, stopst)) -- return(p+XMBRTOWC(NULL, p, m->endp - p, &m->mbs, 0)); -+ return(p+XMBRTOWC(NULL, p, m->endp - p, &m->mbs, 0, m->g->loc)); +- return(p+XMBRTOWC(NULL, p, stop - p, &m->mbs, 0)); ++ return(p+XMBRTOWC(NULL, p, stop - p, &m->mbs, 0, m->g->loc)); else return(NULL); } -@@ -913,7 +925,7 @@ sopno stopst; +@@ -916,7 +928,7 @@ slow( struct match *m, c = OUT; clen = 0; } else @@ -156,7 +156,7 @@ /* is there an EOL and/or BOL between lastc and c? */ flagch = '\0'; -@@ -935,12 +947,12 @@ sopno stopst; +@@ -938,12 +950,12 @@ slow( struct match *m, } /* how about a word boundary? */ @@ -173,7 +173,7 @@ flagch = EOW; } if (flagch == BOW || flagch == EOW) { -@@ -1031,7 +1043,7 @@ states aft; /* states already known re +@@ -1033,7 +1045,7 @@ step(struct re_guts *g, break; case OANYOF: cs = &g->sets[OPND(s)]; diff --git a/regex/FreeBSD/re_format.7 b/regex/FreeBSD/re_format.7 index 4527043..5109e93 100644 --- a/regex/FreeBSD/re_format.7 +++ b/regex/FreeBSD/re_format.7 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)re_format.7 8.3 (Berkeley) 3/20/94 -.\" $FreeBSD: src/lib/libc/regex/re_format.7,v 1.11 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/regex/re_format.7,v 1.12 2008/09/05 17:41:20 keramida Exp $ .\" .Dd March 20, 1994 .Dt RE_FORMAT 7 @@ -288,6 +288,14 @@ These stand for the character classes defined in A locale may provide others. A character class may not be used as an endpoint of a range. .Pp +A bracketed expression like +.Ql [[:class:]] +can be used to match a single character that belongs to a character +class. +The reverse, matching any character that does not belong to a specific +class, the negation operator of bracket expressions may be used: +.Ql [^[:class:]] . +.Pp There are two special cases\(dd of bracket expressions: the bracket expressions .Ql [[:<:]] diff --git a/regex/FreeBSD/regcomp.c b/regex/FreeBSD/regcomp.c index 268a579..6691eec 100644 --- a/regex/FreeBSD/regcomp.c +++ b/regex/FreeBSD/regcomp.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -41,7 +37,7 @@ static char sccsid[] = "@(#)regcomp.c 8.5 (Berkeley) 3/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/regex/regcomp.c,v 1.34 2004/10/03 15:42:59 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/regex/regcomp.c,v 1.36 2007/06/11 03:05:54 delphij Exp $"); #include #include @@ -182,10 +178,9 @@ static int never = 0; /* for use in asserts; shuts lint up */ = #define REG_DUMP 0200 */ int /* 0 success, otherwise REG_something */ -regcomp(preg, pattern, cflags) -regex_t * __restrict preg; -const char * __restrict pattern; -int cflags; +regcomp(regex_t * __restrict preg, + const char * __restrict pattern, + int cflags) { struct parse pa; struct re_guts *g; @@ -293,9 +288,8 @@ int cflags; == static void p_ere(struct parse *p, int stop); */ static void -p_ere(p, stop) -struct parse *p; -int stop; /* character this ERE should end at */ +p_ere(struct parse *p, + int stop) /* character this ERE should end at */ { char c; sopno prevback; @@ -339,8 +333,7 @@ int stop; /* character this ERE should end at */ == static void p_ere_exp(struct parse *p); */ static void -p_ere_exp(p) -struct parse *p; +p_ere_exp(struct parse *p) { char c; wint_t wc; @@ -491,8 +484,7 @@ struct parse *p; == static void p_str(struct parse *p); */ static void -p_str(p) -struct parse *p; +p_str(struct parse *p) { (void)REQUIRE(MORE(), REG_EMPTY); while (MORE()) @@ -510,10 +502,9 @@ struct parse *p; * The amount of lookahead needed to avoid this kludge is excessive. */ static void -p_bre(p, end1, end2) -struct parse *p; -int end1; /* first terminating character */ -int end2; /* second terminating character */ +p_bre(struct parse *p, + int end1, /* first terminating character */ + int end2) /* second terminating character */ { sopno start = HERE(); int first = 1; /* first subexpression? */ @@ -543,9 +534,8 @@ int end2; /* second terminating character */ == static int p_simp_re(struct parse *p, int starordinary); */ static int /* was the simple RE an unbackslashed $? */ -p_simp_re(p, starordinary) -struct parse *p; -int starordinary; /* is a leading * an ordinary character? */ +p_simp_re(struct parse *p, + int starordinary) /* is a leading * an ordinary character? */ { int c; int count; @@ -664,8 +654,7 @@ int starordinary; /* is a leading * an ordinary character? */ == static int p_count(struct parse *p); */ static int /* the value */ -p_count(p) -struct parse *p; +p_count(struct parse *p) { int count = 0; int ndigits = 0; @@ -684,8 +673,7 @@ struct parse *p; == static void p_bracket(struct parse *p); */ static void -p_bracket(p) -struct parse *p; +p_bracket(struct parse *p) { cset *cs; wint_t ch; @@ -737,9 +725,7 @@ struct parse *p; == static void p_b_term(struct parse *p, cset *cs); */ static void -p_b_term(p, cs) -struct parse *p; -cset *cs; +p_b_term(struct parse *p, cset *cs) { char c; wint_t start, finish; @@ -814,9 +800,7 @@ cset *cs; == static void p_b_cclass(struct parse *p, cset *cs); */ static void -p_b_cclass(p, cs) -struct parse *p; -cset *cs; +p_b_cclass(struct parse *p, cset *cs) { char *sp = p->next; size_t len; @@ -846,9 +830,7 @@ cset *cs; * This implementation is incomplete. xxx */ static void -p_b_eclass(p, cs) -struct parse *p; -cset *cs; +p_b_eclass(struct parse *p, cset *cs) { wint_t c; @@ -861,8 +843,7 @@ cset *cs; == static char p_b_symbol(struct parse *p); */ static wint_t /* value of symbol */ -p_b_symbol(p) -struct parse *p; +p_b_symbol(struct parse *p) { wint_t value; @@ -881,9 +862,8 @@ struct parse *p; == static char p_b_coll_elem(struct parse *p, int endc); */ static wint_t /* value of collating element */ -p_b_coll_elem(p, endc) -struct parse *p; -wint_t endc; /* name ended by endc,']' */ +p_b_coll_elem(struct parse *p, + wint_t endc) /* name ended by endc,']' */ { char *sp = p->next; struct cname *cp; @@ -917,8 +897,7 @@ wint_t endc; /* name ended by endc,']' */ == static char othercase(int ch); */ static wint_t /* if no counterpart, return ch */ -othercase(ch) -wint_t ch; +othercase(wint_t ch) { assert(iswalpha(ch)); if (iswupper(ch)) @@ -936,9 +915,7 @@ wint_t ch; * Boy, is this implementation ever a kludge... */ static void -bothcases(p, ch) -struct parse *p; -wint_t ch; +bothcases(struct parse *p, wint_t ch) { char *oldnext = p->next; char *oldend = p->end; @@ -965,9 +942,7 @@ wint_t ch; == static void ordinary(struct parse *p, int ch); */ static void -ordinary(p, ch) -struct parse *p; -wint_t ch; +ordinary(struct parse *p, wint_t ch) { cset *cs; @@ -994,8 +969,7 @@ wint_t ch; * Boy, is this implementation ever a kludge... */ static void -nonnewline(p) -struct parse *p; +nonnewline(struct parse *p) { char *oldnext = p->next; char *oldend = p->end; @@ -1018,11 +992,10 @@ struct parse *p; == static void repeat(struct parse *p, sopno start, int from, int to); */ static void -repeat(p, start, from, to) -struct parse *p; -sopno start; /* operand from here to end of strip */ -int from; /* repeated from this number */ -int to; /* to this number of times (maybe INFINITY) */ +repeat(struct parse *p, + sopno start, /* operand from here to end of strip */ + int from, /* repeated from this number */ + int to) /* to this number of times (maybe INFINITY) */ { sopno finish = HERE(); # define N 2 @@ -1091,8 +1064,7 @@ int to; /* to this number of times (maybe INFINITY) */ - character can't be converted. Returns the number of bytes consumed. */ static wint_t -wgetnext(p) -struct parse *p; +wgetnext(struct parse *p) { mbstate_t mbs; wchar_t wc; @@ -1115,9 +1087,7 @@ struct parse *p; == static int seterr(struct parse *p, int e); */ static int /* useless but makes type checking happy */ -seterr(p, e) -struct parse *p; -int e; +seterr(struct parse *p, int e) { if (p->error == 0) /* keep earliest error condition */ p->error = e; @@ -1131,8 +1101,7 @@ int e; == static cset *allocset(struct parse *p); */ static cset * -allocset(p) -struct parse *p; +allocset(struct parse *p) { cset *cs, *ncs; @@ -1153,9 +1122,7 @@ struct parse *p; == static void freeset(struct parse *p, cset *cs); */ static void -freeset(p, cs) -struct parse *p; -cset *cs; +freeset(struct parse *p, cset *cs) { cset *top = &p->g->sets[p->g->ncsets]; @@ -1172,8 +1139,7 @@ cset *cs; - returning it if so, otherwise returning OUT. */ static wint_t -singleton(cs) -cset *cs; +singleton(cset *cs) { wint_t i, s, n; @@ -1195,10 +1161,7 @@ cset *cs; - CHadd - add character to character set. */ static void -CHadd(p, cs, ch) -struct parse *p; -cset *cs; -wint_t ch; +CHadd(struct parse *p, cset *cs, wint_t ch) { wint_t nch, *newwides; assert(ch >= 0); @@ -1226,10 +1189,7 @@ wint_t ch; - CHaddrange - add all characters in the range [min,max] to a character set. */ static void -CHaddrange(p, cs, min, max) -struct parse *p; -cset *cs; -wint_t min, max; +CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max) { crange *newranges; @@ -1253,10 +1213,7 @@ wint_t min, max; - CHaddtype - add all characters of a certain type to a character set. */ static void -CHaddtype(p, cs, wct) -struct parse *p; -cset *cs; -wctype_t wct; +CHaddtype(struct parse *p, cset *cs, wctype_t wct) { wint_t i; wctype_t *newtypes; @@ -1279,10 +1236,9 @@ wctype_t wct; == static sopno dupl(struct parse *p, sopno start, sopno finish); */ static sopno /* start of duplicate */ -dupl(p, start, finish) -struct parse *p; -sopno start; /* from here */ -sopno finish; /* to this less one */ +dupl(struct parse *p, + sopno start, /* from here */ + sopno finish) /* to this less one */ { sopno ret = HERE(); sopno len = finish - start; @@ -1307,10 +1263,7 @@ sopno finish; /* to this less one */ * some changes to the data structures. Maybe later. */ static void -doemit(p, op, opnd) -struct parse *p; -sop op; -size_t opnd; +doemit(struct parse *p, sop op, size_t opnd) { /* avoid making error situations worse */ if (p->error != 0) @@ -1333,11 +1286,7 @@ size_t opnd; == static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos); */ static void -doinsert(p, op, opnd, pos) -struct parse *p; -sop op; -size_t opnd; -sopno pos; +doinsert(struct parse *p, sop op, size_t opnd, sopno pos) { sopno sn; sop s; @@ -1373,10 +1322,7 @@ sopno pos; == static void dofwd(struct parse *p, sopno pos, sop value); */ static void -dofwd(p, pos, value) -struct parse *p; -sopno pos; -sop value; +dofwd(struct parse *p, sopno pos, sop value) { /* avoid making error situations worse */ if (p->error != 0) @@ -1391,9 +1337,7 @@ sop value; == static void enlarge(struct parse *p, sopno size); */ static void -enlarge(p, size) -struct parse *p; -sopno size; +enlarge(struct parse *p, sopno size) { sop *sp; @@ -1414,9 +1358,7 @@ sopno size; == static void stripsnug(struct parse *p, struct re_guts *g); */ static void -stripsnug(p, g) -struct parse *p; -struct re_guts *g; +stripsnug(struct parse *p, struct re_guts *g) { g->nstates = p->slen; g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop)); @@ -1437,9 +1379,7 @@ struct re_guts *g; * Note that must and mlen got initialized during setup. */ static void -findmust(p, g) -struct parse *p; -struct re_guts *g; +findmust(struct parse *p, struct re_guts *g) { sop *scan; sop *start; @@ -1613,9 +1553,7 @@ struct re_guts *g; * re paths. */ static int -altoffset(scan, offset) -sop *scan; -int offset; +altoffset(sop *scan, int offset) { int largest; int try; @@ -1690,9 +1628,7 @@ int offset; * the value of the character from the text that was mismatched. */ static void -computejumps(p, g) -struct parse *p; -struct re_guts *g; +computejumps(struct parse *p, struct re_guts *g) { int ch; int mindex; @@ -1736,9 +1672,7 @@ struct re_guts *g; * the search algorithm works. */ static void -computematchjumps(p, g) -struct parse *p; -struct re_guts *g; +computematchjumps(struct parse *p, struct re_guts *g) { int mindex; /* General "must" iterator */ int suffix; /* Keeps track of matching suffix */ @@ -1812,9 +1746,7 @@ struct re_guts *g; == static sopno pluscount(struct parse *p, struct re_guts *g); */ static sopno /* nesting depth */ -pluscount(p, g) -struct parse *p; -struct re_guts *g; +pluscount(struct parse *p, struct re_guts *g) { sop *scan; sop s; diff --git a/regex/FreeBSD/regcomp.c.patch b/regex/FreeBSD/regcomp.c.patch index a52baac..4dcf2cd 100644 --- a/regex/FreeBSD/regcomp.c.patch +++ b/regex/FreeBSD/regcomp.c.patch @@ -1,15 +1,15 @@ ---- regcomp.c.orig 2004-11-25 11:38:32.000000000 -0800 -+++ regcomp.c 2005-04-05 14:46:18.000000000 -0700 -@@ -43,6 +43,8 @@ +--- regcomp.c.orig 2010-06-21 14:05:04.000000000 -0700 ++++ regcomp.c 2010-06-21 14:23:51.000000000 -0700 +@@ -39,6 +39,8 @@ static char sccsid[] = "@(#)regcomp.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/regex/regcomp.c,v 1.34 2004/10/03 15:42:59 stefanf Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/regex/regcomp.c,v 1.36 2007/06/11 03:05:54 delphij Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -73,6 +75,9 @@ +@@ -69,6 +71,9 @@ struct parse { sopno ssize; /* malloced strip size (allocated) */ sopno slen; /* malloced strip length (used) */ int ncsalloc; /* number of csets allocated */ @@ -19,7 +19,7 @@ struct re_guts *g; # define NPAREN 10 /* we need to remember () 1-9 for back refs */ sopno pbegin[NPAREN]; /* -> ( ([0] unused) */ -@@ -97,7 +102,7 @@ +@@ -93,7 +98,7 @@ static void p_b_cclass(struct parse *p, static void p_b_eclass(struct parse *p, cset *cs); static wint_t p_b_symbol(struct parse *p); static wint_t p_b_coll_elem(struct parse *p, wint_t endc); @@ -28,7 +28,7 @@ static void bothcases(struct parse *p, wint_t ch); static void ordinary(struct parse *p, wint_t ch); static void nonnewline(struct parse *p); -@@ -108,7 +113,7 @@ +@@ -104,7 +109,7 @@ static void freeset(struct parse *p, cse static void CHadd(struct parse *p, cset *cs, wint_t ch); static void CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max); static void CHaddtype(struct parse *p, cset *cs, wctype_t wct); @@ -37,7 +37,7 @@ static sopno dupl(struct parse *p, sopno start, sopno finish); static void doemit(struct parse *p, sop op, size_t opnd); static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos); -@@ -227,10 +232,14 @@ +@@ -222,10 +227,14 @@ regcomp(regex_t * __restrict preg, p->end = p->next + len; p->error = 0; p->ncsalloc = 0; @@ -52,7 +52,7 @@ g->sets = NULL; g->ncsets = 0; g->cflags = cflags; -@@ -308,8 +317,12 @@ +@@ -302,8 +311,12 @@ p_ere(struct parse *p, conc = HERE(); while (MORE() && (c = PEEK()) != '|' && c != stop) p_ere_exp(p); @@ -66,7 +66,7 @@ if (!EAT('|')) break; /* NOTE BREAK OUT */ -@@ -417,7 +430,7 @@ +@@ -410,7 +423,7 @@ p_ere_exp(struct parse *p) ordinary(p, wc); break; case '{': /* okay as ordinary except if digit follows */ @@ -75,7 +75,7 @@ /* FALLTHROUGH */ default: p->next--; -@@ -431,7 +444,7 @@ +@@ -424,7 +437,7 @@ p_ere_exp(struct parse *p) c = PEEK(); /* we call { a repetition if followed by a digit */ if (!( c == '*' || c == '+' || c == '?' || @@ -84,7 +84,7 @@ return; /* no repetition, we're done */ NEXT(); -@@ -460,7 +473,7 @@ +@@ -453,7 +466,7 @@ p_ere_exp(struct parse *p) case '{': count = p_count(p); if (EAT(',')) { @@ -93,7 +93,7 @@ count2 = p_count(p); (void)REQUIRE(count <= count2, REG_BADBR); } else /* single number with comma */ -@@ -481,7 +494,7 @@ +@@ -474,7 +487,7 @@ p_ere_exp(struct parse *p) return; c = PEEK(); if (!( c == '*' || c == '+' || c == '?' || @@ -102,9 +102,9 @@ return; SETERROR(REG_BADRPT); } -@@ -494,7 +507,12 @@ - p_str(p) - struct parse *p; +@@ -486,7 +499,12 @@ p_ere_exp(struct parse *p) + static void + p_str(struct parse *p) { +#if __DARWIN_UNIX03 + if (!p->zerorepeats) REQUIRE(MORE(), REG_EMPTY); @@ -115,7 +115,7 @@ while (MORE()) ordinary(p, WGETNEXT()); } -@@ -534,8 +552,12 @@ +@@ -525,8 +543,12 @@ p_bre(struct parse *p, p->g->iflags |= USEEOL; p->g->neol++; } @@ -129,7 +129,7 @@ } /* -@@ -609,12 +631,22 @@ +@@ -599,12 +621,22 @@ p_simp_re(struct parse *p, i = (c&~BACKSL) - '0'; assert(i < NPAREN); if (p->pend[i] != 0) { @@ -152,7 +152,7 @@ EMIT(O_BACK, i); } else SETERROR(REG_ESUBREG); -@@ -637,9 +669,10 @@ +@@ -627,9 +659,10 @@ p_simp_re(struct parse *p, INSERT(OQUEST_, pos); ASTERN(O_QUEST, pos); } else if (EATTWO('\\', '{')) { @@ -164,7 +164,7 @@ count2 = p_count(p); (void)REQUIRE(count <= count2, REG_BADBR); } else /* single number with comma */ -@@ -670,7 +703,7 @@ +@@ -659,7 +692,7 @@ p_count(struct parse *p) int count = 0; int ndigits = 0; @@ -173,7 +173,7 @@ count = count*10 + (GETNEXT() - '0'); ndigits++; } -@@ -709,10 +742,22 @@ +@@ -697,10 +730,22 @@ p_bracket(struct parse *p) cs->icase = 1; if (EAT('^')) cs->invert = 1; @@ -196,7 +196,7 @@ while (MORE() && PEEK() != ']' && !SEETWO('-', ']')) p_b_term(p, cs); if (EAT('-')) -@@ -725,7 +770,7 @@ +@@ -713,7 +758,7 @@ p_bracket(struct parse *p) if (cs->invert && p->g->cflags®_NEWLINE) cs->bmp['\n' >> 3] |= 1 << ('\n' & 7); @@ -205,7 +205,7 @@ ordinary(p, ch); freeset(p, cs); } else -@@ -751,8 +796,16 @@ +@@ -737,8 +782,16 @@ p_b_term(struct parse *p, cset *cs) c = (MORE2()) ? PEEK2() : '\0'; break; case '-': @@ -222,7 +222,7 @@ break; default: c = '\0'; -@@ -773,7 +826,11 @@ +@@ -759,7 +812,11 @@ p_b_term(struct parse *p, cset *cs) NEXT2(); (void)REQUIRE(MORE(), REG_EBRACK); c = PEEK(); @@ -234,7 +234,7 @@ p_b_eclass(p, cs); (void)REQUIRE(MORE(), REG_EBRACK); (void)REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); -@@ -792,14 +849,14 @@ +@@ -778,14 +835,14 @@ p_b_term(struct parse *p, cset *cs) if (start == finish) CHadd(p, cs, start); else { @@ -253,7 +253,7 @@ ) CHadd(p, cs, i); } -@@ -823,7 +880,7 @@ +@@ -807,7 +864,7 @@ p_b_cclass(struct parse *p, cset *cs) wctype_t wct; char clname[16]; @@ -262,7 +262,7 @@ NEXT(); len = p->next - sp; if (len >= sizeof(clname) - 1) { -@@ -832,7 +889,7 @@ +@@ -816,7 +873,7 @@ p_b_cclass(struct parse *p, cset *cs) } memcpy(clname, sp, len); clname[len] = '\0'; @@ -271,7 +271,7 @@ SETERROR(REG_ECTYPE); return; } -@@ -842,16 +899,40 @@ +@@ -826,14 +883,38 @@ p_b_cclass(struct parse *p, cset *cs) /* - p_b_eclass - parse an equivalence-class name and deal with it == static void p_b_eclass(struct parse *p, cset *cs); @@ -279,9 +279,7 @@ - * This implementation is incomplete. xxx */ static void - p_b_eclass(p, cs) - struct parse *p; - cset *cs; + p_b_eclass(struct parse *p, cset *cs) { - wint_t c; - @@ -316,8 +314,12 @@ c = p_b_coll_elem(p, '='); CHadd(p, cs, c); } -@@ -889,7 +970,7 @@ - struct cname *cp; +@@ -866,10 +947,10 @@ p_b_coll_elem(struct parse *p, + wint_t endc) /* name ended by endc,']' */ + { + char *sp = p->next; +- struct cname *cp; ++ const struct cname *cp; int len; mbstate_t mbs; - wchar_t wc; @@ -325,7 +327,7 @@ size_t clen; while (MORE() && !SEETWO(endc, ']')) -@@ -903,9 +984,10 @@ +@@ -883,9 +964,10 @@ p_b_coll_elem(struct parse *p, if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') return(cp->code); /* known name */ memset(&mbs, 0, sizeof(mbs)); @@ -339,18 +341,16 @@ SETERROR(REG_ILLSEQ); else SETERROR(REG_ECOLLATE); /* neither */ -@@ -914,17 +996,18 @@ +@@ -894,16 +976,16 @@ p_b_coll_elem(struct parse *p, /* - othercase - return the case counterpart of an alphabetic - == static char othercase(int ch); -+ == static char othercase(int ch, locale_t loc); ++ == static char othercase(wint_t ch, locale_t loc); */ static wint_t /* if no counterpart, return ch */ --othercase(ch) -+othercase(ch, loc) - wint_t ch; -+locale_t loc; +-othercase(wint_t ch) ++othercase(wint_t ch, locale_t loc) { - assert(iswalpha(ch)); - if (iswupper(ch)) @@ -365,7 +365,7 @@ else /* peculiar, but could happen */ return(ch); } -@@ -946,10 +1029,10 @@ +@@ -923,10 +1005,10 @@ bothcases(struct parse *p, wint_t ch) size_t n; mbstate_t mbs; @@ -378,7 +378,7 @@ assert(n != (size_t)-1); bracket[n] = ']'; bracket[n + 1] = '\0'; -@@ -971,7 +1054,7 @@ +@@ -946,7 +1028,7 @@ ordinary(struct parse *p, wint_t ch) { cset *cs; @@ -387,7 +387,7 @@ bothcases(p, ch); else if ((ch & OPDMASK) == ch) EMIT(OCHAR, ch); -@@ -1039,10 +1122,22 @@ +@@ -1012,10 +1094,22 @@ repeat(struct parse *p, switch (REP(MAP(from), MAP(to))) { case REP(0, 0): /* must be user doing this */ DROP(finish-start); /* drop the operand */ @@ -411,7 +411,7 @@ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ INSERT(OCH_, start); /* offset is wrong... */ repeat(p, start+1, 1, to); -@@ -1056,6 +1151,10 @@ +@@ -1029,6 +1123,10 @@ repeat(struct parse *p, /* done */ break; case REP(1, N): /* as x?x{1,n-1} */ @@ -422,7 +422,7 @@ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ INSERT(OCH_, start); ASTERN(OOR1, start); -@@ -1063,6 +1162,7 @@ +@@ -1036,6 +1134,7 @@ repeat(struct parse *p, EMIT(OOR2, 0); /* offset very wrong... */ AHEAD(THERE()); /* ...so fix it */ ASTERN(O_CH, THERETHERE()); @@ -430,7 +430,7 @@ copy = dupl(p, start+1, finish+1); assert(copy == finish+4); repeat(p, copy, 1, to-1); -@@ -1099,7 +1199,7 @@ +@@ -1071,7 +1170,7 @@ wgetnext(struct parse *p) size_t n; memset(&mbs, 0, sizeof(mbs)); @@ -439,14 +439,12 @@ if (n == (size_t)-1 || n == (size_t)-2) { SETERROR(REG_ILLSEQ); return (0); -@@ -1172,13 +1272,14 @@ +@@ -1139,12 +1238,12 @@ freeset(struct parse *p, cset *cs) - returning it if so, otherwise returning OUT. */ static wint_t --singleton(cs) -+singleton(cs, loc) - cset *cs; -+locale_t loc; +-singleton(cset *cs) ++singleton(cset *cs, locale_t loc) { wint_t i, s, n; @@ -456,7 +454,7 @@ n++; s = i; } -@@ -1215,9 +1316,9 @@ +@@ -1178,9 +1277,9 @@ CHadd(struct parse *p, cset *cs, wint_t cs->wides[cs->nwides++] = ch; } if (cs->icase) { @@ -468,7 +466,7 @@ cs->bmp[nch >> 3] |= 1 << (nch & 7); } } -@@ -1262,7 +1363,7 @@ +@@ -1219,7 +1318,7 @@ CHaddtype(struct parse *p, cset *cs, wct wctype_t *newtypes; for (i = 0; i < NC; i++) @@ -477,7 +475,7 @@ CHadd(p, cs, i); newtypes = realloc(cs->types, (cs->ntypes + 1) * sizeof(*cs->types)); -@@ -1451,6 +1552,7 @@ +@@ -1391,6 +1490,7 @@ findmust(struct parse *p, struct re_guts char buf[MB_LEN_MAX]; size_t clen; mbstate_t mbs; @@ -485,7 +483,7 @@ /* avoid making error situations worse */ if (p->error != 0) -@@ -1461,8 +1563,8 @@ +@@ -1401,8 +1501,8 @@ findmust(struct parse *p, struct re_guts * multibyte character strings, but it's safe for at least * UTF-8 (see RFC 3629). */ @@ -496,7 +494,7 @@ return; /* find the longest OCHAR sequence in strip */ -@@ -1478,7 +1580,7 @@ +@@ -1418,7 +1518,7 @@ findmust(struct parse *p, struct re_guts memset(&mbs, 0, sizeof(mbs)); newstart = scan - 1; } @@ -505,7 +503,7 @@ if (clen == (size_t)-1) goto toohard; newlen += clen; -@@ -1597,7 +1699,7 @@ +@@ -1537,7 +1637,7 @@ findmust(struct parse *p, struct re_guts while (cp < g->must + g->mlen) { while (OP(s = *scan++) != OCHAR) continue; diff --git a/regex/FreeBSD/regerror.c b/regex/FreeBSD/regerror.c index 4e43f3d..9364bd4 100644 --- a/regex/FreeBSD/regerror.c +++ b/regex/FreeBSD/regerror.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -41,7 +37,7 @@ static char sccsid[] = "@(#)regerror.c 8.4 (Berkeley) 3/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/regex/regerror.c,v 1.9 2004/07/12 06:07:26 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/regex/regerror.c,v 1.11 2007/06/11 03:05:54 delphij Exp $"); #include #include @@ -116,11 +112,10 @@ static struct rerr { */ /* ARGSUSED */ size_t -regerror(errcode, preg, errbuf, errbuf_size) -int errcode; -const regex_t * __restrict preg; -char * __restrict errbuf; -size_t errbuf_size; +regerror(int errcode, + const regex_t * __restrict preg, + char * __restrict errbuf, + size_t errbuf_size) { struct rerr *r; size_t len; @@ -164,9 +159,7 @@ size_t errbuf_size; == static char *regatoi(const regex_t *preg, char *localbuf); */ static char * -regatoi(preg, localbuf) -const regex_t *preg; -char *localbuf; +regatoi(const regex_t *preg, char *localbuf) { struct rerr *r; diff --git a/regex/FreeBSD/regerror.c.patch b/regex/FreeBSD/regerror.c.patch new file mode 100644 index 0000000..0b7c53b --- /dev/null +++ b/regex/FreeBSD/regerror.c.patch @@ -0,0 +1,38 @@ +--- regerror.c.orig 2010-05-05 14:42:17.000000000 -0700 ++++ regerror.c 2010-05-05 14:42:24.000000000 -0700 +@@ -85,10 +85,10 @@ static char *regatoi(const regex_t *preg + = #define REG_ATOI 255 // convert name to number (!) + = #define REG_ITOA 0400 // convert number to name (!) + */ +-static struct rerr { ++static const struct rerr { + int code; +- char *name; +- char *explain; ++ const char *name; ++ const char *explain; + } rerrs[] = { + {REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"}, + {REG_BADPAT, "REG_BADPAT", "invalid regular expression"}, +@@ -122,10 +122,10 @@ const regex_t * __restrict preg; + char * __restrict errbuf; + size_t errbuf_size; + { +- struct rerr *r; ++ const struct rerr *r; + size_t len; + int target = errcode &~ REG_ITOA; +- char *s; ++ const char *s; + char convbuf[50]; + + if (errcode == REG_ATOI) +@@ -168,7 +168,7 @@ regatoi(preg, localbuf) + const regex_t *preg; + char *localbuf; + { +- struct rerr *r; ++ const struct rerr *r; + + for (r = rerrs; r->code != 0; r++) + if (strcmp(r->name, preg->re_endp) == 0) diff --git a/regex/FreeBSD/regex.3 b/regex/FreeBSD/regex.3 index 33fed75..f848d66 100644 --- a/regex/FreeBSD/regex.3 +++ b/regex/FreeBSD/regex.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)regex.3 8.4 (Berkeley) 3/20/94 -.\" $FreeBSD: src/lib/libc/regex/regex.3,v 1.17 2004/07/12 11:03:42 tjr Exp $ +.\" $FreeBSD: src/lib/libc/regex/regex.3,v 1.21 2007/01/09 00:28:04 imp Exp $ .\" -.Dd July 12, 2004 +.Dd August 17, 2005 .Dt REGEX 3 .Os .Sh NAME @@ -436,7 +432,7 @@ places the NUL-terminated message into the buffer pointed to by limiting the length (including the NUL) to at most .Fa errbuf_size bytes. -If the whole message won't fit, +If the whole message will not fit, as much of it as will fit before the terminating NUL is supplied. In any case, the returned value is the size of buffer needed to hold the whole @@ -588,14 +584,6 @@ and beginning and ending subexpressions in obsolete .Pq Dq basic REs are anchors, not ordinary characters. -.Sh SEE ALSO -.Xr grep 1 , -.Xr re_format 7 -.Pp -.St -p1003.2 , -sections 2.8 (Regular Expression Notation) -and -B.5 (C Binding for Regular Expression Matching). .Sh DIAGNOSTICS Non-zero error codes from .Fn regcomp @@ -649,12 +637,20 @@ operand invalid .It Dv REG_EMPTY empty (sub)expression .It Dv REG_ASSERT -can't happen - you found a bug +cannot happen - you found a bug .It Dv REG_INVARG invalid argument, e.g.\& negative-length string .It Dv REG_ILLSEQ illegal byte sequence (bad multibyte character) .El +.Sh SEE ALSO +.Xr grep 1 , +.Xr re_format 7 +.Pp +.St -p1003.2 , +sections 2.8 (Regular Expression Notation) +and +B.5 (C Binding for Regular Expression Matching). .Sh HISTORY Originally written by .An Henry Spencer . @@ -715,7 +711,7 @@ are legal REs because is a special character only in the presence of a previous unmatched .Ql (\& . -This can't be fixed until the spec is fixed. +This cannot be fixed until the spec is fixed. .Pp The standard's definition of back references is vague. For example, does @@ -727,3 +723,5 @@ behavior in such cases should not be relied on. .Pp The implementation of word-boundary matching is a bit of a kludge, and bugs may lurk in combinations of word-boundary matching and anchoring. +.Pp +Word-boundary matching does not work properly in multibyte locales. diff --git a/regex/FreeBSD/regex.3.patch b/regex/FreeBSD/regex.3.patch index bc740ce..ec526a2 100644 --- a/regex/FreeBSD/regex.3.patch +++ b/regex/FreeBSD/regex.3.patch @@ -1,6 +1,6 @@ ---- regex.3 2004-11-25 11:38:32.000000000 -0800 -+++ regex.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -41,8 +41,8 @@ +--- regex.3.bsdnew 2009-11-11 11:29:04.000000000 -0800 ++++ regex.3 2009-11-11 11:29:04.000000000 -0800 +@@ -37,8 +37,8 @@ .Os .Sh NAME .Nm regcomp , @@ -10,7 +10,7 @@ .Nm regfree .Nd regular-expression library .Sh LIBRARY -@@ -51,20 +51,29 @@ +@@ -47,20 +47,29 @@ .In regex.h .Ft int .Fo regcomp @@ -49,7 +49,7 @@ .Sh DESCRIPTION These routines implement .St -p1003.2 -@@ -75,12 +84,11 @@ +@@ -71,12 +80,11 @@ see The .Fn regcomp function diff --git a/regex/FreeBSD/regex2.h b/regex/FreeBSD/regex2.h index c971c9c..13bbf64 100644 --- a/regex/FreeBSD/regex2.h +++ b/regex/FreeBSD/regex2.h @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ * SUCH DAMAGE. * * @(#)regex2.h 8.4 (Berkeley) 3/20/94 - * $FreeBSD: src/lib/libc/regex/regex2.h,v 1.8 2004/07/12 07:35:59 tjr Exp $ + * $FreeBSD: src/lib/libc/regex/regex2.h,v 1.11 2007/01/09 00:28:04 imp Exp $ */ /* @@ -127,9 +123,7 @@ typedef struct { } cset; static int -CHIN1(cs, ch) -cset *cs; -wint_t ch; +CHIN1(cset *cs, wint_t ch) { int i; @@ -150,9 +144,7 @@ wint_t ch; } static __inline int -CHIN(cs, ch) -cset *cs; -wint_t ch; +CHIN(cset *cs, wint_t ch) { assert(ch >= 0); @@ -196,5 +188,5 @@ struct re_guts { }; /* misc utilities */ -#define OUT (-2) /* a non-character value */ +#define OUT (CHAR_MIN - 1) /* a non-character value */ #define ISWORD(c) (iswalnum((uch)(c)) || (c) == '_') diff --git a/regex/FreeBSD/regex2.h.patch b/regex/FreeBSD/regex2.h.patch index 1b07d49..ec20caa 100644 --- a/regex/FreeBSD/regex2.h.patch +++ b/regex/FreeBSD/regex2.h.patch @@ -1,6 +1,6 @@ ---- regex2.h.orig 2005-04-19 14:43:24.000000000 -0700 -+++ regex2.h 2005-04-19 14:41:08.000000000 -0700 -@@ -124,16 +124,26 @@ +--- regex2.h.bsdnew 2009-11-11 11:29:04.000000000 -0800 ++++ regex2.h 2009-11-11 12:18:35.000000000 -0800 +@@ -120,14 +120,23 @@ typedef struct { int nranges; int invert; int icase; @@ -11,11 +11,8 @@ +#include "collate.h" + static int --CHIN1(cs, ch) -+CHIN1(cs, ch, loc) - cset *cs; - wint_t ch; -+locale_t loc; +-CHIN1(cset *cs, wint_t ch) ++CHIN1(cset *cs, wint_t ch, locale_t loc) { int i; @@ -28,7 +25,7 @@ if (ch < NC) return (((cs->bmp[ch >> 3] & (1 << (ch & 7))) != 0) ^ cs->invert); -@@ -144,26 +154,27 @@ +@@ -138,24 +147,24 @@ CHIN1(cset *cs, wint_t ch) if (cs->ranges[i].min <= ch && ch <= cs->ranges[i].max) return (!cs->invert); for (i = 0; i < cs->ntypes; i++) @@ -39,11 +36,8 @@ } static __inline int --CHIN(cs, ch) -+CHIN(cs, ch, loc) - cset *cs; - wint_t ch; -+locale_t loc; +-CHIN(cset *cs, wint_t ch) ++CHIN(cset *cs, wint_t ch, locale_t loc) { assert(ch >= 0); @@ -62,7 +56,7 @@ } /* -@@ -193,8 +204,9 @@ +@@ -185,8 +194,9 @@ struct re_guts { size_t nsub; /* copy of re_nsub */ int backrefs; /* does it use back references? */ sopno nplus; /* how deep does it nest +s? */ @@ -70,7 +64,7 @@ }; /* misc utilities */ --#define OUT (-2) /* a non-character value */ +-#define OUT (CHAR_MIN - 1) /* a non-character value */ -#define ISWORD(c) (iswalnum((uch)(c)) || (c) == '_') -+#define OUT (-130) /* a non-character value */ ++#define OUT (CHAR_MIN - 2) /* a non-character value */ +#define ISWORD(c,l) (iswalnum_l((uch)(c), l) || (c) == '_') diff --git a/regex/FreeBSD/regexec.c b/regex/FreeBSD/regexec.c index c570369..4bc04ae 100644 --- a/regex/FreeBSD/regexec.c +++ b/regex/FreeBSD/regexec.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -41,7 +37,7 @@ static char sccsid[] = "@(#)regexec.c 8.3 (Berkeley) 3/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/regex/regexec.c,v 1.6 2004/07/12 07:35:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/regex/regexec.c,v 1.8 2007/06/11 03:05:54 delphij Exp $"); /* * the outer shell of regexec() @@ -66,12 +62,7 @@ __FBSDID("$FreeBSD: src/lib/libc/regex/regexec.c,v 1.6 2004/07/12 07:35:59 tjr E static int nope __unused = 0; /* for use in asserts; shuts lint up */ static __inline size_t -xmbrtowc(wi, s, n, mbs, dummy) -wint_t *wi; -const char *s; -size_t n; -mbstate_t *mbs; -wint_t dummy; +xmbrtowc(wint_t *wi, const char *s, size_t n, mbstate_t *mbs, wint_t dummy) { size_t nr; wchar_t wc; @@ -91,12 +82,11 @@ wint_t dummy; } static __inline size_t -xmbrtowc_dummy(wi, s, n, mbs, dummy) -wint_t *wi; -const char *s; -size_t n __unused; -mbstate_t *mbs __unused; -wint_t dummy __unused; +xmbrtowc_dummy(wint_t *wi, + const char *s, + size_t n __unused, + mbstate_t *mbs __unused, + wint_t dummy __unused) { if (wi != NULL) @@ -214,12 +204,11 @@ wint_t dummy __unused; * have been prototyped. */ int /* 0 success, REG_NOMATCH failure */ -regexec(preg, string, nmatch, pmatch, eflags) -const regex_t * __restrict preg; -const char * __restrict string; -size_t nmatch; -regmatch_t pmatch[__restrict]; -int eflags; +regexec(const regex_t * __restrict preg, + const char * __restrict string, + size_t nmatch, + regmatch_t pmatch[__restrict], + int eflags) { struct re_guts *g = preg->re_g; #ifdef REDEBUG diff --git a/regex/FreeBSD/regexec.c.patch b/regex/FreeBSD/regexec.c.patch index c6943c3..409ee17 100644 --- a/regex/FreeBSD/regexec.c.patch +++ b/regex/FreeBSD/regexec.c.patch @@ -1,26 +1,20 @@ ---- regexec.c.orig 2004-11-25 11:38:33.000000000 -0800 -+++ regexec.c 2005-02-24 14:20:50.000000000 -0800 -@@ -43,6 +43,8 @@ +--- regexec.c.bsdnew 2009-11-11 11:29:04.000000000 -0800 ++++ regexec.c 2009-11-11 12:21:46.000000000 -0800 +@@ -39,6 +39,8 @@ static char sccsid[] = "@(#)regexec.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/regex/regexec.c,v 1.6 2004/07/12 07:35:59 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/regex/regexec.c,v 1.8 2007/06/11 03:05:54 delphij Exp $"); +#include "xlocale_private.h" + /* * the outer shell of regexec() * -@@ -66,17 +68,18 @@ +@@ -62,12 +64,12 @@ __FBSDID("$FreeBSD: src/lib/libc/regex/r static int nope __unused = 0; /* for use in asserts; shuts lint up */ static __inline size_t --xmbrtowc(wi, s, n, mbs, dummy) -+xmbrtowc(wi, s, n, mbs, dummy, loc) - wint_t *wi; - const char *s; - size_t n; - mbstate_t *mbs; - wint_t dummy; -+locale_t loc; +-xmbrtowc(wint_t *wi, const char *s, size_t n, mbstate_t *mbs, wint_t dummy) ++xmbrtowc(wint_t *wi, const char *s, size_t n, mbstate_t *mbs, wint_t dummy, locale_t loc) { size_t nr; wchar_t wc; @@ -30,22 +24,17 @@ if (wi != NULL) *wi = wc; if (nr == 0) -@@ -91,12 +94,13 @@ - } - - static __inline size_t --xmbrtowc_dummy(wi, s, n, mbs, dummy) -+xmbrtowc_dummy(wi, s, n, mbs, dummy, loc) - wint_t *wi; - const char *s; - size_t n __unused; - mbstate_t *mbs __unused; - wint_t dummy __unused; -+locale_t loc; +@@ -86,7 +88,8 @@ xmbrtowc_dummy(wint_t *wi, + const char *s, + size_t n __unused, + mbstate_t *mbs __unused, +- wint_t dummy __unused) ++ wint_t dummy __unused, ++ locale_t loc __unused) { if (wi != NULL) -@@ -186,6 +190,8 @@ +@@ -176,6 +179,8 @@ xmbrtowc_dummy(wint_t *wi, /* function names */ #define LNAMES /* flag */ @@ -54,7 +43,7 @@ #include "engine.c" /* multibyte character & large states version */ -@@ -235,7 +241,8 @@ +@@ -224,7 +229,8 @@ regexec(const regex_t * __restrict preg, return(REG_BADPAT); eflags = GOODFLAGS(eflags); diff --git a/regex/FreeBSD/regfree.c b/regex/FreeBSD/regfree.c index 110879e..aa795fa 100644 --- a/regex/FreeBSD/regfree.c +++ b/regex/FreeBSD/regfree.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -41,7 +37,7 @@ static char sccsid[] = "@(#)regfree.c 8.3 (Berkeley) 3/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/regex/regfree.c,v 1.6 2004/07/12 07:35:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/regex/regfree.c,v 1.8 2007/06/11 03:05:54 delphij Exp $"); #include #include @@ -59,8 +55,7 @@ __FBSDID("$FreeBSD: src/lib/libc/regex/regfree.c,v 1.6 2004/07/12 07:35:59 tjr E = extern void regfree(regex_t *); */ void -regfree(preg) -regex_t *preg; +regfree(regex_t *preg) { struct re_guts *g; int i; diff --git a/regex/FreeBSD/regfree.c.patch b/regex/FreeBSD/regfree.c.patch index eadc425..f4744e0 100644 --- a/regex/FreeBSD/regfree.c.patch +++ b/regex/FreeBSD/regfree.c.patch @@ -1,6 +1,6 @@ ---- regfree.c.orig 2004-11-25 11:38:33.000000000 -0800 -+++ regfree.c 2005-04-04 15:16:04.000000000 -0700 -@@ -81,6 +81,7 @@ +--- regfree.c.bsdnew 2009-11-11 11:29:04.000000000 -0800 ++++ regfree.c 2009-11-11 11:29:04.000000000 -0800 +@@ -76,6 +76,7 @@ regfree(regex_t *preg) free(g->sets[i].ranges); free(g->sets[i].wides); free(g->sets[i].types); diff --git a/regex/FreeBSD/utils.h b/regex/FreeBSD/utils.h index 5439b6c..2a2ed96 100644 --- a/regex/FreeBSD/utils.h +++ b/regex/FreeBSD/utils.h @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ * SUCH DAMAGE. * * @(#)utils.h 8.3 (Berkeley) 3/20/94 - * $FreeBSD: src/lib/libc/regex/utils.h,v 1.2 2002/03/22 23:41:56 obrien Exp $ + * $FreeBSD: src/lib/libc/regex/utils.h,v 1.3 2007/01/09 00:28:04 imp Exp $ */ /* utility definitions */ diff --git a/regex/cname.h b/regex/cname.h deleted file mode 120000 index 776c31e..0000000 --- a/regex/cname.h +++ /dev/null @@ -1 +0,0 @@ -./cname.h \ No newline at end of file diff --git a/regex/cname.h b/regex/cname.h new file mode 100644 index 0000000..d3504a5 --- /dev/null +++ b/regex/cname.h @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)cname.h 8.3 (Berkeley) 3/20/94 + * $FreeBSD: src/lib/libc/regex/cname.h,v 1.4 2007/01/09 00:28:04 imp Exp $ + */ + +/* character-name table */ +static const struct cname { + const char *name; + char code; +} cnames[] = { + {"NUL", '\0'}, + {"SOH", '\001'}, + {"STX", '\002'}, + {"ETX", '\003'}, + {"EOT", '\004'}, + {"ENQ", '\005'}, + {"ACK", '\006'}, + {"BEL", '\007'}, + {"alert", '\007'}, + {"BS", '\010'}, + {"backspace", '\b'}, + {"HT", '\011'}, + {"tab", '\t'}, + {"LF", '\012'}, + {"newline", '\n'}, + {"VT", '\013'}, + {"vertical-tab", '\v'}, + {"FF", '\014'}, + {"form-feed", '\f'}, + {"CR", '\015'}, + {"carriage-return", '\r'}, + {"SO", '\016'}, + {"SI", '\017'}, + {"DLE", '\020'}, + {"DC1", '\021'}, + {"DC2", '\022'}, + {"DC3", '\023'}, + {"DC4", '\024'}, + {"NAK", '\025'}, + {"SYN", '\026'}, + {"ETB", '\027'}, + {"CAN", '\030'}, + {"EM", '\031'}, + {"SUB", '\032'}, + {"ESC", '\033'}, + {"IS4", '\034'}, + {"FS", '\034'}, + {"IS3", '\035'}, + {"GS", '\035'}, + {"IS2", '\036'}, + {"RS", '\036'}, + {"IS1", '\037'}, + {"US", '\037'}, + {"space", ' '}, + {"exclamation-mark", '!'}, + {"quotation-mark", '"'}, + {"number-sign", '#'}, + {"dollar-sign", '$'}, + {"percent-sign", '%'}, + {"ampersand", '&'}, + {"apostrophe", '\''}, + {"left-parenthesis", '('}, + {"right-parenthesis", ')'}, + {"asterisk", '*'}, + {"plus-sign", '+'}, + {"comma", ','}, + {"hyphen", '-'}, + {"hyphen-minus", '-'}, + {"period", '.'}, + {"full-stop", '.'}, + {"slash", '/'}, + {"solidus", '/'}, + {"zero", '0'}, + {"one", '1'}, + {"two", '2'}, + {"three", '3'}, + {"four", '4'}, + {"five", '5'}, + {"six", '6'}, + {"seven", '7'}, + {"eight", '8'}, + {"nine", '9'}, + {"colon", ':'}, + {"semicolon", ';'}, + {"less-than-sign", '<'}, + {"equals-sign", '='}, + {"greater-than-sign", '>'}, + {"question-mark", '?'}, + {"commercial-at", '@'}, + {"left-square-bracket", '['}, + {"backslash", '\\'}, + {"reverse-solidus", '\\'}, + {"right-square-bracket",']'}, + {"circumflex", '^'}, + {"circumflex-accent", '^'}, + {"underscore", '_'}, + {"low-line", '_'}, + {"grave-accent", '`'}, + {"left-brace", '{'}, + {"left-curly-bracket", '{'}, + {"vertical-line", '|'}, + {"right-brace", '}'}, + {"right-curly-bracket", '}'}, + {"tilde", '~'}, + {"DEL", '\177'}, + {NULL, 0} +}; diff --git a/regex/cname.h.orig b/regex/cname.h.orig new file mode 100644 index 0000000..19b4ddb --- /dev/null +++ b/regex/cname.h.orig @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)cname.h 8.3 (Berkeley) 3/20/94 + * $FreeBSD: src/lib/libc/regex/cname.h,v 1.4 2007/01/09 00:28:04 imp Exp $ + */ + +/* character-name table */ +static struct cname { + char *name; + char code; +} cnames[] = { + {"NUL", '\0'}, + {"SOH", '\001'}, + {"STX", '\002'}, + {"ETX", '\003'}, + {"EOT", '\004'}, + {"ENQ", '\005'}, + {"ACK", '\006'}, + {"BEL", '\007'}, + {"alert", '\007'}, + {"BS", '\010'}, + {"backspace", '\b'}, + {"HT", '\011'}, + {"tab", '\t'}, + {"LF", '\012'}, + {"newline", '\n'}, + {"VT", '\013'}, + {"vertical-tab", '\v'}, + {"FF", '\014'}, + {"form-feed", '\f'}, + {"CR", '\015'}, + {"carriage-return", '\r'}, + {"SO", '\016'}, + {"SI", '\017'}, + {"DLE", '\020'}, + {"DC1", '\021'}, + {"DC2", '\022'}, + {"DC3", '\023'}, + {"DC4", '\024'}, + {"NAK", '\025'}, + {"SYN", '\026'}, + {"ETB", '\027'}, + {"CAN", '\030'}, + {"EM", '\031'}, + {"SUB", '\032'}, + {"ESC", '\033'}, + {"IS4", '\034'}, + {"FS", '\034'}, + {"IS3", '\035'}, + {"GS", '\035'}, + {"IS2", '\036'}, + {"RS", '\036'}, + {"IS1", '\037'}, + {"US", '\037'}, + {"space", ' '}, + {"exclamation-mark", '!'}, + {"quotation-mark", '"'}, + {"number-sign", '#'}, + {"dollar-sign", '$'}, + {"percent-sign", '%'}, + {"ampersand", '&'}, + {"apostrophe", '\''}, + {"left-parenthesis", '('}, + {"right-parenthesis", ')'}, + {"asterisk", '*'}, + {"plus-sign", '+'}, + {"comma", ','}, + {"hyphen", '-'}, + {"hyphen-minus", '-'}, + {"period", '.'}, + {"full-stop", '.'}, + {"slash", '/'}, + {"solidus", '/'}, + {"zero", '0'}, + {"one", '1'}, + {"two", '2'}, + {"three", '3'}, + {"four", '4'}, + {"five", '5'}, + {"six", '6'}, + {"seven", '7'}, + {"eight", '8'}, + {"nine", '9'}, + {"colon", ':'}, + {"semicolon", ';'}, + {"less-than-sign", '<'}, + {"equals-sign", '='}, + {"greater-than-sign", '>'}, + {"question-mark", '?'}, + {"commercial-at", '@'}, + {"left-square-bracket", '['}, + {"backslash", '\\'}, + {"reverse-solidus", '\\'}, + {"right-square-bracket",']'}, + {"circumflex", '^'}, + {"circumflex-accent", '^'}, + {"underscore", '_'}, + {"low-line", '_'}, + {"grave-accent", '`'}, + {"left-brace", '{'}, + {"left-curly-bracket", '{'}, + {"vertical-line", '|'}, + {"right-brace", '}'}, + {"right-curly-bracket", '}'}, + {"tilde", '~'}, + {"DEL", '\177'}, + {NULL, 0} +}; diff --git a/regex/engine.c b/regex/engine.c index 5d2543f..75590e6 100644 --- a/regex/engine.c +++ b/regex/engine.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/regex/engine.c,v 1.14 2004/07/12 07:35:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/regex/engine.c,v 1.23 2009/09/16 06:32:23 dds Exp $"); /* * The matching engine and friends. This file is #included by regexec.c @@ -86,11 +82,11 @@ struct match { struct re_guts *g; int eflags; regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ - char *offp; /* offsets work from here */ - char *beginp; /* start of string -- virtual NUL precedes */ - char *endp; /* end of string -- virtual NUL here */ - char *coldp; /* can be no match starting before here */ - char **lastpos; /* [nplus+1] */ + const char *offp; /* offsets work from here */ + const char *beginp; /* start of string -- virtual NUL precedes */ + const char *endp; /* end of string -- virtual NUL here */ + const char *coldp; /* can be no match starting before here */ + const char **lastpos; /* [nplus+1] */ STATEVARS; states st; /* current states */ states fresh; /* states for a fresh start */ @@ -105,12 +101,13 @@ extern "C" { #endif /* === engine.c === */ -static int matcher(struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags); -static char *dissect(struct match *m, char *start, char *stop, sopno startst, sopno stopst); -static char *backref(struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev); -static char *fast(struct match *m, char *start, char *stop, sopno startst, sopno stopst); -static char *slow(struct match *m, char *start, char *stop, sopno startst, sopno stopst); +static int matcher(struct re_guts *g, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); +static const char *dissect(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); +static const char *backref(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst, sopno lev, int); +static const char *fast(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); +static const char *slow(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); static states step(struct re_guts *g, sopno start, sopno stop, states bef, wint_t ch, states aft); +#define MAX_RECURSION 100 #define BOL (OUT-1) #define EOL (BOL-1) #define BOLEOL (BOL-2) @@ -120,13 +117,13 @@ static states step(struct re_guts *g, sopno start, sopno stop, states bef, wint_ #define BADCHAR (BOL-6) #define NONCHAR(c) ((c) <= OUT) #ifdef REDEBUG -static void print(struct match *m, char *caption, states st, int ch, FILE *d); +static void print(struct match *m, const char *caption, states st, int ch, FILE *d); #endif #ifdef REDEBUG -static void at(struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst); +static void at(struct match *m, const char *title, const char *start, const char *stop, sopno startst, sopno stopst); #endif #ifdef REDEBUG -static char *pchar(int ch); +static const char *pchar(int ch); #endif #ifdef __cplusplus @@ -146,31 +143,30 @@ static char *pchar(int ch); /* - matcher - the actual matching engine - == static int matcher(struct re_guts *g, char *string, \ + == static int matcher(struct re_guts *g, const char *string, \ == size_t nmatch, regmatch_t pmatch[], int eflags); */ static int /* 0 success, REG_NOMATCH failure */ -matcher(g, string, nmatch, pmatch, eflags) -struct re_guts *g; -char *string; -size_t nmatch; -regmatch_t pmatch[]; -int eflags; +matcher(struct re_guts *g, + const char *string, + size_t nmatch, + regmatch_t pmatch[], + int eflags) { - char *endp; + const char *endp; int i; struct match mv; struct match *m = &mv; - char *dp; + const char *dp; const sopno gf = g->firststate+1; /* +1 for OEND */ const sopno gl = g->laststate; - char *start; - char *stop; + const char *start; + const char *stop; /* Boyer-Moore algorithms variables */ - char *pp; + const char *pp; int cj, mj; - char *mustfirst; - char *mustlast; + const char *mustfirst; + const char *mustlast; int *matchjump; int *charjump; @@ -251,10 +247,16 @@ int eflags; if (g->moffset > -1) start = ((dp - g->moffset) < start) ? start : dp - g->moffset; + SP("mloop", m->st, *start); + /* this loop does only one repetition except for backrefs */ for (;;) { endp = fast(m, start, stop, gf, gl); if (endp == NULL) { /* a miss */ + if (m->pmatch != NULL) + free((char *)m->pmatch); + if (m->lastpos != NULL) + free((char *)m->lastpos); STATETEARDOWN(m); return(REG_NOMATCH); } @@ -290,15 +292,15 @@ int eflags; dp = dissect(m, m->coldp, endp, gf, gl); } else { if (g->nplus > 0 && m->lastpos == NULL) - m->lastpos = (char **)malloc((g->nplus+1) * - sizeof(char *)); + m->lastpos = malloc((g->nplus+1) * + sizeof(const char *)); if (g->nplus > 0 && m->lastpos == NULL) { free(m->pmatch); STATETEARDOWN(m); return(REG_ESPACE); } NOTE("backref dissect"); - dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); + dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0); } if (dp != NULL) break; @@ -321,7 +323,7 @@ int eflags; } #endif NOTE("backoff dissect"); - dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); + dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0); } assert(dp == NULL || dp == endp); if (dp != NULL) /* found a shorter one */ @@ -331,7 +333,7 @@ int eflags; NOTE("false alarm"); /* recycle starting later */ start = m->coldp + XMBRTOWC(NULL, m->coldp, - m->endp - m->coldp, &m->mbs, 0, g->loc); + stop - m->coldp, &m->mbs, 0, g->loc); assert(start <= stop); } @@ -361,30 +363,29 @@ int eflags; /* - dissect - figure out what matched what, no back references - == static char *dissect(struct match *m, char *start, \ - == char *stop, sopno startst, sopno stopst); + == static const char *dissect(struct match *m, const char *start, \ + == const char *stop, sopno startst, sopno stopst); */ -static char * /* == stop (success) always */ -dissect(m, start, stop, startst, stopst) -struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; +static const char * /* == stop (success) always */ +dissect(struct match *m, + const char *start, + const char *stop, + sopno startst, + sopno stopst) { int i; sopno ss; /* start sop of current subRE */ sopno es; /* end sop of current subRE */ - char *sp; /* start of string matched by it */ - char *stp; /* string matched by it cannot pass here */ - char *rest; /* start of rest of string */ - char *tail; /* string unmatched by rest of RE */ + const char *sp; /* start of string matched by it */ + const char *stp; /* string matched by it cannot pass here */ + const char *rest; /* start of rest of string */ + const char *tail; /* string unmatched by rest of RE */ sopno ssub; /* start sop of subsubRE */ sopno esub; /* end sop of subsubRE */ - char *ssp; /* start of string matched by subsubRE */ - char *sep; /* end of string matched by subsubRE */ - char *oldssp; /* previous ssp */ - char *dp; + const char *ssp; /* start of string matched by subsubRE */ + const char *sep; /* end of string matched by subsubRE */ + const char *oldssp; /* previous ssp */ + const char *dp; AT("diss", start, stop, startst, stopst); sp = start; @@ -561,25 +562,25 @@ sopno stopst; /* - backref - figure out what matched what, figuring in back references - == static char *backref(struct match *m, char *start, \ - == char *stop, sopno startst, sopno stopst, sopno lev); + == static const char *backref(struct match *m, const char *start, \ + == const char *stop, sopno startst, sopno stopst, sopno lev); */ -static char * /* == stop (success) or NULL (failure) */ -backref(m, start, stop, startst, stopst, lev) -struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; -sopno lev; /* PLUS nesting level */ +static const char * /* == stop (success) or NULL (failure) */ +backref(struct match *m, + const char *start, + const char *stop, + sopno startst, + sopno stopst, + sopno lev, /* PLUS nesting level */ + int rec) { int i; sopno ss; /* start sop of current subRE */ - char *sp; /* start of string matched by it */ + const char *sp; /* start of string matched by it */ sopno ssub; /* start sop of subsubRE */ sopno esub; /* end sop of subsubRE */ - char *ssp; /* start of string matched by subsubRE */ - char *dp; + const char *ssp; /* start of string matched by subsubRE */ + const char *dp; size_t len; int hard; sop s; @@ -686,6 +687,8 @@ sopno lev; /* PLUS nesting level */ return(NULL); assert(m->pmatch[i].rm_so != -1); len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so; + if (len == 0 && rec++ > MAX_RECURSION) + return(NULL); assert(stop - m->beginp >= len); if (sp > stop - len) return(NULL); /* not enough left to match */ @@ -694,28 +697,28 @@ sopno lev; /* PLUS nesting level */ return(NULL); while (m->g->strip[ss] != SOP(O_BACK, i)) ss++; - return(backref(m, sp+len, stop, ss+1, stopst, lev)); + return(backref(m, sp+len, stop, ss+1, stopst, lev, rec)); break; case OQUEST_: /* to null or not */ - dp = backref(m, sp, stop, ss+1, stopst, lev); + dp = backref(m, sp, stop, ss+1, stopst, lev, rec); if (dp != NULL) return(dp); /* not */ - return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev)); + return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev, rec)); break; case OPLUS_: assert(m->lastpos != NULL); assert(lev+1 <= m->g->nplus); m->lastpos[lev+1] = sp; - return(backref(m, sp, stop, ss+1, stopst, lev+1)); + return(backref(m, sp, stop, ss+1, stopst, lev+1, rec)); break; case O_PLUS: if (sp == m->lastpos[lev]) /* last pass matched null */ - return(backref(m, sp, stop, ss+1, stopst, lev-1)); + return(backref(m, sp, stop, ss+1, stopst, lev-1, rec)); /* try another pass */ m->lastpos[lev] = sp; - dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev); + dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev, rec); if (dp == NULL) - return(backref(m, sp, stop, ss+1, stopst, lev-1)); + return(backref(m, sp, stop, ss+1, stopst, lev-1, rec)); else return(dp); break; @@ -724,7 +727,7 @@ sopno lev; /* PLUS nesting level */ esub = ss + OPND(s) - 1; assert(OP(m->g->strip[esub]) == OOR1); for (;;) { /* find first matching branch */ - dp = backref(m, sp, stop, ssub, esub, lev); + dp = backref(m, sp, stop, ssub, esub, lev, rec); if (dp != NULL) return(dp); /* that one missed, try next one */ @@ -745,7 +748,7 @@ sopno lev; /* PLUS nesting level */ assert(0 < i && i <= m->g->nsub); offsave = m->pmatch[i].rm_so; m->pmatch[i].rm_so = sp - m->offp; - dp = backref(m, sp, stop, ss+1, stopst, lev); + dp = backref(m, sp, stop, ss+1, stopst, lev, rec); if (dp != NULL) return(dp); m->pmatch[i].rm_so = offsave; @@ -756,7 +759,7 @@ sopno lev; /* PLUS nesting level */ assert(0 < i && i <= m->g->nsub); offsave = m->pmatch[i].rm_eo; m->pmatch[i].rm_eo = sp - m->offp; - dp = backref(m, sp, stop, ss+1, stopst, lev); + dp = backref(m, sp, stop, ss+1, stopst, lev, rec); if (dp != NULL) return(dp); m->pmatch[i].rm_eo = offsave; @@ -775,30 +778,30 @@ sopno lev; /* PLUS nesting level */ /* - fast - step through the string at top speed - == static char *fast(struct match *m, char *start, \ - == char *stop, sopno startst, sopno stopst); + == static const char *fast(struct match *m, const char *start, \ + == const char *stop, sopno startst, sopno stopst); */ -static char * /* where tentative match ended, or NULL */ -fast(m, start, stop, startst, stopst) -struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; +static const char * /* where tentative match ended, or NULL */ +fast( struct match *m, + const char *start, + const char *stop, + sopno startst, + sopno stopst) { states st = m->st; states fresh = m->fresh; states tmp = m->tmp; - char *p = start; + const char *p = start; wint_t c; wint_t lastc; /* previous c */ wint_t flagch; int i; - char *coldp; /* last p after which no match was underway */ + const char *coldp; /* last p after which no match was underway */ size_t clen; CLEAR(st); SET1(st, startst); + SP("fast", st, *p); st = step(m->g, startst, stopst, st, NOTHING, st); ASSIGN(fresh, st); SP("start", st, *p); @@ -816,9 +819,10 @@ sopno stopst; for (;;) { /* next character */ lastc = c; - if (p == m->endp) + if (p == m->endp) { + clen = 0; c = OUT; - else + } else clen = XMBRTOWC(&c, p, m->endp - p, &m->mbs, BADCHAR, m->g->loc); if (EQ(st, fresh)) coldp = p; @@ -857,7 +861,7 @@ sopno stopst; } /* are we done? */ - if (ISSET(st, stopst) || p == stop) + if (ISSET(st, stopst) || p == stop || clen > stop - p) break; /* NOTE BREAK OUT */ /* no, we must deal with this character */ @@ -873,33 +877,32 @@ sopno stopst; assert(coldp != NULL); m->coldp = coldp; if (ISSET(st, stopst)) - return(p+XMBRTOWC(NULL, p, m->endp - p, &m->mbs, 0, m->g->loc)); + return(p+XMBRTOWC(NULL, p, stop - p, &m->mbs, 0, m->g->loc)); else return(NULL); } /* - slow - step through the string more deliberately - == static char *slow(struct match *m, char *start, \ - == char *stop, sopno startst, sopno stopst); + == static const char *slow(struct match *m, const char *start, \ + == const char *stop, sopno startst, sopno stopst); */ -static char * /* where it ended */ -slow(m, start, stop, startst, stopst) -struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; +static const char * /* where it ended */ +slow( struct match *m, + const char *start, + const char *stop, + sopno startst, + sopno stopst) { states st = m->st; states empty = m->empty; states tmp = m->tmp; - char *p = start; + const char *p = start; wint_t c; wint_t lastc; /* previous c */ wint_t flagch; int i; - char *matchp; /* last p at which a match ended */ + const char *matchp; /* last p at which a match ended */ size_t clen; AT("slow", start, stop, startst, stopst); @@ -963,7 +966,7 @@ sopno stopst; /* are we done? */ if (ISSET(st, stopst)) matchp = p; - if (EQ(st, empty) || p == stop) + if (EQ(st, empty) || p == stop || clen > stop - p) break; /* NOTE BREAK OUT */ /* no, we must deal with this character */ @@ -994,13 +997,12 @@ sopno stopst; == #define NONCHAR(c) ((c) <= OUT) */ static states -step(g, start, stop, bef, ch, aft) -struct re_guts *g; -sopno start; /* start state within strip */ -sopno stop; /* state after stop state within strip */ -states bef; /* states reachable before */ -wint_t ch; /* character or NONCHAR code */ -states aft; /* states already known reachable after */ +step(struct re_guts *g, + sopno start, /* start state within strip */ + sopno stop, /* state after stop state within strip */ + states bef, /* states reachable before */ + wint_t ch, /* character or NONCHAR code */ + states aft) /* states already known reachable after */ { cset *cs; sop s; @@ -1085,7 +1087,7 @@ states aft; /* states already known reachable after */ OP(s = g->strip[pc+look]) != O_CH; look += OPND(s)) assert(OP(s) == OOR2); - FWD(aft, aft, look); + FWD(aft, aft, look + 1); } break; case OOR2: /* propagate OCH_'s marking */ @@ -1111,17 +1113,16 @@ states aft; /* states already known reachable after */ /* - print - print a set of states == #ifdef REDEBUG - == static void print(struct match *m, char *caption, states st, \ + == static void print(struct match *m, const char *caption, states st, \ == int ch, FILE *d); == #endif */ static void -print(m, caption, st, ch, d) -struct match *m; -char *caption; -states st; -int ch; -FILE *d; +print(struct match *m, + const char *caption, + states st, + int ch, + FILE *d) { struct re_guts *g = m->g; int i; @@ -1144,18 +1145,17 @@ FILE *d; /* - at - print current situation == #ifdef REDEBUG - == static void at(struct match *m, char *title, char *start, char *stop, \ - == sopno startst, sopno stopst); + == static void at(struct match *m, const char *title, const char *start, \ + == const char *stop, sopno startst, sopno stopst); == #endif */ static void -at(m, title, start, stop, startst, stopst) -struct match *m; -char *title; -char *start; -char *stop; -sopno startst; -sopno stopst; +at( struct match *m, + const char *title, + const char *start, + const char *stop, + sopno startst, + sopno stopst) { if (!(m->eflags®_TRACE)) return; @@ -1170,7 +1170,7 @@ sopno stopst; /* - pchar - make a character printable == #ifdef REDEBUG - == static char *pchar(int ch); + == static const char *pchar(int ch); == #endif * * Is this identical to regchar() over in debug.c? Well, yes. But a @@ -1178,9 +1178,8 @@ sopno stopst; * a matching debug.o, and this is convenient. It all disappears in * the non-debug compilation anyway, so it doesn't matter much. */ -static char * /* -> representation */ -pchar(ch) -int ch; +static const char * /* -> representation */ +pchar(int ch) { static char pbuf[10]; diff --git a/regex/regcomp-fbsd.c b/regex/regcomp-fbsd.c index 0f06201..a84a31d 100644 --- a/regex/regcomp-fbsd.c +++ b/regex/regcomp-fbsd.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -41,7 +37,7 @@ static char sccsid[] = "@(#)regcomp.c 8.5 (Berkeley) 3/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/regex/regcomp.c,v 1.34 2004/10/03 15:42:59 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/regex/regcomp.c,v 1.36 2007/06/11 03:05:54 delphij Exp $"); #include "xlocale_private.h" @@ -187,10 +183,9 @@ static int never = 0; /* for use in asserts; shuts lint up */ = #define REG_DUMP 0200 */ int /* 0 success, otherwise REG_something */ -regcomp(preg, pattern, cflags) -regex_t * __restrict preg; -const char * __restrict pattern; -int cflags; +regcomp(regex_t * __restrict preg, + const char * __restrict pattern, + int cflags) { struct parse pa; struct re_guts *g; @@ -302,9 +297,8 @@ int cflags; == static void p_ere(struct parse *p, int stop); */ static void -p_ere(p, stop) -struct parse *p; -int stop; /* character this ERE should end at */ +p_ere(struct parse *p, + int stop) /* character this ERE should end at */ { char c; sopno prevback; @@ -352,8 +346,7 @@ int stop; /* character this ERE should end at */ == static void p_ere_exp(struct parse *p); */ static void -p_ere_exp(p) -struct parse *p; +p_ere_exp(struct parse *p) { char c; wint_t wc; @@ -504,8 +497,7 @@ struct parse *p; == static void p_str(struct parse *p); */ static void -p_str(p) -struct parse *p; +p_str(struct parse *p) { #if __DARWIN_UNIX03 if (!p->zerorepeats) REQUIRE(MORE(), REG_EMPTY); @@ -528,10 +520,9 @@ struct parse *p; * The amount of lookahead needed to avoid this kludge is excessive. */ static void -p_bre(p, end1, end2) -struct parse *p; -int end1; /* first terminating character */ -int end2; /* second terminating character */ +p_bre(struct parse *p, + int end1, /* first terminating character */ + int end2) /* second terminating character */ { sopno start = HERE(); int first = 1; /* first subexpression? */ @@ -565,9 +556,8 @@ int end2; /* second terminating character */ == static int p_simp_re(struct parse *p, int starordinary); */ static int /* was the simple RE an unbackslashed $? */ -p_simp_re(p, starordinary) -struct parse *p; -int starordinary; /* is a leading * an ordinary character? */ +p_simp_re(struct parse *p, + int starordinary) /* is a leading * an ordinary character? */ { int c; int count; @@ -697,8 +687,7 @@ int starordinary; /* is a leading * an ordinary character? */ == static int p_count(struct parse *p); */ static int /* the value */ -p_count(p) -struct parse *p; +p_count(struct parse *p) { int count = 0; int ndigits = 0; @@ -717,8 +706,7 @@ struct parse *p; == static void p_bracket(struct parse *p); */ static void -p_bracket(p) -struct parse *p; +p_bracket(struct parse *p) { cset *cs; wint_t ch; @@ -782,9 +770,7 @@ struct parse *p; == static void p_b_term(struct parse *p, cset *cs); */ static void -p_b_term(p, cs) -struct parse *p; -cset *cs; +p_b_term(struct parse *p, cset *cs) { char c; wint_t start, finish; @@ -871,9 +857,7 @@ cset *cs; == static void p_b_cclass(struct parse *p, cset *cs); */ static void -p_b_cclass(p, cs) -struct parse *p; -cset *cs; +p_b_cclass(struct parse *p, cset *cs) { char *sp = p->next; size_t len; @@ -901,9 +885,7 @@ cset *cs; == static void p_b_eclass(struct parse *p, cset *cs); */ static void -p_b_eclass(p, cs) -struct parse *p; -cset *cs; +p_b_eclass(struct parse *p, cset *cs) { char *sp = p->next; int len, ec; @@ -942,8 +924,7 @@ cset *cs; == static char p_b_symbol(struct parse *p); */ static wint_t /* value of symbol */ -p_b_symbol(p) -struct parse *p; +p_b_symbol(struct parse *p) { wint_t value; @@ -962,12 +943,11 @@ struct parse *p; == static char p_b_coll_elem(struct parse *p, int endc); */ static wint_t /* value of collating element */ -p_b_coll_elem(p, endc) -struct parse *p; -wint_t endc; /* name ended by endc,']' */ +p_b_coll_elem(struct parse *p, + wint_t endc) /* name ended by endc,']' */ { char *sp = p->next; - struct cname *cp; + const struct cname *cp; int len; mbstate_t mbs; wchar_t wbuf[16]; @@ -996,12 +976,10 @@ wint_t endc; /* name ended by endc,']' */ /* - othercase - return the case counterpart of an alphabetic - == static char othercase(int ch, locale_t loc); + == static char othercase(wint_t ch, locale_t loc); */ static wint_t /* if no counterpart, return ch */ -othercase(ch, loc) -wint_t ch; -locale_t loc; +othercase(wint_t ch, locale_t loc) { assert(iswalpha_l(ch, loc)); if (iswupper_l(ch, loc)) @@ -1019,9 +997,7 @@ locale_t loc; * Boy, is this implementation ever a kludge... */ static void -bothcases(p, ch) -struct parse *p; -wint_t ch; +bothcases(struct parse *p, wint_t ch) { char *oldnext = p->next; char *oldend = p->end; @@ -1048,9 +1024,7 @@ wint_t ch; == static void ordinary(struct parse *p, int ch); */ static void -ordinary(p, ch) -struct parse *p; -wint_t ch; +ordinary(struct parse *p, wint_t ch) { cset *cs; @@ -1077,8 +1051,7 @@ wint_t ch; * Boy, is this implementation ever a kludge... */ static void -nonnewline(p) -struct parse *p; +nonnewline(struct parse *p) { char *oldnext = p->next; char *oldend = p->end; @@ -1101,11 +1074,10 @@ struct parse *p; == static void repeat(struct parse *p, sopno start, int from, int to); */ static void -repeat(p, start, from, to) -struct parse *p; -sopno start; /* operand from here to end of strip */ -int from; /* repeated from this number */ -int to; /* to this number of times (maybe INFINITY) */ +repeat(struct parse *p, + sopno start, /* operand from here to end of strip */ + int from, /* repeated from this number */ + int to) /* to this number of times (maybe INFINITY) */ { sopno finish = HERE(); # define N 2 @@ -1191,8 +1163,7 @@ int to; /* to this number of times (maybe INFINITY) */ - character can't be converted. Returns the number of bytes consumed. */ static wint_t -wgetnext(p) -struct parse *p; +wgetnext(struct parse *p) { mbstate_t mbs; wchar_t wc; @@ -1215,9 +1186,7 @@ struct parse *p; == static int seterr(struct parse *p, int e); */ static int /* useless but makes type checking happy */ -seterr(p, e) -struct parse *p; -int e; +seterr(struct parse *p, int e) { if (p->error == 0) /* keep earliest error condition */ p->error = e; @@ -1231,8 +1200,7 @@ int e; == static cset *allocset(struct parse *p); */ static cset * -allocset(p) -struct parse *p; +allocset(struct parse *p) { cset *cs, *ncs; @@ -1253,9 +1221,7 @@ struct parse *p; == static void freeset(struct parse *p, cset *cs); */ static void -freeset(p, cs) -struct parse *p; -cset *cs; +freeset(struct parse *p, cset *cs) { cset *top = &p->g->sets[p->g->ncsets]; @@ -1272,9 +1238,7 @@ cset *cs; - returning it if so, otherwise returning OUT. */ static wint_t -singleton(cs, loc) -cset *cs; -locale_t loc; +singleton(cset *cs, locale_t loc) { wint_t i, s, n; @@ -1296,10 +1260,7 @@ locale_t loc; - CHadd - add character to character set. */ static void -CHadd(p, cs, ch) -struct parse *p; -cset *cs; -wint_t ch; +CHadd(struct parse *p, cset *cs, wint_t ch) { wint_t nch, *newwides; assert(ch >= 0); @@ -1327,10 +1288,7 @@ wint_t ch; - CHaddrange - add all characters in the range [min,max] to a character set. */ static void -CHaddrange(p, cs, min, max) -struct parse *p; -cset *cs; -wint_t min, max; +CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max) { crange *newranges; @@ -1354,10 +1312,7 @@ wint_t min, max; - CHaddtype - add all characters of a certain type to a character set. */ static void -CHaddtype(p, cs, wct) -struct parse *p; -cset *cs; -wctype_t wct; +CHaddtype(struct parse *p, cset *cs, wctype_t wct) { wint_t i; wctype_t *newtypes; @@ -1380,10 +1335,9 @@ wctype_t wct; == static sopno dupl(struct parse *p, sopno start, sopno finish); */ static sopno /* start of duplicate */ -dupl(p, start, finish) -struct parse *p; -sopno start; /* from here */ -sopno finish; /* to this less one */ +dupl(struct parse *p, + sopno start, /* from here */ + sopno finish) /* to this less one */ { sopno ret = HERE(); sopno len = finish - start; @@ -1408,10 +1362,7 @@ sopno finish; /* to this less one */ * some changes to the data structures. Maybe later. */ static void -doemit(p, op, opnd) -struct parse *p; -sop op; -size_t opnd; +doemit(struct parse *p, sop op, size_t opnd) { /* avoid making error situations worse */ if (p->error != 0) @@ -1434,11 +1385,7 @@ size_t opnd; == static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos); */ static void -doinsert(p, op, opnd, pos) -struct parse *p; -sop op; -size_t opnd; -sopno pos; +doinsert(struct parse *p, sop op, size_t opnd, sopno pos) { sopno sn; sop s; @@ -1474,10 +1421,7 @@ sopno pos; == static void dofwd(struct parse *p, sopno pos, sop value); */ static void -dofwd(p, pos, value) -struct parse *p; -sopno pos; -sop value; +dofwd(struct parse *p, sopno pos, sop value) { /* avoid making error situations worse */ if (p->error != 0) @@ -1492,9 +1436,7 @@ sop value; == static void enlarge(struct parse *p, sopno size); */ static void -enlarge(p, size) -struct parse *p; -sopno size; +enlarge(struct parse *p, sopno size) { sop *sp; @@ -1515,9 +1457,7 @@ sopno size; == static void stripsnug(struct parse *p, struct re_guts *g); */ static void -stripsnug(p, g) -struct parse *p; -struct re_guts *g; +stripsnug(struct parse *p, struct re_guts *g) { g->nstates = p->slen; g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop)); @@ -1538,9 +1478,7 @@ struct re_guts *g; * Note that must and mlen got initialized during setup. */ static void -findmust(p, g) -struct parse *p; -struct re_guts *g; +findmust(struct parse *p, struct re_guts *g) { sop *scan; sop *start; @@ -1715,9 +1653,7 @@ struct re_guts *g; * re paths. */ static int -altoffset(scan, offset) -sop *scan; -int offset; +altoffset(sop *scan, int offset) { int largest; int try; @@ -1792,9 +1728,7 @@ int offset; * the value of the character from the text that was mismatched. */ static void -computejumps(p, g) -struct parse *p; -struct re_guts *g; +computejumps(struct parse *p, struct re_guts *g) { int ch; int mindex; @@ -1838,9 +1772,7 @@ struct re_guts *g; * the search algorithm works. */ static void -computematchjumps(p, g) -struct parse *p; -struct re_guts *g; +computematchjumps(struct parse *p, struct re_guts *g) { int mindex; /* General "must" iterator */ int suffix; /* Keeps track of matching suffix */ @@ -1914,9 +1846,7 @@ struct re_guts *g; == static sopno pluscount(struct parse *p, struct re_guts *g); */ static sopno /* nesting depth */ -pluscount(p, g) -struct parse *p; -struct re_guts *g; +pluscount(struct parse *p, struct re_guts *g) { sop *scan; sop s; diff --git a/regex/regerror-fbsd.c b/regex/regerror-fbsd.c deleted file mode 120000 index e635b8f..0000000 --- a/regex/regerror-fbsd.c +++ /dev/null @@ -1 +0,0 @@ -./regerror.c \ No newline at end of file diff --git a/regex/regerror-fbsd.c b/regex/regerror-fbsd.c new file mode 100644 index 0000000..a22066c --- /dev/null +++ b/regex/regerror-fbsd.c @@ -0,0 +1,174 @@ +/*- + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)regerror.c 8.4 (Berkeley) 3/20/94 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)regerror.c 8.4 (Berkeley) 3/20/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/regex/regerror.c,v 1.11 2007/06/11 03:05:54 delphij Exp $"); + +#include +#include +#include +#include +#include +#include + +#include "utils.h" + +/* ========= begin header generated by ./mkh ========= */ +#ifdef __cplusplus +extern "C" { +#endif + +/* === regerror.c === */ +static char *regatoi(const regex_t *preg, char *localbuf); + +#ifdef __cplusplus +} +#endif +/* ========= end header generated by ./mkh ========= */ +/* + = #define REG_NOMATCH 1 + = #define REG_BADPAT 2 + = #define REG_ECOLLATE 3 + = #define REG_ECTYPE 4 + = #define REG_EESCAPE 5 + = #define REG_ESUBREG 6 + = #define REG_EBRACK 7 + = #define REG_EPAREN 8 + = #define REG_EBRACE 9 + = #define REG_BADBR 10 + = #define REG_ERANGE 11 + = #define REG_ESPACE 12 + = #define REG_BADRPT 13 + = #define REG_EMPTY 14 + = #define REG_ASSERT 15 + = #define REG_INVARG 16 + = #define REG_ILLSEQ 17 + = #define REG_ATOI 255 // convert name to number (!) + = #define REG_ITOA 0400 // convert number to name (!) + */ +static const struct rerr { + int code; + const char *name; + const char *explain; +} rerrs[] = { + {REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"}, + {REG_BADPAT, "REG_BADPAT", "invalid regular expression"}, + {REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"}, + {REG_ECTYPE, "REG_ECTYPE", "invalid character class"}, + {REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)"}, + {REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"}, + {REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced"}, + {REG_EPAREN, "REG_EPAREN", "parentheses not balanced"}, + {REG_EBRACE, "REG_EBRACE", "braces not balanced"}, + {REG_BADBR, "REG_BADBR", "invalid repetition count(s)"}, + {REG_ERANGE, "REG_ERANGE", "invalid character range"}, + {REG_ESPACE, "REG_ESPACE", "out of memory"}, + {REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid"}, + {REG_EMPTY, "REG_EMPTY", "empty (sub)expression"}, + {REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"}, + {REG_INVARG, "REG_INVARG", "invalid argument to regex routine"}, + {REG_ILLSEQ, "REG_ILLSEQ", "illegal byte sequence"}, + {0, "", "*** unknown regexp error code ***"} +}; + +/* + - regerror - the interface to error numbers + = extern size_t regerror(int, const regex_t *, char *, size_t); + */ +/* ARGSUSED */ +size_t +regerror(int errcode, + const regex_t * __restrict preg, + char * __restrict errbuf, + size_t errbuf_size) +{ + const struct rerr *r; + size_t len; + int target = errcode &~ REG_ITOA; + const char *s; + char convbuf[50]; + + if (errcode == REG_ATOI) + s = regatoi(preg, convbuf); + else { + for (r = rerrs; r->code != 0; r++) + if (r->code == target) + break; + + if (errcode®_ITOA) { + if (r->code != 0) + (void) strcpy(convbuf, r->name); + else + sprintf(convbuf, "REG_0x%x", target); + assert(strlen(convbuf) < sizeof(convbuf)); + s = convbuf; + } else + s = r->explain; + } + + len = strlen(s) + 1; + if (errbuf_size > 0) { + if (errbuf_size > len) + (void) strcpy(errbuf, s); + else { + (void) strncpy(errbuf, s, errbuf_size-1); + errbuf[errbuf_size-1] = '\0'; + } + } + + return(len); +} + +/* + - regatoi - internal routine to implement REG_ATOI + == static char *regatoi(const regex_t *preg, char *localbuf); + */ +static char * +regatoi(const regex_t *preg, char *localbuf) +{ + const struct rerr *r; + + for (r = rerrs; r->code != 0; r++) + if (strcmp(r->name, preg->re_endp) == 0) + break; + if (r->code == 0) + return("0"); + + sprintf(localbuf, "%d", r->code); + return(localbuf); +} diff --git a/regex/regerror-fbsd.c.orig b/regex/regerror-fbsd.c.orig new file mode 100644 index 0000000..9364bd4 --- /dev/null +++ b/regex/regerror-fbsd.c.orig @@ -0,0 +1,174 @@ +/*- + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)regerror.c 8.4 (Berkeley) 3/20/94 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)regerror.c 8.4 (Berkeley) 3/20/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/regex/regerror.c,v 1.11 2007/06/11 03:05:54 delphij Exp $"); + +#include +#include +#include +#include +#include +#include + +#include "utils.h" + +/* ========= begin header generated by ./mkh ========= */ +#ifdef __cplusplus +extern "C" { +#endif + +/* === regerror.c === */ +static char *regatoi(const regex_t *preg, char *localbuf); + +#ifdef __cplusplus +} +#endif +/* ========= end header generated by ./mkh ========= */ +/* + = #define REG_NOMATCH 1 + = #define REG_BADPAT 2 + = #define REG_ECOLLATE 3 + = #define REG_ECTYPE 4 + = #define REG_EESCAPE 5 + = #define REG_ESUBREG 6 + = #define REG_EBRACK 7 + = #define REG_EPAREN 8 + = #define REG_EBRACE 9 + = #define REG_BADBR 10 + = #define REG_ERANGE 11 + = #define REG_ESPACE 12 + = #define REG_BADRPT 13 + = #define REG_EMPTY 14 + = #define REG_ASSERT 15 + = #define REG_INVARG 16 + = #define REG_ILLSEQ 17 + = #define REG_ATOI 255 // convert name to number (!) + = #define REG_ITOA 0400 // convert number to name (!) + */ +static struct rerr { + int code; + char *name; + char *explain; +} rerrs[] = { + {REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"}, + {REG_BADPAT, "REG_BADPAT", "invalid regular expression"}, + {REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"}, + {REG_ECTYPE, "REG_ECTYPE", "invalid character class"}, + {REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)"}, + {REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"}, + {REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced"}, + {REG_EPAREN, "REG_EPAREN", "parentheses not balanced"}, + {REG_EBRACE, "REG_EBRACE", "braces not balanced"}, + {REG_BADBR, "REG_BADBR", "invalid repetition count(s)"}, + {REG_ERANGE, "REG_ERANGE", "invalid character range"}, + {REG_ESPACE, "REG_ESPACE", "out of memory"}, + {REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid"}, + {REG_EMPTY, "REG_EMPTY", "empty (sub)expression"}, + {REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"}, + {REG_INVARG, "REG_INVARG", "invalid argument to regex routine"}, + {REG_ILLSEQ, "REG_ILLSEQ", "illegal byte sequence"}, + {0, "", "*** unknown regexp error code ***"} +}; + +/* + - regerror - the interface to error numbers + = extern size_t regerror(int, const regex_t *, char *, size_t); + */ +/* ARGSUSED */ +size_t +regerror(int errcode, + const regex_t * __restrict preg, + char * __restrict errbuf, + size_t errbuf_size) +{ + struct rerr *r; + size_t len; + int target = errcode &~ REG_ITOA; + char *s; + char convbuf[50]; + + if (errcode == REG_ATOI) + s = regatoi(preg, convbuf); + else { + for (r = rerrs; r->code != 0; r++) + if (r->code == target) + break; + + if (errcode®_ITOA) { + if (r->code != 0) + (void) strcpy(convbuf, r->name); + else + sprintf(convbuf, "REG_0x%x", target); + assert(strlen(convbuf) < sizeof(convbuf)); + s = convbuf; + } else + s = r->explain; + } + + len = strlen(s) + 1; + if (errbuf_size > 0) { + if (errbuf_size > len) + (void) strcpy(errbuf, s); + else { + (void) strncpy(errbuf, s, errbuf_size-1); + errbuf[errbuf_size-1] = '\0'; + } + } + + return(len); +} + +/* + - regatoi - internal routine to implement REG_ATOI + == static char *regatoi(const regex_t *preg, char *localbuf); + */ +static char * +regatoi(const regex_t *preg, char *localbuf) +{ + struct rerr *r; + + for (r = rerrs; r->code != 0; r++) + if (strcmp(r->name, preg->re_endp) == 0) + break; + if (r->code == 0) + return("0"); + + sprintf(localbuf, "%d", r->code); + return(localbuf); +} diff --git a/regex/regex.3 b/regex/regex.3 index 9f6b115..dc3b5bf 100644 --- a/regex/regex.3 +++ b/regex/regex.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)regex.3 8.4 (Berkeley) 3/20/94 -.\" $FreeBSD: src/lib/libc/regex/regex.3,v 1.17 2004/07/12 11:03:42 tjr Exp $ +.\" $FreeBSD: src/lib/libc/regex/regex.3,v 1.21 2007/01/09 00:28:04 imp Exp $ .\" -.Dd July 12, 2004 +.Dd August 17, 2005 .Dt REGEX 3 .Os .Sh NAME @@ -444,7 +440,7 @@ places the NUL-terminated message into the buffer pointed to by limiting the length (including the NUL) to at most .Fa errbuf_size bytes. -If the whole message won't fit, +If the whole message will not fit, as much of it as will fit before the terminating NUL is supplied. In any case, the returned value is the size of buffer needed to hold the whole @@ -596,14 +592,6 @@ and beginning and ending subexpressions in obsolete .Pq Dq basic REs are anchors, not ordinary characters. -.Sh SEE ALSO -.Xr grep 1 , -.Xr re_format 7 -.Pp -.St -p1003.2 , -sections 2.8 (Regular Expression Notation) -and -B.5 (C Binding for Regular Expression Matching). .Sh DIAGNOSTICS Non-zero error codes from .Fn regcomp @@ -657,12 +645,20 @@ operand invalid .It Dv REG_EMPTY empty (sub)expression .It Dv REG_ASSERT -can't happen - you found a bug +cannot happen - you found a bug .It Dv REG_INVARG invalid argument, e.g.\& negative-length string .It Dv REG_ILLSEQ illegal byte sequence (bad multibyte character) .El +.Sh SEE ALSO +.Xr grep 1 , +.Xr re_format 7 +.Pp +.St -p1003.2 , +sections 2.8 (Regular Expression Notation) +and +B.5 (C Binding for Regular Expression Matching). .Sh HISTORY Originally written by .An Henry Spencer . @@ -723,7 +719,7 @@ are legal REs because is a special character only in the presence of a previous unmatched .Ql (\& . -This can't be fixed until the spec is fixed. +This cannot be fixed until the spec is fixed. .Pp The standard's definition of back references is vague. For example, does @@ -735,3 +731,5 @@ behavior in such cases should not be relied on. .Pp The implementation of word-boundary matching is a bit of a kludge, and bugs may lurk in combinations of word-boundary matching and anchoring. +.Pp +Word-boundary matching does not work properly in multibyte locales. diff --git a/regex/regex2.h b/regex/regex2.h index 15a6bcf..8c0a49c 100644 --- a/regex/regex2.h +++ b/regex/regex2.h @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ * SUCH DAMAGE. * * @(#)regex2.h 8.4 (Berkeley) 3/20/94 - * $FreeBSD: src/lib/libc/regex/regex2.h,v 1.8 2004/07/12 07:35:59 tjr Exp $ + * $FreeBSD: src/lib/libc/regex/regex2.h,v 1.11 2007/01/09 00:28:04 imp Exp $ */ /* @@ -131,10 +127,7 @@ typedef struct { #include "collate.h" static int -CHIN1(cs, ch, loc) -cset *cs; -wint_t ch; -locale_t loc; +CHIN1(cset *cs, wint_t ch, locale_t loc) { int i; @@ -160,10 +153,7 @@ locale_t loc; } static __inline int -CHIN(cs, ch, loc) -cset *cs; -wint_t ch; -locale_t loc; +CHIN(cset *cs, wint_t ch, locale_t loc) { assert(ch >= 0); @@ -208,5 +198,5 @@ struct re_guts { }; /* misc utilities */ -#define OUT (-130) /* a non-character value */ +#define OUT (CHAR_MIN - 2) /* a non-character value */ #define ISWORD(c,l) (iswalnum_l((uch)(c), l) || (c) == '_') diff --git a/regex/regexec-fbsd.c b/regex/regexec-fbsd.c index 55eecfb..38c7281 100644 --- a/regex/regexec-fbsd.c +++ b/regex/regexec-fbsd.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -41,7 +37,7 @@ static char sccsid[] = "@(#)regexec.c 8.3 (Berkeley) 3/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/regex/regexec.c,v 1.6 2004/07/12 07:35:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/regex/regexec.c,v 1.8 2007/06/11 03:05:54 delphij Exp $"); #include "xlocale_private.h" @@ -68,13 +64,7 @@ __FBSDID("$FreeBSD: src/lib/libc/regex/regexec.c,v 1.6 2004/07/12 07:35:59 tjr E static int nope __unused = 0; /* for use in asserts; shuts lint up */ static __inline size_t -xmbrtowc(wi, s, n, mbs, dummy, loc) -wint_t *wi; -const char *s; -size_t n; -mbstate_t *mbs; -wint_t dummy; -locale_t loc; +xmbrtowc(wint_t *wi, const char *s, size_t n, mbstate_t *mbs, wint_t dummy, locale_t loc) { size_t nr; wchar_t wc; @@ -94,13 +84,12 @@ locale_t loc; } static __inline size_t -xmbrtowc_dummy(wi, s, n, mbs, dummy, loc) -wint_t *wi; -const char *s; -size_t n __unused; -mbstate_t *mbs __unused; -wint_t dummy __unused; -locale_t loc; +xmbrtowc_dummy(wint_t *wi, + const char *s, + size_t n __unused, + mbstate_t *mbs __unused, + wint_t dummy __unused, + locale_t loc __unused) { if (wi != NULL) @@ -220,12 +209,11 @@ locale_t loc; * have been prototyped. */ int /* 0 success, REG_NOMATCH failure */ -regexec(preg, string, nmatch, pmatch, eflags) -const regex_t * __restrict preg; -const char * __restrict string; -size_t nmatch; -regmatch_t pmatch[__restrict]; -int eflags; +regexec(const regex_t * __restrict preg, + const char * __restrict string, + size_t nmatch, + regmatch_t pmatch[__restrict], + int eflags) { struct re_guts *g = preg->re_g; #ifdef REDEBUG diff --git a/regex/regfree-fbsd.c b/regex/regfree-fbsd.c index d11060c..4e231c9 100644 --- a/regex/regfree-fbsd.c +++ b/regex/regfree-fbsd.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -41,7 +37,7 @@ static char sccsid[] = "@(#)regfree.c 8.3 (Berkeley) 3/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/regex/regfree.c,v 1.6 2004/07/12 07:35:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/regex/regfree.c,v 1.8 2007/06/11 03:05:54 delphij Exp $"); #include #include @@ -59,8 +55,7 @@ __FBSDID("$FreeBSD: src/lib/libc/regex/regfree.c,v 1.6 2004/07/12 07:35:59 tjr E = extern void regfree(regex_t *); */ void -regfree(preg) -regex_t *preg; +regfree(regex_t *preg) { struct re_guts *g; int i; diff --git a/secure/Makefile.inc b/secure/Makefile.inc index 7e904d1..9748566 100644 --- a/secure/Makefile.inc +++ b/secure/Makefile.inc @@ -7,6 +7,7 @@ MISRCS += chk_fail.c \ strcpy_chk.c \ stpcpy_chk.c \ strncpy_chk.c \ + stpncpy_chk.c \ strcat_chk.c \ strncat_chk.c \ sprintf_chk.c \ diff --git a/sys/unlink.c b/secure/stpncpy_chk.c similarity index 71% rename from sys/unlink.c rename to secure/stpncpy_chk.c index b3830e5..acbc600 100644 --- a/sys/unlink.c +++ b/secure/stpncpy_chk.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2009 Apple Inc. All rights reserved. + * Copyright (c) 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,19 +17,21 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ -#include +#include +#include -void __inc_remove_counter(void); -int __unlink(const char *path); +extern void __chk_fail (void) __attribute__((__noreturn__)); -int -unlink(const char *path) +void * +__stpncpy_chk (char *restrict dest, char *restrict src, + size_t len, size_t dstlen) { - int res = __unlink(path); - if (res == 0) __inc_remove_counter(); - return res; + if (__builtin_expect (dstlen < len, 0)) + __chk_fail (); + + return stpncpy (dest, src, len); } diff --git a/stdio/FreeBSD/_flock_stub.c b/stdio/FreeBSD/_flock_stub.c index 3a73ee1..07e02fd 100644 --- a/stdio/FreeBSD/_flock_stub.c +++ b/stdio/FreeBSD/_flock_stub.c @@ -10,10 +10,7 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by John Birrell. - * 4. Neither the name of the author nor the names of any co-contributors + * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -38,7 +35,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/_flock_stub.c,v 1.14 2004/03/09 04:51:58 jb Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/_flock_stub.c,v 1.16 2008/04/17 22:17:53 jhb Exp $"); #include "namespace.h" #include @@ -58,31 +55,21 @@ __weak_reference(_flockfile_debug_stub, _flockfile_debug); __weak_reference(_ftrylockfile, ftrylockfile); __weak_reference(_funlockfile, funlockfile); -/* - * We need to retain binary compatibility for a while. So pretend - * that _lock is part of FILE * even though it is dereferenced off - * _extra now. When we stop encoding the size of FILE into binaries - * this can be changed in stdio.h. This will reduce the amount of - * code that has to change in the future (just remove this comment - * and #define). - */ -#define _lock _extra - void _flockfile(FILE *fp) { pthread_t curthread = _pthread_self(); - if (fp->_lock->fl_owner == curthread) - fp->_lock->fl_count++; + if (fp->_fl_owner == curthread) + fp->_fl_count++; else { /* * Make sure this mutex is treated as a private * internal mutex: */ - _pthread_mutex_lock(&fp->_lock->fl_mutex); - fp->_lock->fl_owner = curthread; - fp->_lock->fl_count = 1; + _pthread_mutex_lock(&fp->_fl_mutex); + fp->_fl_owner = curthread; + fp->_fl_count = 1; } } @@ -101,15 +88,15 @@ _ftrylockfile(FILE *fp) pthread_t curthread = _pthread_self(); int ret = 0; - if (fp->_lock->fl_owner == curthread) - fp->_lock->fl_count++; + if (fp->_fl_owner == curthread) + fp->_fl_count++; /* * Make sure this mutex is treated as a private * internal mutex: */ - else if (_pthread_mutex_trylock(&fp->_lock->fl_mutex) == 0) { - fp->_lock->fl_owner = curthread; - fp->_lock->fl_count = 1; + else if (_pthread_mutex_trylock(&fp->_fl_mutex) == 0) { + fp->_fl_owner = curthread; + fp->_fl_count = 1; } else ret = -1; @@ -124,26 +111,26 @@ _funlockfile(FILE *fp) /* * Check if this file is owned by the current thread: */ - if (fp->_lock->fl_owner == curthread) { + if (fp->_fl_owner == curthread) { /* * Check if this thread has locked the FILE * more than once: */ - if (fp->_lock->fl_count > 1) + if (fp->_fl_count > 1) /* * Decrement the count of the number of * times the running thread has locked this * file: */ - fp->_lock->fl_count--; + fp->_fl_count--; else { /* * The running thread will release the * lock now: */ - fp->_lock->fl_count = 0; - fp->_lock->fl_owner = NULL; - _pthread_mutex_unlock(&fp->_lock->fl_mutex); + fp->_fl_count = 0; + fp->_fl_owner = NULL; + _pthread_mutex_unlock(&fp->_fl_mutex); } } } diff --git a/stdio/FreeBSD/asprintf.c b/stdio/FreeBSD/asprintf.c index 02362b0..5e089e1 100644 --- a/stdio/FreeBSD/asprintf.c +++ b/stdio/FreeBSD/asprintf.c @@ -1,8 +1,9 @@ -/* $OpenBSD: asprintf.c,v 1.8 2002/02/19 19:39:36 millert Exp $ */ - -/* - * Copyright (c) 1997 Todd C. Miller - * All rights reserved. +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -12,60 +13,37 @@ * 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED ``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 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. + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 -__FBSDID("$FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.13 2002/09/26 13:09:48 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.15 2009/03/02 04:11:42 das Exp $"); #include -#include -#include #include -#include "local.h" - int -asprintf(char **str, char const *fmt, ...) +asprintf(char ** __restrict s, char const * __restrict fmt, ...) { int ret; va_list ap; - FILE f; - struct __sFILEX ext; - f._file = -1; - f._flags = __SWR | __SSTR | __SALC; - f._bf._base = f._p = (unsigned char *)malloc(128); - if (f._bf._base == NULL) { - *str = NULL; - errno = ENOMEM; - return (-1); - } - f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); va_start(ap, fmt); - ret = __vfprintf(&f, fmt, ap); /* Use unlocked __vfprintf */ + ret = vasprintf(s, fmt, ap); va_end(ap); - if (ret < 0) { - free(f._bf._base); - *str = NULL; - errno = ENOMEM; - return (-1); - } - *f._p = '\0'; - *str = (char *)f._bf._base; return (ret); } diff --git a/stdio/FreeBSD/asprintf.c.patch b/stdio/FreeBSD/asprintf.c.patch index 1f21732..bc41588 100644 --- a/stdio/FreeBSD/asprintf.c.patch +++ b/stdio/FreeBSD/asprintf.c.patch @@ -1,54 +1,32 @@ ---- asprintf.c.orig 2003-05-20 15:22:40.000000000 -0700 -+++ asprintf.c 2005-02-23 16:17:23.000000000 -0800 -@@ -30,6 +30,8 @@ +--- asprintf.c.bsdnew 2009-11-11 19:15:16.000000000 -0800 ++++ asprintf.c 2009-11-11 19:15:42.000000000 -0800 +@@ -33,6 +33,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.13 2002/09/26 13:09:48 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.15 2009/03/02 04:11:42 das Exp $"); +#include "xlocale_private.h" + #include - #include - #include -@@ -57,7 +59,41 @@ - f._extra = &ext; - INITEXTRA(&f); + #include + +@@ -43,7 +45,19 @@ asprintf(char ** __restrict s, char cons + va_list ap; + va_start(ap, fmt); -- ret = __vfprintf(&f, fmt, ap); /* Use unlocked __vfprintf */ -+ ret = __vfprintf(&f, __current_locale(), fmt, ap); /* Use unlocked __vfprintf */ +- ret = vasprintf(s, fmt, ap); ++ ret = vasprintf_l(s, __current_locale(), fmt, ap); + va_end(ap); -+ if (ret < 0) { -+ free(f._bf._base); -+ *str = NULL; -+ errno = ENOMEM; -+ return (-1); -+ } -+ *f._p = '\0'; -+ *str = (char *)f._bf._base; + return (ret); +} + +int -+asprintf_l(char **str, locale_t loc, char const *fmt, ...) ++asprintf_l(char ** __restrict s, locale_t loc, char const * __restrict fmt, ...) +{ + int ret; + va_list ap; -+ FILE f; -+ struct __sFILEX ext; + -+ NORMALIZE_LOCALE(loc); -+ f._file = -1; -+ f._flags = __SWR | __SSTR | __SALC; -+ f._bf._base = f._p = (unsigned char *)malloc(128); -+ if (f._bf._base == NULL) { -+ *str = NULL; -+ errno = ENOMEM; -+ return (-1); -+ } -+ f._bf._size = f._w = 127; /* Leave room for the NUL */ -+ f._extra = &ext; -+ INITEXTRA(&f); + va_start(ap, fmt); -+ ret = __vfprintf(&f, loc, fmt, ap); /* Use unlocked __vfprintf */ ++ ret = vasprintf_l(s, loc, fmt, ap); va_end(ap); - if (ret < 0) { - free(f._bf._base); + return (ret); + } diff --git a/stdio/FreeBSD/clrerr.c b/stdio/FreeBSD/clrerr.c index bfac2c1..bebb155 100644 --- a/stdio/FreeBSD/clrerr.c +++ b/stdio/FreeBSD/clrerr.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,13 +34,15 @@ static char sccsid[] = "@(#)clrerr.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/clrerr.c,v 1.9 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/clrerr.c,v 1.12 2008/05/05 16:03:52 jhb Exp $"); #include "namespace.h" #include #include "un-namespace.h" #include "libc_private.h" -#undef clearerr + +#undef clearerr +#undef clearerr_unlocked void clearerr(fp) @@ -54,3 +52,10 @@ clearerr(fp) __sclearerr(fp); FUNLOCKFILE(fp); } + +void +clearerr_unlocked(FILE *fp) +{ + + __sclearerr(fp); +} diff --git a/stdio/FreeBSD/dprintf.c b/stdio/FreeBSD/dprintf.c new file mode 100644 index 0000000..ff5a864 --- /dev/null +++ b/stdio/FreeBSD/dprintf.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/stdio/dprintf.c,v 1.1 2009/03/04 03:38:51 das Exp $"); + +#define _WITH_DPRINTF +#include "namespace.h" +#include +#include +#include "un-namespace.h" + +int +dprintf(int fd, const char * __restrict fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vdprintf(fd, fmt, ap); + va_end(ap); + return (ret); +} diff --git a/stdio/FreeBSD/dprintf.c.patch b/stdio/FreeBSD/dprintf.c.patch new file mode 100644 index 0000000..43957fd --- /dev/null +++ b/stdio/FreeBSD/dprintf.c.patch @@ -0,0 +1,33 @@ +--- dprintf.c.orig 2009-12-15 17:43:05.000000000 -0800 ++++ dprintf.c 2009-12-15 17:45:32.000000000 -0800 +@@ -27,7 +27,8 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/stdio/dprintf.c,v 1.1 2009/03/04 03:38:51 das Exp $"); + +-#define _WITH_DPRINTF ++#include "xlocale_private.h" ++ + #include "namespace.h" + #include + #include +@@ -40,7 +41,19 @@ dprintf(int fd, const char * __restrict + int ret; + + va_start(ap, fmt); +- ret = vdprintf(fd, fmt, ap); ++ ret = vdprintf_l(fd, __current_locale(), fmt, ap); ++ va_end(ap); ++ return (ret); ++} ++ ++int ++dprintf_l(int fd, locale_t loc, const char * __restrict fmt, ...) ++{ ++ va_list ap; ++ int ret; ++ ++ va_start(ap, fmt); ++ ret = vdprintf_l(fd, loc, fmt, ap); + va_end(ap); + return (ret); + } diff --git a/stdio/FreeBSD/fclose.3 b/stdio/FreeBSD/fclose.3 index 8adc65a..c3720bf 100644 --- a/stdio/FreeBSD/fclose.3 +++ b/stdio/FreeBSD/fclose.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,13 +30,14 @@ .\" SUCH DAMAGE. .\" .\" @(#)fclose.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fclose.3,v 1.12 2002/12/18 12:45:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fclose.3,v 1.15 2007/01/09 00:28:06 imp Exp $ .\" -.Dd June 4, 1993 +.Dd April 22, 2006 .Dt FCLOSE 3 .Os .Sh NAME -.Nm fclose +.Nm fclose , +.Nm fcloseall .Nd close a stream .Sh LIBRARY .Lb libc @@ -48,6 +45,8 @@ .In stdio.h .Ft int .Fn fclose "FILE *stream" +.Ft void +.Fn fcloseall void .Sh DESCRIPTION The .Fn fclose @@ -58,6 +57,12 @@ from its underlying file or set of functions. If the stream was being used for output, any buffered data is written first, using .Xr fflush 3 . +.Pp +The +.Fn fcloseall +function calls +.Fn fclose +on all open streams. .Sh RETURN VALUES Upon successful completion 0 is returned. Otherwise, @@ -99,3 +104,8 @@ The function conforms to .St -isoC . +.Pp +The +.Fn fcloseall +function first appeared in +.Fx 7.0 . diff --git a/stdio/FreeBSD/fclose.c b/stdio/FreeBSD/fclose.c index ad4dae7..e80edcf 100644 --- a/stdio/FreeBSD/fclose.c +++ b/stdio/FreeBSD/fclose.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fclose.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fclose.c,v 1.11 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fclose.c,v 1.12 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/fclose.c.patch b/stdio/FreeBSD/fclose.c.patch index 176981b..7e5eef7 100644 --- a/stdio/FreeBSD/fclose.c.patch +++ b/stdio/FreeBSD/fclose.c.patch @@ -1,6 +1,6 @@ ---- fclose.c.orig 2009-02-15 03:11:22.000000000 -0800 -+++ fclose.c 2009-02-15 19:01:59.000000000 -0800 -@@ -53,6 +53,13 @@ fclose(FILE *fp) +--- fclose.c.bsdnew 2009-11-11 13:33:03.000000000 -0800 ++++ fclose.c 2009-11-11 13:33:03.000000000 -0800 +@@ -49,6 +49,13 @@ fclose(FILE *fp) { int r; @@ -14,7 +14,7 @@ if (fp->_flags == 0) { /* not open! */ errno = EBADF; return (EOF); -@@ -69,7 +76,7 @@ fclose(FILE *fp) +@@ -65,7 +72,7 @@ fclose(FILE *fp) FREELB(fp); fp->_file = -1; fp->_r = fp->_w = 0; /* Mess up if reaccessed. */ diff --git a/stdio/FreeBSD/fdopen.c b/stdio/FreeBSD/fdopen.c index 15e7e8f..4d106c4 100644 --- a/stdio/FreeBSD/fdopen.c +++ b/stdio/FreeBSD/fdopen.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fdopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fdopen.c,v 1.7 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fdopen.c,v 1.11 2008/05/10 18:39:20 antoine Exp $"); #include "namespace.h" #include @@ -46,6 +42,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/fdopen.c,v 1.7 2002/03/22 21:53:04 obrien #include #include #include +#include #include "un-namespace.h" #include "local.h" @@ -55,11 +52,19 @@ fdopen(fd, mode) const char *mode; { FILE *fp; - static int nofile; int flags, oflags, fdflags, tmp; - if (nofile == 0) - nofile = getdtablesize(); + /* + * File descriptors are a full int, but _file is only a short. + * If we get a valid file descriptor that is greater than + * SHRT_MAX, then the fd will get sign-extended into an + * invalid file descriptor. Handle this case by failing the + * open. + */ + if (fd > SHRT_MAX) { + errno = EMFILE; + return (NULL); + } if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); diff --git a/stdio/FreeBSD/fdopen.c.patch b/stdio/FreeBSD/fdopen.c.patch index a94c452..466abe3 100644 --- a/stdio/FreeBSD/fdopen.c.patch +++ b/stdio/FreeBSD/fdopen.c.patch @@ -1,6 +1,6 @@ ---- fdopen.c.orig 2009-02-15 03:11:22.000000000 -0800 -+++ fdopen.c 2009-02-15 17:52:46.000000000 -0800 -@@ -34,6 +34,15 @@ +--- fdopen.c.bsdnew 2009-11-11 13:33:03.000000000 -0800 ++++ fdopen.c 2009-11-11 13:33:04.000000000 -0800 +@@ -30,6 +30,15 @@ * SUCH DAMAGE. */ @@ -16,7 +16,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)fdopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ -@@ -73,7 +82,7 @@ fdopen(fd, mode) +@@ -78,7 +87,7 @@ fdopen(fd, mode) return (NULL); } diff --git a/stdio/FreeBSD/feof.c b/stdio/FreeBSD/feof.c index 7c09187..51f54f7 100644 --- a/stdio/FreeBSD/feof.c +++ b/stdio/FreeBSD/feof.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)feof.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/feof.c,v 1.9 2004/03/17 01:43:07 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/feof.c,v 1.12 2008/05/05 16:03:52 jhb Exp $"); #include "namespace.h" #include @@ -46,6 +42,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/feof.c,v 1.9 2004/03/17 01:43:07 tjr Exp #include "libc_private.h" #undef feof +#undef feof_unlocked int feof(FILE *fp) @@ -57,3 +54,10 @@ feof(FILE *fp) FUNLOCKFILE(fp); return (ret); } + +int +feof_unlocked(FILE *fp) +{ + + return (__sfeof(fp)); +} diff --git a/stdio/FreeBSD/ferror.3 b/stdio/FreeBSD/ferror.3 index 6e7d1ba..22bc13c 100644 --- a/stdio/FreeBSD/ferror.3 +++ b/stdio/FreeBSD/ferror.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)ferror.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/stdio/ferror.3,v 1.9 2003/02/23 01:47:47 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/ferror.3,v 1.13 2009/01/28 14:38:41 trhodes Exp $ .\" -.Dd January 10, 2003 +.Dd January 28, 2009 .Dt FERROR 3 .Os .Sh NAME @@ -81,17 +77,16 @@ The function tests the end-of-file indicator for the stream pointed to by .Fa stream , returning non-zero if it is set. -The end-of-file indicator can only be cleared by the function -.Fn clearerr . +The end-of-file indicator may be cleared by explicitly calling +.Fn clearerr , +or as a side-effect of other operations, e.g.\& +.Fn fseek . .Pp The function .Fn ferror tests the error indicator for the stream pointed to by .Fa stream , returning non-zero if it is set. -The error indicator can only be reset by the -.Fn clearerr -function. .Pp The function .Fn fileno diff --git a/stdio/FreeBSD/ferror.c b/stdio/FreeBSD/ferror.c index 0f960f7..830fb9b 100644 --- a/stdio/FreeBSD/ferror.c +++ b/stdio/FreeBSD/ferror.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)ferror.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/ferror.c,v 1.9 2004/03/17 01:43:07 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/ferror.c,v 1.12 2008/05/05 16:03:52 jhb Exp $"); #include "namespace.h" #include @@ -46,6 +42,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/ferror.c,v 1.9 2004/03/17 01:43:07 tjr Ex #include "libc_private.h" #undef ferror +#undef ferror_unlocked int ferror(FILE *fp) @@ -57,3 +54,10 @@ ferror(FILE *fp) FUNLOCKFILE(fp); return (ret); } + +int +ferror_unlocked(FILE *fp) +{ + + return (__sferror(fp)); +} diff --git a/stdio/FreeBSD/fflush.3 b/stdio/FreeBSD/fflush.3 index cc3e7e8..e05b2ff 100644 --- a/stdio/FreeBSD/fflush.3 +++ b/stdio/FreeBSD/fflush.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fflush.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fflush.3,v 1.10 2003/06/08 10:01:52 charnier Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fflush.3,v 1.11 2007/01/09 00:28:06 imp Exp $ .\" .Dd June 4, 1993 .Dt FFLUSH 3 diff --git a/stdio/FreeBSD/fflush.c b/stdio/FreeBSD/fflush.c index 59da908..2507c79 100644 --- a/stdio/FreeBSD/fflush.c +++ b/stdio/FreeBSD/fflush.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fflush.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fflush.c,v 1.13 2004/07/04 20:17:00 cperciva Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fflush.c,v 1.14 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/fflush.c.patch b/stdio/FreeBSD/fflush.c.patch index 29fb1fb..7f6d2a6 100644 --- a/stdio/FreeBSD/fflush.c.patch +++ b/stdio/FreeBSD/fflush.c.patch @@ -1,6 +1,6 @@ ---- fflush.c.orig 2007-07-20 11:15:28.000000000 -0700 -+++ fflush.c 2007-07-20 15:47:15.000000000 -0700 -@@ -43,6 +43,7 @@ +--- fflush.c.bsdnew 2009-11-11 13:33:04.000000000 -0800 ++++ fflush.c 2009-11-11 13:33:04.000000000 -0800 +@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/f #include "namespace.h" #include #include @@ -8,7 +8,7 @@ #include "un-namespace.h" #include "libc_private.h" #include "local.h" -@@ -126,6 +127,14 @@ +@@ -122,6 +123,14 @@ __sflush(FILE *fp) for (; n > 0; n -= t, p += t) { t = _swrite(fp, (char *)p, n); if (t <= 0) { diff --git a/stdio/FreeBSD/fgetc.c b/stdio/FreeBSD/fgetc.c index 5cd8c7e..96cd999 100644 --- a/stdio/FreeBSD/fgetc.c +++ b/stdio/FreeBSD/fgetc.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fgetc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetc.c,v 1.12 2004/03/19 09:04:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetc.c,v 1.13 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/fgetln.3 b/stdio/FreeBSD/fgetln.3 index e96dcf7..4fb0a8a 100644 --- a/stdio/FreeBSD/fgetln.3 +++ b/stdio/FreeBSD/fgetln.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fgetln.3 8.3 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/stdio/fgetln.3,v 1.8 2004/07/16 06:07:12 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fgetln.3,v 1.10 2009/02/28 06:00:58 das Exp $ .\" .Dd April 19, 1994 .Dt FGETLN 3 @@ -120,6 +116,7 @@ or .Xr fgets 3 , .Xr fgetwln 3 , .Xr fopen 3 , +.Xr getline 3 , .Xr putc 3 .Sh HISTORY The diff --git a/stdio/FreeBSD/fgetln.3.patch b/stdio/FreeBSD/fgetln.3.patch new file mode 100644 index 0000000..d134522 --- /dev/null +++ b/stdio/FreeBSD/fgetln.3.patch @@ -0,0 +1,12 @@ +--- fgetln.3.orig 2010-07-09 13:54:22.000000000 -0700 ++++ fgetln.3 2010-07-10 12:40:15.000000000 -0700 +@@ -97,6 +97,9 @@ + The argument + .Fa stream + is not a stream open for reading. ++.It Bq Er ENOMEM ++The internal line buffer could not be expanded due to lack of available memory, ++or because it would need to expand beyond INT_MAX in size. + .El + .Pp + The diff --git a/stdio/FreeBSD/fgetln.c b/stdio/FreeBSD/fgetln.c index a1b303e..bbad594 100644 --- a/stdio/FreeBSD/fgetln.c +++ b/stdio/FreeBSD/fgetln.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fgetln.c 8.2 (Berkeley) 1/2/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetln.c,v 1.10 2004/07/16 05:52:51 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetln.c,v 1.11 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/fgetln.c.patch b/stdio/FreeBSD/fgetln.c.patch new file mode 100644 index 0000000..035233c --- /dev/null +++ b/stdio/FreeBSD/fgetln.c.patch @@ -0,0 +1,29 @@ +--- fgetln.c.orig 2010-07-09 13:54:22.000000000 -0700 ++++ fgetln.c 2010-07-10 12:23:58.000000000 -0700 +@@ -37,6 +37,7 @@ static char sccsid[] = "@(#)fgetln.c 8.2 + __FBSDID("$FreeBSD: src/lib/libc/stdio/fgetln.c,v 1.11 2007/01/09 00:28:06 imp Exp $"); + + #include "namespace.h" ++#include + #include + #include + #include +@@ -61,6 +62,10 @@ __slbexpand(FILE *fp, size_t newsize) + #endif + if (fp->_lb._size >= newsize) + return (0); ++ if (newsize > INT_MAX) { ++ errno = ENOMEM; ++ return (-1); ++ } + if ((p = realloc(fp->_lb._base, newsize)) == NULL) + return (-1); + fp->_lb._base = p; +@@ -159,6 +164,7 @@ fgetln(FILE *fp, size_t *lenp) + + error: + *lenp = 0; /* ??? */ ++ fp->_flags |= __SERR; + FUNLOCKFILE(fp); + return (NULL); /* ??? */ + } diff --git a/stdio/FreeBSD/fgetpos.c b/stdio/FreeBSD/fgetpos.c index 581c5c8..40e134d 100644 --- a/stdio/FreeBSD/fgetpos.c +++ b/stdio/FreeBSD/fgetpos.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fgetpos.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetpos.c,v 1.12 2002/10/12 16:13:37 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetpos.c,v 1.13 2007/01/09 00:28:06 imp Exp $"); #include diff --git a/stdio/FreeBSD/fgets.3 b/stdio/FreeBSD/fgets.3 index 1b43d4c..e8909d2 100644 --- a/stdio/FreeBSD/fgets.3 +++ b/stdio/FreeBSD/fgets.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fgets.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fgets.3,v 1.19 2002/12/04 18:57:45 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fgets.3,v 1.22 2009/02/28 06:00:58 das Exp $ .\" .Dd June 4, 1993 .Dt FGETS 3 @@ -151,12 +147,8 @@ the FSA.) .Xr feof 3 , .Xr ferror 3 , .Xr fgetln 3 , -.Xr fgetws 3 -.Rs -.%T "The FreeBSD Security Architecture" -.Re -(See -.Pa /usr/share/doc/{to be determined} . ) +.Xr fgetws 3 , +.Xr getline 3 .Sh STANDARDS The functions .Fn fgets diff --git a/stdio/FreeBSD/fgets.3.patch b/stdio/FreeBSD/fgets.3.patch deleted file mode 100644 index 045ec30..0000000 --- a/stdio/FreeBSD/fgets.3.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- _SB/Libc/stdio/FreeBSD/fgets.3 2003-05-20 15:22:41.000000000 -0700 -+++ _SB/Libc/stdio/FreeBSD/fgets.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -48,19 +48,19 @@ - .Sh SYNOPSIS - .In stdio.h - .Ft char * --.Fn fgets "char * restrict str" "int size" "FILE * restrict stream" -+.Fn fgets "char *restrict s" "int n" "FILE *restrict stream" - .Ft char * --.Fn gets "char *str" -+.Fn gets "char *s" - .Sh DESCRIPTION - The - .Fn fgets - function - reads at most one less than the number of characters specified by --.Fa size -+.Fa n - from the given - .Fa stream - and stores them in the string --.Fa str . -+.Fa s . - Reading stops when a newline character is found, - at end-of-file or error. - The newline, if any, is retained. -@@ -74,7 +74,7 @@ - is equivalent to - .Fn fgets - with an infinite --.Fa size -+.Fa n - and a - .Fa stream - of -@@ -102,7 +102,7 @@ - and - .Fn gets - functions --do not distinguish between end-of-file and error, and callers must use -+do not distinguish between end-of-file and error; callers must use - .Xr feof 3 - and - .Xr ferror 3 -@@ -152,11 +152,6 @@ - .Xr ferror 3 , - .Xr fgetln 3 , - .Xr fgetws 3 --.Rs --.%T "The FreeBSD Security Architecture" --.Re --(See --.Pa /usr/share/doc/{to be determined} . ) - .Sh STANDARDS - The functions - .Fn fgets diff --git a/stdio/FreeBSD/fgets.c b/stdio/FreeBSD/fgets.c index 36ae4fd..c9efd57 100644 --- a/stdio/FreeBSD/fgets.c +++ b/stdio/FreeBSD/fgets.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fgets.c 8.2 (Berkeley) 12/22/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fgets.c,v 1.13 2002/08/13 09:30:41 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgets.c,v 1.14 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/fgetwc.c b/stdio/FreeBSD/fgetwc.c index f4a273a..1570178 100644 --- a/stdio/FreeBSD/fgetwc.c +++ b/stdio/FreeBSD/fgetwc.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwc.c,v 1.12 2004/07/20 08:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwc.c,v 1.13 2008/04/17 22:17:53 jhb Exp $"); #include "namespace.h" #include @@ -71,7 +71,7 @@ __fgetwc(FILE *fp) return (wc); } do { - nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_extra->mbstate); + nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_mbstate); if (nconv == (size_t)-1) break; else if (nconv == (size_t)-2) diff --git a/stdio/FreeBSD/fgetwc.c.patch b/stdio/FreeBSD/fgetwc.c.patch index af467f5..eec75c7 100644 --- a/stdio/FreeBSD/fgetwc.c.patch +++ b/stdio/FreeBSD/fgetwc.c.patch @@ -1,15 +1,15 @@ ---- fgetwc.c.orig 2004-11-25 11:38:34.000000000 -0800 -+++ fgetwc.c 2005-02-23 17:15:00.000000000 -0800 +--- fgetwc.c.bsdnew 2009-11-11 13:33:05.000000000 -0800 ++++ fgetwc.c 2009-11-11 13:43:19.000000000 -0800 @@ -27,6 +27,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwc.c,v 1.12 2004/07/20 08:27:27 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwc.c,v 1.13 2008/04/17 22:17:53 jhb Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include #include -@@ -47,7 +49,21 @@ +@@ -47,7 +49,21 @@ fgetwc(FILE *fp) FLOCKFILE(fp); ORIENT(fp, 1); @@ -32,7 +32,7 @@ FUNLOCKFILE(fp); return (r); -@@ -57,21 +73,23 @@ +@@ -57,21 +73,23 @@ fgetwc(FILE *fp) * Non-MT-safe version. */ wint_t @@ -54,8 +54,8 @@ return (wc); } do { -- nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_extra->mbstate); -+ nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_extra->mbstate, loc); +- nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_mbstate); ++ nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_mbstate, loc); if (nconv == (size_t)-1) break; else if (nconv == (size_t)-2) diff --git a/stdio/FreeBSD/fgetwln.3 b/stdio/FreeBSD/fgetwln.3 new file mode 100644 index 0000000..5a8119c --- /dev/null +++ b/stdio/FreeBSD/fgetwln.3 @@ -0,0 +1,116 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. 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. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. +.\" +.\" @(#)fgetln.3 8.3 (Berkeley) 4/19/94 +.\" $FreeBSD: src/lib/libc/stdio/fgetwln.3,v 1.3 2007/01/09 00:28:06 imp Exp $ +.\" +.Dd July 16, 2004 +.Dt FGETWLN 3 +.Os +.Sh NAME +.Nm fgetwln +.Nd get a line of wide characters from a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft wchar_t * +.Fn fgetwln "FILE * restrict stream" "size_t * restrict len" +.Sh DESCRIPTION +The +.Fn fgetwln +function +returns a pointer to the next line from the stream referenced by +.Fa stream . +This line is +.Em not +a standard wide character string as it does not end with a terminating +null wide character. +The length of the line, including the final newline, +is stored in the memory location to which +.Fa len +points. +(Note, however, that if the line is the last +in a file that does not end in a newline, +the returned text will not contain a newline.) +.Sh RETURN VALUES +Upon successful completion a pointer is returned; +this pointer becomes invalid after the next +.Tn I/O +operation on +.Fa stream +(whether successful or not) +or as soon as the stream is closed. +Otherwise, +.Dv NULL +is returned. +The +.Fn fgetwln +function +does not distinguish between end-of-file and error; the routines +.Xr feof 3 +and +.Xr ferror 3 +must be used +to determine which occurred. +If an error occurs, the global variable +.Va errno +is set to indicate the error. +The end-of-file condition is remembered, even on a terminal, and all +subsequent attempts to read will return +.Dv NULL +until the condition is +cleared with +.Xr clearerr 3 . +.Pp +The text to which the returned pointer points may be modified, +provided that no changes are made beyond the returned size. +These changes are lost as soon as the pointer becomes invalid. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +The argument +.Fa stream +is not a stream open for reading. +.El +.Pp +The +.Fn fgetwln +function +may also fail and set +.Va errno +for any of the errors specified for the routines +.Xr mbrtowc 3 , +.Xr realloc 3 , +or +.Xr read 2 . +.Sh SEE ALSO +.Xr ferror 3 , +.Xr fgetln 3 , +.Xr fgetws 3 , +.Xr fopen 3 diff --git a/stdio/FreeBSD/fgetwln.3.patch b/stdio/FreeBSD/fgetwln.3.patch new file mode 100644 index 0000000..7be9de1 --- /dev/null +++ b/stdio/FreeBSD/fgetwln.3.patch @@ -0,0 +1,44 @@ +--- fgetwln.3.orig 2009-10-29 11:41:29.000000000 -0700 ++++ fgetwln.3 2009-10-29 11:44:37.000000000 -0700 +@@ -32,7 +32,8 @@ + .Dt FGETWLN 3 + .Os + .Sh NAME +-.Nm fgetwln ++.Nm fgetwln , ++.Nm fgetwln_l + .Nd get a line of wide characters from a stream + .Sh LIBRARY + .Lb libc +@@ -41,6 +42,9 @@ + .In wchar.h + .Ft wchar_t * + .Fn fgetwln "FILE * restrict stream" "size_t * restrict len" ++.In xlocale.h ++.Ft wchar_t * ++.Fn fgetwln_l "FILE * restrict stream" "size_t * restrict len" "locale_t loc" + .Sh DESCRIPTION + The + .Fn fgetwln +@@ -58,6 +62,14 @@ points. + (Note, however, that if the line is the last + in a file that does not end in a newline, + the returned text will not contain a newline.) ++.Pp ++While the ++.Fn fgetwln ++function uses the current locale, the ++.Fn fgetwln_l ++function may be passed a locale directly. See ++.Xr xlocale 3 ++for more information. + .Sh RETURN VALUES + Upon successful completion a pointer is returned; + this pointer becomes invalid after the next +@@ -113,4 +125,5 @@ or + .Xr ferror 3 , + .Xr fgetln 3 , + .Xr fgetws 3 , +-.Xr fopen 3 ++.Xr fopen 3 , ++.Xr xlocale 3 diff --git a/stdio/FreeBSD/fgetwln.c b/stdio/FreeBSD/fgetwln.c new file mode 100644 index 0000000..49b52af --- /dev/null +++ b/stdio/FreeBSD/fgetwln.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * 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 +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwln.c,v 1.2 2004/08/06 17:00:09 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +wchar_t * +fgetwln(FILE * __restrict fp, size_t *lenp) +{ + wint_t wc; + size_t len; + + FLOCKFILE(fp); + ORIENT(fp, 1); + + len = 0; + while ((wc = __fgetwc(fp)) != WEOF) { +#define GROW 512 + if (len * sizeof(wchar_t) >= fp->_lb._size && + __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) + goto error; + *((wchar_t *)fp->_lb._base + len++) = wc; + if (wc == L'\n') + break; + } + if (len == 0) + goto error; + + FUNLOCKFILE(fp); + *lenp = len; + return ((wchar_t *)fp->_lb._base); + +error: + FUNLOCKFILE(fp); + *lenp = 0; + return (NULL); +} diff --git a/stdio/FreeBSD/fgetwln.c.patch b/stdio/FreeBSD/fgetwln.c.patch new file mode 100644 index 0000000..ee02383 --- /dev/null +++ b/stdio/FreeBSD/fgetwln.c.patch @@ -0,0 +1,30 @@ +--- fgetwln.c.orig 2005-09-14 19:51:14.000000000 -0700 ++++ fgetwln.c 2005-09-14 19:53:18.000000000 -0700 +@@ -35,7 +35,7 @@ + #include "local.h" + + wchar_t * +-fgetwln(FILE * __restrict fp, size_t *lenp) ++fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t loc) + { + wint_t wc; + size_t len; +@@ -44,7 +44,7 @@ + ORIENT(fp, 1); + + len = 0; +- while ((wc = __fgetwc(fp)) != WEOF) { ++ while ((wc = __fgetwc(fp, loc)) != WEOF) { + #define GROW 512 + if (len * sizeof(wchar_t) >= fp->_lb._size && + __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) +@@ -65,3 +65,9 @@ + *lenp = 0; + return (NULL); + } ++ ++wchar_t * ++fgetwln(FILE * __restrict fp, size_t *lenp) ++{ ++ return fgetwln_l(fp, lenp, __current_locale()); ++} diff --git a/stdio/FreeBSD/fgetws.3 b/stdio/FreeBSD/fgetws.3 index ac51398..eba1bb9 100644 --- a/stdio/FreeBSD/fgetws.3 +++ b/stdio/FreeBSD/fgetws.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)fgets.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/stdio/fgets.3,v 1.16 2002/05/31 05:01:17 archie Exp -.\" $FreeBSD: src/lib/libc/stdio/fgetws.3,v 1.3 2003/03/09 02:56:54 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fgetws.3,v 1.4 2007/01/09 00:28:06 imp Exp $ .\" .Dd August 6, 2002 .Dt FGETWS 3 diff --git a/stdio/FreeBSD/fgetws.3.patch b/stdio/FreeBSD/fgetws.3.patch index c589e6f..e170d86 100644 --- a/stdio/FreeBSD/fgetws.3.patch +++ b/stdio/FreeBSD/fgetws.3.patch @@ -1,6 +1,6 @@ ---- fgetws.3 2003-05-20 15:22:41.000000000 -0700 -+++ fgetws.3.edit 2006-08-12 09:44:23.000000000 -0700 -@@ -41,7 +41,8 @@ +--- fgetws.3.bsdnew 2009-11-11 13:33:05.000000000 -0800 ++++ fgetws.3 2009-11-11 13:33:05.000000000 -0800 +@@ -37,7 +37,8 @@ .Dt FGETWS 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nd get a line of wide characters from a stream .Sh LIBRARY .Lb libc -@@ -49,7 +50,21 @@ +@@ -45,7 +46,21 @@ .In stdio.h .In wchar.h .Ft "wchar_t *" @@ -33,7 +33,7 @@ .Sh DESCRIPTION The .Fn fgetws -@@ -57,7 +72,7 @@ +@@ -53,7 +68,7 @@ function reads at most one less than the number of characters specified by .Fa n from the given @@ -42,7 +42,7 @@ and stores them in the wide character string .Fa ws . Reading stops when a newline character is found, -@@ -66,6 +81,14 @@ +@@ -62,6 +77,14 @@ The newline, if any, is retained. If any characters are read and there is no error, a .Ql \e0 character is appended to end the string. @@ -57,7 +57,7 @@ .Sh RETURN VALUES Upon successful completion, .Fn fgetws -@@ -84,7 +107,8 @@ +@@ -80,7 +103,8 @@ and the buffer contents are indeterminat The .Fn fgetws function @@ -67,7 +67,7 @@ .Xr feof 3 and .Xr ferror 3 -@@ -96,7 +120,7 @@ +@@ -92,7 +116,7 @@ function will fail if: .Bl -tag -width Er .It Bq Er EBADF The given @@ -76,7 +76,7 @@ argument is not a readable stream. .It Bq Er EILSEQ The data obtained from the input stream does not form a valid -@@ -116,7 +140,8 @@ +@@ -112,7 +136,8 @@ or .Sh SEE ALSO .Xr feof 3 , .Xr ferror 3 , diff --git a/stdio/FreeBSD/fgetws.c b/stdio/FreeBSD/fgetws.c index be180c9..eaaa0f8 100644 --- a/stdio/FreeBSD/fgetws.c +++ b/stdio/FreeBSD/fgetws.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetws.c,v 1.6 2004/10/03 15:48:32 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetws.c,v 1.8 2009/11/25 04:45:45 wollman Exp $"); #include "namespace.h" #include @@ -62,7 +62,7 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) nl = memchr(fp->_p, '\n', fp->_r); nconv = __mbsnrtowcs(wsp, &src, nl != NULL ? (nl - fp->_p + 1) : fp->_r, - n - 1, &fp->_extra->mbstate); + n - 1, &fp->_mbstate); if (nconv == (size_t)-1) /* Conversion error */ goto error; @@ -86,10 +86,10 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) if (wsp == ws) /* EOF */ goto error; - if (!__mbsinit(&fp->_extra->mbstate)) + if (!__mbsinit(&fp->_mbstate)) /* Incomplete character */ goto error; - *wsp++ = L'\0'; + *wsp = L'\0'; FUNLOCKFILE(fp); return (ws); diff --git a/stdio/FreeBSD/fgetws.c.patch b/stdio/FreeBSD/fgetws.c.patch index 4f47289..b16f5a7 100644 --- a/stdio/FreeBSD/fgetws.c.patch +++ b/stdio/FreeBSD/fgetws.c.patch @@ -1,15 +1,15 @@ ---- fgetws.c.orig 2004-11-25 11:38:34.000000000 -0800 -+++ fgetws.c 2005-02-24 16:20:29.000000000 -0800 +--- fgetws.c.bsdnew 2009-11-30 16:15:32.000000000 -0800 ++++ fgetws.c 2009-11-30 16:15:32.000000000 -0800 @@ -27,6 +27,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/fgetws.c,v 1.6 2004/10/03 15:48:32 stefanf Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/fgetws.c,v 1.8 2009/11/25 04:45:45 wollman Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include #include -@@ -38,13 +40,18 @@ +@@ -38,13 +40,18 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/f #include "mblocal.h" wchar_t * @@ -29,7 +29,7 @@ FLOCKFILE(fp); ORIENT(fp, 1); -@@ -58,11 +65,11 @@ +@@ -58,11 +65,11 @@ fgetws(wchar_t * __restrict ws, int n, F goto error; wsp = ws; do { @@ -38,21 +38,21 @@ nl = memchr(fp->_p, '\n', fp->_r); nconv = __mbsnrtowcs(wsp, &src, nl != NULL ? (nl - fp->_p + 1) : fp->_r, -- n - 1, &fp->_extra->mbstate); -+ n - 1, &fp->_extra->mbstate, loc); +- n - 1, &fp->_mbstate); ++ n - 1, &fp->_mbstate, loc); if (nconv == (size_t)-1) /* Conversion error */ goto error; -@@ -86,7 +93,7 @@ +@@ -86,7 +93,7 @@ fgetws(wchar_t * __restrict ws, int n, F if (wsp == ws) /* EOF */ goto error; -- if (!__mbsinit(&fp->_extra->mbstate)) -+ if (!rl->__mbsinit(&fp->_extra->mbstate, loc)) +- if (!__mbsinit(&fp->_mbstate)) ++ if (!rl->__mbsinit(&fp->_mbstate, loc)) /* Incomplete character */ goto error; - *wsp++ = L'\0'; -@@ -98,3 +105,9 @@ + *wsp = L'\0'; +@@ -98,3 +105,9 @@ error: FUNLOCKFILE(fp); return (NULL); } diff --git a/stdio/FreeBSD/fileno.c b/stdio/FreeBSD/fileno.c index 60bac45..d99438c 100644 --- a/stdio/FreeBSD/fileno.c +++ b/stdio/FreeBSD/fileno.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fileno.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fileno.c,v 1.10 2004/03/17 01:43:07 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fileno.c,v 1.13 2008/05/05 16:03:52 jhb Exp $"); #include "namespace.h" #include @@ -46,6 +42,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/fileno.c,v 1.10 2004/03/17 01:43:07 tjr E #include "libc_private.h" #undef fileno +#undef fileno_unlocked int fileno(FILE *fp) @@ -58,3 +55,10 @@ fileno(FILE *fp) return (fd); } + +int +fileno_unlocked(FILE *fp) +{ + + return (__sfileno(fp)); +} diff --git a/stdio/FreeBSD/findfp.c b/stdio/FreeBSD/findfp.c index 2621966..f370d7a 100644 --- a/stdio/FreeBSD/findfp.c +++ b/stdio/FreeBSD/findfp.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)findfp.c 8.2 (Berkeley) 1/4/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/findfp.c,v 1.29 2004/05/22 15:19:41 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/findfp.c,v 1.34 2009/12/05 19:31:38 ed Exp $"); #include #include @@ -57,37 +53,25 @@ int __sdidinit; #define NDYNAMIC 10 /* add ten more whenever necessary */ -#define std(flags, file) \ - {0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \ - {0}, __sFX + file} - /* p r w flags file _bf z cookie close read seek write */ - /* _ub _extra */ +#define std(flags, file) { \ + ._flags = (flags), \ + ._file = (file), \ + ._cookie = __sF + (file), \ + ._close = __sclose, \ + ._read = __sread, \ + ._seek = __sseek, \ + ._write = __swrite, \ +} /* the usual - (stdin + stdout + stderr) */ static FILE usual[FOPEN_MAX - 3]; -static struct __sFILEX usual_extra[FOPEN_MAX - 3]; static struct glue uglue = { NULL, FOPEN_MAX - 3, usual }; -static struct __sFILEX __sFX[3]; - -/* - * We can't make this 'static' until 6.0-current due to binary - * compatibility concerns. This also means we cannot change the - * sizeof(FILE) until that time either and must continue to use the - * __sFILEX stuff to add to FILE. - */ -FILE __sF[3] = { +static FILE __sF[3] = { std(__SRD, STDIN_FILENO), std(__SWR, STDOUT_FILENO), std(__SWR|__SNBF, STDERR_FILENO) }; -/* - * The following kludge is done to ensure enough binary compatibility - * with future versions of libc. Or rather it allows us to work with - * libraries that have been built with a newer libc that defines these - * symbols and expects libc to provide them. We only have need to support - * i386 and alpha because they are the only "old" systems we have deployed. - */ FILE *__stdinp = &__sF[0]; FILE *__stdoutp = &__sF[1]; FILE *__stderrp = &__sF[2]; @@ -113,25 +97,17 @@ moreglue(n) { struct glue *g; static FILE empty; - static struct __sFILEX emptyx; FILE *p; - struct __sFILEX *fx; - g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE) + - n * sizeof(struct __sFILEX)); + g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)); if (g == NULL) return (NULL); p = (FILE *)ALIGN(g + 1); - fx = (struct __sFILEX *)&p[n]; g->next = NULL; g->niobs = n; g->iobs = p; - while (--n >= 0) { - *p = empty; - p->_extra = fx; - *p->_extra = emptyx; - p++, fx++; - } + while (--n >= 0) + *p++ = empty; return (g); } @@ -179,8 +155,8 @@ found: fp->_lb._base = NULL; /* no line buffer */ fp->_lb._size = 0; /* fp->_lock = NULL; */ /* once set always set (reused) */ - fp->_extra->orientation = 0; - memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t)); + fp->_orientation = 0; + memset(&fp->_mbstate, 0, sizeof(mbstate_t)); return (fp); } @@ -192,7 +168,7 @@ __warn_references(f_prealloc, "warning: this program uses f_prealloc(), which is not recommended."); void -f_prealloc() +f_prealloc(void) { struct glue *g; int n; @@ -233,17 +209,8 @@ _cleanup() void __sinit() { - int i; - THREAD_LOCK(); - if (__sdidinit == 0) { - /* Set _extra for the usual suspects. */ - for (i = 0; i < FOPEN_MAX - 3; i++) - usual[i]._extra = &usual_extra[i]; - - /* Make sure we clean up on exit. */ - __cleanup = _cleanup; /* conservative */ - __sdidinit = 1; - } - THREAD_UNLOCK(); + /* Make sure we clean up on exit. */ + __cleanup = _cleanup; /* conservative */ + __sdidinit = 1; } diff --git a/stdio/FreeBSD/findfp.c.patch b/stdio/FreeBSD/findfp.c.patch index c2d06d6..01da320 100644 --- a/stdio/FreeBSD/findfp.c.patch +++ b/stdio/FreeBSD/findfp.c.patch @@ -1,6 +1,14 @@ ---- findfp.c.orig 2009-02-15 03:11:22.000000000 -0800 -+++ findfp.c 2009-02-15 18:45:19.000000000 -0800 -@@ -46,7 +46,10 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/f +--- findfp.c.orig 2011-02-15 16:29:38.000000000 -0800 ++++ findfp.c 2011-02-16 10:36:00.000000000 -0800 +@@ -36,13 +36,18 @@ static char sccsid[] = "@(#)findfp.c 8.2 + #include + __FBSDID("$FreeBSD: src/lib/libc/stdio/findfp.c,v 1.34 2009/12/05 19:31:38 ed Exp $"); + ++#include ++ + #include + #include + #include #include #include #include @@ -11,37 +19,96 @@ #include #include "libc_private.h" -@@ -62,12 +65,19 @@ int __sdidinit; - {0}, __sFX + file} - /* p r w flags file _bf z cookie close read seek write */ - /* _ub _extra */ -+#define __sFXInit {0, PTHREAD_MUTEX_INITIALIZER} +@@ -51,7 +56,11 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/f + + int __sdidinit; + ++#if !TARGET_OS_EMBEDDED + #define NDYNAMIC 10 /* add ten more whenever necessary */ ++#else ++#define NDYNAMIC 1 /* add one at a time on embedded */ ++#endif + + #define std(flags, file) { \ + ._flags = (flags), \ +@@ -61,12 +70,32 @@ int __sdidinit; + ._read = __sread, \ + ._seek = __sseek, \ + ._write = __swrite, \ ++ ._extra = __sFX + file, \ + } ++#define __sFXInit {.fl_mutex = PTHREAD_MUTEX_INITIALIZER} + /* set counted */ -+#define __sFXInit3 {0, PTHREAD_MUTEX_INITIALIZER, 0, 0, 0, 1} - /* the usual - (stdin + stdout + stderr) */ ++#define __sFXInit3 {.fl_mutex = PTHREAD_MUTEX_INITIALIZER, .counted = 1} + +static int __scounted; /* streams counted against STREAM_MAX */ +static int __stream_max; + ++#if !TARGET_OS_EMBEDDED ++/* usual and usual_extra are data pigs. See 7929728. For embedded we should ++ * always allocate dynamically, and probably should for desktop too. */ + /* the usual - (stdin + stdout + stderr) */ static FILE usual[FOPEN_MAX - 3]; - static struct __sFILEX usual_extra[FOPEN_MAX - 3]; ++static struct __sFILEX usual_extra[FOPEN_MAX - 3]; static struct glue uglue = { NULL, FOPEN_MAX - 3, usual }; ++#endif /* !TARGET_OS_EMBEDDED */ --static struct __sFILEX __sFX[3]; +-static FILE __sF[3] = { +static struct __sFILEX __sFX[3] = {__sFXInit3, __sFXInit3, __sFXInit3}; ++ ++/* ++ * We can't make this 'static' due to binary compatibility concerns. ++ * This also means we cannot change the sizeof(FILE) and must continue to ++ * use the __sFILEX stuff to add to FILE. ++ */ ++FILE __sF[3] = { + std(__SRD, STDIN_FILENO), + std(__SWR, STDOUT_FILENO), + std(__SWR|__SNBF, STDERR_FILENO) +@@ -76,8 +105,13 @@ FILE *__stdinp = &__sF[0]; + FILE *__stdoutp = &__sF[1]; + FILE *__stderrp = &__sF[2]; - /* - * We can't make this 'static' until 6.0-current due to binary -@@ -113,7 +123,7 @@ moreglue(n) - { ++#if !TARGET_OS_EMBEDDED + struct glue __sglue = { &uglue, 3, __sF }; + static struct glue *lastglue = &uglue; ++#else ++struct glue __sglue = { NULL, 3, __sF }; ++static struct glue *lastglue = &__sglue; ++#endif + + static struct glue * moreglue(int); + +@@ -98,16 +132,25 @@ moreglue(n) struct glue *g; static FILE empty; -- static struct __sFILEX emptyx; -+ static struct __sFILEX emptyx = __sFXInit; FILE *p; - struct __sFILEX *fx; ++ static struct __sFILEX emptyx = __sFXInit; ++ struct __sFILEX *fx; + +- g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)); ++ g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE) + ++ n * sizeof(struct __sFILEX)); + if (g == NULL) + return (NULL); + p = (FILE *)ALIGN(g + 1); ++ fx = (struct __sFILEX *)&p[n]; + g->next = NULL; + g->niobs = n; + g->iobs = p; +- while (--n >= 0) +- *p++ = empty; ++ ++ while (--n >= 0) { ++ *p = empty; ++ p->_extra = fx; ++ *p->_extra = emptyx; ++ p++, fx++; ++ } + return (g); + } -@@ -139,7 +149,7 @@ moreglue(n) +@@ -115,7 +158,7 @@ moreglue(n) * Find a free FILE for fopen et al. */ FILE * @@ -50,7 +117,7 @@ { FILE *fp; int n; -@@ -147,6 +157,15 @@ __sfp() +@@ -123,6 +166,15 @@ __sfp() if (!__sdidinit) __sinit(); @@ -66,14 +133,14 @@ /* * The list must be locked because a FILE may be updated. */ -@@ -179,12 +198,27 @@ found: +@@ -155,12 +207,25 @@ found: fp->_lb._base = NULL; /* no line buffer */ fp->_lb._size = 0; /* fp->_lock = NULL; */ /* once set always set (reused) */ -+ fp->_extra->fl_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; - fp->_extra->orientation = 0; +- fp->_orientation = 0; +- memset(&fp->_mbstate, 0, sizeof(mbstate_t)); ++ INITEXTRA(fp); + fp->_extra->counted = count ? 1 : 0; - memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t)); return (fp); } @@ -83,9 +150,9 @@ +__private_extern__ void +__sfprelease(FILE *fp) +{ -+ if (fp->_extra->counted) { ++ if (fp->_counted) { + OSAtomicDecrement32(&__scounted); -+ fp->_extra->counted = 0; ++ fp->_counted = 0; + } + fp->_flags = 0; +} @@ -94,12 +161,32 @@ * XXX. Force immediate allocation of internal memory. Not used by stdio, * but documented historically for certain applications. Bad applications. */ -@@ -244,6 +278,8 @@ __sinit() - /* Make sure we clean up on exit. */ - __cleanup = _cleanup; /* conservative */ - __sdidinit = 1; +@@ -209,8 +274,25 @@ _cleanup() + void + __sinit() + { ++ THREAD_LOCK(); ++ if (__sdidinit == 0) { ++#if !TARGET_OS_EMBEDDED ++ int i; ++#endif ++ /* Make sure we clean up on exit. */ ++ __cleanup = _cleanup; /* conservative */ + __stream_max = sysconf(_SC_STREAM_MAX); + __scounted = 3; /* std{in,out,err} already exists */ - } - THREAD_UNLOCK(); ++ ++#if !TARGET_OS_EMBEDDED ++ /* Set _extra for the usual suspects. */ ++ for (i = 0; i < FOPEN_MAX - 3; i++) { ++ usual[i]._extra = &usual_extra[i]; ++ INITEXTRA(&usual[i]); ++ } ++#endif + +- /* Make sure we clean up on exit. */ +- __cleanup = _cleanup; /* conservative */ +- __sdidinit = 1; ++ __sdidinit = 1; ++ } ++ THREAD_UNLOCK(); } diff --git a/stdio/FreeBSD/flags.c b/stdio/FreeBSD/flags.c index cd90f83..17d175d 100644 --- a/stdio/FreeBSD/flags.c +++ b/stdio/FreeBSD/flags.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)flags.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/flags.c,v 1.9 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/flags.c,v 1.10 2007/01/09 00:28:06 imp Exp $"); #include #include diff --git a/stdio/FreeBSD/flags.c.patch b/stdio/FreeBSD/flags.c.patch index 31c0dab..1710d8a 100644 --- a/stdio/FreeBSD/flags.c.patch +++ b/stdio/FreeBSD/flags.c.patch @@ -1,6 +1,6 @@ ---- flags.c.orig 2003-05-20 15:22:41.000000000 -0700 -+++ flags.c 2005-11-16 17:49:13.000000000 -0800 -@@ -85,10 +85,17 @@ +--- flags.c.bsdnew 2009-11-11 13:33:06.000000000 -0800 ++++ flags.c 2009-11-11 13:33:06.000000000 -0800 +@@ -81,10 +81,17 @@ __sflags(mode, optr) } /* [rwa]\+ or [rwa]b\+ means read and write */ diff --git a/stdio/FreeBSD/floatio.h b/stdio/FreeBSD/floatio.h index 83beec7..9c57d8e 100644 --- a/stdio/FreeBSD/floatio.h +++ b/stdio/FreeBSD/floatio.h @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,7 +30,7 @@ * SUCH DAMAGE. * * @(#)floatio.h 8.1 (Berkeley) 6/4/93 - * $FreeBSD: src/lib/libc/stdio/floatio.h,v 1.5 2004/01/18 08:28:47 das Exp $ + * $FreeBSD: src/lib/libc/stdio/floatio.h,v 1.6 2007/01/09 00:28:06 imp Exp $ */ /* diff --git a/stdio/FreeBSD/fopen.3 b/stdio/FreeBSD/fopen.3 index a328c5b..aed0511 100644 --- a/stdio/FreeBSD/fopen.3 +++ b/stdio/FreeBSD/fopen.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fopen.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fopen.3,v 1.18 2003/01/26 10:01:59 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fopen.3,v 1.21 2009/09/09 19:38:19 ed Exp $ .\" .Dd January 26, 2003 .Dt FOPEN 3 @@ -74,7 +70,7 @@ The stream is positioned at the beginning of the file. Open for reading and writing. The stream is positioned at the beginning of the file. .It Dq Li w -Truncate file to zero length or create text file for writing. +Truncate to zero length or create text file for writing. The stream is positioned at the beginning of the file. .It Dq Li w+ Open for reading and writing. @@ -100,7 +96,7 @@ or similar. .Pp The .Fa mode -string can also include the letter ``b'' either as a third character or +string can also include the letter ``b'' either as last character or as a character between the characters in any of the two-character strings described above. This is strictly for compatibility with diff --git a/stdio/FreeBSD/fopen.3.patch b/stdio/FreeBSD/fopen.3.patch index 8675abe..cfb6e0c 100644 --- a/stdio/FreeBSD/fopen.3.patch +++ b/stdio/FreeBSD/fopen.3.patch @@ -1,6 +1,6 @@ ---- fopen.3 2003-05-20 15:22:41.000000000 -0700 -+++ fopen.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -40,8 +40,8 @@ +--- fopen.3.bsdnew 2009-11-11 13:33:06.000000000 -0800 ++++ fopen.3 2009-11-11 13:33:07.000000000 -0800 +@@ -36,8 +36,8 @@ .Dt FOPEN 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nm freopen .Nd stream open functions .Sh LIBRARY -@@ -49,17 +49,27 @@ +@@ -45,17 +45,27 @@ .Sh SYNOPSIS .In stdio.h .Ft FILE * @@ -42,7 +42,7 @@ and associates a stream with it. .Pp The argument -@@ -107,6 +117,17 @@ +@@ -103,6 +113,17 @@ This is strictly for compatibility with .St -isoC and has no effect; the ``b'' is ignored. .Pp @@ -60,7 +60,7 @@ Any created files will have mode .Pf \\*q Dv S_IRUSR \&| -@@ -148,7 +169,7 @@ +@@ -144,7 +165,7 @@ The .Fn freopen function opens the file whose name is the string pointed to by @@ -69,7 +69,7 @@ and associates the stream pointed to by .Fa stream with it. -@@ -160,7 +181,7 @@ +@@ -156,7 +177,7 @@ argument is used just as in the function. .Pp If the @@ -78,7 +78,7 @@ argument is .Dv NULL , .Fn freopen -@@ -204,7 +225,7 @@ +@@ -200,7 +221,7 @@ or .Sh RETURN VALUES Upon successful completion .Fn fopen , diff --git a/stdio/FreeBSD/fopen.c b/stdio/FreeBSD/fopen.c index 5a043ca..af7b71b 100644 --- a/stdio/FreeBSD/fopen.c +++ b/stdio/FreeBSD/fopen.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,14 +34,16 @@ static char sccsid[] = "@(#)fopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fopen.c,v 1.10 2002/10/12 16:13:37 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fopen.c,v 1.14 2008/04/22 17:03:32 jhb Exp $"); #include "namespace.h" #include #include #include +#include #include #include +#include #include "un-namespace.h" #include "local.h" @@ -67,6 +65,19 @@ fopen(file, mode) fp->_flags = 0; /* release */ return (NULL); } + /* + * File descriptors are a full int, but _file is only a short. + * If we get a valid file descriptor that is greater than + * SHRT_MAX, then the fd will get sign-extended into an + * invalid file descriptor. Handle this case by failing the + * open. + */ + if (f > SHRT_MAX) { + fp->_flags = 0; /* release */ + _close(f); + errno = EMFILE; + return (NULL); + } fp->_file = f; fp->_flags = flags; fp->_cookie = fp; diff --git a/stdio/FreeBSD/fopen.c.patch b/stdio/FreeBSD/fopen.c.patch index a6542f3..cd254a8 100644 --- a/stdio/FreeBSD/fopen.c.patch +++ b/stdio/FreeBSD/fopen.c.patch @@ -1,6 +1,6 @@ ---- fopen.c.orig 2009-02-15 03:11:22.000000000 -0800 -+++ fopen.c 2009-02-15 17:53:37.000000000 -0800 -@@ -34,6 +34,15 @@ +--- fopen.c.bsdnew 2009-11-11 13:33:07.000000000 -0800 ++++ fopen.c 2009-11-11 13:33:07.000000000 -0800 +@@ -30,6 +30,15 @@ * SUCH DAMAGE. */ @@ -16,7 +16,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)fopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ -@@ -61,10 +70,10 @@ fopen(file, mode) +@@ -59,10 +68,10 @@ fopen(file, mode) if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); @@ -28,4 +28,4 @@ + __sfprelease(fp); /* release */ return (NULL); } - fp->_file = f; + /* diff --git a/stdio/FreeBSD/fprintf.c b/stdio/FreeBSD/fprintf.c index 35093b0..f061bc9 100644 --- a/stdio/FreeBSD/fprintf.c +++ b/stdio/FreeBSD/fprintf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fprintf.c,v 1.10 2002/09/06 11:23:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fprintf.c,v 1.11 2007/01/09 00:28:06 imp Exp $"); #include #include diff --git a/stdio/FreeBSD/fprintf.c.patch b/stdio/FreeBSD/fprintf.c.patch index ec7b01f..add604c 100644 --- a/stdio/FreeBSD/fprintf.c.patch +++ b/stdio/FreeBSD/fprintf.c.patch @@ -1,15 +1,15 @@ ---- fprintf.c.orig 2003-05-20 15:22:41.000000000 -0700 -+++ fprintf.c 2005-02-23 16:20:47.000000000 -0800 -@@ -40,6 +40,8 @@ +--- fprintf.c.bsdnew 2009-11-11 13:33:07.000000000 -0800 ++++ fprintf.c 2009-11-11 13:33:07.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)fprintf.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/fprintf.c,v 1.10 2002/09/06 11:23:55 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/fprintf.c,v 1.11 2007/01/09 00:28:06 imp Exp $"); +#include "xlocale_private.h" + #include #include -@@ -50,7 +52,20 @@ +@@ -46,7 +48,20 @@ fprintf(FILE * __restrict fp, const char va_list ap; va_start(ap, fmt); diff --git a/stdio/FreeBSD/fpurge.c b/stdio/FreeBSD/fpurge.c index f191843..4a673ec 100644 --- a/stdio/FreeBSD/fpurge.c +++ b/stdio/FreeBSD/fpurge.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fpurge.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fpurge.c,v 1.10 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fpurge.c,v 1.11 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/fputc.c b/stdio/FreeBSD/fputc.c index a10af2b..e429d1c 100644 --- a/stdio/FreeBSD/fputc.c +++ b/stdio/FreeBSD/fputc.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fputc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fputc.c,v 1.13 2004/03/19 09:04:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fputc.c,v 1.14 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/fputs.3 b/stdio/FreeBSD/fputs.3 index a0c0341..c0feb0c 100644 --- a/stdio/FreeBSD/fputs.3 +++ b/stdio/FreeBSD/fputs.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fputs.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fputs.3,v 1.11 2002/12/19 09:40:24 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fputs.3,v 1.14 2007/04/19 14:01:04 phk Exp $ .\" .Dd June 4, 1993 .Dt FPUTS 3 @@ -70,14 +66,11 @@ and a terminating newline character, to the stream .Dv stdout . .Sh RETURN VALUES -The +The functions .Fn fputs -function -returns 0 on success and -.Dv EOF -on error; +and .Fn puts -returns a nonnegative integer on success and +return a nonnegative integer on success and .Dv EOF on error. .Sh ERRORS diff --git a/stdio/FreeBSD/fputs.3.patch b/stdio/FreeBSD/fputs.3.patch index 2d786ce..8f929c4 100644 --- a/stdio/FreeBSD/fputs.3.patch +++ b/stdio/FreeBSD/fputs.3.patch @@ -1,6 +1,6 @@ ---- fputs.3 2003-05-20 15:22:42.000000000 -0700 -+++ fputs.3.edit 2006-07-13 09:28:07.000000000 -0700 -@@ -48,14 +48,19 @@ +--- fputs.3.bsdnew 2009-11-11 13:33:07.000000000 -0800 ++++ fputs.3 2009-11-11 13:33:08.000000000 -0800 +@@ -44,14 +44,19 @@ .Sh SYNOPSIS .In stdio.h .Ft int @@ -23,7 +23,7 @@ to the stream pointed to by .Fa stream . .\" The terminating -@@ -65,7 +70,7 @@ +@@ -61,7 +66,7 @@ to the stream pointed to by The function .Fn puts writes the string @@ -32,7 +32,7 @@ and a terminating newline character, to the stream .Dv stdout . -@@ -97,6 +102,14 @@ +@@ -90,6 +95,14 @@ may also fail and set .Va errno for any of the errors specified for the routines .Xr write 2 . @@ -47,7 +47,7 @@ .Sh SEE ALSO .Xr ferror 3 , .Xr fputws 3 , -@@ -109,3 +122,13 @@ +@@ -102,3 +115,13 @@ and .Fn puts conform to .St -isoC . diff --git a/stdio/FreeBSD/fputs.c b/stdio/FreeBSD/fputs.c index 58278ab..a521685 100644 --- a/stdio/FreeBSD/fputs.c +++ b/stdio/FreeBSD/fputs.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fputs.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fputs.c,v 1.11 2002/10/12 16:13:37 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fputs.c,v 1.12 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/fputs.c.patch b/stdio/FreeBSD/fputs.c.patch index 1f55656..94ddea7 100644 --- a/stdio/FreeBSD/fputs.c.patch +++ b/stdio/FreeBSD/fputs.c.patch @@ -1,11 +1,6 @@ -Index: fputs.c -=================================================================== -RCS file: /cvs/root/Libc/stdio/FreeBSD/fputs.c,v -retrieving revision 1.2 -diff -u -d -b -w -p -u -r1.2 fputs.c ---- fputs.c 2003/05/20 22:22:42 1.2 -+++ fputs.c 2004/12/31 22:46:58 -@@ -48,6 +48,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/f +--- fputs.c.bsdnew 2009-11-11 13:33:08.000000000 -0800 ++++ fputs.c 2009-11-11 13:33:08.000000000 -0800 +@@ -44,6 +44,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/f #include "libc_private.h" #include "local.h" @@ -15,7 +10,7 @@ diff -u -d -b -w -p -u -r1.2 fputs.c /* * Write the given string to the given file. */ -@@ -60,6 +63,9 @@ fputs(s, fp) +@@ -56,6 +59,9 @@ fputs(s, fp) struct __suio uio; struct __siov iov; @@ -25,7 +20,7 @@ diff -u -d -b -w -p -u -r1.2 fputs.c iov.iov_base = (void *)s; iov.iov_len = uio.uio_resid = strlen(s); uio.uio_iov = &iov; -@@ -68,5 +74,9 @@ fputs(s, fp) +@@ -64,5 +70,9 @@ fputs(s, fp) ORIENT(fp, -1); retval = __sfvwrite(fp, &uio); FUNLOCKFILE(fp); diff --git a/stdio/FreeBSD/fputwc.c b/stdio/FreeBSD/fputwc.c index dfe876f..a26cdbd 100644 --- a/stdio/FreeBSD/fputwc.c +++ b/stdio/FreeBSD/fputwc.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fputwc.c,v 1.10 2004/07/20 08:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fputwc.c,v 1.11 2008/04/17 22:17:53 jhb Exp $"); #include "namespace.h" #include @@ -56,8 +56,7 @@ __fputwc(wchar_t wc, FILE *fp) *buf = (unsigned char)wc; len = 1; } else { - if ((len = __wcrtomb(buf, wc, &fp->_extra->mbstate)) == - (size_t)-1) { + if ((len = __wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); } diff --git a/stdio/FreeBSD/fputwc.c.patch b/stdio/FreeBSD/fputwc.c.patch index c514dd9..7264139 100644 --- a/stdio/FreeBSD/fputwc.c.patch +++ b/stdio/FreeBSD/fputwc.c.patch @@ -1,15 +1,15 @@ ---- fputwc.c.orig 2004-11-25 11:38:34.000000000 -0800 -+++ fputwc.c 2005-02-23 17:21:10.000000000 -0800 +--- fputwc.c.orig 2009-11-11 13:33:08.000000000 -0800 ++++ fputwc.c 2009-11-13 11:45:45.000000000 -0800 @@ -27,6 +27,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/fputwc.c,v 1.10 2004/07/20 08:27:27 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/fputwc.c,v 1.11 2008/04/17 22:17:53 jhb Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include #include -@@ -41,13 +43,14 @@ +@@ -41,13 +43,14 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/f /* * Non-MT-safe version. */ @@ -27,16 +27,16 @@ /* * Assume single-byte locale with no special encoding. * A more careful test would be to check -@@ -56,7 +59,7 @@ +@@ -56,7 +59,7 @@ __fputwc(wchar_t wc, FILE *fp) *buf = (unsigned char)wc; len = 1; } else { -- if ((len = __wcrtomb(buf, wc, &fp->_extra->mbstate)) == -+ if ((len = xrl->__wcrtomb(buf, wc, &fp->_extra->mbstate, loc)) == - (size_t)-1) { +- if ((len = __wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) { ++ if ((len = loc->__lc_ctype->__wcrtomb(buf, wc, &fp->_mbstate, loc)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); -@@ -80,7 +83,21 @@ + } +@@ -79,7 +82,21 @@ fputwc(wchar_t wc, FILE *fp) FLOCKFILE(fp); ORIENT(fp, 1); diff --git a/stdio/FreeBSD/fputws.3 b/stdio/FreeBSD/fputws.3 index 2642a74..096e349 100644 --- a/stdio/FreeBSD/fputws.3 +++ b/stdio/FreeBSD/fputws.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)fputs.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/stdio/fputs.3,v 1.8 2001/10/01 16:08:59 ru Exp -.\" $FreeBSD: src/lib/libc/stdio/fputws.3,v 1.5 2003/05/22 13:02:27 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fputws.3,v 1.6 2007/01/09 00:28:06 imp Exp $ .\" .Dd August 6, 2002 .Dt FPUTWS 3 diff --git a/stdio/FreeBSD/fputws.3.patch b/stdio/FreeBSD/fputws.3.patch index e9e9cb8..3b0e069 100644 --- a/stdio/FreeBSD/fputws.3.patch +++ b/stdio/FreeBSD/fputws.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdio/FreeBSD/fputws.3 2003-07-24 12:42:14.000000000 -0700 -+++ _SB/Libc/stdio/FreeBSD/fputws.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -41,7 +41,8 @@ +--- fputws.3.bsdnew 2009-11-11 13:33:08.000000000 -0800 ++++ fputws.3 2009-11-11 13:33:08.000000000 -0800 +@@ -37,7 +37,8 @@ .Dt FPUTWS 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nd output a line of wide characters to a stream .Sh LIBRARY .Lb libc -@@ -49,14 +50,34 @@ +@@ -45,14 +46,34 @@ .In stdio.h .In wchar.h .Ft int @@ -47,7 +47,7 @@ .Sh RETURN VALUES The .Fn fputws -@@ -69,7 +90,7 @@ +@@ -65,7 +86,7 @@ function will fail if: .Bl -tag -width Er .It Bq Er EBADF The @@ -56,7 +56,7 @@ argument supplied is not a writable stream. .El -@@ -84,7 +105,8 @@ +@@ -80,7 +101,8 @@ for any of the errors specified for the .Xr ferror 3 , .Xr fputs 3 , .Xr putwc 3 , diff --git a/stdio/FreeBSD/fputws.c b/stdio/FreeBSD/fputws.c index fea5914..6c4a333 100644 --- a/stdio/FreeBSD/fputws.c +++ b/stdio/FreeBSD/fputws.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fputws.c,v 1.6 2004/07/21 10:54:57 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fputws.c,v 1.8 2009/01/15 18:53:52 rdivacky Exp $"); #include "namespace.h" #include @@ -45,6 +45,7 @@ fputws(const wchar_t * __restrict ws, FILE * __restrict fp) char buf[BUFSIZ]; struct __suio uio; struct __siov iov; + const wchar_t *wsp; FLOCKFILE(fp); ORIENT(fp, 1); @@ -54,8 +55,9 @@ fputws(const wchar_t * __restrict ws, FILE * __restrict fp) uio.uio_iovcnt = 1; iov.iov_base = buf; do { - nbytes = __wcsnrtombs(buf, &ws, SIZE_T_MAX, sizeof(buf), - &fp->_extra->mbstate); + wsp = ws; + nbytes = __wcsnrtombs(buf, &wsp, SIZE_T_MAX, sizeof(buf), + &fp->_mbstate); if (nbytes == (size_t)-1) goto error; iov.iov_len = uio.uio_resid = nbytes; diff --git a/stdio/FreeBSD/fputws.c.patch b/stdio/FreeBSD/fputws.c.patch index 7be9f5e..4b2e29a 100644 --- a/stdio/FreeBSD/fputws.c.patch +++ b/stdio/FreeBSD/fputws.c.patch @@ -1,15 +1,15 @@ ---- fputws.c.orig 2004-11-25 11:38:34.000000000 -0800 -+++ fputws.c 2005-02-23 17:23:49.000000000 -0800 +--- fputws.c.orig 2010-03-18 18:11:42.000000000 -0700 ++++ fputws.c 2010-03-18 18:17:53.000000000 -0700 @@ -27,6 +27,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/fputws.c,v 1.6 2004/07/21 10:54:57 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/fputws.c,v 1.8 2009/01/15 18:53:52 rdivacky Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include #include -@@ -39,13 +41,17 @@ +@@ -39,14 +41,18 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/f #include "mblocal.h" int @@ -20,6 +20,8 @@ char buf[BUFSIZ]; struct __suio uio; struct __siov iov; +- const wchar_t *wsp; ++ const wchar_t *wsp = ws; + size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict, locale_t); @@ -28,16 +30,25 @@ FLOCKFILE(fp); ORIENT(fp, 1); if (prepwrite(fp) != 0) -@@ -55,7 +61,7 @@ +@@ -55,15 +61,14 @@ fputws(const wchar_t * __restrict ws, FI + uio.uio_iovcnt = 1; iov.iov_base = buf; do { - nbytes = __wcsnrtombs(buf, &ws, SIZE_T_MAX, sizeof(buf), -- &fp->_extra->mbstate); -+ &fp->_extra->mbstate, loc); +- wsp = ws; + nbytes = __wcsnrtombs(buf, &wsp, SIZE_T_MAX, sizeof(buf), +- &fp->_mbstate); ++ &fp->_mbstate, loc); if (nbytes == (size_t)-1) goto error; iov.iov_len = uio.uio_resid = nbytes; -@@ -69,3 +75,9 @@ + if (__sfvwrite(fp, &uio) != 0) + goto error; +- } while (ws != NULL); ++ } while (wsp != NULL); + FUNLOCKFILE(fp); + return (0); + +@@ -71,3 +76,9 @@ error: FUNLOCKFILE(fp); return (-1); } diff --git a/stdio/FreeBSD/fread.3 b/stdio/FreeBSD/fread.3 index b0bf094..4da3569 100644 --- a/stdio/FreeBSD/fread.3 +++ b/stdio/FreeBSD/fread.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fread.3 8.2 (Berkeley) 3/8/94 -.\" $FreeBSD: src/lib/libc/stdio/fread.3,v 1.9 2002/10/12 16:13:37 mike Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fread.3,v 1.10 2007/01/09 00:28:06 imp Exp $ .\" .Dd March 8, 1994 .Dt FREAD 3 diff --git a/stdio/FreeBSD/fread.3.patch b/stdio/FreeBSD/fread.3.patch index 697cc0a..2b00f38 100644 --- a/stdio/FreeBSD/fread.3.patch +++ b/stdio/FreeBSD/fread.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdio/FreeBSD/fread.3 2003-05-20 15:22:42.000000000 -0700 -+++ _SB/Libc/stdio/FreeBSD/fread.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -48,14 +48,16 @@ +--- fread.3.bsdnew 2009-11-11 13:33:08.000000000 -0800 ++++ fread.3 2009-11-11 13:33:09.000000000 -0800 +@@ -44,14 +44,16 @@ .Sh SYNOPSIS .In stdio.h .Ft size_t @@ -20,7 +20,7 @@ objects, each .Fa size bytes long, from the stream pointed to by -@@ -66,7 +68,7 @@ +@@ -62,7 +64,7 @@ storing them at the location given by The function .Fn fwrite writes @@ -29,7 +29,7 @@ objects, each .Fa size bytes long, to the stream pointed to by -@@ -86,7 +88,7 @@ +@@ -82,7 +84,7 @@ the return value is a short object count .Pp The function .Fn fread @@ -38,7 +38,7 @@ must use .Xr feof 3 and -@@ -95,7 +97,7 @@ +@@ -91,7 +93,7 @@ to determine which occurred. The function .Fn fwrite returns a value less than diff --git a/stdio/FreeBSD/fread.c b/stdio/FreeBSD/fread.c index ad5d81b..2430dab 100644 --- a/stdio/FreeBSD/fread.c +++ b/stdio/FreeBSD/fread.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fread.c 8.2 (Berkeley) 12/11/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fread.c,v 1.12 2002/10/12 16:13:37 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fread.c,v 1.16 2009/07/12 13:09:43 ed Exp $"); #include "namespace.h" #include @@ -47,11 +43,23 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/fread.c,v 1.12 2002/10/12 16:13:37 mike E #include "local.h" #include "libc_private.h" +/* + * MT-safe version + */ + size_t -fread(buf, size, count, fp) - void * __restrict buf; - size_t size, count; - FILE * __restrict fp; +fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) +{ + size_t ret; + + FLOCKFILE(fp); + ret = __fread(buf, size, count, fp); + FUNLOCKFILE(fp); + return (ret); +} + +size_t +__fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) { size_t resid; char *p; @@ -59,13 +67,10 @@ fread(buf, size, count, fp) size_t total; /* - * The ANSI standard requires a return value of 0 for a count - * or a size of 0. Peculiarily, it imposes no such requirements - * on fwrite; it only requires fread to be broken. + * ANSI and SUSv2 require a return value of 0 if size or count are 0. */ if ((resid = count * size) == 0) return (0); - FLOCKFILE(fp); ORIENT(fp, -1); if (fp->_r < 0) fp->_r = 0; @@ -79,13 +84,11 @@ fread(buf, size, count, fp) resid -= r; if (__srefill(fp)) { /* no more input: return partial result */ - FUNLOCKFILE(fp); return ((total - resid) / size); } } (void)memcpy((void *)p, (void *)fp->_p, resid); fp->_r -= resid; fp->_p += resid; - FUNLOCKFILE(fp); return (count); } diff --git a/stdio/FreeBSD/fread.c.patch b/stdio/FreeBSD/fread.c.patch index 59b4883..7d38746 100644 --- a/stdio/FreeBSD/fread.c.patch +++ b/stdio/FreeBSD/fread.c.patch @@ -1,6 +1,6 @@ ---- fread.c.orig 2008-08-29 21:58:50.000000000 -0700 -+++ fread.c 2008-09-02 02:18:06.000000000 -0700 -@@ -55,7 +55,7 @@ fread(buf, size, count, fp) +--- fread.c.bsdnew 2009-11-11 13:33:09.000000000 -0800 ++++ fread.c 2009-11-11 14:14:22.000000000 -0800 +@@ -63,7 +63,7 @@ __fread(void * __restrict buf, size_t si { size_t resid; char *p; @@ -9,7 +9,7 @@ size_t total; /* -@@ -71,21 +71,70 @@ fread(buf, size, count, fp) +@@ -76,19 +76,66 @@ __fread(void * __restrict buf, size_t si fp->_r = 0; total = resid; p = buf; @@ -25,7 +25,6 @@ + break; + else if (ret) { /* no more input: return partial result */ - FUNLOCKFILE(fp); return ((total - resid) / size); } } @@ -52,7 +51,6 @@ + fp->_bf = save; + fp->_p = fp->_bf._base; + /* fp->_r = 0; already set in __srefill1 */ -+ FUNLOCKFILE(fp); + return ((total - resid) / size); + } + fp->_bf._base += fp->_r; @@ -73,7 +71,6 @@ + resid -= r; + if (__srefill1(fp)) { + /* no more input: return partial result */ -+ FUNLOCKFILE(fp); + return ((total - resid) / size); + } + } @@ -81,6 +78,5 @@ + fp->_r -= resid; + fp->_p += resid; + } - FUNLOCKFILE(fp); return (count); } diff --git a/stdio/FreeBSD/freopen.c b/stdio/FreeBSD/freopen.c index ddd978e..524ae6d 100644 --- a/stdio/FreeBSD/freopen.c +++ b/stdio/FreeBSD/freopen.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,13 +34,14 @@ static char sccsid[] = "@(#)freopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/freopen.c,v 1.13 2004/05/22 15:19:41 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/freopen.c,v 1.21 2008/04/17 22:17:54 jhb Exp $"); #include "namespace.h" #include #include #include #include +#include #include #include #include @@ -67,7 +64,9 @@ freopen(file, mode, fp) int dflags, flags, isopen, oflags, sverrno, wantfd; if ((flags = __sflags(mode, &oflags)) == 0) { + sverrno = errno; (void) fclose(fp); + errno = sverrno; return (NULL); } @@ -102,6 +101,8 @@ freopen(file, mode, fp) errno = EINVAL; return (NULL); } + if (fp->_flags & __SWR) + (void) __sflush(fp); if ((oflags ^ dflags) & O_APPEND) { dflags &= ~O_APPEND; dflags |= oflags & O_APPEND; @@ -114,15 +115,9 @@ freopen(file, mode, fp) } } if (oflags & O_TRUNC) - ftruncate(fp->_file, 0); - if (_fseeko(fp, 0, oflags & O_APPEND ? SEEK_END : SEEK_SET, - 0) < 0 && errno != ESPIPE) { - sverrno = errno; - fclose(fp); - FUNLOCKFILE(fp); - errno = sverrno; - return (NULL); - } + (void) ftruncate(fp->_file, (off_t)0); + if (!(oflags & O_APPEND)) + (void) _sseek(fp, (fpos_t)0, SEEK_SET); f = fp->_file; isopen = 0; wantfd = -1; @@ -187,13 +182,13 @@ finish: if (HASLB(fp)) FREELB(fp); fp->_lb._size = 0; - fp->_extra->orientation = 0; - memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t)); + fp->_orientation = 0; + memset(&fp->_mbstate, 0, sizeof(mbstate_t)); if (f < 0) { /* did not get it after all */ fp->_flags = 0; /* set it free */ - errno = sverrno; /* restore in case _close clobbered */ FUNLOCKFILE(fp); + errno = sverrno; /* restore in case _close clobbered */ return (NULL); } @@ -209,6 +204,20 @@ finish: } } + /* + * File descriptors are a full int, but _file is only a short. + * If we get a valid file descriptor that is greater than + * SHRT_MAX, then the fd will get sign-extended into an + * invalid file descriptor. Handle this case by failing the + * open. + */ + if (f > SHRT_MAX) { + fp->_flags = 0; /* set it free */ + FUNLOCKFILE(fp); + errno = EMFILE; + return (NULL); + } + fp->_flags = flags; fp->_file = f; fp->_cookie = fp; @@ -216,6 +225,16 @@ finish: fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; + /* + * When opening in append mode, even though we use O_APPEND, + * we need to seek to the end so that ftell() gets the right + * answer. If the user then alters the seek pointer, or + * the file extends, this will fail, but there is not much + * we can do about this. (We could set __SAPP and check in + * fseek and ftell.) + */ + if (oflags & O_APPEND) + (void) _sseek(fp, (fpos_t)0, SEEK_END); FUNLOCKFILE(fp); return (fp); } diff --git a/stdio/FreeBSD/freopen.c.patch b/stdio/FreeBSD/freopen.c.patch index a07ac7c..ba84faa 100644 --- a/stdio/FreeBSD/freopen.c.patch +++ b/stdio/FreeBSD/freopen.c.patch @@ -1,6 +1,6 @@ ---- freopen.c.orig 2009-02-15 03:11:22.000000000 -0800 -+++ freopen.c 2009-02-15 14:26:16.000000000 -0800 -@@ -99,7 +99,7 @@ freopen(file, mode, fp) +--- freopen.c.bsdnew 2009-11-11 13:33:09.000000000 -0800 ++++ freopen.c 2009-11-11 14:45:57.000000000 -0800 +@@ -98,7 +98,7 @@ freopen(file, mode, fp) (oflags & O_ACCMODE)) { fclose(fp); FUNLOCKFILE(fp); @@ -8,8 +8,8 @@ + errno = EBADF; return (NULL); } - if ((oflags ^ dflags) & O_APPEND) { -@@ -136,6 +136,8 @@ freopen(file, mode, fp) + if (fp->_flags & __SWR) +@@ -131,6 +131,8 @@ freopen(file, mode, fp) * descriptor (if any) was associated with it. If it was attached to * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin) * should work. This is unnecessary if it was not a Unix file. @@ -18,7 +18,7 @@ */ if (fp->_flags == 0) { fp->_flags = __SEOF; /* hold on to it */ -@@ -146,11 +148,18 @@ freopen(file, mode, fp) +@@ -141,11 +143,18 @@ freopen(file, mode, fp) if (fp->_flags & __SWR) (void) __sflush(fp); /* if close is NULL, closing is a no-op, hence pointless */ @@ -37,12 +37,21 @@ } /* Get a new descriptor to refer to the new file. */ -@@ -191,7 +200,7 @@ finish: - memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t)); +@@ -186,7 +195,7 @@ finish: + memset(&fp->_mbstate, 0, sizeof(mbstate_t)); if (f < 0) { /* did not get it after all */ - fp->_flags = 0; /* set it free */ + __sfprelease(fp); /* set it free */ + FUNLOCKFILE(fp); errno = sverrno; /* restore in case _close clobbered */ + return (NULL); +@@ -212,7 +221,7 @@ finish: + * open. + */ + if (f > SHRT_MAX) { +- fp->_flags = 0; /* set it free */ ++ __sfprelease(fp); /* set it free */ FUNLOCKFILE(fp); + errno = EMFILE; return (NULL); diff --git a/stdio/FreeBSD/fscanf.c b/stdio/FreeBSD/fscanf.c index aaad500..27b6849 100644 --- a/stdio/FreeBSD/fscanf.c +++ b/stdio/FreeBSD/fscanf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fscanf.c,v 1.12 2003/01/03 23:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fscanf.c,v 1.13 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/fscanf.c.patch b/stdio/FreeBSD/fscanf.c.patch index fd0150f..4a2796c 100644 --- a/stdio/FreeBSD/fscanf.c.patch +++ b/stdio/FreeBSD/fscanf.c.patch @@ -1,15 +1,15 @@ ---- fscanf.c.orig 2003-05-20 15:22:42.000000000 -0700 -+++ fscanf.c 2005-02-23 16:23:38.000000000 -0800 -@@ -40,6 +40,8 @@ +--- fscanf.c.bsdnew 2009-11-11 13:33:09.000000000 -0800 ++++ fscanf.c 2009-11-11 13:33:09.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)fscanf.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/fscanf.c,v 1.12 2003/01/03 23:27:27 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/fscanf.c,v 1.13 2007/01/09 00:28:06 imp Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include #include -@@ -55,7 +57,22 @@ +@@ -51,7 +53,22 @@ fscanf(FILE * __restrict fp, char const va_start(ap, fmt); FLOCKFILE(fp); diff --git a/stdio/FreeBSD/fseek.3 b/stdio/FreeBSD/fseek.3 index 2f35186..5a25dab 100644 --- a/stdio/FreeBSD/fseek.3 +++ b/stdio/FreeBSD/fseek.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fseek.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fseek.3,v 1.25 2004/03/20 08:38:27 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fseek.3,v 1.27 2007/06/18 02:13:04 ache Exp $ .\" .Dd March 19, 2004 .Dt FSEEK 3 @@ -236,8 +232,9 @@ The functions .Fn fseeko , .Fn fsetpos , .Fn ftell , +.Fn ftello , and -.Fn ftello +.Fn rewind may also fail and set .Va errno for any of the errors specified for the routines diff --git a/stdio/FreeBSD/fseek.3.patch b/stdio/FreeBSD/fseek.3.patch index 9ac9e00..91fe9fe 100644 --- a/stdio/FreeBSD/fseek.3.patch +++ b/stdio/FreeBSD/fseek.3.patch @@ -1,6 +1,6 @@ ---- fseek.3 2004-11-25 11:38:34.000000000 -0800 -+++ fseek.3.edit 2006-07-12 11:18:41.000000000 -0700 -@@ -53,20 +53,39 @@ +--- fseek.3.bsdnew 2009-11-11 13:33:09.000000000 -0800 ++++ fseek.3 2009-11-11 13:33:09.000000000 -0800 +@@ -49,20 +49,39 @@ .Sh SYNOPSIS .In stdio.h .Ft int @@ -50,7 +50,7 @@ .Sh DESCRIPTION The .Fn fseek -@@ -246,12 +265,29 @@ +@@ -243,12 +262,29 @@ for any of the errors specified for the .Xr lseek 2 , and .Xr malloc 3 . diff --git a/stdio/FreeBSD/fseek.c b/stdio/FreeBSD/fseek.c index e6a5bd6..24c424e 100644 --- a/stdio/FreeBSD/fseek.c +++ b/stdio/FreeBSD/fseek.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fseek.c 8.3 (Berkeley) 1/2/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fseek.c,v 1.41 2004/05/22 15:19:41 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fseek.c,v 1.44 2008/04/17 22:17:54 jhb Exp $"); #include "namespace.h" #include @@ -237,7 +233,7 @@ _fseeko(fp, offset, whence, ltest) */ if (HASUB(fp)) { curoff += fp->_r; /* kill off ungetc */ - n = fp->_extra->_up - fp->_bf._base; + n = fp->_up - fp->_bf._base; curoff -= n; n += fp->_ur; } else { @@ -259,7 +255,7 @@ _fseeko(fp, offset, whence, ltest) if (HASUB(fp)) FREEUB(fp); fp->_flags &= ~__SEOF; - memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t)); + memset(&fp->_mbstate, 0, sizeof(mbstate_t)); return (0); } @@ -287,6 +283,7 @@ abspos: fp->_r -= n; } fp->_flags &= ~__SEOF; + memset(&fp->_mbstate, 0, sizeof(mbstate_t)); return (0); /* @@ -297,6 +294,11 @@ dumb: if (__sflush(fp) || (ret = _sseek(fp, (fpos_t)offset, whence)) == POS_ERR) return (-1); + if (ltest && ret > LONG_MAX) { + fp->_flags |= __SERR; + errno = EOVERFLOW; + return (-1); + } /* success: clear EOF indicator and discard ungetc() data */ if (HASUB(fp)) FREEUB(fp); @@ -304,11 +306,6 @@ dumb: fp->_r = 0; /* fp->_w = 0; */ /* unnecessary (I think...) */ fp->_flags &= ~__SEOF; - memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t)); - if (ltest && ret > LONG_MAX) { - fp->_flags |= __SERR; - errno = EOVERFLOW; - return (-1); - } + memset(&fp->_mbstate, 0, sizeof(mbstate_t)); return (0); } diff --git a/stdio/FreeBSD/fsetpos.c b/stdio/FreeBSD/fsetpos.c index 6d75acd..6d9bddf 100644 --- a/stdio/FreeBSD/fsetpos.c +++ b/stdio/FreeBSD/fsetpos.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fsetpos.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fsetpos.c,v 1.8 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fsetpos.c,v 1.9 2007/01/09 00:28:06 imp Exp $"); #include #include diff --git a/stdio/FreeBSD/ftell.c b/stdio/FreeBSD/ftell.c index 477e3a1..a0849d2 100644 --- a/stdio/FreeBSD/ftell.c +++ b/stdio/FreeBSD/ftell.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)ftell.c 8.2 (Berkeley) 5/4/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/ftell.c,v 1.26 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/ftell.c,v 1.27 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/ftell.c.patch b/stdio/FreeBSD/ftell.c.patch index 68109d1..528b85b 100644 --- a/stdio/FreeBSD/ftell.c.patch +++ b/stdio/FreeBSD/ftell.c.patch @@ -1,11 +1,6 @@ -Index: ftell.c -=================================================================== -RCS file: /cvs/root/Libc/stdio/FreeBSD/ftell.c,v -retrieving revision 1.2 -diff -u -d -b -w -p -p -r1.2 ftell.c ---- ftell.c 2003/05/20 22:22:42 1.2 -+++ ftell.c 2005/03/14 03:10:02 -@@ -105,6 +105,8 @@ _ftello(fp, offset) +--- ftell.c.bsdnew 2009-11-11 13:33:10.000000000 -0800 ++++ ftell.c 2009-11-11 13:33:10.000000000 -0800 +@@ -101,6 +101,8 @@ _ftello(fp, offset) * Find offset of underlying I/O object, then * adjust for buffered bytes. */ diff --git a/stdio/FreeBSD/funopen.3 b/stdio/FreeBSD/funopen.3 index e40a5dd..f4a3f1c 100644 --- a/stdio/FreeBSD/funopen.3 +++ b/stdio/FreeBSD/funopen.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)funopen.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/stdio/funopen.3,v 1.15 2004/07/03 22:30:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/funopen.3,v 1.16 2007/01/09 00:28:06 imp Exp $ .\" .Dd March 19, 2004 .Dt FUNOPEN 3 diff --git a/stdio/FreeBSD/funopen.c b/stdio/FreeBSD/funopen.c index 040c806..64a56f2 100644 --- a/stdio/FreeBSD/funopen.c +++ b/stdio/FreeBSD/funopen.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)funopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/funopen.c,v 1.5 2002/05/28 16:59:39 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/funopen.c,v 1.7 2009/12/05 19:31:38 ed Exp $"); #include #include @@ -46,11 +42,11 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/funopen.c,v 1.5 2002/05/28 16:59:39 alfre #include "local.h" FILE * -funopen(cookie, readfn, writefn, seekfn, closefn) - const void *cookie; - int (*readfn)(), (*writefn)(); - fpos_t (*seekfn)(void *cookie, fpos_t off, int whence); - int (*closefn)(); +funopen(const void *cookie, + int (*readfn)(void *, char *, int), + int (*writefn)(void *, const char *, int), + fpos_t (*seekfn)(void *, fpos_t, int), + int (*closefn)(void *)) { FILE *fp; int flags; diff --git a/stdio/FreeBSD/funopen.c.patch b/stdio/FreeBSD/funopen.c.patch index 5b4045d..b7edcfc 100644 --- a/stdio/FreeBSD/funopen.c.patch +++ b/stdio/FreeBSD/funopen.c.patch @@ -1,6 +1,6 @@ ---- funopen.c.orig 2009-02-15 03:11:22.000000000 -0800 -+++ funopen.c 2009-02-15 14:02:06.000000000 -0800 -@@ -67,7 +67,8 @@ funopen(cookie, readfn, writefn, seekfn, +--- funopen.c.bsdnew 2009-11-11 13:33:10.000000000 -0800 ++++ funopen.c 2009-11-11 13:33:10.000000000 -0800 +@@ -63,7 +63,8 @@ funopen(cookie, readfn, writefn, seekfn, else flags = __SRW; /* read-write */ } diff --git a/stdio/FreeBSD/fvwrite.c b/stdio/FreeBSD/fvwrite.c index fd12da1..719c120 100644 --- a/stdio/FreeBSD/fvwrite.c +++ b/stdio/FreeBSD/fvwrite.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fvwrite.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fvwrite.c,v 1.17 2004/06/08 05:45:48 das Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fvwrite.c,v 1.19 2009/11/25 04:21:42 wollman Exp $"); #include #include @@ -64,7 +60,7 @@ __sfvwrite(fp, uio) char *nl; int nlknown, nldist; - if ((len = uio->uio_resid) == 0) + if (uio->uio_resid == 0) return (0); /* make sure we can write */ if (prepwrite(fp) != 0) diff --git a/stdio/FreeBSD/fvwrite.h b/stdio/FreeBSD/fvwrite.h index 5414ec8..45a0382 100644 --- a/stdio/FreeBSD/fvwrite.h +++ b/stdio/FreeBSD/fvwrite.h @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,7 +30,7 @@ * SUCH DAMAGE. * * @(#)fvwrite.h 8.1 (Berkeley) 6/4/93 - * $FreeBSD: src/lib/libc/stdio/fvwrite.h,v 1.3 2002/05/28 16:59:39 alfred Exp $ + * $FreeBSD: src/lib/libc/stdio/fvwrite.h,v 1.4 2007/01/09 00:28:06 imp Exp $ */ /* diff --git a/stdio/FreeBSD/fwalk.c b/stdio/FreeBSD/fwalk.c index a8a49fc..10d93d9 100644 --- a/stdio/FreeBSD/fwalk.c +++ b/stdio/FreeBSD/fwalk.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fwalk.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fwalk.c,v 1.9 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fwalk.c,v 1.10 2007/01/09 00:28:06 imp Exp $"); #include #include diff --git a/stdio/FreeBSD/fwide.c b/stdio/FreeBSD/fwide.c index 1386c48..c19aa5c 100644 --- a/stdio/FreeBSD/fwide.c +++ b/stdio/FreeBSD/fwide.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fwide.c,v 1.1 2002/08/13 09:30:41 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fwide.c,v 1.2 2008/04/17 22:17:54 jhb Exp $"); #include "namespace.h" #include @@ -42,9 +42,9 @@ fwide(FILE *fp, int mode) FLOCKFILE(fp); /* Only change the orientation if the stream is not oriented yet. */ - if (mode != 0 && fp->_extra->orientation == 0) - fp->_extra->orientation = mode > 0 ? 1 : -1; - m = fp->_extra->orientation; + if (mode != 0 && fp->_orientation == 0) + fp->_orientation = mode > 0 ? 1 : -1; + m = fp->_orientation; FUNLOCKFILE(fp); return (m); diff --git a/stdio/FreeBSD/fwrite.c b/stdio/FreeBSD/fwrite.c index 27b660e..0c40b93 100644 --- a/stdio/FreeBSD/fwrite.c +++ b/stdio/FreeBSD/fwrite.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fwrite.c,v 1.11 2002/10/12 16:13:41 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fwrite.c,v 1.13 2009/07/12 13:09:43 ed Exp $"); #include "namespace.h" #include @@ -61,8 +57,15 @@ fwrite(buf, size, count, fp) struct __suio uio; struct __siov iov; + /* + * ANSI and SUSv2 require a return value of 0 if size or count are 0. + */ + n = count * size; + if (n == 0) + return (0); + iov.iov_base = (void *)buf; - uio.uio_resid = iov.iov_len = n = count * size; + uio.uio_resid = iov.iov_len = n; uio.uio_iov = &iov; uio.uio_iovcnt = 1; diff --git a/stdio/FreeBSD/fwrite.c.patch b/stdio/FreeBSD/fwrite.c.patch index 55399f3..5dcd790 100644 --- a/stdio/FreeBSD/fwrite.c.patch +++ b/stdio/FreeBSD/fwrite.c.patch @@ -1,14 +1,14 @@ ---- fwrite.c.orig 2004-11-01 00:27:25.000000000 -0800 -+++ fwrite.c 2004-11-01 00:29:40.000000000 -0800 -@@ -63,6 +63,11 @@ - - iov.iov_base = (void *)buf; - uio.uio_resid = iov.iov_len = n = count * size; -+ +--- fwrite.c.orig 2009-12-08 00:25:43.000000000 -0800 ++++ fwrite.c 2009-12-08 00:25:12.000000000 -0800 +@@ -61,9 +61,10 @@ fwrite(buf, size, count, fp) + * ANSI and SUSv2 require a return value of 0 if size or count are 0. + */ + n = count * size; +#if __DARWIN_UNIX03 -+ if (n == 0) /* POSIX */ -+ return 0; -+#endif /* __DARWIN_UNIX03 */ + if (n == 0) + return (0); +- ++#endif + iov.iov_base = (void *)buf; + uio.uio_resid = iov.iov_len = n; uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - diff --git a/stdio/FreeBSD/getc.3 b/stdio/FreeBSD/getc.3 index fd015af..26a7022 100644 --- a/stdio/FreeBSD/getc.3 +++ b/stdio/FreeBSD/getc.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/getc.3,v 1.19 2004/03/17 12:37:28 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/getc.3,v 1.21 2007/01/09 00:28:06 imp Exp $ .\" .Dd January 10, 2003 .Dt GETC 3 @@ -58,7 +54,7 @@ .Ft int .Fn getc_unlocked "FILE *stream" .Ft int -.Fn getchar +.Fn getchar void .Ft int .Fn getchar_unlocked "void" .Ft int diff --git a/stdio/FreeBSD/getc.3.patch b/stdio/FreeBSD/getc.3.patch index 045b4ab..6435525 100644 --- a/stdio/FreeBSD/getc.3.patch +++ b/stdio/FreeBSD/getc.3.patch @@ -1,15 +1,15 @@ ---- _SB/Libc/stdio/FreeBSD/getc.3 2004-11-25 11:38:34.000000000 -0800 -+++ _SB/Libc/stdio/FreeBSD/getc.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -58,7 +58,7 @@ +--- getc.3.bsdnew 2009-11-11 13:33:11.000000000 -0800 ++++ getc.3 2009-11-11 14:52:54.000000000 -0800 +@@ -54,7 +54,7 @@ .Ft int .Fn getc_unlocked "FILE *stream" .Ft int --.Fn getchar +-.Fn getchar void +.Fn getchar "void" .Ft int .Fn getchar_unlocked "void" .Ft int -@@ -145,7 +145,7 @@ +@@ -141,7 +141,7 @@ until the condition is cleared with .Sh STANDARDS The .Fn fgetc , diff --git a/stdio/FreeBSD/getc.c b/stdio/FreeBSD/getc.c index 0aa9dca..06ad2a3 100644 --- a/stdio/FreeBSD/getc.c +++ b/stdio/FreeBSD/getc.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)getc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/getc.c,v 1.13 2004/03/19 09:04:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/getc.c,v 1.16 2008/05/05 16:03:52 jhb Exp $"); #include "namespace.h" #include @@ -47,6 +43,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/getc.c,v 1.13 2004/03/19 09:04:56 tjr Exp #include "local.h" #undef getc +#undef getc_unlocked int getc(FILE *fp) @@ -59,3 +56,10 @@ getc(FILE *fp) FUNLOCKFILE(fp); return (retval); } + +int +getc_unlocked(FILE *fp) +{ + + return (__sgetc(fp)); +} diff --git a/stdio/FreeBSD/getchar.c b/stdio/FreeBSD/getchar.c index 2ea530f..a17496a 100644 --- a/stdio/FreeBSD/getchar.c +++ b/stdio/FreeBSD/getchar.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)getchar.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/getchar.c,v 1.12 2004/03/19 09:04:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/getchar.c,v 1.15 2008/05/05 16:03:52 jhb Exp $"); /* * A subroutine version of the macro getchar. @@ -50,6 +46,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/getchar.c,v 1.12 2004/03/19 09:04:56 tjr #include "libc_private.h" #undef getchar +#undef getchar_unlocked int getchar() @@ -62,3 +59,10 @@ getchar() FUNLOCKFILE(stdin); return (retval); } + +int +getchar_unlocked(void) +{ + + return (__sgetc(stdin)); +} diff --git a/stdio/FreeBSD/getdelim.c b/stdio/FreeBSD/getdelim.c new file mode 100644 index 0000000..8faa92d --- /dev/null +++ b/stdio/FreeBSD/getdelim.c @@ -0,0 +1,160 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/stdio/getdelim.c,v 1.3 2009/10/04 19:43:36 das Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" +#include "local.h" + +static inline size_t +p2roundup(size_t n) +{ + + if (!powerof2(n)) { + n--; + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; +#if SIZE_T_MAX > 0xffffffffU + n |= n >> 32; +#endif + n++; + } + return (n); +} + +/* + * Expand *linep to hold len bytes (up to SSIZE_MAX + 1). + */ +static inline int +expandtofit(char ** __restrict linep, size_t len, size_t * __restrict capp) +{ + char *newline; + size_t newcap; + + if (len > (size_t)SSIZE_MAX + 1) { + errno = EOVERFLOW; + return (-1); + } + if (len > *capp) { + if (len == (size_t)SSIZE_MAX + 1) /* avoid overflow */ + newcap = (size_t)SSIZE_MAX + 1; + else + newcap = p2roundup(len); + newline = realloc(*linep, newcap); + if (newline == NULL) + return (-1); + *capp = newcap; + *linep = newline; + } + return (0); +} + +/* + * Append the src buffer to the *dstp buffer. The buffers are of + * length srclen and *dstlenp, respectively, and dst has space for + * *dstlenp bytes. After the call, *dstlenp and *dstcapp are updated + * appropriately, and *dstp is reallocated if needed. Returns 0 on + * success, -1 on allocation failure. + */ +static int +sappend(char ** __restrict dstp, size_t * __restrict dstlenp, + size_t * __restrict dstcapp, char * __restrict src, size_t srclen) +{ + + /* ensure room for srclen + dstlen + terminating NUL */ + if (expandtofit(dstp, srclen + *dstlenp + 1, dstcapp)) + return (-1); + memcpy(*dstp + *dstlenp, src, srclen); + *dstlenp += srclen; + return (0); +} + +ssize_t +getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim, + FILE * __restrict fp) +{ + u_char *endp; + size_t linelen; + + FLOCKFILE(fp); + ORIENT(fp, -1); + + if (linep == NULL || linecapp == NULL) { + errno = EINVAL; + goto error; + } + + if (*linep == NULL) + *linecapp = 0; + + if (fp->_r <= 0 && __srefill(fp)) { + /* If fp is at EOF already, we just need space for the NUL. */ + if (__sferror(fp) || expandtofit(linep, 1, linecapp)) + goto error; + FUNLOCKFILE(fp); + (*linep)[0] = '\0'; + return (-1); + } + + linelen = 0; + while ((endp = memchr(fp->_p, delim, fp->_r)) == NULL) { + if (sappend(linep, &linelen, linecapp, fp->_p, fp->_r)) + goto error; + if (__srefill(fp)) { + if (__sferror(fp)) + goto error; + goto done; /* hit EOF */ + } + } + endp++; /* snarf the delimiter, too */ + if (sappend(linep, &linelen, linecapp, fp->_p, endp - fp->_p)) + goto error; + fp->_r -= endp - fp->_p; + fp->_p = endp; +done: + /* Invariant: *linep has space for at least linelen+1 bytes. */ + (*linep)[linelen] = '\0'; + FUNLOCKFILE(fp); + return (linelen); + +error: + fp->_flags |= __SERR; + FUNLOCKFILE(fp); + return (-1); +} diff --git a/stdio/FreeBSD/getline.3 b/stdio/FreeBSD/getline.3 new file mode 100644 index 0000000..fba1461 --- /dev/null +++ b/stdio/FreeBSD/getline.3 @@ -0,0 +1,164 @@ +.\" Copyright (c) 2009 David Schultz +.\" 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: src/lib/libc/stdio/getline.3,v 1.2 2009/04/06 13:50:04 das Exp $ +.\" +.Dd March 29, 2009 +.Dt GETLINE 3 +.Os +.Sh NAME +.Nm getdelim , +.Nm getline +.Nd get a line from a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.Fd "#define _WITH_GETLINE" +.In stdio.h +.Ft ssize_t +.Fn getdelim "char ** restrict linep" "size_t * restrict linecapp" "int delimiter" " FILE * restrict stream" +.Ft ssize_t +.Fn getline "char ** restrict linep" "size_t * restrict linecapp" " FILE * restrict stream" +.Sh DESCRIPTION +The +.Fn getdelim +function reads a line from +.Fa stream , +delimited by the character +.Fa delimiter . +The +.Fn getline +function is equivalent to +.Fn getdelim +with the newline character as the delimiter. +The delimiter character is included as part of the line, unless +the end of the file is reached. +The caller may provide a pointer to a malloc buffer for the line in +.Fa *linep , +and the capacity of that buffer in +.Fa *linecapp ; +if +.Fa *linecapp +is 0, then +.Fa *linep +is treated as +.Dv NULL . +These functions may expand the buffer as needed, as if via +.Fn realloc , +and update +.Fa *linep +and +.Fa *linecapp +accordingly. +.Sh RETURN VALUES +The +.Fn getdelim +and +.Fn getline +functions return the number of characters written, excluding the +terminating +.Dv NULL . +The value \-1 is returned if an error occurs, or if end-of-file is reached. +.Sh EXAMPLES +The following code fragment reads lines from a file and +writes them to standard output. +The +.Fn fwrite +function is used in case the line contains embedded +.Dv NUL +characters. +.Bd -literal -offset indent +char *line = NULL; +size_t linecap = 0; +ssize_t linelen; +while ((linelen = getline(&line, &linecap, fp)) > 0) + fwrite(line, linelen, 1, stdout); +.Ed +.Sh COMPATIBILITY +Many application writers used the name +.Va getline +before the +.Fn getline +function was introduced in +.St -p1003.1 , +so a prototype is not provided by default in order to avoid +compatibility problems. +Applications that wish to use the +.Fn getline +function described herein should either request a strict +.St -p1003.1-2008 +environment by defining the macro +.Dv _POSIX_C_SOURCE +to the value 200809 or greater, or by defining the macro +.Dv _WITH_GETLINE , +prior to the inclusion of +.In stdio.h . +For compatibility with GNU libc, defining either +.Dv _BSD_SOURCE +or +.Dv _GNU_SOURCE +prior to the inclusion of +.In stdio.h +will also make +.Fn getline +available. +.Sh ERRORS +These functions may fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +Either +.Fa linep +or +.Fa linecapp +is +.Dv NULL . +.It Bq Er EOVERFLOW +No delimiter was found in the first +.Dv SSIZE_MAX +characters. +.El +.Pp +These functions may also fail for any of the errors specified for +.Fn fgets +and +.Fn malloc . +.Sh SEE ALSO +.Xr fgetln 3 , +.Xr fgets 3 , +.Xr malloc 3 +.Sh STANDARDS +The +.Fn getdelim +and +.Fn getline +functions conform to +.St -p1003.1-2008 . +.Sh HISTORY +These routines first appeared in +.Fx 8.0 . +.Sh BUGS +There are no wide character versions of +.Fn getdelim +or +.Fn getline . diff --git a/stdio/FreeBSD/getline.3.patch b/stdio/FreeBSD/getline.3.patch new file mode 100644 index 0000000..34875e7 --- /dev/null +++ b/stdio/FreeBSD/getline.3.patch @@ -0,0 +1,45 @@ +--- getline.3.orig 2009-12-15 15:37:17.000000000 -0800 ++++ getline.3 2009-12-15 15:37:57.000000000 -0800 +@@ -34,7 +34,6 @@ + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS +-.Fd "#define _WITH_GETLINE" + .In stdio.h + .Ft ssize_t + .Fn getdelim "char ** restrict linep" "size_t * restrict linecapp" "int delimiter" " FILE * restrict stream" +@@ -95,34 +94,6 @@ ssize_t linelen; + while ((linelen = getline(&line, &linecap, fp)) > 0) + fwrite(line, linelen, 1, stdout); + .Ed +-.Sh COMPATIBILITY +-Many application writers used the name +-.Va getline +-before the +-.Fn getline +-function was introduced in +-.St -p1003.1 , +-so a prototype is not provided by default in order to avoid +-compatibility problems. +-Applications that wish to use the +-.Fn getline +-function described herein should either request a strict +-.St -p1003.1-2008 +-environment by defining the macro +-.Dv _POSIX_C_SOURCE +-to the value 200809 or greater, or by defining the macro +-.Dv _WITH_GETLINE , +-prior to the inclusion of +-.In stdio.h . +-For compatibility with GNU libc, defining either +-.Dv _BSD_SOURCE +-or +-.Dv _GNU_SOURCE +-prior to the inclusion of +-.In stdio.h +-will also make +-.Fn getline +-available. + .Sh ERRORS + These functions may fail if: + .Bl -tag -width Er diff --git a/stdio/FreeBSD/getline.c b/stdio/FreeBSD/getline.c new file mode 100644 index 0000000..1384481 --- /dev/null +++ b/stdio/FreeBSD/getline.c @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/stdio/getline.c,v 1.1 2009/02/28 06:00:58 das Exp $"); + +#define _WITH_GETLINE +#include + +ssize_t +getline(char ** __restrict linep, size_t * __restrict linecapp, + FILE * __restrict fp) +{ + + return (getdelim(linep, linecapp, '\n', fp)); +} diff --git a/stdio/FreeBSD/gets.c b/stdio/FreeBSD/gets.c index 5ef23ab..5c3d64f 100644 --- a/stdio/FreeBSD/gets.c +++ b/stdio/FreeBSD/gets.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)gets.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/gets.c,v 1.16 2003/01/30 23:32:53 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/gets.c,v 1.17 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/getw.c b/stdio/FreeBSD/getw.c index c7ba04f..7b669aa 100644 --- a/stdio/FreeBSD/getw.c +++ b/stdio/FreeBSD/getw.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)getw.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/getw.c,v 1.7 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/getw.c,v 1.8 2007/01/09 00:28:06 imp Exp $"); #include diff --git a/stdio/FreeBSD/getwc.3 b/stdio/FreeBSD/getwc.3 index c470554..0f2fe2e 100644 --- a/stdio/FreeBSD/getwc.3 +++ b/stdio/FreeBSD/getwc.3 @@ -15,10 +15,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -36,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/getwc.3,v 1.6 2004/03/16 13:30:11 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/getwc.3,v 1.8 2007/01/09 00:28:06 imp Exp $ .\" .Dd March 3, 2004 .Dt GETWC 3 @@ -56,7 +52,7 @@ .Ft wint_t .Fn getwc "FILE *stream" .Ft wint_t -.Fn getwchar +.Fn getwchar void .Sh DESCRIPTION The .Fn fgetwc diff --git a/stdio/FreeBSD/getwc.3.patch b/stdio/FreeBSD/getwc.3.patch index 7728d51..a271508 100644 --- a/stdio/FreeBSD/getwc.3.patch +++ b/stdio/FreeBSD/getwc.3.patch @@ -1,15 +1,15 @@ ---- getwc.3 2004-11-25 11:38:35.000000000 -0800 -+++ getwc.3.edit 2006-08-09 13:40:43.000000000 -0700 -@@ -56,7 +56,7 @@ +--- getwc.3.bsdnew 2009-11-11 13:33:12.000000000 -0800 ++++ getwc.3 2009-11-11 14:56:18.000000000 -0800 +@@ -52,7 +52,7 @@ .Ft wint_t .Fn getwc "FILE *stream" .Ft wint_t --.Fn getwchar -+.Fn getwchar void +-.Fn getwchar void ++.Fn getwchar "void" .Sh DESCRIPTION The .Fn fgetwc -@@ -79,6 +79,12 @@ +@@ -75,6 +75,12 @@ is equivalent to .Fn getwc with the argument .Dv stdin . @@ -22,11 +22,11 @@ .Sh RETURN VALUES If successful, these routines return the next wide character from the -@@ -104,13 +110,14 @@ +@@ -100,13 +106,14 @@ until the condition is cleared with .Xr fopen 3 , .Xr fread 3 , .Xr getc 3 , -+.Xr getwc_l 3 , ++.Xr getwc_l , .Xr putwc 3 , .Xr stdio 3 , .Xr ungetwc 3 diff --git a/stdio/FreeBSD/glue.h b/stdio/FreeBSD/glue.h index 44223ff..1543dc3 100644 --- a/stdio/FreeBSD/glue.h +++ b/stdio/FreeBSD/glue.h @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,7 +30,7 @@ * SUCH DAMAGE. * * @(#)glue.h 8.1 (Berkeley) 6/4/93 - * $FreeBSD: src/lib/libc/stdio/glue.h,v 1.2 2002/03/22 23:42:01 obrien Exp $ + * $FreeBSD: src/lib/libc/stdio/glue.h,v 1.4 2007/01/09 00:28:06 imp Exp $ */ /* @@ -45,4 +41,5 @@ struct glue { struct glue *next; int niobs; FILE *iobs; -} __sglue; +}; +extern struct glue __sglue; diff --git a/stdio/FreeBSD/glue.h.patch b/stdio/FreeBSD/glue.h.patch deleted file mode 100644 index 3734fe9..0000000 --- a/stdio/FreeBSD/glue.h.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- glue.h.orig Fri Mar 22 15:42:01 2002 -+++ glue.h Sat May 3 14:38:31 2003 -@@ -45,4 +45,5 @@ - struct glue *next; - int niobs; - FILE *iobs; --} __sglue; -+}; -+extern struct glue __sglue; diff --git a/stdio/FreeBSD/local.h b/stdio/FreeBSD/local.h index 7cef096..0cb856e 100644 --- a/stdio/FreeBSD/local.h +++ b/stdio/FreeBSD/local.h @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,7 +30,7 @@ * SUCH DAMAGE. * * @(#)local.h 8.3 (Berkeley) 7/3/94 - * $FreeBSD: src/lib/libc/stdio/local.h,v 1.26 2004/07/16 05:52:51 tjr Exp $ + * $FreeBSD: src/lib/libc/stdio/local.h,v 1.33 2008/05/05 16:03:52 jhb Exp $ */ #include /* for off_t */ @@ -53,6 +49,7 @@ extern fpos_t _sseek(FILE *, fpos_t, int); extern int _ftello(FILE *, fpos_t *); extern int _fseeko(FILE *, off_t, int, int); extern int __fflush(FILE *fp); +extern void __fcloseall(void); extern wint_t __fgetwc(FILE *); extern wint_t __fputwc(wchar_t, FILE *); extern int __sflush(FILE *); @@ -65,7 +62,6 @@ extern fpos_t __sseek(void *, fpos_t, int); extern int __sclose(void *); extern void __sinit(void); extern void _cleanup(void); -extern void (*__cleanup)(void); extern void __smakebuf(FILE *); extern int __swhatbuf(FILE *, size_t *, int *); extern int _fwalk(int (*)(FILE *)); @@ -79,20 +75,11 @@ extern int __vfscanf(FILE *, const char *, __va_list); extern int __vfwprintf(FILE *, const wchar_t *, __va_list); extern int __vfwscanf(FILE * __restrict, const wchar_t * __restrict, __va_list); - +extern size_t __fread(void * __restrict buf, size_t size, size_t count, + FILE * __restrict fp); extern int __sdidinit; -/* hold a buncha junk that would grow the ABI */ -struct __sFILEX { - unsigned char *_up; /* saved _p when _p is doing ungetc data */ - pthread_mutex_t fl_mutex; /* used for MT-safety */ - pthread_t fl_owner; /* current owner */ - int fl_count; /* recursive lock count */ - int orientation; /* orientation for fwide() */ - mbstate_t mbstate; /* multibyte conversion state */ -}; - /* * Prepare the given FILE for writing, and return 0 iff it * can be written now. Otherwise, return EOF and set errno. @@ -122,20 +109,11 @@ struct __sFILEX { (fp)->_lb._base = NULL; \ } -#define INITEXTRA(fp) { \ - (fp)->_extra->_up = NULL; \ - (fp)->_extra->fl_mutex = PTHREAD_MUTEX_INITIALIZER; \ - (fp)->_extra->fl_owner = NULL; \ - (fp)->_extra->fl_count = 0; \ - (fp)->_extra->orientation = 0; \ - memset(&(fp)->_extra->mbstate, 0, sizeof(mbstate_t)); \ -} - /* * Set the orientation for a stream. If o > 0, the stream has wide- * orientation. If o < 0, the stream has byte-orientation. */ #define ORIENT(fp, o) do { \ - if ((fp)->_extra->orientation == 0) \ - (fp)->_extra->orientation = (o); \ + if ((fp)->_orientation == 0) \ + (fp)->_orientation = (o); \ } while (0) diff --git a/stdio/FreeBSD/local.h.patch b/stdio/FreeBSD/local.h.patch index dd295b7..2024f06 100644 --- a/stdio/FreeBSD/local.h.patch +++ b/stdio/FreeBSD/local.h.patch @@ -1,7 +1,7 @@ ---- local.h.orig 2009-02-15 03:11:22.000000000 -0800 -+++ local.h 2009-02-15 18:12:54.000000000 -0800 -@@ -37,8 +37,11 @@ - * $FreeBSD: src/lib/libc/stdio/local.h,v 1.26 2004/07/16 05:52:51 tjr Exp $ +--- local.h.orig 2011-02-15 10:44:57.000000000 -0800 ++++ local.h 2011-02-15 11:16:59.000000000 -0800 +@@ -33,8 +33,11 @@ + * $FreeBSD: src/lib/libc/stdio/local.h,v 1.33 2008/05/05 16:03:52 jhb Exp $ */ +#include @@ -12,17 +12,17 @@ #include #include -@@ -53,12 +56,15 @@ extern fpos_t _sseek(FILE *, fpos_t, int - extern int _ftello(FILE *, fpos_t *); +@@ -50,36 +53,69 @@ extern int _fseeko(FILE *, off_t, int, int); extern int __fflush(FILE *fp); + extern void __fcloseall(void); -extern wint_t __fgetwc(FILE *); -extern wint_t __fputwc(wchar_t, FILE *); +extern wint_t __fgetwc(FILE *, locale_t); +extern wint_t __fputwc(wchar_t, FILE *, locale_t); extern int __sflush(FILE *); -extern FILE *__sfp(void); -+extern FILE *__sfp(int); /* arg is whether to count against STREAM_MAX or not */ ++extern FILE *__sfp(int); +extern void __sfprelease(FILE *); /* mark free and update count as needed */ extern int __slbexpand(FILE *, size_t); extern int __srefill(FILE *); @@ -31,7 +31,10 @@ extern int __sread(void *, char *, int); extern int __swrite(void *, char const *, int); extern fpos_t __sseek(void *, fpos_t, int); -@@ -69,16 +75,16 @@ extern void (*__cleanup)(void); + extern int __sclose(void *); + extern void __sinit(void); + extern void _cleanup(void); ++extern void (*__cleanup)(void); extern void __smakebuf(FILE *); extern int __swhatbuf(FILE *, size_t *, int *); extern int _fwalk(int (*)(FILE *)); @@ -52,25 +55,40 @@ +extern int __vfwprintf(FILE *, locale_t, const wchar_t *, __va_list) __DARWIN_LDBL_COMPAT(__vfwprintf); +extern int __vfwscanf(FILE * __restrict, locale_t, const wchar_t * __restrict, + __va_list) __DARWIN_LDBL_COMPAT(__vfwscanf); - + extern size_t __fread(void * __restrict buf, size_t size, size_t count, + FILE * __restrict fp); extern int __sdidinit; -@@ -89,7 +95,8 @@ struct __sFILEX { - pthread_mutex_t fl_mutex; /* used for MT-safety */ - pthread_t fl_owner; /* current owner */ - int fl_count; /* recursive lock count */ -- int orientation; /* orientation for fwide() */ + ++/* hold a buncha junk that would grow the ABI */ ++struct __sFILEX { ++ unsigned char *up; /* saved _p when _p is doing ungetc data */ ++ pthread_mutex_t fl_mutex; /* used for MT-safety */ ++ pthread_t fl_owner; /* current owner */ ++ int fl_count; /* recursive lock count */ + int orientation:2; /* orientation for fwide() */ + int counted:1; /* stream counted against STREAM_MAX */ - mbstate_t mbstate; /* multibyte conversion state */ - }; - -@@ -124,7 +131,7 @@ struct __sFILEX { - - #define INITEXTRA(fp) { \ - (fp)->_extra->_up = NULL; \ -- (fp)->_extra->fl_mutex = PTHREAD_MUTEX_INITIALIZER; \ ++ mbstate_t mbstate; /* multibyte conversion state */ ++}; ++ ++#define _up _extra->up ++#define _fl_mutex _extra->fl_mutex ++#define _fl_owner _extra->fl_owner ++#define _fl_count _extra->fl_count ++#define _orientation _extra->orientation ++#define _mbstate _extra->mbstate ++#define _counted _extra->counted ++ ++#define INITEXTRA(fp) do { \ ++ (fp)->_extra->up = NULL; \ + (fp)->_extra->fl_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; \ - (fp)->_extra->fl_owner = NULL; \ - (fp)->_extra->fl_count = 0; \ - (fp)->_extra->orientation = 0; \ ++ (fp)->_extra->fl_owner = NULL; \ ++ (fp)->_extra->fl_count = 0; \ ++ (fp)->_extra->orientation = 0; \ ++ memset(&(fp)->_extra->mbstate, 0, sizeof(mbstate_t)); \ ++ (fp)->_extra->counted = 0; \ ++} while(0); ++ + /* + * Prepare the given FILE for writing, and return 0 iff it + * can be written now. Otherwise, return EOF and set errno. diff --git a/stdio/FreeBSD/makebuf.c b/stdio/FreeBSD/makebuf.c index a4c5c36..7d90164 100644 --- a/stdio/FreeBSD/makebuf.c +++ b/stdio/FreeBSD/makebuf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)makebuf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/makebuf.c,v 1.4 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/makebuf.c,v 1.6 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include @@ -46,9 +42,11 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/makebuf.c,v 1.4 2002/03/22 21:53:04 obrie #include #include #include -#include "local.h" #include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + /* * Allocate a file buffer, or switch to unbuffered I/O. * Per the ANSI C standard, ALL tty devices default to line buffered. diff --git a/stdio/FreeBSD/makebuf.c.patch b/stdio/FreeBSD/makebuf.c.patch index a265505..970a38d 100644 --- a/stdio/FreeBSD/makebuf.c.patch +++ b/stdio/FreeBSD/makebuf.c.patch @@ -1,8 +1,8 @@ ---- makebuf.c.orig 2008-08-28 17:18:09.000000000 -0700 -+++ makebuf.c 2008-09-04 14:20:48.000000000 -0700 -@@ -49,6 +49,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/m +--- makebuf.c.bsdnew 2009-11-11 13:33:12.000000000 -0800 ++++ makebuf.c 2009-11-11 13:33:13.000000000 -0800 +@@ -47,6 +47,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/m + #include "libc_private.h" #include "local.h" - #include "un-namespace.h" +#define MAXBUFSIZE (1 << 16) +#define TTYBUFSIZE 4096 @@ -10,7 +10,7 @@ /* * Allocate a file buffer, or switch to unbuffered I/O. * Per the ANSI C standard, ALL tty devices default to line buffered. -@@ -71,6 +74,12 @@ __smakebuf(fp) +@@ -69,6 +72,12 @@ __smakebuf(fp) return; } flags = __swhatbuf(fp, &size, &couldbetty); @@ -23,7 +23,7 @@ if ((p = malloc(size)) == NULL) { fp->_flags |= __SNBF; fp->_bf._base = fp->_p = fp->_nbuf; -@@ -81,8 +90,6 @@ __smakebuf(fp) +@@ -79,8 +88,6 @@ __smakebuf(fp) flags |= __SMBF; fp->_bf._base = fp->_p = p; fp->_bf._size = size; @@ -32,7 +32,7 @@ fp->_flags |= flags; } -@@ -115,8 +122,7 @@ __swhatbuf(fp, bufsize, couldbetty) +@@ -113,8 +120,7 @@ __swhatbuf(fp, bufsize, couldbetty) * __sseek is mainly paranoia.) It is safe to set _blksize * unconditionally; it will only be used if __SOPT is also set. */ diff --git a/stdio/FreeBSD/mktemp.3 b/stdio/FreeBSD/mktemp.3 index acbecc4..af2eba7 100644 --- a/stdio/FreeBSD/mktemp.3 +++ b/stdio/FreeBSD/mktemp.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)mktemp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/mktemp.3,v 1.20 2004/02/20 04:08:28 green Exp $ +.\" $FreeBSD: src/lib/libc/stdio/mktemp.3,v 1.22 2007/01/09 00:28:07 imp Exp $ .\" .Dd February 11, 1998 .Dt MKTEMP 3 @@ -190,6 +186,33 @@ so that it will store string constants in a writable segment of memory. See .Xr gcc 1 for more information. +.Sh SEE ALSO +.Xr chmod 2 , +.Xr getpid 2 , +.Xr mkdir 2 , +.Xr open 2 , +.Xr stat 2 +.Sh HISTORY +A +.Fn mktemp +function appeared in +.At v7 . +The +.Fn mkstemp +function appeared in +.Bx 4.4 . +The +.Fn mkdtemp +function first appeared in +.Ox 2.2 , +and later in +.Fx 3.2 . +The +.Fn mkstemps +function first appeared in +.Ox 2.4 , +and later in +.Fx 3.4 . .Sh BUGS This family of functions produces filenames which can be guessed, though the risk is minimized when large numbers of @@ -226,30 +249,3 @@ which is not reentrant. You must provide your own locking around this and other consumers of the .Xr arc4random 3 API. -.Sh SEE ALSO -.Xr chmod 2 , -.Xr getpid 2 , -.Xr mkdir 2 , -.Xr open 2 , -.Xr stat 2 -.Sh HISTORY -A -.Fn mktemp -function appeared in -.At v7 . -The -.Fn mkstemp -function appeared in -.Bx 4.4 . -The -.Fn mkdtemp -function first appeared in -.Ox 2.2 , -and later in -.Fx 3.2 . -The -.Fn mkstemps -function first appeared in -.Ox 2.4 , -and later in -.Fx 3.4 . diff --git a/stdio/FreeBSD/mktemp.3.patch b/stdio/FreeBSD/mktemp.3.patch index ac1b34b..03cafdd 100644 --- a/stdio/FreeBSD/mktemp.3.patch +++ b/stdio/FreeBSD/mktemp.3.patch @@ -1,17 +1,16 @@ ---- mktemp.3.orig 2008-02-29 10:45:39.000000000 -0800 -+++ mktemp.3 2008-02-29 11:21:10.000000000 -0800 -@@ -36,20 +36,33 @@ +--- mktemp.3.orig 2010-04-28 23:38:47.000000000 -0700 ++++ mktemp.3 2010-04-29 11:05:28.000000000 -0700 +@@ -32,6 +32,9 @@ .Dt MKTEMP 3 .Os .Sh NAME --.Nm mktemp +.Nm mkdtemp , +.Nm mkstemp , -+.Nm mktemp , -+.Nm mktemps ++.Nm mkstemps , + .Nm mktemp .Nd make temporary file name (unique) .Sh LIBRARY - .Lb libc +@@ -39,13 +42,23 @@ .Sh SYNOPSIS .In unistd.h .Ft char * @@ -39,7 +38,7 @@ .Sh DESCRIPTION The .Fn mktemp -@@ -137,7 +150,7 @@ +@@ -133,7 +146,7 @@ The pathname portion of the template is .Pp The .Fn mkstemp , @@ -48,7 +47,7 @@ and .Fn mkdtemp functions -@@ -171,7 +184,7 @@ +@@ -167,7 +180,7 @@ A common problem that results in a core passes in a read-only string to .Fn mktemp , .Fn mkstemp , @@ -57,19 +56,13 @@ or .Fn mkdtemp . This is common with programs that were developed before -@@ -219,19 +232,19 @@ - This will ensure that the program does not continue blindly - in the event that an attacker has already created the file - with the intention of manipulating or reading its contents. +@@ -186,12 +199,19 @@ so that it will store string constants i + See + .Xr gcc 1 + for more information. +.Sh LEGACY SYNOPSIS +.Fd #include - .Pp --The implementation of these functions calls --.Xr arc4random 3 , --which is not reentrant. --You must provide your own locking around this and other consumers of the --.Xr arc4random 3 --API. ++.Pp +The include file +.In unistd.h +is necessary and sufficient for all functions. @@ -84,3 +77,14 @@ .Sh HISTORY A .Fn mktemp +@@ -242,10 +262,3 @@ and the return status of the call should + This will ensure that the program does not continue blindly + in the event that an attacker has already created the file + with the intention of manipulating or reading its contents. +-.Pp +-The implementation of these functions calls +-.Xr arc4random 3 , +-which is not reentrant. +-You must provide your own locking around this and other consumers of the +-.Xr arc4random 3 +-API. diff --git a/stdio/FreeBSD/mktemp.c b/stdio/FreeBSD/mktemp.c index 8207c17..18e47c2 100644 --- a/stdio/FreeBSD/mktemp.c +++ b/stdio/FreeBSD/mktemp.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,10 +31,10 @@ static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/mktemp.c,v 1.28 2003/02/16 17:29:10 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/mktemp.c,v 1.32 2010/02/28 13:31:29 jh Exp $"); #include "namespace.h" -#include +#include #include #include #include @@ -106,34 +102,42 @@ _gettemp(path, doopen, domkdir, slen) int domkdir; int slen; { - char *start, *trv, *suffp; + char *start, *trv, *suffp, *carryp; char *pad; struct stat sbuf; int rval; uint32_t rand; + char carrybuf[MAXPATHLEN]; - if (doopen != NULL && domkdir) { + if ((doopen != NULL && domkdir) || slen < 0) { errno = EINVAL; return (0); } for (trv = path; *trv != '\0'; ++trv) ; + if (trv - path >= MAXPATHLEN) { + errno = ENAMETOOLONG; + return (0); + } trv -= slen; suffp = trv; --trv; - if (trv < path) { + if (trv < path || NULL != strchr(suffp, '/')) { errno = EINVAL; return (0); } /* Fill space with random characters */ while (trv >= path && *trv == 'X') { - rand = arc4random() % (sizeof(padchar) - 1); + rand = arc4random_uniform(sizeof(padchar) - 1); *trv-- = padchar[rand]; } start = trv + 1; + /* save first combination of random characters */ + memcpy(carrybuf, start, suffp - start); + /* * check the target directory. */ @@ -170,14 +174,25 @@ _gettemp(path, doopen, domkdir, slen) return (errno == ENOENT); /* If we have a collision, cycle through the space of filenames */ - for (trv = start;;) { - if (*trv == '\0' || trv == suffp) - return (0); + for (trv = start, carryp = carrybuf;;) { + /* have we tried all possible permutations? */ + if (trv == suffp) + return (0); /* yes - exit with EEXIST */ pad = strchr(padchar, *trv); - if (pad == NULL || *++pad == '\0') - *trv++ = padchar[0]; - else { - *trv++ = *pad; + if (pad == NULL) { + /* this should never happen */ + errno = EIO; + return (0); + } + /* increment character */ + *trv = (*++pad == '\0') ? padchar[0] : *pad; + /* carry to next position? */ + if (*trv == *carryp) { + /* increment position and loop */ + ++trv; + ++carryp; + } else { + /* try with new name */ break; } } diff --git a/stdio/FreeBSD/mktemp.c.patch b/stdio/FreeBSD/mktemp.c.patch index 9d5f5be..1c3da0c 100644 --- a/stdio/FreeBSD/mktemp.c.patch +++ b/stdio/FreeBSD/mktemp.c.patch @@ -1,79 +1,11 @@ ---- mktemp.c.orig Tue Mar 30 22:56:07 2004 -+++ mktemp.c Tue Mar 30 23:39:22 2004 -@@ -40,6 +40,7 @@ - #include "namespace.h" - #include - #include -+#include - #include - #include - #include -@@ -106,13 +107,14 @@ - int domkdir; - int slen; - { -- char *start, *trv, *suffp; -+ char *start, *trv, *suffp, *carryp; - char *pad; - struct stat sbuf; - int rval; - uint32_t rand; -+ char carrybuf[NAME_MAX]; +--- mktemp.c.orig 2010-04-08 10:37:06.000000000 -0700 ++++ mktemp.c 2010-04-08 10:40:05.000000000 -0700 +@@ -130,7 +130,7 @@ _gettemp(path, doopen, domkdir, slen) -- if (doopen != NULL && domkdir) { -+ if ((doopen != NULL && domkdir) || slen < 0) { - errno = EINVAL; - return (0); - } -@@ -122,7 +124,7 @@ - trv -= slen; - suffp = trv; - --trv; -- if (trv < path) { -+ if (trv < path || NULL != strchr(suffp, '/')) { - errno = EINVAL; - return (0); - } -@@ -134,6 +136,9 @@ + /* Fill space with random characters */ + while (trv >= path && *trv == 'X') { +- rand = arc4random_uniform(sizeof(padchar) - 1); ++ rand = arc4random() % (sizeof(padchar) - 1); + *trv-- = padchar[rand]; } start = trv + 1; - -+ /* save first combination of random characters */ -+ memcpy(carrybuf, start, suffp - start); -+ - /* - * check the target directory. - */ -@@ -170,14 +175,25 @@ - return (errno == ENOENT); - - /* If we have a collision, cycle through the space of filenames */ -- for (trv = start;;) { -- if (*trv == '\0' || trv == suffp) -- return (0); -+ for (trv = start, carryp = carrybuf;;) { -+ /* have we tried all possible permutations? */ -+ if (trv == suffp) -+ return (0); /* yes - exit with EEXIST */ - pad = strchr(padchar, *trv); -- if (pad == NULL || *++pad == '\0') -- *trv++ = padchar[0]; -- else { -- *trv++ = *pad; -+ if (pad == NULL) { -+ /* this should never happen */ -+ errno = EIO; -+ return (0); -+ } -+ /* increment character */ -+ *trv = (*++pad == '\0') ? padchar[0] : *pad; -+ /* carry to next position? */ -+ if (*trv == *carryp) { -+ /* increment position and loop */ -+ ++trv; -+ ++carryp; -+ } else { -+ /* try with new name */ - break; - } - } diff --git a/stdio/FreeBSD/perror.c b/stdio/FreeBSD/perror.c index 658b880..25d147f 100644 --- a/stdio/FreeBSD/perror.c +++ b/stdio/FreeBSD/perror.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)perror.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/perror.c,v 1.8 2002/12/19 09:53:26 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/perror.c,v 1.9 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/perror.c.patch b/stdio/FreeBSD/perror.c.patch deleted file mode 100644 index e816373..0000000 --- a/stdio/FreeBSD/perror.c.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- perror.c.orig 2003-05-20 15:22:43.000000000 -0700 -+++ perror.c 2005-04-29 17:06:52.000000000 -0700 -@@ -73,6 +73,7 @@ - v->iov_base = "\n"; - v->iov_len = 1; - FLOCKFILE(stderr); -+ ORIENT(stderr, -1); - __sflush(stderr); - (void)_writev(stderr->_file, iov, (v - iov) + 1); - stderr->_flags &= ~__SOFF; diff --git a/stdio/FreeBSD/printf-pos.c b/stdio/FreeBSD/printf-pos.c new file mode 100644 index 0000000..2cae4e6 --- /dev/null +++ b/stdio/FreeBSD/printf-pos.c @@ -0,0 +1,758 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdio/printf-pos.c,v 1.6 2009/03/02 04:07:58 das Exp $"); + +/* + * This is the code responsible for handling positional arguments + * (%m$ and %m$.n$) for vfprintf() and vfwprintf(). + */ + +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "un-namespace.h" +#include "printflocal.h" + +/* + * Type ids for argument type table. + */ +enum typeid { + T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, + T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, + T_PTRDIFFT, TP_PTRDIFFT, T_SSIZET, T_SIZET, TP_SSIZET, + T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, + T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR +}; + +/* An expandable array of types. */ +struct typetable { + enum typeid *table; /* table of types */ + enum typeid stattable[STATIC_ARG_TBL_SIZE]; + int tablesize; /* current size of type table */ + int tablemax; /* largest used index in table */ + int nextarg; /* 1-based argument index */ +}; + +static int __grow_type_table(struct typetable *); +static void build_arg_table (struct typetable *, va_list, union arg **); + +/* + * Initialize a struct typetable. + */ +static inline void +inittypes(struct typetable *types) +{ + int n; + + types->table = types->stattable; + types->tablesize = STATIC_ARG_TBL_SIZE; + types->tablemax = 0; + types->nextarg = 1; + for (n = 0; n < STATIC_ARG_TBL_SIZE; n++) + types->table[n] = T_UNUSED; +} + +/* + * struct typetable destructor. + */ +static inline void +freetypes(struct typetable *types) +{ + + if (types->table != types->stattable) + free (types->table); +} + +/* + * Ensure that there is space to add a new argument type to the type table. + * Expand the table if necessary. Returns 0 on success. + */ +static inline int +_ensurespace(struct typetable *types) +{ + + if (types->nextarg >= types->tablesize) { + if (__grow_type_table(types)) + return (-1); + } + if (types->nextarg > types->tablemax) + types->tablemax = types->nextarg; + return (0); +} + +/* + * Add an argument type to the table, expanding if necessary. + * Returns 0 on success. + */ +static inline int +addtype(struct typetable *types, enum typeid type) +{ + + if (_ensurespace(types)) + return (-1); + types->table[types->nextarg++] = type; + return (0); +} + +static inline int +addsarg(struct typetable *types, int flags) +{ + + if (_ensurespace(types)) + return (-1); + if (flags & INTMAXT) + types->table[types->nextarg++] = T_INTMAXT; + else if (flags & SIZET) + types->table[types->nextarg++] = T_SSIZET; + else if (flags & PTRDIFFT) + types->table[types->nextarg++] = T_PTRDIFFT; + else if (flags & LLONGINT) + types->table[types->nextarg++] = T_LLONG; + else if (flags & LONGINT) + types->table[types->nextarg++] = T_LONG; + else + types->table[types->nextarg++] = T_INT; + return (0); +} + +static inline int +adduarg(struct typetable *types, int flags) +{ + + if (_ensurespace(types)) + return (-1); + if (flags & INTMAXT) + types->table[types->nextarg++] = T_UINTMAXT; + else if (flags & SIZET) + types->table[types->nextarg++] = T_SIZET; + else if (flags & PTRDIFFT) + types->table[types->nextarg++] = T_SIZET; + else if (flags & LLONGINT) + types->table[types->nextarg++] = T_U_LLONG; + else if (flags & LONGINT) + types->table[types->nextarg++] = T_U_LONG; + else + types->table[types->nextarg++] = T_U_INT; + return (0); +} + +/* + * Add * arguments to the type array. + */ +static inline int +addaster(struct typetable *types, char **fmtp) +{ + char *cp; + int n2; + + n2 = 0; + cp = *fmtp; + while (is_digit(*cp)) { + n2 = 10 * n2 + to_digit(*cp); + cp++; + } + if (*cp == '$') { + int hold = types->nextarg; + types->nextarg = n2; + if (addtype(types, T_INT)) + return (-1); + types->nextarg = hold; + *fmtp = ++cp; + } else { + if (addtype(types, T_INT)) + return (-1); + } + return (0); +} + +static inline int +addwaster(struct typetable *types, wchar_t **fmtp) +{ + wchar_t *cp; + int n2; + + n2 = 0; + cp = *fmtp; + while (is_digit(*cp)) { + n2 = 10 * n2 + to_digit(*cp); + cp++; + } + if (*cp == '$') { + int hold = types->nextarg; + types->nextarg = n2; + if (addtype(types, T_INT)) + return (-1); + types->nextarg = hold; + *fmtp = ++cp; + } else { + if (addtype(types, T_INT)) + return (-1); + } + return (0); +} + +/* + * Find all arguments when a positional parameter is encountered. Returns a + * table, indexed by argument number, of pointers to each arguments. The + * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. + * It will be replaces with a malloc-ed one if it overflows. + * Returns 0 on success. On failure, returns nonzero and sets errno. + */ +int +__find_arguments (const char *fmt0, va_list ap, union arg **argtable) +{ + char *fmt; /* format string */ + int ch; /* character from fmt */ + int n; /* handy integer (short term usage) */ + int error; + int flags; /* flags as above */ + int width; /* width from format (%8d), or 0 */ + struct typetable types; /* table of types */ + + fmt = (char *)fmt0; + inittypes(&types); + error = 0; + + /* + * Scan the format for conversions (`%' character). + */ + for (;;) { + while ((ch = *fmt) != '\0' && ch != '%') + fmt++; + if (ch == '\0') + goto done; + fmt++; /* skip over '%' */ + + flags = 0; + width = 0; + +rflag: ch = *fmt++; +reswitch: switch (ch) { + case ' ': + case '#': + goto rflag; + case '*': + if ((error = addaster(&types, &fmt))) + goto error; + goto rflag; + case '-': + case '+': + case '\'': + goto rflag; + case '.': + if ((ch = *fmt++) == '*') { + if ((error = addaster(&types, &fmt))) + goto error; + goto rflag; + } + while (is_digit(ch)) { + ch = *fmt++; + } + goto reswitch; + case '0': + goto rflag; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = 0; + do { + n = 10 * n + to_digit(ch); + ch = *fmt++; + } while (is_digit(ch)); + if (ch == '$') { + types.nextarg = n; + goto rflag; + } + width = n; + goto reswitch; +#ifndef NO_FLOATING_POINT + case 'L': + flags |= LONGDBL; + goto rflag; +#endif + case 'h': + if (flags & SHORTINT) { + flags &= ~SHORTINT; + flags |= CHARINT; + } else + flags |= SHORTINT; + goto rflag; + case 'j': + flags |= INTMAXT; + goto rflag; + case 'l': + if (flags & LONGINT) { + flags &= ~LONGINT; + flags |= LLONGINT; + } else + flags |= LONGINT; + goto rflag; + case 'q': + flags |= LLONGINT; /* not necessarily */ + goto rflag; + case 't': + flags |= PTRDIFFT; + goto rflag; + case 'z': + flags |= SIZET; + goto rflag; + case 'C': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'c': + error = addtype(&types, + (flags & LONGINT) ? T_WINT : T_INT); + if (error) + goto error; + break; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': + if ((error = addsarg(&types, flags))) + goto error; + break; +#ifndef NO_FLOATING_POINT + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + error = addtype(&types, + (flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE); + if (error) + goto error; + break; +#endif /* !NO_FLOATING_POINT */ + case 'n': + if (flags & INTMAXT) + error = addtype(&types, TP_INTMAXT); + else if (flags & PTRDIFFT) + error = addtype(&types, TP_PTRDIFFT); + else if (flags & SIZET) + error = addtype(&types, TP_SSIZET); + else if (flags & LLONGINT) + error = addtype(&types, TP_LLONG); + else if (flags & LONGINT) + error = addtype(&types, TP_LONG); + else if (flags & SHORTINT) + error = addtype(&types, TP_SHORT); + else if (flags & CHARINT) + error = addtype(&types, TP_SCHAR); + else + error = addtype(&types, TP_INT); + if (error) + goto error; + continue; /* no output */ + case 'O': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': + if ((error = adduarg(&types, flags))) + goto error; + break; + case 'p': + if ((error = addtype(&types, TP_VOID))) + goto error; + break; + case 'S': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 's': + error = addtype(&types, + (flags & LONGINT) ? TP_WCHAR : TP_CHAR); + if (error) + goto error; + break; + case 'U': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': + case 'X': + case 'x': + if ((error = adduarg(&types, flags))) + goto error; + break; + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; + break; + } + } +done: + build_arg_table(&types, ap, argtable); +error: + freetypes(&types); + return (error || *argtable == NULL); +} + +/* wchar version of __find_arguments. */ +int +__find_warguments (const wchar_t *fmt0, va_list ap, union arg **argtable) +{ + wchar_t *fmt; /* format string */ + wchar_t ch; /* character from fmt */ + int n; /* handy integer (short term usage) */ + int error; + int flags; /* flags as above */ + int width; /* width from format (%8d), or 0 */ + struct typetable types; /* table of types */ + + fmt = (wchar_t *)fmt0; + inittypes(&types); + error = 0; + + /* + * Scan the format for conversions (`%' character). + */ + for (;;) { + while ((ch = *fmt) != '\0' && ch != '%') + fmt++; + if (ch == '\0') + goto done; + fmt++; /* skip over '%' */ + + flags = 0; + width = 0; + +rflag: ch = *fmt++; +reswitch: switch (ch) { + case ' ': + case '#': + goto rflag; + case '*': + if ((error = addwaster(&types, &fmt))) + goto error; + goto rflag; + case '-': + case '+': + case '\'': + goto rflag; + case '.': + if ((ch = *fmt++) == '*') { + if ((error = addwaster(&types, &fmt))) + goto error; + goto rflag; + } + while (is_digit(ch)) { + ch = *fmt++; + } + goto reswitch; + case '0': + goto rflag; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = 0; + do { + n = 10 * n + to_digit(ch); + ch = *fmt++; + } while (is_digit(ch)); + if (ch == '$') { + types.nextarg = n; + goto rflag; + } + width = n; + goto reswitch; +#ifndef NO_FLOATING_POINT + case 'L': + flags |= LONGDBL; + goto rflag; +#endif + case 'h': + if (flags & SHORTINT) { + flags &= ~SHORTINT; + flags |= CHARINT; + } else + flags |= SHORTINT; + goto rflag; + case 'j': + flags |= INTMAXT; + goto rflag; + case 'l': + if (flags & LONGINT) { + flags &= ~LONGINT; + flags |= LLONGINT; + } else + flags |= LONGINT; + goto rflag; + case 'q': + flags |= LLONGINT; /* not necessarily */ + goto rflag; + case 't': + flags |= PTRDIFFT; + goto rflag; + case 'z': + flags |= SIZET; + goto rflag; + case 'C': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'c': + error = addtype(&types, + (flags & LONGINT) ? T_WINT : T_INT); + if (error) + goto error; + break; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': + if ((error = addsarg(&types, flags))) + goto error; + break; +#ifndef NO_FLOATING_POINT + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + error = addtype(&types, + (flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE); + if (error) + goto error; + break; +#endif /* !NO_FLOATING_POINT */ + case 'n': + if (flags & INTMAXT) + error = addtype(&types, TP_INTMAXT); + else if (flags & PTRDIFFT) + error = addtype(&types, TP_PTRDIFFT); + else if (flags & SIZET) + error = addtype(&types, TP_SSIZET); + else if (flags & LLONGINT) + error = addtype(&types, TP_LLONG); + else if (flags & LONGINT) + error = addtype(&types, TP_LONG); + else if (flags & SHORTINT) + error = addtype(&types, TP_SHORT); + else if (flags & CHARINT) + error = addtype(&types, TP_SCHAR); + else + error = addtype(&types, TP_INT); + if (error) + goto error; + continue; /* no output */ + case 'O': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': + if ((error = adduarg(&types, flags))) + goto error; + break; + case 'p': + if ((error = addtype(&types, TP_VOID))) + goto error; + break; + case 'S': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 's': + error = addtype(&types, + (flags & LONGINT) ? TP_WCHAR : TP_CHAR); + if (error) + goto error; + break; + case 'U': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': + case 'X': + case 'x': + if ((error = adduarg(&types, flags))) + goto error; + break; + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; + break; + } + } +done: + build_arg_table(&types, ap, argtable); +error: + freetypes(&types); + return (error || *argtable == NULL); +} + +/* + * Increase the size of the type table. Returns 0 on success. + */ +static int +__grow_type_table(struct typetable *types) +{ + enum typeid *const oldtable = types->table; + const int oldsize = types->tablesize; + enum typeid *newtable; + int n, newsize = oldsize * 2; + + if (newsize < types->nextarg + 1) + newsize = types->nextarg + 1; + if (oldsize == STATIC_ARG_TBL_SIZE) { + if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL) + return (-1); + bcopy(oldtable, newtable, oldsize * sizeof(enum typeid)); + } else { + newtable = realloc(oldtable, newsize * sizeof(enum typeid)); + if (newtable == NULL) + return (-1); + } + for (n = oldsize; n < newsize; n++) + newtable[n] = T_UNUSED; + + types->table = newtable; + types->tablesize = newsize; + + return (0); +} + +/* + * Build the argument table from the completed type table. + * On malloc failure, *argtable is set to NULL. + */ +static void +build_arg_table(struct typetable *types, va_list ap, union arg **argtable) +{ + int n; + + if (types->tablemax >= STATIC_ARG_TBL_SIZE) { + *argtable = (union arg *) + malloc (sizeof (union arg) * (types->tablemax + 1)); + if (*argtable == NULL) + return; + } + + (*argtable) [0].intarg = 0; + for (n = 1; n <= types->tablemax; n++) { + switch (types->table[n]) { + case T_UNUSED: /* whoops! */ + (*argtable) [n].intarg = va_arg (ap, int); + break; + case TP_SCHAR: + (*argtable) [n].pschararg = va_arg (ap, signed char *); + break; + case TP_SHORT: + (*argtable) [n].pshortarg = va_arg (ap, short *); + break; + case T_INT: + (*argtable) [n].intarg = va_arg (ap, int); + break; + case T_U_INT: + (*argtable) [n].uintarg = va_arg (ap, unsigned int); + break; + case TP_INT: + (*argtable) [n].pintarg = va_arg (ap, int *); + break; + case T_LONG: + (*argtable) [n].longarg = va_arg (ap, long); + break; + case T_U_LONG: + (*argtable) [n].ulongarg = va_arg (ap, unsigned long); + break; + case TP_LONG: + (*argtable) [n].plongarg = va_arg (ap, long *); + break; + case T_LLONG: + (*argtable) [n].longlongarg = va_arg (ap, long long); + break; + case T_U_LLONG: + (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); + break; + case TP_LLONG: + (*argtable) [n].plonglongarg = va_arg (ap, long long *); + break; + case T_PTRDIFFT: + (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); + break; + case TP_PTRDIFFT: + (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); + break; + case T_SIZET: + (*argtable) [n].sizearg = va_arg (ap, size_t); + break; + case T_SSIZET: + (*argtable) [n].sizearg = va_arg (ap, ssize_t); + break; + case TP_SSIZET: + (*argtable) [n].pssizearg = va_arg (ap, ssize_t *); + break; + case T_INTMAXT: + (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); + break; + case T_UINTMAXT: + (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); + break; + case TP_INTMAXT: + (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); + break; + case T_DOUBLE: +#ifndef NO_FLOATING_POINT + (*argtable) [n].doublearg = va_arg (ap, double); +#endif + break; + case T_LONG_DOUBLE: +#ifndef NO_FLOATING_POINT + (*argtable) [n].longdoublearg = va_arg (ap, long double); +#endif + break; + case TP_CHAR: + (*argtable) [n].pchararg = va_arg (ap, char *); + break; + case TP_VOID: + (*argtable) [n].pvoidarg = va_arg (ap, void *); + break; + case T_WINT: + (*argtable) [n].wintarg = va_arg (ap, wint_t); + break; + case TP_WCHAR: + (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); + break; + } + } +} diff --git a/stdio/FreeBSD/printf-pos.c.patch b/stdio/FreeBSD/printf-pos.c.patch new file mode 100644 index 0000000..fdbb58e --- /dev/null +++ b/stdio/FreeBSD/printf-pos.c.patch @@ -0,0 +1,128 @@ +--- printf-pos.c.orig 2010-10-25 19:45:24.000000000 -0700 ++++ printf-pos.c 2010-10-25 19:47:02.000000000 -0700 +@@ -63,7 +63,10 @@ enum typeid { + T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, + T_PTRDIFFT, TP_PTRDIFFT, T_SSIZET, T_SIZET, TP_SSIZET, + T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, +- T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR ++ T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, ++#ifdef VECTORS ++ T_VECTOR, ++#endif + }; + + /* An expandable array of types. */ +@@ -240,7 +243,7 @@ addwaster(struct typetable *types, wchar + * It will be replaces with a malloc-ed one if it overflows. + * Returns 0 on success. On failure, returns nonzero and sets errno. + */ +-int ++__private_extern__ int + __find_arguments (const char *fmt0, va_list ap, union arg **argtable) + { + char *fmt; /* format string */ +@@ -342,7 +345,11 @@ reswitch: switch (ch) { + /*FALLTHROUGH*/ + case 'c': + error = addtype(&types, ++#ifdef VECTORS ++ (flags & LONGINT) ? T_WINT : ((flags & VECTOR) ? T_VECTOR : T_INT)); ++#else + (flags & LONGINT) ? T_WINT : T_INT); ++#endif + if (error) + goto error; + break; +@@ -351,6 +358,12 @@ reswitch: switch (ch) { + /*FALLTHROUGH*/ + case 'd': + case 'i': ++#ifdef VECTORS ++ if (flags & VECTOR) { ++ if ((error = addtype(&types, T_VECTOR))) ++ goto error; ++ } else ++#endif + if ((error = addsarg(&types, flags))) + goto error; + break; +@@ -360,10 +373,15 @@ reswitch: switch (ch) { + case 'e': + case 'E': + case 'f': ++ case 'F': + case 'g': + case 'G': + error = addtype(&types, ++#ifdef VECTORS ++ (flags & VECTOR) ? T_VECTOR : ((flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE)); ++#else + (flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE); ++#endif + if (error) + goto error; + break; +@@ -392,11 +410,21 @@ reswitch: switch (ch) { + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': ++#ifdef VECTORS ++ if (flags & VECTOR) { ++ if ((error = addtype(&types, T_VECTOR))) ++ goto error; ++ } else ++#endif + if ((error = adduarg(&types, flags))) + goto error; + break; + case 'p': ++#ifdef VECTORS ++ if ((error = addtype(&types, (flags & VECTOR) ? T_VECTOR : TP_VOID))) ++#else + if ((error = addtype(&types, TP_VOID))) ++#endif + goto error; + break; + case 'S': +@@ -414,6 +442,12 @@ reswitch: switch (ch) { + case 'u': + case 'X': + case 'x': ++#ifdef VECTORS ++ if (flags & VECTOR) { ++ if ((error = addtype(&types, T_VECTOR))) ++ goto error; ++ } else ++#endif + if ((error = adduarg(&types, flags))) + goto error; + break; +@@ -431,7 +465,7 @@ error: + } + + /* wchar version of __find_arguments. */ +-int ++__private_extern__ int + __find_warguments (const wchar_t *fmt0, va_list ap, union arg **argtable) + { + wchar_t *fmt; /* format string */ +@@ -551,6 +585,7 @@ reswitch: switch (ch) { + case 'e': + case 'E': + case 'f': ++ case 'F': + case 'g': + case 'G': + error = addtype(&types, +@@ -741,6 +776,11 @@ build_arg_table(struct typetable *types, + (*argtable) [n].longdoublearg = va_arg (ap, long double); + #endif + break; ++#ifdef VECTORS ++ case T_VECTOR: ++ (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE); ++ break; ++#endif /* VECTORS */ + case TP_CHAR: + (*argtable) [n].pchararg = va_arg (ap, char *); + break; diff --git a/stdio/FreeBSD/printf.3 b/stdio/FreeBSD/printf.3 index a14c8fe..cbafaf9 100644 --- a/stdio/FreeBSD/printf.3 +++ b/stdio/FreeBSD/printf.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,18 +30,19 @@ .\" SUCH DAMAGE. .\" .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.58 2004/10/16 16:00:01 stefanf Exp $ +.\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.64 2009/12/02 07:51:25 brueffer Exp $ .\" -.Dd October 16, 2004 +.Dd December 2, 2009 .Dt PRINTF 3 .Os .Sh NAME -.Nm printf , fprintf , sprintf , snprintf , asprintf , -.Nm vprintf , vfprintf, vsprintf , vsnprintf , vasprintf +.Nm printf , fprintf , sprintf , snprintf , asprintf , dprintf , +.Nm vprintf , vfprintf, vsprintf , vsnprintf , vasprintf, vdprintf .Nd formatted output conversion .Sh LIBRARY .Lb libc .Sh SYNOPSIS +.Fd "#define _WITH_DPRINTF" .In stdio.h .Ft int .Fn printf "const char * restrict format" ... @@ -57,6 +54,8 @@ .Fn snprintf "char * restrict str" "size_t size" "const char * restrict format" ... .Ft int .Fn asprintf "char **ret" "const char *format" ... +.Ft int +.Fn dprintf "int fd" "const char * restrict format" ... .In stdarg.h .Ft int .Fn vprintf "const char * restrict format" "va_list ap" @@ -68,6 +67,8 @@ .Fn vsnprintf "char * restrict str" "size_t size" "const char * restrict format" "va_list ap" .Ft int .Fn vasprintf "char **ret" "const char *format" "va_list ap" +.Ft int +.Fn vdprintf "int fd" "const char * restrict format" "va_list ap" .Sh DESCRIPTION The .Fn printf @@ -87,6 +88,10 @@ and .Fn vfprintf write output to the given output .Fa stream ; +.Fn dprintf +and +.Fn vdprintf +write output to the given file descriptor; .Fn sprintf , .Fn snprintf , .Fn vsprintf , @@ -211,8 +216,7 @@ conversions, this option has no effect. For .Cm o conversions, the precision of the number is increased to force the first -character of the output string to a zero (except if a zero value is printed -with an explicit precision of zero). +character of the output string to a zero. For .Cm x and @@ -553,13 +557,14 @@ to separate the mantissa and exponent. Note that there may be multiple valid ways to represent floating-point numbers in this hexadecimal format. For example, -.Li 0x3.24p+0 , 0x6.48p-1 +.Li 0x1.92p+1 , 0x3.24p+0 , 0x6.48p-1 , and .Li 0xc.9p-2 are all equivalent. -The format chosen depends on the internal representation of the -number, but the implementation guarantees that the length of the -mantissa will be minimized. +.Fx 8.0 +and later always prints finite non-zero numbers using +.Ql 1 +as the digit before the hexadecimal point. Zeroes are always represented with a mantissa of 0 (preceded by a .Ql - if appropriate) and an exponent of @@ -775,6 +780,57 @@ for later interpolation by Always use the proper secure idiom: .Pp .Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);" +.Sh COMPATIBILITY +Many application writers used the name +.Va dprintf +before the +.Fn dprintf +function was introduced in +.St -p1003.1 , +so a prototype is not provided by default in order to avoid +compatibility problems. +Applications that wish to use the +.Fn dprintf +function described herein should either request a strict +.St -p1003.1-2008 +environment by defining the macro +.Dv _POSIX_C_SOURCE +to the value 200809 or greater, or by defining the macro +.Dv _WITH_DPRINTF , +prior to the inclusion of +.In stdio.h . +For compatibility with GNU libc, defining either +.Dv _BSD_SOURCE +or +.Dv _GNU_SOURCE +prior to the inclusion of +.In stdio.h +will also make +.Fn dprintf +available. +.Pp +The conversion formats +.Cm \&%D , \&%O , +and +.Cm %U +are not standard and +are provided only for backward compatibility. +The effect of padding the +.Cm %p +format with zeros (either by the +.Cm 0 +flag or by specifying a precision), and the benign effect (i.e., none) +of the +.Cm # +flag on +.Cm %n +and +.Cm %p +conversions, as well as other +nonsensical combinations such as +.Cm %Ld , +are not standard; such combinations +should be avoided. .Sh ERRORS In addition to the errors documented for the .Xr write 2 @@ -793,11 +849,6 @@ Insufficient storage space is available. .Xr scanf 3 , .Xr setlocale 3 , .Xr wprintf 3 -.Rs -.%T "The FreeBSD Security Architecture" -.Re -(See -.Pa "/usr/share/doc/{to be determined}" . ) .Sh STANDARDS Subject to the caveats noted in the .Sx BUGS @@ -819,7 +870,13 @@ With the same reservation, the and .Fn vsnprintf functions conform to -.St -isoC-99 . +.St -isoC-99 , +while +.Fn dprintf +and +.Fn vdprintf +conform to +.St -p1003.1-2008 . .Sh HISTORY The functions .Fn asprintf @@ -837,30 +894,13 @@ from .An Todd C. Miller Aq Todd.Miller@courtesan.com for .Ox 2.3 . -.Sh BUGS -The conversion formats -.Cm \&%D , \&%O , -and -.Cm %U -are not standard and -are provided only for backward compatibility. -The effect of padding the -.Cm %p -format with zeros (either by the -.Cm 0 -flag or by specifying a precision), and the benign effect (i.e., none) -of the -.Cm # -flag on -.Cm %n +The +.Fn dprintf and -.Cm %p -conversions, as well as other -nonsensical combinations such as -.Cm %Ld , -are not standard; such combinations -should be avoided. -.Pp +.Fn vdprintf +functions were added in +.Fx 8.0 . +.Sh BUGS The .Nm family of functions do not correctly handle multibyte characters in the diff --git a/stdio/FreeBSD/printf.3.patch b/stdio/FreeBSD/printf.3.patch index 6defa49..d34b422 100644 --- a/stdio/FreeBSD/printf.3.patch +++ b/stdio/FreeBSD/printf.3.patch @@ -1,103 +1,14 @@ ---- printf.3.orig 2008-02-29 10:45:39.000000000 -0800 -+++ printf.3 2008-02-29 12:19:06.000000000 -0800 -@@ -40,39 +40,83 @@ - .Dt PRINTF 3 - .Os - .Sh NAME --.Nm printf , fprintf , sprintf , snprintf , asprintf , --.Nm vprintf , vfprintf, vsprintf , vsnprintf , vasprintf -+.Nm asprintf , -+.Nm fprintf , -+.Nm printf , -+.Nm snprintf , -+.Nm sprintf , -+.Nm vasprintf , -+.Nm vfprintf, -+.Nm vprintf , -+.Nm vsnprintf , -+.Nm vsprintf - .Nd formatted output conversion +--- printf.3.orig 2009-12-15 17:50:20.000000000 -0800 ++++ printf.3 2009-12-15 17:58:46.000000000 -0800 +@@ -42,7 +42,6 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS +-.Fd "#define _WITH_DPRINTF" .In stdio.h .Ft int --.Fn printf "const char * restrict format" ... -+.Fo asprintf -+.Fa "char **ret" -+.Fa "const char *format" ... -+.Fc - .Ft int --.Fn fprintf "FILE * restrict stream" "const char * restrict format" ... -+.Fo fprintf -+.Fa "FILE *restrict stream" -+.Fa "const char *restrict format" ... -+.Fc - .Ft int --.Fn sprintf "char * restrict str" "const char * restrict format" ... -+.Fo printf -+.Fa "const char *restrict format" ... -+.Fc - .Ft int --.Fn snprintf "char * restrict str" "size_t size" "const char * restrict format" ... -+.Fo snprintf -+.Fa "char *restrict s" -+.Fa "size_t n" -+.Fa "const char *restrict format" ... -+.Fc - .Ft int --.Fn asprintf "char **ret" "const char *format" ... -+.Fo sprintf -+.Fa "char *restrict s" -+.Fa "const char *restrict format" ... -+.Fc - .In stdarg.h -+.In stdio.h - .Ft int --.Fn vprintf "const char * restrict format" "va_list ap" -+.Fo vasprintf -+.Fa "char **ret" -+.Fa "const char *format" -+.Fa "va_list ap" -+.Fc - .Ft int --.Fn vfprintf "FILE * restrict stream" "const char * restrict format" "va_list ap" -+.Fo vfprintf -+.Fa "FILE *restrict stream" -+.Fa "const char *restrict format" -+.Fa "va_list ap" -+.Fc - .Ft int --.Fn vsprintf "char * restrict str" "const char * restrict format" "va_list ap" -+.Fo vprintf -+.Fa "const char *restrict format" -+.Fa "va_list ap" -+.Fc - .Ft int --.Fn vsnprintf "char * restrict str" "size_t size" "const char * restrict format" "va_list ap" -+.Fo vsnprintf -+.Fa "char *restrict s" -+.Fa "size_t n" -+.Fa "const char *restrict format" -+.Fa "va_list ap" -+.Fc - .Ft int --.Fn vasprintf "char **ret" "const char *format" "va_list ap" -+.Fo vsprintf -+.Fa "char *restrict s" -+.Fa "const char *restrict format" -+.Fa "va_list ap" -+.Fc - .Sh DESCRIPTION - The - .Fn printf - family of functions produces output according to a --.Fa format -+.Fa format , - as described below. - The - .Fn printf -@@ -93,7 +137,7 @@ + .Fn printf "const char * restrict format" ... +@@ -98,7 +97,7 @@ write output to the given file descripto and .Fn vsnprintf write to the character string @@ -106,7 +17,7 @@ and .Fn asprintf and -@@ -101,6 +145,12 @@ +@@ -106,6 +105,12 @@ and dynamically allocate a new string with .Xr malloc 3 . .Pp @@ -119,7 +30,7 @@ These functions write the output under the control of a .Fa format string that specifies how subsequent arguments -@@ -117,7 +167,7 @@ +@@ -122,7 +127,7 @@ except for and .Fn vsnprintf , which return the number of characters that would have been printed if the @@ -128,7 +39,7 @@ were unlimited (again, not including the final .Ql \e0 ) . -@@ -149,14 +199,14 @@ +@@ -154,14 +159,14 @@ and .Fn vsnprintf functions will write at most @@ -146,7 +57,7 @@ argument, the string was too short and some of the printed characters were discarded. The output is always null-terminated. -@@ -167,7 +217,11 @@ +@@ -172,7 +177,11 @@ and .Fn vsprintf functions effectively assume an infinite @@ -159,7 +70,7 @@ .Pp The format string is composed of zero or more directives: ordinary -@@ -287,6 +341,20 @@ +@@ -291,6 +300,20 @@ the non-monetary separator returned by .Xr localeconv 3 . .El .It @@ -180,7 +91,7 @@ An optional decimal digit string specifying a minimum field width. If the converted value has fewer characters than the field width, it will be padded with spaces on the left (or right, if the left-adjustment -@@ -379,6 +447,34 @@ +@@ -383,6 +406,34 @@ conversion: .It Sy Modifier Ta Cm c Ta Cm s .It Cm l No (ell) Ta Vt wint_t Ta Vt "wchar_t *" .El @@ -215,20 +126,64 @@ .It A character that specifies the type of conversion to be applied. .El -@@ -790,14 +886,11 @@ +@@ -561,10 +612,9 @@ For example, + and + .Li 0xc.9p-2 + are all equivalent. +-.Fx 8.0 +-and later always prints finite non-zero numbers using +-.Ql 1 +-as the digit before the hexadecimal point. ++The format chosen depends on the internal representation of the ++number, but the implementation guarantees that the length of the ++mantissa will be minimized. + Zeroes are always represented with a mantissa of 0 (preceded by a + .Ql - + if appropriate) and an exponent of +@@ -781,34 +831,6 @@ Always use the proper secure idiom: + .Pp + .Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);" + .Sh COMPATIBILITY +-Many application writers used the name +-.Va dprintf +-before the +-.Fn dprintf +-function was introduced in +-.St -p1003.1 , +-so a prototype is not provided by default in order to avoid +-compatibility problems. +-Applications that wish to use the +-.Fn dprintf +-function described herein should either request a strict +-.St -p1003.1-2008 +-environment by defining the macro +-.Dv _POSIX_C_SOURCE +-to the value 200809 or greater, or by defining the macro +-.Dv _WITH_DPRINTF , +-prior to the inclusion of +-.In stdio.h . +-For compatibility with GNU libc, defining either +-.Dv _BSD_SOURCE +-or +-.Dv _GNU_SOURCE +-prior to the inclusion of +-.In stdio.h +-will also make +-.Fn dprintf +-available. +-.Pp + The conversion formats + .Cm \&%D , \&%O , + and +@@ -845,9 +867,11 @@ Insufficient storage space is available. + .El .Sh SEE ALSO .Xr printf 1 , - .Xr fmtcheck 3 , +.Xr printf_l 3 , + .Xr fmtcheck 3 , .Xr scanf 3 , .Xr setlocale 3 , +.Xr stdarg 3 , .Xr wprintf 3 --.Rs --.%T "The FreeBSD Security Architecture" --.Re --(See --.Pa "/usr/share/doc/{to be determined}" . ) .Sh STANDARDS Subject to the caveats noted in the - .Sx BUGS diff --git a/stdio/FreeBSD/printf.c b/stdio/FreeBSD/printf.c index 86452e2..c1ee178 100644 --- a/stdio/FreeBSD/printf.c +++ b/stdio/FreeBSD/printf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)printf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/printf.c,v 1.10 2002/09/06 11:23:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/printf.c,v 1.11 2007/01/09 00:28:07 imp Exp $"); #include #include diff --git a/stdio/FreeBSD/printf.c.patch b/stdio/FreeBSD/printf.c.patch index 236b834..dfd8cbe 100644 --- a/stdio/FreeBSD/printf.c.patch +++ b/stdio/FreeBSD/printf.c.patch @@ -1,15 +1,15 @@ ---- printf.c.orig 2003-05-20 15:22:43.000000000 -0700 -+++ printf.c 2005-02-23 16:34:28.000000000 -0800 -@@ -40,6 +40,8 @@ +--- printf.c.bsdnew 2009-11-11 13:33:13.000000000 -0800 ++++ printf.c 2009-11-11 13:33:13.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)printf.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/printf.c,v 1.10 2002/09/06 11:23:55 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/printf.c,v 1.11 2007/01/09 00:28:07 imp Exp $"); +#include "xlocale_private.h" + #include #include -@@ -50,7 +52,20 @@ +@@ -46,7 +48,20 @@ printf(char const * __restrict fmt, ...) va_list ap; va_start(ap, fmt); diff --git a/stdio/FreeBSD/printfcommon.h b/stdio/FreeBSD/printfcommon.h new file mode 100644 index 0000000..01504f9 --- /dev/null +++ b/stdio/FreeBSD/printfcommon.h @@ -0,0 +1,301 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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: src/lib/libc/stdio/printfcommon.h,v 1.4 2009/01/22 08:14:28 das Exp $ + */ + +/* + * This file defines common routines used by both printf and wprintf. + * You must define CHAR to either char or wchar_t prior to including this. + */ + + +#ifndef NO_FLOATING_POINT + +#define dtoa __dtoa +#define freedtoa __freedtoa + +#include +#include +#include "floatio.h" +#include "gdtoa.h" + +#define DEFPREC 6 + +static int exponent(CHAR *, int, CHAR); + +#endif /* !NO_FLOATING_POINT */ + +static CHAR *__ujtoa(uintmax_t, CHAR *, int, int, const char *); +static CHAR *__ultoa(u_long, CHAR *, int, int, const char *); + +#define NIOV 8 +struct io_state { + FILE *fp; + struct __suio uio; /* output information: summary */ + struct __siov iov[NIOV];/* ... and individual io vectors */ +}; + +static inline void +io_init(struct io_state *iop, FILE *fp) +{ + + iop->uio.uio_iov = iop->iov; + iop->uio.uio_resid = 0; + iop->uio.uio_iovcnt = 0; + iop->fp = fp; +} + +/* + * WARNING: The buffer passed to io_print() is not copied immediately; it must + * remain valid until io_flush() is called. + */ +static inline int +io_print(struct io_state *iop, const CHAR * __restrict ptr, int len) +{ + + iop->iov[iop->uio.uio_iovcnt].iov_base = (char *)ptr; + iop->iov[iop->uio.uio_iovcnt].iov_len = len; + iop->uio.uio_resid += len; + if (++iop->uio.uio_iovcnt >= NIOV) + return (__sprint(iop->fp, &iop->uio)); + else + return (0); +} + +/* + * Choose PADSIZE to trade efficiency vs. size. If larger printf + * fields occur frequently, increase PADSIZE and make the initialisers + * below longer. + */ +#define PADSIZE 16 /* pad chunk size */ +static const CHAR blanks[PADSIZE] = +{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; +static const CHAR zeroes[PADSIZE] = +{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; + +/* + * Pad with blanks or zeroes. 'with' should point to either the blanks array + * or the zeroes array. + */ +static inline int +io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with) +{ + int n; + + while (howmany > 0) { + n = (howmany >= PADSIZE) ? PADSIZE : howmany; + if (io_print(iop, with, n)) + return (-1); + howmany -= n; + } + return (0); +} + +/* + * Print exactly len characters of the string spanning p to ep, truncating + * or padding with 'with' as necessary. + */ +static inline int +io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep, + int len, const CHAR * __restrict with) +{ + int p_len; + + p_len = ep - p; + if (p_len > len) + p_len = len; + if (p_len > 0) { + if (io_print(iop, p, p_len)) + return (-1); + } else { + p_len = 0; + } + return (io_pad(iop, len - p_len, with)); +} + +static inline int +io_flush(struct io_state *iop) +{ + + return (__sprint(iop->fp, &iop->uio)); +} + +/* + * Convert an unsigned long to ASCII for printf purposes, returning + * a pointer to the first character of the string representation. + * Octal numbers can be forced to have a leading zero; hex numbers + * use the given digits. + */ +static CHAR * +__ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs) +{ + CHAR *cp = endp; + long sval; + + /* + * Handle the three cases separately, in the hope of getting + * better/faster code. + */ + switch (base) { + case 10: + if (val < 10) { /* many numbers are 1 digit */ + *--cp = to_char(val); + return (cp); + } + /* + * On many machines, unsigned arithmetic is harder than + * signed arithmetic, so we do at most one unsigned mod and + * divide; this is sufficient to reduce the range of + * the incoming value to where signed arithmetic works. + */ + if (val > LONG_MAX) { + *--cp = to_char(val % 10); + sval = val / 10; + } else + sval = val; + do { + *--cp = to_char(sval % 10); + sval /= 10; + } while (sval != 0); + break; + + case 8: + do { + *--cp = to_char(val & 7); + val >>= 3; + } while (val); + if (octzero && *cp != '0') + *--cp = '0'; + break; + + case 16: + do { + *--cp = xdigs[val & 15]; + val >>= 4; + } while (val); + break; + + default: /* oops */ + abort(); + } + return (cp); +} + +/* Identical to __ultoa, but for intmax_t. */ +static CHAR * +__ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs) +{ + CHAR *cp = endp; + intmax_t sval; + + /* quick test for small values; __ultoa is typically much faster */ + /* (perhaps instead we should run until small, then call __ultoa?) */ + if (val <= ULONG_MAX) + return (__ultoa((u_long)val, endp, base, octzero, xdigs)); + switch (base) { + case 10: + if (val < 10) { + *--cp = to_char(val % 10); + return (cp); + } + if (val > INTMAX_MAX) { + *--cp = to_char(val % 10); + sval = val / 10; + } else + sval = val; + do { + *--cp = to_char(sval % 10); + sval /= 10; + } while (sval != 0); + break; + + case 8: + do { + *--cp = to_char(val & 7); + val >>= 3; + } while (val); + if (octzero && *cp != '0') + *--cp = '0'; + break; + + case 16: + do { + *--cp = xdigs[val & 15]; + val >>= 4; + } while (val); + break; + + default: + abort(); + } + return (cp); +} + +#ifndef NO_FLOATING_POINT + +static int +exponent(CHAR *p0, int exp, CHAR fmtch) +{ + CHAR *p, *t; + CHAR expbuf[MAXEXPDIG]; + + p = p0; + *p++ = fmtch; + if (exp < 0) { + exp = -exp; + *p++ = '-'; + } + else + *p++ = '+'; + t = expbuf + MAXEXPDIG; + if (exp > 9) { + do { + *--t = to_char(exp % 10); + } while ((exp /= 10) > 9); + *--t = to_char(exp); + for (; t < expbuf + MAXEXPDIG; *p++ = *t++); + } + else { + /* + * Exponents for decimal floating point conversions + * (%[eEgG]) must be at least two characters long, + * whereas exponents for hexadecimal conversions can + * be only one character long. + */ + if (fmtch == 'e' || fmtch == 'E') + *p++ = '0'; + *p++ = to_char(exp); + } + return (p - p0); +} + +#endif /* !NO_FLOATING_POINT */ diff --git a/stdio/FreeBSD/printfcommon.h.patch b/stdio/FreeBSD/printfcommon.h.patch new file mode 100644 index 0000000..38db417 --- /dev/null +++ b/stdio/FreeBSD/printfcommon.h.patch @@ -0,0 +1,86 @@ +--- printfcommon.h.orig 2009-11-12 13:29:57.000000000 -0800 ++++ printfcommon.h 2009-11-12 23:50:26.000000000 -0800 +@@ -79,14 +79,14 @@ io_init(struct io_state *iop, FILE *fp) + * remain valid until io_flush() is called. + */ + static inline int +-io_print(struct io_state *iop, const CHAR * __restrict ptr, int len) ++io_print(struct io_state *iop, const CHAR * __restrict ptr, int len, locale_t loc) + { + + iop->iov[iop->uio.uio_iovcnt].iov_base = (char *)ptr; + iop->iov[iop->uio.uio_iovcnt].iov_len = len; + iop->uio.uio_resid += len; + if (++iop->uio.uio_iovcnt >= NIOV) +- return (__sprint(iop->fp, &iop->uio)); ++ return (__sprint(iop->fp, loc, &iop->uio)); + else + return (0); + } +@@ -107,13 +107,13 @@ static const CHAR zeroes[PADSIZE] = + * or the zeroes array. + */ + static inline int +-io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with) ++io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with, locale_t loc) + { + int n; + + while (howmany > 0) { + n = (howmany >= PADSIZE) ? PADSIZE : howmany; +- if (io_print(iop, with, n)) ++ if (io_print(iop, with, n, loc)) + return (-1); + howmany -= n; + } +@@ -126,7 +126,7 @@ io_pad(struct io_state *iop, int howmany + */ + static inline int + io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep, +- int len, const CHAR * __restrict with) ++ int len, const CHAR * __restrict with, locale_t loc) + { + int p_len; + +@@ -134,19 +134,19 @@ io_printandpad(struct io_state *iop, con + if (p_len > len) + p_len = len; + if (p_len > 0) { +- if (io_print(iop, p, p_len)) ++ if (io_print(iop, p, p_len, loc)) + return (-1); + } else { + p_len = 0; + } +- return (io_pad(iop, len - p_len, with)); ++ return (io_pad(iop, len - p_len, with, loc)); + } + + static inline int +-io_flush(struct io_state *iop) ++io_flush(struct io_state *iop, locale_t loc) + { + +- return (__sprint(iop->fp, &iop->uio)); ++ return (__sprint(iop->fp, loc, &iop->uio)); + } + + /* +@@ -205,7 +205,7 @@ __ultoa(u_long val, CHAR *endp, int base + break; + + default: /* oops */ +- abort(); ++ LIBC_ABORT("__ultoa: invalid base=%d", base); + } + return (cp); + } +@@ -255,7 +255,7 @@ __ujtoa(uintmax_t val, CHAR *endp, int b + break; + + default: +- abort(); ++ LIBC_ABORT("__ujtoa: invalid base=%d", base); + } + return (cp); + } diff --git a/stdio/FreeBSD/printflocal.h b/stdio/FreeBSD/printflocal.h new file mode 100644 index 0000000..ca7e05d --- /dev/null +++ b/stdio/FreeBSD/printflocal.h @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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: src/lib/libc/stdio/printflocal.h,v 1.3 2009/03/02 04:07:58 das Exp $ + */ + +/* + * Flags used during conversion. + */ +#define ALT 0x001 /* alternate form */ +#define LADJUST 0x004 /* left adjustment */ +#define LONGDBL 0x008 /* long double */ +#define LONGINT 0x010 /* long integer */ +#define LLONGINT 0x020 /* long long integer */ +#define SHORTINT 0x040 /* short integer */ +#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ +#define FPT 0x100 /* Floating point number */ +#define GROUPING 0x200 /* use grouping ("'" flag) */ + /* C99 additional size modifiers: */ +#define SIZET 0x400 /* size_t */ +#define PTRDIFFT 0x800 /* ptrdiff_t */ +#define INTMAXT 0x1000 /* intmax_t */ +#define CHARINT 0x2000 /* print char using int format */ + +/* + * Macros for converting digits to letters and vice versa + */ +#define to_digit(c) ((c) - '0') +#define is_digit(c) ((unsigned)to_digit(c) <= 9) +#define to_char(n) ((n) + '0') + +/* Size of the static argument table. */ +#define STATIC_ARG_TBL_SIZE 8 + +union arg { + int intarg; + u_int uintarg; + long longarg; + u_long ulongarg; + long long longlongarg; + unsigned long long ulonglongarg; + ptrdiff_t ptrdiffarg; + size_t sizearg; + intmax_t intmaxarg; + uintmax_t uintmaxarg; + void *pvoidarg; + char *pchararg; + signed char *pschararg; + short *pshortarg; + int *pintarg; + long *plongarg; + long long *plonglongarg; + ptrdiff_t *pptrdiffarg; + ssize_t *pssizearg; + intmax_t *pintmaxarg; +#ifndef NO_FLOATING_POINT + double doublearg; + long double longdoublearg; +#endif + wint_t wintarg; + wchar_t *pwchararg; +}; + +/* Handle positional parameters. */ +int __find_arguments(const char *, va_list, union arg **); +int __find_warguments(const wchar_t *, va_list, union arg **); diff --git a/stdio/FreeBSD/printflocal.h.patch b/stdio/FreeBSD/printflocal.h.patch new file mode 100644 index 0000000..209dc14 --- /dev/null +++ b/stdio/FreeBSD/printflocal.h.patch @@ -0,0 +1,60 @@ +--- printflocal.h.orig 2009-11-12 13:40:46.000000000 -0800 ++++ printflocal.h 2009-11-12 23:06:25.000000000 -0800 +@@ -32,6 +32,11 @@ + * $FreeBSD: src/lib/libc/stdio/printflocal.h,v 1.3 2009/03/02 04:07:58 das Exp $ + */ + ++/* ++ * Defining here VECTORS for all files that include this header () ++ */ ++#define VECTORS ++ + /* + * Flags used during conversion. + */ +@@ -49,6 +49,9 @@ + #define PTRDIFFT 0x800 /* ptrdiff_t */ + #define INTMAXT 0x1000 /* intmax_t */ + #define CHARINT 0x2000 /* print char using int format */ ++#ifdef VECTORS ++#define VECTOR 0x4000 /* Altivec or SSE vector */ ++#endif /* VECTORS */ + + /* + * Macros for converting digits to letters and vice versa +@@ -60,6 +63,13 @@ + /* Size of the static argument table. */ + #define STATIC_ARG_TBL_SIZE 8 + ++#ifdef VECTORS ++typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE; ++#ifdef __SSE2__ ++#define V64TYPE ++#endif /* __SSE2__ */ ++#endif /* VECTORS */ ++ + union arg { + int intarg; + u_int uintarg; +@@ -87,6 +97,21 @@ union arg { + #endif + wint_t wintarg; + wchar_t *pwchararg; ++#ifdef VECTORS ++ VECTORTYPE vectorarg; ++ unsigned char vuchararg[16]; ++ signed char vchararg[16]; ++ unsigned short vushortarg[8]; ++ signed short vshortarg[8]; ++ unsigned int vuintarg[4]; ++ signed int vintarg[4]; ++ float vfloatarg[4]; ++#ifdef V64TYPE ++ double vdoublearg[2]; ++ unsigned long long vulonglongarg[2]; ++ long long vlonglongarg[2]; ++#endif /* V64TYPE */ ++#endif /* VECTORS */ + }; + + /* Handle positional parameters. */ diff --git a/stdio/FreeBSD/putc.3 b/stdio/FreeBSD/putc.3 index 7c766b0..216c1cb 100644 --- a/stdio/FreeBSD/putc.3 +++ b/stdio/FreeBSD/putc.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)putc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/putc.3,v 1.15 2004/03/17 12:46:17 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/putc.3,v 1.16 2007/01/09 00:28:07 imp Exp $ .\" .Dd January 10, 2003 .Dt PUTC 3 diff --git a/stdio/FreeBSD/putc.3.patch b/stdio/FreeBSD/putc.3.patch index 744545a..613d138 100644 --- a/stdio/FreeBSD/putc.3.patch +++ b/stdio/FreeBSD/putc.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdio/FreeBSD/putc.3 2004-11-25 11:38:35.000000000 -0800 -+++ _SB/Libc/stdio/FreeBSD/putc.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -52,17 +52,33 @@ +--- putc.3.bsdnew 2009-11-11 13:33:13.000000000 -0800 ++++ putc.3 2009-11-11 13:33:14.000000000 -0800 +@@ -48,17 +48,33 @@ .Sh SYNOPSIS .In stdio.h .Ft int @@ -45,7 +45,7 @@ .Sh DESCRIPTION The .Fn fputc -@@ -121,7 +137,7 @@ +@@ -117,7 +133,7 @@ The functions, .Fn fputc , .Fn putc , .Fn putchar , diff --git a/stdio/FreeBSD/putc.c b/stdio/FreeBSD/putc.c index e78bb42..44b64b4 100644 --- a/stdio/FreeBSD/putc.c +++ b/stdio/FreeBSD/putc.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)putc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/putc.c,v 1.13 2004/03/19 09:04:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/putc.c,v 1.16 2008/05/05 16:03:52 jhb Exp $"); #include "namespace.h" #include @@ -47,6 +43,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/putc.c,v 1.13 2004/03/19 09:04:56 tjr Exp #include "libc_private.h" #undef putc +#undef putc_unlocked int putc(c, fp) @@ -61,3 +58,10 @@ putc(c, fp) FUNLOCKFILE(fp); return (retval); } + +int +putc_unlocked(int ch, FILE *fp) +{ + + return (__sputc(ch, fp)); +} diff --git a/stdio/FreeBSD/putchar.c b/stdio/FreeBSD/putchar.c index d23161d..d07157b 100644 --- a/stdio/FreeBSD/putchar.c +++ b/stdio/FreeBSD/putchar.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)putchar.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/putchar.c,v 1.13 2004/03/19 09:04:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/putchar.c,v 1.16 2008/05/05 16:03:52 jhb Exp $"); #include "namespace.h" #include @@ -47,6 +43,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/putchar.c,v 1.13 2004/03/19 09:04:56 tjr #include "libc_private.h" #undef putchar +#undef putchar_unlocked /* * A subroutine version of the macro putchar @@ -65,3 +62,10 @@ putchar(c) FUNLOCKFILE(so); return (retval); } + +int +putchar_unlocked(int ch) +{ + + return (__sputc(ch, stdout)); +} diff --git a/stdio/FreeBSD/puts.c b/stdio/FreeBSD/puts.c index 9ac915e..4b27733 100644 --- a/stdio/FreeBSD/puts.c +++ b/stdio/FreeBSD/puts.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)puts.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/puts.c,v 1.10 2004/03/10 09:15:38 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/puts.c,v 1.11 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/puts.c.patch b/stdio/FreeBSD/puts.c.patch index 1dd56ca..f56c66a 100644 --- a/stdio/FreeBSD/puts.c.patch +++ b/stdio/FreeBSD/puts.c.patch @@ -1,6 +1,6 @@ ---- /Volumes/XDisk/tmp/Libc/stdio/FreeBSD/puts.c.orig 2004-03-10 01:15:38.000000000 -0800 -+++ /Volumes/XDisk/tmp/Libc/stdio/FreeBSD/puts.c 2004-10-24 17:08:31.000000000 -0700 -@@ -48,6 +48,9 @@ +--- puts.c.bsdnew 2009-11-11 13:33:14.000000000 -0800 ++++ puts.c 2009-11-11 13:33:14.000000000 -0800 +@@ -44,6 +44,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/p #include "libc_private.h" #include "local.h" @@ -10,7 +10,7 @@ /* * Write the given string to stdout, appending a newline. */ -@@ -56,12 +59,15 @@ +@@ -52,12 +55,15 @@ puts(s) char const *s; { int retval; diff --git a/stdio/FreeBSD/putw.c b/stdio/FreeBSD/putw.c index ee0c23b..b5a88a8 100644 --- a/stdio/FreeBSD/putw.c +++ b/stdio/FreeBSD/putw.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)putw.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/putw.c,v 1.9 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/putw.c,v 1.10 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/putwc.3 b/stdio/FreeBSD/putwc.3 index aaaec12..47b728c 100644 --- a/stdio/FreeBSD/putwc.3 +++ b/stdio/FreeBSD/putwc.3 @@ -15,10 +15,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -36,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)putc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/putwc.3,v 1.7 2004/03/16 13:30:11 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/putwc.3,v 1.8 2007/01/09 00:28:07 imp Exp $ .\" .Dd March 3, 2004 .Dt PUTWC 3 diff --git a/stdio/FreeBSD/putwc.3.patch b/stdio/FreeBSD/putwc.3.patch index 5589478..a4b0008 100644 --- a/stdio/FreeBSD/putwc.3.patch +++ b/stdio/FreeBSD/putwc.3.patch @@ -1,6 +1,6 @@ ---- putwc.3 2004-11-25 11:38:35.000000000 -0800 -+++ putwc.3.edit 2006-08-09 13:41:39.000000000 -0700 -@@ -52,11 +52,19 @@ +--- putwc.3.bsdnew 2009-11-11 13:33:14.000000000 -0800 ++++ putwc.3 2009-11-11 13:33:14.000000000 -0800 +@@ -48,11 +48,19 @@ .In stdio.h .In wchar.h .Ft wint_t @@ -23,7 +23,7 @@ .Sh DESCRIPTION The .Fn fputwc -@@ -79,6 +87,12 @@ +@@ -75,6 +83,12 @@ is identical to .Fn putwc with an output stream of .Dv stdout . @@ -36,7 +36,7 @@ .Sh RETURN VALUES The .Fn fputwc , -@@ -95,6 +109,7 @@ +@@ -91,6 +105,7 @@ is returned. .Xr fopen 3 , .Xr getwc 3 , .Xr putc 3 , diff --git a/stdio/FreeBSD/refill.c b/stdio/FreeBSD/refill.c index edd8bb6..a7d486f 100644 --- a/stdio/FreeBSD/refill.c +++ b/stdio/FreeBSD/refill.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)refill.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/refill.c,v 1.18 2002/08/13 09:30:41 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/refill.c,v 1.20 2008/04/17 22:17:54 jhb Exp $"); #include "namespace.h" #include @@ -110,7 +106,7 @@ __srefill(FILE *fp) if (HASUB(fp)) { FREEUB(fp); if ((fp->_r = fp->_ur) != 0) { - fp->_p = fp->_extra->_up; + fp->_p = fp->_up; return (0); } } diff --git a/stdio/FreeBSD/refill.c.patch b/stdio/FreeBSD/refill.c.patch index 1bcc968..ef4573d 100644 --- a/stdio/FreeBSD/refill.c.patch +++ b/stdio/FreeBSD/refill.c.patch @@ -1,6 +1,6 @@ ---- refill.c.orig 2008-01-24 17:13:42.000000000 -0800 -+++ refill.c 2008-02-17 13:19:27.000000000 -0800 -@@ -68,8 +68,8 @@ lflush(FILE *fp) +--- refill.c.bsdnew 2009-11-11 13:33:14.000000000 -0800 ++++ refill.c 2009-11-11 13:33:14.000000000 -0800 +@@ -64,8 +64,8 @@ lflush(FILE *fp) * Refill a stdio buffer. * Return EOF on eof or error, 0 otherwise. */ @@ -11,7 +11,7 @@ { /* make sure stdio is set up */ -@@ -134,6 +134,13 @@ __srefill(FILE *fp) +@@ -130,6 +130,13 @@ __srefill(FILE *fp) if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) __sflush(fp); } @@ -25,7 +25,7 @@ fp->_p = fp->_bf._base; fp->_r = _sread(fp, (char *)fp->_p, fp->_bf._size); fp->_flags &= ~__SMOD; /* buffer contents are again pristine */ -@@ -148,3 +155,13 @@ __srefill(FILE *fp) +@@ -144,3 +151,13 @@ __srefill(FILE *fp) } return (0); } diff --git a/stdio/FreeBSD/remove.3 b/stdio/FreeBSD/remove.3 index 8c9d65f..618111f 100644 --- a/stdio/FreeBSD/remove.3 +++ b/stdio/FreeBSD/remove.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)remove.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/remove.3,v 1.9 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/remove.3,v 1.10 2007/01/09 00:28:07 imp Exp $ .\" .Dd June 4, 1993 .Dt REMOVE 3 diff --git a/stdio/FreeBSD/remove.3.patch b/stdio/FreeBSD/remove.3.patch index 9d94403..8a24b15 100644 --- a/stdio/FreeBSD/remove.3.patch +++ b/stdio/FreeBSD/remove.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdio/FreeBSD/remove.3 2003-05-20 15:22:43.000000000 -0700 -+++ _SB/Libc/stdio/FreeBSD/remove.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -72,7 +72,7 @@ +--- remove.3.bsdnew 2009-11-11 13:33:15.000000000 -0800 ++++ remove.3 2009-11-11 13:33:15.000000000 -0800 +@@ -68,7 +68,7 @@ may fail and set .Va errno for any of the errors specified for the routines .Xr lstat 2 , diff --git a/stdio/FreeBSD/remove.c b/stdio/FreeBSD/remove.c index 2553f64..c6e608b 100644 --- a/stdio/FreeBSD/remove.c +++ b/stdio/FreeBSD/remove.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)remove.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/remove.c,v 1.8 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/remove.c,v 1.9 2007/01/09 00:28:07 imp Exp $"); #include #include diff --git a/stdio/FreeBSD/rewind.c b/stdio/FreeBSD/rewind.c index 76f2ed3..b5204ed 100644 --- a/stdio/FreeBSD/rewind.c +++ b/stdio/FreeBSD/rewind.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)rewind.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/rewind.c,v 1.11 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/rewind.c,v 1.12 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/rewind.c.patch b/stdio/FreeBSD/rewind.c.patch index d1ceb77..ffdf7fd 100644 --- a/stdio/FreeBSD/rewind.c.patch +++ b/stdio/FreeBSD/rewind.c.patch @@ -1,11 +1,6 @@ -Index: rewind.c -=================================================================== -RCS file: /cvs/root/Libc/stdio/FreeBSD/rewind.c,v -retrieving revision 1.2 -diff -u -d -b -w -p -u -r1.2 rewind.c ---- rewind.c 2003/05/20 22:22:43 1.2 -+++ rewind.c 2004/10/27 05:51:34 -@@ -58,8 +58,8 @@ rewind(FILE *fp) +--- rewind.c.bsdnew 2009-11-11 13:33:15.000000000 -0800 ++++ rewind.c 2009-11-11 13:33:15.000000000 -0800 +@@ -54,8 +54,8 @@ rewind(FILE *fp) FLOCKFILE(fp); if (_fseeko(fp, (off_t)0, SEEK_SET, 1) == 0) { diff --git a/stdio/FreeBSD/rget.c b/stdio/FreeBSD/rget.c index 9b7f586..7e69c41 100644 --- a/stdio/FreeBSD/rget.c +++ b/stdio/FreeBSD/rget.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)rget.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/rget.c,v 1.5 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/rget.c,v 1.6 2007/01/09 00:28:07 imp Exp $"); #include #include "local.h" diff --git a/stdio/FreeBSD/scanf.3 b/stdio/FreeBSD/scanf.3 index 3f5913a..5f424ff 100644 --- a/stdio/FreeBSD/scanf.3 +++ b/stdio/FreeBSD/scanf.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)scanf.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/stdio/scanf.3,v 1.24 2003/06/28 09:03:25 das Exp $ +.\" $FreeBSD: src/lib/libc/stdio/scanf.3,v 1.25 2007/01/09 00:28:07 imp Exp $ .\" .Dd January 4, 2003 .Dt SCANF 3 diff --git a/stdio/FreeBSD/scanf.3.patch b/stdio/FreeBSD/scanf.3.patch index ec916bb..e8501fd 100644 --- a/stdio/FreeBSD/scanf.3.patch +++ b/stdio/FreeBSD/scanf.3.patch @@ -1,6 +1,6 @@ ---- scanf.3.orig 2008-07-30 01:54:48.000000000 -0700 -+++ scanf.3 2008-07-30 02:06:07.000000000 -0700 -@@ -40,35 +40,55 @@ +--- scanf.3.bsdnew 2009-11-11 13:33:15.000000000 -0800 ++++ scanf.3 2009-11-11 13:33:15.000000000 -0800 +@@ -36,35 +36,55 @@ .Dt SCANF 3 .Os .Sh NAME @@ -66,7 +66,7 @@ as described below. This format may contain .Em conversion specifiers ; -@@ -87,7 +107,8 @@ +@@ -83,7 +103,8 @@ reads input from the stream pointer and .Fn sscanf reads its input from the character string pointed to by @@ -76,7 +76,7 @@ The .Fn vfscanf function -@@ -108,7 +129,8 @@ +@@ -104,7 +125,8 @@ the .Fn vprintf and .Fn vsprintf @@ -86,7 +86,7 @@ Each successive .Em pointer argument must correspond properly with -@@ -132,10 +154,16 @@ +@@ -128,10 +150,16 @@ Scanning stops when an input character does not match such a format character. Scanning also stops when an input conversion cannot be made (see below). @@ -104,7 +104,7 @@ there may be a number of .Em flag characters, as follows: -@@ -415,7 +443,8 @@ +@@ -411,7 +439,8 @@ Matches a pointer value (as printed by in .Xr printf 3 ) ; the next pointer must be a pointer to @@ -114,7 +114,7 @@ .It Cm n Nothing is expected; instead, the number of characters consumed thus far from the input -@@ -440,13 +469,10 @@ +@@ -436,13 +465,10 @@ of causes an immediate return of .Dv EOF . .Sh RETURN VALUES @@ -132,7 +132,7 @@ no conversions were assigned; typically this is due to an invalid input character, such as an alphabetic character for a -@@ -463,6 +489,7 @@ +@@ -459,6 +485,7 @@ the number of conversions which were suc .Xr getc 3 , .Xr mbrtowc 3 , .Xr printf 3 , @@ -140,7 +140,7 @@ .Xr strtod 3 , .Xr strtol 3 , .Xr strtoul 3 , -@@ -473,7 +500,7 @@ +@@ -469,7 +496,7 @@ The functions .Fn scanf , .Fn sscanf , .Fn vfscanf , diff --git a/stdio/FreeBSD/scanf.c b/stdio/FreeBSD/scanf.c index b4fb1a3..7941499 100644 --- a/stdio/FreeBSD/scanf.c +++ b/stdio/FreeBSD/scanf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)scanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/scanf.c,v 1.12 2003/01/03 23:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/scanf.c,v 1.13 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/scanf.c.patch b/stdio/FreeBSD/scanf.c.patch index 729fc57..1462320 100644 --- a/stdio/FreeBSD/scanf.c.patch +++ b/stdio/FreeBSD/scanf.c.patch @@ -1,15 +1,15 @@ ---- scanf.c.orig 2003-05-20 15:22:43.000000000 -0700 -+++ scanf.c 2005-02-23 16:37:59.000000000 -0800 -@@ -40,6 +40,8 @@ +--- scanf.c.bsdnew 2009-11-11 13:33:15.000000000 -0800 ++++ scanf.c 2009-11-11 13:33:15.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)scanf.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/scanf.c,v 1.12 2003/01/03 23:27:27 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/scanf.c,v 1.13 2007/01/09 00:28:07 imp Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include #include -@@ -55,7 +57,22 @@ +@@ -51,7 +53,22 @@ scanf(char const * __restrict fmt, ...) va_start(ap, fmt); FLOCKFILE(stdin); diff --git a/stdio/FreeBSD/setbuf.3 b/stdio/FreeBSD/setbuf.3 index 6020d4b..8f4ef0a 100644 --- a/stdio/FreeBSD/setbuf.3 +++ b/stdio/FreeBSD/setbuf.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setbuf.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/setbuf.3,v 1.15 2004/08/24 21:48:21 alfred Exp $ +.\" $FreeBSD: src/lib/libc/stdio/setbuf.3,v 1.17 2007/01/09 00:28:07 imp Exp $ .\" .Dd June 4, 1993 .Dt SETBUF 3 @@ -117,7 +113,9 @@ bytes long; this buffer will be used instead of the current buffer. If .Fa buf -is not NULL, it is the caller's responsibility to +is not +.Dv NULL , +it is the caller's responsibility to .Xr free 3 this buffer after closing the stream. (If the diff --git a/stdio/FreeBSD/setbuf.3.patch b/stdio/FreeBSD/setbuf.3.patch index 64744e1..4ba00dd 100644 --- a/stdio/FreeBSD/setbuf.3.patch +++ b/stdio/FreeBSD/setbuf.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdio/FreeBSD/setbuf.3 2004-11-25 11:38:35.000000000 -0800 -+++ _SB/Libc/stdio/FreeBSD/setbuf.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -50,21 +50,37 @@ +--- setbuf.3.bsdnew 2009-11-11 13:33:15.000000000 -0800 ++++ setbuf.3 2009-11-11 13:33:15.000000000 -0800 +@@ -46,21 +46,37 @@ .Sh SYNOPSIS .In stdio.h .Ft void @@ -47,7 +47,7 @@ (typically .Dv stdin ) . The function -@@ -73,17 +89,16 @@ +@@ -69,17 +85,16 @@ may be used to force the block out early (See .Xr fclose 3 . ) .Pp @@ -68,7 +68,7 @@ The standard error stream .Dv stderr is always unbuffered. -@@ -93,7 +108,7 @@ +@@ -89,7 +104,7 @@ The function may be used to alter the buffering behavior of a stream. The diff --git a/stdio/FreeBSD/setbuf.c b/stdio/FreeBSD/setbuf.c index 5eb6fb1..933afb7 100644 --- a/stdio/FreeBSD/setbuf.c +++ b/stdio/FreeBSD/setbuf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)setbuf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/setbuf.c,v 1.4 2002/09/06 11:23:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/setbuf.c,v 1.5 2007/01/09 00:28:07 imp Exp $"); #include #include "local.h" diff --git a/stdio/FreeBSD/setbuffer.c b/stdio/FreeBSD/setbuffer.c index 6ec4376..64e5932 100644 --- a/stdio/FreeBSD/setbuffer.c +++ b/stdio/FreeBSD/setbuffer.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)setbuffer.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/setbuffer.c,v 1.7 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/setbuffer.c,v 1.8 2007/01/09 00:28:07 imp Exp $"); #include diff --git a/stdio/FreeBSD/setvbuf.c b/stdio/FreeBSD/setvbuf.c index 166d5b1..bedaa37 100644 --- a/stdio/FreeBSD/setvbuf.c +++ b/stdio/FreeBSD/setvbuf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)setvbuf.c 8.2 (Berkeley) 11/16/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/setvbuf.c,v 1.13 2002/09/06 11:23:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/setvbuf.c,v 1.14 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/snprintf.c b/stdio/FreeBSD/snprintf.c index b381852..61d9c8a 100644 --- a/stdio/FreeBSD/snprintf.c +++ b/stdio/FreeBSD/snprintf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/snprintf.c,v 1.20 2002/09/06 11:23:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/snprintf.c,v 1.22 2008/04/17 22:17:54 jhb Exp $"); #include #include @@ -53,7 +49,6 @@ snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...) int ret; va_list ap; FILE f; - struct __sFILEX ext; on = n; if (n != 0) @@ -65,8 +60,8 @@ snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...) f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); ret = __vfprintf(&f, fmt, ap); if (on > 0) *f._p = '\0'; diff --git a/stdio/FreeBSD/snprintf.c.patch b/stdio/FreeBSD/snprintf.c.patch index 506989d..fb74cf8 100644 --- a/stdio/FreeBSD/snprintf.c.patch +++ b/stdio/FreeBSD/snprintf.c.patch @@ -1,22 +1,39 @@ ---- snprintf.c.orig 2003-05-20 15:22:43.000000000 -0700 -+++ snprintf.c 2005-02-23 16:39:33.000000000 -0800 -@@ -40,6 +40,8 @@ +--- snprintf.c.orig 2009-11-30 16:15:30.000000000 -0800 ++++ snprintf.c 2009-12-02 16:48:44.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)snprintf.c 8 #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/snprintf.c,v 1.20 2002/09/06 11:23:55 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/snprintf.c,v 1.22 2008/04/17 22:17:54 jhb Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -67,7 +69,37 @@ - f._bf._size = f._w = n; - f._extra = &ext; - INITEXTRA(&f); +@@ -45,26 +47,24 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/s + int + snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...) + { +- size_t on; + int ret; + va_list ap; +- FILE f; + +- on = n; +- if (n != 0) +- n--; +- if (n > INT_MAX) +- n = INT_MAX; + va_start(ap, fmt); +- f._file = -1; +- f._flags = __SWR | __SSTR; +- f._bf._base = f._p = (unsigned char *)str; +- f._bf._size = f._w = n; +- f._orientation = 0; +- memset(&f._mbstate, 0, sizeof(mbstate_t)); - ret = __vfprintf(&f, fmt, ap); -+ ret = __vfprintf(&f, __current_locale(), fmt, ap); -+ if (on > 0) -+ *f._p = '\0'; +- if (on > 0) +- *f._p = '\0'; ++ ret = vsnprintf_l(str, n, __current_locale(), fmt, ap); + va_end(ap); + return (ret); +} @@ -25,26 +42,11 @@ +snprintf_l(char * __restrict str, size_t n, locale_t loc, + char const * __restrict fmt, ...) +{ -+ size_t on; + int ret; + va_list ap; -+ FILE f; -+ struct __sFILEX ext; + -+ NORMALIZE_LOCALE(loc); -+ on = n; -+ if (n != 0) -+ n--; -+ if (n > INT_MAX) -+ n = INT_MAX; + va_start(ap, fmt); -+ f._file = -1; -+ f._flags = __SWR | __SSTR; -+ f._bf._base = f._p = (unsigned char *)str; -+ f._bf._size = f._w = n; -+ f._extra = &ext; -+ INITEXTRA(&f); -+ ret = __vfprintf(&f, loc, fmt, ap); - if (on > 0) - *f._p = '\0'; ++ ret = vsnprintf_l(str, n, loc, fmt, ap); va_end(ap); + return (ret); + } diff --git a/stdio/FreeBSD/sprintf.c b/stdio/FreeBSD/sprintf.c index 6b9ed99..005d300 100644 --- a/stdio/FreeBSD/sprintf.c +++ b/stdio/FreeBSD/sprintf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)sprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/sprintf.c,v 1.14 2002/09/06 11:23:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/sprintf.c,v 1.16 2008/04/17 22:17:54 jhb Exp $"); #include #include @@ -51,14 +47,13 @@ sprintf(char * __restrict str, char const * __restrict fmt, ...) int ret; va_list ap; FILE f; - struct __sFILEX ext; f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); va_start(ap, fmt); ret = __vfprintf(&f, fmt, ap); va_end(ap); diff --git a/stdio/FreeBSD/sprintf.c.patch b/stdio/FreeBSD/sprintf.c.patch index f3af689..b275aff 100644 --- a/stdio/FreeBSD/sprintf.c.patch +++ b/stdio/FreeBSD/sprintf.c.patch @@ -1,22 +1,30 @@ ---- sprintf.c.orig 2003-05-20 15:22:43.000000000 -0700 -+++ sprintf.c 2005-02-23 16:40:52.000000000 -0800 -@@ -40,6 +40,8 @@ +--- sprintf.c.orig 2009-11-30 16:15:30.000000000 -0800 ++++ sprintf.c 2009-12-02 16:49:29.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)sprintf.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/sprintf.c,v 1.14 2002/09/06 11:23:55 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/sprintf.c,v 1.16 2008/04/17 22:17:54 jhb Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -60,7 +62,29 @@ - f._extra = &ext; - INITEXTRA(&f); +@@ -46,17 +48,21 @@ sprintf(char * __restrict str, char cons + { + int ret; + va_list ap; +- FILE f; + +- f._file = -1; +- f._flags = __SWR | __SSTR; +- f._bf._base = f._p = (unsigned char *)str; +- f._bf._size = f._w = INT_MAX; +- f._orientation = 0; +- memset(&f._mbstate, 0, sizeof(mbstate_t)); va_start(ap, fmt); - ret = __vfprintf(&f, fmt, ap); -+ ret = __vfprintf(&f, __current_locale(), fmt, ap); ++ ret = vsprintf_l(str, __current_locale(), fmt, ap); + va_end(ap); -+ *f._p = 0; + return (ret); +} + @@ -25,18 +33,10 @@ +{ + int ret; + va_list ap; -+ FILE f; -+ struct __sFILEX ext; + -+ NORMALIZE_LOCALE(loc); -+ f._file = -1; -+ f._flags = __SWR | __SSTR; -+ f._bf._base = f._p = (unsigned char *)str; -+ f._bf._size = f._w = INT_MAX; -+ f._extra = &ext; -+ INITEXTRA(&f); + va_start(ap, fmt); -+ ret = __vfprintf(&f, loc, fmt, ap); ++ ret = vsprintf_l(str, loc, fmt, ap); va_end(ap); - *f._p = 0; +- *f._p = 0; return (ret); + } diff --git a/stdio/FreeBSD/sscanf.c b/stdio/FreeBSD/sscanf.c index b4850cd..1598562 100644 --- a/stdio/FreeBSD/sscanf.c +++ b/stdio/FreeBSD/sscanf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)sscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/sscanf.c,v 1.11 2002/10/12 16:13:41 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/sscanf.c,v 1.13 2008/04/17 22:17:54 jhb Exp $"); #include #include @@ -63,7 +59,6 @@ sscanf(const char * __restrict str, char const * __restrict fmt, ...) { int ret; va_list ap; - struct __sFILEX extra; FILE f; f._file = -1; @@ -73,8 +68,8 @@ sscanf(const char * __restrict str, char const * __restrict fmt, ...) f._read = eofread; f._ub._base = NULL; f._lb._base = NULL; - f._extra = &extra; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); va_start(ap, fmt); ret = __svfscanf(&f, fmt, ap); va_end(ap); diff --git a/stdio/FreeBSD/sscanf.c.patch b/stdio/FreeBSD/sscanf.c.patch index 23e636b..6ab773c 100644 --- a/stdio/FreeBSD/sscanf.c.patch +++ b/stdio/FreeBSD/sscanf.c.patch @@ -1,44 +1,57 @@ ---- sscanf.c.orig 2003-05-20 15:22:44.000000000 -0700 -+++ sscanf.c 2005-02-23 16:42:49.000000000 -0800 -@@ -40,6 +40,8 @@ +--- sscanf.c.orig 2009-11-30 16:15:30.000000000 -0800 ++++ sscanf.c 2009-12-02 16:50:00.000000000 -0800 +@@ -36,42 +36,33 @@ static char sccsid[] = "@(#)sscanf.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/sscanf.c,v 1.11 2002/10/12 16:13:41 mike Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/sscanf.c,v 1.13 2008/04/17 22:17:54 jhb Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -76,7 +78,31 @@ - f._extra = &extra; - INITEXTRA(&f); - va_start(ap, fmt); -- ret = __svfscanf(&f, fmt, ap); -+ ret = __svfscanf_l(&f, __current_locale(), fmt, ap); -+ va_end(ap); -+ return (ret); -+} -+ + #include "local.h" + +-static int eofread(void *, char *, int); +- +-/* ARGSUSED */ +-static int +-eofread(cookie, buf, len) +- void *cookie; +- char *buf; +- int len; +int -+sscanf_l(const char * __restrict str, locale_t loc, char const * __restrict fmt, ...) -+{ ++sscanf(const char * __restrict str, char const * __restrict fmt, ...) + { + int ret; + va_list ap; -+ struct __sFILEX extra; -+ FILE f; -+ -+ NORMALIZE_LOCALE(loc); -+ f._file = -1; -+ f._flags = __SRD; -+ f._bf._base = f._p = (unsigned char *)str; -+ f._bf._size = f._r = strlen(str); -+ f._read = eofread; -+ f._ub._base = NULL; -+ f._lb._base = NULL; -+ f._extra = &extra; -+ INITEXTRA(&f); + +- return (0); + va_start(ap, fmt); -+ ret = __svfscanf_l(&f, loc, fmt, ap); ++ ret = vsscanf_l(str, __current_locale(), fmt, ap); ++ va_end(ap); ++ return (ret); + } + + int +-sscanf(const char * __restrict str, char const * __restrict fmt, ...) ++sscanf_l(const char * __restrict str, locale_t loc, char const * __restrict fmt, ...) + { + int ret; + va_list ap; +- FILE f; + +- f._file = -1; +- f._flags = __SRD; +- f._bf._base = f._p = (unsigned char *)str; +- f._bf._size = f._r = strlen(str); +- f._read = eofread; +- f._ub._base = NULL; +- f._lb._base = NULL; +- f._orientation = 0; +- memset(&f._mbstate, 0, sizeof(mbstate_t)); + va_start(ap, fmt); +- ret = __svfscanf(&f, fmt, ap); ++ ret = vsscanf_l(str, loc, fmt, ap); va_end(ap); return (ret); } diff --git a/stdio/FreeBSD/stdio.3 b/stdio/FreeBSD/stdio.3 index 3a349da..71488a1 100644 --- a/stdio/FreeBSD/stdio.3 +++ b/stdio/FreeBSD/stdio.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)stdio.3 8.7 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/stdio/stdio.3,v 1.26 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/stdio.3,v 1.30 2009/03/04 03:38:51 das Exp $ .\" -.Dd January 10, 2003 +.Dd March 3, 2009 .Dt STDIO 3 .Os .Sh NAME @@ -237,10 +233,6 @@ definitions are explicitly removed. .Xr open 2 , .Xr read 2 , .Xr write 2 -.Sh BUGS -The standard buffered functions do not interact well with certain other -library and system functions, especially -.Xr vfork 2 . .Sh STANDARDS The .Nm @@ -251,6 +243,7 @@ library conforms to .It Sy "Function Description" .It "asprintf formatted output conversion" .It "clearerr check and reset stream status" +.It "dprintf formatted output conversion" .It "fclose close a stream" .It "fdopen stream open functions" .It "feof check and reset stream status" @@ -284,6 +277,8 @@ library conforms to .It "fwrite binary stream input/output" .It "getc get next character or word from input stream" .It "getchar get next character or word from input stream" +.It "getdelim get a line from a stream" +.It "getline get a line from a stream" .It "gets get a line from a stream" .It "getw get next character or word from input stream" .It "getwc get next wide character from input stream" @@ -319,6 +314,7 @@ library conforms to .It "ungetc un-get character from input stream" .It "ungetwc un-get wide character from input stream" .It "vasprintf formatted output conversion" +.It "vdprintf formatted output conversion" .It "vfprintf formatted output conversion" .It "vfscanf input format conversion" .It "vfwprintf formatted wide character output conversion" @@ -331,3 +327,7 @@ library conforms to .It "vwprintf formatted wide character output conversion" .It "wprintf formatted wide character output conversion" .El +.Sh BUGS +The standard buffered functions do not interact well with certain other +library and system functions, especially +.Xr vfork 2 . diff --git a/stdio/FreeBSD/stdio.3.patch b/stdio/FreeBSD/stdio.3.patch index 7ed9c8e..06eaaad 100644 --- a/stdio/FreeBSD/stdio.3.patch +++ b/stdio/FreeBSD/stdio.3.patch @@ -1,6 +1,6 @@ ---- stdio.3 2004-11-25 11:38:35.000000000 -0800 -+++ stdio.3.edit 2006-09-06 16:18:21.000000000 -0700 -@@ -45,6 +45,20 @@ +--- stdio.3.bsdnew 2009-11-11 13:33:16.000000000 -0800 ++++ stdio.3 2009-11-11 15:14:22.000000000 -0800 +@@ -41,6 +41,20 @@ .Vt FILE *stdin ; .Vt FILE *stdout ; .Vt FILE *stderr ; @@ -21,7 +21,7 @@ .Sh DESCRIPTION The standard .Tn I/O -@@ -232,11 +246,21 @@ +@@ -228,11 +242,21 @@ and .Dv putchar_unlocked exist and will be used if the macro definitions are explicitly removed. @@ -41,27 +41,29 @@ -.Xr write 2 +.Xr write 2 , +.Xr compat 5 - .Sh BUGS - The standard buffered functions do not interact well with certain other - library and system functions, especially -@@ -250,7 +274,9 @@ + .Sh STANDARDS + The + .Nm +@@ -242,8 +266,9 @@ library conforms to .Bl -column "Description" .It Sy "Function Description" .It "asprintf formatted output conversion" +.It "" .It "clearerr check and reset stream status" +-.It "dprintf formatted output conversion" +.It "" .It "fclose close a stream" .It "fdopen stream open functions" .It "feof check and reset stream status" -@@ -282,15 +308,18 @@ +@@ -275,6 +300,7 @@ library conforms to .It "fwopen open a stream" .It "fwprintf formatted wide character output conversion" .It "fwrite binary stream input/output" +.It "" .It "getc get next character or word from input stream" .It "getchar get next character or word from input stream" - .It "gets get a line from a stream" + .It "getdelim get a line from a stream" +@@ -283,9 +309,11 @@ library conforms to .It "getw get next character or word from input stream" .It "getwc get next wide character from input stream" .It "getwchar get next wide character from input stream" @@ -73,7 +75,7 @@ .It "perror system error messages" .It "printf formatted output conversion" .It "putc output a character or word to a stream" -@@ -299,8 +328,10 @@ +@@ -294,8 +322,10 @@ library conforms to .It "putw output a character or word to a stream" .It "putwc output a wide character to a stream" .It "putwchar output a wide character to a stream" @@ -84,7 +86,7 @@ .It "scanf input format conversion" .It "setbuf stream buffering operations" .It "setbuffer stream buffering operations" -@@ -313,11 +344,14 @@ +@@ -308,13 +338,15 @@ library conforms to .It "swprintf formatted wide character output conversion" .It "sys_errlist system error messages" .It "sys_nerr system error messages" @@ -97,12 +99,15 @@ .It "ungetwc un-get wide character from input stream" +.It "" .It "vasprintf formatted output conversion" +-.It "vdprintf formatted output conversion" .It "vfprintf formatted output conversion" .It "vfscanf input format conversion" -@@ -329,5 +363,6 @@ + .It "vfwprintf formatted wide character output conversion" +@@ -325,6 +357,7 @@ library conforms to .It "vsscanf input format conversion" .It "vswprintf formatted wide character output conversion" .It "vwprintf formatted wide character output conversion" +.It "" .It "wprintf formatted wide character output conversion" .El + .Sh BUGS diff --git a/stdio/FreeBSD/stdio.c b/stdio/FreeBSD/stdio.c index 233427c..70f455d 100644 --- a/stdio/FreeBSD/stdio.c +++ b/stdio/FreeBSD/stdio.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)stdio.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/stdio.c,v 1.24 2003/01/07 06:17:13 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/stdio.c,v 1.28 2008/05/05 16:14:02 jhb Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/tempnam.c b/stdio/FreeBSD/tempnam.c index d4dbaa3..72a5e60 100644 --- a/stdio/FreeBSD/tempnam.c +++ b/stdio/FreeBSD/tempnam.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)tempnam.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/tempnam.c,v 1.10 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/tempnam.c,v 1.11 2007/01/09 00:28:07 imp Exp $"); #include #include diff --git a/stdio/FreeBSD/tempnam.c.patch b/stdio/FreeBSD/tempnam.c.patch index 5878749..7e1c8be 100644 --- a/stdio/FreeBSD/tempnam.c.patch +++ b/stdio/FreeBSD/tempnam.c.patch @@ -1,6 +1,6 @@ ---- tempnam.c.orig 2008-11-12 17:08:45.000000000 -0800 -+++ tempnam.c 2008-11-12 17:41:23.000000000 -0800 -@@ -57,35 +57,68 @@ tempnam(dir, pfx) +--- tempnam.c.orig 2010-10-25 19:45:24.000000000 -0700 ++++ tempnam.c 2010-10-25 22:01:51.000000000 -0700 +@@ -53,35 +53,60 @@ tempnam(dir, pfx) int sverrno; char *f, *name; @@ -59,14 +59,6 @@ + } +#endif /* __DARWIN_UNIX03 */ f = _PATH_TMP; -+#if __DARWIN_UNIX03 -+ if (access(f, W_OK) < 0) { -+ f = "./"; /* directory inaccessible */ -+ if (access(f, W_OK) < 0) { -+ return(NULL); -+ } -+ } -+#endif /* __DARWIN_UNIX03 */ (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); - if ((f = _mktemp(name))) + if ((f = _mktemp(name))) { diff --git a/stdio/FreeBSD/tmpfile.c b/stdio/FreeBSD/tmpfile.c index cf5b70a..3f1679f 100644 --- a/stdio/FreeBSD/tmpfile.c +++ b/stdio/FreeBSD/tmpfile.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)tmpfile.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/tmpfile.c,v 1.9 2003/02/06 01:08:19 mtm Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/tmpfile.c,v 1.10 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/tmpnam.3 b/stdio/FreeBSD/tmpnam.3 index 78a78d3..3392af2 100644 --- a/stdio/FreeBSD/tmpnam.3 +++ b/stdio/FreeBSD/tmpnam.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)tmpnam.3 8.2 (Berkeley) 11/17/93 -.\" $FreeBSD: src/lib/libc/stdio/tmpnam.3,v 1.16 2004/06/21 19:38:25 mpp Exp $ +.\" $FreeBSD: src/lib/libc/stdio/tmpnam.3,v 1.20 2007/03/16 21:46:24 maxim Exp $ .\" -.Dd November 17, 1993 +.Dd March 18, 2007 .Dt TMPFILE 3 .Os .Sh NAME @@ -156,6 +152,43 @@ return a pointer to a file name on success, and a .Dv NULL pointer on error. +.Sh ENVIRONMENT +.Bl -tag -width Ds +.It Ev TMPDIR +.Pf [ Fn tempnam +only] +If set, +the directory in which the temporary file is stored. +.Ev TMPDIR +is ignored for processes +for which +.Xr issetugid 2 +is true. +.El +.Sh COMPATIBILITY +These interfaces are provided from System V and +.Tn ANSI +compatibility only. +.Pp +Most historic implementations of these functions provide +only a limited number of possible temporary file names +(usually 26) +before file names will start being recycled. +System V implementations of these functions +(and of +.Xr mktemp 3 ) +use the +.Xr access 2 +system call to determine whether or not the temporary file +may be created. +This has obvious ramifications for setuid or setgid programs, +complicating the portable use of these interfaces in such programs. +.Pp +The +.Fn tmpfile +interface should not be used in software expected to be used on other systems +if there is any possibility that the user does not wish the temporary file to +be publicly readable and writable. .Sh ERRORS The .Fn tmpfile @@ -202,38 +235,9 @@ It is strongly suggested that be used in place of these functions. (See the FSA.) -.Sh COMPATIBILITY -These interfaces are provided from System V and -.Tn ANSI -compatibility only. -.Pp -Most historic implementations of these functions provide -only a limited number of possible temporary file names -(usually 26) -before file names will start being recycled. -System V implementations of these functions -(and of -.Xr mktemp 3 ) -use the -.Xr access 2 -system call to determine whether or not the temporary file -may be created. -This has obvious ramifications for setuid or setgid programs, -complicating the portable use of these interfaces in such programs. -.Pp -The -.Fn tmpfile -interface should not be used in software expected to be used on other systems -if there is any possibility that the user does not wish the temporary file to -be publicly readable and writable. .Sh SEE ALSO .Xr mkstemp 3 , .Xr mktemp 3 -.Rs -.%T "The FreeBSD Security Architecture" -.Re -(See -.Pa "/usr/share/doc/{to be determined}" . ) .Sh STANDARDS The .Fn tmpfile diff --git a/stdio/FreeBSD/tmpnam.3.patch b/stdio/FreeBSD/tmpnam.3.patch index 2fa5688..24478e1 100644 --- a/stdio/FreeBSD/tmpnam.3.patch +++ b/stdio/FreeBSD/tmpnam.3.patch @@ -1,21 +1,21 @@ ---- tmpnam.3.orig 2008-11-13 16:39:10.000000000 -0800 -+++ tmpnam.3 2008-11-13 16:45:15.000000000 -0800 -@@ -36,7 +36,7 @@ +--- tmpnam.3.bsdnew 2009-11-11 13:33:17.000000000 -0800 ++++ tmpnam.3 2009-11-11 15:17:16.000000000 -0800 +@@ -32,7 +32,7 @@ .\" @(#)tmpnam.3 8.2 (Berkeley) 11/17/93 - .\" $FreeBSD: src/lib/libc/stdio/tmpnam.3,v 1.16 2004/06/21 19:38:25 mpp Exp $ + .\" $FreeBSD: src/lib/libc/stdio/tmpnam.3,v 1.20 2007/03/16 21:46:24 maxim Exp $ .\" --.Dd November 17, 1993 +-.Dd March 18, 2007 +.Dd November 12, 2008 .Dt TMPFILE 3 .Os .Sh NAME -@@ -49,11 +49,18 @@ +@@ -45,11 +45,18 @@ .Sh SYNOPSIS .In stdio.h .Ft FILE * -.Fn tmpfile void +.Fo tmpfile -+.Fa void ++.Fa "void" +.Fc .Ft char * -.Fn tmpnam "char *str" @@ -31,7 +31,7 @@ .Sh DESCRIPTION The .Fn tmpfile -@@ -67,12 +74,13 @@ +@@ -63,12 +70,13 @@ returns, causing the file to be automati reference to it is closed. The file is opened with the access value .Ql w+ . @@ -49,7 +49,7 @@ .Pa /tmp . .Pp The -@@ -87,7 +95,7 @@ +@@ -83,7 +91,7 @@ past. is defined in the include file .In stdio.h . If the argument @@ -58,7 +58,7 @@ is .Pf non- Dv NULL , the file name is copied to the buffer it references. -@@ -97,7 +105,7 @@ +@@ -93,7 +101,7 @@ In either case, returns a pointer to the file name. .Pp The buffer referenced by @@ -67,7 +67,7 @@ is expected to be at least .Dv L_tmpnam bytes in length. -@@ -113,21 +121,23 @@ +@@ -109,21 +117,23 @@ is similar to but provides the ability to specify the directory which will contain the temporary file and the file name prefix. .Pp @@ -97,10 +97,10 @@ if .Pf non- Dv NULL , is used to specify a file name prefix, which will be the -@@ -226,14 +236,15 @@ - interface should not be used in software expected to be used on other systems - if there is any possibility that the user does not wish the temporary file to - be publicly readable and writable. +@@ -235,6 +245,12 @@ It is strongly suggested that + be used in place of these functions. + (See + the FSA.) +.Sh LEGACY DESCRIPTION +In legacy mode, the order directories are tried by the +.Fn tempnam @@ -110,11 +110,3 @@ .Sh SEE ALSO .Xr mkstemp 3 , .Xr mktemp 3 --.Rs --.%T "The FreeBSD Security Architecture" --.Re --(See --.Pa "/usr/share/doc/{to be determined}" . ) - .Sh STANDARDS - The - .Fn tmpfile diff --git a/stdio/FreeBSD/tmpnam.c b/stdio/FreeBSD/tmpnam.c index 38fcdd6..f3ab680 100644 --- a/stdio/FreeBSD/tmpnam.c +++ b/stdio/FreeBSD/tmpnam.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)tmpnam.c 8.3 (Berkeley) 3/28/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/tmpnam.c,v 1.5 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/tmpnam.c,v 1.6 2007/01/09 00:28:07 imp Exp $"); #include diff --git a/stdio/FreeBSD/tmpnam.c.patch b/stdio/FreeBSD/tmpnam.c.patch new file mode 100644 index 0000000..5ff86df --- /dev/null +++ b/stdio/FreeBSD/tmpnam.c.patch @@ -0,0 +1,41 @@ +--- tmpnam.c.orig 2010-07-06 16:02:20.000000000 -0700 ++++ tmpnam.c 2010-07-06 16:32:52.000000000 -0700 +@@ -40,21 +40,35 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/t + + #include + #include ++#include ++#include + + __warn_references(tmpnam, + "warning: tmpnam() possibly used unsafely; consider using mkstemp()"); + + extern char *_mktemp(char *); + ++static char *tmpnam_buf = NULL; ++static pthread_once_t tmpnam_buf_control = PTHREAD_ONCE_INIT; ++ ++static void tmpnam_buf_allocate(void) ++{ ++ tmpnam_buf = malloc(L_tmpnam); ++} ++ + char * + tmpnam(s) + char *s; + { + static u_long tmpcount; +- static char buf[L_tmpnam]; + +- if (s == NULL) +- s = buf; ++ if (s == NULL) { ++ if (pthread_once(&tmpnam_buf_control, tmpnam_buf_allocate) ++ || !tmpnam_buf) { ++ return NULL; ++ } ++ s = tmpnam_buf; ++ } + (void)snprintf(s, L_tmpnam, "%stmp.%lu.XXXXXX", P_tmpdir, tmpcount); + ++tmpcount; + return (_mktemp(s)); diff --git a/stdio/FreeBSD/ungetc.3 b/stdio/FreeBSD/ungetc.3 index 0c0bf83..ee280eb 100644 --- a/stdio/FreeBSD/ungetc.3 +++ b/stdio/FreeBSD/ungetc.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ungetc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/ungetc.3,v 1.13 2002/10/10 04:12:40 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/ungetc.3,v 1.14 2007/01/09 00:28:07 imp Exp $ .\" .Dd June 4, 1993 .Dt UNGETC 3 diff --git a/stdio/FreeBSD/ungetc.3.patch b/stdio/FreeBSD/ungetc.3.patch index cb470b3..bc9668d 100644 --- a/stdio/FreeBSD/ungetc.3.patch +++ b/stdio/FreeBSD/ungetc.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdio/FreeBSD/ungetc.3 2003-05-20 15:22:44.000000000 -0700 -+++ _SB/Libc/stdio/FreeBSD/ungetc.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -47,7 +47,10 @@ +--- ungetc.3.bsdnew 2009-11-11 13:33:17.000000000 -0800 ++++ ungetc.3 2009-11-11 13:33:18.000000000 -0800 +@@ -43,7 +43,10 @@ .Sh SYNOPSIS .In stdio.h .Ft int @@ -12,7 +12,7 @@ .Sh DESCRIPTION The .Fn ungetc -@@ -56,20 +59,20 @@ +@@ -52,20 +55,20 @@ function pushes the character (converted to an unsigned char) back onto the input stream pointed to by .Fa stream . diff --git a/stdio/FreeBSD/ungetc.c b/stdio/FreeBSD/ungetc.c index 2217259..fc8ddb1 100644 --- a/stdio/FreeBSD/ungetc.c +++ b/stdio/FreeBSD/ungetc.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/ungetc.c,v 1.16 2004/03/10 12:41:11 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/ungetc.c,v 1.18 2008/04/17 22:17:54 jhb Exp $"); #include "namespace.h" #include @@ -162,7 +158,7 @@ __ungetc(int c, FILE *fp) * Initially, we will use the `reserve' buffer. */ fp->_ur = fp->_r; - fp->_extra->_up = fp->_p; + fp->_up = fp->_p; fp->_ub._base = fp->_ubuf; fp->_ub._size = sizeof(fp->_ubuf); fp->_ubuf[sizeof(fp->_ubuf) - 1] = c; diff --git a/stdio/FreeBSD/ungetwc.3 b/stdio/FreeBSD/ungetwc.3 index 0ffe7e8..5618253 100644 --- a/stdio/FreeBSD/ungetwc.3 +++ b/stdio/FreeBSD/ungetwc.3 @@ -15,10 +15,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -36,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ungetc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/ungetwc.3,v 1.5 2004/03/16 13:30:11 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/ungetwc.3,v 1.6 2007/01/09 00:28:07 imp Exp $ .\" .Dd March 3, 2004 .Dt UNGETWC 3 diff --git a/stdio/FreeBSD/ungetwc.3.patch b/stdio/FreeBSD/ungetwc.3.patch index 0cc1a09..8bf0a85 100644 --- a/stdio/FreeBSD/ungetwc.3.patch +++ b/stdio/FreeBSD/ungetwc.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdio/FreeBSD/ungetwc.3 2004-11-25 11:38:35.000000000 -0800 -+++ _SB/Libc/stdio/FreeBSD/ungetwc.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -42,7 +42,8 @@ +--- ungetwc.3.bsdnew 2009-11-11 13:33:18.000000000 -0800 ++++ ungetwc.3 2009-11-11 13:33:18.000000000 -0800 +@@ -38,7 +38,8 @@ .Dt UNGETWC 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nd un-get wide character from input stream .Sh LIBRARY .Lb libc -@@ -50,7 +51,19 @@ +@@ -46,7 +47,19 @@ .In stdio.h .In wchar.h .Ft wint_t @@ -31,7 +31,7 @@ .Sh DESCRIPTION The .Fn ungetwc -@@ -60,22 +73,31 @@ +@@ -56,22 +69,31 @@ function pushes the wide character .Vt wchar_t ) back onto the input stream pointed to by .Fa stream . @@ -71,7 +71,7 @@ .Sh RETURN VALUES The .Fn ungetwc -@@ -91,7 +113,8 @@ +@@ -87,7 +109,8 @@ character equals the operation will fail and the stream will remain unchanged. .Sh SEE ALSO .Xr fseek 3 , diff --git a/stdio/FreeBSD/ungetwc.c b/stdio/FreeBSD/ungetwc.c index b90671a..47e84ae 100644 --- a/stdio/FreeBSD/ungetwc.c +++ b/stdio/FreeBSD/ungetwc.c @@ -25,10 +25,11 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/ungetwc.c,v 1.9 2004/07/20 08:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/ungetwc.c,v 1.11 2008/04/17 22:17:54 jhb Exp $"); #include "namespace.h" #include +#include #include #include #include @@ -48,7 +49,7 @@ __ungetwc(wint_t wc, FILE *fp) if (wc == WEOF) return (WEOF); - if ((len = __wcrtomb(buf, wc, &fp->_extra->mbstate)) == (size_t)-1) { + if ((len = __wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); } diff --git a/stdio/FreeBSD/ungetwc.c.patch b/stdio/FreeBSD/ungetwc.c.patch index 4b01c93..e9e1c3d 100644 --- a/stdio/FreeBSD/ungetwc.c.patch +++ b/stdio/FreeBSD/ungetwc.c.patch @@ -1,15 +1,15 @@ ---- ungetwc.c.orig 2004-11-25 11:38:35.000000000 -0800 -+++ ungetwc.c 2005-02-23 17:38:14.000000000 -0800 +--- ungetwc.c.bsdnew 2009-11-11 13:33:18.000000000 -0800 ++++ ungetwc.c 2009-11-11 16:30:36.000000000 -0800 @@ -27,6 +27,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/ungetwc.c,v 1.9 2004/07/20 08:27:27 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/ungetwc.c,v 1.11 2008/04/17 22:17:54 jhb Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include - #include -@@ -41,14 +43,14 @@ + #include +@@ -42,14 +44,14 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/u * Non-MT-safe version. */ wint_t @@ -21,12 +21,12 @@ if (wc == WEOF) return (WEOF); -- if ((len = __wcrtomb(buf, wc, &fp->_extra->mbstate)) == (size_t)-1) { -+ if ((len = loc->__lc_ctype->__wcrtomb(buf, wc, &fp->_extra->mbstate, loc)) == (size_t)-1) { +- if ((len = __wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) { ++ if ((len = loc->__lc_ctype->__wcrtomb(buf, wc, &fp->_mbstate, loc)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); } -@@ -69,7 +71,21 @@ +@@ -70,7 +72,21 @@ ungetwc(wint_t wc, FILE *fp) FLOCKFILE(fp); ORIENT(fp, 1); diff --git a/stdio/FreeBSD/vasprintf.c b/stdio/FreeBSD/vasprintf.c index 197c427..fd5bfa2 100644 --- a/stdio/FreeBSD/vasprintf.c +++ b/stdio/FreeBSD/vasprintf.c @@ -28,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.18 2002/09/26 13:11:24 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.19 2008/04/17 22:17:54 jhb Exp $"); #include #include @@ -43,7 +43,6 @@ vasprintf(str, fmt, ap) { int ret; FILE f; - struct __sFILEX ext; f._file = -1; f._flags = __SWR | __SSTR | __SALC; @@ -54,8 +53,8 @@ vasprintf(str, fmt, ap) return (-1); } f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); ret = __vfprintf(&f, fmt, ap); if (ret < 0) { free(f._bf._base); diff --git a/stdio/FreeBSD/vasprintf.c.patch b/stdio/FreeBSD/vasprintf.c.patch index 15549b6..e08af0e 100644 --- a/stdio/FreeBSD/vasprintf.c.patch +++ b/stdio/FreeBSD/vasprintf.c.patch @@ -1,55 +1,54 @@ ---- vasprintf.c.orig 2003-05-20 15:22:44.000000000 -0700 -+++ vasprintf.c 2005-02-23 18:55:18.000000000 -0800 -@@ -30,6 +30,8 @@ +--- vasprintf.c.orig 2009-11-30 16:15:30.000000000 -0800 ++++ vasprintf.c 2009-12-03 15:19:16.000000000 -0800 +@@ -30,20 +30,27 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.18 2002/09/26 13:11:24 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.19 2008/04/17 22:17:54 jhb Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -56,7 +58,42 @@ - f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); -- ret = __vfprintf(&f, fmt, ap); -+ ret = __vfprintf(&f, __current_locale(), fmt, ap); -+ if (ret < 0) { -+ free(f._bf._base); -+ *str = NULL; -+ errno = ENOMEM; -+ return (-1); -+ } -+ *f._p = '\0'; -+ *str = (char *)f._bf._base; -+ return (ret); -+} -+ -+int + #include "local.h" + + int +-vasprintf(str, fmt, ap) +vasprintf_l(str, loc, fmt, ap) -+ char **str; + char **str; + locale_t loc; -+ const char *fmt; -+ __va_list ap; -+{ -+ int ret; -+ FILE f; + const char *fmt; + __va_list ap; + { + int ret; + FILE f; +- + struct __sFILEX ext; -+ -+ NORMALIZE_LOCALE(loc); -+ f._file = -1; -+ f._flags = __SWR | __SSTR | __SALC; -+ f._bf._base = f._p = (unsigned char *)malloc(128); -+ if (f._bf._base == NULL) { -+ *str = NULL; -+ errno = ENOMEM; -+ return (-1); -+ } -+ f._bf._size = f._w = 127; /* Leave room for the NUL */ + f._extra = &ext; + INITEXTRA(&f); ++ ++ NORMALIZE_LOCALE(loc); + f._file = -1; + f._flags = __SWR | __SSTR | __SALC; + f._bf._base = f._p = (unsigned char *)malloc(128); +@@ -55,7 +62,7 @@ vasprintf(str, fmt, ap) + f._bf._size = f._w = 127; /* Leave room for the NUL */ + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); +- ret = __vfprintf(&f, fmt, ap); + ret = __vfprintf(&f, loc, fmt, ap); if (ret < 0) { free(f._bf._base); *str = NULL; +@@ -66,3 +73,12 @@ vasprintf(str, fmt, ap) + *str = (char *)f._bf._base; + return (ret); + } ++ ++int ++vasprintf(str, fmt, ap) ++ char **str; ++ const char *fmt; ++ __va_list ap; ++{ ++ return vasprintf_l(str, __current_locale(), fmt, ap); ++} diff --git a/stdio/FreeBSD/vdprintf.c b/stdio/FreeBSD/vdprintf.c new file mode 100644 index 0000000..cba376b --- /dev/null +++ b/stdio/FreeBSD/vdprintf.c @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/stdio/vdprintf.c,v 1.1 2009/03/04 03:38:51 das Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" + +#include "local.h" + +int +vdprintf(int fd, const char * __restrict fmt, va_list ap) +{ + FILE f; + unsigned char buf[BUFSIZ]; + int ret; + + if (fd > SHRT_MAX) { + errno = EMFILE; + return (EOF); + } + + f._p = buf; + f._w = sizeof(buf); + f._flags = __SWR; + f._file = fd; + f._cookie = &f; + f._write = __swrite; + f._bf._base = buf; + f._bf._size = sizeof(buf); + f._orientation = 0; + bzero(&f._mbstate, sizeof(f._mbstate)); + + if ((ret = __vfprintf(&f, fmt, ap)) < 0) + return (ret); + + return (__fflush(&f) ? EOF : ret); +} diff --git a/stdio/FreeBSD/vdprintf.c.patch b/stdio/FreeBSD/vdprintf.c.patch new file mode 100644 index 0000000..519239b --- /dev/null +++ b/stdio/FreeBSD/vdprintf.c.patch @@ -0,0 +1,44 @@ +--- vdprintf.c.orig 2009-12-15 17:43:09.000000000 -0800 ++++ vdprintf.c 2009-12-15 18:09:12.000000000 -0800 +@@ -27,6 +27,8 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/stdio/vdprintf.c,v 1.1 2009/03/04 03:38:51 das Exp $"); + ++#include "xlocale_private.h" ++ + #include "namespace.h" + #include + #include +@@ -37,11 +39,16 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v + #include "local.h" + + int +-vdprintf(int fd, const char * __restrict fmt, va_list ap) ++vdprintf_l(int fd, locale_t loc, const char * __restrict fmt, va_list ap) + { + FILE f; + unsigned char buf[BUFSIZ]; + int ret; ++ struct __sFILEX ext; ++ f._extra = &ext; ++ INITEXTRA(&f); ++ ++ NORMALIZE_LOCALE(loc); + + if (fd > SHRT_MAX) { + errno = EMFILE; +@@ -59,8 +66,13 @@ vdprintf(int fd, const char * __restrict + f._orientation = 0; + bzero(&f._mbstate, sizeof(f._mbstate)); + +- if ((ret = __vfprintf(&f, fmt, ap)) < 0) ++ if ((ret = __vfprintf(&f, loc, fmt, ap)) < 0) + return (ret); + + return (__fflush(&f) ? EOF : ret); + } ++ ++int ++vdprintf(int fd, const char * __restrict fmt, va_list ap) { ++ return vdprintf_l(fd, __current_locale(), fmt, ap); ++} diff --git a/stdio/FreeBSD/vfprintf.c b/stdio/FreeBSD/vfprintf.c index 1355b81..df992ce 100644 --- a/stdio/FreeBSD/vfprintf.c +++ b/stdio/FreeBSD/vfprintf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.90 2009/02/28 06:06:57 das Exp $"); /* * Actual printf innards. @@ -58,6 +54,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des #include #include #include +#include #include #include "un-namespace.h" @@ -65,56 +62,84 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des #include "libc_private.h" #include "local.h" #include "fvwrite.h" +#include "printflocal.h" -union arg { - int intarg; - u_int uintarg; - long longarg; - u_long ulongarg; - long long longlongarg; - unsigned long long ulonglongarg; - ptrdiff_t ptrdiffarg; - size_t sizearg; - intmax_t intmaxarg; - uintmax_t uintmaxarg; - void *pvoidarg; - char *pchararg; - signed char *pschararg; - short *pshortarg; - int *pintarg; - long *plongarg; - long long *plonglongarg; - ptrdiff_t *pptrdiffarg; - size_t *psizearg; - intmax_t *pintmaxarg; -#ifndef NO_FLOATING_POINT - double doublearg; - long double longdoublearg; -#endif - wint_t wintarg; - wchar_t *pwchararg; +static int __sprint(FILE *, struct __suio *); +static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0) + __noinline; +static char *__wcsconv(wchar_t *, int); + +#define CHAR char +#include "printfcommon.h" + +struct grouping_state { + char *thousands_sep; /* locale-specific thousands separator */ + int thousep_len; /* length of thousands_sep */ + const char *grouping; /* locale-specific numeric grouping rules */ + int lead; /* sig figs before decimal or group sep */ + int nseps; /* number of group separators with ' */ + int nrepeats; /* number of repeats of the last group */ }; /* - * Type ids for argument type table. + * Initialize the thousands' grouping state in preparation to print a + * number with ndigits digits. This routine returns the total number + * of bytes that will be needed. */ -enum typeid { - T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, - T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, - T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, - T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, - T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR -}; +static int +grouping_init(struct grouping_state *gs, int ndigits) +{ + struct lconv *locale; + + locale = localeconv(); + gs->grouping = locale->grouping; + gs->thousands_sep = locale->thousands_sep; + gs->thousep_len = strlen(gs->thousands_sep); + + gs->nseps = gs->nrepeats = 0; + gs->lead = ndigits; + while (*gs->grouping != CHAR_MAX) { + if (gs->lead <= *gs->grouping) + break; + gs->lead -= *gs->grouping; + if (*(gs->grouping+1)) { + gs->nseps++; + gs->grouping++; + } else + gs->nrepeats++; + } + return ((gs->nseps + gs->nrepeats) * gs->thousep_len); +} -static int __sprint(FILE *, struct __suio *); -static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0); -static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char, - const char *); -static char *__ultoa(u_long, char *, int, int, const char *, int, char, - const char *); -static char *__wcsconv(wchar_t *, int); -static void __find_arguments(const char *, va_list, union arg **); -static void __grow_type_table(int, enum typeid **, int *); +/* + * Print a number with thousands' separators. + */ +static int +grouping_print(struct grouping_state *gs, struct io_state *iop, + const CHAR *cp, const CHAR *ep) +{ + const CHAR *cp0 = cp; + + if (io_printandpad(iop, cp, ep, gs->lead, zeroes)) + return (-1); + cp += gs->lead; + while (gs->nseps > 0 || gs->nrepeats > 0) { + if (gs->nrepeats > 0) + gs->nrepeats--; + else { + gs->grouping--; + gs->nseps--; + } + if (io_print(iop, gs->thousands_sep, gs->thousep_len)) + return (-1); + if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes)) + return (-1); + cp += *gs->grouping; + } + if (cp > ep) + cp = ep; + return (cp - cp0); +} /* * Flush out all the vectors defined by the given uio, @@ -147,12 +172,17 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap) FILE fake; unsigned char buf[BUFSIZ]; + /* XXX This is probably not needed. */ + if (prepwrite(fp) != 0) + return (EOF); + /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; - fake._extra = fp->_extra; + fake._orientation = fp->_orientation; + fake._mbstate = fp->_mbstate; /* set up the buffer */ fake._bf._base = fake._p = buf; @@ -168,172 +198,11 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap) return (ret); } -/* - * Macros for converting digits to letters and vice versa - */ -#define to_digit(c) ((c) - '0') -#define is_digit(c) ((unsigned)to_digit(c) <= 9) -#define to_char(n) ((n) + '0') - -/* - * Convert an unsigned long to ASCII for printf purposes, returning - * a pointer to the first character of the string representation. - * Octal numbers can be forced to have a leading zero; hex numbers - * use the given digits. - */ -static char * -__ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs, - int needgrp, char thousep, const char *grp) -{ - char *cp = endp; - long sval; - int ndig; - - /* - * Handle the three cases separately, in the hope of getting - * better/faster code. - */ - switch (base) { - case 10: - if (val < 10) { /* many numbers are 1 digit */ - *--cp = to_char(val); - return (cp); - } - ndig = 0; - /* - * On many machines, unsigned arithmetic is harder than - * signed arithmetic, so we do at most one unsigned mod and - * divide; this is sufficient to reduce the range of - * the incoming value to where signed arithmetic works. - */ - if (val > LONG_MAX) { - *--cp = to_char(val % 10); - ndig++; - sval = val / 10; - } else - sval = val; - do { - *--cp = to_char(sval % 10); - ndig++; - /* - * If (*grp == CHAR_MAX) then no more grouping - * should be performed. - */ - if (needgrp && ndig == *grp && *grp != CHAR_MAX - && sval > 9) { - *--cp = thousep; - ndig = 0; - /* - * If (*(grp+1) == '\0') then we have to - * use *grp character (last grouping rule) - * for all next cases - */ - if (*(grp+1) != '\0') - grp++; - } - sval /= 10; - } while (sval != 0); - break; - - case 8: - do { - *--cp = to_char(val & 7); - val >>= 3; - } while (val); - if (octzero && *cp != '0') - *--cp = '0'; - break; - - case 16: - do { - *--cp = xdigs[val & 15]; - val >>= 4; - } while (val); - break; - - default: /* oops */ - abort(); - } - return (cp); -} - -/* Identical to __ultoa, but for intmax_t. */ -static char * -__ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs, - int needgrp, char thousep, const char *grp) -{ - char *cp = endp; - intmax_t sval; - int ndig; - - /* quick test for small values; __ultoa is typically much faster */ - /* (perhaps instead we should run until small, then call __ultoa?) */ - if (val <= ULONG_MAX) - return (__ultoa((u_long)val, endp, base, octzero, xdigs, - needgrp, thousep, grp)); - switch (base) { - case 10: - if (val < 10) { - *--cp = to_char(val % 10); - return (cp); - } - ndig = 0; - if (val > INTMAX_MAX) { - *--cp = to_char(val % 10); - ndig++; - sval = val / 10; - } else - sval = val; - do { - *--cp = to_char(sval % 10); - ndig++; - /* - * If (*grp == CHAR_MAX) then no more grouping - * should be performed. - */ - if (needgrp && *grp != CHAR_MAX && ndig == *grp - && sval > 9) { - *--cp = thousep; - ndig = 0; - /* - * If (*(grp+1) == '\0') then we have to - * use *grp character (last grouping rule) - * for all next cases - */ - if (*(grp+1) != '\0') - grp++; - } - sval /= 10; - } while (sval != 0); - break; - - case 8: - do { - *--cp = to_char(val & 7); - val >>= 3; - } while (val); - if (octzero && *cp != '0') - *--cp = '0'; - break; - - case 16: - do { - *--cp = xdigs[val & 15]; - val >>= 4; - } while (val); - break; - - default: - abort(); - } - return (cp); -} - /* * Convert a wide character string argument for the %ls format to a multibyte - * string representation. ``prec'' specifies the maximum number of bytes - * to output. If ``prec'' is greater than or equal to zero, we can't assume - * that the wide char. string ends in a null character. + * string representation. If not -1, prec specifies the maximum number of + * bytes to output, and also means that we can't assume that the wide char. + * string ends is null-terminated. */ static char * __wcsconv(wchar_t *wcsarg, int prec) @@ -342,53 +211,49 @@ __wcsconv(wchar_t *wcsarg, int prec) mbstate_t mbs; char buf[MB_LEN_MAX]; wchar_t *p; - char *convbuf, *mbp; + char *convbuf; size_t clen, nbytes; - /* - * Determine the number of bytes to output and allocate space for - * the output. - */ - if (prec >= 0) { - nbytes = 0; - p = wcsarg; - mbs = initial; - for (;;) { - clen = wcrtomb(buf, *p++, &mbs); - if (clen == 0 || clen == (size_t)-1 || - nbytes + clen > prec) - break; - nbytes += clen; - } - } else { + /* Allocate space for the maximum number of bytes we could output. */ + if (prec < 0) { p = wcsarg; mbs = initial; nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs); if (nbytes == (size_t)-1) return (NULL); + } else { + /* + * Optimisation: if the output precision is small enough, + * just allocate enough memory for the maximum instead of + * scanning the string. + */ + if (prec < 128) + nbytes = prec; + else { + nbytes = 0; + p = wcsarg; + mbs = initial; + for (;;) { + clen = wcrtomb(buf, *p++, &mbs); + if (clen == 0 || clen == (size_t)-1 || + nbytes + clen > prec) + break; + nbytes += clen; + } + } } if ((convbuf = malloc(nbytes + 1)) == NULL) return (NULL); - /* - * Fill the output buffer with the multibyte representations of as - * many wide characters as will fit. - */ - mbp = convbuf; + /* Fill the output buffer. */ p = wcsarg; mbs = initial; - while (mbp - convbuf < nbytes) { - clen = wcrtomb(mbp, *p++, &mbs); - if (clen == 0 || clen == (size_t)-1) - break; - mbp += clen; - } - if (clen == (size_t)-1) { + if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p, + nbytes, &mbs)) == (size_t)-1) { free(convbuf); return (NULL); } - *mbp = '\0'; - + convbuf[nbytes] = '\0'; return (convbuf); } @@ -402,55 +267,26 @@ vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) int ret; FLOCKFILE(fp); - ret = __vfprintf(fp, fmt0, ap); + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) + ret = __sbprintf(fp, fmt0, ap); + else + ret = __vfprintf(fp, fmt0, ap); FUNLOCKFILE(fp); return (ret); } -#ifndef NO_FLOATING_POINT - -#define dtoa __dtoa -#define freedtoa __freedtoa - -#include -#include -#include "floatio.h" -#include "gdtoa.h" - -#define DEFPREC 6 - -static int exponent(char *, int, int); - -#endif /* !NO_FLOATING_POINT */ - /* * The size of the buffer we use as scratch space for integer - * conversions, among other things. Technically, we would need the - * most space for base 10 conversions with thousands' grouping - * characters between each pair of digits. 100 bytes is a - * conservative overestimate even for a 128-bit uintmax_t. + * conversions, among other things. We need enough space to + * write a uintmax_t in octal (plus one byte). */ -#define BUF 100 - -#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ - -/* - * Flags used during conversion. - */ -#define ALT 0x001 /* alternate form */ -#define LADJUST 0x004 /* left adjustment */ -#define LONGDBL 0x008 /* long double */ -#define LONGINT 0x010 /* long integer */ -#define LLONGINT 0x020 /* long long integer */ -#define SHORTINT 0x040 /* short integer */ -#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ -#define FPT 0x100 /* Floating point number */ -#define GROUPING 0x200 /* use grouping ("'" flag) */ - /* C99 additional size modifiers: */ -#define SIZET 0x400 /* size_t */ -#define PTRDIFFT 0x800 /* ptrdiff_t */ -#define INTMAXT 0x1000 /* intmax_t */ -#define CHARINT 0x2000 /* print char using int format */ +#if UINTMAX_MAX <= UINT64_MAX +#define BUF 32 +#else +#error "BUF must be large enough to format a uintmax_t" +#endif /* * Non-MT-safe version @@ -462,14 +298,13 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) int ch; /* character from fmt */ int n, n2; /* handy integer (short term usage) */ char *cp; /* handy char pointer (short term usage) */ - struct __siov *iovp; /* for PRINT macro */ int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format; <0 for N/A */ char sign; /* sign prefix (' ', '+', '-', or \0) */ - char thousands_sep; /* locale specific thousands separator */ - const char *grouping; /* locale specific numeric grouping rules */ + struct grouping_state gs; /* thousands' grouping info */ + #ifndef NO_FLOATING_POINT /* * We can decompose the printed representation of floating @@ -486,6 +321,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) * F: at least two digits for decimal, at least one digit for hex */ char *decimal_point; /* locale specific decimal point */ + int decpt_len; /* length of decimal_point */ int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; @@ -495,12 +331,9 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) char expchar; /* exponent character: [eEpP\0] */ char *dtoaend; /* pointer to end of converted digits */ int expsize; /* character count for expstr */ - int lead; /* sig figs before decimal or group sep */ int ndig; /* actual number of digits returned by dtoa */ char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ char *dtoaresult; /* buffer allocated by dtoa */ - int nseps; /* number of group separators with ' */ - int nrepeats; /* number of repeats of the last group */ #endif u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ @@ -510,9 +343,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) int size; /* size of converted field or string */ int prsize; /* max size of printed field */ const char *xdigs; /* digits for %[xX] conversion */ -#define NIOV 8 - struct __suio uio; /* output information: summary */ - struct __siov iov[NIOV];/* ... and individual io vectors */ + struct io_state io; /* I/O buffering state */ char buf[BUF]; /* buffer with space for digits of uintmax_t */ char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */ union arg *argtable; /* args, built due to positional arg */ @@ -521,56 +352,25 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) va_list orgap; /* original argument pointer */ char *convbuf; /* wide to multibyte conversion result */ - /* - * Choose PADSIZE to trade efficiency vs. size. If larger printf - * fields occur frequently, increase PADSIZE and make the initialisers - * below longer. - */ -#define PADSIZE 16 /* pad chunk size */ - static char blanks[PADSIZE] = - {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; - static char zeroes[PADSIZE] = - {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; - static const char xdigs_lower[16] = "0123456789abcdef"; static const char xdigs_upper[16] = "0123456789ABCDEF"; - /* - * BEWARE, these `goto error' on error, and PAD uses `n'. - */ + /* BEWARE, these `goto error' on error. */ #define PRINT(ptr, len) { \ - iovp->iov_base = (ptr); \ - iovp->iov_len = (len); \ - uio.uio_resid += (len); \ - iovp++; \ - if (++uio.uio_iovcnt >= NIOV) { \ - if (__sprint(fp, &uio)) \ - goto error; \ - iovp = iov; \ - } \ + if (io_print(&io, (ptr), (len))) \ + goto error; \ } #define PAD(howmany, with) { \ - if ((n = (howmany)) > 0) { \ - while (n > PADSIZE) { \ - PRINT(with, PADSIZE); \ - n -= PADSIZE; \ - } \ - PRINT(with, n); \ - } \ + if (io_pad(&io, (howmany), (with))) \ + goto error; \ +} +#define PRINTANDPAD(p, ep, len, with) { \ + if (io_printandpad(&io, (p), (ep), (len), (with))) \ + goto error; \ } -#define PRINTANDPAD(p, ep, len, with) do { \ - n2 = (ep) - (p); \ - if (n2 > (len)) \ - n2 = (len); \ - if (n2 > 0) \ - PRINT((p), n2); \ - PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ -} while(0) #define FLUSH() { \ - if (uio.uio_resid && __sprint(fp, &uio)) \ + if (io_flush(&io)) \ goto error; \ - uio.uio_iovcnt = 0; \ - iovp = iov; \ } /* @@ -599,7 +399,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) #define SJARG() \ (flags&INTMAXT ? GETARG(intmax_t) : \ - flags&SIZET ? (intmax_t)GETARG(size_t) : \ + flags&SIZET ? (intmax_t)GETARG(ssize_t) : \ flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ (intmax_t)GETARG(long long)) #define UJARG() \ @@ -623,7 +423,10 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) int hold = nextarg; \ if (argtable == NULL) { \ argtable = statargtable; \ - __find_arguments (fmt0, orgap, &argtable); \ + if (__find_arguments (fmt0, orgap, &argtable)) { \ + ret = EOF; \ + goto error; \ + } \ } \ nextarg = n2; \ val = GETARG (int); \ @@ -633,31 +436,28 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) val = GETARG (int); \ } + if (__use_xprintf == 0 && getenv("USE_XPRINTF")) + __use_xprintf = 1; + if (__use_xprintf > 0) + return (__xvprintf(fp, fmt0, ap)); - thousands_sep = '\0'; - grouping = NULL; - convbuf = NULL; -#ifndef NO_FLOATING_POINT - dtoaresult = NULL; - decimal_point = localeconv()->decimal_point; -#endif /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ if (prepwrite(fp) != 0) return (EOF); - /* optimise fprintf(stderr) (and other unbuffered Unix files) */ - if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) - return (__sbprintf(fp, fmt0, ap)); - + convbuf = NULL; fmt = (char *)fmt0; argtable = NULL; nextarg = 1; va_copy(orgap, ap); - uio.uio_iov = iovp = iov; - uio.uio_resid = 0; - uio.uio_iovcnt = 0; + io_init(&io, fp); ret = 0; +#ifndef NO_FLOATING_POINT + dtoaresult = NULL; + decimal_point = localeconv()->decimal_point; + /* The overwhelmingly common case is decpt_len == 1. */ + decpt_len = (decimal_point[1] == '\0' ? 1 : strlen(decimal_point)); +#endif /* * Scan the format for conversions (`%' character). @@ -681,6 +481,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) dprec = 0; width = 0; prec = -1; + gs.grouping = NULL; sign = '\0'; ox[1] = '\0'; @@ -718,8 +519,6 @@ reswitch: switch (ch) { goto rflag; case '\'': flags |= GROUPING; - thousands_sep = *(localeconv()->thousands_sep); - grouping = localeconv()->grouping; goto rflag; case '.': if ((ch = *fmt++) == '*') { @@ -751,8 +550,11 @@ reswitch: switch (ch) { nextarg = n; if (argtable == NULL) { argtable = statargtable; - __find_arguments (fmt0, orgap, - &argtable); + if (__find_arguments (fmt0, orgap, + &argtable)) { + ret = EOF; + goto error; + } } goto rflag; } @@ -909,6 +711,7 @@ fp_common: } else cp = (ch >= 'a') ? "inf" : "INF"; size = 3; + flags &= ~ZEROPAD; break; } flags |= FPT; @@ -936,7 +739,7 @@ fp_common: expsize = exponent(expstr, expt - 1, expchar); size = expsize + prec; if (prec > 1 || flags & ALT) - ++size; + size += decpt_len; } else { /* space for digits before decimal point */ if (expt > 0) @@ -945,24 +748,9 @@ fp_common: size = 1; /* space for decimal pt and following digits */ if (prec || flags & ALT) - size += prec + 1; - if (grouping && expt > 0) { - /* space for thousands' grouping */ - nseps = nrepeats = 0; - lead = expt; - while (*grouping != CHAR_MAX) { - if (lead <= *grouping) - break; - lead -= *grouping; - if (*(grouping+1)) { - nseps++; - grouping++; - } else - nrepeats++; - } - size += nseps + nrepeats; - } else - lead = expt; + size += prec + decpt_len; + if ((flags & GROUPING) && expt > 0) + size += grouping_init(&gs, expt); } break; #endif /* !NO_FLOATING_POINT */ @@ -1034,22 +822,7 @@ fp_common: } } else if ((cp = GETARG(char *)) == NULL) cp = "(null)"; - if (prec >= 0) { - /* - * can't use strlen; can only look for the - * NUL in the first `prec' characters, and - * strlen() will go further. - */ - char *p = memchr(cp, 0, (size_t)prec); - - if (p != NULL) { - size = p - cp; - if (size > prec) - size = prec; - } else - size = prec; - } else - size = strlen(cp); + size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp); sign = '\0'; break; case 'U': @@ -1093,24 +866,28 @@ number: if ((dprec = prec) >= 0) * ``The result of converting a zero value with an * explicit precision of zero is no characters.'' * -- ANSI X3J11 + * + * ``The C Standard is clear enough as is. The call + * printf("%#.0o", 0) should print 0.'' + * -- Defect Report #151 */ cp = buf + BUF; if (flags & INTMAX_SIZE) { - if (ujval != 0 || prec != 0) + if (ujval != 0 || prec != 0 || + (flags & ALT && base == 8)) cp = __ujtoa(ujval, cp, base, - flags & ALT, xdigs, - flags & GROUPING, thousands_sep, - grouping); + flags & ALT, xdigs); } else { - if (ulval != 0 || prec != 0) + if (ulval != 0 || prec != 0 || + (flags & ALT && base == 8)) cp = __ultoa(ulval, cp, base, - flags & ALT, xdigs, - flags & GROUPING, thousands_sep, - grouping); + flags & ALT, xdigs); } size = buf + BUF - cp; if (size > BUF) /* should never happen */ abort(); + if ((flags & GROUPING) && size != 0) + size += grouping_init(&gs, size); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') @@ -1166,51 +943,48 @@ number: if ((dprec = prec) >= 0) if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) PAD(width - realsz, zeroes); - /* leading zeroes from decimal precision */ - PAD(dprec - size, zeroes); - /* the string or number proper */ #ifndef NO_FLOATING_POINT if ((flags & FPT) == 0) { - PRINT(cp, size); +#endif + /* leading zeroes from decimal precision */ + PAD(dprec - size, zeroes); + if (gs.grouping) { + if (grouping_print(&gs, &io, cp, buf+BUF) < 0) + goto error; + } else { + PRINT(cp, size); + } +#ifndef NO_FLOATING_POINT } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { PRINT(zeroes, 1); if (prec || flags & ALT) - PRINT(decimal_point, 1); + PRINT(decimal_point,decpt_len); PAD(-expt, zeroes); /* already handled initial 0's */ prec += expt; } else { - PRINTANDPAD(cp, dtoaend, lead, zeroes); - cp += lead; - if (grouping) { - while (nseps>0 || nrepeats>0) { - if (nrepeats > 0) - nrepeats--; - else { - grouping--; - nseps--; - } - PRINT(&thousands_sep, - 1); - PRINTANDPAD(cp,dtoaend, - *grouping, zeroes); - cp += *grouping; - } - if (cp > dtoaend) - cp = dtoaend; + if (gs.grouping) { + n = grouping_print(&gs, &io, + cp, dtoaend); + if (n < 0) + goto error; + cp += n; + } else { + PRINTANDPAD(cp, dtoaend, + expt, zeroes); + cp += expt; } if (prec || flags & ALT) - PRINT(decimal_point,1); + PRINT(decimal_point,decpt_len); } PRINTANDPAD(cp, dtoaend, prec, zeroes); } else { /* %[eE] or sufficiently long %[gG] */ if (prec > 1 || flags & ALT) { - buf[0] = *cp++; - buf[1] = *decimal_point; - PRINT(buf, 2); + PRINT(cp++, 1); + PRINT(decimal_point, decpt_len); PRINT(cp, ndig-1); PAD(prec - ndig, zeroes); } else /* XeYYY */ @@ -1218,8 +992,6 @@ number: if ((dprec = prec) >= 0) PRINT(expstr, expsize); } } -#else - PRINT(cp, size); #endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) @@ -1248,398 +1020,3 @@ error: /* NOTREACHED */ } -/* - * Find all arguments when a positional parameter is encountered. Returns a - * table, indexed by argument number, of pointers to each arguments. The - * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. - * It will be replaces with a malloc-ed one if it overflows. - */ -static void -__find_arguments (const char *fmt0, va_list ap, union arg **argtable) -{ - char *fmt; /* format string */ - int ch; /* character from fmt */ - int n, n2; /* handy integer (short term usage) */ - char *cp; /* handy char pointer (short term usage) */ - int flags; /* flags as above */ - int width; /* width from format (%8d), or 0 */ - enum typeid *typetable; /* table of types */ - enum typeid stattypetable [STATIC_ARG_TBL_SIZE]; - int tablesize; /* current size of type table */ - int tablemax; /* largest used index in table */ - int nextarg; /* 1-based argument index */ - - /* - * Add an argument type to the table, expanding if necessary. - */ -#define ADDTYPE(type) \ - ((nextarg >= tablesize) ? \ - __grow_type_table(nextarg, &typetable, &tablesize) : (void)0, \ - (nextarg > tablemax) ? tablemax = nextarg : 0, \ - typetable[nextarg++] = type) - -#define ADDSARG() \ - ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \ - ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ - ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ - ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \ - ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT)))))) - -#define ADDUARG() \ - ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \ - ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ - ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ - ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \ - ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT)))))) - - /* - * Add * arguments to the type array. - */ -#define ADDASTER() \ - n2 = 0; \ - cp = fmt; \ - while (is_digit(*cp)) { \ - n2 = 10 * n2 + to_digit(*cp); \ - cp++; \ - } \ - if (*cp == '$') { \ - int hold = nextarg; \ - nextarg = n2; \ - ADDTYPE (T_INT); \ - nextarg = hold; \ - fmt = ++cp; \ - } else { \ - ADDTYPE (T_INT); \ - } - fmt = (char *)fmt0; - typetable = stattypetable; - tablesize = STATIC_ARG_TBL_SIZE; - tablemax = 0; - nextarg = 1; - for (n = 0; n < STATIC_ARG_TBL_SIZE; n++) - typetable[n] = T_UNUSED; - - /* - * Scan the format for conversions (`%' character). - */ - for (;;) { - for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) - /* void */; - if (ch == '\0') - goto done; - fmt++; /* skip over '%' */ - - flags = 0; - width = 0; - -rflag: ch = *fmt++; -reswitch: switch (ch) { - case ' ': - case '#': - goto rflag; - case '*': - ADDASTER (); - goto rflag; - case '-': - case '+': - case '\'': - goto rflag; - case '.': - if ((ch = *fmt++) == '*') { - ADDASTER (); - goto rflag; - } - while (is_digit(ch)) { - ch = *fmt++; - } - goto reswitch; - case '0': - goto rflag; - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - n = 0; - do { - n = 10 * n + to_digit(ch); - ch = *fmt++; - } while (is_digit(ch)); - if (ch == '$') { - nextarg = n; - goto rflag; - } - width = n; - goto reswitch; -#ifndef NO_FLOATING_POINT - case 'L': - flags |= LONGDBL; - goto rflag; -#endif - case 'h': - if (flags & SHORTINT) { - flags &= ~SHORTINT; - flags |= CHARINT; - } else - flags |= SHORTINT; - goto rflag; - case 'j': - flags |= INTMAXT; - goto rflag; - case 'l': - if (flags & LONGINT) { - flags &= ~LONGINT; - flags |= LLONGINT; - } else - flags |= LONGINT; - goto rflag; - case 'q': - flags |= LLONGINT; /* not necessarily */ - goto rflag; - case 't': - flags |= PTRDIFFT; - goto rflag; - case 'z': - flags |= SIZET; - goto rflag; - case 'C': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'c': - if (flags & LONGINT) - ADDTYPE(T_WINT); - else - ADDTYPE(T_INT); - break; - case 'D': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'd': - case 'i': - ADDSARG(); - break; -#ifndef NO_FLOATING_POINT - case 'a': - case 'A': - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - if (flags & LONGDBL) - ADDTYPE(T_LONG_DOUBLE); - else - ADDTYPE(T_DOUBLE); - break; -#endif /* !NO_FLOATING_POINT */ - case 'n': - if (flags & INTMAXT) - ADDTYPE(TP_INTMAXT); - else if (flags & PTRDIFFT) - ADDTYPE(TP_PTRDIFFT); - else if (flags & SIZET) - ADDTYPE(TP_SIZET); - else if (flags & LLONGINT) - ADDTYPE(TP_LLONG); - else if (flags & LONGINT) - ADDTYPE(TP_LONG); - else if (flags & SHORTINT) - ADDTYPE(TP_SHORT); - else if (flags & CHARINT) - ADDTYPE(TP_SCHAR); - else - ADDTYPE(TP_INT); - continue; /* no output */ - case 'O': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'o': - ADDUARG(); - break; - case 'p': - ADDTYPE(TP_VOID); - break; - case 'S': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 's': - if (flags & LONGINT) - ADDTYPE(TP_WCHAR); - else - ADDTYPE(TP_CHAR); - break; - case 'U': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'u': - case 'X': - case 'x': - ADDUARG(); - break; - default: /* "%?" prints ?, unless ? is NUL */ - if (ch == '\0') - goto done; - break; - } - } -done: - /* - * Build the argument table. - */ - if (tablemax >= STATIC_ARG_TBL_SIZE) { - *argtable = (union arg *) - malloc (sizeof (union arg) * (tablemax + 1)); - } - - (*argtable) [0].intarg = 0; - for (n = 1; n <= tablemax; n++) { - switch (typetable [n]) { - case T_UNUSED: /* whoops! */ - (*argtable) [n].intarg = va_arg (ap, int); - break; - case TP_SCHAR: - (*argtable) [n].pschararg = va_arg (ap, signed char *); - break; - case TP_SHORT: - (*argtable) [n].pshortarg = va_arg (ap, short *); - break; - case T_INT: - (*argtable) [n].intarg = va_arg (ap, int); - break; - case T_U_INT: - (*argtable) [n].uintarg = va_arg (ap, unsigned int); - break; - case TP_INT: - (*argtable) [n].pintarg = va_arg (ap, int *); - break; - case T_LONG: - (*argtable) [n].longarg = va_arg (ap, long); - break; - case T_U_LONG: - (*argtable) [n].ulongarg = va_arg (ap, unsigned long); - break; - case TP_LONG: - (*argtable) [n].plongarg = va_arg (ap, long *); - break; - case T_LLONG: - (*argtable) [n].longlongarg = va_arg (ap, long long); - break; - case T_U_LLONG: - (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); - break; - case TP_LLONG: - (*argtable) [n].plonglongarg = va_arg (ap, long long *); - break; - case T_PTRDIFFT: - (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); - break; - case TP_PTRDIFFT: - (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); - break; - case T_SIZET: - (*argtable) [n].sizearg = va_arg (ap, size_t); - break; - case TP_SIZET: - (*argtable) [n].psizearg = va_arg (ap, ssize_t *); - break; - case T_INTMAXT: - (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); - break; - case T_UINTMAXT: - (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); - break; - case TP_INTMAXT: - (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); - break; -#ifndef NO_FLOATING_POINT - case T_DOUBLE: - (*argtable) [n].doublearg = va_arg (ap, double); - break; - case T_LONG_DOUBLE: - (*argtable) [n].longdoublearg = va_arg (ap, long double); - break; -#endif - case TP_CHAR: - (*argtable) [n].pchararg = va_arg (ap, char *); - break; - case TP_VOID: - (*argtable) [n].pvoidarg = va_arg (ap, void *); - break; - case T_WINT: - (*argtable) [n].wintarg = va_arg (ap, wint_t); - break; - case TP_WCHAR: - (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); - break; - } - } - - if ((typetable != NULL) && (typetable != stattypetable)) - free (typetable); -} - -/* - * Increase the size of the type table. - */ -static void -__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) -{ - enum typeid *const oldtable = *typetable; - const int oldsize = *tablesize; - enum typeid *newtable; - int n, newsize = oldsize * 2; - - if (newsize < nextarg + 1) - newsize = nextarg + 1; - if (oldsize == STATIC_ARG_TBL_SIZE) { - if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL) - abort(); /* XXX handle better */ - bcopy(oldtable, newtable, oldsize * sizeof(enum typeid)); - } else { - newtable = reallocf(oldtable, newsize * sizeof(enum typeid)); - if (newtable == NULL) - abort(); /* XXX handle better */ - } - for (n = oldsize; n < newsize; n++) - newtable[n] = T_UNUSED; - - *typetable = newtable; - *tablesize = newsize; -} - - -#ifndef NO_FLOATING_POINT - -static int -exponent(char *p0, int exp, int fmtch) -{ - char *p, *t; - char expbuf[MAXEXPDIG]; - - p = p0; - *p++ = fmtch; - if (exp < 0) { - exp = -exp; - *p++ = '-'; - } - else - *p++ = '+'; - t = expbuf + MAXEXPDIG; - if (exp > 9) { - do { - *--t = to_char(exp % 10); - } while ((exp /= 10) > 9); - *--t = to_char(exp); - for (; t < expbuf + MAXEXPDIG; *p++ = *t++); - } - else { - /* - * Exponents for decimal floating point conversions - * (%[eEgG]) must be at least two characters long, - * whereas exponents for hexadecimal conversions can - * be only one character long. - */ - if (fmtch == 'e' || fmtch == 'E') - *p++ = '0'; - *p++ = to_char(exp); - } - return (p - p0); -} -#endif /* !NO_FLOATING_POINT */ diff --git a/stdio/FreeBSD/vfprintf.c.patch b/stdio/FreeBSD/vfprintf.c.patch index 46fbf12..b3ffc42 100644 --- a/stdio/FreeBSD/vfprintf.c.patch +++ b/stdio/FreeBSD/vfprintf.c.patch @@ -1,82 +1,93 @@ ---- vfprintf.c.orig 2008-09-07 11:37:54.000000000 -0700 -+++ vfprintf.c 2008-09-07 17:33:16.000000000 -0700 -@@ -40,6 +40,8 @@ static char sccsid[] = "@(#)vfprintf.c 8 +--- vfprintf.c.orig 2010-11-22 22:37:24.000000000 -0800 ++++ vfprintf.c 2010-11-22 22:38:38.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)vfprintf.c 8 #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.90 2009/02/28 06:06:57 das Exp $"); +#include "xlocale_private.h" + /* * Actual printf innards. * -@@ -58,6 +60,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v +@@ -54,7 +56,10 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v #include #include #include ++#if 0 // xprintf pending API review + #include ++#endif +#include #include #include "un-namespace.h" -@@ -66,6 +69,13 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v - #include "local.h" +@@ -64,10 +69,11 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v #include "fvwrite.h" + #include "printflocal.h" -+#ifdef VECTORS -+typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE; -+#ifdef __SSE2__ -+#define V64TYPE -+#endif /* __SSE2__ */ -+#endif /* VECTORS */ +-static int __sprint(FILE *, struct __suio *); +-static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0) +- __noinline; +-static char *__wcsconv(wchar_t *, int); ++static int __sprint(FILE *, locale_t, struct __suio *); ++static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0); ++static char *__wcsconv(wchar_t *, int, locale_t); + - union arg { - int intarg; - u_int uintarg; -@@ -93,6 +103,21 @@ union arg { - #endif - wint_t wintarg; - wchar_t *pwchararg; -+#ifdef VECTORS -+ VECTORTYPE vectorarg; -+ unsigned char vuchararg[16]; -+ signed char vchararg[16]; -+ unsigned short vushortarg[8]; -+ signed short vshortarg[8]; -+ unsigned int vuintarg[4]; -+ signed int vintarg[4]; -+ float vfloatarg[4]; -+#ifdef V64TYPE -+ double vdoublearg[2]; -+ unsigned long long vulonglongarg[2]; -+ long long vlonglongarg[2]; -+#endif /* V64TYPE */ -+#endif /* VECTORS */ - }; ++__private_extern__ const char *__fix_nogrouping(const char *); - /* -@@ -103,16 +128,20 @@ enum typeid { - T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, - T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, - T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, -+#ifdef VECTORS -+ T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR -+#else /* ! VECTORS */ - T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR -+#endif /* VECTORS */ - }; + #define CHAR char + #include "printfcommon.h" +@@ -87,12 +93,12 @@ struct grouping_state { + * of bytes that will be needed. + */ + static int +-grouping_init(struct grouping_state *gs, int ndigits) ++grouping_init(struct grouping_state *gs, int ndigits, locale_t loc) + { + struct lconv *locale; - static int __sprint(FILE *, struct __suio *); --static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0); -+static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0); - static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char, - const char *); - static char *__ultoa(u_long, char *, int, int, const char *, int, char, - const char *); --static char *__wcsconv(wchar_t *, int); -+static char *__wcsconv(wchar_t *, int, locale_t); - static void __find_arguments(const char *, va_list, union arg **); - static void __grow_type_table(int, enum typeid **, int *); +- locale = localeconv(); +- gs->grouping = locale->grouping; ++ locale = localeconv_l(loc); ++ gs->grouping = __fix_nogrouping(locale->grouping); + gs->thousands_sep = locale->thousands_sep; + gs->thousep_len = strlen(gs->thousands_sep); + +@@ -116,11 +122,11 @@ grouping_init(struct grouping_state *gs, + */ + static int + grouping_print(struct grouping_state *gs, struct io_state *iop, +- const CHAR *cp, const CHAR *ep) ++ const CHAR *cp, const CHAR *ep, locale_t loc) + { + const CHAR *cp0 = cp; + +- if (io_printandpad(iop, cp, ep, gs->lead, zeroes)) ++ if (io_printandpad(iop, cp, ep, gs->lead, zeroes, loc)) + return (-1); + cp += gs->lead; + while (gs->nseps > 0 || gs->nrepeats > 0) { +@@ -130,9 +136,9 @@ grouping_print(struct grouping_state *gs + gs->grouping--; + gs->nseps--; + } +- if (io_print(iop, gs->thousands_sep, gs->thousep_len)) ++ if (io_print(iop, gs->thousands_sep, gs->thousep_len, loc)) + return (-1); +- if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes)) ++ if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes, loc)) + return (-1); + cp += *gs->grouping; + } +@@ -146,7 +152,7 @@ grouping_print(struct grouping_state *gs + * then reset it so that it can be reused. + */ + static int +-__sprint(FILE *fp, struct __suio *uio) ++__sprint(FILE *fp, locale_t loc __unused, struct __suio *uio) + { + int err; -@@ -141,7 +170,7 @@ __sprint(FILE *fp, struct __suio *uio) +@@ -166,11 +172,14 @@ __sprint(FILE *fp, struct __suio *uio) * worries about ungetc buffers and so forth. */ static int @@ -85,7 +96,14 @@ { int ret; FILE fake; -@@ -160,7 +189,7 @@ __sbprintf(FILE *fp, const char *fmt, va + unsigned char buf[BUFSIZ]; ++ struct __sFILEX ext; ++ fake._extra = &ext; ++ INITEXTRA(&fake); + + /* XXX This is probably not needed. */ + if (prepwrite(fp) != 0) +@@ -190,7 +199,7 @@ __sbprintf(FILE *fp, const char *fmt, va fake._lbfsize = 0; /* not actually used, but Just In Case */ /* do the work, then copy any error status */ @@ -94,26 +112,8 @@ if (ret >= 0 && __fflush(&fake)) ret = EOF; if (fake._flags & __SERR) -@@ -252,7 +281,7 @@ __ultoa(u_long val, char *endp, int base - break; - - default: /* oops */ -- abort(); -+ LIBC_ABORT("base = %d", base); - } - return (cp); - } -@@ -324,7 +353,7 @@ __ujtoa(uintmax_t val, char *endp, int b - break; - - default: -- abort(); -+ LIBC_ABORT("base = %d", base); - } - return (cp); - } -@@ -336,14 +365,14 @@ __ujtoa(uintmax_t val, char *endp, int b - * that the wide char. string ends in a null character. +@@ -205,7 +214,7 @@ __sbprintf(FILE *fp, const char *fmt, va + * string ends is null-terminated. */ static char * -__wcsconv(wchar_t *wcsarg, int prec) @@ -121,81 +121,70 @@ { static const mbstate_t initial; mbstate_t mbs; - char buf[MB_LEN_MAX]; - wchar_t *p; - char *convbuf, *mbp; -- size_t clen, nbytes; -+ size_t clen = 0, nbytes; - - /* - * Determine the number of bytes to output and allocate space for -@@ -354,7 +383,7 @@ __wcsconv(wchar_t *wcsarg, int prec) - p = wcsarg; - mbs = initial; - for (;;) { -- clen = wcrtomb(buf, *p++, &mbs); -+ clen = wcrtomb_l(buf, *p++, &mbs, loc); - if (clen == 0 || clen == (size_t)-1 || - nbytes + clen > prec) - break; -@@ -363,7 +392,7 @@ __wcsconv(wchar_t *wcsarg, int prec) - } else { +@@ -218,7 +227,7 @@ __wcsconv(wchar_t *wcsarg, int prec) + if (prec < 0) { p = wcsarg; mbs = initial; - nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs); + nbytes = wcsrtombs_l(NULL, (const wchar_t **)&p, 0, &mbs, loc); if (nbytes == (size_t)-1) return (NULL); - } -@@ -378,7 +407,7 @@ __wcsconv(wchar_t *wcsarg, int prec) + } else { +@@ -234,7 +243,7 @@ __wcsconv(wchar_t *wcsarg, int prec) + p = wcsarg; + mbs = initial; + for (;;) { +- clen = wcrtomb(buf, *p++, &mbs); ++ clen = wcrtomb_l(buf, *p++, &mbs, loc); + if (clen == 0 || clen == (size_t)-1 || + nbytes + clen > prec) + break; +@@ -248,8 +257,8 @@ __wcsconv(wchar_t *wcsarg, int prec) + /* Fill the output buffer. */ p = wcsarg; mbs = initial; - while (mbp - convbuf < nbytes) { -- clen = wcrtomb(mbp, *p++, &mbs); -+ clen = wcrtomb_l(mbp, *p++, &mbs, loc); - if (clen == 0 || clen == (size_t)-1) - break; - mbp += clen; -@@ -395,6 +424,8 @@ __wcsconv(wchar_t *wcsarg, int prec) - /* +- if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p, +- nbytes, &mbs)) == (size_t)-1) { ++ if ((nbytes = wcsrtombs_l(convbuf, (const wchar_t **)&p, ++ nbytes, &mbs, loc)) == (size_t)-1) { + free(convbuf); + return (NULL); + } +@@ -261,22 +270,30 @@ __wcsconv(wchar_t *wcsarg, int prec) * MT-safe version */ -+__private_extern__ const char *__fix_nogrouping(const char *); -+ int - vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) +-vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) ++vfprintf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, va_list ap) -@@ -402,7 +433,21 @@ vfprintf(FILE * __restrict fp, const cha + { int ret; - FLOCKFILE(fp); -- ret = __vfprintf(fp, fmt0, ap); -+ ret = __vfprintf(fp, __current_locale(), fmt0, ap); -+ FUNLOCKFILE(fp); -+ return (ret); -+} -+ -+int -+vfprintf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, -+ va_list ap) -+ -+{ -+ int ret; -+ + NORMALIZE_LOCALE(loc); -+ FLOCKFILE(fp); -+ ret = __vfprintf(fp, loc, fmt0, ap); + FLOCKFILE(fp); + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) +- ret = __sbprintf(fp, fmt0, ap); ++ ret = __sbprintf(fp, loc, fmt0, ap); + else +- ret = __vfprintf(fp, fmt0, ap); ++ ret = __vfprintf(fp, loc, fmt0, ap); FUNLOCKFILE(fp); return (ret); } -@@ -451,12 +496,15 @@ static int exponent(char *, int, int); - #define PTRDIFFT 0x800 /* ptrdiff_t */ - #define INTMAXT 0x1000 /* intmax_t */ - #define CHARINT 0x2000 /* print char using int format */ -+#ifdef VECTORS -+#define VECTOR 0x4000 /* Altivec or SSE vector */ -+#endif /* VECTORS */ ++int ++vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) ++ ++{ ++ return vfprintf_l(fp, __current_locale(), fmt0, ap); ++} ++ + /* + * The size of the buffer we use as scratch space for integer + * conversions, among other things. We need enough space to +@@ -291,8 +308,8 @@ vfprintf(FILE * __restrict fp, const cha /* * Non-MT-safe version */ @@ -206,9 +195,9 @@ { char *fmt; /* format string */ int ch; /* character from fmt */ -@@ -502,6 +550,11 @@ __vfprintf(FILE *fp, const char *fmt0, v - int nseps; /* number of group separators with ' */ - int nrepeats; /* number of repeats of the last group */ +@@ -335,6 +352,11 @@ __vfprintf(FILE *fp, const char *fmt0, v + char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ + char *dtoaresult; /* buffer allocated by dtoa */ #endif +#ifdef VECTORS + union arg vval; /* Vector argument. */ @@ -218,35 +207,51 @@ u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ -@@ -599,13 +652,13 @@ __vfprintf(FILE *fp, const char *fmt0, v - #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) - #define SJARG() \ - (flags&INTMAXT ? GETARG(intmax_t) : \ -- flags&SIZET ? (intmax_t)GETARG(size_t) : \ -+ flags&SIZET ? (intmax_t)GETARG(ssize_t) : \ - flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ - (intmax_t)GETARG(long long)) +@@ -357,19 +379,19 @@ __vfprintf(FILE *fp, const char *fmt0, v + + /* BEWARE, these `goto error' on error. */ + #define PRINT(ptr, len) { \ +- if (io_print(&io, (ptr), (len))) \ ++ if (io_print(&io, (ptr), (len), loc)) \ + goto error; \ + } + #define PAD(howmany, with) { \ +- if (io_pad(&io, (howmany), (with))) \ ++ if (io_pad(&io, (howmany), (with), loc)) \ + goto error; \ + } + #define PRINTANDPAD(p, ep, len, with) { \ +- if (io_printandpad(&io, (p), (ep), (len), (with))) \ ++ if (io_printandpad(&io, (p), (ep), (len), (with), loc)) \ + goto error; \ + } + #define FLUSH() { \ +- if (io_flush(&io)) \ ++ if (io_flush(&io, loc)) \ + goto error; \ + } + +@@ -405,7 +427,7 @@ __vfprintf(FILE *fp, const char *fmt0, v #define UJARG() \ (flags&INTMAXT ? GETARG(uintmax_t) : \ flags&SIZET ? (uintmax_t)GETARG(size_t) : \ - flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ -+ flags&PTRDIFFT ? (uintmax_t)(unsigned)GETARG(ptrdiff_t) : \ ++ flags&PTRDIFFT ? (uintmax_t)(unsigned long)GETARG(ptrdiff_t) : \ (uintmax_t)GETARG(unsigned long long)) /* -@@ -633,22 +686,24 @@ __vfprintf(FILE *fp, const char *fmt0, v +@@ -436,14 +458,19 @@ __vfprintf(FILE *fp, const char *fmt0, v val = GETARG (int); \ } -- - thousands_sep = '\0'; - grouping = NULL; - convbuf = NULL; - #ifndef NO_FLOATING_POINT - dtoaresult = NULL; -- decimal_point = localeconv()->decimal_point; -+ decimal_point = localeconv_l(loc)->decimal_point; - #endif ++#if 0 // xprintf pending API review + if (__use_xprintf == 0 && getenv("USE_XPRINTF")) + __use_xprintf = 1; + if (__use_xprintf > 0) +- return (__xvprintf(fp, fmt0, ap)); ++ return (__xvprintf(fp, loc, fmt0, ap)); ++#endif + /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ - if (prepwrite(fp) != 0) + if (prepwrite(fp) != 0) { @@ -255,15 +260,18 @@ + } + ORIENT(fp, -1); - /* optimise fprintf(stderr) (and other unbuffered Unix files) */ - if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) -- return (__sbprintf(fp, fmt0, ap)); -+ return (__sbprintf(fp, loc, fmt0, ap)); - + convbuf = NULL; fmt = (char *)fmt0; - argtable = NULL; -@@ -675,6 +730,9 @@ __vfprintf(FILE *fp, const char *fmt0, v +@@ -454,7 +481,7 @@ __vfprintf(FILE *fp, const char *fmt0, v + ret = 0; + #ifndef NO_FLOATING_POINT + dtoaresult = NULL; +- decimal_point = localeconv()->decimal_point; ++ decimal_point = localeconv_l(loc)->decimal_point; + /* The overwhelmingly common case is decpt_len == 1. */ + decpt_len = (decimal_point[1] == '\0' ? 1 : strlen(decimal_point)); + #endif +@@ -475,6 +502,9 @@ __vfprintf(FILE *fp, const char *fmt0, v } if (ch == '\0') goto done; @@ -273,8 +281,8 @@ fmt++; /* skip over '%' */ flags = 0; -@@ -683,6 +741,9 @@ __vfprintf(FILE *fp, const char *fmt0, v - prec = -1; +@@ -484,6 +514,9 @@ __vfprintf(FILE *fp, const char *fmt0, v + gs.grouping = NULL; sign = '\0'; ox[1] = '\0'; +#ifdef VECTORS @@ -283,7 +291,7 @@ rflag: ch = *fmt++; reswitch: switch (ch) { -@@ -698,6 +759,11 @@ reswitch: switch (ch) { +@@ -499,6 +532,11 @@ reswitch: switch (ch) { case '#': flags |= ALT; goto rflag; @@ -295,18 +303,7 @@ case '*': /*- * ``A negative field width argument is taken as a -@@ -718,8 +784,8 @@ reswitch: switch (ch) { - goto rflag; - case '\'': - flags |= GROUPING; -- thousands_sep = *(localeconv()->thousands_sep); -- grouping = localeconv()->grouping; -+ thousands_sep = *(localeconv_l(loc)->thousands_sep); -+ grouping = __fix_nogrouping(localeconv_l(loc)->grouping); - goto rflag; - case '.': - if ((ch = *fmt++) == '*') { -@@ -793,14 +859,18 @@ reswitch: switch (ch) { +@@ -595,14 +633,18 @@ reswitch: switch (ch) { flags |= LONGINT; /*FALLTHROUGH*/ case 'c': @@ -327,7 +324,7 @@ if (mbseqlen == (size_t)-1) { fp->_flags |= __SERR; goto error; -@@ -817,6 +887,10 @@ reswitch: switch (ch) { +@@ -619,6 +661,10 @@ reswitch: switch (ch) { /*FALLTHROUGH*/ case 'd': case 'i': @@ -338,7 +335,7 @@ if (flags & INTMAX_SIZE) { ujval = SJARG(); if ((intmax_t)ujval < 0) { -@@ -835,6 +909,12 @@ reswitch: switch (ch) { +@@ -637,6 +683,12 @@ reswitch: switch (ch) { #ifndef NO_FLOATING_POINT case 'a': case 'A': @@ -351,7 +348,7 @@ if (ch == 'a') { ox[1] = 'x'; xdigs = xdigs_lower; -@@ -848,6 +928,12 @@ reswitch: switch (ch) { +@@ -650,6 +702,12 @@ reswitch: switch (ch) { prec++; if (dtoaresult != NULL) freedtoa(dtoaresult); @@ -364,7 +361,7 @@ if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = cp = -@@ -859,6 +945,7 @@ reswitch: switch (ch) { +@@ -661,6 +719,7 @@ reswitch: switch (ch) { __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend); } @@ -372,7 +369,7 @@ if (prec < 0) prec = dtoaend - cp; if (expt == INT_MAX) -@@ -866,6 +953,12 @@ reswitch: switch (ch) { +@@ -668,6 +727,12 @@ reswitch: switch (ch) { goto fp_common; case 'e': case 'E': @@ -385,7 +382,7 @@ expchar = ch; if (prec < 0) /* account for digit before decpt */ prec = DEFPREC + 1; -@@ -874,10 +967,22 @@ reswitch: switch (ch) { +@@ -676,10 +741,22 @@ reswitch: switch (ch) { goto fp_begin; case 'f': case 'F': @@ -408,7 +405,7 @@ expchar = ch - ('g' - 'e'); if (prec == 0) prec = 1; -@@ -886,6 +991,14 @@ fp_begin: +@@ -688,6 +765,14 @@ fp_begin: prec = DEFPREC; if (dtoaresult != NULL) freedtoa(dtoaresult); @@ -423,7 +420,7 @@ if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = cp = -@@ -899,6 +1012,7 @@ fp_begin: +@@ -701,6 +786,7 @@ fp_begin: if (expt == 9999) expt = INT_MAX; } @@ -431,7 +428,53 @@ fp_common: if (signflag) sign = '-'; -@@ -993,6 +1107,10 @@ fp_common: +@@ -750,37 +836,46 @@ fp_common: + if (prec || flags & ALT) + size += prec + decpt_len; + if ((flags & GROUPING) && expt > 0) +- size += grouping_init(&gs, expt); ++ size += grouping_init(&gs, expt, loc); + } + break; + #endif /* !NO_FLOATING_POINT */ + case 'n': ++ { + /* + * Assignment-like behavior is specified if the + * value overflows or is otherwise unrepresentable. + * C99 says to use `signed char' for %hhn conversions. + */ +- if (flags & LLONGINT) +- *GETARG(long long *) = ret; ++ void *ptr = GETARG(void *); ++ if (ptr == NULL) ++ continue; ++ else if (flags & LLONGINT) ++ *(long long *)ptr = ret; + else if (flags & SIZET) +- *GETARG(ssize_t *) = (ssize_t)ret; ++ *(ssize_t *)ptr = (ssize_t)ret; + else if (flags & PTRDIFFT) +- *GETARG(ptrdiff_t *) = ret; ++ *(ptrdiff_t *)ptr = ret; + else if (flags & INTMAXT) +- *GETARG(intmax_t *) = ret; ++ *(intmax_t *)ptr = ret; + else if (flags & LONGINT) +- *GETARG(long *) = ret; ++ *(long *)ptr = ret; + else if (flags & SHORTINT) +- *GETARG(short *) = ret; ++ *(short *)ptr = ret; + else if (flags & CHARINT) +- *GETARG(signed char *) = ret; ++ *(signed char *)ptr = ret; + else +- *GETARG(int *) = ret; ++ *(int *)ptr = ret; + continue; /* no output */ ++ } + case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': @@ -442,7 +485,7 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1007,6 +1125,10 @@ fp_common: +@@ -795,6 +890,10 @@ fp_common: * defined manner.'' * -- ANSI X3J11 */ @@ -453,7 +496,7 @@ ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; xdigs = xdigs_lower; -@@ -1025,7 +1147,7 @@ fp_common: +@@ -813,7 +912,7 @@ fp_common: if ((wcp = GETARG(wchar_t *)) == NULL) cp = "(null)"; else { @@ -462,7 +505,7 @@ if (convbuf == NULL) { fp->_flags |= __SERR; goto error; -@@ -1056,6 +1178,10 @@ fp_common: +@@ -829,6 +928,10 @@ fp_common: flags |= LONGINT; /*FALLTHROUGH*/ case 'u': @@ -473,7 +516,7 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1068,6 +1194,10 @@ fp_common: +@@ -841,6 +944,10 @@ fp_common: case 'x': xdigs = xdigs_lower; hex: @@ -484,29 +527,23 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1093,6 +1223,7 @@ number: if ((dprec = prec) >= 0) - * ``The result of converting a zero value with an - * explicit precision of zero is no characters.'' +@@ -858,6 +965,7 @@ nosign: sign = '\0'; + * ``... diouXx conversions ... if a precision is + * specified, the 0 flag will be ignored.'' * -- ANSI X3J11 + * except for %#.0o and zero value */ - cp = buf + BUF; - if (flags & INTMAX_SIZE) { -@@ -1102,7 +1233,7 @@ number: if ((dprec = prec) >= 0) - flags & GROUPING, thousands_sep, - grouping); - } else { -- if (ulval != 0 || prec != 0) -+ if (ulval != 0 || prec != 0 || (flags & ALT)) - cp = __ultoa(ulval, cp, base, - flags & ALT, xdigs, - flags & GROUPING, thousands_sep, -@@ -1110,8 +1241,13 @@ number: if ((dprec = prec) >= 0) + number: if ((dprec = prec) >= 0) + flags &= ~ZEROPAD; +@@ -885,10 +993,15 @@ number: if ((dprec = prec) >= 0) } size = buf + BUF - cp; if (size > BUF) /* should never happen */ - abort(); -+ LIBC_ABORT("size %d > BUF %d", size, BUF); ++ LIBC_ABORT("size (%d) > BUF (%d)", size, BUF); + if ((flags & GROUPING) && size != 0) +- size += grouping_init(&gs, size); ++ size += grouping_init(&gs, size, loc); break; +#ifdef VECTORS + case 'v': @@ -516,7 +553,7 @@ default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; -@@ -1123,6 +1259,290 @@ number: if ((dprec = prec) >= 0) +@@ -900,6 +1013,290 @@ number: if ((dprec = prec) >= 0) break; } @@ -682,25 +719,25 @@ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \ + break; \ + case V_PCHAR: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuchararg[ind]); \ + break; \ + case V_SHORT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \ + break; \ + case V_PSHORT: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vushortarg[ind]); \ + break; \ + case V_INT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \ + break; \ + case V_PINT: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuintarg[ind]); \ + break; \ + case V_LONGLONG: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vulonglongarg[ind]); \ + break; \ + case V_PLONGLONG: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vulonglongarg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vulonglongarg[ind]); \ + break; \ + case V_FLOAT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ @@ -721,19 +758,19 @@ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \ + break; \ + case V_PCHAR: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuchararg[ind]); \ + break; \ + case V_SHORT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \ + break; \ + case V_PSHORT: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vushortarg[ind]); \ + break; \ + case V_INT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \ + break; \ + case V_PINT: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuintarg[ind]); \ + break; \ + case V_FLOAT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ @@ -807,137 +844,21 @@ /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be -@@ -1178,7 +1598,7 @@ number: if ((dprec = prec) >= 0) - if (expt <= 0) { - PRINT(zeroes, 1); - if (prec || flags & ALT) -- PRINT(decimal_point, 1); -+ PRINT(decimal_point, strlen(decimal_point)); - PAD(-expt, zeroes); - /* already handled initial 0's */ - prec += expt; -@@ -1203,14 +1623,14 @@ number: if ((dprec = prec) >= 0) - cp = dtoaend; - } - if (prec || flags & ALT) -- PRINT(decimal_point,1); -+ PRINT(decimal_point, strlen(decimal_point)); - } - PRINTANDPAD(cp, dtoaend, prec, zeroes); - } else { /* %[eE] or sufficiently long %[gG] */ - if (prec > 1 || flags & ALT) { - buf[0] = *cp++; -- buf[1] = *decimal_point; -- PRINT(buf, 2); -+ PRINT(buf, 1); -+ PRINT(decimal_point, strlen(decimal_point)); - PRINT(cp, ndig-1); - PAD(prec - ndig, zeroes); - } else /* XeYYY */ -@@ -1406,6 +1826,11 @@ reswitch: switch (ch) { - if (flags & LONGINT) - ADDTYPE(T_WINT); - else -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - ADDTYPE(T_INT); - break; - case 'D': -@@ -1413,6 +1838,11 @@ reswitch: switch (ch) { - /*FALLTHROUGH*/ - case 'd': - case 'i': -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif - ADDSARG(); - break; - #ifndef NO_FLOATING_POINT -@@ -1421,8 +1851,14 @@ reswitch: switch (ch) { - case 'e': - case 'E': - case 'f': -+ case 'F': - case 'g': - case 'G': -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - if (flags & LONGDBL) - ADDTYPE(T_LONG_DOUBLE); - else -@@ -1451,9 +1887,19 @@ reswitch: switch (ch) { - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'o': -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - ADDUARG(); - break; - case 'p': -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - ADDTYPE(TP_VOID); - break; - case 'S': -@@ -1471,6 +1917,11 @@ reswitch: switch (ch) { - case 'u': - case 'X': - case 'x': -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - ADDUARG(); - break; - default: /* "%?" prints ?, unless ? is NUL */ -@@ -1537,7 +1988,7 @@ done: - (*argtable) [n].sizearg = va_arg (ap, size_t); - break; - case TP_SIZET: -- (*argtable) [n].psizearg = va_arg (ap, ssize_t *); -+ (*argtable) [n].psizearg = va_arg (ap, size_t *); - break; - case T_INTMAXT: - (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); -@@ -1556,6 +2007,11 @@ done: - (*argtable) [n].longdoublearg = va_arg (ap, long double); - break; - #endif -+#ifdef VECTORS -+ case T_VECTOR: -+ (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE); -+ break; -+#endif /* VECTORS */ - case TP_CHAR: - (*argtable) [n].pchararg = va_arg (ap, char *); - break; -@@ -1590,12 +2046,12 @@ __grow_type_table (int nextarg, enum typ - newsize = nextarg + 1; - if (oldsize == STATIC_ARG_TBL_SIZE) { - if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL) -- abort(); /* XXX handle better */ -+ LIBC_ABORT("malloc: %s", strerror(errno)); /* XXX handle better */ - bcopy(oldtable, newtable, oldsize * sizeof(enum typeid)); - } else { - newtable = reallocf(oldtable, newsize * sizeof(enum typeid)); - if (newtable == NULL) -- abort(); /* XXX handle better */ -+ LIBC_ABORT("reallocf: %s", strerror(errno)); /* XXX handle better */ - } - for (n = oldsize; n < newsize; n++) - newtable[n] = T_UNUSED; +@@ -950,7 +1347,7 @@ number: if ((dprec = prec) >= 0) + /* leading zeroes from decimal precision */ + PAD(dprec - size, zeroes); + if (gs.grouping) { +- if (grouping_print(&gs, &io, cp, buf+BUF) < 0) ++ if (grouping_print(&gs, &io, cp, buf+BUF, loc) < 0) + goto error; + } else { + PRINT(cp, size); +@@ -968,7 +1365,7 @@ number: if ((dprec = prec) >= 0) + } else { + if (gs.grouping) { + n = grouping_print(&gs, &io, +- cp, dtoaend); ++ cp, dtoaend, loc); + if (n < 0) + goto error; + cp += n; diff --git a/stdio/FreeBSD/vfscanf.c b/stdio/FreeBSD/vfscanf.c index 61087e8..69b7297 100644 --- a/stdio/FreeBSD/vfscanf.c +++ b/stdio/FreeBSD/vfscanf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.37 2004/05/02 10:55:05 das Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.43 2009/01/19 06:19:51 das Exp $"); #include "namespace.h" #include @@ -98,9 +94,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.37 2004/05/02 10:55:05 das #define CT_FLOAT 4 /* %[efgEFG] conversion */ static const u_char *__sccl(char *, const u_char *); +#ifndef NO_FLOATING_POINT static int parsefloat(FILE *, char *, char *); - -int __scanfdebug = 0; +#endif __weak_reference(__vfscanf, vfscanf); @@ -138,7 +134,6 @@ __svfscanf(FILE *fp, const char *fmt0, va_list ap) char ccltab[256]; /* character class table for %[...] */ char buf[BUF]; /* buffer for numeric and mb conversions */ wchar_t *wcp; /* handy wide character pointer */ - wchar_t *wcp0; /* saves original value of wcp */ size_t nconv; /* length of multibyte sequence converted */ static const mbstate_t initial; mbstate_t mbs; @@ -413,7 +408,7 @@ literal: } nread += sum; } else { - size_t r = fread((void *)va_arg(ap, char *), 1, + size_t r = __fread((void *)va_arg(ap, char *), 1, width, fp); if (r == 0) @@ -434,9 +429,9 @@ literal: int nchars; if ((flags & SUPPRESS) == 0) - wcp = wcp0 = va_arg(ap, wchar_t *); + wcp = va_arg(ap, wchar_t *); else - wcp = wcp0 = &twc; + wcp = &twc; n = 0; nchars = 0; while (width != 0) { @@ -784,8 +779,6 @@ literal: float res = strtof(buf, &p); *va_arg(ap, float *) = res; } - if (__scanfdebug && p - buf != width) - abort(); nassigned++; } nread += width; @@ -918,13 +911,13 @@ static int parsefloat(FILE *fp, char *buf, char *end) { char *commit, *p; - int infnanpos = 0; + int infnanpos = 0, decptpos = 0; enum { - S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX, - S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS + S_START, S_GOTSIGN, S_INF, S_NAN, S_DONE, S_MAYBEHEX, + S_DIGITS, S_DECPT, S_FRAC, S_EXP, S_EXPDIGITS } state = S_START; unsigned char c; - char decpt = *localeconv()->decimal_point; + const char *decpt = localeconv()->decimal_point; _Bool gotmantdig = 0, ishex = 0; /* @@ -977,8 +970,6 @@ reswitch: break; case S_NAN: switch (infnanpos) { - case -1: /* XXX kludge to deal with nan(...) */ - goto parsedone; case 0: if (c != 'A' && c != 'a') goto parsedone; @@ -996,13 +987,15 @@ reswitch: default: if (c == ')') { commit = p; - infnanpos = -2; + state = S_DONE; } else if (!isalnum(c) && c != '_') goto parsedone; break; } infnanpos++; break; + case S_DONE: + goto parsedone; case S_MAYBEHEX: state = S_DIGITS; if (c == 'X' || c == 'x') { @@ -1013,16 +1006,34 @@ reswitch: goto reswitch; } case S_DIGITS: - if ((ishex && isxdigit(c)) || isdigit(c)) + if ((ishex && isxdigit(c)) || isdigit(c)) { gotmantdig = 1; - else { + commit = p; + break; + } else { + state = S_DECPT; + goto reswitch; + } + case S_DECPT: + if (c == decpt[decptpos]) { + if (decpt[++decptpos] == '\0') { + /* We read the complete decpt seq. */ + state = S_FRAC; + if (gotmantdig) + commit = p; + } + break; + } else if (!decptpos) { + /* We didn't read any decpt characters. */ state = S_FRAC; - if (c != decpt) - goto reswitch; + goto reswitch; + } else { + /* + * We read part of a multibyte decimal point, + * but the rest is invalid, so bail. + */ + goto parsedone; } - if (gotmantdig) - commit = p; - break; case S_FRAC: if (((c == 'E' || c == 'e') && !ishex) || ((c == 'P' || c == 'p') && ishex)) { diff --git a/stdio/FreeBSD/vfscanf.c.patch b/stdio/FreeBSD/vfscanf.c.patch index 2b6ab1d..4dd84b8 100644 --- a/stdio/FreeBSD/vfscanf.c.patch +++ b/stdio/FreeBSD/vfscanf.c.patch @@ -1,15 +1,15 @@ ---- vfscanf.c.orig 2009-02-15 03:11:22.000000000 -0800 -+++ vfscanf.c 2009-02-16 00:22:06.000000000 -0800 -@@ -40,6 +40,8 @@ static char sccsid[] = "@(#)vfscanf.c 8. +--- vfscanf.c.orig 2010-07-15 10:03:36.000000000 -0700 ++++ vfscanf.c 2010-07-15 10:18:58.000000000 -0700 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)vfscanf.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.37 2004/05/02 10:55:05 das Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.43 2009/01/19 06:19:51 das Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include #include -@@ -50,6 +52,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v +@@ -46,6 +48,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v #include #include #include @@ -17,31 +17,19 @@ #include "un-namespace.h" #include "collate.h" -@@ -97,10 +100,21 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v +@@ -93,9 +96,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v #define CT_INT 3 /* %[dioupxX] conversion */ #define CT_FLOAT 4 /* %[efgEFG] conversion */ -static const u_char *__sccl(char *, const u_char *); --static int parsefloat(FILE *, char *, char *); +static const u_char *__sccl(char *, const u_char *, locale_t); -+#ifndef NO_FLOATING_POINT + #ifndef NO_FLOATING_POINT +-static int parsefloat(FILE *, char *, char *); +static int parsefloat(FILE *, char **, size_t, locale_t); -+#endif /* !NO_FLOATING_POINT */ - -+/* -+ * For ppc, we need to have the 64-bit long double version defining storage for -+ * __scanfdebug, to be compatible with 10.3. For ppc64 and i386, we want the -+ * storage defined in the only version. -+ */ -+#if defined(__ppc__) && !defined(BUILDING_VARIANT) -+extern int __scanfdebug; -+#else /* !__ppc__ || BUILDING_VARIANT */ - int __scanfdebug = 0; -+#endif /* __ppc__ && !BUILDING_VARIANT */ + #endif __weak_reference(__vfscanf, vfscanf); - -@@ -108,12 +122,24 @@ __weak_reference(__vfscanf, vfscanf); +@@ -104,12 +107,24 @@ __weak_reference(__vfscanf, vfscanf); * __vfscanf - MT-safe version */ int @@ -68,7 +56,7 @@ FUNLOCKFILE(fp); return (ret); } -@@ -121,8 +147,8 @@ __vfscanf(FILE *fp, char const *fmt0, va +@@ -117,8 +132,8 @@ __vfscanf(FILE *fp, char const *fmt0, va /* * __svfscanf - non-MT-safe version of __vfscanf */ @@ -79,7 +67,7 @@ { const u_char *fmt = (const u_char *)fmt0; int c; /* character from format, or conversion */ -@@ -132,7 +158,6 @@ __svfscanf(FILE *fp, const char *fmt0, v +@@ -128,36 +143,43 @@ __svfscanf(FILE *fp, const char *fmt0, v int flags; /* flags as defined above */ char *p0; /* saves original value of p when necessary */ int nassigned; /* number of fields assigned */ @@ -87,9 +75,8 @@ int nread; /* number of characters consumed from fp */ int base; /* base argument to conversion function */ char ccltab[256]; /* character class table for %[...] */ -@@ -140,29 +165,37 @@ __svfscanf(FILE *fp, const char *fmt0, v + char buf[BUF]; /* buffer for numeric and mb conversions */ wchar_t *wcp; /* handy wide character pointer */ - wchar_t *wcp0; /* saves original value of wcp */ size_t nconv; /* length of multibyte sequence converted */ + int index; /* %index$, zero if unset */ + va_list ap_orig; /* to reset ap to first argument */ @@ -129,7 +116,7 @@ width = 0; flags = 0; /* -@@ -172,15 +205,35 @@ __svfscanf(FILE *fp, const char *fmt0, v +@@ -167,15 +189,35 @@ __svfscanf(FILE *fp, const char *fmt0, v again: c = *fmt++; switch (c) { case '%': @@ -167,7 +154,7 @@ case '*': flags |= SUPPRESS; goto again; -@@ -267,7 +320,7 @@ literal: +@@ -262,7 +304,7 @@ literal: break; case '[': @@ -176,15 +163,48 @@ flags |= NOSKIP; c = CT_CCL; break; -@@ -288,7 +341,6 @@ literal: +@@ -283,27 +325,28 @@ literal: break; case 'n': - nconversions++; - if (flags & SUPPRESS) /* ??? */ +- if (flags & SUPPRESS) /* ??? */ ++ { ++ void *ptr = va_arg(ap, void *); ++ if ((ptr == NULL) || (flags & SUPPRESS)) /* ??? */ continue; - if (flags & SHORTSHORT) -@@ -330,7 +382,7 @@ literal: +- if (flags & SHORTSHORT) +- *va_arg(ap, char *) = nread; ++ else if (flags & SHORTSHORT) ++ *(char *)ptr = nread; + else if (flags & SHORT) +- *va_arg(ap, short *) = nread; ++ *(short *)ptr = nread; + else if (flags & LONG) +- *va_arg(ap, long *) = nread; ++ *(long *)ptr = nread; + else if (flags & LONGLONG) +- *va_arg(ap, long long *) = nread; ++ *(long long *)ptr = nread; + else if (flags & INTMAXT) +- *va_arg(ap, intmax_t *) = nread; ++ *(intmax_t *)ptr = nread; + else if (flags & SIZET) +- *va_arg(ap, size_t *) = nread; ++ *(size_t *)ptr = nread; + else if (flags & PTRDIFFT) +- *va_arg(ap, ptrdiff_t *) = nread; ++ *(ptrdiff_t *)ptr = nread; + else +- *va_arg(ap, int *) = nread; ++ *(int *)ptr = nread; + continue; +- ++ } + default: + goto match_failure; + +@@ -325,7 +368,7 @@ literal: * that suppress this. */ if ((flags & NOSKIP) == 0) { @@ -193,7 +213,7 @@ nread++; if (--fp->_r > 0) fp->_p++; -@@ -360,7 +412,7 @@ literal: +@@ -355,7 +398,7 @@ literal: wcp = NULL; n = 0; while (width != 0) { @@ -202,7 +222,7 @@ fp->_flags |= __SERR; goto input_failure; } -@@ -368,7 +420,7 @@ literal: +@@ -363,7 +406,7 @@ literal: fp->_p++; fp->_r--; mbs = initial; @@ -211,7 +231,7 @@ if (nconv == (size_t)-1) { fp->_flags |= __SERR; goto input_failure; -@@ -421,7 +473,6 @@ literal: +@@ -416,7 +459,6 @@ literal: nread += r; nassigned++; } @@ -219,7 +239,7 @@ break; case CT_CCL: -@@ -440,7 +491,7 @@ literal: +@@ -435,7 +477,7 @@ literal: n = 0; nchars = 0; while (width != 0) { @@ -228,7 +248,7 @@ fp->_flags |= __SERR; goto input_failure; } -@@ -448,7 +499,7 @@ literal: +@@ -443,7 +485,7 @@ literal: fp->_p++; fp->_r--; mbs = initial; @@ -237,7 +257,7 @@ if (nconv == (size_t)-1) { fp->_flags |= __SERR; goto input_failure; -@@ -456,8 +507,8 @@ literal: +@@ -451,8 +493,8 @@ literal: if (nconv == 0) *wcp = L'\0'; if (nconv != (size_t)-2) { @@ -248,7 +268,7 @@ while (n != 0) { n--; __ungetc(buf[n], -@@ -525,7 +576,6 @@ literal: +@@ -520,7 +562,6 @@ literal: nassigned++; } nread += n; @@ -256,7 +276,7 @@ break; case CT_STRING: -@@ -540,8 +590,8 @@ literal: +@@ -535,8 +576,8 @@ literal: else wcp = &twc; n = 0; @@ -267,7 +287,7 @@ fp->_flags |= __SERR; goto input_failure; } -@@ -549,7 +599,7 @@ literal: +@@ -544,7 +585,7 @@ literal: fp->_p++; fp->_r--; mbs = initial; @@ -276,7 +296,7 @@ if (nconv == (size_t)-1) { fp->_flags |= __SERR; goto input_failure; -@@ -557,7 +607,7 @@ literal: +@@ -552,7 +593,7 @@ literal: if (nconv == 0) *wcp = L'\0'; if (nconv != (size_t)-2) { @@ -285,7 +305,7 @@ while (n != 0) { n--; __ungetc(buf[n], -@@ -585,7 +635,7 @@ literal: +@@ -580,7 +621,7 @@ literal: } } else if (flags & SUPPRESS) { n = 0; @@ -294,7 +314,7 @@ n++, fp->_r--, fp->_p++; if (--width == 0) break; -@@ -595,7 +645,7 @@ literal: +@@ -590,7 +631,7 @@ literal: nread += n; } else { p0 = p = va_arg(ap, char *); @@ -303,7 +323,7 @@ fp->_r--; *p++ = *fp->_p++; if (--width == 0) -@@ -607,7 +657,6 @@ literal: +@@ -602,7 +643,6 @@ literal: nread += p - p0; nassigned++; } @@ -311,7 +331,7 @@ continue; case CT_INT: -@@ -738,9 +787,9 @@ literal: +@@ -733,9 +773,9 @@ literal: *p = 0; if ((flags & UNSIGNED) == 0) @@ -323,7 +343,7 @@ if (flags & POINTER) *va_arg(ap, void **) = (void *)(uintptr_t)res; -@@ -763,43 +812,48 @@ literal: +@@ -758,41 +798,46 @@ literal: nassigned++; } nread += p - buf; @@ -354,10 +374,6 @@ + float res = strtof_l(pbuf, &p, loc); *va_arg(ap, float *) = res; } -- if (__scanfdebug && p - buf != width) -- abort(); -+ if (__scanfdebug && p - pbuf != width) -+ LIBC_ABORT("p - pbuf %ld != width %ld", (long)(p - pbuf), width); nassigned++; } nread += width; @@ -383,7 +399,7 @@ /* * Fill in the given table from the scanset at the given format * (just after `['). Return a pointer to the character past the -@@ -807,9 +861,10 @@ match_failure: +@@ -800,9 +845,10 @@ match_failure: * considered part of the scanset. */ static const u_char * @@ -395,7 +411,7 @@ { int c, n, v, i; -@@ -845,6 +900,7 @@ doswitch: +@@ -838,6 +884,7 @@ doswitch: return (fmt - 1); case '-': @@ -403,7 +419,7 @@ /* * A scanset of the form * [01+-] -@@ -865,8 +921,8 @@ doswitch: +@@ -858,8 +905,8 @@ doswitch: */ n = *fmt; if (n == ']' @@ -414,7 +430,7 @@ ) ) { c = '-'; -@@ -874,14 +930,14 @@ doswitch: +@@ -867,14 +914,14 @@ doswitch: } fmt++; /* fill in the range */ @@ -432,7 +448,7 @@ ) tab[i] = v; } -@@ -901,7 +957,7 @@ doswitch: +@@ -894,7 +941,7 @@ doswitch: return (fmt); #endif break; @@ -441,7 +457,7 @@ case ']': /* end of scanset */ return (fmt); -@@ -914,19 +970,75 @@ doswitch: +@@ -907,8 +954,54 @@ doswitch: } #ifndef NO_FLOATING_POINT @@ -496,16 +512,13 @@ +parsefloat(FILE *fp, char **buf, size_t width, locale_t loc) { char *commit, *p; - int infnanpos = 0; - enum { - S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX, -- S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS -+ S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS, S_DECIMAL_POINT + int infnanpos = 0, decptpos = 0; +@@ -917,9 +1010,18 @@ parsefloat(FILE *fp, char *buf, char *en + S_DIGITS, S_DECPT, S_FRAC, S_EXP, S_EXPDIGITS } state = S_START; unsigned char c; -- char decpt = *localeconv()->decimal_point; -+ unsigned char *decpt = (unsigned char *)localeconv_l(loc)->decimal_point; -+ char *decpt_start; +- const char *decpt = localeconv()->decimal_point; ++ const char *decpt = localeconv_l(loc)->decimal_point; _Bool gotmantdig = 0, ishex = 0; - + char *b; @@ -521,7 +534,7 @@ /* * We set commit = p whenever the string we have read so far * constitutes a valid representation of a floating point -@@ -936,8 +1048,8 @@ parsefloat(FILE *fp, char *buf, char *en +@@ -929,8 +1031,8 @@ parsefloat(FILE *fp, char *buf, char *en * always necessary to read at least one character that doesn't * match; thus, we can't short-circuit "infinity" or "nan(...)". */ @@ -532,54 +545,25 @@ c = *fp->_p; reswitch: switch (state) { -@@ -997,7 +1109,7 @@ reswitch: +@@ -988,7 +1090,7 @@ reswitch: if (c == ')') { commit = p; - infnanpos = -2; + state = S_DONE; - } else if (!isalnum(c) && c != '_') + } else if (!isalnum_l(c, loc) && c != '_') goto parsedone; break; } -@@ -1013,16 +1125,33 @@ reswitch: +@@ -1006,7 +1108,7 @@ reswitch: goto reswitch; } case S_DIGITS: -- if ((ishex && isxdigit(c)) || isdigit(c)) -+ if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc)) +- if ((ishex && isxdigit(c)) || isdigit(c)) { ++ if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc)) { gotmantdig = 1; - else { -- state = S_FRAC; -- if (c != decpt) -- goto reswitch; -+ state = S_DECIMAL_POINT; -+ decpt_start = p; -+ goto reswitch; - } - if (gotmantdig) commit = p; - break; -+ case S_DECIMAL_POINT: -+ if (*decpt == 0) { -+ if (gotmantdig) -+ commit = p - 1; -+ state = S_FRAC; -+ goto reswitch; -+ } -+ if (*decpt++ == c) -+ break; -+ /* not decimal point */ -+ state = S_FRAC; -+ if (decpt_start == p) -+ goto reswitch; -+ while (decpt_start < --p) -+ __ungetc(*(u_char *)p, fp); -+ c = *(u_char *)p; -+ goto reswitch; - case S_FRAC: - if (((c == 'E' || c == 'e') && !ishex) || - ((c == 'P' || c == 'p') && ishex)) { -@@ -1030,7 +1159,7 @@ reswitch: + break; +@@ -1041,7 +1143,7 @@ reswitch: goto parsedone; else state = S_EXP; @@ -588,7 +572,7 @@ commit = p; gotmantdig = 1; } else -@@ -1043,13 +1172,26 @@ reswitch: +@@ -1054,13 +1156,26 @@ reswitch: else goto reswitch; case S_EXPDIGITS: @@ -617,7 +601,7 @@ } *p++ = c; if (--fp->_r > 0) -@@ -1062,6 +1204,7 @@ parsedone: +@@ -1073,6 +1188,7 @@ parsedone: while (commit < --p) __ungetc(*(u_char *)p, fp); *++commit = '\0'; diff --git a/stdio/FreeBSD/vfwprintf.c b/stdio/FreeBSD/vfwprintf.c index dd0693e..5e1c059 100644 --- a/stdio/FreeBSD/vfwprintf.c +++ b/stdio/FreeBSD/vfwprintf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #endif #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.23 2004/08/26 06:25:28 des Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.42 2009/11/25 04:27:55 wollman Exp $"); /* * Actual wprintf innards. @@ -68,56 +64,140 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.23 2004/08/26 06:25:28 de #include "libc_private.h" #include "local.h" #include "fvwrite.h" +#include "printflocal.h" -union arg { - int intarg; - u_int uintarg; - long longarg; - u_long ulongarg; - long long longlongarg; - unsigned long long ulonglongarg; - ptrdiff_t ptrdiffarg; - size_t sizearg; - intmax_t intmaxarg; - uintmax_t uintmaxarg; - void *pvoidarg; - char *pchararg; - signed char *pschararg; - short *pshortarg; - int *pintarg; - long *plongarg; - long long *plonglongarg; - ptrdiff_t *pptrdiffarg; - size_t *psizearg; - intmax_t *pintmaxarg; -#ifndef NO_FLOATING_POINT - double doublearg; - long double longdoublearg; -#endif - wint_t wintarg; - wchar_t *pwchararg; +static int __sprint(FILE *, struct __suio *); +static int __sbprintf(FILE *, const wchar_t *, va_list) __noinline; +static wint_t __xfputwc(wchar_t, FILE *); +static wchar_t *__mbsconv(char *, int); + +#define CHAR wchar_t +#include "printfcommon.h" + +struct grouping_state { + wchar_t thousands_sep; /* locale-specific thousands separator */ + const char *grouping; /* locale-specific numeric grouping rules */ + int lead; /* sig figs before decimal or group sep */ + int nseps; /* number of group separators with ' */ + int nrepeats; /* number of repeats of the last group */ }; +static const mbstate_t initial_mbs; + +static inline wchar_t +get_decpt(void) +{ + mbstate_t mbs; + wchar_t decpt; + int nconv; + + mbs = initial_mbs; + nconv = mbrtowc(&decpt, localeconv()->decimal_point, MB_CUR_MAX, &mbs); + if (nconv == (size_t)-1 || nconv == (size_t)-2) + decpt = '.'; /* failsafe */ + return (decpt); +} + +static inline wchar_t +get_thousep(void) +{ + mbstate_t mbs; + wchar_t thousep; + int nconv; + + mbs = initial_mbs; + nconv = mbrtowc(&thousep, localeconv()->thousands_sep, + MB_CUR_MAX, &mbs); + if (nconv == (size_t)-1 || nconv == (size_t)-2) + thousep = '\0'; /* failsafe */ + return (thousep); +} + /* - * Type ids for argument type table. + * Initialize the thousands' grouping state in preparation to print a + * number with ndigits digits. This routine returns the total number + * of wide characters that will be printed. */ -enum typeid { - T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, - T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, - T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, - T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, - T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR -}; +static int +grouping_init(struct grouping_state *gs, int ndigits) +{ -static int __sbprintf(FILE *, const wchar_t *, va_list); -static wint_t __xfputwc(wchar_t, FILE *); -static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int, - char, const char *); -static wchar_t *__ultoa(u_long, wchar_t *, int, int, const char *, int, - char, const char *); -static wchar_t *__mbsconv(char *, int); -static void __find_arguments(const wchar_t *, va_list, union arg **); -static void __grow_type_table(int, enum typeid **, int *); + gs->grouping = localeconv()->grouping; + gs->thousands_sep = get_thousep(); + + gs->nseps = gs->nrepeats = 0; + gs->lead = ndigits; + while (*gs->grouping != CHAR_MAX) { + if (gs->lead <= *gs->grouping) + break; + gs->lead -= *gs->grouping; + if (*(gs->grouping+1)) { + gs->nseps++; + gs->grouping++; + } else + gs->nrepeats++; + } + return (gs->nseps + gs->nrepeats); +} + +/* + * Print a number with thousands' separators. + */ +static int +grouping_print(struct grouping_state *gs, struct io_state *iop, + const CHAR *cp, const CHAR *ep) +{ + const CHAR *cp0 = cp; + + if (io_printandpad(iop, cp, ep, gs->lead, zeroes)) + return (-1); + cp += gs->lead; + while (gs->nseps > 0 || gs->nrepeats > 0) { + if (gs->nrepeats > 0) + gs->nrepeats--; + else { + gs->grouping--; + gs->nseps--; + } + if (io_print(iop, &gs->thousands_sep, 1)) + return (-1); + if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes)) + return (-1); + cp += *gs->grouping; + } + if (cp > ep) + cp = ep; + return (cp - cp0); +} + + +/* + * Flush out all the vectors defined by the given uio, + * then reset it so that it can be reused. + * + * XXX The fact that we do this a character at a time and convert to a + * multibyte character sequence even if the destination is a wide + * string eclipses the benefits of buffering. + */ +static int +__sprint(FILE *fp, struct __suio *uio) +{ + struct __siov *iov; + wchar_t *p; + int i, len; + + iov = uio->uio_iov; + for (; uio->uio_resid != 0; uio->uio_resid -= len, iov++) { + p = (wchar_t *)iov->iov_base; + len = iov->iov_len; + for (i = 0; i < len; i++) { + if (__xfputwc(p[i], fp) == WEOF) + return (-1); + } + } + uio->uio_iovcnt = 0; + return (0); +} /* * Helper function for `fprintf to unbuffered unix file': creates a @@ -131,12 +211,17 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap) FILE fake; unsigned char buf[BUFSIZ]; + /* XXX This is probably not needed. */ + if (prepwrite(fp) != 0) + return (EOF); + /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; - fake._extra = fp->_extra; + fake._orientation = fp->_orientation; + fake._mbstate = fp->_mbstate; /* set up the buffer */ fake._bf._base = fake._p = buf; @@ -159,7 +244,6 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap) static wint_t __xfputwc(wchar_t wc, FILE *fp) { - static const mbstate_t initial; mbstate_t mbs; char buf[MB_LEN_MAX]; struct __suio uio; @@ -169,7 +253,7 @@ __xfputwc(wchar_t wc, FILE *fp) if ((fp->_flags & __SSTR) == 0) return (__fputwc(wc, fp)); - mbs = initial; + mbs = initial_mbs; if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); @@ -182,167 +266,6 @@ __xfputwc(wchar_t wc, FILE *fp) return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : WEOF); } -/* - * Macros for converting digits to letters and vice versa - */ -#define to_digit(c) ((c) - '0') -#define is_digit(c) ((unsigned)to_digit(c) <= 9) -#define to_char(n) ((n) + '0') - -/* - * Convert an unsigned long to ASCII for printf purposes, returning - * a pointer to the first character of the string representation. - * Octal numbers can be forced to have a leading zero; hex numbers - * use the given digits. - */ -static wchar_t * -__ultoa(u_long val, wchar_t *endp, int base, int octzero, const char *xdigs, - int needgrp, char thousep, const char *grp) -{ - wchar_t *cp = endp; - long sval; - int ndig; - - /* - * Handle the three cases separately, in the hope of getting - * better/faster code. - */ - switch (base) { - case 10: - if (val < 10) { /* many numbers are 1 digit */ - *--cp = to_char(val); - return (cp); - } - ndig = 0; - /* - * On many machines, unsigned arithmetic is harder than - * signed arithmetic, so we do at most one unsigned mod and - * divide; this is sufficient to reduce the range of - * the incoming value to where signed arithmetic works. - */ - if (val > LONG_MAX) { - *--cp = to_char(val % 10); - ndig++; - sval = val / 10; - } else - sval = val; - do { - *--cp = to_char(sval % 10); - ndig++; - /* - * If (*grp == CHAR_MAX) then no more grouping - * should be performed. - */ - if (needgrp && ndig == *grp && *grp != CHAR_MAX - && sval > 9) { - *--cp = thousep; - ndig = 0; - /* - * If (*(grp+1) == '\0') then we have to - * use *grp character (last grouping rule) - * for all next cases - */ - if (*(grp+1) != '\0') - grp++; - } - sval /= 10; - } while (sval != 0); - break; - - case 8: - do { - *--cp = to_char(val & 7); - val >>= 3; - } while (val); - if (octzero && *cp != '0') - *--cp = '0'; - break; - - case 16: - do { - *--cp = xdigs[val & 15]; - val >>= 4; - } while (val); - break; - - default: /* oops */ - abort(); - } - return (cp); -} - -/* Identical to __ultoa, but for intmax_t. */ -static wchar_t * -__ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, - const char *xdigs, int needgrp, char thousep, const char *grp) -{ - wchar_t *cp = endp; - intmax_t sval; - int ndig; - - /* quick test for small values; __ultoa is typically much faster */ - /* (perhaps instead we should run until small, then call __ultoa?) */ - if (val <= ULONG_MAX) - return (__ultoa((u_long)val, endp, base, octzero, xdigs, - needgrp, thousep, grp)); - switch (base) { - case 10: - if (val < 10) { - *--cp = to_char(val % 10); - return (cp); - } - ndig = 0; - if (val > INTMAX_MAX) { - *--cp = to_char(val % 10); - ndig++; - sval = val / 10; - } else - sval = val; - do { - *--cp = to_char(sval % 10); - ndig++; - /* - * If (*grp == CHAR_MAX) then no more grouping - * should be performed. - */ - if (needgrp && *grp != CHAR_MAX && ndig == *grp - && sval > 9) { - *--cp = thousep; - ndig = 0; - /* - * If (*(grp+1) == '\0') then we have to - * use *grp character (last grouping rule) - * for all next cases - */ - if (*(grp+1) != '\0') - grp++; - } - sval /= 10; - } while (sval != 0); - break; - - case 8: - do { - *--cp = to_char(val & 7); - val >>= 3; - } while (val); - if (octzero && *cp != '0') - *--cp = '0'; - break; - - case 16: - do { - *--cp = xdigs[val & 15]; - val >>= 4; - } while (val); - break; - - default: - abort(); - } - return (cp); -} - /* * Convert a multibyte character string argument for the %s format to a wide * string representation. ``prec'' specifies the maximum number of bytes @@ -352,7 +275,6 @@ __ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, static wchar_t * __mbsconv(char *mbsarg, int prec) { - static const mbstate_t initial; mbstate_t mbs; wchar_t *convbuf, *wcp; const char *p; @@ -371,8 +293,8 @@ __mbsconv(char *mbsarg, int prec) * number of characters to print. */ p = mbsarg; - insize = nchars = 0; - mbs = initial; + insize = nchars = nconv = 0; + mbs = initial_mbs; while (nchars != (size_t)prec) { nconv = mbrlen(p, MB_CUR_MAX, &mbs); if (nconv == 0 || nconv == (size_t)-1 || @@ -384,8 +306,10 @@ __mbsconv(char *mbsarg, int prec) } if (nconv == (size_t)-1 || nconv == (size_t)-2) return (NULL); - } else + } else { insize = strlen(mbsarg); + nconv = 0; + } /* * Allocate buffer for the result and perform the conversion, @@ -397,7 +321,7 @@ __mbsconv(char *mbsarg, int prec) return (NULL); wcp = convbuf; p = mbsarg; - mbs = initial; + mbs = initial_mbs; while (insize != 0) { nconv = mbrtowc(wcp, p, insize, &mbs); if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) @@ -425,55 +349,26 @@ vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) int ret; FLOCKFILE(fp); - ret = __vfwprintf(fp, fmt0, ap); + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) + ret = __sbprintf(fp, fmt0, ap); + else + ret = __vfwprintf(fp, fmt0, ap); FUNLOCKFILE(fp); return (ret); } -#ifndef NO_FLOATING_POINT - -#define dtoa __dtoa -#define freedtoa __freedtoa - -#include -#include -#include "floatio.h" -#include "gdtoa.h" - -#define DEFPREC 6 - -static int exponent(wchar_t *, int, wchar_t); - -#endif /* !NO_FLOATING_POINT */ - /* * The size of the buffer we use as scratch space for integer - * conversions, among other things. Technically, we would need the - * most space for base 10 conversions with thousands' grouping - * characters between each pair of digits. 100 bytes is a - * conservative overestimate even for a 128-bit uintmax_t. - */ -#define BUF 100 - -#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ - -/* - * Flags used during conversion. + * conversions, among other things. We need enough space to + * write a uintmax_t in octal (plus one byte). */ -#define ALT 0x001 /* alternate form */ -#define LADJUST 0x004 /* left adjustment */ -#define LONGDBL 0x008 /* long double */ -#define LONGINT 0x010 /* long integer */ -#define LLONGINT 0x020 /* long long integer */ -#define SHORTINT 0x040 /* short integer */ -#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ -#define FPT 0x100 /* Floating point number */ -#define GROUPING 0x200 /* use grouping ("'" flag) */ - /* C99 additional size modifiers: */ -#define SIZET 0x400 /* size_t */ -#define PTRDIFFT 0x800 /* ptrdiff_t */ -#define INTMAXT 0x1000 /* intmax_t */ -#define CHARINT 0x2000 /* print char using int format */ +#if UINTMAX_MAX <= UINT64_MAX +#define BUF 32 +#else +#error "BUF must be large enough to format a uintmax_t" +#endif /* * Non-MT-safe version @@ -483,15 +378,14 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) { wchar_t *fmt; /* format string */ wchar_t ch; /* character from fmt */ - int n, n2, n3; /* handy integer (short term usage) */ + int n, n2; /* handy integer (short term usage) */ wchar_t *cp; /* handy char pointer (short term usage) */ int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format; <0 for N/A */ wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */ - char thousands_sep; /* locale specific thousands separator */ - const char *grouping; /* locale specific numeric grouping rules */ + struct grouping_state gs; /* thousands' grouping info */ #ifndef NO_FLOATING_POINT /* * We can decompose the printed representation of floating @@ -507,7 +401,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) * D: expchar holds this character; '\0' if no exponent, e.g. %f * F: at least two digits for decimal, at least one digit for hex */ - char *decimal_point; /* locale specific decimal point */ + wchar_t decimal_point; /* locale specific decimal point */ int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; @@ -517,12 +411,9 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) char expchar; /* exponent character: [eEpP\0] */ char *dtoaend; /* pointer to end of converted digits */ int expsize; /* character count for expstr */ - int lead; /* sig figs before decimal or group sep */ int ndig; /* actual number of digits returned by dtoa */ wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ char *dtoaresult; /* buffer allocated by dtoa */ - int nseps; /* number of group separators with ' */ - int nrepeats; /* number of repeats of the last group */ #endif u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ @@ -532,6 +423,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) int size; /* size of converted field or string */ int prsize; /* max size of printed field */ const char *xdigs; /* digits for [xX] conversion */ + struct io_state io; /* I/O buffering state */ wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */ wchar_t ox[2]; /* space for 0x hex-prefix */ union arg *argtable; /* args, built due to positional arg */ @@ -540,45 +432,26 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) va_list orgap; /* original argument pointer */ wchar_t *convbuf; /* multibyte to wide conversion result */ - /* - * Choose PADSIZE to trade efficiency vs. size. If larger printf - * fields occur frequently, increase PADSIZE and make the initialisers - * below longer. - */ -#define PADSIZE 16 /* pad chunk size */ - static wchar_t blanks[PADSIZE] = - {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; - static wchar_t zeroes[PADSIZE] = - {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; - static const char xdigs_lower[16] = "0123456789abcdef"; static const char xdigs_upper[16] = "0123456789ABCDEF"; - /* - * BEWARE, these `goto error' on error, PRINT uses `n2' and - * PAD uses `n'. - */ + /* BEWARE, these `goto error' on error. */ #define PRINT(ptr, len) do { \ - for (n3 = 0; n3 < (len); n3++) \ - __xfputwc((ptr)[n3], fp); \ -} while (0) -#define PAD(howmany, with) do { \ - if ((n = (howmany)) > 0) { \ - while (n > PADSIZE) { \ - PRINT(with, PADSIZE); \ - n -= PADSIZE; \ - } \ - PRINT(with, n); \ - } \ + if (io_print(&io, (ptr), (len))) \ + goto error; \ } while (0) -#define PRINTANDPAD(p, ep, len, with) do { \ - n2 = (ep) - (p); \ - if (n2 > (len)) \ - n2 = (len); \ - if (n2 > 0) \ - PRINT((p), n2); \ - PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ -} while(0) +#define PAD(howmany, with) { \ + if (io_pad(&io, (howmany), (with))) \ + goto error; \ +} +#define PRINTANDPAD(p, ep, len, with) { \ + if (io_printandpad(&io, (p), (ep), (len), (with))) \ + goto error; \ +} +#define FLUSH() { \ + if (io_flush(&io)) \ + goto error; \ +} /* * Get the argument indexed by nextarg. If the argument table is @@ -606,7 +479,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) #define SJARG() \ (flags&INTMAXT ? GETARG(intmax_t) : \ - flags&SIZET ? (intmax_t)GETARG(size_t) : \ + flags&SIZET ? (intmax_t)GETARG(ssize_t) : \ flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ (intmax_t)GETARG(long long)) #define UJARG() \ @@ -630,7 +503,10 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) int hold = nextarg; \ if (argtable == NULL) { \ argtable = statargtable; \ - __find_arguments (fmt0, orgap, &argtable); \ + if (__find_warguments (fmt0, orgap, &argtable)) { \ + ret = EOF; \ + goto error; \ + } \ } \ nextarg = n2; \ val = GETARG (int); \ @@ -641,26 +517,20 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) } - thousands_sep = '\0'; - grouping = NULL; -#ifndef NO_FLOATING_POINT - decimal_point = localeconv()->decimal_point; -#endif - convbuf = NULL; /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */ if (prepwrite(fp) != 0) return (EOF); - /* optimise fprintf(stderr) (and other unbuffered Unix files) */ - if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) - return (__sbprintf(fp, fmt0, ap)); - + convbuf = NULL; fmt = (wchar_t *)fmt0; argtable = NULL; nextarg = 1; va_copy(orgap, ap); + io_init(&io, fp); ret = 0; +#ifndef NO_FLOATING_POINT + decimal_point = get_decpt(); +#endif /* * Scan the format for conversions (`%' character). @@ -684,6 +554,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) dprec = 0; width = 0; prec = -1; + gs.grouping = NULL; sign = '\0'; ox[1] = '\0'; @@ -721,8 +592,6 @@ reswitch: switch (ch) { goto rflag; case '\'': flags |= GROUPING; - thousands_sep = *(localeconv()->thousands_sep); - grouping = localeconv()->grouping; goto rflag; case '.': if ((ch = *fmt++) == '*') { @@ -754,8 +623,11 @@ reswitch: switch (ch) { nextarg = n; if (argtable == NULL) { argtable = statargtable; - __find_arguments (fmt0, orgap, - &argtable); + if (__find_warguments (fmt0, orgap, + &argtable)) { + ret = EOF; + goto error; + } } goto rflag; } @@ -906,6 +778,7 @@ fp_common: } else cp = (ch >= 'a') ? L"inf" : L"INF"; size = 3; + flags &= ~ZEROPAD; break; } flags |= FPT; @@ -942,23 +815,8 @@ fp_common: /* space for decimal pt and following digits */ if (prec || flags & ALT) size += prec + 1; - if (grouping && expt > 0) { - /* space for thousands' grouping */ - nseps = nrepeats = 0; - lead = expt; - while (*grouping != CHAR_MAX) { - if (lead <= *grouping) - break; - lead -= *grouping; - if (*(grouping+1)) { - nseps++; - grouping++; - } else - nrepeats++; - } - size += nseps + nrepeats; - } else - lead = expt; + if ((flags & GROUPING) && expt > 0) + size += grouping_init(&gs, expt); } break; #endif /* !NO_FLOATING_POINT */ @@ -1032,23 +890,7 @@ fp_common: cp = convbuf; } } - - if (prec >= 0) { - /* - * can't use wcslen; can only look for the - * NUL in the first `prec' characters, and - * wcslen() will go further. - */ - wchar_t *p = wmemchr(cp, 0, (size_t)prec); - - if (p != NULL) { - size = p - cp; - if (size > prec) - size = prec; - } else - size = prec; - } else - size = wcslen(cp); + size = (prec >= 0) ? wcsnlen(cp, prec) : wcslen(cp); sign = '\0'; break; case 'U': @@ -1092,24 +934,28 @@ number: if ((dprec = prec) >= 0) * ``The result of converting a zero value with an * explicit precision of zero is no characters.'' * -- ANSI X3J11 + * + * ``The C Standard is clear enough as is. The call + * printf("%#.0o", 0) should print 0.'' + * -- Defect Report #151 */ cp = buf + BUF; if (flags & INTMAX_SIZE) { - if (ujval != 0 || prec != 0) + if (ujval != 0 || prec != 0 || + (flags & ALT && base == 8)) cp = __ujtoa(ujval, cp, base, - flags & ALT, xdigs, - flags & GROUPING, thousands_sep, - grouping); + flags & ALT, xdigs); } else { - if (ulval != 0 || prec != 0) + if (ulval != 0 || prec != 0 || + (flags & ALT && base == 8)) cp = __ultoa(ulval, cp, base, - flags & ALT, xdigs, - flags & GROUPING, thousands_sep, - grouping); + flags & ALT, xdigs); } size = buf + BUF - cp; if (size > BUF) /* should never happen */ abort(); + if ((flags & GROUPING) && size != 0) + size += grouping_init(&gs, size); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') @@ -1165,53 +1011,48 @@ number: if ((dprec = prec) >= 0) if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) PAD(width - realsz, zeroes); - /* leading zeroes from decimal precision */ - PAD(dprec - size, zeroes); - /* the string or number proper */ #ifndef NO_FLOATING_POINT if ((flags & FPT) == 0) { - PRINT(cp, size); +#endif + /* leading zeroes from decimal precision */ + PAD(dprec - size, zeroes); + if (gs.grouping) { + if (grouping_print(&gs, &io, cp, buf+BUF) < 0) + goto error; + } else { + PRINT(cp, size); + } +#ifndef NO_FLOATING_POINT } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { PRINT(zeroes, 1); if (prec || flags & ALT) - PRINT(decimal_point, 1); + PRINT(&decimal_point, 1); PAD(-expt, zeroes); /* already handled initial 0's */ prec += expt; } else { - PRINTANDPAD(cp, convbuf + ndig, lead, zeroes); - cp += lead; - if (grouping) { - while (nseps>0 || nrepeats>0) { - if (nrepeats > 0) - nrepeats--; - else { - grouping--; - nseps--; - } - PRINT(&thousands_sep, - 1); - PRINTANDPAD(cp, - convbuf + ndig, - *grouping, zeroes); - cp += *grouping; - } - if (cp > convbuf + ndig) - cp = convbuf + ndig; - } - if (prec || flags & ALT) { - buf[0] = *decimal_point; - PRINT(buf, 1); + if (gs.grouping) { + n = grouping_print(&gs, &io, + cp, convbuf + ndig); + if (n < 0) + goto error; + cp += n; + } else { + PRINTANDPAD(cp, convbuf + ndig, + expt, zeroes); + cp += expt; } + if (prec || flags & ALT) + PRINT(&decimal_point, 1); } PRINTANDPAD(cp, convbuf + ndig, prec, zeroes); } else { /* %[eE] or sufficiently long %[gG] */ if (prec > 1 || flags & ALT) { buf[0] = *cp++; - buf[1] = *decimal_point; + buf[1] = decimal_point; PRINT(buf, 2); PRINT(cp, ndig-1); PAD(prec - ndig, zeroes); @@ -1220,8 +1061,6 @@ number: if ((dprec = prec) >= 0) PRINT(expstr, expsize); } } -#else - PRINT(cp, size); #endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) @@ -1229,8 +1068,11 @@ number: if ((dprec = prec) >= 0) /* finally, adjust ret */ ret += prsize; + + FLUSH(); /* copy out the I/O vectors */ } done: + FLUSH(); error: va_end(orgap); if (convbuf != NULL) @@ -1242,399 +1084,3 @@ error: return (ret); /* NOTREACHED */ } - -/* - * Find all arguments when a positional parameter is encountered. Returns a - * table, indexed by argument number, of pointers to each arguments. The - * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. - * It will be replaces with a malloc-ed one if it overflows. - */ -static void -__find_arguments (const wchar_t *fmt0, va_list ap, union arg **argtable) -{ - wchar_t *fmt; /* format string */ - wchar_t ch; /* character from fmt */ - int n, n2; /* handy integer (short term usage) */ - wchar_t *cp; /* handy char pointer (short term usage) */ - int flags; /* flags as above */ - int width; /* width from format (%8d), or 0 */ - enum typeid *typetable; /* table of types */ - enum typeid stattypetable [STATIC_ARG_TBL_SIZE]; - int tablesize; /* current size of type table */ - int tablemax; /* largest used index in table */ - int nextarg; /* 1-based argument index */ - - /* - * Add an argument type to the table, expanding if necessary. - */ -#define ADDTYPE(type) \ - ((nextarg >= tablesize) ? \ - __grow_type_table(nextarg, &typetable, &tablesize) : (void)0, \ - (nextarg > tablemax) ? tablemax = nextarg : 0, \ - typetable[nextarg++] = type) - -#define ADDSARG() \ - ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \ - ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ - ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ - ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \ - ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT)))))) - -#define ADDUARG() \ - ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \ - ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ - ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ - ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \ - ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT)))))) - - /* - * Add * arguments to the type array. - */ -#define ADDASTER() \ - n2 = 0; \ - cp = fmt; \ - while (is_digit(*cp)) { \ - n2 = 10 * n2 + to_digit(*cp); \ - cp++; \ - } \ - if (*cp == '$') { \ - int hold = nextarg; \ - nextarg = n2; \ - ADDTYPE (T_INT); \ - nextarg = hold; \ - fmt = ++cp; \ - } else { \ - ADDTYPE (T_INT); \ - } - fmt = (wchar_t *)fmt0; - typetable = stattypetable; - tablesize = STATIC_ARG_TBL_SIZE; - tablemax = 0; - nextarg = 1; - for (n = 0; n < STATIC_ARG_TBL_SIZE; n++) - typetable[n] = T_UNUSED; - - /* - * Scan the format for conversions (`%' character). - */ - for (;;) { - for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) - /* void */; - if (ch == '\0') - goto done; - fmt++; /* skip over '%' */ - - flags = 0; - width = 0; - -rflag: ch = *fmt++; -reswitch: switch (ch) { - case ' ': - case '#': - goto rflag; - case '*': - ADDASTER (); - goto rflag; - case '-': - case '+': - case '\'': - goto rflag; - case '.': - if ((ch = *fmt++) == '*') { - ADDASTER (); - goto rflag; - } - while (is_digit(ch)) { - ch = *fmt++; - } - goto reswitch; - case '0': - goto rflag; - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - n = 0; - do { - n = 10 * n + to_digit(ch); - ch = *fmt++; - } while (is_digit(ch)); - if (ch == '$') { - nextarg = n; - goto rflag; - } - width = n; - goto reswitch; -#ifndef NO_FLOATING_POINT - case 'L': - flags |= LONGDBL; - goto rflag; -#endif - case 'h': - if (flags & SHORTINT) { - flags &= ~SHORTINT; - flags |= CHARINT; - } else - flags |= SHORTINT; - goto rflag; - case 'j': - flags |= INTMAXT; - goto rflag; - case 'l': - if (flags & LONGINT) { - flags &= ~LONGINT; - flags |= LLONGINT; - } else - flags |= LONGINT; - goto rflag; - case 'q': - flags |= LLONGINT; /* not necessarily */ - goto rflag; - case 't': - flags |= PTRDIFFT; - goto rflag; - case 'z': - flags |= SIZET; - goto rflag; - case 'C': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'c': - if (flags & LONGINT) - ADDTYPE(T_WINT); - else - ADDTYPE(T_INT); - break; - case 'D': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'd': - case 'i': - ADDSARG(); - break; -#ifndef NO_FLOATING_POINT - case 'a': - case 'A': - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - if (flags & LONGDBL) - ADDTYPE(T_LONG_DOUBLE); - else - ADDTYPE(T_DOUBLE); - break; -#endif /* !NO_FLOATING_POINT */ - case 'n': - if (flags & INTMAXT) - ADDTYPE(TP_INTMAXT); - else if (flags & PTRDIFFT) - ADDTYPE(TP_PTRDIFFT); - else if (flags & SIZET) - ADDTYPE(TP_SIZET); - else if (flags & LLONGINT) - ADDTYPE(TP_LLONG); - else if (flags & LONGINT) - ADDTYPE(TP_LONG); - else if (flags & SHORTINT) - ADDTYPE(TP_SHORT); - else if (flags & CHARINT) - ADDTYPE(TP_SCHAR); - else - ADDTYPE(TP_INT); - continue; /* no output */ - case 'O': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'o': - ADDUARG(); - break; - case 'p': - ADDTYPE(TP_VOID); - break; - case 'S': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 's': - if (flags & LONGINT) - ADDTYPE(TP_WCHAR); - else - ADDTYPE(TP_CHAR); - break; - case 'U': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'u': - case 'X': - case 'x': - ADDUARG(); - break; - default: /* "%?" prints ?, unless ? is NUL */ - if (ch == '\0') - goto done; - break; - } - } -done: - /* - * Build the argument table. - */ - if (tablemax >= STATIC_ARG_TBL_SIZE) { - *argtable = (union arg *) - malloc (sizeof (union arg) * (tablemax + 1)); - } - - (*argtable) [0].intarg = 0; - for (n = 1; n <= tablemax; n++) { - switch (typetable [n]) { - case T_UNUSED: /* whoops! */ - (*argtable) [n].intarg = va_arg (ap, int); - break; - case TP_SCHAR: - (*argtable) [n].pschararg = va_arg (ap, signed char *); - break; - case TP_SHORT: - (*argtable) [n].pshortarg = va_arg (ap, short *); - break; - case T_INT: - (*argtable) [n].intarg = va_arg (ap, int); - break; - case T_U_INT: - (*argtable) [n].uintarg = va_arg (ap, unsigned int); - break; - case TP_INT: - (*argtable) [n].pintarg = va_arg (ap, int *); - break; - case T_LONG: - (*argtable) [n].longarg = va_arg (ap, long); - break; - case T_U_LONG: - (*argtable) [n].ulongarg = va_arg (ap, unsigned long); - break; - case TP_LONG: - (*argtable) [n].plongarg = va_arg (ap, long *); - break; - case T_LLONG: - (*argtable) [n].longlongarg = va_arg (ap, long long); - break; - case T_U_LLONG: - (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); - break; - case TP_LLONG: - (*argtable) [n].plonglongarg = va_arg (ap, long long *); - break; - case T_PTRDIFFT: - (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); - break; - case TP_PTRDIFFT: - (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); - break; - case T_SIZET: - (*argtable) [n].sizearg = va_arg (ap, size_t); - break; - case TP_SIZET: - (*argtable) [n].psizearg = va_arg (ap, ssize_t *); - break; - case T_INTMAXT: - (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); - break; - case T_UINTMAXT: - (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); - break; - case TP_INTMAXT: - (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); - break; -#ifndef NO_FLOATING_POINT - case T_DOUBLE: - (*argtable) [n].doublearg = va_arg (ap, double); - break; - case T_LONG_DOUBLE: - (*argtable) [n].longdoublearg = va_arg (ap, long double); - break; -#endif - case TP_CHAR: - (*argtable) [n].pchararg = va_arg (ap, char *); - break; - case TP_VOID: - (*argtable) [n].pvoidarg = va_arg (ap, void *); - break; - case T_WINT: - (*argtable) [n].wintarg = va_arg (ap, wint_t); - break; - case TP_WCHAR: - (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); - break; - } - } - - if ((typetable != NULL) && (typetable != stattypetable)) - free (typetable); -} - -/* - * Increase the size of the type table. - */ -static void -__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) -{ - enum typeid *const oldtable = *typetable; - const int oldsize = *tablesize; - enum typeid *newtable; - int n, newsize = oldsize * 2; - - if (newsize < nextarg + 1) - newsize = nextarg + 1; - if (oldsize == STATIC_ARG_TBL_SIZE) { - if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL) - abort(); /* XXX handle better */ - bcopy(oldtable, newtable, oldsize * sizeof(enum typeid)); - } else { - newtable = reallocf(oldtable, newsize * sizeof(enum typeid)); - if (newtable == NULL) - abort(); /* XXX handle better */ - } - for (n = oldsize; n < newsize; n++) - newtable[n] = T_UNUSED; - - *typetable = newtable; - *tablesize = newsize; -} - - -#ifndef NO_FLOATING_POINT - -static int -exponent(wchar_t *p0, int exp, wchar_t fmtch) -{ - wchar_t *p, *t; - wchar_t expbuf[MAXEXPDIG]; - - p = p0; - *p++ = fmtch; - if (exp < 0) { - exp = -exp; - *p++ = '-'; - } - else - *p++ = '+'; - t = expbuf + MAXEXPDIG; - if (exp > 9) { - do { - *--t = to_char(exp % 10); - } while ((exp /= 10) > 9); - *--t = to_char(exp); - for (; t < expbuf + MAXEXPDIG; *p++ = *t++); - } - else { - /* - * Exponents for decimal floating point conversions - * (%[eEgG]) must be at least two characters long, - * whereas exponents for hexadecimal conversions can - * be only one character long. - */ - if (fmtch == 'e' || fmtch == 'E') - *p++ = '0'; - *p++ = to_char(exp); - } - return (p - p0); -} -#endif /* !NO_FLOATING_POINT */ diff --git a/stdio/FreeBSD/vfwprintf.c.patch b/stdio/FreeBSD/vfwprintf.c.patch index 06dcee8..ac8b4e2 100644 --- a/stdio/FreeBSD/vfwprintf.c.patch +++ b/stdio/FreeBSD/vfwprintf.c.patch @@ -1,15 +1,15 @@ ---- vfwprintf.c.orig 2008-09-07 11:37:54.000000000 -0700 -+++ vfwprintf.c 2008-09-07 17:47:18.000000000 -0700 -@@ -42,6 +42,8 @@ static char sccsid[] = "@(#)vfprintf.c 8 +--- vfwprintf.c.orig 2010-07-15 10:03:36.000000000 -0700 ++++ vfwprintf.c 2010-07-15 10:49:02.000000000 -0700 +@@ -38,6 +38,8 @@ static char sccsid[] = "@(#)vfprintf.c 8 #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.23 2004/08/26 06:25:28 des Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.42 2009/11/25 04:27:55 wollman Exp $"); +#include "xlocale_private.h" + /* * Actual wprintf innards. * -@@ -63,12 +65,20 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v +@@ -59,6 +61,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v #include #include #include @@ -17,66 +17,117 @@ #include "un-namespace.h" #include "libc_private.h" - #include "local.h" +@@ -66,10 +69,11 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v #include "fvwrite.h" + #include "printflocal.h" -+#ifdef VECTORS -+typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE; -+#ifdef __SSE2__ -+#define V64TYPE -+#endif /* __SSE2__ */ -+#endif /* VECTORS */ -+ - union arg { - int intarg; - u_int uintarg; -@@ -96,6 +106,21 @@ union arg { - #endif - wint_t wintarg; - wchar_t *pwchararg; -+#ifdef VECTORS -+ VECTORTYPE vectorarg; -+ unsigned char vuchararg[16]; -+ signed char vchararg[16]; -+ unsigned short vushortarg[8]; -+ signed short vshortarg[8]; -+ unsigned int vuintarg[4]; -+ signed int vintarg[4]; -+ float vfloatarg[4]; -+#ifdef V64TYPE -+ double vdoublearg[2]; -+ unsigned long long vulonglongarg[2]; -+ long long vlonglongarg[2]; -+#endif /* V64TYPE */ -+#endif /* VECTORS */ - }; - - /* -@@ -106,16 +131,20 @@ enum typeid { - T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, - T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, - T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, -+#ifdef VECTORS -+ T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR -+#else /* ! VECTORS */ - T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR -+#endif /* VECTORS */ - }; - --static int __sbprintf(FILE *, const wchar_t *, va_list); +-static int __sprint(FILE *, struct __suio *); +-static int __sbprintf(FILE *, const wchar_t *, va_list) __noinline; -static wint_t __xfputwc(wchar_t, FILE *); +-static wchar_t *__mbsconv(char *, int); ++static int __sprint(FILE *, locale_t, struct __suio *); +static int __sbprintf(FILE *, locale_t, const wchar_t *, va_list); +static wint_t __xfputwc(wchar_t, FILE *, locale_t); - static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int, - char, const char *); - static wchar_t *__ultoa(u_long, wchar_t *, int, int, const char *, int, - char, const char *); --static wchar_t *__mbsconv(char *, int); +static wchar_t *__mbsconv(char *, int, locale_t); - static void __find_arguments(const wchar_t *, va_list, union arg **); - static void __grow_type_table(int, enum typeid **, int *); ++__private_extern__ const char *__fix_nogrouping(const char *); -@@ -125,7 +154,7 @@ static void __grow_type_table(int, enum + #define CHAR wchar_t + #include "printfcommon.h" +@@ -85,29 +89,29 @@ struct grouping_state { + static const mbstate_t initial_mbs; + + static inline wchar_t +-get_decpt(void) ++get_decpt(locale_t loc) + { + mbstate_t mbs; + wchar_t decpt; + int nconv; + + mbs = initial_mbs; +- nconv = mbrtowc(&decpt, localeconv()->decimal_point, MB_CUR_MAX, &mbs); ++ nconv = mbrtowc_l(&decpt, localeconv_l(loc)->decimal_point, MB_CUR_MAX_L(loc), &mbs, loc); + if (nconv == (size_t)-1 || nconv == (size_t)-2) + decpt = '.'; /* failsafe */ + return (decpt); + } + + static inline wchar_t +-get_thousep(void) ++get_thousep(locale_t loc) + { + mbstate_t mbs; + wchar_t thousep; + int nconv; + + mbs = initial_mbs; +- nconv = mbrtowc(&thousep, localeconv()->thousands_sep, +- MB_CUR_MAX, &mbs); ++ nconv = mbrtowc_l(&thousep, localeconv_l(loc)->thousands_sep, ++ MB_CUR_MAX_L(loc), &mbs, loc); + if (nconv == (size_t)-1 || nconv == (size_t)-2) + thousep = '\0'; /* failsafe */ + return (thousep); +@@ -119,11 +123,11 @@ get_thousep(void) + * of wide characters that will be printed. + */ + static int +-grouping_init(struct grouping_state *gs, int ndigits) ++grouping_init(struct grouping_state *gs, int ndigits, locale_t loc) + { + +- gs->grouping = localeconv()->grouping; +- gs->thousands_sep = get_thousep(); ++ gs->grouping = __fix_nogrouping(localeconv_l(loc)->grouping); ++ gs->thousands_sep = get_thousep(loc); + + gs->nseps = gs->nrepeats = 0; + gs->lead = ndigits; +@@ -145,11 +149,11 @@ grouping_init(struct grouping_state *gs, + */ + static int + grouping_print(struct grouping_state *gs, struct io_state *iop, +- const CHAR *cp, const CHAR *ep) ++ const CHAR *cp, const CHAR *ep, locale_t loc) + { + const CHAR *cp0 = cp; + +- if (io_printandpad(iop, cp, ep, gs->lead, zeroes)) ++ if (io_printandpad(iop, cp, ep, gs->lead, zeroes, loc)) + return (-1); + cp += gs->lead; + while (gs->nseps > 0 || gs->nrepeats > 0) { +@@ -159,9 +163,9 @@ grouping_print(struct grouping_state *gs + gs->grouping--; + gs->nseps--; + } +- if (io_print(iop, &gs->thousands_sep, 1)) ++ if (io_print(iop, &gs->thousands_sep, 1, loc)) + return (-1); +- if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes)) ++ if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes, loc)) + return (-1); + cp += *gs->grouping; + } +@@ -180,7 +184,7 @@ grouping_print(struct grouping_state *gs + * string eclipses the benefits of buffering. + */ + static int +-__sprint(FILE *fp, struct __suio *uio) ++__sprint(FILE *fp, locale_t loc, struct __suio *uio) + { + struct __siov *iov; + wchar_t *p; +@@ -191,7 +195,7 @@ __sprint(FILE *fp, struct __suio *uio) + p = (wchar_t *)iov->iov_base; + len = iov->iov_len; + for (i = 0; i < len; i++) { +- if (__xfputwc(p[i], fp) == WEOF) ++ if (__xfputwc(p[i], fp, loc) == WEOF) + return (-1); + } + } +@@ -205,11 +209,14 @@ __sprint(FILE *fp, struct __suio *uio) * worries about ungetc buffers and so forth. */ static int @@ -85,7 +136,14 @@ { int ret; FILE fake; -@@ -144,7 +173,7 @@ __sbprintf(FILE *fp, const wchar_t *fmt, + unsigned char buf[BUFSIZ]; ++ struct __sFILEX ext; ++ fake._extra = &ext; ++ INITEXTRA(&fake); + + /* XXX This is probably not needed. */ + if (prepwrite(fp) != 0) +@@ -229,7 +236,7 @@ __sbprintf(FILE *fp, const wchar_t *fmt, fake._lbfsize = 0; /* not actually used, but Just In Case */ /* do the work, then copy any error status */ @@ -94,54 +152,35 @@ if (ret >= 0 && __fflush(&fake)) ret = WEOF; if (fake._flags & __SERR) -@@ -157,7 +186,7 @@ __sbprintf(FILE *fp, const wchar_t *fmt, +@@ -242,7 +249,7 @@ __sbprintf(FILE *fp, const wchar_t *fmt, * File must already be locked. */ static wint_t -__xfputwc(wchar_t wc, FILE *fp) +__xfputwc(wchar_t wc, FILE *fp, locale_t loc) { - static const mbstate_t initial; mbstate_t mbs; -@@ -167,10 +196,10 @@ __xfputwc(wchar_t wc, FILE *fp) + char buf[MB_LEN_MAX]; +@@ -251,10 +258,10 @@ __xfputwc(wchar_t wc, FILE *fp) size_t len; if ((fp->_flags & __SSTR) == 0) - return (__fputwc(wc, fp)); + return (__fputwc(wc, fp, loc)); - mbs = initial; + mbs = initial_mbs; - if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) { + if ((len = wcrtomb_l(buf, wc, &mbs, loc)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); } -@@ -266,7 +295,7 @@ __ultoa(u_long val, wchar_t *endp, int b - break; - - default: /* oops */ -- abort(); -+ LIBC_ABORT("base = %d", base); - } - return (cp); - } -@@ -338,7 +367,7 @@ __ujtoa(uintmax_t val, wchar_t *endp, in - break; - - default: -- abort(); -+ LIBC_ABORT("base = %d", base); - } - return (cp); - } -@@ -350,13 +379,14 @@ __ujtoa(uintmax_t val, wchar_t *endp, in +@@ -273,12 +280,13 @@ __xfputwc(wchar_t wc, FILE *fp) * that the multibyte char. string ends in a null character. */ static wchar_t * -__mbsconv(char *mbsarg, int prec) +__mbsconv(char *mbsarg, int prec, locale_t loc) { - static const mbstate_t initial; mbstate_t mbs; wchar_t *convbuf, *wcp; const char *p; @@ -151,64 +190,58 @@ if (mbsarg == NULL) return (NULL); -@@ -374,7 +404,7 @@ __mbsconv(char *mbsarg, int prec) - insize = nchars = 0; - mbs = initial; +@@ -296,7 +304,7 @@ __mbsconv(char *mbsarg, int prec) + insize = nchars = nconv = 0; + mbs = initial_mbs; while (nchars != (size_t)prec) { - nconv = mbrlen(p, MB_CUR_MAX, &mbs); + nconv = mbrlen_l(p, mb_cur_max, &mbs, loc); if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) break; -@@ -399,7 +429,7 @@ __mbsconv(char *mbsarg, int prec) +@@ -323,7 +331,7 @@ __mbsconv(char *mbsarg, int prec) p = mbsarg; - mbs = initial; + mbs = initial_mbs; while (insize != 0) { - nconv = mbrtowc(wcp, p, insize, &mbs); + nconv = mbrtowc_l(wcp, p, insize, &mbs, loc); if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) break; wcp++; -@@ -418,6 +448,8 @@ __mbsconv(char *mbsarg, int prec) - /* +@@ -343,22 +351,28 @@ __mbsconv(char *mbsarg, int prec) * MT-safe version */ -+__private_extern__ const char *__fix_nogrouping(const char *); -+ int - vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) - -@@ -425,7 +457,21 @@ vfwprintf(FILE * __restrict fp, const wc +-vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) +- ++vfwprintf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt0, va_list ap) + { int ret; - FLOCKFILE(fp); -- ret = __vfwprintf(fp, fmt0, ap); -+ ret = __vfwprintf(fp, __current_locale(), fmt0, ap); -+ FUNLOCKFILE(fp); -+ return (ret); -+} -+ -+int -+vfwprintf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt0, -+ va_list ap) -+ -+{ -+ int ret; -+ + NORMALIZE_LOCALE(loc); -+ FLOCKFILE(fp); -+ ret = __vfwprintf(fp, loc, fmt0, ap); + FLOCKFILE(fp); + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) +- ret = __sbprintf(fp, fmt0, ap); ++ ret = __sbprintf(fp, loc, fmt0, ap); + else +- ret = __vfwprintf(fp, fmt0, ap); ++ ret = __vfwprintf(fp, loc, fmt0, ap); FUNLOCKFILE(fp); return (ret); } -@@ -474,12 +520,15 @@ static int exponent(wchar_t *, int, wcha - #define PTRDIFFT 0x800 /* ptrdiff_t */ - #define INTMAXT 0x1000 /* intmax_t */ - #define CHARINT 0x2000 /* print char using int format */ -+#ifdef VECTORS -+#define VECTOR 0x4000 /* Altivec or SSE vector */ -+#endif /* VECTORS */ ++int ++vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) ++{ ++ return vfwprintf_l(fp, __current_locale(), fmt0, ap); ++} ++ + /* + * The size of the buffer we use as scratch space for integer + * conversions, among other things. We need enough space to +@@ -373,8 +387,8 @@ vfwprintf(FILE * __restrict fp, const wc /* * Non-MT-safe version */ @@ -219,19 +252,9 @@ { wchar_t *fmt; /* format string */ wchar_t ch; /* character from fmt */ -@@ -507,7 +556,8 @@ __vfwprintf(FILE *fp, const wchar_t *fmt - * D: expchar holds this character; '\0' if no exponent, e.g. %f - * F: at least two digits for decimal, at least one digit for hex - */ -- char *decimal_point; /* locale specific decimal point */ -+ wchar_t decimal_point; /* locale specific decimal point */ -+ char *decimal_point_mb; /* multibyte decimal point */ - int signflag; /* true if float is negative */ - union { /* floating point arguments %[aAeEfFgG] */ - double dbl; -@@ -524,6 +574,11 @@ __vfwprintf(FILE *fp, const wchar_t *fmt - int nseps; /* number of group separators with ' */ - int nrepeats; /* number of repeats of the last group */ +@@ -415,6 +429,11 @@ __vfwprintf(FILE *fp, const wchar_t *fmt + wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ + char *dtoaresult; /* buffer allocated by dtoa */ #endif +#ifdef VECTORS + union arg vval; /* Vector argument. */ @@ -241,44 +264,42 @@ u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ -@@ -560,7 +615,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt - */ +@@ -437,19 +456,19 @@ __vfwprintf(FILE *fp, const wchar_t *fmt + + /* BEWARE, these `goto error' on error. */ #define PRINT(ptr, len) do { \ - for (n3 = 0; n3 < (len); n3++) \ -- __xfputwc((ptr)[n3], fp); \ -+ __xfputwc((ptr)[n3], fp, loc); \ +- if (io_print(&io, (ptr), (len))) \ ++ if (io_print(&io, (ptr), (len), loc)) \ + goto error; \ } while (0) - #define PAD(howmany, with) do { \ - if ((n = (howmany)) > 0) { \ -@@ -606,13 +661,13 @@ __vfwprintf(FILE *fp, const wchar_t *fmt - #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) - #define SJARG() \ - (flags&INTMAXT ? GETARG(intmax_t) : \ -- flags&SIZET ? (intmax_t)GETARG(size_t) : \ -+ flags&SIZET ? (intmax_t)GETARG(ssize_t) : \ - flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ - (intmax_t)GETARG(long long)) + #define PAD(howmany, with) { \ +- if (io_pad(&io, (howmany), (with))) \ ++ if (io_pad(&io, (howmany), (with), loc)) \ + goto error; \ + } + #define PRINTANDPAD(p, ep, len, with) { \ +- if (io_printandpad(&io, (p), (ep), (len), (with))) \ ++ if (io_printandpad(&io, (p), (ep), (len), (with), loc)) \ + goto error; \ + } + #define FLUSH() { \ +- if (io_flush(&io)) \ ++ if (io_flush(&io, loc)) \ + goto error; \ + } + +@@ -485,7 +504,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt #define UJARG() \ (flags&INTMAXT ? GETARG(uintmax_t) : \ flags&SIZET ? (uintmax_t)GETARG(size_t) : \ - flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ -+ flags&PTRDIFFT ? (uintmax_t)(unsigned)GETARG(ptrdiff_t) : \ ++ flags&PTRDIFFT ? (uintmax_t)(unsigned long)GETARG(ptrdiff_t) : \ (uintmax_t)GETARG(unsigned long long)) /* -@@ -640,21 +695,24 @@ __vfwprintf(FILE *fp, const wchar_t *fmt - val = GETARG (int); \ - } +@@ -518,8 +537,11 @@ __vfwprintf(FILE *fp, const wchar_t *fmt + -- - thousands_sep = '\0'; - grouping = NULL; - #ifndef NO_FLOATING_POINT -- decimal_point = localeconv()->decimal_point; -+ decimal_point_mb = localeconv_l(loc)->decimal_point; -+ mbtowc_l(&decimal_point, decimal_point_mb, strlen(decimal_point_mb), loc); - #endif - convbuf = NULL; /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */ - if (prepwrite(fp) != 0) + if (prepwrite(fp) != 0) { @@ -287,15 +308,18 @@ + } + ORIENT(fp, 1); - /* optimise fprintf(stderr) (and other unbuffered Unix files) */ - if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) -- return (__sbprintf(fp, fmt0, ap)); -+ return (__sbprintf(fp, loc, fmt0, ap)); - + convbuf = NULL; fmt = (wchar_t *)fmt0; - argtable = NULL; -@@ -678,6 +736,9 @@ __vfwprintf(FILE *fp, const wchar_t *fmt +@@ -529,7 +551,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt + io_init(&io, fp); + ret = 0; + #ifndef NO_FLOATING_POINT +- decimal_point = get_decpt(); ++ decimal_point = get_decpt(loc); + #endif + + /* +@@ -548,6 +570,9 @@ __vfwprintf(FILE *fp, const wchar_t *fmt } if (ch == '\0') goto done; @@ -305,8 +329,8 @@ fmt++; /* skip over '%' */ flags = 0; -@@ -686,6 +747,9 @@ __vfwprintf(FILE *fp, const wchar_t *fmt - prec = -1; +@@ -557,6 +582,9 @@ __vfwprintf(FILE *fp, const wchar_t *fmt + gs.grouping = NULL; sign = '\0'; ox[1] = '\0'; +#ifdef VECTORS @@ -315,7 +339,7 @@ rflag: ch = *fmt++; reswitch: switch (ch) { -@@ -701,6 +765,11 @@ reswitch: switch (ch) { +@@ -572,6 +600,11 @@ reswitch: switch (ch) { case '#': flags |= ALT; goto rflag; @@ -327,18 +351,7 @@ case '*': /*- * ``A negative field width argument is taken as a -@@ -721,8 +790,8 @@ reswitch: switch (ch) { - goto rflag; - case '\'': - flags |= GROUPING; -- thousands_sep = *(localeconv()->thousands_sep); -- grouping = localeconv()->grouping; -+ thousands_sep = *(localeconv_l(loc)->thousands_sep); -+ grouping = __fix_nogrouping(localeconv_l(loc)->grouping); - goto rflag; - case '.': - if ((ch = *fmt++) == '*') { -@@ -796,10 +865,14 @@ reswitch: switch (ch) { +@@ -668,10 +701,14 @@ reswitch: switch (ch) { flags |= LONGINT; /*FALLTHROUGH*/ case 'c': @@ -354,7 +367,7 @@ size = 1; sign = '\0'; break; -@@ -808,6 +881,10 @@ reswitch: switch (ch) { +@@ -680,6 +717,10 @@ reswitch: switch (ch) { /*FALLTHROUGH*/ case 'd': case 'i': @@ -365,7 +378,7 @@ if (flags & INTMAX_SIZE) { ujval = SJARG(); if ((intmax_t)ujval < 0) { -@@ -826,6 +903,12 @@ reswitch: switch (ch) { +@@ -698,6 +739,12 @@ reswitch: switch (ch) { #ifndef NO_FLOATING_POINT case 'a': case 'A': @@ -378,7 +391,7 @@ if (ch == 'a') { ox[1] = 'x'; xdigs = xdigs_lower; -@@ -837,6 +920,12 @@ reswitch: switch (ch) { +@@ -709,6 +756,12 @@ reswitch: switch (ch) { } if (prec >= 0) prec++; @@ -391,7 +404,7 @@ if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = -@@ -848,6 +937,7 @@ reswitch: switch (ch) { +@@ -720,6 +773,7 @@ reswitch: switch (ch) { __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend); } @@ -399,7 +412,7 @@ if (prec < 0) prec = dtoaend - dtoaresult; if (expt == INT_MAX) -@@ -855,11 +945,17 @@ reswitch: switch (ch) { +@@ -727,11 +781,17 @@ reswitch: switch (ch) { if (convbuf != NULL) free(convbuf); ndig = dtoaend - dtoaresult; @@ -418,7 +431,7 @@ expchar = ch; if (prec < 0) /* account for digit before decpt */ prec = DEFPREC + 1; -@@ -868,10 +964,22 @@ reswitch: switch (ch) { +@@ -740,10 +800,22 @@ reswitch: switch (ch) { goto fp_begin; case 'f': case 'F': @@ -441,7 +454,7 @@ expchar = ch - ('g' - 'e'); if (prec == 0) prec = 1; -@@ -880,6 +988,14 @@ fp_begin: +@@ -752,6 +824,14 @@ fp_begin: prec = DEFPREC; if (convbuf != NULL) free(convbuf); @@ -456,7 +469,7 @@ if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = -@@ -893,8 +1009,9 @@ fp_begin: +@@ -765,8 +845,9 @@ fp_begin: if (expt == 9999) expt = INT_MAX; } @@ -467,7 +480,53 @@ freedtoa(dtoaresult); fp_common: if (signflag) -@@ -989,6 +1106,10 @@ fp_common: +@@ -816,37 +897,46 @@ fp_common: + if (prec || flags & ALT) + size += prec + 1; + if ((flags & GROUPING) && expt > 0) +- size += grouping_init(&gs, expt); ++ size += grouping_init(&gs, expt, loc); + } + break; + #endif /* !NO_FLOATING_POINT */ + case 'n': ++ { + /* + * Assignment-like behavior is specified if the + * value overflows or is otherwise unrepresentable. + * C99 says to use `signed char' for %hhn conversions. + */ +- if (flags & LLONGINT) +- *GETARG(long long *) = ret; ++ void *ptr = GETARG(void *); ++ if (ptr == NULL) ++ continue; ++ else if (flags & LLONGINT) ++ *(long long *)ptr = ret; + else if (flags & SIZET) +- *GETARG(ssize_t *) = (ssize_t)ret; ++ *(ssize_t *)ptr = (ssize_t)ret; + else if (flags & PTRDIFFT) +- *GETARG(ptrdiff_t *) = ret; ++ *(ptrdiff_t *)ptr = ret; + else if (flags & INTMAXT) +- *GETARG(intmax_t *) = ret; ++ *(intmax_t *)ptr = ret; + else if (flags & LONGINT) +- *GETARG(long *) = ret; ++ *(long *)ptr = ret; + else if (flags & SHORTINT) +- *GETARG(short *) = ret; ++ *(short *)ptr = ret; + else if (flags & CHARINT) +- *GETARG(signed char *) = ret; ++ *(signed char *)ptr = ret; + else +- *GETARG(int *) = ret; ++ *(int *)ptr = ret; + continue; /* no output */ ++ } + case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': @@ -478,7 +537,7 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1003,6 +1124,10 @@ fp_common: +@@ -861,6 +951,10 @@ fp_common: * defined manner.'' * -- ANSI X3J11 */ @@ -489,7 +548,7 @@ ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; xdigs = xdigs_lower; -@@ -1024,7 +1149,7 @@ fp_common: +@@ -882,7 +976,7 @@ fp_common: if ((mbp = GETARG(char *)) == NULL) cp = L"(null)"; else { @@ -498,7 +557,20 @@ if (convbuf == NULL) { fp->_flags |= __SERR; goto error; -@@ -1055,6 +1180,10 @@ fp_common: +@@ -890,13 +984,23 @@ fp_common: + cp = convbuf; + } + } ++#if 0 // wcsnlen needs API review first + size = (prec >= 0) ? wcsnlen(cp, prec) : wcslen(cp); ++#else ++ size = wcslen(cp); ++ if(prec >= 0 && prec < size) ++ size = prec; ++#endif + sign = '\0'; + break; + case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': @@ -509,7 +581,7 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1067,6 +1196,10 @@ fp_common: +@@ -909,6 +1013,10 @@ fp_common: case 'x': xdigs = xdigs_lower; hex: @@ -520,29 +592,23 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1092,6 +1225,7 @@ number: if ((dprec = prec) >= 0) - * ``The result of converting a zero value with an - * explicit precision of zero is no characters.'' +@@ -926,6 +1034,7 @@ nosign: sign = '\0'; + * ``... diouXx conversions ... if a precision is + * specified, the 0 flag will be ignored.'' * -- ANSI X3J11 + * except for %#.0o and zero value */ - cp = buf + BUF; - if (flags & INTMAX_SIZE) { -@@ -1101,7 +1235,7 @@ number: if ((dprec = prec) >= 0) - flags & GROUPING, thousands_sep, - grouping); - } else { -- if (ulval != 0 || prec != 0) -+ if (ulval != 0 || prec != 0 || (flags & ALT)) - cp = __ultoa(ulval, cp, base, - flags & ALT, xdigs, - flags & GROUPING, thousands_sep, -@@ -1109,8 +1243,13 @@ number: if ((dprec = prec) >= 0) + number: if ((dprec = prec) >= 0) + flags &= ~ZEROPAD; +@@ -953,10 +1062,15 @@ number: if ((dprec = prec) >= 0) } size = buf + BUF - cp; if (size > BUF) /* should never happen */ - abort(); -+ LIBC_ABORT("size %d > BUF %d", size, BUF); ++ LIBC_ABORT("size (%d) > BUF (%d)", size, BUF); + if ((flags & GROUPING) && size != 0) +- size += grouping_init(&gs, size); ++ size += grouping_init(&gs, size, loc); break; +#ifdef VECTORS + case 'v': @@ -552,7 +618,7 @@ default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; -@@ -1122,6 +1261,288 @@ number: if ((dprec = prec) >= 0) +@@ -968,6 +1082,288 @@ number: if ((dprec = prec) >= 0) break; } @@ -718,25 +784,25 @@ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \ + break; \ + case V_PCHAR: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuchararg[ind]); \ + break; \ + case V_SHORT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \ + break; \ + case V_PSHORT: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vushortarg[ind]); \ + break; \ + case V_INT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \ + break; \ + case V_PINT: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuintarg[ind]); \ + break; \ + case V_LONGLONG: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vulonglongarg[ind]); \ + break; \ + case V_PLONGLONG: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vulonglongarg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vulonglongarg[ind]); \ + break; \ + case V_FLOAT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ @@ -756,19 +822,19 @@ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \ + break; \ + case V_PCHAR: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuchararg[ind]); \ + break; \ + case V_SHORT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \ + break; \ + case V_PSHORT: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vushortarg[ind]); \ + break; \ + case V_INT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \ + break; \ + case V_PINT: \ -+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuintarg[ind]); \ + break; \ + case V_FLOAT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ @@ -841,137 +907,21 @@ /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be -@@ -1177,7 +1598,7 @@ number: if ((dprec = prec) >= 0) - if (expt <= 0) { - PRINT(zeroes, 1); - if (prec || flags & ALT) -- PRINT(decimal_point, 1); -+ PRINT(&decimal_point, 1); - PAD(-expt, zeroes); - /* already handled initial 0's */ - prec += expt; -@@ -1203,15 +1624,14 @@ number: if ((dprec = prec) >= 0) - cp = convbuf + ndig; - } - if (prec || flags & ALT) { -- buf[0] = *decimal_point; -- PRINT(buf, 1); -+ PRINT(&decimal_point, 1); - } - } - PRINTANDPAD(cp, convbuf + ndig, prec, zeroes); - } else { /* %[eE] or sufficiently long %[gG] */ - if (prec > 1 || flags & ALT) { - buf[0] = *cp++; -- buf[1] = *decimal_point; -+ buf[1] = decimal_point; - PRINT(buf, 2); - PRINT(cp, ndig-1); - PAD(prec - ndig, zeroes); -@@ -1401,6 +1821,11 @@ reswitch: switch (ch) { - if (flags & LONGINT) - ADDTYPE(T_WINT); - else -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - ADDTYPE(T_INT); - break; - case 'D': -@@ -1408,6 +1833,11 @@ reswitch: switch (ch) { - /*FALLTHROUGH*/ - case 'd': - case 'i': -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - ADDSARG(); - break; - #ifndef NO_FLOATING_POINT -@@ -1416,8 +1846,14 @@ reswitch: switch (ch) { - case 'e': - case 'E': - case 'f': -+ case 'F': - case 'g': - case 'G': -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - if (flags & LONGDBL) - ADDTYPE(T_LONG_DOUBLE); - else -@@ -1446,9 +1882,19 @@ reswitch: switch (ch) { - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'o': -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - ADDUARG(); - break; - case 'p': -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - ADDTYPE(TP_VOID); - break; - case 'S': -@@ -1466,6 +1912,11 @@ reswitch: switch (ch) { - case 'u': - case 'X': - case 'x': -+#ifdef VECTORS -+ if (flags & VECTOR) -+ ADDTYPE(T_VECTOR); -+ else -+#endif /* VECTORS */ - ADDUARG(); - break; - default: /* "%?" prints ?, unless ? is NUL */ -@@ -1532,7 +1983,7 @@ done: - (*argtable) [n].sizearg = va_arg (ap, size_t); - break; - case TP_SIZET: -- (*argtable) [n].psizearg = va_arg (ap, ssize_t *); -+ (*argtable) [n].psizearg = va_arg (ap, size_t *); - break; - case T_INTMAXT: - (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); -@@ -1551,6 +2002,11 @@ done: - (*argtable) [n].longdoublearg = va_arg (ap, long double); - break; - #endif -+#ifdef VECTORS -+ case T_VECTOR: -+ (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE); -+ break; -+#endif /* VECTORS */ - case TP_CHAR: - (*argtable) [n].pchararg = va_arg (ap, char *); - break; -@@ -1585,12 +2041,12 @@ __grow_type_table (int nextarg, enum typ - newsize = nextarg + 1; - if (oldsize == STATIC_ARG_TBL_SIZE) { - if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL) -- abort(); /* XXX handle better */ -+ LIBC_ABORT("malloc: %s", strerror(errno)); /* XXX handle better */ - bcopy(oldtable, newtable, oldsize * sizeof(enum typeid)); - } else { - newtable = reallocf(oldtable, newsize * sizeof(enum typeid)); - if (newtable == NULL) -- abort(); /* XXX handle better */ -+ LIBC_ABORT("reallocf: %s", strerror(errno)); /* XXX handle better */ - } - for (n = oldsize; n < newsize; n++) - newtable[n] = T_UNUSED; +@@ -1018,7 +1414,7 @@ number: if ((dprec = prec) >= 0) + /* leading zeroes from decimal precision */ + PAD(dprec - size, zeroes); + if (gs.grouping) { +- if (grouping_print(&gs, &io, cp, buf+BUF) < 0) ++ if (grouping_print(&gs, &io, cp, buf+BUF, loc) < 0) + goto error; + } else { + PRINT(cp, size); +@@ -1036,7 +1432,7 @@ number: if ((dprec = prec) >= 0) + } else { + if (gs.grouping) { + n = grouping_print(&gs, &io, +- cp, convbuf + ndig); ++ cp, convbuf + ndig, loc); + if (n < 0) + goto error; + cp += n; diff --git a/stdio/FreeBSD/vfwscanf.c b/stdio/FreeBSD/vfwscanf.c index 8bc9636..79b5469 100644 --- a/stdio/FreeBSD/vfwscanf.c +++ b/stdio/FreeBSD/vfwscanf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,11 +36,12 @@ static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #endif #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.12 2004/05/02 20:13:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.17 2009/01/19 06:19:51 das Exp $"); #include "namespace.h" #include #include +#include #include #include #include @@ -98,14 +95,16 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.12 2004/05/02 20:13:29 obr #define CT_INT 3 /* %[dioupxX] conversion */ #define CT_FLOAT 4 /* %[efgEFG] conversion */ +#ifndef NO_FLOATING_POINT static int parsefloat(FILE *, wchar_t *, wchar_t *); - -extern int __scanfdebug; +#endif #define INCCL(_c) \ (cclcompl ? (wmemchr(ccls, (_c), ccle - ccls) == NULL) : \ (wmemchr(ccls, (_c), ccle - ccls) != NULL)) +static const mbstate_t initial_mbs; + /* * MT-safe version. */ @@ -145,7 +144,6 @@ __vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap) char *mbp; /* multibyte string pointer for %c %s %[ */ size_t nconv; /* number of bytes in mb. conversion */ char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */ - static const mbstate_t initial; mbstate_t mbs; /* `basefix' is used to avoid `if' tests in the integer scanner */ @@ -378,7 +376,7 @@ literal: if (!(flags & SUPPRESS)) mbp = va_arg(ap, char *); n = 0; - mbs = initial; + mbs = initial_mbs; while (width != 0 && (wi = __fgetwc(fp)) != WEOF) { if (width >= MB_CUR_MAX && @@ -443,7 +441,7 @@ literal: if (!(flags & SUPPRESS)) mbp = va_arg(ap, char *); n = 0; - mbs = initial; + mbs = initial_mbs; while ((wi = __fgetwc(fp)) != WEOF && width != 0 && INCCL(wi)) { if (width >= MB_CUR_MAX && @@ -504,7 +502,7 @@ literal: } else { if (!(flags & SUPPRESS)) mbp = va_arg(ap, char *); - mbs = initial; + mbs = initial_mbs; while ((wi = __fgetwc(fp)) != WEOF && width != 0 && !iswspace(wi)) { @@ -706,8 +704,6 @@ literal: float res = wcstof(buf, &p); *va_arg(ap, float *) = res; } - if (__scanfdebug && p - buf != width) - abort(); nassigned++; } nread += width; @@ -726,16 +722,23 @@ match_failure: static int parsefloat(FILE *fp, wchar_t *buf, wchar_t *end) { + mbstate_t mbs; + size_t nconv; wchar_t *commit, *p; int infnanpos = 0; enum { - S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX, + S_START, S_GOTSIGN, S_INF, S_NAN, S_DONE, S_MAYBEHEX, S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS } state = S_START; wchar_t c; - wchar_t decpt = (wchar_t)(unsigned char)*localeconv()->decimal_point; + wchar_t decpt; _Bool gotmantdig = 0, ishex = 0; + mbs = initial_mbs; + nconv = mbrtowc(&decpt, localeconv()->decimal_point, MB_CUR_MAX, &mbs); + if (nconv == (size_t)-1 || nconv == (size_t)-2) + decpt = '.'; /* failsafe */ + /* * We set commit = p whenever the string we have read so far * constitutes a valid representation of a floating point @@ -788,8 +791,6 @@ reswitch: break; case S_NAN: switch (infnanpos) { - case -1: /* XXX kludge to deal with nan(...) */ - goto parsedone; case 0: if (c != 'A' && c != 'a') goto parsedone; @@ -807,13 +808,15 @@ reswitch: default: if (c == ')') { commit = p; - infnanpos = -2; + state = S_DONE; } else if (!iswalnum(c) && c != '_') goto parsedone; break; } infnanpos++; break; + case S_DONE: + goto parsedone; case S_MAYBEHEX: state = S_DIGITS; if (c == 'X' || c == 'x') { diff --git a/stdio/FreeBSD/vfwscanf.c.patch b/stdio/FreeBSD/vfwscanf.c.patch index 3cb6a7c..7a22303 100644 --- a/stdio/FreeBSD/vfwscanf.c.patch +++ b/stdio/FreeBSD/vfwscanf.c.patch @@ -1,35 +1,35 @@ ---- vfwscanf.c.orig 2009-02-15 03:11:22.000000000 -0800 -+++ vfwscanf.c 2009-02-16 00:10:06.000000000 -0800 -@@ -42,6 +42,8 @@ static char sccsid[] = "@(#)vfscanf.c 8. +Index: vfwscanf.c +=================================================================== +--- vfwscanf.c (revision 55443) ++++ vfwscanf.c (working copy) +@@ -38,6 +38,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.12 2004/05/02 20:13:29 obrien Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.17 2009/01/19 06:19:51 das Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include #include -@@ -98,7 +100,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v - #define CT_INT 3 /* %[dioupxX] conversion */ +@@ -96,7 +98,7 @@ #define CT_FLOAT 4 /* %[efgEFG] conversion */ + #ifndef NO_FLOATING_POINT -static int parsefloat(FILE *, wchar_t *, wchar_t *); -+#ifndef NO_FLOATING_POINT +static int parsefloat(FILE *, wchar_t **, size_t, locale_t loc); -+#endif /* !NO_FLOATING_POINT */ - - extern int __scanfdebug; + #endif -@@ -116,7 +120,21 @@ vfwscanf(FILE * __restrict fp, const wch + #define INCCL(_c) \ +@@ -115,16 +117,31 @@ FLOCKFILE(fp); ORIENT(fp, 1); - ret = __vfwscanf(fp, fmt, ap); + ret = __vfwscanf(fp, __current_locale(), fmt, ap); -+ FUNLOCKFILE(fp); -+ return (ret); -+} -+ + FUNLOCKFILE(fp); + return (ret); + } + +int +vfwscanf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt, + va_list ap) @@ -40,10 +40,10 @@ + FLOCKFILE(fp); + ORIENT(fp, 1); + ret = __vfwscanf(fp, loc, fmt, ap); - FUNLOCKFILE(fp); - return (ret); - } -@@ -124,8 +142,9 @@ vfwscanf(FILE * __restrict fp, const wch ++ FUNLOCKFILE(fp); ++ return (ret); ++} ++ /* * Non-MT-safe version. */ @@ -55,7 +55,7 @@ { wint_t c; /* character from format, or conversion */ size_t width; /* field width, or 0 */ -@@ -134,7 +153,6 @@ __vfwscanf(FILE * __restrict fp, const w +@@ -133,7 +150,6 @@ int flags; /* flags as defined above */ wchar_t *p0; /* saves original value of p when necessary */ int nassigned; /* number of fields assigned */ @@ -63,13 +63,12 @@ int nread; /* number of characters consumed from fp */ int base; /* base argument to conversion function */ wchar_t buf[BUF]; /* buffer for numeric conversions */ -@@ -145,31 +163,37 @@ __vfwscanf(FILE * __restrict fp, const w +@@ -144,30 +160,36 @@ char *mbp; /* multibyte string pointer for %c %s %[ */ size_t nconv; /* number of bytes in mb. conversion */ char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */ + int index; /* for %index$ */ + va_list ap_orig; /* to reset ap to first argument */ - static const mbstate_t initial; mbstate_t mbs; + int mb_cur_max = MB_CUR_MAX_L(loc); @@ -107,7 +106,7 @@ width = 0; flags = 0; /* -@@ -179,16 +203,34 @@ __vfwscanf(FILE * __restrict fp, const w +@@ -177,16 +199,34 @@ again: c = *fmt++; switch (c) { case '%': @@ -146,15 +145,48 @@ case '*': flags |= SUPPRESS; goto again; -@@ -307,7 +349,6 @@ literal: +@@ -305,27 +345,28 @@ break; case 'n': - nconversions++; - if (flags & SUPPRESS) /* ??? */ +- if (flags & SUPPRESS) /* ??? */ ++ { ++ void *ptr = va_arg(ap, void *); ++ if ((ptr == NULL) || (flags & SUPPRESS)) /* ??? */ continue; - if (flags & SHORTSHORT) -@@ -343,11 +384,11 @@ literal: +- if (flags & SHORTSHORT) +- *va_arg(ap, char *) = nread; ++ else if (flags & SHORTSHORT) ++ *(char *)ptr = nread; + else if (flags & SHORT) +- *va_arg(ap, short *) = nread; ++ *(short *)ptr = nread; + else if (flags & LONG) +- *va_arg(ap, long *) = nread; ++ *(long *)ptr = nread; + else if (flags & LONGLONG) +- *va_arg(ap, long long *) = nread; ++ *(long long *)ptr = nread; + else if (flags & INTMAXT) +- *va_arg(ap, intmax_t *) = nread; ++ *(intmax_t *)ptr = nread; + else if (flags & SIZET) +- *va_arg(ap, size_t *) = nread; ++ *(size_t *)ptr = nread; + else if (flags & PTRDIFFT) +- *va_arg(ap, ptrdiff_t *) = nread; ++ *(ptrdiff_t *)ptr = nread; + else +- *va_arg(ap, int *) = nread; ++ *(int *)ptr = nread; + continue; +- ++ } + default: + goto match_failure; + +@@ -341,11 +382,11 @@ * that suppress this. */ if ((flags & NOSKIP) == 0) { @@ -168,7 +200,7 @@ } /* -@@ -364,7 +405,7 @@ literal: +@@ -362,7 +403,7 @@ p = va_arg(ap, wchar_t *); n = 0; while (width-- != 0 && @@ -177,9 +209,9 @@ if (!(flags & SUPPRESS)) *p++ = (wchar_t)wi; n++; -@@ -380,19 +421,19 @@ literal: +@@ -378,19 +419,19 @@ n = 0; - mbs = initial; + mbs = initial_mbs; while (width != 0 && - (wi = __fgetwc(fp)) != WEOF) { - if (width >= MB_CUR_MAX && @@ -203,7 +235,7 @@ break; } if (!(flags & SUPPRESS)) -@@ -410,7 +451,6 @@ literal: +@@ -408,7 +449,6 @@ if (!(flags & SUPPRESS)) nassigned++; } @@ -211,7 +243,7 @@ break; case CT_CCL: -@@ -420,20 +460,20 @@ literal: +@@ -418,20 +458,20 @@ /* take only those things in the class */ if ((flags & SUPPRESS) && (flags & LONG)) { n = 0; @@ -236,10 +268,10 @@ n = p - p0; if (n == 0) goto match_failure; -@@ -444,16 +484,16 @@ literal: +@@ -442,16 +482,16 @@ mbp = va_arg(ap, char *); n = 0; - mbs = initial; + mbs = initial_mbs; - while ((wi = __fgetwc(fp)) != WEOF && + while ((wi = __fgetwc(fp, loc)) != WEOF && width != 0 && INCCL(wi)) { @@ -258,7 +290,7 @@ if (nconv == (size_t)-1) goto input_failure; if (nconv > width) -@@ -468,14 +508,15 @@ literal: +@@ -466,14 +506,15 @@ n++; } if (wi != WEOF) @@ -276,7 +308,7 @@ break; case CT_STRING: -@@ -483,39 +524,39 @@ literal: +@@ -481,39 +522,39 @@ if (width == 0) width = (size_t)~0; if ((flags & SUPPRESS) && (flags & LONG)) { @@ -307,7 +339,7 @@ } else { if (!(flags & SUPPRESS)) mbp = va_arg(ap, char *); - mbs = initial; + mbs = initial_mbs; - while ((wi = __fgetwc(fp)) != WEOF && + while ((wi = __fgetwc(fp, loc)) != WEOF && width != 0 && @@ -328,7 +360,7 @@ if (nconv == (size_t)-1) goto input_failure; if (nconv > width) -@@ -530,13 +571,12 @@ literal: +@@ -528,13 +569,12 @@ nread++; } if (wi != WEOF) @@ -343,7 +375,7 @@ continue; case CT_INT: -@@ -546,7 +586,7 @@ literal: +@@ -544,7 +584,7 @@ width = sizeof(buf) / sizeof(*buf) - 1; flags |= SIGNOK | NDIGITS | NZDIGITS; for (p = buf; width; width--) { @@ -352,7 +384,7 @@ /* * Switch on the character; `goto ok' * if we accept it as a part of number. -@@ -630,7 +670,7 @@ literal: +@@ -628,7 +668,7 @@ * for a number. Stop accumulating digits. */ if (c != WEOF) @@ -361,7 +393,7 @@ break; ok: /* -@@ -646,22 +686,22 @@ literal: +@@ -644,22 +684,22 @@ */ if (flags & NDIGITS) { if (p > buf) @@ -388,7 +420,7 @@ if (flags & POINTER) *va_arg(ap, void **) = (void *)(uintptr_t)res; -@@ -684,47 +724,47 @@ literal: +@@ -682,45 +722,45 @@ nassigned++; } nread += p - buf; @@ -420,10 +452,6 @@ + float res = wcstof_l(pbuf, &p, loc); *va_arg(ap, float *) = res; } -- if (__scanfdebug && p - buf != width) -- abort(); -+ if (__scanfdebug && p - pbuf != width) -+ LIBC_ABORT("p - pbuf %ld != width %ld", (long)(p - pbuf), width); nassigned++; } nread += width; @@ -447,21 +475,24 @@ -parsefloat(FILE *fp, wchar_t *buf, wchar_t *end) +parsefloat(FILE *fp, wchar_t **buf, size_t width, locale_t loc) { - wchar_t *commit, *p; - int infnanpos = 0; -@@ -733,9 +773,19 @@ parsefloat(FILE *fp, wchar_t *buf, wchar - S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS - } state = S_START; + mbstate_t mbs; + size_t nconv; +@@ -733,12 +773,22 @@ wchar_t c; -- wchar_t decpt = (wchar_t)(unsigned char)*localeconv()->decimal_point; -+ char *decimal_point; -+ wchar_t decpt; + wchar_t decpt; _Bool gotmantdig = 0, ishex = 0; -- + wchar_t *b; + wchar_t *e; + size_t s; + + mbs = initial_mbs; +- nconv = mbrtowc(&decpt, localeconv()->decimal_point, MB_CUR_MAX, &mbs); + ++ nconv = mbrtowc_l(&decpt, localeconv()->decimal_point, MB_CUR_MAX_L(loc), &mbs, loc); + if (nconv == (size_t)-1 || nconv == (size_t)-2) +- decpt = '.'; /* failsafe */ ++ decpt = '.'; /* failsafe */ + + s = (width == 0 ? BUF : (width + 1)); + if ((b = (wchar_t *)__parsefloat_buf(s * sizeof(wchar_t))) == NULL) { + *buf = NULL; @@ -471,7 +502,7 @@ /* * We set commit = p whenever the string we have read so far * constitutes a valid representation of a floating point -@@ -745,10 +795,12 @@ parsefloat(FILE *fp, wchar_t *buf, wchar +@@ -748,10 +798,10 @@ * always necessary to read at least one character that doesn't * match; thus, we can't short-circuit "infinity" or "nan(...)". */ @@ -480,23 +511,21 @@ c = WEOF; - for (p = buf; p < end; ) { - if ((c = __fgetwc(fp)) == WEOF) -+ decimal_point = localeconv_l(loc)->decimal_point; -+ mbtowc_l(&decpt, decimal_point, strlen(decimal_point), loc); + for (p = b; width == 0 || p < e; ) { + if ((c = __fgetwc(fp, loc)) == WEOF) break; reswitch: switch (state) { -@@ -808,7 +860,7 @@ reswitch: +@@ -809,7 +859,7 @@ if (c == ')') { commit = p; - infnanpos = -2; + state = S_DONE; - } else if (!iswalnum(c) && c != '_') + } else if (!iswalnum_l(c, loc) && c != '_') goto parsedone; break; } -@@ -824,7 +876,7 @@ reswitch: +@@ -827,7 +877,7 @@ goto reswitch; } case S_DIGITS: @@ -505,7 +534,7 @@ gotmantdig = 1; else { state = S_FRAC; -@@ -841,7 +893,7 @@ reswitch: +@@ -844,7 +894,7 @@ goto parsedone; else state = S_EXP; @@ -514,7 +543,7 @@ commit = p; gotmantdig = 1; } else -@@ -854,13 +906,26 @@ reswitch: +@@ -857,24 +907,38 @@ else goto reswitch; case S_EXPDIGITS: @@ -527,7 +556,7 @@ default: - abort(); + LIBC_ABORT("unknown state %d", state); -+ } + } + if (p >= e) { + ssize_t diff = (p - b); + ssize_t com = (commit - b); @@ -540,10 +569,10 @@ + e = b + (s - 1); + p = b + diff; + commit = b + com; - } ++ } *p++ = c; c = WEOF; -@@ -868,10 +933,11 @@ reswitch: + } parsedone: if (c != WEOF) diff --git a/stdio/FreeBSD/vprintf.c b/stdio/FreeBSD/vprintf.c index 329bbf0..b11af0d 100644 --- a/stdio/FreeBSD/vprintf.c +++ b/stdio/FreeBSD/vprintf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vprintf.c,v 1.10 2002/09/06 11:23:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vprintf.c,v 1.11 2007/01/09 00:28:08 imp Exp $"); #include diff --git a/stdio/FreeBSD/vprintf.c.patch b/stdio/FreeBSD/vprintf.c.patch index 1677c5e..5616998 100644 --- a/stdio/FreeBSD/vprintf.c.patch +++ b/stdio/FreeBSD/vprintf.c.patch @@ -1,8 +1,8 @@ ---- vprintf.c.orig 2003-05-20 15:22:44.000000000 -0700 -+++ vprintf.c 2005-02-23 16:51:20.000000000 -0800 -@@ -40,11 +40,21 @@ +--- vprintf.c.bsdnew 2009-11-11 13:33:19.000000000 -0800 ++++ vprintf.c 2009-11-11 13:33:19.000000000 -0800 +@@ -36,11 +36,21 @@ static char sccsid[] = "@(#)vprintf.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/vprintf.c,v 1.10 2002/09/06 11:23:56 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vprintf.c,v 1.11 2007/01/09 00:28:08 imp Exp $"); +#include "xlocale_private.h" + diff --git a/stdio/FreeBSD/vscanf.c b/stdio/FreeBSD/vscanf.c index 6945736..7792970 100644 --- a/stdio/FreeBSD/vscanf.c +++ b/stdio/FreeBSD/vscanf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vscanf.c,v 1.12 2003/01/03 23:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vscanf.c,v 1.13 2007/01/09 00:28:08 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/FreeBSD/vscanf.c.patch b/stdio/FreeBSD/vscanf.c.patch index 4372a3a..26c561c 100644 --- a/stdio/FreeBSD/vscanf.c.patch +++ b/stdio/FreeBSD/vscanf.c.patch @@ -1,15 +1,15 @@ ---- vscanf.c.orig 2003-05-20 15:22:44.000000000 -0700 -+++ vscanf.c 2005-02-23 19:11:44.000000000 -0800 -@@ -40,6 +40,8 @@ +--- vscanf.c.bsdnew 2009-11-11 13:33:19.000000000 -0800 ++++ vscanf.c 2009-11-11 13:33:19.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)vscanf.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/vscanf.c,v 1.12 2003/01/03 23:27:27 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vscanf.c,v 1.13 2007/01/09 00:28:08 imp Exp $"); +#include "xlocale_private.h" + #include "namespace.h" #include #include "un-namespace.h" -@@ -54,7 +56,22 @@ +@@ -50,7 +52,22 @@ vscanf(fmt, ap) int retval; FLOCKFILE(stdin); diff --git a/stdio/FreeBSD/vsnprintf.c b/stdio/FreeBSD/vsnprintf.c index 3a43939..1a20c99 100644 --- a/stdio/FreeBSD/vsnprintf.c +++ b/stdio/FreeBSD/vsnprintf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vsnprintf.c,v 1.22 2003/07/02 07:08:44 jkh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vsnprintf.c,v 1.24 2008/04/17 22:17:54 jhb Exp $"); #include #include @@ -52,7 +48,6 @@ vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, int ret; char dummy[2]; FILE f; - struct __sFILEX ext; on = n; if (n != 0) @@ -70,8 +65,8 @@ vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); ret = __vfprintf(&f, fmt, ap); if (on > 0) *f._p = '\0'; diff --git a/stdio/FreeBSD/vsnprintf.c.patch b/stdio/FreeBSD/vsnprintf.c.patch index 9324ff6..a765aae 100644 --- a/stdio/FreeBSD/vsnprintf.c.patch +++ b/stdio/FreeBSD/vsnprintf.c.patch @@ -1,55 +1,46 @@ ---- vsnprintf.c.orig 2003-07-24 12:42:14.000000000 -0700 -+++ vsnprintf.c 2005-02-23 16:54:44.000000000 -0800 -@@ -40,6 +40,8 @@ +--- vsnprintf.c.orig 2009-11-30 16:15:30.000000000 -0800 ++++ vsnprintf.c 2009-12-03 15:20:43.000000000 -0800 +@@ -36,19 +36,25 @@ static char sccsid[] = "@(#)vsnprintf.c #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/vsnprintf.c,v 1.22 2003/07/02 07:08:44 jkh Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vsnprintf.c,v 1.24 2008/04/17 22:17:54 jhb Exp $"); +#include "xlocale_private.h" + #include #include #include "local.h" -@@ -72,7 +74,42 @@ - f._bf._size = f._w = n; - f._extra = &ext; - INITEXTRA(&f); -- ret = __vfprintf(&f, fmt, ap); -+ ret = __vfprintf(&f, __current_locale(), fmt, ap); -+ if (on > 0) -+ *f._p = '\0'; -+ return (ret); -+} -+ -+int -+vsnprintf_l(char * __restrict str, size_t n, locale_t loc, -+ const char * __restrict fmt, __va_list ap) -+{ -+ size_t on; -+ int ret; -+ char dummy[2]; -+ FILE f; + + int +-vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, ++vsnprintf_l(char * __restrict str, size_t n, locale_t loc, const char * __restrict fmt, + __va_list ap) + { + size_t on; + int ret; + char dummy[2]; + FILE f; + struct __sFILEX ext; -+ -+ NORMALIZE_LOCALE(loc); -+ on = n; -+ if (n != 0) -+ n--; -+ if (n > INT_MAX) -+ n = INT_MAX; -+ /* Stdio internals do not deal correctly with zero length buffer */ -+ if (n == 0) { -+ if (on > 0) -+ *str = '\0'; -+ str = dummy; -+ n = 1; -+ } -+ f._file = -1; -+ f._flags = __SWR | __SSTR; -+ f._bf._base = f._p = (unsigned char *)str; -+ f._bf._size = f._w = n; + f._extra = &ext; + INITEXTRA(&f); + ++ NORMALIZE_LOCALE(loc); + on = n; + if (n != 0) + n--; +@@ -67,8 +73,15 @@ vsnprintf(char * __restrict str, size_t + f._bf._size = f._w = n; + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); +- ret = __vfprintf(&f, fmt, ap); + ret = __vfprintf(&f, loc, fmt, ap); if (on > 0) *f._p = '\0'; return (ret); + } ++ ++int ++vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, ++ __va_list ap) ++{ ++ return vsnprintf_l(str, n, __current_locale(), fmt, ap); ++} diff --git a/stdio/FreeBSD/vsprintf.c b/stdio/FreeBSD/vsprintf.c index 698f752..6cbc368 100644 --- a/stdio/FreeBSD/vsprintf.c +++ b/stdio/FreeBSD/vsprintf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vsprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vsprintf.c,v 1.14 2002/09/06 11:23:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vsprintf.c,v 1.16 2008/04/17 22:17:54 jhb Exp $"); #include #include @@ -49,14 +45,13 @@ vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap) { int ret; FILE f; - struct __sFILEX ext; f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); ret = __vfprintf(&f, fmt, ap); *f._p = 0; return (ret); diff --git a/stdio/FreeBSD/vsprintf.c.patch b/stdio/FreeBSD/vsprintf.c.patch index a01a91b..1a59860 100644 --- a/stdio/FreeBSD/vsprintf.c.patch +++ b/stdio/FreeBSD/vsprintf.c.patch @@ -1,40 +1,40 @@ ---- vsprintf.c.orig 2003-05-20 15:22:44.000000000 -0700 -+++ vsprintf.c 2005-02-23 16:56:03.000000000 -0800 -@@ -40,6 +40,8 @@ +--- vsprintf.c.orig 2009-11-30 16:15:30.000000000 -0800 ++++ vsprintf.c 2009-12-03 15:20:55.000000000 -0800 +@@ -36,23 +36,35 @@ static char sccsid[] = "@(#)vsprintf.c 8 #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/vsprintf.c,v 1.14 2002/09/06 11:23:56 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vsprintf.c,v 1.16 2008/04/17 22:17:54 jhb Exp $"); +#include "xlocale_private.h" + #include #include #include "local.h" -@@ -57,7 +59,27 @@ - f._bf._size = f._w = INT_MAX; - f._extra = &ext; - INITEXTRA(&f); -- ret = __vfprintf(&f, fmt, ap); -+ ret = __vfprintf(&f, __current_locale(), fmt, ap); -+ *f._p = 0; -+ return (ret); -+} -+ -+int -+vsprintf_l(char * __restrict str, locale_t loc, const char * __restrict fmt, -+ __va_list ap) -+{ -+ int ret; -+ FILE f; + + int +-vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap) ++vsprintf_l(char * __restrict str, locale_t loc, const char * __restrict fmt, __va_list ap) + { + int ret; + FILE f; + struct __sFILEX ext; -+ -+ NORMALIZE_LOCALE(loc); -+ f._file = -1; -+ f._flags = __SWR | __SSTR; -+ f._bf._base = f._p = (unsigned char *)str; -+ f._bf._size = f._w = INT_MAX; + f._extra = &ext; + INITEXTRA(&f); + ++ NORMALIZE_LOCALE(loc); + f._file = -1; + f._flags = __SWR | __SSTR; + f._bf._base = f._p = (unsigned char *)str; + f._bf._size = f._w = INT_MAX; + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); +- ret = __vfprintf(&f, fmt, ap); + ret = __vfprintf(&f, loc, fmt, ap); *f._p = 0; return (ret); } ++ ++int ++vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap) ++{ ++ return vsprintf_l(str, __current_locale(), fmt, ap); ++} diff --git a/stdio/FreeBSD/vsscanf.c b/stdio/FreeBSD/vsscanf.c index e7bbe25..86a3837 100644 --- a/stdio/FreeBSD/vsscanf.c +++ b/stdio/FreeBSD/vsscanf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vsscanf.c,v 1.12 2002/10/12 16:13:41 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vsscanf.c,v 1.14 2008/04/17 22:17:54 jhb Exp $"); #include #include @@ -65,7 +61,6 @@ vsscanf(str, fmt, ap) __va_list ap; { FILE f; - struct __sFILEX ext; f._file = -1; f._flags = __SRD; @@ -74,7 +69,7 @@ vsscanf(str, fmt, ap) f._read = eofread; f._ub._base = NULL; f._lb._base = NULL; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); return (__svfscanf(&f, fmt, ap)); } diff --git a/stdio/FreeBSD/vsscanf.c.patch b/stdio/FreeBSD/vsscanf.c.patch index 01c4075..1f13645 100644 --- a/stdio/FreeBSD/vsscanf.c.patch +++ b/stdio/FreeBSD/vsscanf.c.patch @@ -1,41 +1,46 @@ ---- vsscanf.c.orig 2003-05-20 15:22:44.000000000 -0700 -+++ vsscanf.c 2005-02-23 16:57:18.000000000 -0800 -@@ -40,6 +40,8 @@ +--- vsscanf.c.orig 2011-03-01 17:54:44.000000000 -0800 ++++ vsscanf.c 2011-03-01 18:03:46.000000000 -0800 +@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)vsscanf.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/stdio/vsscanf.c,v 1.12 2002/10/12 16:13:41 mike Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vsscanf.c,v 1.14 2008/04/17 22:17:54 jhb Exp $"); +#include "xlocale_private.h" + #include #include #include "local.h" -@@ -76,5 +78,28 @@ +@@ -55,12 +57,16 @@ eofread(cookie, buf, len) + } + + int +-vsscanf(str, fmt, ap) ++vsscanf_l(str, loc, fmt, ap) + const char * __restrict str; ++ locale_t loc; + const char * __restrict fmt; + __va_list ap; + { + FILE f; ++ struct __sFILEX ext; ++ f._extra = &ext; ++ INITEXTRA(&f); + + f._file = -1; + f._flags = __SRD; +@@ -71,5 +77,15 @@ vsscanf(str, fmt, ap) f._lb._base = NULL; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); - return (__svfscanf(&f, fmt, ap)); -+ return (__svfscanf_l(&f, __current_locale(), fmt, ap)); -+} ++ return (__svfscanf_l(&f, loc, fmt, ap)); + } + +int -+vsscanf_l(str, loc, fmt, ap) ++vsscanf(str, fmt, ap) + const char * __restrict str; -+ locale_t loc; + const char * __restrict fmt; + __va_list ap; +{ -+ FILE f; -+ struct __sFILEX ext; ++ return vsscanf_l(str, __current_locale(), fmt, ap); ++} + -+ NORMALIZE_LOCALE(loc); -+ f._file = -1; -+ f._flags = __SRD; -+ f._bf._base = f._p = (unsigned char *)str; -+ f._bf._size = f._r = strlen(str); -+ f._read = eofread; -+ f._ub._base = NULL; -+ f._lb._base = NULL; -+ f._extra = &ext; -+ INITEXTRA(&f); -+ return (__svfscanf_l(&f, loc, fmt, ap)); - } diff --git a/stdio/FreeBSD/vswprintf.c b/stdio/FreeBSD/vswprintf.c index 50c9876..d2911c5 100644 --- a/stdio/FreeBSD/vswprintf.c +++ b/stdio/FreeBSD/vswprintf.c @@ -31,7 +31,7 @@ #if 0 __FBSDID("FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.16 2002/08/21 16:19:57 mike Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/stdio/vswprintf.c,v 1.5 2004/04/07 09:55:05 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vswprintf.c,v 1.7 2008/04/17 22:17:54 jhb Exp $"); #include #include @@ -46,9 +46,9 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, static const mbstate_t initial; mbstate_t mbs; FILE f; - struct __sFILEX ext; char *mbp; int ret, sverrno; + size_t nwc; if (n == 0) { errno = EINVAL; @@ -63,8 +63,8 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, return (-1); } f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); ret = __vfwprintf(&f, fmt, ap); if (ret < 0) { sverrno = errno; @@ -79,13 +79,13 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, * fputwc() did in __vfwprintf(). */ mbs = initial; - if (mbsrtowcs(s, (const char **)&mbp, n, &mbs) == (size_t)-1) { - free(f._bf._base); + nwc = mbsrtowcs(s, (const char **)&mbp, n, &mbs); + free(f._bf._base); + if (nwc == (size_t)-1) { errno = EILSEQ; return (-1); } - free(f._bf._base); - if (s[n - 1] != L'\0') { + if (nwc == n) { s[n - 1] = L'\0'; errno = EOVERFLOW; return (-1); diff --git a/stdio/FreeBSD/vswprintf.c.patch b/stdio/FreeBSD/vswprintf.c.patch index 4e46d74..9e5555c 100644 --- a/stdio/FreeBSD/vswprintf.c.patch +++ b/stdio/FreeBSD/vswprintf.c.patch @@ -1,110 +1,63 @@ ---- vswprintf.c.orig 2004-11-25 11:38:36.000000000 -0800 -+++ vswprintf.c 2005-02-24 15:20:20.000000000 -0800 -@@ -33,6 +33,8 @@ +--- vswprintf.c.orig 2009-11-30 16:15:30.000000000 -0800 ++++ vswprintf.c 2009-12-03 15:21:59.000000000 -0800 +@@ -33,6 +33,8 @@ __FBSDID("FreeBSD: src/lib/libc/stdio/va #endif - __FBSDID("$FreeBSD: src/lib/libc/stdio/vswprintf.c,v 1.5 2004/04/07 09:55:05 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vswprintf.c,v 1.7 2008/04/17 22:17:54 jhb Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -49,7 +51,66 @@ - struct __sFILEX ext; +@@ -40,8 +42,8 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v + #include "local.h" + + int +-vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, +- __va_list ap) ++vswprintf_l(wchar_t * __restrict s, size_t n, locale_t loc, ++ const wchar_t * __restrict fmt, __va_list ap) + { + static const mbstate_t initial; + mbstate_t mbs; +@@ -49,7 +51,11 @@ vswprintf(wchar_t * __restrict s, size_t char *mbp; int ret, sverrno; -+ size_t conv; -+ locale_t loc = __current_locale(); -+ -+ if (n == 0) { -+ errno = EINVAL; -+ return (-1); -+ } -+ -+ f._file = -1; -+ f._flags = __SWR | __SSTR | __SALC; -+ f._bf._base = f._p = (unsigned char *)malloc(128); -+ if (f._bf._base == NULL) { -+ errno = ENOMEM; -+ return (-1); -+ } -+ f._bf._size = f._w = 127; /* Leave room for the NUL */ + size_t nwc; ++ struct __sFILEX ext; + f._extra = &ext; + INITEXTRA(&f); -+ ret = __vfwprintf(&f, loc, fmt, ap); -+ if (ret < 0) { -+ sverrno = errno; -+ free(f._bf._base); -+ errno = sverrno; -+ return (-1); -+ } -+ *f._p = '\0'; -+ mbp = (char *)f._bf._base; -+ /* -+ * XXX Undo the conversion from wide characters to multibyte that -+ * fputwc() did in __vfwprintf(). -+ */ -+ mbs = initial; -+ if ((conv = mbsrtowcs_l(s, (const char **)&mbp, n, &mbs, loc)) == (size_t)-1) { -+ free(f._bf._base); -+ errno = EILSEQ; -+ return (-1); -+ } -+ free(f._bf._base); -+ if (conv >= n) { -+ s[n - 1] = L'\0'; -+ errno = EOVERFLOW; -+ return (-1); -+ } -+ -+ return (ret); -+} -+ -+int -+vswprintf_l(wchar_t * __restrict s, size_t n, locale_t loc, -+ const wchar_t * __restrict fmt, __va_list ap) -+{ -+ static const mbstate_t initial; -+ mbstate_t mbs; -+ FILE f; -+ struct __sFILEX ext; -+ char *mbp; -+ int ret, sverrno; -+ size_t conv; + NORMALIZE_LOCALE(loc); if (n == 0) { errno = EINVAL; return (-1); -@@ -65,7 +126,7 @@ +@@ -65,7 +71,7 @@ vswprintf(wchar_t * __restrict s, size_t f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); - ret = __vfwprintf(&f, fmt, ap); + ret = __vfwprintf(&f, loc, fmt, ap); if (ret < 0) { sverrno = errno; free(f._bf._base); -@@ -73,19 +134,19 @@ - return (-1); - } - *f._p = '\0'; -- mbp = f._bf._base; -+ mbp = (char *)f._bf._base; - /* - * XXX Undo the conversion from wide characters to multibyte that +@@ -79,7 +85,7 @@ vswprintf(wchar_t * __restrict s, size_t * fputwc() did in __vfwprintf(). */ mbs = initial; -- if (mbsrtowcs(s, (const char **)&mbp, n, &mbs) == (size_t)-1) { -+ if ((conv = mbsrtowcs_l(s, (const char **)&mbp, n, &mbs, loc)) == (size_t)-1) { - free(f._bf._base); - errno = EILSEQ; - return (-1); - } +- nwc = mbsrtowcs(s, (const char **)&mbp, n, &mbs); ++ nwc = mbsrtowcs_l(s, (const char **)&mbp, n, &mbs, loc); free(f._bf._base); -- if (s[n - 1] != L'\0') { -+ if (conv >= n) { - s[n - 1] = L'\0'; - errno = EOVERFLOW; - return (-1); + if (nwc == (size_t)-1) { + errno = EILSEQ; +@@ -93,3 +99,10 @@ vswprintf(wchar_t * __restrict s, size_t + + return (ret); + } ++ ++int ++vswprintf(wchar_t * __restrict s, size_t n, ++ const wchar_t * __restrict fmt, __va_list ap) ++{ ++ return vswprintf_l(s, n, __current_locale(), fmt, ap); ++} diff --git a/stdio/FreeBSD/vswscanf.c b/stdio/FreeBSD/vswscanf.c index 03675d4..1c2648f 100644 --- a/stdio/FreeBSD/vswscanf.c +++ b/stdio/FreeBSD/vswscanf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -41,7 +37,7 @@ static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdio/vsscanf.c,v 1.11 2002/08/21 16:19:57 mike Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/stdio/vswscanf.c,v 1.3 2004/04/07 09:55:05 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vswscanf.c,v 1.6 2009/01/15 18:53:52 rdivacky Exp $"); #include #include @@ -67,10 +63,10 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, static const mbstate_t initial; mbstate_t mbs; FILE f; - struct __sFILEX ext; char *mbstr; size_t mlen; int r; + const wchar_t *strp; /* * XXX Convert the wide character string to multibyte, which @@ -79,7 +75,8 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, if ((mbstr = malloc(wcslen(str) * MB_CUR_MAX + 1)) == NULL) return (EOF); mbs = initial; - if ((mlen = wcsrtombs(mbstr, &str, SIZE_T_MAX, &mbs)) == (size_t)-1) { + strp = str; + if ((mlen = wcsrtombs(mbstr, &strp, SIZE_T_MAX, &mbs)) == (size_t)-1) { free(mbstr); return (EOF); } @@ -90,8 +87,8 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, f._read = eofread; f._ub._base = NULL; f._lb._base = NULL; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); r = __vfwscanf(&f, fmt, ap); free(mbstr); diff --git a/stdio/FreeBSD/vswscanf.c.patch b/stdio/FreeBSD/vswscanf.c.patch index 390ee66..a0a7584 100644 --- a/stdio/FreeBSD/vswscanf.c.patch +++ b/stdio/FreeBSD/vswscanf.c.patch @@ -1,57 +1,30 @@ ---- vswscanf.c.orig 2004-11-25 11:38:36.000000000 -0800 -+++ vswscanf.c 2005-02-23 17:03:30.000000000 -0800 -@@ -43,6 +43,8 @@ +--- vswscanf.c.orig 2009-11-30 16:15:30.000000000 -0800 ++++ vswscanf.c 2009-12-03 15:21:47.000000000 -0800 +@@ -39,6 +39,8 @@ __FBSDID("FreeBSD: src/lib/libc/stdio/vs #endif - __FBSDID("$FreeBSD: src/lib/libc/stdio/vswscanf.c,v 1.3 2004/04/07 09:55:05 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdio/vswscanf.c,v 1.6 2009/01/15 18:53:52 rdivacky Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -71,15 +73,55 @@ - char *mbstr; +@@ -57,7 +59,7 @@ eofread(void *cookie, char *buf, int len + } + + int +-vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, ++vswscanf_l(const wchar_t * __restrict str, locale_t loc, const wchar_t * __restrict fmt, + va_list ap) + { + static const mbstate_t initial; +@@ -67,16 +69,20 @@ vswscanf(const wchar_t * __restrict str, size_t mlen; int r; -+ locale_t loc = __current_locale(); -+ -+ /* -+ * XXX Convert the wide character string to multibyte, which -+ * __vfwscanf() will convert back to wide characters. -+ */ -+ if ((mbstr = malloc(wcslen(str) * MB_CUR_MAX_L(loc) + 1)) == NULL) -+ return (EOF); -+ mbs = initial; -+ if ((mlen = wcsrtombs_l(mbstr, &str, SIZE_T_MAX, &mbs, loc)) == (size_t)-1) { -+ free(mbstr); -+ return (EOF); -+ } -+ f._file = -1; -+ f._flags = __SRD; -+ f._bf._base = f._p = (unsigned char *)mbstr; -+ f._bf._size = f._r = mlen; -+ f._read = eofread; -+ f._ub._base = NULL; -+ f._lb._base = NULL; + const wchar_t *strp; ++ struct __sFILEX ext; + f._extra = &ext; + INITEXTRA(&f); -+ r = __vfwscanf(&f, loc, fmt, ap); -+ free(mbstr); -+ -+ return (r); -+} -+ -+int -+vswscanf_l(const wchar_t * __restrict str, locale_t loc, -+ const wchar_t * __restrict fmt, va_list ap) -+{ -+ static const mbstate_t initial; -+ mbstate_t mbs; -+ FILE f; -+ struct __sFILEX ext; -+ char *mbstr; -+ size_t mlen; -+ int r; + NORMALIZE_LOCALE(loc); /* @@ -62,17 +35,27 @@ + if ((mbstr = malloc(wcslen(str) * MB_CUR_MAX_L(loc) + 1)) == NULL) return (EOF); mbs = initial; -- if ((mlen = wcsrtombs(mbstr, &str, SIZE_T_MAX, &mbs)) == (size_t)-1) { -+ if ((mlen = wcsrtombs_l(mbstr, &str, SIZE_T_MAX, &mbs, loc)) == (size_t)-1) { + strp = str; +- if ((mlen = wcsrtombs(mbstr, &strp, SIZE_T_MAX, &mbs)) == (size_t)-1) { ++ if ((mlen = wcsrtombs_l(mbstr, &strp, SIZE_T_MAX, &mbs, loc)) == (size_t)-1) { free(mbstr); return (EOF); } -@@ -92,7 +134,7 @@ +@@ -89,8 +95,16 @@ vswscanf(const wchar_t * __restrict str, f._lb._base = NULL; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); - r = __vfwscanf(&f, fmt, ap); + r = __vfwscanf(&f, loc, fmt, ap); free(mbstr); return (r); + } ++ ++int ++vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, ++ va_list ap) ++{ ++ return vswscanf_l(str, __current_locale(), fmt, ap); ++} ++ diff --git a/stdio/FreeBSD/wbuf.c b/stdio/FreeBSD/wbuf.c index 3697be8..4f1c4aa 100644 --- a/stdio/FreeBSD/wbuf.c +++ b/stdio/FreeBSD/wbuf.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)wbuf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/wbuf.c,v 1.11 2004/06/08 05:45:32 das Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/wbuf.c,v 1.12 2007/01/09 00:28:08 imp Exp $"); #include #include "local.h" diff --git a/stdio/FreeBSD/wbuf.c.patch b/stdio/FreeBSD/wbuf.c.patch index 3d8a4ce..f878a04 100644 --- a/stdio/FreeBSD/wbuf.c.patch +++ b/stdio/FreeBSD/wbuf.c.patch @@ -1,14 +1,14 @@ ---- wbuf.c.orig 2004-06-07 22:45:32.000000000 -0700 -+++ wbuf.c 2004-10-25 00:49:10.000000000 -0700 -@@ -41,6 +41,7 @@ - __FBSDID("$FreeBSD: src/lib/libc/stdio/wbuf.c,v 1.11 2004/06/08 05:45:32 das Exp $"); +--- wbuf.c.bsdnew 2009-11-11 13:33:20.000000000 -0800 ++++ wbuf.c 2009-11-11 13:33:22.000000000 -0800 +@@ -37,6 +37,7 @@ static char sccsid[] = "@(#)wbuf.c 8.1 ( + __FBSDID("$FreeBSD: src/lib/libc/stdio/wbuf.c,v 1.12 2007/01/09 00:28:08 imp Exp $"); #include +#include #include "local.h" /* -@@ -65,8 +66,10 @@ +@@ -61,8 +62,10 @@ __swbuf(c, fp) * calls might wrap _w from negative to positive. */ fp->_w = fp->_lbfsize; diff --git a/stdio/FreeBSD/wprintf.3 b/stdio/FreeBSD/wprintf.3 index def25bd..39713e2 100644 --- a/stdio/FreeBSD/wprintf.3 +++ b/stdio/FreeBSD/wprintf.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/stdio/printf.3,v 1.47 2002/09/06 11:23:55 tjr Exp -.\" $FreeBSD: src/lib/libc/stdio/wprintf.3,v 1.5 2003/07/05 07:55:34 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/wprintf.3,v 1.6 2007/01/09 00:28:08 imp Exp $ .\" .Dd July 5, 2003 .Dt WPRINTF 3 diff --git a/stdio/FreeBSD/wprintf.3.patch b/stdio/FreeBSD/wprintf.3.patch index fa7ca8b..ed363e1 100644 --- a/stdio/FreeBSD/wprintf.3.patch +++ b/stdio/FreeBSD/wprintf.3.patch @@ -1,6 +1,6 @@ ---- wprintf.3.orig 2007-04-08 18:49:37.000000000 -0700 -+++ wprintf.3 2007-04-08 20:12:12.000000000 -0700 -@@ -41,8 +41,12 @@ +--- wprintf.3.bsdnew 2009-11-11 13:33:22.000000000 -0800 ++++ wprintf.3 2009-11-11 13:33:22.000000000 -0800 +@@ -37,8 +37,12 @@ .Dt WPRINTF 3 .Os .Sh NAME @@ -15,7 +15,7 @@ .Nd formatted wide character output conversion .Sh LIBRARY .Lb libc -@@ -50,23 +54,49 @@ +@@ -46,23 +50,49 @@ .In stdio.h .In wchar.h .Ft int @@ -72,7 +72,7 @@ as described below. The .Fn wprintf -@@ -87,6 +117,12 @@ +@@ -83,6 +113,12 @@ and write to the wide character string .Fa ws . .Pp @@ -85,7 +85,7 @@ These functions write the output under the control of a .Fa format string that specifies how subsequent arguments -@@ -96,7 +132,7 @@ +@@ -92,7 +128,7 @@ are converted for output. .Pp These functions return the number of characters printed (not including the trailing @@ -94,7 +94,7 @@ used to end output to strings). .Pp The -@@ -602,6 +638,7 @@ +@@ -598,6 +634,7 @@ Refer to .Xr putwc 3 , .Xr setlocale 3 , .Xr wcsrtombs 3 , @@ -102,7 +102,7 @@ .Xr wscanf 3 .Sh STANDARDS Subject to the caveats noted in the -@@ -614,7 +651,7 @@ +@@ -610,7 +647,7 @@ the .Fn fwprintf , .Fn swprintf , .Fn vwprintf , diff --git a/stdio/FreeBSD/wscanf.3 b/stdio/FreeBSD/wscanf.3 index b7eac3c..21d32ab 100644 --- a/stdio/FreeBSD/wscanf.3 +++ b/stdio/FreeBSD/wscanf.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)scanf.3 8.2 (Berkeley) 12/11/93 .\" FreeBSD: src/lib/libc/stdio/scanf.3,v 1.24 2003/06/28 09:03:25 das Exp -.\" $FreeBSD: src/lib/libc/stdio/wscanf.3,v 1.6 2003/07/05 07:47:55 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/wscanf.3,v 1.7 2007/01/09 00:28:08 imp Exp $ .\" .Dd July 5, 2003 .Dt WSCANF 3 diff --git a/stdio/FreeBSD/wscanf.3.patch b/stdio/FreeBSD/wscanf.3.patch index 1fd5edc..744d3e9 100644 --- a/stdio/FreeBSD/wscanf.3.patch +++ b/stdio/FreeBSD/wscanf.3.patch @@ -1,6 +1,6 @@ ---- wscanf.3.orig 2007-04-08 18:49:37.000000000 -0700 -+++ wscanf.3 2007-04-08 20:05:10.000000000 -0700 -@@ -41,12 +41,12 @@ +--- wscanf.3.bsdnew 2009-11-11 13:33:22.000000000 -0800 ++++ wscanf.3 2009-11-11 13:33:22.000000000 -0800 +@@ -37,12 +37,12 @@ .Dt WSCANF 3 .Os .Sh NAME @@ -16,7 +16,7 @@ .Nd wide character input format conversion .Sh LIBRARY .Lb libc -@@ -54,22 +54,46 @@ +@@ -50,22 +50,46 @@ .In stdio.h .In wchar.h .Ft int @@ -70,7 +70,7 @@ .Fa format as described below. This format may contain -@@ -89,7 +113,8 @@ +@@ -85,7 +109,8 @@ reads input from the stream pointer and .Fn swscanf reads its input from the wide character string pointed to by @@ -80,7 +80,7 @@ The .Fn vfwscanf function -@@ -121,6 +146,7 @@ +@@ -117,6 +142,7 @@ conversion below). All conversions are introduced by the .Cm % (percent sign) character. @@ -88,7 +88,7 @@ The .Fa format string -@@ -134,10 +160,16 @@ +@@ -130,10 +156,16 @@ Scanning stops when an input character does not match such a format character. Scanning also stops when an input conversion cannot be made (see below). @@ -106,7 +106,7 @@ there may be a number of .Em flag characters, as follows: -@@ -433,15 +465,12 @@ +@@ -429,15 +461,12 @@ of causes an immediate return of .Dv EOF . .Sh RETURN VALUES @@ -127,7 +127,7 @@ such as an alphabetic character for a .Ql %d conversion. -@@ -459,14 +488,15 @@ +@@ -455,14 +484,15 @@ the number of conversions which were suc .Xr wcstod 3 , .Xr wcstol 3 , .Xr wcstoul 3 , diff --git a/stdio/FreeBSD/wsetup.c b/stdio/FreeBSD/wsetup.c index 7b120ff..ea1b9e8 100644 --- a/stdio/FreeBSD/wsetup.c +++ b/stdio/FreeBSD/wsetup.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)wsetup.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/wsetup.c,v 1.9 2004/06/08 05:44:52 das Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/wsetup.c,v 1.11 2009/01/08 06:38:06 das Exp $"); #include #include @@ -64,6 +60,7 @@ __swsetup(fp) if ((fp->_flags & __SWR) == 0) { if ((fp->_flags & __SRW) == 0) { errno = EBADF; + fp->_flags |= __SERR; return (EOF); } if (fp->_flags & __SRD) { diff --git a/stdio/Makefile.inc b/stdio/Makefile.inc index af62bb4..a22dde9 100644 --- a/stdio/Makefile.inc +++ b/stdio/Makefile.inc @@ -6,33 +6,29 @@ CWD := ${.CURDIR}/stdio .include "Makefile.fbsd_begin" -FBSDMISRCS= _flock_stub.c asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c \ - fflush.c fgetc.c fgetln.c fgetpos.c fgets.c fgetwc.c fgetws.c \ +FBSDMISRCS= _flock_stub.c asprintf.c clrerr.c dprintf.c fclose.c fdopen.c feof.c ferror.c \ + fflush.c fgetc.c fgetln.c fgetpos.c fgets.c fgetwc.c fgetwln.c fgetws.c \ fileno.c findfp.c flags.c fopen.c fprintf.c fpurge.c fputc.c fputs.c \ fputwc.c fputws.c fread.c freopen.c fscanf.c fseek.c fsetpos.c \ ftell.c funopen.c fvwrite.c fwalk.c fwide.c fwprintf.c fwscanf.c \ - fwrite.c getc.c getchar.c gets.c getw.c getwc.c getwchar.c makebuf.c \ - mktemp.c perror.c printf.c putc.c putchar.c puts.c putw.c putwc.c \ + fwrite.c getc.c getchar.c getdelim.c getline.c gets.c getw.c getwc.c getwchar.c makebuf.c \ + mktemp.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 setvbuf.c snprintf.c sprintf.c sscanf.c stdio.c \ swprintf.c swscanf.c tempnam.c tmpfile.c tmpnam.c ungetc.c ungetwc.c \ - unlocked.c vasprintf.c vfprintf.c vfscanf.c vfwprintf.c vfwscanf.c \ + vasprintf.c vdprintf.c vfprintf.c vfscanf.c vfwprintf.c vfwscanf.c \ vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c vswprintf.c \ vswscanf.c vwprintf.c vwscanf.c wbuf.c wprintf.c wscanf.c wsetup.c -FBSDHDRS= floatio.h fvwrite.h glue.h local.h +FBSDHDRS= floatio.h fvwrite.h glue.h local.h printfcommon.h printflocal.h .include "Makefile.fbsd_end" # also build 64-bit long double versions (ppc only) -LDBLSRCS += asprintf.c fprintf.c fscanf.c fwprintf.c fwscanf.c printf.c \ +LDBLSRCS += asprintf.c dprintf.c fprintf.c fscanf.c fwprintf.c fwscanf.c printf.c \ scanf.c snprintf.c sprintf.c sscanf.c swprintf.c swscanf.c \ - vasprintf.c vfprintf.c vfscanf.c vfwprintf.c vfwscanf.c \ + vasprintf.c vdprintf.c vfprintf.c vfscanf.c vfwprintf.c vfwscanf.c \ vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c vswprintf.c \ vswscanf.c vwprintf.c vwscanf.c wprintf.c wscanf.c -.for _src in vfprintf-fbsd.c vfwprintf-fbsd.c -CFLAGS-${_src} += -fshort-enums -DVECTORS -.endfor - LEGACYSRCS+= fdopen.c fopen.c fputs.c freopen.c fwrite.c tempnam.c DARWINEXTSNSRCS+= fdopen.c fopen.c @@ -50,9 +46,9 @@ CFLAGS-tmpfile-fbsd.c += -D_DARWIN_UNLIMITED_STREAMS MAN3+= getwc_l.3 putwc_l.3 printf_l.3 scanf_l.3 wprintf_l.3 wscanf_l.3 .include "Makefile.fbsd_begin" -FBSDMAN3= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetws.3 flockfile.3 \ +FBSDMAN3= 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 \ - getwc.3 mktemp.3 printf.3 putc.3 putwc.3 remove.3 scanf.3 setbuf.3 \ + getline.3 getwc.3 mktemp.3 printf.3 putc.3 putwc.3 remove.3 scanf.3 setbuf.3 \ stdio.3 tmpnam.3 ungetc.3 ungetwc.3 wprintf.3 wscanf.3 .include "Makefile.fbsd_end" @@ -68,6 +64,8 @@ MLINKS+= fflush.3 fpurge.3 MLINKS+= fgets.3 gets.3 +MLINKS+= fgetwln.3 fgetwln_l.3 + MLINKS+= fgetws.3 fgetws_l.3 MLINKS+= flockfile.3 ftrylockfile.3 \ @@ -92,6 +90,8 @@ MLINKS+= fseek.3 fgetpos.3 \ MLINKS+= funopen.3 fropen.3 \ funopen.3 fwopen.3 +MLINKS+= getline.3 getdelim.3 + MLINKS+= getc.3 fgetc.3 \ getc.3 getc_unlocked.3 \ getc.3 getchar.3 \ @@ -109,10 +109,12 @@ MLINKS+= mktemp.3 mkdtemp.3 \ mktemp.3 mkstemps.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 \ printf.3 vfprintf.3 \ printf.3 vprintf.3 \ printf.3 vsnprintf.3 \ diff --git a/stdio/asprintf-fbsd.c b/stdio/asprintf-fbsd.c index 539d2ce..90c5617 100644 --- a/stdio/asprintf-fbsd.c +++ b/stdio/asprintf-fbsd.c @@ -1,8 +1,9 @@ -/* $OpenBSD: asprintf.c,v 1.8 2002/02/19 19:39:36 millert Exp $ */ - -/* - * Copyright (c) 1997 Todd C. Miller - * All rights reserved. +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -12,96 +13,51 @@ * 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED ``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 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. + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 -__FBSDID("$FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.13 2002/09/26 13:09:48 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.15 2009/03/02 04:11:42 das Exp $"); #include "xlocale_private.h" #include -#include -#include #include -#include "local.h" - int -asprintf(char **str, char const *fmt, ...) +asprintf(char ** __restrict s, char const * __restrict fmt, ...) { int ret; va_list ap; - FILE f; - struct __sFILEX ext; - f._file = -1; - f._flags = __SWR | __SSTR | __SALC; - f._bf._base = f._p = (unsigned char *)malloc(128); - if (f._bf._base == NULL) { - *str = NULL; - errno = ENOMEM; - return (-1); - } - f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); va_start(ap, fmt); - ret = __vfprintf(&f, __current_locale(), fmt, ap); /* Use unlocked __vfprintf */ + ret = vasprintf_l(s, __current_locale(), fmt, ap); va_end(ap); - if (ret < 0) { - free(f._bf._base); - *str = NULL; - errno = ENOMEM; - return (-1); - } - *f._p = '\0'; - *str = (char *)f._bf._base; return (ret); } int -asprintf_l(char **str, locale_t loc, char const *fmt, ...) +asprintf_l(char ** __restrict s, locale_t loc, char const * __restrict fmt, ...) { int ret; va_list ap; - FILE f; - struct __sFILEX ext; - NORMALIZE_LOCALE(loc); - f._file = -1; - f._flags = __SWR | __SSTR | __SALC; - f._bf._base = f._p = (unsigned char *)malloc(128); - if (f._bf._base == NULL) { - *str = NULL; - errno = ENOMEM; - return (-1); - } - f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); va_start(ap, fmt); - ret = __vfprintf(&f, loc, fmt, ap); /* Use unlocked __vfprintf */ + ret = vasprintf_l(s, loc, fmt, ap); va_end(ap); - if (ret < 0) { - free(f._bf._base); - *str = NULL; - errno = ENOMEM; - return (-1); - } - *f._p = '\0'; - *str = (char *)f._bf._base; return (ret); } diff --git a/stdio/FreeBSD/unlocked.c b/stdio/dprintf-fbsd.c similarity index 64% rename from stdio/FreeBSD/unlocked.c rename to stdio/dprintf-fbsd.c index 6b1c0ef..22115fa 100644 --- a/stdio/FreeBSD/unlocked.c +++ b/stdio/dprintf-fbsd.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Tim J. Robbins. + * Copyright (c) 2009 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,70 +25,35 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/unlocked.c,v 1.1 2003/01/10 04:35:08 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/dprintf.c,v 1.1 2009/03/04 03:38:51 das Exp $"); -#include - -#undef getchar_unlocked -int -getchar_unlocked(void) -{ - - return (__sgetc(stdin)); -} - -#undef getc_unlocked -int -getc_unlocked(FILE *fp) -{ - - return (__sgetc(fp)); -} - -#undef putchar_unlocked -int -putchar_unlocked(int ch) -{ - - return (__sputc(ch, stdout)); -} - -#undef putc_unlocked -int -putc_unlocked(int ch, FILE *fp) -{ +#include "xlocale_private.h" - return (__sputc(ch, fp)); -} - -#undef feof_unlocked -int -feof_unlocked(FILE *fp) -{ - - return (__sfeof(fp)); -} +#include "namespace.h" +#include +#include +#include "un-namespace.h" -#undef ferror_unlocked int -ferror_unlocked(FILE *fp) -{ - - return (__sferror(fp)); -} - -#undef clearerr_unlocked -void -clearerr_unlocked(FILE *fp) +dprintf(int fd, const char * __restrict fmt, ...) { + va_list ap; + int ret; - __sclearerr(fp); + va_start(ap, fmt); + ret = vdprintf_l(fd, __current_locale(), fmt, ap); + va_end(ap); + return (ret); } -#undef fileno_unlocked int -fileno_unlocked(FILE *fp) +dprintf_l(int fd, locale_t loc, const char * __restrict fmt, ...) { + va_list ap; + int ret; - return (__sfileno(fp)); + va_start(ap, fmt); + ret = vdprintf_l(fd, loc, fmt, ap); + va_end(ap); + return (ret); } diff --git a/stdio/fclose-fbsd.c b/stdio/fclose-fbsd.c index cd4ff1e..91df68a 100644 --- a/stdio/fclose-fbsd.c +++ b/stdio/fclose-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fclose.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fclose.c,v 1.11 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fclose.c,v 1.12 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/fdopen-fbsd.c b/stdio/fdopen-fbsd.c index fcac038..c49e36e 100644 --- a/stdio/fdopen-fbsd.c +++ b/stdio/fdopen-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -47,7 +43,7 @@ static char sccsid[] = "@(#)fdopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fdopen.c,v 1.7 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fdopen.c,v 1.11 2008/05/10 18:39:20 antoine Exp $"); #include "namespace.h" #include @@ -55,6 +51,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/fdopen.c,v 1.7 2002/03/22 21:53:04 obrien #include #include #include +#include #include "un-namespace.h" #include "local.h" @@ -64,11 +61,19 @@ fdopen(fd, mode) const char *mode; { FILE *fp; - static int nofile; int flags, oflags, fdflags, tmp; - if (nofile == 0) - nofile = getdtablesize(); + /* + * File descriptors are a full int, but _file is only a short. + * If we get a valid file descriptor that is greater than + * SHRT_MAX, then the fd will get sign-extended into an + * invalid file descriptor. Handle this case by failing the + * open. + */ + if (fd > SHRT_MAX) { + errno = EMFILE; + return (NULL); + } if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); diff --git a/stdio/fflush-fbsd.c b/stdio/fflush-fbsd.c index 34040cd..7c83b75 100644 --- a/stdio/fflush-fbsd.c +++ b/stdio/fflush-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fflush.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fflush.c,v 1.13 2004/07/04 20:17:00 cperciva Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fflush.c,v 1.14 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/fgetln-fbsd.c b/stdio/fgetln-fbsd.c deleted file mode 120000 index 61a12e8..0000000 --- a/stdio/fgetln-fbsd.c +++ /dev/null @@ -1 +0,0 @@ -./fgetln.c \ No newline at end of file diff --git a/stdio/fgetln-fbsd.c b/stdio/fgetln-fbsd.c new file mode 100644 index 0000000..8de4aa9 --- /dev/null +++ b/stdio/fgetln-fbsd.c @@ -0,0 +1,170 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)fgetln.c 8.2 (Berkeley) 1/2/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetln.c,v 1.11 2007/01/09 00:28:06 imp Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * Expand the line buffer. Return -1 on error. +#ifdef notdef + * The `new size' does not account for a terminating '\0', + * so we add 1 here. +#endif + */ +int +__slbexpand(FILE *fp, size_t newsize) +{ + void *p; + +#ifdef notdef + ++newsize; +#endif + if (fp->_lb._size >= newsize) + return (0); + if (newsize > INT_MAX) { + errno = ENOMEM; + return (-1); + } + if ((p = realloc(fp->_lb._base, newsize)) == NULL) + return (-1); + fp->_lb._base = p; + fp->_lb._size = newsize; + return (0); +} + +/* + * Get an input line. The returned pointer often (but not always) + * points into a stdio buffer. Fgetln does not alter the text of + * the returned line (which is thus not a C string because it will + * not necessarily end with '\0'), but does allow callers to modify + * it if they wish. Thus, we set __SMOD in case the caller does. + */ +char * +fgetln(FILE *fp, size_t *lenp) +{ + unsigned char *p; + size_t len; + size_t off; + + FLOCKFILE(fp); + ORIENT(fp, -1); + /* make sure there is input */ + if (fp->_r <= 0 && __srefill(fp)) { + *lenp = 0; + FUNLOCKFILE(fp); + return (NULL); + } + + /* look for a newline in the input */ + if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) != NULL) { + char *ret; + + /* + * Found one. Flag buffer as modified to keep fseek from + * `optimising' a backward seek, in case the user stomps on + * the text. + */ + p++; /* advance over it */ + ret = (char *)fp->_p; + *lenp = len = p - fp->_p; + fp->_flags |= __SMOD; + fp->_r -= len; + fp->_p = p; + FUNLOCKFILE(fp); + return (ret); + } + + /* + * We have to copy the current buffered data to the line buffer. + * 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 + * loop below. + */ +#define OPTIMISTIC 80 + + for (len = fp->_r, off = 0;; len += fp->_r) { + size_t diff; + + /* + * Make sure there is room for more bytes. Copy data from + * file buffer to line buffer, refill file and look for + * newline. The loop stops only when we find a newline. + */ + if (__slbexpand(fp, len + OPTIMISTIC)) + goto error; + (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, + len - off); + off = len; + if (__srefill(fp)) + break; /* EOF or error: return partial line */ + if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL) + continue; + + /* got it: finish up the line (like code above) */ + p++; + diff = p - fp->_p; + len += diff; + if (__slbexpand(fp, len)) + goto error; + (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, + diff); + fp->_r -= diff; + fp->_p = p; + break; + } + *lenp = len; +#ifdef notdef + fp->_lb._base[len] = 0; +#endif + FUNLOCKFILE(fp); + return ((char *)fp->_lb._base); + +error: + *lenp = 0; /* ??? */ + fp->_flags |= __SERR; + FUNLOCKFILE(fp); + return (NULL); /* ??? */ +} diff --git a/stdio/fgetln.3 b/stdio/fgetln.3 deleted file mode 120000 index 3f9ad0c..0000000 --- a/stdio/fgetln.3 +++ /dev/null @@ -1 +0,0 @@ -./fgetln.3 \ No newline at end of file diff --git a/stdio/fgetln.3 b/stdio/fgetln.3 new file mode 100644 index 0000000..61a3391 --- /dev/null +++ b/stdio/fgetln.3 @@ -0,0 +1,128 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. 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. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. +.\" +.\" @(#)fgetln.3 8.3 (Berkeley) 4/19/94 +.\" $FreeBSD: src/lib/libc/stdio/fgetln.3,v 1.10 2009/02/28 06:00:58 das Exp $ +.\" +.Dd April 19, 1994 +.Dt FGETLN 3 +.Os +.Sh NAME +.Nm fgetln +.Nd get a line from a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft char * +.Fn fgetln "FILE *stream" "size_t *len" +.Sh DESCRIPTION +The +.Fn fgetln +function +returns a pointer to the next line from the stream referenced by +.Fa stream . +This line is +.Em not +a C string as it does not end with a terminating +.Dv NUL +character. +The length of the line, including the final newline, +is stored in the memory location to which +.Fa len +points. +(Note, however, that if the line is the last +in a file that does not end in a newline, +the returned text will not contain a newline.) +.Sh RETURN VALUES +Upon successful completion a pointer is returned; +this pointer becomes invalid after the next +.Tn I/O +operation on +.Fa stream +(whether successful or not) +or as soon as the stream is closed. +Otherwise, +.Dv NULL +is returned. +The +.Fn fgetln +function +does not distinguish between end-of-file and error; the routines +.Xr feof 3 +and +.Xr ferror 3 +must be used +to determine which occurred. +If an error occurs, the global variable +.Va errno +is set to indicate the error. +The end-of-file condition is remembered, even on a terminal, and all +subsequent attempts to read will return +.Dv NULL +until the condition is +cleared with +.Xr clearerr 3 . +.Pp +The text to which the returned pointer points may be modified, +provided that no changes are made beyond the returned size. +These changes are lost as soon as the pointer becomes invalid. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +The argument +.Fa stream +is not a stream open for reading. +.It Bq Er ENOMEM +The internal line buffer could not be expanded due to lack of available memory, +or because it would need to expand beyond INT_MAX in size. +.El +.Pp +The +.Fn fgetln +function +may also fail and set +.Va errno +for any of the errors specified for the routines +.Xr fflush 3 , +.Xr malloc 3 , +.Xr read 2 , +.Xr stat 2 , +or +.Xr realloc 3 . +.Sh SEE ALSO +.Xr ferror 3 , +.Xr fgets 3 , +.Xr fgetwln 3 , +.Xr fopen 3 , +.Xr getline 3 , +.Xr putc 3 +.Sh HISTORY +The +.Fn fgetln +function first appeared in +.Bx 4.4 . diff --git a/stdio/fgets.3 b/stdio/fgets.3 deleted file mode 100644 index 6c6eaeb..0000000 --- a/stdio/fgets.3 +++ /dev/null @@ -1,161 +0,0 @@ -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Chris Torek and the American National Standards Committee X3, -.\" on Information Processing Systems. -.\" -.\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)fgets.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fgets.3,v 1.19 2002/12/04 18:57:45 ru Exp $ -.\" -.Dd June 4, 1993 -.Dt FGETS 3 -.Os -.Sh NAME -.Nm fgets , -.Nm gets -.Nd get a line from a stream -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In stdio.h -.Ft char * -.Fn fgets "char *restrict s" "int n" "FILE *restrict stream" -.Ft char * -.Fn gets "char *s" -.Sh DESCRIPTION -The -.Fn fgets -function -reads at most one less than the number of characters specified by -.Fa n -from the given -.Fa stream -and stores them in the string -.Fa s . -Reading stops when a newline character is found, -at end-of-file or error. -The newline, if any, is retained. -If any characters are read and there is no error, a -.Ql \e0 -character is appended to end the string. -.Pp -The -.Fn gets -function -is equivalent to -.Fn fgets -with an infinite -.Fa n -and a -.Fa stream -of -.Dv stdin , -except that the newline character (if any) is not stored in the string. -It is the caller's responsibility to ensure that the input line, -if any, is sufficiently short to fit in the string. -.Sh RETURN VALUES -Upon successful completion, -.Fn fgets -and -.Fn gets -return -a pointer to the string. -If end-of-file occurs before any characters are read, -they return -.Dv NULL -and the buffer contents remain unchanged. -If an error occurs, -they return -.Dv NULL -and the buffer contents are indeterminate. -The -.Fn fgets -and -.Fn gets -functions -do not distinguish between end-of-file and error; callers must use -.Xr feof 3 -and -.Xr ferror 3 -to determine which occurred. -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er EBADF -The given -.Fa stream -is not a readable stream. -.El -.Pp -The function -.Fn fgets -may also fail and set -.Va errno -for any of the errors specified for the routines -.Xr fflush 3 , -.Xr fstat 2 , -.Xr read 2 , -or -.Xr malloc 3 . -.Pp -The function -.Fn gets -may also fail and set -.Va errno -for any of the errors specified for the routine -.Xr getchar 3 . -.Sh SECURITY CONSIDERATIONS -The -.Fn gets -function cannot be used securely. -Because of its lack of bounds checking, -and the inability for the calling program -to reliably determine the length of the next incoming line, -the use of this function enables malicious users -to arbitrarily change a running program's functionality through -a buffer overflow attack. -It is strongly suggested that the -.Fn fgets -function be used in all cases. -(See -the FSA.) -.Sh SEE ALSO -.Xr feof 3 , -.Xr ferror 3 , -.Xr fgetln 3 , -.Xr fgetws 3 -.Sh STANDARDS -The functions -.Fn fgets -and -.Fn gets -conform to -.St -isoC-99 . diff --git a/stdio/fgets.3 b/stdio/fgets.3 new file mode 120000 index 0000000..e9f5002 --- /dev/null +++ b/stdio/fgets.3 @@ -0,0 +1 @@ +./fgets.3 \ No newline at end of file diff --git a/stdio/fgetwc-fbsd.c b/stdio/fgetwc-fbsd.c index af3dd5f..ead24c3 100644 --- a/stdio/fgetwc-fbsd.c +++ b/stdio/fgetwc-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwc.c,v 1.12 2004/07/20 08:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwc.c,v 1.13 2008/04/17 22:17:53 jhb Exp $"); #include "xlocale_private.h" @@ -89,7 +89,7 @@ __fgetwc(FILE *fp, locale_t loc) return (wc); } do { - nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_extra->mbstate, loc); + nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_mbstate, loc); if (nconv == (size_t)-1) break; else if (nconv == (size_t)-2) diff --git a/stdio/fgetwln-fbsd.c b/stdio/fgetwln-fbsd.c new file mode 100644 index 0000000..43485cb --- /dev/null +++ b/stdio/fgetwln-fbsd.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * 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 +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwln.c,v 1.2 2004/08/06 17:00:09 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +wchar_t * +fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t loc) +{ + wint_t wc; + size_t len; + + FLOCKFILE(fp); + ORIENT(fp, 1); + + len = 0; + while ((wc = __fgetwc(fp, loc)) != WEOF) { +#define GROW 512 + if (len * sizeof(wchar_t) >= fp->_lb._size && + __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) + goto error; + *((wchar_t *)fp->_lb._base + len++) = wc; + if (wc == L'\n') + break; + } + if (len == 0) + goto error; + + FUNLOCKFILE(fp); + *lenp = len; + return ((wchar_t *)fp->_lb._base); + +error: + FUNLOCKFILE(fp); + *lenp = 0; + return (NULL); +} + +wchar_t * +fgetwln(FILE * __restrict fp, size_t *lenp) +{ + return fgetwln_l(fp, lenp, __current_locale()); +} diff --git a/stdio/fgetwln.3 b/stdio/fgetwln.3 new file mode 100644 index 0000000..c38fb39 --- /dev/null +++ b/stdio/fgetwln.3 @@ -0,0 +1,129 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. 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. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. +.\" +.\" @(#)fgetln.3 8.3 (Berkeley) 4/19/94 +.\" $FreeBSD: src/lib/libc/stdio/fgetwln.3,v 1.3 2007/01/09 00:28:06 imp Exp $ +.\" +.Dd July 16, 2004 +.Dt FGETWLN 3 +.Os +.Sh NAME +.Nm fgetwln , +.Nm fgetwln_l +.Nd get a line of wide characters from a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft wchar_t * +.Fn fgetwln "FILE * restrict stream" "size_t * restrict len" +.In xlocale.h +.Ft wchar_t * +.Fn fgetwln_l "FILE * restrict stream" "size_t * restrict len" "locale_t loc" +.Sh DESCRIPTION +The +.Fn fgetwln +function +returns a pointer to the next line from the stream referenced by +.Fa stream . +This line is +.Em not +a standard wide character string as it does not end with a terminating +null wide character. +The length of the line, including the final newline, +is stored in the memory location to which +.Fa len +points. +(Note, however, that if the line is the last +in a file that does not end in a newline, +the returned text will not contain a newline.) +.Pp +While the +.Fn fgetwln +function uses the current locale, the +.Fn fgetwln_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +Upon successful completion a pointer is returned; +this pointer becomes invalid after the next +.Tn I/O +operation on +.Fa stream +(whether successful or not) +or as soon as the stream is closed. +Otherwise, +.Dv NULL +is returned. +The +.Fn fgetwln +function +does not distinguish between end-of-file and error; the routines +.Xr feof 3 +and +.Xr ferror 3 +must be used +to determine which occurred. +If an error occurs, the global variable +.Va errno +is set to indicate the error. +The end-of-file condition is remembered, even on a terminal, and all +subsequent attempts to read will return +.Dv NULL +until the condition is +cleared with +.Xr clearerr 3 . +.Pp +The text to which the returned pointer points may be modified, +provided that no changes are made beyond the returned size. +These changes are lost as soon as the pointer becomes invalid. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +The argument +.Fa stream +is not a stream open for reading. +.El +.Pp +The +.Fn fgetwln +function +may also fail and set +.Va errno +for any of the errors specified for the routines +.Xr mbrtowc 3 , +.Xr realloc 3 , +or +.Xr read 2 . +.Sh SEE ALSO +.Xr ferror 3 , +.Xr fgetln 3 , +.Xr fgetws 3 , +.Xr fopen 3 , +.Xr xlocale 3 diff --git a/stdio/fgetws-fbsd.c b/stdio/fgetws-fbsd.c index bd64c2b..278e809 100644 --- a/stdio/fgetws-fbsd.c +++ b/stdio/fgetws-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetws.c,v 1.6 2004/10/03 15:48:32 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetws.c,v 1.8 2009/11/25 04:45:45 wollman Exp $"); #include "xlocale_private.h" @@ -69,7 +69,7 @@ fgetws_l(wchar_t * __restrict ws, int n, FILE * __restrict fp, locale_t loc) nl = memchr(fp->_p, '\n', fp->_r); nconv = __mbsnrtowcs(wsp, &src, nl != NULL ? (nl - fp->_p + 1) : fp->_r, - n - 1, &fp->_extra->mbstate, loc); + n - 1, &fp->_mbstate, loc); if (nconv == (size_t)-1) /* Conversion error */ goto error; @@ -93,10 +93,10 @@ fgetws_l(wchar_t * __restrict ws, int n, FILE * __restrict fp, locale_t loc) if (wsp == ws) /* EOF */ goto error; - if (!rl->__mbsinit(&fp->_extra->mbstate, loc)) + if (!rl->__mbsinit(&fp->_mbstate, loc)) /* Incomplete character */ goto error; - *wsp++ = L'\0'; + *wsp = L'\0'; FUNLOCKFILE(fp); return (ws); diff --git a/stdio/fgetws.3 b/stdio/fgetws.3 index e29130c..49c9d90 100644 --- a/stdio/fgetws.3 +++ b/stdio/fgetws.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)fgets.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/stdio/fgets.3,v 1.16 2002/05/31 05:01:17 archie Exp -.\" $FreeBSD: src/lib/libc/stdio/fgetws.3,v 1.3 2003/03/09 02:56:54 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fgetws.3,v 1.4 2007/01/09 00:28:06 imp Exp $ .\" .Dd August 6, 2002 .Dt FGETWS 3 diff --git a/stdio/findfp-fbsd.c b/stdio/findfp-fbsd.c index 9f0300e..6cade0b 100644 --- a/stdio/findfp-fbsd.c +++ b/stdio/findfp-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,9 @@ static char sccsid[] = "@(#)findfp.c 8.2 (Berkeley) 1/4/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/findfp.c,v 1.29 2004/05/22 15:19:41 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/findfp.c,v 1.34 2009/12/05 19:31:38 ed Exp $"); + +#include #include #include @@ -58,32 +56,44 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/findfp.c,v 1.29 2004/05/22 15:19:41 tjr E int __sdidinit; +#if !TARGET_OS_EMBEDDED #define NDYNAMIC 10 /* add ten more whenever necessary */ +#else +#define NDYNAMIC 1 /* add one at a time on embedded */ +#endif -#define std(flags, file) \ - {0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \ - {0}, __sFX + file} - /* p r w flags file _bf z cookie close read seek write */ - /* _ub _extra */ -#define __sFXInit {0, PTHREAD_MUTEX_INITIALIZER} +#define std(flags, file) { \ + ._flags = (flags), \ + ._file = (file), \ + ._cookie = __sF + (file), \ + ._close = __sclose, \ + ._read = __sread, \ + ._seek = __sseek, \ + ._write = __swrite, \ + ._extra = __sFX + file, \ +} +#define __sFXInit {.fl_mutex = PTHREAD_MUTEX_INITIALIZER} /* set counted */ -#define __sFXInit3 {0, PTHREAD_MUTEX_INITIALIZER, 0, 0, 0, 1} - /* the usual - (stdin + stdout + stderr) */ +#define __sFXInit3 {.fl_mutex = PTHREAD_MUTEX_INITIALIZER, .counted = 1} static int __scounted; /* streams counted against STREAM_MAX */ static int __stream_max; +#if !TARGET_OS_EMBEDDED +/* usual and usual_extra are data pigs. See 7929728. For embedded we should + * always allocate dynamically, and probably should for desktop too. */ + /* the usual - (stdin + stdout + stderr) */ static FILE usual[FOPEN_MAX - 3]; static struct __sFILEX usual_extra[FOPEN_MAX - 3]; static struct glue uglue = { NULL, FOPEN_MAX - 3, usual }; +#endif /* !TARGET_OS_EMBEDDED */ static struct __sFILEX __sFX[3] = {__sFXInit3, __sFXInit3, __sFXInit3}; /* - * We can't make this 'static' until 6.0-current due to binary - * compatibility concerns. This also means we cannot change the - * sizeof(FILE) until that time either and must continue to use the - * __sFILEX stuff to add to FILE. + * We can't make this 'static' due to binary compatibility concerns. + * This also means we cannot change the sizeof(FILE) and must continue to + * use the __sFILEX stuff to add to FILE. */ FILE __sF[3] = { std(__SRD, STDIN_FILENO), @@ -91,19 +101,17 @@ FILE __sF[3] = { std(__SWR|__SNBF, STDERR_FILENO) }; -/* - * The following kludge is done to ensure enough binary compatibility - * with future versions of libc. Or rather it allows us to work with - * libraries that have been built with a newer libc that defines these - * symbols and expects libc to provide them. We only have need to support - * i386 and alpha because they are the only "old" systems we have deployed. - */ FILE *__stdinp = &__sF[0]; FILE *__stdoutp = &__sF[1]; FILE *__stderrp = &__sF[2]; +#if !TARGET_OS_EMBEDDED struct glue __sglue = { &uglue, 3, __sF }; static struct glue *lastglue = &uglue; +#else +struct glue __sglue = { NULL, 3, __sF }; +static struct glue *lastglue = &__sglue; +#endif static struct glue * moreglue(int); @@ -123,8 +131,8 @@ moreglue(n) { struct glue *g; static FILE empty; - static struct __sFILEX emptyx = __sFXInit; FILE *p; + static struct __sFILEX emptyx = __sFXInit; struct __sFILEX *fx; g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE) + @@ -136,6 +144,7 @@ moreglue(n) g->next = NULL; g->niobs = n; g->iobs = p; + while (--n >= 0) { *p = empty; p->_extra = fx; @@ -198,10 +207,8 @@ found: fp->_lb._base = NULL; /* no line buffer */ fp->_lb._size = 0; /* fp->_lock = NULL; */ /* once set always set (reused) */ - fp->_extra->fl_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; - fp->_extra->orientation = 0; + INITEXTRA(fp); fp->_extra->counted = count ? 1 : 0; - memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t)); return (fp); } @@ -211,9 +218,9 @@ found: __private_extern__ void __sfprelease(FILE *fp) { - if (fp->_extra->counted) { + if (fp->_counted) { OSAtomicDecrement32(&__scounted); - fp->_extra->counted = 0; + fp->_counted = 0; } fp->_flags = 0; } @@ -226,7 +233,7 @@ __warn_references(f_prealloc, "warning: this program uses f_prealloc(), which is not recommended."); void -f_prealloc() +f_prealloc(void) { struct glue *g; int n; @@ -267,19 +274,25 @@ _cleanup() void __sinit() { - int i; - THREAD_LOCK(); if (__sdidinit == 0) { - /* Set _extra for the usual suspects. */ - for (i = 0; i < FOPEN_MAX - 3; i++) - usual[i]._extra = &usual_extra[i]; - +#if !TARGET_OS_EMBEDDED + int i; +#endif /* Make sure we clean up on exit. */ __cleanup = _cleanup; /* conservative */ - __sdidinit = 1; __stream_max = sysconf(_SC_STREAM_MAX); __scounted = 3; /* std{in,out,err} already exists */ + +#if !TARGET_OS_EMBEDDED + /* Set _extra for the usual suspects. */ + for (i = 0; i < FOPEN_MAX - 3; i++) { + usual[i]._extra = &usual_extra[i]; + INITEXTRA(&usual[i]); + } +#endif + + __sdidinit = 1; } THREAD_UNLOCK(); } diff --git a/stdio/flags-fbsd.c b/stdio/flags-fbsd.c index 85687f6..3b90476 100644 --- a/stdio/flags-fbsd.c +++ b/stdio/flags-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)flags.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/flags.c,v 1.9 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/flags.c,v 1.10 2007/01/09 00:28:06 imp Exp $"); #include #include diff --git a/stdio/fopen-fbsd.c b/stdio/fopen-fbsd.c index fcc2f40..df3deea 100644 --- a/stdio/fopen-fbsd.c +++ b/stdio/fopen-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -47,14 +43,16 @@ static char sccsid[] = "@(#)fopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fopen.c,v 1.10 2002/10/12 16:13:37 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fopen.c,v 1.14 2008/04/22 17:03:32 jhb Exp $"); #include "namespace.h" #include #include #include +#include #include #include +#include #include "un-namespace.h" #include "local.h" @@ -76,6 +74,19 @@ fopen(file, mode) __sfprelease(fp); /* release */ return (NULL); } + /* + * File descriptors are a full int, but _file is only a short. + * If we get a valid file descriptor that is greater than + * SHRT_MAX, then the fd will get sign-extended into an + * invalid file descriptor. Handle this case by failing the + * open. + */ + if (f > SHRT_MAX) { + fp->_flags = 0; /* release */ + _close(f); + errno = EMFILE; + return (NULL); + } fp->_file = f; fp->_flags = flags; fp->_cookie = fp; diff --git a/stdio/fopen.3 b/stdio/fopen.3 index 0416170..3bb0c0f 100644 --- a/stdio/fopen.3 +++ b/stdio/fopen.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fopen.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fopen.3,v 1.18 2003/01/26 10:01:59 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fopen.3,v 1.21 2009/09/09 19:38:19 ed Exp $ .\" .Dd January 26, 2003 .Dt FOPEN 3 @@ -84,7 +80,7 @@ The stream is positioned at the beginning of the file. Open for reading and writing. The stream is positioned at the beginning of the file. .It Dq Li w -Truncate file to zero length or create text file for writing. +Truncate to zero length or create text file for writing. The stream is positioned at the beginning of the file. .It Dq Li w+ Open for reading and writing. @@ -110,7 +106,7 @@ or similar. .Pp The .Fa mode -string can also include the letter ``b'' either as a third character or +string can also include the letter ``b'' either as last character or as a character between the characters in any of the two-character strings described above. This is strictly for compatibility with diff --git a/stdio/fprintf-fbsd.c b/stdio/fprintf-fbsd.c index 9b9cdd4..76bca94 100644 --- a/stdio/fprintf-fbsd.c +++ b/stdio/fprintf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fprintf.c,v 1.10 2002/09/06 11:23:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fprintf.c,v 1.11 2007/01/09 00:28:06 imp Exp $"); #include "xlocale_private.h" diff --git a/stdio/fputs-fbsd.c b/stdio/fputs-fbsd.c index 5e99ef4..163541b 100644 --- a/stdio/fputs-fbsd.c +++ b/stdio/fputs-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fputs.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fputs.c,v 1.11 2002/10/12 16:13:37 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fputs.c,v 1.12 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/fputs.3 b/stdio/fputs.3 index 1c1eb7f..4c4ca1e 100644 --- a/stdio/fputs.3 +++ b/stdio/fputs.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fputs.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fputs.3,v 1.11 2002/12/19 09:40:24 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fputs.3,v 1.14 2007/04/19 14:01:04 phk Exp $ .\" .Dd June 4, 1993 .Dt FPUTS 3 @@ -75,14 +71,11 @@ and a terminating newline character, to the stream .Dv stdout . .Sh RETURN VALUES -The +The functions .Fn fputs -function -returns 0 on success and -.Dv EOF -on error; +and .Fn puts -returns a nonnegative integer on success and +return a nonnegative integer on success and .Dv EOF on error. .Sh ERRORS diff --git a/stdio/fputwc-fbsd.c b/stdio/fputwc-fbsd.c index df646f8..e835bc2 100644 --- a/stdio/fputwc-fbsd.c +++ b/stdio/fputwc-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fputwc.c,v 1.10 2004/07/20 08:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fputwc.c,v 1.11 2008/04/17 22:17:53 jhb Exp $"); #include "xlocale_private.h" @@ -59,8 +59,7 @@ __fputwc(wchar_t wc, FILE *fp, locale_t loc) *buf = (unsigned char)wc; len = 1; } else { - if ((len = xrl->__wcrtomb(buf, wc, &fp->_extra->mbstate, loc)) == - (size_t)-1) { + if ((len = loc->__lc_ctype->__wcrtomb(buf, wc, &fp->_mbstate, loc)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); } diff --git a/stdio/fputws-fbsd.c b/stdio/fputws-fbsd.c index e299065..1ff0484 100644 --- a/stdio/fputws-fbsd.c +++ b/stdio/fputws-fbsd.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fputws.c,v 1.6 2004/07/21 10:54:57 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fputws.c,v 1.8 2009/01/15 18:53:52 rdivacky Exp $"); #include "xlocale_private.h" @@ -47,6 +47,7 @@ fputws_l(const wchar_t * __restrict ws, FILE * __restrict fp, locale_t loc) char buf[BUFSIZ]; struct __suio uio; struct __siov iov; + const wchar_t *wsp = ws; size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict, locale_t); @@ -60,14 +61,14 @@ fputws_l(const wchar_t * __restrict ws, FILE * __restrict fp, locale_t loc) uio.uio_iovcnt = 1; iov.iov_base = buf; do { - nbytes = __wcsnrtombs(buf, &ws, SIZE_T_MAX, sizeof(buf), - &fp->_extra->mbstate, loc); + nbytes = __wcsnrtombs(buf, &wsp, SIZE_T_MAX, sizeof(buf), + &fp->_mbstate, loc); if (nbytes == (size_t)-1) goto error; iov.iov_len = uio.uio_resid = nbytes; if (__sfvwrite(fp, &uio) != 0) goto error; - } while (ws != NULL); + } while (wsp != NULL); FUNLOCKFILE(fp); return (0); diff --git a/stdio/fputws.3 b/stdio/fputws.3 index 3882b1b..d7326b2 100644 --- a/stdio/fputws.3 +++ b/stdio/fputws.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)fputs.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/stdio/fputs.3,v 1.8 2001/10/01 16:08:59 ru Exp -.\" $FreeBSD: src/lib/libc/stdio/fputws.3,v 1.5 2003/05/22 13:02:27 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fputws.3,v 1.6 2007/01/09 00:28:06 imp Exp $ .\" .Dd August 6, 2002 .Dt FPUTWS 3 diff --git a/stdio/fread-fbsd.c b/stdio/fread-fbsd.c index 95edcc3..544d94a 100644 --- a/stdio/fread-fbsd.c +++ b/stdio/fread-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fread.c 8.2 (Berkeley) 12/11/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fread.c,v 1.12 2002/10/12 16:13:37 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fread.c,v 1.16 2009/07/12 13:09:43 ed Exp $"); #include "namespace.h" #include @@ -47,11 +43,23 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/fread.c,v 1.12 2002/10/12 16:13:37 mike E #include "local.h" #include "libc_private.h" +/* + * MT-safe version + */ + size_t -fread(buf, size, count, fp) - void * __restrict buf; - size_t size, count; - FILE * __restrict fp; +fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) +{ + size_t ret; + + FLOCKFILE(fp); + ret = __fread(buf, size, count, fp); + FUNLOCKFILE(fp); + return (ret); +} + +size_t +__fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) { size_t resid; char *p; @@ -59,13 +67,10 @@ fread(buf, size, count, fp) size_t total; /* - * The ANSI standard requires a return value of 0 for a count - * or a size of 0. Peculiarily, it imposes no such requirements - * on fwrite; it only requires fread to be broken. + * ANSI and SUSv2 require a return value of 0 if size or count are 0. */ if ((resid = count * size) == 0) return (0); - FLOCKFILE(fp); ORIENT(fp, -1); if (fp->_r < 0) fp->_r = 0; @@ -82,7 +87,6 @@ fread(buf, size, count, fp) break; else if (ret) { /* no more input: return partial result */ - FUNLOCKFILE(fp); return ((total - resid) / size); } } @@ -106,7 +110,6 @@ fread(buf, size, count, fp) fp->_bf = save; fp->_p = fp->_bf._base; /* fp->_r = 0; already set in __srefill1 */ - FUNLOCKFILE(fp); return ((total - resid) / size); } fp->_bf._base += fp->_r; @@ -127,7 +130,6 @@ fread(buf, size, count, fp) resid -= r; if (__srefill1(fp)) { /* no more input: return partial result */ - FUNLOCKFILE(fp); return ((total - resid) / size); } } @@ -135,6 +137,5 @@ fread(buf, size, count, fp) fp->_r -= resid; fp->_p += resid; } - FUNLOCKFILE(fp); return (count); } diff --git a/stdio/fread.3 b/stdio/fread.3 index ffebed6..1ba5005 100644 --- a/stdio/fread.3 +++ b/stdio/fread.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fread.3 8.2 (Berkeley) 3/8/94 -.\" $FreeBSD: src/lib/libc/stdio/fread.3,v 1.9 2002/10/12 16:13:37 mike Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fread.3,v 1.10 2007/01/09 00:28:06 imp Exp $ .\" .Dd March 8, 1994 .Dt FREAD 3 diff --git a/stdio/freopen-fbsd.c b/stdio/freopen-fbsd.c index 0ce1588..3451106 100644 --- a/stdio/freopen-fbsd.c +++ b/stdio/freopen-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,13 +34,14 @@ static char sccsid[] = "@(#)freopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/freopen.c,v 1.13 2004/05/22 15:19:41 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/freopen.c,v 1.21 2008/04/17 22:17:54 jhb Exp $"); #include "namespace.h" #include #include #include #include +#include #include #include #include @@ -67,7 +64,9 @@ freopen(file, mode, fp) int dflags, flags, isopen, oflags, sverrno, wantfd; if ((flags = __sflags(mode, &oflags)) == 0) { + sverrno = errno; (void) fclose(fp); + errno = sverrno; return (NULL); } @@ -102,6 +101,8 @@ freopen(file, mode, fp) errno = EBADF; return (NULL); } + if (fp->_flags & __SWR) + (void) __sflush(fp); if ((oflags ^ dflags) & O_APPEND) { dflags &= ~O_APPEND; dflags |= oflags & O_APPEND; @@ -114,15 +115,9 @@ freopen(file, mode, fp) } } if (oflags & O_TRUNC) - ftruncate(fp->_file, 0); - if (_fseeko(fp, 0, oflags & O_APPEND ? SEEK_END : SEEK_SET, - 0) < 0 && errno != ESPIPE) { - sverrno = errno; - fclose(fp); - FUNLOCKFILE(fp); - errno = sverrno; - return (NULL); - } + (void) ftruncate(fp->_file, (off_t)0); + if (!(oflags & O_APPEND)) + (void) _sseek(fp, (fpos_t)0, SEEK_SET); f = fp->_file; isopen = 0; wantfd = -1; @@ -196,13 +191,13 @@ finish: if (HASLB(fp)) FREELB(fp); fp->_lb._size = 0; - fp->_extra->orientation = 0; - memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t)); + fp->_orientation = 0; + memset(&fp->_mbstate, 0, sizeof(mbstate_t)); if (f < 0) { /* did not get it after all */ __sfprelease(fp); /* set it free */ - errno = sverrno; /* restore in case _close clobbered */ FUNLOCKFILE(fp); + errno = sverrno; /* restore in case _close clobbered */ return (NULL); } @@ -218,6 +213,20 @@ finish: } } + /* + * File descriptors are a full int, but _file is only a short. + * If we get a valid file descriptor that is greater than + * SHRT_MAX, then the fd will get sign-extended into an + * invalid file descriptor. Handle this case by failing the + * open. + */ + if (f > SHRT_MAX) { + __sfprelease(fp); /* set it free */ + FUNLOCKFILE(fp); + errno = EMFILE; + return (NULL); + } + fp->_flags = flags; fp->_file = f; fp->_cookie = fp; @@ -225,6 +234,16 @@ finish: fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; + /* + * When opening in append mode, even though we use O_APPEND, + * we need to seek to the end so that ftell() gets the right + * answer. If the user then alters the seek pointer, or + * the file extends, this will fail, but there is not much + * we can do about this. (We could set __SAPP and check in + * fseek and ftell.) + */ + if (oflags & O_APPEND) + (void) _sseek(fp, (fpos_t)0, SEEK_END); FUNLOCKFILE(fp); return (fp); } diff --git a/stdio/fscanf-fbsd.c b/stdio/fscanf-fbsd.c index 3bf8252..2db747e 100644 --- a/stdio/fscanf-fbsd.c +++ b/stdio/fscanf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fscanf.c,v 1.12 2003/01/03 23:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fscanf.c,v 1.13 2007/01/09 00:28:06 imp Exp $"); #include "xlocale_private.h" diff --git a/stdio/fseek.3 b/stdio/fseek.3 index 5c46469..edf7791 100644 --- a/stdio/fseek.3 +++ b/stdio/fseek.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fseek.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fseek.3,v 1.25 2004/03/20 08:38:27 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fseek.3,v 1.27 2007/06/18 02:13:04 ache Exp $ .\" .Dd March 19, 2004 .Dt FSEEK 3 @@ -255,8 +251,9 @@ The functions .Fn fseeko , .Fn fsetpos , .Fn ftell , +.Fn ftello , and -.Fn ftello +.Fn rewind may also fail and set .Va errno for any of the errors specified for the routines diff --git a/stdio/ftell-fbsd.c b/stdio/ftell-fbsd.c index 4c80885..8bb5716 100644 --- a/stdio/ftell-fbsd.c +++ b/stdio/ftell-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)ftell.c 8.2 (Berkeley) 5/4/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/ftell.c,v 1.26 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/ftell.c,v 1.27 2007/01/09 00:28:06 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/funopen-fbsd.c b/stdio/funopen-fbsd.c index ac00f99..408f0f4 100644 --- a/stdio/funopen-fbsd.c +++ b/stdio/funopen-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)funopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/funopen.c,v 1.5 2002/05/28 16:59:39 alfred Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/funopen.c,v 1.7 2009/12/05 19:31:38 ed Exp $"); #include #include @@ -46,11 +42,11 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/funopen.c,v 1.5 2002/05/28 16:59:39 alfre #include "local.h" FILE * -funopen(cookie, readfn, writefn, seekfn, closefn) - const void *cookie; - int (*readfn)(), (*writefn)(); - fpos_t (*seekfn)(void *cookie, fpos_t off, int whence); - int (*closefn)(); +funopen(const void *cookie, + int (*readfn)(void *, char *, int), + int (*writefn)(void *, const char *, int), + fpos_t (*seekfn)(void *, fpos_t, int), + int (*closefn)(void *)) { FILE *fp; int flags; diff --git a/stdio/fwrite-fbsd.c b/stdio/fwrite-fbsd.c index 6f51be3..b1910c1 100644 --- a/stdio/fwrite-fbsd.c +++ b/stdio/fwrite-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fwrite.c,v 1.11 2002/10/12 16:13:41 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fwrite.c,v 1.13 2009/07/12 13:09:43 ed Exp $"); #include "namespace.h" #include @@ -61,13 +57,16 @@ fwrite(buf, size, count, fp) struct __suio uio; struct __siov iov; - iov.iov_base = (void *)buf; - uio.uio_resid = iov.iov_len = n = count * size; - + /* + * ANSI and SUSv2 require a return value of 0 if size or count are 0. + */ + n = count * size; #if __DARWIN_UNIX03 - if (n == 0) /* POSIX */ - return 0; -#endif /* __DARWIN_UNIX03 */ + if (n == 0) + return (0); +#endif + iov.iov_base = (void *)buf; + uio.uio_resid = iov.iov_len = n; uio.uio_iov = &iov; uio.uio_iovcnt = 1; diff --git a/stdio/getc.3 b/stdio/getc.3 index 2d9ea4e..b1c114b 100644 --- a/stdio/getc.3 +++ b/stdio/getc.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/getc.3,v 1.19 2004/03/17 12:37:28 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/getc.3,v 1.21 2007/01/09 00:28:06 imp Exp $ .\" .Dd January 10, 2003 .Dt GETC 3 diff --git a/stdio/getdelim-fbsd.c b/stdio/getdelim-fbsd.c new file mode 120000 index 0000000..d0d70e5 --- /dev/null +++ b/stdio/getdelim-fbsd.c @@ -0,0 +1 @@ +./getdelim.c \ No newline at end of file diff --git a/stdio/getline-fbsd.c b/stdio/getline-fbsd.c new file mode 120000 index 0000000..4ac67a7 --- /dev/null +++ b/stdio/getline-fbsd.c @@ -0,0 +1 @@ +./getline.c \ No newline at end of file diff --git a/stdio/getline.3 b/stdio/getline.3 new file mode 100644 index 0000000..ddefe70 --- /dev/null +++ b/stdio/getline.3 @@ -0,0 +1,135 @@ +.\" Copyright (c) 2009 David Schultz +.\" 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: src/lib/libc/stdio/getline.3,v 1.2 2009/04/06 13:50:04 das Exp $ +.\" +.Dd March 29, 2009 +.Dt GETLINE 3 +.Os +.Sh NAME +.Nm getdelim , +.Nm getline +.Nd get a line from a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft ssize_t +.Fn getdelim "char ** restrict linep" "size_t * restrict linecapp" "int delimiter" " FILE * restrict stream" +.Ft ssize_t +.Fn getline "char ** restrict linep" "size_t * restrict linecapp" " FILE * restrict stream" +.Sh DESCRIPTION +The +.Fn getdelim +function reads a line from +.Fa stream , +delimited by the character +.Fa delimiter . +The +.Fn getline +function is equivalent to +.Fn getdelim +with the newline character as the delimiter. +The delimiter character is included as part of the line, unless +the end of the file is reached. +The caller may provide a pointer to a malloc buffer for the line in +.Fa *linep , +and the capacity of that buffer in +.Fa *linecapp ; +if +.Fa *linecapp +is 0, then +.Fa *linep +is treated as +.Dv NULL . +These functions may expand the buffer as needed, as if via +.Fn realloc , +and update +.Fa *linep +and +.Fa *linecapp +accordingly. +.Sh RETURN VALUES +The +.Fn getdelim +and +.Fn getline +functions return the number of characters written, excluding the +terminating +.Dv NULL . +The value \-1 is returned if an error occurs, or if end-of-file is reached. +.Sh EXAMPLES +The following code fragment reads lines from a file and +writes them to standard output. +The +.Fn fwrite +function is used in case the line contains embedded +.Dv NUL +characters. +.Bd -literal -offset indent +char *line = NULL; +size_t linecap = 0; +ssize_t linelen; +while ((linelen = getline(&line, &linecap, fp)) > 0) + fwrite(line, linelen, 1, stdout); +.Ed +.Sh ERRORS +These functions may fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +Either +.Fa linep +or +.Fa linecapp +is +.Dv NULL . +.It Bq Er EOVERFLOW +No delimiter was found in the first +.Dv SSIZE_MAX +characters. +.El +.Pp +These functions may also fail for any of the errors specified for +.Fn fgets +and +.Fn malloc . +.Sh SEE ALSO +.Xr fgetln 3 , +.Xr fgets 3 , +.Xr malloc 3 +.Sh STANDARDS +The +.Fn getdelim +and +.Fn getline +functions conform to +.St -p1003.1-2008 . +.Sh HISTORY +These routines first appeared in +.Fx 8.0 . +.Sh BUGS +There are no wide character versions of +.Fn getdelim +or +.Fn getline . diff --git a/stdio/getwc.3 b/stdio/getwc.3 index b1e0bef..d994aad 100644 --- a/stdio/getwc.3 +++ b/stdio/getwc.3 @@ -15,10 +15,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -36,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/getwc.3,v 1.6 2004/03/16 13:30:11 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/getwc.3,v 1.8 2007/01/09 00:28:06 imp Exp $ .\" .Dd March 3, 2004 .Dt GETWC 3 @@ -56,7 +52,7 @@ .Ft wint_t .Fn getwc "FILE *stream" .Ft wint_t -.Fn getwchar void +.Fn getwchar "void" .Sh DESCRIPTION The .Fn fgetwc @@ -110,7 +106,7 @@ until the condition is cleared with .Xr fopen 3 , .Xr fread 3 , .Xr getc 3 , -.Xr getwc_l 3 , +.Xr getwc_l , .Xr putwc 3 , .Xr stdio 3 , .Xr ungetwc 3 diff --git a/stdio/glue.h b/stdio/glue.h deleted file mode 100644 index ef74293..0000000 --- a/stdio/glue.h +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * @(#)glue.h 8.1 (Berkeley) 6/4/93 - * $FreeBSD: src/lib/libc/stdio/glue.h,v 1.2 2002/03/22 23:42:01 obrien Exp $ - */ - -/* - * The first few FILEs are statically allocated; others are dynamically - * allocated and linked in via this glue structure. - */ -struct glue { - struct glue *next; - int niobs; - FILE *iobs; -}; -extern struct glue __sglue; diff --git a/stdio/glue.h b/stdio/glue.h new file mode 120000 index 0000000..5f05123 --- /dev/null +++ b/stdio/glue.h @@ -0,0 +1 @@ +./glue.h \ No newline at end of file diff --git a/stdio/local.h b/stdio/local.h index 6278c2c..73958b7 100644 --- a/stdio/local.h +++ b/stdio/local.h @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,7 +30,7 @@ * SUCH DAMAGE. * * @(#)local.h 8.3 (Berkeley) 7/3/94 - * $FreeBSD: src/lib/libc/stdio/local.h,v 1.26 2004/07/16 05:52:51 tjr Exp $ + * $FreeBSD: src/lib/libc/stdio/local.h,v 1.33 2008/05/05 16:03:52 jhb Exp $ */ #include @@ -56,10 +52,11 @@ extern fpos_t _sseek(FILE *, fpos_t, int); extern int _ftello(FILE *, fpos_t *); extern int _fseeko(FILE *, off_t, int, int); extern int __fflush(FILE *fp); +extern void __fcloseall(void); extern wint_t __fgetwc(FILE *, locale_t); extern wint_t __fputwc(wchar_t, FILE *, locale_t); extern int __sflush(FILE *); -extern FILE *__sfp(int); /* arg is whether to count against STREAM_MAX or not */ +extern FILE *__sfp(int); extern void __sfprelease(FILE *); /* mark free and update count as needed */ extern int __slbexpand(FILE *, size_t); extern int __srefill(FILE *); @@ -85,13 +82,14 @@ extern int __vfscanf(FILE *, const char *, __va_list) __DARWIN_LDBL_COMPAT(__vfs extern int __vfwprintf(FILE *, locale_t, const wchar_t *, __va_list) __DARWIN_LDBL_COMPAT(__vfwprintf); extern int __vfwscanf(FILE * __restrict, locale_t, const wchar_t * __restrict, __va_list) __DARWIN_LDBL_COMPAT(__vfwscanf); - +extern size_t __fread(void * __restrict buf, size_t size, size_t count, + FILE * __restrict fp); extern int __sdidinit; /* hold a buncha junk that would grow the ABI */ struct __sFILEX { - unsigned char *_up; /* saved _p when _p is doing ungetc data */ + unsigned char *up; /* saved _p when _p is doing ungetc data */ pthread_mutex_t fl_mutex; /* used for MT-safety */ pthread_t fl_owner; /* current owner */ int fl_count; /* recursive lock count */ @@ -100,6 +98,24 @@ struct __sFILEX { mbstate_t mbstate; /* multibyte conversion state */ }; +#define _up _extra->up +#define _fl_mutex _extra->fl_mutex +#define _fl_owner _extra->fl_owner +#define _fl_count _extra->fl_count +#define _orientation _extra->orientation +#define _mbstate _extra->mbstate +#define _counted _extra->counted + +#define INITEXTRA(fp) do { \ + (fp)->_extra->up = NULL; \ + (fp)->_extra->fl_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; \ + (fp)->_extra->fl_owner = NULL; \ + (fp)->_extra->fl_count = 0; \ + (fp)->_extra->orientation = 0; \ + memset(&(fp)->_extra->mbstate, 0, sizeof(mbstate_t)); \ + (fp)->_extra->counted = 0; \ +} while(0); + /* * Prepare the given FILE for writing, and return 0 iff it * can be written now. Otherwise, return EOF and set errno. @@ -129,20 +145,11 @@ struct __sFILEX { (fp)->_lb._base = NULL; \ } -#define INITEXTRA(fp) { \ - (fp)->_extra->_up = NULL; \ - (fp)->_extra->fl_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; \ - (fp)->_extra->fl_owner = NULL; \ - (fp)->_extra->fl_count = 0; \ - (fp)->_extra->orientation = 0; \ - memset(&(fp)->_extra->mbstate, 0, sizeof(mbstate_t)); \ -} - /* * Set the orientation for a stream. If o > 0, the stream has wide- * orientation. If o < 0, the stream has byte-orientation. */ #define ORIENT(fp, o) do { \ - if ((fp)->_extra->orientation == 0) \ - (fp)->_extra->orientation = (o); \ + if ((fp)->_orientation == 0) \ + (fp)->_orientation = (o); \ } while (0) diff --git a/stdio/makebuf-fbsd.c b/stdio/makebuf-fbsd.c index d011a26..17e45e2 100644 --- a/stdio/makebuf-fbsd.c +++ b/stdio/makebuf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)makebuf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/makebuf.c,v 1.4 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/makebuf.c,v 1.6 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include @@ -46,9 +42,11 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/makebuf.c,v 1.4 2002/03/22 21:53:04 obrie #include #include #include -#include "local.h" #include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + #define MAXBUFSIZE (1 << 16) #define TTYBUFSIZE 4096 diff --git a/stdio/mktemp-fbsd.c b/stdio/mktemp-fbsd.c index 244cc00..5e288f8 100644 --- a/stdio/mktemp-fbsd.c +++ b/stdio/mktemp-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,12 +31,11 @@ static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/mktemp.c,v 1.28 2003/02/16 17:29:10 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/mktemp.c,v 1.32 2010/02/28 13:31:29 jh Exp $"); #include "namespace.h" -#include +#include #include -#include #include #include #include @@ -112,7 +107,7 @@ _gettemp(path, doopen, domkdir, slen) struct stat sbuf; int rval; uint32_t rand; - char carrybuf[NAME_MAX]; + char carrybuf[MAXPATHLEN]; if ((doopen != NULL && domkdir) || slen < 0) { errno = EINVAL; @@ -121,6 +116,10 @@ _gettemp(path, doopen, domkdir, slen) for (trv = path; *trv != '\0'; ++trv) ; + if (trv - path >= MAXPATHLEN) { + errno = ENAMETOOLONG; + return (0); + } trv -= slen; suffp = trv; --trv; diff --git a/stdio/mktemp.3 b/stdio/mktemp.3 index 0606202..f55ceef 100644 --- a/stdio/mktemp.3 +++ b/stdio/mktemp.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)mktemp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/mktemp.3,v 1.20 2004/02/20 04:08:28 green Exp $ +.\" $FreeBSD: src/lib/libc/stdio/mktemp.3,v 1.22 2007/01/09 00:28:07 imp Exp $ .\" .Dd February 11, 1998 .Dt MKTEMP 3 @@ -38,8 +34,8 @@ .Sh NAME .Nm mkdtemp , .Nm mkstemp , -.Nm mktemp , -.Nm mktemps +.Nm mkstemps , +.Nm mktemp .Nd make temporary file name (unique) .Sh LIBRARY .Lb libc @@ -203,35 +199,6 @@ so that it will store string constants in a writable segment of memory. See .Xr gcc 1 for more information. -.Sh BUGS -This family of functions produces filenames which can be guessed, -though the risk is minimized when large numbers of -.Ql X Ns s -are used to -increase the number of possible temporary filenames. -This makes the race in -.Fn mktemp , -between testing for a file's existence (in the -.Fn mktemp -function call) -and opening it for use -(later in the user application) -particularly dangerous from a security perspective. -Whenever it is possible, -.Fn mkstemp -should be used instead, since it does not have the race condition. -If -.Fn mkstemp -cannot be used, the filename created by -.Fn mktemp -should be created using the -.Dv O_EXCL -flag to -.Xr open 2 -and the return status of the call should be tested for failure. -This will ensure that the program does not continue blindly -in the event that an attacker has already created the file -with the intention of manipulating or reading its contents. .Sh LEGACY SYNOPSIS .Fd #include .Pp @@ -266,3 +233,32 @@ function first appeared in .Ox 2.4 , and later in .Fx 3.4 . +.Sh BUGS +This family of functions produces filenames which can be guessed, +though the risk is minimized when large numbers of +.Ql X Ns s +are used to +increase the number of possible temporary filenames. +This makes the race in +.Fn mktemp , +between testing for a file's existence (in the +.Fn mktemp +function call) +and opening it for use +(later in the user application) +particularly dangerous from a security perspective. +Whenever it is possible, +.Fn mkstemp +should be used instead, since it does not have the race condition. +If +.Fn mkstemp +cannot be used, the filename created by +.Fn mktemp +should be created using the +.Dv O_EXCL +flag to +.Xr open 2 +and the return status of the call should be tested for failure. +This will ensure that the program does not continue blindly +in the event that an attacker has already created the file +with the intention of manipulating or reading its contents. diff --git a/stdio/perror-fbsd.c b/stdio/perror-fbsd.c deleted file mode 100644 index 8b5934b..0000000 --- a/stdio/perror-fbsd.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 1988, 1993 - * The Regents of the University of California. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)perror.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/stdio/perror.c,v 1.8 2002/12/19 09:53:26 tjr Exp $"); - -#include "namespace.h" -#include -#include -#include -#include -#include -#include -#include -#include "un-namespace.h" -#include "libc_private.h" -#include "local.h" - -void -perror(s) - const char *s; -{ - char msgbuf[NL_TEXTMAX]; - struct iovec *v; - struct iovec iov[4]; - - v = iov; - if (s != NULL && *s != '\0') { - v->iov_base = (char *)s; - v->iov_len = strlen(s); - v++; - v->iov_base = ": "; - v->iov_len = 2; - v++; - } - strerror_r(errno, msgbuf, sizeof(msgbuf)); - v->iov_base = msgbuf; - v->iov_len = strlen(v->iov_base); - v++; - v->iov_base = "\n"; - v->iov_len = 1; - FLOCKFILE(stderr); - ORIENT(stderr, -1); - __sflush(stderr); - (void)_writev(stderr->_file, iov, (v - iov) + 1); - stderr->_flags &= ~__SOFF; - FUNLOCKFILE(stderr); -} diff --git a/stdio/perror-fbsd.c b/stdio/perror-fbsd.c new file mode 120000 index 0000000..4cbf19f --- /dev/null +++ b/stdio/perror-fbsd.c @@ -0,0 +1 @@ +./perror.c \ No newline at end of file diff --git a/stdio/printf-fbsd.c b/stdio/printf-fbsd.c index ab89d95..e65851a 100644 --- a/stdio/printf-fbsd.c +++ b/stdio/printf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)printf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/printf.c,v 1.10 2002/09/06 11:23:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/printf.c,v 1.11 2007/01/09 00:28:07 imp Exp $"); #include "xlocale_private.h" diff --git a/stdio/printf-pos-fbsd.c b/stdio/printf-pos-fbsd.c new file mode 100644 index 0000000..4de7aba --- /dev/null +++ b/stdio/printf-pos-fbsd.c @@ -0,0 +1,798 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdio/printf-pos.c,v 1.6 2009/03/02 04:07:58 das Exp $"); + +/* + * This is the code responsible for handling positional arguments + * (%m$ and %m$.n$) for vfprintf() and vfwprintf(). + */ + +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "un-namespace.h" +#include "printflocal.h" + +/* + * Type ids for argument type table. + */ +enum typeid { + T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, + T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, + T_PTRDIFFT, TP_PTRDIFFT, T_SSIZET, T_SIZET, TP_SSIZET, + T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, + T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, +#ifdef VECTORS + T_VECTOR, +#endif +}; + +/* An expandable array of types. */ +struct typetable { + enum typeid *table; /* table of types */ + enum typeid stattable[STATIC_ARG_TBL_SIZE]; + int tablesize; /* current size of type table */ + int tablemax; /* largest used index in table */ + int nextarg; /* 1-based argument index */ +}; + +static int __grow_type_table(struct typetable *); +static void build_arg_table (struct typetable *, va_list, union arg **); + +/* + * Initialize a struct typetable. + */ +static inline void +inittypes(struct typetable *types) +{ + int n; + + types->table = types->stattable; + types->tablesize = STATIC_ARG_TBL_SIZE; + types->tablemax = 0; + types->nextarg = 1; + for (n = 0; n < STATIC_ARG_TBL_SIZE; n++) + types->table[n] = T_UNUSED; +} + +/* + * struct typetable destructor. + */ +static inline void +freetypes(struct typetable *types) +{ + + if (types->table != types->stattable) + free (types->table); +} + +/* + * Ensure that there is space to add a new argument type to the type table. + * Expand the table if necessary. Returns 0 on success. + */ +static inline int +_ensurespace(struct typetable *types) +{ + + if (types->nextarg >= types->tablesize) { + if (__grow_type_table(types)) + return (-1); + } + if (types->nextarg > types->tablemax) + types->tablemax = types->nextarg; + return (0); +} + +/* + * Add an argument type to the table, expanding if necessary. + * Returns 0 on success. + */ +static inline int +addtype(struct typetable *types, enum typeid type) +{ + + if (_ensurespace(types)) + return (-1); + types->table[types->nextarg++] = type; + return (0); +} + +static inline int +addsarg(struct typetable *types, int flags) +{ + + if (_ensurespace(types)) + return (-1); + if (flags & INTMAXT) + types->table[types->nextarg++] = T_INTMAXT; + else if (flags & SIZET) + types->table[types->nextarg++] = T_SSIZET; + else if (flags & PTRDIFFT) + types->table[types->nextarg++] = T_PTRDIFFT; + else if (flags & LLONGINT) + types->table[types->nextarg++] = T_LLONG; + else if (flags & LONGINT) + types->table[types->nextarg++] = T_LONG; + else + types->table[types->nextarg++] = T_INT; + return (0); +} + +static inline int +adduarg(struct typetable *types, int flags) +{ + + if (_ensurespace(types)) + return (-1); + if (flags & INTMAXT) + types->table[types->nextarg++] = T_UINTMAXT; + else if (flags & SIZET) + types->table[types->nextarg++] = T_SIZET; + else if (flags & PTRDIFFT) + types->table[types->nextarg++] = T_SIZET; + else if (flags & LLONGINT) + types->table[types->nextarg++] = T_U_LLONG; + else if (flags & LONGINT) + types->table[types->nextarg++] = T_U_LONG; + else + types->table[types->nextarg++] = T_U_INT; + return (0); +} + +/* + * Add * arguments to the type array. + */ +static inline int +addaster(struct typetable *types, char **fmtp) +{ + char *cp; + int n2; + + n2 = 0; + cp = *fmtp; + while (is_digit(*cp)) { + n2 = 10 * n2 + to_digit(*cp); + cp++; + } + if (*cp == '$') { + int hold = types->nextarg; + types->nextarg = n2; + if (addtype(types, T_INT)) + return (-1); + types->nextarg = hold; + *fmtp = ++cp; + } else { + if (addtype(types, T_INT)) + return (-1); + } + return (0); +} + +static inline int +addwaster(struct typetable *types, wchar_t **fmtp) +{ + wchar_t *cp; + int n2; + + n2 = 0; + cp = *fmtp; + while (is_digit(*cp)) { + n2 = 10 * n2 + to_digit(*cp); + cp++; + } + if (*cp == '$') { + int hold = types->nextarg; + types->nextarg = n2; + if (addtype(types, T_INT)) + return (-1); + types->nextarg = hold; + *fmtp = ++cp; + } else { + if (addtype(types, T_INT)) + return (-1); + } + return (0); +} + +/* + * Find all arguments when a positional parameter is encountered. Returns a + * table, indexed by argument number, of pointers to each arguments. The + * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. + * It will be replaces with a malloc-ed one if it overflows. + * Returns 0 on success. On failure, returns nonzero and sets errno. + */ +__private_extern__ int +__find_arguments (const char *fmt0, va_list ap, union arg **argtable) +{ + char *fmt; /* format string */ + int ch; /* character from fmt */ + int n; /* handy integer (short term usage) */ + int error; + int flags; /* flags as above */ + int width; /* width from format (%8d), or 0 */ + struct typetable types; /* table of types */ + + fmt = (char *)fmt0; + inittypes(&types); + error = 0; + + /* + * Scan the format for conversions (`%' character). + */ + for (;;) { + while ((ch = *fmt) != '\0' && ch != '%') + fmt++; + if (ch == '\0') + goto done; + fmt++; /* skip over '%' */ + + flags = 0; + width = 0; + +rflag: ch = *fmt++; +reswitch: switch (ch) { + case ' ': + case '#': + goto rflag; + case '*': + if ((error = addaster(&types, &fmt))) + goto error; + goto rflag; + case '-': + case '+': + case '\'': + goto rflag; + case '.': + if ((ch = *fmt++) == '*') { + if ((error = addaster(&types, &fmt))) + goto error; + goto rflag; + } + while (is_digit(ch)) { + ch = *fmt++; + } + goto reswitch; + case '0': + goto rflag; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = 0; + do { + n = 10 * n + to_digit(ch); + ch = *fmt++; + } while (is_digit(ch)); + if (ch == '$') { + types.nextarg = n; + goto rflag; + } + width = n; + goto reswitch; +#ifndef NO_FLOATING_POINT + case 'L': + flags |= LONGDBL; + goto rflag; +#endif + case 'h': + if (flags & SHORTINT) { + flags &= ~SHORTINT; + flags |= CHARINT; + } else + flags |= SHORTINT; + goto rflag; + case 'j': + flags |= INTMAXT; + goto rflag; + case 'l': + if (flags & LONGINT) { + flags &= ~LONGINT; + flags |= LLONGINT; + } else + flags |= LONGINT; + goto rflag; + case 'q': + flags |= LLONGINT; /* not necessarily */ + goto rflag; + case 't': + flags |= PTRDIFFT; + goto rflag; + case 'z': + flags |= SIZET; + goto rflag; + case 'C': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'c': + error = addtype(&types, +#ifdef VECTORS + (flags & LONGINT) ? T_WINT : ((flags & VECTOR) ? T_VECTOR : T_INT)); +#else + (flags & LONGINT) ? T_WINT : T_INT); +#endif + if (error) + goto error; + break; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': +#ifdef VECTORS + if (flags & VECTOR) { + if ((error = addtype(&types, T_VECTOR))) + goto error; + } else +#endif + if ((error = addsarg(&types, flags))) + goto error; + break; +#ifndef NO_FLOATING_POINT + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + error = addtype(&types, +#ifdef VECTORS + (flags & VECTOR) ? T_VECTOR : ((flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE)); +#else + (flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE); +#endif + if (error) + goto error; + break; +#endif /* !NO_FLOATING_POINT */ + case 'n': + if (flags & INTMAXT) + error = addtype(&types, TP_INTMAXT); + else if (flags & PTRDIFFT) + error = addtype(&types, TP_PTRDIFFT); + else if (flags & SIZET) + error = addtype(&types, TP_SSIZET); + else if (flags & LLONGINT) + error = addtype(&types, TP_LLONG); + else if (flags & LONGINT) + error = addtype(&types, TP_LONG); + else if (flags & SHORTINT) + error = addtype(&types, TP_SHORT); + else if (flags & CHARINT) + error = addtype(&types, TP_SCHAR); + else + error = addtype(&types, TP_INT); + if (error) + goto error; + continue; /* no output */ + case 'O': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': +#ifdef VECTORS + if (flags & VECTOR) { + if ((error = addtype(&types, T_VECTOR))) + goto error; + } else +#endif + if ((error = adduarg(&types, flags))) + goto error; + break; + case 'p': +#ifdef VECTORS + if ((error = addtype(&types, (flags & VECTOR) ? T_VECTOR : TP_VOID))) +#else + if ((error = addtype(&types, TP_VOID))) +#endif + goto error; + break; + case 'S': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 's': + error = addtype(&types, + (flags & LONGINT) ? TP_WCHAR : TP_CHAR); + if (error) + goto error; + break; + case 'U': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': + case 'X': + case 'x': +#ifdef VECTORS + if (flags & VECTOR) { + if ((error = addtype(&types, T_VECTOR))) + goto error; + } else +#endif + if ((error = adduarg(&types, flags))) + goto error; + break; + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; + break; + } + } +done: + build_arg_table(&types, ap, argtable); +error: + freetypes(&types); + return (error || *argtable == NULL); +} + +/* wchar version of __find_arguments. */ +__private_extern__ int +__find_warguments (const wchar_t *fmt0, va_list ap, union arg **argtable) +{ + wchar_t *fmt; /* format string */ + wchar_t ch; /* character from fmt */ + int n; /* handy integer (short term usage) */ + int error; + int flags; /* flags as above */ + int width; /* width from format (%8d), or 0 */ + struct typetable types; /* table of types */ + + fmt = (wchar_t *)fmt0; + inittypes(&types); + error = 0; + + /* + * Scan the format for conversions (`%' character). + */ + for (;;) { + while ((ch = *fmt) != '\0' && ch != '%') + fmt++; + if (ch == '\0') + goto done; + fmt++; /* skip over '%' */ + + flags = 0; + width = 0; + +rflag: ch = *fmt++; +reswitch: switch (ch) { + case ' ': + case '#': + goto rflag; + case '*': + if ((error = addwaster(&types, &fmt))) + goto error; + goto rflag; + case '-': + case '+': + case '\'': + goto rflag; + case '.': + if ((ch = *fmt++) == '*') { + if ((error = addwaster(&types, &fmt))) + goto error; + goto rflag; + } + while (is_digit(ch)) { + ch = *fmt++; + } + goto reswitch; + case '0': + goto rflag; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = 0; + do { + n = 10 * n + to_digit(ch); + ch = *fmt++; + } while (is_digit(ch)); + if (ch == '$') { + types.nextarg = n; + goto rflag; + } + width = n; + goto reswitch; +#ifndef NO_FLOATING_POINT + case 'L': + flags |= LONGDBL; + goto rflag; +#endif + case 'h': + if (flags & SHORTINT) { + flags &= ~SHORTINT; + flags |= CHARINT; + } else + flags |= SHORTINT; + goto rflag; + case 'j': + flags |= INTMAXT; + goto rflag; + case 'l': + if (flags & LONGINT) { + flags &= ~LONGINT; + flags |= LLONGINT; + } else + flags |= LONGINT; + goto rflag; + case 'q': + flags |= LLONGINT; /* not necessarily */ + goto rflag; + case 't': + flags |= PTRDIFFT; + goto rflag; + case 'z': + flags |= SIZET; + goto rflag; + case 'C': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'c': + error = addtype(&types, + (flags & LONGINT) ? T_WINT : T_INT); + if (error) + goto error; + break; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': + if ((error = addsarg(&types, flags))) + goto error; + break; +#ifndef NO_FLOATING_POINT + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + error = addtype(&types, + (flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE); + if (error) + goto error; + break; +#endif /* !NO_FLOATING_POINT */ + case 'n': + if (flags & INTMAXT) + error = addtype(&types, TP_INTMAXT); + else if (flags & PTRDIFFT) + error = addtype(&types, TP_PTRDIFFT); + else if (flags & SIZET) + error = addtype(&types, TP_SSIZET); + else if (flags & LLONGINT) + error = addtype(&types, TP_LLONG); + else if (flags & LONGINT) + error = addtype(&types, TP_LONG); + else if (flags & SHORTINT) + error = addtype(&types, TP_SHORT); + else if (flags & CHARINT) + error = addtype(&types, TP_SCHAR); + else + error = addtype(&types, TP_INT); + if (error) + goto error; + continue; /* no output */ + case 'O': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': + if ((error = adduarg(&types, flags))) + goto error; + break; + case 'p': + if ((error = addtype(&types, TP_VOID))) + goto error; + break; + case 'S': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 's': + error = addtype(&types, + (flags & LONGINT) ? TP_WCHAR : TP_CHAR); + if (error) + goto error; + break; + case 'U': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': + case 'X': + case 'x': + if ((error = adduarg(&types, flags))) + goto error; + break; + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; + break; + } + } +done: + build_arg_table(&types, ap, argtable); +error: + freetypes(&types); + return (error || *argtable == NULL); +} + +/* + * Increase the size of the type table. Returns 0 on success. + */ +static int +__grow_type_table(struct typetable *types) +{ + enum typeid *const oldtable = types->table; + const int oldsize = types->tablesize; + enum typeid *newtable; + int n, newsize = oldsize * 2; + + if (newsize < types->nextarg + 1) + newsize = types->nextarg + 1; + if (oldsize == STATIC_ARG_TBL_SIZE) { + if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL) + return (-1); + bcopy(oldtable, newtable, oldsize * sizeof(enum typeid)); + } else { + newtable = realloc(oldtable, newsize * sizeof(enum typeid)); + if (newtable == NULL) + return (-1); + } + for (n = oldsize; n < newsize; n++) + newtable[n] = T_UNUSED; + + types->table = newtable; + types->tablesize = newsize; + + return (0); +} + +/* + * Build the argument table from the completed type table. + * On malloc failure, *argtable is set to NULL. + */ +static void +build_arg_table(struct typetable *types, va_list ap, union arg **argtable) +{ + int n; + + if (types->tablemax >= STATIC_ARG_TBL_SIZE) { + *argtable = (union arg *) + malloc (sizeof (union arg) * (types->tablemax + 1)); + if (*argtable == NULL) + return; + } + + (*argtable) [0].intarg = 0; + for (n = 1; n <= types->tablemax; n++) { + switch (types->table[n]) { + case T_UNUSED: /* whoops! */ + (*argtable) [n].intarg = va_arg (ap, int); + break; + case TP_SCHAR: + (*argtable) [n].pschararg = va_arg (ap, signed char *); + break; + case TP_SHORT: + (*argtable) [n].pshortarg = va_arg (ap, short *); + break; + case T_INT: + (*argtable) [n].intarg = va_arg (ap, int); + break; + case T_U_INT: + (*argtable) [n].uintarg = va_arg (ap, unsigned int); + break; + case TP_INT: + (*argtable) [n].pintarg = va_arg (ap, int *); + break; + case T_LONG: + (*argtable) [n].longarg = va_arg (ap, long); + break; + case T_U_LONG: + (*argtable) [n].ulongarg = va_arg (ap, unsigned long); + break; + case TP_LONG: + (*argtable) [n].plongarg = va_arg (ap, long *); + break; + case T_LLONG: + (*argtable) [n].longlongarg = va_arg (ap, long long); + break; + case T_U_LLONG: + (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); + break; + case TP_LLONG: + (*argtable) [n].plonglongarg = va_arg (ap, long long *); + break; + case T_PTRDIFFT: + (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); + break; + case TP_PTRDIFFT: + (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); + break; + case T_SIZET: + (*argtable) [n].sizearg = va_arg (ap, size_t); + break; + case T_SSIZET: + (*argtable) [n].sizearg = va_arg (ap, ssize_t); + break; + case TP_SSIZET: + (*argtable) [n].pssizearg = va_arg (ap, ssize_t *); + break; + case T_INTMAXT: + (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); + break; + case T_UINTMAXT: + (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); + break; + case TP_INTMAXT: + (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); + break; + case T_DOUBLE: +#ifndef NO_FLOATING_POINT + (*argtable) [n].doublearg = va_arg (ap, double); +#endif + break; + case T_LONG_DOUBLE: +#ifndef NO_FLOATING_POINT + (*argtable) [n].longdoublearg = va_arg (ap, long double); +#endif + break; +#ifdef VECTORS + case T_VECTOR: + (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE); + break; +#endif /* VECTORS */ + case TP_CHAR: + (*argtable) [n].pchararg = va_arg (ap, char *); + break; + case TP_VOID: + (*argtable) [n].pvoidarg = va_arg (ap, void *); + break; + case T_WINT: + (*argtable) [n].wintarg = va_arg (ap, wint_t); + break; + case TP_WCHAR: + (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); + break; + } + } +} diff --git a/stdio/printf.3 b/stdio/printf.3 index 11fe01f..031d7f7 100644 --- a/stdio/printf.3 +++ b/stdio/printf.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,89 +30,49 @@ .\" SUCH DAMAGE. .\" .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.58 2004/10/16 16:00:01 stefanf Exp $ +.\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.64 2009/12/02 07:51:25 brueffer Exp $ .\" -.Dd October 16, 2004 +.Dd December 2, 2009 .Dt PRINTF 3 .Os .Sh NAME -.Nm asprintf , -.Nm fprintf , -.Nm printf , -.Nm snprintf , -.Nm sprintf , -.Nm vasprintf , -.Nm vfprintf, -.Nm vprintf , -.Nm vsnprintf , -.Nm vsprintf +.Nm printf , fprintf , sprintf , snprintf , asprintf , dprintf , +.Nm vprintf , vfprintf, vsprintf , vsnprintf , vasprintf, vdprintf .Nd formatted output conversion .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdio.h .Ft int -.Fo asprintf -.Fa "char **ret" -.Fa "const char *format" ... -.Fc +.Fn printf "const char * restrict format" ... .Ft int -.Fo fprintf -.Fa "FILE *restrict stream" -.Fa "const char *restrict format" ... -.Fc +.Fn fprintf "FILE * restrict stream" "const char * restrict format" ... .Ft int -.Fo printf -.Fa "const char *restrict format" ... -.Fc +.Fn sprintf "char * restrict str" "const char * restrict format" ... .Ft int -.Fo snprintf -.Fa "char *restrict s" -.Fa "size_t n" -.Fa "const char *restrict format" ... -.Fc +.Fn snprintf "char * restrict str" "size_t size" "const char * restrict format" ... .Ft int -.Fo sprintf -.Fa "char *restrict s" -.Fa "const char *restrict format" ... -.Fc +.Fn asprintf "char **ret" "const char *format" ... +.Ft int +.Fn dprintf "int fd" "const char * restrict format" ... .In stdarg.h -.In stdio.h .Ft int -.Fo vasprintf -.Fa "char **ret" -.Fa "const char *format" -.Fa "va_list ap" -.Fc +.Fn vprintf "const char * restrict format" "va_list ap" .Ft int -.Fo vfprintf -.Fa "FILE *restrict stream" -.Fa "const char *restrict format" -.Fa "va_list ap" -.Fc +.Fn vfprintf "FILE * restrict stream" "const char * restrict format" "va_list ap" .Ft int -.Fo vprintf -.Fa "const char *restrict format" -.Fa "va_list ap" -.Fc +.Fn vsprintf "char * restrict str" "const char * restrict format" "va_list ap" .Ft int -.Fo vsnprintf -.Fa "char *restrict s" -.Fa "size_t n" -.Fa "const char *restrict format" -.Fa "va_list ap" -.Fc +.Fn vsnprintf "char * restrict str" "size_t size" "const char * restrict format" "va_list ap" .Ft int -.Fo vsprintf -.Fa "char *restrict s" -.Fa "const char *restrict format" -.Fa "va_list ap" -.Fc +.Fn vasprintf "char **ret" "const char *format" "va_list ap" +.Ft int +.Fn vdprintf "int fd" "const char * restrict format" "va_list ap" .Sh DESCRIPTION The .Fn printf family of functions produces output according to a -.Fa format , +.Fa format as described below. The .Fn printf @@ -131,6 +87,10 @@ and .Fn vfprintf write output to the given output .Fa stream ; +.Fn dprintf +and +.Fn vdprintf +write output to the given file descriptor; .Fn sprintf , .Fn snprintf , .Fn vsprintf , @@ -265,8 +225,7 @@ conversions, this option has no effect. For .Cm o conversions, the precision of the number is increased to force the first -character of the output string to a zero (except if a zero value is printed -with an explicit precision of zero). +character of the output string to a zero. For .Cm x and @@ -649,7 +608,7 @@ to separate the mantissa and exponent. Note that there may be multiple valid ways to represent floating-point numbers in this hexadecimal format. For example, -.Li 0x3.24p+0 , 0x6.48p-1 +.Li 0x1.92p+1 , 0x3.24p+0 , 0x6.48p-1 , and .Li 0xc.9p-2 are all equivalent. @@ -871,6 +830,29 @@ for later interpolation by Always use the proper secure idiom: .Pp .Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);" +.Sh COMPATIBILITY +The conversion formats +.Cm \&%D , \&%O , +and +.Cm %U +are not standard and +are provided only for backward compatibility. +The effect of padding the +.Cm %p +format with zeros (either by the +.Cm 0 +flag or by specifying a precision), and the benign effect (i.e., none) +of the +.Cm # +flag on +.Cm %n +and +.Cm %p +conversions, as well as other +nonsensical combinations such as +.Cm %Ld , +are not standard; such combinations +should be avoided. .Sh ERRORS In addition to the errors documented for the .Xr write 2 @@ -885,8 +867,8 @@ Insufficient storage space is available. .El .Sh SEE ALSO .Xr printf 1 , -.Xr fmtcheck 3 , .Xr printf_l 3 , +.Xr fmtcheck 3 , .Xr scanf 3 , .Xr setlocale 3 , .Xr stdarg 3 , @@ -912,7 +894,13 @@ With the same reservation, the and .Fn vsnprintf functions conform to -.St -isoC-99 . +.St -isoC-99 , +while +.Fn dprintf +and +.Fn vdprintf +conform to +.St -p1003.1-2008 . .Sh HISTORY The functions .Fn asprintf @@ -930,30 +918,13 @@ from .An Todd C. Miller Aq Todd.Miller@courtesan.com for .Ox 2.3 . -.Sh BUGS -The conversion formats -.Cm \&%D , \&%O , -and -.Cm %U -are not standard and -are provided only for backward compatibility. -The effect of padding the -.Cm %p -format with zeros (either by the -.Cm 0 -flag or by specifying a precision), and the benign effect (i.e., none) -of the -.Cm # -flag on -.Cm %n +The +.Fn dprintf and -.Cm %p -conversions, as well as other -nonsensical combinations such as -.Cm %Ld , -are not standard; such combinations -should be avoided. -.Pp +.Fn vdprintf +functions were added in +.Fx 8.0 . +.Sh BUGS The .Nm family of functions do not correctly handle multibyte characters in the diff --git a/stdio/printf_l.3 b/stdio/printf_l.3 index 0f1f67c..9ac0bcd 100644 --- a/stdio/printf_l.3 +++ b/stdio/printf_l.3 @@ -36,16 +36,18 @@ .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.58 2004/10/16 16:00:01 stefanf Exp $ .\" -.Dd March 11, 2005 +.Dd December 15, 2009 .Dt PRINTF_L 3 .Os .Sh NAME .Nm asprintf_l , +.Nm dprintf_l , .Nm fprintf_l , .Nm printf_l , .Nm snprintf_l , .Nm sprintf_l , .Nm vasprintf_l , +.Nm vdprintf_l , .Nm vfprintf_l , .Nm vprintf_l , .Nm vsnprintf_l , @@ -64,6 +66,13 @@ .Fa ... .Fc .Ft int +.Fo dprintf_l +.Fa "int fd" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa ... +.Fc +.Ft int .Fo fprintf_l .Fa "FILE * restrict stream" .Fa "locale_t loc" @@ -101,6 +110,13 @@ .Fa "va_list ap" .Fc .Ft int +.Fo vdprintf_l +.Fa "int fd" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa "va_list ap" +.Fc +.Ft int .Fo vfprintf_l .Fa "FILE * restrict stream" .Fa "locale_t loc" @@ -131,11 +147,13 @@ .Sh DESCRIPTION The .Fn printf_l , +.Fn dprintf_l , .Fn fprintf_l , .Fn sprintf_l , .Fn snprintf_l , .Fn asprintf_l , .Fn vprintf_l , +.Fn vdprintf_l , .Fn vfprintf_l , .Fn vsprintf_l , .Fn vsnprintf_l , @@ -143,11 +161,13 @@ and .Fn vasprintf_l functions are extended locale versions of the .Fn printf , +.Fn dprintf , .Fn fprintf , .Fn sprintf , .Fn snprintf , .Fn asprintf , .Fn vprintf , +.Fn vdprintf , .Fn vfprintf , .Fn vsprintf , .Fn vsnprintf , diff --git a/stdio/printfcommon.h b/stdio/printfcommon.h new file mode 100644 index 0000000..27141e6 --- /dev/null +++ b/stdio/printfcommon.h @@ -0,0 +1,301 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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: src/lib/libc/stdio/printfcommon.h,v 1.4 2009/01/22 08:14:28 das Exp $ + */ + +/* + * This file defines common routines used by both printf and wprintf. + * You must define CHAR to either char or wchar_t prior to including this. + */ + + +#ifndef NO_FLOATING_POINT + +#define dtoa __dtoa +#define freedtoa __freedtoa + +#include +#include +#include "floatio.h" +#include "gdtoa.h" + +#define DEFPREC 6 + +static int exponent(CHAR *, int, CHAR); + +#endif /* !NO_FLOATING_POINT */ + +static CHAR *__ujtoa(uintmax_t, CHAR *, int, int, const char *); +static CHAR *__ultoa(u_long, CHAR *, int, int, const char *); + +#define NIOV 8 +struct io_state { + FILE *fp; + struct __suio uio; /* output information: summary */ + struct __siov iov[NIOV];/* ... and individual io vectors */ +}; + +static inline void +io_init(struct io_state *iop, FILE *fp) +{ + + iop->uio.uio_iov = iop->iov; + iop->uio.uio_resid = 0; + iop->uio.uio_iovcnt = 0; + iop->fp = fp; +} + +/* + * WARNING: The buffer passed to io_print() is not copied immediately; it must + * remain valid until io_flush() is called. + */ +static inline int +io_print(struct io_state *iop, const CHAR * __restrict ptr, int len, locale_t loc) +{ + + iop->iov[iop->uio.uio_iovcnt].iov_base = (char *)ptr; + iop->iov[iop->uio.uio_iovcnt].iov_len = len; + iop->uio.uio_resid += len; + if (++iop->uio.uio_iovcnt >= NIOV) + return (__sprint(iop->fp, loc, &iop->uio)); + else + return (0); +} + +/* + * Choose PADSIZE to trade efficiency vs. size. If larger printf + * fields occur frequently, increase PADSIZE and make the initialisers + * below longer. + */ +#define PADSIZE 16 /* pad chunk size */ +static const CHAR blanks[PADSIZE] = +{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; +static const CHAR zeroes[PADSIZE] = +{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; + +/* + * Pad with blanks or zeroes. 'with' should point to either the blanks array + * or the zeroes array. + */ +static inline int +io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with, locale_t loc) +{ + int n; + + while (howmany > 0) { + n = (howmany >= PADSIZE) ? PADSIZE : howmany; + if (io_print(iop, with, n, loc)) + return (-1); + howmany -= n; + } + return (0); +} + +/* + * Print exactly len characters of the string spanning p to ep, truncating + * or padding with 'with' as necessary. + */ +static inline int +io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep, + int len, const CHAR * __restrict with, locale_t loc) +{ + int p_len; + + p_len = ep - p; + if (p_len > len) + p_len = len; + if (p_len > 0) { + if (io_print(iop, p, p_len, loc)) + return (-1); + } else { + p_len = 0; + } + return (io_pad(iop, len - p_len, with, loc)); +} + +static inline int +io_flush(struct io_state *iop, locale_t loc) +{ + + return (__sprint(iop->fp, loc, &iop->uio)); +} + +/* + * Convert an unsigned long to ASCII for printf purposes, returning + * a pointer to the first character of the string representation. + * Octal numbers can be forced to have a leading zero; hex numbers + * use the given digits. + */ +static CHAR * +__ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs) +{ + CHAR *cp = endp; + long sval; + + /* + * Handle the three cases separately, in the hope of getting + * better/faster code. + */ + switch (base) { + case 10: + if (val < 10) { /* many numbers are 1 digit */ + *--cp = to_char(val); + return (cp); + } + /* + * On many machines, unsigned arithmetic is harder than + * signed arithmetic, so we do at most one unsigned mod and + * divide; this is sufficient to reduce the range of + * the incoming value to where signed arithmetic works. + */ + if (val > LONG_MAX) { + *--cp = to_char(val % 10); + sval = val / 10; + } else + sval = val; + do { + *--cp = to_char(sval % 10); + sval /= 10; + } while (sval != 0); + break; + + case 8: + do { + *--cp = to_char(val & 7); + val >>= 3; + } while (val); + if (octzero && *cp != '0') + *--cp = '0'; + break; + + case 16: + do { + *--cp = xdigs[val & 15]; + val >>= 4; + } while (val); + break; + + default: /* oops */ + LIBC_ABORT("__ultoa: invalid base=%d", base); + } + return (cp); +} + +/* Identical to __ultoa, but for intmax_t. */ +static CHAR * +__ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs) +{ + CHAR *cp = endp; + intmax_t sval; + + /* quick test for small values; __ultoa is typically much faster */ + /* (perhaps instead we should run until small, then call __ultoa?) */ + if (val <= ULONG_MAX) + return (__ultoa((u_long)val, endp, base, octzero, xdigs)); + switch (base) { + case 10: + if (val < 10) { + *--cp = to_char(val % 10); + return (cp); + } + if (val > INTMAX_MAX) { + *--cp = to_char(val % 10); + sval = val / 10; + } else + sval = val; + do { + *--cp = to_char(sval % 10); + sval /= 10; + } while (sval != 0); + break; + + case 8: + do { + *--cp = to_char(val & 7); + val >>= 3; + } while (val); + if (octzero && *cp != '0') + *--cp = '0'; + break; + + case 16: + do { + *--cp = xdigs[val & 15]; + val >>= 4; + } while (val); + break; + + default: + LIBC_ABORT("__ujtoa: invalid base=%d", base); + } + return (cp); +} + +#ifndef NO_FLOATING_POINT + +static int +exponent(CHAR *p0, int exp, CHAR fmtch) +{ + CHAR *p, *t; + CHAR expbuf[MAXEXPDIG]; + + p = p0; + *p++ = fmtch; + if (exp < 0) { + exp = -exp; + *p++ = '-'; + } + else + *p++ = '+'; + t = expbuf + MAXEXPDIG; + if (exp > 9) { + do { + *--t = to_char(exp % 10); + } while ((exp /= 10) > 9); + *--t = to_char(exp); + for (; t < expbuf + MAXEXPDIG; *p++ = *t++); + } + else { + /* + * Exponents for decimal floating point conversions + * (%[eEgG]) must be at least two characters long, + * whereas exponents for hexadecimal conversions can + * be only one character long. + */ + if (fmtch == 'e' || fmtch == 'E') + *p++ = '0'; + *p++ = to_char(exp); + } + return (p - p0); +} + +#endif /* !NO_FLOATING_POINT */ diff --git a/stdio/printflocal.h b/stdio/printflocal.h new file mode 100644 index 0000000..f57e8e9 --- /dev/null +++ b/stdio/printflocal.h @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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: src/lib/libc/stdio/printflocal.h,v 1.3 2009/03/02 04:07:58 das Exp $ + */ + +/* + * Defining here VECTORS for all files that include this header () + */ +#define VECTORS + +/* + * Flags used during conversion. + */ +#define ALT 0x001 /* alternate form */ +#define LADJUST 0x004 /* left adjustment */ +#define LONGDBL 0x008 /* long double */ +#define LONGINT 0x010 /* long integer */ +#define LLONGINT 0x020 /* long long integer */ +#define SHORTINT 0x040 /* short integer */ +#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ +#define FPT 0x100 /* Floating point number */ +#define GROUPING 0x200 /* use grouping ("'" flag) */ + /* C99 additional size modifiers: */ +#define SIZET 0x400 /* size_t */ +#define PTRDIFFT 0x800 /* ptrdiff_t */ +#define INTMAXT 0x1000 /* intmax_t */ +#define CHARINT 0x2000 /* print char using int format */ +#ifdef VECTORS +#define VECTOR 0x4000 /* Altivec or SSE vector */ +#endif /* VECTORS */ + +/* + * Macros for converting digits to letters and vice versa + */ +#define to_digit(c) ((c) - '0') +#define is_digit(c) ((unsigned)to_digit(c) <= 9) +#define to_char(n) ((n) + '0') + +/* Size of the static argument table. */ +#define STATIC_ARG_TBL_SIZE 8 + +#ifdef VECTORS +typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE; +#ifdef __SSE2__ +#define V64TYPE +#endif /* __SSE2__ */ +#endif /* VECTORS */ + +union arg { + int intarg; + u_int uintarg; + long longarg; + u_long ulongarg; + long long longlongarg; + unsigned long long ulonglongarg; + ptrdiff_t ptrdiffarg; + size_t sizearg; + intmax_t intmaxarg; + uintmax_t uintmaxarg; + void *pvoidarg; + char *pchararg; + signed char *pschararg; + short *pshortarg; + int *pintarg; + long *plongarg; + long long *plonglongarg; + ptrdiff_t *pptrdiffarg; + ssize_t *pssizearg; + intmax_t *pintmaxarg; +#ifndef NO_FLOATING_POINT + double doublearg; + long double longdoublearg; +#endif + wint_t wintarg; + wchar_t *pwchararg; +#ifdef VECTORS + VECTORTYPE vectorarg; + unsigned char vuchararg[16]; + signed char vchararg[16]; + unsigned short vushortarg[8]; + signed short vshortarg[8]; + unsigned int vuintarg[4]; + signed int vintarg[4]; + float vfloatarg[4]; +#ifdef V64TYPE + double vdoublearg[2]; + unsigned long long vulonglongarg[2]; + long long vlonglongarg[2]; +#endif /* V64TYPE */ +#endif /* VECTORS */ +}; + +/* Handle positional parameters. */ +int __find_arguments(const char *, va_list, union arg **); +int __find_warguments(const wchar_t *, va_list, union arg **); diff --git a/stdio/putc.3 b/stdio/putc.3 index 877a92b..b5370aa 100644 --- a/stdio/putc.3 +++ b/stdio/putc.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)putc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/putc.3,v 1.15 2004/03/17 12:46:17 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/putc.3,v 1.16 2007/01/09 00:28:07 imp Exp $ .\" .Dd January 10, 2003 .Dt PUTC 3 diff --git a/stdio/puts-fbsd.c b/stdio/puts-fbsd.c index ef7faed..511cab4 100644 --- a/stdio/puts-fbsd.c +++ b/stdio/puts-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)puts.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/puts.c,v 1.10 2004/03/10 09:15:38 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/puts.c,v 1.11 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/putwc.3 b/stdio/putwc.3 index f727d91..84799bc 100644 --- a/stdio/putwc.3 +++ b/stdio/putwc.3 @@ -15,10 +15,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -36,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)putc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/putwc.3,v 1.7 2004/03/16 13:30:11 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/putwc.3,v 1.8 2007/01/09 00:28:07 imp Exp $ .\" .Dd March 3, 2004 .Dt PUTWC 3 diff --git a/stdio/refill-fbsd.c b/stdio/refill-fbsd.c index ea4cff2..8d42bbb 100644 --- a/stdio/refill-fbsd.c +++ b/stdio/refill-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)refill.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/refill.c,v 1.18 2002/08/13 09:30:41 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/refill.c,v 1.20 2008/04/17 22:17:54 jhb Exp $"); #include "namespace.h" #include @@ -110,7 +106,7 @@ __srefill0(FILE *fp) if (HASUB(fp)) { FREEUB(fp); if ((fp->_r = fp->_ur) != 0) { - fp->_p = fp->_extra->_up; + fp->_p = fp->_up; return (0); } } diff --git a/stdio/remove.3 b/stdio/remove.3 index 42745de..5f10003 100644 --- a/stdio/remove.3 +++ b/stdio/remove.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)remove.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/remove.3,v 1.9 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/remove.3,v 1.10 2007/01/09 00:28:07 imp Exp $ .\" .Dd June 4, 1993 .Dt REMOVE 3 diff --git a/stdio/rewind-fbsd.c b/stdio/rewind-fbsd.c index 9ade822..3dc282d 100644 --- a/stdio/rewind-fbsd.c +++ b/stdio/rewind-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)rewind.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/rewind.c,v 1.11 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/rewind.c,v 1.12 2007/01/09 00:28:07 imp Exp $"); #include "namespace.h" #include diff --git a/stdio/scanf-fbsd.c b/stdio/scanf-fbsd.c index f4cb68d..c2992ec 100644 --- a/stdio/scanf-fbsd.c +++ b/stdio/scanf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)scanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/scanf.c,v 1.12 2003/01/03 23:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/scanf.c,v 1.13 2007/01/09 00:28:07 imp Exp $"); #include "xlocale_private.h" diff --git a/stdio/scanf.3 b/stdio/scanf.3 index 763a753..4bf7240 100644 --- a/stdio/scanf.3 +++ b/stdio/scanf.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)scanf.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/stdio/scanf.3,v 1.24 2003/06/28 09:03:25 das Exp $ +.\" $FreeBSD: src/lib/libc/stdio/scanf.3,v 1.25 2007/01/09 00:28:07 imp Exp $ .\" .Dd January 4, 2003 .Dt SCANF 3 diff --git a/stdio/setbuf.3 b/stdio/setbuf.3 index da56bf4..466d8b3 100644 --- a/stdio/setbuf.3 +++ b/stdio/setbuf.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setbuf.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/setbuf.3,v 1.15 2004/08/24 21:48:21 alfred Exp $ +.\" $FreeBSD: src/lib/libc/stdio/setbuf.3,v 1.17 2007/01/09 00:28:07 imp Exp $ .\" .Dd June 4, 1993 .Dt SETBUF 3 @@ -132,7 +128,9 @@ bytes long; this buffer will be used instead of the current buffer. If .Fa buf -is not NULL, it is the caller's responsibility to +is not +.Dv NULL , +it is the caller's responsibility to .Xr free 3 this buffer after closing the stream. (If the diff --git a/stdio/snprintf-fbsd.c b/stdio/snprintf-fbsd.c index 6f4f83c..55f01cf 100644 --- a/stdio/snprintf-fbsd.c +++ b/stdio/snprintf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/snprintf.c,v 1.20 2002/09/06 11:23:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/snprintf.c,v 1.22 2008/04/17 22:17:54 jhb Exp $"); #include "xlocale_private.h" @@ -51,27 +47,11 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/snprintf.c,v 1.20 2002/09/06 11:23:55 tjr int snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...) { - size_t on; int ret; va_list ap; - FILE f; - struct __sFILEX ext; - on = n; - if (n != 0) - n--; - if (n > INT_MAX) - n = INT_MAX; va_start(ap, fmt); - f._file = -1; - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = n; - f._extra = &ext; - INITEXTRA(&f); - ret = __vfprintf(&f, __current_locale(), fmt, ap); - if (on > 0) - *f._p = '\0'; + ret = vsnprintf_l(str, n, __current_locale(), fmt, ap); va_end(ap); return (ret); } @@ -80,28 +60,11 @@ int snprintf_l(char * __restrict str, size_t n, locale_t loc, char const * __restrict fmt, ...) { - size_t on; int ret; va_list ap; - FILE f; - struct __sFILEX ext; - NORMALIZE_LOCALE(loc); - on = n; - if (n != 0) - n--; - if (n > INT_MAX) - n = INT_MAX; va_start(ap, fmt); - f._file = -1; - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = n; - f._extra = &ext; - INITEXTRA(&f); - ret = __vfprintf(&f, loc, fmt, ap); - if (on > 0) - *f._p = '\0'; + ret = vsnprintf_l(str, n, loc, fmt, ap); va_end(ap); return (ret); } diff --git a/stdio/sprintf-fbsd.c b/stdio/sprintf-fbsd.c index 38d534e..f2cb3a9 100644 --- a/stdio/sprintf-fbsd.c +++ b/stdio/sprintf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)sprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/sprintf.c,v 1.14 2002/09/06 11:23:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/sprintf.c,v 1.16 2008/04/17 22:17:54 jhb Exp $"); #include "xlocale_private.h" @@ -52,19 +48,10 @@ sprintf(char * __restrict str, char const * __restrict fmt, ...) { int ret; va_list ap; - FILE f; - struct __sFILEX ext; - f._file = -1; - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = INT_MAX; - f._extra = &ext; - INITEXTRA(&f); va_start(ap, fmt); - ret = __vfprintf(&f, __current_locale(), fmt, ap); + ret = vsprintf_l(str, __current_locale(), fmt, ap); va_end(ap); - *f._p = 0; return (ret); } @@ -73,19 +60,9 @@ sprintf_l(char * __restrict str, locale_t loc, char const * __restrict fmt, ...) { int ret; va_list ap; - FILE f; - struct __sFILEX ext; - NORMALIZE_LOCALE(loc); - f._file = -1; - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = INT_MAX; - f._extra = &ext; - INITEXTRA(&f); va_start(ap, fmt); - ret = __vfprintf(&f, loc, fmt, ap); + ret = vsprintf_l(str, loc, fmt, ap); va_end(ap); - *f._p = 0; return (ret); } diff --git a/stdio/sscanf-fbsd.c b/stdio/sscanf-fbsd.c index 992032d..16c313f 100644 --- a/stdio/sscanf-fbsd.c +++ b/stdio/sscanf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)sscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/sscanf.c,v 1.11 2002/10/12 16:13:41 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/sscanf.c,v 1.13 2008/04/17 22:17:54 jhb Exp $"); #include "xlocale_private.h" @@ -47,38 +43,14 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/sscanf.c,v 1.11 2002/10/12 16:13:41 mike #include #include "local.h" -static int eofread(void *, char *, int); - -/* ARGSUSED */ -static int -eofread(cookie, buf, len) - void *cookie; - char *buf; - int len; -{ - - return (0); -} - int sscanf(const char * __restrict str, char const * __restrict fmt, ...) { int ret; va_list ap; - struct __sFILEX extra; - FILE f; - f._file = -1; - f._flags = __SRD; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._r = strlen(str); - f._read = eofread; - f._ub._base = NULL; - f._lb._base = NULL; - f._extra = &extra; - INITEXTRA(&f); va_start(ap, fmt); - ret = __svfscanf_l(&f, __current_locale(), fmt, ap); + ret = vsscanf_l(str, __current_locale(), fmt, ap); va_end(ap); return (ret); } @@ -88,21 +60,9 @@ sscanf_l(const char * __restrict str, locale_t loc, char const * __restrict fmt, { int ret; va_list ap; - struct __sFILEX extra; - FILE f; - NORMALIZE_LOCALE(loc); - f._file = -1; - f._flags = __SRD; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._r = strlen(str); - f._read = eofread; - f._ub._base = NULL; - f._lb._base = NULL; - f._extra = &extra; - INITEXTRA(&f); va_start(ap, fmt); - ret = __svfscanf_l(&f, loc, fmt, ap); + ret = vsscanf_l(str, loc, fmt, ap); va_end(ap); return (ret); } diff --git a/stdio/stdio.3 b/stdio/stdio.3 index 9831af0..1cf1be6 100644 --- a/stdio/stdio.3 +++ b/stdio/stdio.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)stdio.3 8.7 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/stdio/stdio.3,v 1.26 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/stdio.3,v 1.30 2009/03/04 03:38:51 das Exp $ .\" -.Dd January 10, 2003 +.Dd March 3, 2009 .Dt STDIO 3 .Os .Sh NAME @@ -261,10 +257,6 @@ static FILE *var = stdout; .Xr read 2 , .Xr write 2 , .Xr compat 5 -.Sh BUGS -The standard buffered functions do not interact well with certain other -library and system functions, especially -.Xr vfork 2 . .Sh STANDARDS The .Nm @@ -311,6 +303,8 @@ library conforms to .It "" .It "getc get next character or word from input stream" .It "getchar get next character or word from input stream" +.It "getdelim get a line from a stream" +.It "getline get a line from a stream" .It "gets get a line from a stream" .It "getw get next character or word from input stream" .It "getwc get next wide character from input stream" @@ -366,3 +360,7 @@ library conforms to .It "" .It "wprintf formatted wide character output conversion" .El +.Sh BUGS +The standard buffered functions do not interact well with certain other +library and system functions, especially +.Xr vfork 2 . diff --git a/stdio/tempnam-fbsd.c b/stdio/tempnam-fbsd.c index a68da8f..adc2adf 100644 --- a/stdio/tempnam-fbsd.c +++ b/stdio/tempnam-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)tempnam.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/tempnam.c,v 1.10 2002/03/22 21:53:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/tempnam.c,v 1.11 2007/01/09 00:28:07 imp Exp $"); #include #include @@ -107,14 +103,6 @@ tempnam(dir, pfx) } #endif /* __DARWIN_UNIX03 */ f = _PATH_TMP; -#if __DARWIN_UNIX03 - if (access(f, W_OK) < 0) { - f = "./"; /* directory inaccessible */ - if (access(f, W_OK) < 0) { - return(NULL); - } - } -#endif /* __DARWIN_UNIX03 */ (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); if ((f = _mktemp(name))) { return(f); diff --git a/stdio/tmpnam-fbsd.c b/stdio/tmpnam-fbsd.c deleted file mode 120000 index d8c0fc5..0000000 --- a/stdio/tmpnam-fbsd.c +++ /dev/null @@ -1 +0,0 @@ -./tmpnam.c \ No newline at end of file diff --git a/stdio/tmpnam-fbsd.c b/stdio/tmpnam-fbsd.c new file mode 100644 index 0000000..6dad888 --- /dev/null +++ b/stdio/tmpnam-fbsd.c @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)tmpnam.c 8.3 (Berkeley) 3/28/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdio/tmpnam.c,v 1.6 2007/01/09 00:28:07 imp Exp $"); + +#include + +#include +#include +#include +#include + +__warn_references(tmpnam, + "warning: tmpnam() possibly used unsafely; consider using mkstemp()"); + +extern char *_mktemp(char *); + +static char *tmpnam_buf = NULL; +static pthread_once_t tmpnam_buf_control = PTHREAD_ONCE_INIT; + +static void tmpnam_buf_allocate(void) +{ + tmpnam_buf = malloc(L_tmpnam); +} + +char * +tmpnam(s) + char *s; +{ + static u_long tmpcount; + + if (s == NULL) { + if (pthread_once(&tmpnam_buf_control, tmpnam_buf_allocate) + || !tmpnam_buf) { + return NULL; + } + s = tmpnam_buf; + } + (void)snprintf(s, L_tmpnam, "%stmp.%lu.XXXXXX", P_tmpdir, tmpcount); + ++tmpcount; + return (_mktemp(s)); +} diff --git a/stdio/tmpnam.3 b/stdio/tmpnam.3 index ed45314..5f377d9 100644 --- a/stdio/tmpnam.3 +++ b/stdio/tmpnam.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)tmpnam.3 8.2 (Berkeley) 11/17/93 -.\" $FreeBSD: src/lib/libc/stdio/tmpnam.3,v 1.16 2004/06/21 19:38:25 mpp Exp $ +.\" $FreeBSD: src/lib/libc/stdio/tmpnam.3,v 1.20 2007/03/16 21:46:24 maxim Exp $ .\" .Dd November 12, 2008 .Dt TMPFILE 3 @@ -50,7 +46,7 @@ .In stdio.h .Ft FILE * .Fo tmpfile -.Fa void +.Fa "void" .Fc .Ft char * .Fo tmpnam @@ -166,6 +162,43 @@ return a pointer to a file name on success, and a .Dv NULL pointer on error. +.Sh ENVIRONMENT +.Bl -tag -width Ds +.It Ev TMPDIR +.Pf [ Fn tempnam +only] +If set, +the directory in which the temporary file is stored. +.Ev TMPDIR +is ignored for processes +for which +.Xr issetugid 2 +is true. +.El +.Sh COMPATIBILITY +These interfaces are provided from System V and +.Tn ANSI +compatibility only. +.Pp +Most historic implementations of these functions provide +only a limited number of possible temporary file names +(usually 26) +before file names will start being recycled. +System V implementations of these functions +(and of +.Xr mktemp 3 ) +use the +.Xr access 2 +system call to determine whether or not the temporary file +may be created. +This has obvious ramifications for setuid or setgid programs, +complicating the portable use of these interfaces in such programs. +.Pp +The +.Fn tmpfile +interface should not be used in software expected to be used on other systems +if there is any possibility that the user does not wish the temporary file to +be publicly readable and writable. .Sh ERRORS The .Fn tmpfile @@ -212,30 +245,6 @@ It is strongly suggested that be used in place of these functions. (See the FSA.) -.Sh COMPATIBILITY -These interfaces are provided from System V and -.Tn ANSI -compatibility only. -.Pp -Most historic implementations of these functions provide -only a limited number of possible temporary file names -(usually 26) -before file names will start being recycled. -System V implementations of these functions -(and of -.Xr mktemp 3 ) -use the -.Xr access 2 -system call to determine whether or not the temporary file -may be created. -This has obvious ramifications for setuid or setgid programs, -complicating the portable use of these interfaces in such programs. -.Pp -The -.Fn tmpfile -interface should not be used in software expected to be used on other systems -if there is any possibility that the user does not wish the temporary file to -be publicly readable and writable. .Sh LEGACY DESCRIPTION In legacy mode, the order directories are tried by the .Fn tempnam diff --git a/stdio/ungetc.3 b/stdio/ungetc.3 index 3b3f686..169a02b 100644 --- a/stdio/ungetc.3 +++ b/stdio/ungetc.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ungetc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/ungetc.3,v 1.13 2002/10/10 04:12:40 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/ungetc.3,v 1.14 2007/01/09 00:28:07 imp Exp $ .\" .Dd June 4, 1993 .Dt UNGETC 3 diff --git a/stdio/ungetwc-fbsd.c b/stdio/ungetwc-fbsd.c index f221940..37e6402 100644 --- a/stdio/ungetwc-fbsd.c +++ b/stdio/ungetwc-fbsd.c @@ -25,12 +25,13 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/ungetwc.c,v 1.9 2004/07/20 08:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/ungetwc.c,v 1.11 2008/04/17 22:17:54 jhb Exp $"); #include "xlocale_private.h" #include "namespace.h" #include +#include #include #include #include @@ -50,7 +51,7 @@ __ungetwc(wint_t wc, FILE *fp, locale_t loc) if (wc == WEOF) return (WEOF); - if ((len = loc->__lc_ctype->__wcrtomb(buf, wc, &fp->_extra->mbstate, loc)) == (size_t)-1) { + if ((len = loc->__lc_ctype->__wcrtomb(buf, wc, &fp->_mbstate, loc)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); } diff --git a/stdio/ungetwc.3 b/stdio/ungetwc.3 index 039a57d..726ec65 100644 --- a/stdio/ungetwc.3 +++ b/stdio/ungetwc.3 @@ -15,10 +15,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -36,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ungetc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/ungetwc.3,v 1.5 2004/03/16 13:30:11 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/ungetwc.3,v 1.6 2007/01/09 00:28:07 imp Exp $ .\" .Dd March 3, 2004 .Dt UNGETWC 3 diff --git a/stdio/unlocked-fbsd.c b/stdio/unlocked-fbsd.c deleted file mode 120000 index 242fcd9..0000000 --- a/stdio/unlocked-fbsd.c +++ /dev/null @@ -1 +0,0 @@ -./unlocked.c \ No newline at end of file diff --git a/stdio/vasprintf-fbsd.c b/stdio/vasprintf-fbsd.c index f90d0a6..d872a9e 100644 --- a/stdio/vasprintf-fbsd.c +++ b/stdio/vasprintf-fbsd.c @@ -28,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.18 2002/09/26 13:11:24 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.19 2008/04/17 22:17:54 jhb Exp $"); #include "xlocale_private.h" @@ -38,15 +38,19 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.18 2002/09/26 13:11:24 tj #include "local.h" int -vasprintf(str, fmt, ap) +vasprintf_l(str, loc, fmt, ap) char **str; + locale_t loc; const char *fmt; __va_list ap; { int ret; FILE f; struct __sFILEX ext; - + f._extra = &ext; + INITEXTRA(&f); + + NORMALIZE_LOCALE(loc); f._file = -1; f._flags = __SWR | __SSTR | __SALC; f._bf._base = f._p = (unsigned char *)malloc(128); @@ -56,9 +60,9 @@ vasprintf(str, fmt, ap) return (-1); } f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); - ret = __vfprintf(&f, __current_locale(), fmt, ap); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); + ret = __vfprintf(&f, loc, fmt, ap); if (ret < 0) { free(f._bf._base); *str = NULL; @@ -71,36 +75,10 @@ vasprintf(str, fmt, ap) } int -vasprintf_l(str, loc, fmt, ap) +vasprintf(str, fmt, ap) char **str; - locale_t loc; const char *fmt; __va_list ap; { - int ret; - FILE f; - struct __sFILEX ext; - - NORMALIZE_LOCALE(loc); - f._file = -1; - f._flags = __SWR | __SSTR | __SALC; - f._bf._base = f._p = (unsigned char *)malloc(128); - if (f._bf._base == NULL) { - *str = NULL; - errno = ENOMEM; - return (-1); - } - f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); - ret = __vfprintf(&f, loc, fmt, ap); - if (ret < 0) { - free(f._bf._base); - *str = NULL; - errno = ENOMEM; - return (-1); - } - *f._p = '\0'; - *str = (char *)f._bf._base; - return (ret); + return vasprintf_l(str, __current_locale(), fmt, ap); } diff --git a/stdio/vdprintf-fbsd.c b/stdio/vdprintf-fbsd.c new file mode 100644 index 0000000..5625bd6 --- /dev/null +++ b/stdio/vdprintf-fbsd.c @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/stdio/vdprintf.c,v 1.1 2009/03/04 03:38:51 das Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" + +#include "local.h" + +int +vdprintf_l(int fd, locale_t loc, const char * __restrict fmt, va_list ap) +{ + FILE f; + unsigned char buf[BUFSIZ]; + int ret; + struct __sFILEX ext; + f._extra = &ext; + INITEXTRA(&f); + + NORMALIZE_LOCALE(loc); + + if (fd > SHRT_MAX) { + errno = EMFILE; + return (EOF); + } + + f._p = buf; + f._w = sizeof(buf); + f._flags = __SWR; + f._file = fd; + f._cookie = &f; + f._write = __swrite; + f._bf._base = buf; + f._bf._size = sizeof(buf); + f._orientation = 0; + bzero(&f._mbstate, sizeof(f._mbstate)); + + if ((ret = __vfprintf(&f, loc, fmt, ap)) < 0) + return (ret); + + return (__fflush(&f) ? EOF : ret); +} + +int +vdprintf(int fd, const char * __restrict fmt, va_list ap) { + return vdprintf_l(fd, __current_locale(), fmt, ap); +} diff --git a/stdio/vfprintf-fbsd.c b/stdio/vfprintf-fbsd.c index 7d900db..3182836 100644 --- a/stdio/vfprintf-fbsd.c +++ b/stdio/vfprintf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.90 2009/02/28 06:06:57 das Exp $"); #include "xlocale_private.h" @@ -60,6 +56,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des #include #include #include +#if 0 // xprintf pending API review +#include +#endif #include #include @@ -68,89 +67,92 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des #include "libc_private.h" #include "local.h" #include "fvwrite.h" +#include "printflocal.h" -#ifdef VECTORS -typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE; -#ifdef __SSE2__ -#define V64TYPE -#endif /* __SSE2__ */ -#endif /* VECTORS */ +static int __sprint(FILE *, locale_t, struct __suio *); +static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0); +static char *__wcsconv(wchar_t *, int, locale_t); -union arg { - int intarg; - u_int uintarg; - long longarg; - u_long ulongarg; - long long longlongarg; - unsigned long long ulonglongarg; - ptrdiff_t ptrdiffarg; - size_t sizearg; - intmax_t intmaxarg; - uintmax_t uintmaxarg; - void *pvoidarg; - char *pchararg; - signed char *pschararg; - short *pshortarg; - int *pintarg; - long *plongarg; - long long *plonglongarg; - ptrdiff_t *pptrdiffarg; - size_t *psizearg; - intmax_t *pintmaxarg; -#ifndef NO_FLOATING_POINT - double doublearg; - long double longdoublearg; -#endif - wint_t wintarg; - wchar_t *pwchararg; -#ifdef VECTORS - VECTORTYPE vectorarg; - unsigned char vuchararg[16]; - signed char vchararg[16]; - unsigned short vushortarg[8]; - signed short vshortarg[8]; - unsigned int vuintarg[4]; - signed int vintarg[4]; - float vfloatarg[4]; -#ifdef V64TYPE - double vdoublearg[2]; - unsigned long long vulonglongarg[2]; - long long vlonglongarg[2]; -#endif /* V64TYPE */ -#endif /* VECTORS */ +__private_extern__ const char *__fix_nogrouping(const char *); + +#define CHAR char +#include "printfcommon.h" + +struct grouping_state { + char *thousands_sep; /* locale-specific thousands separator */ + int thousep_len; /* length of thousands_sep */ + const char *grouping; /* locale-specific numeric grouping rules */ + int lead; /* sig figs before decimal or group sep */ + int nseps; /* number of group separators with ' */ + int nrepeats; /* number of repeats of the last group */ }; /* - * Type ids for argument type table. + * Initialize the thousands' grouping state in preparation to print a + * number with ndigits digits. This routine returns the total number + * of bytes that will be needed. */ -enum typeid { - T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, - T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, - T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, - T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, -#ifdef VECTORS - T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR -#else /* ! VECTORS */ - T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR -#endif /* VECTORS */ -}; +static int +grouping_init(struct grouping_state *gs, int ndigits, locale_t loc) +{ + struct lconv *locale; -static int __sprint(FILE *, struct __suio *); -static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0); -static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char, - const char *); -static char *__ultoa(u_long, char *, int, int, const char *, int, char, - const char *); -static char *__wcsconv(wchar_t *, int, locale_t); -static void __find_arguments(const char *, va_list, union arg **); -static void __grow_type_table(int, enum typeid **, int *); + locale = localeconv_l(loc); + gs->grouping = __fix_nogrouping(locale->grouping); + gs->thousands_sep = locale->thousands_sep; + gs->thousep_len = strlen(gs->thousands_sep); + + gs->nseps = gs->nrepeats = 0; + gs->lead = ndigits; + while (*gs->grouping != CHAR_MAX) { + if (gs->lead <= *gs->grouping) + break; + gs->lead -= *gs->grouping; + if (*(gs->grouping+1)) { + gs->nseps++; + gs->grouping++; + } else + gs->nrepeats++; + } + return ((gs->nseps + gs->nrepeats) * gs->thousep_len); +} + +/* + * Print a number with thousands' separators. + */ +static int +grouping_print(struct grouping_state *gs, struct io_state *iop, + const CHAR *cp, const CHAR *ep, locale_t loc) +{ + const CHAR *cp0 = cp; + + if (io_printandpad(iop, cp, ep, gs->lead, zeroes, loc)) + return (-1); + cp += gs->lead; + while (gs->nseps > 0 || gs->nrepeats > 0) { + if (gs->nrepeats > 0) + gs->nrepeats--; + else { + gs->grouping--; + gs->nseps--; + } + if (io_print(iop, gs->thousands_sep, gs->thousep_len, loc)) + return (-1); + if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes, loc)) + return (-1); + cp += *gs->grouping; + } + if (cp > ep) + cp = ep; + return (cp - cp0); +} /* * Flush out all the vectors defined by the given uio, * then reset it so that it can be reused. */ static int -__sprint(FILE *fp, struct __suio *uio) +__sprint(FILE *fp, locale_t loc __unused, struct __suio *uio) { int err; @@ -175,13 +177,21 @@ __sbprintf(FILE *fp, locale_t loc, const char *fmt, va_list ap) int ret; FILE fake; unsigned char buf[BUFSIZ]; + struct __sFILEX ext; + fake._extra = &ext; + INITEXTRA(&fake); + + /* XXX This is probably not needed. */ + if (prepwrite(fp) != 0) + return (EOF); /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; - fake._extra = fp->_extra; + fake._orientation = fp->_orientation; + fake._mbstate = fp->_mbstate; /* set up the buffer */ fake._bf._base = fake._p = buf; @@ -197,172 +207,11 @@ __sbprintf(FILE *fp, locale_t loc, const char *fmt, va_list ap) return (ret); } -/* - * Macros for converting digits to letters and vice versa - */ -#define to_digit(c) ((c) - '0') -#define is_digit(c) ((unsigned)to_digit(c) <= 9) -#define to_char(n) ((n) + '0') - -/* - * Convert an unsigned long to ASCII for printf purposes, returning - * a pointer to the first character of the string representation. - * Octal numbers can be forced to have a leading zero; hex numbers - * use the given digits. - */ -static char * -__ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs, - int needgrp, char thousep, const char *grp) -{ - char *cp = endp; - long sval; - int ndig; - - /* - * Handle the three cases separately, in the hope of getting - * better/faster code. - */ - switch (base) { - case 10: - if (val < 10) { /* many numbers are 1 digit */ - *--cp = to_char(val); - return (cp); - } - ndig = 0; - /* - * On many machines, unsigned arithmetic is harder than - * signed arithmetic, so we do at most one unsigned mod and - * divide; this is sufficient to reduce the range of - * the incoming value to where signed arithmetic works. - */ - if (val > LONG_MAX) { - *--cp = to_char(val % 10); - ndig++; - sval = val / 10; - } else - sval = val; - do { - *--cp = to_char(sval % 10); - ndig++; - /* - * If (*grp == CHAR_MAX) then no more grouping - * should be performed. - */ - if (needgrp && ndig == *grp && *grp != CHAR_MAX - && sval > 9) { - *--cp = thousep; - ndig = 0; - /* - * If (*(grp+1) == '\0') then we have to - * use *grp character (last grouping rule) - * for all next cases - */ - if (*(grp+1) != '\0') - grp++; - } - sval /= 10; - } while (sval != 0); - break; - - case 8: - do { - *--cp = to_char(val & 7); - val >>= 3; - } while (val); - if (octzero && *cp != '0') - *--cp = '0'; - break; - - case 16: - do { - *--cp = xdigs[val & 15]; - val >>= 4; - } while (val); - break; - - default: /* oops */ - LIBC_ABORT("base = %d", base); - } - return (cp); -} - -/* Identical to __ultoa, but for intmax_t. */ -static char * -__ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs, - int needgrp, char thousep, const char *grp) -{ - char *cp = endp; - intmax_t sval; - int ndig; - - /* quick test for small values; __ultoa is typically much faster */ - /* (perhaps instead we should run until small, then call __ultoa?) */ - if (val <= ULONG_MAX) - return (__ultoa((u_long)val, endp, base, octzero, xdigs, - needgrp, thousep, grp)); - switch (base) { - case 10: - if (val < 10) { - *--cp = to_char(val % 10); - return (cp); - } - ndig = 0; - if (val > INTMAX_MAX) { - *--cp = to_char(val % 10); - ndig++; - sval = val / 10; - } else - sval = val; - do { - *--cp = to_char(sval % 10); - ndig++; - /* - * If (*grp == CHAR_MAX) then no more grouping - * should be performed. - */ - if (needgrp && *grp != CHAR_MAX && ndig == *grp - && sval > 9) { - *--cp = thousep; - ndig = 0; - /* - * If (*(grp+1) == '\0') then we have to - * use *grp character (last grouping rule) - * for all next cases - */ - if (*(grp+1) != '\0') - grp++; - } - sval /= 10; - } while (sval != 0); - break; - - case 8: - do { - *--cp = to_char(val & 7); - val >>= 3; - } while (val); - if (octzero && *cp != '0') - *--cp = '0'; - break; - - case 16: - do { - *--cp = xdigs[val & 15]; - val >>= 4; - } while (val); - break; - - default: - LIBC_ABORT("base = %d", base); - } - return (cp); -} - /* * Convert a wide character string argument for the %ls format to a multibyte - * string representation. ``prec'' specifies the maximum number of bytes - * to output. If ``prec'' is greater than or equal to zero, we can't assume - * that the wide char. string ends in a null character. + * string representation. If not -1, prec specifies the maximum number of + * bytes to output, and also means that we can't assume that the wide char. + * string ends is null-terminated. */ static char * __wcsconv(wchar_t *wcsarg, int prec, locale_t loc) @@ -371,134 +220,90 @@ __wcsconv(wchar_t *wcsarg, int prec, locale_t loc) mbstate_t mbs; char buf[MB_LEN_MAX]; wchar_t *p; - char *convbuf, *mbp; - size_t clen = 0, nbytes; + char *convbuf; + size_t clen, nbytes; - /* - * Determine the number of bytes to output and allocate space for - * the output. - */ - if (prec >= 0) { - nbytes = 0; - p = wcsarg; - mbs = initial; - for (;;) { - clen = wcrtomb_l(buf, *p++, &mbs, loc); - if (clen == 0 || clen == (size_t)-1 || - nbytes + clen > prec) - break; - nbytes += clen; - } - } else { + /* Allocate space for the maximum number of bytes we could output. */ + if (prec < 0) { p = wcsarg; mbs = initial; nbytes = wcsrtombs_l(NULL, (const wchar_t **)&p, 0, &mbs, loc); if (nbytes == (size_t)-1) return (NULL); + } else { + /* + * Optimisation: if the output precision is small enough, + * just allocate enough memory for the maximum instead of + * scanning the string. + */ + if (prec < 128) + nbytes = prec; + else { + nbytes = 0; + p = wcsarg; + mbs = initial; + for (;;) { + clen = wcrtomb_l(buf, *p++, &mbs, loc); + if (clen == 0 || clen == (size_t)-1 || + nbytes + clen > prec) + break; + nbytes += clen; + } + } } if ((convbuf = malloc(nbytes + 1)) == NULL) return (NULL); - /* - * Fill the output buffer with the multibyte representations of as - * many wide characters as will fit. - */ - mbp = convbuf; + /* Fill the output buffer. */ p = wcsarg; mbs = initial; - while (mbp - convbuf < nbytes) { - clen = wcrtomb_l(mbp, *p++, &mbs, loc); - if (clen == 0 || clen == (size_t)-1) - break; - mbp += clen; - } - if (clen == (size_t)-1) { + if ((nbytes = wcsrtombs_l(convbuf, (const wchar_t **)&p, + nbytes, &mbs, loc)) == (size_t)-1) { free(convbuf); return (NULL); } - *mbp = '\0'; - + convbuf[nbytes] = '\0'; return (convbuf); } /* * MT-safe version */ -__private_extern__ const char *__fix_nogrouping(const char *); - int -vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) +vfprintf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, va_list ap) { int ret; + NORMALIZE_LOCALE(loc); FLOCKFILE(fp); - ret = __vfprintf(fp, __current_locale(), fmt0, ap); + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) + ret = __sbprintf(fp, loc, fmt0, ap); + else + ret = __vfprintf(fp, loc, fmt0, ap); FUNLOCKFILE(fp); return (ret); } int -vfprintf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, - va_list ap) +vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) { - int ret; - - NORMALIZE_LOCALE(loc); - FLOCKFILE(fp); - ret = __vfprintf(fp, loc, fmt0, ap); - FUNLOCKFILE(fp); - return (ret); + return vfprintf_l(fp, __current_locale(), fmt0, ap); } -#ifndef NO_FLOATING_POINT - -#define dtoa __dtoa -#define freedtoa __freedtoa - -#include -#include -#include "floatio.h" -#include "gdtoa.h" - -#define DEFPREC 6 - -static int exponent(char *, int, int); - -#endif /* !NO_FLOATING_POINT */ - /* * The size of the buffer we use as scratch space for integer - * conversions, among other things. Technically, we would need the - * most space for base 10 conversions with thousands' grouping - * characters between each pair of digits. 100 bytes is a - * conservative overestimate even for a 128-bit uintmax_t. + * conversions, among other things. We need enough space to + * write a uintmax_t in octal (plus one byte). */ -#define BUF 100 - -#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ - -/* - * Flags used during conversion. - */ -#define ALT 0x001 /* alternate form */ -#define LADJUST 0x004 /* left adjustment */ -#define LONGDBL 0x008 /* long double */ -#define LONGINT 0x010 /* long integer */ -#define LLONGINT 0x020 /* long long integer */ -#define SHORTINT 0x040 /* short integer */ -#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ -#define FPT 0x100 /* Floating point number */ -#define GROUPING 0x200 /* use grouping ("'" flag) */ - /* C99 additional size modifiers: */ -#define SIZET 0x400 /* size_t */ -#define PTRDIFFT 0x800 /* ptrdiff_t */ -#define INTMAXT 0x1000 /* intmax_t */ -#define CHARINT 0x2000 /* print char using int format */ -#ifdef VECTORS -#define VECTOR 0x4000 /* Altivec or SSE vector */ -#endif /* VECTORS */ +#if UINTMAX_MAX <= UINT64_MAX +#define BUF 32 +#else +#error "BUF must be large enough to format a uintmax_t" +#endif /* * Non-MT-safe version @@ -510,14 +315,13 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) int ch; /* character from fmt */ int n, n2; /* handy integer (short term usage) */ char *cp; /* handy char pointer (short term usage) */ - struct __siov *iovp; /* for PRINT macro */ int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format; <0 for N/A */ char sign; /* sign prefix (' ', '+', '-', or \0) */ - char thousands_sep; /* locale specific thousands separator */ - const char *grouping; /* locale specific numeric grouping rules */ + struct grouping_state gs; /* thousands' grouping info */ + #ifndef NO_FLOATING_POINT /* * We can decompose the printed representation of floating @@ -534,6 +338,7 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) * F: at least two digits for decimal, at least one digit for hex */ char *decimal_point; /* locale specific decimal point */ + int decpt_len; /* length of decimal_point */ int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; @@ -543,12 +348,9 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) char expchar; /* exponent character: [eEpP\0] */ char *dtoaend; /* pointer to end of converted digits */ int expsize; /* character count for expstr */ - int lead; /* sig figs before decimal or group sep */ int ndig; /* actual number of digits returned by dtoa */ char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ char *dtoaresult; /* buffer allocated by dtoa */ - int nseps; /* number of group separators with ' */ - int nrepeats; /* number of repeats of the last group */ #endif #ifdef VECTORS union arg vval; /* Vector argument. */ @@ -563,9 +365,7 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) int size; /* size of converted field or string */ int prsize; /* max size of printed field */ const char *xdigs; /* digits for %[xX] conversion */ -#define NIOV 8 - struct __suio uio; /* output information: summary */ - struct __siov iov[NIOV];/* ... and individual io vectors */ + struct io_state io; /* I/O buffering state */ char buf[BUF]; /* buffer with space for digits of uintmax_t */ char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */ union arg *argtable; /* args, built due to positional arg */ @@ -574,56 +374,25 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) va_list orgap; /* original argument pointer */ char *convbuf; /* wide to multibyte conversion result */ - /* - * Choose PADSIZE to trade efficiency vs. size. If larger printf - * fields occur frequently, increase PADSIZE and make the initialisers - * below longer. - */ -#define PADSIZE 16 /* pad chunk size */ - static char blanks[PADSIZE] = - {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; - static char zeroes[PADSIZE] = - {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; - static const char xdigs_lower[16] = "0123456789abcdef"; static const char xdigs_upper[16] = "0123456789ABCDEF"; - /* - * BEWARE, these `goto error' on error, and PAD uses `n'. - */ + /* BEWARE, these `goto error' on error. */ #define PRINT(ptr, len) { \ - iovp->iov_base = (ptr); \ - iovp->iov_len = (len); \ - uio.uio_resid += (len); \ - iovp++; \ - if (++uio.uio_iovcnt >= NIOV) { \ - if (__sprint(fp, &uio)) \ - goto error; \ - iovp = iov; \ - } \ + if (io_print(&io, (ptr), (len), loc)) \ + goto error; \ } #define PAD(howmany, with) { \ - if ((n = (howmany)) > 0) { \ - while (n > PADSIZE) { \ - PRINT(with, PADSIZE); \ - n -= PADSIZE; \ - } \ - PRINT(with, n); \ - } \ + if (io_pad(&io, (howmany), (with), loc)) \ + goto error; \ +} +#define PRINTANDPAD(p, ep, len, with) { \ + if (io_printandpad(&io, (p), (ep), (len), (with), loc)) \ + goto error; \ } -#define PRINTANDPAD(p, ep, len, with) do { \ - n2 = (ep) - (p); \ - if (n2 > (len)) \ - n2 = (len); \ - if (n2 > 0) \ - PRINT((p), n2); \ - PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ -} while(0) #define FLUSH() { \ - if (uio.uio_resid && __sprint(fp, &uio)) \ + if (io_flush(&io, loc)) \ goto error; \ - uio.uio_iovcnt = 0; \ - iovp = iov; \ } /* @@ -658,7 +427,7 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) #define UJARG() \ (flags&INTMAXT ? GETARG(uintmax_t) : \ flags&SIZET ? (uintmax_t)GETARG(size_t) : \ - flags&PTRDIFFT ? (uintmax_t)(unsigned)GETARG(ptrdiff_t) : \ + flags&PTRDIFFT ? (uintmax_t)(unsigned long)GETARG(ptrdiff_t) : \ (uintmax_t)GETARG(unsigned long long)) /* @@ -676,7 +445,10 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) int hold = nextarg; \ if (argtable == NULL) { \ argtable = statargtable; \ - __find_arguments (fmt0, orgap, &argtable); \ + if (__find_arguments (fmt0, orgap, &argtable)) { \ + ret = EOF; \ + goto error; \ + } \ } \ nextarg = n2; \ val = GETARG (int); \ @@ -686,13 +458,13 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) val = GETARG (int); \ } - thousands_sep = '\0'; - grouping = NULL; - convbuf = NULL; -#ifndef NO_FLOATING_POINT - dtoaresult = NULL; - decimal_point = localeconv_l(loc)->decimal_point; +#if 0 // xprintf pending API review + if (__use_xprintf == 0 && getenv("USE_XPRINTF")) + __use_xprintf = 1; + if (__use_xprintf > 0) + return (__xvprintf(fp, loc, fmt0, ap)); #endif + /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ if (prepwrite(fp) != 0) { errno = EBADF; @@ -700,19 +472,19 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) } ORIENT(fp, -1); - /* optimise fprintf(stderr) (and other unbuffered Unix files) */ - if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) - return (__sbprintf(fp, loc, fmt0, ap)); - + convbuf = NULL; fmt = (char *)fmt0; argtable = NULL; nextarg = 1; va_copy(orgap, ap); - uio.uio_iov = iovp = iov; - uio.uio_resid = 0; - uio.uio_iovcnt = 0; + io_init(&io, fp); ret = 0; +#ifndef NO_FLOATING_POINT + dtoaresult = NULL; + decimal_point = localeconv_l(loc)->decimal_point; + /* The overwhelmingly common case is decpt_len == 1. */ + decpt_len = (decimal_point[1] == '\0' ? 1 : strlen(decimal_point)); +#endif /* * Scan the format for conversions (`%' character). @@ -739,6 +511,7 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) dprec = 0; width = 0; prec = -1; + gs.grouping = NULL; sign = '\0'; ox[1] = '\0'; #ifdef VECTORS @@ -784,8 +557,6 @@ reswitch: switch (ch) { goto rflag; case '\'': flags |= GROUPING; - thousands_sep = *(localeconv_l(loc)->thousands_sep); - grouping = __fix_nogrouping(localeconv_l(loc)->grouping); goto rflag; case '.': if ((ch = *fmt++) == '*') { @@ -817,8 +588,11 @@ reswitch: switch (ch) { nextarg = n; if (argtable == NULL) { argtable = statargtable; - __find_arguments (fmt0, orgap, - &argtable); + if (__find_arguments (fmt0, orgap, + &argtable)) { + ret = EOF; + goto error; + } } goto rflag; } @@ -1023,6 +797,7 @@ fp_common: } else cp = (ch >= 'a') ? "inf" : "INF"; size = 3; + flags &= ~ZEROPAD; break; } flags |= FPT; @@ -1050,7 +825,7 @@ fp_common: expsize = exponent(expstr, expt - 1, expchar); size = expsize + prec; if (prec > 1 || flags & ALT) - ++size; + size += decpt_len; } else { /* space for digits before decimal point */ if (expt > 0) @@ -1059,50 +834,40 @@ fp_common: size = 1; /* space for decimal pt and following digits */ if (prec || flags & ALT) - size += prec + 1; - if (grouping && expt > 0) { - /* space for thousands' grouping */ - nseps = nrepeats = 0; - lead = expt; - while (*grouping != CHAR_MAX) { - if (lead <= *grouping) - break; - lead -= *grouping; - if (*(grouping+1)) { - nseps++; - grouping++; - } else - nrepeats++; - } - size += nseps + nrepeats; - } else - lead = expt; + size += prec + decpt_len; + if ((flags & GROUPING) && expt > 0) + size += grouping_init(&gs, expt, loc); } break; #endif /* !NO_FLOATING_POINT */ case 'n': + { /* * Assignment-like behavior is specified if the * value overflows or is otherwise unrepresentable. * C99 says to use `signed char' for %hhn conversions. */ - if (flags & LLONGINT) - *GETARG(long long *) = ret; + void *ptr = GETARG(void *); + if (ptr == NULL) + continue; + else if (flags & LLONGINT) + *(long long *)ptr = ret; else if (flags & SIZET) - *GETARG(ssize_t *) = (ssize_t)ret; + *(ssize_t *)ptr = (ssize_t)ret; else if (flags & PTRDIFFT) - *GETARG(ptrdiff_t *) = ret; + *(ptrdiff_t *)ptr = ret; else if (flags & INTMAXT) - *GETARG(intmax_t *) = ret; + *(intmax_t *)ptr = ret; else if (flags & LONGINT) - *GETARG(long *) = ret; + *(long *)ptr = ret; else if (flags & SHORTINT) - *GETARG(short *) = ret; + *(short *)ptr = ret; else if (flags & CHARINT) - *GETARG(signed char *) = ret; + *(signed char *)ptr = ret; else - *GETARG(int *) = ret; + *(int *)ptr = ret; continue; /* no output */ + } case 'O': flags |= LONGINT; /*FALLTHROUGH*/ @@ -1156,22 +921,7 @@ fp_common: } } else if ((cp = GETARG(char *)) == NULL) cp = "(null)"; - if (prec >= 0) { - /* - * can't use strlen; can only look for the - * NUL in the first `prec' characters, and - * strlen() will go further. - */ - char *p = memchr(cp, 0, (size_t)prec); - - if (p != NULL) { - size = p - cp; - if (size > prec) - size = prec; - } else - size = prec; - } else - size = strlen(cp); + size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp); sign = '\0'; break; case 'U': @@ -1215,6 +965,7 @@ nosign: sign = '\0'; * ``... diouXx conversions ... if a precision is * specified, the 0 flag will be ignored.'' * -- ANSI X3J11 + * except for %#.0o and zero value */ number: if ((dprec = prec) >= 0) flags &= ~ZEROPAD; @@ -1223,25 +974,28 @@ number: if ((dprec = prec) >= 0) * ``The result of converting a zero value with an * explicit precision of zero is no characters.'' * -- ANSI X3J11 - * except for %#.0o and zero value + * + * ``The C Standard is clear enough as is. The call + * printf("%#.0o", 0) should print 0.'' + * -- Defect Report #151 */ cp = buf + BUF; if (flags & INTMAX_SIZE) { - if (ujval != 0 || prec != 0) + if (ujval != 0 || prec != 0 || + (flags & ALT && base == 8)) cp = __ujtoa(ujval, cp, base, - flags & ALT, xdigs, - flags & GROUPING, thousands_sep, - grouping); + flags & ALT, xdigs); } else { - if (ulval != 0 || prec != 0 || (flags & ALT)) + if (ulval != 0 || prec != 0 || + (flags & ALT && base == 8)) cp = __ultoa(ulval, cp, base, - flags & ALT, xdigs, - flags & GROUPING, thousands_sep, - grouping); + flags & ALT, xdigs); } size = buf + BUF - cp; if (size > BUF) /* should never happen */ - LIBC_ABORT("size %d > BUF %d", size, BUF); + LIBC_ABORT("size (%d) > BUF (%d)", size, BUF); + if ((flags & GROUPING) && size != 0) + size += grouping_init(&gs, size, loc); break; #ifdef VECTORS case 'v': @@ -1421,25 +1175,25 @@ number: if ((dprec = prec) >= 0) vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \ break; \ case V_PCHAR: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuchararg[ind]); \ break; \ case V_SHORT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \ break; \ case V_PSHORT: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vushortarg[ind]); \ break; \ case V_INT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \ break; \ case V_PINT: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuintarg[ind]); \ break; \ case V_LONGLONG: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vulonglongarg[ind]); \ break; \ case V_PLONGLONG: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vulonglongarg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vulonglongarg[ind]); \ break; \ case V_FLOAT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ @@ -1460,19 +1214,19 @@ number: if ((dprec = prec) >= 0) vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \ break; \ case V_PCHAR: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuchararg[ind]); \ break; \ case V_SHORT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \ break; \ case V_PSHORT: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vushortarg[ind]); \ break; \ case V_INT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \ break; \ case V_PINT: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuintarg[ind]); \ break; \ case V_FLOAT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ @@ -1586,51 +1340,48 @@ number: if ((dprec = prec) >= 0) if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) PAD(width - realsz, zeroes); - /* leading zeroes from decimal precision */ - PAD(dprec - size, zeroes); - /* the string or number proper */ #ifndef NO_FLOATING_POINT if ((flags & FPT) == 0) { - PRINT(cp, size); +#endif + /* leading zeroes from decimal precision */ + PAD(dprec - size, zeroes); + if (gs.grouping) { + if (grouping_print(&gs, &io, cp, buf+BUF, loc) < 0) + goto error; + } else { + PRINT(cp, size); + } +#ifndef NO_FLOATING_POINT } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { PRINT(zeroes, 1); if (prec || flags & ALT) - PRINT(decimal_point, strlen(decimal_point)); + PRINT(decimal_point,decpt_len); PAD(-expt, zeroes); /* already handled initial 0's */ prec += expt; } else { - PRINTANDPAD(cp, dtoaend, lead, zeroes); - cp += lead; - if (grouping) { - while (nseps>0 || nrepeats>0) { - if (nrepeats > 0) - nrepeats--; - else { - grouping--; - nseps--; - } - PRINT(&thousands_sep, - 1); - PRINTANDPAD(cp,dtoaend, - *grouping, zeroes); - cp += *grouping; - } - if (cp > dtoaend) - cp = dtoaend; + if (gs.grouping) { + n = grouping_print(&gs, &io, + cp, dtoaend, loc); + if (n < 0) + goto error; + cp += n; + } else { + PRINTANDPAD(cp, dtoaend, + expt, zeroes); + cp += expt; } if (prec || flags & ALT) - PRINT(decimal_point, strlen(decimal_point)); + PRINT(decimal_point,decpt_len); } PRINTANDPAD(cp, dtoaend, prec, zeroes); } else { /* %[eE] or sufficiently long %[gG] */ if (prec > 1 || flags & ALT) { - buf[0] = *cp++; - PRINT(buf, 1); - PRINT(decimal_point, strlen(decimal_point)); + PRINT(cp++, 1); + PRINT(decimal_point, decpt_len); PRINT(cp, ndig-1); PAD(prec - ndig, zeroes); } else /* XeYYY */ @@ -1638,8 +1389,6 @@ number: if ((dprec = prec) >= 0) PRINT(expstr, expsize); } } -#else - PRINT(cp, size); #endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) @@ -1668,434 +1417,3 @@ error: /* NOTREACHED */ } -/* - * Find all arguments when a positional parameter is encountered. Returns a - * table, indexed by argument number, of pointers to each arguments. The - * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. - * It will be replaces with a malloc-ed one if it overflows. - */ -static void -__find_arguments (const char *fmt0, va_list ap, union arg **argtable) -{ - char *fmt; /* format string */ - int ch; /* character from fmt */ - int n, n2; /* handy integer (short term usage) */ - char *cp; /* handy char pointer (short term usage) */ - int flags; /* flags as above */ - int width; /* width from format (%8d), or 0 */ - enum typeid *typetable; /* table of types */ - enum typeid stattypetable [STATIC_ARG_TBL_SIZE]; - int tablesize; /* current size of type table */ - int tablemax; /* largest used index in table */ - int nextarg; /* 1-based argument index */ - - /* - * Add an argument type to the table, expanding if necessary. - */ -#define ADDTYPE(type) \ - ((nextarg >= tablesize) ? \ - __grow_type_table(nextarg, &typetable, &tablesize) : (void)0, \ - (nextarg > tablemax) ? tablemax = nextarg : 0, \ - typetable[nextarg++] = type) - -#define ADDSARG() \ - ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \ - ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ - ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ - ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \ - ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT)))))) - -#define ADDUARG() \ - ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \ - ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ - ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ - ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \ - ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT)))))) - - /* - * Add * arguments to the type array. - */ -#define ADDASTER() \ - n2 = 0; \ - cp = fmt; \ - while (is_digit(*cp)) { \ - n2 = 10 * n2 + to_digit(*cp); \ - cp++; \ - } \ - if (*cp == '$') { \ - int hold = nextarg; \ - nextarg = n2; \ - ADDTYPE (T_INT); \ - nextarg = hold; \ - fmt = ++cp; \ - } else { \ - ADDTYPE (T_INT); \ - } - fmt = (char *)fmt0; - typetable = stattypetable; - tablesize = STATIC_ARG_TBL_SIZE; - tablemax = 0; - nextarg = 1; - for (n = 0; n < STATIC_ARG_TBL_SIZE; n++) - typetable[n] = T_UNUSED; - - /* - * Scan the format for conversions (`%' character). - */ - for (;;) { - for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) - /* void */; - if (ch == '\0') - goto done; - fmt++; /* skip over '%' */ - - flags = 0; - width = 0; - -rflag: ch = *fmt++; -reswitch: switch (ch) { - case ' ': - case '#': - goto rflag; - case '*': - ADDASTER (); - goto rflag; - case '-': - case '+': - case '\'': - goto rflag; - case '.': - if ((ch = *fmt++) == '*') { - ADDASTER (); - goto rflag; - } - while (is_digit(ch)) { - ch = *fmt++; - } - goto reswitch; - case '0': - goto rflag; - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - n = 0; - do { - n = 10 * n + to_digit(ch); - ch = *fmt++; - } while (is_digit(ch)); - if (ch == '$') { - nextarg = n; - goto rflag; - } - width = n; - goto reswitch; -#ifndef NO_FLOATING_POINT - case 'L': - flags |= LONGDBL; - goto rflag; -#endif - case 'h': - if (flags & SHORTINT) { - flags &= ~SHORTINT; - flags |= CHARINT; - } else - flags |= SHORTINT; - goto rflag; - case 'j': - flags |= INTMAXT; - goto rflag; - case 'l': - if (flags & LONGINT) { - flags &= ~LONGINT; - flags |= LLONGINT; - } else - flags |= LONGINT; - goto rflag; - case 'q': - flags |= LLONGINT; /* not necessarily */ - goto rflag; - case 't': - flags |= PTRDIFFT; - goto rflag; - case 'z': - flags |= SIZET; - goto rflag; - case 'C': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'c': - if (flags & LONGINT) - ADDTYPE(T_WINT); - else -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - ADDTYPE(T_INT); - break; - case 'D': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'd': - case 'i': -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif - ADDSARG(); - break; -#ifndef NO_FLOATING_POINT - case 'a': - case 'A': - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - if (flags & LONGDBL) - ADDTYPE(T_LONG_DOUBLE); - else - ADDTYPE(T_DOUBLE); - break; -#endif /* !NO_FLOATING_POINT */ - case 'n': - if (flags & INTMAXT) - ADDTYPE(TP_INTMAXT); - else if (flags & PTRDIFFT) - ADDTYPE(TP_PTRDIFFT); - else if (flags & SIZET) - ADDTYPE(TP_SIZET); - else if (flags & LLONGINT) - ADDTYPE(TP_LLONG); - else if (flags & LONGINT) - ADDTYPE(TP_LONG); - else if (flags & SHORTINT) - ADDTYPE(TP_SHORT); - else if (flags & CHARINT) - ADDTYPE(TP_SCHAR); - else - ADDTYPE(TP_INT); - continue; /* no output */ - case 'O': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'o': -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - ADDUARG(); - break; - case 'p': -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - ADDTYPE(TP_VOID); - break; - case 'S': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 's': - if (flags & LONGINT) - ADDTYPE(TP_WCHAR); - else - ADDTYPE(TP_CHAR); - break; - case 'U': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'u': - case 'X': - case 'x': -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - ADDUARG(); - break; - default: /* "%?" prints ?, unless ? is NUL */ - if (ch == '\0') - goto done; - break; - } - } -done: - /* - * Build the argument table. - */ - if (tablemax >= STATIC_ARG_TBL_SIZE) { - *argtable = (union arg *) - malloc (sizeof (union arg) * (tablemax + 1)); - } - - (*argtable) [0].intarg = 0; - for (n = 1; n <= tablemax; n++) { - switch (typetable [n]) { - case T_UNUSED: /* whoops! */ - (*argtable) [n].intarg = va_arg (ap, int); - break; - case TP_SCHAR: - (*argtable) [n].pschararg = va_arg (ap, signed char *); - break; - case TP_SHORT: - (*argtable) [n].pshortarg = va_arg (ap, short *); - break; - case T_INT: - (*argtable) [n].intarg = va_arg (ap, int); - break; - case T_U_INT: - (*argtable) [n].uintarg = va_arg (ap, unsigned int); - break; - case TP_INT: - (*argtable) [n].pintarg = va_arg (ap, int *); - break; - case T_LONG: - (*argtable) [n].longarg = va_arg (ap, long); - break; - case T_U_LONG: - (*argtable) [n].ulongarg = va_arg (ap, unsigned long); - break; - case TP_LONG: - (*argtable) [n].plongarg = va_arg (ap, long *); - break; - case T_LLONG: - (*argtable) [n].longlongarg = va_arg (ap, long long); - break; - case T_U_LLONG: - (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); - break; - case TP_LLONG: - (*argtable) [n].plonglongarg = va_arg (ap, long long *); - break; - case T_PTRDIFFT: - (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); - break; - case TP_PTRDIFFT: - (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); - break; - case T_SIZET: - (*argtable) [n].sizearg = va_arg (ap, size_t); - break; - case TP_SIZET: - (*argtable) [n].psizearg = va_arg (ap, size_t *); - break; - case T_INTMAXT: - (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); - break; - case T_UINTMAXT: - (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); - break; - case TP_INTMAXT: - (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); - break; -#ifndef NO_FLOATING_POINT - case T_DOUBLE: - (*argtable) [n].doublearg = va_arg (ap, double); - break; - case T_LONG_DOUBLE: - (*argtable) [n].longdoublearg = va_arg (ap, long double); - break; -#endif -#ifdef VECTORS - case T_VECTOR: - (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE); - break; -#endif /* VECTORS */ - case TP_CHAR: - (*argtable) [n].pchararg = va_arg (ap, char *); - break; - case TP_VOID: - (*argtable) [n].pvoidarg = va_arg (ap, void *); - break; - case T_WINT: - (*argtable) [n].wintarg = va_arg (ap, wint_t); - break; - case TP_WCHAR: - (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); - break; - } - } - - if ((typetable != NULL) && (typetable != stattypetable)) - free (typetable); -} - -/* - * Increase the size of the type table. - */ -static void -__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) -{ - enum typeid *const oldtable = *typetable; - const int oldsize = *tablesize; - enum typeid *newtable; - int n, newsize = oldsize * 2; - - if (newsize < nextarg + 1) - newsize = nextarg + 1; - if (oldsize == STATIC_ARG_TBL_SIZE) { - if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL) - LIBC_ABORT("malloc: %s", strerror(errno)); /* XXX handle better */ - bcopy(oldtable, newtable, oldsize * sizeof(enum typeid)); - } else { - newtable = reallocf(oldtable, newsize * sizeof(enum typeid)); - if (newtable == NULL) - LIBC_ABORT("reallocf: %s", strerror(errno)); /* XXX handle better */ - } - for (n = oldsize; n < newsize; n++) - newtable[n] = T_UNUSED; - - *typetable = newtable; - *tablesize = newsize; -} - - -#ifndef NO_FLOATING_POINT - -static int -exponent(char *p0, int exp, int fmtch) -{ - char *p, *t; - char expbuf[MAXEXPDIG]; - - p = p0; - *p++ = fmtch; - if (exp < 0) { - exp = -exp; - *p++ = '-'; - } - else - *p++ = '+'; - t = expbuf + MAXEXPDIG; - if (exp > 9) { - do { - *--t = to_char(exp % 10); - } while ((exp /= 10) > 9); - *--t = to_char(exp); - for (; t < expbuf + MAXEXPDIG; *p++ = *t++); - } - else { - /* - * Exponents for decimal floating point conversions - * (%[eEgG]) must be at least two characters long, - * whereas exponents for hexadecimal conversions can - * be only one character long. - */ - if (fmtch == 'e' || fmtch == 'E') - *p++ = '0'; - *p++ = to_char(exp); - } - return (p - p0); -} -#endif /* !NO_FLOATING_POINT */ diff --git a/stdio/vfscanf-fbsd.c b/stdio/vfscanf-fbsd.c index 387d6a0..a3f9f3e 100644 --- a/stdio/vfscanf-fbsd.c +++ b/stdio/vfscanf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.37 2004/05/02 10:55:05 das Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.43 2009/01/19 06:19:51 das Exp $"); #include "xlocale_private.h" @@ -103,18 +99,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.37 2004/05/02 10:55:05 das static const u_char *__sccl(char *, const u_char *, locale_t); #ifndef NO_FLOATING_POINT static int parsefloat(FILE *, char **, size_t, locale_t); -#endif /* !NO_FLOATING_POINT */ - -/* - * For ppc, we need to have the 64-bit long double version defining storage for - * __scanfdebug, to be compatible with 10.3. For ppc64 and i386, we want the - * storage defined in the only version. - */ -#if defined(__ppc__) && !defined(BUILDING_VARIANT) -extern int __scanfdebug; -#else /* !__ppc__ || BUILDING_VARIANT */ -int __scanfdebug = 0; -#endif /* __ppc__ && !BUILDING_VARIANT */ +#endif __weak_reference(__vfscanf, vfscanf); @@ -163,7 +148,6 @@ __svfscanf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, v char ccltab[256]; /* character class table for %[...] */ char buf[BUF]; /* buffer for numeric and mb conversions */ wchar_t *wcp; /* handy wide character pointer */ - wchar_t *wcp0; /* saves original value of wcp */ size_t nconv; /* length of multibyte sequence converted */ int index; /* %index$, zero if unset */ va_list ap_orig; /* to reset ap to first argument */ @@ -341,26 +325,28 @@ literal: break; case 'n': - if (flags & SUPPRESS) /* ??? */ + { + void *ptr = va_arg(ap, void *); + if ((ptr == NULL) || (flags & SUPPRESS)) /* ??? */ continue; - if (flags & SHORTSHORT) - *va_arg(ap, char *) = nread; + else if (flags & SHORTSHORT) + *(char *)ptr = nread; else if (flags & SHORT) - *va_arg(ap, short *) = nread; + *(short *)ptr = nread; else if (flags & LONG) - *va_arg(ap, long *) = nread; + *(long *)ptr = nread; else if (flags & LONGLONG) - *va_arg(ap, long long *) = nread; + *(long long *)ptr = nread; else if (flags & INTMAXT) - *va_arg(ap, intmax_t *) = nread; + *(intmax_t *)ptr = nread; else if (flags & SIZET) - *va_arg(ap, size_t *) = nread; + *(size_t *)ptr = nread; else if (flags & PTRDIFFT) - *va_arg(ap, ptrdiff_t *) = nread; + *(ptrdiff_t *)ptr = nread; else - *va_arg(ap, int *) = nread; + *(int *)ptr = nread; continue; - + } default: goto match_failure; @@ -465,7 +451,7 @@ literal: } nread += sum; } else { - size_t r = fread((void *)va_arg(ap, char *), 1, + size_t r = __fread((void *)va_arg(ap, char *), 1, width, fp); if (r == 0) @@ -485,9 +471,9 @@ literal: int nchars; if ((flags & SUPPRESS) == 0) - wcp = wcp0 = va_arg(ap, wchar_t *); + wcp = va_arg(ap, wchar_t *); else - wcp = wcp0 = &twc; + wcp = &twc; n = 0; nchars = 0; while (width != 0) { @@ -832,8 +818,6 @@ literal: float res = strtof_l(pbuf, &p, loc); *va_arg(ap, float *) = res; } - if (__scanfdebug && p - pbuf != width) - LIBC_ABORT("p - pbuf %ld != width %ld", (long)(p - pbuf), width); nassigned++; } nread += width; @@ -1020,14 +1004,13 @@ static int parsefloat(FILE *fp, char **buf, size_t width, locale_t loc) { char *commit, *p; - int infnanpos = 0; + int infnanpos = 0, decptpos = 0; enum { - S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX, - S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS, S_DECIMAL_POINT + S_START, S_GOTSIGN, S_INF, S_NAN, S_DONE, S_MAYBEHEX, + S_DIGITS, S_DECPT, S_FRAC, S_EXP, S_EXPDIGITS } state = S_START; unsigned char c; - unsigned char *decpt = (unsigned char *)localeconv_l(loc)->decimal_point; - char *decpt_start; + const char *decpt = localeconv_l(loc)->decimal_point; _Bool gotmantdig = 0, ishex = 0; char *b; char *e; @@ -1089,8 +1072,6 @@ reswitch: break; case S_NAN: switch (infnanpos) { - case -1: /* XXX kludge to deal with nan(...) */ - goto parsedone; case 0: if (c != 'A' && c != 'a') goto parsedone; @@ -1108,13 +1089,15 @@ reswitch: default: if (c == ')') { commit = p; - infnanpos = -2; + state = S_DONE; } else if (!isalnum_l(c, loc) && c != '_') goto parsedone; break; } infnanpos++; break; + case S_DONE: + goto parsedone; case S_MAYBEHEX: state = S_DIGITS; if (c == 'X' || c == 'x') { @@ -1125,33 +1108,34 @@ reswitch: goto reswitch; } case S_DIGITS: - if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc)) + if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc)) { gotmantdig = 1; - else { - state = S_DECIMAL_POINT; - decpt_start = p; - goto reswitch; - } - if (gotmantdig) commit = p; - break; - case S_DECIMAL_POINT: - if (*decpt == 0) { - if (gotmantdig) - commit = p - 1; - state = S_FRAC; + break; + } else { + state = S_DECPT; goto reswitch; } - if (*decpt++ == c) + case S_DECPT: + if (c == decpt[decptpos]) { + if (decpt[++decptpos] == '\0') { + /* We read the complete decpt seq. */ + state = S_FRAC; + if (gotmantdig) + commit = p; + } break; - /* not decimal point */ - state = S_FRAC; - if (decpt_start == p) + } else if (!decptpos) { + /* We didn't read any decpt characters. */ + state = S_FRAC; goto reswitch; - while (decpt_start < --p) - __ungetc(*(u_char *)p, fp); - c = *(u_char *)p; - goto reswitch; + } else { + /* + * We read part of a multibyte decimal point, + * but the rest is invalid, so bail. + */ + goto parsedone; + } case S_FRAC: if (((c == 'E' || c == 'e') && !ishex) || ((c == 'P' || c == 'p') && ishex)) { diff --git a/stdio/vfwprintf-fbsd.c b/stdio/vfwprintf-fbsd.c index 45f0bc8..d085dcc 100644 --- a/stdio/vfwprintf-fbsd.c +++ b/stdio/vfwprintf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #endif #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.23 2004/08/26 06:25:28 des Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.42 2009/11/25 04:27:55 wollman Exp $"); #include "xlocale_private.h" @@ -71,82 +67,141 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.23 2004/08/26 06:25:28 de #include "libc_private.h" #include "local.h" #include "fvwrite.h" +#include "printflocal.h" -#ifdef VECTORS -typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE; -#ifdef __SSE2__ -#define V64TYPE -#endif /* __SSE2__ */ -#endif /* VECTORS */ +static int __sprint(FILE *, locale_t, struct __suio *); +static int __sbprintf(FILE *, locale_t, const wchar_t *, va_list); +static wint_t __xfputwc(wchar_t, FILE *, locale_t); +static wchar_t *__mbsconv(char *, int, locale_t); +__private_extern__ const char *__fix_nogrouping(const char *); -union arg { - int intarg; - u_int uintarg; - long longarg; - u_long ulongarg; - long long longlongarg; - unsigned long long ulonglongarg; - ptrdiff_t ptrdiffarg; - size_t sizearg; - intmax_t intmaxarg; - uintmax_t uintmaxarg; - void *pvoidarg; - char *pchararg; - signed char *pschararg; - short *pshortarg; - int *pintarg; - long *plongarg; - long long *plonglongarg; - ptrdiff_t *pptrdiffarg; - size_t *psizearg; - intmax_t *pintmaxarg; -#ifndef NO_FLOATING_POINT - double doublearg; - long double longdoublearg; -#endif - wint_t wintarg; - wchar_t *pwchararg; -#ifdef VECTORS - VECTORTYPE vectorarg; - unsigned char vuchararg[16]; - signed char vchararg[16]; - unsigned short vushortarg[8]; - signed short vshortarg[8]; - unsigned int vuintarg[4]; - signed int vintarg[4]; - float vfloatarg[4]; -#ifdef V64TYPE - double vdoublearg[2]; - unsigned long long vulonglongarg[2]; - long long vlonglongarg[2]; -#endif /* V64TYPE */ -#endif /* VECTORS */ +#define CHAR wchar_t +#include "printfcommon.h" + +struct grouping_state { + wchar_t thousands_sep; /* locale-specific thousands separator */ + const char *grouping; /* locale-specific numeric grouping rules */ + int lead; /* sig figs before decimal or group sep */ + int nseps; /* number of group separators with ' */ + int nrepeats; /* number of repeats of the last group */ }; +static const mbstate_t initial_mbs; + +static inline wchar_t +get_decpt(locale_t loc) +{ + mbstate_t mbs; + wchar_t decpt; + int nconv; + + mbs = initial_mbs; + nconv = mbrtowc_l(&decpt, localeconv_l(loc)->decimal_point, MB_CUR_MAX_L(loc), &mbs, loc); + if (nconv == (size_t)-1 || nconv == (size_t)-2) + decpt = '.'; /* failsafe */ + return (decpt); +} + +static inline wchar_t +get_thousep(locale_t loc) +{ + mbstate_t mbs; + wchar_t thousep; + int nconv; + + mbs = initial_mbs; + nconv = mbrtowc_l(&thousep, localeconv_l(loc)->thousands_sep, + MB_CUR_MAX_L(loc), &mbs, loc); + if (nconv == (size_t)-1 || nconv == (size_t)-2) + thousep = '\0'; /* failsafe */ + return (thousep); +} + /* - * Type ids for argument type table. + * Initialize the thousands' grouping state in preparation to print a + * number with ndigits digits. This routine returns the total number + * of wide characters that will be printed. */ -enum typeid { - T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, - T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, - T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, - T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, -#ifdef VECTORS - T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR -#else /* ! VECTORS */ - T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR -#endif /* VECTORS */ -}; +static int +grouping_init(struct grouping_state *gs, int ndigits, locale_t loc) +{ -static int __sbprintf(FILE *, locale_t, const wchar_t *, va_list); -static wint_t __xfputwc(wchar_t, FILE *, locale_t); -static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int, - char, const char *); -static wchar_t *__ultoa(u_long, wchar_t *, int, int, const char *, int, - char, const char *); -static wchar_t *__mbsconv(char *, int, locale_t); -static void __find_arguments(const wchar_t *, va_list, union arg **); -static void __grow_type_table(int, enum typeid **, int *); + gs->grouping = __fix_nogrouping(localeconv_l(loc)->grouping); + gs->thousands_sep = get_thousep(loc); + + gs->nseps = gs->nrepeats = 0; + gs->lead = ndigits; + while (*gs->grouping != CHAR_MAX) { + if (gs->lead <= *gs->grouping) + break; + gs->lead -= *gs->grouping; + if (*(gs->grouping+1)) { + gs->nseps++; + gs->grouping++; + } else + gs->nrepeats++; + } + return (gs->nseps + gs->nrepeats); +} + +/* + * Print a number with thousands' separators. + */ +static int +grouping_print(struct grouping_state *gs, struct io_state *iop, + const CHAR *cp, const CHAR *ep, locale_t loc) +{ + const CHAR *cp0 = cp; + + if (io_printandpad(iop, cp, ep, gs->lead, zeroes, loc)) + return (-1); + cp += gs->lead; + while (gs->nseps > 0 || gs->nrepeats > 0) { + if (gs->nrepeats > 0) + gs->nrepeats--; + else { + gs->grouping--; + gs->nseps--; + } + if (io_print(iop, &gs->thousands_sep, 1, loc)) + return (-1); + if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes, loc)) + return (-1); + cp += *gs->grouping; + } + if (cp > ep) + cp = ep; + return (cp - cp0); +} + + +/* + * Flush out all the vectors defined by the given uio, + * then reset it so that it can be reused. + * + * XXX The fact that we do this a character at a time and convert to a + * multibyte character sequence even if the destination is a wide + * string eclipses the benefits of buffering. + */ +static int +__sprint(FILE *fp, locale_t loc, struct __suio *uio) +{ + struct __siov *iov; + wchar_t *p; + int i, len; + + iov = uio->uio_iov; + for (; uio->uio_resid != 0; uio->uio_resid -= len, iov++) { + p = (wchar_t *)iov->iov_base; + len = iov->iov_len; + for (i = 0; i < len; i++) { + if (__xfputwc(p[i], fp, loc) == WEOF) + return (-1); + } + } + uio->uio_iovcnt = 0; + return (0); +} /* * Helper function for `fprintf to unbuffered unix file': creates a @@ -159,13 +214,21 @@ __sbprintf(FILE *fp, locale_t loc, const wchar_t *fmt, va_list ap) int ret; FILE fake; unsigned char buf[BUFSIZ]; + struct __sFILEX ext; + fake._extra = &ext; + INITEXTRA(&fake); + + /* XXX This is probably not needed. */ + if (prepwrite(fp) != 0) + return (EOF); /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; - fake._extra = fp->_extra; + fake._orientation = fp->_orientation; + fake._mbstate = fp->_mbstate; /* set up the buffer */ fake._bf._base = fake._p = buf; @@ -188,7 +251,6 @@ __sbprintf(FILE *fp, locale_t loc, const wchar_t *fmt, va_list ap) static wint_t __xfputwc(wchar_t wc, FILE *fp, locale_t loc) { - static const mbstate_t initial; mbstate_t mbs; char buf[MB_LEN_MAX]; struct __suio uio; @@ -198,7 +260,7 @@ __xfputwc(wchar_t wc, FILE *fp, locale_t loc) if ((fp->_flags & __SSTR) == 0) return (__fputwc(wc, fp, loc)); - mbs = initial; + mbs = initial_mbs; if ((len = wcrtomb_l(buf, wc, &mbs, loc)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); @@ -211,167 +273,6 @@ __xfputwc(wchar_t wc, FILE *fp, locale_t loc) return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : WEOF); } -/* - * Macros for converting digits to letters and vice versa - */ -#define to_digit(c) ((c) - '0') -#define is_digit(c) ((unsigned)to_digit(c) <= 9) -#define to_char(n) ((n) + '0') - -/* - * Convert an unsigned long to ASCII for printf purposes, returning - * a pointer to the first character of the string representation. - * Octal numbers can be forced to have a leading zero; hex numbers - * use the given digits. - */ -static wchar_t * -__ultoa(u_long val, wchar_t *endp, int base, int octzero, const char *xdigs, - int needgrp, char thousep, const char *grp) -{ - wchar_t *cp = endp; - long sval; - int ndig; - - /* - * Handle the three cases separately, in the hope of getting - * better/faster code. - */ - switch (base) { - case 10: - if (val < 10) { /* many numbers are 1 digit */ - *--cp = to_char(val); - return (cp); - } - ndig = 0; - /* - * On many machines, unsigned arithmetic is harder than - * signed arithmetic, so we do at most one unsigned mod and - * divide; this is sufficient to reduce the range of - * the incoming value to where signed arithmetic works. - */ - if (val > LONG_MAX) { - *--cp = to_char(val % 10); - ndig++; - sval = val / 10; - } else - sval = val; - do { - *--cp = to_char(sval % 10); - ndig++; - /* - * If (*grp == CHAR_MAX) then no more grouping - * should be performed. - */ - if (needgrp && ndig == *grp && *grp != CHAR_MAX - && sval > 9) { - *--cp = thousep; - ndig = 0; - /* - * If (*(grp+1) == '\0') then we have to - * use *grp character (last grouping rule) - * for all next cases - */ - if (*(grp+1) != '\0') - grp++; - } - sval /= 10; - } while (sval != 0); - break; - - case 8: - do { - *--cp = to_char(val & 7); - val >>= 3; - } while (val); - if (octzero && *cp != '0') - *--cp = '0'; - break; - - case 16: - do { - *--cp = xdigs[val & 15]; - val >>= 4; - } while (val); - break; - - default: /* oops */ - LIBC_ABORT("base = %d", base); - } - return (cp); -} - -/* Identical to __ultoa, but for intmax_t. */ -static wchar_t * -__ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, - const char *xdigs, int needgrp, char thousep, const char *grp) -{ - wchar_t *cp = endp; - intmax_t sval; - int ndig; - - /* quick test for small values; __ultoa is typically much faster */ - /* (perhaps instead we should run until small, then call __ultoa?) */ - if (val <= ULONG_MAX) - return (__ultoa((u_long)val, endp, base, octzero, xdigs, - needgrp, thousep, grp)); - switch (base) { - case 10: - if (val < 10) { - *--cp = to_char(val % 10); - return (cp); - } - ndig = 0; - if (val > INTMAX_MAX) { - *--cp = to_char(val % 10); - ndig++; - sval = val / 10; - } else - sval = val; - do { - *--cp = to_char(sval % 10); - ndig++; - /* - * If (*grp == CHAR_MAX) then no more grouping - * should be performed. - */ - if (needgrp && *grp != CHAR_MAX && ndig == *grp - && sval > 9) { - *--cp = thousep; - ndig = 0; - /* - * If (*(grp+1) == '\0') then we have to - * use *grp character (last grouping rule) - * for all next cases - */ - if (*(grp+1) != '\0') - grp++; - } - sval /= 10; - } while (sval != 0); - break; - - case 8: - do { - *--cp = to_char(val & 7); - val >>= 3; - } while (val); - if (octzero && *cp != '0') - *--cp = '0'; - break; - - case 16: - do { - *--cp = xdigs[val & 15]; - val >>= 4; - } while (val); - break; - - default: - LIBC_ABORT("base = %d", base); - } - return (cp); -} - /* * Convert a multibyte character string argument for the %s format to a wide * string representation. ``prec'' specifies the maximum number of bytes @@ -381,7 +282,6 @@ __ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, static wchar_t * __mbsconv(char *mbsarg, int prec, locale_t loc) { - static const mbstate_t initial; mbstate_t mbs; wchar_t *convbuf, *wcp; const char *p; @@ -401,8 +301,8 @@ __mbsconv(char *mbsarg, int prec, locale_t loc) * number of characters to print. */ p = mbsarg; - insize = nchars = 0; - mbs = initial; + insize = nchars = nconv = 0; + mbs = initial_mbs; while (nchars != (size_t)prec) { nconv = mbrlen_l(p, mb_cur_max, &mbs, loc); if (nconv == 0 || nconv == (size_t)-1 || @@ -414,8 +314,10 @@ __mbsconv(char *mbsarg, int prec, locale_t loc) } if (nconv == (size_t)-1 || nconv == (size_t)-2) return (NULL); - } else + } else { insize = strlen(mbsarg); + nconv = 0; + } /* * Allocate buffer for the result and perform the conversion, @@ -427,7 +329,7 @@ __mbsconv(char *mbsarg, int prec, locale_t loc) return (NULL); wcp = convbuf; p = mbsarg; - mbs = initial; + mbs = initial_mbs; while (insize != 0) { nconv = mbrtowc_l(wcp, p, insize, &mbs, loc); if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) @@ -448,81 +350,39 @@ __mbsconv(char *mbsarg, int prec, locale_t loc) /* * MT-safe version */ -__private_extern__ const char *__fix_nogrouping(const char *); - int -vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) - +vfwprintf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt0, va_list ap) { int ret; + NORMALIZE_LOCALE(loc); FLOCKFILE(fp); - ret = __vfwprintf(fp, __current_locale(), fmt0, ap); + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) + ret = __sbprintf(fp, loc, fmt0, ap); + else + ret = __vfwprintf(fp, loc, fmt0, ap); FUNLOCKFILE(fp); return (ret); } int -vfwprintf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt0, - va_list ap) - +vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) { - int ret; - - NORMALIZE_LOCALE(loc); - FLOCKFILE(fp); - ret = __vfwprintf(fp, loc, fmt0, ap); - FUNLOCKFILE(fp); - return (ret); + return vfwprintf_l(fp, __current_locale(), fmt0, ap); } -#ifndef NO_FLOATING_POINT - -#define dtoa __dtoa -#define freedtoa __freedtoa - -#include -#include -#include "floatio.h" -#include "gdtoa.h" - -#define DEFPREC 6 - -static int exponent(wchar_t *, int, wchar_t); - -#endif /* !NO_FLOATING_POINT */ - /* * The size of the buffer we use as scratch space for integer - * conversions, among other things. Technically, we would need the - * most space for base 10 conversions with thousands' grouping - * characters between each pair of digits. 100 bytes is a - * conservative overestimate even for a 128-bit uintmax_t. + * conversions, among other things. We need enough space to + * write a uintmax_t in octal (plus one byte). */ -#define BUF 100 - -#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ - -/* - * Flags used during conversion. - */ -#define ALT 0x001 /* alternate form */ -#define LADJUST 0x004 /* left adjustment */ -#define LONGDBL 0x008 /* long double */ -#define LONGINT 0x010 /* long integer */ -#define LLONGINT 0x020 /* long long integer */ -#define SHORTINT 0x040 /* short integer */ -#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ -#define FPT 0x100 /* Floating point number */ -#define GROUPING 0x200 /* use grouping ("'" flag) */ - /* C99 additional size modifiers: */ -#define SIZET 0x400 /* size_t */ -#define PTRDIFFT 0x800 /* ptrdiff_t */ -#define INTMAXT 0x1000 /* intmax_t */ -#define CHARINT 0x2000 /* print char using int format */ -#ifdef VECTORS -#define VECTOR 0x4000 /* Altivec or SSE vector */ -#endif /* VECTORS */ +#if UINTMAX_MAX <= UINT64_MAX +#define BUF 32 +#else +#error "BUF must be large enough to format a uintmax_t" +#endif /* * Non-MT-safe version @@ -532,15 +392,14 @@ __vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) { wchar_t *fmt; /* format string */ wchar_t ch; /* character from fmt */ - int n, n2, n3; /* handy integer (short term usage) */ + int n, n2; /* handy integer (short term usage) */ wchar_t *cp; /* handy char pointer (short term usage) */ int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format; <0 for N/A */ wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */ - char thousands_sep; /* locale specific thousands separator */ - const char *grouping; /* locale specific numeric grouping rules */ + struct grouping_state gs; /* thousands' grouping info */ #ifndef NO_FLOATING_POINT /* * We can decompose the printed representation of floating @@ -557,7 +416,6 @@ __vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) * F: at least two digits for decimal, at least one digit for hex */ wchar_t decimal_point; /* locale specific decimal point */ - char *decimal_point_mb; /* multibyte decimal point */ int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; @@ -567,12 +425,9 @@ __vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) char expchar; /* exponent character: [eEpP\0] */ char *dtoaend; /* pointer to end of converted digits */ int expsize; /* character count for expstr */ - int lead; /* sig figs before decimal or group sep */ int ndig; /* actual number of digits returned by dtoa */ wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ char *dtoaresult; /* buffer allocated by dtoa */ - int nseps; /* number of group separators with ' */ - int nrepeats; /* number of repeats of the last group */ #endif #ifdef VECTORS union arg vval; /* Vector argument. */ @@ -587,6 +442,7 @@ __vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) int size; /* size of converted field or string */ int prsize; /* max size of printed field */ const char *xdigs; /* digits for [xX] conversion */ + struct io_state io; /* I/O buffering state */ wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */ wchar_t ox[2]; /* space for 0x hex-prefix */ union arg *argtable; /* args, built due to positional arg */ @@ -595,45 +451,26 @@ __vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) va_list orgap; /* original argument pointer */ wchar_t *convbuf; /* multibyte to wide conversion result */ - /* - * Choose PADSIZE to trade efficiency vs. size. If larger printf - * fields occur frequently, increase PADSIZE and make the initialisers - * below longer. - */ -#define PADSIZE 16 /* pad chunk size */ - static wchar_t blanks[PADSIZE] = - {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; - static wchar_t zeroes[PADSIZE] = - {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; - static const char xdigs_lower[16] = "0123456789abcdef"; static const char xdigs_upper[16] = "0123456789ABCDEF"; - /* - * BEWARE, these `goto error' on error, PRINT uses `n2' and - * PAD uses `n'. - */ + /* BEWARE, these `goto error' on error. */ #define PRINT(ptr, len) do { \ - for (n3 = 0; n3 < (len); n3++) \ - __xfputwc((ptr)[n3], fp, loc); \ -} while (0) -#define PAD(howmany, with) do { \ - if ((n = (howmany)) > 0) { \ - while (n > PADSIZE) { \ - PRINT(with, PADSIZE); \ - n -= PADSIZE; \ - } \ - PRINT(with, n); \ - } \ + if (io_print(&io, (ptr), (len), loc)) \ + goto error; \ } while (0) -#define PRINTANDPAD(p, ep, len, with) do { \ - n2 = (ep) - (p); \ - if (n2 > (len)) \ - n2 = (len); \ - if (n2 > 0) \ - PRINT((p), n2); \ - PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ -} while(0) +#define PAD(howmany, with) { \ + if (io_pad(&io, (howmany), (with), loc)) \ + goto error; \ +} +#define PRINTANDPAD(p, ep, len, with) { \ + if (io_printandpad(&io, (p), (ep), (len), (with), loc)) \ + goto error; \ +} +#define FLUSH() { \ + if (io_flush(&io, loc)) \ + goto error; \ +} /* * Get the argument indexed by nextarg. If the argument table is @@ -667,7 +504,7 @@ __vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) #define UJARG() \ (flags&INTMAXT ? GETARG(uintmax_t) : \ flags&SIZET ? (uintmax_t)GETARG(size_t) : \ - flags&PTRDIFFT ? (uintmax_t)(unsigned)GETARG(ptrdiff_t) : \ + flags&PTRDIFFT ? (uintmax_t)(unsigned long)GETARG(ptrdiff_t) : \ (uintmax_t)GETARG(unsigned long long)) /* @@ -685,7 +522,10 @@ __vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) int hold = nextarg; \ if (argtable == NULL) { \ argtable = statargtable; \ - __find_arguments (fmt0, orgap, &argtable); \ + if (__find_warguments (fmt0, orgap, &argtable)) { \ + ret = EOF; \ + goto error; \ + } \ } \ nextarg = n2; \ val = GETARG (int); \ @@ -695,13 +535,7 @@ __vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) val = GETARG (int); \ } - thousands_sep = '\0'; - grouping = NULL; -#ifndef NO_FLOATING_POINT - decimal_point_mb = localeconv_l(loc)->decimal_point; - mbtowc_l(&decimal_point, decimal_point_mb, strlen(decimal_point_mb), loc); -#endif - convbuf = NULL; + /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */ if (prepwrite(fp) != 0) { errno = EBADF; @@ -709,16 +543,16 @@ __vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) } ORIENT(fp, 1); - /* optimise fprintf(stderr) (and other unbuffered Unix files) */ - if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) - return (__sbprintf(fp, loc, fmt0, ap)); - + convbuf = NULL; fmt = (wchar_t *)fmt0; argtable = NULL; nextarg = 1; va_copy(orgap, ap); + io_init(&io, fp); ret = 0; +#ifndef NO_FLOATING_POINT + decimal_point = get_decpt(loc); +#endif /* * Scan the format for conversions (`%' character). @@ -745,6 +579,7 @@ __vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) dprec = 0; width = 0; prec = -1; + gs.grouping = NULL; sign = '\0'; ox[1] = '\0'; #ifdef VECTORS @@ -790,8 +625,6 @@ reswitch: switch (ch) { goto rflag; case '\'': flags |= GROUPING; - thousands_sep = *(localeconv_l(loc)->thousands_sep); - grouping = __fix_nogrouping(localeconv_l(loc)->grouping); goto rflag; case '.': if ((ch = *fmt++) == '*') { @@ -823,8 +656,11 @@ reswitch: switch (ch) { nextarg = n; if (argtable == NULL) { argtable = statargtable; - __find_arguments (fmt0, orgap, - &argtable); + if (__find_warguments (fmt0, orgap, + &argtable)) { + ret = EOF; + goto error; + } } goto rflag; } @@ -1023,6 +859,7 @@ fp_common: } else cp = (ch >= 'a') ? L"inf" : L"INF"; size = 3; + flags &= ~ZEROPAD; break; } flags |= FPT; @@ -1059,49 +896,39 @@ fp_common: /* space for decimal pt and following digits */ if (prec || flags & ALT) size += prec + 1; - if (grouping && expt > 0) { - /* space for thousands' grouping */ - nseps = nrepeats = 0; - lead = expt; - while (*grouping != CHAR_MAX) { - if (lead <= *grouping) - break; - lead -= *grouping; - if (*(grouping+1)) { - nseps++; - grouping++; - } else - nrepeats++; - } - size += nseps + nrepeats; - } else - lead = expt; + if ((flags & GROUPING) && expt > 0) + size += grouping_init(&gs, expt, loc); } break; #endif /* !NO_FLOATING_POINT */ case 'n': + { /* * Assignment-like behavior is specified if the * value overflows or is otherwise unrepresentable. * C99 says to use `signed char' for %hhn conversions. */ - if (flags & LLONGINT) - *GETARG(long long *) = ret; + void *ptr = GETARG(void *); + if (ptr == NULL) + continue; + else if (flags & LLONGINT) + *(long long *)ptr = ret; else if (flags & SIZET) - *GETARG(ssize_t *) = (ssize_t)ret; + *(ssize_t *)ptr = (ssize_t)ret; else if (flags & PTRDIFFT) - *GETARG(ptrdiff_t *) = ret; + *(ptrdiff_t *)ptr = ret; else if (flags & INTMAXT) - *GETARG(intmax_t *) = ret; + *(intmax_t *)ptr = ret; else if (flags & LONGINT) - *GETARG(long *) = ret; + *(long *)ptr = ret; else if (flags & SHORTINT) - *GETARG(short *) = ret; + *(short *)ptr = ret; else if (flags & CHARINT) - *GETARG(signed char *) = ret; + *(signed char *)ptr = ret; else - *GETARG(int *) = ret; + *(int *)ptr = ret; continue; /* no output */ + } case 'O': flags |= LONGINT; /*FALLTHROUGH*/ @@ -1157,23 +984,13 @@ fp_common: cp = convbuf; } } - - if (prec >= 0) { - /* - * can't use wcslen; can only look for the - * NUL in the first `prec' characters, and - * wcslen() will go further. - */ - wchar_t *p = wmemchr(cp, 0, (size_t)prec); - - if (p != NULL) { - size = p - cp; - if (size > prec) - size = prec; - } else - size = prec; - } else - size = wcslen(cp); +#if 0 // wcsnlen needs API review first + size = (prec >= 0) ? wcsnlen(cp, prec) : wcslen(cp); +#else + size = wcslen(cp); + if(prec >= 0 && prec < size) + size = prec; +#endif sign = '\0'; break; case 'U': @@ -1217,6 +1034,7 @@ nosign: sign = '\0'; * ``... diouXx conversions ... if a precision is * specified, the 0 flag will be ignored.'' * -- ANSI X3J11 + * except for %#.0o and zero value */ number: if ((dprec = prec) >= 0) flags &= ~ZEROPAD; @@ -1225,25 +1043,28 @@ number: if ((dprec = prec) >= 0) * ``The result of converting a zero value with an * explicit precision of zero is no characters.'' * -- ANSI X3J11 - * except for %#.0o and zero value + * + * ``The C Standard is clear enough as is. The call + * printf("%#.0o", 0) should print 0.'' + * -- Defect Report #151 */ cp = buf + BUF; if (flags & INTMAX_SIZE) { - if (ujval != 0 || prec != 0) + if (ujval != 0 || prec != 0 || + (flags & ALT && base == 8)) cp = __ujtoa(ujval, cp, base, - flags & ALT, xdigs, - flags & GROUPING, thousands_sep, - grouping); + flags & ALT, xdigs); } else { - if (ulval != 0 || prec != 0 || (flags & ALT)) + if (ulval != 0 || prec != 0 || + (flags & ALT && base == 8)) cp = __ultoa(ulval, cp, base, - flags & ALT, xdigs, - flags & GROUPING, thousands_sep, - grouping); + flags & ALT, xdigs); } size = buf + BUF - cp; if (size > BUF) /* should never happen */ - LIBC_ABORT("size %d > BUF %d", size, BUF); + LIBC_ABORT("size (%d) > BUF (%d)", size, BUF); + if ((flags & GROUPING) && size != 0) + size += grouping_init(&gs, size, loc); break; #ifdef VECTORS case 'v': @@ -1423,25 +1244,25 @@ number: if ((dprec = prec) >= 0) vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \ break; \ case V_PCHAR: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuchararg[ind]); \ break; \ case V_SHORT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \ break; \ case V_PSHORT: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vushortarg[ind]); \ break; \ case V_INT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \ break; \ case V_PINT: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuintarg[ind]); \ break; \ case V_LONGLONG: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vulonglongarg[ind]); \ break; \ case V_PLONGLONG: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vulonglongarg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vulonglongarg[ind]); \ break; \ case V_FLOAT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ @@ -1461,19 +1282,19 @@ number: if ((dprec = prec) >= 0) vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \ break; \ case V_PCHAR: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuchararg[ind]); \ break; \ case V_SHORT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \ break; \ case V_PSHORT: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vushortarg[ind]); \ break; \ case V_INT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \ break; \ case V_PINT: \ - vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(uintptr_t)vval.vuintarg[ind]); \ break; \ case V_FLOAT: \ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ @@ -1586,13 +1407,19 @@ number: if ((dprec = prec) >= 0) if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) PAD(width - realsz, zeroes); - /* leading zeroes from decimal precision */ - PAD(dprec - size, zeroes); - /* the string or number proper */ #ifndef NO_FLOATING_POINT if ((flags & FPT) == 0) { - PRINT(cp, size); +#endif + /* leading zeroes from decimal precision */ + PAD(dprec - size, zeroes); + if (gs.grouping) { + if (grouping_print(&gs, &io, cp, buf+BUF, loc) < 0) + goto error; + } else { + PRINT(cp, size); + } +#ifndef NO_FLOATING_POINT } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { @@ -1603,29 +1430,19 @@ number: if ((dprec = prec) >= 0) /* already handled initial 0's */ prec += expt; } else { - PRINTANDPAD(cp, convbuf + ndig, lead, zeroes); - cp += lead; - if (grouping) { - while (nseps>0 || nrepeats>0) { - if (nrepeats > 0) - nrepeats--; - else { - grouping--; - nseps--; - } - PRINT(&thousands_sep, - 1); - PRINTANDPAD(cp, - convbuf + ndig, - *grouping, zeroes); - cp += *grouping; - } - if (cp > convbuf + ndig) - cp = convbuf + ndig; + if (gs.grouping) { + n = grouping_print(&gs, &io, + cp, convbuf + ndig, loc); + if (n < 0) + goto error; + cp += n; + } else { + PRINTANDPAD(cp, convbuf + ndig, + expt, zeroes); + cp += expt; } - if (prec || flags & ALT) { + if (prec || flags & ALT) PRINT(&decimal_point, 1); - } } PRINTANDPAD(cp, convbuf + ndig, prec, zeroes); } else { /* %[eE] or sufficiently long %[gG] */ @@ -1640,8 +1457,6 @@ number: if ((dprec = prec) >= 0) PRINT(expstr, expsize); } } -#else - PRINT(cp, size); #endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) @@ -1649,8 +1464,11 @@ number: if ((dprec = prec) >= 0) /* finally, adjust ret */ ret += prsize; + + FLUSH(); /* copy out the I/O vectors */ } done: + FLUSH(); error: va_end(orgap); if (convbuf != NULL) @@ -1662,435 +1480,3 @@ error: return (ret); /* NOTREACHED */ } - -/* - * Find all arguments when a positional parameter is encountered. Returns a - * table, indexed by argument number, of pointers to each arguments. The - * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. - * It will be replaces with a malloc-ed one if it overflows. - */ -static void -__find_arguments (const wchar_t *fmt0, va_list ap, union arg **argtable) -{ - wchar_t *fmt; /* format string */ - wchar_t ch; /* character from fmt */ - int n, n2; /* handy integer (short term usage) */ - wchar_t *cp; /* handy char pointer (short term usage) */ - int flags; /* flags as above */ - int width; /* width from format (%8d), or 0 */ - enum typeid *typetable; /* table of types */ - enum typeid stattypetable [STATIC_ARG_TBL_SIZE]; - int tablesize; /* current size of type table */ - int tablemax; /* largest used index in table */ - int nextarg; /* 1-based argument index */ - - /* - * Add an argument type to the table, expanding if necessary. - */ -#define ADDTYPE(type) \ - ((nextarg >= tablesize) ? \ - __grow_type_table(nextarg, &typetable, &tablesize) : (void)0, \ - (nextarg > tablemax) ? tablemax = nextarg : 0, \ - typetable[nextarg++] = type) - -#define ADDSARG() \ - ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \ - ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ - ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ - ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \ - ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT)))))) - -#define ADDUARG() \ - ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \ - ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ - ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ - ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \ - ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT)))))) - - /* - * Add * arguments to the type array. - */ -#define ADDASTER() \ - n2 = 0; \ - cp = fmt; \ - while (is_digit(*cp)) { \ - n2 = 10 * n2 + to_digit(*cp); \ - cp++; \ - } \ - if (*cp == '$') { \ - int hold = nextarg; \ - nextarg = n2; \ - ADDTYPE (T_INT); \ - nextarg = hold; \ - fmt = ++cp; \ - } else { \ - ADDTYPE (T_INT); \ - } - fmt = (wchar_t *)fmt0; - typetable = stattypetable; - tablesize = STATIC_ARG_TBL_SIZE; - tablemax = 0; - nextarg = 1; - for (n = 0; n < STATIC_ARG_TBL_SIZE; n++) - typetable[n] = T_UNUSED; - - /* - * Scan the format for conversions (`%' character). - */ - for (;;) { - for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) - /* void */; - if (ch == '\0') - goto done; - fmt++; /* skip over '%' */ - - flags = 0; - width = 0; - -rflag: ch = *fmt++; -reswitch: switch (ch) { - case ' ': - case '#': - goto rflag; - case '*': - ADDASTER (); - goto rflag; - case '-': - case '+': - case '\'': - goto rflag; - case '.': - if ((ch = *fmt++) == '*') { - ADDASTER (); - goto rflag; - } - while (is_digit(ch)) { - ch = *fmt++; - } - goto reswitch; - case '0': - goto rflag; - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - n = 0; - do { - n = 10 * n + to_digit(ch); - ch = *fmt++; - } while (is_digit(ch)); - if (ch == '$') { - nextarg = n; - goto rflag; - } - width = n; - goto reswitch; -#ifndef NO_FLOATING_POINT - case 'L': - flags |= LONGDBL; - goto rflag; -#endif - case 'h': - if (flags & SHORTINT) { - flags &= ~SHORTINT; - flags |= CHARINT; - } else - flags |= SHORTINT; - goto rflag; - case 'j': - flags |= INTMAXT; - goto rflag; - case 'l': - if (flags & LONGINT) { - flags &= ~LONGINT; - flags |= LLONGINT; - } else - flags |= LONGINT; - goto rflag; - case 'q': - flags |= LLONGINT; /* not necessarily */ - goto rflag; - case 't': - flags |= PTRDIFFT; - goto rflag; - case 'z': - flags |= SIZET; - goto rflag; - case 'C': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'c': - if (flags & LONGINT) - ADDTYPE(T_WINT); - else -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - ADDTYPE(T_INT); - break; - case 'D': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'd': - case 'i': -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - ADDSARG(); - break; -#ifndef NO_FLOATING_POINT - case 'a': - case 'A': - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - if (flags & LONGDBL) - ADDTYPE(T_LONG_DOUBLE); - else - ADDTYPE(T_DOUBLE); - break; -#endif /* !NO_FLOATING_POINT */ - case 'n': - if (flags & INTMAXT) - ADDTYPE(TP_INTMAXT); - else if (flags & PTRDIFFT) - ADDTYPE(TP_PTRDIFFT); - else if (flags & SIZET) - ADDTYPE(TP_SIZET); - else if (flags & LLONGINT) - ADDTYPE(TP_LLONG); - else if (flags & LONGINT) - ADDTYPE(TP_LONG); - else if (flags & SHORTINT) - ADDTYPE(TP_SHORT); - else if (flags & CHARINT) - ADDTYPE(TP_SCHAR); - else - ADDTYPE(TP_INT); - continue; /* no output */ - case 'O': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'o': -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - ADDUARG(); - break; - case 'p': -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - ADDTYPE(TP_VOID); - break; - case 'S': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 's': - if (flags & LONGINT) - ADDTYPE(TP_WCHAR); - else - ADDTYPE(TP_CHAR); - break; - case 'U': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'u': - case 'X': - case 'x': -#ifdef VECTORS - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif /* VECTORS */ - ADDUARG(); - break; - default: /* "%?" prints ?, unless ? is NUL */ - if (ch == '\0') - goto done; - break; - } - } -done: - /* - * Build the argument table. - */ - if (tablemax >= STATIC_ARG_TBL_SIZE) { - *argtable = (union arg *) - malloc (sizeof (union arg) * (tablemax + 1)); - } - - (*argtable) [0].intarg = 0; - for (n = 1; n <= tablemax; n++) { - switch (typetable [n]) { - case T_UNUSED: /* whoops! */ - (*argtable) [n].intarg = va_arg (ap, int); - break; - case TP_SCHAR: - (*argtable) [n].pschararg = va_arg (ap, signed char *); - break; - case TP_SHORT: - (*argtable) [n].pshortarg = va_arg (ap, short *); - break; - case T_INT: - (*argtable) [n].intarg = va_arg (ap, int); - break; - case T_U_INT: - (*argtable) [n].uintarg = va_arg (ap, unsigned int); - break; - case TP_INT: - (*argtable) [n].pintarg = va_arg (ap, int *); - break; - case T_LONG: - (*argtable) [n].longarg = va_arg (ap, long); - break; - case T_U_LONG: - (*argtable) [n].ulongarg = va_arg (ap, unsigned long); - break; - case TP_LONG: - (*argtable) [n].plongarg = va_arg (ap, long *); - break; - case T_LLONG: - (*argtable) [n].longlongarg = va_arg (ap, long long); - break; - case T_U_LLONG: - (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); - break; - case TP_LLONG: - (*argtable) [n].plonglongarg = va_arg (ap, long long *); - break; - case T_PTRDIFFT: - (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); - break; - case TP_PTRDIFFT: - (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); - break; - case T_SIZET: - (*argtable) [n].sizearg = va_arg (ap, size_t); - break; - case TP_SIZET: - (*argtable) [n].psizearg = va_arg (ap, size_t *); - break; - case T_INTMAXT: - (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); - break; - case T_UINTMAXT: - (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); - break; - case TP_INTMAXT: - (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); - break; -#ifndef NO_FLOATING_POINT - case T_DOUBLE: - (*argtable) [n].doublearg = va_arg (ap, double); - break; - case T_LONG_DOUBLE: - (*argtable) [n].longdoublearg = va_arg (ap, long double); - break; -#endif -#ifdef VECTORS - case T_VECTOR: - (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE); - break; -#endif /* VECTORS */ - case TP_CHAR: - (*argtable) [n].pchararg = va_arg (ap, char *); - break; - case TP_VOID: - (*argtable) [n].pvoidarg = va_arg (ap, void *); - break; - case T_WINT: - (*argtable) [n].wintarg = va_arg (ap, wint_t); - break; - case TP_WCHAR: - (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); - break; - } - } - - if ((typetable != NULL) && (typetable != stattypetable)) - free (typetable); -} - -/* - * Increase the size of the type table. - */ -static void -__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) -{ - enum typeid *const oldtable = *typetable; - const int oldsize = *tablesize; - enum typeid *newtable; - int n, newsize = oldsize * 2; - - if (newsize < nextarg + 1) - newsize = nextarg + 1; - if (oldsize == STATIC_ARG_TBL_SIZE) { - if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL) - LIBC_ABORT("malloc: %s", strerror(errno)); /* XXX handle better */ - bcopy(oldtable, newtable, oldsize * sizeof(enum typeid)); - } else { - newtable = reallocf(oldtable, newsize * sizeof(enum typeid)); - if (newtable == NULL) - LIBC_ABORT("reallocf: %s", strerror(errno)); /* XXX handle better */ - } - for (n = oldsize; n < newsize; n++) - newtable[n] = T_UNUSED; - - *typetable = newtable; - *tablesize = newsize; -} - - -#ifndef NO_FLOATING_POINT - -static int -exponent(wchar_t *p0, int exp, wchar_t fmtch) -{ - wchar_t *p, *t; - wchar_t expbuf[MAXEXPDIG]; - - p = p0; - *p++ = fmtch; - if (exp < 0) { - exp = -exp; - *p++ = '-'; - } - else - *p++ = '+'; - t = expbuf + MAXEXPDIG; - if (exp > 9) { - do { - *--t = to_char(exp % 10); - } while ((exp /= 10) > 9); - *--t = to_char(exp); - for (; t < expbuf + MAXEXPDIG; *p++ = *t++); - } - else { - /* - * Exponents for decimal floating point conversions - * (%[eEgG]) must be at least two characters long, - * whereas exponents for hexadecimal conversions can - * be only one character long. - */ - if (fmtch == 'e' || fmtch == 'E') - *p++ = '0'; - *p++ = to_char(exp); - } - return (p - p0); -} -#endif /* !NO_FLOATING_POINT */ diff --git a/stdio/vfwscanf-fbsd.c b/stdio/vfwscanf-fbsd.c index 603d28f..bba07f2 100644 --- a/stdio/vfwscanf-fbsd.c +++ b/stdio/vfwscanf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,13 +36,14 @@ static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #endif #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.12 2004/05/02 20:13:29 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.17 2009/01/19 06:19:51 das Exp $"); #include "xlocale_private.h" #include "namespace.h" #include #include +#include #include #include #include @@ -102,14 +99,14 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.12 2004/05/02 20:13:29 obr #ifndef NO_FLOATING_POINT static int parsefloat(FILE *, wchar_t **, size_t, locale_t loc); -#endif /* !NO_FLOATING_POINT */ - -extern int __scanfdebug; +#endif #define INCCL(_c) \ (cclcompl ? (wmemchr(ccls, (_c), ccle - ccls) == NULL) : \ (wmemchr(ccls, (_c), ccle - ccls) != NULL)) +static const mbstate_t initial_mbs; + /* * MT-safe version. */ @@ -165,7 +162,6 @@ __vfwscanf(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt, char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */ int index; /* for %index$ */ va_list ap_orig; /* to reset ap to first argument */ - static const mbstate_t initial; mbstate_t mbs; int mb_cur_max = MB_CUR_MAX_L(loc); @@ -349,26 +345,28 @@ literal: break; case 'n': - if (flags & SUPPRESS) /* ??? */ + { + void *ptr = va_arg(ap, void *); + if ((ptr == NULL) || (flags & SUPPRESS)) /* ??? */ continue; - if (flags & SHORTSHORT) - *va_arg(ap, char *) = nread; + else if (flags & SHORTSHORT) + *(char *)ptr = nread; else if (flags & SHORT) - *va_arg(ap, short *) = nread; + *(short *)ptr = nread; else if (flags & LONG) - *va_arg(ap, long *) = nread; + *(long *)ptr = nread; else if (flags & LONGLONG) - *va_arg(ap, long long *) = nread; + *(long long *)ptr = nread; else if (flags & INTMAXT) - *va_arg(ap, intmax_t *) = nread; + *(intmax_t *)ptr = nread; else if (flags & SIZET) - *va_arg(ap, size_t *) = nread; + *(size_t *)ptr = nread; else if (flags & PTRDIFFT) - *va_arg(ap, ptrdiff_t *) = nread; + *(ptrdiff_t *)ptr = nread; else - *va_arg(ap, int *) = nread; + *(int *)ptr = nread; continue; - + } default: goto match_failure; @@ -419,7 +417,7 @@ literal: if (!(flags & SUPPRESS)) mbp = va_arg(ap, char *); n = 0; - mbs = initial; + mbs = initial_mbs; while (width != 0 && (wi = __fgetwc(fp, loc)) != WEOF) { if (width >= mb_cur_max && @@ -483,7 +481,7 @@ literal: if (!(flags & SUPPRESS)) mbp = va_arg(ap, char *); n = 0; - mbs = initial; + mbs = initial_mbs; while ((wi = __fgetwc(fp, loc)) != WEOF && width != 0 && INCCL(wi)) { if (width >= mb_cur_max && @@ -545,7 +543,7 @@ literal: } else { if (!(flags & SUPPRESS)) mbp = va_arg(ap, char *); - mbs = initial; + mbs = initial_mbs; while ((wi = __fgetwc(fp, loc)) != WEOF && width != 0 && !iswspace_l(wi, loc)) { @@ -744,8 +742,6 @@ literal: float res = wcstof_l(pbuf, &p, loc); *va_arg(ap, float *) = res; } - if (__scanfdebug && p - pbuf != width) - LIBC_ABORT("p - pbuf %ld != width %ld", (long)(p - pbuf), width); nassigned++; } nread += width; @@ -766,20 +762,27 @@ extern char *__parsefloat_buf(size_t s); /* see vfscanf-fbsd.c */ static int parsefloat(FILE *fp, wchar_t **buf, size_t width, locale_t loc) { + mbstate_t mbs; + size_t nconv; wchar_t *commit, *p; int infnanpos = 0; enum { - S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX, + S_START, S_GOTSIGN, S_INF, S_NAN, S_DONE, S_MAYBEHEX, S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS } state = S_START; wchar_t c; - char *decimal_point; wchar_t decpt; _Bool gotmantdig = 0, ishex = 0; wchar_t *b; wchar_t *e; size_t s; + mbs = initial_mbs; + + nconv = mbrtowc_l(&decpt, localeconv()->decimal_point, MB_CUR_MAX_L(loc), &mbs, loc); + if (nconv == (size_t)-1 || nconv == (size_t)-2) + decpt = '.'; /* failsafe */ + s = (width == 0 ? BUF : (width + 1)); if ((b = (wchar_t *)__parsefloat_buf(s * sizeof(wchar_t))) == NULL) { *buf = NULL; @@ -797,8 +800,6 @@ parsefloat(FILE *fp, wchar_t **buf, size_t width, locale_t loc) */ commit = b - 1; c = WEOF; - decimal_point = localeconv_l(loc)->decimal_point; - mbtowc_l(&decpt, decimal_point, strlen(decimal_point), loc); for (p = b; width == 0 || p < e; ) { if ((c = __fgetwc(fp, loc)) == WEOF) break; @@ -840,8 +841,6 @@ reswitch: break; case S_NAN: switch (infnanpos) { - case -1: /* XXX kludge to deal with nan(...) */ - goto parsedone; case 0: if (c != 'A' && c != 'a') goto parsedone; @@ -859,13 +858,15 @@ reswitch: default: if (c == ')') { commit = p; - infnanpos = -2; + state = S_DONE; } else if (!iswalnum_l(c, loc) && c != '_') goto parsedone; break; } infnanpos++; break; + case S_DONE: + goto parsedone; case S_MAYBEHEX: state = S_DIGITS; if (c == 'X' || c == 'x') { diff --git a/stdio/vprintf-fbsd.c b/stdio/vprintf-fbsd.c index 329816c..894cd79 100644 --- a/stdio/vprintf-fbsd.c +++ b/stdio/vprintf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vprintf.c,v 1.10 2002/09/06 11:23:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vprintf.c,v 1.11 2007/01/09 00:28:08 imp Exp $"); #include "xlocale_private.h" diff --git a/stdio/vscanf-fbsd.c b/stdio/vscanf-fbsd.c index f17456b..397382e 100644 --- a/stdio/vscanf-fbsd.c +++ b/stdio/vscanf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vscanf.c,v 1.12 2003/01/03 23:27:27 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vscanf.c,v 1.13 2007/01/09 00:28:08 imp Exp $"); #include "xlocale_private.h" diff --git a/stdio/vsnprintf-fbsd.c b/stdio/vsnprintf-fbsd.c index 1a24ce3..5f9a295 100644 --- a/stdio/vsnprintf-fbsd.c +++ b/stdio/vsnprintf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vsnprintf.c,v 1.22 2003/07/02 07:08:44 jkh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vsnprintf.c,v 1.24 2008/04/17 22:17:54 jhb Exp $"); #include "xlocale_private.h" @@ -47,7 +43,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vsnprintf.c,v 1.22 2003/07/02 07:08:44 jk #include "local.h" int -vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, +vsnprintf_l(char * __restrict str, size_t n, locale_t loc, const char * __restrict fmt, __va_list ap) { size_t on; @@ -55,40 +51,8 @@ vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, char dummy[2]; FILE f; struct __sFILEX ext; - - on = n; - if (n != 0) - n--; - if (n > INT_MAX) - n = INT_MAX; - /* Stdio internals do not deal correctly with zero length buffer */ - if (n == 0) { - if (on > 0) - *str = '\0'; - str = dummy; - n = 1; - } - f._file = -1; - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = n; f._extra = &ext; INITEXTRA(&f); - ret = __vfprintf(&f, __current_locale(), fmt, ap); - if (on > 0) - *f._p = '\0'; - return (ret); -} - -int -vsnprintf_l(char * __restrict str, size_t n, locale_t loc, - const char * __restrict fmt, __va_list ap) -{ - size_t on; - int ret; - char dummy[2]; - FILE f; - struct __sFILEX ext; NORMALIZE_LOCALE(loc); on = n; @@ -107,10 +71,17 @@ vsnprintf_l(char * __restrict str, size_t n, locale_t loc, f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); ret = __vfprintf(&f, loc, fmt, ap); if (on > 0) *f._p = '\0'; return (ret); } + +int +vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, + __va_list ap) +{ + return vsnprintf_l(str, n, __current_locale(), fmt, ap); +} diff --git a/stdio/vsprintf-fbsd.c b/stdio/vsprintf-fbsd.c index 24b7903..9b85352 100644 --- a/stdio/vsprintf-fbsd.c +++ b/stdio/vsprintf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vsprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vsprintf.c,v 1.14 2002/09/06 11:23:56 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vsprintf.c,v 1.16 2008/04/17 22:17:54 jhb Exp $"); #include "xlocale_private.h" @@ -47,39 +43,28 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vsprintf.c,v 1.14 2002/09/06 11:23:56 tjr #include "local.h" int -vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap) +vsprintf_l(char * __restrict str, locale_t loc, const char * __restrict fmt, __va_list ap) { int ret; FILE f; struct __sFILEX ext; - - f._file = -1; - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = INT_MAX; f._extra = &ext; INITEXTRA(&f); - ret = __vfprintf(&f, __current_locale(), fmt, ap); - *f._p = 0; - return (ret); -} - -int -vsprintf_l(char * __restrict str, locale_t loc, const char * __restrict fmt, - __va_list ap) -{ - int ret; - FILE f; - struct __sFILEX ext; NORMALIZE_LOCALE(loc); f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); ret = __vfprintf(&f, loc, fmt, ap); *f._p = 0; return (ret); } + +int +vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap) +{ + return vsprintf_l(str, __current_locale(), fmt, ap); +} diff --git a/stdio/vsscanf-fbsd.c b/stdio/vsscanf-fbsd.c index 0ed3562..7144259 100644 --- a/stdio/vsscanf-fbsd.c +++ b/stdio/vsscanf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/vsscanf.c,v 1.12 2002/10/12 16:13:41 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vsscanf.c,v 1.14 2008/04/17 22:17:54 jhb Exp $"); #include "xlocale_private.h" @@ -61,13 +57,16 @@ eofread(cookie, buf, len) } int -vsscanf(str, fmt, ap) +vsscanf_l(str, loc, fmt, ap) const char * __restrict str; + locale_t loc; const char * __restrict fmt; __va_list ap; { FILE f; struct __sFILEX ext; + f._extra = &ext; + INITEXTRA(&f); f._file = -1; f._flags = __SRD; @@ -76,30 +75,17 @@ vsscanf(str, fmt, ap) f._read = eofread; f._ub._base = NULL; f._lb._base = NULL; - f._extra = &ext; - INITEXTRA(&f); - return (__svfscanf_l(&f, __current_locale(), fmt, ap)); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); + return (__svfscanf_l(&f, loc, fmt, ap)); } int -vsscanf_l(str, loc, fmt, ap) +vsscanf(str, fmt, ap) const char * __restrict str; - locale_t loc; const char * __restrict fmt; __va_list ap; { - FILE f; - struct __sFILEX ext; - - NORMALIZE_LOCALE(loc); - f._file = -1; - f._flags = __SRD; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._r = strlen(str); - f._read = eofread; - f._ub._base = NULL; - f._lb._base = NULL; - f._extra = &ext; - INITEXTRA(&f); - return (__svfscanf_l(&f, loc, fmt, ap)); + return vsscanf_l(str, __current_locale(), fmt, ap); } + diff --git a/stdio/vswprintf-fbsd.c b/stdio/vswprintf-fbsd.c index c955981..4227e74 100644 --- a/stdio/vswprintf-fbsd.c +++ b/stdio/vswprintf-fbsd.c @@ -31,7 +31,7 @@ #if 0 __FBSDID("FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.16 2002/08/21 16:19:57 mike Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/stdio/vswprintf.c,v 1.5 2004/04/07 09:55:05 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vswprintf.c,v 1.7 2008/04/17 22:17:54 jhb Exp $"); #include "xlocale_private.h" @@ -42,18 +42,20 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vswprintf.c,v 1.5 2004/04/07 09:55:05 tjr #include "local.h" int -vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, - __va_list ap) +vswprintf_l(wchar_t * __restrict s, size_t n, locale_t loc, + const wchar_t * __restrict fmt, __va_list ap) { static const mbstate_t initial; mbstate_t mbs; FILE f; - struct __sFILEX ext; char *mbp; int ret, sverrno; - size_t conv; - locale_t loc = __current_locale(); + size_t nwc; + struct __sFILEX ext; + f._extra = &ext; + INITEXTRA(&f); + NORMALIZE_LOCALE(loc); if (n == 0) { errno = EINVAL; return (-1); @@ -67,8 +69,8 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, return (-1); } f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); ret = __vfwprintf(&f, loc, fmt, ap); if (ret < 0) { sverrno = errno; @@ -77,19 +79,19 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, return (-1); } *f._p = '\0'; - mbp = (char *)f._bf._base; + mbp = f._bf._base; /* * XXX Undo the conversion from wide characters to multibyte that * fputwc() did in __vfwprintf(). */ mbs = initial; - if ((conv = mbsrtowcs_l(s, (const char **)&mbp, n, &mbs, loc)) == (size_t)-1) { - free(f._bf._base); + nwc = mbsrtowcs_l(s, (const char **)&mbp, n, &mbs, loc); + free(f._bf._base); + if (nwc == (size_t)-1) { errno = EILSEQ; return (-1); } - free(f._bf._base); - if (conv >= n) { + if (nwc == n) { s[n - 1] = L'\0'; errno = EOVERFLOW; return (-1); @@ -99,58 +101,8 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, } int -vswprintf_l(wchar_t * __restrict s, size_t n, locale_t loc, +vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, __va_list ap) { - static const mbstate_t initial; - mbstate_t mbs; - FILE f; - struct __sFILEX ext; - char *mbp; - int ret, sverrno; - size_t conv; - - NORMALIZE_LOCALE(loc); - if (n == 0) { - errno = EINVAL; - return (-1); - } - - f._file = -1; - f._flags = __SWR | __SSTR | __SALC; - f._bf._base = f._p = (unsigned char *)malloc(128); - if (f._bf._base == NULL) { - errno = ENOMEM; - return (-1); - } - f._bf._size = f._w = 127; /* Leave room for the NUL */ - f._extra = &ext; - INITEXTRA(&f); - ret = __vfwprintf(&f, loc, fmt, ap); - if (ret < 0) { - sverrno = errno; - free(f._bf._base); - errno = sverrno; - return (-1); - } - *f._p = '\0'; - mbp = (char *)f._bf._base; - /* - * XXX Undo the conversion from wide characters to multibyte that - * fputwc() did in __vfwprintf(). - */ - mbs = initial; - if ((conv = mbsrtowcs_l(s, (const char **)&mbp, n, &mbs, loc)) == (size_t)-1) { - free(f._bf._base); - errno = EILSEQ; - return (-1); - } - free(f._bf._base); - if (conv >= n) { - s[n - 1] = L'\0'; - errno = EOVERFLOW; - return (-1); - } - - return (ret); + return vswprintf_l(s, n, __current_locale(), fmt, ap); } diff --git a/stdio/vswscanf-fbsd.c b/stdio/vswscanf-fbsd.c index bad7e18..d688164 100644 --- a/stdio/vswscanf-fbsd.c +++ b/stdio/vswscanf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -41,7 +37,7 @@ static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdio/vsscanf.c,v 1.11 2002/08/21 16:19:57 mike Exp "); #endif -__FBSDID("$FreeBSD: src/lib/libc/stdio/vswscanf.c,v 1.3 2004/04/07 09:55:05 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/vswscanf.c,v 1.6 2009/01/15 18:53:52 rdivacky Exp $"); #include "xlocale_private.h" @@ -63,18 +59,21 @@ eofread(void *cookie, char *buf, int len) } int -vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, +vswscanf_l(const wchar_t * __restrict str, locale_t loc, const wchar_t * __restrict fmt, va_list ap) { static const mbstate_t initial; mbstate_t mbs; FILE f; - struct __sFILEX ext; char *mbstr; size_t mlen; int r; - locale_t loc = __current_locale(); + const wchar_t *strp; + struct __sFILEX ext; + f._extra = &ext; + INITEXTRA(&f); + NORMALIZE_LOCALE(loc); /* * XXX Convert the wide character string to multibyte, which * __vfwscanf() will convert back to wide characters. @@ -82,7 +81,8 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, if ((mbstr = malloc(wcslen(str) * MB_CUR_MAX_L(loc) + 1)) == NULL) return (EOF); mbs = initial; - if ((mlen = wcsrtombs_l(mbstr, &str, SIZE_T_MAX, &mbs, loc)) == (size_t)-1) { + strp = str; + if ((mlen = wcsrtombs_l(mbstr, &strp, SIZE_T_MAX, &mbs, loc)) == (size_t)-1) { free(mbstr); return (EOF); } @@ -93,8 +93,8 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, f._read = eofread; f._ub._base = NULL; f._lb._base = NULL; - f._extra = &ext; - INITEXTRA(&f); + f._orientation = 0; + memset(&f._mbstate, 0, sizeof(mbstate_t)); r = __vfwscanf(&f, loc, fmt, ap); free(mbstr); @@ -102,40 +102,9 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, } int -vswscanf_l(const wchar_t * __restrict str, locale_t loc, - const wchar_t * __restrict fmt, va_list ap) +vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, + va_list ap) { - static const mbstate_t initial; - mbstate_t mbs; - FILE f; - struct __sFILEX ext; - char *mbstr; - size_t mlen; - int r; - - NORMALIZE_LOCALE(loc); - /* - * XXX Convert the wide character string to multibyte, which - * __vfwscanf() will convert back to wide characters. - */ - if ((mbstr = malloc(wcslen(str) * MB_CUR_MAX_L(loc) + 1)) == NULL) - return (EOF); - mbs = initial; - if ((mlen = wcsrtombs_l(mbstr, &str, SIZE_T_MAX, &mbs, loc)) == (size_t)-1) { - free(mbstr); - return (EOF); - } - f._file = -1; - f._flags = __SRD; - f._bf._base = f._p = (unsigned char *)mbstr; - f._bf._size = f._r = mlen; - f._read = eofread; - f._ub._base = NULL; - f._lb._base = NULL; - f._extra = &ext; - INITEXTRA(&f); - r = __vfwscanf(&f, loc, fmt, ap); - free(mbstr); - - return (r); + return vswscanf_l(str, __current_locale(), fmt, ap); } + diff --git a/stdio/wbuf-fbsd.c b/stdio/wbuf-fbsd.c index 6d30d58..9e9b59e 100644 --- a/stdio/wbuf-fbsd.c +++ b/stdio/wbuf-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)wbuf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/wbuf.c,v 1.11 2004/06/08 05:45:32 das Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/wbuf.c,v 1.12 2007/01/09 00:28:08 imp Exp $"); #include #include diff --git a/stdio/wprintf.3 b/stdio/wprintf.3 index 917ce76..d1c3498 100644 --- a/stdio/wprintf.3 +++ b/stdio/wprintf.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/stdio/printf.3,v 1.47 2002/09/06 11:23:55 tjr Exp -.\" $FreeBSD: src/lib/libc/stdio/wprintf.3,v 1.5 2003/07/05 07:55:34 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/wprintf.3,v 1.6 2007/01/09 00:28:08 imp Exp $ .\" .Dd July 5, 2003 .Dt WPRINTF 3 diff --git a/stdio/wscanf.3 b/stdio/wscanf.3 index e07bc7a..54fa5d6 100644 --- a/stdio/wscanf.3 +++ b/stdio/wscanf.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)scanf.3 8.2 (Berkeley) 12/11/93 .\" FreeBSD: src/lib/libc/stdio/scanf.3,v 1.24 2003/06/28 09:03:25 das Exp -.\" $FreeBSD: src/lib/libc/stdio/wscanf.3,v 1.6 2003/07/05 07:47:55 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdio/wscanf.3,v 1.7 2007/01/09 00:28:08 imp Exp $ .\" .Dd July 5, 2003 .Dt WSCANF 3 diff --git a/stdlib/FreeBSD/abort.3 b/stdlib/FreeBSD/abort.3 index 07ca798..c283b31 100644 --- a/stdlib/FreeBSD/abort.3 +++ b/stdlib/FreeBSD/abort.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)abort.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/abort.3,v 1.9 2001/09/09 18:52:00 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/abort.3,v 1.10 2007/01/09 00:28:09 imp Exp $ .\" .Dd June 4, 1993 .Dt ABORT 3 diff --git a/stdlib/FreeBSD/abort.3.patch b/stdlib/FreeBSD/abort.3.patch new file mode 100644 index 0000000..af99681 --- /dev/null +++ b/stdlib/FreeBSD/abort.3.patch @@ -0,0 +1,16 @@ +--- abort.3.orig 2010-02-22 12:52:54.000000000 -0800 ++++ abort.3 2010-02-22 12:56:29.000000000 -0800 +@@ -58,6 +58,13 @@ The + .Fn abort + function is thread-safe. + It is unknown if it is async-cancel-safe. ++.Pp ++The ++.Fn abort ++function causes a report to be generated by Crash Reporter. If you wish to ++terminate without generating a crash report, use ++.Xr exit 3 ++instead. + .Sh RETURN VALUES + The + .Fn abort diff --git a/stdlib/FreeBSD/abort.c b/stdlib/FreeBSD/abort.c index 18d0c73..50e34b0 100644 --- a/stdlib/FreeBSD/abort.c +++ b/stdlib/FreeBSD/abort.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)abort.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/abort.c,v 1.9 2003/08/16 11:43:57 davidxu Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/abort.c,v 1.11 2007/01/09 00:28:09 imp Exp $"); #include "namespace.h" #include @@ -45,7 +41,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/abort.c,v 1.9 2003/08/16 11:43:57 davidx #include #include "un-namespace.h" -void (*__cleanup)(); +#include "libc_private.h" void abort() diff --git a/stdlib/FreeBSD/abort.c.patch b/stdlib/FreeBSD/abort.c.patch index 317179a..bb72417 100644 --- a/stdlib/FreeBSD/abort.c.patch +++ b/stdlib/FreeBSD/abort.c.patch @@ -1,6 +1,6 @@ ---- abort.c.orig 2008-09-07 11:37:51.000000000 -0700 -+++ abort.c 2008-09-07 11:56:01.000000000 -0700 -@@ -39,19 +39,26 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ +--- abort.c.orig 2010-09-07 22:42:56.000000000 -0700 ++++ abort.c 2010-09-07 22:46:29.000000000 -0700 +@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ #include "namespace.h" #include @@ -8,30 +8,54 @@ #include #include #include - #include - #include "un-namespace.h" +@@ -43,11 +44,22 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ --void (*__cleanup)(); + #include "libc_private.h" + ++#include "CrashReporterClient.h" ++#include "_simple.h" ++ +extern void (*__cleanup)(); +extern void __abort(void) __dead2; -+extern const char *__crashreporter_info__; + +#define TIMEOUT 10000 /* 10 milliseconds */ - ++ void abort() { struct sigaction act; -+ if (!__crashreporter_info__) -+ __crashreporter_info__ = "abort() called"; ++ if (!CRGetCrashLogMessage()) ++ CRSetCrashLogMessage("abort() called"); ++ /* * POSIX requires we flush stdio buffers on abort. * XXX ISO C requires that abort() be async-signal-safe. -@@ -67,11 +74,22 @@ abort() +@@ -61,19 +73,90 @@ abort() + * any errors -- ISO C doesn't allow abort to return anyway. + */ sigdelset(&act.sa_mask, SIGABRT); - (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); - (void)raise(SIGABRT); +- (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); +- (void)raise(SIGABRT); ++ ++ /* abort() should call pthread_kill to deliver a signal to the aborting thread ++ * This helps gdb focus on the thread calling abort() ++ */ ++ if (__is_threaded) { ++ /* Block all signals on all other threads */ ++ sigset_t fullmask; ++ sigfillset(&fullmask); ++ (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL); ++ ++ /* Set the workqueue killable */ ++ __pthread_workqueue_setkill(1); ++ ++ (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL); ++ (void)pthread_kill(pthread_self(), SIGABRT); ++ } else { ++ (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); ++ (void)kill(getpid(), SIGABRT); ++ } + usleep(TIMEOUT); /* give time for signal to happen */ /* @@ -46,29 +70,59 @@ +{ + struct sigaction act; + -+ if (!__crashreporter_info__) -+ __crashreporter_info__ = "__abort() called"; ++ if (!CRGetCrashLogMessage()) ++ CRSetCrashLogMessage("__abort() called"); act.sa_handler = SIG_DFL; act.sa_flags = 0; sigfillset(&act.sa_mask); -@@ -79,5 +97,19 @@ abort() + (void)_sigaction(SIGABRT, &act, NULL); sigdelset(&act.sa_mask, SIGABRT); ++ ++ /* abort() should call pthread_kill to deliver a signal to the aborting thread ++ * This helps gdb focus on the thread calling abort() ++ */ ++ if (__is_threaded) { ++ /* Block all signals on all other threads */ ++ sigset_t fullmask; ++ sigfillset(&fullmask); ++ (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL); ++ ++ /* Set the workqueue killable */ ++ __pthread_workqueue_setkill(1); ++ ++ (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL); ++ (void)pthread_kill(pthread_self(), SIGABRT); ++ } else { ++ (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); ++ (void)kill(getpid(), SIGABRT); ++ } ++ usleep(TIMEOUT); /* give time for signal to happen */ ++ ++ /* If for some reason SIGABRT was not delivered, we exit using __builtin_trap ++ * which generates an illegal instruction on i386: ++ * and SIGTRAP on arm. ++ */ ++ sigfillset(&act.sa_mask); ++ sigdelset(&act.sa_mask, SIGILL); ++ sigdelset(&act.sa_mask, SIGTRAP); (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); - (void)raise(SIGABRT); +- (void)raise(SIGABRT); - exit(1); -+ usleep(TIMEOUT); /* give time for signal to happen */ -+ __builtin_trap(); /* never exit normally */ ++ __builtin_trap(); +} + +__private_extern__ void +abort_report_np(const char *fmt, ...) +{ -+ char *str; ++ _SIMPLE_STRING s; + va_list ap; + -+ va_start(ap, fmt); -+ vasprintf(&str, fmt, ap); -+ va_end(ap); -+ __crashreporter_info__ = str ? str : fmt; ++ if ((s = _simple_salloc()) != NULL) { ++ va_start(ap, fmt); ++ _simple_vsprintf(s, fmt, ap); ++ va_end(ap); ++ CRSetCrashLogMessage(_simple_string(s)); ++ } else ++ CRSetCrashLogMessage(fmt); /* the format string is better than nothing */ + abort(); } diff --git a/stdlib/FreeBSD/abs.3 b/stdlib/FreeBSD/abs.3 index f2556e8..d53f7c1 100644 --- a/stdlib/FreeBSD/abs.3 +++ b/stdlib/FreeBSD/abs.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)abs.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/abs.3,v 1.12 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/abs.3,v 1.13 2007/01/09 00:28:09 imp Exp $ .\" .Dd November 14, 2001 .Dt ABS 3 diff --git a/stdlib/FreeBSD/abs.3.patch b/stdlib/FreeBSD/abs.3.patch index 9e9ce75..6ea6642 100644 --- a/stdlib/FreeBSD/abs.3.patch +++ b/stdlib/FreeBSD/abs.3.patch @@ -1,6 +1,6 @@ ---- abs.3 2003-05-20 15:23:24.000000000 -0700 -+++ abs.3.edit 2006-09-27 18:20:25.000000000 -0700 -@@ -47,14 +47,12 @@ +--- abs.3.bsdnew 2009-11-13 14:11:46.000000000 -0800 ++++ abs.3 2009-11-13 14:11:46.000000000 -0800 +@@ -43,14 +43,12 @@ .Sh SYNOPSIS .In stdlib.h .Ft int diff --git a/stdlib/FreeBSD/abs.c b/stdlib/FreeBSD/abs.c index 26f87eb..85cc8f0 100644 --- a/stdlib/FreeBSD/abs.c +++ b/stdlib/FreeBSD/abs.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)abs.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/abs.c,v 1.2 2002/03/22 21:53:09 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/abs.c,v 1.3 2007/01/09 00:28:09 imp Exp $"); #include diff --git a/stdlib/FreeBSD/alloca.3 b/stdlib/FreeBSD/alloca.3 index c5be9ff..9866edf 100644 --- a/stdlib/FreeBSD/alloca.3 +++ b/stdlib/FreeBSD/alloca.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)alloca.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/alloca.3,v 1.11 2003/06/28 22:12:30 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/alloca.3,v 1.13 2007/01/09 00:28:09 imp Exp $ .\" -.Dd June 4, 1993 +.Dd September 5, 2006 .Dt ALLOCA 3 .Os .Sh NAME @@ -57,9 +53,6 @@ return. The .Fn alloca function returns a pointer to the beginning of the allocated space. -If the allocation failed, a -.Dv NULL -pointer is returned. .Sh SEE ALSO .Xr brk 2 , .Xr calloc 3 , @@ -81,3 +74,15 @@ The function is machine and compiler dependent; its use is discouraged. +.Pp +The +.Fn alloca +function is slightly unsafe because it cannot ensure that the pointer +returned points to a valid and usable block of memory. +The allocation made may exceed the bounds of the stack, or even go +further into other objects in memory, and +.Fn alloca +cannot determine such an error. +Avoid +.Fn alloca +with large unbounded allocations. diff --git a/stdlib/FreeBSD/alloca.3.patch b/stdlib/FreeBSD/alloca.3.patch index f3ccd8a..bf397fb 100644 --- a/stdlib/FreeBSD/alloca.3.patch +++ b/stdlib/FreeBSD/alloca.3.patch @@ -1,8 +1,11 @@ ---- /Volumes/XDisk/tmp/Libc/stdlib/FreeBSD/alloca.3.orig 2003-06-28 15:12:30.000000000 -0700 -+++ /Volumes/XDisk/tmp/Libc/stdlib/FreeBSD/alloca.3 2004-10-24 17:08:31.000000000 -0700 -@@ -41,6 +41,9 @@ - .Sh LIBRARY - .Lb libc +--- alloca.3.orig 2010-02-22 12:44:05.000000000 -0800 ++++ alloca.3 2010-02-22 12:50:53.000000000 -0800 +@@ -34,25 +34,25 @@ + .Sh NAME + .Nm alloca + .Nd memory allocator +-.Sh LIBRARY +-.Lb libc .Sh SYNOPSIS +.In alloca.h +or @@ -10,3 +13,57 @@ .In stdlib.h .Ft void * .Fn alloca "size_t size" + .Sh DESCRIPTION + The + .Fn alloca +-function ++macro + allocates + .Fa size + bytes of space in the stack frame of the caller. + This temporary space is automatically freed on + return. + .Sh RETURN VALUES +-The + .Fn alloca +-function returns a pointer to the beginning of the allocated space. ++returns a pointer to the beginning of the allocated space. + .Sh SEE ALSO + .Xr brk 2 , + .Xr calloc 3 , +@@ -60,24 +60,20 @@ function returns a pointer to the beginn + .Xr malloc 3 , + .Xr realloc 3 + .Sh HISTORY +-The + .Fn alloca +-function appeared in ++appeared in + .At 32v . + .\" .Bx ?? . + .\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd + .\" The first man page (or link to a man page that I can find at the + .\" moment is 4.3... + .Sh BUGS +-The + .Fn alloca +-function + is machine and compiler dependent; + its use is discouraged. + .Pp +-The + .Fn alloca +-function is slightly unsafe because it cannot ensure that the pointer ++is slightly unsafe because it cannot ensure that the pointer + returned points to a valid and usable block of memory. + The allocation made may exceed the bounds of the stack, or even go + further into other objects in memory, and +@@ -86,3 +82,8 @@ cannot determine such an error. + Avoid + .Fn alloca + with large unbounded allocations. ++.Pp ++The use of C99 variable-length arrays and ++.Fn alloca ++in the same function will cause the lifetime of alloca's storage to be limited to the block containing the ++.Fn alloca diff --git a/stdlib/FreeBSD/atexit.3 b/stdlib/FreeBSD/atexit.3 index 72a9977..bf40c80 100644 --- a/stdlib/FreeBSD/atexit.3 +++ b/stdlib/FreeBSD/atexit.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)atexit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atexit.3,v 1.10 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/atexit.3,v 1.11 2007/01/09 00:28:09 imp Exp $ .\" .Dd September 6, 2002 .Dt ATEXIT 3 diff --git a/stdlib/FreeBSD/atexit.3.patch b/stdlib/FreeBSD/atexit.3.patch index 8348ffa..5d23a79 100644 --- a/stdlib/FreeBSD/atexit.3.patch +++ b/stdlib/FreeBSD/atexit.3.patch @@ -1,8 +1,8 @@ ---- atexit.3.orig 2009-05-12 11:21:33.000000000 -0700 -+++ atexit.3 2009-05-20 14:13:00.000000000 -0700 -@@ -36,46 +36,69 @@ +--- atexit.3.bsdnew 2009-11-13 14:11:47.000000000 -0800 ++++ atexit.3 2009-11-13 14:11:47.000000000 -0800 +@@ -32,46 +32,69 @@ .\" @(#)atexit.3 8.1 (Berkeley) 6/4/93 - .\" $FreeBSD: src/lib/libc/stdlib/atexit.3,v 1.10 2002/12/18 13:33:03 ru Exp $ + .\" $FreeBSD: src/lib/libc/stdlib/atexit.3,v 1.11 2007/01/09 00:28:09 imp Exp $ .\" -.Dd September 6, 2002 +.Dd May 20, 2008 diff --git a/stdlib/FreeBSD/atexit.c b/stdlib/FreeBSD/atexit.c index bd94bcd..05dad84 100644 --- a/stdlib/FreeBSD/atexit.c +++ b/stdlib/FreeBSD/atexit.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)atexit.c 8.2 (Berkeley) 7/3/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/atexit.c,v 1.7 2003/12/19 17:11:20 kan Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atexit.c,v 1.8 2007/01/09 00:28:09 imp Exp $"); #include "namespace.h" #include diff --git a/stdlib/FreeBSD/atexit.c.patch b/stdlib/FreeBSD/atexit.c.patch index 8439c2a..a75ede0 100644 --- a/stdlib/FreeBSD/atexit.c.patch +++ b/stdlib/FreeBSD/atexit.c.patch @@ -1,10 +1,10 @@ ---- atexit.c.orig 2009-05-12 11:21:33.000000000 -0700 -+++ atexit.c 2009-05-23 13:46:33.000000000 -0700 -@@ -45,14 +45,23 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ +--- atexit.c.bsdnew 2009-11-13 14:11:47.000000000 -0800 ++++ atexit.c 2009-11-13 14:11:47.000000000 -0800 +@@ -41,14 +41,23 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ #include #include #include -+#if defined(__DYNAMIC__) ++#if defined(__DYNAMIC__) || defined (__BLOCKS__) +#include +#endif /* defined(__DYNAMIC__) */ #include "atexit.h" @@ -24,7 +24,7 @@ static pthread_mutex_t atexit_mutex = PTHREAD_MUTEX_INITIALIZER; -@@ -67,6 +76,9 @@ struct atexit { +@@ -63,6 +72,9 @@ struct atexit { union { void (*std_func)(void); void (*cxa_func)(void *); @@ -34,7 +34,7 @@ } fn_ptr; /* function pointer */ void *fn_arg; /* argument for CXA callback */ void *fn_dso; /* shared module handle */ -@@ -74,6 +86,7 @@ struct atexit { +@@ -70,6 +82,7 @@ struct atexit { }; static struct atexit *__atexit; /* points to head of LIFO stack */ @@ -42,7 +42,7 @@ /* * Register the function described by 'fptr' to be called at application -@@ -109,6 +122,7 @@ atexit_register(struct atexit_fn *fptr) +@@ -105,6 +118,7 @@ atexit_register(struct atexit_fn *fptr) __atexit = p; } p->fns[p->ind++] = *fptr; @@ -50,7 +50,7 @@ _MUTEX_UNLOCK(&atexit_mutex); return 0; } -@@ -120,17 +134,50 @@ int +@@ -116,17 +130,50 @@ int atexit(void (*func)(void)) { struct atexit_fn fn; @@ -102,7 +102,7 @@ /* * Register a function to be performed at exit or when an shared object * with given dso handle is unloaded dynamically. -@@ -156,13 +203,14 @@ __cxa_atexit(void (*func)(void *), void +@@ -152,13 +199,14 @@ __cxa_atexit(void (*func)(void *), void * handlers are called. */ void @@ -118,7 +118,7 @@ for (p = __atexit; p; p = p->next) { for (n = p->ind; --n >= 0;) { if (p->fns[n].fn_type == ATEXIT_FN_EMPTY) -@@ -175,6 +223,7 @@ __cxa_finalize(void *dso) +@@ -171,6 +219,7 @@ __cxa_finalize(void *dso) has already been called. */ p->fns[n].fn_type = ATEXIT_FN_EMPTY; @@ -126,7 +126,7 @@ _MUTEX_UNLOCK(&atexit_mutex); /* Call the function of correct type. */ -@@ -182,7 +231,13 @@ __cxa_finalize(void *dso) +@@ -178,7 +227,13 @@ __cxa_finalize(void *dso) fn.fn_ptr.cxa_func(fn.fn_arg); else if (fn.fn_type == ATEXIT_FN_STD) fn.fn_ptr.std_func(); diff --git a/stdlib/FreeBSD/atexit.h b/stdlib/FreeBSD/atexit.h index cd30b3f..94929b5 100644 --- a/stdlib/FreeBSD/atexit.h +++ b/stdlib/FreeBSD/atexit.h @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -31,7 +27,7 @@ * SUCH DAMAGE. * * @(#)atexit.h 8.2 (Berkeley) 7/3/94 - * $FreeBSD: src/lib/libc/stdlib/atexit.h,v 1.3 2003/12/19 17:11:20 kan Exp $ + * $FreeBSD: src/lib/libc/stdlib/atexit.h,v 1.4 2007/01/09 00:28:09 imp Exp $ */ /* must be at least 32 to guarantee ANSI conformance */ diff --git a/stdlib/FreeBSD/atexit.h.patch b/stdlib/FreeBSD/atexit.h.patch index 4310ee3..cea87c1 100644 --- a/stdlib/FreeBSD/atexit.h.patch +++ b/stdlib/FreeBSD/atexit.h.patch @@ -1,6 +1,6 @@ ---- atexit.h.orig 2004-03-11 13:16:53.000000000 -0800 -+++ atexit.h 2004-09-15 00:15:16.000000000 -0700 -@@ -37,4 +37,4 @@ +--- atexit.h.bsdnew 2009-11-13 14:11:47.000000000 -0800 ++++ atexit.h 2009-11-13 14:11:47.000000000 -0800 +@@ -33,4 +33,4 @@ /* must be at least 32 to guarantee ANSI conformance */ #define ATEXIT_SIZE 32 diff --git a/stdlib/FreeBSD/atof.3 b/stdlib/FreeBSD/atof.3 index 785f9d1..e417e27 100644 --- a/stdlib/FreeBSD/atof.3 +++ b/stdlib/FreeBSD/atof.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)atof.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atof.3,v 1.16 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/atof.3,v 1.17 2007/01/09 00:28:09 imp Exp $ .\" .Dd June 4, 1993 .Dt ATOF 3 diff --git a/stdlib/FreeBSD/atof.3.patch b/stdlib/FreeBSD/atof.3.patch index b87bd4b..ae7bddc 100644 --- a/stdlib/FreeBSD/atof.3.patch +++ b/stdlib/FreeBSD/atof.3.patch @@ -1,6 +1,6 @@ ---- atof.3.orig 2007-04-08 18:49:34.000000000 -0700 -+++ atof.3 2007-04-08 19:18:24.000000000 -0700 -@@ -40,7 +40,8 @@ +--- atof.3.orig 2010-02-08 16:26:10.000000000 -0800 ++++ atof.3 2010-02-13 20:58:26.000000000 -0800 +@@ -36,7 +36,8 @@ .Dt ATOF 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nd convert .Tn ASCII string to double -@@ -49,24 +50,35 @@ +@@ -45,33 +46,50 @@ string to double .Sh SYNOPSIS .In stdlib.h .Ft double @@ -49,7 +49,24 @@ .Sh IMPLEMENTATION NOTES The .Fn atof -@@ -88,7 +100,8 @@ +-function is not thread-safe and also not async-cancel-safe. ++and ++.Fn atof_l ++functions are thread-safe and async-cancel-safe. + .Pp + The + .Fn atof +-function has been deprecated by ++and ++.Fn atof_l ++functions have been deprecated by + .Fn strtod ++and ++.Fn strtod_l + and should not be used in new code. + .Sh ERRORS + The function +@@ -84,7 +102,8 @@ on an error. .Xr atol 3 , .Xr strtod 3 , .Xr strtol 3 , diff --git a/stdlib/FreeBSD/atof.c b/stdlib/FreeBSD/atof.c index ca69ab6..8ece097 100644 --- a/stdlib/FreeBSD/atof.c +++ b/stdlib/FreeBSD/atof.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)atof.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/atof.c,v 1.5 2004/02/10 20:42:32 cperciva Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atof.c,v 1.6 2007/01/09 00:28:09 imp Exp $"); #include diff --git a/stdlib/FreeBSD/atof.c.patch b/stdlib/FreeBSD/atof.c.patch index 1522473..35b0776 100644 --- a/stdlib/FreeBSD/atof.c.patch +++ b/stdlib/FreeBSD/atof.c.patch @@ -1,8 +1,8 @@ ---- atof.c.orig 2004-11-25 11:38:41.000000000 -0800 -+++ atof.c 2005-02-23 18:31:38.000000000 -0800 -@@ -37,11 +37,22 @@ +--- atof.c.bsdnew 2009-11-13 14:11:47.000000000 -0800 ++++ atof.c 2009-11-13 14:11:47.000000000 -0800 +@@ -33,11 +33,22 @@ static char sccsid[] = "@(#)atof.c 8.1 ( #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/atof.c,v 1.5 2004/02/10 20:42:32 cperciva Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/atof.c,v 1.6 2007/01/09 00:28:09 imp Exp $"); +#include "xlocale_private.h" + diff --git a/stdlib/FreeBSD/atoi.3 b/stdlib/FreeBSD/atoi.3 index 6f71dc1..a73998e 100644 --- a/stdlib/FreeBSD/atoi.3 +++ b/stdlib/FreeBSD/atoi.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)atoi.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atoi.3,v 1.12 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/atoi.3,v 1.14 2007/10/19 06:23:39 davidxu Exp $ .\" .Dd June 4, 1993 .Dt ATOI 3 @@ -63,10 +59,6 @@ It is equivalent to: .Bd -literal -offset indent (int)strtol(nptr, (char **)NULL, 10); .Ed -.Sh IMPLEMENTATION NOTES -The -.Fn atoi -function is not thread-safe and also not async-cancel safe. .Pp The .Fn atoi diff --git a/stdlib/FreeBSD/atoi.3.patch b/stdlib/FreeBSD/atoi.3.patch index f9f1ae2..a322d59 100644 --- a/stdlib/FreeBSD/atoi.3.patch +++ b/stdlib/FreeBSD/atoi.3.patch @@ -1,6 +1,6 @@ ---- atoi.3.orig 2007-04-08 18:49:34.000000000 -0700 -+++ atoi.3 2007-04-08 19:19:59.000000000 -0700 -@@ -40,7 +40,8 @@ +--- atoi.3.orig 2010-02-08 16:26:10.000000000 -0800 ++++ atoi.3 2010-02-13 20:59:41.000000000 -0800 +@@ -36,7 +36,8 @@ .Dt ATOI 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nd convert .Tn ASCII string to integer -@@ -49,20 +50,31 @@ +@@ -45,25 +46,46 @@ string to integer .Sh SYNOPSIS .In stdlib.h .Ft int @@ -34,7 +34,7 @@ -(int)strtol(nptr, (char **)NULL, 10); +(int)strtol(str, (char **)NULL, 10); .Ed -+.Pp + .Pp +While the +.Fn atoi +function uses the current locale, the @@ -42,10 +42,26 @@ +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. - .Sh IMPLEMENTATION NOTES ++.Sh IMPLEMENTATION NOTES ++The ++.Fn atoi ++and ++.Fn atoi_l ++functions are thread-safe and async-cancel-safe. ++.Pp The .Fn atoi -@@ -84,7 +96,8 @@ +-function has been deprecated by ++and ++.Fn atoi_l ++functions have been deprecated by + .Fn strtol ++and ++.Fn strtol_l + and should not be used in new code. + .Sh ERRORS + The function +@@ -76,7 +98,8 @@ on an error. .Xr atol 3 , .Xr strtod 3 , .Xr strtol 3 , diff --git a/stdlib/FreeBSD/atoi.c b/stdlib/FreeBSD/atoi.c index 3da2fda..38ab632 100644 --- a/stdlib/FreeBSD/atoi.c +++ b/stdlib/FreeBSD/atoi.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)atoi.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/atoi.c,v 1.5 2002/03/22 21:53:09 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atoi.c,v 1.6 2007/01/09 00:28:09 imp Exp $"); #include diff --git a/stdlib/FreeBSD/atoi.c.patch b/stdlib/FreeBSD/atoi.c.patch index cc1776d..ed23851 100644 --- a/stdlib/FreeBSD/atoi.c.patch +++ b/stdlib/FreeBSD/atoi.c.patch @@ -1,8 +1,8 @@ ---- atoi.c.orig 2003-05-20 15:23:24.000000000 -0700 -+++ atoi.c 2005-02-23 18:32:57.000000000 -0800 -@@ -37,11 +37,22 @@ +--- atoi.c.bsdnew 2009-11-13 14:11:47.000000000 -0800 ++++ atoi.c 2009-11-13 14:11:47.000000000 -0800 +@@ -33,11 +33,22 @@ static char sccsid[] = "@(#)atoi.c 8.1 ( #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/atoi.c,v 1.5 2002/03/22 21:53:09 obrien Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/atoi.c,v 1.6 2007/01/09 00:28:09 imp Exp $"); +#include "xlocale_private.h" + diff --git a/stdlib/FreeBSD/atol.3 b/stdlib/FreeBSD/atol.3 index bbd7ddb..68bf942 100644 --- a/stdlib/FreeBSD/atol.3 +++ b/stdlib/FreeBSD/atol.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)atol.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atol.3,v 1.13 2002/01/09 14:03:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/atol.3,v 1.16 2009/03/01 05:44:28 delphij Exp $ .\" -.Dd November 28, 2001 +.Dd February 1, 2009 .Dt ATOL 3 .Os .Sh NAME @@ -82,13 +78,42 @@ representation. It is equivalent to: .Pp .Dl "strtoll(nptr, (char **)NULL, 10);" +.Sh COMPATIBILITY +The +.Fx +implementations of the +.Fn atol +and +.Fn atoll +functions are thin wrappers around +.Fn strtol +and +.Fn stroll +respectively, so these functions will affect the value of +.Va errno +in the same way that the +.Fn strtol +and +.Fn stroll +functions are able to. +This behavior of +.Fn atol +and +.Fn atoll +is not required by +.St -isoC +or +.St -isoC-99 , +but it is allowed by all of +.St -isoC , St -isoC-99 +and +.St -p1003.1-2001 . .Sh ERRORS The functions .Fn atol and .Fn atoll -need not -affect the value of +may affect the value of .Va errno on an error. .Sh SEE ALSO diff --git a/stdlib/FreeBSD/atol.3.patch b/stdlib/FreeBSD/atol.3.patch index c10d971..6ad8177 100644 --- a/stdlib/FreeBSD/atol.3.patch +++ b/stdlib/FreeBSD/atol.3.patch @@ -1,6 +1,6 @@ ---- atol.3.orig 2007-04-08 18:49:34.000000000 -0700 -+++ atol.3 2007-04-08 19:21:38.000000000 -0700 -@@ -40,7 +40,8 @@ +--- atol.3.orig 2010-02-08 16:26:10.000000000 -0800 ++++ atol.3 2010-02-13 21:01:28.000000000 -0800 +@@ -36,7 +36,8 @@ .Dt ATOL 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nd convert .Tn ASCII string to -@@ -53,14 +54,19 @@ +@@ -49,14 +50,19 @@ integer .Sh SYNOPSIS .In stdlib.h .Ft long @@ -33,7 +33,7 @@ to .Vt long integer -@@ -68,12 +74,12 @@ +@@ -64,12 +70,12 @@ representation. .Pp It is equivalent to: .Pp @@ -48,11 +48,12 @@ to .Vt "long long" integer -@@ -81,7 +87,19 @@ +@@ -77,8 +83,28 @@ representation. .Pp It is equivalent to: .Pp -.Dl "strtoll(nptr, (char **)NULL, 10);" +-.Sh COMPATIBILITY +.Dl "strtoll(str, (char **)NULL, 10);" +.Pp +While the @@ -66,10 +67,19 @@ +functions may be passed locales directly. See +.Xr xlocale 3 +for more information. - .Sh ERRORS - The functions - .Fn atol -@@ -96,7 +114,8 @@ ++.Sh IMPLEMENTATION NOTES ++The ++.Fn atol , ++.Fn atoll , ++.Fn atol_l , ++and ++.Fn atoll_l ++functions are thread-safe and async-cancel-safe. ++.Pp + The + .Fx + implementations of the +@@ -121,7 +147,8 @@ on an error. .Xr atoi 3 , .Xr strtod 3 , .Xr strtol 3 , diff --git a/stdlib/FreeBSD/atol.c b/stdlib/FreeBSD/atol.c index c66c04e..2209340 100644 --- a/stdlib/FreeBSD/atol.c +++ b/stdlib/FreeBSD/atol.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)atol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/atol.c,v 1.4 2002/03/22 21:53:09 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atol.c,v 1.5 2007/01/09 00:28:09 imp Exp $"); #include diff --git a/stdlib/FreeBSD/atol.c.patch b/stdlib/FreeBSD/atol.c.patch index 89b10ba..93958d9 100644 --- a/stdlib/FreeBSD/atol.c.patch +++ b/stdlib/FreeBSD/atol.c.patch @@ -1,8 +1,8 @@ ---- atol.c.orig 2003-05-20 15:23:24.000000000 -0700 -+++ atol.c 2005-02-23 18:33:54.000000000 -0800 -@@ -37,11 +37,22 @@ +--- atol.c.bsdnew 2009-11-13 14:11:47.000000000 -0800 ++++ atol.c 2009-11-13 14:11:47.000000000 -0800 +@@ -33,11 +33,22 @@ static char sccsid[] = "@(#)atol.c 8.1 ( #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/atol.c,v 1.4 2002/03/22 21:53:09 obrien Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/atol.c,v 1.5 2007/01/09 00:28:09 imp Exp $"); +#include "xlocale_private.h" + diff --git a/stdlib/FreeBSD/atoll.c b/stdlib/FreeBSD/atoll.c index b7c38b8..c5bc881 100644 --- a/stdlib/FreeBSD/atoll.c +++ b/stdlib/FreeBSD/atoll.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -32,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/atoll.c,v 1.4 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atoll.c,v 1.5 2007/01/09 00:28:09 imp Exp $"); #include diff --git a/stdlib/FreeBSD/atoll.c.patch b/stdlib/FreeBSD/atoll.c.patch index 4e53f3b..fb43ecf 100644 --- a/stdlib/FreeBSD/atoll.c.patch +++ b/stdlib/FreeBSD/atoll.c.patch @@ -1,8 +1,8 @@ ---- atoll.c.orig 2003-05-20 15:23:24.000000000 -0700 -+++ atoll.c 2005-02-23 18:35:02.000000000 -0800 -@@ -34,11 +34,22 @@ +--- atoll.c.bsdnew 2009-11-13 14:11:47.000000000 -0800 ++++ atoll.c 2009-11-13 14:11:47.000000000 -0800 +@@ -30,11 +30,22 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/atoll.c,v 1.4 2002/03/22 21:53:10 obrien Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/atoll.c,v 1.5 2007/01/09 00:28:09 imp Exp $"); +#include "xlocale_private.h" + diff --git a/stdlib/FreeBSD/bsearch.3 b/stdlib/FreeBSD/bsearch.3 index 25c608d..5ae5867 100644 --- a/stdlib/FreeBSD/bsearch.3 +++ b/stdlib/FreeBSD/bsearch.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bsearch.3 8.3 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/stdlib/bsearch.3,v 1.8 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/bsearch.3,v 1.9 2007/01/09 00:28:09 imp Exp $ .\" .Dd April 19, 1994 .Dt BSEARCH 3 diff --git a/stdlib/FreeBSD/bsearch.3.patch b/stdlib/FreeBSD/bsearch.3.patch index 2d4dff8..4486b7d 100644 --- a/stdlib/FreeBSD/bsearch.3.patch +++ b/stdlib/FreeBSD/bsearch.3.patch @@ -1,8 +1,8 @@ ---- bsearch.3.orig 2009-05-12 11:21:33.000000000 -0700 -+++ bsearch.3 2009-05-20 14:53:48.000000000 -0700 -@@ -36,30 +36,37 @@ +--- bsearch.3.bsdnew 2009-11-13 14:11:47.000000000 -0800 ++++ bsearch.3 2009-11-13 14:11:48.000000000 -0800 +@@ -32,30 +32,37 @@ .\" @(#)bsearch.3 8.3 (Berkeley) 4/19/94 - .\" $FreeBSD: src/lib/libc/stdlib/bsearch.3,v 1.8 2001/09/07 14:46:35 asmodai Exp $ + .\" $FreeBSD: src/lib/libc/stdlib/bsearch.3,v 1.9 2007/01/09 00:28:09 imp Exp $ .\" -.Dd April 19, 1994 +.Dd May 20, 2008 @@ -45,7 +45,7 @@ .Pp The contents of the array should be in ascending sorted order according to the comparison function referenced by -@@ -70,15 +77,33 @@ +@@ -66,15 +73,33 @@ routine is expected to have two arguments which point to the .Fa key diff --git a/stdlib/FreeBSD/bsearch.c b/stdlib/FreeBSD/bsearch.c index 7717582..b698869 100644 --- a/stdlib/FreeBSD/bsearch.c +++ b/stdlib/FreeBSD/bsearch.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)bsearch.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/bsearch.c,v 1.3 2002/03/21 22:48:41 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/bsearch.c,v 1.4 2007/01/09 00:28:09 imp Exp $"); #include #include diff --git a/stdlib/FreeBSD/bsearch.c.patch b/stdlib/FreeBSD/bsearch.c.patch index 398758a..4d86020 100644 --- a/stdlib/FreeBSD/bsearch.c.patch +++ b/stdlib/FreeBSD/bsearch.c.patch @@ -1,6 +1,6 @@ ---- bsearch.c.orig 2009-05-12 11:21:33.000000000 -0700 -+++ bsearch.c 2009-05-20 13:11:05.000000000 -0700 -@@ -81,3 +81,31 @@ bsearch(key, base0, nmemb, size, compar) +--- bsearch.c.bsdnew 2009-11-13 14:11:48.000000000 -0800 ++++ bsearch.c 2009-11-13 14:11:48.000000000 -0800 +@@ -77,3 +77,31 @@ bsearch(key, base0, nmemb, size, compar) } return (NULL); } diff --git a/stdlib/FreeBSD/div.3 b/stdlib/FreeBSD/div.3 index 49f2b4f..b29ca13 100644 --- a/stdlib/FreeBSD/div.3 +++ b/stdlib/FreeBSD/div.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)div.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/div.3,v 1.8 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/div.3,v 1.9 2007/01/09 00:28:09 imp Exp $ .\" .Dd November 14, 2001 .Dt DIV 3 diff --git a/stdlib/FreeBSD/div.3.patch b/stdlib/FreeBSD/div.3.patch index aa7cf1c..9d2d044 100644 --- a/stdlib/FreeBSD/div.3.patch +++ b/stdlib/FreeBSD/div.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdlib/FreeBSD/div.3 2003-05-20 15:23:24.000000000 -0700 -+++ _SB/Libc/stdlib/FreeBSD/div.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -45,21 +45,23 @@ +--- div.3.bsdnew 2009-11-13 14:11:48.000000000 -0800 ++++ div.3 2009-11-13 14:11:48.000000000 -0800 +@@ -41,21 +41,23 @@ .Sh SYNOPSIS .In stdlib.h .Ft div_t diff --git a/stdlib/FreeBSD/div.c b/stdlib/FreeBSD/div.c index 54278d6..2aa3492 100644 --- a/stdlib/FreeBSD/div.c +++ b/stdlib/FreeBSD/div.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)div.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/div.c,v 1.2 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/div.c,v 1.3 2007/01/09 00:28:09 imp Exp $"); #include /* div_t */ diff --git a/stdlib/FreeBSD/exit.3 b/stdlib/FreeBSD/exit.3 index aa07fda..250f529 100644 --- a/stdlib/FreeBSD/exit.3 +++ b/stdlib/FreeBSD/exit.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)exit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/exit.3,v 1.15 2004/07/04 20:55:48 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/exit.3,v 1.16 2007/01/09 00:28:09 imp Exp $ .\" .Dd September 9, 2002 .Dt EXIT 3 diff --git a/stdlib/FreeBSD/exit.c b/stdlib/FreeBSD/exit.c index e71b3db..8449600 100644 --- a/stdlib/FreeBSD/exit.c +++ b/stdlib/FreeBSD/exit.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,15 +31,17 @@ static char sccsid[] = "@(#)exit.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/exit.c,v 1.7 2003/12/19 17:11:20 kan Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/exit.c,v 1.9 2007/01/09 00:28:09 imp Exp $"); #include "namespace.h" #include #include #include "un-namespace.h" + #include "atexit.h" +#include "libc_private.h" -void (*__cleanup)(); +void (*__cleanup)(void); /* * This variable is zero until a process has created a thread. diff --git a/stdlib/FreeBSD/exit.c.patch b/stdlib/FreeBSD/exit.c.patch index 0524eb0..7afb640 100644 --- a/stdlib/FreeBSD/exit.c.patch +++ b/stdlib/FreeBSD/exit.c.patch @@ -1,9 +1,9 @@ ---- exit.c.orig 2006-08-08 16:13:56.000000000 -0700 -+++ exit.c 2006-08-11 22:12:56.000000000 -0700 -@@ -44,15 +44,7 @@ - #include "atexit.h" +--- exit.c.bsdnew 2009-11-13 14:11:48.000000000 -0800 ++++ exit.c 2009-11-13 14:47:07.000000000 -0800 +@@ -42,15 +42,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ + #include "libc_private.h" - void (*__cleanup)(); + void (*__cleanup)(void); - -/* - * This variable is zero until a process has created a thread. @@ -17,7 +17,7 @@ /* * Exit, flushing stdio buffers if necessary. -@@ -61,13 +53,8 @@ +@@ -59,13 +51,8 @@ void exit(status) int status; { diff --git a/stdlib/FreeBSD/getenv.c b/stdlib/FreeBSD/getenv.c index aa15989..b1e034a 100644 --- a/stdlib/FreeBSD/getenv.c +++ b/stdlib/FreeBSD/getenv.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)getenv.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/getenv.c,v 1.4 2002/03/21 22:48:41 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/getenv.c,v 1.8 2007/05/01 16:02:41 ache Exp $"); #include #include diff --git a/stdlib/FreeBSD/getenv.c.patch b/stdlib/FreeBSD/getenv.c.patch index 1b454e2..2155a0b 100644 --- a/stdlib/FreeBSD/getenv.c.patch +++ b/stdlib/FreeBSD/getenv.c.patch @@ -1,6 +1,6 @@ ---- getenv.c.orig 2006-08-29 00:12:28.000000000 -0700 -+++ getenv.c 2006-08-29 00:13:31.000000000 -0700 -@@ -40,8 +40,9 @@ +--- getenv.c.bsdnew 2009-11-13 15:14:36.000000000 -0800 ++++ getenv.c 2009-11-13 15:14:50.000000000 -0800 +@@ -36,8 +36,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ #include #include #include @@ -11,7 +11,7 @@ /* * __findenv -- -@@ -52,12 +53,12 @@ +@@ -48,12 +49,12 @@ inline char *__findenv(const char *, int * * This routine *should* be a static; don't use it. */ @@ -27,7 +27,7 @@ int len, i; const char *np; char **p, *cp; -@@ -80,6 +81,19 @@ +@@ -76,6 +77,19 @@ __findenv(name, offset) } /* @@ -47,7 +47,7 @@ * getenv -- * Returns ptr to value associated with name, if any, else NULL. */ -@@ -89,5 +103,5 @@ +@@ -85,5 +99,5 @@ getenv(name) { int offset; diff --git a/stdlib/FreeBSD/getopt.3 b/stdlib/FreeBSD/getopt.3 index b24a75c..ec9bf19 100644 --- a/stdlib/FreeBSD/getopt.3 +++ b/stdlib/FreeBSD/getopt.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getopt.3 8.5 (Berkeley) 4/27/95 -.\" $FreeBSD: src/lib/libc/stdlib/getopt.3,v 1.25 2004/07/31 01:00:50 imp Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/getopt.3,v 1.26 2007/01/09 00:28:10 imp Exp $ .\" .Dd April 27, 1995 .Dt GETOPT 3 diff --git a/stdlib/FreeBSD/getopt.c b/stdlib/FreeBSD/getopt.c index efcfa0a..375907a 100644 --- a/stdlib/FreeBSD/getopt.c +++ b/stdlib/FreeBSD/getopt.c @@ -12,10 +12,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -37,7 +33,7 @@ static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.7 2004/03/06 17:05:45 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.8 2007/01/09 00:28:10 imp Exp $"); #include "namespace.h" #include diff --git a/stdlib/FreeBSD/getopt.c.patch b/stdlib/FreeBSD/getopt.c.patch index 4b9ad71..b4b18e9 100644 --- a/stdlib/FreeBSD/getopt.c.patch +++ b/stdlib/FreeBSD/getopt.c.patch @@ -1,6 +1,6 @@ ---- ../Libc/stdlib/FreeBSD/getopt.c 2004-11-25 11:38:41.000000000 -0800 -+++ getopt.c 2005-01-26 19:27:09.000000000 -0800 -@@ -48,16 +48,24 @@ +--- getopt.c.bsdnew 2009-11-13 14:11:48.000000000 -0800 ++++ getopt.c 2009-11-13 14:11:48.000000000 -0800 +@@ -44,16 +44,24 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ #include "libc_private.h" @@ -25,7 +25,7 @@ /* * getopt -- * Parse argc/argv argument vector. -@@ -103,8 +111,8 @@ +@@ -99,8 +107,8 @@ getopt(nargc, nargv, ostr) ++optind; if (opterr && *ostr != ':') (void)fprintf(stderr, @@ -36,7 +36,7 @@ return (BADCH); } -@@ -123,13 +131,19 @@ +@@ -119,13 +127,19 @@ getopt(nargc, nargv, ostr) optarg = nargv[optind]; else { /* option-argument absent */ diff --git a/stdlib/FreeBSD/getopt_long.3 b/stdlib/FreeBSD/getopt_long.3 index dde7980..fd33cfc 100644 --- a/stdlib/FreeBSD/getopt_long.3 +++ b/stdlib/FreeBSD/getopt_long.3 @@ -29,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getopt.3 8.5 (Berkeley) 4/27/95 -.\" $FreeBSD: src/lib/libc/stdlib/getopt_long.3,v 1.11 2004/03/06 14:47:49 ache Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/getopt_long.3,v 1.13 2005/01/20 09:17:04 ru Exp $ .\" .Dd April 1, 2000 .Dt GETOPT_LONG 3 @@ -133,7 +133,7 @@ field should be one of: no argument to the option is expect .It Dv required_argument an argument to the option is required -.It Li optional_argument +.It Dv optional_argument an argument to the option may be presented. .El .Pp @@ -190,7 +190,7 @@ the single-character option is returned. If the .Fa flag field in -.Li struct option +.Vt "struct option" is .Dv NULL , .Fn getopt_long @@ -213,6 +213,18 @@ if there was a missing option argument, .Ql \&? if the user specified an unknown or ambiguous option, and \-1 when the argument list has been exhausted. +.Sh ENVIRONMENT +.Bl -tag -width ".Ev POSIXLY_CORRECT" +.It Ev POSIXLY_CORRECT +If set, option processing stops when the first non-option is found and +a leading +.Ql - +or +.Ql + +in the +.Fa optstring +is ignored. +.El .Sh EXAMPLES .Bd -literal -compact int bflag, ch, fd; @@ -450,18 +462,6 @@ relative to current positions) are the same, though. (We do fewer variable swaps.) .El -.Sh ENVIRONMENT -.Bl -tag -width POSIXLY_CORRECT -.It Ev POSIXLY_CORRECT -If set, option processing stops when the first non-option is found and -a leading -.Ql - -or -.Ql + -in the -.Ar optstring -is ignored. -.El .Sh SEE ALSO .Xr getopt 3 .Sh HISTORY @@ -494,9 +494,9 @@ in .Fx 5.2 . .Sh BUGS The -.Ar argv +.Fa argv argument is not really -.Dv const +.Vt const as its elements may be permuted (unless .Ev POSIXLY_CORRECT is set). diff --git a/stdlib/FreeBSD/getopt_long.c b/stdlib/FreeBSD/getopt_long.c index ef306bc..c42edb3 100644 --- a/stdlib/FreeBSD/getopt_long.c +++ b/stdlib/FreeBSD/getopt_long.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getopt_long.c,v 1.17 2004/06/03 18:46:52 millert Exp $ */ +/* $OpenBSD: getopt_long.c,v 1.21 2006/09/22 17:22:05 millert Exp $ */ /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ /* @@ -62,7 +62,7 @@ static char *rcsid = "$OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert #endif /* LIBC_SCCS and not lint */ #endif #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/getopt_long.c,v 1.12 2004/07/06 13:58:45 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/getopt_long.c,v 1.15 2006/09/23 14:48:31 ache Exp $"); #include #include @@ -72,7 +72,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/getopt_long.c,v 1.12 2004/07/06 13:58:45 #define GNU_COMPATIBLE /* Be more compatible, configure's use us! */ -#ifndef GNU_COMPATIBLE +#if 0 /* we prefer to keep our getopt(3) */ #define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ #endif @@ -366,7 +366,7 @@ getopt_internal(int nargc, char * const *nargv, const char *options, { char *oli; /* option letter list index */ int optchar, short_too; - int posixly_correct; + int posixly_correct; /* no static, can be changed on the fly */ if (options == NULL) return (-1); @@ -558,7 +558,6 @@ start: optarg = NULL; if (*place) /* no white space */ optarg = place; - /* XXX: disable test for :: if PC? (GNU doesn't) */ else if (oli[1] != ':') { /* arg not optional */ if (++optind >= nargc) { /* no arg */ place = EMSG; @@ -568,14 +567,6 @@ start: return (BADARG); } else optarg = nargv[optind]; - } else if (!(flags & FLAG_PERMUTE)) { - /* - * If permutation is disabled, we can accept an - * optional arg separated by whitespace so long - * as it does not start with a dash (-). - */ - if (optind + 1 < nargc && *nargv[optind + 1] != '-') - optarg = nargv[++optind]; } place = EMSG; ++optind; @@ -612,12 +603,8 @@ getopt(int nargc, char * const *nargv, const char *options) * Parse argc/argv argument vector. */ int -getopt_long(nargc, nargv, options, long_options, idx) - int nargc; - char * const *nargv; - const char *options; - const struct option *long_options; - int *idx; +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) { return (getopt_internal(nargc, nargv, options, long_options, idx, @@ -629,12 +616,8 @@ getopt_long(nargc, nargv, options, long_options, idx) * Parse argc/argv argument vector. */ int -getopt_long_only(nargc, nargv, options, long_options, idx) - int nargc; - char * const *nargv; - const char *options; - const struct option *long_options; - int *idx; +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) { return (getopt_internal(nargc, nargv, options, long_options, idx, diff --git a/stdlib/FreeBSD/getsubopt.3 b/stdlib/FreeBSD/getsubopt.3 index 651f357..544e343 100644 --- a/stdlib/FreeBSD/getsubopt.3 +++ b/stdlib/FreeBSD/getsubopt.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/stdlib/getsubopt.3,v 1.10 2004/02/23 03:32:10 ache Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/getsubopt.3,v 1.11 2007/01/09 00:28:10 imp Exp $ .\" .Dd June 9, 1993 .Dt GETSUBOPT 3 diff --git a/stdlib/FreeBSD/getsubopt.3.patch b/stdlib/FreeBSD/getsubopt.3.patch index 5b472e7..9198467 100644 --- a/stdlib/FreeBSD/getsubopt.3.patch +++ b/stdlib/FreeBSD/getsubopt.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdlib/FreeBSD/getsubopt.3 2004-11-25 11:38:41.000000000 -0800 -+++ _SB/Libc/stdlib/FreeBSD/getsubopt.3.edit 2006-06-28 16:55:52.000000000 -0700 -@@ -44,23 +44,27 @@ +--- getsubopt.3.bsdnew 2009-11-13 14:11:48.000000000 -0800 ++++ getsubopt.3 2009-11-13 14:11:48.000000000 -0800 +@@ -40,23 +40,27 @@ .In stdlib.h .Vt extern char *suboptarg ; .Ft int @@ -34,7 +34,7 @@ is a pointer to a .Dv NULL Ns -terminated array of pointers to strings. -@@ -69,10 +73,10 @@ +@@ -65,10 +69,10 @@ The .Fn getsubopt function returns the zero-based offset of the pointer in the @@ -49,7 +49,7 @@ does not contain a matching string. .Pp If the token is of the form ``name=value'', the location referenced by -@@ -97,7 +101,7 @@ +@@ -93,7 +97,7 @@ will be set to point to the ``value'' po if no ``value'' portion was present. .Sh EXAMPLES .Bd -literal -compact @@ -58,7 +58,7 @@ #define ONE 0 "one", #define TWO 1 -@@ -118,7 +122,7 @@ +@@ -114,7 +118,7 @@ while ((ch = getopt(argc, argv, "ab:")) case 'b': options = optarg; while (*options) { diff --git a/stdlib/FreeBSD/getsubopt.c b/stdlib/FreeBSD/getsubopt.c index 488706a..194734e 100644 --- a/stdlib/FreeBSD/getsubopt.c +++ b/stdlib/FreeBSD/getsubopt.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/getsubopt.c,v 1.6 2004/02/23 03:30:02 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/getsubopt.c,v 1.7 2007/01/09 00:28:10 imp Exp $"); #include #include diff --git a/stdlib/FreeBSD/hcreate.3 b/stdlib/FreeBSD/hcreate.3 index e6a5e44..10cbbaf 100644 --- a/stdlib/FreeBSD/hcreate.3 +++ b/stdlib/FreeBSD/hcreate.3 @@ -1,6 +1,34 @@ -.\" $FreeBSD: src/lib/libc/stdlib/hcreate.3,v 1.4 2003/09/08 19:57:15 ru Exp $ +.\"- +.\" Copyright (c) 1999 The NetBSD Foundation, Inc. +.\" All rights reserved. .\" -.Dd May 8, 2001 +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Klaus Klein. +.\" +.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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: src/lib/libc/stdlib/hcreate.3,v 1.7 2008/07/06 17:03:37 danger Exp $ +.\" +.Dd July 6, 2008 .Os .Dt HCREATE 3 .Sh NAME @@ -111,8 +139,10 @@ is called. .Sh RETURN VALUES The .Fn hcreate -function returns 0 if it cannot allocate sufficient space for the table; -otherwise, it returns non-zero. +function returns 0 if the table creation failed and the global variable +.Va errno +is set to indicate the error; +otherwise, a non-zero value is returned. .Pp The .Fn hdestroy @@ -133,16 +163,6 @@ could not be found or the is .Dv ENTER and the table is full. -.Sh ERRORS -The -.Fn hcreate -and -.Fn hsearch -functions may fail if: -.Bl -tag -width Er -.It Bq Er ENOMEM -Insufficient storage space is available. -.El .Sh EXAMPLES The following example reads in strings followed by two numbers and stores them in a hash table, discarding duplicates. @@ -200,6 +220,18 @@ main(void) return 0; } .Ed +.Sh ERRORS +The +.Fn hcreate +and +.Fn hsearch +functions may fail if: +.Bl -tag -width Er +.It Bq Er ENOMEM +Insufficient storage space is available. +.It Bq Er EINVAL +A table already exists. +.El .Sh SEE ALSO .Xr bsearch 3 , .Xr lsearch 3 , diff --git a/stdlib/FreeBSD/hcreate.c b/stdlib/FreeBSD/hcreate.c index 6ab33e5..9264599 100644 --- a/stdlib/FreeBSD/hcreate.c +++ b/stdlib/FreeBSD/hcreate.c @@ -52,7 +52,7 @@ __RCSID("$NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/stdlib/hcreate.c,v 1.3 2002/06/27 13:18:27 deischen Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/hcreate.c,v 1.4 2008/07/06 11:31:20 danger Exp $"); #include #include @@ -93,7 +93,7 @@ hcreate(size_t nel) size_t idx; unsigned int p2; - /* Make sure this this isn't called when a table already exists. */ + /* Make sure this is not called when a table already exists. */ if (htable != NULL) { errno = EINVAL; return 0; @@ -103,11 +103,11 @@ hcreate(size_t nel) if (nel < MIN_BUCKETS) nel = MIN_BUCKETS; - /* If it's too large, cap it. */ + /* If it is too large, cap it. */ if (nel > MAX_BUCKETS) nel = MAX_BUCKETS; - /* If it's is not a power of two in size, round up. */ + /* If it is not a power of two in size, round up. */ if ((nel & (nel - 1)) != 0) { for (p2 = 0; nel != 0; p2++) nel >>= 1; diff --git a/stdlib/FreeBSD/labs.3 b/stdlib/FreeBSD/labs.3 index d496b30..b38d8ad 100644 --- a/stdlib/FreeBSD/labs.3 +++ b/stdlib/FreeBSD/labs.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)labs.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/labs.3,v 1.9 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/labs.3,v 1.10 2007/01/09 00:28:10 imp Exp $ .\" .Dd November 14, 2001 .Dt LABS 3 diff --git a/stdlib/FreeBSD/labs.3.patch b/stdlib/FreeBSD/labs.3.patch index 79b3180..baa4f45 100644 --- a/stdlib/FreeBSD/labs.3.patch +++ b/stdlib/FreeBSD/labs.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdlib/FreeBSD/labs.3 2003-05-20 15:23:24.000000000 -0700 -+++ _SB/Libc/stdlib/FreeBSD/labs.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -47,13 +47,13 @@ +--- labs.3.bsdnew 2009-11-13 14:11:49.000000000 -0800 ++++ labs.3 2009-11-13 14:11:49.000000000 -0800 +@@ -43,13 +43,13 @@ .Sh SYNOPSIS .In stdlib.h .Ft long diff --git a/stdlib/FreeBSD/labs.c b/stdlib/FreeBSD/labs.c index 42e63d1..f2ead54 100644 --- a/stdlib/FreeBSD/labs.c +++ b/stdlib/FreeBSD/labs.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)labs.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/labs.c,v 1.2 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/labs.c,v 1.3 2007/01/09 00:28:10 imp Exp $"); #include diff --git a/stdlib/FreeBSD/ldiv.3 b/stdlib/FreeBSD/ldiv.3 index c75b8be..492d508 100644 --- a/stdlib/FreeBSD/ldiv.3 +++ b/stdlib/FreeBSD/ldiv.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ldiv.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/ldiv.3,v 1.9 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/ldiv.3,v 1.10 2007/01/09 00:28:10 imp Exp $ .\" .Dd November 14, 2001 .Dt LDIV 3 diff --git a/stdlib/FreeBSD/ldiv.3.patch b/stdlib/FreeBSD/ldiv.3.patch index e70b205..107a217 100644 --- a/stdlib/FreeBSD/ldiv.3.patch +++ b/stdlib/FreeBSD/ldiv.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdlib/FreeBSD/ldiv.3 2003-05-20 15:23:24.000000000 -0700 -+++ _SB/Libc/stdlib/FreeBSD/ldiv.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -47,14 +47,15 @@ +--- ldiv.3.bsdnew 2009-11-13 14:11:49.000000000 -0800 ++++ ldiv.3 2009-11-13 14:11:49.000000000 -0800 +@@ -43,14 +43,15 @@ .Sh SYNOPSIS .In stdlib.h .Ft ldiv_t diff --git a/stdlib/FreeBSD/ldiv.c b/stdlib/FreeBSD/ldiv.c index 560d5c2..a0707e3 100644 --- a/stdlib/FreeBSD/ldiv.c +++ b/stdlib/FreeBSD/ldiv.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)ldiv.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/ldiv.c,v 1.2 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/ldiv.c,v 1.3 2007/01/09 00:28:10 imp Exp $"); #include /* ldiv_t */ diff --git a/stdlib/FreeBSD/lsearch.3 b/stdlib/FreeBSD/lsearch.3 index fd79b9a..3ad6f6c 100644 --- a/stdlib/FreeBSD/lsearch.3 +++ b/stdlib/FreeBSD/lsearch.3 @@ -6,7 +6,7 @@ .\" As long as the above copyright statement and this notice remain .\" unchanged, you can do what ever you want with this file. .\" -.\" $FreeBSD: src/lib/libc/stdlib/lsearch.3,v 1.4 2002/12/19 09:40:24 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/lsearch.3,v 1.5 2005/01/20 09:17:04 ru Exp $ .\" .Dd October 11, 2002 .Dt LSEARCH 3 @@ -85,6 +85,13 @@ if an error occurs. .Xr bsearch 3 , .Xr hsearch 3 , .Xr tsearch 3 +.Sh STANDARDS +The +.Fn lsearch +and +.Fn lfind +functions conform to +.St -p1003.1-2001 . .Sh HISTORY The .Fn lsearch @@ -96,10 +103,3 @@ In .Fx 5.0 , they reappeared conforming to .St -p1003.1-2001 . -.Sh STANDARDS -The -.Fn lsearch -and -.Fn lfind -functions conform to -.St -p1003.1-2001 . diff --git a/stdlib/FreeBSD/lsearch.3.patch b/stdlib/FreeBSD/lsearch.3.patch index 763bd27..ddf90a4 100644 --- a/stdlib/FreeBSD/lsearch.3.patch +++ b/stdlib/FreeBSD/lsearch.3.patch @@ -1,5 +1,5 @@ ---- _SB/Libc/stdlib/FreeBSD/lsearch.3 2003-05-20 15:23:25.000000000 -0700 -+++ _SB/Libc/stdlib/FreeBSD/lsearch.3.edit 2006-06-28 16:55:53.000000000 -0700 +--- lsearch.3.bsdnew 2009-11-13 14:11:50.000000000 -0800 ++++ lsearch.3 2009-11-13 14:11:50.000000000 -0800 @@ -12,21 +12,21 @@ .Dt LSEARCH 3 .Os @@ -28,7 +28,7 @@ .Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" .Fc .Sh DESCRIPTION -@@ -34,8 +34,8 @@ +@@ -34,8 +34,8 @@ The .Fn lsearch and .Fn lfind diff --git a/stdlib/FreeBSD/memory.3 b/stdlib/FreeBSD/memory.3 index 25222d4..3802a32 100644 --- a/stdlib/FreeBSD/memory.3 +++ b/stdlib/FreeBSD/memory.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memory.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/memory.3,v 1.11 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/memory.3,v 1.12 2007/01/09 00:28:10 imp Exp $ .\" .Dd June 4, 1993 .Dt MEMORY 3 diff --git a/stdlib/FreeBSD/memory.3.patch b/stdlib/FreeBSD/memory.3.patch index d93412f..900b4cd 100644 --- a/stdlib/FreeBSD/memory.3.patch +++ b/stdlib/FreeBSD/memory.3.patch @@ -1,6 +1,6 @@ ---- memory.3 2003-05-20 15:23:25.000000000 -0700 -+++ memory.3.edit 2006-07-13 09:26:29.000000000 -0700 -@@ -36,42 +36,101 @@ +--- memory.3.bsdnew 2009-11-13 14:11:50.000000000 -0800 ++++ memory.3 2009-11-13 14:11:50.000000000 -0800 +@@ -32,42 +32,101 @@ .Dt MEMORY 3 .Os .Sh NAME diff --git a/stdlib/FreeBSD/putenv.c b/stdlib/FreeBSD/putenv.c index c8f3b60..e74d346 100644 --- a/stdlib/FreeBSD/putenv.c +++ b/stdlib/FreeBSD/putenv.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)putenv.c 8.2 (Berkeley) 3/27/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/putenv.c,v 1.2 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/putenv.c,v 1.6 2007/05/01 16:02:41 ache Exp $"); #include #include diff --git a/stdlib/FreeBSD/putenv.c.patch b/stdlib/FreeBSD/putenv.c.patch index 36017bc..47a412e 100644 --- a/stdlib/FreeBSD/putenv.c.patch +++ b/stdlib/FreeBSD/putenv.c.patch @@ -1,6 +1,6 @@ ---- putenv.c.orig 2006-10-05 11:57:06.000000000 -0700 -+++ putenv.c 2006-11-02 11:15:33.000000000 -0800 -@@ -39,22 +39,65 @@ +--- putenv.c.orig 2011-04-12 22:08:20.000000000 -0700 ++++ putenv.c 2011-04-13 14:33:50.000000000 -0700 +@@ -35,22 +35,81 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ #include #include @@ -9,10 +9,13 @@ +#include +#include +#include - ++ +extern malloc_zone_t *__zone0; -+extern void __malloc_check_env_name(const char *); ++#ifdef LEGACY_CRT1_ENVIRON ++extern char **_saved_environ; ++#endif /* LEGACY_CRT1_ENVIRON */ + ++extern void __malloc_check_env_name(const char *); +__private_extern__ int __setenv(const char *, const char *, int, int, char ***, malloc_zone_t *); + +#ifndef BUILDING_VARIANT @@ -21,13 +24,9 @@ + * have been created with malloc) and an env state, created by _allocenvstate(). + * Returns ptr to value associated with name, if any, else NULL. + */ - int --putenv(str) -- const char *str; ++int +_putenvp(char *str, char ***envp, void *state) - { -- char *p, *equal; -- int rval; ++{ + /* insure __zone0 is set up */ + if (!__zone0) { + __zone0 = malloc_create_zone(0, 0); @@ -40,11 +39,18 @@ +} +#endif /* BUILDING_VARIANT */ -- if ((p = strdup(str)) == NULL) -+int -+putenv(str) + int + putenv(str) +- const char *str; + char *str; -+{ + { +- char *p, *equal; +- int rval; ++#ifdef LEGACY_CRT1_ENVIRON ++ int ret; ++#endif /* LEGACY_CRT1_ENVIRON */ + +- if ((p = strdup(str)) == NULL) +#if __DARWIN_UNIX03 + if (str == NULL || *str == 0 || index(str, '=') == NULL) { + errno = EINVAL; @@ -69,11 +75,20 @@ - (void)free(p); - return (rval); + __malloc_check_env_name(str); /* see if we are changing a malloc environment variable */ -+ return (__setenv(str, NULL, 1, ++#ifdef LEGACY_CRT1_ENVIRON ++ ret = ++#else /* !LEGACY_CRT1_ENVIRON */ ++ return ++#endif /* !LEGACY_CRT1_ENVIRON */ ++ __setenv(str, NULL, 1, +#if __DARWIN_UNIX03 + 0, +#else /* !__DARWIN_UNIX03 */ + -1, +#endif /* __DARWIN_UNIX03 */ -+ _NSGetEnviron(), __zone0)); ++ _NSGetEnviron(), __zone0); ++#ifdef LEGACY_CRT1_ENVIRON ++ _saved_environ = *_NSGetEnviron(); ++ return ret; ++#endif /* LEGACY_CRT1_ENVIRON */ } diff --git a/stdlib/FreeBSD/qsort.3 b/stdlib/FreeBSD/qsort.3 index 5a901ce..23a116c 100644 --- a/stdlib/FreeBSD/qsort.3 +++ b/stdlib/FreeBSD/qsort.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)qsort.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.15 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.17 2007/01/09 00:28:10 imp Exp $ .\" .Dd September 30, 2003 .Dt QSORT 3 @@ -209,6 +205,12 @@ functions return no value. .Pp .Rv -std heapsort mergesort +.Sh COMPATIBILITY +Previous versions of +.Fn qsort +did not permit the comparison routine itself to call +.Fn qsort 3 . +This is no longer true. .Sh ERRORS The .Fn heapsort @@ -234,12 +236,6 @@ or functions were unable to allocate memory. .El -.Sh COMPATIBILITY -Previous versions of -.Fn qsort -did not permit the comparison routine itself to call -.Fn qsort 3 . -This is no longer true. .Sh SEE ALSO .Xr sort 1 , .Xr radixsort 3 diff --git a/stdlib/FreeBSD/qsort.3.patch b/stdlib/FreeBSD/qsort.3.patch index 17358cd..f511988 100644 --- a/stdlib/FreeBSD/qsort.3.patch +++ b/stdlib/FreeBSD/qsort.3.patch @@ -1,6 +1,6 @@ ---- qsort.3.orig 2009-05-12 11:21:33.000000000 -0700 -+++ qsort.3 2009-05-20 15:00:21.000000000 -0700 -@@ -40,41 +40,78 @@ +--- qsort.3.orig 2010-10-07 21:23:04.000000000 -0700 ++++ qsort.3 2010-10-07 21:24:45.000000000 -0700 +@@ -36,41 +36,78 @@ .Dt QSORT 3 .Os .Sh NAME @@ -63,9 +63,7 @@ .Ft int -.Fo mergesort +.Fo mergesort_b - .Fa "void *base" --.Fa "size_t nmemb" --.Fa "size_t size" ++.Fa "void *base" +.Fa "size_t nel" +.Fa "size_t width" +.Fa "int \*[lp]^compar\*[rp]\*[lp]const void *, const void *\*[rp]" @@ -73,7 +71,9 @@ +#endif +.Ft void +.Fo qsort -+.Fa "void *base" + .Fa "void *base" +-.Fa "size_t nmemb" +-.Fa "size_t size" +.Fa "size_t nel" +.Fa "size_t width" .Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" @@ -98,7 +98,7 @@ .Sh DESCRIPTION The .Fn qsort -@@ -84,7 +121,7 @@ +@@ -80,7 +117,7 @@ function is a modified selection sort. The .Fn mergesort @@ -107,7 +107,7 @@ intended for sorting data with pre-existing order. .Pp The -@@ -92,19 +129,19 @@ +@@ -88,19 +125,19 @@ and .Fn heapsort functions sort an array of @@ -131,7 +131,7 @@ .Dq "sizeof(void *) / 2" . .Pp The contents of the array -@@ -139,7 +176,7 @@ +@@ -135,7 +172,7 @@ .Fn heapsort are .Em not @@ -140,7 +140,7 @@ the sorted array is undefined. The .Fn mergesort -@@ -183,8 +220,8 @@ +@@ -179,8 +216,8 @@ The function .Fn mergesort requires additional memory of size @@ -151,13 +151,11 @@ bytes; it should be used only when space is not at a premium. The .Fn mergesort -@@ -195,42 +232,83 @@ - Normally, +@@ -192,19 +229,40 @@ .Fn qsort is faster than --.Fn mergesort + .Fn mergesort -is faster than -+.Fn mergesort , +which is faster than .Fn heapsort . Memory availability and pre-existing order in the data can make this @@ -193,12 +191,17 @@ +.ds MERGESORT_B mergesort_b +#endif +.Rv -std heapsort \*[HEAPSORT_B] mergesort \*[MERGESORT_B] + .Sh COMPATIBILITY + Previous versions of + .Fn qsort +@@ -213,26 +271,46 @@ + This is no longer true. .Sh ERRORS The +#ifdef UNIFDEF_BLOCKS +.Fn heapsort , +.Fn heapsort_b , -+.Fn mergesort ++.Fn mergesort , +and +.Fn mergesort_b +#else @@ -229,13 +232,12 @@ +#ifdef UNIFDEF_BLOCKS +.Fn heapsort , +.Fn heapsort_b , -+.Fn mergesort -+and ++.Fn mergesort , ++or +.Fn mergesort_b +#else .Fn heapsort --or -+and + or .Fn mergesort +#endif functions diff --git a/stdlib/FreeBSD/radixsort.3 b/stdlib/FreeBSD/radixsort.3 index a1421c6..9dc2286 100644 --- a/stdlib/FreeBSD/radixsort.3 +++ b/stdlib/FreeBSD/radixsort.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)radixsort.3 8.2 (Berkeley) 1/27/94 -.\" $FreeBSD: src/lib/libc/stdlib/radixsort.3,v 1.11 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/radixsort.3,v 1.12 2007/01/09 00:28:10 imp Exp $ .\" .Dd January 27, 1994 .Dt RADIXSORT 3 diff --git a/stdlib/FreeBSD/radixsort.c b/stdlib/FreeBSD/radixsort.c index 5f9eaeb..5e7c6dc 100644 --- a/stdlib/FreeBSD/radixsort.c +++ b/stdlib/FreeBSD/radixsort.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)radixsort.c 8.2 (Berkeley) 4/28/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/radixsort.c,v 1.7 2003/11/11 04:59:23 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/radixsort.c,v 1.8 2007/01/09 00:28:10 imp Exp $"); /* * Radixsort routines. diff --git a/stdlib/FreeBSD/radixsort.c.patch b/stdlib/FreeBSD/radixsort.c.patch index b47a976..60f3cd6 100644 --- a/stdlib/FreeBSD/radixsort.c.patch +++ b/stdlib/FreeBSD/radixsort.c.patch @@ -1,6 +1,14 @@ ---- radixsort.c.orig 2004-12-01 20:08:48.000000000 -0800 -+++ radixsort.c 2004-12-01 20:11:23.000000000 -0800 -@@ -64,7 +64,7 @@ +--- radixsort.c.orig 2010-06-21 14:05:02.000000000 -0700 ++++ radixsort.c 2010-06-21 14:26:55.000000000 -0700 +@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ + #include + #include + #include ++#include + + typedef struct { + const u_char **sa; +@@ -60,11 +61,17 @@ typedef struct { } stack; static inline void simplesort @@ -9,3 +17,68 @@ static void r_sort_a(const u_char **, int, int, const u_char *, u_int); static void r_sort_b(const u_char **, const u_char **, int, int, const u_char *, u_int); + ++static int *r_sort_a_count; ++static int *r_sort_b_count; ++ ++static void r_sort_count_allocate(void); ++static pthread_once_t r_sort_count_control = PTHREAD_ONCE_INIT; ++ + #define THRESHOLD 20 /* Divert to simplesort(). */ + #define SIZE 512 /* Default stack size. */ + +@@ -124,6 +131,12 @@ sradixsort(a, n, tab, endch) + return (0); + } + ++static void r_sort_count_allocate(void) ++{ ++ r_sort_a_count = calloc(256, sizeof(int)); ++ r_sort_b_count = calloc(256, sizeof(int)); ++} ++ + #define empty(s) (s >= sp) + #define pop(a, n, i) a = (--sp)->sa, n = sp->sn, i = sp->si + #define push(a, n, i) sp->sa = a, sp->sn = n, (sp++)->si = i +@@ -137,13 +150,19 @@ r_sort_a(a, n, i, tr, endch) + const u_char *tr; + u_int endch; + { +- static int count[256], nc, bmin; ++ static int *count, nc, bmin; + int c; + const u_char **ak, *r; + stack s[SIZE], *sp, *sp0, *sp1, temp; + int *cp, bigc; + const u_char **an, *t, **aj, **top[256]; + ++ if (pthread_once(&r_sort_count_control, r_sort_count_allocate)) { ++ return; ++ } ++ ++ count = r_sort_a_count; ++ + /* Set up stack. */ + sp = s; + push(a, n, i); +@@ -239,13 +258,19 @@ r_sort_b(a, ta, n, i, tr, endch) + const u_char *tr; + u_int endch; + { +- static int count[256], nc, bmin; ++ static int *count, nc, bmin; + int c; + const u_char **ak, **ai; + stack s[512], *sp, *sp0, *sp1, temp; + const u_char **top[256]; + int *cp, bigc; + ++ if (pthread_once(&r_sort_count_control, r_sort_count_allocate)) { ++ return; ++ } ++ ++ count = r_sort_b_count; ++ + sp = s; + push(a, n, i); + while (!empty(s)) { diff --git a/stdlib/FreeBSD/rand.3 b/stdlib/FreeBSD/rand.3 index 59e0ee2..f470523 100644 --- a/stdlib/FreeBSD/rand.3 +++ b/stdlib/FreeBSD/rand.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)rand.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/rand.3,v 1.14 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/rand.3,v 1.16 2007/01/09 00:28:10 imp Exp $ .\" .Dd May 25, 1999 .Dt RAND 3 @@ -91,8 +87,10 @@ The .Fn sranddev function initializes a seed using the .Xr random 4 -random number device which returns good random numbers, -suitable for cryptographic use. +random number device which returns good random numbers. +However, the +.Fn rand +function still remains unsuitable for cryptographic use. .Pp The .Fn rand_r diff --git a/stdlib/FreeBSD/rand.3.patch b/stdlib/FreeBSD/rand.3.patch index 6286a4b..f0944a2 100644 --- a/stdlib/FreeBSD/rand.3.patch +++ b/stdlib/FreeBSD/rand.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdlib/FreeBSD/rand.3 2004-11-25 11:38:42.000000000 -0800 -+++ _SB/Libc/stdlib/FreeBSD/rand.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -41,22 +41,30 @@ +--- rand.3.bsdnew 2009-11-13 14:11:50.000000000 -0800 ++++ rand.3 2009-11-13 14:11:50.000000000 -0800 +@@ -37,22 +37,30 @@ .Os .Sh NAME .Nm rand , @@ -39,16 +39,16 @@ .Sh DESCRIPTION .Bf -symbolic These interfaces are obsoleted by -@@ -89,7 +97,7 @@ +@@ -85,7 +93,7 @@ seeded with a value of 1. .Pp The .Fn sranddev -function initializes a seed using the +function initializes a seed, using the .Xr random 4 - random number device which returns good random numbers, - suitable for cryptographic use. -@@ -100,7 +108,7 @@ + random number device which returns good random numbers. + However, the +@@ -98,7 +106,7 @@ function provides the same functionality as .Fn rand . A pointer to the context value diff --git a/stdlib/FreeBSD/rand.c b/stdlib/FreeBSD/rand.c index 359e12a..fd9973f 100644 --- a/stdlib/FreeBSD/rand.c +++ b/stdlib/FreeBSD/rand.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -37,7 +33,7 @@ static char sccsid[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/rand.c,v 1.15 2003/02/17 03:52:35 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/rand.c,v 1.17 2007/12/11 20:39:32 ache Exp $"); #include "namespace.h" #include /* for sranddev() */ @@ -64,7 +60,7 @@ do_rand(unsigned long *ctx) #else /* !USE_WEAK_SEEDING */ /* * Compute x = (7^5 * x) mod (2^31 - 1) - * wihout overflowing 31 bits: + * without overflowing 31 bits: * (2^31 - 1) = 127773 * (7^5) + 2836 * From "Random number generators: good ones are hard to find", * Park and Miller, Communications of the ACM, vol. 31, no. 10, diff --git a/stdlib/FreeBSD/random.3 b/stdlib/FreeBSD/random.3 index 9af134b..4c3f061 100644 --- a/stdlib/FreeBSD/random.3 +++ b/stdlib/FreeBSD/random.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)random.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/random.3,v 1.20 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/random.3,v 1.22 2007/01/09 00:28:10 imp Exp $ .\" .Dd June 4, 1993 .Dt RANDOM 3 @@ -168,8 +164,6 @@ generator is greater than .if t 2\u\s769\s10\d, .if n 2**69 which should be sufficient for most purposes. -.Sh AUTHORS -.An Earl T. Cohen .Sh DIAGNOSTICS If .Fn initstate @@ -186,6 +180,8 @@ messages are printed on the standard error output. These functions appeared in .Bx 4.2 . +.Sh AUTHORS +.An Earl T. Cohen .Sh BUGS About 2/3 the speed of .Xr rand 3 . diff --git a/stdlib/FreeBSD/random.3.patch b/stdlib/FreeBSD/random.3.patch index 398385b..61c0621 100644 --- a/stdlib/FreeBSD/random.3.patch +++ b/stdlib/FreeBSD/random.3.patch @@ -1,6 +1,6 @@ ---- random.3 2004-11-25 11:38:42.000000000 -0800 -+++ random.3.edit 2006-07-12 11:25:20.000000000 -0700 -@@ -36,32 +36,45 @@ +--- random.3.orig 2010-04-28 23:38:47.000000000 -0700 ++++ random.3 2010-04-29 09:47:13.000000000 -0700 +@@ -32,32 +32,45 @@ .Dt RANDOM 3 .Os .Sh NAME @@ -58,7 +58,7 @@ numbers in the range from 0 to .if t 2\u\s731\s10\d\(mi1. .if n (2**31)\(mi1. -@@ -82,7 +95,7 @@ +@@ -78,7 +91,7 @@ The difference is that .Xr rand 3 produces a much less random sequence \(em in fact, the low dozen bits generated by rand go through a cyclic pattern. @@ -67,7 +67,24 @@ .Fn random are usable. For example, -@@ -102,7 +115,7 @@ +@@ -87,18 +100,21 @@ will produce a random binary + value. + .Pp + Like ++.Xr srand 3 , ++.Fn srandom ++sets the initial seed value for future calls to ++.Fn random . ++Like + .Xr rand 3 , + .Fn random + will by default produce a sequence of numbers that can be duplicated + by calling + .Fn srandom +-with +-.Ql 1 +-as the seed. ++with the same seed. .Pp The .Fn srandomdev @@ -76,7 +93,7 @@ .Xr random 4 random number device which returns good random numbers, suitable for cryptographic use. -@@ -127,7 +140,7 @@ +@@ -123,7 +139,7 @@ more state, the better the random number the nearest known amount. Using less than 8 bytes will cause an error.) The seed for the initialization (which specifies a starting point for @@ -85,16 +102,16 @@ point) is also an argument. The .Fn initstate -@@ -166,7 +179,7 @@ +@@ -162,7 +178,7 @@ it is initialized. With 256 bytes of state information, the period of the random number generator is greater than .if t 2\u\s769\s10\d, -.if n 2**69 +.if n 2**69 , which should be sufficient for most purposes. - .Sh AUTHORS - .An Earl T. Cohen -@@ -177,11 +190,36 @@ + .Sh DIAGNOSTICS + If +@@ -171,11 +187,36 @@ is called with less than 8 bytes of stat .Fn setstate detects that the state information has been garbled, error messages are printed on the standard error output. diff --git a/stdlib/FreeBSD/random.c b/stdlib/FreeBSD/random.c index f42436a..693550b 100644 --- a/stdlib/FreeBSD/random.c +++ b/stdlib/FreeBSD/random.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.24 2004/01/20 03:02:18 das Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.25 2007/01/09 00:28:10 imp Exp $"); #include "namespace.h" #include /* for srandomdev() */ diff --git a/stdlib/FreeBSD/random.c.patch b/stdlib/FreeBSD/random.c.patch index 2770cd5..d7feafa 100644 --- a/stdlib/FreeBSD/random.c.patch +++ b/stdlib/FreeBSD/random.c.patch @@ -1,8 +1,8 @@ ---- random.c.org 2006-09-08 18:48:58.000000000 -0700 -+++ random.c 2006-09-08 18:50:03.000000000 -0700 -@@ -37,6 +37,14 @@ +--- random.c.bsdnew 2009-11-13 14:11:50.000000000 -0800 ++++ random.c 2009-11-13 14:11:51.000000000 -0800 +@@ -33,6 +33,14 @@ static char sccsid[] = "@(#)random.c 8.2 #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.24 2004/01/20 03:02:18 das Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.25 2007/01/09 00:28:10 imp Exp $"); +/* + * We always compile with __DARWIN_UNIX03 set to one, relying on the fact that @@ -15,7 +15,7 @@ #include "namespace.h" #include /* for srandomdev() */ #include /* for srandomdev() */ -@@ -220,7 +228,7 @@ +@@ -216,7 +224,7 @@ static int rand_deg = DEG_3; static int rand_sep = SEP_3; static uint32_t *end_ptr = &randtbl[DEG_3 + 1]; @@ -24,7 +24,7 @@ static inline uint32_t good_rand (x) int32_t x; -@@ -269,7 +277,7 @@ +@@ -265,7 +273,7 @@ static inline uint32_t good_rand (x) */ void srandom(x) @@ -33,7 +33,7 @@ { int i, lim; -@@ -357,9 +365,9 @@ +@@ -353,9 +361,9 @@ srandomdev() */ char * initstate(seed, arg_state, n) @@ -45,7 +45,7 @@ { char *ostate = (char *)(&state[-1]); uint32_t *int_arg_state = (uint32_t *)arg_state; -@@ -425,7 +433,7 @@ +@@ -421,7 +429,7 @@ initstate(seed, arg_state, n) */ char * setstate(arg_state) diff --git a/stdlib/FreeBSD/realpath.3 b/stdlib/FreeBSD/realpath.3 index 5fe8c16..dc6ba9a 100644 --- a/stdlib/FreeBSD/realpath.3 +++ b/stdlib/FreeBSD/realpath.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)realpath.3 8.2 (Berkeley) 2/16/94 -.\" $FreeBSD: src/lib/libc/stdlib/realpath.3,v 1.13 2003/03/27 20:48:53 fjoe Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/realpath.3,v 1.14 2007/01/09 00:28:10 imp Exp $ .\" .Dd February 16, 1994 .Dt REALPATH 3 diff --git a/stdlib/FreeBSD/realpath.3.patch b/stdlib/FreeBSD/realpath.3.patch index 5e240fc..f253985 100644 --- a/stdlib/FreeBSD/realpath.3.patch +++ b/stdlib/FreeBSD/realpath.3.patch @@ -1,8 +1,8 @@ ---- realpath.3.orig 2008-04-05 00:03:06.000000000 -0700 -+++ realpath.3 2008-04-05 17:42:41.000000000 -0700 -@@ -35,63 +35,73 @@ +--- realpath.3.bsdnew 2009-11-13 14:11:51.000000000 -0800 ++++ realpath.3 2009-11-13 14:11:51.000000000 -0800 +@@ -31,63 +31,73 @@ .\" @(#)realpath.3 8.2 (Berkeley) 2/16/94 - .\" $FreeBSD: src/lib/libc/stdlib/realpath.3,v 1.13 2003/03/27 20:48:53 fjoe Exp $ + .\" $FreeBSD: src/lib/libc/stdlib/realpath.3,v 1.14 2007/01/09 00:28:10 imp Exp $ .\" -.Dd February 16, 1994 +.Dd April 5, 2008 @@ -97,7 +97,7 @@ contains the pathname which caused the problem. .Sh ERRORS The function -@@ -99,24 +109,44 @@ +@@ -95,24 +105,44 @@ The function may fail and set the external variable .Va errno for any of the errors specified for the library functions diff --git a/stdlib/FreeBSD/realpath.c.patch b/stdlib/FreeBSD/realpath.c.patch index 2d154b1..604474d 100644 --- a/stdlib/FreeBSD/realpath.c.patch +++ b/stdlib/FreeBSD/realpath.c.patch @@ -1,5 +1,5 @@ ---- realpath.c.orig 2008-04-04 14:39:39.000000000 -0700 -+++ realpath.c 2008-04-04 19:59:19.000000000 -0700 +--- realpath.c.orig 2010-06-24 17:32:55.000000000 -0700 ++++ realpath.c 2010-06-25 13:46:50.000000000 -0700 @@ -35,13 +35,41 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ #include "namespace.h" #include @@ -42,7 +42,7 @@ /* * char *realpath(const char *path, char resolved[PATH_MAX]); * -@@ -50,26 +78,67 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ +@@ -50,36 +78,89 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ * in which case the path which caused trouble is left in (resolved). */ char * @@ -77,18 +77,23 @@ +#endif /* __DARWIN_UNIX03 */ + /* + * Extension to the standard; if inresolved == NULL, allocate memory -+ * (first on the stack, then use strdup()) + */ + if (!inresolved) { -+ if ((resolved = alloca(PATH_MAX)) == NULL) return (NULL); ++ if ((resolved = malloc(PATH_MAX)) == NULL) return (NULL); + } else { + resolved = inresolved; + } + if (!rootdev_inited) { + rootdev_inited = 1; + if (stat("/", &sb) < 0) { -+ return (NULL); ++error_return: ++ if (!inresolved) { ++ int e = errno; ++ free(resolved); ++ errno = e; + } ++ return (NULL); ++ } + rootdev = sb.st_dev; + } serrno = errno; @@ -113,15 +118,20 @@ +#endif /* !VARIANT_DARWINEXTSN && __DARWIN_UNIX03 */ + { strlcpy(resolved, ".", PATH_MAX); - return (NULL); +- return (NULL); ++ goto error_return; } -@@ -80,6 +149,13 @@ realpath(const char *path, char resolved + resolved_len = strlen(resolved); + left_len = strlcpy(left, path, sizeof(left)); + } + if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; - return (NULL); +- return (NULL); ++ goto error_return; } + if (resolved_len > 1) { + if (stat(resolved, &sb) < 0) { -+ return (NULL); ++ goto error_return; + } + lastdev = sb.st_dev; + } else @@ -129,7 +139,25 @@ /* * Iterate over path components in `left'. -@@ -127,6 +203,13 @@ realpath(const char *path, char resolved +@@ -93,7 +174,7 @@ realpath(const char *path, char resolved + s = p ? p : left + left_len; + if (s - left >= sizeof(next_token)) { + errno = ENAMETOOLONG; +- return (NULL); ++ goto error_return; + } + memcpy(next_token, left, s - left); + next_token[s - left] = '\0'; +@@ -103,7 +184,7 @@ realpath(const char *path, char resolved + if (resolved[resolved_len - 1] != '/') { + if (resolved_len + 1 >= PATH_MAX) { + errno = ENAMETOOLONG; +- return (NULL); ++ goto error_return; + } + resolved[resolved_len++] = '/'; + resolved[resolved_len] = '\0'; +@@ -127,6 +208,13 @@ realpath(const char *path, char resolved } /* @@ -143,9 +171,12 @@ * Append the next path component and lstat() it. If * lstat() fails we still can return successfully if * there are no more path components left. -@@ -136,25 +219,87 @@ realpath(const char *path, char resolved +@@ -134,27 +222,89 @@ realpath(const char *path, char resolved + resolved_len = strlcat(resolved, next_token, PATH_MAX); + if (resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; - return (NULL); +- return (NULL); ++ goto error_return; } - if (lstat(resolved, &sb) != 0) { + if (getattrlist(resolved, &_rp_alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) { @@ -167,8 +198,9 @@ errno = serrno; return (resolved); } +- return (NULL); +#endif /* !__DARWIN_UNIX03 */ - return (NULL); ++ goto error_return; } - if (S_ISLNK(sb.st_mode)) { + if (dev != lastdev) { @@ -219,12 +251,14 @@ + if (islink) { if (symlinks++ > MAXSYMLINKS) { errno = ELOOP; - return (NULL); +- return (NULL); ++ goto error_return; } slen = readlink(resolved, symlink, sizeof(symlink) - 1); - if (slen < 0) +- return (NULL); + if (slen < 0) { - return (NULL); ++ goto error_return; + } symlink[slen] = '\0'; if (symlink[0] == '/') { @@ -234,7 +268,21 @@ } else if (resolved_len > 1) { /* Strip the last path component. */ resolved[resolved_len - 1] = '\0'; -@@ -184,7 +329,30 @@ realpath(const char *path, char resolved +@@ -172,7 +322,7 @@ realpath(const char *path, char resolved + if (symlink[slen - 1] != '/') { + if (slen + 1 >= sizeof(symlink)) { + errno = ENAMETOOLONG; +- return (NULL); ++ goto error_return; + } + symlink[slen] = '/'; + symlink[slen + 1] = 0; +@@ -180,11 +330,34 @@ realpath(const char *path, char resolved + left_len = strlcat(symlink, left, sizeof(left)); + if (left_len >= sizeof(left)) { + errno = ENAMETOOLONG; +- return (NULL); ++ goto error_return; } } left_len = strlcpy(left, symlink, sizeof(left)); @@ -247,7 +295,7 @@ + resolved_len = strlcat(resolved, (const char *)&attrs.name + attrs.name.attr_dataoffset, PATH_MAX); + if (resolved_len >= PATH_MAX) { + errno = ENAMETOOLONG; -+ return (NULL); ++ goto error_return; + } } + /* @@ -265,10 +313,3 @@ } /* -@@ -193,5 +361,6 @@ realpath(const char *path, char resolved - */ - if (resolved_len > 1 && resolved[resolved_len - 1] == '/') - resolved[resolved_len - 1] = '\0'; -+ if (!inresolved) resolved = strdup(resolved); - return (resolved); - } diff --git a/stdlib/FreeBSD/setenv.c b/stdlib/FreeBSD/setenv.c index d7c0394..6e0596e 100644 --- a/stdlib/FreeBSD/setenv.c +++ b/stdlib/FreeBSD/setenv.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)setenv.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/setenv.c,v 1.9 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/setenv.c,v 1.14 2007/05/01 16:02:41 ache Exp $"); #include #include diff --git a/stdlib/FreeBSD/setenv.c.patch b/stdlib/FreeBSD/setenv.c.patch index bbdda18..4d46b4f 100644 --- a/stdlib/FreeBSD/setenv.c.patch +++ b/stdlib/FreeBSD/setenv.c.patch @@ -1,8 +1,6 @@ -Index: setenv.c -=================================================================== ---- setenv.c (revision 41051) -+++ setenv.c (working copy) -@@ -40,32 +40,79 @@ +--- setenv.c.orig 2011-04-13 01:21:14.000000000 -0700 ++++ setenv.c 2011-04-13 14:44:04.000000000 -0700 +@@ -36,32 +36,115 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ #include #include #include @@ -14,23 +12,59 @@ Index: setenv.c -char *__findenv(const char *, int *); +#define ZONE_OWNS_PTR(zone, ptr) (malloc_zone_from_ptr((ptr)) == zone) - ++ +extern malloc_zone_t *__zone0; +extern void __malloc_check_env_name(const char *); + +__private_extern__ char *__findenv(const char *, int *, char **); +__private_extern__ int __setenv(const char *, const char *, int, int, char ***, malloc_zone_t *); +__private_extern__ void __unsetenv(const char *, char **, malloc_zone_t *); -+ -+#ifndef BUILDING_VARIANT ++__private_extern__ int init__zone0(int); + /* - * setenv -- - * Set the value of the environmental variable "name" to be - * "value". If rewrite is set, replace any current value. -+ * Create the environment malloc zone and give it a recognizable name. ++ * _cthread_init_routine used to be called from crt1.o to initialize threads. ++ * This is no longer needed, as initialization happens in dylib initializers, ++ * but is provided to maintain backwards compatibility. Normally, for 10.5 ++ * or greater, _cthread_init_routine does nothing. ++ * ++ * Before 10.5, the _start routine in crt1.o clobbers environ with the original ++ * stack value, which effectively undoes any environment changes made in ++ * initializers. When LEGACY_CRT1_ENVIRON is defined, we replace the ++ * do-nothing routine with one that attempts to restore the environ value. ++ * But this only works if the setenv (and family) routines were used ++ * exclusively, (no direct manipulation of environ). Note that according to ++ * SUSv3, direct manipulation of environ may result in undefined behavior in ++ * setenv and family, so we don't support that (on less than 10.5). */ -int -setenv(name, value, rewrite) ++#ifdef BUILDING_VARIANT ++# ifdef LEGACY_CRT1_ENVIRON ++extern char **_saved_environ; ++# endif /* LEGACY_CRT1_ENVIRON */ ++#else /* !BUILDING_VARIANT */ ++# ifdef LEGACY_CRT1_ENVIRON ++__private_extern__ char **_saved_environ = NULL; ++ ++static int ++_legacy_crt1_environ(void) ++{ ++ if (_saved_environ) *_NSGetEnviron() = _saved_environ; ++ return 0; ++} ++int (*_cthread_init_routine)(void) = _legacy_crt1_environ; ++ ++# else /* !LEGACY_CRT1_ENVIRON */ ++static int _do_nothing(void) { return 0; } ++int (*_cthread_init_routine)(void) = _do_nothing; ++# endif /* !LEGACY_CRT1_ENVIRON */ ++ ++/* ++ * Create the environment malloc zone and give it a recognizable name. ++ */ +__private_extern__ int +init__zone0(int should_set_errno) +{ @@ -97,7 +131,7 @@ Index: setenv.c while ( (*c++ = *value++) ); return (0); } -@@ -73,48 +120,225 @@ +@@ -69,48 +152,235 @@ setenv(name, value, rewrite) int cnt; char **p; @@ -178,7 +212,7 @@ Index: setenv.c +} + +/****************************************************************************/ - /* ++/* + * _allocenvstate -- SPI that creates a new state (opaque) + */ +void * @@ -276,6 +310,10 @@ Index: setenv.c + const char *value; + int rewrite; +{ ++#ifdef LEGACY_CRT1_ENVIRON ++ int ret; ++#endif /* LEGACY_CRT1_ENVIRON */ ++ + /* no null ptr or empty str */ + if(name == NULL || *name == 0) { + errno = EINVAL; @@ -295,10 +333,16 @@ Index: setenv.c + /* insure __zone0 is set up before calling __malloc_check_env_name */ + if (init__zone0(1)) return (-1); + __malloc_check_env_name(name); /* see if we are changing a malloc environment variable */ ++#ifdef LEGACY_CRT1_ENVIRON ++ ret = __setenv(name, value, rewrite, 1, _NSGetEnviron(), __zone0); ++ _saved_environ = *_NSGetEnviron(); ++ return ret; ++#else /* !LEGACY_CRT1_ENVIRON */ + return (__setenv(name, value, rewrite, 1, _NSGetEnviron(), __zone0)); ++#endif /* !LEGACY_CRT1_ENVIRON */ +} + -+/* + /* * unsetenv(name) -- * Delete environmental variable "name". */ diff --git a/stdlib/FreeBSD/strtod.3 b/stdlib/FreeBSD/strtod.3 index f40d896..42352b3 100644 --- a/stdlib/FreeBSD/strtod.3 +++ b/stdlib/FreeBSD/strtod.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtod.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/strtod.3,v 1.19 2003/05/22 13:02:28 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strtod.3,v 1.22 2007/12/16 21:19:28 das Exp $ .\" .Dd March 2, 2003 .Dt STRTOD 3 @@ -90,8 +86,28 @@ For hexadecimal constants, the scaling is instead done by powers of 2. .Pp Alternatively, if the portion of the string following the optional -plus or minus sign begins with ``INFINITY'' or ``NAN'', ignoring -case, it is interpreted as an infinity or a quiet NaN, respectively. +plus or minus sign begins with +.Dq INFINITY +or +.Dq NAN , +ignoring case, it is interpreted as an infinity or a quiet \*(Na, +respectively. +The syntax +.Dq Xo Pf NAN( Ar "s" ) Xc , +where +.Ar s +is an alphanumeric string, produces the same value as the call +.Fo nan +.Qq Ar s Ns +.Fc +(respectively, +.Fo nanf +.Qq Ar s Ns +.Fc +and +.Fo nanl +.Qq Ar s Ns +.Fc . ) .Pp In any of the above cases, leading white-space characters in the string (as defined by the @@ -144,6 +160,7 @@ Overflow or underflow occurred. .Xr atof 3 , .Xr atoi 3 , .Xr atol 3 , +.Xr nan 3 , .Xr strtol 3 , .Xr strtoul 3 , .Xr wcstod 3 @@ -154,8 +171,6 @@ function conforms to .St -isoC-99 , with the exception of the bug noted below. -.Sh BUGS -These routines do not recognize the C99 ``NaN(...)'' syntax. .Sh AUTHORS The author of this software is .An David M. Gay . diff --git a/stdlib/FreeBSD/strtod.3.patch b/stdlib/FreeBSD/strtod.3.patch index 091602a..600a792 100644 --- a/stdlib/FreeBSD/strtod.3.patch +++ b/stdlib/FreeBSD/strtod.3.patch @@ -1,6 +1,6 @@ ---- strtod.3 2004-11-25 11:38:42.000000000 -0800 -+++ strtod.3.edit 2006-08-09 13:42:36.000000000 -0700 -@@ -49,11 +49,20 @@ +--- strtod.3.orig 2010-04-29 10:40:21.000000000 -0700 ++++ strtod.3 2010-04-29 10:40:42.000000000 -0700 +@@ -45,11 +45,20 @@ string to floating point .Sh SYNOPSIS .In stdlib.h .Ft double @@ -24,7 +24,7 @@ .Sh DESCRIPTION These conversion functions convert the initial portion of the string -@@ -66,16 +75,17 @@ +@@ -62,16 +71,17 @@ and .Vt "long double" representation, respectively. .Pp @@ -49,7 +49,7 @@ .El .Pp In both cases, the significand may be optionally followed by an -@@ -100,6 +110,12 @@ +@@ -116,6 +126,12 @@ function) are skipped. The decimal point character is defined in the program's locale (category .Dv LC_NUMERIC ) . @@ -62,11 +62,21 @@ .Sh RETURN VALUES The .Fn strtod , -@@ -144,6 +160,7 @@ - .Xr atof 3 , +@@ -161,6 +177,7 @@ Overflow or underflow occurred. .Xr atoi 3 , .Xr atol 3 , + .Xr nan 3 , +.Xr strtod_l 3 , .Xr strtol 3 , .Xr strtoul 3 , .Xr wcstod 3 +@@ -169,8 +186,7 @@ The + .Fn strtod + function + conforms to +-.St -isoC-99 , +-with the exception of the bug noted below. ++.St -isoC-99 . + .Sh AUTHORS + The author of this software is + .An David M. Gay . diff --git a/stdlib/FreeBSD/strtoimax.c b/stdlib/FreeBSD/strtoimax.c index c57d044..09e073f 100644 --- a/stdlib/FreeBSD/strtoimax.c +++ b/stdlib/FreeBSD/strtoimax.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "from @(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoimax.c,v 1.9 2003/01/01 18:48:43 schweikh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoimax.c,v 1.12 2007/01/09 00:28:10 imp Exp $"); #include #include @@ -75,7 +71,10 @@ strtoimax(const char * __restrict nptr, char ** __restrict endptr, int base) c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/FreeBSD/strtoimax.c.patch b/stdlib/FreeBSD/strtoimax.c.patch index 4ef7931..5725b73 100644 --- a/stdlib/FreeBSD/strtoimax.c.patch +++ b/stdlib/FreeBSD/strtoimax.c.patch @@ -1,15 +1,15 @@ ---- strtoimax.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ strtoimax.c 2005-02-23 13:20:23.000000000 -0800 -@@ -37,6 +37,8 @@ +--- strtoimax.c.bsdnew 2009-11-13 14:11:51.000000000 -0800 ++++ strtoimax.c 2009-11-13 14:11:51.000000000 -0800 +@@ -33,6 +33,8 @@ static char sccsid[] = "from @(#)strtol. #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoimax.c,v 1.9 2003/01/01 18:48:43 schweikh Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoimax.c,v 1.12 2007/01/09 00:28:10 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -49,7 +51,8 @@ +@@ -45,7 +47,8 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ * alphabets and digits are each contiguous. */ intmax_t @@ -19,7 +19,7 @@ { const char *s; uintmax_t acc; -@@ -57,6 +60,7 @@ +@@ -53,6 +56,7 @@ strtoimax(const char * __restrict nptr, uintmax_t cutoff; int neg, any, cutlim; @@ -27,7 +27,7 @@ /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else -@@ -65,7 +69,7 @@ +@@ -61,7 +65,7 @@ strtoimax(const char * __restrict nptr, s = nptr; do { c = *s++; @@ -36,7 +36,7 @@ if (c == '-') { neg = 1; c = *s++; -@@ -139,3 +143,9 @@ +@@ -138,3 +142,9 @@ noconv: *endptr = (char *)(any ? s - 1 : nptr); return (acc); } diff --git a/stdlib/FreeBSD/strtol.3 b/stdlib/FreeBSD/strtol.3 index aa92717..42f7db3 100644 --- a/stdlib/FreeBSD/strtol.3 +++ b/stdlib/FreeBSD/strtol.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtol.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/strtol.3,v 1.20 2005/01/22 18:02:58 ache Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strtol.3,v 1.23 2007/04/10 11:17:00 ru Exp $ .\" .Dd November 28, 2001 .Dt STRTOL 3 @@ -181,8 +177,8 @@ is set to .Er ERANGE and the function return value is clamped according to the following table. -.Bl -column -offset indent ".Fn strtoimax" ".Sy overflow" ".Sy underflow" -.It Sy Function Ta Sy overflow Ta Sy underflow +.Bl -column -offset indent ".Fn strtoimax" ".Sy underflow" ".Sy overflow" +.It Sy Function Ta Sy underflow Ta Sy overflow .It Fn strtol Ta Dv LONG_MIN Ta Dv LONG_MAX .It Fn strtoll Ta Dv LLONG_MIN Ta Dv LLONG_MAX .It Fn strtoimax Ta Dv INTMAX_MIN Ta Dv INTMAX_MAX @@ -204,6 +200,7 @@ The given string was out of range; the value converted has been clamped. .Xr atoi 3 , .Xr atol 3 , .Xr strtod 3 , +.Xr strtonum 3 , .Xr strtoul 3 , .Xr wcstol 3 .Sh STANDARDS diff --git a/stdlib/FreeBSD/strtol.3.patch b/stdlib/FreeBSD/strtol.3.patch index 489f5e9..befb02b 100644 --- a/stdlib/FreeBSD/strtol.3.patch +++ b/stdlib/FreeBSD/strtol.3.patch @@ -1,6 +1,6 @@ ---- strtol.3 2006-02-14 14:41:58.000000000 -0800 -+++ strtol.3.edit 2006-08-09 13:42:57.000000000 -0700 -@@ -40,7 +40,10 @@ +--- strtol.3.bsdnew 2009-11-13 14:11:51.000000000 -0800 ++++ strtol.3 2009-11-13 14:33:25.000000000 -0800 +@@ -36,7 +36,10 @@ .Dt STRTOL 3 .Os .Sh NAME @@ -12,7 +12,7 @@ .Nd "convert a string value to a" .Vt long , "long long" , intmax_t or -@@ -49,26 +52,41 @@ +@@ -45,26 +48,41 @@ integer .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -62,7 +62,7 @@ to a .Vt long value. -@@ -76,7 +94,7 @@ +@@ -72,7 +90,7 @@ The .Fn strtoll function converts the string in @@ -71,7 +71,7 @@ to a .Vt "long long" value. -@@ -84,7 +102,7 @@ +@@ -80,7 +98,7 @@ The .Fn strtoimax function converts the string in @@ -80,7 +80,7 @@ to an .Vt intmax_t value. -@@ -92,7 +110,7 @@ +@@ -88,7 +106,7 @@ The .Fn strtoq function converts the string in @@ -89,7 +89,7 @@ to a .Vt quad_t value. -@@ -147,11 +165,11 @@ +@@ -143,11 +161,11 @@ stores the address of the first invalid If there were no digits at all, however, .Fn strtol stores the original value of @@ -103,7 +103,7 @@ is not .Ql \e0 but -@@ -159,11 +177,17 @@ +@@ -155,11 +173,17 @@ but is .Ql \e0 on return, the entire string was valid.) @@ -122,18 +122,16 @@ and .Fn strtoq functions -@@ -181,8 +205,8 @@ +@@ -177,7 +201,7 @@ is set to .Er ERANGE and the function return value is clamped according to the following table. --.Bl -column -offset indent ".Fn strtoimax" ".Sy overflow" ".Sy underflow" --.It Sy Function Ta Sy overflow Ta Sy underflow +-.Bl -column -offset indent ".Fn strtoimax" ".Sy underflow" ".Sy overflow" +.Bl -column -offset indent ".Fn strtoimax" ".Dv INTMAX_MIN" ".Dv INTMAX_MAX" -+.It Sy Function Ta Sy underflow Ta Sy overflow + .It Sy Function Ta Sy underflow Ta Sy overflow .It Fn strtol Ta Dv LONG_MIN Ta Dv LONG_MAX .It Fn strtoll Ta Dv LLONG_MIN Ta Dv LLONG_MAX - .It Fn strtoimax Ta Dv INTMAX_MIN Ta Dv INTMAX_MAX -@@ -199,13 +223,25 @@ +@@ -195,14 +219,25 @@ no conversion could be performed .It Bq Er ERANGE The given string was out of range; the value converted has been clamped. .El @@ -152,6 +150,7 @@ .Xr atoi 3 , .Xr atol 3 , .Xr strtod 3 , +-.Xr strtonum 3 , +.Xr strtol_l 3 , .Xr strtoul 3 , -.Xr wcstol 3 diff --git a/stdlib/FreeBSD/strtol.c b/stdlib/FreeBSD/strtol.c index 2b3fcf4..6bb1551 100644 --- a/stdlib/FreeBSD/strtol.c +++ b/stdlib/FreeBSD/strtol.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtol.c,v 1.17 2002/09/06 11:23:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtol.c,v 1.20 2007/01/09 00:28:10 imp Exp $"); #include #include @@ -76,7 +72,10 @@ strtol(const char * __restrict nptr, char ** __restrict endptr, int base) c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/FreeBSD/strtol.c.patch b/stdlib/FreeBSD/strtol.c.patch index 3558818..d968ad7 100644 --- a/stdlib/FreeBSD/strtol.c.patch +++ b/stdlib/FreeBSD/strtol.c.patch @@ -1,15 +1,15 @@ ---- strtol.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ strtol.c 2005-02-17 00:43:42.000000000 -0800 -@@ -37,6 +37,8 @@ +--- strtol.c.bsdnew 2009-11-13 14:11:51.000000000 -0800 ++++ strtol.c 2009-11-13 14:11:51.000000000 -0800 +@@ -33,6 +33,8 @@ static char sccsid[] = "@(#)strtol.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtol.c,v 1.17 2002/09/06 11:23:59 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtol.c,v 1.20 2007/01/09 00:28:10 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -50,7 +52,8 @@ +@@ -46,7 +48,8 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ * alphabets and digits are each contiguous. */ long @@ -19,7 +19,7 @@ { const char *s; unsigned long acc; -@@ -58,6 +61,7 @@ +@@ -54,6 +57,7 @@ strtol(const char * __restrict nptr, cha unsigned long cutoff; int neg, any, cutlim; @@ -27,7 +27,7 @@ /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else -@@ -66,7 +70,7 @@ +@@ -62,7 +66,7 @@ strtol(const char * __restrict nptr, cha s = nptr; do { c = *s++; @@ -36,7 +36,7 @@ if (c == '-') { neg = 1; c = *s++; -@@ -139,3 +143,9 @@ +@@ -138,3 +142,9 @@ noconv: *endptr = (char *)(any ? s - 1 : nptr); return (acc); } diff --git a/stdlib/FreeBSD/strtoll.c b/stdlib/FreeBSD/strtoll.c index cff57d9..80dac67 100644 --- a/stdlib/FreeBSD/strtoll.c +++ b/stdlib/FreeBSD/strtoll.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.19 2002/09/06 11:23:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.22 2007/01/09 00:28:10 imp Exp $"); #include #include @@ -75,7 +71,10 @@ strtoll(const char * __restrict nptr, char ** __restrict endptr, int base) c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/FreeBSD/strtoll.c.patch b/stdlib/FreeBSD/strtoll.c.patch index 6eb5d1a..9510635 100644 --- a/stdlib/FreeBSD/strtoll.c.patch +++ b/stdlib/FreeBSD/strtoll.c.patch @@ -1,15 +1,15 @@ ---- strtoll.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ strtoll.c 2005-02-17 00:46:45.000000000 -0800 -@@ -37,6 +37,8 @@ +--- strtoll.c.bsdnew 2009-11-13 14:11:51.000000000 -0800 ++++ strtoll.c 2009-11-13 14:11:51.000000000 -0800 +@@ -33,6 +33,8 @@ static char sccsid[] = "@(#)strtoq.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.19 2002/09/06 11:23:59 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.22 2007/01/09 00:28:10 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -49,7 +51,8 @@ +@@ -45,7 +47,8 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ * alphabets and digits are each contiguous. */ long long @@ -19,7 +19,7 @@ { const char *s; unsigned long long acc; -@@ -57,6 +60,7 @@ +@@ -53,6 +56,7 @@ strtoll(const char * __restrict nptr, ch unsigned long long cutoff; int neg, any, cutlim; @@ -27,7 +27,7 @@ /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else -@@ -65,7 +69,7 @@ +@@ -61,7 +65,7 @@ strtoll(const char * __restrict nptr, ch s = nptr; do { c = *s++; @@ -36,7 +36,7 @@ if (c == '-') { neg = 1; c = *s++; -@@ -139,3 +143,9 @@ +@@ -138,3 +142,9 @@ noconv: *endptr = (char *)(any ? s - 1 : nptr); return (acc); } diff --git a/stdlib/FreeBSD/strtoq.c b/stdlib/FreeBSD/strtoq.c index 6e8bcb8..0d101d5 100644 --- a/stdlib/FreeBSD/strtoq.c +++ b/stdlib/FreeBSD/strtoq.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoq.c,v 1.11 2002/08/15 09:25:04 robert Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoq.c,v 1.12 2007/01/09 00:28:10 imp Exp $"); #include diff --git a/stdlib/FreeBSD/strtoq.c.patch b/stdlib/FreeBSD/strtoq.c.patch index 7daea36..b5a517d 100644 --- a/stdlib/FreeBSD/strtoq.c.patch +++ b/stdlib/FreeBSD/strtoq.c.patch @@ -1,15 +1,15 @@ ---- strtoq.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ strtoq.c 2005-02-23 18:26:32.000000000 -0800 -@@ -37,6 +37,8 @@ +--- strtoq.c.bsdnew 2009-11-13 14:11:51.000000000 -0800 ++++ strtoq.c 2009-11-13 14:11:51.000000000 -0800 +@@ -33,6 +33,8 @@ static char sccsid[] = "@(#)strtoq.c 8.1 #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoq.c,v 1.11 2002/08/15 09:25:04 robert Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoq.c,v 1.12 2007/01/09 00:28:10 imp Exp $"); +#include "xlocale_private.h" + #include #include -@@ -48,5 +50,13 @@ +@@ -44,5 +46,13 @@ quad_t strtoq(const char *nptr, char **endptr, int base) { diff --git a/stdlib/FreeBSD/strtoul.3 b/stdlib/FreeBSD/strtoul.3 index 48bf05c..adc6643 100644 --- a/stdlib/FreeBSD/strtoul.3 +++ b/stdlib/FreeBSD/strtoul.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtoul.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/strtoul.3,v 1.20 2002/10/10 04:31:57 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strtoul.3,v 1.23 2007/01/09 00:28:10 imp Exp $ .\" .Dd November 28, 2001 .Dt STRTOUL 3 @@ -192,19 +188,22 @@ If no conversion could be performed, 0 is returned and the global variable .Va errno is set to -.Er EINVAL . +.Er EINVAL +(the last feature is not portable across all platforms). .Sh ERRORS .Bl -tag -width Er .It Bq Er EINVAL The value of .Fa base is not supported or -no conversion could be performed. +no conversion could be performed +(the last feature is not portable across all platforms). .It Bq Er ERANGE The given string was out of range; the value converted has been clamped. .El .Sh SEE ALSO .Xr strtol 3 , +.Xr strtonum 3 , .Xr wcstoul 3 .Sh STANDARDS The diff --git a/stdlib/FreeBSD/strtoul.3.patch b/stdlib/FreeBSD/strtoul.3.patch index f863d93..e9730cd 100644 --- a/stdlib/FreeBSD/strtoul.3.patch +++ b/stdlib/FreeBSD/strtoul.3.patch @@ -1,6 +1,6 @@ ---- strtoul.3 2003-05-20 15:23:25.000000000 -0700 -+++ strtoul.3.edit 2006-08-09 13:43:16.000000000 -0700 -@@ -40,7 +40,10 @@ +--- strtoul.3.bsdnew 2009-11-13 14:11:51.000000000 -0800 ++++ strtoul.3 2009-11-13 14:40:07.000000000 -0800 +@@ -36,7 +36,10 @@ .Dt STRTOUL 3 .Os .Sh NAME @@ -12,7 +12,7 @@ .Nd "convert a string to an" .Vt "unsigned long" , "unsigned long long" , uintmax_t , or -@@ -50,25 +53,40 @@ +@@ -46,25 +49,40 @@ integer .Lb libc .Sh SYNOPSIS .In stdlib.h @@ -59,7 +59,7 @@ to an .Vt "unsigned long" value. -@@ -76,7 +94,7 @@ +@@ -72,7 +90,7 @@ The .Fn strtoull function converts the string in @@ -68,7 +68,7 @@ to an .Vt "unsigned long long" value. -@@ -84,7 +102,7 @@ +@@ -80,7 +98,7 @@ The .Fn strtoumax function converts the string in @@ -77,7 +77,7 @@ to an .Vt uintmax_t value. -@@ -92,7 +110,7 @@ +@@ -88,7 +106,7 @@ The .Fn strtouq function converts the string in @@ -86,7 +86,7 @@ to a .Vt u_quad_t value. -@@ -146,11 +164,11 @@ +@@ -142,11 +160,11 @@ stores the address of the first invalid If there were no digits at all, however, .Fn strtoul stores the original value of @@ -100,7 +100,7 @@ is not .Ql \e0 but -@@ -203,9 +221,21 @@ +@@ -201,10 +219,22 @@ no conversion could be performed .It Bq Er ERANGE The given string was out of range; the value converted has been clamped. .El @@ -116,8 +116,9 @@ +functions. .Sh SEE ALSO .Xr strtol 3 , --.Xr wcstoul 3 +.Xr strtol_l 3 , + .Xr strtonum 3 , +-.Xr wcstoul 3 +.Xr wcstoul 3 , +.Xr compat 5 .Sh STANDARDS diff --git a/stdlib/FreeBSD/strtoul.c b/stdlib/FreeBSD/strtoul.c index 40eeba3..76cd7b0 100644 --- a/stdlib/FreeBSD/strtoul.c +++ b/stdlib/FreeBSD/strtoul.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoul.c,v 1.16 2002/09/06 11:23:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoul.c,v 1.19 2007/01/09 00:28:10 imp Exp $"); #include #include @@ -73,7 +69,10 @@ strtoul(const char * __restrict nptr, char ** __restrict endptr, int base) c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/FreeBSD/strtoul.c.patch b/stdlib/FreeBSD/strtoul.c.patch index 03ed531..9c56431 100644 --- a/stdlib/FreeBSD/strtoul.c.patch +++ b/stdlib/FreeBSD/strtoul.c.patch @@ -1,15 +1,15 @@ ---- strtoul.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ strtoul.c 2005-02-17 12:52:46.000000000 -0800 -@@ -37,6 +37,8 @@ +--- strtoul.c.bsdnew 2009-11-13 14:11:52.000000000 -0800 ++++ strtoul.c 2009-11-13 14:11:52.000000000 -0800 +@@ -33,6 +33,8 @@ static char sccsid[] = "@(#)strtoul.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoul.c,v 1.16 2002/09/06 11:23:59 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoul.c,v 1.19 2007/01/09 00:28:10 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -49,7 +51,8 @@ +@@ -45,7 +47,8 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ * alphabets and digits are each contiguous. */ unsigned long @@ -19,7 +19,7 @@ { const char *s; unsigned long acc; -@@ -57,13 +60,14 @@ +@@ -53,13 +56,14 @@ strtoul(const char * __restrict nptr, ch unsigned long cutoff; int neg, any, cutlim; @@ -35,7 +35,7 @@ if (c == '-') { neg = 1; c = *s++; -@@ -117,3 +121,9 @@ +@@ -116,3 +120,9 @@ noconv: *endptr = (char *)(any ? s - 1 : nptr); return (acc); } diff --git a/stdlib/FreeBSD/strtoull.c b/stdlib/FreeBSD/strtoull.c index 43f3138..38d6194 100644 --- a/stdlib/FreeBSD/strtoull.c +++ b/stdlib/FreeBSD/strtoull.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.18 2002/09/06 11:23:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.21 2007/01/09 00:28:10 imp Exp $"); #include #include @@ -73,7 +69,10 @@ strtoull(const char * __restrict nptr, char ** __restrict endptr, int base) c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/FreeBSD/strtoull.c.patch b/stdlib/FreeBSD/strtoull.c.patch index 244fac2..fac7b63 100644 --- a/stdlib/FreeBSD/strtoull.c.patch +++ b/stdlib/FreeBSD/strtoull.c.patch @@ -1,15 +1,15 @@ ---- strtoull.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ strtoull.c 2005-02-17 00:52:41.000000000 -0800 -@@ -37,6 +37,8 @@ +--- strtoull.c.bsdnew 2009-11-13 14:11:52.000000000 -0800 ++++ strtoull.c 2009-11-13 14:11:52.000000000 -0800 +@@ -33,6 +33,8 @@ static char sccsid[] = "@(#)strtouq.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.18 2002/09/06 11:23:59 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.21 2007/01/09 00:28:10 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -49,7 +51,8 @@ +@@ -45,7 +47,8 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ * alphabets and digits are each contiguous. */ unsigned long long @@ -19,7 +19,7 @@ { const char *s; unsigned long long acc; -@@ -57,13 +60,14 @@ +@@ -53,13 +56,14 @@ strtoull(const char * __restrict nptr, c unsigned long long cutoff; int neg, any, cutlim; @@ -35,7 +35,7 @@ if (c == '-') { neg = 1; c = *s++; -@@ -117,3 +121,9 @@ +@@ -116,3 +120,9 @@ noconv: *endptr = (char *)(any ? s - 1 : nptr); return (acc); } diff --git a/stdlib/FreeBSD/strtoumax.c b/stdlib/FreeBSD/strtoumax.c index eb714d7..f592063 100644 --- a/stdlib/FreeBSD/strtoumax.c +++ b/stdlib/FreeBSD/strtoumax.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "from @(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoumax.c,v 1.8 2002/09/06 11:23:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoumax.c,v 1.11 2007/01/09 00:28:10 imp Exp $"); #include #include @@ -73,7 +69,10 @@ strtoumax(const char * __restrict nptr, char ** __restrict endptr, int base) c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/FreeBSD/strtoumax.c.patch b/stdlib/FreeBSD/strtoumax.c.patch index ab7112e..fbbc5e0 100644 --- a/stdlib/FreeBSD/strtoumax.c.patch +++ b/stdlib/FreeBSD/strtoumax.c.patch @@ -1,15 +1,15 @@ ---- strtoumax.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ strtoumax.c 2005-02-23 13:24:30.000000000 -0800 -@@ -37,6 +37,8 @@ +--- strtoumax.c.bsdnew 2009-11-13 14:11:52.000000000 -0800 ++++ strtoumax.c 2009-11-13 14:11:52.000000000 -0800 +@@ -33,6 +33,8 @@ static char sccsid[] = "from @(#)strtoul #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoumax.c,v 1.8 2002/09/06 11:23:59 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoumax.c,v 1.11 2007/01/09 00:28:10 imp Exp $"); +#include "xlocale_private.h" + #include #include #include -@@ -49,7 +51,8 @@ +@@ -45,7 +47,8 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ * alphabets and digits are each contiguous. */ uintmax_t @@ -19,7 +19,7 @@ { const char *s; uintmax_t acc; -@@ -57,13 +60,14 @@ +@@ -53,13 +56,14 @@ strtoumax(const char * __restrict nptr, uintmax_t cutoff; int neg, any, cutlim; @@ -35,7 +35,7 @@ if (c == '-') { neg = 1; c = *s++; -@@ -117,3 +121,9 @@ +@@ -116,3 +120,9 @@ noconv: *endptr = (char *)(any ? s - 1 : nptr); return (acc); } diff --git a/stdlib/FreeBSD/strtouq.c b/stdlib/FreeBSD/strtouq.c index c0e0bef..614c5b8 100644 --- a/stdlib/FreeBSD/strtouq.c +++ b/stdlib/FreeBSD/strtouq.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtouq.c,v 1.11 2002/08/15 09:25:04 robert Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtouq.c,v 1.12 2007/01/09 00:28:10 imp Exp $"); #include diff --git a/stdlib/FreeBSD/strtouq.c.patch b/stdlib/FreeBSD/strtouq.c.patch index 2af9cfd..cfeabed 100644 --- a/stdlib/FreeBSD/strtouq.c.patch +++ b/stdlib/FreeBSD/strtouq.c.patch @@ -1,15 +1,15 @@ ---- strtouq.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ strtouq.c 2005-02-23 18:29:05.000000000 -0800 -@@ -37,6 +37,8 @@ +--- strtouq.c.bsdnew 2009-11-13 14:11:52.000000000 -0800 ++++ strtouq.c 2009-11-13 14:11:52.000000000 -0800 +@@ -33,6 +33,8 @@ static char sccsid[] = "@(#)strtouq.c 8. #include - __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtouq.c,v 1.11 2002/08/15 09:25:04 robert Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdlib/strtouq.c,v 1.12 2007/01/09 00:28:10 imp Exp $"); +#include "xlocale_private.h" + #include #include -@@ -48,5 +50,13 @@ +@@ -44,5 +46,13 @@ u_quad_t strtouq(const char *nptr, char **endptr, int base) { diff --git a/stdlib/FreeBSD/system.3 b/stdlib/FreeBSD/system.3 index f0557c8..ba5fb6e 100644 --- a/stdlib/FreeBSD/system.3 +++ b/stdlib/FreeBSD/system.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)system.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/system.3,v 1.11 2002/05/27 03:45:27 dd Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/system.3,v 1.13 2008/06/26 08:24:59 danger Exp $ .\" .Dd June 4, 1993 .Dt SYSTEM 3 @@ -74,7 +70,7 @@ pointer, will return non-zero if the command interpreter .Xr sh 1 is available, and zero if it is not. -.Pp +.Sh RETURN VALUES The .Fn system function diff --git a/stdlib/FreeBSD/system.3.patch b/stdlib/FreeBSD/system.3.patch index 434b325..b202c83 100644 --- a/stdlib/FreeBSD/system.3.patch +++ b/stdlib/FreeBSD/system.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdlib/FreeBSD/system.3 2003-05-20 15:23:25.000000000 -0700 -+++ _SB/Libc/stdlib/FreeBSD/system.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -47,13 +47,13 @@ +--- system.3.bsdnew 2009-11-13 14:11:52.000000000 -0800 ++++ system.3 2009-11-13 14:11:52.000000000 -0800 +@@ -43,13 +43,13 @@ .Sh SYNOPSIS .In stdlib.h .Ft int @@ -16,7 +16,7 @@ to the command interpreter .Xr sh 1 . The calling process waits for the shell -@@ -66,7 +66,7 @@ +@@ -62,7 +62,7 @@ and blocking .Dv SIGCHLD . .Pp If diff --git a/stdlib/FreeBSD/system.c b/stdlib/FreeBSD/system.c index fd2cc2a..8cdc1dd 100644 --- a/stdlib/FreeBSD/system.c +++ b/stdlib/FreeBSD/system.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)system.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/system.c,v 1.10 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/system.c,v 1.11 2007/01/09 00:28:10 imp Exp $"); #include "namespace.h" #include diff --git a/stdlib/FreeBSD/system.c.patch b/stdlib/FreeBSD/system.c.patch index e65ce57..6691e7a 100644 --- a/stdlib/FreeBSD/system.c.patch +++ b/stdlib/FreeBSD/system.c.patch @@ -1,6 +1,6 @@ ---- system.c.orig 2008-08-28 02:12:39.000000000 -0700 -+++ system.c 2008-08-28 02:15:08.000000000 -0700 -@@ -44,23 +44,61 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ +--- system.c.bsdnew 2009-11-13 14:11:52.000000000 -0800 ++++ system.c 2009-11-13 14:11:52.000000000 -0800 +@@ -40,23 +40,61 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ #include #include #include @@ -66,7 +66,7 @@ /* * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save * existing signal dispositions. -@@ -69,33 +107,45 @@ __system(command) +@@ -65,33 +103,45 @@ __system(command) (void)sigemptyset(&ign.sa_mask); ign.sa_flags = 0; (void)_sigaction(SIGINT, &ign, &intact); diff --git a/stdlib/FreeBSD/tsearch.3 b/stdlib/FreeBSD/tsearch.3 index 073ec80..d7121d4 100644 --- a/stdlib/FreeBSD/tsearch.3 +++ b/stdlib/FreeBSD/tsearch.3 @@ -25,7 +25,7 @@ .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" OpenBSD: tsearch.3,v 1.2 1998/06/21 22:13:49 millert Exp -.\" $FreeBSD: src/lib/libc/stdlib/tsearch.3,v 1.13 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/tsearch.3,v 1.15 2006/06/23 13:36:33 keramida Exp $ .\" .Dd June 15, 1997 .Dt TSEARCH 3 @@ -42,7 +42,7 @@ .Ft void * .Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)" .Ft void -.Fn twalk "const void *root" "void (*compar) (const void *, VISIT, int)" +.Fn twalk "const void *root" "void (*action) (const void *, VISIT, int)" .Sh DESCRIPTION The .Fn tdelete , @@ -107,10 +107,6 @@ a value from the enum .Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;" specifying the traversal type, and a node level (where level zero is the root of the tree). -.Sh SEE ALSO -.Xr bsearch 3 , -.Xr hsearch 3 , -.Xr lsearch 3 .Sh RETURN VALUES The .Fn tsearch @@ -130,3 +126,7 @@ is NULL or the datum cannot be found. The .Fn twalk function returns no value. +.Sh SEE ALSO +.Xr bsearch 3 , +.Xr hsearch 3 , +.Xr lsearch 3 diff --git a/stdlib/FreeBSD/tsearch.3.patch b/stdlib/FreeBSD/tsearch.3.patch index 77fa73a..7e8355c 100644 --- a/stdlib/FreeBSD/tsearch.3.patch +++ b/stdlib/FreeBSD/tsearch.3.patch @@ -1,5 +1,5 @@ ---- tsearch.3.orig 2007-03-06 15:44:54.000000000 -0800 -+++ tsearch.3 2007-03-06 16:04:48.000000000 -0800 +--- tsearch.3.bsdnew 2009-11-13 14:11:52.000000000 -0800 ++++ tsearch.3 2009-11-13 14:42:09.000000000 -0800 @@ -31,18 +31,36 @@ .Dt TSEARCH 3 .Os @@ -34,15 +34,15 @@ +.Fa "int (*compar) (const void *key1, const void *key2)" +.Fc .Ft void --.Fn twalk "const void *root" "void (*compar) (const void *, VISIT, int)" +-.Fn twalk "const void *root" "void (*action) (const void *, VISIT, int)" +.Fo twalk +.Fa "const void *root" -+.Fa "void (*compar) (const void *node, VISIT order, int level)" ++.Fa "void (*action) (const void *node, VISIT order, int level)" +.Fc .Sh DESCRIPTION The .Fn tdelete , -@@ -50,39 +68,46 @@ +@@ -50,39 +68,46 @@ The .Fn tsearch , and .Fn twalk @@ -101,7 +101,7 @@ It takes the same arguments as .Fn tfind and -@@ -93,20 +118,44 @@ +@@ -93,20 +118,44 @@ will be adjusted. .Pp The .Fn twalk @@ -147,10 +147,10 @@ +to what would typically be referred to as in-order, and the +traversal type "endorder" corresponds to what would typically +be referred to as post-order. - .Sh SEE ALSO - .Xr bsearch 3 , - .Xr hsearch 3 , -@@ -125,7 +174,7 @@ + .Sh RETURN VALUES + The + .Fn tsearch +@@ -121,7 +170,7 @@ and functions return NULL if .Fa rootp diff --git a/stdlib/Makefile.inc b/stdlib/Makefile.inc index 9feb682..c33b883 100644 --- a/stdlib/Makefile.inc +++ b/stdlib/Makefile.inc @@ -99,6 +99,7 @@ OBSDMISRCS=ecvt.c gcvt.c LEGACYSRCS+= getopt.c putenv.c realpath.c setenv.c system.c DARWINEXTSNSRCS += realpath.c CANCELABLESRCS += system.c +DYLDSRCS += atexit.c exit.c gettimeofday.c heapsort.c merge.c qsort.c reallocf.c realpath.c # set the LIBC_ALIAS_* macros so we can decorate the symbol independent # of other macro settings diff --git a/stdlib/NetBSD/strfmon.3.patch b/stdlib/NetBSD/strfmon.3.patch index 6bba2fa..1a72c21 100644 --- a/stdlib/NetBSD/strfmon.3.patch +++ b/stdlib/NetBSD/strfmon.3.patch @@ -1,5 +1,5 @@ ---- strfmon.3.orig 2008-04-05 20:02:08.000000000 -0700 -+++ strfmon.3 2008-04-05 20:05:49.000000000 -0700 +--- strfmon.3.orig 2010-02-08 16:26:10.000000000 -0800 ++++ strfmon.3 2010-02-08 17:57:07.000000000 -0800 @@ -30,25 +30,49 @@ .Dt STRFMON 3 .Os @@ -55,7 +55,7 @@ The format string is composed of zero or more directives: ordinary characters (not .Cm % ) , -@@ -116,9 +140,9 @@ +@@ -116,9 +140,9 @@ character is written. .El .El .Sh RETURN VALUES @@ -67,9 +67,24 @@ .Fa maxsize , .Fn strfmon returns the number of bytes placed into the array pointed to by -@@ -144,7 +168,8 @@ +@@ -143,8 +167,23 @@ The format string is invalid. + .It Bq Er ENOMEM Not enough memory for temporary buffers. .El ++.Sh EXAMPLE ++.Bd -literal -offset indent -compact ++ #include ++ #include ++ #include ++ ++ int main() { ++ char buf[200]; ++ setlocale(LC_ALL, "en_US"); ++ (void)strfmon (buf, sizeof(buf)-1, "%n" , 123456.78); ++ printf("%s\n", buf); ++ } ++.Ed ++.Pp .Sh SEE ALSO -.Xr localeconv 3 +.Xr localeconv 3 , diff --git a/stdlib/NetBSD/strfmon.c b/stdlib/NetBSD/strfmon.c index 98f0aad..d53ed7f 100644 --- a/stdlib/NetBSD/strfmon.c +++ b/stdlib/NetBSD/strfmon.c @@ -1,4 +1,4 @@ -/* $NetBSD: strfmon.c,v 1.6 2008/03/27 21:50:30 christos Exp $ */ +/* $NetBSD: strfmon.c,v 1.7 2009/01/30 23:46:03 lukem Exp $ */ /*- * Copyright (c) 2001 Alexey Zelkin @@ -32,7 +32,7 @@ #if 0 __FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.14 2003/03/20 08:18:55 ache Exp $"); #else -__RCSID("$NetBSD: strfmon.c,v 1.6 2008/03/27 21:50:30 christos Exp $"); +__RCSID("$NetBSD: strfmon.c,v 1.7 2009/01/30 23:46:03 lukem Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -204,7 +204,7 @@ strfmon(char * __restrict s, size_t maxsize, const char * __restrict format, * required width ? */ - if (d + width >= maxsize) + if ((size_t)(d + width) >= maxsize) goto e2big_error; } diff --git a/stdlib/OpenBSD/ecvt.3 b/stdlib/OpenBSD/ecvt.3 index 689cb1c..0717a2c 100644 --- a/stdlib/OpenBSD/ecvt.3 +++ b/stdlib/OpenBSD/ecvt.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ecvt.3,v 1.7 2004/01/25 14:48:32 jmc Exp $ +.\" $OpenBSD: ecvt.3,v 1.8 2007/05/31 19:19:31 jmc Exp $ .\" .\" Copyright (c) 2002 Todd C. Miller .\" @@ -18,7 +18,7 @@ .\" Agency (DARPA) and Air Force Research Laboratory, Air Force .\" Materiel Command, USAF, under agreement number F39502-99-1-0512. .\" -.Dd December 1, 2002 +.Dd $Mdocdate: May 31 2007 $ .Dt ECVT 3 .Os .Sh NAME diff --git a/stdlib/OpenBSD/ecvt.c b/stdlib/OpenBSD/ecvt.c index 657c531..03ff918 100644 --- a/stdlib/OpenBSD/ecvt.c +++ b/stdlib/OpenBSD/ecvt.c @@ -1,7 +1,7 @@ -/* $OpenBSD: ecvt.c,v 1.3 2003/06/17 21:56:24 millert Exp $ */ +/* $OpenBSD: ecvt.c,v 1.7 2009/10/16 12:15:03 martynas Exp $ */ /* - * Copyright (c) 2002 Todd C. Miller + * Copyright (c) 2002, 2006 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -20,22 +20,19 @@ * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: ecvt.c,v 1.3 2003/06/17 21:56:24 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - #include #include #include extern char *__dtoa(double, int, int, int *, int *, char **); +extern void __freedtoa(char *); static char *__cvt(double, int, int *, int *, int, int); static char * __cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad) { static char *s; - char *p, *rve; + char *p, *rve, c; size_t siz; if (ndigit == 0) { @@ -65,22 +62,29 @@ __cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad) *rve = '\0'; } else { p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve); + if (p == NULL) + return (NULL); if (*decpt == 9999) { - /* Nan or Infinity */ + /* Infinity or Nan, convert to inf or nan like printf */ *decpt = 0; - return(p); + c = *p; + __freedtoa(p); + return(c == 'I' ? "inf" : "nan"); } - /* make a local copy and adjust rve to be in terms of s */ + /* Make a local copy and adjust rve to be in terms of s */ if (pad && fmode) siz += *decpt; - if ((s = (char *)malloc(siz)) == NULL) + if ((s = (char *)malloc(siz)) == NULL) { + __freedtoa(p); return(NULL); + } (void) strlcpy(s, p, siz); rve = s + (rve - p); + __freedtoa(p); } - /* Add trailing zeros (unless we got NaN or Inf) */ - if (pad && *decpt != 9999) { + /* Add trailing zeros */ + if (pad) { siz -= rve - s; while (--siz) *rve++ = '0'; diff --git a/stdlib/OpenBSD/ecvt.c.patch b/stdlib/OpenBSD/ecvt.c.patch index 7805ff0..96586f4 100644 --- a/stdlib/OpenBSD/ecvt.c.patch +++ b/stdlib/OpenBSD/ecvt.c.patch @@ -1,18 +1,14 @@ ---- ecvt.c.orig Thu Jul 8 16:06:45 2004 -+++ ecvt.c Fri Jul 9 12:23:51 2004 +--- ecvt.c.orig 2009-11-06 00:43:00.000000000 -0800 ++++ ecvt.c 2009-11-06 00:45:11.000000000 -0800 @@ -20,6 +20,7 @@ * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ +#include - #if defined(LIBC_SCCS) && !defined(lint) - static char rcsid[] = "$OpenBSD: ecvt.c,v 1.3 2003/06/17 21:56:24 millert Exp $"; - #endif /* LIBC_SCCS and not lint */ -@@ -29,10 +30,11 @@ + #include + #include #include - - extern char *__dtoa(double, int, int, int *, int *, char **); -+extern void __freedtoa(char *); /* special gdtoa free function */ +@@ -29,7 +30,7 @@ extern void __freedtoa(char *); static char *__cvt(double, int, int *, int *, int, int); static char * @@ -20,31 +16,8 @@ +__cvt(double value, int ndigit, int * __restrict decpt, int * __restrict sign, int fmode, int pad) { static char *s; - char *p, *rve; -@@ -68,15 +70,20 @@ - if (*decpt == 9999) { - /* Nan or Infinity */ - *decpt = 0; -- return(p); -+ rve = (*p == 'N') ? "nan" : "inf"; -+ __freedtoa(p); -+ return(rve); - } - /* make a local copy and adjust rve to be in terms of s */ - if (pad && fmode) - siz += *decpt; -- if ((s = (char *)malloc(siz)) == NULL) -+ if ((s = (char *)malloc(siz)) == NULL) { -+ __freedtoa(p); - return(NULL); -+ } - (void) strlcpy(s, p, siz); - rve = s + (rve - p); -+ __freedtoa(p); - } - - /* Add trailing zeros (unless we got NaN or Inf) */ -@@ -91,13 +98,13 @@ + char *p, *rve, c; +@@ -95,13 +96,13 @@ __cvt(double value, int ndigit, int *dec } char * diff --git a/stdlib/OpenBSD/gcvt.c b/stdlib/OpenBSD/gcvt.c index 9fd664b..e5488d9 100644 --- a/stdlib/OpenBSD/gcvt.c +++ b/stdlib/OpenBSD/gcvt.c @@ -1,7 +1,7 @@ -/* $OpenBSD: gcvt.c,v 1.5 2003/06/17 21:56:24 millert Exp $ */ +/* $OpenBSD: gcvt.c,v 1.11 2009/10/16 12:15:03 martynas Exp $ */ /* - * Copyright (c) 2002, 2003 Todd C. Miller + * Copyright (c) 2002, 2003, 2006 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -20,31 +20,38 @@ * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: gcvt.c,v 1.5 2003/06/17 21:56:24 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - +#include #include #include #include extern char *__dtoa(double, int, int, int *, int *, char **); +extern void __freedtoa(char *); char * gcvt(double value, int ndigit, char *buf) { char *digits, *dst, *src; int i, decpt, sign; + struct lconv *lconv; + lconv = localeconv(); if (ndigit == 0) { buf[0] = '\0'; return (buf); } digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL); + if (digits == NULL) + return (NULL); if (decpt == 9999) { - /* Infinity or NaN, assume buffer is at least ndigit long. */ - strlcpy(buf, digits, ndigit + 1); + /* + * Infinity or NaN, convert to inf or nan with sign. + * We assume the buffer is at least ndigit long. + */ + snprintf(buf, ndigit + 1, "%s%s", sign ? "-" : "", + *digits == 'I' ? "inf" : "nan"); + __freedtoa(digits); return (buf); } @@ -53,13 +60,16 @@ gcvt(double value, int ndigit, char *buf) *dst++ = '-'; if (decpt < 0 || decpt > ndigit) { - /* exponential format */ + /* exponential format (e.g. 1.2345e+13) */ if (--decpt < 0) { sign = 1; decpt = -decpt; } else sign = 0; - for (src = digits; *src != '\0'; ) + src = digits; + *dst++ = *src++; + *dst++ = *lconv->decimal_point; + while (*src != '\0') *dst++ = *src++; *dst++ = 'e'; if (sign) @@ -73,7 +83,8 @@ gcvt(double value, int ndigit, char *buf) } else { /* XXX - optimize */ for (sign = decpt, i = 0; (sign /= 10) != 0; i++) - sign /= 10; + continue; + dst[i + 1] = '\0'; while (decpt != 0) { dst[i--] = '0' + decpt % 10; decpt /= 10; @@ -88,12 +99,15 @@ gcvt(double value, int ndigit, char *buf) *dst++ = '0'; } if (*src != '\0') { - *dst++ = '.'; /* XXX - locale-specific (LC_NUMERIC) */ + if (src == digits) + *dst++ = '0'; /* zero before decimal point */ + *dst++ = *lconv->decimal_point; for (i = decpt; digits[i] != '\0'; i++) { *dst++ = digits[i]; } } *dst = '\0'; } + __freedtoa(digits); return (buf); } diff --git a/stdlib/OpenBSD/gcvt.c.patch b/stdlib/OpenBSD/gcvt.c.patch index 39af6d4..63377e9 100644 --- a/stdlib/OpenBSD/gcvt.c.patch +++ b/stdlib/OpenBSD/gcvt.c.patch @@ -1,75 +1,20 @@ ---- gcvt.c.orig Thu Jul 8 16:06:45 2004 -+++ gcvt.c Fri Jul 9 12:16:25 2004 -@@ -27,14 +27,17 @@ - #include - #include - #include -+#include - - extern char *__dtoa(double, int, int, int *, int *, char **); -+extern void __freedtoa(char *); - - char * - gcvt(double value, int ndigit, char *buf) - { - char *digits, *dst, *src; - int i, decpt, sign; -+ char *decimal_point = localeconv()->decimal_point; - - if (ndigit == 0) { - buf[0] = '\0'; -@@ -43,8 +46,12 @@ - - digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL); - if (decpt == 9999) { -- /* Infinity or NaN, assume buffer is at least ndigit long. */ -- strlcpy(buf, digits, ndigit + 1); -+ /* Infinity or NaN, assume buffer is long enough. */ -+ dst = buf; -+ if (sign) -+ *dst++ = '-'; -+ strcpy(dst, (*digits == 'N') ? "nan" : "inf"); -+ __freedtoa(digits); - return (buf); - } - -@@ -59,7 +66,10 @@ - decpt = -decpt; - } else +--- gcvt.c.orig 2009-11-06 00:45:45.000000000 -0800 ++++ gcvt.c 2009-11-06 00:52:51.000000000 -0800 +@@ -68,7 +68,7 @@ gcvt(double value, int ndigit, char *buf sign = 0; -- for (src = digits; *src != '\0'; ) -+ src = digits; -+ *dst++ = *src++; -+ dst = stpcpy(dst, decimal_point); -+ while (*src != '\0') + src = digits; + *dst++ = *src++; +- *dst++ = *lconv->decimal_point; ++ dst = stpcpy(dst, lconv->decimal_point); + while (*src != '\0') *dst++ = *src++; *dst++ = 'e'; - if (sign) -@@ -72,8 +82,8 @@ - *dst = '\0'; - } else { - /* XXX - optimize */ -- for (sign = decpt, i = 0; (sign /= 10) != 0; i++) -- sign /= 10; -+ for (sign = decpt, i = 0; (sign /= 10) != 0; i++) {} -+ dst[i + 1] = '\0'; - while (decpt != 0) { - dst[i--] = '0' + decpt % 10; - decpt /= 10; -@@ -88,12 +98,15 @@ - *dst++ = '0'; - } +@@ -101,7 +101,7 @@ gcvt(double value, int ndigit, char *buf if (*src != '\0') { -- *dst++ = '.'; /* XXX - locale-specific (LC_NUMERIC) */ -+ if (src == digits) /* need leading zero */ -+ *dst++ = '0'; -+ dst = stpcpy(dst, decimal_point); + if (src == digits) + *dst++ = '0'; /* zero before decimal point */ +- *dst++ = *lconv->decimal_point; ++ dst = stpcpy(dst, lconv->decimal_point); for (i = decpt; digits[i] != '\0'; i++) { *dst++ = digits[i]; } - } - *dst = '\0'; - } -+ __freedtoa(digits); - return (buf); - } diff --git a/stdlib/abort-fbsd.c b/stdlib/abort-fbsd.c index c2a98ec..0fcbb9e 100644 --- a/stdlib/abort-fbsd.c +++ b/stdlib/abort-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)abort.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/abort.c,v 1.9 2003/08/16 11:43:57 davidxu Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/abort.c,v 1.11 2007/01/09 00:28:09 imp Exp $"); #include "namespace.h" #include @@ -46,9 +42,13 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/abort.c,v 1.9 2003/08/16 11:43:57 davidx #include #include "un-namespace.h" +#include "libc_private.h" + +#include "CrashReporterClient.h" +#include "_simple.h" + extern void (*__cleanup)(); extern void __abort(void) __dead2; -extern const char *__crashreporter_info__; #define TIMEOUT 10000 /* 10 milliseconds */ @@ -57,8 +57,9 @@ abort() { struct sigaction act; - if (!__crashreporter_info__) - __crashreporter_info__ = "abort() called"; + if (!CRGetCrashLogMessage()) + CRSetCrashLogMessage("abort() called"); + /* * POSIX requires we flush stdio buffers on abort. * XXX ISO C requires that abort() be async-signal-safe. @@ -72,8 +73,25 @@ abort() * any errors -- ISO C doesn't allow abort to return anyway. */ sigdelset(&act.sa_mask, SIGABRT); - (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); - (void)raise(SIGABRT); + + /* abort() should call pthread_kill to deliver a signal to the aborting thread + * This helps gdb focus on the thread calling abort() + */ + if (__is_threaded) { + /* Block all signals on all other threads */ + sigset_t fullmask; + sigfillset(&fullmask); + (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL); + + /* Set the workqueue killable */ + __pthread_workqueue_setkill(1); + + (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)pthread_kill(pthread_self(), SIGABRT); + } else { + (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)kill(getpid(), SIGABRT); + } usleep(TIMEOUT); /* give time for signal to happen */ /* @@ -88,28 +106,57 @@ __abort() { struct sigaction act; - if (!__crashreporter_info__) - __crashreporter_info__ = "__abort() called"; + if (!CRGetCrashLogMessage()) + CRSetCrashLogMessage("__abort() called"); act.sa_handler = SIG_DFL; act.sa_flags = 0; sigfillset(&act.sa_mask); (void)_sigaction(SIGABRT, &act, NULL); sigdelset(&act.sa_mask, SIGABRT); - (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); - (void)raise(SIGABRT); + + /* abort() should call pthread_kill to deliver a signal to the aborting thread + * This helps gdb focus on the thread calling abort() + */ + if (__is_threaded) { + /* Block all signals on all other threads */ + sigset_t fullmask; + sigfillset(&fullmask); + (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL); + + /* Set the workqueue killable */ + __pthread_workqueue_setkill(1); + + (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)pthread_kill(pthread_self(), SIGABRT); + } else { + (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)kill(getpid(), SIGABRT); + } usleep(TIMEOUT); /* give time for signal to happen */ - __builtin_trap(); /* never exit normally */ + + /* If for some reason SIGABRT was not delivered, we exit using __builtin_trap + * which generates an illegal instruction on i386: + * and SIGTRAP on arm. + */ + sigfillset(&act.sa_mask); + sigdelset(&act.sa_mask, SIGILL); + sigdelset(&act.sa_mask, SIGTRAP); + (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + __builtin_trap(); } __private_extern__ void abort_report_np(const char *fmt, ...) { - char *str; + _SIMPLE_STRING s; va_list ap; - va_start(ap, fmt); - vasprintf(&str, fmt, ap); - va_end(ap); - __crashreporter_info__ = str ? str : fmt; + if ((s = _simple_salloc()) != NULL) { + va_start(ap, fmt); + _simple_vsprintf(s, fmt, ap); + va_end(ap); + CRSetCrashLogMessage(_simple_string(s)); + } else + CRSetCrashLogMessage(fmt); /* the format string is better than nothing */ abort(); } diff --git a/stdlib/abort.3 b/stdlib/abort.3 deleted file mode 120000 index 4adb0ba..0000000 --- a/stdlib/abort.3 +++ /dev/null @@ -1 +0,0 @@ -./abort.3 \ No newline at end of file diff --git a/stdlib/abort.3 b/stdlib/abort.3 new file mode 100644 index 0000000..80ed972 --- /dev/null +++ b/stdlib/abort.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. +.\" +.\" @(#)abort.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: src/lib/libc/stdlib/abort.3,v 1.10 2007/01/09 00:28:09 imp Exp $ +.\" +.Dd June 4, 1993 +.Dt ABORT 3 +.Os +.Sh NAME +.Nm abort +.Nd cause abnormal program termination +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft void +.Fn abort void +.Sh DESCRIPTION +The +.Fn abort +function causes abnormal program termination to occur, unless the +signal +.Dv SIGABRT +is being caught and the signal handler does not return. +.Pp +Any open streams are flushed and closed. +.Sh IMPLEMENTATION NOTES +The +.Fn abort +function is thread-safe. +It is unknown if it is async-cancel-safe. +.Pp +The +.Fn abort +function causes a report to be generated by Crash Reporter. If you wish to +terminate without generating a crash report, use +.Xr exit 3 +instead. +.Sh RETURN VALUES +The +.Fn abort +function +never returns. +.Sh SEE ALSO +.Xr sigaction 2 , +.Xr exit 3 +.Sh STANDARDS +The +.Fn abort +function +conforms to +.St -p1003.1-90 . +The +.Fn abort +function also conforms to +.St -isoC-99 +with the implementation specific details as noted above. diff --git a/stdlib/abs.3 b/stdlib/abs.3 index 9252143..9dc5299 100644 --- a/stdlib/abs.3 +++ b/stdlib/abs.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)abs.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/abs.3,v 1.12 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/abs.3,v 1.13 2007/01/09 00:28:09 imp Exp $ .\" .Dd November 14, 2001 .Dt ABS 3 diff --git a/stdlib/alloca.3 b/stdlib/alloca.3 index fc58f0b..492100a 100644 --- a/stdlib/alloca.3 +++ b/stdlib/alloca.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,16 +26,14 @@ .\" SUCH DAMAGE. .\" .\" @(#)alloca.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/alloca.3,v 1.11 2003/06/28 22:12:30 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/alloca.3,v 1.13 2007/01/09 00:28:09 imp Exp $ .\" -.Dd June 4, 1993 +.Dd September 5, 2006 .Dt ALLOCA 3 .Os .Sh NAME .Nm alloca .Nd memory allocator -.Sh LIBRARY -.Lb libc .Sh SYNOPSIS .In alloca.h or @@ -50,19 +44,15 @@ or .Sh DESCRIPTION The .Fn alloca -function +macro allocates .Fa size bytes of space in the stack frame of the caller. This temporary space is automatically freed on return. .Sh RETURN VALUES -The .Fn alloca -function returns a pointer to the beginning of the allocated space. -If the allocation failed, a -.Dv NULL -pointer is returned. +returns a pointer to the beginning of the allocated space. .Sh SEE ALSO .Xr brk 2 , .Xr calloc 3 , @@ -70,17 +60,30 @@ pointer is returned. .Xr malloc 3 , .Xr realloc 3 .Sh HISTORY -The .Fn alloca -function appeared in +appeared in .At 32v . .\" .Bx ?? . .\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd .\" The first man page (or link to a man page that I can find at the .\" moment is 4.3... .Sh BUGS -The .Fn alloca -function is machine and compiler dependent; its use is discouraged. +.Pp +.Fn alloca +is slightly unsafe because it cannot ensure that the pointer +returned points to a valid and usable block of memory. +The allocation made may exceed the bounds of the stack, or even go +further into other objects in memory, and +.Fn alloca +cannot determine such an error. +Avoid +.Fn alloca +with large unbounded allocations. +.Pp +The use of C99 variable-length arrays and +.Fn alloca +in the same function will cause the lifetime of alloca's storage to be limited to the block containing the +.Fn alloca diff --git a/stdlib/atexit-fbsd.c b/stdlib/atexit-fbsd.c index f88f517..6acc776 100644 --- a/stdlib/atexit-fbsd.c +++ b/stdlib/atexit-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,14 +34,14 @@ static char sccsid[] = "@(#)atexit.c 8.2 (Berkeley) 7/3/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/atexit.c,v 1.7 2003/12/19 17:11:20 kan Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atexit.c,v 1.8 2007/01/09 00:28:09 imp Exp $"); #include "namespace.h" #include #include #include #include -#if defined(__DYNAMIC__) +#if defined(__DYNAMIC__) || defined (__BLOCKS__) #include #endif /* defined(__DYNAMIC__) */ #include "atexit.h" diff --git a/stdlib/atexit.3 b/stdlib/atexit.3 index 87dcff8..b3d978b 100644 --- a/stdlib/atexit.3 +++ b/stdlib/atexit.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)atexit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atexit.3,v 1.10 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/atexit.3,v 1.11 2007/01/09 00:28:09 imp Exp $ .\" .Dd May 20, 2008 .Dt ATEXIT 3 diff --git a/stdlib/atexit.h b/stdlib/atexit.h index ac14b27..56220ef 100644 --- a/stdlib/atexit.h +++ b/stdlib/atexit.h @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -31,7 +27,7 @@ * SUCH DAMAGE. * * @(#)atexit.h 8.2 (Berkeley) 7/3/94 - * $FreeBSD: src/lib/libc/stdlib/atexit.h,v 1.3 2003/12/19 17:11:20 kan Exp $ + * $FreeBSD: src/lib/libc/stdlib/atexit.h,v 1.4 2007/01/09 00:28:09 imp Exp $ */ /* must be at least 32 to guarantee ANSI conformance */ diff --git a/stdlib/atof-fbsd.c b/stdlib/atof-fbsd.c index a958725..fff3e7d 100644 --- a/stdlib/atof-fbsd.c +++ b/stdlib/atof-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)atof.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/atof.c,v 1.5 2004/02/10 20:42:32 cperciva Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atof.c,v 1.6 2007/01/09 00:28:09 imp Exp $"); #include "xlocale_private.h" diff --git a/stdlib/atof.3 b/stdlib/atof.3 index 1d32d06..28f0870 100644 --- a/stdlib/atof.3 +++ b/stdlib/atof.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)atof.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atof.3,v 1.16 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/atof.3,v 1.17 2007/01/09 00:28:09 imp Exp $ .\" .Dd June 4, 1993 .Dt ATOF 3 @@ -82,12 +78,18 @@ for more information. .Sh IMPLEMENTATION NOTES The .Fn atof -function is not thread-safe and also not async-cancel-safe. +and +.Fn atof_l +functions are thread-safe and async-cancel-safe. .Pp The .Fn atof -function has been deprecated by +and +.Fn atof_l +functions have been deprecated by .Fn strtod +and +.Fn strtod_l and should not be used in new code. .Sh ERRORS The function diff --git a/stdlib/atoi-fbsd.c b/stdlib/atoi-fbsd.c index 779bedc..ac6fcca 100644 --- a/stdlib/atoi-fbsd.c +++ b/stdlib/atoi-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)atoi.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/atoi.c,v 1.5 2002/03/22 21:53:09 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atoi.c,v 1.6 2007/01/09 00:28:09 imp Exp $"); #include "xlocale_private.h" diff --git a/stdlib/atoi.3 b/stdlib/atoi.3 index 7002274..3dc33e8 100644 --- a/stdlib/atoi.3 +++ b/stdlib/atoi.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)atoi.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atoi.3,v 1.12 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/atoi.3,v 1.14 2007/10/19 06:23:39 davidxu Exp $ .\" .Dd June 4, 1993 .Dt ATOI 3 @@ -78,12 +74,18 @@ for more information. .Sh IMPLEMENTATION NOTES The .Fn atoi -function is not thread-safe and also not async-cancel safe. +and +.Fn atoi_l +functions are thread-safe and async-cancel-safe. .Pp The .Fn atoi -function has been deprecated by +and +.Fn atoi_l +functions have been deprecated by .Fn strtol +and +.Fn strtol_l and should not be used in new code. .Sh ERRORS The function diff --git a/stdlib/atol-fbsd.c b/stdlib/atol-fbsd.c index b8b9161..5e52d95 100644 --- a/stdlib/atol-fbsd.c +++ b/stdlib/atol-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)atol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/atol.c,v 1.4 2002/03/22 21:53:09 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atol.c,v 1.5 2007/01/09 00:28:09 imp Exp $"); #include "xlocale_private.h" diff --git a/stdlib/atol.3 b/stdlib/atol.3 index eb014ba..2c21151 100644 --- a/stdlib/atol.3 +++ b/stdlib/atol.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)atol.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atol.3,v 1.13 2002/01/09 14:03:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/atol.3,v 1.16 2009/03/01 05:44:28 delphij Exp $ .\" -.Dd November 28, 2001 +.Dd February 1, 2009 .Dt ATOL 3 .Os .Sh NAME @@ -100,13 +96,50 @@ and functions may be passed locales directly. See .Xr xlocale 3 for more information. +.Sh IMPLEMENTATION NOTES +The +.Fn atol , +.Fn atoll , +.Fn atol_l , +and +.Fn atoll_l +functions are thread-safe and async-cancel-safe. +.Pp +The +.Fx +implementations of the +.Fn atol +and +.Fn atoll +functions are thin wrappers around +.Fn strtol +and +.Fn stroll +respectively, so these functions will affect the value of +.Va errno +in the same way that the +.Fn strtol +and +.Fn stroll +functions are able to. +This behavior of +.Fn atol +and +.Fn atoll +is not required by +.St -isoC +or +.St -isoC-99 , +but it is allowed by all of +.St -isoC , St -isoC-99 +and +.St -p1003.1-2001 . .Sh ERRORS The functions .Fn atol and .Fn atoll -need not -affect the value of +may affect the value of .Va errno on an error. .Sh SEE ALSO diff --git a/stdlib/atoll-fbsd.c b/stdlib/atoll-fbsd.c index e1e2176..c25a4da 100644 --- a/stdlib/atoll-fbsd.c +++ b/stdlib/atoll-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -32,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/atoll.c,v 1.4 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atoll.c,v 1.5 2007/01/09 00:28:09 imp Exp $"); #include "xlocale_private.h" diff --git a/stdlib/bsearch-fbsd.c b/stdlib/bsearch-fbsd.c index d689045..6af4291 100644 --- a/stdlib/bsearch-fbsd.c +++ b/stdlib/bsearch-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)bsearch.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/bsearch.c,v 1.3 2002/03/21 22:48:41 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/bsearch.c,v 1.4 2007/01/09 00:28:09 imp Exp $"); #include #include diff --git a/stdlib/bsearch.3 b/stdlib/bsearch.3 index 5eeac32..857f800 100644 --- a/stdlib/bsearch.3 +++ b/stdlib/bsearch.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bsearch.3 8.3 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/stdlib/bsearch.3,v 1.8 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/bsearch.3,v 1.9 2007/01/09 00:28:09 imp Exp $ .\" .Dd May 20, 2008 .Dt BSEARCH 3 diff --git a/stdlib/div.3 b/stdlib/div.3 index ed02b75..4a5bd35 100644 --- a/stdlib/div.3 +++ b/stdlib/div.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)div.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/div.3,v 1.8 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/div.3,v 1.9 2007/01/09 00:28:09 imp Exp $ .\" .Dd November 14, 2001 .Dt DIV 3 diff --git a/stdlib/ecvt-obsd.c b/stdlib/ecvt-obsd.c index 0a1e095..869674e 100644 --- a/stdlib/ecvt-obsd.c +++ b/stdlib/ecvt-obsd.c @@ -1,7 +1,7 @@ -/* $OpenBSD: ecvt.c,v 1.3 2003/06/17 21:56:24 millert Exp $ */ +/* $OpenBSD: ecvt.c,v 1.7 2009/10/16 12:15:03 martynas Exp $ */ /* - * Copyright (c) 2002 Todd C. Miller + * Copyright (c) 2002, 2006 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,23 +21,19 @@ */ #include -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: ecvt.c,v 1.3 2003/06/17 21:56:24 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - #include #include #include extern char *__dtoa(double, int, int, int *, int *, char **); -extern void __freedtoa(char *); /* special gdtoa free function */ +extern void __freedtoa(char *); static char *__cvt(double, int, int *, int *, int, int); static char * __cvt(double value, int ndigit, int * __restrict decpt, int * __restrict sign, int fmode, int pad) { static char *s; - char *p, *rve; + char *p, *rve, c; size_t siz; if (ndigit == 0) { @@ -67,14 +63,16 @@ __cvt(double value, int ndigit, int * __restrict decpt, int * __restrict sign, i *rve = '\0'; } else { p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve); + if (p == NULL) + return (NULL); if (*decpt == 9999) { - /* Nan or Infinity */ + /* Infinity or Nan, convert to inf or nan like printf */ *decpt = 0; - rve = (*p == 'N') ? "nan" : "inf"; + c = *p; __freedtoa(p); - return(rve); + return(c == 'I' ? "inf" : "nan"); } - /* make a local copy and adjust rve to be in terms of s */ + /* Make a local copy and adjust rve to be in terms of s */ if (pad && fmode) siz += *decpt; if ((s = (char *)malloc(siz)) == NULL) { @@ -86,8 +84,8 @@ __cvt(double value, int ndigit, int * __restrict decpt, int * __restrict sign, i __freedtoa(p); } - /* Add trailing zeros (unless we got NaN or Inf) */ - if (pad && *decpt != 9999) { + /* Add trailing zeros */ + if (pad) { siz -= rve - s; while (--siz) *rve++ = '0'; diff --git a/stdlib/ecvt.3 b/stdlib/ecvt.3 index 5353d94..d8d663e 100644 --- a/stdlib/ecvt.3 +++ b/stdlib/ecvt.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ecvt.3,v 1.7 2004/01/25 14:48:32 jmc Exp $ +.\" $OpenBSD: ecvt.3,v 1.8 2007/05/31 19:19:31 jmc Exp $ .\" .\" Copyright (c) 2002 Todd C. Miller .\" @@ -18,7 +18,7 @@ .\" Agency (DARPA) and Air Force Research Laboratory, Air Force .\" Materiel Command, USAF, under agreement number F39502-99-1-0512. .\" -.Dd December 1, 2002 +.Dd $Mdocdate: May 31 2007 $ .Dt ECVT 3 .Os .Sh NAME diff --git a/stdlib/exit-fbsd.c b/stdlib/exit-fbsd.c index 19fc265..aa23703 100644 --- a/stdlib/exit-fbsd.c +++ b/stdlib/exit-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,15 +31,17 @@ static char sccsid[] = "@(#)exit.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/exit.c,v 1.7 2003/12/19 17:11:20 kan Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/exit.c,v 1.9 2007/01/09 00:28:09 imp Exp $"); #include "namespace.h" #include #include #include "un-namespace.h" + #include "atexit.h" +#include "libc_private.h" -void (*__cleanup)(); +void (*__cleanup)(void); extern void __exit(int); /* diff --git a/stdlib/gcvt-obsd.c b/stdlib/gcvt-obsd.c index 08b65fc..703f783 100644 --- a/stdlib/gcvt-obsd.c +++ b/stdlib/gcvt-obsd.c @@ -1,7 +1,7 @@ -/* $OpenBSD: gcvt.c,v 1.5 2003/06/17 21:56:24 millert Exp $ */ +/* $OpenBSD: gcvt.c,v 1.11 2009/10/16 12:15:03 martynas Exp $ */ /* - * Copyright (c) 2002, 2003 Todd C. Miller + * Copyright (c) 2002, 2003, 2006 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -20,37 +20,37 @@ * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: gcvt.c,v 1.5 2003/06/17 21:56:24 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - +#include #include #include #include -#include extern char *__dtoa(double, int, int, int *, int *, char **); -extern void __freedtoa(char *); +extern void __freedtoa(char *); char * gcvt(double value, int ndigit, char *buf) { char *digits, *dst, *src; int i, decpt, sign; - char *decimal_point = localeconv()->decimal_point; + struct lconv *lconv; + lconv = localeconv(); if (ndigit == 0) { buf[0] = '\0'; return (buf); } digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL); + if (digits == NULL) + return (NULL); if (decpt == 9999) { - /* Infinity or NaN, assume buffer is long enough. */ - dst = buf; - if (sign) - *dst++ = '-'; - strcpy(dst, (*digits == 'N') ? "nan" : "inf"); + /* + * Infinity or NaN, convert to inf or nan with sign. + * We assume the buffer is at least ndigit long. + */ + snprintf(buf, ndigit + 1, "%s%s", sign ? "-" : "", + *digits == 'I' ? "inf" : "nan"); __freedtoa(digits); return (buf); } @@ -60,7 +60,7 @@ gcvt(double value, int ndigit, char *buf) *dst++ = '-'; if (decpt < 0 || decpt > ndigit) { - /* exponential format */ + /* exponential format (e.g. 1.2345e+13) */ if (--decpt < 0) { sign = 1; decpt = -decpt; @@ -68,7 +68,7 @@ gcvt(double value, int ndigit, char *buf) sign = 0; src = digits; *dst++ = *src++; - dst = stpcpy(dst, decimal_point); + dst = stpcpy(dst, lconv->decimal_point); while (*src != '\0') *dst++ = *src++; *dst++ = 'e'; @@ -82,7 +82,8 @@ gcvt(double value, int ndigit, char *buf) *dst = '\0'; } else { /* XXX - optimize */ - for (sign = decpt, i = 0; (sign /= 10) != 0; i++) {} + for (sign = decpt, i = 0; (sign /= 10) != 0; i++) + continue; dst[i + 1] = '\0'; while (decpt != 0) { dst[i--] = '0' + decpt % 10; @@ -98,9 +99,9 @@ gcvt(double value, int ndigit, char *buf) *dst++ = '0'; } if (*src != '\0') { - if (src == digits) /* need leading zero */ - *dst++ = '0'; - dst = stpcpy(dst, decimal_point); + if (src == digits) + *dst++ = '0'; /* zero before decimal point */ + dst = stpcpy(dst, lconv->decimal_point); for (i = decpt; digits[i] != '\0'; i++) { *dst++ = digits[i]; } diff --git a/stdlib/getenv-fbsd.c b/stdlib/getenv-fbsd.c index 3fdfe80..47b60df 100644 --- a/stdlib/getenv-fbsd.c +++ b/stdlib/getenv-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)getenv.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/getenv.c,v 1.4 2002/03/21 22:48:41 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/getenv.c,v 1.8 2007/05/01 16:02:41 ache Exp $"); #include #include diff --git a/stdlib/getopt-fbsd.c b/stdlib/getopt-fbsd.c index ce37be2..c45494c 100644 --- a/stdlib/getopt-fbsd.c +++ b/stdlib/getopt-fbsd.c @@ -12,10 +12,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -37,7 +33,7 @@ static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.7 2004/03/06 17:05:45 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.8 2007/01/09 00:28:10 imp Exp $"); #include "namespace.h" #include diff --git a/stdlib/getsubopt.3 b/stdlib/getsubopt.3 index eb77d75..c1ddee2 100644 --- a/stdlib/getsubopt.3 +++ b/stdlib/getsubopt.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/stdlib/getsubopt.3,v 1.10 2004/02/23 03:32:10 ache Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/getsubopt.3,v 1.11 2007/01/09 00:28:10 imp Exp $ .\" .Dd June 9, 1993 .Dt GETSUBOPT 3 diff --git a/stdlib/labs.3 b/stdlib/labs.3 index 20bdf15..b000955 100644 --- a/stdlib/labs.3 +++ b/stdlib/labs.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)labs.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/labs.3,v 1.9 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/labs.3,v 1.10 2007/01/09 00:28:10 imp Exp $ .\" .Dd November 14, 2001 .Dt LABS 3 diff --git a/stdlib/ldiv.3 b/stdlib/ldiv.3 index 0d83562..904f0d5 100644 --- a/stdlib/ldiv.3 +++ b/stdlib/ldiv.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ldiv.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/ldiv.3,v 1.9 2002/12/18 13:33:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/ldiv.3,v 1.10 2007/01/09 00:28:10 imp Exp $ .\" .Dd November 14, 2001 .Dt LDIV 3 diff --git a/stdlib/lsearch.3 b/stdlib/lsearch.3 index 94fcee0..5be997c 100644 --- a/stdlib/lsearch.3 +++ b/stdlib/lsearch.3 @@ -6,7 +6,7 @@ .\" As long as the above copyright statement and this notice remain .\" unchanged, you can do what ever you want with this file. .\" -.\" $FreeBSD: src/lib/libc/stdlib/lsearch.3,v 1.4 2002/12/19 09:40:24 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/lsearch.3,v 1.5 2005/01/20 09:17:04 ru Exp $ .\" .Dd October 11, 2002 .Dt LSEARCH 3 @@ -85,6 +85,13 @@ if an error occurs. .Xr bsearch 3 , .Xr hsearch 3 , .Xr tsearch 3 +.Sh STANDARDS +The +.Fn lsearch +and +.Fn lfind +functions conform to +.St -p1003.1-2001 . .Sh HISTORY The .Fn lsearch @@ -96,10 +103,3 @@ In .Fx 5.0 , they reappeared conforming to .St -p1003.1-2001 . -.Sh STANDARDS -The -.Fn lsearch -and -.Fn lfind -functions conform to -.St -p1003.1-2001 . diff --git a/stdlib/memory.3 b/stdlib/memory.3 index d6ebc9b..96cef24 100644 --- a/stdlib/memory.3 +++ b/stdlib/memory.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memory.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/memory.3,v 1.11 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/memory.3,v 1.12 2007/01/09 00:28:10 imp Exp $ .\" .Dd June 4, 1993 .Dt MEMORY 3 diff --git a/stdlib/psort.3 b/stdlib/psort.3 index 447a3f7..e5572fc 100644 --- a/stdlib/psort.3 +++ b/stdlib/psort.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)qsort.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.15 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.17 2007/01/09 00:28:10 imp Exp $ .\" .Dd Nov 25, 2008 .Dt PSORT 3 @@ -131,3 +127,51 @@ functions return no value. .Sh SEE ALSO .Xr qsort 3 +.Sh SEE ALSO +.Xr sort 1 , +.Xr radixsort 3 +.Rs +.%A Hoare, C.A.R. +.%D 1962 +.%T "Quicksort" +.%J "The Computer Journal" +.%V 5:1 +.%P pp. 10-15 +.Re +.Rs +.%A Williams, J.W.J +.%D 1964 +.%T "Heapsort" +.%J "Communications of the ACM" +.%V 7:1 +.%P pp. 347-348 +.Re +.Rs +.%A Knuth, D.E. +.%D 1968 +.%B "The Art of Computer Programming" +.%V Vol. 3 +.%T "Sorting and Searching" +.%P pp. 114-123, 145-149 +.Re +.Rs +.%A McIlroy, P.M. +.%T "Optimistic Sorting and Information Theoretic Complexity" +.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms" +.%V January 1992 +.Re +.Rs +.%A Bentley, J.L. +.%A McIlroy, M.D. +.%T "Engineering a Sort Function" +.%J "Software--Practice and Experience" +.%V Vol. 23(11) +.%P pp. 1249-1265 +.%D November\ 1993 +.Re +.Sh STANDARDS +The +.Fn qsort +function +conforms to +.St -isoC . diff --git a/stdlib/psort.3.patch b/stdlib/psort.3.patch index 303a234..77aea36 100644 --- a/stdlib/psort.3.patch +++ b/stdlib/psort.3.patch @@ -1,8 +1,8 @@ ---- psort.3.orig 2009-05-20 15:59:00.000000000 -0700 -+++ psort.3 2009-05-20 16:08:34.000000000 -0700 -@@ -36,60 +36,20 @@ +--- psort.3.orig 2010-10-07 21:34:52.000000000 -0700 ++++ psort.3 2010-10-07 21:45:11.000000000 -0700 +@@ -32,60 +32,20 @@ .\" @(#)qsort.3 8.1 (Berkeley) 6/4/93 - .\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.15 2004/07/02 23:52:12 ru Exp $ + .\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.17 2007/01/09 00:28:10 imp Exp $ .\" -.Dd September 30, 2003 -.Dt QSORT 3 @@ -69,7 +69,7 @@ .Fa "void *base" .Fa "size_t nel" .Fa "size_t width" -@@ -97,7 +57,7 @@ +@@ -93,7 +53,7 @@ .Fc #ifdef UNIFDEF_BLOCKS .Ft void @@ -78,7 +78,7 @@ .Fa "void *base" .Fa "size_t nel" .Fa "size_t width" -@@ -105,7 +65,7 @@ +@@ -101,7 +61,7 @@ .Fc #endif .Ft void @@ -87,7 +87,7 @@ .Fa "void *base" .Fa "size_t nel" .Fa "size_t width" -@@ -114,255 +74,60 @@ +@@ -110,210 +70,63 @@ .Fc .Sh DESCRIPTION The @@ -209,12 +209,12 @@ -Normally, -.Fn qsort -is faster than --.Fn mergesort , +-.Fn mergesort -which is faster than -.Fn heapsort . -Memory availability and pre-existing order in the data can make this -untrue. --#ifdef UNIFDEF_BLOCKS + #ifdef UNIFDEF_BLOCKS -.Pp -The -.Fn heapsort_b , @@ -225,29 +225,12 @@ -that the -.Fa compar -callback is a block pointer instead of a function pointer. --#endif --.Sh RETURN VALUES --The - #ifdef UNIFDEF_BLOCKS --.Fn qsort , --.Fn qsort_b +.Fn psort , +.Fn psort_b , - #else --.Fn qsort ++#else +.Fn psort #endif - and --.Fn qsort_r --functions --return no value. --.Pp --#ifdef UNIFDEF_BLOCKS --.ds HEAPSORT_B heapsort_b --.ds MERGESORT_B mergesort_b --#endif --.Rv -std heapsort \*[HEAPSORT_B] mergesort \*[MERGESORT_B] --.Sh ERRORS ++and +.Fn psort_r +functions are parallel sort routines that are drop-in compatible with the +corresponding @@ -284,17 +267,43 @@ +Like +.Xr qsort 3 , +the sort is not stable. -+.Sh RETURN VALUES + .Sh RETURN VALUES The #ifdef UNIFDEF_BLOCKS +-.Fn qsort , +-.Fn qsort_b ++.Fn psort , ++.Fn psort_b + #else +-.Fn qsort ++.Fn psort + #endif + and +-.Fn qsort_r ++.Fn psort_r + functions + return no value. +-.Pp +-#ifdef UNIFDEF_BLOCKS +-.ds HEAPSORT_B heapsort_b +-.ds MERGESORT_B mergesort_b +-#endif +-.Rv -std heapsort \*[HEAPSORT_B] mergesort \*[MERGESORT_B] +-.Sh COMPATIBILITY +-Previous versions of +-.Fn qsort +-did not permit the comparison routine itself to call +-.Fn qsort 3 . +-This is no longer true. +-.Sh ERRORS +-The +-#ifdef UNIFDEF_BLOCKS -.Fn heapsort , -.Fn heapsort_b , --.Fn mergesort +-.Fn mergesort , -and -.Fn mergesort_b -+.Fn psort , -+.Fn psort_b - #else +-#else -.Fn heapsort -and -.Fn mergesort @@ -312,8 +321,7 @@ -#ifdef UNIFDEF_BLOCKS -or -.Fn mergesort_b -+.Fn psort - #endif +-#endif -is less than -.Dq "sizeof(void *) / 2" . -.It Bq Er ENOMEM @@ -321,71 +329,19 @@ -#ifdef UNIFDEF_BLOCKS -.Fn heapsort , -.Fn heapsort_b , --.Fn mergesort --and +-.Fn mergesort , +-or -.Fn mergesort_b -#else -.Fn heapsort - and +-or -.Fn mergesort -#endif -+.Fn psort_r - functions +-functions -were unable to allocate memory. -.El --.Sh COMPATIBILITY --Previous versions of --.Fn qsort --did not permit the comparison routine itself to call --.Fn qsort 3 . --This is no longer true. -+return no value. - .Sh SEE ALSO --.Xr sort 1 , --.Xr radixsort 3 --.Rs --.%A Hoare, C.A.R. --.%D 1962 --.%T "Quicksort" --.%J "The Computer Journal" --.%V 5:1 --.%P pp. 10-15 --.Re --.Rs --.%A Williams, J.W.J --.%D 1964 --.%T "Heapsort" --.%J "Communications of the ACM" --.%V 7:1 --.%P pp. 347-348 --.Re --.Rs --.%A Knuth, D.E. --.%D 1968 --.%B "The Art of Computer Programming" --.%V Vol. 3 --.%T "Sorting and Searching" --.%P pp. 114-123, 145-149 --.Re --.Rs --.%A McIlroy, P.M. --.%T "Optimistic Sorting and Information Theoretic Complexity" --.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms" --.%V January 1992 --.Re --.Rs --.%A Bentley, J.L. --.%A McIlroy, M.D. --.%T "Engineering a Sort Function" --.%J "Software--Practice and Experience" --.%V Vol. 23(11) --.%P pp. 1249-1265 --.%D November\ 1993 --.Re --.Sh STANDARDS --The --.Fn qsort --function --conforms to --.St -isoC . ++.Sh SEE ALSO +.Xr qsort 3 + .Sh SEE ALSO + .Xr sort 1 , + .Xr radixsort 3 diff --git a/stdlib/putenv-fbsd.c b/stdlib/putenv-fbsd.c index 03cdb16..55ce0c1 100644 --- a/stdlib/putenv-fbsd.c +++ b/stdlib/putenv-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)putenv.c 8.2 (Berkeley) 3/27/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/putenv.c,v 1.2 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/putenv.c,v 1.6 2007/05/01 16:02:41 ache Exp $"); #include #include @@ -46,8 +42,11 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/putenv.c,v 1.2 2002/03/22 21:53:10 obrie #include extern malloc_zone_t *__zone0; -extern void __malloc_check_env_name(const char *); +#ifdef LEGACY_CRT1_ENVIRON +extern char **_saved_environ; +#endif /* LEGACY_CRT1_ENVIRON */ +extern void __malloc_check_env_name(const char *); __private_extern__ int __setenv(const char *, const char *, int, int, char ***, malloc_zone_t *); #ifndef BUILDING_VARIANT @@ -75,6 +74,10 @@ int putenv(str) char *str; { +#ifdef LEGACY_CRT1_ENVIRON + int ret; +#endif /* LEGACY_CRT1_ENVIRON */ + #if __DARWIN_UNIX03 if (str == NULL || *str == 0 || index(str, '=') == NULL) { errno = EINVAL; @@ -93,11 +96,20 @@ putenv(str) } } __malloc_check_env_name(str); /* see if we are changing a malloc environment variable */ - return (__setenv(str, NULL, 1, +#ifdef LEGACY_CRT1_ENVIRON + ret = +#else /* !LEGACY_CRT1_ENVIRON */ + return +#endif /* !LEGACY_CRT1_ENVIRON */ + __setenv(str, NULL, 1, #if __DARWIN_UNIX03 0, #else /* !__DARWIN_UNIX03 */ -1, #endif /* __DARWIN_UNIX03 */ - _NSGetEnviron(), __zone0)); + _NSGetEnviron(), __zone0); +#ifdef LEGACY_CRT1_ENVIRON + _saved_environ = *_NSGetEnviron(); + return ret; +#endif /* LEGACY_CRT1_ENVIRON */ } diff --git a/stdlib/qsort.3 b/stdlib/qsort.3 index b159ffb..f137a8d 100644 --- a/stdlib/qsort.3 +++ b/stdlib/qsort.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)qsort.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.15 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.17 2007/01/09 00:28:10 imp Exp $ .\" .Dd September 30, 2003 .Dt QSORT 3 @@ -232,7 +228,7 @@ time is O N lg N; its best case is O N. Normally, .Fn qsort is faster than -.Fn mergesort , +.Fn mergesort which is faster than .Fn heapsort . Memory availability and pre-existing order in the data can make this @@ -267,12 +263,18 @@ return no value. .ds MERGESORT_B mergesort_b #endif .Rv -std heapsort \*[HEAPSORT_B] mergesort \*[MERGESORT_B] +.Sh COMPATIBILITY +Previous versions of +.Fn qsort +did not permit the comparison routine itself to call +.Fn qsort 3 . +This is no longer true. .Sh ERRORS The #ifdef UNIFDEF_BLOCKS .Fn heapsort , .Fn heapsort_b , -.Fn mergesort +.Fn mergesort , and .Fn mergesort_b #else @@ -301,23 +303,17 @@ The #ifdef UNIFDEF_BLOCKS .Fn heapsort , .Fn heapsort_b , -.Fn mergesort -and +.Fn mergesort , +or .Fn mergesort_b #else .Fn heapsort -and +or .Fn mergesort #endif functions were unable to allocate memory. .El -.Sh COMPATIBILITY -Previous versions of -.Fn qsort -did not permit the comparison routine itself to call -.Fn qsort 3 . -This is no longer true. .Sh SEE ALSO .Xr sort 1 , .Xr radixsort 3 diff --git a/stdlib/radixsort-fbsd.c b/stdlib/radixsort-fbsd.c index b712f89..5208ce9 100644 --- a/stdlib/radixsort-fbsd.c +++ b/stdlib/radixsort-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)radixsort.c 8.2 (Berkeley) 4/28/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/radixsort.c,v 1.7 2003/11/11 04:59:23 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/radixsort.c,v 1.8 2007/01/09 00:28:10 imp Exp $"); /* * Radixsort routines. @@ -57,6 +53,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/radixsort.c,v 1.7 2003/11/11 04:59:23 ki #include #include #include +#include typedef struct { const u_char **sa; @@ -69,6 +66,12 @@ static void r_sort_a(const u_char **, int, int, const u_char *, u_int); static void r_sort_b(const u_char **, const u_char **, int, int, const u_char *, u_int); +static int *r_sort_a_count; +static int *r_sort_b_count; + +static void r_sort_count_allocate(void); +static pthread_once_t r_sort_count_control = PTHREAD_ONCE_INIT; + #define THRESHOLD 20 /* Divert to simplesort(). */ #define SIZE 512 /* Default stack size. */ @@ -128,6 +131,12 @@ sradixsort(a, n, tab, endch) return (0); } +static void r_sort_count_allocate(void) +{ + r_sort_a_count = calloc(256, sizeof(int)); + r_sort_b_count = calloc(256, sizeof(int)); +} + #define empty(s) (s >= sp) #define pop(a, n, i) a = (--sp)->sa, n = sp->sn, i = sp->si #define push(a, n, i) sp->sa = a, sp->sn = n, (sp++)->si = i @@ -141,13 +150,19 @@ r_sort_a(a, n, i, tr, endch) const u_char *tr; u_int endch; { - static int count[256], nc, bmin; + static int *count, nc, bmin; int c; const u_char **ak, *r; stack s[SIZE], *sp, *sp0, *sp1, temp; int *cp, bigc; const u_char **an, *t, **aj, **top[256]; + if (pthread_once(&r_sort_count_control, r_sort_count_allocate)) { + return; + } + + count = r_sort_a_count; + /* Set up stack. */ sp = s; push(a, n, i); @@ -243,13 +258,19 @@ r_sort_b(a, ta, n, i, tr, endch) const u_char *tr; u_int endch; { - static int count[256], nc, bmin; + static int *count, nc, bmin; int c; const u_char **ak, **ai; stack s[512], *sp, *sp0, *sp1, temp; const u_char **top[256]; int *cp, bigc; + if (pthread_once(&r_sort_count_control, r_sort_count_allocate)) { + return; + } + + count = r_sort_b_count; + sp = s; push(a, n, i); while (!empty(s)) { diff --git a/stdlib/rand.3 b/stdlib/rand.3 index a57c7d5..fec6ac6 100644 --- a/stdlib/rand.3 +++ b/stdlib/rand.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)rand.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/rand.3,v 1.14 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/rand.3,v 1.16 2007/01/09 00:28:10 imp Exp $ .\" .Dd May 25, 1999 .Dt RAND 3 @@ -99,8 +95,10 @@ The .Fn sranddev function initializes a seed, using the .Xr random 4 -random number device which returns good random numbers, -suitable for cryptographic use. +random number device which returns good random numbers. +However, the +.Fn rand +function still remains unsuitable for cryptographic use. .Pp The .Fn rand_r diff --git a/stdlib/random-fbsd.c b/stdlib/random-fbsd.c index b422b4c..15db640 100644 --- a/stdlib/random-fbsd.c +++ b/stdlib/random-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.24 2004/01/20 03:02:18 das Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.25 2007/01/09 00:28:10 imp Exp $"); /* * We always compile with __DARWIN_UNIX03 set to one, relying on the fact that diff --git a/stdlib/random.3 b/stdlib/random.3 index b4cdd05..84c8755 100644 --- a/stdlib/random.3 +++ b/stdlib/random.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)random.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/random.3,v 1.20 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/random.3,v 1.22 2007/01/09 00:28:10 imp Exp $ .\" .Dd June 4, 1993 .Dt RANDOM 3 @@ -104,14 +100,17 @@ will produce a random binary value. .Pp Like +.Xr srand 3 , +.Fn srandom +sets the initial seed value for future calls to +.Fn random . +Like .Xr rand 3 , .Fn random will by default produce a sequence of numbers that can be duplicated by calling .Fn srandom -with -.Ql 1 -as the seed. +with the same seed. .Pp The .Fn srandomdev @@ -181,8 +180,6 @@ generator is greater than .if t 2\u\s769\s10\d, .if n 2**69 , which should be sufficient for most purposes. -.Sh AUTHORS -.An Earl T. Cohen .Sh DIAGNOSTICS If .Fn initstate @@ -224,6 +221,8 @@ The type of each parameter is different in the legacy version. These functions appeared in .Bx 4.2 . +.Sh AUTHORS +.An Earl T. Cohen .Sh BUGS About 2/3 the speed of .Xr rand 3 . diff --git a/stdlib/realpath-fbsd.c b/stdlib/realpath-fbsd.c index 9309965..234bce9 100644 --- a/stdlib/realpath-fbsd.c +++ b/stdlib/realpath-fbsd.c @@ -106,18 +106,23 @@ realpath(const char *path, char inresolved[PATH_MAX]) #endif /* __DARWIN_UNIX03 */ /* * Extension to the standard; if inresolved == NULL, allocate memory - * (first on the stack, then use strdup()) */ if (!inresolved) { - if ((resolved = alloca(PATH_MAX)) == NULL) return (NULL); + if ((resolved = malloc(PATH_MAX)) == NULL) return (NULL); } else { resolved = inresolved; } if (!rootdev_inited) { rootdev_inited = 1; if (stat("/", &sb) < 0) { - return (NULL); +error_return: + if (!inresolved) { + int e = errno; + free(resolved); + errno = e; } + return (NULL); + } rootdev = sb.st_dev; } serrno = errno; @@ -140,18 +145,18 @@ realpath(const char *path, char inresolved[PATH_MAX]) #endif /* !VARIANT_DARWINEXTSN && __DARWIN_UNIX03 */ { strlcpy(resolved, ".", PATH_MAX); - return (NULL); + goto error_return; } resolved_len = strlen(resolved); left_len = strlcpy(left, path, sizeof(left)); } if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; - return (NULL); + goto error_return; } if (resolved_len > 1) { if (stat(resolved, &sb) < 0) { - return (NULL); + goto error_return; } lastdev = sb.st_dev; } else @@ -169,7 +174,7 @@ realpath(const char *path, char inresolved[PATH_MAX]) s = p ? p : left + left_len; if (s - left >= sizeof(next_token)) { errno = ENAMETOOLONG; - return (NULL); + goto error_return; } memcpy(next_token, left, s - left); next_token[s - left] = '\0'; @@ -179,7 +184,7 @@ realpath(const char *path, char inresolved[PATH_MAX]) if (resolved[resolved_len - 1] != '/') { if (resolved_len + 1 >= PATH_MAX) { errno = ENAMETOOLONG; - return (NULL); + goto error_return; } resolved[resolved_len++] = '/'; resolved[resolved_len] = '\0'; @@ -217,7 +222,7 @@ realpath(const char *path, char inresolved[PATH_MAX]) resolved_len = strlcat(resolved, next_token, PATH_MAX); if (resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; - return (NULL); + goto error_return; } if (getattrlist(resolved, &_rp_alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) { useattrs = 1; @@ -239,7 +244,7 @@ realpath(const char *path, char inresolved[PATH_MAX]) return (resolved); } #endif /* !__DARWIN_UNIX03 */ - return (NULL); + goto error_return; } if (dev != lastdev) { /* @@ -289,11 +294,11 @@ realpath(const char *path, char inresolved[PATH_MAX]) if (islink) { if (symlinks++ > MAXSYMLINKS) { errno = ELOOP; - return (NULL); + goto error_return; } slen = readlink(resolved, symlink, sizeof(symlink) - 1); if (slen < 0) { - return (NULL); + goto error_return; } symlink[slen] = '\0'; if (symlink[0] == '/') { @@ -317,7 +322,7 @@ realpath(const char *path, char inresolved[PATH_MAX]) if (symlink[slen - 1] != '/') { if (slen + 1 >= sizeof(symlink)) { errno = ENAMETOOLONG; - return (NULL); + goto error_return; } symlink[slen] = '/'; symlink[slen + 1] = 0; @@ -325,7 +330,7 @@ realpath(const char *path, char inresolved[PATH_MAX]) left_len = strlcat(symlink, left, sizeof(left)); if (left_len >= sizeof(left)) { errno = ENAMETOOLONG; - return (NULL); + goto error_return; } } left_len = strlcpy(left, symlink, sizeof(left)); @@ -338,7 +343,7 @@ realpath(const char *path, char inresolved[PATH_MAX]) resolved_len = strlcat(resolved, (const char *)&attrs.name + attrs.name.attr_dataoffset, PATH_MAX); if (resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; - return (NULL); + goto error_return; } } /* @@ -361,6 +366,5 @@ realpath(const char *path, char inresolved[PATH_MAX]) */ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') resolved[resolved_len - 1] = '\0'; - if (!inresolved) resolved = strdup(resolved); return (resolved); } diff --git a/stdlib/realpath.3 b/stdlib/realpath.3 index 0d3cd3a..3ffdf9c 100644 --- a/stdlib/realpath.3 +++ b/stdlib/realpath.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)realpath.3 8.2 (Berkeley) 2/16/94 -.\" $FreeBSD: src/lib/libc/stdlib/realpath.3,v 1.13 2003/03/27 20:48:53 fjoe Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/realpath.3,v 1.14 2007/01/09 00:28:10 imp Exp $ .\" .Dd April 5, 2008 .Dt REALPATH 3 diff --git a/stdlib/setenv-fbsd.c b/stdlib/setenv-fbsd.c index 27061ac..8965a6a 100644 --- a/stdlib/setenv-fbsd.c +++ b/stdlib/setenv-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)setenv.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/setenv.c,v 1.9 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/setenv.c,v 1.14 2007/05/01 16:02:41 ache Exp $"); #include #include @@ -54,8 +50,44 @@ extern void __malloc_check_env_name(const char *); __private_extern__ char *__findenv(const char *, int *, char **); __private_extern__ int __setenv(const char *, const char *, int, int, char ***, malloc_zone_t *); __private_extern__ void __unsetenv(const char *, char **, malloc_zone_t *); +__private_extern__ int init__zone0(int); + +/* + * _cthread_init_routine used to be called from crt1.o to initialize threads. + * This is no longer needed, as initialization happens in dylib initializers, + * but is provided to maintain backwards compatibility. Normally, for 10.5 + * or greater, _cthread_init_routine does nothing. + * + * Before 10.5, the _start routine in crt1.o clobbers environ with the original + * stack value, which effectively undoes any environment changes made in + * initializers. When LEGACY_CRT1_ENVIRON is defined, we replace the + * do-nothing routine with one that attempts to restore the environ value. + * But this only works if the setenv (and family) routines were used + * exclusively, (no direct manipulation of environ). Note that according to + * SUSv3, direct manipulation of environ may result in undefined behavior in + * setenv and family, so we don't support that (on less than 10.5). + */ +#ifdef BUILDING_VARIANT +# ifdef LEGACY_CRT1_ENVIRON +extern char **_saved_environ; +# endif /* LEGACY_CRT1_ENVIRON */ +#else /* !BUILDING_VARIANT */ +# ifdef LEGACY_CRT1_ENVIRON +__private_extern__ char **_saved_environ = NULL; + +static int +_legacy_crt1_environ(void) +{ + if (_saved_environ) *_NSGetEnviron() = _saved_environ; + return 0; +} +int (*_cthread_init_routine)(void) = _legacy_crt1_environ; + +# else /* !LEGACY_CRT1_ENVIRON */ +static int _do_nothing(void) { return 0; } +int (*_cthread_init_routine)(void) = _do_nothing; +# endif /* !LEGACY_CRT1_ENVIRON */ -#ifndef BUILDING_VARIANT /* * Create the environment malloc zone and give it a recognizable name. */ @@ -281,6 +313,10 @@ setenv(name, value, rewrite) const char *value; int rewrite; { +#ifdef LEGACY_CRT1_ENVIRON + int ret; +#endif /* LEGACY_CRT1_ENVIRON */ + /* no null ptr or empty str */ if(name == NULL || *name == 0) { errno = EINVAL; @@ -300,7 +336,13 @@ setenv(name, value, rewrite) /* insure __zone0 is set up before calling __malloc_check_env_name */ if (init__zone0(1)) return (-1); __malloc_check_env_name(name); /* see if we are changing a malloc environment variable */ +#ifdef LEGACY_CRT1_ENVIRON + ret = __setenv(name, value, rewrite, 1, _NSGetEnviron(), __zone0); + _saved_environ = *_NSGetEnviron(); + return ret; +#else /* !LEGACY_CRT1_ENVIRON */ return (__setenv(name, value, rewrite, 1, _NSGetEnviron(), __zone0)); +#endif /* !LEGACY_CRT1_ENVIRON */ } /* diff --git a/stdlib/strfmon-nbsd.c b/stdlib/strfmon-nbsd.c index ac7a536..2afa835 100644 --- a/stdlib/strfmon-nbsd.c +++ b/stdlib/strfmon-nbsd.c @@ -1,4 +1,4 @@ -/* $NetBSD: strfmon.c,v 1.6 2008/03/27 21:50:30 christos Exp $ */ +/* $NetBSD: strfmon.c,v 1.7 2009/01/30 23:46:03 lukem Exp $ */ /*- * Copyright (c) 2001 Alexey Zelkin @@ -32,7 +32,7 @@ #if 0 __FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.14 2003/03/20 08:18:55 ache Exp $"); #else -__RCSID("$NetBSD: strfmon.c,v 1.6 2008/03/27 21:50:30 christos Exp $"); +__RCSID("$NetBSD: strfmon.c,v 1.7 2009/01/30 23:46:03 lukem Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -202,7 +202,7 @@ _strfmon(char * __restrict s, size_t maxsize, locale_t loc, const char * __restr * required width ? */ - if (d + width >= maxsize) + if ((size_t)(d + width) >= maxsize) goto e2big_error; } diff --git a/stdlib/strfmon.3 b/stdlib/strfmon.3 index a3d9133..6b6976f 100644 --- a/stdlib/strfmon.3 +++ b/stdlib/strfmon.3 @@ -167,6 +167,20 @@ The format string is invalid. .It Bq Er ENOMEM Not enough memory for temporary buffers. .El +.Sh EXAMPLE +.Bd -literal -offset indent -compact + #include + #include + #include + + int main() { + char buf[200]; + setlocale(LC_ALL, "en_US"); + (void)strfmon (buf, sizeof(buf)-1, "%n" , 123456.78); + printf("%s\n", buf); + } +.Ed +.Pp .Sh SEE ALSO .Xr localeconv 3 , .Xr xlocale 3 diff --git a/stdlib/strtod.3 b/stdlib/strtod.3 index b57f810..463553d 100644 --- a/stdlib/strtod.3 +++ b/stdlib/strtod.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtod.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/strtod.3,v 1.19 2003/05/22 13:02:28 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strtod.3,v 1.22 2007/12/16 21:19:28 das Exp $ .\" .Dd March 2, 2003 .Dt STRTOD 3 @@ -100,8 +96,28 @@ For hexadecimal constants, the scaling is instead done by powers of 2. .Pp Alternatively, if the portion of the string following the optional -plus or minus sign begins with ``INFINITY'' or ``NAN'', ignoring -case, it is interpreted as an infinity or a quiet NaN, respectively. +plus or minus sign begins with +.Dq INFINITY +or +.Dq NAN , +ignoring case, it is interpreted as an infinity or a quiet \*(Na, +respectively. +The syntax +.Dq Xo Pf NAN( Ar "s" ) Xc , +where +.Ar s +is an alphanumeric string, produces the same value as the call +.Fo nan +.Qq Ar s Ns +.Fc +(respectively, +.Fo nanf +.Qq Ar s Ns +.Fc +and +.Fo nanl +.Qq Ar s Ns +.Fc . ) .Pp In any of the above cases, leading white-space characters in the string (as defined by the @@ -160,6 +176,7 @@ Overflow or underflow occurred. .Xr atof 3 , .Xr atoi 3 , .Xr atol 3 , +.Xr nan 3 , .Xr strtod_l 3 , .Xr strtol 3 , .Xr strtoul 3 , @@ -169,10 +186,7 @@ The .Fn strtod function conforms to -.St -isoC-99 , -with the exception of the bug noted below. -.Sh BUGS -These routines do not recognize the C99 ``NaN(...)'' syntax. +.St -isoC-99 . .Sh AUTHORS The author of this software is .An David M. Gay . diff --git a/stdlib/strtoimax-fbsd.c b/stdlib/strtoimax-fbsd.c index 38d8ee8..0c4c994 100644 --- a/stdlib/strtoimax-fbsd.c +++ b/stdlib/strtoimax-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "from @(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoimax.c,v 1.9 2003/01/01 18:48:43 schweikh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoimax.c,v 1.12 2007/01/09 00:28:10 imp Exp $"); #include "xlocale_private.h" @@ -79,7 +75,10 @@ strtoimax_l(const char * __restrict nptr, char ** __restrict endptr, int base, c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/strtol-fbsd.c b/stdlib/strtol-fbsd.c index 1ee81f4..cac93b2 100644 --- a/stdlib/strtol-fbsd.c +++ b/stdlib/strtol-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtol.c,v 1.17 2002/09/06 11:23:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtol.c,v 1.20 2007/01/09 00:28:10 imp Exp $"); #include "xlocale_private.h" @@ -80,7 +76,10 @@ strtol_l(const char * __restrict nptr, char ** __restrict endptr, int base, c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/strtol.3 b/stdlib/strtol.3 index dfa12fe..6a6c99e 100644 --- a/stdlib/strtol.3 +++ b/stdlib/strtol.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtol.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/strtol.3,v 1.20 2005/01/22 18:02:58 ache Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strtol.3,v 1.23 2007/04/10 11:17:00 ru Exp $ .\" .Dd November 28, 2001 .Dt STRTOL 3 diff --git a/stdlib/strtoll-fbsd.c b/stdlib/strtoll-fbsd.c index 2a3f9de..f7e11f3 100644 --- a/stdlib/strtoll-fbsd.c +++ b/stdlib/strtoll-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.19 2002/09/06 11:23:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.22 2007/01/09 00:28:10 imp Exp $"); #include "xlocale_private.h" @@ -79,7 +75,10 @@ strtoll_l(const char * __restrict nptr, char ** __restrict endptr, int base, c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/strtoq-fbsd.c b/stdlib/strtoq-fbsd.c index f6d28b1..9dd03e2 100644 --- a/stdlib/strtoq-fbsd.c +++ b/stdlib/strtoq-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoq.c,v 1.11 2002/08/15 09:25:04 robert Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoq.c,v 1.12 2007/01/09 00:28:10 imp Exp $"); #include "xlocale_private.h" diff --git a/stdlib/strtoul-fbsd.c b/stdlib/strtoul-fbsd.c index 816068a..c7b5967 100644 --- a/stdlib/strtoul-fbsd.c +++ b/stdlib/strtoul-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoul.c,v 1.16 2002/09/06 11:23:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoul.c,v 1.19 2007/01/09 00:28:10 imp Exp $"); #include "xlocale_private.h" @@ -77,7 +73,10 @@ strtoul_l(const char * __restrict nptr, char ** __restrict endptr, int base, c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/strtoul.3 b/stdlib/strtoul.3 index b7f916d..91c759e 100644 --- a/stdlib/strtoul.3 +++ b/stdlib/strtoul.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtoul.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/strtoul.3,v 1.20 2002/10/10 04:31:57 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strtoul.3,v 1.23 2007/01/09 00:28:10 imp Exp $ .\" .Dd November 28, 2001 .Dt STRTOUL 3 @@ -210,14 +206,16 @@ If no conversion could be performed, 0 is returned and the global variable .Va errno is set to -.Er EINVAL . +.Er EINVAL +(the last feature is not portable across all platforms). .Sh ERRORS .Bl -tag -width Er .It Bq Er EINVAL The value of .Fa base is not supported or -no conversion could be performed. +no conversion could be performed +(the last feature is not portable across all platforms). .It Bq Er ERANGE The given string was out of range; the value converted has been clamped. .El @@ -234,6 +232,7 @@ functions. .Sh SEE ALSO .Xr strtol 3 , .Xr strtol_l 3 , +.Xr strtonum 3 , .Xr wcstoul 3 , .Xr compat 5 .Sh STANDARDS diff --git a/stdlib/strtoull-fbsd.c b/stdlib/strtoull-fbsd.c index a26c033..8f2fd94 100644 --- a/stdlib/strtoull-fbsd.c +++ b/stdlib/strtoull-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.18 2002/09/06 11:23:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.21 2007/01/09 00:28:10 imp Exp $"); #include "xlocale_private.h" @@ -77,7 +73,10 @@ strtoull_l(const char * __restrict nptr, char ** __restrict endptr, int base, c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/strtoumax-fbsd.c b/stdlib/strtoumax-fbsd.c index de4dcb3..22400a5 100644 --- a/stdlib/strtoumax-fbsd.c +++ b/stdlib/strtoumax-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "from @(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoumax.c,v 1.8 2002/09/06 11:23:59 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoumax.c,v 1.11 2007/01/09 00:28:10 imp Exp $"); #include "xlocale_private.h" @@ -77,7 +73,10 @@ strtoumax_l(const char * __restrict nptr, char ** __restrict endptr, int base, c = *s++; } if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; diff --git a/stdlib/strtouq-fbsd.c b/stdlib/strtouq-fbsd.c index a8ea87c..29f0f13 100644 --- a/stdlib/strtouq-fbsd.c +++ b/stdlib/strtouq-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtouq.c,v 1.11 2002/08/15 09:25:04 robert Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtouq.c,v 1.12 2007/01/09 00:28:10 imp Exp $"); #include "xlocale_private.h" diff --git a/stdlib/system-fbsd.c b/stdlib/system-fbsd.c index 2b0424c..c2a56c7 100644 --- a/stdlib/system-fbsd.c +++ b/stdlib/system-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)system.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/system.c,v 1.10 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdlib/system.c,v 1.11 2007/01/09 00:28:10 imp Exp $"); #include "namespace.h" #include diff --git a/stdlib/system.3 b/stdlib/system.3 index 52dc99a..72bc6cb 100644 --- a/stdlib/system.3 +++ b/stdlib/system.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)system.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/system.3,v 1.11 2002/05/27 03:45:27 dd Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/system.3,v 1.13 2008/06/26 08:24:59 danger Exp $ .\" .Dd June 4, 1993 .Dt SYSTEM 3 @@ -74,7 +70,7 @@ pointer, will return non-zero if the command interpreter .Xr sh 1 is available, and zero if it is not. -.Pp +.Sh RETURN VALUES The .Fn system function diff --git a/stdlib/tsearch.3 b/stdlib/tsearch.3 index 64a8b2b..9d7a863 100644 --- a/stdlib/tsearch.3 +++ b/stdlib/tsearch.3 @@ -25,7 +25,7 @@ .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" OpenBSD: tsearch.3,v 1.2 1998/06/21 22:13:49 millert Exp -.\" $FreeBSD: src/lib/libc/stdlib/tsearch.3,v 1.13 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/tsearch.3,v 1.15 2006/06/23 13:36:33 keramida Exp $ .\" .Dd June 15, 1997 .Dt TSEARCH 3 @@ -59,7 +59,7 @@ .Ft void .Fo twalk .Fa "const void *root" -.Fa "void (*compar) (const void *node, VISIT order, int level)" +.Fa "void (*action) (const void *node, VISIT order, int level)" .Fc .Sh DESCRIPTION The @@ -156,10 +156,6 @@ common parlance. The traversal type "postorder" corresponds to what would typically be referred to as in-order, and the traversal type "endorder" corresponds to what would typically be referred to as post-order. -.Sh SEE ALSO -.Xr bsearch 3 , -.Xr hsearch 3 , -.Xr lsearch 3 .Sh RETURN VALUES The .Fn tsearch @@ -179,3 +175,7 @@ is NULL or the node cannot be found. The .Fn twalk function returns no value. +.Sh SEE ALSO +.Xr bsearch 3 , +.Xr hsearch 3 , +.Xr lsearch 3 diff --git a/stdtime/FreeBSD/asctime.c b/stdtime/FreeBSD/asctime.c index c28abae..0a291df 100644 --- a/stdtime/FreeBSD/asctime.c +++ b/stdtime/FreeBSD/asctime.c @@ -1,15 +1,21 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. +*/ + +/* +** Avoid the temptation to punt entirely to strftime; +** the output of strftime is supposed to be locale specific +** whereas the output of asctime is supposed to be constant. */ #include #ifndef lint #ifndef NOID -static char elsieid[] __unused = "@(#)asctime.c 7.9"; +static char elsieid[] __unused = "@(#)asctime.c 8.2"; #endif /* !defined NOID */ #endif /* !defined lint */ -__FBSDID("$FreeBSD: src/lib/libc/stdtime/asctime.c,v 1.12 2004/06/14 10:31:52 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdtime/asctime.c,v 1.13 2009/05/23 06:31:50 edwin Exp $"); /*LINTLIBRARY*/ @@ -19,7 +25,57 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime/asctime.c,v 1.12 2004/06/14 10:31:52 st #include "tzfile.h" /* -** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, Second Edition, 1996-07-12. +** Some systems only handle "%.2d"; others only handle "%02d"; +** "%02.2d" makes (most) everybody happy. +** At least some versions of gcc warn about the %02.2d; +** we conditionalize below to avoid the warning. +*/ +/* +** All years associated with 32-bit time_t values are exactly four digits long; +** some years associated with 64-bit time_t values are not. +** Vintage programs are coded for years that are always four digits long +** and may assume that the newline always lands in the same place. +** For years that are less than four digits, we pad the output with +** leading zeroes to get the newline in the traditional place. +** The -4 ensures that we get four characters of output even if +** we call a strftime variant that produces fewer characters for some years. +** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year, +** but many implementations pad anyway; most likely the standards are buggy. +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n" +#endif /* !defined __GNUC__ */ +/* +** For years that are more than four digits we put extra spaces before the year +** so that code trying to overwrite the newline won't end up overwriting +** a digit within a year and truncating the year (operating on the assumption +** that no output is better than wrong output). +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n" +#endif /* !defined __GNUC__ */ + +#define STD_ASCTIME_BUF_SIZE 26 +/* +** Big enough for something such as +** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n +** (two three-character abbreviations, five strings denoting integers, +** seven explicit spaces, two explicit colons, a newline, +** and a trailing ASCII nul). +** The values above are for systems where an int is 32 bits and are provided +** as an example; the define below calculates the maximum for the system at +** hand. +*/ +#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1) + +static char buf_asctime[MAX_ASCTIME_BUF_SIZE]; + +/* +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. */ char * @@ -36,6 +92,8 @@ char * buf; }; const char * wn; const char * mn; + char year[INT_STRLEN_MAXIMUM(int) + 2]; + char result[MAX_ASCTIME_BUF_SIZE]; if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) wn = "???"; @@ -44,35 +102,41 @@ char * buf; mn = "???"; else mn = mon_name[timeptr->tm_mon]; /* - ** The X3J11-suggested format is - ** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n" - ** Since the .2 in 02.2d is ignored, we drop it. + ** Use strftime's %Y to generate the year, to avoid overflow problems + ** when computing timeptr->tm_year + TM_YEAR_BASE. + ** Assume that strftime is unaffected by other out-of-range members + ** (e.g., timeptr->tm_mday) when processing "%Y". */ - (void) sprintf(buf, "%.3s %.3s%3d %02d:%02d:%02d %d\n", + (void) strftime(year, sizeof year, "%Y", timeptr); + /* + ** We avoid using snprintf since it's not available on all systems. + */ + (void) sprintf(result, + ((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B), wn, mn, timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec, - TM_YEAR_BASE + timeptr->tm_year); - return buf; + year); + if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) { + (void) strcpy(buf, result); + return buf; + } else { +#ifdef EOVERFLOW + errno = EOVERFLOW; +#else /* !defined EOVERFLOW */ + errno = EINVAL; +#endif /* !defined EOVERFLOW */ + return NULL; + } } /* -** A la X3J11, with core dump avoidance. +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. */ char * asctime(timeptr) const struct tm * timeptr; { - /* - ** Big enough for something such as - ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n - ** (two three-character abbreviations, five strings denoting integers, - ** three explicit spaces, two explicit colons, a newline, - ** and a trailing ASCII nul). - */ - static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) + - 3 + 2 + 1 + 1]; - - return asctime_r(timeptr, result); + return asctime_r(timeptr, buf_asctime); } diff --git a/stdtime/FreeBSD/asctime.c.patch b/stdtime/FreeBSD/asctime.c.patch index 4adbae4..07e8113 100644 --- a/stdtime/FreeBSD/asctime.c.patch +++ b/stdtime/FreeBSD/asctime.c.patch @@ -1,11 +1,8 @@ ---- asctime.c.orig 2008-12-15 11:41:07.000000000 -0800 -+++ asctime.c 2009-01-21 17:09:27.000000000 -0800 -@@ -22,10 +22,10 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime - ** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, Second Edition, 1996-07-12. +--- asctime.c.bsdnew 2009-11-14 13:55:43.000000000 -0800 ++++ asctime.c 2009-11-14 14:04:38.000000000 -0800 +@@ -79,9 +79,7 @@ static char buf_asctime[MAX_ASCTIME_BUF_ */ -+#define EXPECTEDLEN 26 -+ char * -asctime_r(timeptr, buf) -const struct tm * timeptr; @@ -14,55 +11,3 @@ { static const char wday_name[][3] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -@@ -36,6 +36,8 @@ char * buf; - }; - const char * wn; - const char * mn; -+ int len; -+ char tmp[EXPECTEDLEN]; - - if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) - wn = "???"; -@@ -48,31 +50,28 @@ char * buf; - ** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n" - ** Since the .2 in 02.2d is ignored, we drop it. - */ -- (void) sprintf(buf, "%.3s %.3s%3d %02d:%02d:%02d %d\n", -+ /* -+ ** Because various values in the tm structure may cause the -+ ** resulting string to be longer than the 26-bytes that is -+ ** specified in the spec, we should return NULL rather than -+ ** possibly overwrite beyond the string. -+ */ -+ len = snprintf(tmp, EXPECTEDLEN, "%.3s %.3s%3d %02d:%02d:%02d %d\n", - wn, mn, - timeptr->tm_mday, timeptr->tm_hour, - timeptr->tm_min, timeptr->tm_sec, - TM_YEAR_BASE + timeptr->tm_year); -+ if (len >= EXPECTEDLEN) -+ return NULL; -+ strcpy(buf, tmp); - return buf; - } - --/* --** A la X3J11, with core dump avoidance. --*/ -- - char * - asctime(timeptr) - const struct tm * timeptr; - { -- /* -- ** Big enough for something such as -- ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n -- ** (two three-character abbreviations, five strings denoting integers, -- ** three explicit spaces, two explicit colons, a newline, -- ** and a trailing ASCII nul). -- */ -- static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) + -- 3 + 2 + 1 + 1]; -+ static char result[EXPECTEDLEN]; - - return asctime_r(timeptr, result); - } diff --git a/stdtime/FreeBSD/ctime.3 b/stdtime/FreeBSD/ctime.3 index e20b954..5e7f3b7 100644 --- a/stdtime/FreeBSD/ctime.3 +++ b/stdtime/FreeBSD/ctime.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)ctime.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdtime/ctime.3,v 1.22 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdtime/ctime.3,v 1.24 2007/01/09 00:28:11 imp Exp $ .\" .Dd January 2, 1999 .Dt CTIME 3 @@ -118,7 +114,7 @@ element of .Fa tzname to a pointer to an .Tn ASCII -string that's the time zone abbreviation to be +string that is the time zone abbreviation to be used with .Fn localtime Ns 's return value. diff --git a/stdtime/FreeBSD/ctime.3.patch b/stdtime/FreeBSD/ctime.3.patch index e046ce8..b91ccb4 100644 --- a/stdtime/FreeBSD/ctime.3.patch +++ b/stdtime/FreeBSD/ctime.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdtime/FreeBSD/ctime.3 2004-11-25 11:38:44.000000000 -0800 -+++ _SB/Libc/stdtime/FreeBSD/ctime.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -56,31 +56,31 @@ +--- ctime.3.bsdnew 2009-11-14 13:55:43.000000000 -0800 ++++ ctime.3 2009-11-14 14:01:29.000000000 -0800 +@@ -52,31 +52,31 @@ .In time.h .Vt extern char *tzname[2] ; .Ft char * @@ -46,7 +46,7 @@ and .Fn localtime all take as an argument a time value representing the time in seconds since -@@ -92,10 +92,10 @@ +@@ -88,10 +88,10 @@ January 1, 1970; see The function .Fn localtime converts the time value pointed at by @@ -60,7 +60,7 @@ the broken-out time information for the value after adjusting for the current time zone (and any other factors such as Daylight Saving Time). Time zone adjustments are performed as specified by the -@@ -106,7 +106,7 @@ +@@ -102,7 +102,7 @@ The function .Fn localtime uses .Xr tzset 3 @@ -69,11 +69,11 @@ .Xr tzset 3 has not already been called by the process. .Pp -@@ -118,36 +118,36 @@ +@@ -114,36 +114,36 @@ element of .Fa tzname to a pointer to an .Tn ASCII --string that's the time zone abbreviation to be +-string that is the time zone abbreviation to be +string containing the time zone abbreviation to be used with .Fn localtime Ns 's @@ -116,7 +116,7 @@ The .Fn localtime_r and -@@ -156,17 +156,17 @@ +@@ -152,17 +152,17 @@ functions provide the same functionality as .Fn localtime and @@ -138,7 +138,7 @@ to the form shown in the example above. .Pp -@@ -174,17 +174,19 @@ +@@ -170,17 +170,19 @@ The .Fn asctime_r function provides the same functionality as @@ -163,7 +163,7 @@ values returned by the .Xr time 3 function (that is, seconds from the Epoch, -@@ -197,17 +199,17 @@ +@@ -193,17 +195,17 @@ interprets the input structure according .Xr tzset 3 ) . The .Fn timegm @@ -186,7 +186,7 @@ For example, October 40 is changed into November 9, a -@@ -223,7 +225,7 @@ +@@ -219,7 +221,7 @@ of \-2 means 2 months before January of causes .Fn mktime to presume initially that summer time (for example, Daylight Saving Time) @@ -195,7 +195,7 @@ A negative value for .Fa tm_isdst causes the -@@ -265,7 +267,8 @@ +@@ -261,7 +263,8 @@ returns the difference between two calen .Fa time0 ) , expressed in seconds. .Pp @@ -205,7 +205,7 @@ .In time.h include file. The tm structure includes at least the following fields: -@@ -286,14 +289,14 @@ +@@ -282,14 +285,14 @@ long tm_gmtoff; /\(** offset from UTC in The field .Fa tm_isdst diff --git a/stdtime/FreeBSD/difftime.c b/stdtime/FreeBSD/difftime.c index df55753..350ee54 100644 --- a/stdtime/FreeBSD/difftime.c +++ b/stdtime/FreeBSD/difftime.c @@ -1,87 +1,69 @@ /* ** This file is in the public domain, so clarified as of -** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. */ #include #ifndef lint #ifndef NOID -static char elsieid[] __unused = "@(#)difftime.c 7.9"; +static char elsieid[] __unused = "@(#)difftime.c 8.1"; #endif /* !defined NOID */ #endif /* !defined lint */ -__FBSDID("$FreeBSD: src/lib/libc/stdtime/difftime.c,v 1.8 2004/06/14 10:31:52 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdtime/difftime.c,v 1.9 2009/05/23 06:31:50 edwin Exp $"); /*LINTLIBRARY*/ #include "namespace.h" -#include "private.h" +#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */ #include "un-namespace.h" -/* -** Algorithm courtesy Paul Eggert (eggert@twinsun.com). -*/ - -#ifdef HAVE_LONG_DOUBLE -#define long_double long double -#endif /* defined HAVE_LONG_DOUBLE */ -#ifndef HAVE_LONG_DOUBLE -#define long_double double -#endif /* !defined HAVE_LONG_DOUBLE */ - double difftime(time1, time0) const time_t time1; const time_t time0; { - time_t delta; - time_t hibit; - - { - time_t tt; - double d; - long_double ld; - - if (sizeof tt < sizeof d) - return (double) time1 - (double) time0; - if (sizeof tt < sizeof ld) - return (long_double) time1 - (long_double) time0; + /* + ** If (sizeof (double) > sizeof (time_t)) simply convert and subtract + ** (assuming that the larger type has more precision). + ** This is the common real-world case circa 2004. + */ + if (sizeof (double) > sizeof (time_t)) + return (double) time1 - (double) time0; + if (!TYPE_INTEGRAL(time_t)) { + /* + ** time_t is floating. + */ + return time1 - time0; + } + if (!TYPE_SIGNED(time_t)) { + /* + ** time_t is integral and unsigned. + ** The difference of two unsigned values can't overflow + ** if the minuend is greater than or equal to the subtrahend. + */ + if (time1 >= time0) + return time1 - time0; + else return -((double) (time0 - time1)); } - if (time1 < time0) - return -difftime(time0, time1); /* - ** As much as possible, avoid loss of precision - ** by computing the difference before converting to double. + ** time_t is integral and signed. + ** Handle cases where both time1 and time0 have the same sign + ** (meaning that their difference cannot overflow). */ - delta = time1 - time0; - if (delta >= 0) - return delta; + if ((time1 < 0) == (time0 < 0)) + return time1 - time0; /* - ** Repair delta overflow. + ** time1 and time0 have opposite signs. + ** Punt if unsigned long is too narrow. */ - hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1); + if (sizeof (unsigned long) < sizeof (time_t)) + return (double) time1 - (double) time0; /* - ** The following expression rounds twice, which means - ** the result may not be the closest to the true answer. - ** For example, suppose time_t is 64-bit signed int, - ** long_double is IEEE 754 double with default rounding, - ** time1 = 9223372036854775807 and time0 = -1536. - ** Then the true difference is 9223372036854777343, - ** which rounds to 9223372036854777856 - ** with a total error of 513. - ** But delta overflows to -9223372036854774273, - ** which rounds to -9223372036854774784, and correcting - ** this by subtracting 2 * (long_double) hibit - ** (i.e. by adding 2**64 = 18446744073709551616) - ** yields 9223372036854776832, which - ** rounds to 9223372036854775808 - ** with a total error of 1535 instead. - ** This problem occurs only with very large differences. - ** It's too painful to fix this portably. - ** We are not alone in this problem; - ** some C compilers round twice when converting - ** large unsigned types to small floating types, - ** so if time_t is unsigned the "return delta" above - ** has the same double-rounding problem with those compilers. + ** Stay calm...decent optimizers will eliminate the complexity below. */ - return delta - 2 * (long_double) hibit; + if (time1 >= 0 /* && time0 < 0 */) + return (unsigned long) time1 + + (unsigned long) (-(time0 + 1)) + 1; + return -(double) ((unsigned long) time0 + + (unsigned long) (-(time1 + 1)) + 1); } diff --git a/stdtime/FreeBSD/localtime.c b/stdtime/FreeBSD/localtime.c index c07f298..97b022c 100644 --- a/stdtime/FreeBSD/localtime.c +++ b/stdtime/FreeBSD/localtime.c @@ -9,7 +9,7 @@ static char elsieid[] __unused = "@(#)localtime.c 7.78"; #endif /* !defined NOID */ #endif /* !defined lint */ -__FBSDID("$FreeBSD: src/lib/libc/stdtime/localtime.c,v 1.40 2004/08/24 00:15:37 peter Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdtime/localtime.c,v 1.43 2008/04/01 06:56:11 davidxu Exp $"); /* ** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu). @@ -34,6 +34,21 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime/localtime.c,v 1.40 2004/08/24 00:15:37 #define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x) #define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x) +#define _RWLOCK_RDLOCK(x) \ + do { \ + if (__isthreaded) _pthread_rwlock_rdlock(x); \ + } while (0) + +#define _RWLOCK_WRLOCK(x) \ + do { \ + if (__isthreaded) _pthread_rwlock_wrlock(x); \ + } while (0) + +#define _RWLOCK_UNLOCK(x) \ + do { \ + if (__isthreaded) _pthread_rwlock_unlock(x); \ + } while (0) + /* ** SunOS 4.1.1 headers lack O_BINARY. */ @@ -196,7 +211,7 @@ static struct state gmtmem; static char lcl_TZname[TZ_STRLEN_MAX + 1]; static int lcl_is_set; static int gmt_is_set; -static pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_rwlock_t lcl_rwlock = PTHREAD_RWLOCK_INITIALIZER; static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; char * tzname[2] = { @@ -949,10 +964,18 @@ struct state * const sp; } static void -tzsetwall_basic(void) +tzsetwall_basic(int rdlocked) { - if (lcl_is_set < 0) + if (!rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); + if (lcl_is_set < 0) { + if (!rdlocked) + _RWLOCK_UNLOCK(&lcl_rwlock); return; + } + _RWLOCK_UNLOCK(&lcl_rwlock); + + _RWLOCK_WRLOCK(&lcl_rwlock); lcl_is_set = -1; #ifdef ALL_STATE @@ -960,6 +983,9 @@ tzsetwall_basic(void) lclptr = (struct state *) malloc(sizeof *lclptr); if (lclptr == NULL) { settzname(); /* all we can do */ + _RWLOCK_UNLOCK(&lcl_rwlock); + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); return; } } @@ -967,29 +993,39 @@ tzsetwall_basic(void) if (tzload((char *) NULL, lclptr) != 0) gmtload(lclptr); settzname(); + _RWLOCK_UNLOCK(&lcl_rwlock); + + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); } void tzsetwall(void) { - _MUTEX_LOCK(&lcl_mutex); - tzsetwall_basic(); - _MUTEX_UNLOCK(&lcl_mutex); + tzsetwall_basic(0); } static void -tzset_basic(void) +tzset_basic(int rdlocked) { const char * name; name = getenv("TZ"); if (name == NULL) { - tzsetwall_basic(); + tzsetwall_basic(rdlocked); return; } - if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) + if (!rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); + if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) { + if (!rdlocked) + _RWLOCK_UNLOCK(&lcl_rwlock); return; + } + _RWLOCK_UNLOCK(&lcl_rwlock); + + _RWLOCK_WRLOCK(&lcl_rwlock); lcl_is_set = strlen(name) < sizeof lcl_TZname; if (lcl_is_set) (void) strcpy(lcl_TZname, name); @@ -999,6 +1035,9 @@ tzset_basic(void) lclptr = (struct state *) malloc(sizeof *lclptr); if (lclptr == NULL) { settzname(); /* all we can do */ + _RWLOCK_UNLOCK(&lcl_rwlock); + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); return; } } @@ -1018,14 +1057,16 @@ tzset_basic(void) if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) (void) gmtload(lclptr); settzname(); + _RWLOCK_UNLOCK(&lcl_rwlock); + + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); } void tzset(void) { - _MUTEX_LOCK(&lcl_mutex); - tzset_basic(); - _MUTEX_UNLOCK(&lcl_mutex); + tzset_basic(0); } /* @@ -1093,14 +1134,16 @@ const time_t * const timep; struct tm *p_tm; if (__isthreaded != 0) { - _pthread_mutex_lock(&localtime_mutex); if (localtime_key < 0) { - if (_pthread_key_create(&localtime_key, free) < 0) { - _pthread_mutex_unlock(&localtime_mutex); - return(NULL); + _pthread_mutex_lock(&localtime_mutex); + if (localtime_key < 0) { + if (_pthread_key_create(&localtime_key, free) < 0) { + _pthread_mutex_unlock(&localtime_mutex); + return(NULL); + } } + _pthread_mutex_unlock(&localtime_mutex); } - _pthread_mutex_unlock(&localtime_mutex); p_tm = _pthread_getspecific(localtime_key); if (p_tm == NULL) { if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) @@ -1108,13 +1151,13 @@ const time_t * const timep; return(NULL); _pthread_setspecific(localtime_key, p_tm); } - _pthread_mutex_lock(&lcl_mutex); - tzset_basic(); + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); localsub(timep, 0L, p_tm); - _pthread_mutex_unlock(&lcl_mutex); + _RWLOCK_UNLOCK(&lcl_rwlock); return(p_tm); } else { - tzset_basic(); + tzset_basic(0); localsub(timep, 0L, &tm); return(&tm); } @@ -1129,10 +1172,10 @@ localtime_r(timep, tm) const time_t * const timep; struct tm * tm; { - _MUTEX_LOCK(&lcl_mutex); - tzset_basic(); + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); localsub(timep, 0L, tm); - _MUTEX_UNLOCK(&lcl_mutex); + _RWLOCK_UNLOCK(&lcl_rwlock); return tm; } @@ -1146,16 +1189,18 @@ const time_t * const timep; const long offset; struct tm * const tmp; { - _MUTEX_LOCK(&gmt_mutex); if (!gmt_is_set) { - gmt_is_set = TRUE; + _MUTEX_LOCK(&gmt_mutex); + if (!gmt_is_set) { #ifdef ALL_STATE - gmtptr = (struct state *) malloc(sizeof *gmtptr); - if (gmtptr != NULL) + gmtptr = (struct state *) malloc(sizeof *gmtptr); + if (gmtptr != NULL) #endif /* defined ALL_STATE */ - gmtload(gmtptr); + gmtload(gmtptr); + gmt_is_set = TRUE; + } + _MUTEX_UNLOCK(&gmt_mutex); } - _MUTEX_UNLOCK(&gmt_mutex); timesub(timep, offset, gmtptr, tmp); #ifdef TM_ZONE /* @@ -1187,14 +1232,16 @@ const time_t * const timep; struct tm *p_tm; if (__isthreaded != 0) { - _pthread_mutex_lock(&gmtime_mutex); if (gmtime_key < 0) { - if (_pthread_key_create(&gmtime_key, free) < 0) { - _pthread_mutex_unlock(&gmtime_mutex); - return(NULL); + _pthread_mutex_lock(&gmtime_mutex); + if (gmtime_key < 0) { + if (_pthread_key_create(&gmtime_key, free) < 0) { + _pthread_mutex_unlock(&gmtime_mutex); + return(NULL); + } } + _pthread_mutex_unlock(&gmtime_mutex); } - _pthread_mutex_unlock(&gmtime_mutex); /* * Changed to follow POSIX.1 threads standard, which * is what BSD currently has. @@ -1518,8 +1565,8 @@ const int do_norm_secs; ** If we have more than this, we will overflow tm_year for tmcomp(). ** We should really return an error if we cannot represent it. */ - if (bits > 56) - bits = 56; + if (bits > 48) + bits = 48; /* ** If time_t is signed, then 0 is just above the median, ** assuming two's complement arithmetic. @@ -1680,10 +1727,10 @@ mktime(tmp) struct tm * const tmp; { time_t mktime_return_value; - _MUTEX_LOCK(&lcl_mutex); - tzset_basic(); + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); mktime_return_value = time1(tmp, localsub, 0L); - _MUTEX_UNLOCK(&lcl_mutex); + _RWLOCK_UNLOCK(&lcl_rwlock); return(mktime_return_value); } diff --git a/stdtime/FreeBSD/localtime.c.patch b/stdtime/FreeBSD/localtime.c.patch index 7609646..67e338f 100644 --- a/stdtime/FreeBSD/localtime.c.patch +++ b/stdtime/FreeBSD/localtime.c.patch @@ -1,5 +1,5 @@ ---- localtime.c.orig 2008-12-15 11:41:07.000000000 -0800 -+++ localtime.c 2009-01-21 15:43:59.000000000 -0800 +--- localtime.c.orig 2011-05-02 23:14:13.000000000 -0700 ++++ localtime.c 2011-05-03 17:12:02.000000000 -0700 @@ -22,8 +22,22 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime #include "namespace.h" #include @@ -23,7 +23,7 @@ #include "private.h" #include "un-namespace.h" -@@ -135,40 +149,96 @@ struct rule { +@@ -150,40 +164,94 @@ struct rule { #define DAY_OF_YEAR 1 /* n - day of year */ #define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ @@ -63,10 +63,8 @@ + long offset, + int unix03); +__private_extern__ -+void tzset_basic(void); ++void tzset_basic(int); -+#define lcl_mutex _st_lcl_mutex -+ +#if !BUILDING_VARIANT static long detzcode(const char * codep); -static const char * getzname(const char * strp); @@ -129,25 +127,23 @@ static int tmcomp(const struct tm * atmp, const struct tm * btmp); static time_t transtime(time_t janfirst, int year, -@@ -194,10 +264,15 @@ static struct state gmtmem; +@@ -209,9 +277,14 @@ static struct state gmtmem; #endif /* !defined TZ_STRLEN_MAX */ static char lcl_TZname[TZ_STRLEN_MAX + 1]; +#ifdef NOTIFY_TZ -+#define lcl_is_set (lcl_notify.is_set) -+#define gmt_is_set (gmt_notify.is_set) ++#define lcl_is_set (lcl_notify.is_set) ++#define gmt_is_set (gmt_notify.is_set) +#else /* ! NOTIFY_TZ */ static int lcl_is_set; static int gmt_is_set; --static pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER; --static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; +-static pthread_rwlock_t lcl_rwlock = PTHREAD_RWLOCK_INITIALIZER; +#endif /* NOTIFY_TZ */ -+__private_extern__ pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER; -+static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; ++__private_extern__ pthread_rwlock_t lcl_rwlock = PTHREAD_RWLOCK_INITIALIZER; + static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; char * tzname[2] = { - wildabbr, -@@ -214,15 +289,62 @@ char * tzname[2] = { +@@ -229,15 +302,62 @@ char * tzname[2] = { static struct tm tm; @@ -212,7 +208,19 @@ static long detzcode(codep) const char * const codep; -@@ -246,14 +368,14 @@ settzname(void) +@@ -255,51 +375,203 @@ static void + settzname(void) + { + struct state * sp = lclptr; +- int i; ++ int i, need; ++ unsigned char * types; ++#define NEED_STD 1 ++#define NEED_DST 2 ++#define NEED_DAYLIGHT 4 ++#define NEED_ALL (NEED_STD | NEED_DST | NEED_DAYLIGHT) + + tzname[0] = wildabbr; tzname[1] = wildabbr; #ifdef USG_COMPAT daylight = 0; @@ -229,19 +237,85 @@ return; } #endif /* defined ALL_STATE */ -@@ -266,7 +388,7 @@ settzname(void) - if (ttisp->tt_isdst) +- for (i = 0; i < sp->typecnt; ++i) { +- const struct ttinfo * const ttisp = &sp->ttis[i]; ++ /* ++ * PR-3765457: The original settzname went sequentially through the ttis ++ * array, rather than correctly indexing via the types array, to get ++ * the real order of the timezone changes. In addition, as a speed up, ++ * we start at the end of the changes, and work back, so that most of ++ * the time, we don't have to look through the entire array. ++ */ ++ if (sp->timecnt == 0 && sp->typecnt == 1) { ++ /* ++ * Unfortunately, there is an edge case when typecnt == 1 and ++ * timecnt == 0, which would cause the loop to never run. So ++ * in that case, we fudge things up so that it is as if ++ * timecnt == 1. ++ */ ++ i = 0; ++ types = (unsigned char *)""; /* we use the null as index */ ++ } else { ++ /* the usual case */ ++ i = sp->timecnt - 1; ++ types = sp->types; ++ } ++ need = NEED_ALL; ++ for (; i >= 0 && need; --i) { ++ const struct ttinfo * const ttisp = &sp->ttis[types[i]]; + +- tzname[ttisp->tt_isdst] = +- &sp->chars[ttisp->tt_abbrind]; + #ifdef USG_COMPAT +- if (ttisp->tt_isdst) ++ if ((need & NEED_DAYLIGHT) && ttisp->tt_isdst) { ++ need &= ~NEED_DAYLIGHT; daylight = 1; - if (i == 0 || !ttisp->tt_isdst) +- if (i == 0 || !ttisp->tt_isdst) - timezone = -(ttisp->tt_gmtoff); -+ _st_set_timezone(-(ttisp->tt_gmtoff)); ++ } #endif /* defined USG_COMPAT */ ++ if (ttisp->tt_isdst) { ++ if (need & NEED_DST) { ++ need &= ~NEED_DST; ++ tzname[1] = &sp->chars[ttisp->tt_abbrind]; #ifdef ALTZONE - if (i == 0 || ttisp->tt_isdst) -@@ -286,6 +408,119 @@ settzname(void) +- if (i == 0 || ttisp->tt_isdst) +- altzone = -(ttisp->tt_gmtoff); ++ altzone = -(ttisp->tt_gmtoff); + #endif /* defined ALTZONE */ ++ } ++ } else if (need & NEED_STD) { ++ need &= ~NEED_STD; ++ tzname[0] = &sp->chars[ttisp->tt_abbrind]; ++#ifdef USG_COMPAT ++ _st_set_timezone(-(ttisp->tt_gmtoff)); ++#endif /* defined USG_COMPAT */ ++ } ++#if defined(ALTZONE) || defined(USG_COMPAT) ++ if (i == 0) { ++#endif /* defined(ALTZONE) || defined(USG_COMPAT) */ ++#ifdef ALTZONE ++ if (need & NEED_DST) ++ altzone = -(ttisp->tt_gmtoff); ++#endif /* defined ALTZONE */ ++#ifdef USG_COMPAT ++ if (need & NEED_STD) ++ _st_set_timezone(-(ttisp->tt_gmtoff)); ++#endif /* defined USG_COMPAT */ ++#if defined(ALTZONE) || defined(USG_COMPAT) ++ } ++#endif /* defined(ALTZONE) || defined(USG_COMPAT) */ } - } - +- /* +- ** And to get the latest zone names into tzname. . . +- */ +- for (i = 0; i < sp->timecnt; ++i) { +- const struct ttinfo * const ttisp = +- &sp->ttis[ +- sp->types[i]]; ++} ++ +#ifdef NOTIFY_TZ +static void +notify_check_tz(notify_tz_t *p) @@ -287,7 +361,9 @@ + char *name; + unsigned int nstat; + int ncheck; -+ + +- tzname[ttisp->tt_isdst] = +- &sp->chars[ttisp->tt_abbrind]; + if (__notify_78945668_info__ < 0) + return; + /*---------------------------------------------------------------- @@ -350,15 +426,14 @@ +#endif /* NOTIFY_TZ_LOG */ + return; + } -+ } + } + notify_check(p->token, &ncheck); /* this always returns true */ -+} + } +#endif /* NOTIFY_TZ */ -+ + static int tzload(name, sp) - const char * name; -@@ -295,6 +530,9 @@ struct state * const sp; +@@ -310,6 +582,9 @@ struct state * const sp; int i; int fid; @@ -368,7 +443,7 @@ /* XXX The following is from OpenBSD, and I'm not sure it is correct */ if (name != NULL && issetugid() != 0) if ((name[0] == ':' && name[1] == '/') || -@@ -312,7 +550,15 @@ struct state * const sp; +@@ -327,7 +602,15 @@ struct state * const sp; ** to hold the longest file name string that the implementation ** guarantees can be opened." */ @@ -384,7 +459,7 @@ if (name[0] == ':') ++name; -@@ -320,7 +566,11 @@ struct state * const sp; +@@ -335,7 +618,11 @@ struct state * const sp; if (!doaccess) { if ((p = TZDIR) == NULL) return -1; @@ -396,7 +471,7 @@ return -1; (void) strcpy(fullname, p); (void) strcat(fullname, "/"); -@@ -332,6 +582,10 @@ struct state * const sp; +@@ -347,6 +634,10 @@ struct state * const sp; doaccess = TRUE; name = fullname; } @@ -407,7 +482,7 @@ if (doaccess && access(name, R_OK) != 0) return -1; if ((fid = _open(name, OPEN_MODE)) == -1) -@@ -350,6 +604,9 @@ struct state * const sp; +@@ -365,6 +656,9 @@ struct state * const sp; int ttisstdcnt; int ttisgmtcnt; @@ -417,7 +492,7 @@ i = _read(fid, u.buf, sizeof u.buf); if (_close(fid) != 0) return -1; -@@ -456,14 +713,24 @@ static const int year_lengths[2] = { +@@ -471,14 +765,24 @@ static const int year_lengths[2] = { */ static const char * @@ -443,7 +518,7 @@ return strp; } -@@ -743,16 +1010,15 @@ const int lastditch; +@@ -758,16 +1062,15 @@ const int lastditch; int load_result; INITIALIZE(dstname); @@ -462,7 +537,7 @@ if (stdlen < 3) return -1; if (*name == '\0') -@@ -764,12 +1030,14 @@ const int lastditch; +@@ -779,12 +1082,14 @@ const int lastditch; } } load_result = tzload(TZDEFRULES, sp); @@ -479,27 +554,45 @@ if (dstlen < 3) return -1; if (*name != '\0' && *name != ',' && *name != ';') { -@@ -951,8 +1219,19 @@ struct state * const sp; +@@ -966,13 +1271,37 @@ struct state * const sp; static void - tzsetwall_basic(void) + tzsetwall_basic(int rdlocked) { +#ifdef NOTIFY_TZ + notify_check_tz(&lcl_notify); ++#else ++ if (TZDEFAULT) { ++ static struct timespec last_mtimespec = {0, 0}; ++ struct stat statbuf; ++ ++ if (lstat(TZDEFAULT, &statbuf) == 0) { ++ if (statbuf.st_mtimespec.tv_sec > last_mtimespec.tv_sec || ++ (statbuf.st_mtimespec.tv_sec == last_mtimespec.tv_sec && ++ statbuf.st_mtimespec.tv_nsec > last_mtimespec.tv_nsec)) { ++ /* Trigger resetting the local TZ */ ++ lcl_is_set = 0; ++ } ++ last_mtimespec = statbuf.st_mtimespec; ++ } ++ } +#endif /* NOTIFY_TZ */ + if (!rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); + if (lcl_is_set < 0) { +#ifdef NOTIFY_TZ_DEBUG -+ if (lcl_is_set < 0) { + NOTIFY_TZ_PRINTF("tzsetwall_basic lcl_is_set < 0\n"); -+ return; -+ } -+ NOTIFY_TZ_PRINTF("tzsetwall_basic not set\n"); -+#else /* ! NOTIFY_TZ_DEBUG */ - if (lcl_is_set < 0) ++#endif + if (!rdlocked) + _RWLOCK_UNLOCK(&lcl_rwlock); return; -+#endif /* NOTIFY_TZ_DEBUG */ - lcl_is_set = -1; + } ++#ifdef NOTIFY_TZ_DEBUG ++ NOTIFY_TZ_PRINTF("tzsetwall_basic not set\n"); ++#endif + _RWLOCK_UNLOCK(&lcl_rwlock); - #ifdef ALL_STATE -@@ -966,18 +1245,24 @@ tzsetwall_basic(void) + _RWLOCK_WRLOCK(&lcl_rwlock); +@@ -992,6 +1321,9 @@ tzsetwall_basic(int rdlocked) #endif /* defined ALL_STATE */ if (tzload((char *) NULL, lclptr) != 0) gmtload(lclptr); @@ -507,44 +600,42 @@ + notify_register_tz(fullname, &lcl_notify); +#endif /* NOTIFY_TZ */ settzname(); - } + _RWLOCK_UNLOCK(&lcl_rwlock); +@@ -1002,10 +1334,13 @@ tzsetwall_basic(int rdlocked) void tzsetwall(void) { +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("tzsetwall called\n"); +#endif /* NOTIFY_TZ_DEBUG */ - _MUTEX_LOCK(&lcl_mutex); - tzsetwall_basic(); - _MUTEX_UNLOCK(&lcl_mutex); + tzsetwall_basic(0); } -static void +__private_extern__ void - tzset_basic(void) + tzset_basic(int rdlocked) { const char * name; -@@ -988,8 +1273,18 @@ tzset_basic(void) +@@ -1016,11 +1351,17 @@ tzset_basic(int rdlocked) return; } +#ifdef NOTIFY_TZ + notify_check_tz(&lcl_notify); +#endif /* NOTIFY_TZ */ + if (!rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); + if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) { + if (!rdlocked) + _RWLOCK_UNLOCK(&lcl_rwlock); +#ifdef NOTIFY_TZ_DEBUG -+ if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) { + NOTIFY_TZ_PRINTF("tzset_basic matched %s\n", lcl_TZname); -+ return; -+ } -+#else /* ! NOTIFY_TZ_DEBUG */ - if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) ++#endif return; -+#endif /* NOTIFY_TZ_DEBUG */ - lcl_is_set = strlen(name) < sizeof lcl_TZname; - if (lcl_is_set) - (void) strcpy(lcl_TZname, name); -@@ -1014,15 +1309,25 @@ tzset_basic(void) + } + _RWLOCK_UNLOCK(&lcl_rwlock); +@@ -1053,9 +1394,16 @@ tzset_basic(int rdlocked) lclptr->ttis[0].tt_gmtoff = 0; lclptr->ttis[0].tt_abbrind = 0; (void) strcpy(lclptr->chars, gmt); @@ -559,18 +650,19 @@ + notify_register_tz(fullname, &lcl_notify); +#endif /* NOTIFY_TZ */ settzname(); - } + _RWLOCK_UNLOCK(&lcl_rwlock); +@@ -1066,6 +1414,9 @@ tzset_basic(int rdlocked) void tzset(void) { +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("tzset called TZ=%s\n", getenv("TZ")); +#endif /* NOTIFY_TZ_DEBUG */ - _MUTEX_LOCK(&lcl_mutex); - tzset_basic(); - _MUTEX_UNLOCK(&lcl_mutex); -@@ -1038,7 +1343,11 @@ tzset(void) + tzset_basic(0); + } + +@@ -1079,7 +1430,11 @@ tzset(void) */ /*ARGSUSED*/ @@ -583,7 +675,7 @@ localsub(timep, offset, tmp) const time_t * const timep; const long offset; -@@ -1049,11 +1358,18 @@ struct tm * const tmp; +@@ -1090,11 +1445,18 @@ struct tm * const tmp; int i; const time_t t = *timep; @@ -602,7 +694,7 @@ } #endif /* defined ALL_STATE */ if (sp->timecnt == 0 || t < sp->ats[0]) { -@@ -1076,12 +1392,20 @@ struct tm * const tmp; +@@ -1117,12 +1479,20 @@ struct tm * const tmp; ** t += ttisp->tt_gmtoff; ** timesub(&t, 0L, sp, tmp); */ @@ -623,31 +715,34 @@ } struct tm * -@@ -1094,8 +1418,9 @@ const time_t * const timep; +@@ -1134,10 +1504,11 @@ const time_t * const timep; + struct tm *p_tm; if (__isthreaded != 0) { - _pthread_mutex_lock(&localtime_mutex); - if (localtime_key < 0) { -- if (_pthread_key_create(&localtime_key, free) < 0) { + if (localtime_key == (pthread_key_t)-1) { -+ localtime_key = __LIBC_PTHREAD_KEY_LOCALTIME; -+ if (pthread_key_init_np(localtime_key, free) < 0) { - _pthread_mutex_unlock(&localtime_mutex); - return(NULL); - } -@@ -1110,13 +1435,21 @@ const time_t * const timep; + _pthread_mutex_lock(&localtime_mutex); +- if (localtime_key < 0) { +- if (_pthread_key_create(&localtime_key, free) < 0) { ++ if (localtime_key == (pthread_key_t)-1) { ++ localtime_key = __LIBC_PTHREAD_KEY_LOCALTIME; ++ if (pthread_key_init_np(localtime_key, free) < 0) { + _pthread_mutex_unlock(&localtime_mutex); + return(NULL); + } +@@ -1153,13 +1524,21 @@ const time_t * const timep; } - _pthread_mutex_lock(&lcl_mutex); - tzset_basic(); + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); +#ifdef __LP64__ + p_tm = localsub(timep, 0L, p_tm); +#else /* !__LP64__ */ localsub(timep, 0L, p_tm); +#endif /* __LP64__ */ - _pthread_mutex_unlock(&lcl_mutex); + _RWLOCK_UNLOCK(&lcl_rwlock); return(p_tm); } else { - tzset_basic(); + tzset_basic(0); +#ifdef __LP64__ + return localsub(timep, 0L, &tm); +#else /* !__LP64__ */ @@ -657,7 +752,7 @@ } } -@@ -1125,13 +1458,15 @@ const time_t * const timep; +@@ -1168,13 +1547,15 @@ const time_t * const timep; */ struct tm * @@ -666,17 +761,17 @@ -struct tm * tm; +localtime_r(const time_t * const __restrict timep, struct tm * __restrict tm) { - _MUTEX_LOCK(&lcl_mutex); - tzset_basic(); + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); +#ifdef __LP64__ + tm = localsub(timep, 0L, tm); +#else /* !__LP64__ */ localsub(timep, 0L, tm); +#endif /* __LP64__ */ - _MUTEX_UNLOCK(&lcl_mutex); + _RWLOCK_UNLOCK(&lcl_rwlock); return tm; } -@@ -1140,23 +1475,48 @@ struct tm * tm; +@@ -1183,25 +1564,52 @@ struct tm * tm; ** gmtsub is to gmtime as localsub is to localtime. */ @@ -693,30 +788,34 @@ +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("gmtsub called\n"); +#endif /* NOTIFY_TZ_DEBUG */ - _MUTEX_LOCK(&gmt_mutex); +#ifdef NOTIFY_TZ + notify_check_tz(&gmt_notify); +#endif /* NOTIFY_TZ */ if (!gmt_is_set) { - gmt_is_set = TRUE; + _MUTEX_LOCK(&gmt_mutex); + if (!gmt_is_set) { #ifdef ALL_STATE -- gmtptr = (struct state *) malloc(sizeof *gmtptr); +- gmtptr = (struct state *) malloc(sizeof *gmtptr); +#ifdef NOTIFY_TZ -+ if (gmtptr == NULL) ++ if (gmtptr == NULL) +#endif /* NOTIFY_TZ */ -+ gmtptr = (struct state *) malloc(sizeof *gmtptr); - if (gmtptr != NULL) ++ gmtptr = (struct state *) malloc(sizeof *gmtptr); + if (gmtptr != NULL) +#ifdef NOTIFY_TZ -+ { ++ { +#endif /* NOTIFY_TZ */ #endif /* defined ALL_STATE */ - gmtload(gmtptr); + gmtload(gmtptr); +#ifdef NOTIFY_TZ -+ notify_register_tz(fullname, &gmt_notify); -+ } ++ notify_register_tz(fullname, &gmt_notify); ++#ifdef ALL_STATE ++ } ++#endif +#endif /* NOTIFY_TZ */ + gmt_is_set = TRUE; + } + _MUTEX_UNLOCK(&gmt_mutex); } - _MUTEX_UNLOCK(&gmt_mutex); +#ifdef __LP64__ + if(timesub(timep, offset, gmtptr, tmp) == NULL) + return NULL; @@ -726,7 +825,7 @@ #ifdef TM_ZONE /* ** Could get fancy here and deliver something such as -@@ -1168,7 +1528,7 @@ struct tm * const tmp; +@@ -1213,7 +1621,7 @@ struct tm * const tmp; else { #ifdef ALL_STATE if (gmtptr == NULL) @@ -735,7 +834,7 @@ else tmp->TM_ZONE = gmtptr->chars; #endif /* defined ALL_STATE */ #ifndef ALL_STATE -@@ -1176,6 +1536,9 @@ struct tm * const tmp; +@@ -1221,6 +1629,9 @@ struct tm * const tmp; #endif /* State Farm */ } #endif /* defined TM_ZONE */ @@ -745,22 +844,22 @@ } struct tm * -@@ -1186,10 +1549,12 @@ const time_t * const timep; - static pthread_key_t gmtime_key = -1; +@@ -1232,10 +1643,11 @@ const time_t * const timep; struct tm *p_tm; -+ if (__isthreaded != 0) { - _pthread_mutex_lock(&gmtime_mutex); - if (gmtime_key < 0) { -- if (_pthread_key_create(&gmtime_key, free) < 0) { + if (gmtime_key == (pthread_key_t)-1) { -+ gmtime_key = __LIBC_PTHREAD_KEY_GMTIME; -+ if (pthread_key_init_np(gmtime_key, free) < 0) { - _pthread_mutex_unlock(&gmtime_mutex); - return(NULL); - } -@@ -1206,12 +1571,20 @@ const time_t * const timep; + _pthread_mutex_lock(&gmtime_mutex); +- if (gmtime_key < 0) { +- if (_pthread_key_create(&gmtime_key, free) < 0) { ++ if (gmtime_key == (pthread_key_t)-1) { ++ gmtime_key = __LIBC_PTHREAD_KEY_GMTIME; ++ if (pthread_key_init_np(gmtime_key, free) < 0) { + _pthread_mutex_unlock(&gmtime_mutex); + return(NULL); + } +@@ -1253,12 +1665,20 @@ const time_t * const timep; } _pthread_setspecific(gmtime_key, p_tm); } @@ -781,7 +880,7 @@ } } -@@ -1224,8 +1597,13 @@ gmtime_r(timep, tm) +@@ -1271,8 +1691,13 @@ gmtime_r(timep, tm) const time_t * const timep; struct tm * tm; { @@ -795,7 +894,7 @@ } #ifdef STD_INSPIRED -@@ -1235,13 +1613,21 @@ offtime(timep, offset) +@@ -1282,13 +1707,21 @@ offtime(timep, offset) const time_t * const timep; const long offset; { @@ -817,7 +916,21 @@ timesub(timep, offset, sp, tmp) const time_t * const timep; const long offset; -@@ -1330,7 +1716,16 @@ struct tm * const tmp; +@@ -1365,7 +1798,12 @@ struct tm * const tmp; + if (tmp->tm_wday < 0) + tmp->tm_wday += DAYSPERWEEK; + y = EPOCH_YEAR; +-#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) ++#define _LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) ++#ifdef __LP64__ ++#define LEAPS_THRU_END_OF(y) ((y) >= 0 ? _LEAPS_THRU_END_OF(y) : _LEAPS_THRU_END_OF((y) + 1) - 1) ++#else /* !__LP64__ */ ++#define LEAPS_THRU_END_OF(y) _LEAPS_THRU_END_OF(y) ++#endif /* __LP64__ */ + while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { + long newy; + +@@ -1377,7 +1815,16 @@ struct tm * const tmp; LEAPS_THRU_END_OF(y - 1); y = newy; } @@ -834,7 +947,7 @@ tmp->tm_yday = (int) days; ip = mon_lengths[yleap]; for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon)) -@@ -1340,6 +1735,9 @@ struct tm * const tmp; +@@ -1387,6 +1834,9 @@ struct tm * const tmp; #ifdef TM_GMTOFF tmp->TM_GMTOFF = offset; #endif /* defined TM_GMTOFF */ @@ -844,7 +957,7 @@ } char * -@@ -1352,7 +1750,20 @@ const time_t * const timep; +@@ -1399,7 +1849,20 @@ const time_t * const timep; ** to local time in the form of a string. It is equivalent to ** asctime(localtime(timer)) */ @@ -865,7 +978,7 @@ } char * -@@ -1362,7 +1773,18 @@ char * buf; +@@ -1409,7 +1872,18 @@ char * buf; { struct tm tm; @@ -884,7 +997,24 @@ } /* -@@ -1427,12 +1849,17 @@ const struct tm * const btmp; +@@ -1464,8 +1938,14 @@ const struct tm * const btmp; + { + int result; + +- if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && +- (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && ++ /* ++ * Assume that atmp and btmp point to normalized tm strutures. ++ * So only arithmetic with tm_year could overflow in 64-bit. ++ */ ++ if (atmp->tm_year != btmp->tm_year) { ++ return (atmp->tm_year > btmp->tm_year ? 1 : -1); ++ } ++ if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && + (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && + (result = (atmp->tm_min - btmp->tm_min)) == 0) +@@ -1474,12 +1954,17 @@ const struct tm * const btmp; } static time_t @@ -903,7 +1033,7 @@ { const struct state * sp; int dir; -@@ -1442,6 +1869,9 @@ const int do_norm_secs; +@@ -1489,6 +1974,9 @@ const int do_norm_secs; time_t newt; time_t t; struct tm yourtm, mytm; @@ -913,7 +1043,7 @@ *okayp = FALSE; yourtm = *tmp; -@@ -1460,33 +1890,64 @@ const int do_norm_secs; +@@ -1507,33 +1995,64 @@ const int do_norm_secs; ** Turn yourtm.tm_year into an actual year number for now. ** It is converted back to an offset from TM_YEAR_BASE later. */ @@ -978,7 +1108,7 @@ /* Don't go below 1900 for POLA */ if (yourtm.tm_year < 0) return WRONG; -@@ -1513,7 +1974,13 @@ const int do_norm_secs; +@@ -1560,13 +2079,21 @@ const int do_norm_secs; ** Divide the search space in half ** (this works whether time_t is signed or unsigned). */ @@ -990,9 +1120,21 @@ bits = TYPE_BIT(time_t) - 1; +#endif /* __LP64__ */ /* - ** If we have more than this, we will overflow tm_year for tmcomp(). - ** We should really return an error if we cannot represent it. -@@ -1527,8 +1994,19 @@ const int do_norm_secs; +- ** If we have more than this, we will overflow tm_year for tmcomp(). +- ** We should really return an error if we cannot represent it. ++ ** In 64-bit, we now return an error if we cannot represent the ++ ** struct tm value in a time_t. And tmcomp() is fixed to avoid ++ ** overflow in tm_year. So we only put a cap on bits because time_t ++ ** can't be larger that 56 bit (when tm_year == INT_MAX). + */ +- if (bits > 48) +- bits = 48; ++ if (bits > 56) ++ bits = 56; + /* + ** If time_t is signed, then 0 is just above the median, + ** assuming two's complement arithmetic. +@@ -1574,8 +2101,19 @@ const int do_norm_secs; */ t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits); for ( ; ; ) { @@ -1012,7 +1154,7 @@ if (dir != 0) { if (bits-- < 0) return WRONG; -@@ -1539,6 +2017,9 @@ const int do_norm_secs; +@@ -1586,6 +2124,9 @@ const int do_norm_secs; else t += ((time_t) 1) << bits; continue; } @@ -1022,7 +1164,7 @@ if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) break; /* -@@ -1547,7 +2028,6 @@ const int do_norm_secs; +@@ -1594,7 +2135,6 @@ const int do_norm_secs; ** It's okay to guess wrong since the guess ** gets checked. */ @@ -1030,7 +1172,7 @@ #ifdef ALL_STATE if (sp == NULL) return WRONG; -@@ -1560,7 +2040,12 @@ const int do_norm_secs; +@@ -1607,7 +2147,12 @@ const int do_norm_secs; continue; newt = t + sp->ttis[j].tt_gmtoff - sp->ttis[i].tt_gmtoff; @@ -1043,7 +1185,7 @@ if (tmcomp(&mytm, &yourtm) != 0) continue; if (mytm.tm_isdst != yourtm.tm_isdst) -@@ -1579,17 +2064,27 @@ label: +@@ -1626,17 +2171,27 @@ label: if ((newt < t) != (saved_seconds < 0)) return WRONG; t = newt; @@ -1072,7 +1214,7 @@ { time_t t; -@@ -1598,15 +2093,20 @@ int * const okayp; +@@ -1645,15 +2200,20 @@ int * const okayp; ** (in case tm_sec contains a value associated with a leap second). ** If that fails, try with normalization of seconds. */ @@ -1097,7 +1239,7 @@ { time_t t; const struct state * sp; -@@ -1620,7 +2120,7 @@ const long offset; +@@ -1667,7 +2227,7 @@ const long offset; if (tmp->tm_isdst > 1) tmp->tm_isdst = 1; @@ -1106,7 +1248,7 @@ #ifdef PCTS /* ** PCTS code courtesy Grant Sullivan (grant@osf.org). -@@ -1664,7 +2164,7 @@ const long offset; +@@ -1711,7 +2271,7 @@ const long offset; tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - sp->ttis[samei].tt_gmtoff; tmp->tm_isdst = !tmp->tm_isdst; @@ -1115,12 +1257,12 @@ if (okay) return t; tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - -@@ -1674,19 +2174,25 @@ const long offset; +@@ -1721,19 +2281,25 @@ const long offset; } return WRONG; } +#else /* BUILDING_VARIANT */ -+__private_extern__ pthread_mutex_t lcl_mutex; ++__private_extern__ pthread_rwlock_t lcl_rwlock; +#endif /* BUILDING_VARIANT */ time_t @@ -1129,11 +1271,11 @@ { time_t mktime_return_value; + int serrno = errno; - _MUTEX_LOCK(&lcl_mutex); - tzset_basic(); + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); - mktime_return_value = time1(tmp, localsub, 0L); + mktime_return_value = time1(tmp, localsub, 0L, __DARWIN_UNIX03); - _MUTEX_UNLOCK(&lcl_mutex); + _RWLOCK_UNLOCK(&lcl_rwlock); + errno = serrno; return(mktime_return_value); } @@ -1142,7 +1284,7 @@ #ifdef STD_INSPIRED time_t -@@ -1702,7 +2208,7 @@ timegm(tmp) +@@ -1749,7 +2315,7 @@ timegm(tmp) struct tm * const tmp; { tmp->tm_isdst = 0; @@ -1151,7 +1293,7 @@ } time_t -@@ -1711,7 +2217,7 @@ struct tm * const tmp; +@@ -1758,7 +2324,7 @@ struct tm * const tmp; const long offset; { tmp->tm_isdst = 0; @@ -1160,7 +1302,7 @@ } #endif /* defined STD_INSPIRED */ -@@ -1811,3 +2317,4 @@ time_t t; +@@ -1858,3 +2424,4 @@ time_t t; } #endif /* defined STD_INSPIRED */ diff --git a/stdtime/FreeBSD/private.h b/stdtime/FreeBSD/private.h index 9878a1a..5f7f595 100644 --- a/stdtime/FreeBSD/private.h +++ b/stdtime/FreeBSD/private.h @@ -4,9 +4,9 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. ** -** $FreeBSD: src/lib/libc/stdtime/private.h,v 1.10 2004/06/14 10:31:52 stefanf Exp $ +** $FreeBSD: src/lib/libc/stdtime/private.h,v 1.11 2009/05/23 06:31:50 edwin Exp $ */ /* Stuff moved from Makefile.inc to reduce clutter */ @@ -37,11 +37,13 @@ #ifndef lint #ifndef NOID /* -static char privatehid[] = "@(#)private.h 7.53"; +static char privatehid[] = "@(#)private.h 8.6"; */ #endif /* !defined NOID */ #endif /* !defined lint */ +#define GRANDPARENTED "Local time zone must be set--see zic manual page" + /* ** Defaults for preprocessor symbols. ** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. @@ -63,10 +65,6 @@ static char privatehid[] = "@(#)private.h 7.53"; #define HAVE_SETTIMEOFDAY 3 #endif /* !defined HAVE_SETTIMEOFDAY */ -#ifndef HAVE_STRERROR -#define HAVE_STRERROR 1 -#endif /* !defined HAVE_STRERROR */ - #ifndef HAVE_SYMLINK #define HAVE_SYMLINK 1 #endif /* !defined HAVE_SYMLINK */ @@ -104,17 +102,17 @@ static char privatehid[] = "@(#)private.h 7.53"; #include "stdio.h" #include "errno.h" #include "string.h" -#include "limits.h" /* for CHAR_BIT */ +#include "limits.h" /* for CHAR_BIT et al. */ #include "time.h" #include "stdlib.h" -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #include "libintl.h" -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ -#if HAVE_SYS_WAIT_H - 0 +#if HAVE_SYS_WAIT_H #include /* for WIFEXITED and WEXITSTATUS */ -#endif /* HAVE_SYS_WAIT_H - 0 */ +#endif /* HAVE_SYS_WAIT_H */ #ifndef WIFEXITED #define WIFEXITED(status) (((status) & 0xff) == 0) @@ -123,55 +121,84 @@ static char privatehid[] = "@(#)private.h 7.53"; #define WEXITSTATUS(status) (((status) >> 8) & 0xff) #endif /* !defined WEXITSTATUS */ -#if HAVE_UNISTD_H - 0 -#include "unistd.h" /* for F_OK and R_OK */ -#endif /* HAVE_UNISTD_H - 0 */ +#if HAVE_UNISTD_H +#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */ +#endif /* HAVE_UNISTD_H */ -#if !(HAVE_UNISTD_H - 0) +#if !(HAVE_UNISTD_H) #ifndef F_OK #define F_OK 0 #endif /* !defined F_OK */ #ifndef R_OK #define R_OK 4 #endif /* !defined R_OK */ -#endif /* !(HAVE_UNISTD_H - 0) */ +#endif /* !(HAVE_UNISTD_H) */ -/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ +/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #define is_digit(c) ((unsigned)(c) - '0' <= 9) /* -** SunOS 4.1.1 headers lack FILENAME_MAX. +** Define HAVE_STDINT_H's default value here, rather than at the +** start, since __GLIBC__'s value depends on previously-included +** files. +** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.) */ +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H \ + (199901 <= __STDC_VERSION__ || \ + 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__))) +#endif /* !defined HAVE_STDINT_H */ + +#if HAVE_STDINT_H +#include "stdint.h" +#endif /* !HAVE_STDINT_H */ + +#ifndef INT_FAST64_MAX +/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */ +#if defined LLONG_MAX || defined __LONG_LONG_MAX__ +typedef long long int_fast64_t; +#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#if (LONG_MAX >> 31) < 0xffffffff +Please use a compiler that supports a 64-bit integer type (or wider); +you may need to compile with "-DHAVE_STDINT_H". +#endif /* (LONG_MAX >> 31) < 0xffffffff */ +typedef long int_fast64_t; +#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#endif /* !defined INT_FAST64_MAX */ + +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif /* !defined INT32_MAX */ +#ifndef INT32_MIN +#define INT32_MIN (-1 - INT32_MAX) +#endif /* !defined INT32_MIN */ -#ifndef FILENAME_MAX - -#ifndef MAXPATHLEN -#ifdef unix -#include "sys/param.h" -#endif /* defined unix */ -#endif /* !defined MAXPATHLEN */ +/* +** Workarounds for compilers/systems. +*/ -#ifdef MAXPATHLEN -#define FILENAME_MAX MAXPATHLEN -#endif /* defined MAXPATHLEN */ -#ifndef MAXPATHLEN -#define FILENAME_MAX 1024 /* Pure guesswork */ -#endif /* !defined MAXPATHLEN */ +/* +** Some time.h implementations don't declare asctime_r. +** Others might define it as a macro. +** Fix the former without affecting the latter. +*/ -#endif /* !defined FILENAME_MAX */ +#ifndef asctime_r +extern char * asctime_r(struct tm const *, char *); +#endif /* ** Private function declarations. */ -char * icalloc(int nelem, int elsize); -char * icatalloc(char * old, const char * new); -char * icpyalloc(const char * string); -char * imalloc(int n); -void * irealloc(void * pointer, int size); -void icfree(char * pointer); -void ifree(char * pointer); -char * scheck(const char *string, const char *format); +char * icalloc(int nelem, int elsize); +char * icatalloc(char * old, const char * new); +char * icpyalloc(const char * string); +char * imalloc(int n); +void * irealloc(void * pointer, int size); +void icfree(char * pointer); +void ifree(char * pointer); +const char * scheck(const char * string, const char * format); /* ** Finally, some convenience items. @@ -193,6 +220,24 @@ char * scheck(const char *string, const char *format); #define TYPE_SIGNED(type) (((type) -1) < 0) #endif /* !defined TYPE_SIGNED */ +/* +** Since the definition of TYPE_INTEGRAL contains floating point numbers, +** it cannot be used in preprocessor directives. +*/ + +#ifndef TYPE_INTEGRAL +#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) +#endif /* !defined TYPE_INTEGRAL */ + +/* +** Since the definition of TYPE_INTEGRAL contains floating point numbers, +** it cannot be used in preprocessor directives. +*/ + +#ifndef TYPE_INTEGRAL +#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) +#endif /* !defined TYPE_INTEGRAL */ + #ifndef INT_STRLEN_MAXIMUM /* ** 302 / 1000 is log10(2.0) rounded up. @@ -201,7 +246,8 @@ char * scheck(const char *string, const char *format); ** add one more for a minus sign if the type is signed. */ #define INT_STRLEN_MAXIMUM(type) \ - ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type)) + ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \ + 1 + TYPE_SIGNED(type)) #endif /* !defined INT_STRLEN_MAXIMUM */ /* @@ -235,11 +281,11 @@ char * scheck(const char *string, const char *format); */ #ifndef _ -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #define _(msgid) gettext(msgid) -#else /* !(HAVE_GETTEXT - 0) */ +#else /* !HAVE_GETTEXT */ #define _(msgid) msgid -#endif /* !(HAVE_GETTEXT - 0) */ +#endif /* !HAVE_GETTEXT */ #endif /* !defined _ */ #ifndef TZ_DOMAIN @@ -252,6 +298,26 @@ char * scheck(const char *string, const char *format); char *asctime_r(struct tm const *, char *); char *ctime_r(time_t const *, char *); #endif /* HAVE_INCOMPATIBLE_CTIME_R */ + +#ifndef YEARSPERREPEAT +#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ +#endif /* !defined YEARSPERREPEAT */ + +/* +** The Gregorian year averages 365.2425 days, which is 31556952 seconds. +*/ + +#ifndef AVGSECSPERYEAR +#define AVGSECSPERYEAR 31556952L +#endif /* !defined AVGSECSPERYEAR */ + +#ifndef SECSPERREPEAT +#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR) +#endif /* !defined SECSPERREPEAT */ + +#ifndef SECSPERREPEAT_BITS +#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */ +#endif /* !defined SECSPERREPEAT_BITS */ /* ** UNIX was a registered trademark of The Open Group in 2003. diff --git a/stdtime/FreeBSD/strftime.3 b/stdtime/FreeBSD/strftime.3 index c3f803d..1a8c9e7 100644 --- a/stdtime/FreeBSD/strftime.3 +++ b/stdtime/FreeBSD/strftime.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)strftime.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdtime/strftime.3,v 1.34 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdtime/strftime.3,v 1.40 2008/05/16 04:33:04 grog Exp $ .\" -.Dd January 4, 2003 +.Dd November 4, 2004 .Dt STRFTIME 3 .Os .Sh NAME @@ -106,7 +102,7 @@ is equivalent to .Dq Li %m/%d/%y . .It Cm %d is replaced by the day of the month as a decimal number (01-31). -.It Cm \&%E* Cm \&%O* +.It Cm %E* %O* POSIX locale extensions. The sequences %Ec %EC %Ex %EX %Ey %EY @@ -115,11 +111,11 @@ The sequences are supposed to provide alternate representations. .Pp -Additionly %OB implemented +Additionally %OB implemented to represent alternative months names (used standalone, without day mentioned). .It Cm %e -is replaced by the day of month as a decimal number (1-31); single +is replaced by the day of the month as a decimal number (1-31); single digits are preceded by a blank. .It Cm \&%F is equivalent to @@ -135,7 +131,8 @@ but as a decimal number without century (00-99). .It Cm \&%H is replaced by the hour (24-hour clock) as a decimal number (00-23). .It Cm %h -the same as %b. +the same as +.Cm %b . .It Cm \&%I is replaced by the hour (12-hour clock) as a decimal number (01-12). .It Cm %j @@ -152,13 +149,14 @@ is replaced by the minute as a decimal number (00-59). is replaced by the month as a decimal number (01-12). .It Cm %n is replaced by a newline. -.It Cm \&%O* -the same as %E*. +.It Cm %O* +the same as +.Cm %E* . .It Cm %p is replaced by national representation of either -"ante meridiem" +"ante meridiem" (a.m.) or -"post meridiem" +"post meridiem" (p.m.) as appropriate. .It Cm \&%R is equivalent to @@ -207,7 +205,7 @@ is replaced by the year with century as a decimal number. is replaced by the year without century as a decimal number (00-99). .It Cm \&%Z is replaced by the time zone name. -.It Cm \&%z +.It Cm %z is replaced by the time zone offset from UTC; a leading plus sign stands for east of UTC, a minus sign for west of UTC, hours and minutes follow with two digits each and no delimiter between them (common form for @@ -216,6 +214,15 @@ RFC 822 date headers). is replaced by national representation of the date and time (the format is similar to that produced by .Xr date 1 ) . +.It Cm %-* +GNU libc extension. +Do not do any padding when performing numerical outputs. +.It Cm %_* +GNU libc extension. +Explicitly specify space for padding. +.It Cm %0* +GNU libc extension. +Explicitly specify zero for padding. .It Cm %% is replaced by .Ql % . diff --git a/stdtime/FreeBSD/strftime.3.patch b/stdtime/FreeBSD/strftime.3.patch index 71386b9..837ad75 100644 --- a/stdtime/FreeBSD/strftime.3.patch +++ b/stdtime/FreeBSD/strftime.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/stdtime/FreeBSD/strftime.3 2004-11-25 11:38:45.000000000 -0800 -+++ _SB/Libc/stdtime/FreeBSD/strftime.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -40,7 +40,8 @@ +--- strftime.3.bsdnew 2009-11-14 13:55:44.000000000 -0800 ++++ strftime.3 2009-11-14 13:55:44.000000000 -0800 +@@ -36,7 +36,8 @@ .Dt STRFTIME 3 .Os .Sh NAME @@ -10,7 +10,7 @@ .Nd format date and time .Sh LIBRARY .Lb libc -@@ -48,10 +49,20 @@ +@@ -44,10 +45,20 @@ .In time.h .Ft size_t .Fo strftime @@ -34,7 +34,7 @@ .Fc .Sh DESCRIPTION The -@@ -59,7 +70,7 @@ +@@ -55,7 +66,7 @@ The function formats the information from .Fa timeptr into the buffer @@ -43,7 +43,7 @@ according to the string pointed to by .Fa format . .Pp -@@ -83,6 +94,14 @@ +@@ -79,6 +90,14 @@ returns the number of characters in the terminating NUL. Otherwise, zero is returned and the buffer contents are indeterminate. .Pp @@ -58,7 +58,7 @@ The conversion specifications are copied to the buffer after expansion as follows:- .Bl -tag -width "xxxx" -@@ -226,7 +245,8 @@ +@@ -233,7 +252,8 @@ is replaced by .Xr ctime 3 , .Xr printf 3 , .Xr strptime 3 , @@ -68,7 +68,7 @@ .Sh STANDARDS The .Fn strftime -@@ -253,11 +273,12 @@ +@@ -260,11 +280,12 @@ with a lot of extensions including .Ql %u , .Ql \&%V , .Ql %z , diff --git a/stdtime/FreeBSD/strftime.c b/stdtime/FreeBSD/strftime.c index fecc821..197f1e9 100644 --- a/stdtime/FreeBSD/strftime.c +++ b/stdtime/FreeBSD/strftime.c @@ -7,7 +7,7 @@ * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the + * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR @@ -17,7 +17,7 @@ #ifndef lint #ifndef NOID -static const char elsieid[] = "@(#)strftime.c 7.64"; +static const char elsieid[] = "@(#)strftime.3 8.3"; /* ** Based on the UCB version with the ID appearing below. ** This is ANSIish only when "multibyte character == plain character". @@ -32,7 +32,7 @@ static const char elsieid[] = "@(#)strftime.c 7.64"; static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.40 2004/06/14 10:31:52 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.44 2009/06/09 09:02:58 delphij Exp $"); #include "tzfile.h" #include @@ -42,10 +42,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.40 2004/06/14 10:31:52 s static char * _add(const char *, char *, const char *); static char * _conv(int, const char *, char *, const char *); -static char * _fmt(const char *, const struct tm *, char *, const char *, int *); - -size_t strftime(char * __restrict, size_t, const char * __restrict, - const struct tm * __restrict); +static char * _fmt(const char *, const struct tm *, char *, const char *, + int *); +static char * _yconv(int, int, int, int, char *, const char *); extern char * tzname[]; @@ -53,12 +52,35 @@ extern char * tzname[]; #define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" #endif /* !defined YEAR_2000_NAME */ - #define IN_NONE 0 #define IN_SOME 1 #define IN_THIS 2 #define IN_ALL 3 +#define PAD_DEFAULT 0 +#define PAD_LESS 1 +#define PAD_SPACE 2 +#define PAD_ZERO 3 + +static const char* fmt_padding[][4] = { + /* DEFAULT, LESS, SPACE, ZERO */ +#define PAD_FMT_MONTHDAY 0 +#define PAD_FMT_HMS 0 +#define PAD_FMT_CENTURY 0 +#define PAD_FMT_SHORTYEAR 0 +#define PAD_FMT_MONTH 0 +#define PAD_FMT_WEEKOFYEAR 0 +#define PAD_FMT_DAYOFMONTH 0 + { "%02d", "%d", "%2d", "%02d" }, +#define PAD_FMT_SDAYOFMONTH 1 +#define PAD_FMT_SHMS 1 + { "%2d", "%d", "%2d", "%02d" }, +#define PAD_FMT_DAYOFYEAR 2 + { "%03d", "%d", "%3d", "%03d" }, +#define PAD_FMT_YEAR 3 + { "%04d", "%d", "%4d", "%04d" } +}; + size_t strftime(char * __restrict s, size_t maxsize, const char * __restrict format, const struct tm * __restrict t) @@ -99,13 +121,14 @@ char * pt; const char * const ptlim; int * warnp; { - int Ealternative, Oalternative; + int Ealternative, Oalternative, PadIndex; struct lc_time_T *tptr = __get_current_time_locale(); for ( ; *format; ++format) { if (*format == '%') { Ealternative = 0; Oalternative = 0; + PadIndex = PAD_DEFAULT; label: switch (*++format) { case '\0': @@ -145,14 +168,14 @@ label: ** something completely different. ** (ado, 1993-05-24) */ - pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, - "%02d", pt, ptlim); + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, + pt, ptlim); continue; case 'c': { int warn2 = IN_SOME; - pt = _fmt(tptr->c_fmt, t, pt, ptlim, warnp); + pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) @@ -163,7 +186,8 @@ label: pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp); continue; case 'd': - pt = _conv(t->tm_mday, "%02d", pt, ptlim); + pt = _conv(t->tm_mday, fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex], + pt, ptlim); continue; case 'E': if (Ealternative || Oalternative) @@ -188,21 +212,24 @@ label: Oalternative++; goto label; case 'e': - pt = _conv(t->tm_mday, "%2d", pt, ptlim); + pt = _conv(t->tm_mday, + fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], pt, ptlim); continue; case 'F': pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); continue; case 'H': - pt = _conv(t->tm_hour, "%02d", pt, ptlim); + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim); continue; case 'I': pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, - "%02d", pt, ptlim); + fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim); continue; case 'j': - pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim); + pt = _conv(t->tm_yday + 1, + fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], pt, ptlim); continue; case 'k': /* @@ -211,11 +238,12 @@ label: ** t->tm_hour % 12 : 12, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbins' - ** strftime version 3.0. That is, "%k" and + ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ - pt = _conv(t->tm_hour, "%2d", pt, ptlim); + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_SHMS][PadIndex], + pt, ptlim); continue; #ifdef KITCHEN_SINK case 'K': @@ -231,19 +259,21 @@ label: ** _conv(t->tm_hour, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbin's - ** strftime version 3.0. That is, "%k" and + ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, - "%2d", pt, ptlim); + fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim); continue; case 'M': - pt = _conv(t->tm_min, "%02d", pt, ptlim); + pt = _conv(t->tm_min, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim); continue; case 'm': - pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim); + pt = _conv(t->tm_mon + 1, + fmt_padding[PAD_FMT_MONTH][PadIndex], pt, ptlim); continue; case 'n': pt = _add("\n", pt, ptlim); @@ -262,7 +292,8 @@ label: warnp); continue; case 'S': - pt = _conv(t->tm_sec, "%02d", pt, ptlim); + pt = _conv(t->tm_sec, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim); continue; case 's': { @@ -290,7 +321,7 @@ label: case 'U': pt = _conv((t->tm_yday + DAYSPERWEEK - t->tm_wday) / DAYSPERWEEK, - "%02d", pt, ptlim); + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); continue; case 'u': /* @@ -307,7 +338,7 @@ label: case 'G': /* ISO 8601 year (four digits) */ case 'g': /* ISO 8601 year (two digits) */ /* -** From Arnold Robbins' strftime version 3.0: "the week number of the +** From Arnold Robbins' strftime version 3.0: "the week number of the ** year (the first Monday as the first day of week 1) as a decimal number ** (01-53)." ** (ado, 1993-05-24) @@ -320,17 +351,19 @@ label: ** might also contain days from the previous year and the week before week ** 01 of a year is the last week (52 or 53) of the previous year even if ** it contains days from the new year. A week starts with Monday (day 1) -** and ends with Sunday (day 7). For example, the first week of the year +** and ends with Sunday (day 7). For example, the first week of the year ** 1997 lasts from 1996-12-30 to 1997-01-05..." ** (ado, 1996-01-02) */ { int year; + int base; int yday; int wday; int w; - year = t->tm_year + TM_YEAR_BASE; + year = t->tm_year; + base = TM_YEAR_BASE; yday = t->tm_yday; wday = t->tm_wday; for ( ; ; ) { @@ -338,7 +371,7 @@ label: int bot; int top; - len = isleap(year) ? + len = isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; /* @@ -357,7 +390,7 @@ label: top += DAYSPERWEEK; top += len; if (yday >= top) { - ++year; + ++base; w = 1; break; } @@ -366,26 +399,26 @@ label: DAYSPERWEEK); break; } - --year; - yday += isleap(year) ? + --base; + yday += isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; } #ifdef XPG4_1994_04_09 - if ((w == 52 - && t->tm_mon == TM_JANUARY) - || (w == 1 - && t->tm_mon == TM_DECEMBER)) - w = 53; + if ((w == 52 && + t->tm_mon == TM_JANUARY) || + (w == 1 && + t->tm_mon == TM_DECEMBER)) + w = 53; #endif /* defined XPG4_1994_04_09 */ if (*format == 'V') - pt = _conv(w, "%02d", + pt = _conv(w, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); else if (*format == 'g') { *warnp = IN_ALL; - pt = _conv(year % 100, "%02d", + pt = _yconv(year, base, 0, 1, pt, ptlim); - } else pt = _conv(year, "%04d", + } else pt = _yconv(year, base, 1, 1, pt, ptlim); } continue; @@ -402,7 +435,7 @@ label: (t->tm_wday ? (t->tm_wday - 1) : (DAYSPERWEEK - 1))) / DAYSPERWEEK, - "%02d", pt, ptlim); + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); continue; case 'w': pt = _conv(t->tm_wday, "%d", pt, ptlim); @@ -423,11 +456,11 @@ label: continue; case 'y': *warnp = IN_ALL; - pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, - "%02d", pt, ptlim); + pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, + pt, ptlim); continue; case 'Y': - pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, pt, ptlim); continue; case 'Z': @@ -458,12 +491,12 @@ label: /* ** C99 says that the UTC offset must ** be computed by looking only at - ** tm_isdst. This requirement is + ** tm_isdst. This requirement is ** incorrect, since it means the code ** must rely on magic (in this case ** altzone and timezone), and the ** magic might not have the correct - ** offset. Doing things correctly is + ** offset. Doing things correctly is ** tricky and requires disobeying C99; ** see GNU C strftime for details. ** For now, punt and conform to the @@ -492,19 +525,36 @@ label: diff = -diff; } else sign = "+"; pt = _add(sign, pt, ptlim); - diff /= 60; - pt = _conv((diff/60)*100 + diff%60, - "%04d", pt, ptlim); + diff /= SECSPERMIN; + diff = (diff / MINSPERHOUR) * 100 + + (diff % MINSPERHOUR); + pt = _conv(diff, + fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim); } continue; case '+': pt = _fmt(tptr->date_fmt, t, pt, ptlim, warnp); continue; + case '-': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_LESS; + goto label; + case '_': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_SPACE; + goto label; + case '0': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_ZERO; + goto label; case '%': /* ** X311J/88-090 (4.12.3.5): if conversion char is - ** undefined, behavior is undefined. Print out the + ** undefined, behavior is undefined. Print out the ** character itself as printf(3) also does. */ default: @@ -541,3 +591,44 @@ const char * const ptlim; ++pt; return pt; } + +/* +** POSIX and the C Standard are unclear or inconsistent about +** what %C and %y do if the year is negative or exceeds 9999. +** Use the convention that %C concatenated with %y yields the +** same output as %Y, and that %Y contains at least 4 bytes, +** with more only if necessary. +*/ + +static char * +_yconv(a, b, convert_top, convert_yy, pt, ptlim) +const int a; +const int b; +const int convert_top; +const int convert_yy; +char * pt; +const char * const ptlim; +{ + register int lead; + register int trail; + +#define DIVISOR 100 + trail = a % DIVISOR + b % DIVISOR; + lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR; + trail %= DIVISOR; + if (trail < 0 && lead > 0) { + trail += DIVISOR; + --lead; + } else if (lead < 0 && trail > 0) { + trail -= DIVISOR; + ++lead; + } + if (convert_top) { + if (lead == 0 && trail < 0) + pt = _add("-0", pt, ptlim); + else pt = _conv(lead, "%02d", pt, ptlim); + } + if (convert_yy) + pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim); + return pt; +} diff --git a/stdtime/FreeBSD/strftime.c.patch b/stdtime/FreeBSD/strftime.c.patch index d62da8f..cef5022 100644 --- a/stdtime/FreeBSD/strftime.c.patch +++ b/stdtime/FreeBSD/strftime.c.patch @@ -1,6 +1,6 @@ ---- strftime.c.orig 2004-11-25 11:38:45.000000000 -0800 -+++ strftime.c 2005-02-27 16:07:41.000000000 -0800 -@@ -25,6 +25,8 @@ +--- strftime.c.orig 2010-06-24 01:11:42.000000000 -0700 ++++ strftime.c 2010-06-24 11:29:51.000000000 -0700 +@@ -25,6 +25,8 @@ static const char elsieid[] = "@(#)strft #endif /* !defined NOID */ #endif /* !defined lint */ @@ -9,8 +9,8 @@ #include "namespace.h" #include "private.h" -@@ -35,19 +37,26 @@ - __FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.40 2004/06/14 10:31:52 stefanf Exp $"); +@@ -35,18 +37,25 @@ static const char sccsid[] = "@(#)strfti + __FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.44 2009/06/09 09:02:58 delphij Exp $"); #include "tzfile.h" +#include @@ -22,14 +22,15 @@ +#if !BUILDING_VARIANT static char * _add(const char *, char *, const char *); -static char * _conv(int, const char *, char *, const char *); --static char * _fmt(const char *, const struct tm *, char *, const char *, int *); +-static char * _fmt(const char *, const struct tm *, char *, const char *, +- int *); +-static char * _yconv(int, int, int, int, char *, const char *); +static char * _conv(int, const char *, char *, const char *, locale_t); -+#endif /* !BUILDING_VARIANT */ ++static char * _yconv(int, int, int, int, char *, const char *, locale_t); ++#endif +#define _fmt _st_fmt -+__private_extern__ char *_fmt(const char *, const struct tm *, char *, const char *, int *, struct lc_time_T *, locale_t); - - size_t strftime(char * __restrict, size_t, const char * __restrict, - const struct tm * __restrict); ++__private_extern__ char * _fmt(const char *, const struct tm *, char *, const char *, ++ int *, struct lc_time_T *, locale_t); extern char * tzname[]; +__private_extern__ long __darwin_altzone; /* DST timezone offset */ @@ -38,8 +39,22 @@ #ifndef YEAR_2000_NAME #define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" -@@ -60,29 +69,40 @@ - #define IN_ALL 3 +@@ -62,6 +71,7 @@ extern char * tzname[]; + #define PAD_SPACE 2 + #define PAD_ZERO 3 + ++#ifndef BUILDING_VARIANT + static const char* fmt_padding[][4] = { + /* DEFAULT, LESS, SPACE, ZERO */ + #define PAD_FMT_MONTHDAY 0 +@@ -80,31 +90,36 @@ static const char* fmt_padding[][4] = { + #define PAD_FMT_YEAR 3 + { "%04d", "%d", "%4d", "%04d" } + }; ++#endif ++ ++#define USG_COMPAT ++#define ALTZONE size_t -strftime(char * __restrict s, size_t maxsize, const char * __restrict format, @@ -49,21 +64,11 @@ { char * p; int warn; -+#if __DARWIN_UNIX03 -+ struct tm t2; -+#endif /* __DARWIN_UNIX03 */ + NORMALIZE_LOCALE(loc); tzset(); warn = IN_NONE; - p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn); -+#if __DARWIN_UNIX03 -+ if (t->tm_isdst >= 0) { -+ t2 = *t; -+ t2.tm_gmtoff = t->tm_isdst ? -__darwin_altzone : -_st_get_timezone(); -+ t = &t2; -+ } -+#endif /* __DARWIN_UNIX03 */ + p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, __get_current_time_locale(loc), loc); #ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) { @@ -90,7 +95,7 @@ } #endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */ if (p == s + maxsize) -@@ -91,16 +111,25 @@ +@@ -113,16 +128,25 @@ strftime(char * __restrict s, size_t max return p - s; } @@ -114,28 +119,35 @@ +struct lc_time_T * tptr; +locale_t loc; { - int Ealternative, Oalternative; + int Ealternative, Oalternative, PadIndex; - struct lc_time_T *tptr = __get_current_time_locale(); for ( ; *format; ++format) { if (*format == '%') { -@@ -146,13 +175,13 @@ +@@ -163,19 +187,19 @@ label: + case 'C': + /* + ** %C used to do a... +- ** _fmt("%a %b %e %X %Y", t); ++ ** _fmt("%a %b %e %X %Y", t, tptr, loc); + ** ...whereas now POSIX 1003.2 calls for + ** something completely different. ** (ado, 1993-05-24) */ - pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, -- "%02d", pt, ptlim); -+ "%02d", pt, ptlim, loc); + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, +- pt, ptlim); ++ pt, ptlim, loc); continue; case 'c': { int warn2 = IN_SOME; -- pt = _fmt(tptr->c_fmt, t, pt, ptlim, warnp); -+ pt = _fmt(tptr->c_fmt, t, pt, ptlim, warnp, tptr, loc); +- pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2); ++ pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2, tptr, loc); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) -@@ -160,10 +189,10 @@ +@@ -183,11 +207,11 @@ label: } continue; case 'D': @@ -143,65 +155,77 @@ + pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp, tptr, loc); continue; case 'd': -- pt = _conv(t->tm_mday, "%02d", pt, ptlim); -+ pt = _conv(t->tm_mday, "%02d", pt, ptlim, loc); + pt = _conv(t->tm_mday, fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex], +- pt, ptlim); ++ pt, ptlim, loc); continue; case 'E': if (Ealternative || Oalternative) -@@ -188,21 +217,21 @@ - Oalternative++; +@@ -213,29 +237,29 @@ label: goto label; case 'e': -- pt = _conv(t->tm_mday, "%2d", pt, ptlim); -+ pt = _conv(t->tm_mday, "%2d", pt, ptlim, loc); + pt = _conv(t->tm_mday, +- fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], pt, ptlim); ++ fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], pt, ptlim, loc); continue; case 'F': - pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); + pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp, tptr, loc); continue; case 'H': -- pt = _conv(t->tm_hour, "%02d", pt, ptlim); -+ pt = _conv(t->tm_hour, "%02d", pt, ptlim, loc); + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_HMS][PadIndex], +- pt, ptlim); ++ pt, ptlim, loc); continue; case 'I': pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, -- "%02d", pt, ptlim); -+ "%02d", pt, ptlim, loc); +- fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim); ++ fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim, loc); continue; case 'j': -- pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim); -+ pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim, loc); + pt = _conv(t->tm_yday + 1, +- fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], pt, ptlim); ++ fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], pt, ptlim, loc); continue; case 'k': /* -@@ -215,7 +244,7 @@ - ** "%l" have been swapped. + ** This used to be... + ** _conv(t->tm_hour % 12 ? +- ** t->tm_hour % 12 : 12, 2, ' '); ++ ** t->tm_hour % 12 : 12, 2, ' ', loc); + ** ...and has been changed to the below to + ** match SunOS 4.1.1 and Arnold Robbins' + ** strftime version 3.0. That is, "%k" and +@@ -243,7 +267,7 @@ label: ** (ado, 1993-05-24) */ -- pt = _conv(t->tm_hour, "%2d", pt, ptlim); -+ pt = _conv(t->tm_hour, "%2d", pt, ptlim, loc); + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_SHMS][PadIndex], +- pt, ptlim); ++ pt, ptlim, loc); continue; #ifdef KITCHEN_SINK case 'K': -@@ -237,13 +266,13 @@ +@@ -265,15 +289,15 @@ label: */ pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, -- "%2d", pt, ptlim); -+ "%2d", pt, ptlim, loc); +- fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim); ++ fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim, loc); continue; case 'M': -- pt = _conv(t->tm_min, "%02d", pt, ptlim); -+ pt = _conv(t->tm_min, "%02d", pt, ptlim, loc); + pt = _conv(t->tm_min, fmt_padding[PAD_FMT_HMS][PadIndex], +- pt, ptlim); ++ pt, ptlim, loc); continue; case 'm': -- pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim); -+ pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim, loc); + pt = _conv(t->tm_mon + 1, +- fmt_padding[PAD_FMT_MONTH][PadIndex], pt, ptlim); ++ fmt_padding[PAD_FMT_MONTH][PadIndex], pt, ptlim, loc); continue; case 'n': pt = _add("\n", pt, ptlim); -@@ -255,14 +284,14 @@ +@@ -285,15 +309,15 @@ label: pt, ptlim); continue; case 'R': @@ -214,12 +238,13 @@ + warnp, tptr, loc); continue; case 'S': -- pt = _conv(t->tm_sec, "%02d", pt, ptlim); -+ pt = _conv(t->tm_sec, "%02d", pt, ptlim, loc); + pt = _conv(t->tm_sec, fmt_padding[PAD_FMT_HMS][PadIndex], +- pt, ptlim); ++ pt, ptlim, loc); continue; case 's': { -@@ -274,15 +303,15 @@ +@@ -305,15 +329,15 @@ label: tm = *t; mkt = mktime(&tm); if (TYPE_SIGNED(time_t)) @@ -238,16 +263,16 @@ continue; case 't': pt = _add("\t", pt, ptlim); -@@ -290,7 +319,7 @@ +@@ -321,7 +345,7 @@ label: case 'U': pt = _conv((t->tm_yday + DAYSPERWEEK - t->tm_wday) / DAYSPERWEEK, -- "%02d", pt, ptlim); -+ "%02d", pt, ptlim, loc); +- fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); ++ fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim, loc); continue; case 'u': /* -@@ -301,7 +330,7 @@ +@@ -332,7 +356,7 @@ label: */ pt = _conv((t->tm_wday == 0) ? DAYSPERWEEK : t->tm_wday, @@ -256,24 +281,24 @@ continue; case 'V': /* ISO 8601 week number */ case 'G': /* ISO 8601 year (four digits) */ -@@ -380,13 +409,13 @@ +@@ -413,13 +437,13 @@ label: #endif /* defined XPG4_1994_04_09 */ if (*format == 'V') - pt = _conv(w, "%02d", + pt = _conv(w, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], - pt, ptlim); + pt, ptlim, loc); else if (*format == 'g') { *warnp = IN_ALL; - pt = _conv(year % 100, "%02d", + pt = _yconv(year, base, 0, 1, - pt, ptlim); + pt, ptlim, loc); - } else pt = _conv(year, "%04d", + } else pt = _yconv(year, base, 1, 1, - pt, ptlim); + pt, ptlim, loc); } continue; case 'v': -@@ -395,26 +424,26 @@ +@@ -428,26 +452,26 @@ label: ** "date as dd-bbb-YYYY" ** (ado, 1993-05-24) */ @@ -285,8 +310,8 @@ (t->tm_wday ? (t->tm_wday - 1) : (DAYSPERWEEK - 1))) / DAYSPERWEEK, -- "%02d", pt, ptlim); -+ "%02d", pt, ptlim, loc); +- fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); ++ fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim, loc); continue; case 'w': - pt = _conv(t->tm_wday, "%d", pt, ptlim); @@ -305,21 +330,33 @@ if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) -@@ -424,11 +453,11 @@ +@@ -457,11 +481,11 @@ label: case 'y': *warnp = IN_ALL; - pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, -- "%02d", pt, ptlim); -+ "%02d", pt, ptlim, loc); + pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, +- pt, ptlim); ++ pt, ptlim, loc); continue; case 'Y': - pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, - pt, ptlim); + pt, ptlim, loc); continue; case 'Z': #ifdef TM_ZONE -@@ -476,7 +505,7 @@ +@@ -485,9 +509,9 @@ label: + + if (t->tm_isdst < 0) + continue; +-#ifdef TM_GMTOFF ++#if defined(TM_GMTOFF) && !__DARWIN_UNIX03 + diff = t->TM_GMTOFF; +-#else /* !defined TM_GMTOFF */ ++#else /* !defined TM_GMTOFF || __DARWIN_UNIX03 */ + /* + ** C99 says that the UTC offset must + ** be computed by looking only at +@@ -509,7 +533,7 @@ label: */ if (t->tm_isdst == 0) #ifdef USG_COMPAT @@ -328,12 +365,21 @@ #else /* !defined USG_COMPAT */ continue; #endif /* !defined USG_COMPAT */ -@@ -494,12 +523,12 @@ - pt = _add(sign, pt, ptlim); - diff /= 60; - pt = _conv((diff/60)*100 + diff%60, -- "%04d", pt, ptlim); -+ "%04d", pt, ptlim, loc); +@@ -519,7 +543,7 @@ label: + #else /* !defined ALTZONE */ + continue; + #endif /* !defined ALTZONE */ +-#endif /* !defined TM_GMTOFF */ ++#endif /* !defined TM_GMTOFF || __DARWIN_UNIX03 */ + if (diff < 0) { + sign = "-"; + diff = -diff; +@@ -529,12 +553,12 @@ label: + diff = (diff / MINSPERHOUR) * 100 + + (diff % MINSPERHOUR); + pt = _conv(diff, +- fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim); ++ fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim, loc); } continue; case '+': @@ -341,9 +387,9 @@ - warnp); + warnp, tptr, loc); continue; - case '%': - /* -@@ -519,15 +548,16 @@ + case '-': + if (PadIndex != PAD_DEFAULT) +@@ -569,15 +593,16 @@ label: } static char * @@ -362,8 +408,32 @@ return _add(buf, pt, ptlim); } -@@ -541,3 +571,4 @@ - ++pt; +@@ -601,13 +626,14 @@ const char * const ptlim; + */ + + static char * +-_yconv(a, b, convert_top, convert_yy, pt, ptlim) ++_yconv(a, b, convert_top, convert_yy, pt, ptlim, loc) + const int a; + const int b; + const int convert_top; + const int convert_yy; + char * pt; + const char * const ptlim; ++locale_t loc; + { + register int lead; + register int trail; +@@ -626,9 +652,10 @@ const char * const ptlim; + if (convert_top) { + if (lead == 0 && trail < 0) + pt = _add("-0", pt, ptlim); +- else pt = _conv(lead, "%02d", pt, ptlim); ++ else pt = _conv(lead, "%02d", pt, ptlim, loc); + } + if (convert_yy) +- pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim); ++ pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim, loc); return pt; } +#endif /* !BUILDING_VARIANT */ diff --git a/stdtime/FreeBSD/strptime.3 b/stdtime/FreeBSD/strptime.3 index c265dd8..00e6b57 100644 --- a/stdtime/FreeBSD/strptime.3 +++ b/stdtime/FreeBSD/strptime.3 @@ -23,7 +23,7 @@ .\" (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: src/lib/libc/stdtime/strptime.3,v 1.23 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdtime/strptime.3,v 1.24 2005/01/20 09:17:04 ru Exp $ .\" " .Dd January 4, 2003 .Dt STRPTIME 3 @@ -108,6 +108,11 @@ if one of the conversions failed. .Xr date 1 , .Xr scanf 3 , .Xr strftime 3 +.Sh HISTORY +The +.Fn strptime +function appeared in +.Fx 3.0 . .Sh AUTHORS The .Fn strptime @@ -115,11 +120,6 @@ function has been contributed by Powerdog Industries. .Pp This man page was written by .An J\(:org Wunsch . -.Sh HISTORY -The -.Fn strptime -function appeared in -.Fx 3.0 . .Sh BUGS Both the .Fa %e diff --git a/stdtime/FreeBSD/strptime.3.patch b/stdtime/FreeBSD/strptime.3.patch index 5945d79..026d9d0 100644 --- a/stdtime/FreeBSD/strptime.3.patch +++ b/stdtime/FreeBSD/strptime.3.patch @@ -1,5 +1,5 @@ ---- strptime.3.orig 2007-04-03 12:19:24.000000000 -0700 -+++ strptime.3 2007-04-03 12:54:12.000000000 -0700 +--- strptime.3.bsdnew 2009-11-14 13:55:44.000000000 -0800 ++++ strptime.3 2009-11-14 14:00:22.000000000 -0800 @@ -29,7 +29,8 @@ .Dt STRPTIME 3 .Os @@ -44,7 +44,7 @@ The resulting values will be relative to the local time zone. Thus, it can be considered the reverse operation of .Xr strftime 3 . -@@ -78,7 +88,7 @@ +@@ -78,7 +88,7 @@ string does not contain enough conversio specify the resulting .Vt struct tm , the unspecified members of @@ -53,7 +53,7 @@ are left untouched. For example, if .Fa format -@@ -91,9 +101,17 @@ +@@ -91,9 +101,17 @@ and .Va tm_min will be modified. If time relative to today is desired, initialize the @@ -72,7 +72,7 @@ .Sh RETURN VALUES Upon successful completion, .Fn strptime -@@ -104,10 +122,16 @@ +@@ -104,10 +122,16 @@ that has not been required to satisfy th It returns .Dv NULL if one of the conversions failed. @@ -87,6 +87,6 @@ -.Xr strftime 3 +.Xr strftime 3 , +.Xr xlocale 3 - .Sh AUTHORS + .Sh HISTORY The .Fn strptime diff --git a/stdtime/FreeBSD/strptime.c b/stdtime/FreeBSD/strptime.c index 901a742..f1503f8 100644 --- a/stdtime/FreeBSD/strptime.c +++ b/stdtime/FreeBSD/strptime.c @@ -59,7 +59,7 @@ static char copyright[] __unused = static char sccsid[] __unused = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; #endif /* !defined NOID */ #endif /* not lint */ -__FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.35 2003/11/17 04:19:15 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.37 2009/09/02 04:56:30 ache Exp $"); #include "namespace.h" #include @@ -514,6 +514,34 @@ label: } } break; + + case 'z': + { + int sign = 1; + + if (*buf != '+') { + if (*buf == '-') + sign = -1; + else + return 0; + } + + buf++; + i = 0; + for (len = 4; len > 0; len--) { + if (isdigit((unsigned char)*buf)) { + i *= 10; + i += *buf - '0'; + buf++; + } else + return 0; + } + + tm->tm_hour -= sign * (i / 100); + tm->tm_min -= sign * (i % 100); + *GMTp = 1; + } + break; } } return (char *)buf; diff --git a/stdtime/FreeBSD/strptime.c.patch b/stdtime/FreeBSD/strptime.c.patch index d312335..5bce7e0 100644 --- a/stdtime/FreeBSD/strptime.c.patch +++ b/stdtime/FreeBSD/strptime.c.patch @@ -1,8 +1,8 @@ ---- strptime.c.orig 2009-03-04 16:49:20.000000000 -0800 -+++ strptime.c 2009-05-13 16:39:36.000000000 -0700 -@@ -61,41 +61,56 @@ static char sccsid[] __unused = "@(#)str +--- strptime.c.orig 2009-11-14 13:55:44.000000000 -0800 ++++ strptime.c 2009-11-18 16:56:27.000000000 -0800 +@@ -61,41 +61,55 @@ static char sccsid[] __unused = "@(#)str #endif /* not lint */ - __FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.35 2003/11/17 04:19:15 nectar Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.37 2009/09/02 04:56:30 ache Exp $"); +#include "xlocale_private.h" + @@ -21,7 +21,6 @@ #include "timelocal.h" -static char * _strptime(const char *, const char *, struct tm *, int *); -+static char * _strptime(const char *, const char *, struct tm *, int *, locale_t) __DARWIN_ALIAS(_strptime); +time_t _mktime(struct tm *, const char *); #define asizeof(a) (sizeof (a) / sizeof ((a)[0])) @@ -51,7 +50,7 @@ + while (isspace_l((unsigned char)*ptr, loc)) { + ptr++; + } -+ return ((*ptr)==0) ? fmt : 0; /* trailing whitespace is ok */ ++ return ((*ptr)==0) ? (char *)fmt : 0; /* trailing whitespace is ok */ + } c = *ptr++; @@ -64,7 +63,7 @@ buf++; else if (c != *buf++) return 0; -@@ -114,18 +129,18 @@ label: +@@ -114,18 +128,18 @@ label: break; case '+': @@ -86,7 +85,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -133,17 +148,21 @@ label: +@@ -133,17 +147,21 @@ label: if (i < 19) return 0; @@ -110,7 +109,7 @@ if (buf == 0) return 0; break; -@@ -161,47 +180,55 @@ label: +@@ -161,47 +179,55 @@ label: goto label; case 'F': @@ -174,7 +173,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -209,19 +236,19 @@ label: +@@ -209,19 +235,19 @@ label: if (i < 1 || i > 366) return 0; @@ -198,7 +197,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -237,8 +264,8 @@ label: +@@ -237,8 +263,8 @@ label: tm->tm_sec = i; } @@ -209,7 +208,7 @@ ptr++; break; -@@ -254,11 +281,11 @@ label: +@@ -254,11 +280,11 @@ label: * XXX The %l specifier may gobble one too many * digits if used incorrectly. */ @@ -223,7 +222,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -271,8 +298,8 @@ label: +@@ -271,8 +297,8 @@ label: tm->tm_hour = i; @@ -234,7 +233,7 @@ ptr++; break; -@@ -282,7 +309,7 @@ label: +@@ -282,7 +308,7 @@ label: * specifiers. */ len = strlen(tptr->am); @@ -243,7 +242,7 @@ if (tm->tm_hour > 12) return 0; if (tm->tm_hour == 12) -@@ -292,7 +319,7 @@ label: +@@ -292,7 +318,7 @@ label: } len = strlen(tptr->pm); @@ -252,7 +251,7 @@ if (tm->tm_hour > 12) return 0; if (tm->tm_hour != 12) -@@ -307,34 +334,28 @@ label: +@@ -307,34 +333,28 @@ label: case 'a': for (i = 0; i < asizeof(tptr->weekday); i++) { len = strlen(tptr->weekday[i]); @@ -296,7 +295,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -342,23 +363,46 @@ label: +@@ -342,23 +362,46 @@ label: if (i > 53) return 0; @@ -353,7 +352,7 @@ ptr++; break; -@@ -372,11 +416,18 @@ label: +@@ -372,11 +415,18 @@ label: * XXX The %e specifier may gobble one too many * digits if used incorrectly. */ @@ -375,7 +374,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -386,8 +437,8 @@ label: +@@ -386,8 +436,8 @@ label: tm->tm_mday = i; @@ -386,7 +385,7 @@ ptr++; break; -@@ -398,19 +449,19 @@ label: +@@ -398,19 +448,19 @@ label: if (Oalternative) { if (c == 'B') { len = strlen(tptr->alt_month[i]); @@ -412,7 +411,7 @@ break; } } -@@ -422,11 +473,11 @@ label: +@@ -422,11 +472,11 @@ label: break; case 'm': @@ -426,7 +425,7 @@ i *= 10; i += *buf - '0'; len--; -@@ -436,8 +487,8 @@ label: +@@ -436,8 +486,8 @@ label: tm->tm_mon = i - 1; @@ -437,7 +436,7 @@ ptr++; break; -@@ -450,7 +501,7 @@ label: +@@ -450,7 +500,7 @@ label: sverrno = errno; errno = 0; @@ -446,7 +445,7 @@ if (errno == ERANGE || (long)(t = n) != n) { errno = sverrno; return 0; -@@ -458,24 +509,82 @@ label: +@@ -458,24 +508,82 @@ label: errno = sverrno; buf = cp; gmtime_r(&t, tm); @@ -533,7 +532,7 @@ if (c == 'Y') i -= 1900; if (c == 'y' && i < 69) -@@ -483,35 +592,58 @@ label: +@@ -483,37 +591,40 @@ label: if (i < 0) return 0; @@ -574,7 +573,7 @@ + *convp = CONVERT_GMT; + buf += len; + break; -+ } + } + tzset(); + tzlen = strlen(tzname[0]); + if (len == tzlen && strncmp(buf, tzname[0], tzlen) == 0) { @@ -587,31 +586,32 @@ + tm->tm_isdst = 1; + buf += len; + break; - } -+ return 0; + } -+ -+ case 'z': -+ { -+ char sign; -+ int hr, min; -+ -+ if ((buf[0] != '+' && buf[0] != '-') -+ || !isdigit_l((unsigned char)buf[1], loc) -+ || !isdigit_l((unsigned char)buf[2], loc) -+ || !isdigit_l((unsigned char)buf[3], loc) -+ || !isdigit_l((unsigned char)buf[4], loc)) -+ return 0; -+ sscanf(buf, "%c%2d%2d", &sign, &hr, &min); -+ *convp = CONVERT_ZONE; -+ tm->tm_gmtoff = 60 * (60 * hr + min); -+ if (sign == '-') -+ tm->tm_gmtoff = -tm->tm_gmtoff; -+ buf += 5; ++ return 0; + } +- break; + + case 'z': + { +@@ -529,7 +640,7 @@ label: + buf++; + i = 0; + for (len = 4; len > 0; len--) { +- if (isdigit((unsigned char)*buf)) { ++ if (isdigit_l((unsigned char)*buf, loc)) { + i *= 10; + i += *buf - '0'; + buf++; +@@ -539,7 +650,7 @@ label: + + tm->tm_hour -= sign * (i / 100); + tm->tm_min -= sign * (i % 100); +- *GMTp = 1; ++ *convp = CONVERT_GMT; } break; } -@@ -524,14 +656,39 @@ char * +@@ -552,14 +663,39 @@ char * strptime(const char * __restrict buf, const char * __restrict fmt, struct tm * __restrict tm) { diff --git a/stdtime/FreeBSD/time2posix.3 b/stdtime/FreeBSD/time2posix.3 index 01a8e51..9beca36 100644 --- a/stdtime/FreeBSD/time2posix.3 +++ b/stdtime/FreeBSD/time2posix.3 @@ -1,6 +1,6 @@ -.\" $FreeBSD: src/lib/libc/stdtime/time2posix.3,v 1.13 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdtime/time2posix.3,v 1.17 2009/05/27 12:18:39 edwin Exp $ .\" -.Dd May 1, 1996 +.Dd September 11, 2005 .Dt TIME2POSIX 3 .Os .Sh NAME @@ -12,9 +12,9 @@ .Sh SYNOPSIS .In time.h .Ft time_t -.Fn time2posix "const time_t *t" +.Fn time2posix "time_t t" .Ft time_t -.Fn posix2time "const time_t *t" +.Fn posix2time "time_t t" .Sh DESCRIPTION .St -p1003.1-88 legislates that a time_t value of @@ -78,7 +78,7 @@ The function is less well-behaved: for a positive leap second hit the result is not unique, and for a negative leap second hit the corresponding -POSIX time_t doesn't exist so an adjacent value is returned. +POSIX time_t does not exist so an adjacent value is returned. Both of these are good indicators of the inferiority of the POSIX representation. .Pp @@ -118,3 +118,6 @@ degenerate to the identity function. .Xr localtime 3 , .Xr mktime 3 , .Xr time 3 +.\" @(#)time2posix.3 8.2 +.\" This file is in the public domain, so clarified as of +.\" 1996-06-05 by Arthur David Olson. diff --git a/stdtime/FreeBSD/time2posix.3.patch b/stdtime/FreeBSD/time2posix.3.patch deleted file mode 100644 index 9ec54fd..0000000 --- a/stdtime/FreeBSD/time2posix.3.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- time2posix.3.orig Tue May 20 15:23:48 2003 -+++ time2posix.3 Tue May 27 12:02:20 2003 -@@ -12,9 +12,9 @@ - .Sh SYNOPSIS - .In time.h - .Ft time_t --.Fn time2posix "const time_t *t" -+.Fn time2posix "time_t t" - .Ft time_t --.Fn posix2time "const time_t *t" -+.Fn posix2time "time_t t" - .Sh DESCRIPTION - .St -p1003.1-88 - legislates that a time_t value of diff --git a/stdtime/FreeBSD/tzfile.h.patch b/stdtime/FreeBSD/tzfile.h.patch index 4ff5d4b..4b7a18c 100644 --- a/stdtime/FreeBSD/tzfile.h.patch +++ b/stdtime/FreeBSD/tzfile.h.patch @@ -1,6 +1,6 @@ ---- tzfile.h.orig 2008-03-15 10:50:45.000000000 -0700 -+++ tzfile.h 2008-03-29 11:45:13.000000000 -0700 -@@ -38,7 +38,11 @@ +--- tzfile.h.orig 2010-01-15 00:06:58.000000000 -0800 ++++ tzfile.h 2010-01-15 00:07:28.000000000 -0800 +@@ -38,7 +38,11 @@ static char tzfilehid[] = "@(#)tzfile.h #endif /* !defined TZDIR */ #ifndef TZDEFAULT @@ -12,3 +12,24 @@ #endif /* !defined TZDEFAULT */ #ifndef TZDEFRULES +@@ -167,6 +171,20 @@ struct tzhead { + + #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) + ++/* ++** Since everything in isleap is modulo 400 (or a factor of 400), we know that ++** isleap(y) == isleap(y % 400) ++** and so ++** isleap(a + b) == isleap((a + b) % 400) ++** or ++** isleap(a + b) == isleap(a % 400 + b % 400) ++** This is true even if % means modulo rather than Fortran remainder ++** (which is allowed by C89 but not C99). ++** We use this to avoid addition overflow problems. ++*/ ++ ++#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) ++ + #ifndef USG + + /* diff --git a/stdtime/asctime-fbsd.c b/stdtime/asctime-fbsd.c index 228b802..89804ab 100644 --- a/stdtime/asctime-fbsd.c +++ b/stdtime/asctime-fbsd.c @@ -1,15 +1,21 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. +*/ + +/* +** Avoid the temptation to punt entirely to strftime; +** the output of strftime is supposed to be locale specific +** whereas the output of asctime is supposed to be constant. */ #include #ifndef lint #ifndef NOID -static char elsieid[] __unused = "@(#)asctime.c 7.9"; +static char elsieid[] __unused = "@(#)asctime.c 8.2"; #endif /* !defined NOID */ #endif /* !defined lint */ -__FBSDID("$FreeBSD: src/lib/libc/stdtime/asctime.c,v 1.12 2004/06/14 10:31:52 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdtime/asctime.c,v 1.13 2009/05/23 06:31:50 edwin Exp $"); /*LINTLIBRARY*/ @@ -19,10 +25,58 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime/asctime.c,v 1.12 2004/06/14 10:31:52 st #include "tzfile.h" /* -** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, Second Edition, 1996-07-12. +** Some systems only handle "%.2d"; others only handle "%02d"; +** "%02.2d" makes (most) everybody happy. +** At least some versions of gcc warn about the %02.2d; +** we conditionalize below to avoid the warning. +*/ +/* +** All years associated with 32-bit time_t values are exactly four digits long; +** some years associated with 64-bit time_t values are not. +** Vintage programs are coded for years that are always four digits long +** and may assume that the newline always lands in the same place. +** For years that are less than four digits, we pad the output with +** leading zeroes to get the newline in the traditional place. +** The -4 ensures that we get four characters of output even if +** we call a strftime variant that produces fewer characters for some years. +** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year, +** but many implementations pad anyway; most likely the standards are buggy. */ +#ifdef __GNUC__ +#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n" +#endif /* !defined __GNUC__ */ +/* +** For years that are more than four digits we put extra spaces before the year +** so that code trying to overwrite the newline won't end up overwriting +** a digit within a year and truncating the year (operating on the assumption +** that no output is better than wrong output). +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n" +#endif /* !defined __GNUC__ */ -#define EXPECTEDLEN 26 +#define STD_ASCTIME_BUF_SIZE 26 +/* +** Big enough for something such as +** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n +** (two three-character abbreviations, five strings denoting integers, +** seven explicit spaces, two explicit colons, a newline, +** and a trailing ASCII nul). +** The values above are for systems where an int is 32 bits and are provided +** as an example; the define below calculates the maximum for the system at +** hand. +*/ +#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1) + +static char buf_asctime[MAX_ASCTIME_BUF_SIZE]; + +/* +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. +*/ char * asctime_r(const struct tm * __restrict timeptr, char * __restrict buf) @@ -36,8 +90,8 @@ asctime_r(const struct tm * __restrict timeptr, char * __restrict buf) }; const char * wn; const char * mn; - int len; - char tmp[EXPECTEDLEN]; + char year[INT_STRLEN_MAXIMUM(int) + 2]; + char result[MAX_ASCTIME_BUF_SIZE]; if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) wn = "???"; @@ -46,32 +100,41 @@ asctime_r(const struct tm * __restrict timeptr, char * __restrict buf) mn = "???"; else mn = mon_name[timeptr->tm_mon]; /* - ** The X3J11-suggested format is - ** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n" - ** Since the .2 in 02.2d is ignored, we drop it. + ** Use strftime's %Y to generate the year, to avoid overflow problems + ** when computing timeptr->tm_year + TM_YEAR_BASE. + ** Assume that strftime is unaffected by other out-of-range members + ** (e.g., timeptr->tm_mday) when processing "%Y". */ + (void) strftime(year, sizeof year, "%Y", timeptr); /* - ** Because various values in the tm structure may cause the - ** resulting string to be longer than the 26-bytes that is - ** specified in the spec, we should return NULL rather than - ** possibly overwrite beyond the string. + ** We avoid using snprintf since it's not available on all systems. */ - len = snprintf(tmp, EXPECTEDLEN, "%.3s %.3s%3d %02d:%02d:%02d %d\n", + (void) sprintf(result, + ((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B), wn, mn, timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec, - TM_YEAR_BASE + timeptr->tm_year); - if (len >= EXPECTEDLEN) + year); + if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) { + (void) strcpy(buf, result); + return buf; + } else { +#ifdef EOVERFLOW + errno = EOVERFLOW; +#else /* !defined EOVERFLOW */ + errno = EINVAL; +#endif /* !defined EOVERFLOW */ return NULL; - strcpy(buf, tmp); - return buf; + } } +/* +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. +*/ + char * asctime(timeptr) const struct tm * timeptr; { - static char result[EXPECTEDLEN]; - - return asctime_r(timeptr, result); + return asctime_r(timeptr, buf_asctime); } diff --git a/stdtime/ctime.3 b/stdtime/ctime.3 index 7326071..7bcc80b 100644 --- a/stdtime/ctime.3 +++ b/stdtime/ctime.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)ctime.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdtime/ctime.3,v 1.22 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdtime/ctime.3,v 1.24 2007/01/09 00:28:11 imp Exp $ .\" .Dd January 2, 1999 .Dt CTIME 3 diff --git a/stdtime/localtime-fbsd.c b/stdtime/localtime-fbsd.c index 63a7b5d..7e3cd2a 100644 --- a/stdtime/localtime-fbsd.c +++ b/stdtime/localtime-fbsd.c @@ -9,7 +9,7 @@ static char elsieid[] __unused = "@(#)localtime.c 7.78"; #endif /* !defined NOID */ #endif /* !defined lint */ -__FBSDID("$FreeBSD: src/lib/libc/stdtime/localtime.c,v 1.40 2004/08/24 00:15:37 peter Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdtime/localtime.c,v 1.43 2008/04/01 06:56:11 davidxu Exp $"); /* ** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu). @@ -48,6 +48,21 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime/localtime.c,v 1.40 2004/08/24 00:15:37 #define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x) #define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x) +#define _RWLOCK_RDLOCK(x) \ + do { \ + if (__isthreaded) _pthread_rwlock_rdlock(x); \ + } while (0) + +#define _RWLOCK_WRLOCK(x) \ + do { \ + if (__isthreaded) _pthread_rwlock_wrlock(x); \ + } while (0) + +#define _RWLOCK_UNLOCK(x) \ + do { \ + if (__isthreaded) _pthread_rwlock_unlock(x); \ + } while (0) + /* ** SunOS 4.1.1 headers lack O_BINARY. */ @@ -185,9 +200,7 @@ time_t time1(struct tm * tmp, long offset, int unix03); __private_extern__ -void tzset_basic(void); - -#define lcl_mutex _st_lcl_mutex +void tzset_basic(int); #if !BUILDING_VARIANT static long detzcode(const char * codep); @@ -265,14 +278,14 @@ static struct state gmtmem; static char lcl_TZname[TZ_STRLEN_MAX + 1]; #ifdef NOTIFY_TZ -#define lcl_is_set (lcl_notify.is_set) -#define gmt_is_set (gmt_notify.is_set) +#define lcl_is_set (lcl_notify.is_set) +#define gmt_is_set (gmt_notify.is_set) #else /* ! NOTIFY_TZ */ static int lcl_is_set; static int gmt_is_set; #endif /* NOTIFY_TZ */ -__private_extern__ pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; +__private_extern__ pthread_rwlock_t lcl_rwlock = PTHREAD_RWLOCK_INITIALIZER; +static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; char * tzname[2] = { wildabbr, @@ -362,7 +375,12 @@ static void settzname(void) { struct state * sp = lclptr; - int i; + int i, need; + unsigned char * types; +#define NEED_STD 1 +#define NEED_DST 2 +#define NEED_DAYLIGHT 4 +#define NEED_ALL (NEED_STD | NEED_DST | NEED_DAYLIGHT) tzname[0] = wildabbr; tzname[1] = wildabbr; @@ -379,32 +397,66 @@ settzname(void) return; } #endif /* defined ALL_STATE */ - for (i = 0; i < sp->typecnt; ++i) { - const struct ttinfo * const ttisp = &sp->ttis[i]; + /* + * PR-3765457: The original settzname went sequentially through the ttis + * array, rather than correctly indexing via the types array, to get + * the real order of the timezone changes. In addition, as a speed up, + * we start at the end of the changes, and work back, so that most of + * the time, we don't have to look through the entire array. + */ + if (sp->timecnt == 0 && sp->typecnt == 1) { + /* + * Unfortunately, there is an edge case when typecnt == 1 and + * timecnt == 0, which would cause the loop to never run. So + * in that case, we fudge things up so that it is as if + * timecnt == 1. + */ + i = 0; + types = (unsigned char *)""; /* we use the null as index */ + } else { + /* the usual case */ + i = sp->timecnt - 1; + types = sp->types; + } + need = NEED_ALL; + for (; i >= 0 && need; --i) { + const struct ttinfo * const ttisp = &sp->ttis[types[i]]; - tzname[ttisp->tt_isdst] = - &sp->chars[ttisp->tt_abbrind]; #ifdef USG_COMPAT - if (ttisp->tt_isdst) + if ((need & NEED_DAYLIGHT) && ttisp->tt_isdst) { + need &= ~NEED_DAYLIGHT; daylight = 1; - if (i == 0 || !ttisp->tt_isdst) + } +#endif /* defined USG_COMPAT */ + if (ttisp->tt_isdst) { + if (need & NEED_DST) { + need &= ~NEED_DST; + tzname[1] = &sp->chars[ttisp->tt_abbrind]; +#ifdef ALTZONE + altzone = -(ttisp->tt_gmtoff); +#endif /* defined ALTZONE */ + } + } else if (need & NEED_STD) { + need &= ~NEED_STD; + tzname[0] = &sp->chars[ttisp->tt_abbrind]; +#ifdef USG_COMPAT _st_set_timezone(-(ttisp->tt_gmtoff)); #endif /* defined USG_COMPAT */ + } +#if defined(ALTZONE) || defined(USG_COMPAT) + if (i == 0) { +#endif /* defined(ALTZONE) || defined(USG_COMPAT) */ #ifdef ALTZONE - if (i == 0 || ttisp->tt_isdst) - altzone = -(ttisp->tt_gmtoff); + if (need & NEED_DST) + altzone = -(ttisp->tt_gmtoff); #endif /* defined ALTZONE */ - } - /* - ** And to get the latest zone names into tzname. . . - */ - for (i = 0; i < sp->timecnt; ++i) { - const struct ttinfo * const ttisp = - &sp->ttis[ - sp->types[i]]; - - tzname[ttisp->tt_isdst] = - &sp->chars[ttisp->tt_abbrind]; +#ifdef USG_COMPAT + if (need & NEED_STD) + _st_set_timezone(-(ttisp->tt_gmtoff)); +#endif /* defined USG_COMPAT */ +#if defined(ALTZONE) || defined(USG_COMPAT) + } +#endif /* defined(ALTZONE) || defined(USG_COMPAT) */ } } @@ -1217,21 +1269,42 @@ struct state * const sp; } static void -tzsetwall_basic(void) +tzsetwall_basic(int rdlocked) { #ifdef NOTIFY_TZ notify_check_tz(&lcl_notify); +#else + if (TZDEFAULT) { + static struct timespec last_mtimespec = {0, 0}; + struct stat statbuf; + + if (lstat(TZDEFAULT, &statbuf) == 0) { + if (statbuf.st_mtimespec.tv_sec > last_mtimespec.tv_sec || + (statbuf.st_mtimespec.tv_sec == last_mtimespec.tv_sec && + statbuf.st_mtimespec.tv_nsec > last_mtimespec.tv_nsec)) { + /* Trigger resetting the local TZ */ + lcl_is_set = 0; + } + last_mtimespec = statbuf.st_mtimespec; + } + } #endif /* NOTIFY_TZ */ -#ifdef NOTIFY_TZ_DEBUG + if (!rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); if (lcl_is_set < 0) { +#ifdef NOTIFY_TZ_DEBUG NOTIFY_TZ_PRINTF("tzsetwall_basic lcl_is_set < 0\n"); +#endif + if (!rdlocked) + _RWLOCK_UNLOCK(&lcl_rwlock); return; } +#ifdef NOTIFY_TZ_DEBUG NOTIFY_TZ_PRINTF("tzsetwall_basic not set\n"); -#else /* ! NOTIFY_TZ_DEBUG */ - if (lcl_is_set < 0) - return; -#endif /* NOTIFY_TZ_DEBUG */ +#endif + _RWLOCK_UNLOCK(&lcl_rwlock); + + _RWLOCK_WRLOCK(&lcl_rwlock); lcl_is_set = -1; #ifdef ALL_STATE @@ -1239,6 +1312,9 @@ tzsetwall_basic(void) lclptr = (struct state *) malloc(sizeof *lclptr); if (lclptr == NULL) { settzname(); /* all we can do */ + _RWLOCK_UNLOCK(&lcl_rwlock); + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); return; } } @@ -1249,6 +1325,10 @@ tzsetwall_basic(void) notify_register_tz(fullname, &lcl_notify); #endif /* NOTIFY_TZ */ settzname(); + _RWLOCK_UNLOCK(&lcl_rwlock); + + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); } void @@ -1257,34 +1337,36 @@ tzsetwall(void) #ifdef NOTIFY_TZ_DEBUG NOTIFY_TZ_PRINTF("tzsetwall called\n"); #endif /* NOTIFY_TZ_DEBUG */ - _MUTEX_LOCK(&lcl_mutex); - tzsetwall_basic(); - _MUTEX_UNLOCK(&lcl_mutex); + tzsetwall_basic(0); } __private_extern__ void -tzset_basic(void) +tzset_basic(int rdlocked) { const char * name; name = getenv("TZ"); if (name == NULL) { - tzsetwall_basic(); + tzsetwall_basic(rdlocked); return; } #ifdef NOTIFY_TZ notify_check_tz(&lcl_notify); #endif /* NOTIFY_TZ */ -#ifdef NOTIFY_TZ_DEBUG + if (!rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) { + if (!rdlocked) + _RWLOCK_UNLOCK(&lcl_rwlock); +#ifdef NOTIFY_TZ_DEBUG NOTIFY_TZ_PRINTF("tzset_basic matched %s\n", lcl_TZname); +#endif return; } -#else /* ! NOTIFY_TZ_DEBUG */ - if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) - return; -#endif /* NOTIFY_TZ_DEBUG */ + _RWLOCK_UNLOCK(&lcl_rwlock); + + _RWLOCK_WRLOCK(&lcl_rwlock); lcl_is_set = strlen(name) < sizeof lcl_TZname; if (lcl_is_set) (void) strcpy(lcl_TZname, name); @@ -1294,6 +1376,9 @@ tzset_basic(void) lclptr = (struct state *) malloc(sizeof *lclptr); if (lclptr == NULL) { settzname(); /* all we can do */ + _RWLOCK_UNLOCK(&lcl_rwlock); + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); return; } } @@ -1320,6 +1405,10 @@ tzset_basic(void) notify_register_tz(fullname, &lcl_notify); #endif /* NOTIFY_TZ */ settzname(); + _RWLOCK_UNLOCK(&lcl_rwlock); + + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); } void @@ -1328,9 +1417,7 @@ tzset(void) #ifdef NOTIFY_TZ_DEBUG NOTIFY_TZ_PRINTF("tzset called TZ=%s\n", getenv("TZ")); #endif /* NOTIFY_TZ_DEBUG */ - _MUTEX_LOCK(&lcl_mutex); - tzset_basic(); - _MUTEX_UNLOCK(&lcl_mutex); + tzset_basic(0); } /* @@ -1417,15 +1504,17 @@ const time_t * const timep; struct tm *p_tm; if (__isthreaded != 0) { - _pthread_mutex_lock(&localtime_mutex); if (localtime_key == (pthread_key_t)-1) { - localtime_key = __LIBC_PTHREAD_KEY_LOCALTIME; - if (pthread_key_init_np(localtime_key, free) < 0) { - _pthread_mutex_unlock(&localtime_mutex); - return(NULL); + _pthread_mutex_lock(&localtime_mutex); + if (localtime_key == (pthread_key_t)-1) { + localtime_key = __LIBC_PTHREAD_KEY_LOCALTIME; + if (pthread_key_init_np(localtime_key, free) < 0) { + _pthread_mutex_unlock(&localtime_mutex); + return(NULL); + } } + _pthread_mutex_unlock(&localtime_mutex); } - _pthread_mutex_unlock(&localtime_mutex); p_tm = _pthread_getspecific(localtime_key); if (p_tm == NULL) { if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) @@ -1433,17 +1522,17 @@ const time_t * const timep; return(NULL); _pthread_setspecific(localtime_key, p_tm); } - _pthread_mutex_lock(&lcl_mutex); - tzset_basic(); + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); #ifdef __LP64__ p_tm = localsub(timep, 0L, p_tm); #else /* !__LP64__ */ localsub(timep, 0L, p_tm); #endif /* __LP64__ */ - _pthread_mutex_unlock(&lcl_mutex); + _RWLOCK_UNLOCK(&lcl_rwlock); return(p_tm); } else { - tzset_basic(); + tzset_basic(0); #ifdef __LP64__ return localsub(timep, 0L, &tm); #else /* !__LP64__ */ @@ -1460,14 +1549,14 @@ const time_t * const timep; struct tm * localtime_r(const time_t * const __restrict timep, struct tm * __restrict tm) { - _MUTEX_LOCK(&lcl_mutex); - tzset_basic(); + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); #ifdef __LP64__ tm = localsub(timep, 0L, tm); #else /* !__LP64__ */ localsub(timep, 0L, tm); #endif /* __LP64__ */ - _MUTEX_UNLOCK(&lcl_mutex); + _RWLOCK_UNLOCK(&lcl_rwlock); return tm; } @@ -1488,29 +1577,33 @@ struct tm * const tmp; #ifdef NOTIFY_TZ_DEBUG NOTIFY_TZ_PRINTF("gmtsub called\n"); #endif /* NOTIFY_TZ_DEBUG */ - _MUTEX_LOCK(&gmt_mutex); #ifdef NOTIFY_TZ notify_check_tz(&gmt_notify); #endif /* NOTIFY_TZ */ if (!gmt_is_set) { - gmt_is_set = TRUE; + _MUTEX_LOCK(&gmt_mutex); + if (!gmt_is_set) { #ifdef ALL_STATE #ifdef NOTIFY_TZ - if (gmtptr == NULL) + if (gmtptr == NULL) #endif /* NOTIFY_TZ */ - gmtptr = (struct state *) malloc(sizeof *gmtptr); - if (gmtptr != NULL) + gmtptr = (struct state *) malloc(sizeof *gmtptr); + if (gmtptr != NULL) #ifdef NOTIFY_TZ - { + { #endif /* NOTIFY_TZ */ #endif /* defined ALL_STATE */ - gmtload(gmtptr); + gmtload(gmtptr); #ifdef NOTIFY_TZ - notify_register_tz(fullname, &gmt_notify); - } + notify_register_tz(fullname, &gmt_notify); +#ifdef ALL_STATE + } +#endif #endif /* NOTIFY_TZ */ + gmt_is_set = TRUE; + } + _MUTEX_UNLOCK(&gmt_mutex); } - _MUTEX_UNLOCK(&gmt_mutex); #ifdef __LP64__ if(timesub(timep, offset, gmtptr, tmp) == NULL) return NULL; @@ -1549,17 +1642,18 @@ const time_t * const timep; static pthread_key_t gmtime_key = -1; struct tm *p_tm; - if (__isthreaded != 0) { - _pthread_mutex_lock(&gmtime_mutex); if (gmtime_key == (pthread_key_t)-1) { - gmtime_key = __LIBC_PTHREAD_KEY_GMTIME; - if (pthread_key_init_np(gmtime_key, free) < 0) { - _pthread_mutex_unlock(&gmtime_mutex); - return(NULL); + _pthread_mutex_lock(&gmtime_mutex); + if (gmtime_key == (pthread_key_t)-1) { + gmtime_key = __LIBC_PTHREAD_KEY_GMTIME; + if (pthread_key_init_np(gmtime_key, free) < 0) { + _pthread_mutex_unlock(&gmtime_mutex); + return(NULL); + } } + _pthread_mutex_unlock(&gmtime_mutex); } - _pthread_mutex_unlock(&gmtime_mutex); /* * Changed to follow POSIX.1 threads standard, which * is what BSD currently has. @@ -1704,7 +1798,12 @@ struct tm * const tmp; if (tmp->tm_wday < 0) tmp->tm_wday += DAYSPERWEEK; y = EPOCH_YEAR; -#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) +#define _LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) +#ifdef __LP64__ +#define LEAPS_THRU_END_OF(y) ((y) >= 0 ? _LEAPS_THRU_END_OF(y) : _LEAPS_THRU_END_OF((y) + 1) - 1) +#else /* !__LP64__ */ +#define LEAPS_THRU_END_OF(y) _LEAPS_THRU_END_OF(y) +#endif /* __LP64__ */ while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { long newy; @@ -1839,8 +1938,14 @@ const struct tm * const btmp; { int result; - if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && - (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + /* + * Assume that atmp and btmp point to normalized tm strutures. + * So only arithmetic with tm_year could overflow in 64-bit. + */ + if (atmp->tm_year != btmp->tm_year) { + return (atmp->tm_year > btmp->tm_year ? 1 : -1); + } + if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && (result = (atmp->tm_min - btmp->tm_min)) == 0) @@ -1982,8 +2087,10 @@ int unix03; bits = TYPE_BIT(time_t) - 1; #endif /* __LP64__ */ /* - ** If we have more than this, we will overflow tm_year for tmcomp(). - ** We should really return an error if we cannot represent it. + ** In 64-bit, we now return an error if we cannot represent the + ** struct tm value in a time_t. And tmcomp() is fixed to avoid + ** overflow in tm_year. So we only put a cap on bits because time_t + ** can't be larger that 56 bit (when tm_year == INT_MAX). */ if (bits > 56) bits = 56; @@ -2175,7 +2282,7 @@ int unix03; return WRONG; } #else /* BUILDING_VARIANT */ -__private_extern__ pthread_mutex_t lcl_mutex; +__private_extern__ pthread_rwlock_t lcl_rwlock; #endif /* BUILDING_VARIANT */ time_t @@ -2184,10 +2291,10 @@ struct tm * const tmp; { time_t mktime_return_value; int serrno = errno; - _MUTEX_LOCK(&lcl_mutex); - tzset_basic(); + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); mktime_return_value = time1(tmp, localsub, 0L, __DARWIN_UNIX03); - _MUTEX_UNLOCK(&lcl_mutex); + _RWLOCK_UNLOCK(&lcl_rwlock); errno = serrno; return(mktime_return_value); } diff --git a/stdtime/strftime-fbsd.c b/stdtime/strftime-fbsd.c index ba29d1a..0f0e524 100644 --- a/stdtime/strftime-fbsd.c +++ b/stdtime/strftime-fbsd.c @@ -7,7 +7,7 @@ * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the + * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR @@ -17,7 +17,7 @@ #ifndef lint #ifndef NOID -static const char elsieid[] = "@(#)strftime.c 7.64"; +static const char elsieid[] = "@(#)strftime.3 8.3"; /* ** Based on the UCB version with the ID appearing below. ** This is ANSIish only when "multibyte character == plain character". @@ -34,7 +34,7 @@ static const char elsieid[] = "@(#)strftime.c 7.64"; static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.40 2004/06/14 10:31:52 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.44 2009/06/09 09:02:58 delphij Exp $"); #include "tzfile.h" #include @@ -46,12 +46,11 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.40 2004/06/14 10:31:52 s #if !BUILDING_VARIANT static char * _add(const char *, char *, const char *); static char * _conv(int, const char *, char *, const char *, locale_t); -#endif /* !BUILDING_VARIANT */ +static char * _yconv(int, int, int, int, char *, const char *, locale_t); +#endif #define _fmt _st_fmt -__private_extern__ char *_fmt(const char *, const struct tm *, char *, const char *, int *, struct lc_time_T *, locale_t); - -size_t strftime(char * __restrict, size_t, const char * __restrict, - const struct tm * __restrict); +__private_extern__ char * _fmt(const char *, const struct tm *, char *, const char *, + int *, struct lc_time_T *, locale_t); extern char * tzname[]; __private_extern__ long __darwin_altzone; /* DST timezone offset */ @@ -62,32 +61,50 @@ __private_extern__ long _st_get_timezone(void); #define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" #endif /* !defined YEAR_2000_NAME */ - #define IN_NONE 0 #define IN_SOME 1 #define IN_THIS 2 #define IN_ALL 3 +#define PAD_DEFAULT 0 +#define PAD_LESS 1 +#define PAD_SPACE 2 +#define PAD_ZERO 3 + +#ifndef BUILDING_VARIANT +static const char* fmt_padding[][4] = { + /* DEFAULT, LESS, SPACE, ZERO */ +#define PAD_FMT_MONTHDAY 0 +#define PAD_FMT_HMS 0 +#define PAD_FMT_CENTURY 0 +#define PAD_FMT_SHORTYEAR 0 +#define PAD_FMT_MONTH 0 +#define PAD_FMT_WEEKOFYEAR 0 +#define PAD_FMT_DAYOFMONTH 0 + { "%02d", "%d", "%2d", "%02d" }, +#define PAD_FMT_SDAYOFMONTH 1 +#define PAD_FMT_SHMS 1 + { "%2d", "%d", "%2d", "%02d" }, +#define PAD_FMT_DAYOFYEAR 2 + { "%03d", "%d", "%3d", "%03d" }, +#define PAD_FMT_YEAR 3 + { "%04d", "%d", "%4d", "%04d" } +}; +#endif + +#define USG_COMPAT +#define ALTZONE + size_t strftime_l(char * __restrict s, size_t maxsize, const char * __restrict format, const struct tm * __restrict t, locale_t loc) { char * p; int warn; -#if __DARWIN_UNIX03 - struct tm t2; -#endif /* __DARWIN_UNIX03 */ NORMALIZE_LOCALE(loc); tzset(); warn = IN_NONE; -#if __DARWIN_UNIX03 - if (t->tm_isdst >= 0) { - t2 = *t; - t2.tm_gmtoff = t->tm_isdst ? -__darwin_altzone : -_st_get_timezone(); - t = &t2; - } -#endif /* __DARWIN_UNIX03 */ p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, __get_current_time_locale(loc), loc); #ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) { @@ -129,12 +146,13 @@ int * warnp; struct lc_time_T * tptr; locale_t loc; { - int Ealternative, Oalternative; + int Ealternative, Oalternative, PadIndex; for ( ; *format; ++format) { if (*format == '%') { Ealternative = 0; Oalternative = 0; + PadIndex = PAD_DEFAULT; label: switch (*++format) { case '\0': @@ -169,19 +187,19 @@ label: case 'C': /* ** %C used to do a... - ** _fmt("%a %b %e %X %Y", t); + ** _fmt("%a %b %e %X %Y", t, tptr, loc); ** ...whereas now POSIX 1003.2 calls for ** something completely different. ** (ado, 1993-05-24) */ - pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, - "%02d", pt, ptlim, loc); + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, + pt, ptlim, loc); continue; case 'c': { int warn2 = IN_SOME; - pt = _fmt(tptr->c_fmt, t, pt, ptlim, warnp, tptr, loc); + pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2, tptr, loc); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) @@ -192,7 +210,8 @@ label: pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp, tptr, loc); continue; case 'd': - pt = _conv(t->tm_mday, "%02d", pt, ptlim, loc); + pt = _conv(t->tm_mday, fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex], + pt, ptlim, loc); continue; case 'E': if (Ealternative || Oalternative) @@ -217,34 +236,38 @@ label: Oalternative++; goto label; case 'e': - pt = _conv(t->tm_mday, "%2d", pt, ptlim, loc); + pt = _conv(t->tm_mday, + fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], pt, ptlim, loc); continue; case 'F': pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp, tptr, loc); continue; case 'H': - pt = _conv(t->tm_hour, "%02d", pt, ptlim, loc); + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim, loc); continue; case 'I': pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, - "%02d", pt, ptlim, loc); + fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim, loc); continue; case 'j': - pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim, loc); + pt = _conv(t->tm_yday + 1, + fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], pt, ptlim, loc); continue; case 'k': /* ** This used to be... ** _conv(t->tm_hour % 12 ? - ** t->tm_hour % 12 : 12, 2, ' '); + ** t->tm_hour % 12 : 12, 2, ' ', loc); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbins' - ** strftime version 3.0. That is, "%k" and + ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ - pt = _conv(t->tm_hour, "%2d", pt, ptlim, loc); + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_SHMS][PadIndex], + pt, ptlim, loc); continue; #ifdef KITCHEN_SINK case 'K': @@ -260,19 +283,21 @@ label: ** _conv(t->tm_hour, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbin's - ** strftime version 3.0. That is, "%k" and + ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, - "%2d", pt, ptlim, loc); + fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim, loc); continue; case 'M': - pt = _conv(t->tm_min, "%02d", pt, ptlim, loc); + pt = _conv(t->tm_min, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim, loc); continue; case 'm': - pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim, loc); + pt = _conv(t->tm_mon + 1, + fmt_padding[PAD_FMT_MONTH][PadIndex], pt, ptlim, loc); continue; case 'n': pt = _add("\n", pt, ptlim); @@ -291,7 +316,8 @@ label: warnp, tptr, loc); continue; case 'S': - pt = _conv(t->tm_sec, "%02d", pt, ptlim, loc); + pt = _conv(t->tm_sec, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim, loc); continue; case 's': { @@ -319,7 +345,7 @@ label: case 'U': pt = _conv((t->tm_yday + DAYSPERWEEK - t->tm_wday) / DAYSPERWEEK, - "%02d", pt, ptlim, loc); + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim, loc); continue; case 'u': /* @@ -336,7 +362,7 @@ label: case 'G': /* ISO 8601 year (four digits) */ case 'g': /* ISO 8601 year (two digits) */ /* -** From Arnold Robbins' strftime version 3.0: "the week number of the +** From Arnold Robbins' strftime version 3.0: "the week number of the ** year (the first Monday as the first day of week 1) as a decimal number ** (01-53)." ** (ado, 1993-05-24) @@ -349,17 +375,19 @@ label: ** might also contain days from the previous year and the week before week ** 01 of a year is the last week (52 or 53) of the previous year even if ** it contains days from the new year. A week starts with Monday (day 1) -** and ends with Sunday (day 7). For example, the first week of the year +** and ends with Sunday (day 7). For example, the first week of the year ** 1997 lasts from 1996-12-30 to 1997-01-05..." ** (ado, 1996-01-02) */ { int year; + int base; int yday; int wday; int w; - year = t->tm_year + TM_YEAR_BASE; + year = t->tm_year; + base = TM_YEAR_BASE; yday = t->tm_yday; wday = t->tm_wday; for ( ; ; ) { @@ -367,7 +395,7 @@ label: int bot; int top; - len = isleap(year) ? + len = isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; /* @@ -386,7 +414,7 @@ label: top += DAYSPERWEEK; top += len; if (yday >= top) { - ++year; + ++base; w = 1; break; } @@ -395,26 +423,26 @@ label: DAYSPERWEEK); break; } - --year; - yday += isleap(year) ? + --base; + yday += isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; } #ifdef XPG4_1994_04_09 - if ((w == 52 - && t->tm_mon == TM_JANUARY) - || (w == 1 - && t->tm_mon == TM_DECEMBER)) - w = 53; + if ((w == 52 && + t->tm_mon == TM_JANUARY) || + (w == 1 && + t->tm_mon == TM_DECEMBER)) + w = 53; #endif /* defined XPG4_1994_04_09 */ if (*format == 'V') - pt = _conv(w, "%02d", + pt = _conv(w, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim, loc); else if (*format == 'g') { *warnp = IN_ALL; - pt = _conv(year % 100, "%02d", + pt = _yconv(year, base, 0, 1, pt, ptlim, loc); - } else pt = _conv(year, "%04d", + } else pt = _yconv(year, base, 1, 1, pt, ptlim, loc); } continue; @@ -431,7 +459,7 @@ label: (t->tm_wday ? (t->tm_wday - 1) : (DAYSPERWEEK - 1))) / DAYSPERWEEK, - "%02d", pt, ptlim, loc); + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim, loc); continue; case 'w': pt = _conv(t->tm_wday, "%d", pt, ptlim, loc); @@ -452,11 +480,11 @@ label: continue; case 'y': *warnp = IN_ALL; - pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, - "%02d", pt, ptlim, loc); + pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, + pt, ptlim, loc); continue; case 'Y': - pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, pt, ptlim, loc); continue; case 'Z': @@ -481,18 +509,18 @@ label: if (t->tm_isdst < 0) continue; -#ifdef TM_GMTOFF +#if defined(TM_GMTOFF) && !__DARWIN_UNIX03 diff = t->TM_GMTOFF; -#else /* !defined TM_GMTOFF */ +#else /* !defined TM_GMTOFF || __DARWIN_UNIX03 */ /* ** C99 says that the UTC offset must ** be computed by looking only at - ** tm_isdst. This requirement is + ** tm_isdst. This requirement is ** incorrect, since it means the code ** must rely on magic (in this case ** altzone and timezone), and the ** magic might not have the correct - ** offset. Doing things correctly is + ** offset. Doing things correctly is ** tricky and requires disobeying C99; ** see GNU C strftime for details. ** For now, punt and conform to the @@ -515,25 +543,42 @@ label: #else /* !defined ALTZONE */ continue; #endif /* !defined ALTZONE */ -#endif /* !defined TM_GMTOFF */ +#endif /* !defined TM_GMTOFF || __DARWIN_UNIX03 */ if (diff < 0) { sign = "-"; diff = -diff; } else sign = "+"; pt = _add(sign, pt, ptlim); - diff /= 60; - pt = _conv((diff/60)*100 + diff%60, - "%04d", pt, ptlim, loc); + diff /= SECSPERMIN; + diff = (diff / MINSPERHOUR) * 100 + + (diff % MINSPERHOUR); + pt = _conv(diff, + fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim, loc); } continue; case '+': pt = _fmt(tptr->date_fmt, t, pt, ptlim, warnp, tptr, loc); continue; + case '-': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_LESS; + goto label; + case '_': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_SPACE; + goto label; + case '0': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_ZERO; + goto label; case '%': /* ** X311J/88-090 (4.12.3.5): if conversion char is - ** undefined, behavior is undefined. Print out the + ** undefined, behavior is undefined. Print out the ** character itself as printf(3) also does. */ default: @@ -571,4 +616,46 @@ const char * const ptlim; ++pt; return pt; } + +/* +** POSIX and the C Standard are unclear or inconsistent about +** what %C and %y do if the year is negative or exceeds 9999. +** Use the convention that %C concatenated with %y yields the +** same output as %Y, and that %Y contains at least 4 bytes, +** with more only if necessary. +*/ + +static char * +_yconv(a, b, convert_top, convert_yy, pt, ptlim, loc) +const int a; +const int b; +const int convert_top; +const int convert_yy; +char * pt; +const char * const ptlim; +locale_t loc; +{ + register int lead; + register int trail; + +#define DIVISOR 100 + trail = a % DIVISOR + b % DIVISOR; + lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR; + trail %= DIVISOR; + if (trail < 0 && lead > 0) { + trail += DIVISOR; + --lead; + } else if (lead < 0 && trail > 0) { + trail -= DIVISOR; + ++lead; + } + if (convert_top) { + if (lead == 0 && trail < 0) + pt = _add("-0", pt, ptlim); + else pt = _conv(lead, "%02d", pt, ptlim, loc); + } + if (convert_yy) + pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim, loc); + return pt; +} #endif /* !BUILDING_VARIANT */ diff --git a/stdtime/strftime.3 b/stdtime/strftime.3 index a2f6366..5454a07 100644 --- a/stdtime/strftime.3 +++ b/stdtime/strftime.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)strftime.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdtime/strftime.3,v 1.34 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdtime/strftime.3,v 1.40 2008/05/16 04:33:04 grog Exp $ .\" -.Dd January 4, 2003 +.Dd November 4, 2004 .Dt STRFTIME 3 .Os .Sh NAME @@ -125,7 +121,7 @@ is equivalent to .Dq Li %m/%d/%y . .It Cm %d is replaced by the day of the month as a decimal number (01-31). -.It Cm \&%E* Cm \&%O* +.It Cm %E* %O* POSIX locale extensions. The sequences %Ec %EC %Ex %EX %Ey %EY @@ -134,11 +130,11 @@ The sequences are supposed to provide alternate representations. .Pp -Additionly %OB implemented +Additionally %OB implemented to represent alternative months names (used standalone, without day mentioned). .It Cm %e -is replaced by the day of month as a decimal number (1-31); single +is replaced by the day of the month as a decimal number (1-31); single digits are preceded by a blank. .It Cm \&%F is equivalent to @@ -154,7 +150,8 @@ but as a decimal number without century (00-99). .It Cm \&%H is replaced by the hour (24-hour clock) as a decimal number (00-23). .It Cm %h -the same as %b. +the same as +.Cm %b . .It Cm \&%I is replaced by the hour (12-hour clock) as a decimal number (01-12). .It Cm %j @@ -171,13 +168,14 @@ is replaced by the minute as a decimal number (00-59). is replaced by the month as a decimal number (01-12). .It Cm %n is replaced by a newline. -.It Cm \&%O* -the same as %E*. +.It Cm %O* +the same as +.Cm %E* . .It Cm %p is replaced by national representation of either -"ante meridiem" +"ante meridiem" (a.m.) or -"post meridiem" +"post meridiem" (p.m.) as appropriate. .It Cm \&%R is equivalent to @@ -226,7 +224,7 @@ is replaced by the year with century as a decimal number. is replaced by the year without century as a decimal number (00-99). .It Cm \&%Z is replaced by the time zone name. -.It Cm \&%z +.It Cm %z is replaced by the time zone offset from UTC; a leading plus sign stands for east of UTC, a minus sign for west of UTC, hours and minutes follow with two digits each and no delimiter between them (common form for @@ -235,6 +233,15 @@ RFC 822 date headers). is replaced by national representation of the date and time (the format is similar to that produced by .Xr date 1 ) . +.It Cm %-* +GNU libc extension. +Do not do any padding when performing numerical outputs. +.It Cm %_* +GNU libc extension. +Explicitly specify space for padding. +.It Cm %0* +GNU libc extension. +Explicitly specify zero for padding. .It Cm %% is replaced by .Ql % . diff --git a/stdtime/strptime-fbsd.c b/stdtime/strptime-fbsd.c index 088fda9..963410b 100644 --- a/stdtime/strptime-fbsd.c +++ b/stdtime/strptime-fbsd.c @@ -59,7 +59,7 @@ static char copyright[] __unused = static char sccsid[] __unused = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; #endif /* !defined NOID */ #endif /* not lint */ -__FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.35 2003/11/17 04:19:15 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.37 2009/09/02 04:56:30 ache Exp $"); #include "xlocale_private.h" @@ -77,7 +77,6 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.35 2003/11/17 04:19:15 n #include "libc_private.h" #include "timelocal.h" -static char * _strptime(const char *, const char *, struct tm *, int *, locale_t) __DARWIN_ALIAS(_strptime); time_t _mktime(struct tm *, const char *); #define asizeof(a) (sizeof (a) / sizeof ((a)[0])) @@ -103,7 +102,7 @@ _strptime0(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t while (isspace_l((unsigned char)*ptr, loc)) { ptr++; } - return ((*ptr)==0) ? fmt : 0; /* trailing whitespace is ok */ + return ((*ptr)==0) ? (char *)fmt : 0; /* trailing whitespace is ok */ } c = *ptr++; @@ -629,21 +628,29 @@ label: case 'z': { - char sign; - int hr, min; - - if ((buf[0] != '+' && buf[0] != '-') - || !isdigit_l((unsigned char)buf[1], loc) - || !isdigit_l((unsigned char)buf[2], loc) - || !isdigit_l((unsigned char)buf[3], loc) - || !isdigit_l((unsigned char)buf[4], loc)) - return 0; - sscanf(buf, "%c%2d%2d", &sign, &hr, &min); - *convp = CONVERT_ZONE; - tm->tm_gmtoff = 60 * (60 * hr + min); - if (sign == '-') - tm->tm_gmtoff = -tm->tm_gmtoff; - buf += 5; + int sign = 1; + + if (*buf != '+') { + if (*buf == '-') + sign = -1; + else + return 0; + } + + buf++; + i = 0; + for (len = 4; len > 0; len--) { + if (isdigit_l((unsigned char)*buf, loc)) { + i *= 10; + i += *buf - '0'; + buf++; + } else + return 0; + } + + tm->tm_hour -= sign * (i / 100); + tm->tm_min -= sign * (i % 100); + *convp = CONVERT_GMT; } break; } diff --git a/stdtime/strptime.3 b/stdtime/strptime.3 index eb41e8d..a9c25f9 100644 --- a/stdtime/strptime.3 +++ b/stdtime/strptime.3 @@ -23,7 +23,7 @@ .\" (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: src/lib/libc/stdtime/strptime.3,v 1.23 2004/07/02 23:52:12 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdtime/strptime.3,v 1.24 2005/01/20 09:17:04 ru Exp $ .\" " .Dd January 4, 2003 .Dt STRPTIME 3 @@ -132,6 +132,11 @@ next specifier). .Xr scanf 3 , .Xr strftime 3 , .Xr xlocale 3 +.Sh HISTORY +The +.Fn strptime +function appeared in +.Fx 3.0 . .Sh AUTHORS The .Fn strptime @@ -139,11 +144,6 @@ function has been contributed by Powerdog Industries. .Pp This man page was written by .An J\(:org Wunsch . -.Sh HISTORY -The -.Fn strptime -function appeared in -.Fx 3.0 . .Sh BUGS Both the .Fa %e diff --git a/stdtime/time2posix.3 b/stdtime/time2posix.3 deleted file mode 100644 index 95f39b8..0000000 --- a/stdtime/time2posix.3 +++ /dev/null @@ -1,120 +0,0 @@ -.\" $FreeBSD: src/lib/libc/stdtime/time2posix.3,v 1.13 2001/10/01 16:08:59 ru Exp $ -.\" -.Dd May 1, 1996 -.Dt TIME2POSIX 3 -.Os -.Sh NAME -.Nm time2posix , -.Nm posix2time -.Nd convert seconds since the Epoch -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In time.h -.Ft time_t -.Fn time2posix "time_t t" -.Ft time_t -.Fn posix2time "time_t t" -.Sh DESCRIPTION -.St -p1003.1-88 -legislates that a time_t value of -536457599 shall correspond to "Wed Dec 31 23:59:59 GMT 1986." -This effectively implies that POSIX time_t's cannot include leap -seconds and, -therefore, -that the system time must be adjusted as each leap occurs. -.Pp -If the time package is configured with leap-second support -enabled, -however, -no such adjustment is needed and -time_t values continue to increase over leap events -(as a true `seconds since...' value). -This means that these values will differ from those required by POSIX -by the net number of leap seconds inserted since the Epoch. -.Pp -Typically this is not a problem as the type time_t is intended -to be -(mostly) -opaque\(emtime_t values should only be obtained-from and -passed-to functions such as -.Xr time 3 , -.Xr localtime 3 , -.Xr mktime 3 -and -.Xr difftime 3 . -However, -.St -p1003.1-88 -gives an arithmetic -expression for directly computing a time_t value from a given date/time, -and the same relationship is assumed by some -(usually older) -applications. -Any programs creating/dissecting time_t's -using such a relationship will typically not handle intervals -over leap seconds correctly. -.Pp -The -.Fn time2posix -and -.Fn posix2time -functions are provided to address this time_t mismatch by converting -between local time_t values and their POSIX equivalents. -This is done by accounting for the number of time-base changes that -would have taken place on a POSIX system as leap seconds were inserted -or deleted. -These converted values can then be used in lieu of correcting the older -applications, -or when communicating with POSIX-compliant systems. -.Pp -The -.Fn time2posix -function is single-valued. -That is, -every local time_t -corresponds to a single POSIX time_t. -The -.Fn posix2time -function is less well-behaved: -for a positive leap second hit the result is not unique, -and for a negative leap second hit the corresponding -POSIX time_t doesn't exist so an adjacent value is returned. -Both of these are good indicators of the inferiority of the -POSIX representation. -.Pp -The following table summarizes the relationship between time_t -and its conversion to, -and back from, -the POSIX representation over the leap second inserted at the end of June, -1993. -.Bl -column "93/06/30" "23:59:59" "A+0" "X=time2posix(T)" -.It Sy "DATE TIME T X=time2posix(T) posix2time(X)" -.It "93/06/30 23:59:59 A+0 B+0 A+0" -.It "93/06/30 23:59:60 A+1 B+1 A+1 or A+2" -.It "93/07/01 00:00:00 A+2 B+1 A+1 or A+2" -.It "93/07/01 00:00:01 A+3 B+2 A+3" -.El -.Pp -A leap second deletion would look like... -.Bl -column "??/06/30" "23:59:58" "A+0" "X=time2posix(T)" -.It Sy "DATE TIME T X=time2posix(T) posix2time(X)" -.It "??/06/30 23:59:58 A+0 B+0 A+0" -.It "??/07/01 00:00:00 A+1 B+2 A+1" -.It "??/07/01 00:00:01 A+2 B+3 A+2" -.El -.Pp -.D1 No "[Note: posix2time(B+1) => A+0 or A+1]" -.Pp -If leap-second support is not enabled, -local time_t's and -POSIX time_t's are equivalent, -and both -.Fn time2posix -and -.Fn posix2time -degenerate to the identity function. -.Sh "SEE ALSO" -.Xr difftime 3 , -.Xr localtime 3 , -.Xr mktime 3 , -.Xr time 3 diff --git a/stdtime/time2posix.3 b/stdtime/time2posix.3 new file mode 120000 index 0000000..88a474d --- /dev/null +++ b/stdtime/time2posix.3 @@ -0,0 +1 @@ +./time2posix.3 \ No newline at end of file diff --git a/stdtime/tzfile.h b/stdtime/tzfile.h index 9ca2f63..efa8416 100644 --- a/stdtime/tzfile.h +++ b/stdtime/tzfile.h @@ -171,6 +171,20 @@ struct tzhead { #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) +/* +** Since everything in isleap is modulo 400 (or a factor of 400), we know that +** isleap(y) == isleap(y % 400) +** and so +** isleap(a + b) == isleap((a + b) % 400) +** or +** isleap(a + b) == isleap(a % 400 + b % 400) +** This is true even if % means modulo rather than Fortran remainder +** (which is allowed by C89 but not C99). +** We use this to avoid addition overflow problems. +*/ + +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) + #ifndef USG /* diff --git a/string/FreeBSD/bcmp.3 b/string/FreeBSD/bcmp.3 index a3709e5..cf68665 100644 --- a/string/FreeBSD/bcmp.3 +++ b/string/FreeBSD/bcmp.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bcmp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bcmp.3,v 1.10 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bcmp.3,v 1.11 2007/01/09 00:28:11 imp Exp $ .\" .Dd June 4, 1993 .Dt BCMP 3 diff --git a/string/FreeBSD/bcmp.3.patch b/string/FreeBSD/bcmp.3.patch index d2bdbfb..ca7df14 100644 --- a/string/FreeBSD/bcmp.3.patch +++ b/string/FreeBSD/bcmp.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/bcmp.3 2004-11-25 11:38:46.000000000 -0800 -+++ _SB/Libc/string/FreeBSD/bcmp.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -45,18 +45,18 @@ +--- bcmp.3.bsdnew 2009-11-18 18:24:31.000000000 -0800 ++++ bcmp.3 2009-11-18 18:24:31.000000000 -0800 +@@ -41,18 +41,18 @@ .Sh SYNOPSIS .In strings.h .Ft int diff --git a/string/FreeBSD/bcmp.c b/string/FreeBSD/bcmp.c index f5227df..4c518ee 100644 --- a/string/FreeBSD/bcmp.c +++ b/string/FreeBSD/bcmp.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)bcmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/bcmp.c,v 1.5 2002/08/30 21:07:40 robert Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/bcmp.c,v 1.6 2007/01/09 00:28:11 imp Exp $"); #include diff --git a/string/FreeBSD/bcopy.3 b/string/FreeBSD/bcopy.3 index 6513af4..b7f511b 100644 --- a/string/FreeBSD/bcopy.3 +++ b/string/FreeBSD/bcopy.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bcopy.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bcopy.3,v 1.9 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bcopy.3,v 1.10 2007/01/09 00:28:11 imp Exp $ .\" .Dd June 4, 1993 .Dt BCOPY 3 diff --git a/string/FreeBSD/bcopy.3.patch b/string/FreeBSD/bcopy.3.patch index e06b82f..c6bb7b8 100644 --- a/string/FreeBSD/bcopy.3.patch +++ b/string/FreeBSD/bcopy.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/bcopy.3 2004-11-25 11:38:46.000000000 -0800 -+++ _SB/Libc/string/FreeBSD/bcopy.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -46,20 +46,20 @@ +--- bcopy.3.bsdnew 2009-11-18 18:24:32.000000000 -0800 ++++ bcopy.3 2009-11-18 18:24:32.000000000 -0800 +@@ -42,20 +42,20 @@ .Sh SYNOPSIS .In strings.h .Ft void diff --git a/string/FreeBSD/bstring.3 b/string/FreeBSD/bstring.3 index 3629a3e..aa3f361 100644 --- a/string/FreeBSD/bstring.3 +++ b/string/FreeBSD/bstring.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bstring.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bstring.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bstring.3,v 1.8 2007/01/09 00:28:11 imp Exp $ .\" .Dd June 4, 1993 .Dt BSTRING 3 diff --git a/string/FreeBSD/bstring.3.patch b/string/FreeBSD/bstring.3.patch index 79c87c1..e2604c9 100644 --- a/string/FreeBSD/bstring.3.patch +++ b/string/FreeBSD/bstring.3.patch @@ -1,6 +1,6 @@ ---- bstring.3 2003-05-20 15:23:54.000000000 -0700 -+++ bstring.3.edit 2006-07-12 10:55:13.000000000 -0700 -@@ -51,33 +51,76 @@ +--- bstring.3.bsdnew 2009-11-18 18:24:32.000000000 -0800 ++++ bstring.3 2009-11-18 18:24:32.000000000 -0800 +@@ -47,33 +47,76 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -89,7 +89,7 @@ .Sh SEE ALSO .Xr bcmp 3 , .Xr bcopy 3 , -@@ -87,7 +130,8 @@ +@@ -83,7 +126,8 @@ See the specific manual pages for more i .Xr memcmp 3 , .Xr memcpy 3 , .Xr memmove 3 , diff --git a/string/FreeBSD/bzero.3 b/string/FreeBSD/bzero.3 index 8a10597..52d2684 100644 --- a/string/FreeBSD/bzero.3 +++ b/string/FreeBSD/bzero.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bzero.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bzero.3,v 1.9 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bzero.3,v 1.10 2007/01/09 00:28:11 imp Exp $ .\" .Dd June 4, 1993 .Dt BZERO 3 diff --git a/string/FreeBSD/bzero.3.patch b/string/FreeBSD/bzero.3.patch index 17f0185..08ec1c7 100644 --- a/string/FreeBSD/bzero.3.patch +++ b/string/FreeBSD/bzero.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/bzero.3 2004-11-25 11:38:46.000000000 -0800 -+++ _SB/Libc/string/FreeBSD/bzero.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -46,17 +46,17 @@ +--- bzero.3.bsdnew 2009-11-18 18:24:32.000000000 -0800 ++++ bzero.3 2009-11-18 18:24:32.000000000 -0800 +@@ -42,17 +42,17 @@ .Sh SYNOPSIS .In strings.h .Ft void diff --git a/string/FreeBSD/ffs.3 b/string/FreeBSD/ffs.3 index 93e7148..141b1be 100644 --- a/string/FreeBSD/ffs.3 +++ b/string/FreeBSD/ffs.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,16 +28,18 @@ .\" SUCH DAMAGE. .\" .\" @(#)ffs.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/string/ffs.3,v 1.9 2004/06/30 20:09:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/ffs.3,v 1.13 2009/01/13 13:19:42 kib Exp $ .\" -.Dd January 13, 2004 +.Dd October 26, 2008 .Dt FFS 3 .Os .Sh NAME .Nm ffs , .Nm ffsl , +.Nm ffsll , .Nm fls , -.Nm flsl +.Nm flsl , +.Nm flsll .Nd find first or last bit set in a bit string .Sh LIBRARY .Lb libc @@ -52,28 +50,35 @@ .Ft int .Fn ffsl "long value" .Ft int +.Ft int +.Fn ffsll "long long value" .Fn fls "int value" .Ft int .Fn flsl "long value" +.Ft int +.Fn flsll "long long value" .Sh DESCRIPTION The -.Fn ffs -and +.Fn ffs , .Fn ffsl -functions find the first bit set in +and +.Fn ffsll +functions find the first bit set +(beginning with the least significant bit) +in .Fa value and return the index of that bit. .Pp The -.Fn fls -and +.Fn fls , .Fn flsl +and +.Fn flsll functions find the last bit set in .Fa value and return the index of that bit. .Pp -Bits are numbered starting from 1, starting at the right-most -(least significant) bit. +Bits are numbered starting at 1 (the least significant bit). A return value of zero from any of these functions means that the argument was zero. .Sh SEE ALSO @@ -98,3 +103,9 @@ and .Fn flsl functions appeared in .Fx 5.3 . +The +.Fn ffsll +and +.Fn flsll +functions appeared in +.Fx 7.1 . diff --git a/string/FreeBSD/ffs.3.patch b/string/FreeBSD/ffs.3.patch index dd1b81a..e5cd57d 100644 --- a/string/FreeBSD/ffs.3.patch +++ b/string/FreeBSD/ffs.3.patch @@ -1,6 +1,17 @@ ---- _SB/Libc/string/FreeBSD/ffs.3 2004-11-25 11:38:46.000000000 -0800 -+++ _SB/Libc/string/FreeBSD/ffs.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -48,20 +48,20 @@ +--- ffs.3.bsdnew 2009-11-30 13:52:21.000000000 -0800 ++++ ffs.3 2009-11-30 13:56:29.000000000 -0800 +@@ -36,46 +36,38 @@ + .Sh NAME + .Nm ffs , + .Nm ffsl , +-.Nm ffsll , + .Nm fls , +-.Nm flsl , +-.Nm flsll ++.Nm flsl + .Nd find first or last bit set in a bit string + .Sh LIBRARY + .Lb libc .Sh SYNOPSIS .In strings.h .Ft int @@ -10,32 +21,44 @@ -.Fn ffsl "long value" +.Fn ffsl "long i" .Ft int --.Fn fls "int value" +.Fn fls "int i" .Ft int +-.Fn ffsll "long long value" +-.Fn fls "int value" +-.Ft int -.Fn flsl "long value" +-.Ft int +-.Fn flsll "long long value" +.Fn flsl "long i" .Sh DESCRIPTION The - .Fn ffs +-.Fn ffs , +-.Fn ffsl ++.Fn ffs and - .Fn ffsl - functions find the first bit set in +-.Fn ffsll ++.Fn ffsl + functions find the first bit set + (beginning with the least significant bit) + in -.Fa value +.Fa i and return the index of that bit. .Pp The -@@ -69,7 +69,7 @@ +-.Fn fls , +-.Fn flsl ++.Fn fls and - .Fn flsl +-.Fn flsll ++.Fn flsl functions find the last bit set in -.Fa value +.Fa i and return the index of that bit. .Pp - Bits are numbered starting from 1, starting at the right-most -@@ -93,7 +93,7 @@ + Bits are numbered starting at 1 (the least significant bit). +@@ -98,14 +90,8 @@ compliance. .Pp The .Fn ffsl , @@ -44,3 +67,10 @@ and .Fn flsl functions appeared in + .Fx 5.3 . +-The +-.Fn ffsll +-and +-.Fn flsll +-functions appeared in +-.Fx 7.1 . diff --git a/string/FreeBSD/index.3 b/string/FreeBSD/index.3 index c47e964..387b1eb 100644 --- a/string/FreeBSD/index.3 +++ b/string/FreeBSD/index.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)index.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/index.3,v 1.11 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/index.3,v 1.12 2007/01/09 00:28:12 imp Exp $ .\" .Dd June 4, 1993 .Dt INDEX 3 diff --git a/string/FreeBSD/index.3.patch b/string/FreeBSD/index.3.patch index cd10d6d..e015562 100644 --- a/string/FreeBSD/index.3.patch +++ b/string/FreeBSD/index.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/index.3 2004-11-25 11:38:46.000000000 -0800 -+++ _SB/Libc/string/FreeBSD/index.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -58,8 +58,8 @@ +--- index.3.bsdnew 2009-11-18 18:24:32.000000000 -0800 ++++ index.3 2009-11-18 18:24:32.000000000 -0800 +@@ -54,8 +54,8 @@ locates the first occurrence of .Vt char ) in the string pointed to by .Fa s . @@ -11,7 +11,7 @@ .Fa c is .Ql \e0 , -@@ -70,7 +70,7 @@ +@@ -66,7 +66,7 @@ The .Fn rindex function is identical to .Fn index , diff --git a/string/FreeBSD/index.c b/string/FreeBSD/index.c index be2c052..eab30b7 100644 --- a/string/FreeBSD/index.c +++ b/string/FreeBSD/index.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)index.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/index.c,v 1.7 2003/12/18 07:44:53 jkh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/index.c,v 1.8 2007/01/09 00:28:12 imp Exp $"); #include diff --git a/string/FreeBSD/memccpy.3 b/string/FreeBSD/memccpy.3 index 44a457f..416d0f8 100644 --- a/string/FreeBSD/memccpy.3 +++ b/string/FreeBSD/memccpy.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memccpy.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/memccpy.3,v 1.6 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/memccpy.3,v 1.7 2007/01/09 00:28:12 imp Exp $ .\" .Dd June 9, 1993 .Dt MEMCCPY 3 diff --git a/string/FreeBSD/memccpy.3.patch b/string/FreeBSD/memccpy.3.patch index 0ebd91d..cdbdd6e 100644 --- a/string/FreeBSD/memccpy.3.patch +++ b/string/FreeBSD/memccpy.3.patch @@ -1,6 +1,6 @@ ---- memccpy.3.orig 2008-02-29 10:45:52.000000000 -0800 -+++ memccpy.3 2008-02-29 12:03:32.000000000 -0800 -@@ -43,27 +43,35 @@ +--- memccpy.3.bsdnew 2009-11-18 18:24:32.000000000 -0800 ++++ memccpy.3 2009-11-18 18:24:32.000000000 -0800 +@@ -39,27 +39,35 @@ .Sh SYNOPSIS .In string.h .Ft void * diff --git a/string/FreeBSD/memccpy.c b/string/FreeBSD/memccpy.c index 0bc6a11..4c5f421 100644 --- a/string/FreeBSD/memccpy.c +++ b/string/FreeBSD/memccpy.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,16 +31,12 @@ static char sccsid[] = "@(#)memccpy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/memccpy.c,v 1.5 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/memccpy.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include void * -memccpy(t, f, c, n) - void *t; - const void *f; - int c; - size_t n; +memccpy(void *t, const void *f, int c, size_t n) { if (n) { diff --git a/string/FreeBSD/memchr.3 b/string/FreeBSD/memchr.3 index b363185..5581ccc 100644 --- a/string/FreeBSD/memchr.3 +++ b/string/FreeBSD/memchr.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)memchr.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memchr.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/memchr.3,v 1.12 2009/04/23 08:37:56 brueffer Exp $ .\" -.Dd June 4, 1993 +.Dd April 9, 2008 .Dt MEMCHR 3 .Os .Sh NAME @@ -48,6 +44,8 @@ .In string.h .Ft void * .Fn memchr "const void *b" "int c" "size_t len" +.Ft void * +.Fn memrchr "const void *b" "int c" "size_t len" .Sh DESCRIPTION The .Fn memchr @@ -57,15 +55,27 @@ locates the first occurrence of (converted to an unsigned char) in string .Fa b . +.Pp +The +.Fn memrchr +function behaves like +.Fn memchr , +except that it locates the last occurrence of +.Fa c +in string +.Fa b . .Sh RETURN VALUES The .Fn memchr -function -returns a pointer to the byte located, +and +.Fn memrchr +functions +return a pointer to the byte located, or NULL if no such byte exists within .Fa len bytes. .Sh SEE ALSO +.Xr memmem 3 , .Xr strchr 3 , .Xr strcspn 3 , .Xr strpbrk 3 , @@ -73,10 +83,23 @@ bytes. .Xr strsep 3 , .Xr strspn 3 , .Xr strstr 3 , -.Xr strtok 3 +.Xr strtok 3 , +.Xr wmemchr 3 .Sh STANDARDS The .Fn memchr function conforms to .St -isoC . +.Pp +The +.Fn memrchr +function is a GNU extension and conforms to no standard. +.Sh HISTORY +The +.Fn memrchr +function first appeared in GNU libc 2.1.91, this implementation +first appeared in +.Fx 6.4 , +coming from +.Ox 4.3 . diff --git a/string/FreeBSD/memchr.3.patch b/string/FreeBSD/memchr.3.patch index 0142127..b0e9102 100644 --- a/string/FreeBSD/memchr.3.patch +++ b/string/FreeBSD/memchr.3.patch @@ -1,10 +1,12 @@ ---- _SB/Libc/string/FreeBSD/memchr.3 2003-05-20 15:23:54.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/memchr.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -47,7 +47,11 @@ +--- memchr.3.bsdnew 2009-11-30 13:52:21.000000000 -0800 ++++ memchr.3 2009-11-30 14:18:10.000000000 -0800 +@@ -43,9 +43,11 @@ .Sh SYNOPSIS .In string.h .Ft void * -.Fn memchr "const void *b" "int c" "size_t len" +-.Ft void * +-.Fn memrchr "const void *b" "int c" "size_t len" +.Fo memchr +.Fa "const void *s" +.Fa "int c" @@ -13,20 +15,52 @@ .Sh DESCRIPTION The .Fn memchr -@@ -56,14 +60,14 @@ +@@ -54,28 +56,16 @@ locates the first occurrence of .Fa c (converted to an unsigned char) in string -.Fa b . +-.Pp +-The +-.Fn memrchr +-function behaves like +-.Fn memchr , +-except that it locates the last occurrence of +-.Fa c +-in string +-.Fa b . +.Fa s . .Sh RETURN VALUES The .Fn memchr - function - returns a pointer to the byte located, +-and +-.Fn memrchr +-functions +-return a pointer to the byte located, ++function ++returns a pointer to the byte located, or NULL if no such byte exists within -.Fa len +.Fa n bytes. .Sh SEE ALSO +-.Xr memmem 3 , .Xr strchr 3 , + .Xr strcspn 3 , + .Xr strpbrk 3 , +@@ -91,15 +81,3 @@ The + function + conforms to + .St -isoC . +-.Pp +-The +-.Fn memrchr +-function is a GNU extension and conforms to no standard. +-.Sh HISTORY +-The +-.Fn memrchr +-function first appeared in GNU libc 2.1.91, this implementation +-first appeared in +-.Fx 6.4 , +-coming from +-.Ox 4.3 . diff --git a/string/FreeBSD/memchr.c b/string/FreeBSD/memchr.c index e3c6679..bf8a431 100644 --- a/string/FreeBSD/memchr.c +++ b/string/FreeBSD/memchr.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,21 +34,18 @@ static char sccsid[] = "@(#)memchr.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/memchr.c,v 1.4 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/memchr.c,v 1.8 2009/02/07 19:34:44 imp Exp $"); #include void * -memchr(s, c, n) - const void *s; - unsigned char c; - size_t n; +memchr(const void *s, int c, size_t n) { if (n != 0) { const unsigned char *p = s; do { - if (*p++ == c) + if (*p++ == (unsigned char)c) return ((void *)(p - 1)); } while (--n != 0); } diff --git a/string/FreeBSD/memcmp.3 b/string/FreeBSD/memcmp.3 index 980af28..98d2b6a 100644 --- a/string/FreeBSD/memcmp.3 +++ b/string/FreeBSD/memcmp.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memcmp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memcmp.3,v 1.8 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/memcmp.3,v 1.10 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt MEMCMP 3 @@ -76,7 +72,8 @@ Zero-length strings are always identical. .Xr strcasecmp 3 , .Xr strcmp 3 , .Xr strcoll 3 , -.Xr strxfrm 3 +.Xr strxfrm 3 , +.Xr wmemcmp 3 .Sh STANDARDS The .Fn memcmp diff --git a/string/FreeBSD/memcmp.3.patch b/string/FreeBSD/memcmp.3.patch index 9b92c7e..277a31d 100644 --- a/string/FreeBSD/memcmp.3.patch +++ b/string/FreeBSD/memcmp.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/memcmp.3 2003-05-20 15:23:54.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/memcmp.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -47,17 +47,21 @@ +--- memcmp.3.bsdnew 2009-11-18 18:24:32.000000000 -0800 ++++ memcmp.3 2009-11-18 18:24:32.000000000 -0800 +@@ -43,17 +43,21 @@ .Sh SYNOPSIS .In string.h .Ft int diff --git a/string/FreeBSD/memcmp.c b/string/FreeBSD/memcmp.c index 045e4d9..f2ac18b 100644 --- a/string/FreeBSD/memcmp.c +++ b/string/FreeBSD/memcmp.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/memcmp.c,v 1.4 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/memcmp.c,v 1.6 2009/02/03 17:58:20 danger Exp $"); #include @@ -46,9 +42,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/memcmp.c,v 1.4 2002/03/21 18:44:54 obrie * Compare memory regions. */ int -memcmp(s1, s2, n) - const void *s1, *s2; - size_t n; +memcmp(const void *s1, const void *s2, size_t n) { if (n != 0) { const unsigned char *p1 = s1, *p2 = s2; diff --git a/string/FreeBSD/memcpy.3 b/string/FreeBSD/memcpy.3 index ba9cae9..b34bc17 100644 --- a/string/FreeBSD/memcpy.3 +++ b/string/FreeBSD/memcpy.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memcpy.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memcpy.3,v 1.7 2002/01/07 06:03:37 dd Exp $ +.\" $FreeBSD: src/lib/libc/string/memcpy.3,v 1.9 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt MEMCPY 3 @@ -68,7 +64,8 @@ returns the original value of .Xr bcopy 3 , .Xr memccpy 3 , .Xr memmove 3 , -.Xr strcpy 3 +.Xr strcpy 3 , +.Xr wmemcpy 3 .Sh STANDARDS The .Fn memcpy diff --git a/string/FreeBSD/memcpy.3.patch b/string/FreeBSD/memcpy.3.patch index 19f2f88..631b4d7 100644 --- a/string/FreeBSD/memcpy.3.patch +++ b/string/FreeBSD/memcpy.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/memcpy.3 2003-05-20 15:23:54.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/memcpy.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -41,29 +41,45 @@ +--- memcpy.3.bsdnew 2009-11-18 18:24:32.000000000 -0800 ++++ memcpy.3 2009-11-18 18:24:32.000000000 -0800 +@@ -37,29 +37,45 @@ .Os .Sh NAME .Nm memcpy @@ -54,7 +54,7 @@ .Sh SEE ALSO .Xr bcopy 3 , .Xr memccpy 3 , -@@ -75,17 +91,3 @@ +@@ -72,17 +88,3 @@ The function conforms to .St -isoC . diff --git a/string/FreeBSD/memmem.3 b/string/FreeBSD/memmem.3 new file mode 100644 index 0000000..c55c525 --- /dev/null +++ b/string/FreeBSD/memmem.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2005 Pascal Gloor +.\" +.\" 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. +.\" 3. The name of the author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" 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: src/lib/libc/string/memmem.3,v 1.3 2005/11/24 06:56:21 ru Exp $ +.\" +.Dd August 24, 2005 +.Dt MEMMEM 3 +.Os +.Sh NAME +.Nm memmem +.Nd "locate a byte substring in a byte string" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft "void *" +.Fo memmem +.Fa "const void *big" "size_t big_len" +.Fa "const void *little" "size_t little_len" +.Fc +.Sh DESCRIPTION +The +.Fn memmem +function +locates the first occurrence of the byte string +.Fa little +in the byte string +.Fa big . +.Sh RETURN VALUES +If +.Fa big_len +is smaller than +.Fa little_len , +if +.Fa little_len +is 0, if +.Fa big_len +is 0 or if +.Fa little +occurs nowhere in +.Fa big , +.Dv NULL +is returned; +otherwise a pointer to the first character of the first occurrence of +.Fa little +is returned. +.Sh SEE ALSO +.Xr memchr 3 , +.Xr strchr 3 , +.Xr strstr 3 +.Sh CONFORMING TO +.Fn memmem +is a GNU extension. +.Sh HISTORY +The +.Fn memmem +function first appeared in +.Fx 6.0 . +.Sh AUTHORS +.An Pascal Gloor Aq pascal.gloor@spale.com +.Sh BUGS +This function was broken in Linux libc up to and including version 5.0.9 +and in GNU libc prior to version 2.1. diff --git a/string/FreeBSD/memmem.c b/string/FreeBSD/memmem.c new file mode 100644 index 0000000..8dba6fb --- /dev/null +++ b/string/FreeBSD/memmem.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2005 Pascal Gloor + * + * 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 +__FBSDID("$FreeBSD: src/lib/libc/string/memmem.c,v 1.2 2009/02/03 17:58:20 danger Exp $"); + +#include + +/* + * Find the first occurrence of the byte string s in byte string l. + */ + +void * +memmem(const void *l, size_t l_len, const void *s, size_t s_len) +{ + register char *cur, *last; + const char *cl = (const char *)l; + const char *cs = (const char *)s; + + /* we need something to compare */ + if (l_len == 0 || s_len == 0) + return NULL; + + /* "s" must be smaller or equal to "l" */ + if (l_len < s_len) + return NULL; + + /* special case where s_len == 1 */ + if (s_len == 1) + return memchr(l, (int)*cs, l_len); + + /* the last position where its possible to find "s" in "l" */ + last = (char *)cl + l_len - s_len; + + for (cur = (char *)cl; cur <= last; cur++) + if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) + return cur; + + return NULL; +} diff --git a/string/FreeBSD/memmove.3 b/string/FreeBSD/memmove.3 index 8f4f2cc..6cac604 100644 --- a/string/FreeBSD/memmove.3 +++ b/string/FreeBSD/memmove.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memmove.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memmove.3,v 1.6 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/memmove.3,v 1.8 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt MEMMOVE 3 @@ -69,7 +65,8 @@ function returns the original value of .Xr bcopy 3 , .Xr memccpy 3 , .Xr memcpy 3 , -.Xr strcpy 3 +.Xr strcpy 3 , +.Xr wmemmove 3 .Sh STANDARDS The .Fn memmove diff --git a/string/FreeBSD/memmove.3.patch b/string/FreeBSD/memmove.3.patch index 6fdf054..a303997 100644 --- a/string/FreeBSD/memmove.3.patch +++ b/string/FreeBSD/memmove.3.patch @@ -1,6 +1,6 @@ ---- memmove.3 2003-05-20 15:23:54.000000000 -0700 -+++ memmove.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -47,24 +47,28 @@ +--- memmove.3.bsdnew 2009-11-18 18:24:33.000000000 -0800 ++++ memmove.3 2009-11-18 18:24:33.000000000 -0800 +@@ -43,24 +43,28 @@ .Sh SYNOPSIS .In string.h .Ft void * diff --git a/string/FreeBSD/memset.3 b/string/FreeBSD/memset.3 index 3f1ba5e..73ffcec 100644 --- a/string/FreeBSD/memset.3 +++ b/string/FreeBSD/memset.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memset.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memset.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/memset.3,v 1.9 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt MEMSET 3 @@ -64,7 +60,8 @@ The function returns its first argument. .Sh SEE ALSO .Xr bzero 3 , -.Xr swab 3 +.Xr swab 3 , +.Xr wmemset 3 .Sh STANDARDS The .Fn memset diff --git a/string/FreeBSD/memset.3.patch b/string/FreeBSD/memset.3.patch index 9f75291..2257b5b 100644 --- a/string/FreeBSD/memset.3.patch +++ b/string/FreeBSD/memset.3.patch @@ -1,6 +1,6 @@ ---- memset.3.orig 2008-02-29 10:45:51.000000000 -0800 -+++ memset.3 2008-02-29 10:59:18.000000000 -0800 -@@ -41,7 +41,7 @@ +--- memset.3.bsdnew 2009-11-30 13:52:22.000000000 -0800 ++++ memset.3 2009-11-30 14:19:30.000000000 -0800 +@@ -37,7 +37,7 @@ .Os .Sh NAME .Nm memset @@ -9,7 +9,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -@@ -56,7 +56,7 @@ +@@ -52,7 +52,7 @@ writes .Fa len bytes of value .Fa c @@ -18,11 +18,11 @@ .Fa b . .Sh RETURN VALUES The -@@ -64,6 +64,7 @@ +@@ -60,6 +60,7 @@ The function returns its first argument. .Sh SEE ALSO .Xr bzero 3 , +.Xr memset_pattern 3 , - .Xr swab 3 + .Xr swab 3 , + .Xr wmemset 3 .Sh STANDARDS - The diff --git a/string/FreeBSD/memset.c b/string/FreeBSD/memset.c index 1cb8644..2b3a226 100644 --- a/string/FreeBSD/memset.c +++ b/string/FreeBSD/memset.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)memset.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/memset.c,v 1.8 2002/09/01 21:53:46 robert Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/memset.c,v 1.9 2007/01/09 00:28:12 imp Exp $"); #include diff --git a/string/FreeBSD/rindex.c b/string/FreeBSD/rindex.c index 697b69a..b687b18 100644 --- a/string/FreeBSD/rindex.c +++ b/string/FreeBSD/rindex.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)rindex.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/rindex.c,v 1.7 2003/12/18 07:44:53 jkh Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/rindex.c,v 1.8 2007/01/09 00:28:12 imp Exp $"); #include diff --git a/string/FreeBSD/stpcpy.c b/string/FreeBSD/stpcpy.c index 2742bf7..ffbc0a2 100644 --- a/string/FreeBSD/stpcpy.c +++ b/string/FreeBSD/stpcpy.c @@ -33,12 +33,12 @@ static char sccsid[] = "@(#)strcpy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/stpcpy.c,v 1.1 2002/10/03 19:39:20 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/stpcpy.c,v 1.2 2009/02/28 06:05:37 das Exp $"); #include char * -stpcpy(char * to, const char * from) +stpcpy(char * __restrict to, const char * __restrict from) { for (; (*to = *from); ++from, ++to); diff --git a/string/FreeBSD/stpncpy.c b/string/FreeBSD/stpncpy.c new file mode 100644 index 0000000..52f6149 --- /dev/null +++ b/string/FreeBSD/stpncpy.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/string/stpncpy.c,v 1.1 2009/02/28 06:00:58 das Exp $"); + +#include + +char * +stpncpy(char * __restrict dst, const char * __restrict src, size_t n) +{ + + for (; n--; dst++, src++) { + if (!(*dst = *src)) { + char *ret = dst; + while (n--) + *++dst = '\0'; + return (ret); + } + } + return (dst); +} diff --git a/string/FreeBSD/strcasecmp.3 b/string/FreeBSD/strcasecmp.3 index 4da0d23..004b081 100644 --- a/string/FreeBSD/strcasecmp.3 +++ b/string/FreeBSD/strcasecmp.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/strcasecmp.3,v 1.11 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strcasecmp.3,v 1.13 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 9, 1993 .Dt STRCASECMP 3 @@ -87,7 +83,8 @@ is greater than .Xr strcmp 3 , .Xr strcoll 3 , .Xr strxfrm 3 , -.Xr tolower 3 +.Xr tolower 3 , +.Xr wcscasecmp 3 .Sh HISTORY The .Fn strcasecmp diff --git a/string/FreeBSD/strcasecmp.3.patch b/string/FreeBSD/strcasecmp.3.patch index de13f67..c34f056 100644 --- a/string/FreeBSD/strcasecmp.3.patch +++ b/string/FreeBSD/strcasecmp.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strcasecmp.3 2004-11-25 11:38:46.000000000 -0800 -+++ _SB/Libc/string/FreeBSD/strcasecmp.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -39,16 +39,40 @@ +--- strcasecmp.3.orig 2009-11-30 13:52:22.000000000 -0800 ++++ strcasecmp.3 2009-11-30 15:12:56.000000000 -0800 +@@ -35,16 +35,40 @@ .Os .Sh NAME .Nm strcasecmp , @@ -44,7 +44,7 @@ .Sh DESCRIPTION The .Fn strcasecmp -@@ -63,8 +87,20 @@ +@@ -59,8 +83,20 @@ and The .Fn strncasecmp compares at most @@ -66,12 +66,11 @@ .Sh RETURN VALUES The .Fn strcasecmp -@@ -87,7 +123,8 @@ - .Xr strcmp 3 , +@@ -84,7 +120,7 @@ is greater than .Xr strcoll 3 , .Xr strxfrm 3 , --.Xr tolower 3 -+.Xr tolower 3 , + .Xr tolower 3 , +-.Xr wcscasecmp 3 +.Xr xlocale 3 .Sh HISTORY The diff --git a/string/FreeBSD/strcasecmp.c b/string/FreeBSD/strcasecmp.c index 6f400d7..2e063bb 100644 --- a/string/FreeBSD/strcasecmp.c +++ b/string/FreeBSD/strcasecmp.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strcasecmp.c,v 1.6 2002/08/30 15:40:01 robert Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strcasecmp.c,v 1.8 2009/02/03 17:58:20 danger Exp $"); #include #include @@ -43,8 +39,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strcasecmp.c,v 1.6 2002/08/30 15:40:01 r typedef unsigned char u_char; int -strcasecmp(s1, s2) - const char *s1, *s2; +strcasecmp(const char *s1, const char *s2) { const u_char *us1 = (const u_char *)s1, @@ -57,9 +52,7 @@ strcasecmp(s1, s2) } int -strncasecmp(s1, s2, n) - const char *s1, *s2; - size_t n; +strncasecmp(const char *s1, const char *s2, size_t n) { if (n != 0) { const u_char diff --git a/string/FreeBSD/strcasecmp.c.patch b/string/FreeBSD/strcasecmp.c.patch index 810edb7..22938eb 100644 --- a/string/FreeBSD/strcasecmp.c.patch +++ b/string/FreeBSD/strcasecmp.c.patch @@ -1,8 +1,8 @@ ---- strcasecmp.c.orig 2003-05-20 15:23:54.000000000 -0700 -+++ strcasecmp.c 2005-02-18 18:46:40.000000000 -0800 -@@ -37,41 +37,62 @@ +--- strcasecmp.c.bsdnew 2009-11-18 18:24:33.000000000 -0800 ++++ strcasecmp.c 2009-11-18 18:24:33.000000000 -0800 +@@ -33,38 +33,59 @@ static char sccsid[] = "@(#)strcasecmp.c #include - __FBSDID("$FreeBSD: src/lib/libc/string/strcasecmp.c,v 1.6 2002/08/30 15:40:01 robert Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/string/strcasecmp.c,v 1.8 2009/02/03 17:58:20 danger Exp $"); +#include "xlocale_private.h" + @@ -12,9 +12,9 @@ typedef unsigned char u_char; int --strcasecmp(s1, s2) +-strcasecmp(const char *s1, const char *s2) +strcasecmp_l(s1, s2, loc) - const char *s1, *s2; ++ const char *s1, *s2; + locale_t loc; { const u_char @@ -31,19 +31,18 @@ } int --strncasecmp(s1, s2, n) -+strcasecmp(s1, s2) -+ const char *s1, *s2; -+{ +-strncasecmp(const char *s1, const char *s2, size_t n) ++strcasecmp(const char *s1, const char *s2) + { + return strcasecmp_l(s1, s2, __current_locale()); +} + +int +strncasecmp_l(s1, s2, n, loc) - const char *s1, *s2; - size_t n; ++ const char *s1, *s2; ++ size_t n; + locale_t loc; - { ++{ + NORMALIZE_LOCALE(loc); if (n != 0) { const u_char @@ -63,9 +62,7 @@ } + +int -+strncasecmp(s1, s2, n) -+ const char *s1, *s2; -+ size_t n; ++strncasecmp(const char *s1, const char *s2, size_t n) +{ + return strncasecmp_l(s1, s2, n, __current_locale()); +} diff --git a/string/FreeBSD/strcasestr.c b/string/FreeBSD/strcasestr.c index dafcb79..54c345b 100644 --- a/string/FreeBSD/strcasestr.c +++ b/string/FreeBSD/strcasestr.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strcasestr.c,v 1.3 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strcasestr.c,v 1.5 2009/02/03 17:58:20 danger Exp $"); #include #include @@ -44,8 +40,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strcasestr.c,v 1.3 2002/03/21 18:44:54 o * Find the first occurrence of find in s, ignore case. */ char * -strcasestr(s, find) - const char *s, *find; +strcasestr(const char *s, const char *find) { char c, sc; size_t len; diff --git a/string/FreeBSD/strcasestr.c.patch b/string/FreeBSD/strcasestr.c.patch index 0c27831..19818d7 100644 --- a/string/FreeBSD/strcasestr.c.patch +++ b/string/FreeBSD/strcasestr.c.patch @@ -1,21 +1,21 @@ ---- strcasestr.c.orig 2003-05-20 15:23:54.000000000 -0700 -+++ strcasestr.c 2005-02-18 18:48:55.000000000 -0800 -@@ -37,6 +37,8 @@ +--- strcasestr.c.bsdnew 2009-11-18 18:24:33.000000000 -0800 ++++ strcasestr.c 2009-11-18 18:24:33.000000000 -0800 +@@ -33,6 +33,8 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/string/strcasestr.c,v 1.3 2002/03/21 18:44:54 obrien Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/string/strcasestr.c,v 1.5 2009/02/03 17:58:20 danger Exp $"); +#include "xlocale_private.h" + #include #include -@@ -44,22 +46,31 @@ +@@ -40,21 +42,30 @@ __FBSDID("$FreeBSD: src/lib/libc/string/ * Find the first occurrence of find in s, ignore case. */ char * --strcasestr(s, find) +-strcasestr(const char *s, const char *find) +strcasestr_l(s, find, loc) - const char *s, *find; ++ const char *s, *find; + locale_t loc; { char c, sc; @@ -40,8 +40,7 @@ } + +char * -+strcasestr(s, find) -+ const char *s, *find; ++strcasestr(const char *s, const char *find) +{ + return strcasestr_l(s, find, __current_locale()); +} diff --git a/string/FreeBSD/strcat.3 b/string/FreeBSD/strcat.3 index 7367895..00d0788 100644 --- a/string/FreeBSD/strcat.3 +++ b/string/FreeBSD/strcat.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,13 +30,14 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcat.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcat.3,v 1.13 2002/09/06 11:24:06 tjr Exp $ +.\" $FreeBSD: src/lib/libc/string/strcat.3,v 1.17 2009/12/01 07:28:56 brueffer Exp $ .\" -.Dd June 4, 1993 +.Dd December 1, 2009 .Dt STRCAT 3 .Os .Sh NAME -.Nm strcat +.Nm strcat , +.Nm strncat .Nd concatenate strings .Sh LIBRARY .Lb libc @@ -148,12 +145,8 @@ foo(const char *arbitrary_string) .Xr memmove 3 , .Xr strcpy 3 , .Xr strlcat 3 , -.Xr strlcpy 3 -.Rs -.%T "The FreeBSD Security Architecture" -.Re -(See -.Pa "/usr/share/doc/{to be decided}" . ) +.Xr strlcpy 3 , +.Xr wcscat 3 .Sh STANDARDS The .Fn strcat diff --git a/string/FreeBSD/strcat.3.patch b/string/FreeBSD/strcat.3.patch index d76276a..2351d2e 100644 --- a/string/FreeBSD/strcat.3.patch +++ b/string/FreeBSD/strcat.3.patch @@ -1,15 +1,6 @@ ---- strcat.3.orig 2008-02-29 10:45:51.000000000 -0800 -+++ strcat.3 2008-02-29 12:07:09.000000000 -0800 -@@ -40,16 +40,24 @@ - .Dt STRCAT 3 - .Os - .Sh NAME --.Nm strcat -+.Nm strcat , -+.Nm strncat - .Nd concatenate strings - .Sh LIBRARY - .Lb libc +--- strcat.3.orig 2010-06-17 08:44:44.000000000 -0700 ++++ strcat.3 2010-06-17 08:46:22.000000000 -0700 +@@ -44,9 +44,16 @@ .Sh SYNOPSIS .In string.h .Ft char * @@ -28,7 +19,7 @@ .Sh DESCRIPTION The .Fn strcat -@@ -57,24 +65,27 @@ +@@ -54,24 +61,27 @@ and .Fn strncat functions append a copy of the null-terminated string @@ -61,7 +52,7 @@ .Sh RETURN VALUES The .Fn strcat -@@ -82,7 +93,7 @@ +@@ -79,7 +89,7 @@ and .Fn strncat functions return the pointer @@ -70,7 +61,7 @@ .Sh SECURITY CONSIDERATIONS The .Fn strcat -@@ -114,7 +125,7 @@ +@@ -111,7 +121,7 @@ Example: void foo(const char *arbitrary_string) { @@ -79,15 +70,3 @@ #if defined(BAD) /* -@@ -149,11 +160,6 @@ - .Xr strcpy 3 , - .Xr strlcat 3 , - .Xr strlcpy 3 --.Rs --.%T "The FreeBSD Security Architecture" --.Re --(See --.Pa "/usr/share/doc/{to be decided}" . ) - .Sh STANDARDS - The - .Fn strcat diff --git a/string/FreeBSD/strcat.c b/string/FreeBSD/strcat.c index 5d28c86..8ebcf1b 100644 --- a/string/FreeBSD/strcat.c +++ b/string/FreeBSD/strcat.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strcat.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strcat.c,v 1.7 2002/09/06 11:24:06 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strcat.c,v 1.8 2007/01/09 00:28:12 imp Exp $"); #include diff --git a/string/FreeBSD/strchr.3 b/string/FreeBSD/strchr.3 index f6780e0..278db74 100644 --- a/string/FreeBSD/strchr.3 +++ b/string/FreeBSD/strchr.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strchr.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/string/strchr.3,v 1.11 2003/09/04 20:36:54 simon Exp $ +.\" $FreeBSD: src/lib/libc/string/strchr.3,v 1.14 2009/04/07 13:42:53 trasz Exp $ .\" .Dd April 19, 1994 .Dt STRCHR 3 @@ -83,12 +79,14 @@ return a pointer to the located character, or if the character does not appear in the string. .Sh SEE ALSO .Xr memchr 3 , +.Xr memmem 3 , .Xr strcspn 3 , .Xr strpbrk 3 , .Xr strsep 3 , .Xr strspn 3 , .Xr strstr 3 , -.Xr strtok 3 +.Xr strtok 3 , +.Xr wcschr 3 .Sh STANDARDS The functions .Fn strchr diff --git a/string/FreeBSD/strchr.3.patch b/string/FreeBSD/strchr.3.patch index 69bf2a3..d5ff416 100644 --- a/string/FreeBSD/strchr.3.patch +++ b/string/FreeBSD/strchr.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strchr.3 2004-11-25 11:38:47.000000000 -0800 -+++ _SB/Libc/string/FreeBSD/strchr.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -47,9 +47,15 @@ +--- strchr.3.bsdnew 2009-11-18 18:24:33.000000000 -0800 ++++ strchr.3 2009-11-18 18:24:33.000000000 -0800 +@@ -43,9 +43,15 @@ .Sh SYNOPSIS .In string.h .Ft "char *" @@ -18,7 +18,7 @@ .Sh DESCRIPTION The .Fn strchr -@@ -59,7 +65,7 @@ +@@ -55,7 +61,7 @@ function locates the first occurrence of .Vt char ) in the string pointed to by .Fa s . @@ -27,7 +27,7 @@ therefore if .Fa c is -@@ -70,7 +76,7 @@ +@@ -66,7 +72,7 @@ the functions locate the terminating The .Fn strrchr function is identical to diff --git a/string/FreeBSD/strcmp.3 b/string/FreeBSD/strcmp.3 index 101d71b..43acd33 100644 --- a/string/FreeBSD/strcmp.3 +++ b/string/FreeBSD/strcmp.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcmp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcmp.3,v 1.10 2001/10/11 17:02:44 mike Exp $ +.\" $FreeBSD: src/lib/libc/string/strcmp.3,v 1.13 2009/12/04 09:20:20 trhodes Exp $ .\" .Dd October 11, 2001 .Dt STRCMP 3 @@ -79,7 +75,7 @@ The .Fn strcmp and .Fn strncmp -return an integer greater than, equal to, or less than 0, according +functions return an integer greater than, equal to, or less than 0, according as the string .Fa s1 is greater than, equal to, or less than the string @@ -93,7 +89,8 @@ is greater than .Xr memcmp 3 , .Xr strcasecmp 3 , .Xr strcoll 3 , -.Xr strxfrm 3 +.Xr strxfrm 3 , +.Xr wcscmp 3 .Sh STANDARDS The .Fn strcmp diff --git a/string/FreeBSD/strcmp.3.patch b/string/FreeBSD/strcmp.3.patch index 292eaa4..1e3d6b4 100644 --- a/string/FreeBSD/strcmp.3.patch +++ b/string/FreeBSD/strcmp.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strcmp.3 2003-05-20 15:23:54.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/strcmp.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -48,9 +48,16 @@ +--- strcmp.3.bsdnew 2009-11-18 18:24:33.000000000 -0800 ++++ strcmp.3 2009-11-18 18:24:34.000000000 -0800 +@@ -44,9 +44,16 @@ .Sh SYNOPSIS .In string.h .Ft int @@ -19,7 +19,7 @@ .Sh DESCRIPTION The .Fn strcmp -@@ -66,7 +73,7 @@ +@@ -62,7 +69,7 @@ The .Fn strncmp function compares not more than diff --git a/string/FreeBSD/strcoll.3 b/string/FreeBSD/strcoll.3 index d2e1ae4..8c18f77 100644 --- a/string/FreeBSD/strcoll.3 +++ b/string/FreeBSD/strcoll.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcoll.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcoll.3,v 1.12 2002/10/15 10:11:53 tjr Exp $ +.\" $FreeBSD: src/lib/libc/string/strcoll.3,v 1.14 2007/01/09 00:28:12 imp Exp $ .\" .Dd June 4, 1993 .Dt STRCOLL 3 @@ -56,13 +52,16 @@ lexicographically compares the null-terminated strings .Fa s1 and .Fa s2 -according to the current locale collation if any, otherwise call -.Fa strcmp , +according to the current locale collation and returns an integer greater than, equal to, or less than 0, according as .Fa s1 is greater than, equal to, or less than .Fa s2 . +If information about the current locale collation is not available, +the value of +.Fn strcmp s1 s2 +is returned. .Sh SEE ALSO .Xr setlocale 3 , .Xr strcmp 3 , diff --git a/string/FreeBSD/strcoll.3.patch b/string/FreeBSD/strcoll.3.patch index 317d110..fc46410 100644 --- a/string/FreeBSD/strcoll.3.patch +++ b/string/FreeBSD/strcoll.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strcoll.3 2003-05-20 15:23:54.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/strcoll.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -40,14 +40,26 @@ +--- strcoll.3.bsdnew 2009-11-30 13:52:22.000000000 -0800 ++++ strcoll.3 2009-11-30 14:29:06.000000000 -0800 +@@ -36,14 +36,26 @@ .Dt STRCOLL 3 .Os .Sh NAME @@ -30,22 +30,10 @@ .Sh DESCRIPTION The .Fn strcoll -@@ -55,19 +67,29 @@ - lexicographically compares the null-terminated strings - .Fa s1 - and --.Fa s2 --according to the current locale collation if any, otherwise call --.Fa strcmp , -+.Fa s2 , -+according to the current locale collation, if any. -+Otherwise, it calls -+.Fa strcmp - and returns an integer greater than, equal to, or less than 0, - according as - .Fa s1 - is greater than, equal to, or less than - .Fa s2 . +@@ -62,11 +74,20 @@ If information about the current locale + the value of + .Fn strcmp s1 s2 + is returned. +.Pp +Although the +.Fn strcoll diff --git a/string/FreeBSD/strcoll.c b/string/FreeBSD/strcoll.c index b93ce48..65448df 100644 --- a/string/FreeBSD/strcoll.c +++ b/string/FreeBSD/strcoll.c @@ -26,15 +26,14 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strcoll.c,v 1.13 2001/11/07 19:55:16 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strcoll.c,v 1.14 2009/02/03 17:58:20 danger Exp $"); #include #include #include "collate.h" int -strcoll(s, s2) - const char *s, *s2; +strcoll(const char *s, const char *s2) { int len, len2, prim, prim2, sec, sec2, ret, ret2; const char *t, *t2; diff --git a/string/FreeBSD/strcoll.c.patch b/string/FreeBSD/strcoll.c.patch index 4dce6b4..58fc3c0 100644 --- a/string/FreeBSD/strcoll.c.patch +++ b/string/FreeBSD/strcoll.c.patch @@ -1,8 +1,8 @@ ---- strcoll.c.orig 2003-05-20 15:23:54.000000000 -0700 -+++ strcoll.c 2005-03-30 15:16:28.000000000 -0800 -@@ -28,59 +28,44 @@ +--- strcoll.c.bsdnew 2009-11-18 18:24:34.000000000 -0800 ++++ strcoll.c 2009-11-18 18:26:43.000000000 -0800 +@@ -28,58 +28,41 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/string/strcoll.c,v 1.13 2001/11/07 19:55:16 obrien Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/string/strcoll.c,v 1.14 2009/02/03 17:58:20 danger Exp $"); +#include "xlocale_private.h" + @@ -13,10 +13,8 @@ #include "collate.h" int --strcoll(s, s2) -+strcoll_l(s, s2, loc) - const char *s, *s2; -+ locale_t loc; +-strcoll(const char *s, const char *s2) ++strcoll_l(const char *s, const char *s2, locale_t loc) { - int len, len2, prim, prim2, sec, sec2, ret, ret2; - const char *t, *t2; @@ -83,8 +81,7 @@ } + +int -+strcoll(s, s2) -+ const char *s, *s2; ++strcoll(const char *s, const char *s2) +{ + return strcoll_l(s, s2, __current_locale()); +} diff --git a/string/FreeBSD/strcpy.3 b/string/FreeBSD/strcpy.3 index 138bace..4b719be 100644 --- a/string/FreeBSD/strcpy.3 +++ b/string/FreeBSD/strcpy.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,20 +30,22 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcpy.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcpy.3,v 1.24 2002/12/19 09:40:24 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strcpy.3,v 1.28 2009/04/07 13:42:53 trasz Exp $ .\" -.Dd August 9, 2001 +.Dd February 28, 2009 .Dt STRCPY 3 .Os .Sh NAME -.Nm strcpy , strncpy +.Nm stpcpy, stpncpy, strcpy , strncpy .Nd copy strings .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In string.h .Ft char * -.Fn stpcpy "char *dst" "const char *src" +.Fn stpcpy "char * restrict dst" "const char * restrict src" +.Ft char * +.Fn stpncpy "char * restrict dst" "const char * restrict src" "size_t len" .Ft char * .Fn strcpy "char * restrict dst" "const char * restrict src" .Ft char * @@ -67,8 +65,10 @@ to character.) .Pp The +.Fn stpncpy +and .Fn strncpy -function copies at most +functions copy at most .Fa len characters from .Fa src @@ -99,10 +99,21 @@ return .Fa dst . The .Fn stpcpy -function returns a pointer to the terminating +and +.Fn stpncpy +functions return a pointer to the terminating .Ql \e0 character of .Fa dst . +If +.Fn stpncpy +does not terminate +.Fa dst +with a +.Dv NUL +character, it instead returns a pointer to +.Li dst[n] +(which does not necessarily refer to a valid memory location.) .Sh EXAMPLES The following sets .Va chararray @@ -178,12 +189,8 @@ and .Xr memccpy 3 , .Xr memcpy 3 , .Xr memmove 3 , -.Xr strlcpy 3 -.Rs -.%T "The FreeBSD Security Architecture" -.Re -(See -.Pa "/usr/share/doc/{to be decided}" . ) +.Xr strlcpy 3 , +.Xr wcscpy 3 .Sh STANDARDS The .Fn strcpy @@ -194,14 +201,16 @@ conform to .St -isoC . The .Fn stpcpy -function is an MS-DOS and GNUism. -The -.Fn stpcpy -function -conforms to no standard. +and +.Fn stpncpy +functions conform to +.St -p1003.1-2008 . .Sh HISTORY The .Fn stpcpy function first appeared in .Fx 4.4 , -coming from 1998-vintage Linux. +and +.Fn stpncpy +was added in +.Fx 8.0 . diff --git a/string/FreeBSD/strcpy.3.patch b/string/FreeBSD/strcpy.3.patch index 420ccc0..d29e550 100644 --- a/string/FreeBSD/strcpy.3.patch +++ b/string/FreeBSD/strcpy.3.patch @@ -1,23 +1,20 @@ ---- strcpy.3.orig 2008-02-29 10:45:51.000000000 -0800 -+++ strcpy.3 2008-02-29 12:08:34.000000000 -0800 -@@ -40,18 +40,30 @@ - .Dt STRCPY 3 - .Os - .Sh NAME --.Nm strcpy , strncpy -+.Nm stpcpy , -+.Nm strcpy , -+.Nm strncpy - .Nd copy strings - .Sh LIBRARY - .Lb libc +--- strcpy.3.orig 2010-04-28 23:38:50.000000000 -0700 ++++ strcpy.3 2010-04-29 09:37:17.000000000 -0700 +@@ -43,13 +43,27 @@ .Sh SYNOPSIS .In string.h .Ft char * --.Fn stpcpy "char *dst" "const char *src" +-.Fn stpcpy "char * restrict dst" "const char * restrict src" +.Fo stpcpy +.Fa "char *s1" +.Fa "const char *s2" ++.Fc + .Ft char * +-.Fn stpncpy "char * restrict dst" "const char * restrict src" "size_t len" ++.Fo stpncpy ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fa "size_t n" +.Fc .Ft char * -.Fn strcpy "char * restrict dst" "const char * restrict src" @@ -35,7 +32,7 @@ .Sh DESCRIPTION The .Fn stpcpy -@@ -59,36 +71,39 @@ +@@ -57,38 +71,41 @@ and .Fn strcpy functions copy the string @@ -50,8 +47,10 @@ +character). .Pp The + .Fn stpncpy + and .Fn strncpy - function copies at most + functions copy at most -.Fa len +.Fa n characters from @@ -85,7 +84,7 @@ .Sh RETURN VALUES The .Fn strcpy -@@ -96,13 +111,13 @@ +@@ -96,7 +113,7 @@ and .Fn strncpy functions return @@ -93,15 +92,27 @@ +.Fa s1 . The .Fn stpcpy - function returns a pointer to the terminating + and +@@ -104,15 +121,15 @@ and + functions return a pointer to the terminating .Ql \e0 character of -.Fa dst . +.Fa s1 . + If + .Fn stpncpy + does not terminate +-.Fa dst ++.Fa s1 + with a + .Dv NUL + character, it instead returns a pointer to +-.Li dst[n] ++.Li s1[n] + (which does not necessarily refer to a valid memory location.) .Sh EXAMPLES The following sets - .Va chararray -@@ -128,7 +143,7 @@ +@@ -139,7 +156,7 @@ Note that it does .Em not .Tn NUL terminate @@ -110,24 +121,37 @@ because the length of the source string is greater than or equal to the length argument. .Pp -@@ -159,7 +174,7 @@ +@@ -169,21 +186,26 @@ This could be better achieved using + as shown in the following example: .Pp .Dl "(void)strlcpy(buf, input, sizeof(buf));" - .Pp +-.Pp -Note that because -+Note that, because - .Xr strlcpy 3 - is not defined in any standards, it should - only be used when portability is not a concern. -@@ -179,11 +194,6 @@ - .Xr memcpy 3 , - .Xr memmove 3 , - .Xr strlcpy 3 --.Rs --.%T "The FreeBSD Security Architecture" --.Re --(See --.Pa "/usr/share/doc/{to be decided}" . ) - .Sh STANDARDS +-.Xr strlcpy 3 +-is not defined in any standards, it should +-only be used when portability is not a concern. + .Sh SECURITY CONSIDERATIONS The - .Fn strcpy +-.Fn strcpy +-function is easily misused in a manner which enables malicious users ++.Fn strcpy , ++.Fn strncpy , ++.Fn stpcpy , ++and ++.Fn stpncpy ++functions are easily misused in a manner which enables malicious users + to arbitrarily change a running program's functionality through a + buffer overflow attack. + (See + the FSA + and + .Sx EXAMPLES . ) ++.Pp ++It is recommended that ++.Xr strlcpy 3 ++be used instead as a way to avoid such problems. ++.Xr strlcpy 3 ++is not defined in any standards, but it has been adopted by most major libc implementations. + .Sh SEE ALSO + .Xr bcopy 3 , + .Xr memccpy 3 , diff --git a/string/FreeBSD/strcpy.c b/string/FreeBSD/strcpy.c index 5cd2f45..7489997 100644 --- a/string/FreeBSD/strcpy.c +++ b/string/FreeBSD/strcpy.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strcpy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strcpy.c,v 1.7 2002/09/06 11:24:06 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strcpy.c,v 1.8 2007/01/09 00:28:12 imp Exp $"); #include diff --git a/string/FreeBSD/strcspn.3 b/string/FreeBSD/strcspn.3 index c105c12..dc57aa1 100644 --- a/string/FreeBSD/strcspn.3 +++ b/string/FreeBSD/strcspn.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcspn.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcspn.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strcspn.3,v 1.9 2007/01/09 00:28:12 imp Exp $ .\" .Dd June 4, 1993 .Dt STRCSPN 3 @@ -63,6 +59,13 @@ spans the .Em complement of .Fa charset ) . +In other words, it computes the string array index in +.Fa s +of the first character of +.Fa s +which is also in +.Fa charset , +else the index of the first null character. .Sh RETURN VALUES The .Fn strcspn diff --git a/string/FreeBSD/strcspn.3.patch b/string/FreeBSD/strcspn.3.patch index 3525890..22519f0 100644 --- a/string/FreeBSD/strcspn.3.patch +++ b/string/FreeBSD/strcspn.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strcspn.3 2003-05-20 15:23:54.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/strcspn.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -47,27 +47,29 @@ +--- strcspn.3.orig 2009-11-30 13:52:23.000000000 -0800 ++++ strcspn.3 2009-11-30 14:57:01.000000000 -0800 +@@ -43,28 +43,31 @@ .Sh SYNOPSIS .In string.h .Ft size_t @@ -28,12 +28,15 @@ of -.Fa charset ) . +.Fa s2 ) . + In other words, it computes the string array index in +-.Fa s ++.Fa s1 + of the first character of +-.Fa s ++.Fa s1 + which is also in +-.Fa charset , ++.Fa s2 , + else the index of the first null character. .Sh RETURN VALUES The - .Fn strcspn --function --returns the number of characters spanned. -+function returns the number of characters spanned. - .Sh SEE ALSO - .Xr memchr 3 , - .Xr strchr 3 , diff --git a/string/FreeBSD/strdup.3 b/string/FreeBSD/strdup.3 index 3bb2516..b9bf40c 100644 --- a/string/FreeBSD/strdup.3 +++ b/string/FreeBSD/strdup.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,13 +26,14 @@ .\" SUCH DAMAGE. .\" .\" @(#)strdup.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/strdup.3,v 1.10 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strdup.3,v 1.15 2009/04/07 13:42:53 trasz Exp $ .\" -.Dd June 9, 1993 +.Dd December 5, 2008 .Dt STRDUP 3 .Os .Sh NAME -.Nm strdup +.Nm strdup , +.Nm strndup .Nd save a copy of a string .Sh LIBRARY .Lb libc @@ -44,6 +41,8 @@ .In string.h .Ft char * .Fn strdup "const char *str" +.Ft char * +.Fn strndup "const char *str" "size_t len" .Sh DESCRIPTION The .Fn strdup @@ -60,11 +59,26 @@ If insufficient memory is available, NULL is returned and .Va errno is set to .Er ENOMEM . +.Pp +The +.Fn strndup +function copies at most +.Fa len +characters from the string +.Fa str +always +.Dv NUL +terminating the copied string. .Sh SEE ALSO .Xr free 3 , -.Xr malloc 3 +.Xr malloc 3 , +.Xr wcsdup 3 .Sh HISTORY The .Fn strdup function first appeared in .Bx 4.4 . +The +.Fn strndup +function was added in +.Fx 7.2 . diff --git a/string/FreeBSD/strdup.3.patch b/string/FreeBSD/strdup.3.patch index e05470d..5ef2029 100644 --- a/string/FreeBSD/strdup.3.patch +++ b/string/FreeBSD/strdup.3.patch @@ -1,12 +1,18 @@ ---- _SB/Libc/string/FreeBSD/strdup.3 2003-05-20 15:23:54.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/strdup.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -43,14 +43,16 @@ +--- strdup.3.orig 2009-11-30 13:52:20.000000000 -0800 ++++ strdup.3 2009-11-30 15:13:21.000000000 -0800 +@@ -40,16 +40,21 @@ .Sh SYNOPSIS .In string.h .Ft char * -.Fn strdup "const char *str" +.Fo strdup +.Fa "const char *s1" ++.Fc + .Ft char * +-.Fn strndup "const char *str" "size_t len" ++.Fo strndup ++.Fa "const char *s1" ++.Fa "size_t n" +.Fc .Sh DESCRIPTION The @@ -19,3 +25,23 @@ does the copy, and returns a pointer to it. The pointer may subsequently be used as an argument to the function +@@ -63,16 +68,15 @@ is set to + The + .Fn strndup + function copies at most +-.Fa len ++.Fa n + characters from the string +-.Fa str ++.Fa s1 + always + .Dv NUL + terminating the copied string. + .Sh SEE ALSO + .Xr free 3 , +-.Xr malloc 3 , +-.Xr wcsdup 3 ++.Xr malloc 3 + .Sh HISTORY + The + .Fn strdup diff --git a/string/FreeBSD/strdup.c b/string/FreeBSD/strdup.c index a9881a1..3043a3b 100644 --- a/string/FreeBSD/strdup.c +++ b/string/FreeBSD/strdup.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,15 +31,14 @@ static char sccsid[] = "@(#)strdup.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strdup.c,v 1.4 2001/11/07 19:55:16 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strdup.c,v 1.6 2009/02/03 17:58:20 danger Exp $"); #include #include #include char * -strdup(str) - const char *str; +strdup(const char *str) { size_t len; char *copy; diff --git a/string/FreeBSD/strerror.3 b/string/FreeBSD/strerror.3 index 3abe237..b8223d2 100644 --- a/string/FreeBSD/strerror.3 +++ b/string/FreeBSD/strerror.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strerror.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/strerror.3,v 1.23 2004/10/12 14:52:52 keramida Exp $ +.\" $FreeBSD: src/lib/libc/string/strerror.3,v 1.24 2007/01/09 00:28:12 imp Exp $ .\" .Dd October 12, 2004 .Dt STRERROR 3 diff --git a/string/FreeBSD/strerror.3.patch b/string/FreeBSD/strerror.3.patch index ed73088..3f34cd9 100644 --- a/string/FreeBSD/strerror.3.patch +++ b/string/FreeBSD/strerror.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strerror.3 2004-11-25 11:38:47.000000000 -0800 -+++ _SB/Libc/string/FreeBSD/strerror.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -51,18 +51,26 @@ +--- strerror.3.orig 2010-10-07 16:06:39.000000000 -0700 ++++ strerror.3 2010-10-07 16:32:34.000000000 -0700 +@@ -47,18 +47,26 @@ .Sh SYNOPSIS .In stdio.h .Ft void @@ -31,7 +31,7 @@ and .Fn perror functions look up the error message string corresponding to an -@@ -92,7 +100,7 @@ +@@ -88,7 +96,7 @@ and writes it, followed by a newline, to the standard error file descriptor. If the argument @@ -40,3 +40,12 @@ is .Pf non- Dv NULL and does not point to the null character, +@@ -110,7 +118,7 @@ + .Er EINVAL + as a warning. + Error numbers recognized by this implementation fall in +-the range 0 < ++the range 0 <= + .Fa errnum + < + .Fa sys_nerr . diff --git a/string/FreeBSD/strerror.c b/string/FreeBSD/strerror.c index b1c4913..7da9796 100644 --- a/string/FreeBSD/strerror.c +++ b/string/FreeBSD/strerror.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,27 +31,33 @@ static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strerror.c,v 1.13 2003/05/01 19:03:14 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strerror.c,v 1.16 2007/01/09 00:28:12 imp Exp $"); +#if defined(NLS) +#include +#endif + +#include #include -#include #include +#include -#define UPREFIX "Unknown error: " +#define UPREFIX "Unknown error" /* * Define a buffer size big enough to describe a 64-bit signed integer * converted to ASCII decimal (19 bytes), with an optional leading sign - * (1 byte); finally, we get the prefix and a trailing NUL from UPREFIX. + * (1 byte); finally, we get the prefix, delimiter (": ") and a trailing + * NUL from UPREFIX. */ -#define EBUFSIZE (20 + sizeof(UPREFIX)) +#define EBUFSIZE (20 + 2 + sizeof(UPREFIX)) /* * Doing this by hand instead of linking with stdio(3) avoids bloat for * statically linked binaries. */ static void -errstr(int num, char *buf, size_t len) +errstr(int num, char *uprefix, char *buf, size_t len) { char *t; unsigned int uerr; @@ -69,31 +71,56 @@ errstr(int num, char *buf, size_t len) } while (uerr /= 10); if (num < 0) *--t = '-'; - strlcpy(buf, UPREFIX, len); + *--t = ' '; + *--t = ':'; + strlcpy(buf, uprefix, len); strlcat(buf, t, len); } int strerror_r(int errnum, char *strerrbuf, size_t buflen) { + int retval = 0; +#if defined(NLS) + int saved_errno = errno; + nl_catd catd; + catd = catopen("libc", NL_CAT_LOCALE); +#endif if (errnum < 1 || errnum >= sys_nerr) { - errstr(errnum, strerrbuf, buflen); - return (EINVAL); + errstr(errnum, +#if defined(NLS) + catgets(catd, 1, 0xffff, UPREFIX), +#else + UPREFIX, +#endif + strerrbuf, buflen); + retval = EINVAL; + } else { + if (strlcpy(strerrbuf, +#if defined(NLS) + catgets(catd, 1, errnum, sys_errlist[errnum]), +#else + sys_errlist[errnum], +#endif + buflen) >= buflen) + retval = ERANGE; } - if (strlcpy(strerrbuf, sys_errlist[errnum], buflen) >= buflen) - return (ERANGE); - return (0); + +#if defined(NLS) + catclose(catd); + errno = saved_errno; +#endif + + return (retval); } char * strerror(int num) { - static char ebuf[EBUFSIZE]; + static char ebuf[NL_TEXTMAX]; - if (num > 0 && num < sys_nerr) - return ((char *)sys_errlist[num]); + if (strerror_r(num, ebuf, sizeof(ebuf)) != 0) errno = EINVAL; - errstr(num, ebuf, sizeof(ebuf)); return (ebuf); } diff --git a/string/FreeBSD/strerror.c.patch b/string/FreeBSD/strerror.c.patch index 077e741..0b88960 100644 --- a/string/FreeBSD/strerror.c.patch +++ b/string/FreeBSD/strerror.c.patch @@ -1,8 +1,8 @@ ---- strerror.c.orig 2004-11-25 11:38:47.000000000 -0800 -+++ strerror.c 2005-04-30 01:26:56.000000000 -0700 -@@ -50,12 +50,13 @@ +--- strerror.c.orig 2010-10-07 16:06:39.000000000 -0700 ++++ strerror.c 2010-10-07 16:17:59.000000000 -0700 +@@ -52,12 +52,13 @@ __FBSDID("$FreeBSD: src/lib/libc/string/ */ - #define EBUFSIZE (20 + sizeof(UPREFIX)) + #define EBUFSIZE (20 + 2 + sizeof(UPREFIX)) +#ifndef BUILDING_VARIANT /* @@ -10,25 +10,26 @@ * statically linked binaries. */ -static void --errstr(int num, char *buf, size_t len) +-errstr(int num, char *uprefix, char *buf, size_t len) +__private_extern__ void -+__errstr(int num, char *buf, size_t len) ++__errstr(int num, char *uprefix, char *buf, size_t len) { char *t; unsigned int uerr; -@@ -77,14 +78,17 @@ - strerror_r(int errnum, char *strerrbuf, size_t buflen) - { +@@ -87,8 +88,8 @@ strerror_r(int errnum, char *strerrbuf, + catd = catopen("libc", NL_CAT_LOCALE); + #endif - if (errnum < 1 || errnum >= sys_nerr) { -- errstr(errnum, strerrbuf, buflen); +- errstr(errnum, + if (errnum < 0 || errnum >= sys_nerr) { -+ __errstr(errnum, strerrbuf, buflen); - return (EINVAL); - } - if (strlcpy(strerrbuf, sys_errlist[errnum], buflen) >= buflen) - return (ERANGE); - return (0); ++ __errstr(errnum, + #if defined(NLS) + catgets(catd, 1, 0xffff, UPREFIX), + #else +@@ -114,13 +115,20 @@ strerror_r(int errnum, char *strerrbuf, + + return (retval); } +#else /* BUILDING_VARIANT */ +__private_extern__ void __errstr(int, char *, size_t); @@ -36,14 +37,14 @@ char * strerror(int num) -@@ -93,7 +97,9 @@ + { + static char ebuf[NL_TEXTMAX]; - if (num > 0 && num < sys_nerr) - return ((char *)sys_errlist[num]); +#if !__DARWIN_UNIX03 + if (strerror_r(num, ebuf, sizeof(ebuf)) != 0) errno = EINVAL; -- errstr(num, ebuf, sizeof(ebuf)); -+#endif /* !__DARWIN_UNIX03 */ -+ __errstr(num, ebuf, sizeof(ebuf)); ++#else ++ (void)strerror_r(num, ebuf, sizeof(ebuf)); ++#endif return (ebuf); } diff --git a/string/FreeBSD/string.3 b/string/FreeBSD/string.3 index 0a59cec..05f92f2 100644 --- a/string/FreeBSD/string.3 +++ b/string/FreeBSD/string.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)string.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/string/string.3,v 1.13 2002/10/19 13:41:22 tjr Exp $ +.\" $FreeBSD: src/lib/libc/string/string.3,v 1.14 2007/01/09 00:28:12 imp Exp $ .\" .Dd December 11, 1993 .Dt STRING 3 diff --git a/string/FreeBSD/string.3.patch b/string/FreeBSD/string.3.patch index 7acc472..ca6f33d 100644 --- a/string/FreeBSD/string.3.patch +++ b/string/FreeBSD/string.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/string.3 2003-05-20 15:23:54.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/string.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -38,77 +38,143 @@ +--- string.3.bsdnew 2009-11-18 18:24:34.000000000 -0800 ++++ string.3 2009-11-18 18:24:34.000000000 -0800 +@@ -34,77 +34,143 @@ .Dt STRING 3 .Os .Sh NAME diff --git a/string/FreeBSD/strlcat.c b/string/FreeBSD/strlcat.c index b8f0ff3..deec7d7 100644 --- a/string/FreeBSD/strlcat.c +++ b/string/FreeBSD/strlcat.c @@ -1,37 +1,23 @@ -/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */ +/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ /* * Copyright (c) 1998 Todd C. Miller - * 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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 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. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strlcat.c,v 1.10 2004/10/16 06:32:43 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strlcat.c,v 1.12 2009/02/28 05:15:02 das Exp $"); #include #include @@ -44,10 +30,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strlcat.c,v 1.10 2004/10/16 06:32:43 obr * If retval >= siz, truncation occurred. */ size_t -strlcat(dst, src, siz) - char *dst; - const char *src; - size_t siz; +strlcat(char * __restrict dst, const char * __restrict src, size_t siz) { char *d = dst; const char *s = src; diff --git a/string/FreeBSD/strlcpy.3 b/string/FreeBSD/strlcpy.3 index c33c0dd..1afd8d8 100644 --- a/string/FreeBSD/strlcpy.3 +++ b/string/FreeBSD/strlcpy.3 @@ -1,18 +1,18 @@ -.\" $OpenBSD: strlcpy.3,v 1.5 1999/06/06 15:17:32 aaron Exp $ +.\" $OpenBSD: strlcpy.3,v 1.19 2007/05/31 19:19:32 jmc Exp $ .\" -.\" Copyright (c) 1998 Todd C. Miller -.\" All rights reserved. +.\" Copyright (c) 1998, 2000 Todd C. Miller .\" -.\" 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. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, .\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY @@ -25,7 +25,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/string/strlcpy.3,v 1.13 2004/07/02 23:52:13 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strlcpy.3,v 1.16 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 22, 1998 .Dt STRLCPY 3 @@ -39,9 +39,9 @@ .Sh SYNOPSIS .In string.h .Ft size_t -.Fn strlcpy "char *dst" "const char *src" "size_t size" +.Fn strlcpy "char * restrict dst" "const char * restrict src" "size_t size" .Ft size_t -.Fn strlcat "char *dst" "const char *src" "size_t size" +.Fn strlcat "char * restrict dst" "const char * restrict src" "size_t size" .Sh DESCRIPTION The .Fn strlcpy @@ -64,7 +64,7 @@ is larger than 0 or, in the case of .Fn strlcat , as long as there is at least one byte free in .Fa dst ) . -Note that you should include a byte for the NUL in +Note that a byte for the NUL should be included in .Fa size . Also note that .Fn strlcpy @@ -121,7 +121,7 @@ that means the initial length of plus the length of .Fa src . -While this may seem somewhat confusing it was done to make +While this may seem somewhat confusing, it was done to make truncation detection simple. .Pp Note however, that if @@ -168,8 +168,8 @@ if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname)) goto toolong; .Ed .Pp -Since we know how many characters we copied the first time, we can -speed things up a bit by using a copy instead of an append: +Since it is known how many characters were copied the first time, things +can be sped up a bit by using a copy instead of an append .Bd -literal -offset indent char *dir, *file, pname[MAXPATHLEN]; size_t n; @@ -192,7 +192,8 @@ As a matter of fact, the first version of this manual page got it wrong. .Sh SEE ALSO .Xr snprintf 3 , .Xr strncat 3 , -.Xr strncpy 3 +.Xr strncpy 3 , +.Xr wcslcpy 3 .Sh HISTORY The .Fn strlcpy diff --git a/string/FreeBSD/strlcpy.3.patch b/string/FreeBSD/strlcpy.3.patch index b15fed9..e008fc6 100644 --- a/string/FreeBSD/strlcpy.3.patch +++ b/string/FreeBSD/strlcpy.3.patch @@ -1,6 +1,6 @@ ---- strlcpy.3.orig 2008-02-29 10:45:51.000000000 -0800 -+++ strlcpy.3 2008-02-29 12:11:21.000000000 -0800 -@@ -103,6 +103,9 @@ +--- strlcpy.3.bsdnew 2009-11-18 18:24:34.000000000 -0800 ++++ strlcpy.3 2009-11-18 18:24:34.000000000 -0800 +@@ -103,6 +103,9 @@ to the end of It will append at most .Fa size - strlen(dst) - 1 bytes, NUL-terminating the result. diff --git a/string/FreeBSD/strlcpy.c b/string/FreeBSD/strlcpy.c index 9383236..082ea3f 100644 --- a/string/FreeBSD/strlcpy.c +++ b/string/FreeBSD/strlcpy.c @@ -1,37 +1,23 @@ -/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */ +/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller - * 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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 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. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strlcpy.c,v 1.8 2004/10/14 21:31:42 stefanf Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strlcpy.c,v 1.11 2009/02/28 05:15:02 das Exp $"); #include #include @@ -41,21 +27,19 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strlcpy.c,v 1.8 2004/10/14 21:31:42 stef * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ -size_t strlcpy(dst, src, siz) - char *dst; - const char *src; - size_t siz; +size_t +strlcpy(char * __restrict dst, const char * __restrict src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) { - do { - if ((*d++ = *s++) == 0) + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') break; - } while (--n != 0); + } } /* Not enough room in dst, add NUL and traverse rest of src */ diff --git a/string/FreeBSD/strlen.3 b/string/FreeBSD/strlen.3 index b490ced..031f450 100644 --- a/string/FreeBSD/strlen.3 +++ b/string/FreeBSD/strlen.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,13 +30,13 @@ .\" SUCH DAMAGE. .\" .\" @(#)strlen.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strlen.3,v 1.6 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strlen.3,v 1.9 2009/04/07 13:42:53 trasz Exp $ .\" -.Dd June 4, 1993 +.Dd February 28, 2009 .Dt STRLEN 3 .Os .Sh NAME -.Nm strlen +.Nm strlen, strnlen .Nd find length of string .Sh LIBRARY .Lb libc @@ -48,12 +44,22 @@ .In string.h .Ft size_t .Fn strlen "const char *s" +.Ft size_t +.Fn strnlen "const char *s" "size_t maxlen" .Sh DESCRIPTION The .Fn strlen function computes the length of the string .Fa s . +The +.Fn strnlen +function attempts to compute the length of +.Fa s , +but never scans beyond the first +.Fa maxlen +bytes of +.Fa s . .Sh RETURN VALUES The .Fn strlen @@ -63,11 +69,24 @@ the number of characters that precede the terminating .Dv NUL character. +The +.Fn strnlen +function returns either the same result as +.Fn strlen +or +.Fa maxlen , +whichever is smaller. .Sh SEE ALSO -.Xr string 3 +.Xr string 3 , +.Xr wcslen 3 , +.Xr wcswidth 3 .Sh STANDARDS The .Fn strlen function conforms to .St -isoC . +The +.Fn strnlen +function conforms to +.St -p1003.1-2008 . diff --git a/string/FreeBSD/strlen.c b/string/FreeBSD/strlen.c index c67667d..81269a2 100644 --- a/string/FreeBSD/strlen.c +++ b/string/FreeBSD/strlen.c @@ -1,6 +1,6 @@ /*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 2009 Xin LI + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,18 +10,11 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * + * 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 REGENTS OR CONTRIBUTORS BE LIABLE + * 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) @@ -31,21 +24,87 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)strlen.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strlen.c,v 1.4 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strlen.c,v 1.7 2009/01/26 07:31:28 delphij Exp $"); +#include +#include #include +/* + * Portable strlen() for 32-bit and 64-bit systems. + * + * Rationale: it is generally much more efficient to do word length + * operations and avoid branches on modern computer systems, as + * compared to byte-length operations with a lot of branches. + * + * The expression: + * + * ((x - 0x01....01) & ~x & 0x80....80) + * + * would evaluate to a non-zero value iff any of the bytes in the + * original word is zero. However, we can further reduce ~1/3 of + * time if we consider that strlen() usually operate on 7-bit ASCII + * by employing the following expression, which allows false positive + * when high bit of 1 and use the tail case to catch these case: + * + * ((x - 0x01....01) & 0x80....80) + * + * This is more than 5.2 times as fast as the raw implementation on + * Intel T7300 under long mode for strings longer than word length. + */ + +/* Magic numbers for the algorithm */ +#if LONG_BIT == 32 +static const unsigned long mask01 = 0x01010101; +static const unsigned long mask80 = 0x80808080; +#elif LONG_BIT == 64 +static const unsigned long mask01 = 0x0101010101010101; +static const unsigned long mask80 = 0x8080808080808080; +#else +#error Unsupported word size +#endif + +#define LONGPTR_MASK (sizeof(long) - 1) + +/* + * Helper macro to return string length if we caught the zero + * byte. + */ +#define testbyte(x) \ + do { \ + if (p[x] == '\0') \ + return (p - str + x); \ + } while (0) + size_t -strlen(str) - const char *str; +strlen(const char *str) { - const char *s; + const char *p; + const unsigned long *lp; + + /* Skip the first few bytes until we have an aligned p */ + for (p = str; (uintptr_t)p & LONGPTR_MASK; p++) + if (*p == '\0') + return (p - str); + + /* Scan the rest of the string using word sized operation */ + for (lp = (const unsigned long *)p; ; lp++) + if ((*lp - mask01) & mask80) { + p = (const char *)(lp); + testbyte(0); + testbyte(1); + testbyte(2); + testbyte(3); +#if (LONG_BIT >= 64) + testbyte(4); + testbyte(5); + testbyte(6); + testbyte(7); +#endif + } - for (s = str; *s; ++s); - return(s - str); + /* NOTREACHED */ + return (0); } diff --git a/string/FreeBSD/strmode.3 b/string/FreeBSD/strmode.3 index f306a5b..4537bc9 100644 --- a/string/FreeBSD/strmode.3 +++ b/string/FreeBSD/strmode.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strmode.3 8.3 (Berkeley) 7/28/94 -.\" $FreeBSD: src/lib/libc/string/strmode.3,v 1.9 2003/07/01 15:28:05 maxim Exp $ +.\" $FreeBSD: src/lib/libc/string/strmode.3,v 1.11 2009/04/14 11:39:56 trasz Exp $ .\" .Dd July 28, 1994 .Dt STRMODE 3 @@ -132,9 +128,7 @@ The file is executable or the directory is searchable. None of the above apply. .El .Pp -The last character is a plus sign ``+'' if any there are any alternate -or additional access control methods associated with the inode, otherwise -it will be a space. +The last character will always be a space. .Sh SEE ALSO .Xr chmod 1 , .Xr find 1 , diff --git a/string/FreeBSD/strmode.3.patch b/string/FreeBSD/strmode.3.patch index 3653596..889c378 100644 --- a/string/FreeBSD/strmode.3.patch +++ b/string/FreeBSD/strmode.3.patch @@ -1,6 +1,6 @@ ---- strmode.3 2004-11-25 11:38:47.000000000 -0800 -+++ strmode.3.edit 2006-08-12 10:29:49.000000000 -0700 -@@ -43,7 +43,10 @@ +--- strmode.3.bsdnew 2009-11-18 18:24:34.000000000 -0800 ++++ strmode.3 2009-11-18 18:24:35.000000000 -0800 +@@ -39,7 +39,10 @@ .Sh SYNOPSIS .In string.h .Ft void diff --git a/string/FreeBSD/strmode.c b/string/FreeBSD/strmode.c index 2409b4e..3375e64 100644 --- a/string/FreeBSD/strmode.c +++ b/string/FreeBSD/strmode.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,16 +31,14 @@ static char sccsid[] = "@(#)strmode.c 8.3 (Berkeley) 8/15/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strmode.c,v 1.4 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strmode.c,v 1.8 2009/04/14 11:39:56 trasz Exp $"); #include #include #include void -strmode(mode, p) - mode_t mode; - char *p; +strmode(/* mode_t */ int mode, char *p) { /* print type */ switch (mode & S_IFMT) { @@ -149,6 +143,6 @@ strmode(mode, p) *p++ = 't'; break; } - *p++ = ' '; /* will be a '+' if ACL's implemented */ + *p++ = ' '; *p = '\0'; } diff --git a/string/FreeBSD/strncat.c b/string/FreeBSD/strncat.c index e05e030..a9b5d7c 100644 --- a/string/FreeBSD/strncat.c +++ b/string/FreeBSD/strncat.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)strncat.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strncat.c,v 1.6 2002/09/06 11:24:06 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strncat.c,v 1.7 2007/01/09 00:28:12 imp Exp $"); #include diff --git a/string/FreeBSD/strncmp.c b/string/FreeBSD/strncmp.c index 6b0cfc8..33c412b 100644 --- a/string/FreeBSD/strncmp.c +++ b/string/FreeBSD/strncmp.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,14 +31,12 @@ static char sccsid[] = "@(#)strncmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strncmp.c,v 1.5 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strncmp.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include int -strncmp(s1, s2, n) - const char *s1, *s2; - size_t n; +strncmp(const char *s1, const char *s2, size_t n) { if (n == 0) @@ -51,7 +45,7 @@ strncmp(s1, s2, n) if (*s1 != *s2++) return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); - if (*s1++ == 0) + if (*s1++ == '\0') break; } while (--n != 0); return (0); diff --git a/string/FreeBSD/strncpy.c b/string/FreeBSD/strncpy.c index 2fcc957..c2e11f9 100644 --- a/string/FreeBSD/strncpy.c +++ b/string/FreeBSD/strncpy.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)strncpy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strncpy.c,v 1.6 2002/09/06 11:24:06 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strncpy.c,v 1.8 2009/02/03 17:58:20 danger Exp $"); #include @@ -54,10 +50,10 @@ strncpy(char * __restrict dst, const char * __restrict src, size_t n) const char *s = src; do { - if ((*d++ = *s++) == 0) { + if ((*d++ = *s++) == '\0') { /* NUL pad the remaining n-1 bytes */ while (--n != 0) - *d++ = 0; + *d++ = '\0'; break; } } while (--n != 0); diff --git a/string/FreeBSD/strndup.c b/string/FreeBSD/strndup.c new file mode 100644 index 0000000..c63f6a3 --- /dev/null +++ b/string/FreeBSD/strndup.c @@ -0,0 +1,53 @@ +/* $NetBSD: strndup.c,v 1.3 2007/01/14 23:41:24 cbiere Exp $ */ + +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 +__FBSDID("$FreeBSD: src/lib/libc/string/strndup.c,v 1.1 2008/12/06 09:37:54 kib Exp $"); + +#include +#include +#include + +char * +strndup(const char *str, size_t n) +{ + size_t len; + char *copy; + + for (len = 0; len < n && str[len]; len++) + continue; + + if ((copy = malloc(len + 1)) == NULL) + return (NULL); + memcpy(copy, str, len); + copy[len] = '\0'; + return (copy); +} diff --git a/gen/FreeBSD/errno_.c b/string/FreeBSD/strnlen.c similarity index 81% rename from gen/FreeBSD/errno_.c rename to string/FreeBSD/strnlen.c index 7d98857..06a47a4 100644 --- a/gen/FreeBSD/errno_.c +++ b/string/FreeBSD/strnlen.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002 Peter Wemm + * Copyright (c) 2009 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,6 +25,18 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/errno.c,v 1.1 2002/10/09 08:04:24 peter Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strnlen.c,v 1.1 2009/02/28 06:00:58 das Exp $"); -int errno; +#include + +size_t +strnlen(const char *s, size_t maxlen) +{ + size_t len; + + for (len = 0; len < maxlen; len++, s++) { + if (!*s) + break; + } + return (len); +} diff --git a/string/FreeBSD/strnstr.c b/string/FreeBSD/strnstr.c index abe2f8d..ca12ba1 100644 --- a/string/FreeBSD/strnstr.c +++ b/string/FreeBSD/strnstr.c @@ -14,10 +14,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -39,7 +35,7 @@ static char sccsid[] = "@(#)strstr.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strnstr.c,v 1.3 2005/02/11 21:07:51 pjd Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strnstr.c,v 1.5 2009/02/03 17:58:20 danger Exp $"); #include @@ -48,10 +44,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strnstr.c,v 1.3 2005/02/11 21:07:51 pjd * first slen characters of s. */ char * -strnstr(s, find, slen) - const char *s; - const char *find; - size_t slen; +strnstr(const char *s, const char *find, size_t slen) { char c, sc; size_t len; diff --git a/string/FreeBSD/strpbrk.3 b/string/FreeBSD/strpbrk.3 index 715bb71..105febe 100644 --- a/string/FreeBSD/strpbrk.3 +++ b/string/FreeBSD/strpbrk.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strpbrk.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strpbrk.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strpbrk.3,v 1.9 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt STRPBRK 3 @@ -71,7 +67,8 @@ returns NULL. .Xr strsep 3 , .Xr strspn 3 , .Xr strstr 3 , -.Xr strtok 3 +.Xr strtok 3 , +.Xr wcspbrk 3 .Sh STANDARDS The .Fn strpbrk diff --git a/string/FreeBSD/strpbrk.3.patch b/string/FreeBSD/strpbrk.3.patch index 6befc6f..cd2c7b6 100644 --- a/string/FreeBSD/strpbrk.3.patch +++ b/string/FreeBSD/strpbrk.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strpbrk.3 2003-05-20 15:23:55.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/strpbrk.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -47,20 +47,23 @@ +--- strpbrk.3.bsdnew 2009-11-18 18:24:36.000000000 -0800 ++++ strpbrk.3 2009-11-18 18:24:36.000000000 -0800 +@@ -43,20 +43,23 @@ .Sh SYNOPSIS .In string.h .Ft char * diff --git a/string/FreeBSD/strpbrk.c b/string/FreeBSD/strpbrk.c index fb0e1d4..b4a0354 100644 --- a/string/FreeBSD/strpbrk.c +++ b/string/FreeBSD/strpbrk.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strpbrk.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strpbrk.c,v 1.4 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strpbrk.c,v 1.6 2009/02/03 17:58:20 danger Exp $"); #include @@ -43,14 +39,13 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strpbrk.c,v 1.4 2002/03/21 18:44:54 obri * Find the first occurrence in s1 of a character in s2 (excluding NUL). */ char * -strpbrk(s1, s2) - const char *s1, *s2; +strpbrk(const char *s1, const char *s2) { const char *scanp; int c, sc; while ((c = *s1++) != 0) { - for (scanp = s2; (sc = *scanp++) != 0;) + for (scanp = s2; (sc = *scanp++) != '\0';) if (sc == c) return ((char *)(s1 - 1)); } diff --git a/string/FreeBSD/strsep.3 b/string/FreeBSD/strsep.3 index ca23520..ae0259a 100644 --- a/string/FreeBSD/strsep.3 +++ b/string/FreeBSD/strsep.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,9 +29,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)strsep.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/strsep.3,v 1.14 2004/07/02 23:52:13 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strsep.3,v 1.16 2008/12/05 15:50:59 pjd Exp $ .\" -.Dd June 9, 1993 +.Dd December 5, 2008 .Dt STRSEP 3 .Os .Sh NAME @@ -85,6 +81,21 @@ returns .Sh EXAMPLES The following uses .Fn strsep +to parse a string, and prints each token in separate line: +.Bd -literal -offset indent +char *token, *string, *tofree; + +tofree = string = strdup("abc,def,ghi"); +assert(string != NULL); + +while ((token = strsep(&string, ",")) != NULL) + printf("%s\en", token); + +free(tofree); +.Ed +.Pp +The following uses +.Fn strsep to parse a string, containing tokens delimited by white space, into an argument vector: .Bd -literal -offset indent diff --git a/string/FreeBSD/strsep.c b/string/FreeBSD/strsep.c index d0bccce..34b7d29 100644 --- a/string/FreeBSD/strsep.c +++ b/string/FreeBSD/strsep.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strsep.c,v 1.5 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strsep.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include #include @@ -52,9 +48,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strsep.c,v 1.5 2002/03/21 18:44:54 obrie * If *stringp is NULL, strsep returns NULL. */ char * -strsep(stringp, delim) - char **stringp; - const char *delim; +strsep(char **stringp, const char *delim) { char *s; const char *spanp; diff --git a/string/FreeBSD/strsignal.c b/string/FreeBSD/strsignal.c index 0cbb4cd..b5453a1 100644 --- a/string/FreeBSD/strsignal.c +++ b/string/FreeBSD/strsignal.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,40 +31,122 @@ static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strsignal.c,v 1.4 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strsignal.c,v 1.9 2010/01/24 10:35:26 ume Exp $"); -#include +#include "namespace.h" +#if defined(NLS) +#include +#endif +#include +#include +#include #include #include +#include "reentrant.h" +#include "un-namespace.h" +#define UPREFIX "Unknown signal" + +static char sig_ebuf[NL_TEXTMAX]; +static char sig_ebuf_err[NL_TEXTMAX]; +static once_t sig_init_once = ONCE_INITIALIZER; +static thread_key_t sig_key; +static int sig_keycreated = 0; + +static void +sig_keycreate(void) +{ + sig_keycreated = (thr_keycreate(&sig_key, free) == 0); +} + +static char * +sig_tlsalloc(void) +{ + char *ebuf = NULL; + + if (thr_main() != 0) + ebuf = sig_ebuf; + else { + if (thr_once(&sig_init_once, sig_keycreate) != 0 || + !sig_keycreated) + goto thr_err; + if ((ebuf = thr_getspecific(sig_key)) == NULL) { + if ((ebuf = malloc(sizeof(sig_ebuf))) == NULL) + goto thr_err; + if (thr_setspecific(sig_key, ebuf) != 0) { + free(ebuf); + ebuf = NULL; + goto thr_err; + } + } + } +thr_err: + if (ebuf == NULL) + ebuf = sig_ebuf_err; + return (ebuf); +} + +/* XXX: negative 'num' ? (REGR) */ char * -strsignal(num) - int num; +strsignal(int num) { -#define UPREFIX "Unknown signal: " - static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ - unsigned int signum; - char *p, *t; - char tmp[40]; + char *ebuf; + char tmp[20]; + size_t n; + int signum; + char *t, *p; - signum = num; /* convert to unsigned */ - if (signum < sys_nsig) - return ((char *)sys_siglist[signum]); +#if defined(NLS) + int saved_errno = errno; + nl_catd catd; + catd = catopen("libc", NL_CAT_LOCALE); +#endif - /* Do this by hand, so we don't link to stdio(3). */ - t = tmp; + ebuf = sig_tlsalloc(); + + if (num > 0 && num < sys_nsig) { + n = strlcpy(ebuf, +#if defined(NLS) + catgets(catd, 2, num, sys_siglist[num]), +#else + sys_siglist[num], +#endif + sizeof(sig_ebuf)); + } else { + n = strlcpy(ebuf, +#if defined(NLS) + catgets(catd, 2, 0xffff, UPREFIX), +#else + UPREFIX, +#endif + sizeof(sig_ebuf)); + } + + signum = num; if (num < 0) signum = -signum; + + t = tmp; do { *t++ = "0123456789"[signum % 10]; } while (signum /= 10); if (num < 0) *t++ = '-'; - for (p = ebuf + sizeof(UPREFIX) - 1;;) { + + p = (ebuf + n); + *p++ = ':'; + *p++ = ' '; + + for (;;) { *p++ = *--t; if (t <= tmp) break; } *p = '\0'; + +#if defined(NLS) + catclose(catd); + errno = saved_errno; +#endif return (ebuf); } diff --git a/string/FreeBSD/strsignal.c.patch b/string/FreeBSD/strsignal.c.patch index 378e74d..4df57ad 100644 --- a/string/FreeBSD/strsignal.c.patch +++ b/string/FreeBSD/strsignal.c.patch @@ -1,11 +1,77 @@ ---- strsignal.c.orig Thu Mar 21 10:44:54 2002 -+++ strsignal.c Thu May 8 00:44:31 2003 -@@ -52,7 +52,7 @@ - char tmp[40]; +--- strsignal.c.orig 2010-01-24 02:35:26.000000000 -0800 ++++ strsignal.c 2010-05-06 12:29:53.000000000 -0700 +@@ -47,8 +47,6 @@ __FBSDID("$FreeBSD: src/lib/libc/string/ - signum = num; /* convert to unsigned */ -- if (signum < sys_nsig) -+ if (signum < NSIG) - return ((char *)sys_siglist[signum]); + #define UPREFIX "Unknown signal" - /* Do this by hand, so we don't link to stdio(3). */ +-static char sig_ebuf[NL_TEXTMAX]; +-static char sig_ebuf_err[NL_TEXTMAX]; + static once_t sig_init_once = ONCE_INITIALIZER; + static thread_key_t sig_key; + static int sig_keycreated = 0; +@@ -64,25 +62,19 @@ sig_tlsalloc(void) + { + char *ebuf = NULL; + +- if (thr_main() != 0) +- ebuf = sig_ebuf; +- else { +- if (thr_once(&sig_init_once, sig_keycreate) != 0 || +- !sig_keycreated) ++ if (thr_once(&sig_init_once, sig_keycreate) != 0 || ++ !sig_keycreated) ++ goto thr_err; ++ if ((ebuf = thr_getspecific(sig_key)) == NULL) { ++ if ((ebuf = malloc(NL_TEXTMAX * sizeof(char))) == NULL) ++ goto thr_err; ++ if (thr_setspecific(sig_key, ebuf) != 0) { ++ free(ebuf); ++ ebuf = NULL; + goto thr_err; +- if ((ebuf = thr_getspecific(sig_key)) == NULL) { +- if ((ebuf = malloc(sizeof(sig_ebuf))) == NULL) +- goto thr_err; +- if (thr_setspecific(sig_key, ebuf) != 0) { +- free(ebuf); +- ebuf = NULL; +- goto thr_err; +- } + } + } + thr_err: +- if (ebuf == NULL) +- ebuf = sig_ebuf_err; + return (ebuf); + } + +@@ -103,15 +95,19 @@ strsignal(int num) + #endif + + ebuf = sig_tlsalloc(); ++ if(ebuf == NULL) { ++ errno = ENOMEM; ++ return NULL; ++ } + +- if (num > 0 && num < sys_nsig) { ++ if (num > 0 && num < NSIG) { + n = strlcpy(ebuf, + #if defined(NLS) + catgets(catd, 2, num, sys_siglist[num]), + #else + sys_siglist[num], + #endif +- sizeof(sig_ebuf)); ++ NL_TEXTMAX * sizeof(char)); + } else { + n = strlcpy(ebuf, + #if defined(NLS) +@@ -119,7 +115,7 @@ strsignal(int num) + #else + UPREFIX, + #endif +- sizeof(sig_ebuf)); ++ NL_TEXTMAX * sizeof(char)); + } + + signum = num; diff --git a/string/FreeBSD/strspn.3 b/string/FreeBSD/strspn.3 index b55b12c..a976bf9 100644 --- a/string/FreeBSD/strspn.3 +++ b/string/FreeBSD/strspn.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strspn.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strspn.3,v 1.8 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strspn.3,v 1.11 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt STRSPN 3 @@ -56,8 +52,15 @@ spans the initial part of the null-terminated string .Fa s as long as the characters from .Fa s -occur in string +occur in the null-terminated string .Fa charset . +In other words, it computes the string array index in +.Fa s +of the first character of +.Fa s +which is not in +.Fa charset , +else the index of the first null character. .Sh RETURN VALUES The .Fn strspn @@ -71,7 +74,8 @@ returns the number of characters spanned. .Xr strrchr 3 , .Xr strsep 3 , .Xr strstr 3 , -.Xr strtok 3 +.Xr strtok 3 , +.Xr wcsspn 3 .Sh STANDARDS The .Fn strspn diff --git a/string/FreeBSD/strspn.3.patch b/string/FreeBSD/strspn.3.patch index 3db7258..a161f12 100644 --- a/string/FreeBSD/strspn.3.patch +++ b/string/FreeBSD/strspn.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strspn.3 2003-05-20 15:23:55.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/strspn.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -47,17 +47,20 @@ +--- strspn.3.bsdnew 2009-11-30 13:52:24.000000000 -0800 ++++ strspn.3 2009-11-30 14:55:45.000000000 -0800 +@@ -43,23 +43,26 @@ .Sh SYNOPSIS .In string.h .Ft size_t @@ -19,9 +19,18 @@ as long as the characters from -.Fa s +.Fa s1 - occur in string + occur in the null-terminated string -.Fa charset . +.Fa s2 . + In other words, it computes the string array index in +-.Fa s ++.Fa s1 + of the first character of +-.Fa s ++.Fa s1 + which is not in +-.Fa charset , ++.Fa s2 , + else the index of the first null character. .Sh RETURN VALUES The - .Fn strspn diff --git a/string/FreeBSD/strstr.3 b/string/FreeBSD/strstr.3 index 83d7bed..80b383e 100644 --- a/string/FreeBSD/strstr.3 +++ b/string/FreeBSD/strstr.3 @@ -14,10 +14,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strstr.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strstr.3,v 1.12 2001/11/20 14:11:07 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strstr.3,v 1.15 2009/04/07 13:42:53 trasz Exp $ .\" .Dd October 11, 2001 .Dt STRSTR 3 @@ -132,13 +128,15 @@ ptr = strnstr(largestring, smallstring, 4); .Ed .Sh SEE ALSO .Xr memchr 3 , +.Xr memmem 3 , .Xr strchr 3 , .Xr strcspn 3 , .Xr strpbrk 3 , .Xr strrchr 3 , .Xr strsep 3 , .Xr strspn 3 , -.Xr strtok 3 +.Xr strtok 3 , +.Xr wcsstr 3 .Sh STANDARDS The .Fn strstr diff --git a/string/FreeBSD/strstr.3.patch b/string/FreeBSD/strstr.3.patch index 2b7900a..ff2b12f 100644 --- a/string/FreeBSD/strstr.3.patch +++ b/string/FreeBSD/strstr.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strstr.3 2003-05-20 15:23:55.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/strstr.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -41,26 +41,47 @@ +--- strstr.3.bsdnew 2009-11-30 13:52:24.000000000 -0800 ++++ strstr.3 2009-11-30 14:58:48.000000000 -0800 +@@ -37,26 +37,47 @@ .Dt STRSTR 3 .Os .Sh NAME @@ -54,7 +54,7 @@ .Pp The .Fn strcasestr -@@ -72,11 +93,11 @@ +@@ -68,11 +89,11 @@ The .Fn strnstr function locates the first occurrence of the null-terminated string @@ -69,7 +69,7 @@ characters are searched. Characters that appear after a .Ql \e0 -@@ -86,20 +107,28 @@ +@@ -82,20 +103,28 @@ Since the function is a .Fx specific API, it should only be used when portability is not a concern. @@ -103,12 +103,20 @@ is returned. .Sh EXAMPLES The following sets the pointer -@@ -138,7 +167,8 @@ - .Xr strrchr 3 , +@@ -128,7 +157,6 @@ ptr = strnstr(largestring, smallstring, + .Ed + .Sh SEE ALSO + .Xr memchr 3 , +-.Xr memmem 3 , + .Xr strchr 3 , + .Xr strcspn 3 , + .Xr strpbrk 3 , +@@ -136,7 +164,8 @@ ptr = strnstr(largestring, smallstring, .Xr strsep 3 , .Xr strspn 3 , --.Xr strtok 3 -+.Xr strtok 3 , + .Xr strtok 3 , +-.Xr wcsstr 3 ++.Xr wcsstr 3 , +.Xr xlocale 3 .Sh STANDARDS The diff --git a/string/FreeBSD/strstr.c b/string/FreeBSD/strstr.c index f51d170..030db2b 100644 --- a/string/FreeBSD/strstr.c +++ b/string/FreeBSD/strstr.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)strstr.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strstr.c,v 1.4 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strstr.c,v 1.6 2009/02/03 17:58:20 danger Exp $"); #include @@ -46,17 +42,16 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strstr.c,v 1.4 2002/03/21 18:44:54 obrie * Find the first occurrence of find in s. */ char * -strstr(s, find) - const char *s, *find; +strstr(const char *s, const char *find) { char c, sc; size_t len; - if ((c = *find++) != 0) { + if ((c = *find++) != '\0') { len = strlen(find); do { do { - if ((sc = *s++) == 0) + if ((sc = *s++) == '\0') return (NULL); } while (sc != c); } while (strncmp(s, find, len) != 0); diff --git a/string/FreeBSD/strtok.3 b/string/FreeBSD/strtok.3 index b1d41b9..fff792e 100644 --- a/string/FreeBSD/strtok.3 +++ b/string/FreeBSD/strtok.3 @@ -22,12 +22,6 @@ .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" -.\" 3. All advertising materials mentioning features or use of this -.\" software must display the following acknowledgement: -.\" -.\" This product includes software developed by Softweyr LLC, the -.\" University of California, Berkeley, and its contributors. -.\" .\" 4. Neither the name of Softweyr LLC, the University nor the names .\" of its contributors may be used to endorse or promote products .\" derived from this software without specific prior written @@ -48,7 +42,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtok.3 8.2 (Berkeley) 2/3/94 -.\" $FreeBSD: src/lib/libc/string/strtok.3,v 1.24 2002/12/18 12:45:11 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strtok.3,v 1.26 2007/12/12 18:33:06 wes Exp $ .\" .Dd November 27, 1998 .Dt STRTOK 3 @@ -155,6 +149,14 @@ The function conforms to .St -isoC . +.Sh AUTHORS +.An Wes Peters , +Softweyr LLC: +.Aq wes@softweyr.com +.Pp +Based on the +.Fx 3.0 +implementation. .Sh BUGS The System V .Fn strtok , @@ -168,11 +170,3 @@ value. Since this implementation always alters the next starting point, such a sequence of calls would always return .Dv NULL . -.Sh AUTHORS -.An Wes Peters , -Softweyr LLC: -.Aq wes@softweyr.com -.Pp -Based on the -.Fx 3.0 -implementation. diff --git a/string/FreeBSD/strtok.3.patch b/string/FreeBSD/strtok.3.patch index c8ae652..cf057c6 100644 --- a/string/FreeBSD/strtok.3.patch +++ b/string/FreeBSD/strtok.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strtok.3 2003-05-20 15:23:55.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/strtok.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -61,9 +61,16 @@ +--- strtok.3.bsdnew 2009-11-18 18:24:37.000000000 -0800 ++++ strtok.3 2009-11-18 18:24:37.000000000 -0800 +@@ -55,9 +55,16 @@ .Sh SYNOPSIS .In string.h .Ft char * diff --git a/string/FreeBSD/strtok.c b/string/FreeBSD/strtok.c index 6aec194..6fcd78e 100644 --- a/string/FreeBSD/strtok.c +++ b/string/FreeBSD/strtok.c @@ -15,10 +15,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notices, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Softweyr LLC, the - * University of California, Berkeley, and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ static char sccsid[] = "@(#)strtok.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strtok.c,v 1.9 2002/09/07 02:53:19 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strtok.c,v 1.10 2007/12/12 18:33:06 wes Exp $"); #include #ifdef DEBUG_STRTOK diff --git a/string/FreeBSD/strxfrm.3 b/string/FreeBSD/strxfrm.3 index 14b6bbc..c32ea5c 100644 --- a/string/FreeBSD/strxfrm.3 +++ b/string/FreeBSD/strxfrm.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strxfrm.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strxfrm.3,v 1.17 2002/10/15 10:11:53 tjr Exp $ +.\" $FreeBSD: src/lib/libc/string/strxfrm.3,v 1.18 2007/01/09 00:28:12 imp Exp $ .\" .Dd June 4, 1993 .Dt STRXFRM 3 diff --git a/string/FreeBSD/strxfrm.3.patch b/string/FreeBSD/strxfrm.3.patch index 4675a6a..5dce9b9 100644 --- a/string/FreeBSD/strxfrm.3.patch +++ b/string/FreeBSD/strxfrm.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/strxfrm.3 2003-05-20 15:23:55.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/strxfrm.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -40,34 +40,48 @@ +--- strxfrm.3.bsdnew 2009-11-18 18:24:38.000000000 -0800 ++++ strxfrm.3 2009-11-18 18:24:38.000000000 -0800 +@@ -36,34 +36,48 @@ .Dt STRXFRM 3 .Os .Sh NAME @@ -55,7 +55,7 @@ is permitted to be a NULL pointer. .Pp Comparing two strings using -@@ -77,6 +91,14 @@ +@@ -73,6 +87,14 @@ after is equal to comparing two original strings with .Fn strcoll . @@ -70,7 +70,7 @@ .Sh RETURN VALUES Upon successful completion, .Fn strxfrm -@@ -85,13 +107,14 @@ +@@ -81,13 +103,14 @@ the terminating null character. If this value is .Fa n or more, the contents of diff --git a/string/FreeBSD/strxfrm.c b/string/FreeBSD/strxfrm.c index 3ab7b72..9ef2e87 100644 --- a/string/FreeBSD/strxfrm.c +++ b/string/FreeBSD/strxfrm.c @@ -26,7 +26,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strxfrm.c,v 1.15 2002/09/06 11:24:06 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strxfrm.c,v 1.17 2008/10/19 09:10:44 delphij Exp $"); #include #include @@ -45,18 +45,8 @@ strxfrm(char * __restrict dest, const char * __restrict src, size_t len) return 0; } - if (__collate_load_error) { - slen = strlen(src); - if (len > 0) { - if (slen < len) - strcpy(dest, src); - else { - strncpy(dest, src, len - 1); - dest[len - 1] = '\0'; - } - } - return slen; - } + if (__collate_load_error) + return strlcpy(dest, src, len); slen = 0; prim = sec = 0; diff --git a/string/FreeBSD/strxfrm.c.patch b/string/FreeBSD/strxfrm.c.patch index 221d31f..5178604 100644 --- a/string/FreeBSD/strxfrm.c.patch +++ b/string/FreeBSD/strxfrm.c.patch @@ -1,8 +1,8 @@ ---- strxfrm.c.orig 2003-05-20 15:23:55.000000000 -0700 -+++ strxfrm.c 2005-04-02 17:59:53.000000000 -0800 -@@ -28,24 +28,59 @@ +--- strxfrm.c.bsdnew 2009-11-18 18:24:38.000000000 -0800 ++++ strxfrm.c 2009-11-18 18:38:07.000000000 -0800 +@@ -28,46 +28,118 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/string/strxfrm.c,v 1.15 2002/09/06 11:24:06 tjr Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/string/strxfrm.c,v 1.17 2008/10/19 09:10:44 delphij Exp $"); +#include "xlocale_private.h" + @@ -59,15 +59,10 @@ return 0; } -- if (__collate_load_error) { +- if (__collate_load_error) + NORMALIZE_LOCALE(loc); -+ if (loc->__collate_load_error || (wcs = __collate_mbstowcs(src, loc)) == NULL) { - slen = strlen(src); - if (len > 0) { - if (slen < len) -@@ -58,26 +93,63 @@ - return slen; - } ++ if (loc->__collate_load_error || (wcs = __collate_mbstowcs(src, loc)) == NULL) + return strlcpy(dest, src, len); - slen = 0; - prim = sec = 0; diff --git a/string/FreeBSD/swab.3 b/string/FreeBSD/swab.3 index c449add..d42143d 100644 --- a/string/FreeBSD/swab.3 +++ b/string/FreeBSD/swab.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)swab.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/swab.3,v 1.7 2002/08/30 21:18:39 robert Exp $ +.\" $FreeBSD: src/lib/libc/string/swab.3,v 1.10 2007/01/09 00:28:12 imp Exp $ .\" -.Dd June 4, 1993 +.Dd December 10, 2004 .Dt SWAB 3 .Os .Sh NAME @@ -41,9 +37,9 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In string.h +.In unistd.h .Ft void -.Fn swab "const void * restrict src" "void * restrict dst" "size_t len" +.Fn swab "const void * restrict src" "void * restrict dst" "ssize_t len" .Sh DESCRIPTION The function .Fn swab diff --git a/string/FreeBSD/swab.3.patch b/string/FreeBSD/swab.3.patch index 8c915b3..f85ec9c 100644 --- a/string/FreeBSD/swab.3.patch +++ b/string/FreeBSD/swab.3.patch @@ -1,13 +1,19 @@ ---- swab.3 2003-05-20 15:23:55.000000000 -0700 -+++ swab.3.edit 2006-07-12 11:27:22.000000000 -0700 -@@ -41,26 +41,48 @@ - .Sh LIBRARY - .Lb libc +--- swab.3.orig 2010-02-24 20:50:11.000000000 -0800 ++++ swab.3 2010-02-24 21:17:49.000000000 -0800 +@@ -28,7 +28,7 @@ + .\" @(#)swab.3 8.1 (Berkeley) 6/4/93 + .\" $FreeBSD: src/lib/libc/string/swab.3,v 1.10 2007/01/09 00:28:12 imp Exp $ + .\" +-.Dd December 10, 2004 ++.Dd February 24, 2010 + .Dt SWAB 3 + .Os + .Sh NAME +@@ -39,24 +39,41 @@ .Sh SYNOPSIS --.In string.h -+.In unistd.h + .In unistd.h .Ft void --.Fn swab "const void * restrict src" "void * restrict dst" "size_t len" +-.Fn swab "const void * restrict src" "void * restrict dst" "ssize_t len" +.Fo swab +.Fa "const void *restrict src" +.Fa "void *restrict dest" @@ -28,25 +34,21 @@ .Pp The argument -.Fa len +-must be an even number. +.Fa nbytes - must be an even number. -+.Sh LEGACY SYNOPSIS -+.Fd #include -+.Pp -+.Ft void -+.br -+.Fo swab -+.Fa "const void *restrict src" -+.Fa "void *restrict dest" -+.Fa "size_t nbytes" -+.Fc ; -+.Pp -+The include file -+.In string.h -+is necessary for this function. -+The type of ++should be an even number. If ++.Fa nbytes ++is odd, ++.Fn swab ++copies and exchanges ++.Fa nbytes ++-1 bytes and the disposition of the last byte is unspecified. ++If copying takes place between objects that overlap, ++the behavior is undefined. If +.Fa nbytes -+has changed. ++is negative, ++.Fn swab ++does nothing. .Sh SEE ALSO .Xr bzero 3 , -.Xr memset 3 diff --git a/string/FreeBSD/swab.c b/string/FreeBSD/swab.c index de57703..fae6e56 100644 --- a/string/FreeBSD/swab.c +++ b/string/FreeBSD/swab.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,12 +34,12 @@ static char sccsid[] = "@(#)swab.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/swab.c,v 1.5 2002/08/30 20:33:05 robert Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/swab.c,v 1.7 2007/01/09 00:28:12 imp Exp $"); -#include +#include void -swab(const void * __restrict from, void * __restrict to, size_t len) +swab(const void * __restrict from, void * __restrict to, ssize_t len) { unsigned long temp; int n; diff --git a/string/FreeBSD/swab.c.patch b/string/FreeBSD/swab.c.patch index f765e19..5565deb 100644 --- a/string/FreeBSD/swab.c.patch +++ b/string/FreeBSD/swab.c.patch @@ -1,13 +1,6 @@ ---- swab.c.orig 2004-08-03 14:33:13.000000000 -0700 -+++ swab.c 2004-08-03 15:05:03.000000000 -0700 -@@ -43,12 +43,14 @@ - #include - - void --swab(const void * __restrict from, void * __restrict to, size_t len) -+swab(const void * __restrict from, void * __restrict to, ssize_t len) - { - unsigned long temp; +--- swab.c.bsdnew 2009-11-18 18:24:38.000000000 -0800 ++++ swab.c 2009-11-18 18:40:17.000000000 -0800 +@@ -45,6 +45,8 @@ swab(const void * __restrict from, void int n; char *fp, *tp; diff --git a/string/FreeBSD/wcpcpy.c b/string/FreeBSD/wcpcpy.c new file mode 100644 index 0000000..aff2bad --- /dev/null +++ b/string/FreeBSD/wcpcpy.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 1999 + * David E. O'Brien + * Copyright (c) 1988, 1993 + * The Regents of the University of California. 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strcpy.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/string/wcpcpy.c,v 1.1 2009/03/04 06:01:27 das Exp $"); + +#include + +wchar_t * +wcpcpy(wchar_t * __restrict to, const wchar_t * __restrict from) +{ + + for (; (*to = *from); ++from, ++to); + return(to); +} diff --git a/string/FreeBSD/wcpncpy.c b/string/FreeBSD/wcpncpy.c new file mode 100644 index 0000000..625b531 --- /dev/null +++ b/string/FreeBSD/wcpncpy.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/string/wcpncpy.c,v 1.1 2009/03/04 06:01:27 das Exp $"); + +#include + +wchar_t * +wcpncpy(wchar_t * __restrict dst, const wchar_t * __restrict src, size_t n) +{ + + for (; n--; dst++, src++) { + if (!(*dst = *src)) { + wchar_t *ret = dst; + while (n--) + *++dst = L'\0'; + return (ret); + } + } + return (dst); +} diff --git a/string/FreeBSD/wcscasecmp.c b/string/FreeBSD/wcscasecmp.c new file mode 100644 index 0000000..8618c50 --- /dev/null +++ b/string/FreeBSD/wcscasecmp.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/string/wcscasecmp.c,v 1.1 2009/02/28 06:00:58 das Exp $"); + +#include +#include + +int +wcscasecmp(const wchar_t *s1, const wchar_t *s2) +{ + wchar_t c1, c2; + + for (; *s1; s1++, s2++) { + c1 = towlower(*s1); + c2 = towlower(*s2); + if (c1 != c2) + return ((int)c1 - c2); + } + return (-*s2); +} diff --git a/string/FreeBSD/wcscasecmp.c.patch b/string/FreeBSD/wcscasecmp.c.patch new file mode 100644 index 0000000..aa62f56 --- /dev/null +++ b/string/FreeBSD/wcscasecmp.c.patch @@ -0,0 +1,33 @@ +--- wcscasecmp.c.orig 2009-12-16 12:51:30.000000000 -0800 ++++ wcscasecmp.c 2009-12-16 12:59:33.000000000 -0800 +@@ -27,19 +27,27 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/string/wcscasecmp.c,v 1.1 2009/02/28 06:00:58 das Exp $"); + ++#include "xlocale_private.h" ++ + #include + #include + + int +-wcscasecmp(const wchar_t *s1, const wchar_t *s2) ++wcscasecmp_l(const wchar_t *s1, const wchar_t *s2, locale_t loc) + { + wchar_t c1, c2; + + for (; *s1; s1++, s2++) { +- c1 = towlower(*s1); +- c2 = towlower(*s2); ++ c1 = towlower_l(*s1, loc); ++ c2 = towlower_l(*s2, loc); + if (c1 != c2) + return ((int)c1 - c2); + } + return (-*s2); + } ++ ++int ++wcscasecmp(const wchar_t *s1, const wchar_t *s2) { ++ return wcscasecmp_l(s1, s2, __current_locale()); ++} ++ diff --git a/string/FreeBSD/wcscat.c b/string/FreeBSD/wcscat.c index cf7812f..00cd361 100644 --- a/string/FreeBSD/wcscat.c +++ b/string/FreeBSD/wcscat.c @@ -32,14 +32,12 @@ __RCSID("$NetBSD: wcscat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wcscat.c,v 1.8 2002/09/26 09:28:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcscat.c,v 1.9 2009/02/03 17:58:20 danger Exp $"); #include wchar_t * -wcscat(s1, s2) - wchar_t * __restrict s1; - const wchar_t * __restrict s2; +wcscat(wchar_t * __restrict s1, const wchar_t * __restrict s2) { wchar_t *cp; diff --git a/string/FreeBSD/wcscmp.c b/string/FreeBSD/wcscmp.c index 20152b2..8d51347 100644 --- a/string/FreeBSD/wcscmp.c +++ b/string/FreeBSD/wcscmp.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -41,7 +37,7 @@ static char sccsid[] = "@(#)strcmp.c 8.1 (Berkeley) 6/4/93"; __RCSID("$NetBSD: wcscmp.c,v 1.3 2001/01/05 12:13:12 itojun Exp $"); #endif #endif /* LIBC_SCCS and not lint */ -__FBSDID("$FreeBSD: src/lib/libc/string/wcscmp.c,v 1.7 2002/10/23 11:08:40 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcscmp.c,v 1.9 2009/02/03 17:58:20 danger Exp $"); #include @@ -49,12 +45,11 @@ __FBSDID("$FreeBSD: src/lib/libc/string/wcscmp.c,v 1.7 2002/10/23 11:08:40 tjr E * Compare strings. */ int -wcscmp(s1, s2) - const wchar_t *s1, *s2; +wcscmp(const wchar_t *s1, const wchar_t *s2) { while (*s1 == *s2++) - if (*s1++ == 0) + if (*s1++ == '\0') return (0); /* XXX assumes wchar_t = int */ return (*(const unsigned int *)s1 - *(const unsigned int *)--s2); diff --git a/string/FreeBSD/wcscoll.3 b/string/FreeBSD/wcscoll.3 index 18a9ef7..819ae87 100644 --- a/string/FreeBSD/wcscoll.3 +++ b/string/FreeBSD/wcscoll.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)strcoll.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/string/strcoll.3,v 1.11 2001/10/01 16:09:00 ru Exp -.\" $FreeBSD: src/lib/libc/string/wcscoll.3,v 1.2 2002/12/09 14:04:05 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/wcscoll.3,v 1.3 2007/01/09 00:28:12 imp Exp $ .\" .Dd October 4, 2002 .Dt WCSCOLL 3 diff --git a/string/FreeBSD/wcscoll.3.patch b/string/FreeBSD/wcscoll.3.patch index 1fca854..50a59cc 100644 --- a/string/FreeBSD/wcscoll.3.patch +++ b/string/FreeBSD/wcscoll.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/wcscoll.3 2003-05-20 15:23:55.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/wcscoll.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -41,37 +41,57 @@ +--- wcscoll.3.bsdnew 2009-11-18 18:24:39.000000000 -0800 ++++ wcscoll.3 2009-11-18 18:24:39.000000000 -0800 +@@ -37,37 +37,57 @@ .Dt WCSCOLL 3 .Os .Sh NAME @@ -65,7 +65,7 @@ .Pp No return value is reserved to indicate errors; callers should set -@@ -95,7 +115,8 @@ +@@ -91,7 +111,8 @@ Cannot allocate enough memory for tempor .Xr setlocale 3 , .Xr strcoll 3 , .Xr wcscmp 3 , diff --git a/string/FreeBSD/wcscpy.c b/string/FreeBSD/wcscpy.c index b4c236a..d2f929a 100644 --- a/string/FreeBSD/wcscpy.c +++ b/string/FreeBSD/wcscpy.c @@ -32,14 +32,12 @@ __RCSID("$NetBSD: wcscpy.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wcscpy.c,v 1.8 2002/09/26 09:23:07 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcscpy.c,v 1.9 2009/02/03 17:58:20 danger Exp $"); #include wchar_t * -wcscpy(s1, s2) - wchar_t * __restrict s1; - const wchar_t * __restrict s2; +wcscpy(wchar_t * __restrict s1, const wchar_t * __restrict s2) { wchar_t *cp; diff --git a/string/FreeBSD/wcscspn.c b/string/FreeBSD/wcscspn.c index c16f270..77dfa10 100644 --- a/string/FreeBSD/wcscspn.c +++ b/string/FreeBSD/wcscspn.c @@ -32,14 +32,12 @@ __RCSID("$NetBSD: wcscspn.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wcscspn.c,v 1.6 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcscspn.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include size_t -wcscspn(s, set) - const wchar_t *s; - const wchar_t *set; +wcscspn(const wchar_t *s, const wchar_t *set) { const wchar_t *p; const wchar_t *q; diff --git a/string/FreeBSD/wcsdup.c b/string/FreeBSD/wcsdup.c new file mode 100644 index 0000000..4379da1 --- /dev/null +++ b/string/FreeBSD/wcsdup.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2005 Tim J. Robbins. + * 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 +__FBSDID("$FreeBSD: src/lib/libc/string/wcsdup.c,v 1.1 2005/08/13 05:54:33 tjr Exp $"); + +#include +#include + +wchar_t * +wcsdup(const wchar_t *s) +{ + wchar_t *copy; + size_t len; + + len = wcslen(s) + 1; + if ((copy = malloc(len * sizeof(wchar_t))) == NULL) + return (NULL); + return (wmemcpy(copy, s, len)); +} diff --git a/string/FreeBSD/wcslcat.c b/string/FreeBSD/wcslcat.c index f3b9a63..7149a53 100644 --- a/string/FreeBSD/wcslcat.c +++ b/string/FreeBSD/wcslcat.c @@ -33,7 +33,7 @@ __RCSID("$NetBSD: wcslcat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wcslcat.c,v 1.6 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcslcat.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include #include @@ -46,10 +46,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/wcslcat.c,v 1.6 2002/09/21 00:29:23 tjr * truncation occurred. */ size_t -wcslcat(dst, src, siz) - wchar_t *dst; - const wchar_t *src; - size_t siz; +wcslcat(wchar_t *dst, const wchar_t *src, size_t siz) { wchar_t *d = dst; const wchar_t *s = src; diff --git a/string/FreeBSD/wcslcpy.c b/string/FreeBSD/wcslcpy.c index 273c8fd..d0ee113 100644 --- a/string/FreeBSD/wcslcpy.c +++ b/string/FreeBSD/wcslcpy.c @@ -33,7 +33,7 @@ __RCSID("$NetBSD: wcslcpy.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wcslcpy.c,v 1.6 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcslcpy.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include #include @@ -44,10 +44,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/wcslcpy.c,v 1.6 2002/09/21 00:29:23 tjr * Returns wcslen(src); if retval >= siz, truncation occurred. */ size_t -wcslcpy(dst, src, siz) - wchar_t *dst; - const wchar_t *src; - size_t siz; +wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz) { wchar_t *d = dst; const wchar_t *s = src; diff --git a/string/FreeBSD/wcslen.c b/string/FreeBSD/wcslen.c index 5e462a1..cff35ad 100644 --- a/string/FreeBSD/wcslen.c +++ b/string/FreeBSD/wcslen.c @@ -32,13 +32,12 @@ __RCSID("$NetBSD: wcslen.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wcslen.c,v 1.6 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcslen.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include size_t -wcslen(s) - const wchar_t *s; +wcslen(const wchar_t *s) { const wchar_t *p; diff --git a/string/FreeBSD/wcsncasecmp.c b/string/FreeBSD/wcsncasecmp.c new file mode 100644 index 0000000..436a324 --- /dev/null +++ b/string/FreeBSD/wcsncasecmp.c @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/string/wcsncasecmp.c,v 1.1 2009/02/28 06:00:58 das Exp $"); + +#include +#include + +int +wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) +{ + wchar_t c1, c2; + + if (n == 0) + return (0); + for (; *s1; s1++, s2++) { + c1 = towlower(*s1); + c2 = towlower(*s2); + if (c1 != c2) + return ((int)c1 - c2); + if (--n == 0) + return (0); + } + return (-*s2); +} diff --git a/string/FreeBSD/wcsncasecmp.c.patch b/string/FreeBSD/wcsncasecmp.c.patch new file mode 100644 index 0000000..d1d04e6 --- /dev/null +++ b/string/FreeBSD/wcsncasecmp.c.patch @@ -0,0 +1,37 @@ +--- wcsncasecmp.c.orig 2009-12-16 12:51:30.000000000 -0800 ++++ wcsncasecmp.c 2009-12-16 13:02:55.000000000 -0800 +@@ -27,19 +27,21 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/string/wcsncasecmp.c,v 1.1 2009/02/28 06:00:58 das Exp $"); + ++#include "xlocale_private.h" ++ + #include + #include + + int +-wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) ++wcsncasecmp_l(const wchar_t *s1, const wchar_t *s2, size_t n, locale_t loc) + { + wchar_t c1, c2; + + if (n == 0) + return (0); + for (; *s1; s1++, s2++) { +- c1 = towlower(*s1); +- c2 = towlower(*s2); ++ c1 = towlower_l(*s1, loc); ++ c2 = towlower_l(*s2, loc); + if (c1 != c2) + return ((int)c1 - c2); + if (--n == 0) +@@ -47,3 +49,9 @@ wcsncasecmp(const wchar_t *s1, const wch + } + return (-*s2); + } ++ ++int ++wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) { ++ return wcsncasecmp_l(s1, s2, n, __current_locale()); ++} ++ diff --git a/string/FreeBSD/wcsncat.c b/string/FreeBSD/wcsncat.c index 5abb442..1a907da 100644 --- a/string/FreeBSD/wcsncat.c +++ b/string/FreeBSD/wcsncat.c @@ -32,15 +32,12 @@ __RCSID("$NetBSD: wcsncat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wcsncat.c,v 1.7 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcsncat.c,v 1.8 2009/02/03 17:58:20 danger Exp $"); #include wchar_t * -wcsncat(s1, s2, n) - wchar_t * __restrict s1; - const wchar_t * __restrict s2; - size_t n; +wcsncat(wchar_t * __restrict s1, const wchar_t * __restrict s2, size_t n) { wchar_t *p; wchar_t *q; diff --git a/string/FreeBSD/wcsncmp.c b/string/FreeBSD/wcsncmp.c index 7043e06..2ef778c 100644 --- a/string/FreeBSD/wcsncmp.c +++ b/string/FreeBSD/wcsncmp.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,14 +34,12 @@ static char sccsid[] = "@(#)strncmp.c 8.1 (Berkeley) 6/4/93"; __RCSID("$NetBSD: wcsncmp.c,v 1.3 2001/01/05 12:13:13 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wcsncmp.c,v 1.7 2002/10/23 11:08:40 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcsncmp.c,v 1.9 2009/02/03 17:58:20 danger Exp $"); #include int -wcsncmp(s1, s2, n) - const wchar_t *s1, *s2; - size_t n; +wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n) { if (n == 0) diff --git a/string/FreeBSD/wcsncpy.c b/string/FreeBSD/wcsncpy.c index fb9cef0..8c64d59 100644 --- a/string/FreeBSD/wcsncpy.c +++ b/string/FreeBSD/wcsncpy.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ static char sccsid[] = "@(#)strncpy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #endif #include -__FBSDID("$FreeBSD: src/lib/libc/string/wcsncpy.c,v 1.9 2002/10/24 02:48:45 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcsncpy.c,v 1.10 2007/01/09 00:28:12 imp Exp $"); #include diff --git a/string/FreeBSD/wcsnlen.c b/string/FreeBSD/wcsnlen.c new file mode 100644 index 0000000..2cf513e --- /dev/null +++ b/string/FreeBSD/wcsnlen.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/string/wcsnlen.c,v 1.1 2009/02/28 06:00:58 das Exp $"); + +#include + +size_t +wcsnlen(const wchar_t *s, size_t maxlen) +{ + size_t len; + + for (len = 0; len < maxlen; len++, s++) { + if (!*s) + break; + } + return (len); +} diff --git a/string/FreeBSD/wcspbrk.c b/string/FreeBSD/wcspbrk.c index 5502440..ef12064 100644 --- a/string/FreeBSD/wcspbrk.c +++ b/string/FreeBSD/wcspbrk.c @@ -32,14 +32,12 @@ __RCSID("$NetBSD: wcspbrk.c,v 1.1 2000/12/23 23:14:37 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wcspbrk.c,v 1.6 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcspbrk.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include wchar_t * -wcspbrk(s, set) - const wchar_t *s; - const wchar_t *set; +wcspbrk(const wchar_t *s, const wchar_t *set) { const wchar_t *p; const wchar_t *q; diff --git a/string/FreeBSD/wcsspn.c b/string/FreeBSD/wcsspn.c index d4101c7..ff4dbfd 100644 --- a/string/FreeBSD/wcsspn.c +++ b/string/FreeBSD/wcsspn.c @@ -32,14 +32,12 @@ __RCSID("$NetBSD: wcsspn.c,v 1.1 2000/12/23 23:14:37 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wcsspn.c,v 1.7 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcsspn.c,v 1.8 2009/02/03 17:58:20 danger Exp $"); #include size_t -wcsspn(s, set) - const wchar_t *s; - const wchar_t *set; +wcsspn(const wchar_t *s, const wchar_t *set) { const wchar_t *p; const wchar_t *q; diff --git a/string/FreeBSD/wcsstr.c b/string/FreeBSD/wcsstr.c index 0533e59..93cb149 100644 --- a/string/FreeBSD/wcsstr.c +++ b/string/FreeBSD/wcsstr.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ static char sccsid[] = "@(#)strstr.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #endif #include -__FBSDID("$FreeBSD: src/lib/libc/string/wcsstr.c,v 1.8 2002/10/24 02:53:45 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcsstr.c,v 1.10 2009/02/03 17:58:20 danger Exp $"); #include @@ -53,7 +49,7 @@ wcsstr(const wchar_t * __restrict s, const wchar_t * __restrict find) wchar_t c, sc; size_t len; - if ((c = *find++) != 0) { + if ((c = *find++) != L'\0') { len = wcslen(find); do { do { diff --git a/string/FreeBSD/wcstok.c b/string/FreeBSD/wcstok.c index 5781adb..2258716 100644 --- a/string/FreeBSD/wcstok.c +++ b/string/FreeBSD/wcstok.c @@ -15,10 +15,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notices, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Softweyr LLC, the - * University of California, Berkeley, and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -37,7 +33,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/wcstok.c,v 1.2 2003/03/12 06:41:49 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcstok.c,v 1.3 2007/12/12 18:33:06 wes Exp $"); #include diff --git a/string/FreeBSD/wcswidth.c b/string/FreeBSD/wcswidth.c index 98a095d..5a38012 100644 --- a/string/FreeBSD/wcswidth.c +++ b/string/FreeBSD/wcswidth.c @@ -18,10 +18,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/wcswidth.c,v 1.6 2002/08/20 02:06:28 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcswidth.c,v 1.7 2007/01/09 00:28:12 imp Exp $"); #include diff --git a/string/FreeBSD/wcswidth.c.patch b/string/FreeBSD/wcswidth.c.patch index 58c0448..e674206 100644 --- a/string/FreeBSD/wcswidth.c.patch +++ b/string/FreeBSD/wcswidth.c.patch @@ -1,8 +1,8 @@ ---- wcswidth.c.orig 2003-05-20 15:23:56.000000000 -0700 -+++ wcswidth.c 2005-02-25 00:12:43.000000000 -0800 -@@ -42,20 +42,30 @@ +--- wcswidth.c.bsdnew 2009-11-18 18:24:40.000000000 -0800 ++++ wcswidth.c 2009-11-18 18:24:41.000000000 -0800 +@@ -38,20 +38,30 @@ #include - __FBSDID("$FreeBSD: src/lib/libc/string/wcswidth.c,v 1.6 2002/08/20 02:06:28 ache Exp $"); + __FBSDID("$FreeBSD: src/lib/libc/string/wcswidth.c,v 1.7 2007/01/09 00:28:12 imp Exp $"); +#include "xlocale_private.h" + diff --git a/string/FreeBSD/wcsxfrm.3 b/string/FreeBSD/wcsxfrm.3 index e85ebb0..16087fd 100644 --- a/string/FreeBSD/wcsxfrm.3 +++ b/string/FreeBSD/wcsxfrm.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)strxfrm.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/string/strxfrm.3,v 1.16 2002/09/06 11:24:06 tjr Exp -.\" $FreeBSD: src/lib/libc/string/wcsxfrm.3,v 1.2 2002/12/09 14:04:05 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/wcsxfrm.3,v 1.3 2007/01/09 00:28:12 imp Exp $ .\" .Dd October 4, 2002 .Dt WCSXFRM 3 diff --git a/string/FreeBSD/wcsxfrm.3.patch b/string/FreeBSD/wcsxfrm.3.patch index 781420c..f6bc4a1 100644 --- a/string/FreeBSD/wcsxfrm.3.patch +++ b/string/FreeBSD/wcsxfrm.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/wcsxfrm.3 2003-05-20 15:23:56.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/wcsxfrm.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -41,34 +41,47 @@ +--- wcsxfrm.3.bsdnew 2009-11-18 18:24:41.000000000 -0800 ++++ wcsxfrm.3 2009-11-18 18:24:41.000000000 -0800 +@@ -37,34 +37,47 @@ .Dt WCSXFRM 3 .Os .Sh NAME @@ -58,7 +58,7 @@ is permitted to be a .Dv NULL pointer. -@@ -80,6 +93,14 @@ +@@ -76,6 +89,14 @@ after is equivalent to comparing two original strings with .Fn wcscoll . @@ -73,7 +73,7 @@ .Sh RETURN VALUES Upon successful completion, .Fn wcsxfrm -@@ -88,13 +109,14 @@ +@@ -84,13 +105,14 @@ the terminating null character. If this value is .Fa n or more, the contents of @@ -90,7 +90,7 @@ .Sh STANDARDS The .Fn wcsxfrm -@@ -120,7 +142,7 @@ +@@ -116,7 +138,7 @@ always equivalent to comparison with .Fn wcscoll ; .Fn wcsxfrm only stores information about primary collation weights into diff --git a/string/FreeBSD/wmemchr.3 b/string/FreeBSD/wmemchr.3 index de091a6..41b0ac0 100644 --- a/string/FreeBSD/wmemchr.3 +++ b/string/FreeBSD/wmemchr.3 @@ -15,10 +15,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -37,9 +33,9 @@ .\" .\" from: @(#)strcpy.3 8.1 (Berkeley) 6/4/93 .\" -.\" $FreeBSD: src/lib/libc/string/wmemchr.3,v 1.6 2002/09/07 04:07:00 tjr Exp $ +.\" $FreeBSD: src/lib/libc/string/wmemchr.3,v 1.10 2009/03/04 06:01:27 das Exp $ .\" -.Dd December 22, 2000 +.Dd March 4, 2009 .Dt WMEMCHR 3 .Os .Sh NAME @@ -48,17 +44,23 @@ .Nm wmemcpy , .Nm wmemmove , .Nm wmemset , +.Nm wcpcpy , +.Nm wcpncpy , +.Nm wcscasecmp , .Nm wcscat , .Nm wcschr , .Nm wcscmp , .Nm wcscpy , .Nm wcscspn , +.Nm wcsdup , .Nm wcslcat , .Nm wcslcpy , .Nm wcslen , +.Nm wcsncasecmp , .Nm wcsncat , .Nm wcsncmp , .Nm wcsncpy , +.Nm wcsnlen , .Nm wcspbrk , .Nm wcsrchr , .Nm wcsspn , @@ -79,6 +81,12 @@ .Ft wchar_t * .Fn wmemset "wchar_t *s" "wchar_t c" "size_t n" .Ft wchar_t * +.Fn wcpcpy "wchar_t *s1" "wchar_t *s2" +.Ft wchar_t * +.Fn wcpncpy "wchar_t *s1" "wchar_t *s2" "size_t n" +.Ft int +.Fn wcscasecmp "const wchar_t *s1" "const wchar_t *s2" +.Ft wchar_t * .Fn wcscat "wchar_t * restrict s1" "const wchar_t * restrict s2" .Ft wchar_t * .Fn wcschr "const wchar_t *s" "wchar_t c" @@ -88,18 +96,24 @@ .Fn wcscpy "wchar_t * restrict s1" "const wchar_t * restrict s2" .Ft size_t .Fn wcscspn "const wchar_t *s1" "const wchar_t *s2" +.Ft wchar_t * +.Fn wcsdup "const wchar_t *s" .Ft size_t .Fn wcslcat "wchar_t *s1" "const wchar_t *s2" "size_t n" .Ft size_t .Fn wcslcpy "wchar_t *s1" "const wchar_t *s2" "size_t n" .Ft size_t .Fn wcslen "const wchar_t *s" +.Ft int +.Fn wcsncasecmp "const wchar_t *s1" "const wchar_t *s2" "size_t n" .Ft wchar_t * .Fn wcsncat "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" .Ft int .Fn wcsncmp "const wchar_t *s1" "const wchar_t * s2" "size_t n" .Ft wchar_t * .Fn wcsncpy "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" +.Ft size_t +.Fn wcsnlen "const wchar_t *s" "size_t maxlen" .Ft wchar_t * .Fn wcspbrk "const wchar_t *s1" "const wchar_t *s2" .Ft wchar_t * @@ -120,17 +134,22 @@ counterpart, such as .Xr memcpy 3 , .Xr memmove 3 , .Xr memset 3 , +.Xr stpcpy 3 , +.Xr stpncpy 3 , +.Xr strcasecmp 3 , .Xr strcat 3 , .Xr strchr 3 , .Xr strcmp 3 , .Xr strcpy 3 , .Xr strcspn 3 , +.Xr strdup 3 , .Xr strlcat 3 , .Xr strlcpy 3 , .Xr strlen 3 , .Xr strncat 3 , .Xr strncmp 3 , .Xr strncpy 3 , +.Xr strnlen 3 , .Xr strpbrk 3 , .Xr strrchr 3 , .Xr strspn 3 , @@ -139,6 +158,16 @@ counterpart, such as These functions conform to .St -isoC-99 , with the exception of +.Fn wcpcpy , +.Fn wcpncpy , +.Fn wcscasecmp , +.Fn wcsdup , +.Fn wcsncasecmp , +and +.Fn wcsnlen , +which conform to +.St -p1003.1-2008 ; +and .Fn wcslcat and .Fn wcslcpy , diff --git a/string/FreeBSD/wmemchr.3.patch b/string/FreeBSD/wmemchr.3.patch index 40fc3e5..b2ba5da 100644 --- a/string/FreeBSD/wmemchr.3.patch +++ b/string/FreeBSD/wmemchr.3.patch @@ -1,6 +1,6 @@ ---- _SB/Libc/string/FreeBSD/wmemchr.3 2003-05-20 15:23:56.000000000 -0700 -+++ _SB/Libc/string/FreeBSD/wmemchr.3.edit 2006-06-28 16:55:53.000000000 -0700 -@@ -43,11 +43,6 @@ +--- wmemchr.3.orig 2009-12-16 13:19:24.000000000 -0800 ++++ wmemchr.3 2009-12-16 13:30:23.000000000 -0800 +@@ -39,11 +39,6 @@ .Dt WMEMCHR 3 .Os .Sh NAME @@ -9,10 +9,10 @@ -.Nm wmemcpy , -.Nm wmemmove , -.Nm wmemset , - .Nm wcscat , - .Nm wcschr , - .Nm wcscmp , -@@ -62,57 +57,131 @@ + .Nm wcpcpy , + .Nm wcpncpy , + .Nm wcscasecmp , +@@ -64,23 +59,18 @@ .Nm wcspbrk , .Nm wcsrchr , .Nm wcsspn , @@ -30,16 +30,7 @@ .In wchar.h .Ft wchar_t * -.Fn wmemchr "const wchar_t *s" "wchar_t c" "size_t n" -+.Fo wcscat -+.Fa "wchar_t *restrict ws1" -+.Fa "const wchar_t *restrict ws2" -+.Fc -+.Ft wchar_t * -+.Fo wcschr -+.Fa "const wchar_t *ws" -+.Fa "wchar_t wc" -+.Fc - .Ft int +-.Ft int -.Fn wmemcmp "const wchar_t *s1" "const wchar_t *s2" "size_t n" -.Ft wchar_t * -.Fn wmemcpy "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" @@ -48,136 +39,67 @@ -.Ft wchar_t * -.Fn wmemset "wchar_t *s" "wchar_t c" "size_t n" -.Ft wchar_t * --.Fn wcscat "wchar_t * restrict s1" "const wchar_t * restrict s2" --.Ft wchar_t * --.Fn wcschr "const wchar_t *s" "wchar_t c" --.Ft int --.Fn wcscmp "const wchar_t *s1" "const wchar_t *s2" --.Ft wchar_t * --.Fn wcscpy "wchar_t * restrict s1" "const wchar_t * restrict s2" -+.Fo wcscmp -+.Fa "const wchar_t *ws1" -+.Fa "const wchar_t *ws2" -+.Fc -+.Ft wchar_t * -+.Fo wcscpy -+.Fa "wchar_t *restrict ws1" -+.Fa "const wchar_t *restrict ws2" -+.Fc - .Ft size_t --.Fn wcscspn "const wchar_t *s1" "const wchar_t *s2" -+.Fo wcscspn -+.Fa "const wchar_t *ws1" -+.Fa "const wchar_t *ws2" -+.Fc - .Ft size_t --.Fn wcslcat "wchar_t *s1" "const wchar_t *s2" "size_t n" -+.Fo wcslcat -+.Fa "wchar_t *ws1" -+.Fa "const wchar_t *ws2" -+.Fa "size_t n" -+.Fc - .Ft size_t --.Fn wcslcpy "wchar_t *s1" "const wchar_t *s2" "size_t n" -+.Fo wcslcpy -+.Fa "wchar_t *ws1" -+.Fa "const wchar_t *ws2" -+.Fa "size_t n" -+.Fc - .Ft size_t --.Fn wcslen "const wchar_t *s" --.Ft wchar_t * --.Fn wcsncat "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" -+.Fo wcslen -+.Fa "const wchar_t *ws" -+.Fc -+.Ft wchar_t * -+.Fo wcsncat -+.Fa "wchar_t *restrict ws1" -+.Fa "const wchar_t *restrict ws2" -+.Fa "size_t n" -+.Fc - .Ft int --.Fn wcsncmp "const wchar_t *s1" "const wchar_t * s2" "size_t n" --.Ft wchar_t * --.Fn wcsncpy "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" --.Ft wchar_t * --.Fn wcspbrk "const wchar_t *s1" "const wchar_t *s2" --.Ft wchar_t * --.Fn wcsrchr "const wchar_t *s" "wchar_t c" -+.Fo wcsncmp -+.Fa "const wchar_t *ws1" -+.Fa "const wchar_t *ws2" -+.Fa "size_t n" -+.Fc -+.Ft wchar_t * -+.Fo wcsncpy -+.Fa "wchar_t *restrict ws1" -+.Fa "const wchar_t *restrict ws2" -+.Fa "size_t n" -+.Fc -+.Ft wchar_t * -+.Fo wcspbrk -+.Fa "const wchar_t *ws1" -+.Fa "const wchar_t *ws2" -+.Fc -+.Ft wchar_t * -+.Fo wcsrchr -+.Fa "const wchar_t *ws" -+.Fa "wchar_t wc" -+.Fc - .Ft size_t --.Fn wcsspn "const wchar_t *s1" "const wchar_t *s2" --.Ft wchar_t * --.Fn wcsstr "const wchar_t * restrict s1" "const wchar_t * restrict s2" -+.Fo wcsspn -+.Fa "const wchar_t *ws1" -+.Fa "const wchar_t *ws2" -+.Fc -+.Ft wchar_t * -+.Fo wcsstr -+.Fa "const wchar_t *restrict ws1" -+.Fa "const wchar_t *restrict ws2" -+.Fc + .Fn wcpcpy "wchar_t *s1" "wchar_t *s2" + .Ft wchar_t * + .Fn wcpncpy "wchar_t *s1" "wchar_t *s2" "size_t n" +@@ -122,6 +112,22 @@ + .Fn wcsspn "const wchar_t *s1" "const wchar_t *s2" + .Ft wchar_t * + .Fn wcsstr "const wchar_t * restrict s1" "const wchar_t * restrict s2" +.Ft wchar_t * -+.Fo wmemchr -+.Fa "const wchar_t *ws" -+.Fa "wchar_t wc" -+.Fa "size_t n" -+.Fc ++.Fn wmemchr "const wchar_t *s" "wchar_t c" "size_t n" +.Ft int -+.Fo wmemcmp -+.Fa "const wchar_t *ws1" -+.Fa "const wchar_t *ws2" -+.Fa "size_t n" -+.Fc ++.Fn wmemcmp "const wchar_t *s1" "const wchar_t *s2" "size_t n" +.Ft wchar_t * -+.Fo wmemcpy -+.Fa "wchar_t *restrict ws1" -+.Fa "const wchar_t *restrict ws2" -+.Fa "size_t n" -+.Fc ++.Fn wmemcpy "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" +.Ft wchar_t * -+.Fo wmemmove -+.Fa "wchar_t *ws1" -+.Fa "const wchar_t *ws2" -+.Fa "size_t n" -+.Fc ++.Fn wmemmove "wchar_t *s1" "const wchar_t *s2" "size_t n" +.Ft wchar_t * -+.Fo wmemset -+.Fa "wchar_t *ws" -+.Fa "wchar_t wc" -+.Fa "size_t n" -+.Fc ++.Fn wmemset "wchar_t *s" "wchar_t c" "size_t n" ++.In wchar.h ++.In xlocale.h ++.Ft int ++.Fn wcscasecmp_l "const wchar_t *s1" "const wchar_t *s2" "locale_t loc" ++.Ft int ++.Fn wcsncasecmp_l "const wchar_t *s1" "const wchar_t *s2" "size_t n" "locale_t loc" .Sh DESCRIPTION --The functions implement string manipulation operations over wide character --strings. --For a detailed description, refer to documents for the respective single-byte --counterpart, such as -+The functions implement string manipulation operations -+over wide character strings. -+For a detailed description, -+refer to documents for the respective single-byte counterpart, such as - .Xr memchr 3 . - .Sh SEE ALSO - .Xr memchr 3 , + The functions implement string manipulation operations over wide character + strings. +@@ -137,6 +143,7 @@ counterpart, such as + .Xr stpcpy 3 , + .Xr stpncpy 3 , + .Xr strcasecmp 3 , ++.Xr strcasecmp_l 3 , + .Xr strcat 3 , + .Xr strchr 3 , + .Xr strcmp 3 , +@@ -146,6 +153,8 @@ counterpart, such as + .Xr strlcat 3 , + .Xr strlcpy 3 , + .Xr strlen 3 , ++.Xr strncasecmp 3 , ++.Xr strncasecmp_l 3 , + .Xr strncat 3 , + .Xr strncmp 3 , + .Xr strncpy 3 , +@@ -153,7 +162,8 @@ counterpart, such as + .Xr strpbrk 3 , + .Xr strrchr 3 , + .Xr strspn 3 , +-.Xr strstr 3 ++.Xr strstr 3 , ++.Xr xlocale 3 + .Sh STANDARDS + These functions conform to + .St -isoC-99 , +@@ -161,8 +171,10 @@ with the exception of + .Fn wcpcpy , + .Fn wcpncpy , + .Fn wcscasecmp , ++.Fn wcscasecmp_l , + .Fn wcsdup , + .Fn wcsncasecmp , ++.Fn wcsncasecmp_l , + and + .Fn wcsnlen , + which conform to diff --git a/string/FreeBSD/wmemchr.c b/string/FreeBSD/wmemchr.c index 0b09f94..6678fe3 100644 --- a/string/FreeBSD/wmemchr.c +++ b/string/FreeBSD/wmemchr.c @@ -32,15 +32,12 @@ __RCSID("$NetBSD: wmemchr.c,v 1.1 2000/12/23 23:14:37 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wmemchr.c,v 1.6 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wmemchr.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include wchar_t * -wmemchr(s, c, n) - const wchar_t *s; - wchar_t c; - size_t n; +wmemchr(const wchar_t *s, wchar_t c, size_t n) { size_t i; diff --git a/string/FreeBSD/wmemcmp.c b/string/FreeBSD/wmemcmp.c index 3014041..f6cdc6b 100644 --- a/string/FreeBSD/wmemcmp.c +++ b/string/FreeBSD/wmemcmp.c @@ -32,15 +32,12 @@ __RCSID("$NetBSD: wmemcmp.c,v 1.1 2000/12/23 23:14:37 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wmemcmp.c,v 1.6 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wmemcmp.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include int -wmemcmp(s1, s2, n) - const wchar_t *s1; - const wchar_t *s2; - size_t n; +wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n) { size_t i; diff --git a/string/FreeBSD/wmemcpy.c b/string/FreeBSD/wmemcpy.c index 4391309..523e48c 100644 --- a/string/FreeBSD/wmemcpy.c +++ b/string/FreeBSD/wmemcpy.c @@ -32,17 +32,13 @@ __RCSID("$NetBSD: wmemcpy.c,v 1.1 2000/12/23 23:14:37 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wmemcpy.c,v 1.7 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wmemcpy.c,v 1.8 2009/02/03 17:58:20 danger Exp $"); #include #include wchar_t * -wmemcpy(d, s, n) - wchar_t * __restrict d; - const wchar_t * __restrict s; - size_t n; +wmemcpy(wchar_t * __restrict d, const wchar_t * __restrict s, size_t n) { - return (wchar_t *)memcpy(d, s, n * sizeof(wchar_t)); } diff --git a/string/FreeBSD/wmemmove.c b/string/FreeBSD/wmemmove.c index dd2036c..161e357 100644 --- a/string/FreeBSD/wmemmove.c +++ b/string/FreeBSD/wmemmove.c @@ -32,17 +32,13 @@ __RCSID("$NetBSD: wmemmove.c,v 1.1 2000/12/23 23:14:37 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wmemmove.c,v 1.6 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wmemmove.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); #include #include wchar_t * -wmemmove(d, s, n) - wchar_t *d; - const wchar_t *s; - size_t n; +wmemmove(wchar_t *d, const wchar_t *s, size_t n) { - return (wchar_t *)memmove(d, s, n * sizeof(wchar_t)); } diff --git a/string/FreeBSD/wmemset.c b/string/FreeBSD/wmemset.c index df91537..9d9b121 100644 --- a/string/FreeBSD/wmemset.c +++ b/string/FreeBSD/wmemset.c @@ -32,15 +32,12 @@ __RCSID("$NetBSD: wmemset.c,v 1.1 2000/12/23 23:14:37 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif -__FBSDID("$FreeBSD: src/lib/libc/string/wmemset.c,v 1.6 2002/09/21 00:29:23 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wmemset.c,v 1.8 2009/02/03 20:25:36 imp Exp $"); #include wchar_t * -wmemset(s, c, n) - wchar_t *s; - wchar_t c; - size_t n; +wmemset(wchar_t *s, wchar_t c, size_t n) { size_t i; wchar_t *p; diff --git a/string/Makefile.inc b/string/Makefile.inc index e037f52..41191f6 100644 --- a/string/Makefile.inc +++ b/string/Makefile.inc @@ -11,20 +11,34 @@ CFLAGS+= -I${.CURDIR}/locale .include "Makefile.fbsd_begin" # machine-independent string sources -FBSDMISRCS+=bcmp.c index.c memccpy.c memchr.c memcmp.c \ - memset.c rindex.c stpcpy.c strcasecmp.c strcat.c \ - strchr.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 \ +FBSDMISRCS+=bcmp.c index.c memccpy.c memchr.c memcmp.c memmem.c \ + memset.c rindex.c stpcpy.c stpncpy.c strcasecmp.c strcat.c \ + strchr.c strcoll.c strcpy.c strcspn.c strdup.c strndup.c strerror.c \ + strlcat.c strlcpy.c strlen.c strmode.c strncat.c strncmp.c strncpy.c strnlen.c \ strcasestr.c strnstr.c \ strpbrk.c strrchr.c strsep.c strsignal.c strspn.c strstr.c strtok.c \ - strxfrm.c swab.c wcscat.c wcschr.c wcscmp.c wcscoll.c wcscpy.c \ - wcscspn.c \ - wcslcat.c wcslcpy.c wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcspbrk.c \ + strxfrm.c swab.c \ + wcpcpy.c wcpncpy.c wcscasecmp.c wcsncasecmp.c \ + wcscat.c wcschr.c wcscmp.c wcscoll.c wcscpy.c \ + wcscspn.c wcsdup.c wcslcat.c wcslcpy.c \ + wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcsnlen.c wcspbrk.c \ wcsrchr.c wcsspn.c wcsstr.c wcstok.c wcswidth.c wcsxfrm.c wmemchr.c \ wmemcmp.c \ wmemcpy.c wmemmove.c wmemset.c .include "Makefile.fbsd_end" +DYLDSRCS += \ + strcat.c \ + strchr.c \ + strcpy.c \ + strdup.c \ + strlcat.c \ + strlcpy.c \ + strncmp.c \ + strncpy.c \ + strrchr.c \ + strstr.c + LEGACYSRCS+= strerror.c # set the LIBC_ALIAS_* macros so we can decorate the symbol independent @@ -34,7 +48,7 @@ CFLAGS-strerror-fbsd.c += -DLIBC_ALIAS_STRERROR .if ${LIB} == "c" .include "Makefile.fbsd_begin" FBSDMAN3= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \ - memcmp.3 memcpy.3 memmove.3 memset.3 rindex.3 strcasecmp.3 strcat.3 \ + memcmp.3 memcpy.3 memmem.3 memmove.3 memset.3 rindex.3 strcasecmp.3 strcat.3 \ strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strdup.3 strerror.3 \ string.3 strlcpy.3 strlen.3 strmode.3 strpbrk.3 strrchr.3 strsep.3 \ strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 wcscoll.3 wcstok.3 \ @@ -56,8 +70,13 @@ MLINKS+= strcmp.3 strncmp.3 MLINKS+= strcoll.3 strcoll_l.3 MLINKS+= strcpy.3 stpcpy.3 \ + strcpy.3 stpncpy.3 \ strcpy.3 strncpy.3 +MLINKS+= strdup.3 strndup.3 + +MLINKS+= strlen.3 strnlen.3 + MLINKS+= strerror.3 perror.3 \ strerror.3 strerror_r.3 \ strerror.3 sys_errlist.3 \ @@ -83,6 +102,11 @@ MLINKS+= wmemchr.3 wmemcmp.3 \ wmemchr.3 wmemcpy.3 \ wmemchr.3 wmemmove.3 \ wmemchr.3 wmemset.3 \ + wmemchr.3 wcpcpy.3 \ + wmemchr.3 wcpncpy.3 \ + wmemchr.3 wcsdup.3 \ + wmemchr.3 wcscasecmp.3 \ + wmemchr.3 wcscasecmp_l.3 \ wmemchr.3 wcscat.3 \ wmemchr.3 wcschr.3 \ wmemchr.3 wcscmp.3 \ @@ -91,9 +115,12 @@ MLINKS+= wmemchr.3 wmemcmp.3 \ wmemchr.3 wcslcat.3 \ wmemchr.3 wcslcpy.3 \ wmemchr.3 wcslen.3 \ + wmemchr.3 wcsncasecmp.3 \ + wmemchr.3 wcsncasecmp_l.3 \ wmemchr.3 wcsncat.3 \ wmemchr.3 wcsncmp.3 \ wmemchr.3 wcsncpy.3 \ + wmemchr.3 wcsnlen.3 \ wmemchr.3 wcspbrk.3 \ wmemchr.3 wcsrchr.3 \ wmemchr.3 wcsspn.3 \ diff --git a/string/bcmp.3 b/string/bcmp.3 index e3cc973..67f456b 100644 --- a/string/bcmp.3 +++ b/string/bcmp.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bcmp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bcmp.3,v 1.10 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bcmp.3,v 1.11 2007/01/09 00:28:11 imp Exp $ .\" .Dd June 4, 1993 .Dt BCMP 3 diff --git a/string/bcopy.3 b/string/bcopy.3 index 129e753..e0371a4 100644 --- a/string/bcopy.3 +++ b/string/bcopy.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bcopy.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bcopy.3,v 1.9 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bcopy.3,v 1.10 2007/01/09 00:28:11 imp Exp $ .\" .Dd June 4, 1993 .Dt BCOPY 3 diff --git a/string/bstring.3 b/string/bstring.3 index becca80..4b34387 100644 --- a/string/bstring.3 +++ b/string/bstring.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bstring.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bstring.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bstring.3,v 1.8 2007/01/09 00:28:11 imp Exp $ .\" .Dd June 4, 1993 .Dt BSTRING 3 diff --git a/string/bzero.3 b/string/bzero.3 index 1fb20f8..642b2f1 100644 --- a/string/bzero.3 +++ b/string/bzero.3 @@ -12,10 +12,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -33,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bzero.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bzero.3,v 1.9 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bzero.3,v 1.10 2007/01/09 00:28:11 imp Exp $ .\" .Dd June 4, 1993 .Dt BZERO 3 diff --git a/string/ffs.3 b/string/ffs.3 index b5607d4..d019b6d 100644 --- a/string/ffs.3 +++ b/string/ffs.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,9 +28,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)ffs.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/string/ffs.3,v 1.9 2004/06/30 20:09:09 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/ffs.3,v 1.13 2009/01/13 13:19:42 kib Exp $ .\" -.Dd January 13, 2004 +.Dd October 26, 2008 .Dt FFS 3 .Os .Sh NAME @@ -60,7 +56,9 @@ The .Fn ffs and .Fn ffsl -functions find the first bit set in +functions find the first bit set +(beginning with the least significant bit) +in .Fa i and return the index of that bit. .Pp @@ -72,8 +70,7 @@ functions find the last bit set in .Fa i and return the index of that bit. .Pp -Bits are numbered starting from 1, starting at the right-most -(least significant) bit. +Bits are numbered starting at 1 (the least significant bit). A return value of zero from any of these functions means that the argument was zero. .Sh SEE ALSO diff --git a/string/index.3 b/string/index.3 index 28b558f..ecbbb63 100644 --- a/string/index.3 +++ b/string/index.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)index.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/index.3,v 1.11 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/index.3,v 1.12 2007/01/09 00:28:12 imp Exp $ .\" .Dd June 4, 1993 .Dt INDEX 3 diff --git a/string/memccpy.3 b/string/memccpy.3 index e28e935..02cfa37 100644 --- a/string/memccpy.3 +++ b/string/memccpy.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memccpy.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/memccpy.3,v 1.6 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/memccpy.3,v 1.7 2007/01/09 00:28:12 imp Exp $ .\" .Dd June 9, 1993 .Dt MEMCCPY 3 diff --git a/string/memchr.3 b/string/memchr.3 index 80eb092..430441b 100644 --- a/string/memchr.3 +++ b/string/memchr.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)memchr.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memchr.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/memchr.3,v 1.12 2009/04/23 08:37:56 brueffer Exp $ .\" -.Dd June 4, 1993 +.Dd April 9, 2008 .Dt MEMCHR 3 .Os .Sh NAME @@ -77,7 +73,8 @@ bytes. .Xr strsep 3 , .Xr strspn 3 , .Xr strstr 3 , -.Xr strtok 3 +.Xr strtok 3 , +.Xr wmemchr 3 .Sh STANDARDS The .Fn memchr diff --git a/string/memcmp.3 b/string/memcmp.3 index 8c1ae2c..f48f5d4 100644 --- a/string/memcmp.3 +++ b/string/memcmp.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memcmp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memcmp.3,v 1.8 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/memcmp.3,v 1.10 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt MEMCMP 3 @@ -80,7 +76,8 @@ Zero-length strings are always identical. .Xr strcasecmp 3 , .Xr strcmp 3 , .Xr strcoll 3 , -.Xr strxfrm 3 +.Xr strxfrm 3 , +.Xr wmemcmp 3 .Sh STANDARDS The .Fn memcmp diff --git a/string/memcpy.3 b/string/memcpy.3 index 326680d..77bd719 100644 --- a/string/memcpy.3 +++ b/string/memcpy.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memcpy.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memcpy.3,v 1.7 2002/01/07 06:03:37 dd Exp $ +.\" $FreeBSD: src/lib/libc/string/memcpy.3,v 1.9 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt MEMCPY 3 @@ -84,7 +80,8 @@ returns the original value of .Xr bcopy 3 , .Xr memccpy 3 , .Xr memmove 3 , -.Xr strcpy 3 +.Xr strcpy 3 , +.Xr wmemcpy 3 .Sh STANDARDS The .Fn memcpy diff --git a/string/memmem-fbsd.c b/string/memmem-fbsd.c new file mode 120000 index 0000000..845d9f1 --- /dev/null +++ b/string/memmem-fbsd.c @@ -0,0 +1 @@ +./memmem.c \ No newline at end of file diff --git a/string/memmem.3 b/string/memmem.3 new file mode 120000 index 0000000..9b3234e --- /dev/null +++ b/string/memmem.3 @@ -0,0 +1 @@ +./memmem.3 \ No newline at end of file diff --git a/string/memmove.3 b/string/memmove.3 index c29073b..64871c8 100644 --- a/string/memmove.3 +++ b/string/memmove.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memmove.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memmove.3,v 1.6 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/memmove.3,v 1.8 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt MEMMOVE 3 @@ -73,7 +69,8 @@ function returns the original value of .Xr bcopy 3 , .Xr memccpy 3 , .Xr memcpy 3 , -.Xr strcpy 3 +.Xr strcpy 3 , +.Xr wmemmove 3 .Sh STANDARDS The .Fn memmove diff --git a/string/memset.3 b/string/memset.3 index 779d115..701d739 100644 --- a/string/memset.3 +++ b/string/memset.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memset.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memset.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/memset.3,v 1.9 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt MEMSET 3 @@ -65,7 +61,8 @@ function returns its first argument. .Sh SEE ALSO .Xr bzero 3 , .Xr memset_pattern 3 , -.Xr swab 3 +.Xr swab 3 , +.Xr wmemset 3 .Sh STANDARDS The .Fn memset diff --git a/string/stpncpy-fbsd.c b/string/stpncpy-fbsd.c new file mode 120000 index 0000000..9e47db9 --- /dev/null +++ b/string/stpncpy-fbsd.c @@ -0,0 +1 @@ +./stpncpy.c \ No newline at end of file diff --git a/string/strcasecmp-fbsd.c b/string/strcasecmp-fbsd.c index e85897a..8299c16 100644 --- a/string/strcasecmp-fbsd.c +++ b/string/strcasecmp-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strcasecmp.c,v 1.6 2002/08/30 15:40:01 robert Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strcasecmp.c,v 1.8 2009/02/03 17:58:20 danger Exp $"); #include "xlocale_private.h" @@ -61,8 +57,7 @@ strcasecmp_l(s1, s2, loc) } int -strcasecmp(s1, s2) - const char *s1, *s2; +strcasecmp(const char *s1, const char *s2) { return strcasecmp_l(s1, s2, __current_locale()); } @@ -90,9 +85,7 @@ strncasecmp_l(s1, s2, n, loc) } int -strncasecmp(s1, s2, n) - const char *s1, *s2; - size_t n; +strncasecmp(const char *s1, const char *s2, size_t n) { return strncasecmp_l(s1, s2, n, __current_locale()); } diff --git a/string/strcasecmp.3 b/string/strcasecmp.3 index 52fb0e5..0d686a6 100644 --- a/string/strcasecmp.3 +++ b/string/strcasecmp.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/strcasecmp.3,v 1.11 2003/09/08 19:57:15 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strcasecmp.3,v 1.13 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 9, 1993 .Dt STRCASECMP 3 diff --git a/string/strcasestr-fbsd.c b/string/strcasestr-fbsd.c index ef30b54..e8f576f 100644 --- a/string/strcasestr-fbsd.c +++ b/string/strcasestr-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strcasestr.c,v 1.3 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strcasestr.c,v 1.5 2009/02/03 17:58:20 danger Exp $"); #include "xlocale_private.h" @@ -69,8 +65,7 @@ strcasestr_l(s, find, loc) } char * -strcasestr(s, find) - const char *s, *find; +strcasestr(const char *s, const char *find) { return strcasestr_l(s, find, __current_locale()); } diff --git a/string/strcat.3 b/string/strcat.3 index 9effc5e..9eb86ec 100644 --- a/string/strcat.3 +++ b/string/strcat.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcat.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcat.3,v 1.13 2002/09/06 11:24:06 tjr Exp $ +.\" $FreeBSD: src/lib/libc/string/strcat.3,v 1.17 2009/12/01 07:28:56 brueffer Exp $ .\" -.Dd June 4, 1993 +.Dd December 1, 2009 .Dt STRCAT 3 .Os .Sh NAME @@ -159,7 +155,8 @@ foo(const char *arbitrary_string) .Xr memmove 3 , .Xr strcpy 3 , .Xr strlcat 3 , -.Xr strlcpy 3 +.Xr strlcpy 3 , +.Xr wcscat 3 .Sh STANDARDS The .Fn strcat diff --git a/string/strchr.3 b/string/strchr.3 index 72e81b2..512bc6f 100644 --- a/string/strchr.3 +++ b/string/strchr.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strchr.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/string/strchr.3,v 1.11 2003/09/04 20:36:54 simon Exp $ +.\" $FreeBSD: src/lib/libc/string/strchr.3,v 1.14 2009/04/07 13:42:53 trasz Exp $ .\" .Dd April 19, 1994 .Dt STRCHR 3 @@ -89,12 +85,14 @@ return a pointer to the located character, or if the character does not appear in the string. .Sh SEE ALSO .Xr memchr 3 , +.Xr memmem 3 , .Xr strcspn 3 , .Xr strpbrk 3 , .Xr strsep 3 , .Xr strspn 3 , .Xr strstr 3 , -.Xr strtok 3 +.Xr strtok 3 , +.Xr wcschr 3 .Sh STANDARDS The functions .Fn strchr diff --git a/string/strcmp.3 b/string/strcmp.3 index 602e85d..e04b4dd 100644 --- a/string/strcmp.3 +++ b/string/strcmp.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcmp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcmp.3,v 1.10 2001/10/11 17:02:44 mike Exp $ +.\" $FreeBSD: src/lib/libc/string/strcmp.3,v 1.13 2009/12/04 09:20:20 trhodes Exp $ .\" .Dd October 11, 2001 .Dt STRCMP 3 @@ -86,7 +82,7 @@ The .Fn strcmp and .Fn strncmp -return an integer greater than, equal to, or less than 0, according +functions return an integer greater than, equal to, or less than 0, according as the string .Fa s1 is greater than, equal to, or less than the string @@ -100,7 +96,8 @@ is greater than .Xr memcmp 3 , .Xr strcasecmp 3 , .Xr strcoll 3 , -.Xr strxfrm 3 +.Xr strxfrm 3 , +.Xr wcscmp 3 .Sh STANDARDS The .Fn strcmp diff --git a/string/strcoll-fbsd.c b/string/strcoll-fbsd.c index 92d842d..3128289 100644 --- a/string/strcoll-fbsd.c +++ b/string/strcoll-fbsd.c @@ -26,7 +26,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strcoll.c,v 1.13 2001/11/07 19:55:16 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strcoll.c,v 1.14 2009/02/03 17:58:20 danger Exp $"); #include "xlocale_private.h" @@ -37,9 +37,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strcoll.c,v 1.13 2001/11/07 19:55:16 obr #include "collate.h" int -strcoll_l(s, s2, loc) - const char *s, *s2; - locale_t loc; +strcoll_l(const char *s, const char *s2, locale_t loc) { int ret; const wchar_t *t = NULL, *t2 = NULL; @@ -64,8 +62,7 @@ strcoll_l(s, s2, loc) } int -strcoll(s, s2) - const char *s, *s2; +strcoll(const char *s, const char *s2) { return strcoll_l(s, s2, __current_locale()); } diff --git a/string/strcoll.3 b/string/strcoll.3 index 267c836..fcbbbe1 100644 --- a/string/strcoll.3 +++ b/string/strcoll.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcoll.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcoll.3,v 1.12 2002/10/15 10:11:53 tjr Exp $ +.\" $FreeBSD: src/lib/libc/string/strcoll.3,v 1.14 2007/01/09 00:28:12 imp Exp $ .\" .Dd June 4, 1993 .Dt STRCOLL 3 @@ -67,15 +63,17 @@ function lexicographically compares the null-terminated strings .Fa s1 and -.Fa s2 , -according to the current locale collation, if any. -Otherwise, it calls -.Fa strcmp +.Fa s2 +according to the current locale collation and returns an integer greater than, equal to, or less than 0, according as .Fa s1 is greater than, equal to, or less than .Fa s2 . +If information about the current locale collation is not available, +the value of +.Fn strcmp s1 s2 +is returned. .Pp Although the .Fn strcoll diff --git a/string/strcpy.3 b/string/strcpy.3 index 9742ef4..e1fbdc1 100644 --- a/string/strcpy.3 +++ b/string/strcpy.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,15 +30,13 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcpy.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcpy.3,v 1.24 2002/12/19 09:40:24 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strcpy.3,v 1.28 2009/04/07 13:42:53 trasz Exp $ .\" -.Dd August 9, 2001 +.Dd February 28, 2009 .Dt STRCPY 3 .Os .Sh NAME -.Nm stpcpy , -.Nm strcpy , -.Nm strncpy +.Nm stpcpy, stpncpy, strcpy , strncpy .Nd copy strings .Sh LIBRARY .Lb libc @@ -54,6 +48,12 @@ .Fa "const char *s2" .Fc .Ft char * +.Fo stpncpy +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fa "size_t n" +.Fc +.Ft char * .Fo strcpy .Fa "char *restrict s1" .Fa "const char *restrict s2" @@ -79,8 +79,10 @@ to character). .Pp The +.Fn stpncpy +and .Fn strncpy -function copies at most +functions copy at most .Fa n characters from .Fa s2 @@ -114,10 +116,21 @@ return .Fa s1 . The .Fn stpcpy -function returns a pointer to the terminating +and +.Fn stpncpy +functions return a pointer to the terminating .Ql \e0 character of .Fa s1 . +If +.Fn stpncpy +does not terminate +.Fa s1 +with a +.Dv NUL +character, it instead returns a pointer to +.Li s1[n] +(which does not necessarily refer to a valid memory location.) .Sh EXAMPLES The following sets .Va chararray @@ -173,27 +186,33 @@ This could be better achieved using as shown in the following example: .Pp .Dl "(void)strlcpy(buf, input, sizeof(buf));" -.Pp -Note that, because -.Xr strlcpy 3 -is not defined in any standards, it should -only be used when portability is not a concern. .Sh SECURITY CONSIDERATIONS The -.Fn strcpy -function is easily misused in a manner which enables malicious users +.Fn strcpy , +.Fn strncpy , +.Fn stpcpy , +and +.Fn stpncpy +functions are easily misused in a manner which enables malicious users to arbitrarily change a running program's functionality through a buffer overflow attack. (See the FSA and .Sx EXAMPLES . ) +.Pp +It is recommended that +.Xr strlcpy 3 +be used instead as a way to avoid such problems. +.Xr strlcpy 3 +is not defined in any standards, but it has been adopted by most major libc implementations. .Sh SEE ALSO .Xr bcopy 3 , .Xr memccpy 3 , .Xr memcpy 3 , .Xr memmove 3 , -.Xr strlcpy 3 +.Xr strlcpy 3 , +.Xr wcscpy 3 .Sh STANDARDS The .Fn strcpy @@ -204,14 +223,16 @@ conform to .St -isoC . The .Fn stpcpy -function is an MS-DOS and GNUism. -The -.Fn stpcpy -function -conforms to no standard. +and +.Fn stpncpy +functions conform to +.St -p1003.1-2008 . .Sh HISTORY The .Fn stpcpy function first appeared in .Fx 4.4 , -coming from 1998-vintage Linux. +and +.Fn stpncpy +was added in +.Fx 8.0 . diff --git a/string/strcspn.3 b/string/strcspn.3 index 7d17774..938f80b 100644 --- a/string/strcspn.3 +++ b/string/strcspn.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcspn.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcspn.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strcspn.3,v 1.9 2007/01/09 00:28:12 imp Exp $ .\" .Dd June 4, 1993 .Dt STRCSPN 3 @@ -66,10 +62,18 @@ spans the .Em complement of .Fa s2 ) . +In other words, it computes the string array index in +.Fa s1 +of the first character of +.Fa s1 +which is also in +.Fa s2 , +else the index of the first null character. .Sh RETURN VALUES The .Fn strcspn -function returns the number of characters spanned. +function +returns the number of characters spanned. .Sh SEE ALSO .Xr memchr 3 , .Xr strchr 3 , diff --git a/string/strdup.3 b/string/strdup.3 index 506c19a..688d317 100644 --- a/string/strdup.3 +++ b/string/strdup.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,13 +26,14 @@ .\" SUCH DAMAGE. .\" .\" @(#)strdup.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/strdup.3,v 1.10 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strdup.3,v 1.15 2009/04/07 13:42:53 trasz Exp $ .\" -.Dd June 9, 1993 +.Dd December 5, 2008 .Dt STRDUP 3 .Os .Sh NAME -.Nm strdup +.Nm strdup , +.Nm strndup .Nd save a copy of a string .Sh LIBRARY .Lb libc @@ -46,6 +43,11 @@ .Fo strdup .Fa "const char *s1" .Fc +.Ft char * +.Fo strndup +.Fa "const char *s1" +.Fa "size_t n" +.Fc .Sh DESCRIPTION The .Fn strdup @@ -62,6 +64,16 @@ If insufficient memory is available, NULL is returned and .Va errno is set to .Er ENOMEM . +.Pp +The +.Fn strndup +function copies at most +.Fa n +characters from the string +.Fa s1 +always +.Dv NUL +terminating the copied string. .Sh SEE ALSO .Xr free 3 , .Xr malloc 3 @@ -70,3 +82,7 @@ The .Fn strdup function first appeared in .Bx 4.4 . +The +.Fn strndup +function was added in +.Fx 7.2 . diff --git a/string/strerror-fbsd.c b/string/strerror-fbsd.c index 798dbb4..63e8101 100644 --- a/string/strerror-fbsd.c +++ b/string/strerror-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,20 +31,26 @@ static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strerror.c,v 1.13 2003/05/01 19:03:14 nectar Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strerror.c,v 1.16 2007/01/09 00:28:12 imp Exp $"); +#if defined(NLS) +#include +#endif + +#include #include -#include #include +#include -#define UPREFIX "Unknown error: " +#define UPREFIX "Unknown error" /* * Define a buffer size big enough to describe a 64-bit signed integer * converted to ASCII decimal (19 bytes), with an optional leading sign - * (1 byte); finally, we get the prefix and a trailing NUL from UPREFIX. + * (1 byte); finally, we get the prefix, delimiter (": ") and a trailing + * NUL from UPREFIX. */ -#define EBUFSIZE (20 + sizeof(UPREFIX)) +#define EBUFSIZE (20 + 2 + sizeof(UPREFIX)) #ifndef BUILDING_VARIANT /* @@ -56,7 +58,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strerror.c,v 1.13 2003/05/01 19:03:14 ne * statically linked binaries. */ __private_extern__ void -__errstr(int num, char *buf, size_t len) +__errstr(int num, char *uprefix, char *buf, size_t len) { char *t; unsigned int uerr; @@ -70,21 +72,48 @@ __errstr(int num, char *buf, size_t len) } while (uerr /= 10); if (num < 0) *--t = '-'; - strlcpy(buf, UPREFIX, len); + *--t = ' '; + *--t = ':'; + strlcpy(buf, uprefix, len); strlcat(buf, t, len); } int strerror_r(int errnum, char *strerrbuf, size_t buflen) { + int retval = 0; +#if defined(NLS) + int saved_errno = errno; + nl_catd catd; + catd = catopen("libc", NL_CAT_LOCALE); +#endif if (errnum < 0 || errnum >= sys_nerr) { - __errstr(errnum, strerrbuf, buflen); - return (EINVAL); + __errstr(errnum, +#if defined(NLS) + catgets(catd, 1, 0xffff, UPREFIX), +#else + UPREFIX, +#endif + strerrbuf, buflen); + retval = EINVAL; + } else { + if (strlcpy(strerrbuf, +#if defined(NLS) + catgets(catd, 1, errnum, sys_errlist[errnum]), +#else + sys_errlist[errnum], +#endif + buflen) >= buflen) + retval = ERANGE; } - if (strlcpy(strerrbuf, sys_errlist[errnum], buflen) >= buflen) - return (ERANGE); - return (0); + +#if defined(NLS) + catclose(catd); + errno = saved_errno; +#endif + + return (retval); } #else /* BUILDING_VARIANT */ __private_extern__ void __errstr(int, char *, size_t); @@ -93,13 +122,13 @@ __private_extern__ void __errstr(int, char *, size_t); char * strerror(int num) { - static char ebuf[EBUFSIZE]; + static char ebuf[NL_TEXTMAX]; - if (num > 0 && num < sys_nerr) - return ((char *)sys_errlist[num]); #if !__DARWIN_UNIX03 + if (strerror_r(num, ebuf, sizeof(ebuf)) != 0) errno = EINVAL; -#endif /* !__DARWIN_UNIX03 */ - __errstr(num, ebuf, sizeof(ebuf)); +#else + (void)strerror_r(num, ebuf, sizeof(ebuf)); +#endif return (ebuf); } diff --git a/string/strerror.3 b/string/strerror.3 index b7166f1..f6f7510 100644 --- a/string/strerror.3 +++ b/string/strerror.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strerror.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/strerror.3,v 1.23 2004/10/12 14:52:52 keramida Exp $ +.\" $FreeBSD: src/lib/libc/string/strerror.3,v 1.24 2007/01/09 00:28:12 imp Exp $ .\" .Dd October 12, 2004 .Dt STRERROR 3 @@ -122,7 +118,7 @@ functions return .Er EINVAL as a warning. Error numbers recognized by this implementation fall in -the range 0 < +the range 0 <= .Fa errnum < .Fa sys_nerr . diff --git a/string/string.3 b/string/string.3 index 2b43279..7f8f9ad 100644 --- a/string/string.3 +++ b/string/string.3 @@ -11,10 +11,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -32,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)string.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/string/string.3,v 1.13 2002/10/19 13:41:22 tjr Exp $ +.\" $FreeBSD: src/lib/libc/string/string.3,v 1.14 2007/01/09 00:28:12 imp Exp $ .\" .Dd December 11, 1993 .Dt STRING 3 diff --git a/string/strlcpy.3 b/string/strlcpy.3 index 1a50415..3cf8bc2 100644 --- a/string/strlcpy.3 +++ b/string/strlcpy.3 @@ -1,18 +1,18 @@ -.\" $OpenBSD: strlcpy.3,v 1.5 1999/06/06 15:17:32 aaron Exp $ +.\" $OpenBSD: strlcpy.3,v 1.19 2007/05/31 19:19:32 jmc Exp $ .\" -.\" Copyright (c) 1998 Todd C. Miller -.\" All rights reserved. +.\" Copyright (c) 1998, 2000 Todd C. Miller .\" -.\" 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. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, .\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY @@ -25,7 +25,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/string/strlcpy.3,v 1.13 2004/07/02 23:52:13 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strlcpy.3,v 1.16 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 22, 1998 .Dt STRLCPY 3 @@ -39,9 +39,9 @@ .Sh SYNOPSIS .In string.h .Ft size_t -.Fn strlcpy "char *dst" "const char *src" "size_t size" +.Fn strlcpy "char * restrict dst" "const char * restrict src" "size_t size" .Ft size_t -.Fn strlcat "char *dst" "const char *src" "size_t size" +.Fn strlcat "char * restrict dst" "const char * restrict src" "size_t size" .Sh DESCRIPTION The .Fn strlcpy @@ -64,7 +64,7 @@ is larger than 0 or, in the case of .Fn strlcat , as long as there is at least one byte free in .Fa dst ) . -Note that you should include a byte for the NUL in +Note that a byte for the NUL should be included in .Fa size . Also note that .Fn strlcpy @@ -124,7 +124,7 @@ that means the initial length of plus the length of .Fa src . -While this may seem somewhat confusing it was done to make +While this may seem somewhat confusing, it was done to make truncation detection simple. .Pp Note however, that if @@ -171,8 +171,8 @@ if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname)) goto toolong; .Ed .Pp -Since we know how many characters we copied the first time, we can -speed things up a bit by using a copy instead of an append: +Since it is known how many characters were copied the first time, things +can be sped up a bit by using a copy instead of an append .Bd -literal -offset indent char *dir, *file, pname[MAXPATHLEN]; size_t n; @@ -195,7 +195,8 @@ As a matter of fact, the first version of this manual page got it wrong. .Sh SEE ALSO .Xr snprintf 3 , .Xr strncat 3 , -.Xr strncpy 3 +.Xr strncpy 3 , +.Xr wcslcpy 3 .Sh HISTORY The .Fn strlcpy diff --git a/string/strmode.3 b/string/strmode.3 index 535baa1..704224e 100644 --- a/string/strmode.3 +++ b/string/strmode.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strmode.3 8.3 (Berkeley) 7/28/94 -.\" $FreeBSD: src/lib/libc/string/strmode.3,v 1.9 2003/07/01 15:28:05 maxim Exp $ +.\" $FreeBSD: src/lib/libc/string/strmode.3,v 1.11 2009/04/14 11:39:56 trasz Exp $ .\" .Dd July 28, 1994 .Dt STRMODE 3 @@ -135,9 +131,7 @@ The file is executable or the directory is searchable. None of the above apply. .El .Pp -The last character is a plus sign ``+'' if any there are any alternate -or additional access control methods associated with the inode, otherwise -it will be a space. +The last character will always be a space. .Sh SEE ALSO .Xr chmod 1 , .Xr find 1 , diff --git a/string/strndup-fbsd.c b/string/strndup-fbsd.c new file mode 120000 index 0000000..2d7b8d4 --- /dev/null +++ b/string/strndup-fbsd.c @@ -0,0 +1 @@ +./strndup.c \ No newline at end of file diff --git a/string/strnlen-fbsd.c b/string/strnlen-fbsd.c new file mode 120000 index 0000000..e1a5577 --- /dev/null +++ b/string/strnlen-fbsd.c @@ -0,0 +1 @@ +./strnlen.c \ No newline at end of file diff --git a/string/strpbrk.3 b/string/strpbrk.3 index 81e579e..30db8c2 100644 --- a/string/strpbrk.3 +++ b/string/strpbrk.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strpbrk.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strpbrk.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strpbrk.3,v 1.9 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt STRPBRK 3 @@ -74,7 +70,8 @@ returns NULL. .Xr strsep 3 , .Xr strspn 3 , .Xr strstr 3 , -.Xr strtok 3 +.Xr strtok 3 , +.Xr wcspbrk 3 .Sh STANDARDS The .Fn strpbrk diff --git a/string/strsignal-fbsd.c b/string/strsignal-fbsd.c index 523bb42..7806d63 100644 --- a/string/strsignal-fbsd.c +++ b/string/strsignal-fbsd.c @@ -10,10 +10,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,40 +31,118 @@ static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strsignal.c,v 1.4 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strsignal.c,v 1.9 2010/01/24 10:35:26 ume Exp $"); -#include +#include "namespace.h" +#if defined(NLS) +#include +#endif +#include +#include +#include #include #include +#include "reentrant.h" +#include "un-namespace.h" +#define UPREFIX "Unknown signal" + +static once_t sig_init_once = ONCE_INITIALIZER; +static thread_key_t sig_key; +static int sig_keycreated = 0; + +static void +sig_keycreate(void) +{ + sig_keycreated = (thr_keycreate(&sig_key, free) == 0); +} + +static char * +sig_tlsalloc(void) +{ + char *ebuf = NULL; + + if (thr_once(&sig_init_once, sig_keycreate) != 0 || + !sig_keycreated) + goto thr_err; + if ((ebuf = thr_getspecific(sig_key)) == NULL) { + if ((ebuf = malloc(NL_TEXTMAX * sizeof(char))) == NULL) + goto thr_err; + if (thr_setspecific(sig_key, ebuf) != 0) { + free(ebuf); + ebuf = NULL; + goto thr_err; + } + } +thr_err: + return (ebuf); +} + +/* XXX: negative 'num' ? (REGR) */ char * -strsignal(num) - int num; +strsignal(int num) { -#define UPREFIX "Unknown signal: " - static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ - unsigned int signum; - char *p, *t; - char tmp[40]; + char *ebuf; + char tmp[20]; + size_t n; + int signum; + char *t, *p; - signum = num; /* convert to unsigned */ - if (signum < NSIG) - return ((char *)sys_siglist[signum]); +#if defined(NLS) + int saved_errno = errno; + nl_catd catd; + catd = catopen("libc", NL_CAT_LOCALE); +#endif - /* Do this by hand, so we don't link to stdio(3). */ - t = tmp; + ebuf = sig_tlsalloc(); + if(ebuf == NULL) { + errno = ENOMEM; + return NULL; + } + + if (num > 0 && num < NSIG) { + n = strlcpy(ebuf, +#if defined(NLS) + catgets(catd, 2, num, sys_siglist[num]), +#else + sys_siglist[num], +#endif + NL_TEXTMAX * sizeof(char)); + } else { + n = strlcpy(ebuf, +#if defined(NLS) + catgets(catd, 2, 0xffff, UPREFIX), +#else + UPREFIX, +#endif + NL_TEXTMAX * sizeof(char)); + } + + signum = num; if (num < 0) signum = -signum; + + t = tmp; do { *t++ = "0123456789"[signum % 10]; } while (signum /= 10); if (num < 0) *t++ = '-'; - for (p = ebuf + sizeof(UPREFIX) - 1;;) { + + p = (ebuf + n); + *p++ = ':'; + *p++ = ' '; + + for (;;) { *p++ = *--t; if (t <= tmp) break; } *p = '\0'; + +#if defined(NLS) + catclose(catd); + errno = saved_errno; +#endif return (ebuf); } diff --git a/string/strspn.3 b/string/strspn.3 index 1528966..fcd199c 100644 --- a/string/strspn.3 +++ b/string/strspn.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strspn.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strspn.3,v 1.8 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strspn.3,v 1.11 2009/04/07 13:42:53 trasz Exp $ .\" .Dd June 4, 1993 .Dt STRSPN 3 @@ -59,8 +55,15 @@ spans the initial part of the null-terminated string .Fa s1 , as long as the characters from .Fa s1 -occur in string +occur in the null-terminated string .Fa s2 . +In other words, it computes the string array index in +.Fa s1 +of the first character of +.Fa s1 +which is not in +.Fa s2 , +else the index of the first null character. .Sh RETURN VALUES The .Fn strspn @@ -74,7 +77,8 @@ returns the number of characters spanned. .Xr strrchr 3 , .Xr strsep 3 , .Xr strstr 3 , -.Xr strtok 3 +.Xr strtok 3 , +.Xr wcsspn 3 .Sh STANDARDS The .Fn strspn diff --git a/string/strstr.3 b/string/strstr.3 index 1654b96..70fbda4 100644 --- a/string/strstr.3 +++ b/string/strstr.3 @@ -14,10 +14,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strstr.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strstr.3,v 1.12 2001/11/20 14:11:07 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strstr.3,v 1.15 2009/04/07 13:42:53 trasz Exp $ .\" .Dd October 11, 2001 .Dt STRSTR 3 @@ -168,6 +164,7 @@ ptr = strnstr(largestring, smallstring, 4); .Xr strsep 3 , .Xr strspn 3 , .Xr strtok 3 , +.Xr wcsstr 3 , .Xr xlocale 3 .Sh STANDARDS The diff --git a/string/strtok.3 b/string/strtok.3 index 7322193..25b9179 100644 --- a/string/strtok.3 +++ b/string/strtok.3 @@ -22,12 +22,6 @@ .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" -.\" 3. All advertising materials mentioning features or use of this -.\" software must display the following acknowledgement: -.\" -.\" This product includes software developed by Softweyr LLC, the -.\" University of California, Berkeley, and its contributors. -.\" .\" 4. Neither the name of Softweyr LLC, the University nor the names .\" of its contributors may be used to endorse or promote products .\" derived from this software without specific prior written @@ -48,7 +42,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtok.3 8.2 (Berkeley) 2/3/94 -.\" $FreeBSD: src/lib/libc/string/strtok.3,v 1.24 2002/12/18 12:45:11 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strtok.3,v 1.26 2007/12/12 18:33:06 wes Exp $ .\" .Dd November 27, 1998 .Dt STRTOK 3 @@ -162,6 +156,14 @@ The function conforms to .St -isoC . +.Sh AUTHORS +.An Wes Peters , +Softweyr LLC: +.Aq wes@softweyr.com +.Pp +Based on the +.Fx 3.0 +implementation. .Sh BUGS The System V .Fn strtok , @@ -175,11 +177,3 @@ value. Since this implementation always alters the next starting point, such a sequence of calls would always return .Dv NULL . -.Sh AUTHORS -.An Wes Peters , -Softweyr LLC: -.Aq wes@softweyr.com -.Pp -Based on the -.Fx 3.0 -implementation. diff --git a/string/strxfrm-fbsd.c b/string/strxfrm-fbsd.c index d365c98..b1a70dd 100644 --- a/string/strxfrm-fbsd.c +++ b/string/strxfrm-fbsd.c @@ -26,7 +26,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strxfrm.c,v 1.15 2002/09/06 11:24:06 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strxfrm.c,v 1.17 2008/10/19 09:10:44 delphij Exp $"); #include "xlocale_private.h" @@ -80,18 +80,8 @@ strxfrm_l(char * __restrict dest, const char * __restrict src, size_t len, } NORMALIZE_LOCALE(loc); - if (loc->__collate_load_error || (wcs = __collate_mbstowcs(src, loc)) == NULL) { - slen = strlen(src); - if (len > 0) { - if (slen < len) - strcpy(dest, src); - else { - strncpy(dest, src, len - 1); - dest[len - 1] = '\0'; - } - } - return slen; - } + if (loc->__collate_load_error || (wcs = __collate_mbstowcs(src, loc)) == NULL) + return strlcpy(dest, src, len); __collate_xfrm(wcs, xf, loc); diff --git a/string/strxfrm.3 b/string/strxfrm.3 index 5412422..d6ded5b 100644 --- a/string/strxfrm.3 +++ b/string/strxfrm.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -34,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strxfrm.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strxfrm.3,v 1.17 2002/10/15 10:11:53 tjr Exp $ +.\" $FreeBSD: src/lib/libc/string/strxfrm.3,v 1.18 2007/01/09 00:28:12 imp Exp $ .\" .Dd June 4, 1993 .Dt STRXFRM 3 diff --git a/string/swab-fbsd.c b/string/swab-fbsd.c index 41d3b24..1d55327 100644 --- a/string/swab-fbsd.c +++ b/string/swab-fbsd.c @@ -13,10 +13,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,9 +34,9 @@ static char sccsid[] = "@(#)swab.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/swab.c,v 1.5 2002/08/30 20:33:05 robert Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/swab.c,v 1.7 2007/01/09 00:28:12 imp Exp $"); -#include +#include void swab(const void * __restrict from, void * __restrict to, ssize_t len) diff --git a/string/swab.3 b/string/swab.3 index 42b8a9d..82468db 100644 --- a/string/swab.3 +++ b/string/swab.3 @@ -9,10 +9,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)swab.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/swab.3,v 1.7 2002/08/30 21:18:39 robert Exp $ +.\" $FreeBSD: src/lib/libc/string/swab.3,v 1.10 2007/01/09 00:28:12 imp Exp $ .\" -.Dd June 4, 1993 +.Dd February 24, 2010 .Dt SWAB 3 .Os .Sh NAME @@ -61,24 +57,19 @@ swapping adjacent bytes. .Pp The argument .Fa nbytes -must be an even number. -.Sh LEGACY SYNOPSIS -.Fd #include -.Pp -.Ft void -.br -.Fo swab -.Fa "const void *restrict src" -.Fa "void *restrict dest" -.Fa "size_t nbytes" -.Fc ; -.Pp -The include file -.In string.h -is necessary for this function. -The type of +should be an even number. If +.Fa nbytes +is odd, +.Fn swab +copies and exchanges .Fa nbytes -has changed. +-1 bytes and the disposition of the last byte is unspecified. +If copying takes place between objects that overlap, +the behavior is undefined. If +.Fa nbytes +is negative, +.Fn swab +does nothing. .Sh SEE ALSO .Xr bzero 3 , .Xr memset 3 , diff --git a/string/wcpcpy-fbsd.c b/string/wcpcpy-fbsd.c new file mode 120000 index 0000000..e189c60 --- /dev/null +++ b/string/wcpcpy-fbsd.c @@ -0,0 +1 @@ +./wcpcpy.c \ No newline at end of file diff --git a/string/wcpncpy-fbsd.c b/string/wcpncpy-fbsd.c new file mode 120000 index 0000000..7ca173a --- /dev/null +++ b/string/wcpncpy-fbsd.c @@ -0,0 +1 @@ +./wcpncpy.c \ No newline at end of file diff --git a/string/wcscasecmp-fbsd.c b/string/wcscasecmp-fbsd.c new file mode 100644 index 0000000..f158b14 --- /dev/null +++ b/string/wcscasecmp-fbsd.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/string/wcscasecmp.c,v 1.1 2009/02/28 06:00:58 das Exp $"); + +#include "xlocale_private.h" + +#include +#include + +int +wcscasecmp_l(const wchar_t *s1, const wchar_t *s2, locale_t loc) +{ + wchar_t c1, c2; + + for (; *s1; s1++, s2++) { + c1 = towlower_l(*s1, loc); + c2 = towlower_l(*s2, loc); + if (c1 != c2) + return ((int)c1 - c2); + } + return (-*s2); +} + +int +wcscasecmp(const wchar_t *s1, const wchar_t *s2) { + return wcscasecmp_l(s1, s2, __current_locale()); +} + diff --git a/string/wcscoll.3 b/string/wcscoll.3 index 5ffe761..df534cb 100644 --- a/string/wcscoll.3 +++ b/string/wcscoll.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)strcoll.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/string/strcoll.3,v 1.11 2001/10/01 16:09:00 ru Exp -.\" $FreeBSD: src/lib/libc/string/wcscoll.3,v 1.2 2002/12/09 14:04:05 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/wcscoll.3,v 1.3 2007/01/09 00:28:12 imp Exp $ .\" .Dd October 4, 2002 .Dt WCSCOLL 3 diff --git a/string/wcsdup-fbsd.c b/string/wcsdup-fbsd.c new file mode 120000 index 0000000..9cb882c --- /dev/null +++ b/string/wcsdup-fbsd.c @@ -0,0 +1 @@ +./wcsdup.c \ No newline at end of file diff --git a/string/wcsncasecmp-fbsd.c b/string/wcsncasecmp-fbsd.c new file mode 100644 index 0000000..167fac1 --- /dev/null +++ b/string/wcsncasecmp-fbsd.c @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2009 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/string/wcsncasecmp.c,v 1.1 2009/02/28 06:00:58 das Exp $"); + +#include "xlocale_private.h" + +#include +#include + +int +wcsncasecmp_l(const wchar_t *s1, const wchar_t *s2, size_t n, locale_t loc) +{ + wchar_t c1, c2; + + if (n == 0) + return (0); + for (; *s1; s1++, s2++) { + c1 = towlower_l(*s1, loc); + c2 = towlower_l(*s2, loc); + if (c1 != c2) + return ((int)c1 - c2); + if (--n == 0) + return (0); + } + return (-*s2); +} + +int +wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) { + return wcsncasecmp_l(s1, s2, n, __current_locale()); +} + diff --git a/string/wcsnlen-fbsd.c b/string/wcsnlen-fbsd.c new file mode 120000 index 0000000..a87c777 --- /dev/null +++ b/string/wcsnlen-fbsd.c @@ -0,0 +1 @@ +./wcsnlen.c \ No newline at end of file diff --git a/string/wcswidth-fbsd.c b/string/wcswidth-fbsd.c index 798590d..447c8e5 100644 --- a/string/wcswidth-fbsd.c +++ b/string/wcswidth-fbsd.c @@ -18,10 +18,6 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -40,7 +36,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/wcswidth.c,v 1.6 2002/08/20 02:06:28 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcswidth.c,v 1.7 2007/01/09 00:28:12 imp Exp $"); #include "xlocale_private.h" diff --git a/string/wcsxfrm.3 b/string/wcsxfrm.3 index f54a02b..038c7c7 100644 --- a/string/wcsxfrm.3 +++ b/string/wcsxfrm.3 @@ -13,10 +13,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -35,7 +31,7 @@ .\" .\" @(#)strxfrm.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/string/strxfrm.3,v 1.16 2002/09/06 11:24:06 tjr Exp -.\" $FreeBSD: src/lib/libc/string/wcsxfrm.3,v 1.2 2002/12/09 14:04:05 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/wcsxfrm.3,v 1.3 2007/01/09 00:28:12 imp Exp $ .\" .Dd October 4, 2002 .Dt WCSXFRM 3 diff --git a/string/wmemchr.3 b/string/wmemchr.3 index 8638b59..2e1d3ec 100644 --- a/string/wmemchr.3 +++ b/string/wmemchr.3 @@ -15,10 +15,6 @@ .\" 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -37,23 +33,29 @@ .\" .\" from: @(#)strcpy.3 8.1 (Berkeley) 6/4/93 .\" -.\" $FreeBSD: src/lib/libc/string/wmemchr.3,v 1.6 2002/09/07 04:07:00 tjr Exp $ +.\" $FreeBSD: src/lib/libc/string/wmemchr.3,v 1.10 2009/03/04 06:01:27 das Exp $ .\" -.Dd December 22, 2000 +.Dd March 4, 2009 .Dt WMEMCHR 3 .Os .Sh NAME +.Nm wcpcpy , +.Nm wcpncpy , +.Nm wcscasecmp , .Nm wcscat , .Nm wcschr , .Nm wcscmp , .Nm wcscpy , .Nm wcscspn , +.Nm wcsdup , .Nm wcslcat , .Nm wcslcpy , .Nm wcslen , +.Nm wcsncasecmp , .Nm wcsncat , .Nm wcsncmp , .Nm wcsncpy , +.Nm wcsnlen , .Nm wcspbrk , .Nm wcsrchr , .Nm wcsspn , @@ -69,119 +71,68 @@ .Sh SYNOPSIS .In wchar.h .Ft wchar_t * -.Fo wcscat -.Fa "wchar_t *restrict ws1" -.Fa "const wchar_t *restrict ws2" -.Fc +.Fn wcpcpy "wchar_t *s1" "wchar_t *s2" .Ft wchar_t * -.Fo wcschr -.Fa "const wchar_t *ws" -.Fa "wchar_t wc" -.Fc +.Fn wcpncpy "wchar_t *s1" "wchar_t *s2" "size_t n" .Ft int -.Fo wcscmp -.Fa "const wchar_t *ws1" -.Fa "const wchar_t *ws2" -.Fc +.Fn wcscasecmp "const wchar_t *s1" "const wchar_t *s2" .Ft wchar_t * -.Fo wcscpy -.Fa "wchar_t *restrict ws1" -.Fa "const wchar_t *restrict ws2" -.Fc +.Fn wcscat "wchar_t * restrict s1" "const wchar_t * restrict s2" +.Ft wchar_t * +.Fn wcschr "const wchar_t *s" "wchar_t c" +.Ft int +.Fn wcscmp "const wchar_t *s1" "const wchar_t *s2" +.Ft wchar_t * +.Fn wcscpy "wchar_t * restrict s1" "const wchar_t * restrict s2" .Ft size_t -.Fo wcscspn -.Fa "const wchar_t *ws1" -.Fa "const wchar_t *ws2" -.Fc +.Fn wcscspn "const wchar_t *s1" "const wchar_t *s2" +.Ft wchar_t * +.Fn wcsdup "const wchar_t *s" .Ft size_t -.Fo wcslcat -.Fa "wchar_t *ws1" -.Fa "const wchar_t *ws2" -.Fa "size_t n" -.Fc +.Fn wcslcat "wchar_t *s1" "const wchar_t *s2" "size_t n" .Ft size_t -.Fo wcslcpy -.Fa "wchar_t *ws1" -.Fa "const wchar_t *ws2" -.Fa "size_t n" -.Fc +.Fn wcslcpy "wchar_t *s1" "const wchar_t *s2" "size_t n" .Ft size_t -.Fo wcslen -.Fa "const wchar_t *ws" -.Fc +.Fn wcslen "const wchar_t *s" +.Ft int +.Fn wcsncasecmp "const wchar_t *s1" "const wchar_t *s2" "size_t n" .Ft wchar_t * -.Fo wcsncat -.Fa "wchar_t *restrict ws1" -.Fa "const wchar_t *restrict ws2" -.Fa "size_t n" -.Fc +.Fn wcsncat "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" .Ft int -.Fo wcsncmp -.Fa "const wchar_t *ws1" -.Fa "const wchar_t *ws2" -.Fa "size_t n" -.Fc +.Fn wcsncmp "const wchar_t *s1" "const wchar_t * s2" "size_t n" .Ft wchar_t * -.Fo wcsncpy -.Fa "wchar_t *restrict ws1" -.Fa "const wchar_t *restrict ws2" -.Fa "size_t n" -.Fc +.Fn wcsncpy "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" +.Ft size_t +.Fn wcsnlen "const wchar_t *s" "size_t maxlen" .Ft wchar_t * -.Fo wcspbrk -.Fa "const wchar_t *ws1" -.Fa "const wchar_t *ws2" -.Fc +.Fn wcspbrk "const wchar_t *s1" "const wchar_t *s2" .Ft wchar_t * -.Fo wcsrchr -.Fa "const wchar_t *ws" -.Fa "wchar_t wc" -.Fc +.Fn wcsrchr "const wchar_t *s" "wchar_t c" .Ft size_t -.Fo wcsspn -.Fa "const wchar_t *ws1" -.Fa "const wchar_t *ws2" -.Fc +.Fn wcsspn "const wchar_t *s1" "const wchar_t *s2" .Ft wchar_t * -.Fo wcsstr -.Fa "const wchar_t *restrict ws1" -.Fa "const wchar_t *restrict ws2" -.Fc +.Fn wcsstr "const wchar_t * restrict s1" "const wchar_t * restrict s2" .Ft wchar_t * -.Fo wmemchr -.Fa "const wchar_t *ws" -.Fa "wchar_t wc" -.Fa "size_t n" -.Fc +.Fn wmemchr "const wchar_t *s" "wchar_t c" "size_t n" .Ft int -.Fo wmemcmp -.Fa "const wchar_t *ws1" -.Fa "const wchar_t *ws2" -.Fa "size_t n" -.Fc +.Fn wmemcmp "const wchar_t *s1" "const wchar_t *s2" "size_t n" .Ft wchar_t * -.Fo wmemcpy -.Fa "wchar_t *restrict ws1" -.Fa "const wchar_t *restrict ws2" -.Fa "size_t n" -.Fc +.Fn wmemcpy "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" .Ft wchar_t * -.Fo wmemmove -.Fa "wchar_t *ws1" -.Fa "const wchar_t *ws2" -.Fa "size_t n" -.Fc +.Fn wmemmove "wchar_t *s1" "const wchar_t *s2" "size_t n" .Ft wchar_t * -.Fo wmemset -.Fa "wchar_t *ws" -.Fa "wchar_t wc" -.Fa "size_t n" -.Fc +.Fn wmemset "wchar_t *s" "wchar_t c" "size_t n" +.In wchar.h +.In xlocale.h +.Ft int +.Fn wcscasecmp_l "const wchar_t *s1" "const wchar_t *s2" "locale_t loc" +.Ft int +.Fn wcsncasecmp_l "const wchar_t *s1" "const wchar_t *s2" "size_t n" "locale_t loc" .Sh DESCRIPTION -The functions implement string manipulation operations -over wide character strings. -For a detailed description, -refer to documents for the respective single-byte counterpart, such as +The functions implement string manipulation operations over wide character +strings. +For a detailed description, refer to documents for the respective single-byte +counterpart, such as .Xr memchr 3 . .Sh SEE ALSO .Xr memchr 3 , @@ -189,25 +140,46 @@ refer to documents for the respective single-byte counterpart, such as .Xr memcpy 3 , .Xr memmove 3 , .Xr memset 3 , +.Xr stpcpy 3 , +.Xr stpncpy 3 , +.Xr strcasecmp 3 , +.Xr strcasecmp_l 3 , .Xr strcat 3 , .Xr strchr 3 , .Xr strcmp 3 , .Xr strcpy 3 , .Xr strcspn 3 , +.Xr strdup 3 , .Xr strlcat 3 , .Xr strlcpy 3 , .Xr strlen 3 , +.Xr strncasecmp 3 , +.Xr strncasecmp_l 3 , .Xr strncat 3 , .Xr strncmp 3 , .Xr strncpy 3 , +.Xr strnlen 3 , .Xr strpbrk 3 , .Xr strrchr 3 , .Xr strspn 3 , -.Xr strstr 3 +.Xr strstr 3 , +.Xr xlocale 3 .Sh STANDARDS These functions conform to .St -isoC-99 , with the exception of +.Fn wcpcpy , +.Fn wcpncpy , +.Fn wcscasecmp , +.Fn wcscasecmp_l , +.Fn wcsdup , +.Fn wcsncasecmp , +.Fn wcsncasecmp_l , +and +.Fn wcsnlen , +which conform to +.St -p1003.1-2008 ; +and .Fn wcslcat and .Fn wcslcpy , diff --git a/sys/Makefile.inc b/sys/Makefile.inc index b16e72d..5036958 100644 --- a/sys/Makefile.inc +++ b/sys/Makefile.inc @@ -11,18 +11,16 @@ CWD := ${.CURDIR}/sys # Sources common to both syscall interfaces: -MISRCS += chmod.c chmodx_np.c crt_externs.c \ - errno.c fchmod.c \ - getiopolicy_np.c getrlimit.c gettimeofday.c \ - kill.c __libc_init.c \ - mmap.c \ +MISRCS += chmodx_np.c crt_externs.c \ + errno.c fork.c \ + getiopolicy_np.c gettimeofday.c \ + __libc_init.c _libc_fork_child.c \ openx_np.c \ posix_spawn.c \ - remove_counter.c rename.c rmdir.c \ - select.c setrlimit.c settimeofday.c \ - sigaction.c sigcatch.c sigsuspend.c \ - sigtramp.c statx_np.c \ - umaskx_np.c unlink.c + settimeofday.c \ + sigaction.c sigcatch.c \ + sigtramp.c slot_name.c statx_np.c \ + umaskx_np.c .ifdef FEATURE_MEM_THERM_NOTIFICATION_APIS MISRCS += OSMemoryNotification.c OSThermalNotification.c @@ -40,33 +38,15 @@ MISRCS+= context-stubs.c OBSDMISRCS= stack_protector.c .include "Makefile.obsd_end" -.ifdef FEATURE_PATCH_3375657 -# patches for sem_open() sem_unlink() shm_open() shm_unlink() -MISRCS+= fix-3375657.c sem_open.c sem_unlink.c shm_open.c shm_unlink.c -.endif # FEATURE_PATCH_3375657 - DARWINEXTSNSRCS += getgroups.c INODE32SRCS += statx_np.c -CANCELABLESRCS += select.c sigsuspend.c +DYLDSRCS += errno.c -.if defined(LP64) || (${MACHINE_ARCH} == arm) -CANCELABLESRCS+= fcntl.c -MISRCS+= fcntl.c ioctl.c -.endif -.if defined(LP64) -PRE1050SRCS+= select.c -.endif - -LEGACYSRCS += accept.c bind.c connect.c \ - getattrlist.c getpeername.c getsockname.c \ - kill.c lchown.c listen.c \ - mprotect.c msgctl.c msync.c munmap.c \ - open.c \ - recvfrom.c recvmsg.c \ - select.c semctl.c sendmsg.c sendto.c setattrlist.c \ - shmctl.c sigsuspend.c socketpair.c +LEGACYSRCS += msgctl.c \ + semctl.c \ + shmctl.c .for _src in msgctl.c semctl.c shmctl.c CFLAGS-${_src} += -DKERNEL @@ -86,24 +66,16 @@ CFLAGS-chmod.c += -DLIBC_ALIAS_CHMOD #CFLAGS-close.c += -DLIBC_ALIAS_CLOSE CFLAGS-connect.c += -DLIBC_ALIAS_CONNECT CFLAGS-fchmod.c += -DLIBC_ALIAS_FCHMOD -CFLAGS-fcntl.c += -DLIBC_ALIAS_FCNTL #CFLAGS-fsync.c += -DLIBC_ALIAS_FSYNC CFLAGS-getattrlist.c += -DLIBC_ALIAS_GETATTRLIST CFLAGS-getpeername.c += -DLIBC_ALIAS_GETPEERNAME -CFLAGS-getrlimit.c += -DLIBC_ALIAS_GETRLIMIT CFLAGS-getsockname.c += -DLIBC_ALIAS_GETSOCKNAME -CFLAGS-kill.c += -DLIBC_ALIAS_KILL CFLAGS-lchmod.c += -DLIBC_ALIAS_LCHMOD CFLAGS-lchown.c += -DLIBC_ALIAS_LCHOWN CFLAGS-listen.c += -DLIBC_ALIAS_LISTEN -CFLAGS-mmap.c += -DLIBC_ALIAS_MMAP -CFLAGS-mprotect.c += -DLIBC_ALIAS_MPROTECT CFLAGS-msgctl.c += -DLIBC_ALIAS_MSGCTL #CFLAGS-msgrcv.c += -DLIBC_ALIAS_MSGRCV #CFLAGS-msgsnd.c += -DLIBC_ALIAS_MSGSND -CFLAGS-msync.c += -DLIBC_ALIAS_MSYNC -CFLAGS-munmap.c += -DLIBC_ALIAS_MUNMAP -#CFLAGS-open.c += -DLIBC_ALIAS_OPEN #CFLAGS-poll.c += -DLIBC_ALIAS_POLL #CFLAGS-pread.c += -DLIBC_ALIAS_PREAD #CFLAGS-pwrite.c += -DLIBC_ALIAS_PWRITE @@ -111,28 +83,21 @@ CFLAGS-munmap.c += -DLIBC_ALIAS_MUNMAP #CFLAGS-readv.c += -DLIBC_ALIAS_READV CFLAGS-recvfrom.c += -DLIBC_ALIAS_RECVFROM CFLAGS-recvmsg.c += -DLIBC_ALIAS_RECVMSG -CFLAGS-select.c += -DLIBC_ALIAS_SELECT #CFLAGS-sem_wait.c += -DLIBC_ALIAS_SEM_WAIT CFLAGS-semctl.c += -DLIBC_ALIAS_SEMCTL CFLAGS-sendmsg.c += -DLIBC_ALIAS_SENDMSG CFLAGS-sendto.c += -DLIBC_ALIAS_SENDTO CFLAGS-setattrlist.c += -DLIBC_ALIAS_SETATTRLIST -CFLAGS-setrlimit.c += -DLIBC_ALIAS_SETRLIMIT CFLAGS-shmctl.c += -DLIBC_ALIAS_SHMCTL -CFLAGS-sigsuspend.c += -DLIBC_ALIAS_SIGSUSPEND CFLAGS-socketpair.c += -DLIBC_ALIAS_SOCKETPAIR +CFLAGS-stack_protector-obsd.c += -fno-stack-protector #CFLAGS-waitid.c += -DLIBC_ALIAS_WAITID #CFLAGS-write.c += -DLIBC_ALIAS_WRITE #CFLAGS-writev.c += -DLIBC_ALIAS_WRITEV -COPYFILES+= ${.CURDIR}/sys/libc.syscall - .if ${LIB} == "c" MAN2+= pthread_kill.2 pthread_sigmask.2 \ - sem_close.2 sem_open.2 sem_post.2 \ - sem_unlink.2 sem_wait.2 shm_open.2 shm_unlink.2 \ - sigwait.2 getdtablesize.2 setreuid.2 setregid.2 \ - nanosleep.2 undelete.2 + sigwait.2 nanosleep.2 MAN3+= atomic.3 barrier.3 getiopolicy_np.3 spinlock.3 cache.3 MLINKS+= atomic.3 OSAtomicAdd32.3 MLINKS+= atomic.3 OSAtomicAdd32Barrier.3 @@ -178,7 +143,6 @@ MLINKS+= barrier.3 OSMemoryBarrier.3 MLINKS+= getiopolicy_np.3 setiopolicy_np.3 -MLINKS+= sem_wait.2 sem_trywait.2 MLINKS+= cache.3 sys_cache_control.3 MLINKS+= cache.3 sys_icache_invalidate.3 MLINKS+= cache.3 sys_dcache_flush.3 @@ -196,25 +160,25 @@ MLINKS+= spinlock.3 OSSpinLockLock.3 \ # fcntl.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 \ -# getpeername.2 getpgrp.2 getpid.2 getpriority.2 getrlimit.2 \ +# getpeername.2 getpgrp.2 getpid.2 getpriority.2 \ # getrusage.2 getsid.2 getsockname.2 \ # getsockopt.2 gettimeofday.2 getuid.2 \ -# intro.2 ioctl.2 issetugid.2 jail.2 kill.2 \ +# intro.2 ioctl.2 issetugid.2 jail.2 \ # kldfind.2 kldfirstmod.2 kldload.2 kldnext.2 kldstat.2 kldsym.2 \ # kldunload.2 kqueue.2 link.2 listen.2 lseek.2 \ -# madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 mmap.2 \ +# madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 \ # modfind.2 modnext.2 modstat.2 \ -# mount.2 mprotect.2 msync.2 munmap.2 nanosleep.2 \ -# nfssvc.2 open.2 pathconf.2 pipe.2 poll.2 profil.2 ptrace.2 quotactl.2 \ -# read.2 readlink.2 reboot.2 recv.2 rename.2 revoke.2 rfork.2 rmdir.2 \ -# rtprio.2 select.2 semctl.2 semget.2 semop.2 send.2 sendfile.2 \ +# mount.2 nanosleep.2 \ +# nfssvc.2 pathconf.2 pipe.2 poll.2 profil.2 ptrace.2 quotactl.2 \ +# read.2 readlink.2 reboot.2 recv.2 revoke.2 rfork.2 \ +# rtprio.2 semctl.2 semget.2 semop.2 send.2 sendfile.2 \ # setgroups.2 setpgid.2 setregid.2 setresuid.2 setreuid.2 setsid.2 \ # setuid.2 shmat.2 shmctl.2 shmget.2 shutdown.2 \ # sigaction.2 sigaltstack.2 sigpending.2 sigprocmask.2 sigreturn.2 \ -# sigstack.2 sigsuspend.2 socket.2 socketpair.2 stat.2 statfs.2 \ +# sigstack.2 socket.2 socketpair.2 stat.2 statfs.2 \ # swapon.2 symlink.2 sync.2 sysarch.2 syscall.2 \ # truncate.2 umask.2 undelete.2 \ -# unlink.2 utimes.2 vfork.2 wait.2 write.2 +# utimes.2 vfork.2 wait.2 write.2 #.if !defined(NO_P1003_1B) #MAN+= sched_get_priority_max.2 sched_setparam.2 \ # sched_setscheduler.2 sched_yield.2 @@ -243,7 +207,6 @@ MLINKS+= spinlock.3 OSSpinLockLock.3 \ #MLINKS+=getpgrp.2 getpgid.2 #MLINKS+=getpid.2 getppid.2 #MLINKS+=getpriority.2 setpriority.2 -#MLINKS+=getrlimit.2 setrlimit.2 #MLINKS+=getsockopt.2 setsockopt.2 #MLINKS+=gettimeofday.2 settimeofday.2 #MLINKS+=getuid.2 geteuid.2 diff --git a/sys/OSThermalNotification.c b/sys/OSThermalNotification.c index cd4d2b7..618bf58 100644 --- a/sys/OSThermalNotification.c +++ b/sys/OSThermalNotification.c @@ -21,24 +21,55 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include #include #include -const char *kOSThermalNotificationName = "com.apple.system.thermalstatus"; +#define OSThermalStatusName "com.apple.system.thermalstatus" -OSThermalNotificationLevel OSThermalNotificationCurrentLevel(void) -{ - uint64_t val; - int token; - - if (NOTIFY_STATUS_OK != notify_register_check(kOSThermalNotificationName, &token)) - return OSThermalNotificationLevelAny; +const char * const kOSThermalNotificationName = OSThermalStatusName; - if (NOTIFY_STATUS_OK != notify_get_state(token, &val)) - return OSThermalNotificationLevelAny; +static const char * const kOSThermalMitigationNames[kOSThermalMitigationCount] = { + OSThermalStatusName, + "com.apple.system.thermalmitigation.70percenttorch", + "com.apple.system.thermalmitigation.70percentbacklight", + "com.apple.system.thermalmitigation.50percenttorch", + "com.apple.system.thermalmitigation.50percentbacklight", + "com.apple.system.thermalmitigation.disabletorch", + "com.apple.system.thermalmitigation.25percentbacklight", + "com.apple.system.thermalmitigation.disablemapshalo", + "com.apple.system.thermalmitigation.appterminate", + "com.apple.system.thermalmitigation.devicerestart" +}; - if (NOTIFY_STATUS_OK != notify_cancel(token)) - return OSThermalNotificationLevelAny; +static int tokens[kOSThermalMitigationCount]; +static dispatch_once_t predicates[kOSThermalMitigationCount]; +OSThermalNotificationLevel _OSThermalNotificationLevelForBehavior(int behavior) +{ + uint64_t val = OSThermalNotificationLevelAny; + if (behavior >= 0 && behavior < kOSThermalMitigationCount) { + dispatch_once(&predicates[behavior], ^{ + (void)notify_register_check(kOSThermalMitigationNames[behavior], &tokens[behavior]); + }); + (void)notify_get_state(tokens[behavior], &val); + } return (OSThermalNotificationLevel)val; } + +void _OSThermalNotificationSetLevelForBehavior(int level, int behavior) +{ + uint64_t val = (uint64_t)level; + if (behavior >= 0 && behavior < kOSThermalMitigationCount) { + dispatch_once(&predicates[behavior], ^{ + (void)notify_register_check(kOSThermalMitigationNames[behavior], &tokens[behavior]); + }); + (void)notify_set_state(tokens[behavior], val); + } +} + + +OSThermalNotificationLevel OSThermalNotificationCurrentLevel(void) +{ + return _OSThermalNotificationLevelForBehavior(kOSThermalMitigationNone); +} diff --git a/sys/OpenBSD/stack_protector.c b/sys/OpenBSD/stack_protector.c index 368e365..7b96532 100644 --- a/sys/OpenBSD/stack_protector.c +++ b/sys/OpenBSD/stack_protector.c @@ -1,3 +1,5 @@ +/* $OpenBSD: stack_protector.c,v 1.10 2006/03/31 05:34:44 deraadt Exp $ */ + /* * Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat. * All rights reserved. @@ -25,13 +27,14 @@ * */ -#if defined(LIBC_SCCS) && !defined(list) -static char rcsid[] = "$OpenBSD: stack_protector.c,v 1.3 2002/12/10 08:53:42 etoh Exp $"; -#endif - #include #include +#include +#include #include +#include + +extern int __sysctl(int *, u_int, void *, size_t *, void *, size_t); long __guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; static void __guard_setup(void) __attribute__ ((constructor)); @@ -40,36 +43,50 @@ void __stack_smash_handler(char func[], int damaged __attribute__((unused))); static void __guard_setup(void) { - int fd; - if (__guard[0]!=0) return; - fd = open ("/dev/urandom", 0); - if (fd != -1) { - ssize_t size = read (fd, (char*)&__guard, sizeof(__guard)); - close (fd) ; - if (size == sizeof(__guard)) return; - } - /* If a random generator can't be used, the protector switches the guard - to the "terminator canary" */ - ((char*)__guard)[0] = 0; ((char*)__guard)[1] = 0; - ((char*)__guard)[2] = '\n'; ((char*)__guard)[3] = 255; + int mib[2]; + size_t len; + + if (__guard[0] != 0) + return; + + mib[0] = CTL_KERN; + mib[1] = KERN_ARND; + + len = sizeof(__guard); + if (__sysctl(mib, 2, __guard, &len, NULL, 0) == -1 || + len != sizeof(__guard)) { + /* If sysctl was unsuccessful, use the "terminator canary". */ + ((unsigned char *)__guard)[0] = 0; + ((unsigned char *)__guard)[1] = 0; + ((unsigned char *)__guard)[2] = '\n'; + ((unsigned char *)__guard)[3] = 255; + } } +/*ARGSUSED*/ void __stack_smash_handler(char func[], int damaged) { - const char message[] = "stack overflow in function %s"; - struct sigaction sa; + struct syslog_data sdata = SYSLOG_DATA_INIT; + const char message[] = "stack overflow in function %s"; + struct sigaction sa; + sigset_t mask; + + /* Immediately block all signal handlers from running code */ + sigfillset(&mask); + sigdelset(&mask, SIGABRT); + sigprocmask(SIG_BLOCK, &mask, NULL); - /* this may fail on a chroot jail, though luck */ - syslog(LOG_CRIT, message, func); + /* This may fail on a chroot jail... */ + syslog_r(LOG_CRIT, &sdata, message, func); - bzero(&sa, sizeof(struct sigaction)); - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - sigaction(SIGABRT, &sa, NULL); + bzero(&sa, sizeof(struct sigaction)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + sigaction(SIGABRT, &sa, NULL); - kill(getpid(), SIGABRT); + kill(getpid(), SIGABRT); - _exit(127); + _exit(127); } diff --git a/sys/OpenBSD/stack_protector.c.patch b/sys/OpenBSD/stack_protector.c.patch index e6766cc..403b664 100644 --- a/sys/OpenBSD/stack_protector.c.patch +++ b/sys/OpenBSD/stack_protector.c.patch @@ -1,69 +1,157 @@ -Index: stack_protector.c -=================================================================== ---- stack_protector.c (revision 31377) -+++ stack_protector.c (working copy) -@@ -32,44 +32,41 @@ static char rcsid[] = "$OpenBSD: stack_p +--- stack_protector.c.orig 2010-10-07 09:55:01.000000000 -0700 ++++ stack_protector.c 2010-10-07 09:55:30.000000000 -0700 +@@ -28,65 +28,112 @@ + */ + #include - #include - #include +-#include + #include + #include +-#include ++#include ++#include + #include +#include -+#include +#include ++#include "CrashReporterClient.h" ++#include "libproc.h" ++#include "_simple.h" + -+extern void __abort(void) __dead2; -+long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -+void __guard_setup(void) __attribute__ ((visibility ("hidden"))); ++#define GUARD_MAX 8 ++long __stack_chk_guard[GUARD_MAX] = {0, 0, 0, 0, 0, 0, 0, 0}; ++void __abort(void) __dead2; ++void __guard_setup(const char *apple[]) __attribute__ ((visibility ("hidden"))); +void __stack_chk_fail(void); +-extern int __sysctl(int *, u_int, void *, size_t *, void *, size_t); ++static void ++__guard_from_kernel(const char *str) ++{ ++ unsigned long long val; ++ char tmp[20], *p; ++ int idx = 0; ++ ++ /* Skip over the 'stack_guard=' key to the list of values */ ++ str = strchr(str, '='); ++ if (str == NULL) ++ return; ++ str++; + -long __guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -static void __guard_setup(void) __attribute__ ((constructor)); -void __stack_smash_handler(char func[], int damaged __attribute__((unused))); -- ++ while (str && idx < GUARD_MAX) { ++ /* ++ * Pull the next numeric string out of the list and convert it to ++ * a real number. ++ */ ++ strlcpy(tmp, str, 20); ++ p = strchr(tmp, ','); ++ if (p) ++ *p = '\0'; ++ val = strtoull(tmp, NULL, 0); ++ __stack_chk_guard[idx] = (long)(val & ((unsigned long) -1)); ++ idx++; ++ if ((str = strchr(str, ',')) != NULL) ++ str++; ++ } ++} + -static void +-__guard_setup(void) +void - __guard_setup(void) ++__guard_setup(const char *apple[]) { - int fd; -- if (__guard[0]!=0) return; -+ if (__stack_chk_guard[0]!=0) return; - fd = open ("/dev/urandom", 0); - if (fd != -1) { -- ssize_t size = read (fd, (char*)&__guard, sizeof(__guard)); -+ ssize_t size = read (fd, (char*)&__stack_chk_guard, -+ sizeof(__stack_chk_guard)); - close (fd) ; -- if (size == sizeof(__guard)) return; -+ if (size == sizeof(__stack_chk_guard) -+ && *__stack_chk_guard != 0) return; - } - /* If a random generator can't be used, the protector switches the guard - to the "terminator canary" */ -- ((char*)__guard)[0] = 0; ((char*)__guard)[1] = 0; -- ((char*)__guard)[2] = '\n'; ((char*)__guard)[3] = 255; -+ ((char*)__stack_chk_guard)[0] = 0; ((char*)__stack_chk_guard)[1] = 0; -+ ((char*)__stack_chk_guard)[2] = '\n'; ((char*)__stack_chk_guard)[3] = 255; +- int mib[2]; ++ int fd; + size_t len; ++ const char **p; + +- if (__guard[0] != 0) ++ if (__stack_chk_guard[0] != 0) + return; + +- mib[0] = CTL_KERN; +- mib[1] = KERN_ARND; ++ for (p = apple; p && *p; p++) { ++ if (strstr(*p, "stack_guard") == *p) { ++ __guard_from_kernel(*p); ++ if (__stack_chk_guard[0] != 0) ++ return; ++ } ++ } + +- len = sizeof(__guard); +- if (__sysctl(mib, 2, __guard, &len, NULL, 0) == -1 || +- len != sizeof(__guard)) { +- /* If sysctl was unsuccessful, use the "terminator canary". */ +- ((unsigned char *)__guard)[0] = 0; +- ((unsigned char *)__guard)[1] = 0; +- ((unsigned char *)__guard)[2] = '\n'; +- ((unsigned char *)__guard)[3] = 255; ++ fd = open ("/dev/urandom", 0); ++ if (fd != -1) { ++ len = read (fd, (char*)&__stack_chk_guard, sizeof(__stack_chk_guard)); ++ close(fd); ++ if (len == sizeof(__stack_chk_guard) && ++ *__stack_chk_guard != 0) ++ return; + } ++ ++ /* If If a random generator can't be used, the protector switches the guard ++ to the "terminator canary" */ ++ ((unsigned char *)__stack_chk_guard)[0] = 0; ++ ((unsigned char *)__stack_chk_guard)[1] = 0; ++ ((unsigned char *)__stack_chk_guard)[2] = '\n'; ++ ((unsigned char *)__stack_chk_guard)[3] = 255; } +-/*ARGSUSED*/ ++#define STACKOVERFLOW "] stack overflow" ++ void -__stack_smash_handler(char func[], int damaged) +__stack_chk_fail() { -- const char message[] = "stack overflow in function %s"; -- struct sigaction sa; -+ const char message[] = "[%d] stack overflow"; - - /* this may fail on a chroot jail, though luck */ -- syslog(LOG_CRIT, message, func); +- struct syslog_data sdata = SYSLOG_DATA_INIT; +- const char message[] = "stack overflow in function %s"; +- struct sigaction sa; +- sigset_t mask; +- +- /* Immediately block all signal handlers from running code */ +- sigfillset(&mask); +- sigdelset(&mask, SIGABRT); +- sigprocmask(SIG_BLOCK, &mask, NULL); +- ++ char n[16]; // bigger than will hold the digits in a pid_t ++ char *np; ++ int pid = getpid(); ++ char message[sizeof(n) + sizeof(STACKOVERFLOW)] = "["; ++ char prog[2*MAXCOMLEN+1] = {0}; ++ ++ proc_name(pid, prog, 2*MAXCOMLEN); ++ prog[2*MAXCOMLEN] = 0; ++ np = n + sizeof(n); ++ *--np = 0; ++ while(pid > 0) { ++ *--np = (pid % 10) + '0'; ++ pid /= 10; ++ } ++ strlcat(message, np, sizeof(message)); ++ strlcat(message, STACKOVERFLOW, sizeof(message)); + /* This may fail on a chroot jail... */ +- syslog_r(LOG_CRIT, &sdata, message, func); - -- bzero(&sa, sizeof(struct sigaction)); -- sigemptyset(&sa.sa_mask); -- sa.sa_flags = 0; -- sa.sa_handler = SIG_DFL; -- sigaction(SIGABRT, &sa, NULL); +- bzero(&sa, sizeof(struct sigaction)); +- sigemptyset(&sa.sa_mask); +- sa.sa_flags = 0; +- sa.sa_handler = SIG_DFL; +- sigaction(SIGABRT, &sa, NULL); - -- kill(getpid(), SIGABRT); -+ syslog(LOG_CRIT, message, getpid()); +- kill(getpid(), SIGABRT); ++ _simple_asl_log_prog(ASL_LEVEL_CRIT, "user", message, prog); -- _exit(127); -+ __abort(); +- _exit(127); ++ CRSetCrashLogMessage(message); ++ __abort(); } diff --git a/sys/__libc_init.c b/sys/__libc_init.c index d365f5f..963fe1e 100644 --- a/sys/__libc_init.c +++ b/sys/__libc_init.c @@ -31,27 +31,46 @@ struct ProgramVars; /* forward reference */ extern void _program_vars_init(const struct ProgramVars *vars); +extern void _libc_fork_init(void (*prepare)(void), void (*parent)(void), void (*child)(void)); +extern void _init_clock_port(); extern pthread_lock_t _malloc_lock; extern void __xlocale_init(void); -extern void __guard_setup(void); +extern void __guard_setup(const char *apple[]); +extern void __malloc_entropy_setup(const char *apple[]); +extern int usenew_impl; #ifdef PR_5243343 /* 5243343 - temporary hack to detect if we are running the conformance test */ #include __private_extern__ int PR_5243343_flag = 0; #endif /* PR_5243343 */ +__private_extern__ int __pthread_lock_debug = 0; +__private_extern__ int __pthread_lock_old = 0; -__private_extern__ void -__libc_init(const struct ProgramVars *vars) +void +__libc_init(const struct ProgramVars *vars, void (*atfork_prepare)(void), void (*atfork_parent)(void), void (*atfork_child)(void), const char *apple[]) { _program_vars_init(vars); + _libc_fork_init(atfork_prepare, atfork_parent, atfork_child); LOCK_INIT(_malloc_lock); + _init_clock_port(); __xlocale_init(); - __guard_setup(); + __guard_setup(apple); + __malloc_entropy_setup(apple); + #ifdef PR_5243343 /* 5243343 - temporary hack to detect if we are running the conformance test */ if(getenv("TET_EXECUTE")) PR_5243343_flag = 1; #endif /* PR_5243343 */ +#if defined(__i386__) || defined(__x86_64__) + if(getenv("__PTHREAD_LOCK_DEBUG__")) + __pthread_lock_debug = 1; + if(getenv("__PTHREAD_LOCK_OLD__")) { + __pthread_lock_old = 1; + usenew_impl = 0; + } +#endif + } diff --git a/x86_64/string/bzero.s b/sys/_libc_fork_child.c similarity index 70% rename from x86_64/string/bzero.s rename to sys/_libc_fork_child.c index b5e50be..fe665cf 100644 --- a/x86_64/string/bzero.s +++ b/sys/_libc_fork_child.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,21 +20,20 @@ * * @APPLE_LICENSE_HEADER_END@ */ - /* - * Call the comm page routine + * _libc_fork_child() is called from Libsystem's libSystem_atfork_child() */ -#define __APPLE_API_PRIVATE -#include - -#include - - TEXT - ALIGN - -LEAF(_bzero,0) - movq $(_COMM_PAGE_BZERO), %rax - jmp *%rax +extern void _asl_fork_child(); +extern void _arc4_fork_child(); +extern void _init_clock_port(); +extern void _dirhelper_fork_child(); -X_LEAF(___bzero, _bzero) +void +_libc_fork_child(void) +{ + _asl_fork_child(); + _arc4_fork_child(); + _init_clock_port(); + _dirhelper_fork_child(); +} diff --git a/sys/accept.c b/sys/accept.c deleted file mode 100644 index 149ca52..0000000 --- a/sys/accept.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include -#include - -int __accept_nocancel(int, struct sockaddr *, socklen_t *); - -/* - * accept stub, legacy version - */ -int -accept(int s, struct sockaddr *addr, socklen_t *addrlen) -{ - int ret = __accept_nocancel(s, addr, addrlen); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/bind.c b/sys/bind.c deleted file mode 100644 index 01879e3..0000000 --- a/sys/bind.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include -#include - -extern int __bind(int, const struct sockaddr *, socklen_t); - -/* - * bind stub, legacy version - */ -int -bind(int s, const struct sockaddr *name, socklen_t namelen) -{ - int ret = __bind(s, name, namelen); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/chmod.c b/sys/chmod.c deleted file mode 100644 index 175316c..0000000 --- a/sys/chmod.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include - -extern int __chmod(const char *path, mode_t mode); - -/* - * chmod stub, ignore S_ISUID and/or S_ISGID on EPERM, - * mandated for conformance. - * - * This is for UNIX03 only. - */ -int -chmod(const char *path, mode_t mode) -{ - int res = __chmod(path, mode); - - if (res >= 0 || errno != EPERM || (mode & (S_ISUID | S_ISGID)) == 0) - return res; - if (mode & S_ISGID) { - res = __chmod(path, mode ^ S_ISGID); - if (res >= 0 || errno != EPERM) - return res; - } - if (mode & S_ISUID) { - res = __chmod(path, mode ^ S_ISUID); - if (res >= 0 || errno != EPERM) - return res; - } - if (mode & (S_ISUID | S_ISGID) == (S_ISUID | S_ISGID)) - res = __chmod(path, mode ^ (S_ISUID | S_ISGID)); - return res; -} diff --git a/sys/connect.c b/sys/connect.c deleted file mode 100644 index dbaade7..0000000 --- a/sys/connect.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include -#include - -int __connect_nocancel(int, const struct sockaddr *, socklen_t); - -/* - * connect stub, legacy version - */ -int -connect(int s, const struct sockaddr *name, socklen_t namelen) -{ - int ret = __connect_nocancel(s, name, namelen); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/fchmod.c b/sys/fchmod.c deleted file mode 100644 index c0c8152..0000000 --- a/sys/fchmod.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include - -extern int __fchmod(int fd, mode_t mode); - -/* - * fchmod stub, ignore S_ISUID and/or S_ISGID on EPERM, - * mandated for conformance. - * - * This is for UNIX03 only. - */ -int -fchmod(int fd, mode_t mode) -{ - int res = __fchmod(fd, mode); - - if (res >= 0 || errno != EPERM || (mode & (S_ISUID | S_ISGID)) == 0) - return res; - if (mode & S_ISGID) { - res = __fchmod(fd, mode ^ S_ISGID); - if (res >= 0 || errno != EPERM) - return res; - } - if (mode & S_ISUID) { - res = __fchmod(fd, mode ^ S_ISUID); - if (res >= 0 || errno != EPERM) - return res; - } - if (mode & (S_ISUID | S_ISGID) == (S_ISUID | S_ISGID)) - res = __fchmod(fd, mode ^ (S_ISUID | S_ISGID)); - return res; -} diff --git a/sys/fcntl.c b/sys/fcntl.c deleted file mode 100644 index 4b642f3..0000000 --- a/sys/fcntl.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2004, 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include - -#ifdef VARIANT_CANCELABLE -int __fcntl(int, int, void *); -#else /* !VARIANT_CANCELABLE */ -int __fcntl_nocancel(int, int, void *); -#endif /* VARIANT_CANCELABLE */ - -/* - * Stub function to account for the differences in the size of the third - * argument when int and void * are different sizes. Also add pthread - * cancelability. - * - * This is for LP64 only. - */ -int -fcntl(int fd, int cmd, ...) -{ - va_list ap; - void *arg; - - va_start(ap, cmd); - switch(cmd) { - case F_GETLK: - case F_SETLK: - case F_SETLKW: - case F_PREALLOCATE: - case F_SETSIZE: - case F_RDADVISE: - case F_READBOOTSTRAP: - case F_WRITEBOOTSTRAP: - case F_LOG2PHYS: - case F_GETPATH: - case F_PATHPKG_CHECK: - case F_OPENFROM: - case F_UNLINKFROM: - case F_ADDSIGS: - arg = va_arg(ap, void *); - break; - default: - arg = (void *)((unsigned long)va_arg(ap, int)); - break; - } - va_end(ap); -#ifdef VARIANT_CANCELABLE - return (__fcntl(fd, cmd, arg)); -#else /* !VARIANT_CANCELABLE */ - return (__fcntl_nocancel(fd, cmd, arg)); -#endif /* VARIANT_CANCELABLE */ -} diff --git a/sys/fix-3375657.c b/sys/fix-3375657.c deleted file mode 100644 index 0ee18e2..0000000 --- a/sys/fix-3375657.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * When mutexes or spinlocks were added for thread safety, the system would - * hang during the boot process, just after changing to the blue background. - * So for the common case of not calling _s[eh]m_hack_{add,init}(), we just - * use static name lists. This should be reinvestigated when there is time. - */ - -#define PRIVATE __private_extern__ -//#define SEM_DEBUG_FILE "/tmp/sem_names" -//#define SHM_DEBUG_FILE "/tmp/shm_names" - -#if defined(SEM_DEBUG_FILE) || defined(SHM_DEBUG_FILE) -#include -#include -#endif /* defined(SEM_DEBUG_FILE) || defined(SHM_DEBUG_FILE) */ -#include -#include -#include - -#ifdef SEM_DEBUG_FILE -#define SEM_PRINTF(fmt, args...) \ -{ \ - FILE *_sem_fp_; \ - if (access(SEM_DEBUG_FILE, F_OK) == 0 && \ - (_sem_fp_ = fopen(SEM_DEBUG_FILE, "a")) != NULL) { \ - fprintf(_sem_fp_, fmt, ## args); \ - fclose(_sem_fp_); \ - } \ -} -#endif /* SEM_DEBUG_FILE */ -#ifdef SHM_DEBUG_FILE -#define SHM_PRINTF(fmt, args...) \ -{ \ - FILE *_shm_fp_; \ - if (access(SHM_DEBUG_FILE, F_OK) == 0 && \ - (_shm_fp_ = fopen(SHM_DEBUG_FILE, "a")) != NULL) { \ - fprintf(_shm_fp_, fmt, ## args); \ - fclose(_shm_fp_); \ - } \ -} -#endif /* SHM_DEBUG_FILE */ - -/*----------------------------------------------------------------------- - * For the Hack structure: - * - * first >= 0 starting serial number - * first < 0 no serial number - * last ending serial number (only if first >= 0) - * debug whether an option 'D' can be appended - *-----------------------------------------------------------------------*/ -typedef struct { - const char *name; - int first; - int last; - int debug; -} Hack; - -/*----------------------------------------------------------------------- - * For the HackList structure: - * - * list the list of Hack structures - * cur the number of valid Hack structures in list - * max the actual number of Hack structures allocated - *-----------------------------------------------------------------------*/ -#define HACKLISTDELTA 16 -#define HACKLISTSTART 16 -typedef struct { - const Hack *list; - int cur; - int max; -} HackList; - -static const Hack sem_hack_default_names[] = { - {"EDBPool", 1, 255, 0}, - {"EDDPoolLock", -1, 0, 0}, - {"Mso97SharedDg", 1920, 2047, 1}, - {"Office", 1920, 2047, 1}, - {"PT_EDBPool", 1, 255, 0}, - {"PT_EDDPoolLock", -1, 0, 0}, - {"PT_Mso97SharedDg", 1920, 2047, 0}, - {"PT_Office", 1920, 2047, 0}, - {"ShMemExtCritSection", -1, 0, 0}, - {"ShMemIntCritSection", -1, 0, 0}, - {NULL, 0, 0, 0}, -}; -static HackList sem_hack_defaults = { - sem_hack_default_names, - (sizeof(sem_hack_default_names) / sizeof(const Hack)) - 1, - 0 -}; -static HackList *sem_hack_names = &sem_hack_defaults; - -static const Hack shm_hack_default_names[] = { - {"EDBPool", 1, 255, 0}, - {"EDDPoolLock", -1, 0, 0}, - {"Mso97SharedDg", 1920, 2047, 1}, - {"Office", 1920, 2047, 1}, - {"PT_EDBPool", 1, 255, 0}, - {"PT_EDDPoolLock", -1, 0, 0}, - {"PT_Mso97SharedDg", 1920, 2047, 0}, - {"PT_Office", 1920, 2047, 0}, - {"PT_ShMemRefCount", -1, 0, 0}, /* not specified by MS, but seen */ - {"ShMemRefCount", -1, 0, 0}, - {NULL, 0, 0, 0}, -}; -static HackList shm_hack_defaults = { - shm_hack_default_names, - (sizeof(shm_hack_default_names) / sizeof(const Hack)) - 1, - 0 -}; -static HackList *shm_hack_names = &shm_hack_defaults; - -static int comparkey(const void *key, const void *hname); -static int comparstr(const void *a, const void *b); -static int dosearch(const char *name, const HackList *hl); -static int hl_add(HackList *hl, const Hack *h); -static void hl_free(HackList *hl); -static HackList *hl_init(void); -static HackList *initList(const Hack *list); -int _sem_hack_add(const Hack *list); -void _sem_hack_init(void); -PRIVATE int _sem_match(const char *name); -int _shm_hack_add(const Hack *list); -void _shm_hack_init(void); -PRIVATE int _shm_match(const char *name); - -/*----------------------------------------------------------------------- - * comparkey - used by bsearch to find the Hack structure with the given key - *-----------------------------------------------------------------------*/ -static int -comparkey(const void *key, const void *h) -{ - return strcmp(key, ((const Hack *)h)->name); -} - -/*----------------------------------------------------------------------- - * comparstr - used by qsort to sort the Hack list - *-----------------------------------------------------------------------*/ -static int -comparstr(const void *a, const void *b) -{ - return strcmp(((const Hack *)a)->name, ((const Hack *)b)->name); -} - -/*----------------------------------------------------------------------- - * dosearch - search of the given name in the given HackList. First see - * if there is a trailing D, and a serial number. If the serial number - * exists, try to match without the serial number, checking the series - * range and whether the trailing D is allowed. Otherwise, try to match - * the whole string, but check if the matched Hack structure requires a - * serial number. - *-----------------------------------------------------------------------*/ -static int -dosearch(const char *name, const HackList *hl) -{ - int series; - int len = strlen(name); - const char *end, *p; - char *key; - const Hack *h; - - end = name + len - 1; - if (*end != 'D') - end++; - p = end - 1; - while (p >= name && *p >= '0' && *p <= '9') - p--; - p++; - if (p < end && (len = p - name) > 0) { - key = alloca(len + 1); - if (key) { - series = atoi(p); - strncpy(key, name, len); - key[len] = 0; - h = (const Hack *)bsearch(key, hl->list, hl->cur, - sizeof(const Hack), comparkey); - if (h && h->first >= 0 - && series >= h->first && series <= h->last - && (*end == 0 || h->debug)) - return 1; - } - } - h = (const Hack *)bsearch(name, hl->list, hl->cur, sizeof(const Hack), - comparkey); - return (h && h->first < 0); -} - -/*----------------------------------------------------------------------- - * hl_add - append to the given HackList a copy of the given Hack structure - *-----------------------------------------------------------------------*/ -static int -hl_add(HackList *hl, const Hack *c) -{ - int i = hl->cur; - Hack *h; - - if (!c->name) - return -1; - if (i >= hl->max) { - int s = hl->max + HACKLISTDELTA; - const Hack *new = (const Hack *)realloc((void *)hl->list, - s * sizeof(const Hack)); - - if (!new) - return -1; - hl->list = new; - hl->max = s; - } - h = (Hack *)(hl->list + i); - if ((h->name = strdup(c->name)) == NULL) - return -1; - h->first = c->first; - h->last = c->last; - h->debug = c->debug; - hl->cur++; - return 0; -} - -/*----------------------------------------------------------------------- - * hl_free - deallocate all memory from the given HackList - *-----------------------------------------------------------------------*/ -static void -hl_free(HackList *hl) -{ - const Hack *h; - int i; - - for (h = hl->list, i = hl->cur; i > 0; h++, i--) - free((void *)h->name); - free((void *)hl->list); - free(hl); -} - -/*----------------------------------------------------------------------- - * hl_init - create a new HackList, with preallocated Hack structures - *-----------------------------------------------------------------------*/ -static HackList * -hl_init(void) -{ - HackList *hl = (HackList *)malloc(sizeof(HackList)); - - if (!hl) - return NULL; - hl->list = (Hack *)malloc(HACKLISTSTART * sizeof(Hack)); - if (!hl->list) { - free(hl); - return NULL; - } - hl->cur = 0; - hl->max = HACKLISTSTART; - return hl; -} - -/*----------------------------------------------------------------------- - * initList - initialize a new HackList with the given list of Hack structures - *-----------------------------------------------------------------------*/ -static HackList * -initList(const Hack *list) -{ - HackList *hl = hl_init(); - - if (hl == NULL) - return NULL; - for (; list->name; list++) - if (hl_add(hl, list) < 0) { - hl_free(hl); - return NULL; - } - return hl; -} - -/*----------------------------------------------------------------------- - * PUBLIC _sem_hack_add - add the given Hack list to sem_hack_names. - *-----------------------------------------------------------------------*/ -int -_sem_hack_add(const Hack *list) -{ - if (list == NULL) - return -1; - if (sem_hack_names == &sem_hack_defaults) { - HackList *hl = initList(sem_hack_default_names); - if (!hl) - return -1; - sem_hack_names = hl; - } - for (; list->name; list++) - if (hl_add(sem_hack_names, list) < 0) - return -1; - qsort((void *)sem_hack_names->list, sem_hack_names->cur, - sizeof(const Hack), comparstr); - return 0; -} - -/*----------------------------------------------------------------------- - * PUBLIC _sem_hack_init - reinitialize sem_hack_names to the default - *-----------------------------------------------------------------------*/ -void -_sem_hack_init(void) -{ - if (sem_hack_names == &sem_hack_defaults) - return; - hl_free(sem_hack_names); - sem_hack_names = &sem_hack_defaults; -} - -/*----------------------------------------------------------------------- - * _sem_match - try to match the given named to sem_hack_names. Called - * by sem_open() and sem_unlink(). - *-----------------------------------------------------------------------*/ -PRIVATE int -_sem_match(const char *name) -{ -#ifdef SEM_DEBUG_FILE - int match; -#endif /* SEM_DEBUG_FILE */ - - if (!name || !*name) - return 0; -#ifdef SEM_DEBUG_FILE - match = dosearch(name, sem_hack_names); - if (!match) - SEM_PRINTF("%s\n", name); - return match; -#else /* SEM_DEBUG_FILE */ - return dosearch(name, sem_hack_names); -#endif /* SEM_DEBUG_FILE */ -} - -/*----------------------------------------------------------------------- - * PUBLIC _shm_hack_add - add the given Hack list to shm_hack_names. - *-----------------------------------------------------------------------*/ -int -_shm_hack_add(const Hack *list) -{ - if (list == NULL) - return -1; - if (shm_hack_names == &shm_hack_defaults) { - HackList *hl = initList(shm_hack_default_names); - if (!hl) - return -1; - shm_hack_names = hl; - } - for (; list->name; list++) - if (hl_add(shm_hack_names, list) < 0) - return -1; - qsort((void *)shm_hack_names->list, shm_hack_names->cur, - sizeof(const Hack), comparstr); - return 0; -} - -/*----------------------------------------------------------------------- - * PUBLIC _shm_hack_init - reinitialize shm_hack_names to the default - *-----------------------------------------------------------------------*/ -void -_shm_hack_init(void) -{ - if (shm_hack_names == &shm_hack_defaults) - return; - hl_free(shm_hack_names); - shm_hack_names = &shm_hack_defaults; -} - -/*----------------------------------------------------------------------- - * _shm_match - try to match the given named to shm_hack_names. Called - * by shm_open() and shm_unlink(). - *-----------------------------------------------------------------------*/ -PRIVATE int -_shm_match(const char *name) -{ -#ifdef SHM_DEBUG_FILE - int match; -#endif /* SHM_DEBUG_FILE */ - - if (!name || !*name) - return 0; -#ifdef SHM_DEBUG_FILE - match = dosearch(name, shm_hack_names); - if (!match) - SHM_PRINTF("%s\n", name); - return match; -#else /* SHM_DEBUG_FILE */ - return dosearch(name, shm_hack_names); -#endif /* SHM_DEBUG_FILE */ -} diff --git a/sys/fork.c b/sys/fork.c new file mode 100644 index 0000000..b026e06 --- /dev/null +++ b/sys/fork.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2010 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include +#include + +extern pid_t __fork(void); +extern void _cthread_fork_prepare(); +extern void _cthread_fork_parent(); +extern void _cthread_fork_child(); + +static void (*_libSystem_atfork_prepare)(void) = 0; +static void (*_libSystem_atfork_parent)(void) = 0; +static void (*_libSystem_atfork_child)(void) = 0; + +__private_extern__ void _libc_fork_init(void (*prepare)(void), void (*parent)(void), void (*child)(void)) +{ + _libSystem_atfork_prepare = prepare; + _libSystem_atfork_parent = parent; + _libSystem_atfork_child = child; +} + +/* + * fork stub + */ +pid_t +fork(void) +{ + int ret; + + _libSystem_atfork_prepare(); + // Reader beware: this __fork() call is yet another wrapper around the actual syscall + // and lives inside libsyscall. The fork syscall needs some cuddling by asm before it's + // allowed to see the big wide C world. + ret = __fork(); + if (-1 == ret) + { + // __fork already set errno for us + _libSystem_atfork_parent(); + return ret; + } + + if (0 == ret) + { + // We're the child in this part. + _libSystem_atfork_child(); + return 0; + } + + _libSystem_atfork_parent(); + return ret; +} + diff --git a/sys/getattrlist.c b/sys/getattrlist.c deleted file mode 100644 index 8285491..0000000 --- a/sys/getattrlist.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include - -#include - -#ifdef __LP64__ -extern int __getattrlist(const char *, void *, void *, size_t, unsigned int); -#else /* !__LP64__ */ -extern int __getattrlist(const char *, void *, void *, size_t, unsigned long); -#endif /* __LP64__ */ - -/* - * getattrlist stub, legacy version - */ -int -#ifdef __LP64__ -getattrlist(const char *path, void *attrList, void *attrBuf, - size_t attrBufSize, unsigned int options) -#else /* !__LP64__ */ -getattrlist(const char *path, void *attrList, void *attrBuf, - size_t attrBufSize, unsigned long options) -#endif /* __LP64__ */ -{ - int ret = __getattrlist(path, attrList, attrBuf, attrBufSize, options); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/getdtablesize.2 b/sys/getdtablesize.2 deleted file mode 100644 index 7465f9a..0000000 --- a/sys/getdtablesize.2 +++ /dev/null @@ -1,63 +0,0 @@ -.\" Copyright (c) 1983, 1991, 1993 -.\" The Regents of the University of California. 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)getdtablesize.2 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/sys/getdtablesize.2,v 1.4.2.3 2001/12/14 18:34:00 ru Exp $ -.\" -.Dd June 4, 1993 -.Dt GETDTABLESIZE 2 -.Os -.Sh NAME -.Nm getdtablesize -.Nd get descriptor table size -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In unistd.h -.Ft int -.Fn getdtablesize void -.Sh DESCRIPTION -Each process has a fixed size descriptor table, -which is guaranteed to have at least 20 slots. The entries in -the descriptor table are numbered with small integers starting at 0. -The call -.Fn getdtablesize -returns the size of this table. -.Sh SEE ALSO -.Xr close 2 , -.Xr dup 2 , -.Xr open 2 , -.Xr select 2 -.Sh HISTORY -The -.Fn getdtablesize -function call appeared in -.Bx 4.2 . diff --git a/sys/getpeername.c b/sys/getpeername.c deleted file mode 100644 index 743f6fe..0000000 --- a/sys/getpeername.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include - -extern int __getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict); - -/* - * getpeername stub, legacy version - */ -int -getpeername(int socket, struct sockaddr * __restrict address, - socklen_t * __restrict address_len) -{ - int ret = __getpeername(socket, address, address_len); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/getrlimit.c b/sys/getrlimit.c deleted file mode 100644 index 249d443..0000000 --- a/sys/getrlimit.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include - -extern int __getrlimit(int resource, struct rlimit *rlp); - -/* - * getrlimit stub, for conformance, OR in _RLIMIT_POSIX_FLAG - * - * This is for UNIX03 only. - */ -int -getrlimit(int resource, struct rlimit *rlp) -{ - resource |= _RLIMIT_POSIX_FLAG; - return(__getrlimit(resource, rlp)); -} diff --git a/sys/getsockname.c b/sys/getsockname.c deleted file mode 100644 index 9641972..0000000 --- a/sys/getsockname.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include - -extern int __getsockname(int, struct sockaddr * __restrict, socklen_t * __restrict); - -/* - * getsockname stub, legacy version - */ -int -getsockname(int socket, struct sockaddr * __restrict address, - socklen_t * __restrict address_len) -{ - int ret = __getsockname(socket, address, address_len); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/ioctl.c b/sys/ioctl.c deleted file mode 100644 index c735d0c..0000000 --- a/sys/ioctl.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include - -int __ioctl(int, unsigned long, void *); -/* - * Stub function to account for the third argument being void * - * - * This is for LP64 only. - */ -int -ioctl(int d, unsigned long request, ...) -{ - va_list ap; - void *arg; - - va_start(ap, request); - arg = va_arg(ap, void *); - va_end(ap); - return (__ioctl(d, request, arg)); -} diff --git a/sys/kill.c b/sys/kill.c deleted file mode 100644 index 466e624..0000000 --- a/sys/kill.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include - -extern int __kill(pid_t pid, int sig, int posix); - -/* - * kill stub, which wraps a modified kill system call that takes a posix - * behaviour indicator as the third parameter to indicate whether or not - * conformance to standards is needed. We use a trailing parameter in - * case the call is called directly via syscall(), since for most uses, - * it won't matter to the caller. - */ -int -kill(pid_t pid, int sig) -{ -#if __DARWIN_UNIX03 - return(__kill(pid, sig, 1)); -#else /* !__DARWIN_UNIX03 */ - return(__kill(pid, sig, 0)); -#endif /* !__DARWIN_UNIX03 */ -} diff --git a/sys/lchown.c b/sys/lchown.c deleted file mode 100644 index c70db53..0000000 --- a/sys/lchown.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2006, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include - -int __lchown(const char *, uid_t, gid_t); - -/* - * lchown stub, legacy version - */ -int -lchown(const char *path, uid_t owner, gid_t group) -{ - int ret = __lchown(path, owner, group); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/libc.syscall b/sys/libc.syscall deleted file mode 100644 index 3c24170..0000000 --- a/sys/libc.syscall +++ /dev/null @@ -1,16 +0,0 @@ -___sandbox_me ___mac_execve -___sandbox_mm ___mac_mount -___sandbox_ms ___mac_syscall -___sandbox_msp ___mac_set_proc -__exit ___exit -_accessx_np ___access_extended -_getsgroups_np ___getsgroups -_getwgroups_np ___getwgroups -# initgroups wrapper is defined in Libinfo -_initgroups -_posix_madvise ___madvise -_pthread_getugid_np ___gettid -_pthread_setugid_np ___settid -_setsgroups_np ___setsgroups -_setwgroups_np ___setwgroups -_wait4 ___wait4_nocancel diff --git a/sys/listen.c b/sys/listen.c deleted file mode 100644 index e89502e..0000000 --- a/sys/listen.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include - -extern int __listen(int, int); - -/* - * listen stub, legacy version - */ -int -listen(int socket, int backlog) -{ - int ret = __listen(socket, backlog); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/mmap.c b/sys/mmap.c deleted file mode 100644 index 136028b..0000000 --- a/sys/mmap.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include - -void *__mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); - -/* - * mmap stub, with preemptory failures due to extra parameter checking - * mandated for conformance. - * - * This is for UNIX03 only. - */ -void * -mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) -{ - /* - * Preemptory failures: - * - * o off is not a multiple of the page size - * o flags does not contain either MAP_PRIVATE or MAP_SHARED - * o len is zero - */ - extern void cthread_set_errno_self(int); - if ((off & PAGE_MASK) || - (((flags & MAP_PRIVATE) != MAP_PRIVATE) && - ((flags & MAP_SHARED) != MAP_SHARED)) || - (len == 0)) { - cthread_set_errno_self(EINVAL); - return(MAP_FAILED); - } - - return(__mmap(addr, len, prot, flags, fildes, off)); -} diff --git a/sys/mprotect.c b/sys/mprotect.c deleted file mode 100644 index 3e6e98d..0000000 --- a/sys/mprotect.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include -#include - -/* - * Stub function to account for the differences in standard compliance - * while maintaining binary backward compatibility. - * - * This is only the legacy behavior. - */ -extern int __mprotect(void *, size_t, int); - -int -mprotect(void *addr, size_t len, int prot) -{ - void *aligned_addr; - int page_mask; - size_t offset; - int rv; - - /* - * Page-align "addr" since the system now requires it - * for standards compliance. - * Update "len" to reflect the alignment. - */ - page_mask = getpagesize() - 1; - offset = ((uintptr_t) addr) & page_mask; - aligned_addr = (void *) (((uintptr_t) addr) & ~page_mask); - len += offset; - rv = __mprotect(aligned_addr, len, prot); - if (rv == -1 && errno == ENOMEM) { - /* - * Standards now require that we return ENOMEM if there was - * a hole in the address range. Panther and earlier used - * to return an EINVAL error, so honor backwards compatibility. - */ - errno = EINVAL; - } - return rv; -} diff --git a/sys/msync.2 b/sys/msync.2 deleted file mode 100644 index 94de3b6..0000000 --- a/sys/msync.2 +++ /dev/null @@ -1,103 +0,0 @@ -.\" Copyright (c) 1991, 1993 -.\" The Regents of the University of California. 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)msync.2 8.2 (Berkeley) 6/21/94 -.\" $FreeBSD: src/lib/libc/sys/msync.2,v 1.17 2000/04/21 09:41:53 phantom Exp $ -.\" -.Dd June 21, 1994 -.Dt MSYNC 2 -.Os -.Sh NAME -.Nm msync -.Nd synchronize a mapped region -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.Fd #include -.Fd #include -.Ft int -.Fn msync "void *addr" "size_t len" "int flags" -.Sh DESCRIPTION -The -.Fn msync -system call -writes any modified pages back to the filesystem and updates -the file modification time. -If -.Fa len -is 0, all modified pages within the region containing -.Fa addr -will be flushed; -if -.Fa len -is non-zero, only those pages containing -.Fa addr -and -.Fa len-1 -succeeding locations will be examined. -The -.Fa flags -argument may be specified as follows: -.Bd -literal -MS_ASYNC Return immediately -MS_SYNC Perform synchronous writes -MS_INVALIDATE Invalidate all cached data -.Ed -.Sh RETURN VALUES -If any errors occur, -1 is returned and errno is set to indicate the -error. -Otherwise, a 0 value is returned. -.Sh ERRORS -.Fn msync -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -.Fa addr -is not a multiple of the hardware page size. -.It Bq Er EINVAL -.Fa len -is too large or negative. -.It Bq Er EINVAL -.Fa flags -was both MS_ASYNC and MS_INVALIDATE. -Only one of these flags is allowed. -.It Bq Er EIO -An I/O error occurred while writing to the file system. -.Sh SEE ALSO -.Xr madvise 2 , -.Xr mincore 2 , -.Xr mprotect 2 , -.Xr munmap 2 -.Sh HISTORY -The -.Fn msync -function first appeared in -.Bx 4.4 . diff --git a/sys/msync.c b/sys/msync.c deleted file mode 100644 index ea062f8..0000000 --- a/sys/msync.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2004, 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include - -int __msync_nocancel(void *, size_t, int); - -/* - * Stub function for legacy version - */ -int -msync(void *addr, size_t len, int flags) -{ - int page_mask; - size_t offset; - - /* - * Page-align "addr" since the system now requires it - * for standards compliance. - * Update "len" to reflect the alignment. - */ - page_mask = getpagesize() - 1; - offset = ((uintptr_t) addr) & page_mask; - addr = (void *) (((uintptr_t) addr) & ~page_mask); - len += offset; - return __msync_nocancel(addr, len, flags); -} diff --git a/sys/munmap.c b/sys/munmap.c deleted file mode 100644 index be99a85..0000000 --- a/sys/munmap.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include - -/* - * Stub function to account for the differences in standard compliance - * while maintaining binary backward compatibility. - * - * This is only the legacy behavior. - */ -extern int __munmap(void *, size_t); - -int -munmap(void *addr, size_t len) -{ - int page_mask; - size_t offset; - - if (len == 0) { - /* - * Standard compliance now requires the system to return EINVAL - * for munmap(addr, 0). Return success now to maintain - * backwards compatibility. - */ - return 0; - } - /* - * Page-align "addr" since the system now requires it - * for standards compliance. - * Update "len" to reflect the adjustment and still cover the same area. - */ - page_mask = getpagesize() - 1; - offset = ((uintptr_t) addr) & page_mask; - addr = (void *) (((uintptr_t) addr) & ~page_mask); - len += offset; - return __munmap(addr, len); -} diff --git a/sys/nanosleep.2 b/sys/nanosleep.2 index 0b41b9b..729527b 100644 --- a/sys/nanosleep.2 +++ b/sys/nanosleep.2 @@ -87,13 +87,6 @@ The .Fn nanosleep call fails if: .Bl -tag -width Er -.It Bq Er EFAULT -Either -.Fa rqtp -or -.Fa rmtp -points to memory that is not a valid part of the process -address space. .It Bq Er EINTR .Fn nanosleep was interrupted by the delivery of a signal. @@ -101,9 +94,6 @@ was interrupted by the delivery of a signal. .Fa rqtp specified a nanosecond value less than zero or greater than or equal to 1000 million. -.It Bq Er ENOSYS -.Fn nanosleep -is not supported by this implementation. .El .Sh SEE ALSO .Xr sigsuspend 2 , diff --git a/sys/open.c b/sys/open.c deleted file mode 100644 index 79e2043..0000000 --- a/sys/open.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2005, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -int __open_nocancel(const char *path, int flags, mode_t mode); - -/* - * open stub: The legacy interface never automatically associated a controlling - * tty, so we always pass O_NOCTTY. - */ -int -open(const char *path, int flags, ...) -{ - mode_t mode = 0; - - if(flags & O_CREAT) { - va_list ap; - va_start(ap, flags); - // compiler warns to pass int (not mode_t) to va_arg - mode = va_arg(ap, int); - va_end(ap); - } - return(__open_nocancel(path, flags | O_NOCTTY, mode)); -} diff --git a/sys/posix_spawn.c b/sys/posix_spawn.c index 0bed29d..d92ac84 100644 --- a/sys/posix_spawn.c +++ b/sys/posix_spawn.c @@ -131,7 +131,7 @@ posix_spawnattr_init(posix_spawnattr_t *attr) * NOTIMP: Allowed failures (checking NOT required): * EINVAL The value specified by attr is invalid. */ -int posix_spawn_destroyportactions_np(posix_spawnattr_t *); +static int posix_spawn_destroyportactions_np(posix_spawnattr_t *); int posix_spawnattr_destroy(posix_spawnattr_t *attr) @@ -569,7 +569,7 @@ posix_spawnattr_setpcontrol_np(posix_spawnattr_t * __restrict attr, * Description: create a new posix_spawn_port_actions struct and link * it into the posix_spawnattr. */ -int +static int posix_spawn_createportactions_np(posix_spawnattr_t *attr) { _posix_spawnattr_t psattr; @@ -594,7 +594,7 @@ posix_spawn_createportactions_np(posix_spawnattr_t *attr) * posix_spawn_growportactions_np * Description: Enlarge the size of portactions if necessary */ -int +static int posix_spawn_growportactions_np(posix_spawnattr_t *attr) { _posix_spawnattr_t psattr; @@ -623,7 +623,7 @@ posix_spawn_growportactions_np(posix_spawnattr_t *attr) * posix_spawn_destroyportactions_np * Description: clean up portactions struct in posix_spawnattr_t attr */ -int +static int posix_spawn_destroyportactions_np(posix_spawnattr_t *attr) { _posix_spawnattr_t psattr; @@ -937,7 +937,7 @@ _posix_spawn_file_actions_grow(_posix_spawn_file_actions_t *psactsp) * opened with flags 'oflag' and mode 'mode', and, if successful, * return as descriptor 'filedes' to the spawned process. * - * Parameters: file_actions File action object to add open to + * Parameters: file_actions File action object to augment * filedes fd that open is to use * path path to file to open * oflag open file flags @@ -999,7 +999,7 @@ posix_spawn_file_actions_addopen( * that will cause the file referenced by 'filedes' to be * attempted to be closed in the spawned process. * - * Parameters: file_actions File action object to add open to + * Parameters: file_actions File action object to augment * filedes fd to close * * Returns: 0 Success @@ -1049,12 +1049,12 @@ posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *file_actions, /* * posix_spawn_file_actions_adddup2 * - * Description: Add a dpu2 action to the object referenced by 'file_actions' + * Description: Add a dup2 action to the object referenced by 'file_actions' * that will cause the file referenced by 'filedes' to be * attempted to be dup2'ed to the descriptor 'newfiledes' in the * spawned process. * - * Parameters: file_actions File action object to add open to + * Parameters: file_actions File action object to augment * filedes fd to dup2 * newfiledes fd to dup2 it to * @@ -1103,6 +1103,73 @@ posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions, return (0); } +/* + * posix_spawn_file_actions_addinherit_np + * + * Description: Add the "inherit" action to the object referenced by + * 'file_actions' that will cause the file referenced by + * 'filedes' to continue to be available in the spawned + * process via the same descriptor. + * + * Inheritance is the normal default behaviour for + * file descriptors across exec and spawn; but if the + * POSIX_SPAWN_CLOEXEC_DEFAULT flag is set, the usual + * default is reversed for the purposes of the spawn + * invocation. Any pre-existing descriptors that + * need to be made available to the spawned process can + * be marked explicitly as 'inherit' via this interface. + * Otherwise they will be automatically closed. + * + * Note that any descriptors created via the other file + * actions interfaces are automatically marked as 'inherit'. + * + * Parameters: file_actions File action object to augment + * filedes fd to inherit. + * + * Returns: 0 Success + * EBADF The value specified by fildes is + * negative or greater than or equal to + * {OPEN_MAX}. + * ENOMEM Insufficient memory exists to add to + * the spawn file actions object. + * + * NOTIMP: Allowed failures (checking NOT required): + * EINVAL The value specified by file_actions is invalid. + */ +int +posix_spawn_file_actions_addinherit_np(posix_spawn_file_actions_t *file_actions, + int filedes) +{ + _posix_spawn_file_actions_t *psactsp; + _psfa_action_t *psfileact; + + if (file_actions == NULL || *file_actions == NULL) + return (EINVAL); + + psactsp = (_posix_spawn_file_actions_t *)file_actions; + /* Range check; required by POSIX */ + if (filedes < 0 || filedes >= OPEN_MAX) + return (EBADF); + +#if defined(POSIX_SPAWN_CLOEXEC_DEFAULT) // TODO: delete this check + /* If we do not have enough slots, grow the structure */ + if ((*psactsp)->psfa_act_count == (*psactsp)->psfa_act_alloc) { + /* need to grow file actions structure */ + if (_posix_spawn_file_actions_grow(psactsp)) + return (ENOMEM); + } + + /* + * Allocate next available slot and fill it out + */ + psfileact = &(*psactsp)->psfa_act_acts[(*psactsp)->psfa_act_count++]; + + psfileact->psfaa_type = PSFA_INHERIT; + psfileact->psfaa_filedes = filedes; +#endif + return (0); +} + /* * posix_spawnp diff --git a/sys/recvfrom.c b/sys/recvfrom.c deleted file mode 100644 index 320858b..0000000 --- a/sys/recvfrom.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include - -ssize_t __recvfrom_nocancel(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict); - -/* - * recvfrom stub, legacy version - */ -ssize_t -recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr * __restrict from, socklen_t * __restrict fromlen) -{ - int ret = __recvfrom_nocancel(s, buf, len, flags, from, fromlen); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/recvmsg.c b/sys/recvmsg.c deleted file mode 100644 index 7acc6b0..0000000 --- a/sys/recvmsg.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include - -ssize_t __recvmsg_nocancel(int, struct msghdr *, int); - -/* - * recvmsg stub, legacy version - */ -ssize_t -recvmsg(int s, struct msghdr *msg, int flags) -{ - int ret = __recvmsg_nocancel(s, msg, flags); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/remove_counter.c b/sys/remove_counter.c deleted file mode 100644 index 343225f..0000000 --- a/sys/remove_counter.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#if defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) -static int64_t __remove_counter = 0; -#else -static int32_t __remove_counter = 0; -#endif - -uint64_t -__get_remove_counter(void) { -#if defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) - return (uint64_t)OSAtomicAdd64Barrier(0, &__remove_counter); -#else - return (uint64_t)OSAtomicAdd32Barrier(0, &__remove_counter); -#endif -} - -__private_extern__ void -__inc_remove_counter(void) -{ -#if defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) - (void)OSAtomicAdd64(1, &__remove_counter); -#else - (void)OSAtomicAdd32(1, &__remove_counter); -#endif -} diff --git a/sys/rename.c b/sys/rename.c deleted file mode 100644 index 2259eb8..0000000 --- a/sys/rename.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -void __inc_remove_counter(void); -int __rename(const char *old, const char *new); - -int -rename(const char *old, const char *new) -{ - int res = __rename(old, new); - if (res == 0) __inc_remove_counter(); - return res; -} diff --git a/sys/select.c b/sys/select.c deleted file mode 100644 index c975899..0000000 --- a/sys/select.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2005, 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#if defined(__LP64__) && (defined(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050)) -#undef __DARWIN_NON_CANCELABLE -#define __DARWIN_NON_CANCELABLE 0 -#endif /* __LP64__ && (VARIANT_CANCELABLE || VARIANT_PRE1050) */ -#include -#include - -#if defined(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050) -extern int __select(int, fd_set * __restrict, fd_set * __restrict, - fd_set * __restrict, struct timeval * __restrict); -#else /* !VARIANT_CANCELABLE && !VARIANT_PRE1050 */ -int __select_nocancel(int, fd_set * __restrict, fd_set * __restrict, - fd_set * __restrict, struct timeval * __restrict); -#endif /* VARIANT_CANCELABLE || VARIANT_PRE1050 */ - -/* - * select stub, return error if nfds > FD_SETSIZE - * add pthread cancelability - * mandated for conformance. - * - * This is only for (non DARWINEXTSN) UNIX03 (both cancelable and - * non-cancelable) and for legacy - */ -int -select(int nfds, fd_set * __restrict readfds, fd_set * __restrict writefds, - fd_set * __restrict exceptfds, struct timeval * __restrict -#if defined(VARIANT_LEGACY) || defined(VARIANT_PRE1050) - intimeout -#else /* !VARIANT_LEGACY && !VARIANT_PRE1050 */ - timeout -#endif /* VARIANT_LEGACY || VARIANT_PRE1050 */ - ) -{ - -#if defined(VARIANT_LEGACY) || defined(VARIANT_PRE1050) - struct timeval tb, *timeout; - - /* - * Legacy select behavior is minimum 10 msec when tv_usec is non-zero - */ - if (intimeout && intimeout->tv_sec == 0 && intimeout->tv_usec > 0 && intimeout->tv_usec < 10000) { - tb.tv_sec = 0; - tb.tv_usec = 10000; - timeout = &tb; - } else - timeout = intimeout; -#else /* !VARIANT_LEGACY && !VARIANT_PRE1050 */ - if (nfds > FD_SETSIZE) { - errno = EINVAL; - return -1; - } -#endif /* VARIANT_LEGACY || VARIANT_PRE1050 */ -#if defined(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050) - return __select(nfds, readfds, writefds, exceptfds, timeout); -#else /* !VARIANT_CANCELABLE && !VARIANT_PRE1050 */ - return __select_nocancel(nfds, readfds, writefds, exceptfds, timeout); -#endif /* VARIANT_CANCELABLE || VARIANT_PRE1050 */ -} diff --git a/sys/sem_close.2 b/sys/sem_close.2 deleted file mode 100644 index cdff87c..0000000 --- a/sys/sem_close.2 +++ /dev/null @@ -1,60 +0,0 @@ -.\" $Darwin$ -.\" -.\" Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" The contents of this file constitute Original Code as defined in and -.\" are subject to the Apple Public Source License Version 1.1 (the -.\" "License"). You may not use this file except in compliance with the -.\" License. Please obtain a copy of the License at -.\" http://www.apple.com/publicsource and read it before using this file. -.\" -.\" This Original Code and all software distributed under the License are -.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the -.\" License for the specific language governing rights and limitations -.\" under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.Dd June 8, 2000 -.Dt SEM_CLOSE 2 -.Os Darwin -.Sh NAME -.Nm sem_close -.Nd close a named semaphore -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn sem_close "sem_t *sem" -.Sh DESCRIPTION -The system resources associated with the named semaphore referenced by -.Fa sem -are deallocated and the descriptor is invalidated. -.Pp -If successful, -.Fn sem_close -will return 0. Otherwise, -1 is returned and -.Va errno -is set. -.Sh ERRORS -.Fn sem_close -succeeds unless: -.Bl -tag -width Er -.It Bq Er EINVAL -.Fa sem -is not a valid semaphore descriptor. -.El -.Sh SEE ALSO -.Xr sem_init 2 , -.Xr sem_open 2 , -.Xr sem_unlink 2 , -.Xr semctl 2 , -.Xr semget 2 , -.Xr semop 2 -.Sh HISTORY -.Fn sem_close -is specified in the POSIX Realtime Extension (1003.1b-1993/1003.1i-1995). diff --git a/sys/sem_open.2 b/sys/sem_open.2 deleted file mode 100644 index 423e98a..0000000 --- a/sys/sem_open.2 +++ /dev/null @@ -1,169 +0,0 @@ -.\" $Darwin$ -.\" -.\" Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" The contents of this file constitute Original Code as defined in and -.\" are subject to the Apple Public Source License Version 1.1 (the -.\" "License"). You may not use this file except in compliance with the -.\" License. Please obtain a copy of the License at -.\" http://www.apple.com/publicsource and read it before using this file. -.\" -.\" This Original Code and all software distributed under the License are -.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the -.\" License for the specific language governing rights and limitations -.\" under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.Dd June 8, 2000 -.Dt SEM_OPEN 2 -.Os Darwin -.Sh NAME -.Nm sem_open -.Nd initialize and open a named semaphore -.Sh SYNOPSIS -.Fd #include -.Ft sem_t * -.Fo sem_open -.Fa "const char *name" -.Fa "int oflag" -.Fa "..." -.Fc -.Pp -The parameters "mode_t mode" and "unsigned int value" -are optional. -.Sh DESCRIPTION -The named semaphore named -.Fa name -is initialized and opened as specified by the argument -.Fa oflag -and a semaphore descriptor is returned to the calling process. -.Pp -The value of -.Fa oflag -is formed by -.Em or Ns 'ing -the following values: -.Pp -.Bd -literal -offset indent -compact -O_CREAT create the semaphore if it does not exist -O_EXCL error if create and semaphore exists -.Ed -.Pp -If -.Dv O_CREAT -is specified, -.Fn sem_open -requires an additional two arguments. -.Fa mode -specifies the permissions for the semaphore as described in -.Xr chmod 2 -and modified by the process' umask value (see -.Xr umask 2 ) . -The semaphore is created with an initial -.Fa value , -which must be less than or equal to -.Dv SEM_VALUE_MAX . -.Pp -If -.Dv O_EXCL -is specified and the semaphore exists, -.Fn sem_open -fails. The check for the existence of the semaphore and the creation -of the semaphore are atomic with respect to all processes calling -.Fn sem_open -with -.Dv O_CREAT -and -.Dv O_EXCL -set. -.Pp -When a new semaphore is created, it is given the user ID and group ID -which correspond to the effective user and group IDs of the calling -process. There is no visible entry in the file system for the created -object in this implementation. -.Pp -The returned semaphore descriptor is available to the calling process -until it is closed with -.Fn sem_close , -or until the caller exits or execs. -.Pp -If a process makes repeated calls to -.Fn sem_open , -with the same -.Fa name -argument, the same descriptor is returned for each successful call, -unless -.Fn sem_unlink -has been called on the semaphore in the interim. -.Pp -If -.Fn sem_open -fails for any reason, it will return a value of -.Dv SEM_FAILED -and sets -.Va errno . -On success, it returns a semaphore descriptor. -.Sh ERRORS -The named semaphore is opened unless: -.Bl -tag -width Er -.It Bq Er EACCES -The required permissions (for reading and/or writing) -are denied for the given flags; or -.Dv O_CREAT -is specified, the object does not exist, and permission to -create the semaphore is denied. -.It Bq Er EEXIST -.Dv O_CREAT -and -.Dv O_EXCL -were specified and the semaphore exists. -.It Bq Er EINTR -The -.Fn sem_open -operation was interrupted by a signal. -.It Bq Er EINVAL -The -.Fn shm_open -operation is not supported; or -.Dv O_CREAT -is specified and -.Fa value -exceeds -.Dv SEM_VALUE_MAX . -.It Bq Er EMFILE -The process has already reached its limit for semaphores or file -descriptors in use. -.It Bq Er ENAMETOOLONG -.Fa name -exceeded -.Dv SEM_NAME_LEN -characters. -.It Bq Er ENFILE -Too many semaphores or file descriptors are open on the system. -.It Bq Er ENOENT -.Dv O_CREAT -is not set and the named semaphore does not exist. -.It Bq Er ENOSPC -.Dv O_CREAT -is specified, the file does not exist, and there is insufficient -space available to create the semaphore. -.El -.Sh SEE ALSO -.Xr sem_close 2 , -.Xr sem_post 2 , -.Xr sem_trywait 2 , -.Xr sem_unlink 2 , -.Xr sem_wait 2 , -.Xr semctl 2 , -.Xr semget 2 , -.Xr semop 2 , -.Xr umask 2 -.Sh HISTORY -.Fn sem_open -is specified in the POSIX Realtime Extension (1003.1b-1993/1003.1i-1995). diff --git a/sys/sem_open.c b/sys/sem_open.c deleted file mode 100644 index f540e6d..0000000 --- a/sys/sem_open.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 1999, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#ifdef __APPLE_PR3375657_HACK__ - -#include -#include -#include -#include -#include -#include -#include - -__private_extern__ int _sem_match(const char *name); -extern sem_t *__sem_open(const char *, int, int, unsigned int); - -sem_t * -sem_open (const char *name, int flags, ...) -{ - char *buffer; - va_list ap; - int mode; - unsigned int value; - - /* - * To work-around applications that don't play - * well in multiple GUI sessions, we append - * shared memory names with the effective user ID. - * It would be better to append the region name - * with a session ID, but nothing like that - * exists at this level of the system yet. - */ - - if (_sem_match(name) && (buffer = alloca(strlen(name) + 32)) != NULL) { - sprintf(buffer, "%s\t%d", name, geteuid()); - name = buffer; - } - -// sem_open (const char *name, int flags, mode_t mode, unsigned int value) - va_start(ap, flags); - mode = va_arg(ap, int); /* promoted from mode_t to int */ - value = va_arg(ap, unsigned int); - va_end(ap); - - return __sem_open(name, flags, mode, value); -} - -#endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/sem_post.2 b/sys/sem_post.2 deleted file mode 100644 index 36d06fd..0000000 --- a/sys/sem_post.2 +++ /dev/null @@ -1,65 +0,0 @@ -.\" $Darwin$ -.\" -.\" Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" The contents of this file constitute Original Code as defined in and -.\" are subject to the Apple Public Source License Version 1.1 (the -.\" "License"). You may not use this file except in compliance with the -.\" License. Please obtain a copy of the License at -.\" http://www.apple.com/publicsource and read it before using this file. -.\" -.\" This Original Code and all software distributed under the License are -.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the -.\" License for the specific language governing rights and limitations -.\" under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.Dd June 8, 2000 -.Dt SEM_POST 2 -.Os Darwin -.Sh NAME -.Nm sem_post -.Nd unlock a semaphore -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn sem_post "sem_t *sem" -.Sh DESCRIPTION -The semaphore referenced by -.Fa sem -is unlocked, the value of the semaphore is incremented, and all -threads which are waiting on the semaphore are awakened. -.Pp -.Fn sem_post -is reentrant with respect to signals and may be called from within a -signal hanlder. -.Pp -If successful, -.Fn sem_post -will return 0. Otherwise, -1 is returned and -.Va errno -is set. -.Sh ERRORS -.Fn sem_post -succeeds unless: -.Bl -tag -width Er -.It Bq Er EINVAL -.Fa sem -is not a valid semaphore descriptor. -.El -.Sh SEE ALSO -.Xr sem_open 2 , -.Xr sem_trywait 2 , -.Xr sem_wait 2 , -.Xr semctl 2 , -.Xr semget 2 , -.Xr semop 2 -.Sh HISTORY -.Fn sem_post -is specified in the POSIX Realtime Extension (1003.1b-1993/1003.1i-1995). diff --git a/sys/sem_unlink.2 b/sys/sem_unlink.2 deleted file mode 100644 index 7fc7e9c..0000000 --- a/sys/sem_unlink.2 +++ /dev/null @@ -1,74 +0,0 @@ -.\" $Darwin$ -.\" -.\" Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" The contents of this file constitute Original Code as defined in and -.\" are subject to the Apple Public Source License Version 1.1 (the -.\" "License"). You may not use this file except in compliance with the -.\" License. Please obtain a copy of the License at -.\" http://www.apple.com/publicsource and read it before using this file. -.\" -.\" This Original Code and all software distributed under the License are -.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the -.\" License for the specific language governing rights and limitations -.\" under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.Dd June 8, 2000 -.Dt SEM_UNLINK 2 -.Os Darwin -.Sh NAME -.Nm sem_unlink -.Nd remove a named semaphore -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn sem_unlink "const char *name" -.Sh DESCRIPTION -The named semaphore named -.Fa name -is removed. If the semaphore is in use by other processes, then -.Fa name -is immediately disassociated with the semaphore, but the semaphore -itself will not be removed until all references to it have been -closed. Subsequent calls to -.Fn sem_open -using -.Fa name -will refer to or create a new semaphore named -.Fa name . -.Pp -If successful, -.Fn sem_unlink -will return 0. Otherwise, -1 is returned and -.Va errno -is set, and the state of the semaphore is unchanged. -.Sh ERRORS -.Fn sem_unlink -succeeds unless: -.Bl -tag -width Er -.It Bq Er EACCES -Permission is denied to be remove the semaphore. -.It Bq Er ENAMETOOLONG -.Fa name -exceeded -.Dv SEM_NAME_LEN -characters. -.It Bq Er ENOENT -The named semaphore does not exist. -.El -.Sh SEE ALSO -.Xr sem_close 2 , -.Xr sem_open 2 , -.Xr semctl 2 , -.Xr semget 2 , -.Xr semop 2 -.Sh HISTORY -.Fn sem_unlink -is specified in the POSIX Realtime Extension (1003.1b-1993/1003.1i-1995). diff --git a/sys/sem_unlink.c b/sys/sem_unlink.c deleted file mode 100644 index 330c840..0000000 --- a/sys/sem_unlink.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 1999, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#ifdef __APPLE_PR3375657_HACK__ - -#include -#include -#include -#include -#include - -__private_extern__ int _sem_match(const char *name); -extern int __sem_unlink(const char *); - -int -sem_unlink (const char *name) -{ - char *buffer; - - /* - * To work-around applications that don't play - * well in multiple GUI sessions, we append - * shared memory names with the effective user ID. - * It would be better to append the region name - * with a session ID, but nothing like that - * exists at this level of the system yet. - */ - - if (_sem_match(name) && (buffer = alloca(strlen(name) + 32)) != NULL) { - sprintf(buffer, "%s\t%d", name, geteuid()); - name = buffer; - } - - return __sem_unlink(name); -} - -#endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/sem_wait.2 b/sys/sem_wait.2 deleted file mode 100644 index 02f8d85..0000000 --- a/sys/sem_wait.2 +++ /dev/null @@ -1,88 +0,0 @@ -.\" $Darwin$ -.\" -.\" Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" The contents of this file constitute Original Code as defined in and -.\" are subject to the Apple Public Source License Version 1.1 (the -.\" "License"). You may not use this file except in compliance with the -.\" License. Please obtain a copy of the License at -.\" http://www.apple.com/publicsource and read it before using this file. -.\" -.\" This Original Code and all software distributed under the License are -.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the -.\" License for the specific language governing rights and limitations -.\" under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.Dd June 8, 2000 -.Dt SEM_WAIT 2 -.Os Darwin -.Sh NAME -.Nm sem_trywait, sem_wait -.Nd lock a semaphore -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn sem_trywait "sem_t *sem" -.Ft int -.Fn sem_wait "sem_t *sem" -.Sh DESCRIPTION -The semaphore referenced by -.Fa sem -is locked. When calling -.Fn sem_wait , -if the semaphore's value is zero, the calling thread will block until -the lock is acquired or until the call is interrupted by a -signal. Alternatively, the -.Fn sem_trywait -function will fail if the semaphore is already locked, rather than -blocking on the semaphore. -.Pp -If successful (the lock was acquired), -.Fn sem_wait -and -.Fn sem_trywait -will return 0. Otherwise, -1 is returned and -.Va errno -is set, and the state of the semaphore is unchanged. -.Sh ERRORS -.Fn sem_wait -and -.Fn sem_trywait -succeed unless: -.Bl -tag -width Er -.It Bq Er EAGAIN -The semaphore is already locked. -.It Bq Er EDEADLK -A deadlock was detected. -.It Bq Er EINTR -The call was interrupted by a signal. -.It Bq Er EINVAL -.Fa sem -is not a valid semaphore descriptor. -.El -.Sh NOTES -Applications may encounter a priority inversion while using -semaphores. When a thread is waiting on a semaphore which is about to -be posted by a lower-priority thread and the lower-priority thread is -preempted by another thread (of medium priority), a priority inversion -has occured, and the higher-priority thread will be blocked for an -unlimited time period. Programmers using the realtime functionality -of the system should take care to avoid priority inversions. -.Sh SEE ALSO -.Xr sem_open 2 , -.Xr sem_post 2 , -.Xr semctl 2 , -.Xr semget 2 , -.Xr semop 2 -.Sh HISTORY -.Fn sem_wait -and -.Fn sem_trywait -are specified in the POSIX Realtime Extension (1003.1b-1993/1003.1i-1995). diff --git a/sys/sendmsg.c b/sys/sendmsg.c deleted file mode 100644 index 26190cc..0000000 --- a/sys/sendmsg.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2006, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include -#include - -ssize_t __sendmsg_nocancel(int, const struct msghdr *, int); - -/* - * sendmsg stub, legacy version - */ -ssize_t -sendmsg(int s, const struct msghdr *msg, int flags) -{ - int ret = __sendmsg_nocancel(s, msg, flags); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/sendto.c b/sys/sendto.c deleted file mode 100644 index b1fa075..0000000 --- a/sys/sendto.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include -#include - -ssize_t __sendto_nocancel(int, const void *, size_t, int, const struct sockaddr *, socklen_t); - -/* - * sendto stub, legacy version - */ -ssize_t -sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) -{ - int ret = __sendto_nocancel(s, msg, len, flags, to, tolen); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/setattrlist.c b/sys/setattrlist.c deleted file mode 100644 index c8b529a..0000000 --- a/sys/setattrlist.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include - -#include - -#ifdef __LP64__ -extern int __setattrlist(const char *, void *, void *, size_t, unsigned int); -#else /* !__LP64__ */ -extern int __setattrlist(const char *, void *, void *, size_t, unsigned long); -#endif /* __LP64__ */ - -/* - * setattrlist stub, legacy version - */ -int -#ifdef __LP64__ -setattrlist(const char *path, void *attrList, void *attrBuf, - size_t attrBufSize, unsigned int options) -#else /* !__LP64__ */ -setattrlist(const char *path, void *attrList, void *attrBuf, - size_t attrBufSize, unsigned long options) -#endif /* __LP64__ */ -{ - int ret = __setattrlist(path, attrList, attrBuf, attrBufSize, options); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/setregid.2 b/sys/setregid.2 deleted file mode 100644 index 47d7916..0000000 --- a/sys/setregid.2 +++ /dev/null @@ -1,92 +0,0 @@ -.\" Copyright (c) 1980, 1991, 1993, 1994 -.\" The Regents of the University of California. 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)setregid.2 8.2 (Berkeley) 4/16/94 -.\" $FreeBSD: src/lib/libc/sys/setregid.2,v 1.6.2.4 2001/12/14 18:34:01 ru Exp $ -.\" -.Dd April 16, 1994 -.Dt SETREGID 2 -.Os -.Sh NAME -.Nm setregid -.Nd set real and effective group ID -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In unistd.h -.Ft int -.Fn setregid "gid_t rgid" "gid_t egid" -.Sh DESCRIPTION -The real and effective group ID's of the current process -are set to the arguments. -Unprivileged users may change the real group -ID to the effective group ID and vice-versa; only the super-user may -make other changes. -.Pp -Supplying a value of -1 for either the real or effective -group ID forces the system to substitute the current -ID in place of the -1 parameter. -.Pp -The -.Fn setregid -function was intended to allow swapping -the real and effective group IDs -in set-group-ID programs to temporarily relinquish the set-group-ID value. -This function did not work correctly; -its purpose is now better served by the use of the -.Fn setegid -function (see -.Xr setuid 2 ) . -.Pp -When setting the real and effective group IDs to the same value, -the standard -.Fn setgid -function is preferred. -.Sh RETURN VALUES -.Rv -std setregid -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er EPERM -The current process is not the super-user and a change -other than changing the effective group-id to the real group-id -was specified. -.El -.Sh SEE ALSO -.Xr getgid 2 , -.Xr issetugid 2 , -.Xr setegid 2 , -.Xr setgid 2 , -.Xr setuid 2 -.Sh HISTORY -The -.Fn setregid -system call appeared in -.Bx 4.2 . diff --git a/sys/setreuid.2 b/sys/setreuid.2 deleted file mode 100644 index 13cfead..0000000 --- a/sys/setreuid.2 +++ /dev/null @@ -1,90 +0,0 @@ -.\" Copyright (c) 1980, 1991, 1993, 1994 -.\" The Regents of the University of California. 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)setreuid.2 8.2 (Berkeley) 4/16/94 -.\" $FreeBSD: src/lib/libc/sys/setreuid.2,v 1.6.2.6 2001/12/14 18:34:01 ru Exp $ -.\" -.Dd February 8, 2001 -.Dt SETREUID 2 -.Os -.Sh NAME -.Nm setreuid -.Nd set real and effective user IDs -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In unistd.h -.Ft int -.Fn setreuid "uid_t ruid" "uid_t euid" -.Sh DESCRIPTION -The real and effective user IDs of the -current process are set according to the arguments. -If -.Fa ruid -or -.Fa euid -is -1, the current uid is filled in by the system. -Unprivileged users may change the real user -ID to the effective user ID and vice-versa; only the super-user may -make other changes. -.Pp -The -.Fn setreuid -function has been used to swap the real and effective user IDs -in set-user-ID programs to temporarily relinquish the set-user-ID value. -This purpose is now better served by the use of the -.Fn seteuid -function (see -.Xr setuid 2 ) . -.Pp -When setting the real and effective user IDs to the same value, -the standard -.Fn setuid -function is preferred. -.Sh RETURN VALUES -.Rv -std setreuid -.Sh ERRORS -.Bl -tag -width Er -.It Bq Er EPERM -The current process is not the super-user and a change -other than changing the effective user-id to the real user-id -was specified. -.El -.Sh SEE ALSO -.Xr getuid 2 , -.Xr issetugid 2 , -.Xr seteuid 2 , -.Xr setuid 2 -.Sh HISTORY -The -.Fn setreuid -system call appeared in -.Bx 4.2 . diff --git a/sys/setrlimit.c b/sys/setrlimit.c deleted file mode 100644 index 3d1bad8..0000000 --- a/sys/setrlimit.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include - -extern int __setrlimit(int resource, const struct rlimit *rlp); - -/* - * setrlimit stub, for conformance, OR in _RLIMIT_POSIX_FLAG - * - * This is for UNIX03 only. - */ -int -setrlimit(int resource, const struct rlimit *rlp) -{ - resource |= _RLIMIT_POSIX_FLAG; - return(__setrlimit(resource, rlp)); -} diff --git a/sys/shm_open.2 b/sys/shm_open.2 deleted file mode 100644 index 1b4bfc6..0000000 --- a/sys/shm_open.2 +++ /dev/null @@ -1,179 +0,0 @@ -.\" $Darwin$ -.\" -.\" Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" The contents of this file constitute Original Code as defined in and -.\" are subject to the Apple Public Source License Version 1.1 (the -.\" "License"). You may not use this file except in compliance with the -.\" License. Please obtain a copy of the License at -.\" http://www.apple.com/publicsource and read it before using this file. -.\" -.\" This Original Code and all software distributed under the License are -.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the -.\" License for the specific language governing rights and limitations -.\" under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.Dd August 29, 2008 -.Dt SHM_OPEN 2 -.Os Darwin -.Sh NAME -.Nm shm_open -.Nd open a shared memory object -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo shm_open -.Fa "const char *name" -.Fa "int oflag" -.Fa "..." -.Fc -.Pp -The parameter "mode_t mode" is optional. -.Sh DESCRIPTION -The shared memory object referenced by -.Fa name -is opened for reading and/or writing as specified by the argument -.Fa oflag -and the file descriptor returned to the calling process. -The returned file descriptor will be the lowest non-open file -descriptor for the calling process, and is not shared with any -other processes, as it is a new file descriptor. The new file -descriptor will have the -.Dv FD_CLOEXEC -flag set. -Repeated calls -to -.Nm shm_open -with the same string value for -.Fn name -will return a file descriptor referring to the same shared memory -object, provided that the object has not been unlinked by a call to -.Fn shm_unlink . -The -.Fa oflag -argument may indicate the file is to be -created if it does not exist (by specifying the -.Dv O_CREAT -flag), in which case the file is created with mode -.Fa mode -as described in -.Xr chmod 2 -and modified by the process' umask value (see -.Xr umask 2 ) . -.Pp -The value of -.Fa oflag -is formed by -.Em or Ns 'ing -the following values: -.Pp -.Bd -literal -offset indent -compact -O_RDONLY open for reading only -O_RDWR open for reading and writing -O_CREAT create object if it does not exist -O_EXCL error if create and object exists -O_TRUNC truncate size to 0 -.Ed -.Pp -Exactly one of -.Dv O_RDONLY -or -.Dv O_RDWR -must be specified. -.Pp -If -.Dv O_TRUNC -is specified and the -file exists, the file is truncated to zero length. -If -.Dv O_EXCL -is set with -.Dv O_CREAT -and the file already -exists, -.Fn shm_open -returns an error. This may be used to -implement a simple exclusive access locking mechanism. -.Pp -If successful, -.Fn shm_open -returns a non-negative integer, termed a file descriptor. -It returns -1 and sets -.Va errno -on failure. -The file pointer used to mark the current position within the -memory object is set to the beginning of the object. -.Pp -When a new shared memory object is created it is given the -owner and group corresponding to the effective user and -group of the calling process. There is no visible entry in the -file system for the created object in this implementation. -.Pp -When a shared memory object is created, it persists until it -it unlinked and all other references are gone. Objects do -not persist across a system reboot. -.Pp -The system imposes a limit on the number of file descriptors -open simultaneously by one process. -.Xr Getdtablesize 2 -returns the current system limit. -.Sh ERRORS -The named object is opened unless: -.Bl -tag -width Er -.It Bq Er EACCES -The required permissions (for reading and/or writing) -are denied for the given flags. -.It Bq Er EACCES -.Dv O_CREAT -is specified, the object does not exist, and permission to -create the object is denied. -.It Bq Er EEXIST -.Dv O_CREAT -and -.Dv O_EXCL -were specified and the object exists. -.It Bq Er EINTR -The -.Fn shm_open -operation was interrupted by a signal. -.It Bq Er EINVAL -The -.Fn shm_open -operation is not supported. -.It Bq Er EMFILE -The process has already reached its limit for open file descriptors. -.It Bq Er ENAMETOOLONG -.Fa name -exceeded the name size limit. -This is currently -.Dv PSHMNAMLEN -characters (defined in -.In sys/posix_shm.h ) , -but this may change in the future. -.It Bq Er ENFILE -The system file table is full. -.It Bq Er ENOENT -.Dv O_CREAT -is not set and the named object does not exist. -.It Bq Er ENOSPC -.Dv O_CREAT -is specified, the file does not exist, and there is insufficient -space available to create the object. -.El -.Sh SEE ALSO -.Xr chmod 2 , -.Xr close 2 , -.Xr getdtablesize 2 , -.Xr mmap 2 , -.Xr shm_unlink 2 , -.Xr umask 2 -.Sh HISTORY -.Fn shm_open -is specified in the POSIX Realtime Extension (1003.1b-1993/1003.1i-1995). diff --git a/sys/shm_open.c b/sys/shm_open.c deleted file mode 100644 index b03747c..0000000 --- a/sys/shm_open.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 1999, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#ifdef __APPLE_PR3375657_HACK__ - -#include -#include -#include -#include -#include - -__private_extern__ int _shm_match(const char *name); -extern int __shm_open (const char *, int, int); - -int -shm_open (const char *name, int flags, mode_t mode) -{ - char *buffer; - - /* - * To work-around applications that don't play - * well in multiple GUI sessions, we append - * shared memory names with the effective user ID. - * It would be better to append the region name - * with a session ID, but nothing like that - * exists at this level of the system yet. - */ - - if (_shm_match(name) && (buffer = alloca(strlen(name) + 32)) != NULL) { - sprintf(buffer, "%s\t%d", name, geteuid()); - name = buffer; - } - - return __shm_open(name, flags, mode); -} - -#endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/shm_unlink.2 b/sys/shm_unlink.2 deleted file mode 100644 index 7ecc66f..0000000 --- a/sys/shm_unlink.2 +++ /dev/null @@ -1,87 +0,0 @@ -.\" $Darwin$ -.\" -.\" Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" The contents of this file constitute Original Code as defined in and -.\" are subject to the Apple Public Source License Version 1.1 (the -.\" "License"). You may not use this file except in compliance with the -.\" License. Please obtain a copy of the License at -.\" http://www.apple.com/publicsource and read it before using this file. -.\" -.\" This Original Code and all software distributed under the License are -.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the -.\" License for the specific language governing rights and limitations -.\" under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.Dd August 31, 2006 -.Dt SHM_UNLINK 2 -.Os Darwin -.Sh NAME -.Nm shm_unlink -.Nd remove shared memory object -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn shm_unlink "const char *name" -.Sh DESCRIPTION -The -.Fn shm_unlink -function disassociates the shared memory object specified by -.Fa name -from that name. -The resources associated with the shared memory object remain intact -until the last file descriptor reference is removed, e.g., by -.Xr close 2 -or -.Xr munmap 2 , -at which point the resources are reclaimed -(if no references exist at the time of the call to -.Fn shm_unlink , -the resources are reclaimed immediately). -The name can only be reused -when it is bound to a new shared memory object with a call to -.Xr shm_open 2 -with the -.Dv O_CREAT -flag. -.Sh RETURN VALUES -Upon successful completion, a value of 0 is returned. -Otherwise, a value of -1 is returned and -.Va errno -is set to indicate the error, -and the named shared memory object will remain unchanged. -.Sh ERRORS -The -.Fn shm_unlink -succeeds unless: -.Bl -tag -width Er -.It Bq Er EACCES -Permission is denied to be remove the object. -.It Bq Er ENAMETOOLONG -.Fa name -exceeded the name size limit. -This is currently -.Dv PSHMNAMLEN -characters (defined in -.In sys/posix_shm.h ) , -but this may change in the future. -.It Bq Er ENOENT -The named object does not exist. -.El -.Sh SEE ALSO -.Xr close 2 , -.Xr mmap 2 , -.Xr munmap 2 , -.Xr shm_open 2 , -.Xr shmat 2 , -.Xr shmctl 2 -.Sh HISTORY -.Fn shm_open -is specified in the POSIX Realtime Extension (1003.1b-1993/1003.1i-1995). diff --git a/sys/shm_unlink.c b/sys/shm_unlink.c deleted file mode 100644 index 869bfc5..0000000 --- a/sys/shm_unlink.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 1999, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#ifdef __APPLE_PR3375657_HACK__ - -#include -#include -#include -#include -#include - -__private_extern__ int _shm_match(const char *name); -extern int __shm_unlink (const char *); - -int -shm_unlink (const char *name) -{ - char *buffer; - - /* - * To work-around applications that don't play - * well in multiple GUI sessions, we append - * shared memory names with the effective user ID. - * It would be better to append the region name - * with a session ID, but nothing like that - * exists at this level of the system yet. - */ - - if (_shm_match(name) && (buffer = alloca(strlen(name) + 32)) != NULL) { - sprintf(buffer, "%s\t%d", name, geteuid()); - name = buffer; - } - - return __shm_unlink(name); -} - -#endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/slot_name.c b/sys/slot_name.c new file mode 100644 index 0000000..a780430 --- /dev/null +++ b/sys/slot_name.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * File: slot_name.c + * Author: Avadis Tevanian, Jr. + * + * Copyright (C) 1987, Avadis Tevanian, Jr. + * + * Convert machine slot values to human readable strings. + * + * HISTORY + * 26-Jan-88 Mary Thompson (mrt) at Carnegie Mellon + * added case for CUP_SUBTYPE_RT_APC + * + * 28-Feb-87 Avadis Tevanian (avie) at Carnegie-Mellon University + * Created. + * + */ + +#include +#include + +/* + * Convert the specified cpu_type/cpu_subtype pair to their + * human readable form. + */ +void slot_name(cpu_type, cpu_subtype, cpu_name, cpu_subname) + cpu_type_t cpu_type; + cpu_subtype_t cpu_subtype; + char **cpu_name, **cpu_subname; +{ + register char *name = "Unknown CPU"; + register char *subname = ""; + const NXArchInfo *ai = NXGetArchInfoFromCpuType(cpu_type, cpu_subtype); + if (ai != NULL) { + name = (char *)ai->name; + subname = (char *)ai->description; + } + *cpu_name = name; + *cpu_subname = subname; +} diff --git a/sys/socketpair.c b/sys/socketpair.c deleted file mode 100644 index fbe1b79..0000000 --- a/sys/socketpair.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * We need conformance on so that EOPNOTSUPP=102. But the routine symbol - * will still be the legacy (undecorated) one. - */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 - -#include -#include - -#include - -extern int __socketpair(int, int, int, int [2]); - -/* - * socketpair stub, legacy version - */ -int -socketpair(int domain, int type, int protocol, int socket_vector[2]) -{ - int ret = __socketpair(domain, type, protocol, socket_vector); - - /* use ENOTSUP for legacy behavior */ - if (ret < 0 && errno == EOPNOTSUPP) - errno = ENOTSUP; - return ret; -} diff --git a/sys/spinlock.3 b/sys/spinlock.3 index b11de26..18ba5a3 100644 --- a/sys/spinlock.3 +++ b/sys/spinlock.3 @@ -42,5 +42,4 @@ unconditionally unlocks the lock by zeroing it. returns true if it took the lock, false if the lock was already held. .Sh SEE ALSO .Xr atomic 3 , -.Xr atomicqueue 3 , -.Xr barrier 3 \ No newline at end of file +.Xr barrier 3 diff --git a/sys/stack_protector-obsd.c b/sys/stack_protector-obsd.c index 4463619..74976f6 100644 --- a/sys/stack_protector-obsd.c +++ b/sys/stack_protector-obsd.c @@ -1,3 +1,5 @@ +/* $OpenBSD: stack_protector.c,v 1.10 2006/03/31 05:34:44 deraadt Exp $ */ + /* * Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat. * All rights reserved. @@ -25,48 +27,113 @@ * */ -#if defined(LIBC_SCCS) && !defined(list) -static char rcsid[] = "$OpenBSD: stack_protector.c,v 1.3 2002/12/10 08:53:42 etoh Exp $"; -#endif - #include -#include -#include -#include +#include +#include +#include +#include #include +#include #include +#include "CrashReporterClient.h" +#include "libproc.h" +#include "_simple.h" -extern void __abort(void) __dead2; -long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -void __guard_setup(void) __attribute__ ((visibility ("hidden"))); +#define GUARD_MAX 8 +long __stack_chk_guard[GUARD_MAX] = {0, 0, 0, 0, 0, 0, 0, 0}; +void __abort(void) __dead2; +void __guard_setup(const char *apple[]) __attribute__ ((visibility ("hidden"))); void __stack_chk_fail(void); +static void +__guard_from_kernel(const char *str) +{ + unsigned long long val; + char tmp[20], *p; + int idx = 0; + + /* Skip over the 'stack_guard=' key to the list of values */ + str = strchr(str, '='); + if (str == NULL) + return; + str++; + + while (str && idx < GUARD_MAX) { + /* + * Pull the next numeric string out of the list and convert it to + * a real number. + */ + strlcpy(tmp, str, 20); + p = strchr(tmp, ','); + if (p) + *p = '\0'; + val = strtoull(tmp, NULL, 0); + __stack_chk_guard[idx] = (long)(val & ((unsigned long) -1)); + idx++; + if ((str = strchr(str, ',')) != NULL) + str++; + } +} + void -__guard_setup(void) +__guard_setup(const char *apple[]) { - int fd; - if (__stack_chk_guard[0]!=0) return; - fd = open ("/dev/urandom", 0); - if (fd != -1) { - ssize_t size = read (fd, (char*)&__stack_chk_guard, - sizeof(__stack_chk_guard)); - close (fd) ; - if (size == sizeof(__stack_chk_guard) - && *__stack_chk_guard != 0) return; - } - /* If a random generator can't be used, the protector switches the guard - to the "terminator canary" */ - ((char*)__stack_chk_guard)[0] = 0; ((char*)__stack_chk_guard)[1] = 0; - ((char*)__stack_chk_guard)[2] = '\n'; ((char*)__stack_chk_guard)[3] = 255; + int fd; + size_t len; + const char **p; + + if (__stack_chk_guard[0] != 0) + return; + + for (p = apple; p && *p; p++) { + if (strstr(*p, "stack_guard") == *p) { + __guard_from_kernel(*p); + if (__stack_chk_guard[0] != 0) + return; + } + } + + fd = open ("/dev/urandom", 0); + if (fd != -1) { + len = read (fd, (char*)&__stack_chk_guard, sizeof(__stack_chk_guard)); + close(fd); + if (len == sizeof(__stack_chk_guard) && + *__stack_chk_guard != 0) + return; + } + + /* If If a random generator can't be used, the protector switches the guard + to the "terminator canary" */ + ((unsigned char *)__stack_chk_guard)[0] = 0; + ((unsigned char *)__stack_chk_guard)[1] = 0; + ((unsigned char *)__stack_chk_guard)[2] = '\n'; + ((unsigned char *)__stack_chk_guard)[3] = 255; } +#define STACKOVERFLOW "] stack overflow" + void __stack_chk_fail() { - const char message[] = "[%d] stack overflow"; + char n[16]; // bigger than will hold the digits in a pid_t + char *np; + int pid = getpid(); + char message[sizeof(n) + sizeof(STACKOVERFLOW)] = "["; + char prog[2*MAXCOMLEN+1] = {0}; - /* this may fail on a chroot jail, though luck */ - syslog(LOG_CRIT, message, getpid()); + proc_name(pid, prog, 2*MAXCOMLEN); + prog[2*MAXCOMLEN] = 0; + np = n + sizeof(n); + *--np = 0; + while(pid > 0) { + *--np = (pid % 10) + '0'; + pid /= 10; + } + strlcat(message, np, sizeof(message)); + strlcat(message, STACKOVERFLOW, sizeof(message)); + /* This may fail on a chroot jail... */ + _simple_asl_log_prog(ASL_LEVEL_CRIT, "user", message, prog); - __abort(); + CRSetCrashLogMessage(message); + __abort(); } diff --git a/sys/undelete.2 b/sys/undelete.2 deleted file mode 100644 index ea5fef4..0000000 --- a/sys/undelete.2 +++ /dev/null @@ -1,109 +0,0 @@ -.\" Copyright (c) 1994 -.\" Jan-Simon Pendry -.\" The Regents of the University of California. 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. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)undelete.2 8.4 (Berkeley) 10/18/94 -.\" $FreeBSD: src/lib/libc/sys/undelete.2,v 1.17 2006/01/22 19:49:37 truckman Exp $ -.\" -.Dd January 22, 2006 -.Dt UNDELETE 2 -.Os -.Sh NAME -.Nm undelete -.Nd attempt to recover a deleted file -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In unistd.h -.Ft int -.Fn undelete "const char *path" -.Sh DESCRIPTION -The -.Fn undelete -system call attempts to recover the deleted file named by -.Fa path . -Currently, this works only when the named object -is a whiteout in a union file system. -The system call removes the whiteout causing -any objects in a lower layer of the -union stack to become visible once more. -.Pp -Eventually, the -.Fn undelete -functionality may be expanded to other file systems able to recover -deleted files such as the log-structured file system. -.Sh RETURN VALUES -.Rv -std undelete -.Sh ERRORS -The -.Fn undelete -succeeds unless: -.Bl -tag -width Er -.It Bq Er ENOTDIR -A component of the path prefix is not a directory. -.It Bq Er ENAMETOOLONG -A component of a pathname exceeded 255 characters, -or an entire path name exceeded 1023 characters. -.It Bq Er EEXIST -The path does not reference a whiteout. -.It Bq Er ENOENT -The named whiteout does not exist. -.It Bq Er EACCES -Search permission is denied for a component of the path prefix. -.It Bq Er EACCES -Write permission is denied on the directory containing the name -to be undeleted. -.It Bq Er ELOOP -Too many symbolic links were encountered in translating the pathname. -.It Bq Er EPERM -The directory containing the name is marked sticky, -and the containing directory is not owned by the effective user ID. -.It Bq Er EINVAL -The last component of the path is -.Ql .. . -.It Bq Er EIO -An I/O error occurred while updating the directory entry. -.It Bq Er EROFS -The name resides on a read-only file system. -.It Bq Er EFAULT -The -.Fa path -argument -points outside the process's allocated address space. -.El -.Sh SEE ALSO -.Xr unlink 2 , -.Xr mount_unionfs 8 -.Sh HISTORY -The -.Fn undelete -system call first appeared in -.Bx 4.4 Lite . diff --git a/threads/Makefile.inc b/threads/Makefile.inc index 4b5fd6c..ad93bed 100644 --- a/threads/Makefile.inc +++ b/threads/Makefile.inc @@ -2,4 +2,6 @@ .sinclude "${.CURDIR}/${MACHINE_ARCH}/threads/Makefile.inc" -MISRCS += cprocs.c cthreads.c lu_utils.c mig_support.c +MISRCS += cprocs.c cthreads.c mig_support.c + +DYLDSRCS += mig_support.c diff --git a/threads/cprocs.c b/threads/cprocs.c index 9680a18..71be8b9 100644 --- a/threads/cprocs.c +++ b/threads/cprocs.c @@ -145,9 +145,14 @@ cthread_set_errno_self(error) { int *ep = __error(); extern int __unix_conforming; + pthread_t self = NULL; - if ((__unix_conforming) && (error == EINTR) && (__pthread_canceled(0) == 0)) + if ((__unix_conforming) && ((error & 0xff) == EINTR) && (__pthread_canceled(0) == 0)) { + self = pthread_self(); + if (self != NULL) + self->cancel_error = error; pthread_exit(PTHREAD_CANCELED); + } if (ep != &errno) *ep = error; diff --git a/threads/cthreads.c b/threads/cthreads.c index 0aca02d..2b301ab 100644 --- a/threads/cthreads.c +++ b/threads/cthreads.c @@ -77,9 +77,9 @@ extern void _malloc_fork_prepare(), _malloc_fork_parent(); extern void _malloc_fork_child(); extern void fork_mach_init(); extern void _cproc_fork_child(), _stack_fork_child(); -extern void _lu_fork_child(void); extern void _asl_fork_child(void); extern void _pthread_fork_child(pthread_t); +extern void _pthread_fork_child_postinit(); extern void _notify_fork_child(void); static pthread_t psaved_self = 0; @@ -170,7 +170,6 @@ void _cthread_fork_child() */ { pthread_t p = psaved_self; - struct pthread_atfork_entry *e; _pthread_set_self(p); _spin_unlock(&psaved_self_global_lock); @@ -178,24 +177,22 @@ void _cthread_fork_child() _malloc_fork_child(); p->kernel_thread = mach_thread_self(); p->reply_port = mach_reply_port(); - p->mutexes = NULL; p->__cleanup_stack = NULL; p->death = MACH_PORT_NULL; p->joiner = NULL; p->detached |= _PTHREAD_CREATE_PARENT; _spin_unlock(&p->lock); - fork_mach_init(); _pthread_fork_child(p); +} - _cproc_fork_child(); - - _lu_fork_child(); - _asl_fork_child(); - _notify_fork_child(); +void _cthread_fork_child_postinit() +{ + struct pthread_atfork_entry *e; __is_threaded = 0; + _pthread_fork_child_postinit(); mig_init(1); /* enable multi-threaded mig interfaces */ pthread_workqueue_atfork_child(); @@ -204,7 +201,5 @@ void _cthread_fork_child() if (e->child != NULL) e->child(); } - LOCK_INIT(pthread_atfork_lock); - + LOCK_INIT(pthread_atfork_lock); } - diff --git a/threads/lu_utils.c b/threads/lu_utils.c deleted file mode 100644 index 22d7785..0000000 --- a/threads/lu_utils.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Port and memory management for doing lookups to the lookup server - * Copyright (C) 1989 by NeXT, Inc. - */ -/* - * HISTORY - * 27-Mar-90 Gregg Kellogg (gk) at NeXT - * Changed to use bootstrap port instead of service port. - * - */ -#include -#include -#include -#include -#include -#include -#include - -mach_port_t _lu_port = MACH_PORT_NULL; -mach_port_t _ds_port = MACH_PORT_NULL; -mach_port_t _mbr_port = MACH_PORT_NULL; - -static name_t LOOKUP_NAME = "lookup daemon v2"; - -#ifndef kDSStdMachDSLookupPortName -#define kDSStdMachDSLookupPortName "com.apple.system.DirectoryService.libinfo_v1" -#define kDSStdMachDSMembershipPortName "com.apple.system.DirectoryService.membership_v1" -#endif - -mach_port_t -_lookupd_port(mach_port_t port) -{ - kern_return_t status; - - if (port != MACH_PORT_NULL) - { - status = bootstrap_register(bootstrap_port, LOOKUP_NAME, port); - if (status != BOOTSTRAP_SUCCESS) abort(); - - return port; - } - else if ((_lu_port == MACH_PORT_NULL) && (getpid() > 1)) - { - status = bootstrap_look_up(bootstrap_port, LOOKUP_NAME, &_lu_port); - if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _lu_port = MACH_PORT_NULL; - } - - return _lu_port; -} - -/* called as child starts up. mach ports aren't inherited: trash cache */ -void -_lu_fork_child() -{ - _lu_port = MACH_PORT_NULL; - _ds_port = MACH_PORT_NULL; - _mbr_port = MACH_PORT_NULL; -} - -void -_lu_setport(mach_port_t desired) -{ - if (_lu_port != MACH_PORT_NULL) mach_port_deallocate(mach_task_self(), _lu_port); - _lu_port = desired; -} - -int -_lu_running(void) -{ - return ((_lu_port != MACH_PORT_NULL) || (_lookupd_port(MACH_PORT_NULL) != MACH_PORT_NULL)); -} - -int -_ds_running(void) -{ - kern_return_t status; - - if (_ds_port != MACH_PORT_NULL) return 1; - - status = bootstrap_look_up(bootstrap_port, kDSStdMachDSLookupPortName, &_ds_port); - if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _ds_port = MACH_PORT_NULL; - - status = bootstrap_look_up(bootstrap_port, kDSStdMachDSMembershipPortName, &_mbr_port); - if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _mbr_port = MACH_PORT_NULL; - - return (_ds_port != MACH_PORT_NULL); -} diff --git a/threads/mig_support.c b/threads/mig_support.c index bf662c2..30cb7be 100644 --- a/threads/mig_support.c +++ b/threads/mig_support.c @@ -74,99 +74,23 @@ mig_init(init_done) * can result in a call to malloc() which eventually reenters * mig_get_reply_port() and deadlocks. */ -mach_port_t -mig_get_reply_port() +mach_port_t _mig_get_reply_port() { - register cproc_t self; - pthread_t pself; -#ifdef CTHREADS_DEBUG - int d = cthread_debug; -#endif /* CTHREADS_DEBUG */ + pthread_t pself; -#ifdef CTHREADS_DEBUG - cthread_debug = FALSE; -#endif /* CTHREADS_DEBUG */ - pself = pthread_self(); - if ((pself != (pthread_t)NULL) && (pself->sig == _PTHREAD_SIG)) { - if (pself->reply_port == MACH_PORT_NULL) { - pself->reply_port = mach_reply_port(); - } - return pself->reply_port; - } - self = cproc_self(); - if (self == NO_CPROC) { -#ifdef CTHREADS_DEBUG - cthread_debug = d; -#endif /* CTHREADS_DEBUG */ - return(_task_reply_port); - } - if (self->reply_port == MACH_PORT_NULL) { - self->reply_port = mach_reply_port(); - } -#ifdef CTHREADS_DEBUG - cthread_debug = d; -#endif /* CTHREADS_DEBUG */ - return self->reply_port; -} - -/* - * Called by mig interface code after a timeout on the reply port. - * May also be called by user. The new mig calls with port passed in - * We are ignoring this , so is osfmk cthreads code - */ -void -mig_dealloc_reply_port(mach_port_t migport) -{ - register cproc_t self; - pthread_t pself; - register mach_port_t port; -#ifdef CTHREADS_DEBUG - int d = cthread_debug; -#endif /* CTHREADS_DEBUG */ - -#ifdef CTHREADS_DEBUG - cthread_debug = FALSE; -#endif /* CTHREADS_DEBUG */ - pself = pthread_self(); - if ((pself != (pthread_t)NULL) && (pself->sig == _PTHREAD_SIG)) { - port = pself->reply_port; - if (port != MACH_PORT_NULL && port != _task_reply_port) { - LOCK(reply_port_lock); - pself->reply_port = _task_reply_port; - (void) mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1); - pself->reply_port = MACH_PORT_NULL; - UNLOCK(reply_port_lock); - } - return; - } - self = cproc_self(); - if (self == NO_CPROC) { -#ifdef CTHREADS_DEBUG - cthread_debug = d; -#endif /* CTHREADS_DEBUG */ - return; - } - ASSERT(self != NO_CPROC); - port = self->reply_port; - if (port != MACH_PORT_NULL && port != _task_reply_port) { - LOCK(reply_port_lock); - self->reply_port = _task_reply_port; - (void) mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1); - self->reply_port = MACH_PORT_NULL; - UNLOCK(reply_port_lock); - } -#ifdef CTHREADS_DEBUG - cthread_debug = d; -#endif /* CTHREADS_DEBUG */ + pself = pthread_self(); + if ((pself != (pthread_t)NULL) && (pself->sig == _PTHREAD_SIG)) { + return pself->reply_port; + } + return MACH_PORT_NULL; } -/************************************************************* - * Called by mig interfaces after each RPC. - * Could be called by user. - ***********************************************************/ - -void -mig_put_reply_port( - mach_port_t reply_port) +void _mig_set_reply_port(mach_port_t port) { + pthread_t pself; + pself = pthread_self(); + + if ((pself != (pthread_t)NULL) && (pself->sig == _PTHREAD_SIG)) { + pself->reply_port = port; + } } diff --git a/util/login.c b/util/login.c index 2ce03d3..39fcf07 100644 --- a/util/login.c +++ b/util/login.c @@ -53,7 +53,6 @@ * SUCH DAMAGE. */ - #include #include #include diff --git a/util/logout.c b/util/logout.c index d26776c..2452014 100644 --- a/util/logout.c +++ b/util/logout.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2005, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -81,16 +81,16 @@ logout(char *line) strncpy(utx.ut_line, line, sizeof(utx.ut_line)); utx.ut_type = UTMPX_AUTOFILL_MASK | UTMPX_DEAD_IF_CORRESPONDING_MASK | DEAD_PROCESS; (void)gettimeofday(&utx.ut_tv, NULL); - UTMPX_LOCK; - _setutxent(); - ux = _pututxline(&utx); - _endutxent(); + UTMPX_LOCK(&__utx__); + __setutxent(&__utx__); + ux = __pututxline(&__utx__, &utx); + __endutxent(&__utx__); if (!ux) { - UTMPX_UNLOCK; + UTMPX_UNLOCK(&__utx__); return 0; } #ifdef UTMP_COMPAT - if (utfile_system) { /* only if we are using _PATH_UTMPX */ + if (__utx__.utfile_system) { /* only if we are using _PATH_UTMPX */ which = _utmp_compat(ux, &u); if (which & UTMP_COMPAT_UTMP0) _write_utmp(&u, 0); @@ -98,6 +98,6 @@ logout(char *line) _write_utmp(&u, 1); } #endif /* UTMP_COMPAT */ - UTMPX_UNLOCK; + UTMPX_UNLOCK(&__utx__); return 1; } diff --git a/util/opendev.c b/util/opendev.c index e16c707..ee5c85b 100644 --- a/util/opendev.c +++ b/util/opendev.c @@ -31,9 +31,22 @@ #include #include #include +#include #include "util.h" +/* + * opendev(3) is an inherently non-thread-safe API, since + * it returns a buffer to global storage. However we can + * at least make sure the storage allocation is thread safe + * and does not leak memory in case of simultaneous + * initialization + */ +static pthread_once_t opendev_namebuf_once = PTHREAD_ONCE_INIT; +static char *namebuf = NULL; + +static void opendev_namebuf_init(void); + int opendev(path, oflags, dflags, realpath) char *path; @@ -43,7 +56,6 @@ opendev(path, oflags, dflags, realpath) { int fd; char *slash, *prefix; - static char namebuf[PATH_MAX]; /* Initial state */ if (realpath) @@ -51,6 +63,13 @@ opendev(path, oflags, dflags, realpath) fd = -1; errno = ENOENT; + if (pthread_once(&opendev_namebuf_once, + opendev_namebuf_init) + || !namebuf) { + errno = ENOMEM; + return -1; + } + if (dflags & OPENDEV_BLCK) prefix = ""; /* block device */ else @@ -59,8 +78,8 @@ opendev(path, oflags, dflags, realpath) if ((slash = strchr(path, '/'))) fd = open(path, oflags); else if (dflags & OPENDEV_PART) { - if (snprintf(namebuf, sizeof(namebuf), "%s%s%s", - _PATH_DEV, prefix, path) < sizeof(namebuf)) { + if (snprintf(namebuf, PATH_MAX, "%s%s%s", + _PATH_DEV, prefix, path) < PATH_MAX) { char *slice; while ((slice = strrchr(namebuf, 's')) && isdigit(*(slice-1))) *slice = '\0'; @@ -71,8 +90,8 @@ opendev(path, oflags, dflags, realpath) errno = ENAMETOOLONG; } if (!slash && fd == -1 && errno == ENOENT) { - if (snprintf(namebuf, sizeof(namebuf), "%s%s%s", - _PATH_DEV, prefix, path) < sizeof(namebuf)) { + if (snprintf(namebuf, PATH_MAX, "%s%s%s", + _PATH_DEV, prefix, path) < PATH_MAX) { fd = open(namebuf, oflags); if (realpath) *realpath = namebuf; @@ -81,3 +100,8 @@ opendev(path, oflags, dflags, realpath) } return (fd); } + +static void opendev_namebuf_init(void) +{ + namebuf = malloc(PATH_MAX); +} diff --git a/util/pty.c b/util/pty.c index 369ad48..f6a72e1 100644 --- a/util/pty.c +++ b/util/pty.c @@ -69,8 +69,6 @@ #include #include -static char ptytemplate[] = "/dev/ptyXX"; - int openpty(amaster, aslave, name, termp, winp) int *amaster, *aslave; char *name; diff --git a/uuid/unparse-uuid.c b/uuid/unparse-uuid.c deleted file mode 120000 index bac9a9f..0000000 --- a/uuid/unparse-uuid.c +++ /dev/null @@ -1 +0,0 @@ -./unparse.c \ No newline at end of file diff --git a/uuid/unparse-uuid.c b/uuid/unparse-uuid.c new file mode 100644 index 0000000..dd7814a --- /dev/null +++ b/uuid/unparse-uuid.c @@ -0,0 +1,86 @@ +/* + * unparse.c -- convert a UUID to string + * + * Copyright (C) 1996, 1997 Theodore Ts'o. + * + * %Begin-Header% + * 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, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * %End-Header% + */ + +#include + +#include "uuidP.h" + +static const char *fmt_lower = + "0123456789abcdef"; + +static const char *fmt_upper = + "0123456789ABCDEF"; + +#ifdef UUID_UNPARSE_DEFAULT_UPPER +#define FMT_DEFAULT fmt_upper +#else +#define FMT_DEFAULT fmt_lower +#endif + +static void uuid_unparse_x(const uuid_t uu, char *out, const char *fmt) +{ + const uint8_t *uuid_array = (const uint8_t *)uu; + int uuid_index; + + for ( uuid_index = 0; uuid_index < sizeof(uuid_t); ++uuid_index ) { + // insert '-' after the 4th, 6th, 8th, and 10th uuid byte + switch (uuid_index) { + case 4: + case 6: + case 8: + case 10: + *out++ = '-'; + break; + } + // insert uuid byte as two hex characters + *out++ = fmt[*uuid_array >> 4]; + *out++ = fmt[*uuid_array++ & 0xF]; + } + *out = 0; +} + +void uuid_unparse_lower(const uuid_t uu, char *out) +{ + uuid_unparse_x(uu, out, fmt_lower); +} + +void uuid_unparse_upper(const uuid_t uu, char *out) +{ + uuid_unparse_x(uu, out, fmt_upper); +} + +void uuid_unparse(const uuid_t uu, char *out) +{ + uuid_unparse_x(uu, out, FMT_DEFAULT); +} diff --git a/uuid/uuid_unparse.3 b/uuid/uuid_unparse.3 index 4b518a0..a4964db 100644 --- a/uuid/uuid_unparse.3 +++ b/uuid/uuid_unparse.3 @@ -38,15 +38,15 @@ uuid_unparse \- convert an UUID from binary representation to a string .sp \fIvoid\fP .br -\fBuuid_unparse\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +\fBuuid_unparse\fP(\fIuuid_t uu\fP, \fIuuid_string_t out\fP); .sp \fIvoid\fP .br -\fBuuid_unparse_lower\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +\fBuuid_unparse_lower\fP(\fIuuid_t uu\fP, \fIuuid_string_t out\fP); .sp \fIvoid\fP .br -\fBuuid_unparse_upper\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +\fBuuid_unparse_upper\fP(\fIuuid_t uu\fP, \fIuuid_string_t out\fP); .sp .fi .SH DESCRIPTION @@ -54,7 +54,7 @@ The .B uuid_unparse function converts the supplied UUID .I uu -from the binary representation into a 36\-byte string (plus tailing '\\0') +from the binary representation into a uuid_string_t (37\-byte string including tailing '\\0') of the form 1b4e28ba\-2fa1\-11d2\-883f\-b9a761bde3fb and stores this value in the character string pointed to by .IR out . diff --git a/uuid/uuid_unparse.3-uuid.in b/uuid/uuid_unparse.3-uuid.in index 57b7cbe..70734fd 100644 --- a/uuid/uuid_unparse.3-uuid.in +++ b/uuid/uuid_unparse.3-uuid.in @@ -38,15 +38,15 @@ uuid_unparse \- convert an UUID from binary representation to a string .sp \fIvoid\fP .br -\fBuuid_unparse\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +\fBuuid_unparse\fP(\fIuuid_t uu\fP, \fIuuid_string_t out\fP); .sp \fIvoid\fP .br -\fBuuid_unparse_lower\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +\fBuuid_unparse_lower\fP(\fIuuid_t uu\fP, \fIuuid_string_t out\fP); .sp \fIvoid\fP .br -\fBuuid_unparse_upper\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +\fBuuid_unparse_upper\fP(\fIuuid_t uu\fP, \fIuuid_string_t out\fP); .sp .fi .SH DESCRIPTION @@ -54,7 +54,7 @@ The .B uuid_unparse function converts the supplied UUID .I uu -from the binary representation into a 36\-byte string (plus tailing '\\0') +from the binary representation into a uuid_string_t (37\-byte string including tailing '\\0') of the form 1b4e28ba\-2fa1\-11d2\-883f\-b9a761bde3fb and stores this value in the character string pointed to by .IR out . diff --git a/uuid/uuidsrc/unparse.c.patch b/uuid/uuidsrc/unparse.c.patch new file mode 100644 index 0000000..97a71eb --- /dev/null +++ b/uuid/uuidsrc/unparse.c.patch @@ -0,0 +1,48 @@ +--- unparse.c.orig 2010-06-27 12:49:24.000000000 -0700 ++++ unparse.c 2010-06-27 13:06:53.000000000 -0700 +@@ -37,10 +37,10 @@ + #include "uuidP.h" + + static const char *fmt_lower = +- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"; ++ "0123456789abcdef"; + + static const char *fmt_upper = +- "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"; ++ "0123456789ABCDEF"; + + #ifdef UUID_UNPARSE_DEFAULT_UPPER + #define FMT_DEFAULT fmt_upper +@@ -50,14 +50,24 @@ static const char *fmt_upper = + + static void uuid_unparse_x(const uuid_t uu, char *out, const char *fmt) + { +- struct uuid uuid; +- +- uuid_unpack(uu, &uuid); +- sprintf(out, fmt, +- uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, +- uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, +- uuid.node[0], uuid.node[1], uuid.node[2], +- uuid.node[3], uuid.node[4], uuid.node[5]); ++ const uint8_t *uuid_array = (const uint8_t *)uu; ++ int uuid_index; ++ ++ for ( uuid_index = 0; uuid_index < sizeof(uuid_t); ++uuid_index ) { ++ // insert '-' after the 4th, 6th, 8th, and 10th uuid byte ++ switch (uuid_index) { ++ case 4: ++ case 6: ++ case 8: ++ case 10: ++ *out++ = '-'; ++ break; ++ } ++ // insert uuid byte as two hex characters ++ *out++ = fmt[*uuid_array >> 4]; ++ *out++ = fmt[*uuid_array++ & 0xF]; ++ } ++ *out = 0; + } + + void uuid_unparse_lower(const uuid_t uu, char *out) diff --git a/uuid/uuidsrc/uuid_unparse.3.in.patch b/uuid/uuidsrc/uuid_unparse.3.in.patch index 4ffe2c6..170f27b 100644 --- a/uuid/uuidsrc/uuid_unparse.3.in.patch +++ b/uuid/uuidsrc/uuid_unparse.3.in.patch @@ -1,6 +1,6 @@ ---- uuid_unparse.3.in.orig 2008-09-25 10:43:40.000000000 -0700 -+++ uuid_unparse.3.in 2008-09-25 10:51:45.000000000 -0700 -@@ -36,9 +36,18 @@ +--- uuid_unparse.3.in.orig 2010-04-28 23:38:50.000000000 -0700 ++++ uuid_unparse.3.in 2010-04-28 23:53:36.000000000 -0700 +@@ -36,17 +36,26 @@ uuid_unparse \- convert an UUID from bin .nf .B #include .sp @@ -9,24 +9,25 @@ -.BI "void uuid_unparse_lower(uuid_t " uu ", char *" out ); +\fIvoid\fP +.br -+\fBuuid_unparse\fP(\fIuuid_t uu\fP, \fIchar * out\fP); ++\fBuuid_unparse\fP(\fIuuid_t uu\fP, \fIuuid_string_t out\fP); +.sp +\fIvoid\fP +.br -+\fBuuid_unparse_lower\fP(\fIuuid_t uu\fP, \fIchar * out\fP); ++\fBuuid_unparse_lower\fP(\fIuuid_t uu\fP, \fIuuid_string_t out\fP); +.sp +\fIvoid\fP +.br -+\fBuuid_unparse_upper\fP(\fIuuid_t uu\fP, \fIchar * out\fP); ++\fBuuid_unparse_upper\fP(\fIuuid_t uu\fP, \fIuuid_string_t out\fP); +.sp .fi .SH DESCRIPTION The -@@ -46,7 +55,7 @@ + .B uuid_unparse function converts the supplied UUID .I uu - from the binary representation into a 36\-byte string (plus tailing '\\0') +-from the binary representation into a 36\-byte string (plus tailing '\\0') -of the form 1b4e28ba\-2fa1\-11d2\-883f\-b9a76 and stores this value in the ++from the binary representation into a uuid_string_t (37\-byte string including tailing '\\0') +of the form 1b4e28ba\-2fa1\-11d2\-883f\-b9a761bde3fb and stores this value in the character string pointed to by .IR out . diff --git a/x86_64/gen/Makefile.inc b/x86_64/gen/Makefile.inc index ea860f1..ef0825d 100644 --- a/x86_64/gen/Makefile.inc +++ b/x86_64/gen/Makefile.inc @@ -10,7 +10,8 @@ MDSRCS+= _ctx_start.S \ mcount.s \ setcontext.c \ setjmperr.c \ - swapcontext.c + swapcontext.c \ + cpu_number.s .for _src in makecontext.c setcontext.c swapcontext.c CFLAGS-${_src} += -fomit-frame-pointer diff --git a/x86_64/gen/cpu_number.s b/x86_64/gen/cpu_number.s new file mode 100644 index 0000000..e76be3d --- /dev/null +++ b/x86_64/gen/cpu_number.s @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +/* + * This routine provides fast access to the logical cpu number + * of the calling processor assuming no pre-emption occurs. This number + * is encoded in the bottom 12-bits of the limit field of the IDTR (the + * Interrupt Descriptor Table Register). The SIDT instruction is used in + * userspace to read this register and thus to gain access to the cpu number. + * The IDTR is loaded by the kernel for each processor at startup - see + * osfmk/i386/mp_desc.c. + */ + +/* return logical cpu number in %rax */ + + .private_extern _cpu_number +_cpu_number: + push %rbp + mov %rsp,%rbp + sub $16,%rsp // space to read IDTR + + sidt (%rsp) // store limit:base on stack + movw (%rsp), %ax // get limit + and $0xfff, %rax // mask off lower 12 bits to return + + mov %rbp,%rsp + pop %rbp + ret diff --git a/x86_64/gen/getmcontext.c b/x86_64/gen/getmcontext.c index 4359e03..b8a2ea6 100644 --- a/x86_64/gen/getmcontext.c +++ b/x86_64/gen/getmcontext.c @@ -68,7 +68,7 @@ getmcontext(ucontext_t *uctx, void *sp) uctx->uc_mcontext = mctx; #ifdef __DYNAMIC__ - uctx->uc_link = (ucontext_t*)__in_sigtramp; /* non-zero if in signal handler */ + uctx->uc_link = (ucontext_t*)(uintptr_t)__in_sigtramp; /* non-zero if in signal handler */ #else /* !__DYNAMIC__ */ uctx->uc_link = 0; #endif /* __DYNAMIC__ */ diff --git a/x86_64/gen/icacheinval.s b/x86_64/gen/icacheinval.s index ee6a225..f7a3648 100644 --- a/x86_64/gen/icacheinval.s +++ b/x86_64/gen/icacheinval.s @@ -31,15 +31,26 @@ /* void sys_icache_invalidate(addr_t start, int length) */ -.globl _sys_icache_invalidate + .globl _sys_icache_invalidate _sys_icache_invalidate: - movq $(_COMM_PAGE_FLUSH_ICACHE), %rax - jmp *%rax + // This is a NOP on intel processors, since the intent of the API + // is to make data executable, and Intel L1Is are coherent with L1D. + ret /* void sys_dcache_flush(addr_t start, int length) */ -.globl _sys_dcache_flush + .globl _sys_dcache_flush _sys_dcache_flush: - movq $(_COMM_PAGE_FLUSH_DCACHE), %rax - jmp *%rax + testq %rsi,%rsi // length 0? + jz 2f // yes + mfence // ensure previous stores make it to memory + clflush -1(%rdi,%rsi) // make sure last line is flushed +1: + clflush (%rdi) // flush a line + addq $64,%rdi + subq $64,%rsi + ja 1b + mfence // make sure memory is updated before we return +2: + ret diff --git a/x86_64/gen/setcontext.c b/x86_64/gen/setcontext.c index efb3c0c..c89b4f4 100644 --- a/x86_64/gen/setcontext.c +++ b/x86_64/gen/setcontext.c @@ -25,7 +25,8 @@ #define _XOPEN_SOURCE 600L #include -#undef _ANSI_SOURCE +#undef _XOPEN_SOURCE +#undef _POSIX_C_SOURCE /* sigsetmask() */ #include extern int _setcontext(const mcontext_t); diff --git a/x86_64/pthreads/Makefile.inc b/x86_64/pthreads/Makefile.inc index 43c1309..49f1faa 100644 --- a/x86_64/pthreads/Makefile.inc +++ b/x86_64/pthreads/Makefile.inc @@ -9,5 +9,11 @@ MDSRCS += \ pthread_self.s \ pthread_getspecific.s \ start_wqthread.s \ - thread_start.s + thread_start.s \ + preempt.s +DYLDSRCS += \ + pthread_set_self.s \ + pthread_self.s \ + pthread_getspecific.s \ + preempt.s diff --git a/x86_64/pthreads/preempt.s b/x86_64/pthreads/preempt.s new file mode 100644 index 0000000..8fe6b09 --- /dev/null +++ b/x86_64/pthreads/preempt.s @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* Subroutine to make a preempt syscall. Called when we notice %ebx is + * nonzero after returning from a PFZ subroutine. Not in PFZ. + * + * All registers preserved (but does clear the %ebx preemption flag). + */ + .align 2 + .private_extern _preempt +_preempt: + pushq %rax + pushq %rcx + pushq %r11 + movl $(SYSCALL_CONSTRUCT_MACH(58)),%eax /* 58 = pfz_exit */ + xorl %ebx,%ebx + syscall + popq %r11 + popq %rcx + popq %rax + ret + +/* Subroutine to back off if we cannot get the spinlock. Called + * after a few attempts inline in the PFZ subroutines. This code is + * not in the PFZ. + * %rdi = ptr to queue head structure + * %ebx = preemption flag (nonzero if preemption pending) + * Uses: %rax. + */ + .align 2 + .private_extern _backoff +_backoff: + testl %ebx,%ebx // does kernel want to preempt us? + jz 1f // no + call _preempt +1: + pause // SMT-friendly backoff + cmpl $0,16(%rdi) // sniff the lockword + jnz 1b // loop if still taken + ret // lockword is free, so reenter PFZ diff --git a/x86_64/pthreads/pthread_getspecific.s b/x86_64/pthreads/pthread_getspecific.s index 67c00f3..93d849c 100644 --- a/x86_64/pthreads/pthread_getspecific.s +++ b/x86_64/pthreads/pthread_getspecific.s @@ -27,5 +27,5 @@ .align 2, 0x90 .globl _pthread_getspecific _pthread_getspecific: - movq %gs:_PTHREAD_TSD_OFFSET(,%rdi,8),%rax + movq %gs:(,%rdi,8),%rax ret diff --git a/x86_64/pthreads/pthread_mutex_lock.s b/x86_64/pthreads/pthread_mutex_lock.s index 9945a85..b1ca841 100644 --- a/x86_64/pthreads/pthread_mutex_lock.s +++ b/x86_64/pthreads/pthread_mutex_lock.s @@ -23,11 +23,31 @@ #include +#define PTHRW_LVAL 0 +#define PTHRW_UVAL 4 .text .align 2 .globl __commpage_pthread_mutex_lock __commpage_pthread_mutex_lock: - movq $(_COMM_PAGE_MUTEX_LOCK), %rax - jmp *%rax - + pushq %rbp // set up frame for backtrace + movq %rsp,%rbp + pushq %rbx + xorl %ebx,%ebx // clear "preemption pending" flag + movl $(_COMM_PAGE_SPIN_COUNT), %eax +1: + testl PTHRW_LVAL(%rdi),%ecx // is mutex available? + jz 2f // yes, it is available + pause + decl %eax // decrement max spin count + jnz 1b // keep spinning +2: + movq $(_COMM_PAGE_PFZ_MUTEX_LOCK), %rcx + call *%rcx + testl %ebx,%ebx // pending preemption? + jz 1f // no + call _preempt +1: + popq %rbx + popq %rbp + ret diff --git a/x86_64/pthreads/pthread_self.s b/x86_64/pthreads/pthread_self.s index c040841..147beda 100644 --- a/x86_64/pthreads/pthread_self.s +++ b/x86_64/pthreads/pthread_self.s @@ -27,5 +27,5 @@ .align 2, 0x90 .globl _pthread_self _pthread_self: - movq %gs:_PTHREAD_TSD_OFFSET,%rax + movq %gs:0,%rax ret diff --git a/x86_64/string/Makefile.inc b/x86_64/string/Makefile.inc index db0d4c9..a3c985a 100644 --- a/x86_64/string/Makefile.inc +++ b/x86_64/string/Makefile.inc @@ -6,10 +6,17 @@ # .PATH: ${.CURDIR}/x86_64/string -MDSRCS += bcopy.s \ - bzero.s \ - memcpy.s \ - memmove.s \ +MDSRCS += \ + bcopy.c \ + bcopy_sse3x.s \ + bcopy_sse42.s \ + bzero.c \ + bzero_sse2.s \ + bzero_sse42.s \ + __bzero.s \ + longcopy_sse3x.s \ + memcpy.c \ + memmove.c \ strlcat.s \ strlcpy.s \ strlen.s \ @@ -22,3 +29,12 @@ MDSRCS += bcopy.s \ ffs.s SUPPRESSSRCS += bcmp.c + +DYLDSRCS += \ + __bzero.s \ + bcopy_sse3x.s \ + bzero_sse2.s \ + ffs.s \ + longcopy_sse3x.s \ + strcmp.s \ + strlen.s diff --git a/x86_64/string/__bzero.s b/x86_64/string/__bzero.s new file mode 100644 index 0000000..c16f31a --- /dev/null +++ b/x86_64/string/__bzero.s @@ -0,0 +1,3 @@ + .globl ___bzero +___bzero: + jmp _bzero diff --git a/i386/string/bcopy.s b/x86_64/string/bcopy.c similarity index 64% rename from i386/string/bcopy.s rename to x86_64/string/bcopy.c index 34672bf..96fe199 100644 --- a/i386/string/bcopy.s +++ b/x86_64/string/bcopy.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,27 +21,20 @@ * @APPLE_LICENSE_HEADER_END@ */ -/* - * Call the comm page routines - */ - #include +#include -#include +PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse42) +PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse3x) - TEXT - ALIGN +static const platfunc_descriptor *bcopy_platfunc_descriptors[] = { + PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse42), + PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse3x), + 0 +}; -#if defined(MEMCOPY) -LEAF(_memcpy,0) - movl $(_COMM_PAGE_MEMCPY), %eax - jmpl *%eax -#elif defined(MEMMOVE) -LEAF(_memmove,0) - movl $(_COMM_PAGE_MEMMOVE), %eax - jmpl *%eax -#else -LEAF(_bcopy,0) - movl $(_COMM_PAGE_BCOPY), %eax - jmpl *%eax -#endif +void *bcopy_chooser() __asm__("_bcopy"); +void *bcopy_chooser() { + __asm__(".desc _bcopy, 0x100"); + return find_platform_function((const platfunc_descriptor **) bcopy_platfunc_descriptors); +} diff --git a/x86_64/string/bcopy_sse3x.s b/x86_64/string/bcopy_sse3x.s new file mode 100644 index 0000000..8556a10 --- /dev/null +++ b/x86_64/string/bcopy_sse3x.s @@ -0,0 +1,806 @@ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* + * The bcopy/memcpy loops, tuned for 64-bit Pentium-M class processors with + * Supplemental SSE3 and 64-byte cache lines. This is the 64-bit version. + * + * The following #defines are tightly coupled to the u-architecture: + */ + +#define kShort 80 // too short to bother with SSE (must be >=80) +#define kVeryLong (500*1024) // large enough for non-temporal stores (>=8192 and <2GB) +#define kFastUCode ((16*1024)-15) // cutoff for microcode fastpath for "rep/movsl" + +// void bcopy(const void *src, void *dst, size_t len); + +PLATFUNC_FUNCTION_START_GENERIC(bcopy, sse3x, 64, 5) +LZero: + pushq %rbp // set up a frame for backtraces + movq %rsp,%rbp + movq %rsi,%rax // copy dest ptr + movq %rdi,%rsi // xchange source and dest ptrs + movq %rax,%rdi + subq %rsi,%rax // (dest - source) + cmpq %rdx,%rax // must move in reverse if (dest - source) < length + jb LReverseIsland + cmpq $(kShort),%rdx // long enough to bother with SSE? + jbe LShort // no + jmp LNotShort + +// +// void *memcpy(void *dst, const void *src, size_t len); +// void *memmove(void *dst, const void *src, size_t len); +// + +PLATFUNC_FUNCTION_START_GENERIC(memcpy, sse3x, 64, 0) // void *memcpy(void *dst, const void *src, size_t len) +PLATFUNC_FUNCTION_START_GENERIC(memmove, sse3x, 64, 0) // void *memmove(void *dst, const void *src, size_t len) + pushq %rbp // set up a frame for backtraces + movq %rsp,%rbp + movq %rdi,%r11 // save return value here + movq %rdi,%rax + subq %rsi,%rax // (dest - source) + cmpq %rdx,%rax // must move in reverse if (dest - source) < length + jb LReverseIsland + cmpq $(kShort),%rdx // long enough to bother with SSE? + ja LNotShort // yes + +// Handle short forward copies. As the most common case, this is the fall-through path. +// rdx = length (<= kShort) +// rsi = source ptr +// rdi = dest ptr + +LShort: + movl %edx,%ecx // copy length using 32-bit operation + shrl $2,%ecx // get #doublewords + jz LLeftovers +2: // loop copying doublewords + movl (%rsi),%eax + addq $4,%rsi + movl %eax,(%rdi) + addq $4,%rdi + decl %ecx + jnz 2b +LLeftovers: // handle leftover bytes (0..3) in last word + andl $3,%edx // any leftover bytes? + jz 5f +4: // loop copying bytes + movb (%rsi),%al + incq %rsi + movb %al,(%rdi) + incq %rdi + decl %edx + jnz 4b +5: + movq %r11,%rax // get return value (dst ptr) for memcpy/memmove + popq %rbp + ret + + +LReverseIsland: // keep the "jb" above a short branch... + jmp LReverse // ...because reverse moves are uncommon + + +// Handle forward moves that are long enough to justify use of SSE. +// First, 16-byte align the destination. +// rdx = length (> kShort) +// rsi = source ptr +// rdi = dest ptr + +LNotShort: + cmpq $(kVeryLong),%rdx // long enough to justify heavyweight loops? + jae LVeryLong // use very-long-operand path + movl %edi,%ecx // copy low half of destination ptr + negl %ecx + andl $15,%ecx // get #bytes to align destination + jz LDestAligned // already aligned + subl %ecx,%edx // decrement length + rep // align destination + movsb + + +// Destination is now aligned. Dispatch to one of sixteen loops over 64-byte chunks, +// based on the alignment of the source. All vector loads and stores are aligned. +// Even though this means we have to shift and repack vectors, doing so is much faster +// than unaligned loads. Since kShort>=80 and we've moved at most 15 bytes already, +// there is at least one chunk. When we enter the copy loops, the following registers +// are set up: +// rdx = residual length (0..63) +// rcx = -(length to move), a multiple of 64 less than 2GB +// rsi = ptr to 1st source byte not to move (unaligned) +// rdi = ptr to 1st dest byte not to move (aligned) + +LDestAligned: + movq %rdx,%rcx // copy length + movl %esi,%eax // copy low half of source address + andl $63,%edx // get remaining bytes for LShort + andl $15,%eax // mask to low 4 bits of source address + andq $-64,%rcx // get number of bytes we will copy in inner loop + leaq LTable(%rip), %r8 + addq %rcx,%rsi // point to 1st byte not copied + addq %rcx,%rdi + movl (%r8,%rax,4),%eax // get offset of routine + negq %rcx // now generate offset to 1st byte to be copied + addq %r8,%rax // generate address of copy loop + jmp *%rax // enter copy loop, selected by source alignment + + .align 2 +LTable: // table of copy loop addresses +// force generation of assembly-time constants. Otherwise assembler +// creates subtractor relocations relative to first external symbol, +// and this file has none + .set LMod0Offset, LMod0 - LTable + .set LMod1Offset, LMod1 - LTable + .set LMod2Offset, LMod2 - LTable + .set LMod3Offset, LMod3 - LTable + .set LMod4Offset, LMod4 - LTable + .set LMod5Offset, LMod5 - LTable + .set LMod6Offset, LMod6 - LTable + .set LMod7Offset, LMod7 - LTable + .set LMod8Offset, LMod8 - LTable + .set LMod9Offset, LMod9 - LTable + .set LMod10Offset, LMod10 - LTable + .set LMod11Offset, LMod11 - LTable + .set LMod12Offset, LMod12 - LTable + .set LMod13Offset, LMod13 - LTable + .set LMod14Offset, LMod14 - LTable + .set LMod15Offset, LMod15 - LTable + .long LMod0Offset + .long LMod1Offset + .long LMod2Offset + .long LMod3Offset + .long LMod4Offset + .long LMod5Offset + .long LMod6Offset + .long LMod7Offset + .long LMod8Offset + .long LMod9Offset + .long LMod10Offset + .long LMod11Offset + .long LMod12Offset + .long LMod13Offset + .long LMod14Offset + .long LMod15Offset + + +// Very long forward moves. These are at least several pages. They are special cased +// and aggressively optimized, not so much because they are common or useful, but +// because they are subject to benchmark. There isn't enough room for them in the +// area reserved on the platfunc for bcopy, so we put them elsewhere. We call +// the longcopy routine using the normal ABI: +// rdi = dest +// rsi = source +// rdx = length (>= kVeryLong bytes) + +LVeryLong: + pushq %r11 // save return value + call _longcopy // call very long operand routine + popq %rax // pop return value + popq %rbp + ret + + +// On Pentium-M, the microcode for "rep/movsl" is faster than SSE for 16-byte +// aligned operands from about 32KB up to kVeryLong for the hot cache case, and from +// about 256 bytes up to kVeryLong for cold caches. This is because the microcode +// avoids having to read destination cache lines that will be completely overwritten. +// The cutoff we use (ie, kFastUCode) must somehow balance the two cases, since +// we do not know if the destination is in cache or not. + +Lfastpath: + addq %rcx,%rsi // restore ptrs to 1st byte of source and dest + addq %rcx,%rdi + negl %ecx // make length positive (known to be < 2GB) + orl %edx,%ecx // restore total #bytes remaining to move + cld // we'll move forward + shrl $2,%ecx // compute #words to move + rep // the u-code will optimize this + movsl + jmp LLeftovers // handle 0..3 leftover bytes + + +// Forward loop for medium length operands in which low four bits of %rsi == 0000 + +LMod0: + cmpl $(-kFastUCode),%ecx // %rcx == -length, where (length < kVeryLong) + jle Lfastpath // long enough for fastpath in microcode + jmp 1f + .align 4,0x90 // 16-byte align inner loops +1: // loop over 64-byte chunks + movdqa (%rsi,%rcx),%xmm0 + movdqa 16(%rsi,%rcx),%xmm1 + movdqa 32(%rsi,%rcx),%xmm2 + movdqa 48(%rsi,%rcx),%xmm3 + + movdqa %xmm0,(%rdi,%rcx) + movdqa %xmm1,16(%rdi,%rcx) + movdqa %xmm2,32(%rdi,%rcx) + movdqa %xmm3,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 0001 + +LMod1: + movdqa -1(%rsi,%rcx),%xmm0 // prime the loop by loading 1st quadword +1: // loop over 64-byte chunks + movdqa 15(%rsi,%rcx),%xmm1 + movdqa 31(%rsi,%rcx),%xmm2 + movdqa 47(%rsi,%rcx),%xmm3 + movdqa 63(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $1,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $1,%xmm2,%xmm3 + palignr $1,%xmm1,%xmm2 + palignr $1,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 0010 + +LMod2: + movdqa -2(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 14(%rsi,%rcx),%xmm1 + movdqa 30(%rsi,%rcx),%xmm2 + movdqa 46(%rsi,%rcx),%xmm3 + movdqa 62(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $2,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $2,%xmm2,%xmm3 + palignr $2,%xmm1,%xmm2 + palignr $2,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 0011 + +LMod3: + movdqa -3(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 13(%rsi,%rcx),%xmm1 + movdqa 29(%rsi,%rcx),%xmm2 + movdqa 45(%rsi,%rcx),%xmm3 + movdqa 61(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $3,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $3,%xmm2,%xmm3 + palignr $3,%xmm1,%xmm2 + palignr $3,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 0100 +// We use the float single data type in order to use "movss" to merge vectors. + +LMod4: + movaps -4(%rsi,%rcx),%xmm0 // 4-byte aligned: prime the loop + jmp 1f + .align 4,0x90 +1: // loop over 64-byte chunks + movaps 12(%rsi,%rcx),%xmm1 + movaps 28(%rsi,%rcx),%xmm2 + movss %xmm1,%xmm0 // copy low 4 bytes of source into destination + pshufd $(0x39),%xmm0,%xmm0 // rotate right 4 bytes (mask -- 00 11 10 01) + movaps 44(%rsi,%rcx),%xmm3 + movss %xmm2,%xmm1 + pshufd $(0x39),%xmm1,%xmm1 + movaps 60(%rsi,%rcx),%xmm4 + movss %xmm3,%xmm2 + pshufd $(0x39),%xmm2,%xmm2 + + movaps %xmm0,(%rdi,%rcx) + movss %xmm4,%xmm3 + pshufd $(0x39),%xmm3,%xmm3 + movaps %xmm1,16(%rdi,%rcx) + movaps %xmm2,32(%rdi,%rcx) + movaps %xmm4,%xmm0 + movaps %xmm3,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 0101 + +LMod5: + movdqa -5(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 11(%rsi,%rcx),%xmm1 + movdqa 27(%rsi,%rcx),%xmm2 + movdqa 43(%rsi,%rcx),%xmm3 + movdqa 59(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $5,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $5,%xmm2,%xmm3 + palignr $5,%xmm1,%xmm2 + palignr $5,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 0110 + +LMod6: + movdqa -6(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 10(%rsi,%rcx),%xmm1 + movdqa 26(%rsi,%rcx),%xmm2 + movdqa 42(%rsi,%rcx),%xmm3 + movdqa 58(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $6,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $6,%xmm2,%xmm3 + palignr $6,%xmm1,%xmm2 + palignr $6,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 0111 + +LMod7: + movdqa -7(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 9(%rsi,%rcx),%xmm1 + movdqa 25(%rsi,%rcx),%xmm2 + movdqa 41(%rsi,%rcx),%xmm3 + movdqa 57(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $7,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $7,%xmm2,%xmm3 + palignr $7,%xmm1,%xmm2 + palignr $7,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 1000 +// We use the float double data type in order to use "shufpd" to shift by 8 bytes. + +LMod8: + cmpl $(-kFastUCode),%ecx // %rcx == -length, where (length < kVeryLong) + jle Lfastpath // long enough for fastpath in microcode + movapd -8(%rsi,%rcx),%xmm0 // 8-byte aligned: prime the loop + jmp 1f + .align 4,0x90 +1: // loop over 64-byte chunks + movapd 8(%rsi,%rcx),%xmm1 + movapd 24(%rsi,%rcx),%xmm2 + shufpd $01,%xmm1,%xmm0 // %xmm0 <- shr( %xmm0 || %xmm1, 8 bytes) + movapd 40(%rsi,%rcx),%xmm3 + shufpd $01,%xmm2,%xmm1 + movapd 56(%rsi,%rcx),%xmm4 + shufpd $01,%xmm3,%xmm2 + + movapd %xmm0,(%rdi,%rcx) + shufpd $01,%xmm4,%xmm3 + movapd %xmm1,16(%rdi,%rcx) + movapd %xmm2,32(%rdi,%rcx) + movapd %xmm4,%xmm0 + movapd %xmm3,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 1001 + +LMod9: + movdqa -9(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 7(%rsi,%rcx),%xmm1 + movdqa 23(%rsi,%rcx),%xmm2 + movdqa 39(%rsi,%rcx),%xmm3 + movdqa 55(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $9,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $9,%xmm2,%xmm3 + palignr $9,%xmm1,%xmm2 + palignr $9,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 1010 + +LMod10: + movdqa -10(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 6(%rsi,%rcx),%xmm1 + movdqa 22(%rsi,%rcx),%xmm2 + movdqa 38(%rsi,%rcx),%xmm3 + movdqa 54(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $10,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $10,%xmm2,%xmm3 + palignr $10,%xmm1,%xmm2 + palignr $10,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 1011 + +LMod11: + movdqa -11(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 5(%rsi,%rcx),%xmm1 + movdqa 21(%rsi,%rcx),%xmm2 + movdqa 37(%rsi,%rcx),%xmm3 + movdqa 53(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $11,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $11,%xmm2,%xmm3 + palignr $11,%xmm1,%xmm2 + palignr $11,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 1100 +// We use the float single data type in order to use "movss" to merge vectors. + +LMod12: + movss (%rsi,%rcx),%xmm0 // prefetch 1st four bytes of source, right justified + jmp 1f + .align 4,0x90 +1: // loop over 64-byte chunks + pshufd $(0x93),4(%rsi,%rcx),%xmm1 // load and rotate right 12 bytes (mask -- 10 01 00 11) + pshufd $(0x93),20(%rsi,%rcx),%xmm2 + pshufd $(0x93),36(%rsi,%rcx),%xmm3 + pshufd $(0x93),52(%rsi,%rcx),%xmm4 + + movaps %xmm4,%xmm5 + movss %xmm3,%xmm4 // copy low 4 bytes of source into destination + movss %xmm2,%xmm3 + movss %xmm1,%xmm2 + movss %xmm0,%xmm1 + + movaps %xmm1,(%rdi,%rcx) + movaps %xmm2,16(%rdi,%rcx) + movaps %xmm5,%xmm0 + movaps %xmm3,32(%rdi,%rcx) + movaps %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 1101 + +LMod13: + movdqa -13(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 3(%rsi,%rcx),%xmm1 + movdqa 19(%rsi,%rcx),%xmm2 + movdqa 35(%rsi,%rcx),%xmm3 + movdqa 51(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $13,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $13,%xmm2,%xmm3 + palignr $13,%xmm1,%xmm2 + palignr $13,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 1110 + +LMod14: + movdqa -14(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 2(%rsi,%rcx),%xmm1 + movdqa 18(%rsi,%rcx),%xmm2 + movdqa 34(%rsi,%rcx),%xmm3 + movdqa 50(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $14,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $14,%xmm2,%xmm3 + palignr $14,%xmm1,%xmm2 + palignr $14,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for medium length operands in which low four bits of %rsi == 1111 + +LMod15: + movdqa -15(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq +1: // loop over 64-byte chunks + movdqa 1(%rsi,%rcx),%xmm1 + movdqa 17(%rsi,%rcx),%xmm2 + movdqa 33(%rsi,%rcx),%xmm3 + movdqa 49(%rsi,%rcx),%xmm4 + + movdqa %xmm0,%xmm5 + movdqa %xmm4,%xmm0 + + palignr $15,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) + palignr $15,%xmm2,%xmm3 + palignr $15,%xmm1,%xmm2 + palignr $15,%xmm5,%xmm1 + + movdqa %xmm1,(%rdi,%rcx) + movdqa %xmm2,16(%rdi,%rcx) + movdqa %xmm3,32(%rdi,%rcx) + movdqa %xmm4,48(%rdi,%rcx) + + addq $64,%rcx + jnz 1b + + jmp LShort // copy remaining 0..63 bytes and done + + +// Reverse moves. These are not optimized as aggressively as their forward +// counterparts, as they are only used with destructive overlap. +// rdx = length +// rsi = source ptr +// rdi = dest ptr + +LReverse: + addq %rdx,%rsi // point to end of strings + addq %rdx,%rdi + cmpq $(kShort),%rdx // long enough to bother with SSE? + ja LReverseNotShort // yes + +// Handle reverse short copies. +// edx = length (<= kShort) +// rsi = one byte past end of source +// rdi = one byte past end of dest + +LReverseShort: + movl %edx,%ecx // copy length + shrl $3,%ecx // #quadwords + jz 3f +1: + subq $8,%rsi + movq (%rsi),%rax + subq $8,%rdi + movq %rax,(%rdi) + decl %ecx + jnz 1b +3: + andl $7,%edx // bytes? + jz 5f +4: + decq %rsi + movb (%rsi),%al + decq %rdi + movb %al,(%rdi) + decl %edx + jnz 4b +5: + movq %r11,%rax // get return value (dst ptr) for memcpy/memmove + popq %rbp + ret + +// Handle a reverse move long enough to justify using SSE. +// rdx = length (> kShort) +// rsi = one byte past end of source +// rdi = one byte past end of dest + +LReverseNotShort: + movl %edi,%ecx // copy destination + andl $15,%ecx // get #bytes to align destination + je LReverseDestAligned // already aligned + subq %rcx,%rdx // adjust length +1: // loop copying 1..15 bytes + decq %rsi + movb (%rsi),%al + decq %rdi + movb %al,(%rdi) + decl %ecx + jnz 1b + +// Destination is now aligned. Prepare for reverse loops. + +LReverseDestAligned: + movq %rdx,%rcx // copy length + andl $63,%edx // get remaining bytes for LReverseShort + andq $-64,%rcx // get number of bytes we will copy in inner loop + subq %rcx,%rsi // point to endpoint of copy + subq %rcx,%rdi + testl $15,%esi // is source aligned too? + jnz LReverseUnalignedLoop // no + +LReverseAlignedLoop: // loop over 64-byte chunks + movdqa -16(%rsi,%rcx),%xmm0 + movdqa -32(%rsi,%rcx),%xmm1 + movdqa -48(%rsi,%rcx),%xmm2 + movdqa -64(%rsi,%rcx),%xmm3 + + movdqa %xmm0,-16(%rdi,%rcx) + movdqa %xmm1,-32(%rdi,%rcx) + movdqa %xmm2,-48(%rdi,%rcx) + movdqa %xmm3,-64(%rdi,%rcx) + + subq $64,%rcx + jne LReverseAlignedLoop + + jmp LReverseShort // copy remaining 0..63 bytes and done + + +// Reverse, unaligned loop. LDDQU==MOVDQU on these machines. + +LReverseUnalignedLoop: // loop over 64-byte chunks + movdqu -16(%rsi,%rcx),%xmm0 + movdqu -32(%rsi,%rcx),%xmm1 + movdqu -48(%rsi,%rcx),%xmm2 + movdqu -64(%rsi,%rcx),%xmm3 + + movdqa %xmm0,-16(%rdi,%rcx) + movdqa %xmm1,-32(%rdi,%rcx) + movdqa %xmm2,-48(%rdi,%rcx) + movdqa %xmm3,-64(%rdi,%rcx) + + subq $64,%rcx + jne LReverseUnalignedLoop + + jmp LReverseShort // copy remaining 0..63 bytes and done + +PLATFUNC_DESCRIPTOR(bcopy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) +PLATFUNC_DESCRIPTOR(memcpy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) +PLATFUNC_DESCRIPTOR(memmove,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) diff --git a/x86_64/string/bcopy_sse42.s b/x86_64/string/bcopy_sse42.s new file mode 100644 index 0000000..cfb1a28 --- /dev/null +++ b/x86_64/string/bcopy_sse42.s @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* + * The bcopy/memcpy loops, tuned for Nehalem. This is the 64-bit version. + * + * The following #defines are tightly coupled to the u-architecture: + */ + +#define kShort 80 // too short to bother with SSE (must be >=80) + + +// void bcopy(const void *src, void *dst, size_t len); + +PLATFUNC_FUNCTION_START(bcopy, sse42, 64, 5) + pushq %rbp // set up a frame for backtraces + movq %rsp,%rbp + movq %rsi,%rax // copy dest ptr + movq %rdi,%rsi // xchange source and dest ptrs + movq %rax,%rdi + subq %rsi,%rax // (dest - source) + cmpq %rdx,%rax // must move in reverse if (dest - source) < length + jb LReverseIsland + cmpq $(kShort),%rdx // long enough to bother with SSE? + jbe LShort // no + jmp LNotShort + +// +// void *memcpy(void *dst, const void *src, size_t len); +// void *memmove(void *dst, const void *src, size_t len); +// + +PLATFUNC_FUNCTION_START(memcpy, sse42, 64, 0) // void *memcpy(void *dst, const void *src, size_t len) +PLATFUNC_FUNCTION_START(memmove, sse42, 64, 0) // void *memmove(void *dst, const void *src, size_t len) + pushq %rbp // set up a frame for backtraces + movq %rsp,%rbp + movq %rdi,%r11 // save return value here + movq %rdi,%rax + subq %rsi,%rax // (dest - source) + cmpq %rdx,%rax // must move in reverse if (dest - source) < length + jb LReverseIsland + cmpq $(kShort),%rdx // long enough to bother with SSE? + ja LNotShort // yes + +// Handle short forward copies. As the most common case, this is the fall-through path. +// rdx = length (<= kShort) +// rsi = source ptr +// rdi = dest ptr + +LShort: + movl %edx,%ecx // copy length using 32-bit operation + shrl $2,%ecx // get #doublewords + jz 3f +2: // loop copying doublewords + movl (%rsi),%eax + addq $4,%rsi + movl %eax,(%rdi) + addq $4,%rdi + decl %ecx + jnz 2b +3: // handle leftover bytes (0..3) in last word + andl $3,%edx // any leftover bytes? + jz 5f +4: // loop copying bytes + movb (%rsi),%al + incq %rsi + movb %al,(%rdi) + incq %rdi + decl %edx + jnz 4b +5: + movq %r11,%rax // get return value (dst ptr) for memcpy/memmove + popq %rbp + ret + + +LReverseIsland: // keep the "jb" above a short branch... + jmp LReverse // ...because reverse moves are uncommon + + +// Handle forward moves that are long enough to justify use of SSE. +// First, 16-byte align the destination. +// rdx = length (> kShort) +// rsi = source ptr +// rdi = dest ptr + +LNotShort: + movl %edi,%ecx // copy low half of destination ptr + negl %ecx + andl $15,%ecx // get #bytes to align destination + jz LDestAligned // already aligned + subl %ecx,%edx // decrement length +1: // loop copying 1..15 bytes + movb (%rsi),%al + inc %rsi + movb %al,(%rdi) + inc %rdi + dec %ecx + jnz 1b + + +// Destination is now aligned. Nehalem does a great job with unaligned SSE loads, +// so we use MOVDQU rather than aligned loads and shifts. Since kShort>=80, we +// know there is at least one 64-byte chunk to move. +// When we enter the copy loops, the following registers are set up: +// rdx = residual length (0..63) +// rcx = -(length to move), a multiple of 64 less than 2GB +// rsi = ptr to 1st source byte not to move (unaligned) +// rdi = ptr to 1st dest byte not to move (aligned) + +LDestAligned: + movq %rdx,%rcx // copy length + andl $63,%edx // get remaining bytes for LShort + andq $-64,%rcx // get number of bytes we will copy in inner loop + addq %rcx,%rsi // point to 1st byte not copied + addq %rcx,%rdi + negq %rcx // now generate offset to 1st byte to be copied + testl $15,%esi // source also aligned? + jnz LUnalignedLoop + jmp LAlignedLoop + + +// Forward loop for aligned operands. + + .align 4,0x90 // 16-byte align inner loops +LAlignedLoop: // loop over 64-byte chunks + movdqa (%rsi,%rcx),%xmm0 + movdqa 16(%rsi,%rcx),%xmm1 + movdqa 32(%rsi,%rcx),%xmm2 + movdqa 48(%rsi,%rcx),%xmm3 + + movdqa %xmm0,(%rdi,%rcx) + movdqa %xmm1,16(%rdi,%rcx) + movdqa %xmm2,32(%rdi,%rcx) + movdqa %xmm3,48(%rdi,%rcx) + + addq $64,%rcx + jnz LAlignedLoop + + jmp LShort // copy remaining 0..63 bytes and done + + +// Forward loop for unaligned operands. + + .align 4,0x90 // 16-byte align inner loops +LUnalignedLoop: // loop over 64-byte chunks + movdqu (%rsi,%rcx),%xmm0 + movdqu 16(%rsi,%rcx),%xmm1 + movdqu 32(%rsi,%rcx),%xmm2 + movdqu 48(%rsi,%rcx),%xmm3 + + movdqa %xmm0,(%rdi,%rcx) + movdqa %xmm1,16(%rdi,%rcx) + movdqa %xmm2,32(%rdi,%rcx) + movdqa %xmm3,48(%rdi,%rcx) + + addq $64,%rcx + jnz LUnalignedLoop + + jmp LShort // copy remaining 0..63 bytes and done + + +// Reverse moves. These are only used with destructive overlap. +// rdx = length +// rsi = source ptr +// rdi = dest ptr + +LReverse: + addq %rdx,%rsi // point to end of strings + addq %rdx,%rdi + cmpq $(kShort),%rdx // long enough to bother with SSE? + ja LReverseNotShort // yes + +// Handle reverse short copies. +// edx = length (<= kShort) +// rsi = one byte past end of source +// rdi = one byte past end of dest + +LReverseShort: + movl %edx,%ecx // copy length + shrl $3,%ecx // #quadwords + jz 3f +1: + subq $8,%rsi + movq (%rsi),%rax + subq $8,%rdi + movq %rax,(%rdi) + decl %ecx + jnz 1b +3: + andl $7,%edx // bytes? + jz 5f +4: + decq %rsi + movb (%rsi),%al + decq %rdi + movb %al,(%rdi) + decl %edx + jnz 4b +5: + movq %r11,%rax // get return value (dst ptr) for memcpy/memmove + popq %rbp + ret + +// Handle a reverse move long enough to justify using SSE. +// rdx = length (> kShort) +// rsi = one byte past end of source +// rdi = one byte past end of dest + +LReverseNotShort: + movl %edi,%ecx // copy destination + andl $15,%ecx // get #bytes to align destination + jz LReverseDestAligned // already aligned + subq %rcx,%rdx // adjust length +1: // loop copying 1..15 bytes + decq %rsi + movb (%rsi),%al + decq %rdi + movb %al,(%rdi) + decl %ecx + jnz 1b + +// Destination is now aligned. Prepare for reverse loops. + +LReverseDestAligned: + movq %rdx,%rcx // copy length + andl $63,%edx // get remaining bytes for LReverseShort + andq $-64,%rcx // get number of bytes we will copy in inner loop + subq %rcx,%rsi // point to endpoint of copy + subq %rcx,%rdi + testl $15,%esi // is source aligned too? + jnz LReverseUnalignedLoop // no + +LReverseAlignedLoop: // loop over 64-byte chunks + movdqa -16(%rsi,%rcx),%xmm0 + movdqa -32(%rsi,%rcx),%xmm1 + movdqa -48(%rsi,%rcx),%xmm2 + movdqa -64(%rsi,%rcx),%xmm3 + + movdqa %xmm0,-16(%rdi,%rcx) + movdqa %xmm1,-32(%rdi,%rcx) + movdqa %xmm2,-48(%rdi,%rcx) + movdqa %xmm3,-64(%rdi,%rcx) + + subq $64,%rcx + jne LReverseAlignedLoop + + jmp LReverseShort // copy remaining 0..63 bytes and done + + +// Reverse, unaligned loop. LDDQU==MOVDQU on these machines. + +LReverseUnalignedLoop: // loop over 64-byte chunks + movdqu -16(%rsi,%rcx),%xmm0 + movdqu -32(%rsi,%rcx),%xmm1 + movdqu -48(%rsi,%rcx),%xmm2 + movdqu -64(%rsi,%rcx),%xmm3 + + movdqa %xmm0,-16(%rdi,%rcx) + movdqa %xmm1,-32(%rdi,%rcx) + movdqa %xmm2,-48(%rdi,%rcx) + movdqa %xmm3,-64(%rdi,%rcx) + + subq $64,%rcx + jne LReverseUnalignedLoop + + jmp LReverseShort // copy remaining 0..63 bytes and done + + +PLATFUNC_DESCRIPTOR(bcopy,sse42,kHasSSE4_2,0) +PLATFUNC_DESCRIPTOR(memcpy,sse42,kHasSSE4_2,0) +PLATFUNC_DESCRIPTOR(memmove,sse42,kHasSSE4_2,0) diff --git a/x86_64/string/bcopy.s b/x86_64/string/bzero.c similarity index 64% rename from x86_64/string/bcopy.s rename to x86_64/string/bzero.c index d06652d..99e7cae 100644 --- a/x86_64/string/bcopy.s +++ b/x86_64/string/bzero.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,28 +21,20 @@ * @APPLE_LICENSE_HEADER_END@ */ -/* - * Call the comm page routines - */ - -#define __APPLE_API_PRIVATE #include +#include -#include +PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse42) +PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse2) - TEXT - ALIGN +static const platfunc_descriptor *bzero_platfunc_descriptors[] = { + PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse42), + PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse2), + 0 +}; -#if defined(MEMCOPY) -LEAF(_memcpy,0) - movq $(_COMM_PAGE_MEMCPY), %rax - jmp *%rax -#elif defined(MEMMOVE) -LEAF(_memmove,0) - movq $(_COMM_PAGE_MEMMOVE), %rax - jmp *%rax -#else -LEAF(_bcopy,0) - movq $(_COMM_PAGE_BCOPY), %rax - jmp *%rax -#endif +void *bzero_chooser() __asm__("_bzero"); +void *bzero_chooser() { + __asm__(".desc _bzero, 0x100"); + return find_platform_function((const platfunc_descriptor **) bzero_platfunc_descriptors); +} diff --git a/x86_64/string/bzero_sse2.s b/x86_64/string/bzero_sse2.s new file mode 100644 index 0000000..6b6effd --- /dev/null +++ b/x86_64/string/bzero_sse2.s @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* + * Bzero, tuned for Pentium-M class processors with SSE2 + * and 64-byte cache lines. This is the 64-bit version. + * + * This routine is also used for memset(p,0,n), which is a common case + * since gcc sometimes silently maps bzero() into memset(). As a result, + * we always load the original ptr into %eax before returning. + */ + +#define kShort 80 // too short to bother with SSE (must be >=80) +#define kVeryLong (1024*1024) + +// void bzero(void *b, size_t len); + +PLATFUNC_FUNCTION_START_GENERIC(bzero, sse2, 64, 5) + pushq %rbp // set up a frame for backtraces + movq %rsp,%rbp + xorl %eax,%eax // set fill data to 0 + movq %rdi,%r11 // save original ptr as return value + cmpq $(kShort),%rsi // long enough for SSE? + jg LNotShort // yes + +// Here for short operands or the end of long ones. +// %esi = length (<= kShort) +// %rdi = ptr +// %eax = zero + +Lshort: + cmpl $16,%esi // long enough to word align? + jge 3f // yes + test %esi,%esi // length==0? + jz 6f +1: + movb %al,(%rdi) // zero a byte + incq %rdi + decl %esi + jnz 1b + jmp 6f +2: + movb %al,(%rdi) // zero a byte + incq %rdi + decl %esi +3: + testl $3,%edi // is ptr doubleword aligned? + jnz 2b // no + movl %esi,%ecx // copy length + shrl $2,%esi // #doublewords to store +4: + movl %eax,(%rdi) // zero an aligned doubleword + addq $4,%rdi + decl %esi + jnz 4b + andl $3,%ecx // mask down to #bytes at end (0..3) + jz 6f // none +5: + movb %al,(%rdi) // zero a byte + incq %rdi + decl %ecx + jnz 5b +6: + movq %r11,%rax // set return value in case this was a call of memset() + popq %rbp + ret + + +// We will be using SSE, so align ptr. +// %rsi = length (> kShort) +// %rdi = ptr +// %eax = zero + +LNotShort: + movl %edi,%ecx // get #bytes to 16-byte align ptr + negl %ecx + andl $15,%ecx + jz LDestAligned // already aligned + subq %rcx,%rsi // decrement length +0: // loop storing bytes to align the ptr + movb %al,(%rdi) // pack in a byte + incq %rdi + decl %ecx + jnz 0b + +// Destination is now 16-byte aligned. Prepare to loop over 64-byte chunks. +// %rsi = length (> (kShort-15)) +// %rdi = ptr (aligned) +// %eax = zero + +LDestAligned: + movq %rsi,%rcx + andl $63,%esi // mask down to residual length (0..63) + andq $-64,%rcx // get #bytes we will zero in this loop + pxor %xmm0,%xmm0 // zero an SSE register + addq %rcx,%rdi // increment ptr by length to move + cmpq $(kVeryLong),%rcx // long enough to justify non-temporal stores? + jae LVeryLong // yes + negq %rcx // negate length to move + jmp 1f + +// Loop over 64-byte chunks, storing into cache. + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movdqa %xmm0,(%rdi,%rcx) + movdqa %xmm0,16(%rdi,%rcx) + movdqa %xmm0,32(%rdi,%rcx) + movdqa %xmm0,48(%rdi,%rcx) + addq $64,%rcx + jne 1b + + jmp Lshort + +// Very long operands: use non-temporal stores to bypass cache. + +LVeryLong: + negq %rcx // negate length to move + jmp 1f + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movntdq %xmm0,(%rdi,%rcx) + movntdq %xmm0,16(%rdi,%rcx) + movntdq %xmm0,32(%rdi,%rcx) + movntdq %xmm0,48(%rdi,%rcx) + addq $64,%rcx + jne 1b + + sfence // required by non-temporal stores + jmp Lshort + +PLATFUNC_DESCRIPTOR(bzero,sse2,kHasSSE2,kHasSSE4_2) diff --git a/x86_64/string/bzero_sse42.s b/x86_64/string/bzero_sse42.s new file mode 100644 index 0000000..5b0358f --- /dev/null +++ b/x86_64/string/bzero_sse42.s @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* + * Bzero, tuned for processors with SSE4.2 and 64-byte cache lines, ie Nehalem. + * We don't actually use SSE4.2, but rather use it to identify Nehalem. + * This is the 64-bit version. + * + * We do not use nontemporal operations, but use MOVDQA in preference to REP/STOS. + * + * This routine is also used for memset(p,0,n), which is a common case + * since gcc sometimes silently maps bzero() into memset(). As a result, + * we always load the original ptr into %eax before returning. + */ + +#define kShort 80 // too short to bother with SSE (must be >=80) + + +// void bzero(void *b, size_t len); + +PLATFUNC_FUNCTION_START(bzero, sse42, 64, 5) + pushq %rbp // set up a frame for backtraces + movq %rsp,%rbp + xorl %eax,%eax // set fill data to 0 + movq %rdi,%r11 // save original ptr as return value + cmpq $(kShort),%rsi // long enough for SSE? + jg LNotShort // yes + +// Here for short operands or the end of long ones. +// %esi = length (<= kShort) +// %rdi = ptr +// %eax = zero + +Lshort: + cmpl $12,%esi // long enough to word align? + jge 3f // yes + test %esi,%esi // length==0? + jz 6f +1: + movb %al,(%rdi) // zero a byte + incq %rdi + decl %esi + jnz 1b + jmp 6f +2: + movb %al,(%rdi) // zero a byte + incq %rdi + decl %esi +3: + testl $3,%edi // is ptr doubleword aligned? + jnz 2b // no + movl %esi,%ecx // copy length + shrl $2,%esi // #doublewords to store +4: + movl %eax,(%rdi) // zero an aligned doubleword + addq $4,%rdi + decl %esi + jnz 4b + andl $3,%ecx // mask down to #bytes at end (0..3) + jz 6f // none +5: + movb %al,(%rdi) // zero a byte + incq %rdi + decl %ecx + jnz 5b +6: + movq %r11,%rax // set return value in case this was a call of memset() + popq %rbp + ret + + +// We will be using SSE, so align ptr. +// %rsi = length (> kShort) +// %rdi = ptr +// %eax = zero + +LNotShort: + testl $3,%edi // 4-byte aligned? + jz 2f // yes + movb %al,(%rdi) // zero another byte + incq %rdi + decq %rsi + jmp LNotShort +1: // zero doublewords until 16-byte aligned + movl %eax,(%rdi) + addq $4,%rdi + subq $4,%rsi +2: + testl $15,%edi // 16-byte aligned? + jnz 1b // no + +// Destination is now 16-byte aligned. Prepare to loop over 64-byte chunks. +// %rsi = length (> (kShort-15)) +// %rdi = ptr (aligned) +// %eax = zero + +LDestAligned: + movq %rsi,%rcx + andl $63,%esi // mask down to residual length (0..63) + andq $-64,%rcx // get #bytes we will zero in this loop + pxor %xmm0,%xmm0 // zero an SSE register + addq %rcx,%rdi // increment ptr by length to move + negq %rcx // negate length to move + jmp 1f + +// Loop over 64-byte chunks, storing into cache. + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movdqa %xmm0,(%rdi,%rcx) + movdqa %xmm0,16(%rdi,%rcx) + movdqa %xmm0,32(%rdi,%rcx) + movdqa %xmm0,48(%rdi,%rcx) + addq $64,%rcx + jne 1b + + jmp Lshort + + +PLATFUNC_DESCRIPTOR(bzero,sse42,kHasSSE4_2,0) diff --git a/x86_64/string/longcopy_sse3x.s b/x86_64/string/longcopy_sse3x.s new file mode 100644 index 0000000..86dad29 --- /dev/null +++ b/x86_64/string/longcopy_sse3x.s @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include + +/* + * The bcopy/memcpy loops for very long operands, tuned for 64-bit + * Pentium-M class processors with Supplemental SSE3 and 64-byte cache lines. + * This is the 64-bit version. + * + * The following #defines are tightly coupled to the u-architecture: + */ + +#define kBigChunk (256*1024) // outer loop chunk size for kVeryLong sized operands + + +// Very long forward moves. These are at least several pages, so we loop over big +// chunks of memory (kBigChunk in size.) We first prefetch the chunk, and then copy +// it using non-temporal stores. Hopefully all the reads occur in the prefetch loop, +// so the copy loop reads from L2 and writes directly to memory (with write combining.) +// This minimizes bus turnaround and maintains good DRAM page locality. +// Note that for this scheme to work, kVeryLong must be a large fraction of L2 cache +// size. Otherwise, it is counter-productive to bypass L2 on the stores. +// +// We are called from the platfunc bcopy loops when they encounter very long +// operands, with the standard ABI: +// rdi = dest ptr +// rsi = source ptr +// rdx = length (>= 8kb, probably much bigger) + +// void longcopy(const void *dest, void *sou, size_t len) + + .private_extern _longcopy +_longcopy: + pushq %rbp // set up a frame for backtraces + movq %rsp,%rbp + movl %edi,%eax // copy dest ptr + negl %eax + andl $63,%eax // get #bytes to cache line align destination + jz LBigChunkLoop // already aligned + + // Cache line align destination, so temporal stores in copy loops work right. + // The recursive call returns with the source and dest ptrs properly updated. + + subq %rax,%rdx // get length remaining after dest is aligned + pushq %rdx // save length remaining + movl %eax,%edx // #bytes to copy to align destination + call _memcpy + popq %rdx // recover adjusted length + +// Loop over big chunks. +// rdx = length remaining (>= 4096) +// rdi = dest (64-byte aligned) +// rsi = source (may be unaligned) + +LBigChunkLoop: + movl $(kBigChunk),%r8d // assume we can do a full chunk + cmpq %r8,%rdx // do we have a full chunk left to do? + cmovbl %edx,%r8d // if not, only move what we have left + andl $-4096,%r8d // we work in page multiples + xorl %eax,%eax // initialize chunk offset + jmp LTouchLoop + +// Touch in the next chunk. We try to keep the prefetch unit in "kick-start" mode, +// by touching two adjacent cache lines every 8 lines of each page, in four slices. +// Because the source may be unaligned, we use byte loads to touch. +// rdx = length remaining (including this chunk) +// rdi = ptr to start of dest chunk +// rsi = ptr to start of source chunk +// r8d = chunk length (multiples of pages, less than 2**32) +// ecx = scratch reg used to read a byte of each cache line +// eax = chunk offset + + .align 4,0x90 // 16-byte align inner loops +LTouchLoop: + movzb (%rsi,%rax),%ecx // touch line 0, 2, 4, or 6 of page + movzb 1*64(%rsi,%rax),%ecx // touch line 1, 3, 5, or 7 + movzb 8*64(%rsi,%rax),%ecx // touch line 8, 10, 12, or 14 + movzb 9*64(%rsi,%rax),%ecx // etc + + movzb 16*64(%rsi,%rax),%ecx + movzb 17*64(%rsi,%rax),%ecx + movzb 24*64(%rsi,%rax),%ecx + movzb 25*64(%rsi,%rax),%ecx + + movzb 32*64(%rsi,%rax),%ecx + movzb 33*64(%rsi,%rax),%ecx + movzb 40*64(%rsi,%rax),%ecx + movzb 41*64(%rsi,%rax),%ecx + + movzb 48*64(%rsi,%rax),%ecx + movzb 49*64(%rsi,%rax),%ecx + movzb 56*64(%rsi,%rax),%ecx + movzb 57*64(%rsi,%rax),%ecx + + subl $-128,%eax // next slice of page (adding 128 w 8-bit immediate) + testl $512,%eax // done with this page? + jz LTouchLoop // no, next of four slices + addl $(4096-512),%eax // move on to next page + cmpl %eax,%r8d // done with this chunk? + jnz LTouchLoop // no, do next page + + // The chunk has been pre-fetched, now copy it using non-temporal stores. + // There are two copy loops, depending on whether the source is 16-byte aligned + // or not. + + movl %r8d,%ecx // copy chunk size to a reg that doesn't use REX prefix + addq %rcx,%rsi // increment ptrs by chunk length + addq %rcx,%rdi + subq %rcx,%rdx // adjust remaining length + negq %rcx // prepare loop index (counts up to 0) + testl $15,%esi // is source 16-byte aligned? + jnz LVeryLongUnaligned // no + jmp LVeryLongAligned + + .align 4,0x90 // 16-byte align inner loops +LVeryLongAligned: // aligned loop over 128-bytes + movdqa (%rsi,%rcx),%xmm0 + movdqa 16(%rsi,%rcx),%xmm1 + movdqa 32(%rsi,%rcx),%xmm2 + movdqa 48(%rsi,%rcx),%xmm3 + movdqa 64(%rsi,%rcx),%xmm4 + movdqa 80(%rsi,%rcx),%xmm5 + movdqa 96(%rsi,%rcx),%xmm6 + movdqa 112(%rsi,%rcx),%xmm7 + + movntdq %xmm0,(%rdi,%rcx) + movntdq %xmm1,16(%rdi,%rcx) + movntdq %xmm2,32(%rdi,%rcx) + movntdq %xmm3,48(%rdi,%rcx) + movntdq %xmm4,64(%rdi,%rcx) + movntdq %xmm5,80(%rdi,%rcx) + movntdq %xmm6,96(%rdi,%rcx) + movntdq %xmm7,112(%rdi,%rcx) + + subq $-128,%rcx // add 128 with an 8-bit immediate + jnz LVeryLongAligned + jmp LVeryLongChunkEnd + + .align 4,0x90 // 16-byte align inner loops +LVeryLongUnaligned: // unaligned loop over 128-bytes + movdqu (%rsi,%rcx),%xmm0 + movdqu 16(%rsi,%rcx),%xmm1 + movdqu 32(%rsi,%rcx),%xmm2 + movdqu 48(%rsi,%rcx),%xmm3 + movdqu 64(%rsi,%rcx),%xmm4 + movdqu 80(%rsi,%rcx),%xmm5 + movdqu 96(%rsi,%rcx),%xmm6 + movdqu 112(%rsi,%rcx),%xmm7 + + movntdq %xmm0,(%rdi,%rcx) + movntdq %xmm1,16(%rdi,%rcx) + movntdq %xmm2,32(%rdi,%rcx) + movntdq %xmm3,48(%rdi,%rcx) + movntdq %xmm4,64(%rdi,%rcx) + movntdq %xmm5,80(%rdi,%rcx) + movntdq %xmm6,96(%rdi,%rcx) + movntdq %xmm7,112(%rdi,%rcx) + + subq $-128,%rcx // add 128 with an 8-bit immediate + jnz LVeryLongUnaligned + +LVeryLongChunkEnd: + cmpq $4096,%rdx // at least another page to go? + jae LBigChunkLoop // yes + + // Done. Call memcpy() again to handle the 0-4095 bytes at the end. + // We still have the args in the right registers: + // rdi = destination ptr + // rsi = source ptr + // rdx = length remaining (0..4095) + + sfence // required by non-temporal stores + testl %edx,%edx // anything left to copy? + jz 1f + call _memcpy +1: + popq %rbp // restore frame ptr + ret diff --git a/i386/string/bzero.s b/x86_64/string/memcpy.c similarity index 63% rename from i386/string/bzero.s rename to x86_64/string/memcpy.c index 2f5367a..347d185 100644 --- a/i386/string/bzero.s +++ b/x86_64/string/memcpy.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,20 +21,20 @@ * @APPLE_LICENSE_HEADER_END@ */ -/* - * Call the comm page routine - */ - -#define __APPLE_API_PRIVATE #include +#include -#include - - TEXT - ALIGN +PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse42) +PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse3x) -LEAF(_bzero,0) - movl $(_COMM_PAGE_BZERO), %eax - jmpl *%eax +static const platfunc_descriptor *memcpy_platfunc_descriptors[] = { + PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse42), + PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse3x), + 0 +}; -X_LEAF(___bzero, _bzero) +void *memcpy_chooser() __asm__("_memcpy"); +void *memcpy_chooser() { + __asm__(".desc _memcpy, 0x100"); + return find_platform_function((const platfunc_descriptor **) memcpy_platfunc_descriptors); +} diff --git a/x86_64/string/memcpy.s b/x86_64/string/memcpy.s deleted file mode 100644 index 8160b02..0000000 --- a/x86_64/string/memcpy.s +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: libc/i386/ansi/memcpy.c - * Author: Bruce Martin, NeXT Computer, Inc. - * - * HISTORY - * 24-Nov-92 Derek B Clegg (dclegg@next.com) - * Created for m98k. - */ -#define MEMCOPY -#include "bcopy.s" diff --git a/x86_64/string/memmove.c b/x86_64/string/memmove.c new file mode 100644 index 0000000..6fe7d07 --- /dev/null +++ b/x86_64/string/memmove.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse42) +PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse3x) + +static const platfunc_descriptor *memmove_platfunc_descriptors[] = { + PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse42), + PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse3x), + 0 +}; + +void *memmove_chooser() __asm__("_memmove"); +void *memmove_chooser() { + __asm__(".desc _memmove, 0x100"); + return find_platform_function((const platfunc_descriptor **) memmove_platfunc_descriptors); +} diff --git a/x86_64/string/memmove.s b/x86_64/string/memmove.s deleted file mode 100644 index 50fd4e2..0000000 --- a/x86_64/string/memmove.s +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: libc/i386/ansi/memmove.c - * Author: Bruce Martin, NeXT Computer, Inc. - * - * HISTORY - * 24-Nov-92 Derek B Clegg (dclegg@next.com) - * Created for m98k. - */ -#define MEMMOVE -#include "bcopy.s" diff --git a/x86_64/string/memset.s b/x86_64/string/memset.s index 423db2f..e79c214 100644 --- a/x86_64/string/memset.s +++ b/x86_64/string/memset.s @@ -21,7 +21,7 @@ */ #include - + /* This file contains the following functions: * @@ -31,7 +31,7 @@ * void memset_pattern16(void *b, const void *c16, size_t len); * * Calls of memset() with c==0 are routed to the bzero() routine. Most of the - * others go to _COMM_PAGE_MEMSET_PATTERN, which is entered as follows: + * others go to _memset_pattern, which is entered as follows: * %rdi = ptr to memory to set (aligned) * %edx = length (which can be short, though we bias in favor of long operands) * %xmm0 = the pattern to store @@ -41,24 +41,23 @@ * NB: we avoid "stos" family of instructions (stosl, stosb), as they are very slow * on P4s and probably other processors. */ - - #define kShort 255 // for nonzero memset(), too short for commpage - - + +#define kShort 255 // for nonzero memset(), too short for commpage + + .text .globl _memset .align 2 _memset: // void *memset(void *b, int c, size_t len); andl $0xFF,%esi // (c==0) ? jnz LNonzero // not a bzero - - movq $(_COMM_PAGE_BZERO),%rax// map memset(p,0,n) into bzero(p,n) + movq %rdx,%rsi // put count where bzero() expects it - jmp *%rax // enter commpage + jmp _bzero // enter _bzero + +// Handle memset of a nonzero value. - // Handle memset of a nonzero value. - LNonzero: movq %rdi,%r8 // preserve the original pointer so we can return it movl %esi,%eax // replicate byte in %esi into all four bytes @@ -69,12 +68,12 @@ LNonzero: orl %esi,%eax // now %eax has "c" in all 4 bytes cmpq $(kShort),%rdx // is operand too short for SSE? ja LCallCommpage // no - -// Nonzero memset() too short to call commpage. -// %eax = replicated 4-byte pattern -// %rdi = ptr -// %edx = length (<= kShort) - + + // Nonzero memset() too short to call commpage. + // %eax = replicated 4-byte pattern + // %rdi = ptr + // %edx = length (<= kShort) + cmpl $16,%edx // long enough to word align? jge 3f // yes test %edx,%edx // length==0? @@ -109,12 +108,12 @@ LNonzero: 6: movq %r8,%rax // get return value (ie, original ptr) ret - -// Nonzero memset() is long enough to call commpage. -// %eax = replicated 4-byte pattern -// %rdi = ptr -// %rdx = length (> kShort) - + + // Nonzero memset() is long enough to call commpage. + // %eax = replicated 4-byte pattern + // %rdi = ptr + // %rdx = length (> kShort) + LCallCommpage: movd %eax,%xmm0 // move %eax to low 4 bytes of %xmm0 pshufd $(0x00),%xmm0,%xmm0 // replicate across the vector @@ -129,14 +128,13 @@ LCallCommpage: subl $1,%ecx jnz 1b 2: // ptr aligned, length long enough to justify - movq $(_COMM_PAGE_MEMSET_PATTERN),%rax - call *%rax // call commpage to do the heavy lifting + call Lmemset_pattern // call commpage to do the heavy lifting movq %r8,%rax // get return value (ie, original ptr) ret -// Handle memset of a 16-byte pattern. - + // Handle memset of a 16-byte pattern. + .globl _memset_pattern16 .align 2, 0x90 _memset_pattern16: // void memset_pattern16(void *b, const void *c16, size_t len); @@ -144,8 +142,8 @@ _memset_pattern16: // void memset_pattern16(void *b, const void *c16, size_t l jmp LAlignPtr -// Handle memset of an 8-byte pattern. - + // Handle memset of an 8-byte pattern. + .globl _memset_pattern8 .align 2, 0x90 _memset_pattern8: // void memset_pattern8(void *b, const void *c8, size_t len); @@ -153,8 +151,8 @@ _memset_pattern8: // void memset_pattern8(void *b, const void *c8, size_t len) punpcklqdq %xmm0,%xmm0 // replicate into all 16 jmp LAlignPtr -// Handle memset of a 4-byte pattern. - + // Handle memset of a 4-byte pattern. + .globl _memset_pattern4 .align 2, 0x90 _memset_pattern4: // void memset_pattern4(void *b, const void *c4, size_t len); @@ -162,13 +160,13 @@ _memset_pattern4: // void memset_pattern4(void *b, const void *c4, size_t len) pshufd $(0x00),%xmm0,%xmm0 // replicate the 4 bytes across the vector -// Align ptr if necessary. We must rotate the pattern right for each byte we -// store while aligning the ptr. Since there is no rotate instruction in SSE3, -// we have to synthesize the rotates. -// %rdi = ptr -// %rdx = length -// %xmm0 = pattern - + // Align ptr if necessary. We must rotate the pattern right for each byte we + // store while aligning the ptr. Since there is no rotate instruction in SSE3, + // we have to synthesize the rotates. + // %rdi = ptr + // %rdx = length + // %xmm0 = pattern + LAlignPtr: // NB: can drop down to here! cmpq $100,%rdx // long enough to bother aligning ptr? movq %rdi,%rcx // copy ptr @@ -177,7 +175,7 @@ LAlignPtr: // NB: can drop down to here! andl $15,%ecx // get #bytes to align ptr jz LReady // already aligned subq %rcx,%rdx // adjust length - + test $1,%cl // 1-byte store required? movd %xmm0,%eax // get 4 low bytes in %eax jz 2f // no @@ -207,10 +205,138 @@ LAlignPtr: // NB: can drop down to here! movq %xmm0,(%rdi) // store low 8 bytes of %xmm0 pshufd $(0x4e),%xmm0,%xmm0 // rotate %xmm0 right 8 bytes (mask == 01 00 11 10) addq $8,%rdi // adjust ptr - -// Ptr is aligned if practical, we're ready to call commpage to do the heavy lifting. + + // Ptr is aligned if practical, we're ready to call commpage to do the heavy lifting. LReady: - movq $(_COMM_PAGE_MEMSET_PATTERN),%rax - call *%rax // call commpage to do the heavy lifting + call Lmemset_pattern // call commpage to do the heavy lifting ret + + +#define kLShort 63 +#define kVeryLong (1024*1024) + +Lmemset_pattern: + cmpq $(kLShort),%rdx // long enough to bother aligning? + ja LNotShort // yes + jmp LShort // no + + // Here for short operands or the end of long ones. + // %rdx = length (<= kLShort) + // %rdi = ptr (may not be not aligned) + // %xmm0 = pattern + +LUnalignedStore16: + movdqu %xmm0,(%rdi) // stuff in another 16 bytes + subl $16,%edx + addq $16,%rdi +LShort: + cmpl $16,%edx // room for another vector? + jge LUnalignedStore16 // yes +LLessThan16: // here at end of copy with < 16 bytes remaining + test $8,%dl // 8-byte store required? + jz 2f // no + movq %xmm0,(%rdi) // pack in 8 low bytes + psrldq $8,%xmm0 // then shift vector down 8 bytes + addq $8,%rdi +2: + test $4,%dl // 4-byte store required? + jz 3f // no + movd %xmm0,(%rdi) // pack in 4 low bytes + psrldq $4,%xmm0 // then shift vector down 4 bytes + addq $4,%rdi +3: + andl $3,%edx // more to go? + jz 5f // no + movd %xmm0,%eax // move remainders out into %eax +4: // loop on up to three bytes + movb %al,(%rdi) // pack in next byte + shrl $8,%eax // shift next byte into position + incq %rdi + dec %edx + jnz 4b +5: ret + +// Long enough to justify aligning ptr. Note that we have to rotate the +// pattern to account for any alignment. We do this by doing two unaligned +// stores, and then an aligned load from the middle of the two stores. +// This will stall on store forwarding alignment mismatch, and the unaligned +// stores can be pretty slow too, but the alternatives aren't any better. +// Fortunately, in most cases our caller has already aligned the ptr. +// %rdx = length (> kLShort) +// %rdi = ptr (may not be aligned) +// %xmm0 = pattern + +LNotShort: + movl %edi,%ecx // copy low bits of dest ptr + negl %ecx + andl $15,%ecx // mask down to #bytes to 16-byte align + jz LAligned // skip if already aligned + movdqu %xmm0,(%rdi) // store 16 unaligned bytes + movdqu %xmm0,16(%rdi) // and 16 more, to be sure we have an aligned chunk + addq %rcx,%rdi // now point to the aligned chunk + subq %rcx,%rdx // adjust remaining count + movdqa (%rdi),%xmm0 // get the rotated pattern (probably stalling) + addq $16,%rdi // skip past the aligned chunk + subq $16,%rdx + +// Set up for 64-byte loops. +// %rdx = length remaining +// %rdi = ptr (aligned) +// %xmm0 = rotated pattern + +LAligned: + movq %rdx,%rcx // copy length remaining + andl $63,%edx // mask down to residual length (0..63) + andq $-64,%rcx // %ecx <- #bytes we will zero in by-64 loop + jz LNoMoreChunks // no 64-byte chunks + addq %rcx,%rdi // increment ptr by length to move + cmpq $(kVeryLong),%rcx // long enough to justify non-temporal stores? + jge LVeryLong // yes + negq %rcx // negate length to move + jmp 1f + +// Loop over 64-byte chunks, storing into cache. + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movdqa %xmm0,(%rdi,%rcx) + movdqa %xmm0,16(%rdi,%rcx) + movdqa %xmm0,32(%rdi,%rcx) + movdqa %xmm0,48(%rdi,%rcx) + addq $64,%rcx + jne 1b + + jmp LNoMoreChunks + +// Very long operands: use non-temporal stores to bypass cache. + +LVeryLong: + negq %rcx // negate length to move + jmp 1f + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movntdq %xmm0,(%rdi,%rcx) + movntdq %xmm0,16(%rdi,%rcx) + movntdq %xmm0,32(%rdi,%rcx) + movntdq %xmm0,48(%rdi,%rcx) + addq $64,%rcx + jne 1b + + sfence // required by non-temporal stores + jmp LNoMoreChunks + +// Handle leftovers: loop by 16. +// %edx = length remaining (<64) +// %edi = ptr (aligned) +// %xmm0 = rotated pattern + +LLoopBy16: + movdqa %xmm0,(%rdi) // pack in 16 more bytes + subl $16,%edx // decrement count + addq $16,%rdi // increment ptr +LNoMoreChunks: + cmpl $16,%edx // more to go? + jge LLoopBy16 // yes + jmp LLessThan16 // handle up to 15 remaining bytes diff --git a/x86_64/string/strncpy.s b/x86_64/string/strncpy.s index 7159cf1..c926083 100644 --- a/x86_64/string/strncpy.s +++ b/x86_64/string/strncpy.s @@ -174,8 +174,7 @@ LFound0: LZeroBuffer: movq %rdx,%rsi // remaining buffer size (2nd argument) - movq $(_COMM_PAGE_BZERO),%rax - call *%rax + call _bzero LDone: movq %r8,%rax // original dest ptr is return value diff --git a/x86_64/sys/Makefile.inc b/x86_64/sys/Makefile.inc index 95a979c..0719fa2 100644 --- a/x86_64/sys/Makefile.inc +++ b/x86_64/sys/Makefile.inc @@ -3,9 +3,17 @@ AINC+= -I${.CURDIR}/x86_64/sys MDSRCS+= OSAtomic.s \ - i386_gettimeofday.s \ + atomic.c \ + spinlocks.c \ + spinlocks_asm.s \ + i386_gettimeofday_asm.s \ _setjmp.s \ setjmp.s \ - _sigtramp.s + _sigtramp.s \ + nanotime.s -MDCOPYFILES+= ${.CURDIR}/Platforms/${RC_TARGET_CONFIG}/x86_64/libc.syscall.x86_64 +DYLDSRCS += \ + OSAtomic.s \ + i386_gettimeofday_asm.s \ + spinlocks_asm.s \ + nanotime.s diff --git a/x86_64/sys/OSAtomic.s b/x86_64/sys/OSAtomic.s index b4c5e9c..2f18fb9 100644 --- a/x86_64/sys/OSAtomic.s +++ b/x86_64/sys/OSAtomic.s @@ -23,212 +23,238 @@ */ #include +#include #define DECLARE(x) \ -.align 2, 0x90 ; \ -.globl x ; \ -.globl x ## Barrier ; \ + .align 2, 0x90 ; \ + .globl x ; \ + .globl x ## Barrier ; \ x: ; \ x ## Barrier: .text +#define ATOMIC_UP 0 +#define ATOMIC_MP 1 +#define ATOMIC_RET_ORIG 0 +#define ATOMIC_RET_NEW 1 + +// compare and exchange 32-bit +// xchg32 +.macro xchg32 + .if $2 == ATOMIC_MP + lock + .endif + cmpxchgl $0, ($1) +.endm + +// xchg64 +.macro xchg64 + .if $2 == ATOMIC_MP + lock + .endif + cmpxchg $0, ($1) +.endm + +#define ATOMIC_ARITHMETIC(instr, orig, mp) \ + movl (%rsi), %eax /* get 2nd arg -> eax */ ;\ +1: movl %eax, %edx /* copy value to new reg */ ;\ + instr %edi, %edx /* apply instr to %edx with arg2 */ ;\ + xchg32 %edx, %rsi, mp /* do the compare swap (see macro above) */ ;\ + jnz 1b /* jump if failed */ ;\ + .if orig == 1 /* to return the new value, overwrite eax */ ;\ + movl %edx, %eax /* return the new value */ ;\ + .endif + +// Used in OSAtomicTestAndSet( uint32_t n, void *value ), assumes ABI parameter loctions +// Manpage says bit to test/set is (0x80 >> (n & 7)) of byte (addr + (n >> 3)) +#define ATOMIC_BIT_OP(instr, mp) \ + xorl $7, %edi /* bit position is numbered big endian so convert to little endian */ ;\ + shlq $3, %rsi ;\ + addq %rdi, %rsi /* generate bit address */ ;\ + movq %rsi, %rdi ;\ + andq $31, %rdi /* keep bit offset in range 0..31 */ ;\ + xorq %rdi, %rsi /* 4-byte align address */ ;\ + shrq $3, %rsi /* get 4-byte aligned address */ ;\ + .if mp == ATOMIC_MP /* don't plant the lock in UP code */ ;\ + lock /* lock the bit test */ ;\ + .endif ;\ + instr %edi, (%rsi) /* do the bit test, supplied into the macro */ ;\ + setc %al ;\ + movzbl %al,%eax /* widen in case caller assumes we return an int */ // uint32_t OSAtomicAnd32( uint32_t mask, uint32_t *value); -DECLARE(_OSAtomicAnd32) - movq $(_COMM_PAGE_COMPARE_AND_SWAP32), %rcx - movl %edi, %r11d // save mask - movl (%rsi), %eax // get value - movq %rsi, %rdx // put ptr where compare-and-swap expects it -1: - movl %r11d, %esi // original mask - movl %eax, %edi // old value - andl %eax, %esi // new value - call *%rcx // %edi=old value, %esi=new value. %rdx=ptr - jnz 1b - movl %esi, %eax +PLATFUNC_FUNCTION_START(OSAtomicAnd32, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicAnd32Barrier, up, 64, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_UP) + ret + +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Barrier, mp, 64, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_MP) ret - // uint32_t OSAtomicOr32( uint32_t mask, uint32_t *value); -DECLARE(_OSAtomicOr32) - movq $(_COMM_PAGE_COMPARE_AND_SWAP32), %rcx - movl %edi, %r11d // save mask - movl (%rsi), %eax // get value - movq %rsi, %rdx // put ptr where compare-and-swap expects it -1: - movl %r11d, %esi // original mask - movl %eax, %edi // old value - orl %eax, %esi // new value - call *%rcx // %edi=old value, %esi=new value. %rdx=ptr - jnz 1b - movl %esi, %eax +PLATFUNC_FUNCTION_START(OSAtomicOr32, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicOr32Barrier, up, 64, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_UP) ret +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Barrier, mp, 64, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_MP) + ret // uint32_t OSAtomicXor32( uint32_t mask, uint32_t *value); -DECLARE(_OSAtomicXor32) - movq $(_COMM_PAGE_COMPARE_AND_SWAP32), %rcx - movl %edi, %r11d // save mask - movl (%rsi), %eax // get value - movq %rsi, %rdx // put ptr where compare-and-swap expects it -1: - movl %r11d, %esi // original mask - movl %eax, %edi // old value - xorl %eax, %esi // new value - call *%rcx // %edi=old value, %esi=new value. %rdx=ptr - jnz 1b - movl %esi, %eax +PLATFUNC_FUNCTION_START(OSAtomicXor32, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicXor32Barrier, up, 64, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_UP) ret +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Barrier, mp, 64, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_MP) + ret // uint32_t OSAtomicAnd32Orig( uint32_t mask, uint32_t *value); -DECLARE(_OSAtomicAnd32Orig) - movq $(_COMM_PAGE_COMPARE_AND_SWAP32), %rcx - movl %edi, %r11d // save mask - movl (%rsi), %eax // get value - movq %rsi, %rdx // put ptr where compare-and-swap expects it -1: - movl %r11d, %esi // original mask - movl %eax, %edi // old value - andl %eax, %esi // new value - call *%rcx // %edi=old value, %esi=new value. %rdx=ptr - jnz 1b - movl %edi, %eax +PLATFUNC_FUNCTION_START(OSAtomicAnd32Orig, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicAnd32OrigBarrier, up, 64, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_UP) ret - -// uint32_t OSAtomicOr32Orig( uint32_t mask, uint32_t *value); -DECLARE(_OSAtomicOr32Orig) - movq $(_COMM_PAGE_COMPARE_AND_SWAP32), %rcx - movl %edi, %r11d // save mask - movl (%rsi), %eax // get value - movq %rsi, %rdx // put ptr where compare-and-swap expects it -1: - movl %r11d, %esi // original mask - movl %eax, %edi // old value - orl %eax, %esi // new value - call *%rcx // %edi=old value, %esi=new value. %rdx=ptr - jnz 1b - movl %edi, %eax +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Orig, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32OrigBarrier, mp, 64, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_MP) ret +// uint32_t OSAtomicOr32Orig( uint32_t mask, uint32_t *value); +PLATFUNC_FUNCTION_START(OSAtomicOr32Orig, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicOr32OrigBarrier, up, 64, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_UP) + ret + +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Orig, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32OrigBarrier, mp, 64, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_MP) + ret // uint32_t OSAtomicXor32Orig( uint32_t mask, uint32_t *value); -DECLARE(_OSAtomicXor32Orig) - movq $(_COMM_PAGE_COMPARE_AND_SWAP32), %rcx - movl %edi, %r11d // save mask - movl (%rsi), %eax // get value - movq %rsi, %rdx // put ptr where compare-and-swap expects it -1: - movl %r11d, %esi // original mask - movl %eax, %edi // old value - xorl %eax, %esi // new value - call *%rcx // %edi=old value, %esi=new value. %rdx=ptr - jnz 1b - movl %edi, %eax +PLATFUNC_FUNCTION_START(OSAtomicXor32Orig, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicXor32OrigBarrier, up, 64, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_UP) ret +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Orig, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32OrigBarrier, mp, 64, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_MP) + ret // bool OSAtomicCompareAndSwap32( int32_t old, int32_t new, int32_t *value); -DECLARE(_OSAtomicCompareAndSwapInt) -DECLARE(_OSAtomicCompareAndSwap32) - movq $(_COMM_PAGE_COMPARE_AND_SWAP32), %rcx - call *%rcx // %edi=old value, %esi=new value. %rdx=ptr +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapInt, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapIntBarrier, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32Barrier, up, 64, 2) + movl %edi, %eax + xchg32 %esi, %rdx, ATOMIC_UP sete %al movzbl %al,%eax // widen in case caller assumes we return an int ret +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapInt, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapIntBarrier, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32Barrier, mp, 64, 2) + movl %edi, %eax + xchg32 %esi, %rdx, ATOMIC_MP + sete %al + movzbl %al,%eax // widen in case caller assumes we return an int + ret // bool OSAtomicCompareAndSwap64( int64_t old, int64_t new, int64_t *value); -DECLARE(_OSAtomicCompareAndSwapPtr) -DECLARE(_OSAtomicCompareAndSwapLong) -DECLARE(_OSAtomicCompareAndSwap64) - movq $(_COMM_PAGE_COMPARE_AND_SWAP64), %rcx - call *%rcx // %rdi=old value, %rsi=new value. %rdx=ptr +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtr, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtrBarrier, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLong, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLongBarrier, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64Barrier, up, 64, 2) + mov %rdi, %rax + xchg64 %rsi, %rdx, ATOMIC_UP + sete %al + movzbl %al,%eax // widen in case caller assumes we return an int + ret + +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtr, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtrBarrier, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLong, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLongBarrier, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64Barrier, mp, 64, 2) + mov %rdi, %rax + xchg64 %rsi, %rdx, ATOMIC_MP sete %al movzbl %al,%eax // widen in case caller assumes we return an int ret - // int32_t OSAtomicAdd32( int32_t amt, int32_t *value ); -DECLARE(_OSAtomicAdd32) - movq $(_COMM_PAGE_ATOMIC_ADD32), %rcx +PLATFUNC_FUNCTION_START(OSAtomicAdd32, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicAdd32Barrier, up, 64, 2) movl %edi, %eax // save amt to add - call *%rcx - addl %edi,%eax // new value + xaddl %edi, (%rsi) // swap and add value, returns old value in %edi + addl %edi, %eax // add old value to amt as return value ret +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32Barrier, mp, 64, 2) + movl %edi, %eax // save amt to add + lock // lock prefix breaks tabs ;) + xaddl %edi, (%rsi) // swap and add value, returns old value in %edi + addl %edi, %eax // add old value to amt as return value + ret // int64_t OSAtomicAdd64( int64_t amt, int64_t *value ); -DECLARE(_OSAtomicAdd64) - movq $(_COMM_PAGE_ATOMIC_ADD64), %rcx +PLATFUNC_FUNCTION_START(OSAtomicAdd64, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicAdd64Barrier, up, 64, 2) movq %rdi, %rax // save amt to add - call *%rcx - addq %rdi, %rax // new value + xadd %rdi, (%rsi) // swap and add value, returns old value in %rsi + addq %rdi, %rax // add old value to amt as return value ret +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64Barrier, mp, 64, 2) + movq %rdi, %rax // save amt to add + lock + xadd %rdi, (%rsi) // swap and add value, returns old value in %rsi + addq %rdi, %rax // add old value to amt as return value + ret // bool OSAtomicTestAndSet( uint32_t n, void *value ); -DECLARE(_OSAtomicTestAndSet) - movq $(_COMM_PAGE_BTS), %rax - xorl $7, %edi // bit position is numbered big endian - call *%rax - setc %al - movzbl %al,%eax // widen in case caller assumes we return an int +PLATFUNC_FUNCTION_START(OSAtomicTestAndSet, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicTestAndSetBarrier, up, 64, 2) + ATOMIC_BIT_OP(btsl, ATOMIC_UP) ret +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSet, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSetBarrier, mp, 64, 2) + ATOMIC_BIT_OP(btsl, ATOMIC_MP) + ret // bool OSAtomicTestAndClear( uint32_t n, void *value ); -DECLARE(_OSAtomicTestAndClear) - movq $(_COMM_PAGE_BTC), %rax - xorl $7, %edi // bit position is numbered big endian - call *%rax - setc %al - movzbl %al,%eax // widen in case caller assumes we return an int +PLATFUNC_FUNCTION_START(OSAtomicTestAndClear, up, 64, 2) +PLATFUNC_FUNCTION_START(OSAtomicTestAndClearBarrier, up, 64, 2) + ATOMIC_BIT_OP(btrl, ATOMIC_UP) ret -// bool OSSpinLockTry( OSSpinLock *lock ); - .align 2, 0x90 - .globl _OSSpinLockTry - .globl __spin_lock_try -_OSSpinLockTry: -__spin_lock_try: - movq $(_COMM_PAGE_SPINLOCK_TRY), %rax - jmp *%rax - - -// void OSSpinLockLock( OSSpinLock *lock ); - .align 2, 0x90 - .globl _OSSpinLockLock - .globl _spin_lock - .globl __spin_lock -_OSSpinLockLock: -_spin_lock: -__spin_lock: - movq $(_COMM_PAGE_SPINLOCK_LOCK), %rax - jmp *%rax - - -// void OSSpinLockUnlock( OSSpinLock *lock ); - .align 2, 0x90 - .globl _OSSpinLockUnlock - .globl _spin_unlock - .globl __spin_unlock -_OSSpinLockUnlock: -_spin_unlock: -__spin_unlock: - movl $0, (%rdi) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClear, mp, 64, 2) +PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClearBarrier, mp, 64, 2) + ATOMIC_BIT_OP(btrl, ATOMIC_MP) ret - // void OSMemoryBarrier( void ); .align 2, 0x90 .globl _OSMemoryBarrier _OSMemoryBarrier: - movq $(_COMM_PAGE_MEMORY_BARRIER), %rax - jmp *%rax - + mfence + ret /* * typedef volatile struct { @@ -255,9 +281,9 @@ _OSAtomicEnqueue: // %rdi == list head, %rsi == new, %rdx == offset jnz 1b popq %rbx ret - - -/* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */ + + + /* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */ .align 2 .globl _OSAtomicDequeue _OSAtomicDequeue: // %rdi == list head, %rsi == offset @@ -276,3 +302,47 @@ _OSAtomicDequeue: // %rdi == list head, %rsi == offset 2: popq %rbx ret // ptr to 1st element in Q still in %rax + +/* + * typedef volatile struct { + * void *opaque1; <-- ptr to first queue element or null + * void *opaque2; <-- ptr to last queue element or null + * int opaque3; <-- spinlock + * } OSFifoQueueHead; + * + * void OSAtomicFifoEnqueue( OSFifoQueueHead *list, void *new, size_t offset); + */ + .align 2 + .globl _OSAtomicFifoEnqueue +_OSAtomicFifoEnqueue: + pushq %rbx + xorl %ebx,%ebx // clear "preemption pending" flag + movq $(_COMM_PAGE_PFZ_ENQUEUE), %rcx + call *%rcx + testl %ebx,%ebx // pending preemption? + jz 1f + call _preempt // call into the kernel to pfz_exit +1: + popq %rbx + ret + + +/* void* OSAtomicFifoDequeue( OSFifoQueueHead *list, size_t offset); */ + .align 2 + .globl _OSAtomicFifoDequeue +_OSAtomicFifoDequeue: + pushq %rbx + xorl %ebx,%ebx // clear "preemption pending" flag + movq %rsi,%rdx // move offset to %rdx to be like the Enqueue case + movq $(_COMM_PAGE_PFZ_DEQUEUE), %rcx + call *%rcx + testl %ebx,%ebx // pending preemption? + jz 1f + call _preempt // call into the kernel to pfz_exit +1: + popq %rbx + ret // ptr to 1st element in Q in %rax + +// Local Variables: +// tab-width: 8 +// End: diff --git a/x86_64/sys/_setjmp.s b/x86_64/sys/_setjmp.s index 7ebf81c..02cd31e 100644 --- a/x86_64/sys/_setjmp.s +++ b/x86_64/sys/_setjmp.s @@ -70,15 +70,9 @@ LEAF(__setjmp, 0) movq (%rsp), %rax movq %rax, JB_RIP(%rdi) // RSP is set to the frame return address plus 8 - movq %rsp, %rax - addq $8, %rax + leaq 8(%rsp), %rax movq %rax, JB_RSP(%rdi) - // save rflags - you can't use movq - pushfq - popq %rax - movq %rax, JB_RFLAGS(%rdi) - // save fp control word fnstcw JB_FPCONTROL(%rdi) @@ -86,19 +80,18 @@ LEAF(__setjmp, 0) stmxcsr JB_MXCSR(%rdi) // return 0 - xorq %rax, %rax + xorl %eax, %eax ret LEAF(__longjmp, 0) - fninit // reset FP coprocessor - + fninit // Clear all FP exceptions // %rdi is a jmp_buf (struct sigcontext *) - // %rsi is the return value - movq %rsi, %rax - testq %rax, %rax + // %esi is the return value + movl %esi, %eax + testl %esi, %esi jnz 1f - addq $1, %rax + incl %eax // general registers 1: @@ -116,8 +109,8 @@ LEAF(__longjmp, 0) // restore MXCSR ldmxcsr JB_MXCSR(%rdi) - // rflags - pushq JB_RFLAGS(%rdi) - popfq + + // Make sure DF is reset + cld jmp *JB_RIP(%rdi) diff --git a/x86_64/sys/_sigtramp.s b/x86_64/sys/_sigtramp.s index bb1eebf..5c80116 100644 --- a/x86_64/sys/_sigtramp.s +++ b/x86_64/sys/_sigtramp.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007, 2011 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -58,6 +58,7 @@ _sigtramp( .text .align 4,0x90 __sigtramp: +Lstart: /* Although this routine does not need any stack frame, various parts of the OS can't analyse the stack without them. */ pushq %rbp @@ -85,7 +86,9 @@ Lcall_end: #endif movq %rbx, %rdi movl $ UC_FLAVOR, %esi - jmp ___sigreturn + callq ___sigreturn + ret +Lend: /* DWARF unwind table #defines. */ #define DW_CFA_advance_loc_4 0x44 @@ -155,8 +158,8 @@ EH_frame1: .long L$set$0 # Length of Common Information Entry LSCIE1: .long 0 # CIE Identifier Tag - .byte 0x3 # CIE Version - .ascii "zR\0" # CIE Augmentation + .byte 0x1 # CIE Version + .ascii "zRS\0" # CIE Augmentation .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor .byte 0x78 # sleb128 -8; CIE Data Alignment Factor .byte 0x10 # CIE RA Column @@ -167,6 +170,8 @@ LSCIE1: .byte 0x8 # uleb128 0x4 .byte DW_CFA_offset(16) .byte 0x1 # uleb128 0x1 + .byte DW_CFA_offset(16) // duplicate DW_CFA_offset (rip, -8) tells linker to not make compact unwind + .byte 0x1 # uleb128 0x1 .align 3 LECIE1: .globl _sigtramp.eh @@ -176,8 +181,8 @@ LSFDE1: .long L$set$1 # FDE Length LASFDE1: .long LASFDE1-EH_frame1 # FDE CIE offset - .quad Lcall_start-. # FDE initial location - .set L$set$2,Lcall_end-Lcall_start + .quad Lstart-. # FDE initial location + .set L$set$2,Lend-Lstart .quad L$set$2 # FDE address range .byte 0x0 # uleb128 0x0; Augmentation size diff --git a/x86_64/sys/atomic.c b/x86_64/sys/atomic.c new file mode 100644 index 0000000..8a2ee19 --- /dev/null +++ b/x86_64/sys/atomic.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +#define RESOLVER_UP_MP(symbol) \ + PLATFUNC_DESCRIPTOR(symbol, up, kUP, 0); \ + PLATFUNC_DESCRIPTOR(symbol, mp, 0, kUP); \ + static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \ + PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \ + PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \ + 0 \ + }; \ + void* symbol ## _chooser() __asm__("_" #symbol); \ + void* symbol ## _chooser() { \ + __asm__(".symbol_resolver _" #symbol); \ + return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \ + } + +RESOLVER_UP_MP(OSAtomicAnd32) +RESOLVER_UP_MP(OSAtomicAnd32Barrier) +RESOLVER_UP_MP(OSAtomicOr32) +RESOLVER_UP_MP(OSAtomicOr32Barrier) +RESOLVER_UP_MP(OSAtomicXor32) +RESOLVER_UP_MP(OSAtomicXor32Barrier) +RESOLVER_UP_MP(OSAtomicAnd32Orig) +RESOLVER_UP_MP(OSAtomicAnd32OrigBarrier) +RESOLVER_UP_MP(OSAtomicOr32Orig) +RESOLVER_UP_MP(OSAtomicOr32OrigBarrier) +RESOLVER_UP_MP(OSAtomicXor32Orig) +RESOLVER_UP_MP(OSAtomicXor32OrigBarrier) +RESOLVER_UP_MP(OSAtomicCompareAndSwapInt) +RESOLVER_UP_MP(OSAtomicCompareAndSwapIntBarrier) +RESOLVER_UP_MP(OSAtomicCompareAndSwap32) +RESOLVER_UP_MP(OSAtomicCompareAndSwap32Barrier) +RESOLVER_UP_MP(OSAtomicCompareAndSwapPtr) +RESOLVER_UP_MP(OSAtomicCompareAndSwapPtrBarrier) +RESOLVER_UP_MP(OSAtomicCompareAndSwapLong) +RESOLVER_UP_MP(OSAtomicCompareAndSwapLongBarrier) +RESOLVER_UP_MP(OSAtomicCompareAndSwap64) +RESOLVER_UP_MP(OSAtomicCompareAndSwap64Barrier) +RESOLVER_UP_MP(OSAtomicAdd32) +RESOLVER_UP_MP(OSAtomicAdd32Barrier) +RESOLVER_UP_MP(OSAtomicAdd64) +RESOLVER_UP_MP(OSAtomicAdd64Barrier) +RESOLVER_UP_MP(OSAtomicTestAndSet) +RESOLVER_UP_MP(OSAtomicTestAndSetBarrier) +RESOLVER_UP_MP(OSAtomicTestAndClear) +RESOLVER_UP_MP(OSAtomicTestAndClearBarrier) diff --git a/x86_64/sys/i386_gettimeofday.s b/x86_64/sys/i386_gettimeofday.s deleted file mode 100644 index 8865b87..0000000 --- a/x86_64/sys/i386_gettimeofday.s +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* Copyright 1998 Apple Computer, Inc. */ - -#include - -#define __APPLE_API_PRIVATE -#include -#undef __APPLE_API_PRIVATE - -LABEL(___commpage_gettimeofday) - movq $(_COMM_PAGE_GETTIMEOFDAY),%rax - jmp *%rax diff --git a/x86_64/sys/i386_gettimeofday_asm.s b/x86_64/sys/i386_gettimeofday_asm.s new file mode 100644 index 0000000..42898ff --- /dev/null +++ b/x86_64/sys/i386_gettimeofday_asm.s @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2003-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include +#include + +#define NSEC_PER_SEC 1000*1000*1000 +#define NSEC_PER_USEC 1000 + + .private_extern ___commpage_gettimeofday + .align 4, 0x90 +___commpage_gettimeofday: +// %rdi = ptr to timeval + pushq %rbp // set up a frame for backtraces + pushq %r12 // push callee-saved registers we want to use + pushq %r13 + pushq %r14 + movq %rsp,%rbp + movq %rdi,%r12 // save ptr to timeval + movq $(_COMM_PAGE_TIME_DATA_START),%r13 +0: + movl _GTOD_GENERATION(%r13),%r14d // get generation (0 if disabled) + testl %r14d,%r14d // disabled? + jz 4f + + call _mach_absolute_time // get %rax <- nanotime() + + movl _GTOD_SEC_BASE(%r13),%r8d // get _COMM_PAGE_TIMESTAMP + subq _GTOD_NS_BASE(%r13),%rax // generate nanoseconds since timestamp + cmpl _GTOD_GENERATION(%r13),%r14d // has data changed out from under us? + jne 0b + + movl $ NSEC_PER_SEC,%ecx + movq %rax,%rdx + shrq $32,%rdx // get high half of delta in %edx + divl %ecx // %eax <- seconds since timestamp, %edx <- nanoseconds + addl %eax,%r8d // add seconds elapsed to timestamp seconds + + movl $ NSEC_PER_USEC,%ecx + movl %edx,%eax + xorl %edx,%edx + divl %ecx // divide residual ns by 1000 to get residual us in %eax + + movq %r8,(%r12) // store 64-bit seconds into timeval + movl %eax,8(%r12) // store 32-bit useconds into timeval + xorl %eax,%eax // return 0 for success +3: + popq %r14 + popq %r13 + popq %r12 + popq %rbp + ret +4: // fail + movl $1,%eax + jmp 3b diff --git a/x86_64/sys/nanotime.s b/x86_64/sys/nanotime.s new file mode 100644 index 0000000..f5413be --- /dev/null +++ b/x86_64/sys/nanotime.s @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2003-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include + +/* + * 64-bit version _mach_absolute_time. We return the 64-bit nanotime in %rax, + */ + .globl _mach_absolute_time +_mach_absolute_time: + pushq %rbp // set up a frame for backtraces + movq %rsp,%rbp + movq $(_COMM_PAGE_TIME_DATA_START),%rsi +1: + movl _NT_GENERATION(%rsi),%r8d // get generation + testl %r8d,%r8d // if 0, data is being changed... + jz 1b // ...so loop until stable + lfence + rdtsc // edx:eax := tsc + lfence + shlq $32,%rdx // rax := ((edx << 32) | eax), ie 64-bit tsc + orq %rdx,%rax + subq _NT_TSC_BASE(%rsi), %rax // rax := (tsc - base_tsc) + movl _NT_SCALE(%rsi),%ecx + mulq %rcx // rdx:rax := (tsc - base_tsc) * scale + shrdq $32,%rdx,%rax // _COMM_PAGE_NT_SHIFT is always 32 + addq _NT_NS_BASE(%rsi),%rax // (((tsc - base_tsc) * scale) >> 32) + ns_base + + cmpl _NT_GENERATION(%rsi),%r8d // did the data change during computation? + jne 1b + popq %rbp + ret diff --git a/x86_64/sys/spinlocks.c b/x86_64/sys/spinlocks.c new file mode 100644 index 0000000..8bc85a8 --- /dev/null +++ b/x86_64/sys/spinlocks.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +#define RESOLVER_UP_MP(symbol) \ + PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, up); \ + PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, mp); \ + static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \ + PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \ + PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \ + 0 \ + }; \ + void* symbol ## _chooser() __asm__("_" #symbol); \ + void* symbol ## _chooser() { \ + __asm__(".symbol_resolver _" #symbol); \ + return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \ + } + +RESOLVER_UP_MP(OSSpinLockTry) +RESOLVER_UP_MP(_spin_lock_try) +RESOLVER_UP_MP(OSSpinLockLock) +RESOLVER_UP_MP(_spin_lock) +RESOLVER_UP_MP(spin_lock) diff --git a/x86_64/sys/spinlocks_asm.s b/x86_64/sys/spinlocks_asm.s new file mode 100644 index 0000000..7bc0fbd --- /dev/null +++ b/x86_64/sys/spinlocks_asm.s @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2003-2009 Apple, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include + +PLATFUNC_FUNCTION_START(OSSpinLockTry, up, 64, 4) +PLATFUNC_FUNCTION_START(_spin_lock_try, up, 64, 4) + xorl %eax, %eax + orl $-1, %edx + cmpxchgl %edx, (%rdi) + setz %dl + movzbl %dl, %eax + ret +PLATFUNC_DESCRIPTOR(OSSpinLockTry,up,kUP,0) +PLATFUNC_DESCRIPTOR(_spin_lock_try,up,kUP,0) + + +PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockTry, mp, 64, 4) +PLATFUNC_FUNCTION_START_GENERIC(_spin_lock_try, mp, 64, 4) + xorl %eax, %eax + orl $-1, %edx + lock + cmpxchgl %edx, (%rdi) + setz %dl + movzbl %dl, %eax + ret +PLATFUNC_DESCRIPTOR(OSSpinLockTry,mp,0,kUP) +PLATFUNC_DESCRIPTOR(_spin_lock_try,mp,0,kUP) + + +PLATFUNC_FUNCTION_START(OSSpinLockLock, up, 64, 4) +PLATFUNC_FUNCTION_START(_spin_lock, up, 64, 4) +PLATFUNC_FUNCTION_START(spin_lock, up, 64, 4) + movq %rdi,%r8 +0: + xorl %eax, %eax + orl $-1, %edx + cmpxchgl %edx, (%r8) + jnz 1f + ret +1: + /* failed to get lock so relinquish the processor immediately on UP */ + xorl %edi,%edi /* THREAD_NULL */ + movl $1,%esi /* SWITCH_OPTION_DEPRESS */ + movl $1,%edx /* 1 ms */ + movl $(SYSCALL_CONSTRUCT_MACH(61)),%eax /* 61 = thread_switch */ + syscall + jmp 0b +PLATFUNC_DESCRIPTOR(OSSpinLockLock,up,kUP,0) +PLATFUNC_DESCRIPTOR(_spin_lock,up,kUP,0) +PLATFUNC_DESCRIPTOR(spin_lock,up,kUP,0) + + +PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockLock, mp, 64, 4) +PLATFUNC_FUNCTION_START_GENERIC(_spin_lock, mp, 64, 4) +PLATFUNC_FUNCTION_START_GENERIC(spin_lock, mp, 64, 4) + movq %rdi,%r8 +0: + xorl %eax, %eax + orl $-1, %edx + lock + cmpxchgl %edx, (%r8) + jnz 1f + ret +1: + xorl %eax, %eax + movl $(MP_SPIN_TRIES), %edx +2: /* spin for awhile before relinquish */ + pause + cmpl %eax, (%r8) + jz 0b + decl %edx + jnz 2b + /* failed to get lock after spinning so relinquish */ + xorl %edi,%edi /* THREAD_NULL */ + movl $1,%esi /* SWITCH_OPTION_DEPRESS */ + movl $1,%edx /* 1 ms */ + movl $(SYSCALL_CONSTRUCT_MACH(61)),%eax /* 61 = thread_switch */ + syscall + jmp 0b +PLATFUNC_DESCRIPTOR(OSSpinLockLock,mp,0,kUP) +PLATFUNC_DESCRIPTOR(_spin_lock,mp,0,kUP) +PLATFUNC_DESCRIPTOR(spin_lock,mp,0,kUP) + +// void OSSpinLockUnlock( OSSpinLock *lock ); + .align 2, 0x90 + .globl _OSSpinLockUnlock + .globl _spin_unlock + .globl __spin_unlock +_OSSpinLockUnlock: +_spin_unlock: +__spin_unlock: + movl $0, (%rdi) + ret + -- 2.45.2