From 224c70764cab4e0e39a26aaf3ad3016552f62f55 Mon Sep 17 00:00:00 2001 From: Apple Date: Sat, 6 Oct 2007 01:59:23 +0000 Subject: [PATCH] Libc-498.tar.gz --- .autopatched | 0 BSDmakefile | 234 +- CLIB-LIST | 682 ----- MISSING-MANPAGE | 9 - MISSING_SYSCALLS | 8 - Makefile | 45 +- Makefile.autopatch | 6 + Makefile.fbsd_begin | 1 + Makefile.fbsd_end | 41 +- Makefile.inc | 60 +- Makefile.nbsd_end | 32 +- Makefile.obsd_end | 32 +- Makefile.xbs | 276 +- REQUIRED-MACROS | 3 - SYSCALL-LIST | 145 - available.ex | 13 + compat-43/FreeBSD/Makefile.inc | 17 - compat-43/FreeBSD/creat.c.patch | 30 + compat-43/FreeBSD/gethostid.3.patch | 17 + compat-43/FreeBSD/killpg.2.patch | 45 + compat-43/FreeBSD/killpg.c.patch | 30 + compat-43/FreeBSD/setpgrp.c.patch | 20 +- compat-43/Makefile.inc | 23 +- compat-43/creat-fbsd.c | 62 + compat-43/creat.2 | 1 + compat-43/gethostid-fbsd.c | 56 + compat-43/gethostid.3 | 82 + compat-43/getwd-fbsd.c | 56 + compat-43/killpg-fbsd.c | 65 + compat-43/killpg.2 | 109 + compat-43/sethostid-fbsd.c | 53 + compat-43/setpgrp-fbsd.c | 52 + compat-43/setregid.c | 22 - compat-43/setreuid.c | 22 - compat-43/setrgid-fbsd.c | 47 + compat-43/setruid-fbsd.c | 47 + compat-43/setruid.3 | 1 + .../getattrlist.s => compat-43/sigaltstk.c | 27 +- compat-43/sigcompat.c | 38 + compat-43/sigpause.2 | 22 +- darwin/MKGetTimeBaseInfo.c | 62 + darwin/Makefile.inc | 29 +- darwin/_dirhelper.c | 212 ++ darwin/copyfile.c | 1620 ----------- darwin/copyfile.h | 86 - .../dirhelper.defs | 20 +- .../sys/sem_wait.s => darwin/dirhelper_priv.h | 36 +- darwin/kvm.c | 107 + darwin/libproc.c | 168 ++ darwin/libproc.h | 97 + darwin/proc_listpidspath.c | 498 ++++ db/Makefile.inc | 2 + db/btree/Makefile.inc | 11 +- db/btree/bt_close-fbsd.c | 186 ++ db/btree/bt_conv-fbsd.c | 223 ++ db/btree/bt_debug-fbsd.c | 332 +++ db/btree/bt_delete-fbsd.c | 659 +++++ db/btree/bt_extern.h | 71 + db/btree/bt_get-fbsd.c | 107 + db/btree/bt_open-fbsd.c | 449 +++ db/btree/bt_overflow-fbsd.c | 230 ++ db/btree/bt_page-fbsd.c | 102 + db/btree/bt_put-fbsd.c | 325 +++ db/btree/bt_search-fbsd.c | 215 ++ db/btree/bt_seq-fbsd.c | 462 +++ db/btree/bt_split-fbsd.c | 827 ++++++ db/btree/bt_utils-fbsd.c | 262 ++ db/btree/btree.h | 384 +++ db/db/db-fbsd.c | 101 + db/hash/FreeBSD/hash.c.patch | 21 +- db/hash/FreeBSD/ndbm.c.patch | 14 +- db/hash/Makefile.inc | 9 +- db/hash/hash-fbsd.c | 1005 +++++++ db/hash/hash.h | 296 ++ db/hash/hash_bigkey-fbsd.c | 670 +++++ db/hash/hash_buf-fbsd.c | 356 +++ db/hash/hash_extern.h | 66 + db/hash/hash_func-fbsd.c | 214 ++ db/hash/hash_log2-fbsd.c | 56 + db/hash/hash_page-fbsd.c | 959 ++++++ db/hash/ndbm-fbsd.c | 246 ++ db/hash/page.h | 93 + db/man/FreeBSD/dbm.3 | 2 +- db/man/FreeBSD/dbm.3.patch | 192 ++ db/man/Makefile.inc | 30 +- db/man/btree.3 | 1 + db/man/dbm.3 | 280 ++ db/man/dbopen.3 | 1 + db/man/hash.3 | 1 + db/man/mpool.3 | 1 + db/man/recno.3 | 1 + db/mpool/FreeBSD/mpool.c.patch | 2 +- db/mpool/Makefile.inc | 3 + db/mpool/mpool-fbsd.c | 468 +++ db/recno/FreeBSD/extern.h.patch | 2 +- db/recno/FreeBSD/recno.h.patch | 10 +- db/recno/Makefile.inc | 6 +- db/recno/rec_close-fbsd.c | 188 ++ db/recno/rec_delete-fbsd.c | 199 ++ db/recno/rec_extern.h | 55 + db/recno/rec_get-fbsd.c | 313 ++ db/recno/rec_open-fbsd.c | 245 ++ db/recno/rec_put-fbsd.c | 287 ++ db/recno/rec_search-fbsd.c | 128 + db/recno/rec_seq-fbsd.c | 134 + db/recno/rec_utils-fbsd.c | 124 + db/recno/recno.h | 40 + dpkg/control | 4 - emulated/Makefile.inc | 5 +- emulated/bsd_signal.c | 2 +- emulated/lchflags.3 | 52 + emulated/lchflags.c | 44 + emulated/lchmod.3 | 54 + emulated/lchmod.c | 46 + emulated/lutimes.3 | 62 + emulated/lutimes.c | 60 + emulated/statvfs.3 | 54 +- emulated/tcgetsid.3 | 4 +- gdtoa/FreeBSD/_hdtoa.c.patch | 28 +- gdtoa/FreeBSD/_ldtoa.c.patch | 38 +- gdtoa/FreeBSD/gdtoa-gdtoa.c.patch | 15 + gdtoa/FreeBSD/gdtoa-gethex.c.patch | 68 +- gdtoa/FreeBSD/gdtoa-hexnan.c.patch | 126 + gdtoa/FreeBSD/gdtoa-smisc.c.patch | 27 + gdtoa/FreeBSD/gdtoa-strtod.c.patch | 73 +- gdtoa/FreeBSD/gdtoa-strtodg.c.patch | 126 +- gdtoa/FreeBSD/gdtoa-strtof.c.patch | 32 +- gdtoa/FreeBSD/gdtoa-strtopdd.c.patch | 61 +- gdtoa/FreeBSD/gdtoa_strtopx.c.patch | 34 +- gdtoa/FreeBSD/gdtoaimp.h.patch | 31 +- gdtoa/Makefile.inc | 21 +- gdtoa/_hdtoa-fbsd.c | 342 +++ gdtoa/{FreeBSD => }/_ldbl_util.c | 14 +- gdtoa/_ldtoa-fbsd.c | 138 + gdtoa/arith.h | 2 + gdtoa/gdtoa-dmisc-fbsd.c | 216 ++ gdtoa/gdtoa-dtoa-fbsd.c | 753 +++++ gdtoa/gdtoa-gdtoa-fbsd.c | 761 +++++ gdtoa/gdtoa-gethex-fbsd.c | 281 ++ gdtoa/gdtoa-gmisc-fbsd.c | 86 + gdtoa/gdtoa-hd_init-fbsd.c | 55 + gdtoa/gdtoa-hexnan-fbsd.c | 110 + gdtoa/gdtoa-misc-fbsd.c | 865 ++++++ gdtoa/gdtoa-smisc-fbsd.c | 191 ++ gdtoa/gdtoa-strtod-fbsd.c | 1014 +++++++ gdtoa/gdtoa-strtodg-fbsd.c | 1053 +++++++ gdtoa/gdtoa-strtof-fbsd.c | 100 + gdtoa/gdtoa-strtopdd-fbsd.c | 246 ++ gdtoa/gdtoa-strtord-fbsd.c | 69 + gdtoa/gdtoa-sum-fbsd.c | 98 + gdtoa/gdtoa-ulp-fbsd.c | 70 + gdtoa/gdtoa.h | 153 + gdtoa/gdtoa_strtopx-fbsd.c | 120 + gdtoa/gdtoaimp.h | 694 +++++ gdtoa/glue-fbsd.c | 10 + gdtoa/machdep_ldisdd-fbsd.c | 65 + gdtoa/machdep_ldisx-fbsd.c | 57 + gen/FreeBSD/_rand48.c.patch | 40 + gen/FreeBSD/alarm.3.patch | 13 + gen/FreeBSD/arc4random.3 | 107 + gen/{ => FreeBSD}/arc4random.c | 136 +- gen/FreeBSD/arc4random.c.patch | 11 + gen/FreeBSD/basename.3.patch | 44 + gen/FreeBSD/basename.c.patch | 18 + gen/FreeBSD/closedir.c.patch | 12 + gen/FreeBSD/ctermid.3.patch | 54 + gen/FreeBSD/daemon.3.patch | 11 + gen/FreeBSD/daemon.c.patch | 58 + gen/FreeBSD/dirname.3.patch | 42 + gen/FreeBSD/dirname.c.patch | 18 + gen/FreeBSD/drand48.c.patch | 16 + gen/FreeBSD/erand48.c.patch | 15 + gen/FreeBSD/err.c.patch | 94 +- gen/FreeBSD/exec.3.patch | 130 +- gen/FreeBSD/fmtmsg.c.patch | 101 + gen/FreeBSD/fnmatch.3.patch | 11 + gen/FreeBSD/fnmatch.c.patch | 282 +- gen/FreeBSD/fpclassify.3.patch | 18 - gen/FreeBSD/ftok.3.patch | 57 + gen/FreeBSD/getcontext.3 | 121 + gen/FreeBSD/getcwd.c.patch | 49 +- gen/FreeBSD/gethostname.3.patch | 11 + gen/FreeBSD/gethostname.c.patch | 33 + gen/FreeBSD/getlogin.c.patch | 32 +- gen/FreeBSD/getmntinfo.3.patch | 89 + gen/FreeBSD/getmntinfo64.c.patch | 37 + gen/FreeBSD/glob.3.patch | 42 + gen/FreeBSD/glob.c.patch | 194 +- gen/FreeBSD/isatty.c.patch | 14 +- gen/FreeBSD/isgreater.3.patch | 29 +- gen/FreeBSD/jrand48.c.patch | 12 + gen/FreeBSD/lcong48.c.patch | 23 + gen/FreeBSD/lockf.3.patch | 80 + gen/FreeBSD/lockf.c.patch | 51 + gen/FreeBSD/lrand48.c.patch | 16 + gen/FreeBSD/makecontext.3 | 120 + gen/FreeBSD/mrand48.c.patch | 16 + gen/FreeBSD/nice.c.patch | 39 + gen/FreeBSD/nrand48.c.patch | 12 + gen/FreeBSD/opendir.c.patch | 29 +- gen/FreeBSD/pause.c.patch | 28 + gen/FreeBSD/popen.3.patch | 96 + gen/FreeBSD/popen.c.patch | 45 +- gen/FreeBSD/pselect.3.patch | 46 +- gen/FreeBSD/pselect.c.patch | 18 +- gen/FreeBSD/rand48.3.patch | 109 + gen/FreeBSD/rand48.h.patch | 67 + gen/FreeBSD/readdir.c.patch | 27 + gen/FreeBSD/seed48.c.patch | 30 + gen/FreeBSD/setprogname.c.patch | 8 +- gen/FreeBSD/siginterrupt.3.patch | 13 + gen/FreeBSD/signal.3.patch | 59 +- gen/FreeBSD/signbit.3.patch | 18 +- gen/FreeBSD/sleep.c.patch | 14 + gen/FreeBSD/srand48.c.patch | 23 + gen/FreeBSD/sysconf.c.patch | 57 +- gen/FreeBSD/sysctl.3.patch | 30 +- gen/FreeBSD/telldir.c.patch | 44 +- gen/FreeBSD/telldir.h.patch | 35 +- gen/FreeBSD/termios.c.patch | 90 + gen/FreeBSD/time.c.patch | 26 + gen/FreeBSD/times.3.patch | 22 + gen/FreeBSD/ttyname.3.patch | 72 + gen/FreeBSD/ttyname.c.patch | 91 +- gen/FreeBSD/ualarm.3.patch | 47 + gen/FreeBSD/ucontext.3 | 107 + gen/FreeBSD/ulimit.3.patch | 40 + gen/FreeBSD/usleep.3.patch | 42 +- gen/FreeBSD/usleep.c.patch | 14 + gen/FreeBSD/utime.3.patch | 46 + gen/FreeBSD/wait.c.patch | 24 + gen/FreeBSD/waitpid.c.patch | 35 + gen/Makefile.inc | 443 ++- gen/NSSystemDirectories.c | 5 +- gen/NetBSD/endutxent.3.patch | 193 +- gen/NetBSD/getlastlogx.3 | 180 ++ gen/NetBSD/getlastlogx.3.patch | 149 + gen/NetBSD/utmpx.5.patch | 64 +- gen/NetBSD/utmpx.c.patch | 449 ++- gen/__dirent.h | 16 + gen/_rand48-fbsd.c | 21 + gen/_simple.c | 689 +++++ gen/_simple.h | 129 + gen/alarm-fbsd.c | 61 + gen/alarm.3 | 98 + gen/arc4random-fbsd.c | 235 ++ gen/arc4random.3 | 90 +- gen/asl.3 | 399 ++- gen/asl.c | 1974 ++++++++++--- gen/asl_ipc.defs | 45 + gen/asl_private.h | 48 + gen/asl_util.c | 294 ++ gen/assert-fbsd.c | 60 + gen/backtrace.3 | 106 + gen/backtrace.c | 141 + gen/basename-fbsd.c | 88 + gen/basename.3 | 120 + gen/cache.c | 29 +- gen/clock-fbsd.c | 59 + gen/clock.3 | 1 + gen/closedir-fbsd.c | 76 + gen/compat.5 | 95 +- gen/confstr.3 | 8 +- gen/confstr.c | 45 +- gen/crypt.3 | 123 +- gen/crypt.c | 12 + gen/ctermid-fbsd.c | 61 + gen/ctermid.3 | 112 + gen/daemon-fbsd.c | 127 + gen/daemon.3 | 118 + gen/devname.3 | 15 +- gen/directory.3 | 62 +- gen/dirname-fbsd.c | 91 + gen/dirname.3 | 125 + gen/drand48-fbsd.c | 25 + gen/endutxent.3 | 342 +++ gen/erand48-fbsd.c | 26 + gen/err-fbsd.c | 287 ++ gen/err.3 | 1 + gen/errlst.c | 1 + gen/errno_-fbsd.c | 30 + gen/exec-fbsd.c | 277 ++ gen/exec.3 | 330 +++ mach/externs.h => gen/execinfo.h | 19 +- gen/fmtcheck-fbsd.c | 267 ++ gen/fmtcheck.3 | 1 + gen/fmtmsg-fbsd.c | 271 ++ gen/fmtmsg.3 | 1 + gen/fnmatch-fbsd.c | 469 +++ gen/fnmatch.3 | 155 + gen/ftok-fbsd.c | 46 + gen/ftok.3 | 90 + gen/fts.c | 14 +- gen/ftw.3 | 23 +- gen/getbsize-fbsd.c | 109 + gen/getbsize.3 | 1 + gen/getcap-fbsd.c | 1061 +++++++ gen/getcap.3 | 1 + gen/getcontext.3 | 1 + gen/getcwd-fbsd.c | 338 +++ gen/getcwd.3 | 1 + gen/getfsent.3 | 153 - gen/getgrent.3 | 197 -- gen/gethostname-fbsd.c | 76 + gen/gethostname.3 | 135 + gen/getlastlogx.3 | 146 + gen/getlogin-fbsd.c | 105 + gen/getmntinfo-fbsd.c | 72 + gen/getmntinfo.3 | 140 + gen/getmntinfo64-fbsd.c | 72 + gen/getnetgrent.3 | 133 - gen/getobjformat.3 | 128 - gen/getpagesize-fbsd.c | 66 + gen/getpagesize.3 | 1 + gen/getpass.3 | 1 + gen/getpeereid-fbsd.c | 54 + gen/getpeereid.3 | 1 + gen/getprogname-fbsd.c | 19 + gen/getprogname.3 | 93 + gen/getpwent.3 | 242 -- gen/getttyent.3 | 21 - gen/getttyent.c | 163 +- gen/getvfsbyname.3 | 4 - gen/getvfsbyname.c | 2 +- gen/glob-fbsd.c | 1007 +++++++ gen/glob.3 | 487 ++++ gen/intro.3 | 99 +- gen/isatty-fbsd.c | 59 + gen/{FreeBSD/fpclassify.3 => isgreater.3} | 128 +- gen/jrand48-fbsd.c | 25 + gen/lcong48-fbsd.c | 25 + gen/lockf-fbsd.c | 107 + gen/lockf.3 | 277 ++ gen/lrand48-fbsd.c | 24 + gen/makecontext.3 | 1 + gen/malloc.3 | 140 +- gen/malloc.c | 449 ++- ppc/sys/getegid.s => gen/malloc_printf.h | 13 +- gen/malloc_size.3 | 55 + gen/mrand48-fbsd.c | 24 + gen/nanosleep.c | 186 +- gen/nftw.c | 6 +- gen/nice-fbsd.c | 69 + gen/nice.3 | 1 + gen/nlist.c | 3 +- gen/nrand48-fbsd.c | 25 + gen/opendir-fbsd.c | 284 ++ gen/pause-fbsd.c | 62 + gen/pause.3 | 1 + gen/popen-fbsd.c | 218 ++ gen/popen.3 | 205 ++ gen/pselect-fbsd.c | 88 + gen/pselect.3 | 127 + gen/psignal-fbsd.c | 67 + gen/psignal.3 | 1 + string/FreeBSD/ffs.c => gen/raise-fbsd.c | 24 +- gen/raise.3 | 1 + gen/rand48.3 | 201 ++ gen/rand48.h | 81 + gen/readdir-fbsd.c | 141 + gen/readpassphrase-fbsd.c | 181 ++ gen/readpassphrase.3 | 1 + gen/rewinddir-fbsd.c | 52 + gen/scalable_malloc.c | 2427 +++++++++------- gen/scalable_malloc.h | 4 +- gen/scandir-fbsd.c | 150 + gen/scandir.3 | 1 + gen/seed48-fbsd.c | 29 + gen/seekdir-fbsd.c | 63 + gen/sethostname-fbsd.c | 53 + gen/setjmp.3 | 67 +- gen/setlogin.c | 6 +- gen/setmode-fbsd.c | 459 +++ gen/setmode.3 | 1 + gen/setprogname-fbsd.c | 33 + gen/siginterrupt-fbsd.c | 67 + gen/siginterrupt.3 | 124 + gen/siglist-fbsd.c | 111 + gen/signal-fbsd.c | 95 + gen/signal.3 | 269 ++ gen/signbit.3 | 53 + gen/sigsetops.3 | 31 +- gen/sigsetops.c | 6 + gen/simple_dprintf.c | 321 -- gen/sleep-fbsd.c | 77 + gen/sleep.3 | 87 + gen/srand48-fbsd.c | 22 + gen/stack_logging.c | 83 +- gen/stack_logging.h | 54 +- gen/stack_logging_disk.c | 1674 +++++++++++ gen/stringlist-fbsd.c | 125 + gen/stringlist.3 | 1 + gen/strtofflags.3 | 10 +- gen/strtofflags.c | 1 + gen/sysconf-fbsd.c | 627 ++++ gen/sysconf.3 | 1 + gen/sysctl-fbsd.c | 187 ++ gen/sysctl.3 | 866 ++++++ gen/sysctlbyname-fbsd.c | 39 + gen/sysctlnametomib-fbsd.c | 55 + gen/syslog.3 | 57 +- gen/syslog.c | 308 +- gen/tcgetpgrp.3 | 19 +- gen/tcsendbreak.3 | 48 +- gen/tcsetattr.3 | 114 +- gen/tcsetpgrp.3 | 30 +- gen/telldir-fbsd.c | 174 ++ gen/telldir.h | 77 + gen/termios-fbsd.c | 264 ++ gen/thread_stack_pcs.c | 108 + gen/time-fbsd.c | 61 + gen/time.3 | 105 + gen/times-fbsd.c | 69 + gen/times.3 | 146 + gen/timezone-fbsd.c | 137 + gen/timezone.3 | 1 + gen/ttyname-fbsd.c | 200 ++ gen/ttyname.3 | 135 + gen/ttyslot-fbsd.c | 70 + gen/tzset.3 | 16 +- gen/ualarm-fbsd.c | 67 + gen/ualarm.3 | 104 + gen/ucontext.3 | 1 + gen/ulimit-fbsd.c | 68 + gen/ulimit.3 | 101 + gen/uname.c | 22 - gen/unvis-fbsd.c | 300 ++ gen/unvis.3 | 1 + gen/usleep-fbsd.c | 59 + gen/usleep.3 | 88 + gen/utime-fbsd.c | 59 + gen/utime.3 | 93 + gen/utmpx-darwin.c | 1172 ++++++++ gen/utmpx-darwin.h | 97 + gen/utmpx-nbsd.c | 440 +++ gen/utmpx.5 | 97 + gen/vis-fbsd.c | 209 ++ gen/vis.3 | 1 + gen/wait-fbsd.c | 64 + gen/wait3-fbsd.c | 54 + gen/waitpid-fbsd.c | 75 + gen/wordexp.3 | 26 +- gen/wordexp.c | 523 ++-- gen/zone.c | 68 +- gmon/Makefile.inc | 10 +- gmon/gmon.c | 231 +- gmon/moncontrol.3 | 101 + i386/gen/Makefile.inc | 17 +- i386/gen/_ctx_start.S | 76 + .../thread_act.h => i386/gen/_setcontext.S | 37 +- i386/gen/getcontext.S | 53 + i386/gen/getmcontext.c | 82 + i386/gen/icacheinval.s | 20 +- i386/gen/makecontext.c | 191 ++ mach/headers/task.h => i386/gen/setcontext.c | 31 +- i386/gen/setjmperr.c | 2 + i386/gen/swapcontext.c | 81 + i386/mach/Makefile.inc | 3 +- .../mach/mach_absolute_time.s | 15 +- i386/pthreads/Makefile.inc | 4 +- i386/pthreads/init_cpu_capabilities.c | 2 - i386/pthreads/start_wqthread.s | 42 + i386/pthreads/thread_start.s | 43 + i386/stdlib/gdtoa.mk | 2 +- i386/string/Makefile.inc | 3 + i386/string/bcopy.s | 1 - mach/headers/vm_task.h => i386/string/ffs.s | 35 +- i386/string/strlcat.s | 243 ++ i386/string/strlcpy.s | 167 ++ i386/sys/ATPgetreq.s | 29 - i386/sys/ATPgetrsp.s | 29 - i386/sys/ATPsndreq.s | 29 - i386/sys/ATPsndrsp.s | 29 - i386/sys/ATgetmsg.s | 29 - i386/sys/ATputmsg.s | 29 - i386/sys/ATsocket.s | 29 - i386/sys/Makefile.inc | 230 +- i386/sys/OSAtomic.s | 127 +- i386/sys/SYS.h | 36 +- i386/sys/__mmap.s | 26 - i386/sys/__pthread_canceled.s | 29 - i386/sys/__pthread_markcancel.s | 29 - i386/sys/__semwait_signal.s | 29 - i386/sys/_exit.s | 29 - i386/sys/_getlogin.s | 29 - i386/sys/_pthread_kill.s | 29 - i386/sys/_setjmp.s | 2 +- i386/sys/_setlogin.s | 30 - i386/sys/_sigtramp.s | 246 ++ i386/sys/_sysctl.s | 29 - i386/sys/access.s | 29 - i386/sys/acct.s | 29 - i386/sys/add_profil.s | 29 - i386/sys/adjtime.s | 29 - i386/sys/aio_cancel.s | 26 - i386/sys/aio_error.s | 26 - i386/sys/aio_fsync.s | 26 - i386/sys/aio_read.s | 26 - i386/sys/aio_return.s | 26 - i386/sys/aio_suspend.s | 26 - i386/sys/aio_write.s | 26 - i386/sys/audit.s | 26 - i386/sys/auditctl.s | 26 - i386/sys/auditon.s | 26 - i386/sys/auditsvc.s | 26 - i386/sys/chdir.s | 29 - i386/sys/checkuseraccess.s | 29 - i386/sys/chflags.s | 29 - i386/sys/chmod.s | 29 - i386/sys/chown.s | 29 - i386/sys/chroot.s | 29 - i386/sys/close.s | 29 - i386/sys/connect.s | 37 - i386/sys/dup.s | 29 - i386/sys/dup2.s | 29 - i386/sys/exchangedata.s | 29 - i386/sys/execve.s | 29 - i386/sys/fchdir.s | 29 - i386/sys/fchflags.s | 29 - i386/sys/fchmod.s | 29 - i386/sys/fchown.s | 29 - i386/sys/fcntl.s | 29 - i386/sys/fgetxattr.s | 26 - i386/sys/fhopen.s | 26 - i386/sys/flistxattr.s | 26 - i386/sys/flock.s | 29 - i386/sys/fork.s | 156 - i386/sys/fpathconf.s | 29 - i386/sys/fremovexattr.s | 26 - i386/sys/fsctl.s | 29 - i386/sys/fsetxattr.s | 26 - i386/sys/fstat.s | 29 - i386/sys/fstatfs.s | 29 - i386/sys/fstatv.s | 29 - i386/sys/fsync.s | 29 - i386/sys/ftruncate.s | 29 - i386/sys/futimes.s | 29 - i386/sys/getaudit.s | 26 - i386/sys/getaudit_addr.s | 26 - i386/sys/getauid.s | 26 - i386/sys/getdirentries.s | 29 - i386/sys/getdirentriesattr.s | 29 - i386/sys/getdtablesize.s | 27 - i386/sys/getegid.s | 29 - i386/sys/geteuid.s | 29 - i386/sys/getfh.s | 29 - i386/sys/getgid.s | 29 - i386/sys/getgroups.s | 29 - i386/sys/getitimer.s | 29 - i386/sys/getpeername.s | 37 - i386/sys/getpgid.s | 29 - i386/sys/getpgrp.s | 29 - i386/sys/getpid.s | 66 - i386/sys/getppid.s | 29 - i386/sys/getpriority.s | 29 - i386/sys/getrlimit.s | 29 - i386/sys/getrusage.s | 29 - i386/sys/getsid.s | 29 - i386/sys/getsockname.s | 37 - i386/sys/getsockopt.s | 29 - i386/sys/getuid.s | 29 - i386/sys/getxattr.s | 26 - i386/sys/i386_gettimeofday.s | 13 +- i386/sys/ioctl.s | 29 - i386/sys/issetugid.s | 29 - i386/sys/kevent.s | 26 - i386/sys/kill.s | 29 - i386/sys/kqueue.s | 26 - i386/sys/kqueue_from_portset_np.s | 26 - i386/sys/kqueue_portset_np.s | 26 - i386/sys/ktrace.s | 29 - i386/sys/lchown.s | 34 - i386/sys/libc.syscall.i386 | 82 + i386/sys/link.s | 29 - i386/sys/lio_listio.s | 26 - i386/sys/listen.s | 37 - i386/sys/listxattr.s | 26 - i386/sys/load_shared_file.s | 29 - i386/sys/lseek.s | 29 - i386/sys/lstat.s | 29 - i386/sys/lstatv.s | 29 - i386/sys/madvise.s | 29 - i386/sys/mincore.s | 29 - i386/sys/minherit.s | 29 - i386/sys/mkcomplex.s | 29 - i386/sys/mkdir.s | 29 - i386/sys/mkfifo.s | 29 - i386/sys/mknod.s | 29 - i386/sys/mlock.s | 29 - i386/sys/mlockall.s | 29 - i386/sys/mount.s | 29 - i386/sys/msgget.s | 29 - i386/sys/msgrcv.s | 29 - i386/sys/msgsnd.s | 29 - i386/sys/msgsys.s | 29 - i386/sys/munlock.s | 29 - i386/sys/munlockall.s | 29 - i386/sys/new_system_shared_regions.s | 29 - i386/sys/nfsclnt.s | 26 - i386/sys/nfssvc.s | 29 - i386/sys/open.s | 29 - i386/sys/pathconf.s | 29 - i386/sys/pipe.s | 33 - i386/sys/poll.s | 26 - i386/sys/posix_madvise.s | 28 - i386/sys/pread.s | 29 - i386/sys/profil.s | 29 - i386/sys/pthread_sigmask.s | 29 - i386/sys/ptrace.s | 34 - i386/sys/pwrite.s | 29 - i386/sys/quota.s | 31 - i386/sys/quotactl.s | 29 - i386/sys/read.s | 29 - i386/sys/readlink.s | 29 - i386/sys/readv.s | 29 - i386/sys/reboot.s | 29 - i386/sys/recvfrom.s | 37 - i386/sys/recvmsg.s | 37 - i386/sys/removexattr.s | 26 - i386/sys/rename.s | 29 - i386/sys/reset_shared_file.s | 29 - i386/sys/revoke.s | 29 - i386/sys/rmdir.s | 29 - i386/sys/s.template | 7 - i386/sys/searchfs.s | 29 - i386/sys/select.s | 29 - i386/sys/sem_close.s | 27 - i386/sys/sem_destroy.s | 27 - i386/sys/sem_getvalue.s | 27 - i386/sys/sem_init.s | 27 - i386/sys/sem_post.s | 27 - i386/sys/sem_trywait.s | 27 - i386/sys/semget.s | 29 - i386/sys/semop.s | 29 - i386/sys/semsys.s | 29 - i386/sys/sendmsg.s | 37 - i386/sys/sendto.s | 37 - i386/sys/setattrlist.s | 37 - i386/sys/setaudit.s | 26 - i386/sys/setaudit_addr.s | 26 - i386/sys/setauid.s | 26 - i386/sys/setegid.s | 29 - i386/sys/seteuid.s | 29 - i386/sys/setgid.s | 29 - i386/sys/setgroups.s | 29 - i386/sys/setitimer.s | 29 - i386/sys/setjmp.s | 29 +- i386/sys/setpgid.s | 29 - i386/sys/setpriority.s | 29 - i386/sys/setprivexec.s | 29 - i386/sys/setquota.s | 31 - i386/sys/setrlimit.s | 29 - i386/sys/setsid.s | 29 - i386/sys/setsockopt.s | 29 - i386/sys/settimeofday.s | 29 - i386/sys/setuid.s | 29 - i386/sys/setxattr.s | 26 - i386/sys/shmat.s | 29 - i386/sys/shmdt.s | 29 - i386/sys/shmget.s | 29 - i386/sys/shmsys.s | 29 - i386/sys/shutdown.s | 29 - i386/sys/sigaltstack.s | 29 - i386/sys/sigpending.s | 29 - i386/sys/sigprocmask.s | 29 - i386/sys/sigreturn.s | 29 - i386/sys/sigwait.s | 29 - i386/sys/socket.s | 29 - i386/sys/socketpair.s | 37 - i386/sys/stat.s | 29 - i386/sys/statfs.s | 29 - i386/sys/statv.s | 29 - i386/sys/swapon.s | 29 - i386/sys/symlink.s | 29 - i386/sys/sync.s | 29 - i386/sys/syscall.s | 38 - i386/sys/systable.s | 26 - i386/sys/truncate.s | 29 - i386/sys/umask.s | 29 - i386/sys/undelete.s | 29 - i386/sys/unlink.s | 29 - i386/sys/unmount.s | 29 - i386/sys/utimes.s | 29 - i386/sys/vfork.s | 73 - i386/sys/wait4.s | 29 - i386/sys/write.s | 29 - i386/sys/writev.s | 29 - include/Makefile.inc | 12 +- include/NSSystemDirectories.h | 1 + include/NetBSD/utmpx.h.patch | 129 +- include/_.libc_internal.h | 87 + mach/mach_vm.defs => include/_structs.h | 4 +- include/_wctype.h | 120 +- include/ar.h | 22 - include/arpa/ftp.h | 22 - include/arpa/telnet.h | 22 - include/arpa/tftp.h | 22 - include/asl.h | 26 +- include/assert.h | 6 +- include/bitstring.h | 22 - include/c.h | 83 - include/crt_externs.h | 7 +- include/ctype.h | 303 +- include/db.h | 22 - include/dirent.h | 100 +- include/disktab.h | 22 - include/fnmatch.h | 12 +- include/fsproperties.h | 3 + include/fstab.h | 22 - include/fts.h | 71 +- include/ftw.h | 22 +- include/getopt.h | 2 +- include/glob.h | 32 +- include/grp.h | 8 +- include/inttypes.h | 68 +- include/iso646.h | 6 +- include/langinfo.h | 3 +- include/libgen.h | 9 + include/libkern/Makefile.inc | 3 +- include/libkern/OSAtomic.h | 150 +- include/libkern/OSCacheControl.h | 65 + include/limits.h | 16 +- include/malloc/malloc.h | 3 + include/memory.h | 22 - include/mpool.h | 22 - include/ndbm.h | 19 +- include/nl_types.h | 2 +- include/nlist.h | 22 - include/objc/zone.h | 22 +- include/protocols/dumprestore.h | 28 +- include/protocols/routed.h | 22 - include/protocols/rwhod.h | 6 +- include/protocols/talkd.h | 23 +- include/protocols/timed.h | 11 +- include/pwd.h | 6 +- include/readpassphrase.h | 7 +- include/regex.h | 34 +- include/runetype.h | 18 +- include/secure/Makefile.inc | 5 + mach/vm_map.defs => include/secure/_common.h | 36 +- include/secure/_stdio.h | 73 + include/secure/_string.h | 138 + include/sgtty.h | 22 - include/signal.h | 96 +- include/spawn.h | 143 + include/stab.h | 22 - include/standards.h | 6 +- include/stddef.h | 4 +- include/stdio.h | 89 +- include/stdlib.h | 94 +- include/string.h | 45 +- include/strings.h | 10 +- include/struct.h | 22 - include/sys/acl.h | 2 +- include/sysexits.h | 22 - include/tar.h | 22 - include/time.h | 83 +- include/ttyent.h | 23 +- include/ucontext.h | 8 + include/unistd.h | 327 ++- include/util.h | 14 +- include/utmp.h | 23 +- include/utmpx.h | 181 ++ include/wchar.h | 25 +- include/wctype.h | 93 +- include/wordexp.h | 8 +- include/xlocale.h | 12 +- include/xlocale/Makefile.inc | 2 +- include/xlocale/__wctype.h | 109 +- include/xlocale/_ctype.h | 221 +- include/xlocale/_inttypes.h | 5 + include/xlocale/_stdlib.h | 9 +- include/xlocale/_time.h | 21 +- include/xlocale/_wchar.h | 18 +- include/xlocale/_wctype.h | 61 +- locale/FreeBSD/btowc.3.patch | 44 +- locale/FreeBSD/collate.c.patch | 904 +++++- locale/FreeBSD/collate.h.patch | 78 +- locale/FreeBSD/collcmp.c.patch | 20 +- locale/FreeBSD/digittoint.3.patch | 21 +- locale/FreeBSD/fix_grouping.c.patch | 27 + locale/FreeBSD/isalnum.3.patch | 35 +- locale/FreeBSD/isalpha.3.patch | 35 +- locale/FreeBSD/isblank.3.patch | 33 +- locale/FreeBSD/iscntrl.3.patch | 33 +- locale/FreeBSD/isdigit.3.patch | 34 +- locale/FreeBSD/isgraph.3.patch | 38 +- locale/FreeBSD/islower.3.patch | 16 +- locale/FreeBSD/isprint.3.patch | 39 +- locale/FreeBSD/ispunct.3.patch | 42 +- locale/FreeBSD/isspace.3.patch | 33 +- locale/FreeBSD/isupper.3.patch | 33 +- locale/FreeBSD/iswalnum.3.patch | 31 +- locale/FreeBSD/isxdigit.3.patch | 25 +- locale/FreeBSD/lmonetary.c.patch | 11 +- locale/FreeBSD/lnumeric.c.patch | 14 +- locale/FreeBSD/localeconv.3.patch | 21 +- locale/FreeBSD/mblen.3.patch | 70 +- locale/FreeBSD/mbrlen.3.patch | 47 +- locale/FreeBSD/mbrtowc.3.patch | 61 +- locale/FreeBSD/mbsinit.3.patch | 21 +- locale/FreeBSD/mbsrtowcs.3.patch | 70 +- locale/FreeBSD/mbstowcs.3.patch | 47 +- locale/FreeBSD/mbtowc.3.patch | 71 +- locale/FreeBSD/nl_langinfo.3.patch | 32 +- locale/FreeBSD/nl_langinfo.c.patch | 12 +- locale/FreeBSD/rune.c.patch | 76 +- locale/FreeBSD/setlocale.3.patch | 32 + locale/FreeBSD/setlocale.c.patch | 58 +- locale/FreeBSD/setrunelocale.c.patch | 21 +- locale/FreeBSD/table.c.patch | 11 +- locale/FreeBSD/tolower.3.patch | 38 +- locale/FreeBSD/toupper.3.patch | 38 +- locale/FreeBSD/towlower.3.patch | 26 +- locale/FreeBSD/towupper.3.patch | 26 +- locale/FreeBSD/wcrtomb.3.patch | 50 +- locale/FreeBSD/wcsftime.3.patch | 40 +- locale/FreeBSD/wcsrtombs.3.patch | 93 +- locale/FreeBSD/wcstod.3.patch | 62 +- locale/FreeBSD/wcstod.c.patch | 82 +- locale/FreeBSD/wcstof.c.patch | 64 +- locale/FreeBSD/wcstol.3.patch | 119 +- locale/FreeBSD/wcstold.c.patch | 64 +- locale/FreeBSD/wcstombs.3.patch | 56 +- locale/FreeBSD/wctomb.3.patch | 69 +- locale/FreeBSD/wctrans.3.patch | 55 +- locale/FreeBSD/wctype.3.patch | 60 +- locale/FreeBSD/wctype.c.patch | 69 +- locale/FreeBSD/wcwidth.3.patch | 34 +- locale/Makefile.inc | 241 +- locale/big5-fbsd.c | 172 ++ locale/big5.5 | 1 + locale/btowc-fbsd.c | 62 + locale/btowc.3 | 117 + locale/collate-fbsd.c | 954 ++++++ locale/collate.h | 121 + locale/collcmp-fbsd.c | 48 + locale/ctype.3 | 162 ++ locale/ctype_l.3 | 152 +- locale/digittoint.3 | 82 + locale/duplocale.3 | 4 +- locale/euc-fbsd.c | 277 ++ locale/euc.5 | 1 + locale/fix_grouping-fbsd.c | 98 + locale/freelocale.3 | 4 +- locale/gb18030-fbsd.c | 221 ++ locale/gb18030.5 | 1 + locale/gb2312-fbsd.c | 157 + locale/gb2312.5 | 1 + locale/gbk-fbsd.c | 169 ++ locale/gbk.5 | 1 + locale/isalnum.3 | 113 + locale/isalnum_l.3 | 125 +- locale/isalpha.3 | 111 + locale/isascii.3 | 1 + gen/getgrouplist.3 => locale/isblank.3 | 99 +- locale/iscntrl.3 | 101 + sys/other_libc_init.c => locale/isctype.c | 14 +- locale/isctype_l.c | 239 -- locale/isdigit.3 | 112 + locale/isgraph.3 | 116 + locale/isideogram.3 | 58 + locale/islower.3 | 101 + locale/isphonogram.3 | 58 + locale/isprint.3 | 114 + locale/ispunct.3 | 106 + locale/isrune.3 | 64 + locale/isspace.3 | 98 + locale/isspecial.3 | 57 + locale/isupper.3 | 101 + locale/iswalnum.3 | 169 ++ .../__sysenter_trap.s => locale/iswctype.c | 15 +- locale/iswctype_l.c | 227 -- locale/isxdigit.3 | 113 + locale/ldpart-fbsd.c | 160 + locale/ldpart.h | 39 + locale/lmessages-fbsd.c | 123 + locale/lmessages.h | 44 + locale/lmonetary-fbsd.c | 230 ++ locale/lmonetary.h | 61 + locale/lnumeric-fbsd.c | 129 + locale/lnumeric.h | 43 + locale/localeconv-fbsd.c | 200 ++ locale/localeconv.3 | 243 ++ locale/mblen-fbsd.c | 58 + locale/mblen.3 | 131 + locale/mblocal.h | 50 + locale/mbrlen-fbsd.c | 49 + locale/mbrlen.3 | 168 ++ locale/mbrtowc-fbsd.c | 50 + locale/mbrtowc.3 | 161 ++ locale/mbsinit-fbsd.c | 47 + locale/mbsinit.3 | 81 + locale/mbsnrtowcs-fbsd.c | 102 + locale/mbsrtowcs-fbsd.c | 53 + locale/mbsrtowcs.3 | 174 ++ locale/mbstowcs-fbsd.c | 53 + locale/mbstowcs.3 | 111 + locale/mbtowc-fbsd.c | 59 + locale/mbtowc.3 | 138 + locale/mskanji-fbsd.c | 158 + locale/mskanji.5 | 1 + locale/multibyte.3 | 1 + locale/newlocale.3 | 4 +- locale/nextwctype-fbsd.c | 100 + locale/nextwctype.3 | 73 + locale/nl_langinfo-fbsd.c | 188 ++ locale/nl_langinfo.3 | 109 + locale/nomacros-fbsd.c | 12 + locale/none-fbsd.c | 180 ++ locale/querylocale.3 | 4 +- locale/rune-fbsd.c | 363 +++ locale/rune32.h | 15 + locale/runetype-fbsd.c | 82 + locale/setlocale-fbsd.c | 357 +++ locale/setlocale.3 | 181 ++ locale/setlocale.h | 42 + locale/setrunelocale-fbsd.c | 204 ++ locale/table-fbsd.c | 473 +++ locale/toascii.3 | 1 + locale/tolower-fbsd.c | 86 + locale/tolower.3 | 108 + locale/toupper-fbsd.c | 86 + locale/toupper.3 | 108 + locale/towlower.3 | 89 + locale/towupper.3 | 89 + locale/uselocale.3 | 4 +- locale/utf2-fbsd.c | 402 +++ locale/utf8-fbsd.c | 422 +++ locale/utf8.5 | 1 + locale/wcrtomb-fbsd.c | 49 + locale/wcrtomb.3 | 128 + locale/wcsftime-fbsd.c | 116 + locale/wcsftime.3 | 88 + locale/wcsnrtombs-fbsd.c | 122 + locale/wcsrtombs-fbsd.c | 53 + locale/wcsrtombs.3 | 175 ++ locale/wcstod-fbsd.c | 104 + locale/wcstod.3 | 90 + locale/wcstof-fbsd.c | 90 + locale/wcstoimax-fbsd.c | 138 + locale/wcstol-fbsd.c | 131 + locale/wcstol.3 | 141 + locale/wcstol_l.3 | 48 +- locale/wcstold-fbsd.c | 90 + locale/wcstoll-fbsd.c | 137 + locale/wcstombs-fbsd.c | 53 + locale/wcstombs.3 | 115 + locale/wcstoul-fbsd.c | 129 + locale/wcstoull-fbsd.c | 136 + locale/wcstoumax-fbsd.c | 136 + locale/wctob-fbsd.c | 54 + locale/wctomb-fbsd.c | 57 + locale/wctomb.3 | 132 + locale/wctrans-fbsd.c | 100 + locale/wctrans.3 | 156 + locale/wctype-fbsd.c | 89 + locale/wctype.3 | 152 + locale/{FreeBSD/iswctype.c => wcwidth-fbsd.c} | 168 +- locale/wcwidth.3 | 106 + locale/xlocale.3 | 41 +- locale/xlocale.c | 80 +- locale/xlocale_private.h | 18 +- mach/Makefile.inc | 75 - mach/bootstrap_ports.c | 67 - mach/brk.2 | 150 - mach/clock.defs | 23 - mach/clock_priv.defs | 23 - mach/clock_reply.defs | 23 - mach/clock_sleep.c | 33 - mach/err_ipc.sub | 99 - mach/err_kern.sub | 182 -- mach/err_mach_ipc.sub | 119 - mach/err_server.sub | 357 --- mach/err_us.sub | 45 - mach/error_codes.c | 101 - mach/errorlib.h | 95 - mach/exc.defs | 24 - mach/exc_catcher.c | 62 - mach/exc_catcher_state.c | 64 - mach/exc_catcher_state_identity.c | 66 - mach/fprintf_stderr.c | 57 - mach/headers/Makefile.inc | 10 - mach/headers/errorlib.h | 96 - mach/headers/mach.h | 128 - mach/headers/mach_error.h | 88 - mach/headers/mach_init.h | 118 - mach/headers/mach_interface.h | 49 - mach/headers/port_obj.h | 98 - mach/headers/sync.h | 30 - mach/host_priv.defs | 23 - mach/host_security.defs | 23 - mach/ledger.defs | 23 - mach/lock_set.defs | 23 - mach/mach_error.c | 82 - mach/mach_error_string.c | 135 - mach/mach_host.defs | 23 - mach/mach_init.c | 265 -- mach/mach_init_ports.c | 135 - mach/mach_msg.c | 614 ---- mach/mach_port.defs | 23 - mach/mach_traps.s | 49 - mach/mig_allocate.c | 63 - mach/mig_deallocate.c | 60 - mach/mig_reply_setup.c | 76 - mach/mig_strncpy.c | 86 - mach/ms_thread_switch.c | 71 - mach/notify.defs | 23 - mach/panic.c | 83 - mach/processor.defs | 23 - mach/processor_set.defs | 23 - mach/sbrk.c | 73 - mach/semaphore.c | 81 - mach/servers/Makefile.inc | 16 - mach/servers/bootstrap_defs.h | 61 - mach/servers/key_defs.h | 103 - mach/servers/ls_defs.h | 233 -- mach/servers/netname.defs | 71 - mach/servers/netname_defs.h | 66 - mach/servers/nm_defs.h | 79 - mach/servers/srvbootstrap.defs | 359 --- mach/slot_name.c | 83 - mach/task.defs | 23 - mach/thread_act.defs | 23 - makeCombos | 4 +- make_libldbl128 | 30 - man/Makefile.inc | 20 + man/assert.3 | 96 + man/bitstring.3 | 181 ++ man/environ.7 | 215 ++ man/stdarg.3 | 207 ++ net/FreeBSD/inet.3.patch | 127 + net/FreeBSD/recv.c.patch | 25 + net/FreeBSD/send.c.patch | 25 + net/FreeBSD/sockatmark.3 | 123 + net/FreeBSD/sockatmark.3.patch | 11 + net/FreeBSD/sockatmark.c | 36 + net/Makefile.inc | 75 +- net/addr2ascii-fbsd.c | 95 + net/addr2ascii.3 | 1 + net/ascii2addr-fbsd.c | 75 + net/byteorder.3 | 1 + net/hesiod.3 | 159 - net/inet.3 | 328 +++ net/inet_addr-fbsd.c | 203 ++ net/inet_lnaof-fbsd.c | 68 + net/inet_makeaddr-fbsd.c | 71 + net/inet_net.3 | 1 + net/inet_net_ntop-fbsd.c | 148 + net/inet_net_pton-fbsd.c | 217 ++ net/inet_neta-fbsd.c | 92 + net/inet_netof-fbsd.c | 67 + net/inet_network-fbsd.c | 103 + net/inet_ntoa-fbsd.c | 67 + net/linkaddr-fbsd.c | 160 + net/linkaddr.3 | 1 + net/nsap_addr-fbsd.c | 122 + net/recv-fbsd.c | 64 + net/resolver.3 | 422 --- net/send-fbsd.c | 64 + net/sockatmark-fbsd.c | 36 + net/sockatmark.3 | 123 + nls/FreeBSD/msgcat.c.patch | 89 +- nls/FreeBSD/msgcat.h.patch | 88 + nls/Makefile.inc | 2 +- nls/catclose.3 | 1 + nls/catgets.3 | 1 + nls/catopen.3 | 1 + nls/msgcat-fbsd.c | 504 ++++ nls/msgcat.h | 161 ++ patchHeaders | 112 + posix1e/Makefile.inc | 32 +- posix1e/acl.3 | 6 +- posix1e/acl_clear_flags_np.3 | 2 +- posix1e/acl_delete_flag_np.3 | 2 +- posix1e/acl_file.c | 8 + posix1e/acl_get_entry.3 | 25 +- posix1e/acl_get_flagset_np.3 | 8 +- posix1e/acl_set_flagset_np.3 | 20 +- posix1e/acl_translate.c | 198 +- ppc/gen/Makefile.inc | 15 +- ppc/gen/_ctx_start.S | 62 + ppc/gen/_setcontext.S | 76 + ppc/{sys/getdtablesize.s => gen/getcontext.S} | 39 +- ppc/gen/getmcontext.c | 82 + ppc/gen/icacheinval.s | 17 +- ppc/gen/makecontext.c | 160 + sys/accessx_np.c => ppc/gen/setcontext.c | 20 +- ppc/gen/swapcontext.c | 81 + ppc/pthreads/init_cpu_capabilities.c | 2 - ppc/stdlib/gdtoa.mk | 5 +- ppc/string/Makefile.inc | 4 + ppc/{gen => string}/ffs.s | 0 ppc/{sys/connect.s => string/ffsl.s} | 42 +- i386/sys/commpage.c => ppc/string/fls.s | 7 + ppc/{sys/bind.s => string/flsl.s} | 18 +- ppc/string/memset.s | 59 +- ppc/sys/ATPgetreq.s | 26 - ppc/sys/ATPgetrsp.s | 26 - ppc/sys/ATPsndreq.s | 26 - ppc/sys/ATPsndrsp.s | 26 - ppc/sys/ATgetmsg.s | 26 - ppc/sys/ATputmsg.s | 26 - ppc/sys/ATsocket.s | 26 - ppc/sys/Makefile.inc | 228 +- ppc/sys/OSAtomic.s | 168 +- ppc/sys/SYS.h | 19 +- ppc/sys/__mmap.s | 26 - ppc/sys/__pthread_canceled.s | 27 - ppc/sys/__semwait_signal.s | 26 - ppc/sys/_exit.s | 26 - ppc/sys/_getlogin.s | 27 - ppc/sys/_pthread_kill.s | 26 - ppc/sys/_setjmp.h | 6 +- ppc/sys/_setlogin.s | 26 - ppc/sys/_sigtramp.s | 529 ++++ ppc/sys/_sysctl.s | 26 - ppc/sys/accept.s | 33 - ppc/sys/access.s | 26 - ppc/sys/acct.s | 26 - ppc/sys/add_profil.s | 25 - ppc/sys/adjtime.s | 26 - ppc/sys/aio_cancel.s | 26 - ppc/sys/aio_error.s | 26 - ppc/sys/aio_fsync.s | 26 - ppc/sys/aio_read.s | 26 - ppc/sys/aio_return.s | 26 - ppc/sys/aio_suspend.s | 26 - ppc/sys/aio_write.s | 26 - ppc/sys/assym.h | 156 - ppc/sys/assymdefs.c | 129 - ppc/sys/audit.s | 26 - ppc/sys/auditctl.s | 26 - ppc/sys/auditon.s | 26 - ppc/sys/auditsvc.s | 26 - ppc/sys/cerror.s | 62 - ppc/sys/chdir.s | 26 - ppc/sys/checkuseraccess.s | 27 - ppc/sys/chflags.s | 25 - ppc/sys/chmod.s | 26 - ppc/sys/chown.s | 26 - ppc/sys/chroot.s | 26 - ppc/sys/close.s | 26 - ppc/sys/dup.s | 26 - ppc/sys/dup2.s | 26 - ppc/sys/exchangedata.s | 27 - ppc/sys/execve.s | 26 - ppc/sys/fchdir.s | 26 - ppc/sys/fchflags.s | 25 - ppc/sys/fchmod.s | 26 - ppc/sys/fchown.s | 26 - ppc/sys/fcntl.s | 26 - ppc/sys/fgetxattr.s | 26 - ppc/sys/fhopen.s | 26 - ppc/sys/flistxattr.s | 26 - ppc/sys/flock.s | 26 - ppc/sys/fork.s | 191 -- ppc/sys/fpathconf.s | 26 - ppc/sys/fremovexattr.s | 26 - ppc/sys/fsctl.s | 26 - ppc/sys/fsetxattr.s | 26 - ppc/sys/fstat.s | 26 - ppc/sys/fstatfs.s | 26 - ppc/sys/fstatv.s | 27 - ppc/sys/fsync.s | 26 - ppc/sys/ftruncate.s | 26 - ppc/sys/futimes.s | 26 - ppc/sys/genassym.c | 206 -- ppc/sys/genassym.h | 127 - ppc/sys/getaudit.s | 26 - ppc/sys/getaudit_addr.s | 26 - ppc/sys/getauid.s | 26 - ppc/sys/getdirentries.s | 26 - ppc/sys/getdirentriesattr.s | 27 - ppc/sys/geteuid.s | 29 - ppc/sys/getfh.s | 26 - ppc/sys/getfsstat.s | 26 - ppc/sys/getgid.s | 26 - ppc/sys/getgroups.s | 26 - ppc/sys/getitimer.s | 26 - ppc/sys/getpeername.s | 33 - ppc/sys/getpgid.s | 26 - ppc/sys/getpgrp.s | 26 - ppc/sys/getpid.s | 59 - ppc/sys/getpriority.s | 26 - ppc/sys/getrlimit.s | 26 - ppc/sys/getrusage.s | 26 - ppc/sys/getsid.s | 26 - ppc/sys/getsockname.s | 33 - ppc/sys/getsockopt.s | 26 - ppc/sys/getuid.s | 26 - ppc/sys/getxattr.s | 26 - ppc/sys/ioctl.s | 26 - ppc/sys/issetugid.s | 26 - ppc/sys/kevent.s | 26 - ppc/sys/kill.s | 26 - ppc/sys/kqueue.s | 26 - ppc/sys/kqueue_from_portset_np.s | 27 - ppc/sys/kqueue_portset_np.s | 26 - ppc/sys/ktrace.s | 25 - ppc/sys/lchown.s | 32 - ppc/sys/libc.syscall.ppc | 82 + ppc/sys/link.s | 26 - ppc/sys/lio_listio.s | 26 - ppc/sys/listen.s | 33 - ppc/sys/listxattr.s | 26 - ppc/sys/load_shared_file.s | 26 - ppc/sys/longjmp.s | 19 +- ppc/sys/lseek.s | 26 - ppc/sys/lstat.s | 26 - ppc/sys/lstatv.s | 27 - ppc/sys/madvise.s | 28 - ppc/sys/mincore.s | 27 - ppc/sys/minherit.s | 26 - ppc/sys/mkcomplex.s | 27 - ppc/sys/mkdir.s | 26 - ppc/sys/mkfifo.s | 25 - ppc/sys/mknod.s | 26 - ppc/sys/mlock.s | 26 - ppc/sys/mlockall.s | 26 - ppc/sys/mount.s | 27 - ppc/sys/msgget.s | 26 - ppc/sys/msgrcv.s | 26 - ppc/sys/msgsnd.s | 26 - ppc/sys/msgsys.s | 26 - ppc/sys/munlock.s | 26 - ppc/sys/munlockall.s | 26 - ppc/sys/new_system_shared_regions.s | 26 - ppc/sys/nfsclnt.s | 26 - ppc/sys/nfssvc.s | 26 - ppc/sys/oldldbl64.s | 74 - ppc/sys/open.s | 26 - ppc/sys/pathconf.s | 25 - ppc/sys/pipe.s | 33 - ppc/sys/poll.s | 26 - ppc/sys/posix_madvise.s | 28 - ppc/sys/ppc_gettimeofday.s | 16 +- ppc/sys/pread.s | 26 - ppc/sys/processor_facilities.h | 31 - ppc/sys/processor_facilities.s | 27 - ppc/sys/profil.s | 26 - ppc/sys/pthread_sigmask.s | 26 - ppc/sys/ptrace.s | 32 - ppc/sys/pwrite.s | 26 - ppc/sys/quota.s | 28 - ppc/sys/quotactl.s | 26 - ppc/sys/read.s | 26 - ppc/sys/readlink.s | 26 - ppc/sys/readv.s | 26 - ppc/sys/reboot.s | 28 - ppc/sys/recvfrom.s | 33 - ppc/sys/recvmsg.s | 33 - ppc/sys/removexattr.s | 26 - ppc/sys/rename.s | 26 - ppc/sys/reset_shared_file.s | 26 - ppc/sys/revoke.s | 26 - ppc/sys/rmdir.s | 26 - ppc/sys/s.template | 6 - ppc/sys/searchfs.s | 27 - ppc/sys/select.s | 26 - ppc/sys/sem_close.s | 26 - ppc/sys/sem_destroy.s | 26 - ppc/sys/sem_getvalue.s | 26 - ppc/sys/sem_init.s | 26 - ppc/sys/sem_post.s | 26 - ppc/sys/sem_trywait.s | 26 - ppc/sys/sem_wait.s | 26 - ppc/sys/semget.s | 26 - ppc/sys/semop.s | 26 - ppc/sys/semsys.s | 26 - ppc/sys/sendmsg.s | 33 - ppc/sys/sendto.s | 33 - ppc/sys/setattrlist.s | 34 - ppc/sys/setaudit.s | 26 - ppc/sys/setaudit_addr.s | 26 - ppc/sys/setauid.s | 26 - ppc/sys/setegid.s | 26 - ppc/sys/seteuid.s | 26 - ppc/sys/setgid.s | 25 - ppc/sys/setgroups.s | 26 - ppc/sys/setitimer.s | 26 - ppc/sys/setjmp.s | 23 +- ppc/sys/setpgid.s | 26 - ppc/sys/setpriority.s | 26 - ppc/sys/setprivexec.s | 26 - ppc/sys/setquota.s | 27 - ppc/sys/setrlimit.s | 26 - ppc/sys/setsid.s | 26 - ppc/sys/setsockopt.s | 26 - ppc/sys/settimeofday.s | 26 - ppc/sys/setuid.s | 25 - ppc/sys/setxattr.s | 26 - ppc/sys/shmat.s | 26 - ppc/sys/shmdt.s | 26 - ppc/sys/shmget.s | 26 - ppc/sys/shmsys.s | 26 - ppc/sys/shutdown.s | 26 - ppc/sys/sigaltstack.s | 25 - ppc/sys/sigpending.s | 25 - ppc/sys/sigprocmask.s | 26 - ppc/sys/sigreturn.s | 53 - ppc/sys/sigwait.s | 26 - ppc/sys/socket.s | 26 - ppc/sys/socketpair.s | 33 - ppc/sys/stat.s | 26 - ppc/sys/statfs.s | 26 - ppc/sys/statv.s | 27 - ppc/sys/swapon.s | 26 - ppc/sys/symlink.s | 26 - ppc/sys/sync.s | 26 - ppc/sys/syscall.s | 28 - ppc/sys/systable.s | 25 - ppc/sys/truncate.s | 26 - ppc/sys/umask.s | 26 - ppc/sys/undelete.s | 25 - ppc/sys/unlink.s | 26 - ppc/sys/unmount.s | 26 - ppc/sys/utimes.s | 26 - ppc/sys/vfork.s | 80 - ppc/sys/wait4.s | 26 - ppc/sys/write.s | 26 - ppc/sys/writev.s | 26 - ppc64/gen/Makefile.inc | 1 - ppc64/stdlib/gdtoa.mk | 5 +- ppc64/string/Makefile.inc | 4 + ppc64/sys/Makefile.inc | 236 +- ppc64/sys/__fcntl.s | 26 - ppc64/sys/__ioctl.s | 26 - ppc64/sys/libc.syscall.ppc64 | 25 + pthreads/Makefile.inc | 113 +- pthreads/lock.s | 169 -- pthreads/plockstat.d | 23 + pthreads/pthread.3 | 13 +- pthreads/pthread.c | 2569 ++++++++++++++--- pthreads/pthread.h | 436 +-- pthreads/pthread_atfork.3 | 4 +- pthreads/pthread_attr.3 | 116 +- pthreads/pthread_cancelable.c | 294 ++ pthreads/pthread_cleanup_pop.3 | 7 +- pthreads/pthread_cleanup_push.3 | 9 +- pthreads/pthread_cond.c | 309 +- pthreads/pthread_cond_broadcast.3 | 5 +- pthreads/pthread_cond_destroy.3 | 11 +- pthreads/pthread_cond_init.3 | 17 +- pthreads/pthread_cond_signal.3 | 4 +- pthreads/pthread_cond_timedwait.3 | 10 +- pthreads/pthread_cond_wait.3 | 8 +- pthreads/pthread_condattr.3 | 26 +- pthreads/pthread_create.3 | 22 +- pthreads/pthread_detach.3 | 8 +- pthreads/pthread_equal.3 | 7 +- pthreads/pthread_exit.3 | 4 +- pthreads/pthread_getschedparam.3 | 36 +- pthreads/pthread_getspecific.3 | 18 +- pthreads/pthread_impl.h | 1 + pthreads/pthread_internals.h | 180 +- pthreads/pthread_join.3 | 23 +- pthreads/pthread_key_create.3 | 13 +- pthreads/pthread_key_delete.3 | 8 +- pthreads/pthread_machdep.h | 88 +- pthreads/pthread_mutex.c | 270 +- pthreads/pthread_mutex_destroy.3 | 14 +- pthreads/pthread_mutex_init.3 | 15 +- pthreads/pthread_mutex_lock.3 | 14 +- pthreads/pthread_mutex_trylock.3 | 14 +- pthreads/pthread_mutex_unlock.3 | 10 +- pthreads/pthread_mutexattr.3 | 81 +- pthreads/pthread_once.3 | 5 +- pthreads/pthread_rwlock.c | 303 +- pthreads/pthread_rwlock_destroy.3 | 12 +- pthreads/pthread_rwlock_init.3 | 15 +- pthreads/pthread_rwlock_rdlock.3 | 26 +- pthreads/pthread_rwlock_unlock.3 | 12 +- pthreads/pthread_rwlock_wrlock.3 | 20 +- pthreads/pthread_rwlockattr_destroy.3 | 10 +- pthreads/pthread_rwlockattr_getpshared.3 | 15 +- pthreads/pthread_rwlockattr_init.3 | 14 +- pthreads/pthread_rwlockattr_setpshared.3 | 15 +- pthreads/pthread_setcancelstate.3 | 16 +- pthreads/pthread_setspecific.3 | 24 +- pthreads/pthread_tsd.c | 86 +- pthreads/pthread_workqueue.h | 74 + pthreads/sched.h | 2 +- quad/Makefile.inc | 19 - regex/FreeBSD/engine.c.patch | 56 +- regex/FreeBSD/regcomp.c.patch | 193 +- regex/FreeBSD/regex.3.patch | 67 + regex/FreeBSD/regex2.h.patch | 32 +- regex/FreeBSD/regfree.c.patch | 10 + regex/Makefile.inc | 13 +- regex/cclass.h | 63 + regex/cname.h | 142 + regex/engine.c | 1204 ++++++++ regex/re_format.7 | 1 + regex/regcomp-fbsd.c | 1946 +++++++++++++ regex/regerror-fbsd.c | 181 ++ regex/regex.3 | 737 +++++ regex/regex2.h | 212 ++ regex/regexec-fbsd.c | 251 ++ regex/regfree-fbsd.c | 95 + regex/utils.h | 58 + rpc/Makefile.inc | 230 +- secure/Makefile.inc | 20 + sys/getwgroups_np.c => secure/chk_fail.c | 27 +- secure/memcpy_chk.c | 36 + secure/memmove_chk.c | 36 + sys/getsgroups_np.c => secure/memset_chk.c | 24 +- secure/snprintf_chk.c | 51 + secure/sprintf_chk.c | 54 + secure/stpcpy_chk.c | 38 + i386/sys/cerror.s => secure/strcat_chk.c | 60 +- secure/strcpy_chk.c | 38 + secure/strncat_chk.c | 59 + secure/strncpy_chk.c | 37 + .../sys/getfsstat.s => secure/vsnprintf_chk.c | 37 +- secure/vsprintf_chk.c | 50 + stdio/FreeBSD/fclose.c.patch | 18 + stdio/FreeBSD/fflush.c.patch | 25 + stdio/FreeBSD/fgets.3.patch | 46 +- stdio/FreeBSD/fgetws.3.patch | 55 +- stdio/FreeBSD/flags.c.patch | 21 + stdio/FreeBSD/flockfile.3.patch | 74 + stdio/FreeBSD/fopen.3.patch | 89 + stdio/FreeBSD/fputs.3.patch | 53 +- stdio/FreeBSD/fputs.c.patch | 23 +- stdio/FreeBSD/fputws.3.patch | 39 +- stdio/FreeBSD/fread.3.patch | 49 + stdio/FreeBSD/freopen.c.patch | 22 +- stdio/FreeBSD/fseek.3.patch | 83 + stdio/FreeBSD/ftell.c.patch | 14 +- stdio/FreeBSD/fwide.3.patch | 18 + stdio/FreeBSD/getc.3.patch | 20 + stdio/FreeBSD/getwc.3.patch | 27 +- stdio/FreeBSD/makebuf.c.patch | 33 + stdio/FreeBSD/mktemp.3.patch | 80 + stdio/FreeBSD/perror.c.patch | 10 + stdio/FreeBSD/printf.3.patch | 162 +- stdio/FreeBSD/putc.3.patch | 56 + stdio/FreeBSD/putwc.3.patch | 37 +- stdio/FreeBSD/remove.3.patch | 11 + stdio/FreeBSD/scanf.3.patch | 163 +- stdio/FreeBSD/setbuf.3.patch | 79 + stdio/FreeBSD/stdio.3.patch | 108 + stdio/FreeBSD/tempnam.c.patch | 78 + stdio/FreeBSD/tmpnam.3.patch | 82 +- stdio/FreeBSD/ungetc.3.patch | 43 + stdio/FreeBSD/ungetwc.3.patch | 52 +- stdio/FreeBSD/vfprintf.c.patch | 144 +- stdio/FreeBSD/vfscanf.c.patch | 113 +- stdio/FreeBSD/vfwprintf.c.patch | 152 +- stdio/FreeBSD/vfwscanf.c.patch | 67 +- stdio/FreeBSD/wprintf.3.patch | 154 +- stdio/FreeBSD/wscanf.3.patch | 130 +- stdio/Makefile.inc | 187 +- stdio/_flock_stub-fbsd.c | 149 + stdio/asprintf-fbsd.c | 107 + stdio/clrerr-fbsd.c | 56 + stdio/fclose-fbsd.c | 79 + stdio/fclose.3 | 1 + stdio/fdopen-fbsd.c | 93 + stdio/feof-fbsd.c | 59 + stdio/ferror-fbsd.c | 59 + stdio/ferror.3 | 1 + stdio/fflush-fbsd.c | 154 + stdio/fflush.3 | 1 + stdio/fgetc-fbsd.c | 60 + stdio/fgetln-fbsd.c | 168 ++ stdio/fgetln.3 | 1 + stdio/fgetpos-fbsd.c | 55 + stdio/fgets-fbsd.c | 116 + stdio/fgets.3 | 161 ++ stdio/fgetwc-fbsd.c | 114 + stdio/fgetws-fbsd.c | 113 + stdio/fgetws.3 | 150 + stdio/fileno-fbsd.c | 60 + stdio/findfp-fbsd.c | 252 ++ stdio/flags-fbsd.c | 101 + stdio/floatio.h | 58 + stdio/flockfile.3 | 105 + stdio/fopen-fbsd.c | 88 + stdio/fopen.3 | 308 ++ stdio/fprintf-fbsd.c | 71 + stdio/fpurge-fbsd.c | 74 + stdio/fputc-fbsd.c | 61 + stdio/fputs-fbsd.c | 82 + stdio/fputs.3 | 134 + stdio/fputwc-fbsd.c | 104 + stdio/fputws-fbsd.c | 83 + stdio/fputws.3 | 114 + stdio/fread-fbsd.c | 91 + stdio/fread.3 | 111 + stdio/freopen-fbsd.c | 230 ++ stdio/fscanf-fbsd.c | 79 + stdio/fseek-fbsd.c | 314 ++ stdio/fseek.3 | 308 ++ stdio/fsetpos-fbsd.c | 55 + stdio/ftell-fbsd.c | 145 + stdio/funopen-fbsd.c | 80 + stdio/funopen.3 | 1 + stdio/fvwrite-fbsd.c | 211 ++ stdio/fvwrite.h | 53 + stdio/fwalk-fbsd.c | 71 + stdio/fwide-fbsd.c | 51 + stdio/fwide.3 | 99 + stdio/fwprintf-fbsd.c | 61 + stdio/fwrite-fbsd.c | 85 + stdio/fwscanf-fbsd.c | 61 + stdio/getc-fbsd.c | 61 + stdio/getc.3 | 174 ++ stdio/getchar-fbsd.c | 64 + stdio/gets-fbsd.c | 81 + stdio/getw-fbsd.c | 52 + stdio/getwc-fbsd.c | 58 + stdio/getwc.3 | 125 + stdio/getwchar-fbsd.c | 57 + stdio/glue.h | 49 + stdio/local.h | 144 + stdio/makebuf-fbsd.c | 128 + stdio/mktemp-fbsd.c | 202 ++ stdio/mktemp.3 | 275 ++ stdio/perror-fbsd.c | 81 + stdio/printf-fbsd.c | 71 + stdio/printf.3 | 957 ++++++ stdio/printf_l.3 | 83 +- stdio/putc-fbsd.c | 63 + stdio/putc.3 | 185 ++ stdio/putchar-fbsd.c | 67 + stdio/puts-fbsd.c | 81 + stdio/putw-fbsd.c | 66 + stdio/putwc-fbsd.c | 58 + stdio/putwc.3 | 122 + stdio/putwchar-fbsd.c | 57 + stdio/refill-fbsd.c | 150 + stdio/remove-fbsd.c | 59 + stdio/remove.3 | 87 + stdio/rewind-fbsd.c | 65 + stdio/rget-fbsd.c | 59 + stdio/scanf-fbsd.c | 79 + stdio/scanf.3 | 543 ++++ stdio/scanf_l.3 | 47 +- stdio/setbuf-fbsd.c | 50 + stdio/setbuf.3 | 226 ++ stdio/setbuffer-fbsd.c | 64 + stdio/setvbuf-fbsd.c | 165 ++ stdio/snprintf-fbsd.c | 107 + stdio/sprintf-fbsd.c | 91 + stdio/sscanf-fbsd.c | 108 + stdio/stdio-fbsd.c | 191 ++ stdio/stdio.3 | 368 +++ stdio/swprintf-fbsd.c | 62 + stdio/swscanf-fbsd.c | 62 + stdio/tempnam-fbsd.c | 121 + stdio/tmpfile-fbsd.c | 96 + stdio/tmpnam-fbsd.c | 65 + stdio/tmpnam.3 | 247 ++ stdio/ungetc-fbsd.c | 172 ++ stdio/ungetc.3 | 105 + stdio/ungetwc-fbsd.c | 92 + stdio/ungetwc.3 | 122 + stdio/unlocked-fbsd.c | 94 + stdio/vasprintf-fbsd.c | 106 + stdio/vfprintf-fbsd.c | 2101 ++++++++++++++ stdio/vfscanf-fbsd.c | 1168 ++++++++ stdio/vfwprintf-fbsd.c | 2096 ++++++++++++++ stdio/vfwscanf-fbsd.c | 948 ++++++ stdio/vprintf-fbsd.c | 60 + stdio/vscanf-fbsd.c | 77 + stdio/vsnprintf-fbsd.c | 116 + stdio/vsprintf-fbsd.c | 85 + stdio/vsscanf-fbsd.c | 105 + stdio/vswprintf-fbsd.c | 156 + stdio/vswscanf-fbsd.c | 141 + stdio/vwprintf-fbsd.c | 49 + stdio/vwscanf-fbsd.c | 49 + stdio/wbuf-fbsd.c | 98 + stdio/wprintf-fbsd.c | 61 + stdio/wprintf.3 | 659 +++++ stdio/wscanf-fbsd.c | 61 + stdio/wscanf.3 | 513 ++++ stdio/wscanf_l.3 | 47 +- stdio/wsetup-fbsd.c | 96 + stdlib/FreeBSD/abort.c.patch | 38 +- stdlib/FreeBSD/abs.3.patch | 20 + stdlib/FreeBSD/atexit.3.patch | 30 + stdlib/FreeBSD/atexit.c.patch | 48 +- stdlib/FreeBSD/atof.3.patch | 26 +- stdlib/FreeBSD/atoi.3.patch | 24 +- stdlib/FreeBSD/atol.3.patch | 46 +- stdlib/FreeBSD/bsearch.3.patch | 36 + stdlib/FreeBSD/div.3.patch | 31 + stdlib/FreeBSD/exit.c.patch | 23 +- stdlib/FreeBSD/getenv.3.patch | 121 + stdlib/FreeBSD/getenv.c.patch | 44 +- stdlib/FreeBSD/getopt.c.patch | 59 + stdlib/FreeBSD/getsubopt.3.patch | 69 + stdlib/FreeBSD/grantpt.3.patch | 10 - stdlib/FreeBSD/grantpt.c | 259 -- stdlib/FreeBSD/grantpt.c.patch | 161 -- stdlib/FreeBSD/imaxdiv.3.patch | 25 + stdlib/FreeBSD/insque.3.patch | 11 + stdlib/FreeBSD/labs.3.patch | 18 + stdlib/FreeBSD/ldiv.3.patch | 21 + stdlib/FreeBSD/llabs.3.patch | 17 + stdlib/FreeBSD/lldiv.3.patch | 25 + stdlib/FreeBSD/lsearch.3.patch | 41 + stdlib/FreeBSD/memory.3.patch | 118 + stdlib/FreeBSD/putenv.c.patch | 83 +- stdlib/FreeBSD/qsort.3.patch | 141 + stdlib/FreeBSD/rand.3.patch | 59 + stdlib/FreeBSD/random.3.patch | 134 + stdlib/FreeBSD/random.c.patch | 4 +- stdlib/FreeBSD/realpath.3.patch | 107 + stdlib/FreeBSD/realpath.c.patch | 75 +- stdlib/FreeBSD/setenv.c.patch | 255 +- stdlib/FreeBSD/strfmon.3.patch | 43 +- stdlib/FreeBSD/strfmon.c.patch | 81 +- stdlib/FreeBSD/strtod.3.patch | 67 +- stdlib/FreeBSD/strtol.3 | 8 +- stdlib/FreeBSD/strtol.3.patch | 147 +- stdlib/FreeBSD/strtoul.3.patch | 121 +- stdlib/FreeBSD/system.3.patch | 27 + stdlib/FreeBSD/system.c.patch | 53 +- stdlib/FreeBSD/tsearch.3.patch | 161 ++ stdlib/Makefile.inc | 128 +- stdlib/_Exit_-fbsd.c | 22 + stdlib/a64l.3 | 10 +- stdlib/a64l.c | 24 +- stdlib/abort-fbsd.c | 96 + stdlib/abort.3 | 1 + stdlib/abs-fbsd.c | 47 + stdlib/abs.3 | 77 + gen/initgroups.3 => stdlib/alloca.3 | 76 +- stdlib/atexit-fbsd.c | 202 ++ stdlib/atexit.3 | 92 + stdlib/atexit.h | 40 + stdlib/atof-fbsd.c | 58 + stdlib/atof.3 | 112 + stdlib/atoi-fbsd.c | 58 + stdlib/atoi.3 | 108 + stdlib/atol-fbsd.c | 58 + stdlib/atol.3 | 129 + stdlib/atoll-fbsd.c | 55 + stdlib/bsearch-fbsd.c | 83 + stdlib/bsearch.3 | 94 + stdlib/div-fbsd.c | 81 + stdlib/div.3 | 74 + stdlib/ecvt-obsd.c | 110 + stdlib/ecvt.3 | 165 ++ stdlib/exit-fbsd.c | 60 + stdlib/exit.3 | 1 + stdlib/gcvt-obsd.c | 112 + stdlib/getenv-fbsd.c | 107 + stdlib/getenv.3 | 238 ++ stdlib/getopt-fbsd.c | 153 + stdlib/getopt.3 | 1 + stdlib/getopt_long-fbsd.c | 642 ++++ stdlib/getopt_long.3 | 1 + stdlib/getsubopt-fbsd.c | 101 + stdlib/getsubopt.3 | 153 + stdlib/{FreeBSD => }/grantpt.3 | 94 +- stdlib/grantpt.c | 94 + stdlib/hcreate-fbsd.c | 185 ++ stdlib/hcreate.3 | 1 + stdlib/heapsort-fbsd.c | 185 ++ stdlib/imaxabs-fbsd.c | 36 + stdlib/imaxabs.3 | 1 + stdlib/imaxdiv-fbsd.c | 45 + stdlib/imaxdiv.3 | 73 + stdlib/insque-fbsd.c | 47 + stdlib/insque.3 | 61 + stdlib/l64a.c | 32 +- stdlib/labs-fbsd.c | 47 + stdlib/labs.3 | 71 + stdlib/ldiv-fbsd.c | 60 + stdlib/ldiv.3 | 76 + stdlib/llabs-fbsd.c | 36 + stdlib/llabs.3 | 62 + stdlib/lldiv-fbsd.c | 45 + stdlib/lldiv.3 | 73 + stdlib/lsearch-fbsd.c | 64 + stdlib/lsearch.3 | 105 + stdlib/memory.3 | 140 + stdlib/merge-fbsd.c | 352 +++ stdlib/putenv-fbsd.c | 103 + stdlib/qsort-fbsd.c | 197 ++ stdlib/qsort.3 | 293 ++ stdlib/qsort_r-fbsd.c | 8 + stdlib/radixsort-fbsd.c | 331 +++ stdlib/radixsort.3 | 1 + stdlib/rand-fbsd.c | 172 ++ stdlib/rand.3 | 127 + stdlib/random-fbsd.c | 514 ++++ stdlib/random.3 | 237 ++ stdlib/reallocf-fbsd.c | 41 + stdlib/realpath-fbsd.c | 355 +++ stdlib/realpath.3 | 141 + stdlib/remque-fbsd.c | 30 + stdlib/setenv-fbsd.c | 350 +++ stdlib/strfmon-fbsd.c | 639 ++++ stdlib/strfmon.3 | 192 ++ stdlib/strhash-fbsd.c | 406 +++ stdlib/strtod.3 | 202 ++ stdlib/strtoimax-fbsd.c | 151 + stdlib/strtol-fbsd.c | 151 + stdlib/strtol.3 | 261 ++ stdlib/strtoll-fbsd.c | 151 + stdlib/strtoq-fbsd.c | 62 + stdlib/strtoul-fbsd.c | 129 + stdlib/strtoul.3 | 255 ++ stdlib/strtoull-fbsd.c | 129 + stdlib/strtoumax-fbsd.c | 129 + stdlib/strtouq-fbsd.c | 62 + stdlib/system-fbsd.c | 133 + stdlib/system.3 | 103 + stdlib/tdelete-fbsd.c | 71 + stdlib/tfind-fbsd.c | 48 + stdlib/tsearch-fbsd.c | 58 + stdlib/tsearch.3 | 181 ++ stdlib/twalk-fbsd.c | 58 + stdtime/FreeBSD/asctime.c.patch | 13 + stdtime/FreeBSD/ctime.3.patch | 224 ++ stdtime/FreeBSD/ftime.3.patch | 45 +- stdtime/FreeBSD/localtime.c.patch | 687 ++++- stdtime/FreeBSD/strftime.3.patch | 59 +- stdtime/FreeBSD/strptime.3.patch | 66 +- stdtime/FreeBSD/strptime.c.patch | 327 ++- stdtime/FreeBSD/tzfile.5.patch | 11 + stdtime/Makefile.inc | 12 +- stdtime/asctime-fbsd.c | 76 + stdtime/ctime.3 | 381 +++ stdtime/difftime-fbsd.c | 87 + stdtime/ftime-fbsd.c | 54 + stdtime/ftime.3 | 93 + stdtime/getdate.c | 16 +- stdtime/localtime-fbsd.c | 2291 +++++++++++++++ stdtime/private.h | 260 ++ stdtime/strftime-fbsd.c | 574 ++++ stdtime/strftime.3 | 292 ++ stdtime/strptime-fbsd.c | 646 +++++ stdtime/strptime.3 | 197 ++ stdtime/time2posix.3 | 120 + stdtime/time32-fbsd.c | 100 + stdtime/timelocal-fbsd.c | 154 + stdtime/timelocal.h | 57 + stdtime/timezone_unix03.c | 2 - stdtime/tzfile.5 | 138 + stdtime/tzfile.h | 192 ++ string/FreeBSD/bcmp.3.patch | 25 + string/FreeBSD/bcopy.3.patch | 28 + string/FreeBSD/bstring.3.patch | 101 + string/FreeBSD/bzero.3.patch | 25 + string/FreeBSD/ffs.3.patch | 46 + string/FreeBSD/index.3.patch | 22 + string/FreeBSD/memccpy.3.patch | 40 + string/FreeBSD/memchr.3.patch | 32 + string/FreeBSD/memcmp.3.patch | 28 + string/FreeBSD/memcpy.3.patch | 46 +- string/FreeBSD/memmove.3.patch | 36 + string/FreeBSD/memset.3.patch | 41 + string/FreeBSD/rindex.3.patch | 13 + string/FreeBSD/strcasecmp.3.patch | 50 +- string/FreeBSD/strcat.3.patch | 73 +- string/FreeBSD/strchr.3.patch | 38 + string/FreeBSD/strcmp.3.patch | 30 + string/FreeBSD/strcoll.3.patch | 40 +- string/FreeBSD/strcoll.c.patch | 91 +- string/FreeBSD/strcpy.3.patch | 124 +- string/FreeBSD/strcspn.3.patch | 39 + string/FreeBSD/strcspn.c | 77 +- string/FreeBSD/strdup.3.patch | 21 + string/FreeBSD/strerror.3.patch | 42 + string/FreeBSD/strerror.c.patch | 49 + string/FreeBSD/string.3.patch | 193 ++ string/FreeBSD/strmode.3.patch | 14 + string/FreeBSD/strnstr.c | 4 +- string/FreeBSD/strpbrk.3.patch | 32 + string/FreeBSD/strrchr.3.patch | 14 + string/FreeBSD/strspn.3.patch | 27 + string/FreeBSD/strspn.c | 73 +- string/FreeBSD/strstr.3.patch | 91 +- string/FreeBSD/strtok.3.patch | 21 + string/FreeBSD/strxfrm.3.patch | 60 +- string/FreeBSD/strxfrm.c.patch | 125 +- string/FreeBSD/swab.3.patch | 57 + string/FreeBSD/wcscoll.3.patch | 48 +- string/FreeBSD/wcscoll.c.patch | 279 +- string/FreeBSD/wcstok.3.patch | 62 + string/FreeBSD/wcswidth.3.patch | 34 +- string/FreeBSD/wcsxfrm.3.patch | 72 +- string/FreeBSD/wcsxfrm.c.patch | 124 +- string/FreeBSD/wmemchr.3.patch | 183 ++ string/Makefile.inc | 103 +- string/bcmp-fbsd.c | 59 + string/bcmp.3 | 81 + string/bcopy.3 | 81 + string/bstring.3 | 156 + string/bzero.3 | 78 + string/ffs.3 | 100 + string/index-fbsd.c | 65 + string/index.3 | 106 + string/memccpy-fbsd.c | 60 + string/memccpy.3 | 81 + string/memchr-fbsd.c | 60 + string/memchr.3 | 86 + string/memcmp-fbsd.c | 62 + string/memcmp.3 | 89 + string/memcpy.3 | 93 + string/memmove.3 | 82 + string/memset-fbsd.c | 132 + gen/valloc.3 => string/memset.3 | 62 +- string/memset_pattern.3 | 43 + string/rindex-fbsd.c | 66 + string/rindex.3 | 92 + string/stpcpy-fbsd.c | 46 + string/strcasecmp-fbsd.c | 98 + string/strcasecmp.3 | 141 + string/strcasestr-fbsd.c | 76 + string/strcat-fbsd.c | 50 + string/strcat.3 | 167 ++ string/strchr-fbsd.c | 5 + string/strchr.3 | 104 + string/strcmp.3 | 111 + string/strcoll-fbsd.c | 71 + string/strcoll.3 | 98 + string/strcpy-fbsd.c | 49 + string/strcpy.3 | 214 ++ string/strcspn-fbsd.c | 72 + string/strcspn.3 | 87 + string/strdup-fbsd.c | 56 + string/strdup.3 | 72 + string/strerror-fbsd.c | 105 + string/strerror.3 | 198 ++ string/string.3 | 227 ++ string/strlcat-fbsd.c | 75 + string/strlcpy-fbsd.c | 70 + string/strlcpy.3 | 1 + string/strlen-fbsd.c | 51 + string/strlen.3 | 1 + string/strmode-fbsd.c | 154 + string/strmode.3 | 151 + string/strncat-fbsd.c | 66 + string/strncmp-fbsd.c | 58 + string/strncpy-fbsd.c | 66 + string/strnstr-fbsd.c | 72 + string/strpbrk-fbsd.c | 58 + string/strpbrk.3 | 83 + string/strrchr-fbsd.c | 5 + string/strrchr.3 | 94 + string/strsep-fbsd.c | 81 + string/strsep.3 | 1 + string/strsignal-fbsd.c | 74 + string/strspn-fbsd.c | 71 + string/strspn.3 | 83 + string/strstr-fbsd.c | 66 + string/strstr.3 | 177 ++ string/strtok-fbsd.c | 140 + string/strtok.3 | 185 ++ string/strxfrm-fbsd.c | 155 + string/strxfrm.3 | 123 + string/swab-fbsd.c | 65 + string/swab.3 | 90 + string/wcscat-fbsd.c | 53 + string/wcschr-fbsd.c | 41 + string/wcscmp-fbsd.c | 61 + string/wcscoll-fbsd.c | 248 ++ string/wcscoll.3 | 133 + string/wcscpy-fbsd.c | 51 + string/wcscspn-fbsd.c | 60 + string/wcslcat-fbsd.c | 77 + string/wcslcpy-fbsd.c | 73 + string/wcslen-fbsd.c | 50 + string/wcsncat-fbsd.c | 60 + string/wcsncmp-fbsd.c | 63 + string/wcsncpy-fbsd.c | 68 + string/wcspbrk-fbsd.c | 60 + string/wcsrchr-fbsd.c | 47 + string/wcsspn-fbsd.c | 62 + string/wcsstr-fbsd.c | 67 + string/wcstok-fbsd.c | 90 + string/wcstok.3 | 137 + .../isctype.c => string/wcswidth-fbsd.c | 194 +- string/wcswidth.3 | 83 + string/wcsxfrm-fbsd.c | 109 + string/wcsxfrm.3 | 148 + string/wmemchr-fbsd.c | 55 + string/wmemchr.3 | 214 ++ string/wmemcmp-fbsd.c | 56 + string/wmemcpy-fbsd.c | 48 + string/wmemmove-fbsd.c | 48 + string/wmemset-fbsd.c | 54 + sys/Makefile.inc | 189 +- sys/OpenBSD/stack_protector.c.patch | 70 +- sys/SYSCALL-LIST | 2 +- .../mach_absolute_time.c => sys/__libc_init.c | 53 +- sys/accept.c | 48 + sys/atomic.3 | 172 +- sys/barrier.3 | 3 +- sys/{pthread_setuid_np.c => bind.c} | 28 +- sys/cache.3 | 55 + sys/chmod.c | 55 + sys/chmodx_np.c | 8 +- sys/connect.c | 48 + i386/sys/bind.s => sys/context-stubs.c | 22 +- sys/crt_externs.c | 55 +- sys/fchmod.c | 55 + sys/{fcntl64.c => fcntl.c} | 16 +- ppc/sys/getattrlist.s => sys/getattrlist.c | 39 +- sys/getiopolicy_np.3 | 143 + sys/getiopolicy_np.c | 93 + mach/port_obj.c => sys/getpeername.c | 41 +- sys/{pthread_getuid_np.c => getrlimit.c} | 18 +- sys/getsockname.c | 48 + sys/gettimeofday.c | 60 +- sys/{ioctl64.c => ioctl.c} | 2 + sys/kill.c | 42 + sys/lchown.c | 47 + sys/libc.syscall | 18 + sys/listen.c | 47 + sys/mmap.c | 5 +- sys/mprotect.c | 11 +- sys/msgctl.c | 17 +- sys/msync.c | 16 +- sys/munmap.c | 13 +- sys/nanosleep.2 | 26 +- sys/open.c | 45 + sys/openx_np.c | 27 +- sys/posix_spawn.c | 1213 ++++++++ sys/pthread_kill.2 | 17 +- sys/pthread_sigmask.2 | 17 +- sys/recvfrom.c | 47 + x86_64/sys/getpid.s => sys/recvmsg.c | 44 +- sys/select.c | 80 + sys/sem_close.2 | 8 +- sys/sem_open.2 | 29 +- sys/sem_open.c | 4 +- sys/sem_post.2 | 10 +- sys/sem_trywait.2 | 1 - sys/sem_unlink.2 | 10 +- sys/sem_unlink.c | 4 +- sys/sem_wait.2 | 22 +- sys/semctl.c | 60 +- sys/sendmsg.c | 48 + sys/sendto.c | 48 + sys/setattrlist.c | 59 + sys/setregid.2 | 4 +- sys/setreuid.2 | 2 +- sys/setrlimit.c | 39 + sys/setsgroups_np.c | 31 - sys/setwgroups_np.c | 30 - sys/shm_open.2 | 16 +- sys/shm_open.c | 4 +- sys/shm_unlink.2 | 35 +- sys/shm_unlink.c | 4 +- sys/shmctl.c | 33 +- sys/sigaction.c | 7 +- sys/sigsuspend.c | 21 +- sys/sigtramp.c | 144 +- sys/sigwait.2 | 10 +- sys/socketpair.c | 49 + sys/stack_protector-obsd.c | 72 + sys/statx_np.c | 85 +- sys/umaskx_np.c | 5 +- sys/undelete.2 | 109 + threads/Makefile.inc | 2 + threads/cthreads.c | 7 +- threads/lu_utils.c | 58 +- util/Makefile.inc | 7 +- util/fparseln.c | 22 - util/login.3 | 112 + util/login.c | 31 +- util/login_tty.c | 22 - util/logout.c | 58 +- util/logwtmp.c | 60 +- util/opendev.c | 24 - util/openpty.3 | 163 ++ util/pty.c | 76 +- uuid/Makefile.inc | 34 +- uuid/clear-uuid.c | 43 + uuid/compare-uuid.c | 55 + uuid/copy-uuid.c | 45 + uuid/gen_uuid-uuid.c | 272 ++ uuid/isnull-uuid.c | 48 + uuid/pack-uuid.c | 69 + uuid/parse-uuid.c | 79 + uuid/unpack-uuid.c | 63 + uuid/unparse-uuid.c | 76 + uuid/uuid.3 | 66 + uuid/uuid.3-uuid.in | 1 + uuid/uuidP.h | 78 + uuid/uuid_clear.3 | 60 + uuid/uuid_clear.3-uuid.in | 1 + uuid/uuid_compare.3 | 66 + uuid/uuid_compare.3-uuid.in | 1 + uuid/uuid_copy.3 | 62 + uuid/uuid_copy.3-uuid.in | 1 + uuid/uuid_generate.3 | 103 + uuid/uuid_generate.3-uuid.in | 1 + uuid/uuid_is_null.3 | 61 + uuid/uuid_is_null.3-uuid.in | 1 + uuid/uuid_parse.3 | 70 + uuid/uuid_parse.3-uuid.in | 1 + uuid/uuid_unparse.3 | 87 + uuid/uuid_unparse.3-uuid.in | 87 + uuid/uuidsrc/gen_uuid.c.patch | 94 + uuid/uuidsrc/uuid_unparse.3.in.patch | 24 + ppc/sys/getppid.s => x86_64/gen/icacheinval.s | 25 +- x86_64/gen/mcount.s | 52 +- x86_64/mach/Makefile.inc | 7 +- .../__fcntl.s => mach/mach_absolute_time.s} | 15 +- x86_64/pthreads/Makefile.inc | 5 +- .../pthreads/start_wqthread.s | 24 +- .../pthreads/thread_start.s | 24 +- x86_64/stdlib/gdtoa.mk | 2 +- x86_64/string/Makefile.inc | 5 +- i386/sys/accept.s => x86_64/string/ffs.s | 48 +- x86_64/string/strlcat.s | 254 ++ x86_64/string/strlcpy.s | 167 ++ x86_64/string/strlen.s | 11 +- x86_64/sys/Makefile.inc | 231 +- x86_64/sys/OSAtomic.s | 115 + x86_64/sys/SYS.h | 29 - x86_64/sys/_sigtramp.s | 249 ++ x86_64/sys/cerror.s | 47 - x86_64/sys/fork.s | 131 - x86_64/sys/i386_gettimeofday.s | 12 +- x86_64/sys/libc.syscall.x86_64 | 25 + x86_64/sys/lseek.s | 29 - x86_64/sys/pipe.s | 32 - x86_64/sys/ptrace.s | 34 - x86_64/sys/setjmp.s | 9 +- x86_64/sys/sigaltstack.s | 29 - x86_64/sys/sigreturn.s | 29 - x86_64/sys/syscall.s | 32 - x86_64/sys/vfork.s | 65 - xdr/Makefile.inc | 52 - yp/Makefile.inc | 17 - 2036 files changed, 154496 insertions(+), 35341 deletions(-) create mode 100644 .autopatched delete mode 100644 CLIB-LIST delete mode 100644 MISSING-MANPAGE delete mode 100644 MISSING_SYSCALLS create mode 100644 Makefile.autopatch delete mode 100644 REQUIRED-MACROS delete mode 100644 SYSCALL-LIST create mode 100644 available.ex delete mode 100644 compat-43/FreeBSD/Makefile.inc create mode 100644 compat-43/FreeBSD/creat.c.patch create mode 100644 compat-43/FreeBSD/gethostid.3.patch create mode 100644 compat-43/FreeBSD/killpg.2.patch create mode 100644 compat-43/FreeBSD/killpg.c.patch create mode 100644 compat-43/creat-fbsd.c create mode 120000 compat-43/creat.2 create mode 100644 compat-43/gethostid-fbsd.c create mode 100644 compat-43/gethostid.3 create mode 100644 compat-43/getwd-fbsd.c create mode 100644 compat-43/killpg-fbsd.c create mode 100644 compat-43/killpg.2 create mode 100644 compat-43/sethostid-fbsd.c create mode 100644 compat-43/setpgrp-fbsd.c create mode 100644 compat-43/setrgid-fbsd.c create mode 100644 compat-43/setruid-fbsd.c create mode 120000 compat-43/setruid.3 rename i386/sys/getattrlist.s => compat-43/sigaltstk.c (69%) create mode 100644 darwin/MKGetTimeBaseInfo.c create mode 100644 darwin/_dirhelper.c delete mode 100644 darwin/copyfile.c delete mode 100644 darwin/copyfile.h rename ppc/sys/__pthread_markcancel.s => darwin/dirhelper.defs (69%) rename i386/sys/sem_wait.s => darwin/dirhelper_priv.h (57%) create mode 100644 darwin/kvm.c create mode 100644 darwin/libproc.c create mode 100644 darwin/libproc.h create mode 100644 darwin/proc_listpidspath.c create mode 100644 db/btree/bt_close-fbsd.c create mode 100644 db/btree/bt_conv-fbsd.c create mode 100644 db/btree/bt_debug-fbsd.c create mode 100644 db/btree/bt_delete-fbsd.c create mode 100644 db/btree/bt_extern.h create mode 100644 db/btree/bt_get-fbsd.c create mode 100644 db/btree/bt_open-fbsd.c create mode 100644 db/btree/bt_overflow-fbsd.c create mode 100644 db/btree/bt_page-fbsd.c create mode 100644 db/btree/bt_put-fbsd.c create mode 100644 db/btree/bt_search-fbsd.c create mode 100644 db/btree/bt_seq-fbsd.c create mode 100644 db/btree/bt_split-fbsd.c create mode 100644 db/btree/bt_utils-fbsd.c create mode 100644 db/btree/btree.h create mode 100644 db/db/db-fbsd.c create mode 100644 db/hash/hash-fbsd.c create mode 100644 db/hash/hash.h create mode 100644 db/hash/hash_bigkey-fbsd.c create mode 100644 db/hash/hash_buf-fbsd.c create mode 100644 db/hash/hash_extern.h create mode 100644 db/hash/hash_func-fbsd.c create mode 100644 db/hash/hash_log2-fbsd.c create mode 100644 db/hash/hash_page-fbsd.c create mode 100644 db/hash/ndbm-fbsd.c create mode 100644 db/hash/page.h create mode 100644 db/man/FreeBSD/dbm.3.patch create mode 120000 db/man/btree.3 create mode 100644 db/man/dbm.3 create mode 120000 db/man/dbopen.3 create mode 120000 db/man/hash.3 create mode 120000 db/man/mpool.3 create mode 120000 db/man/recno.3 create mode 100644 db/mpool/mpool-fbsd.c create mode 100644 db/recno/rec_close-fbsd.c create mode 100644 db/recno/rec_delete-fbsd.c create mode 100644 db/recno/rec_extern.h create mode 100644 db/recno/rec_get-fbsd.c create mode 100644 db/recno/rec_open-fbsd.c create mode 100644 db/recno/rec_put-fbsd.c create mode 100644 db/recno/rec_search-fbsd.c create mode 100644 db/recno/rec_seq-fbsd.c create mode 100644 db/recno/rec_utils-fbsd.c create mode 100644 db/recno/recno.h delete mode 100644 dpkg/control create mode 100644 emulated/lchflags.3 create mode 100644 emulated/lchflags.c create mode 100644 emulated/lchmod.3 create mode 100644 emulated/lchmod.c create mode 100644 emulated/lutimes.3 create mode 100644 emulated/lutimes.c create mode 100644 gdtoa/FreeBSD/gdtoa-gdtoa.c.patch create mode 100644 gdtoa/FreeBSD/gdtoa-hexnan.c.patch create mode 100644 gdtoa/FreeBSD/gdtoa-smisc.c.patch create mode 100644 gdtoa/_hdtoa-fbsd.c rename gdtoa/{FreeBSD => }/_ldbl_util.c (89%) create mode 100644 gdtoa/_ldtoa-fbsd.c create mode 100644 gdtoa/gdtoa-dmisc-fbsd.c create mode 100644 gdtoa/gdtoa-dtoa-fbsd.c create mode 100644 gdtoa/gdtoa-gdtoa-fbsd.c create mode 100644 gdtoa/gdtoa-gethex-fbsd.c create mode 100644 gdtoa/gdtoa-gmisc-fbsd.c create mode 100644 gdtoa/gdtoa-hd_init-fbsd.c create mode 100644 gdtoa/gdtoa-hexnan-fbsd.c create mode 100644 gdtoa/gdtoa-misc-fbsd.c create mode 100644 gdtoa/gdtoa-smisc-fbsd.c create mode 100644 gdtoa/gdtoa-strtod-fbsd.c create mode 100644 gdtoa/gdtoa-strtodg-fbsd.c create mode 100644 gdtoa/gdtoa-strtof-fbsd.c create mode 100644 gdtoa/gdtoa-strtopdd-fbsd.c create mode 100644 gdtoa/gdtoa-strtord-fbsd.c create mode 100644 gdtoa/gdtoa-sum-fbsd.c create mode 100644 gdtoa/gdtoa-ulp-fbsd.c create mode 100644 gdtoa/gdtoa.h create mode 100644 gdtoa/gdtoa_strtopx-fbsd.c create mode 100644 gdtoa/gdtoaimp.h create mode 100644 gdtoa/glue-fbsd.c create mode 100644 gdtoa/machdep_ldisdd-fbsd.c create mode 100644 gdtoa/machdep_ldisx-fbsd.c create mode 100644 gen/FreeBSD/_rand48.c.patch create mode 100644 gen/FreeBSD/alarm.3.patch create mode 100644 gen/FreeBSD/arc4random.3 rename gen/{ => FreeBSD}/arc4random.c (61%) create mode 100644 gen/FreeBSD/arc4random.c.patch create mode 100644 gen/FreeBSD/basename.3.patch create mode 100644 gen/FreeBSD/basename.c.patch create mode 100644 gen/FreeBSD/closedir.c.patch create mode 100644 gen/FreeBSD/ctermid.3.patch create mode 100644 gen/FreeBSD/daemon.3.patch create mode 100644 gen/FreeBSD/daemon.c.patch create mode 100644 gen/FreeBSD/dirname.3.patch create mode 100644 gen/FreeBSD/dirname.c.patch create mode 100644 gen/FreeBSD/drand48.c.patch create mode 100644 gen/FreeBSD/erand48.c.patch create mode 100644 gen/FreeBSD/fmtmsg.c.patch create mode 100644 gen/FreeBSD/fnmatch.3.patch delete mode 100644 gen/FreeBSD/fpclassify.3.patch create mode 100644 gen/FreeBSD/ftok.3.patch create mode 100644 gen/FreeBSD/getcontext.3 create mode 100644 gen/FreeBSD/gethostname.3.patch create mode 100644 gen/FreeBSD/gethostname.c.patch create mode 100644 gen/FreeBSD/getmntinfo.3.patch create mode 100644 gen/FreeBSD/getmntinfo64.c.patch create mode 100644 gen/FreeBSD/glob.3.patch create mode 100644 gen/FreeBSD/jrand48.c.patch create mode 100644 gen/FreeBSD/lcong48.c.patch create mode 100644 gen/FreeBSD/lockf.3.patch create mode 100644 gen/FreeBSD/lockf.c.patch create mode 100644 gen/FreeBSD/lrand48.c.patch create mode 100644 gen/FreeBSD/makecontext.3 create mode 100644 gen/FreeBSD/mrand48.c.patch create mode 100644 gen/FreeBSD/nice.c.patch create mode 100644 gen/FreeBSD/nrand48.c.patch create mode 100644 gen/FreeBSD/pause.c.patch create mode 100644 gen/FreeBSD/popen.3.patch create mode 100644 gen/FreeBSD/rand48.3.patch create mode 100644 gen/FreeBSD/rand48.h.patch create mode 100644 gen/FreeBSD/readdir.c.patch create mode 100644 gen/FreeBSD/seed48.c.patch create mode 100644 gen/FreeBSD/siginterrupt.3.patch create mode 100644 gen/FreeBSD/sleep.c.patch create mode 100644 gen/FreeBSD/srand48.c.patch create mode 100644 gen/FreeBSD/termios.c.patch create mode 100644 gen/FreeBSD/time.c.patch create mode 100644 gen/FreeBSD/times.3.patch create mode 100644 gen/FreeBSD/ttyname.3.patch create mode 100644 gen/FreeBSD/ualarm.3.patch create mode 100644 gen/FreeBSD/ucontext.3 create mode 100644 gen/FreeBSD/ulimit.3.patch create mode 100644 gen/FreeBSD/usleep.c.patch create mode 100644 gen/FreeBSD/utime.3.patch create mode 100644 gen/FreeBSD/wait.c.patch create mode 100644 gen/FreeBSD/waitpid.c.patch create mode 100644 gen/NetBSD/getlastlogx.3 create mode 100644 gen/NetBSD/getlastlogx.3.patch create mode 100644 gen/__dirent.h create mode 100644 gen/_rand48-fbsd.c create mode 100644 gen/_simple.c create mode 100644 gen/_simple.h create mode 100644 gen/alarm-fbsd.c create mode 100644 gen/alarm.3 create mode 100644 gen/arc4random-fbsd.c mode change 100644 => 120000 gen/arc4random.3 create mode 100644 gen/asl_ipc.defs create mode 100644 gen/asl_util.c create mode 100644 gen/assert-fbsd.c create mode 100644 gen/backtrace.3 create mode 100644 gen/backtrace.c create mode 100644 gen/basename-fbsd.c create mode 100644 gen/basename.3 create mode 100644 gen/clock-fbsd.c create mode 120000 gen/clock.3 create mode 100644 gen/closedir-fbsd.c create mode 100644 gen/ctermid-fbsd.c create mode 100644 gen/ctermid.3 create mode 100644 gen/daemon-fbsd.c create mode 100644 gen/daemon.3 create mode 100644 gen/dirname-fbsd.c create mode 100644 gen/dirname.3 create mode 100644 gen/drand48-fbsd.c create mode 100644 gen/endutxent.3 create mode 100644 gen/erand48-fbsd.c create mode 100644 gen/err-fbsd.c create mode 120000 gen/err.3 create mode 100644 gen/errno_-fbsd.c create mode 100644 gen/exec-fbsd.c create mode 100644 gen/exec.3 rename mach/externs.h => gen/execinfo.h (78%) create mode 100644 gen/fmtcheck-fbsd.c create mode 120000 gen/fmtcheck.3 create mode 100644 gen/fmtmsg-fbsd.c create mode 120000 gen/fmtmsg.3 create mode 100644 gen/fnmatch-fbsd.c create mode 100644 gen/fnmatch.3 create mode 100644 gen/ftok-fbsd.c create mode 100644 gen/ftok.3 create mode 100644 gen/getbsize-fbsd.c create mode 120000 gen/getbsize.3 create mode 100644 gen/getcap-fbsd.c create mode 120000 gen/getcap.3 create mode 120000 gen/getcontext.3 create mode 100644 gen/getcwd-fbsd.c create mode 120000 gen/getcwd.3 delete mode 100644 gen/getfsent.3 delete mode 100644 gen/getgrent.3 create mode 100644 gen/gethostname-fbsd.c create mode 100644 gen/gethostname.3 create mode 100644 gen/getlastlogx.3 create mode 100644 gen/getlogin-fbsd.c create mode 100644 gen/getmntinfo-fbsd.c create mode 100644 gen/getmntinfo.3 create mode 100644 gen/getmntinfo64-fbsd.c delete mode 100644 gen/getnetgrent.3 delete mode 100644 gen/getobjformat.3 create mode 100644 gen/getpagesize-fbsd.c create mode 120000 gen/getpagesize.3 create mode 120000 gen/getpass.3 create mode 100644 gen/getpeereid-fbsd.c create mode 120000 gen/getpeereid.3 create mode 100644 gen/getprogname-fbsd.c create mode 100644 gen/getprogname.3 delete mode 100644 gen/getpwent.3 create mode 100644 gen/glob-fbsd.c create mode 100644 gen/glob.3 create mode 100644 gen/isatty-fbsd.c rename gen/{FreeBSD/fpclassify.3 => isgreater.3} (50%) create mode 100644 gen/jrand48-fbsd.c create mode 100644 gen/lcong48-fbsd.c create mode 100644 gen/lockf-fbsd.c create mode 100644 gen/lockf.3 create mode 100644 gen/lrand48-fbsd.c create mode 120000 gen/makecontext.3 rename ppc/sys/getegid.s => gen/malloc_printf.h (71%) create mode 100644 gen/malloc_size.3 create mode 100644 gen/mrand48-fbsd.c create mode 100644 gen/nice-fbsd.c create mode 120000 gen/nice.3 create mode 100644 gen/nrand48-fbsd.c create mode 100644 gen/opendir-fbsd.c create mode 100644 gen/pause-fbsd.c create mode 120000 gen/pause.3 create mode 100644 gen/popen-fbsd.c create mode 100644 gen/popen.3 create mode 100644 gen/pselect-fbsd.c create mode 100644 gen/pselect.3 create mode 100644 gen/psignal-fbsd.c create mode 120000 gen/psignal.3 rename string/FreeBSD/ffs.c => gen/raise-fbsd.c (85%) create mode 120000 gen/raise.3 create mode 100644 gen/rand48.3 create mode 100644 gen/rand48.h create mode 100644 gen/readdir-fbsd.c create mode 100644 gen/readpassphrase-fbsd.c create mode 120000 gen/readpassphrase.3 create mode 100644 gen/rewinddir-fbsd.c create mode 100644 gen/scandir-fbsd.c create mode 120000 gen/scandir.3 create mode 100644 gen/seed48-fbsd.c create mode 100644 gen/seekdir-fbsd.c create mode 100644 gen/sethostname-fbsd.c create mode 100644 gen/setmode-fbsd.c create mode 120000 gen/setmode.3 create mode 100644 gen/setprogname-fbsd.c create mode 100644 gen/siginterrupt-fbsd.c create mode 100644 gen/siginterrupt.3 create mode 100644 gen/siglist-fbsd.c create mode 100644 gen/signal-fbsd.c create mode 100644 gen/signal.3 create mode 100644 gen/signbit.3 delete mode 100644 gen/simple_dprintf.c create mode 100644 gen/sleep-fbsd.c create mode 100644 gen/sleep.3 create mode 100644 gen/srand48-fbsd.c create mode 100644 gen/stack_logging_disk.c create mode 100644 gen/stringlist-fbsd.c create mode 120000 gen/stringlist.3 create mode 100644 gen/sysconf-fbsd.c create mode 120000 gen/sysconf.3 create mode 100644 gen/sysctl-fbsd.c create mode 100644 gen/sysctl.3 create mode 100644 gen/sysctlbyname-fbsd.c create mode 100644 gen/sysctlnametomib-fbsd.c create mode 100644 gen/telldir-fbsd.c create mode 100644 gen/telldir.h create mode 100644 gen/termios-fbsd.c create mode 100644 gen/thread_stack_pcs.c create mode 100644 gen/time-fbsd.c create mode 100644 gen/time.3 create mode 100644 gen/times-fbsd.c create mode 100644 gen/times.3 create mode 100644 gen/timezone-fbsd.c create mode 120000 gen/timezone.3 create mode 100644 gen/ttyname-fbsd.c create mode 100644 gen/ttyname.3 create mode 100644 gen/ttyslot-fbsd.c create mode 100644 gen/ualarm-fbsd.c create mode 100644 gen/ualarm.3 create mode 120000 gen/ucontext.3 create mode 100644 gen/ulimit-fbsd.c create mode 100644 gen/ulimit.3 create mode 100644 gen/unvis-fbsd.c create mode 120000 gen/unvis.3 create mode 100644 gen/usleep-fbsd.c create mode 100644 gen/usleep.3 create mode 100644 gen/utime-fbsd.c create mode 100644 gen/utime.3 create mode 100644 gen/utmpx-darwin.c create mode 100644 gen/utmpx-darwin.h create mode 100644 gen/utmpx-nbsd.c create mode 100644 gen/utmpx.5 create mode 100644 gen/vis-fbsd.c create mode 120000 gen/vis.3 create mode 100644 gen/wait-fbsd.c create mode 100644 gen/wait3-fbsd.c create mode 100644 gen/waitpid-fbsd.c create mode 100644 gmon/moncontrol.3 create mode 100644 i386/gen/_ctx_start.S rename mach/headers/thread_act.h => i386/gen/_setcontext.S (63%) create mode 100644 i386/gen/getcontext.S create mode 100644 i386/gen/getmcontext.c create mode 100644 i386/gen/makecontext.c rename mach/headers/task.h => i386/gen/setcontext.c (69%) create mode 100644 i386/gen/swapcontext.c rename x86_64/sys/__ioctl.s => i386/mach/mach_absolute_time.s (86%) create mode 100644 i386/pthreads/start_wqthread.s create mode 100644 i386/pthreads/thread_start.s rename mach/headers/vm_task.h => i386/string/ffs.s (74%) create mode 100644 i386/string/strlcat.s create mode 100644 i386/string/strlcpy.s delete mode 100644 i386/sys/ATPgetreq.s delete mode 100644 i386/sys/ATPgetrsp.s delete mode 100644 i386/sys/ATPsndreq.s delete mode 100644 i386/sys/ATPsndrsp.s delete mode 100644 i386/sys/ATgetmsg.s delete mode 100644 i386/sys/ATputmsg.s delete mode 100644 i386/sys/ATsocket.s delete mode 100644 i386/sys/__mmap.s delete mode 100644 i386/sys/__pthread_canceled.s delete mode 100644 i386/sys/__pthread_markcancel.s delete mode 100644 i386/sys/__semwait_signal.s delete mode 100644 i386/sys/_exit.s delete mode 100644 i386/sys/_getlogin.s delete mode 100644 i386/sys/_pthread_kill.s delete mode 100644 i386/sys/_setlogin.s create mode 100644 i386/sys/_sigtramp.s delete mode 100644 i386/sys/_sysctl.s delete mode 100644 i386/sys/access.s delete mode 100644 i386/sys/acct.s delete mode 100644 i386/sys/add_profil.s delete mode 100644 i386/sys/adjtime.s delete mode 100644 i386/sys/aio_cancel.s delete mode 100644 i386/sys/aio_error.s delete mode 100644 i386/sys/aio_fsync.s delete mode 100644 i386/sys/aio_read.s delete mode 100644 i386/sys/aio_return.s delete mode 100644 i386/sys/aio_suspend.s delete mode 100644 i386/sys/aio_write.s delete mode 100644 i386/sys/audit.s delete mode 100644 i386/sys/auditctl.s delete mode 100644 i386/sys/auditon.s delete mode 100644 i386/sys/auditsvc.s delete mode 100644 i386/sys/chdir.s delete mode 100644 i386/sys/checkuseraccess.s delete mode 100644 i386/sys/chflags.s delete mode 100644 i386/sys/chmod.s delete mode 100644 i386/sys/chown.s delete mode 100644 i386/sys/chroot.s delete mode 100644 i386/sys/close.s delete mode 100644 i386/sys/connect.s delete mode 100644 i386/sys/dup.s delete mode 100644 i386/sys/dup2.s delete mode 100644 i386/sys/exchangedata.s delete mode 100644 i386/sys/execve.s delete mode 100644 i386/sys/fchdir.s delete mode 100644 i386/sys/fchflags.s delete mode 100644 i386/sys/fchmod.s delete mode 100644 i386/sys/fchown.s delete mode 100644 i386/sys/fcntl.s delete mode 100644 i386/sys/fgetxattr.s delete mode 100644 i386/sys/fhopen.s delete mode 100644 i386/sys/flistxattr.s delete mode 100644 i386/sys/flock.s delete mode 100644 i386/sys/fork.s delete mode 100644 i386/sys/fpathconf.s delete mode 100644 i386/sys/fremovexattr.s delete mode 100644 i386/sys/fsctl.s delete mode 100644 i386/sys/fsetxattr.s delete mode 100644 i386/sys/fstat.s delete mode 100644 i386/sys/fstatfs.s delete mode 100644 i386/sys/fstatv.s delete mode 100644 i386/sys/fsync.s delete mode 100644 i386/sys/ftruncate.s delete mode 100644 i386/sys/futimes.s delete mode 100644 i386/sys/getaudit.s delete mode 100644 i386/sys/getaudit_addr.s delete mode 100644 i386/sys/getauid.s delete mode 100644 i386/sys/getdirentries.s delete mode 100644 i386/sys/getdirentriesattr.s delete mode 100644 i386/sys/getdtablesize.s delete mode 100644 i386/sys/getegid.s delete mode 100644 i386/sys/geteuid.s delete mode 100644 i386/sys/getfh.s delete mode 100644 i386/sys/getgid.s delete mode 100644 i386/sys/getgroups.s delete mode 100644 i386/sys/getitimer.s delete mode 100644 i386/sys/getpeername.s delete mode 100644 i386/sys/getpgid.s delete mode 100644 i386/sys/getpgrp.s delete mode 100644 i386/sys/getpid.s delete mode 100644 i386/sys/getppid.s delete mode 100644 i386/sys/getpriority.s delete mode 100644 i386/sys/getrlimit.s delete mode 100644 i386/sys/getrusage.s delete mode 100644 i386/sys/getsid.s delete mode 100644 i386/sys/getsockname.s delete mode 100644 i386/sys/getsockopt.s delete mode 100644 i386/sys/getuid.s delete mode 100644 i386/sys/getxattr.s delete mode 100644 i386/sys/ioctl.s delete mode 100644 i386/sys/issetugid.s delete mode 100644 i386/sys/kevent.s delete mode 100644 i386/sys/kill.s delete mode 100644 i386/sys/kqueue.s delete mode 100644 i386/sys/kqueue_from_portset_np.s delete mode 100644 i386/sys/kqueue_portset_np.s delete mode 100644 i386/sys/ktrace.s delete mode 100644 i386/sys/lchown.s create mode 100644 i386/sys/libc.syscall.i386 delete mode 100644 i386/sys/link.s delete mode 100644 i386/sys/lio_listio.s delete mode 100644 i386/sys/listen.s delete mode 100644 i386/sys/listxattr.s delete mode 100644 i386/sys/load_shared_file.s delete mode 100644 i386/sys/lseek.s delete mode 100644 i386/sys/lstat.s delete mode 100644 i386/sys/lstatv.s delete mode 100644 i386/sys/madvise.s delete mode 100644 i386/sys/mincore.s delete mode 100644 i386/sys/minherit.s delete mode 100644 i386/sys/mkcomplex.s delete mode 100644 i386/sys/mkdir.s delete mode 100644 i386/sys/mkfifo.s delete mode 100644 i386/sys/mknod.s delete mode 100644 i386/sys/mlock.s delete mode 100644 i386/sys/mlockall.s delete mode 100644 i386/sys/mount.s delete mode 100644 i386/sys/msgget.s delete mode 100644 i386/sys/msgrcv.s delete mode 100644 i386/sys/msgsnd.s delete mode 100644 i386/sys/msgsys.s delete mode 100644 i386/sys/munlock.s delete mode 100644 i386/sys/munlockall.s delete mode 100644 i386/sys/new_system_shared_regions.s delete mode 100644 i386/sys/nfsclnt.s delete mode 100644 i386/sys/nfssvc.s delete mode 100644 i386/sys/open.s delete mode 100644 i386/sys/pathconf.s delete mode 100644 i386/sys/pipe.s delete mode 100644 i386/sys/poll.s delete mode 100644 i386/sys/posix_madvise.s delete mode 100644 i386/sys/pread.s delete mode 100644 i386/sys/profil.s delete mode 100644 i386/sys/pthread_sigmask.s delete mode 100644 i386/sys/ptrace.s delete mode 100644 i386/sys/pwrite.s delete mode 100644 i386/sys/quota.s delete mode 100644 i386/sys/quotactl.s delete mode 100644 i386/sys/read.s delete mode 100644 i386/sys/readlink.s delete mode 100644 i386/sys/readv.s delete mode 100644 i386/sys/reboot.s delete mode 100644 i386/sys/recvfrom.s delete mode 100644 i386/sys/recvmsg.s delete mode 100644 i386/sys/removexattr.s delete mode 100644 i386/sys/rename.s delete mode 100644 i386/sys/reset_shared_file.s delete mode 100644 i386/sys/revoke.s delete mode 100644 i386/sys/rmdir.s delete mode 100644 i386/sys/s.template delete mode 100644 i386/sys/searchfs.s delete mode 100644 i386/sys/select.s delete mode 100644 i386/sys/sem_close.s delete mode 100644 i386/sys/sem_destroy.s delete mode 100644 i386/sys/sem_getvalue.s delete mode 100644 i386/sys/sem_init.s delete mode 100644 i386/sys/sem_post.s delete mode 100644 i386/sys/sem_trywait.s delete mode 100644 i386/sys/semget.s delete mode 100644 i386/sys/semop.s delete mode 100644 i386/sys/semsys.s delete mode 100644 i386/sys/sendmsg.s delete mode 100644 i386/sys/sendto.s delete mode 100644 i386/sys/setattrlist.s delete mode 100644 i386/sys/setaudit.s delete mode 100644 i386/sys/setaudit_addr.s delete mode 100644 i386/sys/setauid.s delete mode 100644 i386/sys/setegid.s delete mode 100644 i386/sys/seteuid.s delete mode 100644 i386/sys/setgid.s delete mode 100644 i386/sys/setgroups.s delete mode 100644 i386/sys/setitimer.s delete mode 100644 i386/sys/setpgid.s delete mode 100644 i386/sys/setpriority.s delete mode 100644 i386/sys/setprivexec.s delete mode 100644 i386/sys/setquota.s delete mode 100644 i386/sys/setrlimit.s delete mode 100644 i386/sys/setsid.s delete mode 100644 i386/sys/setsockopt.s delete mode 100644 i386/sys/settimeofday.s delete mode 100644 i386/sys/setuid.s delete mode 100644 i386/sys/setxattr.s delete mode 100644 i386/sys/shmat.s delete mode 100644 i386/sys/shmdt.s delete mode 100644 i386/sys/shmget.s delete mode 100644 i386/sys/shmsys.s delete mode 100644 i386/sys/shutdown.s delete mode 100644 i386/sys/sigaltstack.s delete mode 100644 i386/sys/sigpending.s delete mode 100644 i386/sys/sigprocmask.s delete mode 100644 i386/sys/sigreturn.s delete mode 100644 i386/sys/sigwait.s delete mode 100644 i386/sys/socket.s delete mode 100644 i386/sys/socketpair.s delete mode 100644 i386/sys/stat.s delete mode 100644 i386/sys/statfs.s delete mode 100644 i386/sys/statv.s delete mode 100644 i386/sys/swapon.s delete mode 100644 i386/sys/symlink.s delete mode 100644 i386/sys/sync.s delete mode 100644 i386/sys/syscall.s delete mode 100644 i386/sys/systable.s delete mode 100644 i386/sys/truncate.s delete mode 100644 i386/sys/umask.s delete mode 100644 i386/sys/undelete.s delete mode 100644 i386/sys/unlink.s delete mode 100644 i386/sys/unmount.s delete mode 100644 i386/sys/utimes.s delete mode 100644 i386/sys/vfork.s delete mode 100644 i386/sys/wait4.s delete mode 100644 i386/sys/write.s delete mode 100644 i386/sys/writev.s create mode 100644 include/_.libc_internal.h rename mach/mach_vm.defs => include/_structs.h (97%) delete mode 100644 include/c.h create mode 100644 include/libkern/OSCacheControl.h create mode 100644 include/secure/Makefile.inc rename mach/vm_map.defs => include/secure/_common.h (66%) create mode 100644 include/secure/_stdio.h create mode 100644 include/secure/_string.h create mode 100644 include/spawn.h create mode 100644 include/utmpx.h create mode 100644 locale/FreeBSD/fix_grouping.c.patch create mode 100644 locale/FreeBSD/setlocale.3.patch create mode 100644 locale/big5-fbsd.c create mode 120000 locale/big5.5 create mode 100644 locale/btowc-fbsd.c create mode 100644 locale/btowc.3 create mode 100644 locale/collate-fbsd.c create mode 100644 locale/collate.h create mode 100644 locale/collcmp-fbsd.c create mode 100644 locale/ctype.3 create mode 100644 locale/digittoint.3 create mode 100644 locale/euc-fbsd.c create mode 120000 locale/euc.5 create mode 100644 locale/fix_grouping-fbsd.c create mode 100644 locale/gb18030-fbsd.c create mode 120000 locale/gb18030.5 create mode 100644 locale/gb2312-fbsd.c create mode 120000 locale/gb2312.5 create mode 100644 locale/gbk-fbsd.c create mode 120000 locale/gbk.5 create mode 100644 locale/isalnum.3 create mode 100644 locale/isalpha.3 create mode 120000 locale/isascii.3 rename gen/getgrouplist.3 => locale/isblank.3 (59%) create mode 100644 locale/iscntrl.3 rename sys/other_libc_init.c => locale/isctype.c (86%) delete mode 100644 locale/isctype_l.c create mode 100644 locale/isdigit.3 create mode 100644 locale/isgraph.3 create mode 100644 locale/isideogram.3 create mode 100644 locale/islower.3 create mode 100644 locale/isphonogram.3 create mode 100644 locale/isprint.3 create mode 100644 locale/ispunct.3 create mode 100644 locale/isrune.3 create mode 100644 locale/isspace.3 create mode 100644 locale/isspecial.3 create mode 100644 locale/isupper.3 create mode 100644 locale/iswalnum.3 rename i386/sys/__sysenter_trap.s => locale/iswctype.c (83%) delete mode 100644 locale/iswctype_l.c create mode 100644 locale/isxdigit.3 create mode 100644 locale/ldpart-fbsd.c create mode 100644 locale/ldpart.h create mode 100644 locale/lmessages-fbsd.c create mode 100644 locale/lmessages.h create mode 100644 locale/lmonetary-fbsd.c create mode 100644 locale/lmonetary.h create mode 100644 locale/lnumeric-fbsd.c create mode 100644 locale/lnumeric.h create mode 100644 locale/localeconv-fbsd.c create mode 100644 locale/localeconv.3 create mode 100644 locale/mblen-fbsd.c create mode 100644 locale/mblen.3 create mode 100644 locale/mblocal.h create mode 100644 locale/mbrlen-fbsd.c create mode 100644 locale/mbrlen.3 create mode 100644 locale/mbrtowc-fbsd.c create mode 100644 locale/mbrtowc.3 create mode 100644 locale/mbsinit-fbsd.c create mode 100644 locale/mbsinit.3 create mode 100644 locale/mbsnrtowcs-fbsd.c create mode 100644 locale/mbsrtowcs-fbsd.c create mode 100644 locale/mbsrtowcs.3 create mode 100644 locale/mbstowcs-fbsd.c create mode 100644 locale/mbstowcs.3 create mode 100644 locale/mbtowc-fbsd.c create mode 100644 locale/mbtowc.3 create mode 100644 locale/mskanji-fbsd.c create mode 120000 locale/mskanji.5 create mode 120000 locale/multibyte.3 create mode 100644 locale/nextwctype-fbsd.c create mode 100644 locale/nextwctype.3 create mode 100644 locale/nl_langinfo-fbsd.c create mode 100644 locale/nl_langinfo.3 create mode 100644 locale/nomacros-fbsd.c create mode 100644 locale/none-fbsd.c create mode 100644 locale/rune-fbsd.c create mode 100644 locale/rune32.h create mode 100644 locale/runetype-fbsd.c create mode 100644 locale/setlocale-fbsd.c create mode 100644 locale/setlocale.3 create mode 100644 locale/setlocale.h create mode 100644 locale/setrunelocale-fbsd.c create mode 100644 locale/table-fbsd.c create mode 120000 locale/toascii.3 create mode 100644 locale/tolower-fbsd.c create mode 100644 locale/tolower.3 create mode 100644 locale/toupper-fbsd.c create mode 100644 locale/toupper.3 create mode 100644 locale/towlower.3 create mode 100644 locale/towupper.3 create mode 100644 locale/utf2-fbsd.c create mode 100644 locale/utf8-fbsd.c create mode 120000 locale/utf8.5 create mode 100644 locale/wcrtomb-fbsd.c create mode 100644 locale/wcrtomb.3 create mode 100644 locale/wcsftime-fbsd.c create mode 100644 locale/wcsftime.3 create mode 100644 locale/wcsnrtombs-fbsd.c create mode 100644 locale/wcsrtombs-fbsd.c create mode 100644 locale/wcsrtombs.3 create mode 100644 locale/wcstod-fbsd.c create mode 100644 locale/wcstod.3 create mode 100644 locale/wcstof-fbsd.c create mode 100644 locale/wcstoimax-fbsd.c create mode 100644 locale/wcstol-fbsd.c create mode 100644 locale/wcstol.3 create mode 100644 locale/wcstold-fbsd.c create mode 100644 locale/wcstoll-fbsd.c create mode 100644 locale/wcstombs-fbsd.c create mode 100644 locale/wcstombs.3 create mode 100644 locale/wcstoul-fbsd.c create mode 100644 locale/wcstoull-fbsd.c create mode 100644 locale/wcstoumax-fbsd.c create mode 100644 locale/wctob-fbsd.c create mode 100644 locale/wctomb-fbsd.c create mode 100644 locale/wctomb.3 create mode 100644 locale/wctrans-fbsd.c create mode 100644 locale/wctrans.3 create mode 100644 locale/wctype-fbsd.c create mode 100644 locale/wctype.3 rename locale/{FreeBSD/iswctype.c => wcwidth-fbsd.c} (54%) create mode 100644 locale/wcwidth.3 delete mode 100644 mach/Makefile.inc delete mode 100644 mach/bootstrap_ports.c delete mode 100644 mach/brk.2 delete mode 100644 mach/clock.defs delete mode 100644 mach/clock_priv.defs delete mode 100644 mach/clock_reply.defs delete mode 100644 mach/clock_sleep.c delete mode 100644 mach/err_ipc.sub delete mode 100644 mach/err_kern.sub delete mode 100644 mach/err_mach_ipc.sub delete mode 100644 mach/err_server.sub delete mode 100644 mach/err_us.sub delete mode 100644 mach/error_codes.c delete mode 100644 mach/errorlib.h delete mode 100644 mach/exc.defs delete mode 100644 mach/exc_catcher.c delete mode 100644 mach/exc_catcher_state.c delete mode 100644 mach/exc_catcher_state_identity.c delete mode 100644 mach/fprintf_stderr.c delete mode 100644 mach/headers/Makefile.inc delete mode 100644 mach/headers/errorlib.h delete mode 100644 mach/headers/mach.h delete mode 100644 mach/headers/mach_error.h delete mode 100644 mach/headers/mach_init.h delete mode 100644 mach/headers/mach_interface.h delete mode 100644 mach/headers/port_obj.h delete mode 100644 mach/headers/sync.h delete mode 100644 mach/host_priv.defs delete mode 100644 mach/host_security.defs delete mode 100644 mach/ledger.defs delete mode 100644 mach/lock_set.defs delete mode 100644 mach/mach_error.c delete mode 100644 mach/mach_error_string.c delete mode 100644 mach/mach_host.defs delete mode 100644 mach/mach_init.c delete mode 100644 mach/mach_init_ports.c delete mode 100644 mach/mach_msg.c delete mode 100644 mach/mach_port.defs delete mode 100644 mach/mach_traps.s delete mode 100644 mach/mig_allocate.c delete mode 100644 mach/mig_deallocate.c delete mode 100644 mach/mig_reply_setup.c delete mode 100644 mach/mig_strncpy.c delete mode 100644 mach/ms_thread_switch.c delete mode 100644 mach/notify.defs delete mode 100644 mach/panic.c delete mode 100644 mach/processor.defs delete mode 100644 mach/processor_set.defs delete mode 100644 mach/sbrk.c delete mode 100644 mach/semaphore.c delete mode 100644 mach/servers/Makefile.inc delete mode 100644 mach/servers/bootstrap_defs.h delete mode 100644 mach/servers/key_defs.h delete mode 100644 mach/servers/ls_defs.h delete mode 100644 mach/servers/netname.defs delete mode 100644 mach/servers/netname_defs.h delete mode 100644 mach/servers/nm_defs.h delete mode 100644 mach/servers/srvbootstrap.defs delete mode 100644 mach/slot_name.c delete mode 100644 mach/task.defs delete mode 100644 mach/thread_act.defs delete mode 100755 make_libldbl128 create mode 100644 man/Makefile.inc create mode 100644 man/assert.3 create mode 100644 man/bitstring.3 create mode 100644 man/environ.7 create mode 100644 man/stdarg.3 create mode 100644 net/FreeBSD/inet.3.patch create mode 100644 net/FreeBSD/recv.c.patch create mode 100644 net/FreeBSD/send.c.patch create mode 100644 net/FreeBSD/sockatmark.3 create mode 100644 net/FreeBSD/sockatmark.3.patch create mode 100644 net/FreeBSD/sockatmark.c create mode 100644 net/addr2ascii-fbsd.c create mode 120000 net/addr2ascii.3 create mode 100644 net/ascii2addr-fbsd.c delete mode 100644 net/hesiod.3 create mode 100644 net/inet.3 create mode 100644 net/inet_addr-fbsd.c create mode 100644 net/inet_lnaof-fbsd.c create mode 100644 net/inet_makeaddr-fbsd.c create mode 120000 net/inet_net.3 create mode 100644 net/inet_net_ntop-fbsd.c create mode 100644 net/inet_net_pton-fbsd.c create mode 100644 net/inet_neta-fbsd.c create mode 100644 net/inet_netof-fbsd.c create mode 100644 net/inet_network-fbsd.c create mode 100644 net/inet_ntoa-fbsd.c create mode 100644 net/linkaddr-fbsd.c create mode 120000 net/linkaddr.3 create mode 100644 net/nsap_addr-fbsd.c create mode 100644 net/recv-fbsd.c delete mode 100644 net/resolver.3 create mode 100644 net/send-fbsd.c create mode 100644 net/sockatmark-fbsd.c create mode 100644 net/sockatmark.3 create mode 100644 nls/FreeBSD/msgcat.h.patch create mode 120000 nls/catclose.3 create mode 120000 nls/catgets.3 create mode 120000 nls/catopen.3 create mode 100644 nls/msgcat-fbsd.c create mode 100644 nls/msgcat.h create mode 100755 patchHeaders create mode 100644 ppc/gen/_ctx_start.S create mode 100644 ppc/gen/_setcontext.S rename ppc/{sys/getdtablesize.s => gen/getcontext.S} (60%) create mode 100644 ppc/gen/getmcontext.c create mode 100644 ppc/gen/makecontext.c rename sys/accessx_np.c => ppc/gen/setcontext.c (73%) create mode 100644 ppc/gen/swapcontext.c rename ppc/{gen => string}/ffs.s (100%) rename ppc/{sys/connect.s => string/ffsl.s} (57%) rename i386/sys/commpage.c => ppc/string/fls.s (93%) rename ppc/{sys/bind.s => string/flsl.s} (83%) delete mode 100644 ppc/sys/ATPgetreq.s delete mode 100644 ppc/sys/ATPgetrsp.s delete mode 100644 ppc/sys/ATPsndreq.s delete mode 100644 ppc/sys/ATPsndrsp.s delete mode 100644 ppc/sys/ATgetmsg.s delete mode 100644 ppc/sys/ATputmsg.s delete mode 100644 ppc/sys/ATsocket.s delete mode 100644 ppc/sys/__mmap.s delete mode 100644 ppc/sys/__pthread_canceled.s delete mode 100644 ppc/sys/__semwait_signal.s delete mode 100644 ppc/sys/_exit.s delete mode 100644 ppc/sys/_getlogin.s delete mode 100644 ppc/sys/_pthread_kill.s delete mode 100644 ppc/sys/_setlogin.s create mode 100644 ppc/sys/_sigtramp.s delete mode 100644 ppc/sys/_sysctl.s delete mode 100644 ppc/sys/accept.s delete mode 100644 ppc/sys/access.s delete mode 100644 ppc/sys/acct.s delete mode 100644 ppc/sys/add_profil.s delete mode 100644 ppc/sys/adjtime.s delete mode 100644 ppc/sys/aio_cancel.s delete mode 100644 ppc/sys/aio_error.s delete mode 100644 ppc/sys/aio_fsync.s delete mode 100644 ppc/sys/aio_read.s delete mode 100644 ppc/sys/aio_return.s delete mode 100644 ppc/sys/aio_suspend.s delete mode 100644 ppc/sys/aio_write.s delete mode 100644 ppc/sys/assym.h delete mode 100644 ppc/sys/assymdefs.c delete mode 100644 ppc/sys/audit.s delete mode 100644 ppc/sys/auditctl.s delete mode 100644 ppc/sys/auditon.s delete mode 100644 ppc/sys/auditsvc.s delete mode 100644 ppc/sys/cerror.s delete mode 100644 ppc/sys/chdir.s delete mode 100644 ppc/sys/checkuseraccess.s delete mode 100644 ppc/sys/chflags.s delete mode 100644 ppc/sys/chmod.s delete mode 100644 ppc/sys/chown.s delete mode 100644 ppc/sys/chroot.s delete mode 100644 ppc/sys/close.s delete mode 100644 ppc/sys/dup.s delete mode 100644 ppc/sys/dup2.s delete mode 100644 ppc/sys/exchangedata.s delete mode 100644 ppc/sys/execve.s delete mode 100644 ppc/sys/fchdir.s delete mode 100644 ppc/sys/fchflags.s delete mode 100644 ppc/sys/fchmod.s delete mode 100644 ppc/sys/fchown.s delete mode 100644 ppc/sys/fcntl.s delete mode 100644 ppc/sys/fgetxattr.s delete mode 100644 ppc/sys/fhopen.s delete mode 100644 ppc/sys/flistxattr.s delete mode 100644 ppc/sys/flock.s delete mode 100644 ppc/sys/fork.s delete mode 100644 ppc/sys/fpathconf.s delete mode 100644 ppc/sys/fremovexattr.s delete mode 100644 ppc/sys/fsctl.s delete mode 100644 ppc/sys/fsetxattr.s delete mode 100644 ppc/sys/fstat.s delete mode 100644 ppc/sys/fstatfs.s delete mode 100644 ppc/sys/fstatv.s delete mode 100644 ppc/sys/fsync.s delete mode 100644 ppc/sys/ftruncate.s delete mode 100644 ppc/sys/futimes.s delete mode 100644 ppc/sys/genassym.c delete mode 100644 ppc/sys/genassym.h delete mode 100644 ppc/sys/getaudit.s delete mode 100644 ppc/sys/getaudit_addr.s delete mode 100644 ppc/sys/getauid.s delete mode 100644 ppc/sys/getdirentries.s delete mode 100644 ppc/sys/getdirentriesattr.s delete mode 100644 ppc/sys/geteuid.s delete mode 100644 ppc/sys/getfh.s delete mode 100644 ppc/sys/getfsstat.s delete mode 100644 ppc/sys/getgid.s delete mode 100644 ppc/sys/getgroups.s delete mode 100644 ppc/sys/getitimer.s delete mode 100644 ppc/sys/getpeername.s delete mode 100644 ppc/sys/getpgid.s delete mode 100644 ppc/sys/getpgrp.s delete mode 100644 ppc/sys/getpid.s delete mode 100644 ppc/sys/getpriority.s delete mode 100644 ppc/sys/getrlimit.s delete mode 100644 ppc/sys/getrusage.s delete mode 100644 ppc/sys/getsid.s delete mode 100644 ppc/sys/getsockname.s delete mode 100644 ppc/sys/getsockopt.s delete mode 100644 ppc/sys/getuid.s delete mode 100644 ppc/sys/getxattr.s delete mode 100644 ppc/sys/ioctl.s delete mode 100644 ppc/sys/issetugid.s delete mode 100644 ppc/sys/kevent.s delete mode 100644 ppc/sys/kill.s delete mode 100644 ppc/sys/kqueue.s delete mode 100644 ppc/sys/kqueue_from_portset_np.s delete mode 100644 ppc/sys/kqueue_portset_np.s delete mode 100644 ppc/sys/ktrace.s delete mode 100644 ppc/sys/lchown.s create mode 100644 ppc/sys/libc.syscall.ppc delete mode 100644 ppc/sys/link.s delete mode 100644 ppc/sys/lio_listio.s delete mode 100644 ppc/sys/listen.s delete mode 100644 ppc/sys/listxattr.s delete mode 100644 ppc/sys/load_shared_file.s delete mode 100644 ppc/sys/lseek.s delete mode 100644 ppc/sys/lstat.s delete mode 100644 ppc/sys/lstatv.s delete mode 100644 ppc/sys/madvise.s delete mode 100644 ppc/sys/mincore.s delete mode 100644 ppc/sys/minherit.s delete mode 100644 ppc/sys/mkcomplex.s delete mode 100644 ppc/sys/mkdir.s delete mode 100644 ppc/sys/mkfifo.s delete mode 100644 ppc/sys/mknod.s delete mode 100644 ppc/sys/mlock.s delete mode 100644 ppc/sys/mlockall.s delete mode 100644 ppc/sys/mount.s delete mode 100644 ppc/sys/msgget.s delete mode 100644 ppc/sys/msgrcv.s delete mode 100644 ppc/sys/msgsnd.s delete mode 100644 ppc/sys/msgsys.s delete mode 100644 ppc/sys/munlock.s delete mode 100644 ppc/sys/munlockall.s delete mode 100644 ppc/sys/new_system_shared_regions.s delete mode 100644 ppc/sys/nfsclnt.s delete mode 100644 ppc/sys/nfssvc.s delete mode 100644 ppc/sys/oldldbl64.s delete mode 100644 ppc/sys/open.s delete mode 100644 ppc/sys/pathconf.s delete mode 100644 ppc/sys/pipe.s delete mode 100644 ppc/sys/poll.s delete mode 100644 ppc/sys/posix_madvise.s delete mode 100644 ppc/sys/pread.s delete mode 100644 ppc/sys/processor_facilities.h delete mode 100644 ppc/sys/processor_facilities.s delete mode 100644 ppc/sys/profil.s delete mode 100644 ppc/sys/pthread_sigmask.s delete mode 100644 ppc/sys/ptrace.s delete mode 100644 ppc/sys/pwrite.s delete mode 100644 ppc/sys/quota.s delete mode 100644 ppc/sys/quotactl.s delete mode 100644 ppc/sys/read.s delete mode 100644 ppc/sys/readlink.s delete mode 100644 ppc/sys/readv.s delete mode 100644 ppc/sys/reboot.s delete mode 100644 ppc/sys/recvfrom.s delete mode 100644 ppc/sys/recvmsg.s delete mode 100644 ppc/sys/removexattr.s delete mode 100644 ppc/sys/rename.s delete mode 100644 ppc/sys/reset_shared_file.s delete mode 100644 ppc/sys/revoke.s delete mode 100644 ppc/sys/rmdir.s delete mode 100644 ppc/sys/s.template delete mode 100644 ppc/sys/searchfs.s delete mode 100644 ppc/sys/select.s delete mode 100644 ppc/sys/sem_close.s delete mode 100644 ppc/sys/sem_destroy.s delete mode 100644 ppc/sys/sem_getvalue.s delete mode 100644 ppc/sys/sem_init.s delete mode 100644 ppc/sys/sem_post.s delete mode 100644 ppc/sys/sem_trywait.s delete mode 100644 ppc/sys/sem_wait.s delete mode 100644 ppc/sys/semget.s delete mode 100644 ppc/sys/semop.s delete mode 100644 ppc/sys/semsys.s delete mode 100644 ppc/sys/sendmsg.s delete mode 100644 ppc/sys/sendto.s delete mode 100644 ppc/sys/setattrlist.s delete mode 100644 ppc/sys/setaudit.s delete mode 100644 ppc/sys/setaudit_addr.s delete mode 100644 ppc/sys/setauid.s delete mode 100644 ppc/sys/setegid.s delete mode 100644 ppc/sys/seteuid.s delete mode 100644 ppc/sys/setgid.s delete mode 100644 ppc/sys/setgroups.s delete mode 100644 ppc/sys/setitimer.s delete mode 100644 ppc/sys/setpgid.s delete mode 100644 ppc/sys/setpriority.s delete mode 100644 ppc/sys/setprivexec.s delete mode 100644 ppc/sys/setquota.s delete mode 100644 ppc/sys/setrlimit.s delete mode 100644 ppc/sys/setsid.s delete mode 100644 ppc/sys/setsockopt.s delete mode 100644 ppc/sys/settimeofday.s delete mode 100644 ppc/sys/setuid.s delete mode 100644 ppc/sys/setxattr.s delete mode 100644 ppc/sys/shmat.s delete mode 100644 ppc/sys/shmdt.s delete mode 100644 ppc/sys/shmget.s delete mode 100644 ppc/sys/shmsys.s delete mode 100644 ppc/sys/shutdown.s delete mode 100644 ppc/sys/sigaltstack.s delete mode 100644 ppc/sys/sigpending.s delete mode 100644 ppc/sys/sigprocmask.s delete mode 100644 ppc/sys/sigreturn.s delete mode 100644 ppc/sys/sigwait.s delete mode 100644 ppc/sys/socket.s delete mode 100644 ppc/sys/socketpair.s delete mode 100644 ppc/sys/stat.s delete mode 100644 ppc/sys/statfs.s delete mode 100644 ppc/sys/statv.s delete mode 100644 ppc/sys/swapon.s delete mode 100644 ppc/sys/symlink.s delete mode 100644 ppc/sys/sync.s delete mode 100644 ppc/sys/syscall.s delete mode 100644 ppc/sys/systable.s delete mode 100644 ppc/sys/truncate.s delete mode 100644 ppc/sys/umask.s delete mode 100644 ppc/sys/undelete.s delete mode 100644 ppc/sys/unlink.s delete mode 100644 ppc/sys/unmount.s delete mode 100644 ppc/sys/utimes.s delete mode 100644 ppc/sys/vfork.s delete mode 100644 ppc/sys/wait4.s delete mode 100644 ppc/sys/write.s delete mode 100644 ppc/sys/writev.s delete mode 100644 ppc64/sys/__fcntl.s delete mode 100644 ppc64/sys/__ioctl.s create mode 100644 ppc64/sys/libc.syscall.ppc64 delete mode 100644 pthreads/lock.s create mode 100644 pthreads/plockstat.d create mode 100644 pthreads/pthread_cancelable.c create mode 100644 pthreads/pthread_workqueue.h delete mode 100644 quad/Makefile.inc create mode 100644 regex/FreeBSD/regex.3.patch create mode 100644 regex/FreeBSD/regfree.c.patch create mode 100644 regex/cclass.h create mode 100644 regex/cname.h create mode 100644 regex/engine.c create mode 120000 regex/re_format.7 create mode 100644 regex/regcomp-fbsd.c create mode 100644 regex/regerror-fbsd.c create mode 100644 regex/regex.3 create mode 100644 regex/regex2.h create mode 100644 regex/regexec-fbsd.c create mode 100644 regex/regfree-fbsd.c create mode 100644 regex/utils.h create mode 100644 secure/Makefile.inc rename sys/getwgroups_np.c => secure/chk_fail.c (73%) create mode 100644 secure/memcpy_chk.c create mode 100644 secure/memmove_chk.c rename sys/getsgroups_np.c => secure/memset_chk.c (73%) create mode 100644 secure/snprintf_chk.c create mode 100644 secure/sprintf_chk.c create mode 100644 secure/stpcpy_chk.c rename i386/sys/cerror.s => secure/strcat_chk.c (60%) create mode 100644 secure/strcpy_chk.c create mode 100644 secure/strncat_chk.c create mode 100644 secure/strncpy_chk.c rename i386/sys/getfsstat.s => secure/vsnprintf_chk.c (61%) create mode 100644 secure/vsprintf_chk.c create mode 100644 stdio/FreeBSD/fclose.c.patch create mode 100644 stdio/FreeBSD/fflush.c.patch create mode 100644 stdio/FreeBSD/flags.c.patch create mode 100644 stdio/FreeBSD/flockfile.3.patch create mode 100644 stdio/FreeBSD/fopen.3.patch create mode 100644 stdio/FreeBSD/fread.3.patch create mode 100644 stdio/FreeBSD/fseek.3.patch create mode 100644 stdio/FreeBSD/fwide.3.patch create mode 100644 stdio/FreeBSD/getc.3.patch create mode 100644 stdio/FreeBSD/makebuf.c.patch create mode 100644 stdio/FreeBSD/mktemp.3.patch create mode 100644 stdio/FreeBSD/perror.c.patch create mode 100644 stdio/FreeBSD/putc.3.patch create mode 100644 stdio/FreeBSD/remove.3.patch create mode 100644 stdio/FreeBSD/setbuf.3.patch create mode 100644 stdio/FreeBSD/stdio.3.patch create mode 100644 stdio/FreeBSD/tempnam.c.patch create mode 100644 stdio/FreeBSD/ungetc.3.patch create mode 100644 stdio/_flock_stub-fbsd.c create mode 100644 stdio/asprintf-fbsd.c create mode 100644 stdio/clrerr-fbsd.c create mode 100644 stdio/fclose-fbsd.c create mode 120000 stdio/fclose.3 create mode 100644 stdio/fdopen-fbsd.c create mode 100644 stdio/feof-fbsd.c create mode 100644 stdio/ferror-fbsd.c create mode 120000 stdio/ferror.3 create mode 100644 stdio/fflush-fbsd.c create mode 120000 stdio/fflush.3 create mode 100644 stdio/fgetc-fbsd.c create mode 100644 stdio/fgetln-fbsd.c create mode 120000 stdio/fgetln.3 create mode 100644 stdio/fgetpos-fbsd.c create mode 100644 stdio/fgets-fbsd.c create mode 100644 stdio/fgets.3 create mode 100644 stdio/fgetwc-fbsd.c create mode 100644 stdio/fgetws-fbsd.c create mode 100644 stdio/fgetws.3 create mode 100644 stdio/fileno-fbsd.c create mode 100644 stdio/findfp-fbsd.c create mode 100644 stdio/flags-fbsd.c create mode 100644 stdio/floatio.h create mode 100644 stdio/flockfile.3 create mode 100644 stdio/fopen-fbsd.c create mode 100644 stdio/fopen.3 create mode 100644 stdio/fprintf-fbsd.c create mode 100644 stdio/fpurge-fbsd.c create mode 100644 stdio/fputc-fbsd.c create mode 100644 stdio/fputs-fbsd.c create mode 100644 stdio/fputs.3 create mode 100644 stdio/fputwc-fbsd.c create mode 100644 stdio/fputws-fbsd.c create mode 100644 stdio/fputws.3 create mode 100644 stdio/fread-fbsd.c create mode 100644 stdio/fread.3 create mode 100644 stdio/freopen-fbsd.c create mode 100644 stdio/fscanf-fbsd.c create mode 100644 stdio/fseek-fbsd.c create mode 100644 stdio/fseek.3 create mode 100644 stdio/fsetpos-fbsd.c create mode 100644 stdio/ftell-fbsd.c create mode 100644 stdio/funopen-fbsd.c create mode 120000 stdio/funopen.3 create mode 100644 stdio/fvwrite-fbsd.c create mode 100644 stdio/fvwrite.h create mode 100644 stdio/fwalk-fbsd.c create mode 100644 stdio/fwide-fbsd.c create mode 100644 stdio/fwide.3 create mode 100644 stdio/fwprintf-fbsd.c create mode 100644 stdio/fwrite-fbsd.c create mode 100644 stdio/fwscanf-fbsd.c create mode 100644 stdio/getc-fbsd.c create mode 100644 stdio/getc.3 create mode 100644 stdio/getchar-fbsd.c create mode 100644 stdio/gets-fbsd.c create mode 100644 stdio/getw-fbsd.c create mode 100644 stdio/getwc-fbsd.c create mode 100644 stdio/getwc.3 create mode 100644 stdio/getwchar-fbsd.c create mode 100644 stdio/glue.h create mode 100644 stdio/local.h create mode 100644 stdio/makebuf-fbsd.c create mode 100644 stdio/mktemp-fbsd.c create mode 100644 stdio/mktemp.3 create mode 100644 stdio/perror-fbsd.c create mode 100644 stdio/printf-fbsd.c create mode 100644 stdio/printf.3 create mode 100644 stdio/putc-fbsd.c create mode 100644 stdio/putc.3 create mode 100644 stdio/putchar-fbsd.c create mode 100644 stdio/puts-fbsd.c create mode 100644 stdio/putw-fbsd.c create mode 100644 stdio/putwc-fbsd.c create mode 100644 stdio/putwc.3 create mode 100644 stdio/putwchar-fbsd.c create mode 100644 stdio/refill-fbsd.c create mode 100644 stdio/remove-fbsd.c create mode 100644 stdio/remove.3 create mode 100644 stdio/rewind-fbsd.c create mode 100644 stdio/rget-fbsd.c create mode 100644 stdio/scanf-fbsd.c create mode 100644 stdio/scanf.3 create mode 100644 stdio/setbuf-fbsd.c create mode 100644 stdio/setbuf.3 create mode 100644 stdio/setbuffer-fbsd.c create mode 100644 stdio/setvbuf-fbsd.c create mode 100644 stdio/snprintf-fbsd.c create mode 100644 stdio/sprintf-fbsd.c create mode 100644 stdio/sscanf-fbsd.c create mode 100644 stdio/stdio-fbsd.c create mode 100644 stdio/stdio.3 create mode 100644 stdio/swprintf-fbsd.c create mode 100644 stdio/swscanf-fbsd.c create mode 100644 stdio/tempnam-fbsd.c create mode 100644 stdio/tmpfile-fbsd.c create mode 100644 stdio/tmpnam-fbsd.c create mode 100644 stdio/tmpnam.3 create mode 100644 stdio/ungetc-fbsd.c create mode 100644 stdio/ungetc.3 create mode 100644 stdio/ungetwc-fbsd.c create mode 100644 stdio/ungetwc.3 create mode 100644 stdio/unlocked-fbsd.c create mode 100644 stdio/vasprintf-fbsd.c create mode 100644 stdio/vfprintf-fbsd.c create mode 100644 stdio/vfscanf-fbsd.c create mode 100644 stdio/vfwprintf-fbsd.c create mode 100644 stdio/vfwscanf-fbsd.c create mode 100644 stdio/vprintf-fbsd.c create mode 100644 stdio/vscanf-fbsd.c create mode 100644 stdio/vsnprintf-fbsd.c create mode 100644 stdio/vsprintf-fbsd.c create mode 100644 stdio/vsscanf-fbsd.c create mode 100644 stdio/vswprintf-fbsd.c create mode 100644 stdio/vswscanf-fbsd.c create mode 100644 stdio/vwprintf-fbsd.c create mode 100644 stdio/vwscanf-fbsd.c create mode 100644 stdio/wbuf-fbsd.c create mode 100644 stdio/wprintf-fbsd.c create mode 100644 stdio/wprintf.3 create mode 100644 stdio/wscanf-fbsd.c create mode 100644 stdio/wscanf.3 create mode 100644 stdio/wsetup-fbsd.c create mode 100644 stdlib/FreeBSD/abs.3.patch create mode 100644 stdlib/FreeBSD/atexit.3.patch create mode 100644 stdlib/FreeBSD/bsearch.3.patch create mode 100644 stdlib/FreeBSD/div.3.patch create mode 100644 stdlib/FreeBSD/getenv.3.patch create mode 100644 stdlib/FreeBSD/getopt.c.patch create mode 100644 stdlib/FreeBSD/getsubopt.3.patch delete mode 100644 stdlib/FreeBSD/grantpt.3.patch delete mode 100644 stdlib/FreeBSD/grantpt.c delete mode 100644 stdlib/FreeBSD/grantpt.c.patch create mode 100644 stdlib/FreeBSD/imaxdiv.3.patch create mode 100644 stdlib/FreeBSD/insque.3.patch create mode 100644 stdlib/FreeBSD/labs.3.patch create mode 100644 stdlib/FreeBSD/ldiv.3.patch create mode 100644 stdlib/FreeBSD/llabs.3.patch create mode 100644 stdlib/FreeBSD/lldiv.3.patch create mode 100644 stdlib/FreeBSD/lsearch.3.patch create mode 100644 stdlib/FreeBSD/memory.3.patch create mode 100644 stdlib/FreeBSD/qsort.3.patch create mode 100644 stdlib/FreeBSD/rand.3.patch create mode 100644 stdlib/FreeBSD/random.3.patch create mode 100644 stdlib/FreeBSD/realpath.3.patch create mode 100644 stdlib/FreeBSD/system.3.patch create mode 100644 stdlib/FreeBSD/tsearch.3.patch create mode 100644 stdlib/_Exit_-fbsd.c create mode 100644 stdlib/abort-fbsd.c create mode 120000 stdlib/abort.3 create mode 100644 stdlib/abs-fbsd.c create mode 100644 stdlib/abs.3 rename gen/initgroups.3 => stdlib/alloca.3 (67%) create mode 100644 stdlib/atexit-fbsd.c create mode 100644 stdlib/atexit.3 create mode 100644 stdlib/atexit.h create mode 100644 stdlib/atof-fbsd.c create mode 100644 stdlib/atof.3 create mode 100644 stdlib/atoi-fbsd.c create mode 100644 stdlib/atoi.3 create mode 100644 stdlib/atol-fbsd.c create mode 100644 stdlib/atol.3 create mode 100644 stdlib/atoll-fbsd.c create mode 100644 stdlib/bsearch-fbsd.c create mode 100644 stdlib/bsearch.3 create mode 100644 stdlib/div-fbsd.c create mode 100644 stdlib/div.3 create mode 100644 stdlib/ecvt-obsd.c create mode 100644 stdlib/ecvt.3 create mode 100644 stdlib/exit-fbsd.c create mode 120000 stdlib/exit.3 create mode 100644 stdlib/gcvt-obsd.c create mode 100644 stdlib/getenv-fbsd.c create mode 100644 stdlib/getenv.3 create mode 100644 stdlib/getopt-fbsd.c create mode 120000 stdlib/getopt.3 create mode 100644 stdlib/getopt_long-fbsd.c create mode 120000 stdlib/getopt_long.3 create mode 100644 stdlib/getsubopt-fbsd.c create mode 100644 stdlib/getsubopt.3 rename stdlib/{FreeBSD => }/grantpt.3 (85%) create mode 100644 stdlib/grantpt.c create mode 100644 stdlib/hcreate-fbsd.c create mode 120000 stdlib/hcreate.3 create mode 100644 stdlib/heapsort-fbsd.c create mode 100644 stdlib/imaxabs-fbsd.c create mode 120000 stdlib/imaxabs.3 create mode 100644 stdlib/imaxdiv-fbsd.c create mode 100644 stdlib/imaxdiv.3 create mode 100644 stdlib/insque-fbsd.c create mode 100644 stdlib/insque.3 create mode 100644 stdlib/labs-fbsd.c create mode 100644 stdlib/labs.3 create mode 100644 stdlib/ldiv-fbsd.c create mode 100644 stdlib/ldiv.3 create mode 100644 stdlib/llabs-fbsd.c create mode 100644 stdlib/llabs.3 create mode 100644 stdlib/lldiv-fbsd.c create mode 100644 stdlib/lldiv.3 create mode 100644 stdlib/lsearch-fbsd.c create mode 100644 stdlib/lsearch.3 create mode 100644 stdlib/memory.3 create mode 100644 stdlib/merge-fbsd.c create mode 100644 stdlib/putenv-fbsd.c create mode 100644 stdlib/qsort-fbsd.c create mode 100644 stdlib/qsort.3 create mode 100644 stdlib/qsort_r-fbsd.c create mode 100644 stdlib/radixsort-fbsd.c create mode 120000 stdlib/radixsort.3 create mode 100644 stdlib/rand-fbsd.c create mode 100644 stdlib/rand.3 create mode 100644 stdlib/random-fbsd.c create mode 100644 stdlib/random.3 create mode 100644 stdlib/reallocf-fbsd.c create mode 100644 stdlib/realpath-fbsd.c create mode 100644 stdlib/realpath.3 create mode 100644 stdlib/remque-fbsd.c create mode 100644 stdlib/setenv-fbsd.c create mode 100644 stdlib/strfmon-fbsd.c create mode 100644 stdlib/strfmon.3 create mode 100644 stdlib/strhash-fbsd.c create mode 100644 stdlib/strtod.3 create mode 100644 stdlib/strtoimax-fbsd.c create mode 100644 stdlib/strtol-fbsd.c create mode 100644 stdlib/strtol.3 create mode 100644 stdlib/strtoll-fbsd.c create mode 100644 stdlib/strtoq-fbsd.c create mode 100644 stdlib/strtoul-fbsd.c create mode 100644 stdlib/strtoul.3 create mode 100644 stdlib/strtoull-fbsd.c create mode 100644 stdlib/strtoumax-fbsd.c create mode 100644 stdlib/strtouq-fbsd.c create mode 100644 stdlib/system-fbsd.c create mode 100644 stdlib/system.3 create mode 100644 stdlib/tdelete-fbsd.c create mode 100644 stdlib/tfind-fbsd.c create mode 100644 stdlib/tsearch-fbsd.c create mode 100644 stdlib/tsearch.3 create mode 100644 stdlib/twalk-fbsd.c create mode 100644 stdtime/FreeBSD/asctime.c.patch create mode 100644 stdtime/FreeBSD/ctime.3.patch create mode 100644 stdtime/FreeBSD/tzfile.5.patch create mode 100644 stdtime/asctime-fbsd.c create mode 100644 stdtime/ctime.3 create mode 100644 stdtime/difftime-fbsd.c create mode 100644 stdtime/ftime-fbsd.c create mode 100644 stdtime/ftime.3 create mode 100644 stdtime/localtime-fbsd.c create mode 100644 stdtime/private.h create mode 100644 stdtime/strftime-fbsd.c create mode 100644 stdtime/strftime.3 create mode 100644 stdtime/strptime-fbsd.c create mode 100644 stdtime/strptime.3 create mode 100644 stdtime/time2posix.3 create mode 100644 stdtime/time32-fbsd.c create mode 100644 stdtime/timelocal-fbsd.c create mode 100644 stdtime/timelocal.h create mode 100644 stdtime/tzfile.5 create mode 100644 stdtime/tzfile.h create mode 100644 string/FreeBSD/bcmp.3.patch create mode 100644 string/FreeBSD/bcopy.3.patch create mode 100644 string/FreeBSD/bstring.3.patch create mode 100644 string/FreeBSD/bzero.3.patch create mode 100644 string/FreeBSD/ffs.3.patch create mode 100644 string/FreeBSD/index.3.patch create mode 100644 string/FreeBSD/memccpy.3.patch create mode 100644 string/FreeBSD/memchr.3.patch create mode 100644 string/FreeBSD/memcmp.3.patch create mode 100644 string/FreeBSD/memmove.3.patch create mode 100644 string/FreeBSD/memset.3.patch create mode 100644 string/FreeBSD/rindex.3.patch create mode 100644 string/FreeBSD/strchr.3.patch create mode 100644 string/FreeBSD/strcmp.3.patch create mode 100644 string/FreeBSD/strcspn.3.patch create mode 100644 string/FreeBSD/strdup.3.patch create mode 100644 string/FreeBSD/strerror.3.patch create mode 100644 string/FreeBSD/strerror.c.patch create mode 100644 string/FreeBSD/string.3.patch create mode 100644 string/FreeBSD/strmode.3.patch create mode 100644 string/FreeBSD/strpbrk.3.patch create mode 100644 string/FreeBSD/strrchr.3.patch create mode 100644 string/FreeBSD/strspn.3.patch create mode 100644 string/FreeBSD/strtok.3.patch create mode 100644 string/FreeBSD/swab.3.patch create mode 100644 string/FreeBSD/wcstok.3.patch create mode 100644 string/FreeBSD/wmemchr.3.patch create mode 100644 string/bcmp-fbsd.c create mode 100644 string/bcmp.3 create mode 100644 string/bcopy.3 create mode 100644 string/bstring.3 create mode 100644 string/bzero.3 create mode 100644 string/ffs.3 create mode 100644 string/index-fbsd.c create mode 100644 string/index.3 create mode 100644 string/memccpy-fbsd.c create mode 100644 string/memccpy.3 create mode 100644 string/memchr-fbsd.c create mode 100644 string/memchr.3 create mode 100644 string/memcmp-fbsd.c create mode 100644 string/memcmp.3 create mode 100644 string/memcpy.3 create mode 100644 string/memmove.3 create mode 100644 string/memset-fbsd.c rename gen/valloc.3 => string/memset.3 (73%) create mode 100644 string/memset_pattern.3 create mode 100644 string/rindex-fbsd.c create mode 100644 string/rindex.3 create mode 100644 string/stpcpy-fbsd.c create mode 100644 string/strcasecmp-fbsd.c create mode 100644 string/strcasecmp.3 create mode 100644 string/strcasestr-fbsd.c create mode 100644 string/strcat-fbsd.c create mode 100644 string/strcat.3 create mode 100644 string/strchr-fbsd.c create mode 100644 string/strchr.3 create mode 100644 string/strcmp.3 create mode 100644 string/strcoll-fbsd.c create mode 100644 string/strcoll.3 create mode 100644 string/strcpy-fbsd.c create mode 100644 string/strcpy.3 create mode 100644 string/strcspn-fbsd.c create mode 100644 string/strcspn.3 create mode 100644 string/strdup-fbsd.c create mode 100644 string/strdup.3 create mode 100644 string/strerror-fbsd.c create mode 100644 string/strerror.3 create mode 100644 string/string.3 create mode 100644 string/strlcat-fbsd.c create mode 100644 string/strlcpy-fbsd.c create mode 120000 string/strlcpy.3 create mode 100644 string/strlen-fbsd.c create mode 120000 string/strlen.3 create mode 100644 string/strmode-fbsd.c create mode 100644 string/strmode.3 create mode 100644 string/strncat-fbsd.c create mode 100644 string/strncmp-fbsd.c create mode 100644 string/strncpy-fbsd.c create mode 100644 string/strnstr-fbsd.c create mode 100644 string/strpbrk-fbsd.c create mode 100644 string/strpbrk.3 create mode 100644 string/strrchr-fbsd.c create mode 100644 string/strrchr.3 create mode 100644 string/strsep-fbsd.c create mode 120000 string/strsep.3 create mode 100644 string/strsignal-fbsd.c create mode 100644 string/strspn-fbsd.c create mode 100644 string/strspn.3 create mode 100644 string/strstr-fbsd.c create mode 100644 string/strstr.3 create mode 100644 string/strtok-fbsd.c create mode 100644 string/strtok.3 create mode 100644 string/strxfrm-fbsd.c create mode 100644 string/strxfrm.3 create mode 100644 string/swab-fbsd.c create mode 100644 string/swab.3 create mode 100644 string/wcscat-fbsd.c create mode 100644 string/wcschr-fbsd.c create mode 100644 string/wcscmp-fbsd.c create mode 100644 string/wcscoll-fbsd.c create mode 100644 string/wcscoll.3 create mode 100644 string/wcscpy-fbsd.c create mode 100644 string/wcscspn-fbsd.c create mode 100644 string/wcslcat-fbsd.c create mode 100644 string/wcslcpy-fbsd.c create mode 100644 string/wcslen-fbsd.c create mode 100644 string/wcsncat-fbsd.c create mode 100644 string/wcsncmp-fbsd.c create mode 100644 string/wcsncpy-fbsd.c create mode 100644 string/wcspbrk-fbsd.c create mode 100644 string/wcsrchr-fbsd.c create mode 100644 string/wcsspn-fbsd.c create mode 100644 string/wcsstr-fbsd.c create mode 100644 string/wcstok-fbsd.c create mode 100644 string/wcstok.3 rename locale/FreeBSD/isctype.c => string/wcswidth-fbsd.c (53%) create mode 100644 string/wcswidth.3 create mode 100644 string/wcsxfrm-fbsd.c create mode 100644 string/wcsxfrm.3 create mode 100644 string/wmemchr-fbsd.c create mode 100644 string/wmemchr.3 create mode 100644 string/wmemcmp-fbsd.c create mode 100644 string/wmemcpy-fbsd.c create mode 100644 string/wmemmove-fbsd.c create mode 100644 string/wmemset-fbsd.c rename i386/mach/mach_absolute_time.c => sys/__libc_init.c (50%) create mode 100644 sys/accept.c rename sys/{pthread_setuid_np.c => bind.c} (61%) create mode 100644 sys/cache.3 create mode 100644 sys/chmod.c create mode 100644 sys/connect.c rename i386/sys/bind.s => sys/context-stubs.c (65%) create mode 100644 sys/fchmod.c rename sys/{fcntl64.c => fcntl.c} (77%) rename ppc/sys/getattrlist.s => sys/getattrlist.c (50%) create mode 100644 sys/getiopolicy_np.3 create mode 100644 sys/getiopolicy_np.c rename mach/port_obj.c => sys/getpeername.c (58%) rename sys/{pthread_getuid_np.c => getrlimit.c} (71%) create mode 100644 sys/getsockname.c rename sys/{ioctl64.c => ioctl.c} (97%) create mode 100644 sys/kill.c create mode 100644 sys/lchown.c create mode 100644 sys/libc.syscall create mode 100644 sys/listen.c create mode 100644 sys/open.c create mode 100644 sys/posix_spawn.c create mode 100644 sys/recvfrom.c rename x86_64/sys/getpid.s => sys/recvmsg.c (61%) create mode 100644 sys/select.c delete mode 100644 sys/sem_trywait.2 create mode 100644 sys/sendmsg.c create mode 100644 sys/sendto.c create mode 100644 sys/setattrlist.c create mode 100644 sys/setrlimit.c delete mode 100644 sys/setsgroups_np.c delete mode 100644 sys/setwgroups_np.c create mode 100644 sys/socketpair.c create mode 100644 sys/stack_protector-obsd.c create mode 100644 sys/undelete.2 create mode 100644 util/login.3 create mode 100644 util/openpty.3 create mode 100644 uuid/clear-uuid.c create mode 100644 uuid/compare-uuid.c create mode 100644 uuid/copy-uuid.c create mode 100644 uuid/gen_uuid-uuid.c create mode 100644 uuid/isnull-uuid.c create mode 100644 uuid/pack-uuid.c create mode 100644 uuid/parse-uuid.c create mode 100644 uuid/unpack-uuid.c create mode 100644 uuid/unparse-uuid.c create mode 100644 uuid/uuid.3 create mode 120000 uuid/uuid.3-uuid.in create mode 100644 uuid/uuidP.h create mode 100644 uuid/uuid_clear.3 create mode 120000 uuid/uuid_clear.3-uuid.in create mode 100644 uuid/uuid_compare.3 create mode 120000 uuid/uuid_compare.3-uuid.in create mode 100644 uuid/uuid_copy.3 create mode 120000 uuid/uuid_copy.3-uuid.in create mode 100644 uuid/uuid_generate.3 create mode 120000 uuid/uuid_generate.3-uuid.in create mode 100644 uuid/uuid_is_null.3 create mode 120000 uuid/uuid_is_null.3-uuid.in create mode 100644 uuid/uuid_parse.3 create mode 120000 uuid/uuid_parse.3-uuid.in create mode 100644 uuid/uuid_unparse.3 create mode 100644 uuid/uuid_unparse.3-uuid.in create mode 100644 uuid/uuidsrc/gen_uuid.c.patch create mode 100644 uuid/uuidsrc/uuid_unparse.3.in.patch rename ppc/sys/getppid.s => x86_64/gen/icacheinval.s (64%) rename x86_64/{sys/__fcntl.s => mach/mach_absolute_time.s} (86%) rename i386/sys/i386_set_ldt.s => x86_64/pthreads/start_wqthread.s (72%) rename i386/sys/i386_get_ldt.s => x86_64/pthreads/thread_start.s (72%) rename i386/sys/accept.s => x86_64/string/ffs.s (66%) create mode 100644 x86_64/string/strlcat.s create mode 100644 x86_64/string/strlcpy.s create mode 100644 x86_64/sys/_sigtramp.s delete mode 100644 x86_64/sys/cerror.s delete mode 100644 x86_64/sys/fork.s create mode 100644 x86_64/sys/libc.syscall.x86_64 delete mode 100644 x86_64/sys/lseek.s delete mode 100644 x86_64/sys/pipe.s delete mode 100644 x86_64/sys/ptrace.s delete mode 100644 x86_64/sys/sigaltstack.s delete mode 100644 x86_64/sys/sigreturn.s delete mode 100644 x86_64/sys/syscall.s delete mode 100644 x86_64/sys/vfork.s delete mode 100644 xdr/Makefile.inc delete mode 100644 yp/Makefile.inc diff --git a/.autopatched b/.autopatched new file mode 100644 index 0000000..e69de29 diff --git a/BSDmakefile b/BSDmakefile index 45d508d..de14ee9 100644 --- a/BSDmakefile +++ b/BSDmakefile @@ -1,15 +1,28 @@ +PWD != pwd +.ifdef DSTROOT +DESTDIR = $(DSTROOT) +.else +.ifdef DESTDIR +DSTROOT = $(DESTDIR) +.else +DSTROOT = / +DESTDIR = / +.endif +.endif .ifndef OBJROOT -OBJROOT != pwd +OBJROOT = $(PWD)/OBJROOT +.endif +.ifndef SRCROOT +SRCROOT = $(PWD) .endif .ifndef SYMROOT -SYMROOT != pwd +SYMROOT = $(PWD)/SYMROOT .endif ARCH != arch .ifndef RC_ARCHS RC_ARCHS = $(ARCH) RC_$(RC_ARCHS) = 1 .endif -NARCHS != echo $(RC_ARCHS) | wc -w .ifdef ALTUSRLOCALLIBSYSTEM LIBSYS = $(ALTUSRLOCALLIBSYSTEM) .else @@ -17,10 +30,13 @@ LIBSYS = $(NEXT_ROOT)/usr/local/lib/system .endif NJOBS != perl -e '$$n = `/usr/sbin/sysctl -n hw.ncpu`; printf "%d\n", $$n < 2 ? 2 : ($$n * 1.5)' BSDMAKE = bsdmake -f Makefile -#BSDMAKEJ = $(BSDMAKE) -j $(NJOBS) -BSDMAKEJ = $(BSDMAKE) -j $(NJOBS) -P +#BSDMAKEJ = $(BSDMAKE) -j $(NJOBS) -P +BSDMAKEJ = $(BSDMAKE) -j $(NJOBS) + +# Set the DONT-BUILD-arch-form variable to non-empty to turn off building +#DONT-BUILD-x86_64-static = 1 -# This variables are to guarantee that the left-hand side of an expression is +# These variables are to guarantee that the left-hand side of an expression is # always a variable dynamic = dynamic static = static @@ -32,11 +48,19 @@ FORMS := dynamic debug profile static all: build +ROOTS := DSTROOT OBJROOT SYMROOT +.for R in $(ROOTS) # { +roots: $($(R)) +$($(R)): + mkdir -p '$($(R))' +.endfor # ROOTS } + # These are the non B&I defaults .ifndef RC_ProjectName -installhdrs: installhdrs-real -build: build-static build-profile build-debug build-dynamic -install: installhdrs install-all + +installhdrs: roots installhdrs-real +build: roots build-static build-profile build-debug build-dynamic +install: roots installhdrs install-all .else # RC_ProjectName @@ -44,127 +68,163 @@ install: installhdrs install-all # based on RC_ProjectName. .if $(RC_ProjectName) == Libc installhdrs: -build: build-dynamic -install: BI-install-dynamic +build: roots build-dynamic +install: roots BI-install-dynamic .endif .if $(RC_ProjectName) == Libc_headers -installhdrs: installhdrs-real +installhdrs: roots installhdrs-real build: -install: installhdrs-real +install: roots installhdrs-real .endif .if $(RC_ProjectName) == Libc_man installhdrs: build: -install: install-man +install: roots install-man .endif .if $(RC_ProjectName) == Libc_static installhdrs: -build: build-static -install: BI-install-static +build: roots build-static +install: roots BI-install-static .endif .if $(RC_ProjectName) == Libc_debug installhdrs: -build: build-debug -install: BI-install-debug +build: roots build-debug +install: roots BI-install-debug .endif .if $(RC_ProjectName) == Libc_profile installhdrs: -build: build-profile -install: BI-install-profile +build: roots build-profile +install: roots BI-install-profile .endif .endif # RC_ProjectName -# Because of 3780028, there are random failures on HFS because the -# CC_PRINT_OPTIONS_FILE can't be created. So we touch it first. -.if !empty $(CC_PRINT_OPTIONS_FILE) -$(CC_PRINT_OPTIONS_FILE): - touch $(CC_PRINT_OPTIONS_FILE) -.endif # CC_PRINT_OPTIONS_FILE - -.for F in $(FORMS) -.if $(dynamic) == $(F) -SUFFIX$(F) = +# Make a copy of System.framework/Versions/B/PrivateHeaders, with headers +# patched so that we can build variant symbols independently +SYSTEMFRAMEWORK = System.framework +VERSIONSB = Versions/B +PRIVATEHEADERPATH = $(SYSTEMFRAMEWORK)/$(VERSIONSB)/PrivateHeaders +FRAMEWORKS = $(OBJROOT)/Frameworks +.ifdef ALTFRAMEWORKSPATH +FRAMEWORKPATH = ${ALTFRAMEWORKSPATH} .else -SUFFIX$(F) = _$(F) +FRAMEWORKPATH = ${NEXT_ROOT}/System/Library/Frameworks .endif -LIPOARGS$(F) != perl -e 'printf "%s\n", join(" ", map(qq(-arch $$_ \"$(OBJROOT)/obj.$$_/libc$(SUFFIX$(F)).a\"), qw($(RC_ARCHS))))' - -build-$(F): autopatch $(CC_PRINT_OPTIONS_FILE) -.for A in $(RC_ARCHS) -build-$(F): build-$(A)-$(F) -.endfor # RC_ARCHS -build-$(F): -.if $(NARCHS) == 1 - cp -p "$(OBJROOT)/obj.$(RC_ARCHS)/libc$(SUFFIX$(F)).a" "$(SYMROOT)" -.else - lipo -create $(LIPOARGS$(F)) -output $(SYMROOT)/libc$(SUFFIX$(F)).a -.endif - -.for A in $(RC_ARCHS) +$(FRAMEWORKS): + $(SRCROOT)/patchHeaders $(FRAMEWORKPATH)/$(PRIVATEHEADERPATH) $(FRAMEWORKS)/$(PRIVATEHEADERPATH:H) + ln -fs $(VERSIONSB)/PrivateHeaders $(FRAMEWORKS)/$(SYSTEMFRAMEWORK)/PrivateHeaders + +AUTOPATCHED = $(SRCROOT)/.autopatched +PARTIAL = -partial +.for F in $(FORMS) # { +.if $(dynamic) == $(F) # { +SUFFIX-$(F) = +.else # } { +SUFFIX-$(F) = _$(F) +.endif # } +PSUFFIX-$(F) = $(PARTIAL)$(SUFFIX-$(F)) + +.for A in $(RC_ARCHS) # { +.if empty(DONT-BUILD-$(A)-$(F)) # { +ARCHS-$(F) += $(A) build-$(A)-$(F): mkdir -p $(OBJROOT)/obj.$(A) && \ MAKEOBJDIR="$(OBJROOT)/obj.$(A)" MACHINE_ARCH="$(A)" \ - MAKEFLAGS="" CFLAGS="-arch $(A) $(LOCAL_CFLAGS)" $(BSDMAKEJ) libc$(SUFFIX$(F)).a -.endfor # RC_ARCHS -.endfor # FORMS - -# We have to separately call bsdmake to patch the FreeBSD files, because of -# the way its cache works, it would otherwise pick A file in ${SYMROOT}, even -# over A .s file. -autopatch: -.for A in $(RC_ARCHS) - MACHINE_ARCH="$(A)" $(BSDMAKEJ) autopatch -.endfor # RC_ARCHS - -installsrc: - pax -rw . "$(SRCROOT)" - -installhdrs-real: $(CC_PRINT_OPTIONS_FILE) + DSTROOT=$(DSTROOT) OBJROOT=$(OBJROOT) SYMROOT=$(SYMROOT) \ + MAKEFLAGS="" CFLAGS="-arch $(A) $(LOCAL_CFLAGS)" $(BSDMAKEJ) libc$(SUFFIX-$(F)).a +.else # } { +build-$(A)-$(F): + @echo Not building libc$(PSUFFIX-$(F)).a for $(A) +.endif # } +.endfor # RC_ARCHS } + +NARCHS-$(F) != echo $(ARCHS-$(F)) | wc -w + +build-$(F): $(FRAMEWORKS) $(AUTOPATCHED) +.for A in $(RC_ARCHS) # { +build-$(F): build-$(A)-$(F) +.endfor # RC_ARCHS } +.if $(NARCHS-$(F)) == 0 # { +build-$(F): + @echo No libc$(PSUFFIX-$(F)).a built +.else # } { +LIPOARGS-$(F) != perl -e 'printf "%s\n", join(" ", map(qq(-arch $$_ \"$(OBJROOT)/obj.$$_/libc$(SUFFIX-$(F)).a\"), qw($(ARCHS-$(F)))))' +build-$(F): +.if $(NARCHS-$(F)) == 1 # { + cp -p "$(OBJROOT)/obj.$(RC_ARCHS)/libc$(SUFFIX-$(F)).a" "$(SYMROOT)/libc$(PSUFFIX-$(F)).a" +.else # } { + lipo -create $(LIPOARGS-$(F)) -output "$(SYMROOT)/libc$(PSUFFIX-$(F)).a" +.endif # } +.endif # } +.endfor # FORMS } + +# We autopatch the files into the directory containing the Makefile.inc. This +# will happen at installsrc. +$(AUTOPATCHED): + @set -x && \ + for m in `find $(SRCROOT) -name Makefile.inc`; do \ + cd `dirname $$m` && \ + bsdmake -I $(SRCROOT) -f $(SRCROOT)/Makefile.inc -f Makefile.inc -f $(SRCROOT)/Makefile.autopatch autopatch LIB=c SRCROOT=$(SRCROOT) || \ + exit 1; \ + done + touch $(AUTOPATCHED) + +copysrc: + pax -rw -p p . "$(SRCROOT)" + +installsrc: copysrc $(AUTOPATCHED) + +installhdrs-real: MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)" MAKEFLAGS="" \ - $(BSDMAKEJ) installhdrs -.for A in $(RC_ARCHS) + DSTROOT=$(DSTROOT) OBJROOT=$(OBJROOT) SYMROOT=$(SYMROOT) \ + $(BSDMAKEJ) installhdrs +.for A in $(RC_ARCHS) # { mkdir -p "$(OBJROOT)/obj.$(A)" && \ MAKEOBJDIR="$(OBJROOT)/obj.$(A)" MACHINE_ARCH="$(A)" \ - MAKEFLAGS="" $(BSDMAKEJ) installhdrs-md -.endfor # RC_ARCHS + DSTROOT=$(DSTROOT) OBJROOT=$(OBJROOT) SYMROOT=$(SYMROOT) \ + MAKEFLAGS="" $(BSDMAKEJ) installhdrs-md +.endfor # RC_ARCHS # } -.for F in $(FORMS) +.for F in $(FORMS) # { BI-install-$(F): build-$(F) mkdir -p $(DSTROOT)/usr/local/lib/system - if [ -f "$(SYMROOT)/libc$(SUFFIX$(F)).a" ]; then \ - echo "Installing libc$(SUFFIX$(F)).a" && \ - install -c -m 444 "$(SYMROOT)/libc$(SUFFIX$(F)).a" \ + if [ -f "$(SYMROOT)/libc$(PSUFFIX-$(F)).a" ]; then \ + echo "Installing libc$(PSUFFIX-$(F)).a" && \ + install -c -m 444 "$(SYMROOT)/libc$(PSUFFIX-$(F)).a" \ $(DSTROOT)/usr/local/lib/system && \ - ranlib "$(DSTROOT)/usr/local/lib/system/libc$(SUFFIX$(F)).a"; \ + ranlib "$(DSTROOT)/usr/local/lib/system/libc$(PSUFFIX-$(F)).a" || exit 1; \ fi -.if !empty $(RC_ppc) && ($(static) != $(F)) - if [ -f "$(OBJROOT)/obj.ppc/libc-ldbl128$(SUFFIX$(F)).a" ]; then \ - echo "Installing libldbl128$(SUFFIX$(F)).a" ; \ - $(SRCROOT)/make_libldbl128 "$(OBJROOT)/obj.ppc/libc-ldbl128$(SUFFIX$(F)).a" \ - "$(SUFFIX$(F))" "$(DSTROOT)/usr/local/lib/system" $(LIBSYS) ; \ - fi -.endif # RC_ppc && !static -.endfor # FORMS +.if $(dynamic) == $(F) # { +.for A in $(RC_ARCHS) # { + MAKEOBJDIR="$(OBJROOT)/obj.$(A)" MACHINE_ARCH="$(A)" \ + DSTROOT=$(DSTROOT) OBJROOT=$(OBJROOT) SYMROOT=$(SYMROOT) \ + DSTROOT=$(DSTROOT) OBJROOT=$(OBJROOT) SYMROOT=$(SYMROOT) \ + MAKEFLAGS="" $(BSDMAKE) copyfiles +.endfor # RC_ARCHS # } +.endif # } +.endfor # FORMS } # Don't use -j here; it may try to make links before the files are copied +MANARGS != test `id -u` -eq 0 || echo MINSTALL=/usr/bin/install install-man: mkdir -p $(DSTROOT)/usr/share/man/man2 mkdir -p $(DSTROOT)/usr/share/man/man3 mkdir -p $(DSTROOT)/usr/share/man/man4 mkdir -p $(DSTROOT)/usr/share/man/man5 mkdir -p $(DSTROOT)/usr/share/man/man7 - MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)" NOMANCOMPRESS=1 \ - MACHINE_ARCH="$(ARCH)" MAKEFLAGS="" $(BSDMAKE) autopatchman maninstall + MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)" \ + DSTROOT='$(DSTROOT)' OBJROOT='$(OBJROOT)' SYMROOT='$(SYMROOT)' \ + MACHINE_ARCH="$(ARCH)" MAKEFLAGS="" \ + $(BSDMAKE) autopatchman all-man maninstall $(MANARGS) install-all: build install-man -.for F in $(FORMS) +.for F in $(FORMS) # { install-all: BI-install-$(F) -.endfor # FORMS +.endfor # FORMS } clean: -.for F in $(FORMS) - rm -f $(OBJROOT)/libc$(SUFFIX$(F)).a -.endfor # FORMS -.for A in $(RC_ARCHS) +.for F in $(FORMS) # { + rm -f $(SYMROOT)/libc$(PSUFFIX-$(F)).a +.endfor # FORMS } +.for A in $(RC_ARCHS) # { rm -rf $(OBJROOT)/obj.$(A) -.endfor # RC_ARCHS +.endfor # RC_ARCHS # } diff --git a/CLIB-LIST b/CLIB-LIST deleted file mode 100644 index a7cd26f..0000000 --- a/CLIB-LIST +++ /dev/null @@ -1,682 +0,0 @@ -CIRCLEQ_ENTRY M -CIRCLEQ_HEAD M -CIRCLEQ_INIT M -CIRCLEQ_INSERT_AFTER M -CIRCLEQ_INSERT_BEFORE M -CIRCLEQ_INSERT_HEAD M -CIRCLEQ_INSERT_TAIL M -CIRCLEQ_REMOVE M -LIST_ENTRY M -LIST_HEAD M -LIST_INIT M -LIST_INSERT_AFTER M -LIST_REMOVE M -TAILQ_ENTRY M -TAILQ_HEAD M -TAILQ_INIT M -TAILQ_INSERT_AFTER M -TAILQ_INSERT_HEAD M -TAILQ_INSERT_TAIL M -TAILQ_REMOVE M -_longjmp -_setjmp -abort -abs -acl_add -acl_canocicalize_principal -acl_check -acl_delete -acl_exact_match -acl_initialize -acos -acosh -addch -addstr -alarm -alloca -alphasort -arc -asctime -asin -asinh -assert -atan -atan2 -atanh -atexit -atof -atoi -atol -bcmp -bcopy -bit_alloc M -bit_clear M -bit_decl M -bit_ffc M -bit_ffs M -bit_nclear M -bit_nset M -bit_test M -bitstr_size M -box -bsearch -bypot -bzero -cabs -calloc -catclose -catgets -catopen -cbreak -cbrt -ceil -cfgetispeed -cfgetospeed -cfmakeraw -cfsetispeed -cfsetospeed -cfsetspeed -cgetcap -cgetclose -cgetent -cgetfirst -cgetmatch -cgetnext -cgetnum -cgetset -cgetstr -cgetustr -circle -clear -clearerr -clearok -clock -closedir -closelog -closepl -clrtobot -clrtoeol -confstr -cont -copysign -cos -cosh -crypt -ctermid -ctime -daemon -dbopen -delch -delwin -des_cbc_cksum -des_cbc_encrypt -des_cipher -des_ecb_encrypt -des_pcbc_encrypt -des_quad_cksum -des_random_key -des_read_password -des_set_key -des_setkey -des_string_to_key -devanme -diffti8me -dirfd -div -dleteln -dn_comp -dn_expand -drem -echo -ectv -edata -encrypt -end -endfsent -endgrent -endhostent -endnetent -endnetgrent -endprotoent -endpwent -endservent -endttyent -endusershell -endwin -er -erase -erf -erfc -err -errx -etext -etfc -execl -execle -execlp -exect -execv -execvp -exit -exp -expm1 -fabs -fclose -fctv -fdopen -feof -ferror -fflush -ffs -fgetc -fgetline -fgetln -fgetpos -fgets -fileno -finite -floor -flusok -fmin MP -fmod -fmount MP -fnmatch -fopen -fprintf -fpurge -fputc -fputs -fread -free -freopen -frexp -fropen -fscanf -fseek -fsetpos -ftell -ftime -fts_children -fts_close -fts_open -fts_read -fts_set -funopen -fwopen -fwrite -gamma -gcd MP -gctv -getbsize -getc -getcap -getch -getchar -getcwd -getdiskbyname -getenv -getfsent -getfsfile -getfsspec -getgrent -getgrgid -getgrnam -getgrouplist -gethostbyaddr -gethostbyname -gethostent -gethostid -gethostname -getloadavg -getmntinfo -getmntopts -getmode -getnetbyaddr -getnetbyname -getnetent -getnetgrent -getopt -getpagesize -getpass -getprotobyname -getprotobynumber -getprotoent -getpw -getpwent -getpwnam -getpwuid -gets -getservbyname -getservbyport -getservent -getstr -getsubopt -gettmode -getttyent -getttynam -getusershell -getw -getwd -getyx -glob -globfree -gmtime -group_from_gid -gtty -heapsort -herror -htonl -htons -hypot -inch -index -inet_addr -inet_aton -inet_lnaof -inet_makeaddr -inet_netof -inet_network -inet_ntoa -infnan -initgroups -initscr -initstate -innetgr -insch -insetln -insque -invert MP -isalnum -isalpha -isascii -isatty -isblank -iscntrl -isdigit -isgraph -isinf -islower -isnan -iso_addr -iso_ntoa -isprint -ispunct -isspace -isupper -isxdigit -itom MP -j0 -j1 -jn -krb_err_txt -krb_get_admhst -krb_get_cred -krb_get_krbhst -krb_get_lrealm -krb_get_phost -krb_kntoln -krb_mk_err -krb_mk_priv -krb_mk_req -krb_mk_safe -krb_net_read -krb_net_write -krb_rd_err -krb_rd_priv -krb_rd_req -krb_rd_safe -krb_realmofhost -krb_recvauth -krb_sendauth -krb_set_key -krb_set_tkt_string -kuserok -kvm_close -kvm_getargv -kvm_getenvv -kvm_geterr -kvm_getfiles -kvm_getloadavg -kvm_getprocs -kvm_nlist -kvm_open -kvm_openfiles -kvm_read -kvm_write -label -labs -ldexp -ldiv -leaveok -lfind -lgamma -line -linemod -link_addr -link_ntoa -localeconv -localtime -log -log10 -log1p -logb -longjmp -longjmperror -longname -lsearch -m_in MP -m_out MP -madd MP -malloc -mamcpy -mblen -mbmb -mbrrune -mbrune -mbstowcs -mbtowc -mcmp MP -mdiv MP -memccpy -memchr -memcmp -memcpy -memmove -memset -mergesort -min MP -mkstemp -mktemp -mktime -modf -moncontrol -monstartup -mount MP -move -move MP -mpool_close -mpool_filter -mpool_get -mpool_new -mpool_open -mpool_put -mpool_sync -msqrt MP -msub MP -mult MP -mvcur -newein -nice -nl -nlist -nocbreak -noecho -nonl -noraw -ns_addr -ns_ntoa -ntohl -ntohs -omin MP -omount MP -opendir -openlog -openpl -optarg -opterr -optind -optopt -optreset -overlay -overwrite -pause -pclose -perror -point -popen -pow -pow MP -printf -printw -psignal -putc -putchar -putenv -puts -putw -qsort -radixsort -raise -rand -random -raw -rcmd -re_comp -re_exec -readdir -realloc -realpath -refresh -regcomp -regerror -regexec -regfree -regsub -remove -remque -res_init -res_mkquery -res_query -res_send -res_serach -resetty -rewind -rewinddir -rexec -rindex -rint -rpow MP -rresvport -ruserok -savetty -scalb -scandir -scanf -scanw -scroll -scrollok -sdiv MP -seekdir -setbuf -setbuffer -setenv -setfsent -setgrent -setgroupent -sethostent -sethostid -sethostname -setinvalidrunt -setjmp -setkey -setlinebuf -setlocale -setlogmask -setmode -setnetent -setnetgrent -setpassent -setprotoent -setpwent -setrgid -setruid -setrunelocale -setservent -setstate -setterm -setttyent -setusershell -setvbuf -sgetrune -sigaddset -sigdelset -sigemptyset -sigfillset -siginterrupt -sigismember -siglongjmp -signal -signgam -sigsetjmp -sin -sinh -sleep -snprintf -space -sprintf -sputrune -sqrt -sradixsort -srand -sreandom -sscanf -standend -standout -stderr -stdin -stdout -strcasecmp -strcat -strchr -strcmp -strcoll -strcpy -strcspn -strdup -strerror -strftime -strlen -strmode -strncasecmp -strncat -strncmp -strncpy -strpbrk -strrchr -strsep -strspc -strspn -strstr -strtod -strtok -strtol -strtoq -strtoul -strtouq -strunvis -strvis -strvisx -strxfrm -stty -subwin -swab -sys_errlist -sys_nerr -sys_siglist -sys_signame -sysconf -sysctl -syslog -system -tan -tanh -tcdrain -tcflow -tcflush -tcgetattr -tcgetpgrp -tcsendbreak -tcsetattr -tcsetpgrp -telldir -tempnam -tf_close -tf_get_cred -tf_get_pinst -tf_get_pname -tf_init -tgetent -tgetflag -tgetnum -tgetstr -tgoto -time -times -timezone -tmpfile -tmpnam -toascii -tolower -touchline -touchoverlap -touchwin -toupper -tputs -ttynam -ttyslot -tzset -tzsetwall -ualarm -uname -unctrl -ungetc -unsetenv -unvis -user_from_uid -usleep -utime -va_arg M -va_end M -va_start M -valloc -verr -verrx -vfprintf -vfscanf -vis -vlimit -vprintf -vscanf -vsnprintf -vsprintf -vsscanf -vsyslog -vtimes -vwarn -vwarnx -waddch -waddstr -warn -warnx -wclear -wclreol -wclrtobot -wcstombs -wctomb -wdelch -wdeleteln -werase -wgetch -wgetstr -winch -winsch -winsertln -wmove -wprintw -wrefreash -wscanw -wstandend -wstandout -y0 -y1 -yn diff --git a/MISSING-MANPAGE b/MISSING-MANPAGE deleted file mode 100644 index 6aa16bd..0000000 --- a/MISSING-MANPAGE +++ /dev/null @@ -1,9 +0,0 @@ -creat (obsoleted by open) -killpg -ptarce -setregid -setreuid -sigblock (obsoleted by sigprocmask) -sigpause (obsoleted by sigsuspend) -sigsetmask (obsoleted by sigprocmask) -sigvec (obsoleted by sigaction) diff --git a/MISSING_SYSCALLS b/MISSING_SYSCALLS deleted file mode 100644 index 2cb3246..0000000 --- a/MISSING_SYSCALLS +++ /dev/null @@ -1,8 +0,0 @@ -madvise UNIX -mincore UNIX -mlock UNIX -mprotect UNIX -msync UNIX -munlock UNIX -sigpending POSIX -sigstack compat[sigaltstack] diff --git a/Makefile b/Makefile index d8357bc..34a4b2d 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,6 @@ # @(#)Makefile 8.2 (Berkeley) 2/3/94 # $FreeBSD: src/lib/libc/Makefile,v 1.31 2001/08/13 21:48:43 peter Exp $ # -# All library objects contain rcsid strings by default; they may be -# excluded as a space-saving measure. To produce a library that does -# not contain these strings, delete -DLIBC_RCS and -DSYSLIBC_RCS -# from CFLAGS below. To remove these strings from just the system call -# stubs, remove just -DSYSLIBC_RCS from CFLAGS. -# # Yes, we build everything with -g, and strip it out later... # # -faltivec now disables inlining, so we can't use it globally. Fortunately, @@ -23,26 +17,19 @@ MACHINE_ARCH != /usr/bin/arch LP64 = 1 .endif CC = gcc-4.0 -# always set __DARWIN_UNIX03 to zero (variant will set to one) except for ppc64 -.ifdef LP64 -CFLAGS += -D__DARWIN_UNIX03=1 -.else -CFLAGS += -D__DARWIN_UNIX03=0 -.endif -CFLAGS += -D__LIBC__ -DNOID -I${.CURDIR}/include +CFLAGS += -D__LIBC__ -D__DARWIN_UNIX03=1 -D__DARWIN_64_BIT_INO_T=1 -D__DARWIN_NON_CANCELABLE=1 -D__DARWIN_VERS_1050=1 +CFLAGS += -DNOID -I${.CURDIR}/include -std=gnu99 .ifdef ALTLIBCHEADERS INCLUDEDIR = ${ALTLIBCHEADERS} -CFLAGS += -I${INCLUDEDIR} +LIBCFLAGS += -I${INCLUDEDIR} .endif -.ifdef ALTFRAMEWORKSPATH -PRIVINC = -F${ALTFRAMEWORKSPATH} -I${ALTFRAMEWORKSPATH}/System.framework/PrivateHeaders -.else -PRIVINC = -I${NEXT_ROOT}/System/Library/Frameworks/System.framework/PrivateHeaders -.endif -CFLAGS += ${PRIVINC} +LIBCFLAGS += -I$(SRCROOT)/include -include _.libc_internal.h +FRAMEWORKS = ${OBJROOT}/Frameworks +PRIVATEHEADERS = ${FRAMEWORKS}/System.framework/PrivateHeaders +PRIVINC = -F${FRAMEWORKS} -I${PRIVATEHEADERS} +CFLAGS += ${PRIVINC} -I${.OBJDIR} CFLAGS += -DLIBC_MAJOR=${SHLIB_MAJOR} -no-cpp-precomp -force_cpusubtype_ALL CFLAGS += -fno-common -pipe -Wmost -g -D__FBSDID=__RCSID -CFLAGS += -finline-limit=1500 --param inline-unit-growth=200 -Winline AINC= -I${.CURDIR}/${MACHINE_ARCH} -no-cpp-precomp -force_cpusubtype_ALL AINC+=-arch ${MACHINE_ARCH} -g CLEANFILES+=tags @@ -52,12 +39,9 @@ PRECIOUSLIB= yes # workaround for 3649783 AINC += -fdollars-in-identifiers -# ppc64 optimizer still blows up on some files, so we use -O0 to turn it -# off on a per file basis -.if (${MACHINE_ARCH} == ppc64) -OPTIMIZE-acl_entry.c = -O0 -# glob-fbsd.c fails with -static -Os (3869444) so turn off optimization -OPTIMIZE-glob-fbsd.c = -O0 +# workaround for 4268581 +.if make(lib${LIB}_static.a) +OPTIMIZE-glob-fbsd.c += -O0 .endif # If these aren't set give it expected defaults @@ -71,9 +55,12 @@ _x_ != test -d ${SYMROOT} || mkdir -p ${SYMROOT} DESTDIR ?= ${DSTROOT} MAKEOBJDIR ?= ${OBJROOT} -CFLAGS += -I${SYMROOT} +# add version string +SRCS += libc_version.c +libc_version.c: + /Developer/Makefiles/bin/version.pl Libc > $@ + .include "${.CURDIR}/Makefile.inc" -.PATH: ${SYMROOT} .include "Makefile.xbs" .if exists(/usr/share/mk/bsd.init.mk) .include diff --git a/Makefile.autopatch b/Makefile.autopatch new file mode 100644 index 0000000..2d62585 --- /dev/null +++ b/Makefile.autopatch @@ -0,0 +1,6 @@ +autopatch: $(AUTOPATCHHDRS) $(AUTOPATCHSRCS) $(AUTOPATCHMAN) + +.SUFFIXES: .3-uuid.in .3 + +.3-uuid.in.3: + sed -f ${SRCROOT}/uuid/uuidman.sed ${.IMPSRC} > ${.TARGET} diff --git a/Makefile.fbsd_begin b/Makefile.fbsd_begin index f64f188..2bc1c24 100644 --- a/Makefile.fbsd_begin +++ b/Makefile.fbsd_begin @@ -21,4 +21,5 @@ FBSDMAN9= FBSDMDSRCS= FBSDMISRCS= FBSDHDRS= +FBSDPATCHSRCS= FBSDSRCS= diff --git a/Makefile.fbsd_end b/Makefile.fbsd_end index 9b43be0..0a279b7 100644 --- a/Makefile.fbsd_end +++ b/Makefile.fbsd_end @@ -13,32 +13,55 @@ FBSDSECTIONS= 1 2 3 4 5 6 7 8 9 .for _src in ${FBSDSRCS} -${SYMROOT}/${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _AUTOPATCHSYM +.ifmake autopatch +${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-fbsd.${_src:E} +.else # !autopatch SRCS+= ${_src} -AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-fbsd.${_src:E} +.endif # autopatch .endfor .for _src in ${FBSDMDSRCS} -${SYMROOT}/${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _AUTOPATCHSYM +.ifmake autopatch +${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-fbsd.${_src:E} +.else # !autopatch MDSRCS+= ${_src} -AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-fbsd.${_src:E} +.endif # autopatch .endfor .for _src in ${FBSDMISRCS} -${SYMROOT}/${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _AUTOPATCHSYM +.ifmake autopatch +${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-fbsd.${_src:E} +.else # !autopatch MISRCS+= ${_src} -AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-fbsd.${_src:E} +.endif # autopatch .endfor +# FBSDPATCHSRCS are for source that need patching, but don't build +# in base variant (only in other variants) +.ifmake autopatch +.for _src in ${FBSDPATCHSRCS} +${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-fbsd.${_src:E} +.endfor +.endif # autopatch + +.ifmake autopatch .for _src in ${FBSDHDRS} -${SYMROOT}/${_src}: FreeBSD/${_src} _AUTOPATCHSYM -AUTOPATCHHDRS+= ${SYMROOT}/${_src} +${_src}: FreeBSD/${_src} _AUTOPATCHCUR +AUTOPATCHHDRS+= ${_src} .endfor +.endif # autopatch .for _sect in ${FBSDSECTIONS} .for _src in ${FBSDMAN${_sect}} +.ifmake autopatch ${_src}: FreeBSD/${_src} _AUTOPATCH -MAN${_sect}+= ${_src} AUTOPATCHMAN+= ${_src} +.else # !autopatch +MAN${_sect}+= ${_src} +.endif # autopatch .endfor .endfor diff --git a/Makefile.inc b/Makefile.inc index b77ee57..ab0eca2 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -31,15 +31,55 @@ _AUTOPATCH: .USE echo ln -s ${.ALLSRC} ${.TARGET}; \ ln -s ${.ALLSRC} ${.TARGET}; \ fi -# Auto-patch into SYMROOT -_AUTOPATCHSYM: .USE +# Auto-patch into current directory +_AUTOPATCHCUR: .USE @echo cp ${.ALLSRC} ${.TARGET}; \ cp ${.ALLSRC} ${.TARGET}; \ if [ -f ${.ALLSRC}.patch ]; then \ echo patch ${.TARGET} ${.ALLSRC}.patch; \ patch ${.TARGET} ${.ALLSRC}.patch; \ fi +# Standard compilation for the various forms +_STANDARD_STATIC: .USE + ${CC} -static \ + ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${LIBCFLAGS} \ + -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} +_STANDARD_PROFILE: .USE + ${CC} -pg -DPROFILE \ + ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${LIBCFLAGS} \ + -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} +_STANDARD_DYNAMIC: .USE + ${CC} \ + ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${LIBCFLAGS} \ + -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} +_STANDARD_DEBUG: .USE + ${CC} -g -DDEBUG \ + ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${LIBCFLAGS} \ + -c ${.IMPSRC} -o ${.TARGET} +# set object file suffix +.if make(lib${LIB}_static.a) +OBJSUFFIX = o +.endif +.if make(lib${LIB}_profile.a) +OBJSUFFIX = po +.endif +.if make(lib${LIB}_debug.a) +OBJSUFFIX = do +.endif +.if make(lib${LIB}.a) +OBJSUFFIX = So +.endif + +.ifnmake autopatch # # If there is a machine dependent makefile, use it: # @@ -57,15 +97,13 @@ _AUTOPATCHSYM: .USE .include "${.CURDIR}/include/Makefile.inc" .include "${.CURDIR}/internat/Makefile.inc" .include "${.CURDIR}/locale/Makefile.inc" -.include "${.CURDIR}/mach/Makefile.inc" +.include "${.CURDIR}/man/Makefile.inc" .include "${.CURDIR}/net/Makefile.inc" .include "${.CURDIR}/nls/Makefile.inc" .include "${.CURDIR}/posix1e/Makefile.inc" .include "${.CURDIR}/pthreads/Makefile.inc" -.if !defined(NO_QUAD) -#.include "${.CURDIR}/quad/Makefile.inc" -.endif .include "${.CURDIR}/regex/Makefile.inc" +.include "${.CURDIR}/secure/Makefile.inc" .include "${.CURDIR}/stdio/Makefile.inc" .include "${.CURDIR}/stdlib/Makefile.inc" .include "${.CURDIR}/stdtime/Makefile.inc" @@ -74,15 +112,6 @@ _AUTOPATCHSYM: .USE .include "${.CURDIR}/threads/Makefile.inc" .include "${.CURDIR}/util/Makefile.inc" .include "${.CURDIR}/uuid/Makefile.inc" -#.include "${.CURDIR}/rpc/Makefile.inc" -#.include "${.CURDIR}/xdr/Makefile.inc" -#.if !defined(NO_YP_LIBC) -#CFLAGS+= -DYP -#.include "${.CURDIR}/yp/Makefile.inc" -#.endif -#.if !defined(NO_HESIOD_LIBC) -#CFLAGS+= -DHESIOD -#.endif # If there are no machine dependent sources, append all the # machine-independent sources: @@ -99,3 +128,4 @@ SRCS+= ${_src} .endif .endfor .endif +.endif # !autopatch diff --git a/Makefile.nbsd_end b/Makefile.nbsd_end index 7e75dc5..c988964 100644 --- a/Makefile.nbsd_end +++ b/Makefile.nbsd_end @@ -13,32 +13,46 @@ NBSDSECTIONS= 1 2 3 4 5 6 7 8 9 .for _src in ${NBSDSRCS} -${SYMROOT}/${_src:R}-nbsd.${_src:E}: NetBSD/${_src} _AUTOPATCHSYM +.ifmake autopatch +${_src:R}-nbsd.${_src:E}: NetBSD/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-nbsd.${_src:E} +.else # !autopatch SRCS+= ${_src} -AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-nbsd.${_src:E} +.endif # autopatch .endfor .for _src in ${NBSDMDSRCS} -${SYMROOT}/${_src:R}-nbsd.${_src:E}: NetBSD/${_src} _AUTOPATCHSYM +.ifmake autopatch +${_src:R}-nbsd.${_src:E}: NetBSD/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-nbsd.${_src:E} +.else # !autopatch MDSRCS+= ${_src} -AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-nbsd.${_src:E} +.endif # autopatch .endfor .for _src in ${NBSDMISRCS} -${SYMROOT}/${_src:R}-nbsd.${_src:E}: NetBSD/${_src} _AUTOPATCHSYM +.ifmake autopatch +${_src:R}-nbsd.${_src:E}: NetBSD/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-nbsd.${_src:E} +.else # !autopatch MISRCS+= ${_src} -AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-nbsd.${_src:E} +.endif # autopatch .endfor +.ifmake autopatch .for _src in ${NBSDHDRS} -${SYMROOT}/${_src}: NetBSD/${_src} _AUTOPATCHSYM -AUTOPATCHHDRS+= ${SYMROOT}/${_src} +${_src}: NetBSD/${_src} _AUTOPATCHCUR +AUTOPATCHHDRS+= ${_src} .endfor +.endif # autopatch .for _sect in ${NBSDSECTIONS} .for _src in ${NBSDMAN${_sect}} +.ifmake autopatch ${_src}: NetBSD/${_src} _AUTOPATCH -MAN${_sect}+= ${_src} AUTOPATCHMAN+= ${_src} +.else # !autopatch +MAN${_sect}+= ${_src} +.endif # autopatch .endfor .endfor diff --git a/Makefile.obsd_end b/Makefile.obsd_end index 661dcc8..801a018 100644 --- a/Makefile.obsd_end +++ b/Makefile.obsd_end @@ -13,32 +13,46 @@ OBSDSECTIONS= 1 2 3 4 5 6 7 8 9 .for _src in ${OBSDSRCS} -${SYMROOT}/${_src:R}-obsd.${_src:E}: OpenBSD/${_src} _AUTOPATCHSYM +.ifmake autopatch +${_src:R}-obsd.${_src:E}: OpenBSD/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-obsd.${_src:E} +.else # !autopatch SRCS+= ${_src} -AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-obsd.${_src:E} +.endif # autopatch .endfor .for _src in ${OBSDMDSRCS} -${SYMROOT}/${_src:R}-obsd.${_src:E}: OpenBSD/${_src} _AUTOPATCHSYM +.ifmake autopatch +${_src:R}-obsd.${_src:E}: OpenBSD/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-obsd.${_src:E} +.else # !autopatch MDSRCS+= ${_src} -AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-obsd.${_src:E} +.endif # autopatch .endfor .for _src in ${OBSDMISRCS} -${SYMROOT}/${_src:R}-obsd.${_src:E}: OpenBSD/${_src} _AUTOPATCHSYM +.ifmake autopatch +${_src:R}-obsd.${_src:E}: OpenBSD/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-obsd.${_src:E} +.else # !autopatch MISRCS+= ${_src} -AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-obsd.${_src:E} +.endif # autopatch .endfor +.ifmake autopatch .for _src in ${OBSDHDRS} -${SYMROOT}/${_src}: OpenBSD/${_src} _AUTOPATCHSYM -AUTOPATCHHDRS+= ${SYMROOT}/${_src} +${_src}: OpenBSD/${_src} _AUTOPATCHCUR +AUTOPATCHHDRS+= ${_src} .endfor +.endif # autopatch .for _sect in ${OBSDSECTIONS} .for _src in ${OBSDMAN${_sect}} +.ifmake autopatch ${_src}: OpenBSD/${_src} _AUTOPATCH -MAN${_sect}+= ${_src} AUTOPATCHMAN+= ${_src} +.else # !autopatch +MAN${_sect}+= ${_src} +.endif # autopatch .endfor .endfor diff --git a/Makefile.xbs b/Makefile.xbs index efbfdac..b19c831 100644 --- a/Makefile.xbs +++ b/Makefile.xbs @@ -25,12 +25,13 @@ BSDMAKE = bsdmake -f Makefile .MAIN: all all: libc.a libc_static.a libc_debug.a libc_profile.a install: installhdrs install_libc.a install_libc_static.a \ - install_libc_profile.a install_libc_debug.a autopatchman maninstall + install_libc_profile.a install_libc_debug.a \ + autopatchman maninstall .SUFFIXES: .SUFFIXES: .o .po .So .do .SUFFIXES: .S .s .c .cc .cpp .cxx .m .C -.SUFFIXES: -fbsd.c -nbsd.c -obsd.c -uuid.c .3-uuid.in .3 +.SUFFIXES: -fbsd.c -nbsd.c -obsd.c -uuid.c .SUFFIXES: .f .y .l .defs .h .SUFFIXES: User.c User.o User.po User.So User.do .SUFFIXES: Server.c Server.o Server.po Server.So Server.do @@ -40,30 +41,6 @@ DOBJS+= ${OBJS:.o=.do} POBJS+= ${OBJS:.o=.po} ${STATICOBJS:.o=.po} SOBJS+= ${OBJS:.o=.So} -#### 128-bit Long Double libc-ldbl128 for Panther #################### -.if (${MACHINE_ARCH} == ppc) -LIB128= ${LIB}-ldbl128 -LDBL_128_SRCS= _hdtoa.c _ldbl_util.c _ldtoa.c asprintf.c err.c fprintf.c \ - fscanf.c fwprintf.c fwscanf.c gdtoa-strtopdd.c machdep_ldisdd.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 vprintf.c \ - vscanf.c vsnprintf.c vsprintf.c vsscanf.c vswprintf.c vswscanf.c \ - vwprintf.c vwscanf.c wcstold.c wprintf.c wscanf.c \ - oldldbl64.s oldsyslog.c LDBL/oldsyslog-LDBL.c \ - LDBL/err-LDBL.c LDBL/vfprintf-LDBL.c LDBL/vfwprintf-LDBL.c -LDBL_128_OBJS= ${LDBL_128_SRCS:R:S/$/.o/g} -LDBL_128_DOBJS= ${LDBL_128_OBJS:.o=.do} -LDBL_128_POBJS= ${LDBL_128_OBJS:.o=.po} -LDBL_128_SOBJS= ${LDBL_128_OBJS:.o=.So} - -LDBLSRCS2+= oldsyslog.c -SRCS2+= oldldbl64.s oldsyslog.c -OBJS2+= ${SRCS2:N*.h:R:S/$/.o/g} -DOBJS2+= ${OBJS2:.o=.do} -POBJS2+= ${OBJS2:.o=.po} -SOBJS2+= ${OBJS2:.o=.So} -.endif - #### Variant Rules #################################################### # The following magic is used for variants to avoid the exponental explosion # of suffix rules. To add a variant, select a name (typically all-caps). @@ -80,20 +57,23 @@ SOBJS2+= ${OBJS2:.o=.So} # specify sources that will build with both the CFLAGS_XXX and CFLAGS_YYY # flags set. The variants are always in alphabetic order. # -VARIANTS= +VARIANTS= DARWINEXTSN INODE32 CANCELABLE PRE1050 # Append the 64-bit long double sources (ppc only) .if (${MACHINE_ARCH} == ppc) VARIANTS+= LDBL MDSRCS += ldbl64.s .endif -# build UNIX03 variant except on LP64 +# build LEGACY variant except on LP64 .ifndef LP64 -VARIANTS+= UNIX03 +VARIANTS+= LEGACY .endif -CFLAGS+= ${VARIANTCFLAGS} -CFLAGS_UNIX03= -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=1 +CFLAGS_LEGACY= -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0 -U__DARWIN_64_BIT_INO_T -D__DARWIN_64_BIT_INO_T=0 -DVARIANT_LEGACY CFLAGS_LDBL= -mlong-double-64 -DLDBL_COMPAT +CFLAGS_DARWINEXTSN= -DVARIANT_DARWINEXTSN +CFLAGS_INODE32= -U__DARWIN_64_BIT_INO_T -D__DARWIN_64_BIT_INO_T=0 -DVARIANT_INODE32 +CFLAGS_CANCELABLE= -DVARIANT_CANCELABLE +CFLAGS_PRE1050= -U__DARWIN_VERS_1050 -D__DARWIN_VERS_1050=0 -DVARIANT_PRE1050 .for _v in ${VARIANTS} COMBOARGS+= ${_v}/${CFLAGS_${_v}} @@ -153,101 +133,170 @@ VARIANTDOBJS+= ${VARIANTOBJS:.o=.do} VARIANTPOBJS+= ${VARIANTOBJS:.o=.po} VARIANTSOBJS+= ${VARIANTOBJS:.o=.So} #### FreeBSD Rules ################################################## -FBSDFLAGS= -I${.CURDIR}/fbsdcompat -include _fbsd_compat_.h +PREFBSDFLAGS= -I${.CURDIR}/fbsdcompat +FBSDFLAGS= -include _fbsd_compat_.h -fbsd.c.o: - ${CC} -static ${FBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -static \ + ${PREFBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${FBSDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -fbsd.c.po: - ${CC} -pg -DPROFILE ${FBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -pg -DPROFILE \ + ${PREFBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${FBSDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -fbsd.c.So: - ${CC} ${FBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} \ + ${PREFBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${FBSDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -fbsd.c.do: - ${CC} -g -DDEBUG ${FBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -g -DDEBUG \ + ${PREFBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${FBSDFLAGS} ${LIBCFLAGS} \ -c ${.IMPSRC} -o ${.TARGET} #### NetBSD Rules ################################################## -NBSDFLAGS= -I${.CURDIR}/nbsdcompat -include _nbsd_compat_.h +PRENBSDFLAGS= -I${.CURDIR}/nbsdcompat +NBSDFLAGS= -include _nbsd_compat_.h -nbsd.c.o: - ${CC} -static ${NBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -static \ + ${PRENBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${NBSDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -nbsd.c.po: - ${CC} -pg -DPROFILE ${NBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -pg -DPROFILE \ + ${PRENBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${NBSDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -nbsd.c.So: - ${CC} ${NBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} \ + ${PRENBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${NBSDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -nbsd.c.do: - ${CC} -g -DDEBUG ${NBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -g -DDEBUG \ + ${PRENBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${NBSDFLAGS} ${LIBCFLAGS} \ -c ${.IMPSRC} -o ${.TARGET} #### OpenBSD Rules ################################################## +PREOBSDFLAGS= OBSDFLAGS= -obsd.c.o: - ${CC} -static ${OBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -static \ + ${PREOBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${OBSDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -obsd.c.po: - ${CC} -pg -DPROFILE ${OBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -pg -DPROFILE \ + ${PREOBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${OBSDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -obsd.c.So: - ${CC} ${OBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} \ + ${PREOBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${OBSDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -obsd.c.do: - ${CC} -g -DDEBUG ${OBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -g -DDEBUG \ + ${PREOBSDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${OBSDFLAGS} ${LIBCFLAGS} \ -c ${.IMPSRC} -o ${.TARGET} #### UUID Rules ###################################################### -UUIDFLAGS= -I${.CURDIR}/uuid -include uuid-config.h +PREUUIDFLAGS= -I${.CURDIR}/uuid +UUIDFLAGS= -include uuid-config.h -uuid.c.o: - ${CC} -static ${UUIDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -static \ + ${PREUUIDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${UUIDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -uuid.c.po: - ${CC} -pg -DPROFILE ${UUIDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -pg -DPROFILE \ + ${PREUUIDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${UUIDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -uuid.c.So: - ${CC} ${UUIDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} \ + ${PREUUIDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${UUIDFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} -uuid.c.do: - ${CC} -g -DDEBUG ${UUIDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -g -DDEBUG \ + ${PREUUIDFLAGS} ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${UUIDFLAGS} ${LIBCFLAGS} \ -c ${.IMPSRC} -o ${.TARGET} -.3-uuid.in.3: - sed -f ${.CURDIR}/uuid/uuidman.sed ${.IMPSRC} > ${.TARGET} #### Standard C Rules ################################################# +# If you change any of these standard rule, make corresponding changes +# to the _STANDARD_* macros in Makefile.inc +####################################################################### .c.o User.cUser.o Server.cServer.o: - ${CC} -static ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -static \ + ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} .c.po User.cUser.po Server.cServer.po: - ${CC} -pg -DPROFILE ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -pg -DPROFILE \ + ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} .c.So User.cUser.So Server.cServer.So: - ${CC} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} \ + ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${LIBCFLAGS} \ -Os ${OPTIMIZE-${.IMPSRC:T}} -c ${.IMPSRC} -o ${.TARGET} .c.do User.cUser.do Server.cServer.do: - ${CC} -g -DDEBUG ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${CC} -g -DDEBUG \ + ${PRECFLAGS} ${PRECFLAGS-${.IMPSRC:T}} \ + ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \ + ${VARIANTCFLAGS} ${LIBCFLAGS} \ -c ${.IMPSRC} -o ${.TARGET} #### Standard Assembler Rules ######################################### -.s.o: - ${CC} -static -x assembler-with-cpp ${CFLAGS:M-[BIDF]*} \ - ${CFLAGS-${.IMPSRC:T}:M-[BIDF]*} ${AINC} \ +.s.o .S.o: + ${CC} -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} -.s.po: - ${CC} -pg -DPROFILE -x assembler-with-cpp ${CFLAGS:M-[BIDF]*} \ - ${CFLAGS-${.IMPSRC:T}:M-[BIDF]*} ${AINC} \ +.s.po .S.po: + ${CC} -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} -.s.So: - ${CC} -x assembler-with-cpp ${CFLAGS:M-[BIDF]*} \ - ${CFLAGS-${.IMPSRC:T}:M-[BIDF]*} ${AINC} \ +.s.So .S.So: + ${CC} -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} -.s.do: - ${CC} -g -DDEBUG -x assembler-with-cpp ${CFLAGS:M-[BIDF]*} \ - ${CFLAGS-${.IMPSRC:T}:M-[BIDF]*} ${AINC} \ +.s.do .S.do: + ${CC} -g -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} #### mig Rules ######################################################## @@ -269,33 +318,18 @@ lib${LIB}_profile.a:: ${VARIANTCOMBOS:S/$/_P/g} ${POBJS} ${POBJS2} @rm -f lib${LIB}_profile.a @${AR} cq lib${LIB}_profile.a `lorder ${POBJS} ${VARIANTPOBJS} | tsort -q` ${ARADD} ${RANLIB} lib${LIB}_profile.a -.if (${MACHINE_ARCH} == ppc) - @${ECHO} building profiled ${LIB128} library - @rm -f lib${LIB128}_profile.a - @${AR} cq lib${LIB128}_profile.a ${LDBL_128_POBJS} -.endif lib${LIB}_debug.a:: ${VARIANTCOMBOS:S/$/_D/g} ${DOBJS} ${DOBJS2} @${ECHO} building debug ${LIB} library @rm -f lib${LIB}_debug.a @${AR} cq lib${LIB}_debug.a `lorder ${DOBJS} ${VARIANTDOBJS} | tsort -q` ${ARADD} ${RANLIB} lib${LIB}_debug.a -.if (${MACHINE_ARCH} == ppc) - @${ECHO} building debug ${LIB128} library - @rm -f lib${LIB128}_debug.a - @${AR} cq lib${LIB128}_debug.a ${LDBL_128_DOBJS} -.endif lib${LIB}.a:: ${VARIANTCOMBOS:S/$/_S/g} ${SOBJS} ${SOBJS2} @${ECHO} building standard ${LIB} library @rm -f lib${LIB}.a @${AR} cq lib${LIB}.a `lorder ${SOBJS} ${VARIANTSOBJS} | tsort -q` ${ARADD} ${RANLIB} lib${LIB}.a -.if (${MACHINE_ARCH} == ppc) - @${ECHO} building standard ${LIB128} library - @rm -f lib${LIB128}.a - @${AR} cq lib${LIB128}.a ${LDBL_128_SOBJS} -.endif CLEANFILES += ${DOBJS} libc_static.a libc_profile.a libc_debug.a @@ -305,79 +339,73 @@ SYSTEMFRAMEWORK = ${DESTDIR}/System/Library/Frameworks/System.framework PRIVHDRS = ${SYSTEMFRAMEWORK}/Versions/B/PrivateHeaders KERNELFRAMEWORK = ${DESTDIR}/System/Library/Frameworks/Kernel.framework PRIVKERNELHDRS = ${KERNELFRAMEWORK}/Versions/A/PrivateHeaders +INSTALLMODE != test `id -u` -eq 0 && echo 444 || echo 644 installhdrs-md: gen_md_mig_defs - mkdir -p ${INCDIR}/mach/${MACHINE_ARCH} - ${INSTALL} -c -m 444 ${MD_MIGHDRS} ${INCDIR}/mach/${MACHINE_ARCH} -installhdrs: autopatchhdrs gen_mig_defs +installhdrs: gen_mig_defs mkdir -p ${INCDIR}/arpa mkdir -p ${INCDIR}/libkern - mkdir -p ${INCDIR}/mach mkdir -p ${INCDIR}/machine mkdir -p ${INCDIR}/malloc mkdir -p ${INCDIR}/objc mkdir -p ${INCDIR}/protocols - mkdir -p ${INCDIR}/servers + mkdir -p ${INCDIR}/secure mkdir -p ${INCDIR}/sys mkdir -p ${INCDIR}/xlocale - ${INSTALL} -c -m 444 ${INSTHDRS} ${INCDIR} - ${INSTALL} -c -m 444 ${ARPA_INSTHDRS} ${INCDIR}/arpa - ${INSTALL} -c -m 444 ${LIBKERN_INSTHDRS} ${INCDIR}/libkern - ${INSTALL} -c -m 444 ${MACH_INSTHDRS} ${INCDIR}/mach - ${INSTALL} -c -m 444 ${MACHINE_INSTHDRS} ${INCDIR}/machine - ${INSTALL} -c -m 444 ${MALLOC_INSTHDRS} ${INCDIR}/malloc - ${INSTALL} -c -m 444 ${OBJC_INSTHDRS} ${INCDIR}/objc - ${INSTALL} -c -m 444 ${PROTO_INSTHDRS} ${INCDIR}/protocols - ${INSTALL} -c -m 444 ${SRVHDRS} ${INCDIR}/servers - ${INSTALL} -c -m 444 ${SYS_INSTHDRS} ${INCDIR}/sys - ${INSTALL} -c -m 444 ${XLOCALE_INSTHDRS} ${INCDIR}/xlocale + ${INSTALL} -c -m ${INSTALLMODE} ${INSTHDRS} ${INCDIR} + ${INSTALL} -c -m ${INSTALLMODE} ${ARPA_INSTHDRS} ${INCDIR}/arpa + ${INSTALL} -c -m ${INSTALLMODE} ${LIBKERN_INSTHDRS} ${INCDIR}/libkern + ${INSTALL} -c -m ${INSTALLMODE} ${MACHINE_INSTHDRS} ${INCDIR}/machine + ${INSTALL} -c -m ${INSTALLMODE} ${MALLOC_INSTHDRS} ${INCDIR}/malloc + ${INSTALL} -c -m ${INSTALLMODE} ${OBJC_INSTHDRS} ${INCDIR}/objc + ${INSTALL} -c -m ${INSTALLMODE} ${PROTO_INSTHDRS} ${INCDIR}/protocols + ${INSTALL} -c -m ${INSTALLMODE} ${SECURE_INSTHDRS} ${INCDIR}/secure + ${INSTALL} -c -m ${INSTALLMODE} ${SYS_INSTHDRS} ${INCDIR}/sys + ${INSTALL} -c -m ${INSTALLMODE} ${XLOCALE_INSTHDRS} ${INCDIR}/xlocale mkdir -p ${LOCINCDIR} - ${INSTALL} -c -m 444 ${LOCALHDRS} ${LOCINCDIR} - mkdir -p ${PRIVHDRS}/architecture/ppc + ${INSTALL} -c -m ${INSTALLMODE} ${LOCALHDRS} ${LOCINCDIR} mkdir -p ${PRIVHDRS}/btree mkdir -p ${PRIVHDRS}/machine mkdir -p ${PRIVHDRS}/objc mkdir -p ${PRIVHDRS}/uuid mkdir -p ${PRIVHDRS}/sys mkdir -p ${PRIVKERNELHDRS}/uuid - ${INSTALL} -c -m 444 ${PRIV_INSTHDRS} ${PRIVHDRS} - ${INSTALL} -c -m 444 ${SRCROOT}/ppc/sys/processor_facilities.h ${PRIVHDRS}/architecture/ppc - ${INSTALL} -c -m 444 ${SYMROOT}/btree.h ${PRIVHDRS}/btree - ${INSTALL} -c -m 444 ${SYMROOT}/bt_extern.h ${PRIVHDRS}/btree - ${INSTALL} -c -m 444 ${SRCROOT}/internat/NXCType.h ${PRIVHDRS}/objc + ${INSTALL} -c -m ${INSTALLMODE} ${PRIV_INSTHDRS} ${PRIVHDRS} + ${INSTALL} -c -m ${INSTALLMODE} ${INSTBTREEPRIVHDRS_AUTOPATCH} ${PRIVHDRS}/btree + ${INSTALL} -c -m ${INSTALLMODE} ${SRCROOT}/internat/NXCType.h ${PRIVHDRS}/objc mv ${DESTDIR}/usr/include/asm.h ${PRIVHDRS}/machine - mv ${INCDIR}/servers/srvbootstrap.h ${INCDIR}/servers/bootstrap.h - @for i in `find ${DESTDIR}/usr/include/mach ${DESTDIR}/usr/include/servers -name \*.h`; do \ - x=`fgrep '' $$i | uniq -d`; \ - if [ -n "$$x" ]; then \ - echo patching $$i; \ - ed - $$i < ${SRCROOT}/fixdups.ed; \ - fi; \ - done - ${INSTALL} -c -m 444 ${SYS_INSTHDRS} ${PRIVHDRS}/sys - ${INSTALL} -c -m 444 ${PRIVUUID_INSTHDRS} ${PRIVHDRS}/uuid - ${INSTALL} -c -m 444 ${PRIVUUID_INSTHDRS} ${PRIVKERNELHDRS}/uuid - ${INSTALL} -c -m 444 ${INSTHDRS_AUTOPATCH:S,^,${SYMROOT}/,} ${INCDIR} + ${INSTALL} -c -m ${INSTALLMODE} ${SYS_INSTHDRS} ${PRIVHDRS}/sys + ${INSTALL} -c -m ${INSTALLMODE} ${PRIVUUID_INSTHDRS} ${PRIVHDRS}/uuid + ${INSTALL} -c -m ${INSTALLMODE} ${PRIVUUID_INSTHDRS} ${PRIVKERNELHDRS}/uuid .for _h in ${STRIP_HDRS} chmod u+w ${INCDIR}/${_h} ed - ${INCDIR}/${_h} < ${.CURDIR}/strip-header.ed chmod u-w ${INCDIR}/${_h} .endfor + ${INSTALL} -c -m 644 /usr/include/AvailabilityMacros.h ${OBJROOT}/available.h + ex - ${OBJROOT}/available.h < ${.CURDIR}/available.ex + ${INSTALL} -c -m ${INSTALLMODE} ${OBJROOT}/available.h ${INCDIR} install_lib${LIB}_static.a: - ${INSTALL} -c -m 444 lib${LIB}_static.a ${DESTDIR}/usr/local/lib/system/ + ${INSTALL} -c -m ${INSTALLMODE} lib${LIB}_static.a ${DESTDIR}/usr/local/lib/system/ install_lib${LIB}_profile.a: - ${INSTALL} -c -m 444 lib${LIB}_profile.a ${DESTDIR}/usr/local/lib/system + ${INSTALL} -c -m ${INSTALLMODE} lib${LIB}_profile.a ${DESTDIR}/usr/local/lib/system install_lib${LIB}_debug.a: - ${INSTALL} -c -m 444 lib${LIB}_debug.a ${DESTDIR}/usr/local/lib/system/ + ${INSTALL} -c -m ${INSTALLMODE} lib${LIB}_debug.a ${DESTDIR}/usr/local/lib/system/ install_lib${LIB}.a: - ${INSTALL} -c -m 444 lib${LIB}.a ${DESTDIR}/usr/local/lib/system/ + ${INSTALL} -c -m ${INSTALLMODE} lib${LIB}.a ${DESTDIR}/usr/local/lib/system/ -autopatch: autopatchhdrs ${AUTOPATCHSRCS} -autopatchhdrs: ${AUTOPATCHHDRS} autopatchman: ${AUTOPATCHMAN} +copyfiles: +.if !empty $(COPYFILES) + $(INSTALL) -c -m 444 ${COPYFILES} ${DESTDIR}/usr/local/lib/system +.endif +.if !empty $(MDCOPYFILES) + $(INSTALL) -c -m 444 ${MDCOPYFILES} ${DESTDIR}/usr/local/lib/system +.endif + clean: rm -f ${OBJS} ${POBJS} ${DOBJS} ${SOBJS} ${CLEANFILES} rm -f lib${LIB}.a lib${LIB}_static.a lib${LIB}_profile.a \ diff --git a/REQUIRED-MACROS b/REQUIRED-MACROS deleted file mode 100644 index 4482b7a..0000000 --- a/REQUIRED-MACROS +++ /dev/null @@ -1,3 +0,0 @@ -sigmask -WCOREDUMP - diff --git a/SYSCALL-LIST b/SYSCALL-LIST deleted file mode 100644 index 9b909f9..0000000 --- a/SYSCALL-LIST +++ /dev/null @@ -1,145 +0,0 @@ -accept -access -acct -adjtime -bind -brk -sbrk -chdir -fchdir -chflags -creat -fchflags -chmod -fchmod -chown -fchown -lchown -chroot -close -connect -dup -dup2 -execve -_exit -fcntl -fhopen -flock -fork -fsync -getdirentries -getdtablesize -getfh -getfsstat -getgid -getegid -getgroups -getitimer -setitimer -getlogin -setlogin -getpeername -getpgrp -getpid -getppid -getpriority -setpriority -getrlimit -setrlimit -getrusage -getsockname -getsockopt -setsockopt -gettimeofday -settimeofday -getuid -geteuid -ioctl -kill -killpg -ktrace -link -listen -lseek -madvise -mincore -mkdir -mkfifo -mknod -mlock -munlock -mmap -mount -unmount -mprotect -msync -munmap -nfsclnt -nfssvc -open -pathconf -fpathconf -pipe -profil -ptrace -quotactl -read -readv -readlink -reboot -recv -recvfrom -recvmsg -rename -revoke -rmdir -select -send -sendto -sendmsg -setgroups -setpgid -setpgrp -setregid -setreuid -setsid -setuid -seteuid -setgid -setegid -shutdown -sigaction -sigaltstack -sigblock -sigpause -sigpending -sigprocmask -sigreturn -sigsetmask -sigstack -sigsuspend -sigvec -socket -socketpair -stat -lstat -fstat -statfs -fstatfs -swapon -symlink -sync -syscall -__syscall -truncate -ftruncate -umask -unlink -utimes -vfork -wait -waitpid -wait3 -wait4 -write -writev diff --git a/available.ex b/available.ex new file mode 100644 index 0000000..4221cf5 --- /dev/null +++ b/available.ex @@ -0,0 +1,13 @@ +g/AvailabilityMacros\.h/s//available.h/ +/Contains:/c + Contains: Double-underbar-prefixed availability macros, derived from + AvailabilityMacros.h +. +g/__AVAILABILITYMACROS__/s//_AVAILABLE_H_/ +g/\ + __FBSDID("$FreeBSD: src/lib/libc/compat-43/creat.c,v 1.7 2002/03/22 21:51:56 obrien Exp $"); + ++ + #include "namespace.h" + #include + #include "un-namespace.h" + ++#ifdef VARIANT_CANCELABLE ++int __open(const char *path, int flags, mode_t mode); ++#else /* !VARIANT_CANCELABLE */ ++int __open_nocancel(const char *path, int flags, mode_t mode); ++#endif /* VARIANT_CANCELABLE */ ++ ++ + int + __creat(const char *path, mode_t mode) + { +- return(_open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)); ++#ifdef VARIANT_CANCELABLE ++ return(__open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)); ++#else /* !VARIANT_CANCELABLE */ ++ return(__open_nocancel(path, O_WRONLY|O_CREAT|O_TRUNC, mode)); ++#endif /* VARIANT_CANCELABLE */ + } + __weak_reference(__creat, creat); + __weak_reference(__creat, _creat); diff --git a/compat-43/FreeBSD/gethostid.3.patch b/compat-43/FreeBSD/gethostid.3.patch new file mode 100644 index 0000000..5cfd027 --- /dev/null +++ b/compat-43/FreeBSD/gethostid.3.patch @@ -0,0 +1,17 @@ +--- _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 @@ + The + .Fn sethostid + function +-establishes a 32-bit identifier for the +-current processor that is intended to be unique among all +-UNIX systems in existence. +-This is normally a DARPA Internet +-address for the local machine. ++establishes a 32-bit identifier for the current processor. ++The id, intended to be unique among all UNIX systems in existence, ++is normally a DARPA Internet address for the local machine. + This call is allowed only to the + super-user and is normally performed at boot time. + .Pp diff --git a/compat-43/FreeBSD/killpg.2.patch b/compat-43/FreeBSD/killpg.2.patch new file mode 100644 index 0000000..7bfa229 --- /dev/null +++ b/compat-43/FreeBSD/killpg.2.patch @@ -0,0 +1,45 @@ +--- 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 @@ + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS +-.In sys/types.h + .In signal.h + .Ft int + .Fn killpg "pid_t pgrp" "int sig" +@@ -80,21 +79,29 @@ + .Fa sig + argument + is not a valid signal number. ++.It Bq Er EPERM ++The sending process is not the super-user and one or more ++of the target processes has an effective user ID different from that ++of the sending process. + .It Bq Er ESRCH + No process can be found in the process group specified by + .Fa pgrp . + .It Bq Er ESRCH + The process group was given as 0 + but the sending process does not have a process group. +-.It Bq Er EPERM +-The sending process is not the super-user and one or more +-of the target processes has an effective user ID different from that +-of the sending process. + .El ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Pp ++The include file ++.In sys/types.h ++is necessary. + .Sh SEE ALSO + .Xr getpgrp 2 , + .Xr kill 2 , +-.Xr sigaction 2 ++.Xr sigaction 2 , ++.Xr compat 5 + .Sh HISTORY + The + .Fn killpg diff --git a/compat-43/FreeBSD/killpg.c.patch b/compat-43/FreeBSD/killpg.c.patch new file mode 100644 index 0000000..37d7abd --- /dev/null +++ b/compat-43/FreeBSD/killpg.c.patch @@ -0,0 +1,30 @@ +--- 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 @@ + #include + #include + ++int __kill(pid_t pid, int sig, int posix); ++ ++#if __DARWIN_UNIX03 ++#define _PID1ERR EPERM ++#define _POSIXKILL 1 ++#else /* !__DARWIN_UNIX03 */ ++#define _PID1ERR ESRCH ++#define _POSIXKILL 0 ++#endif /* !__DARWIN_UNIX03 */ ++ + /* + * Backwards-compatible killpg(). + */ +@@ -48,8 +58,8 @@ + killpg(pid_t pgid, int sig) + { + if (pgid == 1) { +- errno = ESRCH; ++ errno = _PID1ERR; + return (-1); + } +- return (kill(-pgid, sig)); ++ return (__kill(-pgid, sig, _POSIXKILL)); + } diff --git a/compat-43/FreeBSD/setpgrp.c.patch b/compat-43/FreeBSD/setpgrp.c.patch index 8b8dc78..c728f03 100644 --- a/compat-43/FreeBSD/setpgrp.c.patch +++ b/compat-43/FreeBSD/setpgrp.c.patch @@ -1,23 +1,19 @@ ---- setpgrp.c.orig 2004-10-10 12:08:09.000000000 -0700 -+++ setpgrp.c 2004-10-10 12:11:13.000000000 -0700 -@@ -40,8 +40,20 @@ +--- 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 @@ #include #include -+#if __DARWIN_UNIX03 +-int +-setpgrp(pid_t pid, pid_t pgid) ++/* UNIX03 only */ +pid_t +setpgrp(void) -+{ + { +- return(setpgid(pid, pgid)); + pid_t pgid = getpgrp(); + pid_t pid = getpid(); + if (pgid != pid) + setpgid(pid, pid); + return pid; -+} -+#else /* !__DARWIN_UNIX03 */ - int - setpgrp(pid_t pid, pid_t pgid) - { - return(setpgid(pid, pgid)); } -+#endif /* __DARWIN_UNIX03 */ diff --git a/compat-43/Makefile.inc b/compat-43/Makefile.inc index 9d089d2..3cb4845 100644 --- a/compat-43/Makefile.inc +++ b/compat-43/Makefile.inc @@ -4,13 +4,24 @@ # compat-43 sources .PATH: ${.CURDIR}/${MACHINE_ARCH}/compat-43 ${.CURDIR}/compat-43 -MISRCS+= setregid.c setreuid.c sigcompat.c +MISRCS+= sigaltstk.c sigcompat.c .include "Makefile.fbsd_begin" FBSDMISRCS= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \ setrgid.c setruid.c .include "Makefile.fbsd_end" -UNIX03SRCS += setpgrp.c +LEGACYSRCS += creat.c setregid.c setreuid.c sigcompat.c killpg.c +CANCELABLESRCS += creat.c sigcompat.c + +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +CFLAGS-creat-fbsd.c += -DLIBC_ALIAS_CREAT +CFLAGS-setregid.c += -DLIBC_ALIAS_SETREGID +CFLAGS-setreuid.c += -DLIBC_ALIAS_SETREUID +CFLAGS-setpgrp-fbsd.c += -DLIBC_ALIAS_SETPGRP +CFLAGS-sigcompat.c += -DLIBC_ALIAS_SIGPAUSE +CFLAGS-killpg-fbsd.c += -DLIBC_ALIAS_KILLPG +CFLAGS-sigaltstk.c += -DLIBC_ALIAS_SIGALTSTACK .if ${LIB} == "c" MAN2+= sigblock.2 sigpause.2 sigsetmask.2 sigvec.2 @@ -20,8 +31,10 @@ FBSDMAN2= creat.2 killpg.2 FBSDMAN3= gethostid.3 setruid.3 .include "Makefile.fbsd_end" -MLINKS+=gethostid.3 sethostid.3 -MLINKS+=setruid.3 setrgid.3 -MLINKS+=sigsetmask.2 sigmask.2 +MLINKS+= gethostid.3 sethostid.3 + +MLINKS+= setruid.3 setrgid.3 + +MLINKS+= sigsetmask.2 sigmask.2 .endif diff --git a/compat-43/creat-fbsd.c b/compat-43/creat-fbsd.c new file mode 100644 index 0000000..3293e46 --- /dev/null +++ b/compat-43/creat-fbsd.c @@ -0,0 +1,62 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + + +#include "namespace.h" +#include +#include "un-namespace.h" + +#ifdef VARIANT_CANCELABLE +int __open(const char *path, int flags, mode_t mode); +#else /* !VARIANT_CANCELABLE */ +int __open_nocancel(const char *path, int flags, mode_t mode); +#endif /* VARIANT_CANCELABLE */ + + +int +__creat(const char *path, mode_t mode) +{ +#ifdef VARIANT_CANCELABLE + return(__open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)); +#else /* !VARIANT_CANCELABLE */ + return(__open_nocancel(path, O_WRONLY|O_CREAT|O_TRUNC, mode)); +#endif /* VARIANT_CANCELABLE */ +} +__weak_reference(__creat, creat); +__weak_reference(__creat, _creat); diff --git a/compat-43/creat.2 b/compat-43/creat.2 new file mode 120000 index 0000000..3904d0d --- /dev/null +++ b/compat-43/creat.2 @@ -0,0 +1 @@ +./creat.2 \ 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..0f08fad --- /dev/null +++ b/compat-43/gethostid-fbsd.c @@ -0,0 +1,56 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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.3 2002/05/28 16:56:57 alfred Exp $"); + +#include +#include + +long +gethostid(void) +{ + int mib[2]; + size_t size; + long 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 new file mode 100644 index 0000000..b0d07c3 --- /dev/null +++ b/compat-43/gethostid.3 @@ -0,0 +1,82 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 2, 1993 +.Dt GETHOSTID 3 +.Os +.Sh NAME +.Nm gethostid , +.Nm sethostid +.Nd get/set unique identifier of current host +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft long +.Fn gethostid void +.Ft void +.Fn sethostid "long hostid" +.Sh DESCRIPTION +The +.Fn sethostid +function +establishes a 32-bit identifier for the current processor. +The id, intended to be unique among all UNIX systems in existence, +is normally a DARPA Internet address for the local machine. +This call is allowed only to the +super-user and is normally performed at boot time. +.Pp +The +.Fn gethostid +function +returns the 32-bit identifier for the current processor. +.Pp +This function has been deprecated. +The hostid should be set or retrieved by use of +.Xr sysctl 3 . +.Sh SEE ALSO +.Xr gethostname 3 , +.Xr sysctl 3 , +.Xr sysctl 8 +.Sh BUGS +32 bits for the identifier is too small. +.Sh HISTORY +The +.Fn gethostid +and +.Fn sethostid +syscalls appeared in +.Bx 4.2 +and were dropped in +.Bx 4.4 . diff --git a/compat-43/getwd-fbsd.c b/compat-43/getwd-fbsd.c new file mode 100644 index 0000000..b15d2e2 --- /dev/null +++ b/compat-43/getwd-fbsd.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include +#include +#include +#include +#include + +char * +getwd(buf) + char *buf; +{ + char *p; + + if ( (p = getcwd(buf, MAXPATHLEN)) ) + return(p); + (void)strcpy(buf, strerror(errno)); + return((char *)NULL); +} diff --git a/compat-43/killpg-fbsd.c b/compat-43/killpg-fbsd.c new file mode 100644 index 0000000..b57bec0 --- /dev/null +++ b/compat-43/killpg-fbsd.c @@ -0,0 +1,65 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include +#include +#include + +int __kill(pid_t pid, int sig, int posix); + +#if __DARWIN_UNIX03 +#define _PID1ERR EPERM +#define _POSIXKILL 1 +#else /* !__DARWIN_UNIX03 */ +#define _PID1ERR ESRCH +#define _POSIXKILL 0 +#endif /* !__DARWIN_UNIX03 */ + +/* + * Backwards-compatible killpg(). + */ +int +killpg(pid_t pgid, int sig) +{ + if (pgid == 1) { + errno = _PID1ERR; + return (-1); + } + return (__kill(-pgid, sig, _POSIXKILL)); +} diff --git a/compat-43/killpg.2 b/compat-43/killpg.2 new file mode 100644 index 0000000..5671153 --- /dev/null +++ b/compat-43/killpg.2 @@ -0,0 +1,109 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 2, 1993 +.Dt KILLPG 2 +.Os +.Sh NAME +.Nm killpg +.Nd send signal to a process group +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Ft int +.Fn killpg "pid_t pgrp" "int sig" +.Sh DESCRIPTION +The +.Fn killpg +function +sends the signal +.Fa sig +to the process group +.Fa pgrp . +See +.Xr sigaction 2 +for a list of signals. +If +.Fa pgrp +is 0, +.Fn killpg +sends the signal to the sending process's process group. +.Pp +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. +.Sh RETURN VALUES +.Rv -std killpg +.Sh ERRORS +The +.Fn killpg +function +will fail and no signal will be sent if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sig +argument +is not a valid signal number. +.It Bq Er EPERM +The sending process is not the super-user and one or more +of the target processes has an effective user ID different from that +of the sending process. +.It Bq Er ESRCH +No process can be found in the process group specified by +.Fa pgrp . +.It Bq Er ESRCH +The process group was given as 0 +but the sending process does not have a process group. +.El +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +The include file +.In sys/types.h +is necessary. +.Sh SEE ALSO +.Xr getpgrp 2 , +.Xr kill 2 , +.Xr sigaction 2 , +.Xr compat 5 +.Sh HISTORY +The +.Fn killpg +function appeared in +.Bx 4.0 . diff --git a/compat-43/sethostid-fbsd.c b/compat-43/sethostid-fbsd.c new file mode 100644 index 0000000..a23ec8e --- /dev/null +++ b/compat-43/sethostid-fbsd.c @@ -0,0 +1,53 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include +#include + +long +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); +} diff --git a/compat-43/setpgrp-fbsd.c b/compat-43/setpgrp-fbsd.c new file mode 100644 index 0000000..bc18609 --- /dev/null +++ b/compat-43/setpgrp-fbsd.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include +#include + +/* UNIX03 only */ +pid_t +setpgrp(void) +{ + pid_t pgid = getpgrp(); + pid_t pid = getpid(); + if (pgid != pid) + setpgid(pid, pid); + return pid; +} diff --git a/compat-43/setregid.c b/compat-43/setregid.c index 748943a..e782d0b 100644 --- a/compat-43/setregid.c +++ b/compat-43/setregid.c @@ -1,25 +1,3 @@ -/* - * 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) 1983, 1993 * The Regents of the University of California. All rights reserved. diff --git a/compat-43/setreuid.c b/compat-43/setreuid.c index 3a6626a..337829f 100644 --- a/compat-43/setreuid.c +++ b/compat-43/setreuid.c @@ -1,25 +1,3 @@ -/* - * 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, 1993 * The Regents of the University of California. All rights reserved. diff --git a/compat-43/setrgid-fbsd.c b/compat-43/setrgid-fbsd.c new file mode 100644 index 0000000..360e562 --- /dev/null +++ b/compat-43/setrgid-fbsd.c @@ -0,0 +1,47 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include + +int +setrgid(gid_t rgid) +{ + + return (setregid(rgid, -1)); +} diff --git a/compat-43/setruid-fbsd.c b/compat-43/setruid-fbsd.c new file mode 100644 index 0000000..5fb6d60 --- /dev/null +++ b/compat-43/setruid-fbsd.c @@ -0,0 +1,47 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include + +int +setruid(uid_t ruid) +{ + + return (setreuid(ruid, -1)); +} diff --git a/compat-43/setruid.3 b/compat-43/setruid.3 new file mode 120000 index 0000000..dde144b --- /dev/null +++ b/compat-43/setruid.3 @@ -0,0 +1 @@ +./setruid.3 \ No newline at end of file diff --git a/i386/sys/getattrlist.s b/compat-43/sigaltstk.c similarity index 69% rename from i386/sys/getattrlist.s rename to compat-43/sigaltstk.c index a35ff4d..968d1ac 100644 --- a/i386/sys/getattrlist.s +++ b/compat-43/sigaltstk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005, 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,18 +20,17 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include +#include +#include -#ifdef __LP64__ -UNIX_SYSCALL(getattrlist, 0) - ret -#else /* !__LP64__ */ -PSEUDO(getattrlist$UNIX2003, getattrlist, 0) - ret +int __sigaltstack(const stack_t * __restrict, stack_t * __restrict); -UNIX_SYSCALL_ERR(getattrlist, 0, cerror_cvt) - ret -#endif /* !__LP64__ */ +/* UNIX03 only */ +int sigaltstack(const stack_t * __restrict nstack, stack_t * __restrict ostack) +{ + if (nstack && nstack->ss_size < MINSIGSTKSZ) { + errno = ENOMEM; + return -1; + } + return __sigaltstack(nstack, ostack); +} diff --git a/compat-43/sigcompat.c b/compat-43/sigcompat.c index ba1aed1..8c4410d 100644 --- a/compat-43/sigcompat.c +++ b/compat-43/sigcompat.c @@ -53,10 +53,20 @@ * SUCH DAMAGE. */ +#if __DARWIN_UNIX03 +#ifdef VARIANT_CANCELABLE +#include + +extern void _pthread_testcancel(pthread_t thread, int isconforming); +#endif /* VARIANT_CANCELABLE */ +extern int __unix_conforming; +#endif /* __DARWIN_UNIX03 */ #include #include #include + +#ifndef BUILDING_VARIANT #if defined(__DYNAMIC__) extern int _sigaction_nobind (int sig, const struct sigaction *nsv, struct sigaction *osv); #endif @@ -126,14 +136,41 @@ sigblock(mask) return (n); return (omask); } +#endif /* !BUILDING_VARIANT */ + +#if __DARWIN_UNIX03 +int +sigpause(sig) + int sig; +{ + sigset_t mask; + + if (__unix_conforming == 0) + __unix_conforming = 1; +#ifdef VARIANT_CANCELABLE + _pthread_testcancel(pthread_self(), 1); +#endif /* VARIANT_CANCELABLE */ + if ((sig <= 0) || (sig >= NSIG)) { + errno = EINVAL; + return(-1); + } + if (sigprocmask(SIG_BLOCK, (sigset_t *) 0, (sigset_t *) &mask) < 0) { + return(-1); + } + sigdelset(&mask, sig); + return (sigsuspend(&mask)); +} +#else int sigpause(mask) int mask; { return (sigsuspend((sigset_t *)&mask)); } +#endif /* __DARWIN_UNIX03 */ +#ifndef BUILDING_VARIANT int sighold(sig) int sig; @@ -203,3 +240,4 @@ void (*sigset(int sig, void (*disp)(int)))(int) { return (rv); } } +#endif /* !BUILDING_VARIANT */ diff --git a/compat-43/sigpause.2 b/compat-43/sigpause.2 index cd39071..802e039 100644 --- a/compat-43/sigpause.2 +++ b/compat-43/sigpause.2 @@ -43,25 +43,37 @@ .Sh SYNOPSIS .In signal.h .Ft int -.Fn sigpause "int sigmask" +.Fn sigpause "int sig" .Sh DESCRIPTION .Sy This interface is made obsolete by .Xr sigsuspend 2 . .Pp .Fn Sigpause assigns -.Fa sigmask +.Fa sig to the set of masked signals and then waits for a signal to arrive; on return the set of masked signals is restored. -.Fa Sigmask -is usually 0 to indicate that no +.Fa Sig +is usually 0, indicating that no signals are to be blocked. .Fn Sigpause always terminates by being interrupted, returning -1 with .Va errno set to -.Er EINTR +.Er EINTR . +.Sh COMPATIBILITY +.Fn sigpause +now takes a signal value and not a mask. +This often appears as a hang in sigpause$UNIX2003 +or with +.Fn sigpause +returning with +.Va errno +set to EINVAL. +Use +.Fn sigsuspend +with signal masks. .Sh SEE ALSO .Xr kill 2 , .Xr sigaction 2 , diff --git a/darwin/MKGetTimeBaseInfo.c b/darwin/MKGetTimeBaseInfo.c new file mode 100644 index 0000000..6b2af36 --- /dev/null +++ b/darwin/MKGetTimeBaseInfo.c @@ -0,0 +1,62 @@ +/* + * 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 +#include +#include + +extern void spin_lock(int *); +extern void spin_unlock(int *); + +/* deprecated function stub */ +kern_return_t +MKGetTimeBaseInfo( + uint32_t *minAbsoluteTimeDelta, + uint32_t *theAbsoluteTimeToNanosecondNumerator, + uint32_t *theAbsoluteTimeToNanosecondDenominator, + uint32_t *theProcessorToAbsoluteTimeNumerator, + uint32_t *theProcessorToAbsoluteTimeDenominator +) { + static struct mach_timebase_info mti = {0}; + static int MKGetTimeBaseInfo_spin_lock = 0; + + if(mti.numer == 0) { + kern_return_t err; + spin_lock(&MKGetTimeBaseInfo_spin_lock); + err = mach_timebase_info(&mti); + spin_unlock(&MKGetTimeBaseInfo_spin_lock); + if(err != KERN_SUCCESS) + return err; + } + if(theAbsoluteTimeToNanosecondNumerator) + *theAbsoluteTimeToNanosecondNumerator = mti.numer; + if(theAbsoluteTimeToNanosecondDenominator) + *theAbsoluteTimeToNanosecondDenominator = mti.denom; + if(minAbsoluteTimeDelta) + *minAbsoluteTimeDelta = 1; + if(theProcessorToAbsoluteTimeNumerator) + *theProcessorToAbsoluteTimeNumerator = 1; + if(theProcessorToAbsoluteTimeDenominator) + *theProcessorToAbsoluteTimeDenominator = 1; + return KERN_SUCCESS; +} diff --git a/darwin/Makefile.inc b/darwin/Makefile.inc index a47cbda..a0c9e99 100644 --- a/darwin/Makefile.inc +++ b/darwin/Makefile.inc @@ -1,5 +1,28 @@ .PATH: ${.CURDIR}/darwin -MISRCS += copyfile.c -LOCALHDRS += ${.CURDIR}/darwin/copyfile.h -CFLAGS-copyfile.c = -I${.CURDIR}/darwin +.ifnmake autopatch +.if exists(${.CURDIR}/${MACHINE_ARCH}/darwin/Makefile.inc) +.include "${.CURDIR}/${MACHINE_ARCH}/darwin/Makefile.inc" +.endif +.endif # !autopatch + +DARWINMIGDEFS += dirhelper.defs +DARWINMIGHDRS += ${DARWINMIGDEFS:.defs=.h} +DARWINMIGSRCS += ${DARWINMIGDEFS:.defs=User.c} + +INSTHDRS += ${.CURDIR}/darwin/libproc.h + +LOCALHDRS += ${.CURDIR}/darwin/dirhelper.defs \ + ${.CURDIR}/darwin/dirhelper_priv.h \ + ${.CURDIR}/darwin/libproc.h +MISRCS += ${DARWINMIGSRCS} _dirhelper.c libproc.c proc_listpidspath.c + +.ifndef LP64 +MISRCS += kvm.c MKGetTimeBaseInfo.c +.endif + +# force building of the mig stuff before _dirhelper.c +_dirhelper.So _dirhelper.po _dirhelper.do _dirhelper.o: dirhelperUser.c + +CFLAGS-_dirhelper.c += -I${OBJROOT} +CFLAGS-proc_listpidspath.c += -I${.CURDIR}/darwin diff --git a/darwin/_dirhelper.c b/darwin/_dirhelper.c new file mode 100644 index 0000000..c28a0cc --- /dev/null +++ b/darwin/_dirhelper.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2006, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dirhelper.h" +#include "dirhelper_priv.h" + +#define BUCKETLEN 2 + +#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 +#define ENCODEDSIZE ((8 * UUID_UID_SIZE + ENCODEBITS - 1) / ENCODEBITS) +#define UUID_UID_SIZE (sizeof(uuid_t) + sizeof(uid_t)) + +extern int __is_threaded; + +static const mode_t modes[] = { + 0, /* unused */ + 0700, /* temp */ + 0700, /* cache */ +}; + +static const char *subdirs[] = { + DIRHELPER_TOP_STR, + DIRHELPER_TEMP_STR, + DIRHELPER_CACHE_STR, +}; + +static const char encode[] = "+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static void +encode_uuid_uid(uuid_t uuid, uid_t uid, char *str) +{ + unsigned char buf[UUID_UID_SIZE + 1]; + unsigned char *bp = buf; + int i = 0; + 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) { + case 0: + n = *bp++; + *str++ = encode[n >> 2]; + break; + case 1: + n = ((n & 0x3) << 8) | *bp++; + *str++ = encode[n >> 4]; + break; + case 2: + n = ((n & 0xf) << 8) | *bp++; + *str++ = encode[n >> 6]; + break; + case 3: + *str++ = encode[n & 0x3f]; + break; + } + i++; + } + *str = 0; +} + +char * +__user_local_dirname(uid_t uid, dirhelper_which_t which, char *path, size_t pathlen) +{ + uuid_t uuid; + char str[ENCODEDSIZE + 1]; + int res; + + if(which < 0 || which > DIRHELPER_USER_LOCAL_LAST) { + errno = EINVAL; + return NULL; + } + + res = mbr_uid_to_uuid(uid, uuid); + if(res != 0) { + errno = res; + return NULL; + } + + // + // We partition the namespace so that we don't end up with too + // many users in a single directory. With 4096 buckets, we + // could scale to 1,000,000 users while keeping the average + // number of files in a single directory below 250 + // + encode_uuid_uid(uuid, uid, str); + res = snprintf(path, pathlen, + "%s%.*s/%s/%s", + VAR_FOLDERS_PATH, BUCKETLEN, str, str, subdirs[which]); + if(res >= pathlen) { + errno = EINVAL; + return NULL; /* buffer too small */ + } + return path; +} + +__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) { + errno = EINVAL; + return NULL; + } + + if(!*userdir) { + MUTEX_LOCK(&lock); + if(!*userdir) { + mach_port_t mp; + + if(bootstrap_look_up(bootstrap_port, DIRHELPER_BOOTSTRAP_NAME, &mp) != KERN_SUCCESS) { + errno = EPERM; + MUTEX_UNLOCK(&lock); + return NULL; + } + if(__user_local_dirname(geteuid(), DIRHELPER_USER_LOCAL, userdir, sizeof(userdir)) == NULL) { +server_error: + mach_port_deallocate(mach_task_self(), mp); + MUTEX_UNLOCK(&lock); + return NULL; + } + /* + * check if userdir exists, and if not, call + * __dirhelper_create_user_local to create it + * (we have to check again afterwards). + */ + if(stat(userdir, &sb) < 0) { + if(errno != ENOENT) { /* some unknown error */ + *userdir = 0; + goto server_error; + } + if(__dirhelper_create_user_local(mp) != KERN_SUCCESS) { + errno = EPERM; + *userdir = 0; + goto server_error; + } + /* double check that the directory really got created */ + if(stat(userdir, &sb) < 0) { + *userdir = 0; + goto server_error; + } + } + mach_port_deallocate(mach_task_self(), mp); + } + MUTEX_UNLOCK(&lock); + } + + if(pathlen < strlen(userdir) + strlen(subdirs[which]) + 1) { + errno = EINVAL; + return NULL; /* buffer too small */ + } + strcpy(path, userdir); + strcat(path, subdirs[which]); + + /* + * now for subdirectories, create it with the appropriate permissions + * if it doesn't already exist. + */ + if(which != DIRHELPER_USER_LOCAL) { + res = mkdir(path, modes[which]); + if(res != 0 && errno != EEXIST) + return NULL; + } + + return path; +} diff --git a/darwin/copyfile.c b/darwin/copyfile.c deleted file mode 100644 index d1d0c8a..0000000 --- a/darwin/copyfile.c +++ /dev/null @@ -1,1620 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -struct _copyfile_state -{ - char *src; - char *dst; - int src_fd; - int dst_fd; - struct stat sb; - filesec_t fsec; - copyfile_flags_t flags; - void *stats; - uint32_t debug; -}; - -static int copyfile_open (copyfile_state_t); -static int copyfile_close (copyfile_state_t); -static int copyfile_data (copyfile_state_t); -static int copyfile_stat (copyfile_state_t); -static int copyfile_security (copyfile_state_t); -static int copyfile_xattr (copyfile_state_t); -static int copyfile_pack (copyfile_state_t); -static int copyfile_unpack (copyfile_state_t); - -static copyfile_flags_t copyfile_check (copyfile_state_t); -static int copyfile_fix_perms(copyfile_state_t, filesec_t *, int); - -#define COPYFILE_DEBUG (1<<31) - -#ifndef _COPYFILE_TEST -# define copyfile_warn(str, ...) syslog(LOG_WARNING, str ": %m", ## __VA_ARGS__) -# define copyfile_debug(d, str, ...) \ - if (s && (d <= s->debug)) {\ - syslog(LOG_DEBUG, "%s:%d:%s() " str "\n", __FILE__, __LINE__ , __FUNCTION__, ## __VA_ARGS__); \ - } else -#else -#define copyfile_warn(str, ...) \ - fprintf(stderr, "%s:%d:%s() " str ": %s\n", __FILE__, __LINE__ , __FUNCTION__, ## __VA_ARGS__, (errno) ? strerror(errno) : "") -# define copyfile_debug(d, str, ...) \ - if (s && (d <= s->debug)) {\ - fprintf(stderr, "%s:%d:%s() " str "\n", __FILE__, __LINE__ , __FUNCTION__, ## __VA_ARGS__); \ - } else -#endif - -int copyfile(const char *src, const char *dst, copyfile_state_t state, copyfile_flags_t flags) -{ - int ret = 0; - copyfile_state_t s = state; - filesec_t original_fsec; - int fix_perms = 0; - - original_fsec = filesec_init(); - if (s == NULL && (s = copyfile_init()) == NULL) - return -1; - - if (src != NULL) - { - if (s->src_fd != -2 && s->src && !strncmp(src, s->src, MAXPATHLEN)) - close(s->src_fd); - s->src = strdup(src); - } - - if (dst != NULL) - { - if (s->dst_fd != -2 && s->dst && !strncmp(dst, s->dst, MAXPATHLEN)) - close(s->dst_fd); - s->dst = strdup(dst); - } - - s->flags = flags; - - if (COPYFILE_DEBUG & s->flags) - { - char *e; - if ((e = getenv("COPYFILE_DEBUG"))) - { - s->debug = strtol(e, NULL, 0); - if (s->debug < 1) - s->debug = 1; - } - copyfile_debug(1, "debug value set to: %d\n", s->debug); - } - if (COPYFILE_CHECK & flags) - return copyfile_check(s); - - if (copyfile_open(s) < 0) - ret = -1; - else - { - if (s->dst_fd == -2 || s->src_fd == -2) - return 0; - - if (COPYFILE_PACK & flags) - { - if (copyfile_pack(s) < 0) - { - unlink(s->dst); - ret = -1; - } - } else if (COPYFILE_UNPACK & flags) - { - if (!(COPYFILE_STAT & flags || COPYFILE_ACL & flags)) - fix_perms = !copyfile_fix_perms(s, &original_fsec, 1); - - if (copyfile_unpack(s) < 0) - ret = -1; - } else - { - if (COPYFILE_SECURITY & flags) - { - if (copyfile_security(s) < 0) - { - copyfile_warn("error processing security information"); - ret -= 1; - } - } else if (COPYFILE_UNPACK & flags) - { - fix_perms = !copyfile_fix_perms(s, &original_fsec, 1); - if (copyfile_unpack(s) < 0) - ret = -1; - } else - { - if (COPYFILE_SECURITY & flags) - { - copyfile_warn("error processing stat information"); - ret -= 1; - } - } - fix_perms = !copyfile_fix_perms(s, &original_fsec, 1); - - if (COPYFILE_XATTR & flags) - { - if (copyfile_xattr(s) < 0) - { - copyfile_warn("error processing extended attributes"); - ret -= 1; - } - } - if (COPYFILE_DATA & flags) - { - if (copyfile_data(s) < 0) - { - copyfile_warn("error processing data"); - ret = -1; - if (s->dst && unlink(s->dst)) - copyfile_warn("%s: remove", s->src); - goto exit; - } - } - } - } -exit: - if (fix_perms) - copyfile_fix_perms(s, &original_fsec, 0); - - filesec_free(original_fsec); - - if (state == NULL) { - if (copyfile_free(s) < 0) { - ret = -1; - } - } - - return ret; -} - -copyfile_state_t copyfile_init(void) -{ - copyfile_state_t s = (copyfile_state_t) calloc(1, sizeof(struct _copyfile_state)); - - if (s != NULL) - { - s->src_fd = -2; - s->dst_fd = -2; - s->fsec = filesec_init(); - } - - return s; -} - -int copyfile_free(copyfile_state_t s) -{ - if (s != NULL) - { - if (s->fsec) - filesec_free(s->fsec); - - if (s->dst) - free(s->dst); - if (s->src) - free(s->src); - if (copyfile_close(s) < 0) - { - copyfile_warn("error closing files"); - return -1; - } - free(s); - } - return 0; -} - -static int copyfile_close(copyfile_state_t s) -{ - if (s->src_fd >= 0) - close(s->src_fd); - - if (s->dst_fd >= 0 && close(s->dst_fd)) - { - copyfile_warn("close on %s", s->dst); - return -1; - } - return 0; -} - -static int copyfile_fix_perms(copyfile_state_t s, filesec_t *fsec, int on) -{ - filesec_t tmp_fsec; - struct stat sb; - mode_t mode; - acl_t acl; - - if (on) - { - if(fstatx_np(s->dst_fd, &sb, *fsec)) - goto error; - - tmp_fsec = filesec_dup(*fsec); - - if (!filesec_get_property(tmp_fsec, FILESEC_ACL, &acl)) - { - acl_entry_t entry; - acl_permset_t permset; - uuid_t qual; - - if (mbr_uid_to_uuid(getuid(), qual) != 0) - goto error; - - if (acl_create_entry_np(&acl, &entry, ACL_FIRST_ENTRY) == -1) - goto error; - if (acl_get_permset(entry, &permset) == -1) - goto error; - if (acl_clear_perms(permset) == -1) - goto error; - if (acl_add_perm(permset, ACL_WRITE_DATA) == -1) - goto error; - if (acl_add_perm(permset, ACL_WRITE_ATTRIBUTES) == -1) - goto error; - if (acl_add_perm(permset, ACL_WRITE_EXTATTRIBUTES) == -1) - goto error; - if (acl_set_tag_type(entry, ACL_EXTENDED_ALLOW) == -1) - goto error; - - if(acl_set_permset(entry, permset) == -1) - goto error; - if(acl_set_qualifier(entry, qual) == -1) - goto error; - - if (filesec_set_property(tmp_fsec, FILESEC_ACL, &acl) != 0) - goto error; - } - - if (filesec_get_property(tmp_fsec, FILESEC_MODE, &mode) == 0) - { - if (~mode & S_IWUSR) - { - mode |= S_IWUSR; - if (filesec_set_property(tmp_fsec, FILESEC_MODE, &mode) != 0) - goto error; - } - } - if (fchmodx_np(s->dst_fd, tmp_fsec) < 0 && errno != ENOTSUP) - copyfile_warn("setting security information"); - filesec_free(tmp_fsec); - } else - if (fchmodx_np(s->dst_fd, *fsec) < 0 && errno != ENOTSUP) - copyfile_warn("setting security information"); - - return 0; -error: - filesec_free(*fsec); - return -1; -} - - -static int copyfile_open(copyfile_state_t s) -{ - int oflags = O_EXCL | O_CREAT; - - if (s->src && s->src_fd == -2) - { - if ((COPYFILE_NOFOLLOW_SRC & s->flags ? lstatx_np : statx_np) - (s->src, &s->sb, s->fsec)) - { - copyfile_warn("stat on %s", s->src); - return -1; - } - if ((s->src_fd = open(s->src, O_RDONLY, 0)) < 0) - { - copyfile_warn("open on %s", s->src); - return -1; - } - } - - if (s->dst && s->dst_fd == -2) - { - if (COPYFILE_DATA & s->flags || COPYFILE_PACK & s->flags) - oflags |= O_WRONLY; - - if (COPYFILE_ACL & ~s->flags) - { - if (filesec_set_property(s->fsec, FILESEC_ACL, NULL) == -1) - { - copyfile_debug(1, "unsetting acl attribute on %s", s->dst); - } - } - if (COPYFILE_STAT & ~s->flags) - { - if (filesec_set_property(s->fsec, FILESEC_MODE, NULL) == -1) - { - copyfile_debug(1, "unsetting mode attribute on %s", s->dst); - } - } - if (COPYFILE_PACK & s->flags) - { - mode_t m = S_IRUSR; - if (filesec_set_property(s->fsec, FILESEC_MODE, &m) == -1) - { - mode_t m = S_IRUSR | S_IWUSR; - if (filesec_set_property(s->fsec, FILESEC_MODE, &m) == -1) - { - copyfile_debug(1, "setting mode attribute on %s", s->dst); - } - } - if (filesec_set_property(s->fsec, FILESEC_OWNER, NULL) == -1) - { - copyfile_debug(1, "unsetting uid attribute on %s", s->dst); - } - if (filesec_set_property(s->fsec, FILESEC_UUID, NULL) == -1) - { - copyfile_debug(1, "unsetting uuid attribute on %s", s->dst); - } - if (filesec_set_property(s->fsec, FILESEC_GROUP, NULL) == -1) - { - copyfile_debug(1, "unsetting gid attribute on %s", s->dst); - } - } - - if (COPYFILE_UNLINK & s->flags && unlink(s->dst) < 0) - { - copyfile_warn("%s: remove", s->dst); - return -1; - } - - while((s->dst_fd = open(s->dst, oflags, s->sb.st_mode | S_IWUSR)) < 0) - { - /* - * We set S_IWUSR because fsetxattr does not -- at the time this comment - * was written -- allow one to set an extended attribute on a file descriptor - * for a read-only file, even if the file descriptor is opened for writing. - * This will only matter if the file does not already exist. - */ - switch(errno) - { - case EEXIST: - copyfile_debug(3, "open failed, retrying (%s)", s->dst); - if (s->flags & COPYFILE_EXCL) - break; - oflags = oflags & ~O_CREAT; - if (s->flags & (COPYFILE_PACK | COPYFILE_DATA)) - { - copyfile_debug(4, "truncating existing file (%s)", s->dst); - oflags |= O_TRUNC; - } - continue; - case EACCES: - if(chmod(s->dst, (s->sb.st_mode | S_IWUSR) & ~S_IFMT) == 0) - continue; - else { - break; - } - } - copyfile_warn("open on %s", s->dst); - return -1; - } - } - return 0; -} - -static copyfile_flags_t copyfile_check(copyfile_state_t s) -{ - acl_t acl; - copyfile_flags_t ret = 0; - - if (!s->src) - return ret; - - // check EAs - if (COPYFILE_XATTR & s->flags) - if (listxattr(s->src, 0, 0, 0) > 0) - ret |= COPYFILE_XATTR; - - if (COPYFILE_ACL & s->flags) - { - (COPYFILE_NOFOLLOW_SRC & s->flags ? lstatx_np : statx_np) - (s->src, &s->sb, s->fsec); - - if (filesec_get_property(s->fsec, FILESEC_ACL, &acl) == 0) - ret |= COPYFILE_ACL; - } - - return ret; -} - -static int copyfile_data(copyfile_state_t s) -{ - unsigned int blen; - char *bp; - int nread; - int ret; - - if ((bp = malloc((size_t)s->sb.st_blksize)) == NULL) - { - blen = 0; - warnx("malloc failed"); - return -1; - } - blen = s->sb.st_blksize; - - while ((nread = read(s->src_fd, bp, (size_t)blen)) > 0) - { - if (write(s->dst_fd, bp, (size_t)nread) != nread) - { - copyfile_warn("writing to %s", s->dst); - return -1; - } - } - if (nread < 0) - { - copyfile_warn("reading from %s", s->src); - ret = -1; - } - - free(bp); - - if (ftruncate(s->dst_fd, s->sb.st_size) < 0) - ret = -1; - - return ret; -} - -static int copyfile_security(copyfile_state_t s) -{ - filesec_t fsec_dst = filesec_init(); - - int copied = 0; - acl_flagset_t flags; - struct stat sb; - acl_entry_t entry_src = NULL, entry_dst = NULL; - acl_t acl_src, acl_dst; - int inited_dst = 0, inited_src = 0, ret = 0; - - if (COPYFILE_ACL & s->flags) - { - if(fstatx_np(s->dst_fd, &sb, fsec_dst)) - { - goto cleanup; - } - - if (filesec_get_property(fsec_dst, FILESEC_ACL, &acl_dst)) - { - if (errno == ENOENT) - { - acl_dst = acl_init(4); - inited_dst = 1; - } - else - { - ret = -1; - goto cleanup; - } - } - - if (filesec_get_property(s->fsec, FILESEC_ACL, &acl_src)) - { - if (errno == ENOENT) - { - if (inited_dst) - goto no_acl; - acl_dst = acl_init(4); - inited_src = 1; - } - else - { - ret = -1; - goto cleanup; - } - } - - for (;acl_get_entry(acl_src, - entry_src == NULL ? ACL_FIRST_ENTRY : ACL_NEXT_ENTRY, - &entry_src) == 0;) - { - acl_get_flagset_np(entry_src, &flags); - if (!acl_get_flag_np(flags, ACL_ENTRY_INHERITED)) - { - if ((ret = acl_create_entry(&acl_dst, &entry_dst)) == -1) - goto cleanup; - - if ((ret = acl_copy_entry(entry_dst, entry_src)) == -1) - goto cleanup; - - copyfile_debug(1, "copied acl entry from %s to %s", s->src, s->dst); - copied++; - } - } - - if (!filesec_set_property(fsec_dst, FILESEC_ACL, &acl_dst)) - { - copyfile_debug(1, "altered acl"); - } - } -no_acl: - if (fchmodx_np(s->dst_fd, fsec_dst) < 0 && errno != ENOTSUP) - { - copyfile_warn("setting security information: %s", s->dst); - ret = -1; - } - -cleanup: - filesec_free(fsec_dst); - if (inited_src) acl_free(acl_src); - if (inited_dst) acl_free(acl_dst); - - return ret; -} - -static int copyfile_stat(copyfile_state_t s) -{ - struct timeval tval[2]; - /* - * NFS doesn't support chflags; ignore errors unless there's reason - * to believe we're losing bits. (Note, this still won't be right - * if the server supports flags and we were trying to *remove* flags - * on a file that we copied, i.e., that we didn't create.) - */ - if (chflags(s->dst, (u_long)s->sb.st_flags)) - if (errno != EOPNOTSUPP || s->sb.st_flags != 0) - copyfile_warn("%s: set flags (was: 0%07o)", s->dst, s->sb.st_flags); - - tval[0].tv_sec = s->sb.st_atime; - tval[1].tv_sec = s->sb.st_mtime; - tval[0].tv_usec = tval[1].tv_usec = 0; - if (utimes(s->dst, tval)) - copyfile_warn("%s: set times", s->dst); - return 0; -} - -static int copyfile_xattr(copyfile_state_t s) -{ - char *name; - char *namebuf; - size_t xa_size; - void *xa_dataptr; - size_t bufsize = 4096; - ssize_t asize; - ssize_t nsize; - int ret = 0; - int flags = 0; - - if (COPYFILE_NOFOLLOW_SRC & s->flags) - flags |= XATTR_NOFOLLOW; - - /* delete EAs on destination */ - if ((nsize = flistxattr(s->dst_fd, 0, 0, 0)) > 0) - { - if ((namebuf = (char *) malloc(nsize)) == NULL) - return -1; - else - nsize = flistxattr(s->dst_fd, namebuf, nsize, 0); - - if (nsize > 0) - for (name = namebuf; name < namebuf + nsize; name += strlen(name) + 1) - fremovexattr(s->dst_fd, name,flags); - - free(namebuf); - } else if (nsize < 0) - { - if (errno == ENOTSUP) - return 0; - else - return -1; - } - - /* get name list of EAs on source */ - if ((nsize = flistxattr(s->src_fd, 0, 0, 0)) < 0) - { - if (errno == ENOTSUP) - return 0; - else - return -1; - } else if (nsize == 0) - return 0; - - if ((namebuf = (char *) malloc(nsize)) == NULL) - return -1; - else - nsize = flistxattr(s->src_fd, namebuf, nsize, 0); - - if (nsize <= 0) - return nsize; - - if ((xa_dataptr = (void *) malloc(bufsize)) == NULL) - return -1; - - for (name = namebuf; name < namebuf + nsize; name += strlen(name) + 1) - { - if ((xa_size = fgetxattr(s->src_fd, name, 0, 0, 0, flags)) < 0) - { - ret = -1; - continue; - } - - if (xa_size > bufsize) - { - bufsize = xa_size; - if ((xa_dataptr = - (void *) realloc((void *) xa_dataptr, bufsize)) == NULL) - { - ret = -1; - continue; - } - } - - if ((asize = fgetxattr(s->src_fd, name, xa_dataptr, xa_size, 0, flags)) < 0) - { - ret = -1; - continue; - } - - if (xa_size != asize) - xa_size = asize; - - if (fsetxattr(s->dst_fd, name, xa_dataptr, xa_size, 0, flags) < 0) - { - ret = -1; - continue; - } - } - free((void *) xa_dataptr); - return ret; -} - - -#ifdef _COPYFILE_TEST -#define COPYFILE_OPTION(x) { #x, COPYFILE_ ## x }, - -struct {char *s; int v;} opts[] = { - COPYFILE_OPTION(ACL) - COPYFILE_OPTION(STAT) - COPYFILE_OPTION(XATTR) - COPYFILE_OPTION(DATA) - COPYFILE_OPTION(SECURITY) - COPYFILE_OPTION(METADATA) - COPYFILE_OPTION(ALL) - COPYFILE_OPTION(NOFOLLOW_SRC) - COPYFILE_OPTION(NOFOLLOW_DST) - COPYFILE_OPTION(NOFOLLOW) - COPYFILE_OPTION(EXCL) - COPYFILE_OPTION(MOVE) - COPYFILE_OPTION(UNLINK) - COPYFILE_OPTION(PACK) - COPYFILE_OPTION(UNPACK) - COPYFILE_OPTION(CHECK) - COPYFILE_OPTION(VERBOSE) - COPYFILE_OPTION(DEBUG) - {NULL, 0} -}; - -int main(int c, char *v[]) -{ - int i; - int flags = 0; - - if (c < 3) - errx(1, "insufficient arguments"); - - while(c-- > 3) - { - for (i = 0; opts[i].s != NULL; ++i) - { - if (strcasecmp(opts[i].s, v[c]) == 0) - { - printf("option %d: %s <- %d\n", c, opts[i].s, opts[i].v); - flags |= opts[i].v; - break; - } - } - } - - return copyfile(v[1], v[2], NULL, flags); -} -#endif -/* - * Apple Double Create - * - * Create an Apple Double "._" file from a file's extented attributes - * - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. - */ - - -#define offsetof(type, member) ((size_t)(&((type *)0)->member)) - -#define XATTR_MAXATTRLEN (4*1024) - - -/* - Typical "._" AppleDouble Header File layout: - ------------------------------------------------------------ - MAGIC 0x00051607 - VERSION 0x00020000 - FILLER 0 - COUNT 2 - .-- AD ENTRY[0] Finder Info Entry (must be first) - .--+-- AD ENTRY[1] Resource Fork Entry (must be last) - | '-> FINDER INFO - | ///////////// Fixed Size Data (32 bytes) - | EXT ATTR HDR - | ///////////// - | ATTR ENTRY[0] --. - | ATTR ENTRY[1] --+--. - | ATTR ENTRY[2] --+--+--. - | ... | | | - | ATTR ENTRY[N] --+--+--+--. - | ATTR DATA 0 <-' | | | - | //////////// | | | - | ATTR DATA 1 <----' | | - | ///////////// | | - | ATTR DATA 2 <-------' | - | ///////////// | - | ... | - | ATTR DATA N <----------' - | ///////////// - | Attribute Free Space - | - '----> RESOURCE FORK - ///////////// Variable Sized Data - ///////////// - ///////////// - ///////////// - ///////////// - ///////////// - ... - ///////////// - - ------------------------------------------------------------ - - NOTE: The EXT ATTR HDR, ATTR ENTRY's and ATTR DATA's are - stored as part of the Finder Info. The length in the Finder - Info AppleDouble entry includes the length of the extended - attribute header, attribute entries, and attribute data. -*/ - - -/* - * On Disk Data Structures - * - * Note: Motorola 68K alignment and big-endian. - * - * See RFC 1740 for additional information about the AppleDouble file format. - * - */ - -#define ADH_MAGIC 0x00051607 -#define ADH_VERSION 0x00020000 -#define ADH_MACOSX "Mac OS X " - -/* - * AppleDouble Entry ID's - */ -#define AD_DATA 1 /* Data fork */ -#define AD_RESOURCE 2 /* Resource fork */ -#define AD_REALNAME 3 /* FileÕs name on home file system */ -#define AD_COMMENT 4 /* Standard Mac comment */ -#define AD_ICONBW 5 /* Mac black & white icon */ -#define AD_ICONCOLOR 6 /* Mac color icon */ -#define AD_UNUSED 7 /* Not used */ -#define AD_FILEDATES 8 /* File dates; create, modify, etc */ -#define AD_FINDERINFO 9 /* Mac Finder info & extended info */ -#define AD_MACINFO 10 /* Mac file info, attributes, etc */ -#define AD_PRODOSINFO 11 /* Pro-DOS file info, attrib., etc */ -#define AD_MSDOSINFO 12 /* MS-DOS file info, attributes, etc */ -#define AD_AFPNAME 13 /* Short name on AFP server */ -#define AD_AFPINFO 14 /* AFP file info, attrib., etc */ -#define AD_AFPDIRID 15 /* AFP directory ID */ -#define AD_ATTRIBUTES AD_FINDERINFO - - -#define ATTR_FILE_PREFIX "._" -#define ATTR_HDR_MAGIC 0x41545452 /* 'ATTR' */ - -#define ATTR_BUF_SIZE 4096 /* default size of the attr file and how much we'll grow by */ - -/* Implementation Limits */ -#define ATTR_MAX_SIZE (128*1024) /* 128K maximum attribute data size */ -#define ATTR_MAX_NAME_LEN 128 -#define ATTR_MAX_HDR_SIZE (65536+18) - -/* - * Note: ATTR_MAX_HDR_SIZE is the largest attribute header - * size supported (including the attribute entries). All of - * the attribute entries must reside within this limit. - */ - - -#pragma options align=mac68k - -#define FINDERINFOSIZE 32 - -typedef struct apple_double_entry -{ - u_int32_t type; /* entry type: see list, 0 invalid */ - u_int32_t offset; /* entry data offset from the beginning of the file. */ - u_int32_t length; /* entry data length in bytes. */ -} __attribute__((packed)) apple_double_entry_t; - - -typedef struct apple_double_header -{ - u_int32_t magic; /* == ADH_MAGIC */ - u_int32_t version; /* format version: 2 = 0x00020000 */ - u_int32_t filler[4]; - u_int16_t numEntries; /* number of entries which follow */ - apple_double_entry_t entries[2]; /* 'finfo' & 'rsrc' always exist */ - u_int8_t finfo[FINDERINFOSIZE]; /* Must start with Finder Info (32 bytes) */ - u_int8_t pad[2]; /* get better alignment inside attr_header */ -} __attribute__((packed)) apple_double_header_t; - - -/* Entries are aligned on 4 byte boundaries */ -typedef struct attr_entry -{ - u_int32_t offset; /* file offset to data */ - u_int32_t length; /* size of attribute data */ - u_int16_t flags; - u_int8_t namelen; /* length of name including NULL termination char */ - u_int8_t name[1]; /* NULL-terminated UTF-8 name (up to 128 bytes max) */ -} __attribute__((packed)) attr_entry_t; - - -/* Header + entries must fit into 64K */ -typedef struct attr_header -{ - apple_double_header_t appledouble; - u_int32_t magic; /* == ATTR_HDR_MAGIC */ - u_int32_t debug_tag; /* for debugging == file id of owning file */ - u_int32_t total_size; /* total size of attribute header + entries + data */ - u_int32_t data_start; /* file offset to attribute data area */ - u_int32_t data_length; /* length of attribute data area */ - u_int32_t reserved[3]; - u_int16_t flags; - u_int16_t num_attrs; -} __attribute__((packed)) attr_header_t; - - -#pragma options align=reset - -#define SWAP16(x) OSSwapBigToHostInt16(x) -#define SWAP32(x) OSSwapBigToHostInt32(x) -#define SWAP64(x) OSSwapBigToHostInt64(x) - -#define ATTR_ALIGN 3L /* Use four-byte alignment */ - -#define ATTR_ENTRY_LENGTH(namelen) \ - ((sizeof(attr_entry_t) - 1 + (namelen) + ATTR_ALIGN) & (~ATTR_ALIGN)) - -#define ATTR_NEXT(ae) \ - (attr_entry_t *)((u_int8_t *)(ae) + ATTR_ENTRY_LENGTH((ae)->namelen)) - -#define XATTR_SECURITY_NAME "com.apple.acl.text" - -/* - * Endian swap Apple Double header - */ -static void -swap_adhdr(apple_double_header_t *adh) -{ -#if BYTE_ORDER == LITTLE_ENDIAN - int count; - int i; - - count = (adh->magic == ADH_MAGIC) ? adh->numEntries : SWAP16(adh->numEntries); - - adh->magic = SWAP32 (adh->magic); - adh->version = SWAP32 (adh->version); - adh->numEntries = SWAP16 (adh->numEntries); - - for (i = 0; i < count; i++) - { - adh->entries[i].type = SWAP32 (adh->entries[i].type); - adh->entries[i].offset = SWAP32 (adh->entries[i].offset); - adh->entries[i].length = SWAP32 (adh->entries[i].length); - } -#endif -} - -/* - * Endian swap extended attributes header - */ -static void -swap_attrhdr(attr_header_t *ah) -{ -#if BYTE_ORDER == LITTLE_ENDIAN - attr_entry_t *ae; - int count; - int i; - - count = (ah->magic == ATTR_HDR_MAGIC) ? ah->num_attrs : SWAP16(ah->num_attrs); - - ah->magic = SWAP32 (ah->magic); - ah->debug_tag = SWAP32 (ah->debug_tag); - ah->total_size = SWAP32 (ah->total_size); - ah->data_start = SWAP32 (ah->data_start); - ah->data_length = SWAP32 (ah->data_length); - ah->flags = SWAP16 (ah->flags); - ah->num_attrs = SWAP16 (ah->num_attrs); - - ae = (attr_entry_t *)(&ah[1]); - for (i = 0; i < count; i++, ae++) - { - ae->offset = SWAP32 (ae->offset); - ae->length = SWAP32 (ae->length); - ae->flags = SWAP16 (ae->flags); - } -#endif -} - -static const u_int32_t emptyfinfo[8] = {0}; - -static int copyfile_unpack(copyfile_state_t s) -{ - ssize_t bytes; - void * buffer, * endptr; - apple_double_header_t *adhdr; - size_t hdrsize; - int error = 0; - - if (s->sb.st_size < ATTR_MAX_HDR_SIZE) - hdrsize = s->sb.st_size; - else - hdrsize = ATTR_MAX_HDR_SIZE; - - buffer = calloc(1, hdrsize); - if (buffer == NULL) { - copyfile_debug(1, "copyfile_unpack: calloc(1, %u) returned NULL", hdrsize); - error = -1; - goto exit; - } else - endptr = (char*)buffer + hdrsize; - - bytes = pread(s->src_fd, buffer, hdrsize, 0); - - if (bytes < 0) - { - copyfile_debug(1, "pread returned: %d", bytes); - error = -1; - goto exit; - } - if (bytes < hdrsize) - { - copyfile_debug(1, - "pread couldn't read entire header: %d of %d", - (int)bytes, (int)s->sb.st_size); - error = -1; - goto exit; - } - adhdr = (apple_double_header_t *)buffer; - - /* - * Check for Apple Double file. - */ - if (bytes < sizeof(apple_double_header_t) - 2 || - SWAP32(adhdr->magic) != ADH_MAGIC || - SWAP32(adhdr->version) != ADH_VERSION || - SWAP16(adhdr->numEntries) != 2 || - SWAP32(adhdr->entries[0].type) != AD_FINDERINFO) - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("Not a valid Apple Double header"); - error = -1; - goto exit; - } - swap_adhdr(adhdr); - - /* - * Extract the extended attributes. - * - * >>> WARNING <<< - * This assumes that the data is already in memory (not - * the case when there are lots of attributes or one of - * the attributes is very large. - */ - if (adhdr->entries[0].length > FINDERINFOSIZE) - { - attr_header_t *attrhdr; - attr_entry_t *entry; - int count; - int i; - - if (hdrsize < sizeof(attr_header_t)) { - copyfile_warn("bad attribute header: %u < %u", hdrsize, sizeof(attr_header_t)); - error = -1; - goto exit; - } - - attrhdr = (attr_header_t *)buffer; - swap_attrhdr(attrhdr); - if (attrhdr->magic != ATTR_HDR_MAGIC) - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("bad attribute header"); - error = -1; - goto exit; - } - count = attrhdr->num_attrs; - entry = (attr_entry_t *)&attrhdr[1]; - - for (i = 0; i < count; i++) - { - void * dataptr; - - /* - * First we do some simple sanity checking. - * +) See if entry is within the buffer's range; - * - * +) Check the attribute name length; if it's longer than the - * maximum, we truncate it down. (We could error out as well; - * I'm not sure which is the better way to go here.) - * - * +) If, given the name length, it goes beyond the end of - * the buffer, error out. - * - * +) If the last byte isn't a NUL, make it a NUL. (Since we - * truncated the name length above, we truncate the name here.) - * - * +) If entry->offset is so large that it causes dataptr to - * go beyond the end of the buffer -- or, worse, so large that - * it wraps around! -- we error out. - * - * +) If entry->length would cause the entry to go beyond the - * end of the buffer (or, worse, wrap around to before it), - * *or* if the length is larger than the hdrsize, we error out. - * (An explanation of that: what we're checking for there is - * the small range of values such that offset+length would cause - * it to go beyond endptr, and then wrap around past buffer. We - * care about this because we are passing entry->length down to - * fgetxattr() below, and an erroneously large value could cause - * problems there. By making sure that it's less than hdrsize, - * which has already been sanity-checked above, we're safe. - * That may mean that the check against < buffer is unnecessary.) - */ - if ((void*)entry >= endptr || (void*)entry < buffer) { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("Incomplete or corrupt attribute entry"); - error = -1; - goto exit; - } - - if (((void*)entry + sizeof(*entry)) > endptr) { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("Incomplete or corrupt attribute entry"); - error = -1; - goto exit; - } - - if (entry->namelen < 2) { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("Corrupt attribute entry (only %d bytes)", entry->namelen); - error = -1; - goto exit; - } - if (entry->namelen > ATTR_MAX_NAME_LEN + 1) { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("Corrupt attribute entry (name length is %d bytes)", entry->namelen); - error = -1; - goto exit; - } - if ((void*)(entry->name + entry->namelen) >= endptr) { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("Incomplete or corrupt attribute entry"); - error = -1; - goto exit; - } - - /* Because namelen includes the NUL, we check one byte back */ - if (entry->name[entry->namelen-1] != 0) { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("Corrupt attribute entry (name is not NUL-terminated)"); - error = -1; - goto exit; - } - - copyfile_debug(3, "extracting \"%s\" (%d bytes) at offset %u", - entry->name, entry->length, entry->offset); - - dataptr = (char *)attrhdr + entry->offset; - - if (dataptr >= endptr || dataptr < buffer) { - copyfile_debug(1, "Entry %d overflows: offset = %u", entry->offset); - error = -1; - goto exit; - } - if ((dataptr + entry->length) > endptr || - ((dataptr + entry->length) < buffer) || - (entry->length > hdrsize)) { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("Incomplete or corrupt attribute entry"); - copyfile_debug(1, "Entry %d length overflows: dataptr = %u, offset = %u, length = %u, buffer = %u, endptr = %u", - i, dataptr, entry->offset, entry->length, buffer, endptr); - error = -1; - goto exit; - } - - if (COPYFILE_ACL & s->flags && strcmp((char*)entry->name, XATTR_SECURITY_NAME) == 0) - copyfile_debug(2, "extracting \"%s\" (%d bytes)", - entry->name, entry->length); - dataptr = (char *)attrhdr + entry->offset; - - if (COPYFILE_ACL & s->flags && strncmp(entry->name, XATTR_SECURITY_NAME, strlen(XATTR_SECURITY_NAME)) == 0) - { - acl_t acl; - char *tacl = strdup(dataptr); - if (tacl) - { - tacl[entry->length] = 0; /* Ensure it is NUL-terminated */ - if (acl = acl_from_text(tacl)) - { - filesec_t tfsec = filesec_init(); - if (tfsec) - { - if (filesec_set_property(tfsec, FILESEC_ACL, &acl) < 0) - { - copyfile_debug(1, "setting acl"); - error = -1; - } - else if (fchmodx_np(s->dst_fd, tfsec) < 0 && errno != ENOTSUP) - { - error = -1; - copyfile_debug(1, "applying acl to file"); - } - filesec_free(tfsec); - } - acl_free(acl); - } - free(tacl); - } - if (error) - goto exit; - } else - if (COPYFILE_XATTR & s->flags && (fsetxattr(s->dst_fd, entry->name, dataptr, entry->length, 0, 0))) { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("error %d setting attribute %s", error, entry->name); - break; - } - entry = ATTR_NEXT(entry); - } - } - - /* - * Extract the Finder Info. - */ - if (adhdr->entries[0].offset > (hdrsize - sizeof(emptyfinfo))) { - error = -1; - goto exit; - } - - if (bcmp((u_int8_t*)buffer + adhdr->entries[0].offset, emptyfinfo, sizeof(emptyfinfo)) != 0) - { - copyfile_debug(1, " extracting \"%s\" (32 bytes)", XATTR_FINDERINFO_NAME); - error = fsetxattr(s->dst_fd, XATTR_FINDERINFO_NAME, (u_int8_t*)buffer + adhdr->entries[0].offset, sizeof(emptyfinfo), 0, 0); - if (error) - goto exit; - } - - /* - * Extract the Resource Fork. - */ - if (adhdr->entries[1].type == AD_RESOURCE && - adhdr->entries[1].length > 0) - { - void * rsrcforkdata = NULL; - size_t length; - off_t offset; - struct stat sb; - struct timeval tval[2]; - - length = adhdr->entries[1].length; - offset = adhdr->entries[1].offset; - rsrcforkdata = malloc(length); - - if (rsrcforkdata == NULL) { - copyfile_debug(1, "could not allocate %u bytes for rsrcforkdata", - length); - error = -1; - goto bad; - } - - if (fstat(s->dst_fd, &sb) < 0) - { - copyfile_debug(1, "couldn't stat destination file"); - error = -1; - goto exit; - } - - bytes = pread(s->src_fd, rsrcforkdata, length, offset); - if (bytes < length) - { - if (bytes == -1) - { - copyfile_debug(1, "couldn't read resource fork"); - } - else - { - copyfile_debug(1, - "couldn't read resource fork (only read %d bytes of %d)", - (int)bytes, (int)length); - } - error = -1; - goto bad; - } - error = fsetxattr(s->dst_fd, XATTR_RESOURCEFORK_NAME, rsrcforkdata, bytes, 0, 0); - if (error) - { - copyfile_debug(1, "error %d setting resource fork attribute", error); - error = -1; - goto bad; - } - copyfile_debug(1, "extracting \"%s\" (%d bytes)", - XATTR_RESOURCEFORK_NAME, (int)length); - - tval[0].tv_sec = sb.st_atime; - tval[1].tv_sec = sb.st_mtime; - tval[0].tv_usec = tval[1].tv_usec = 0; - - if (futimes(s->dst_fd, tval)) - { - copyfile_warn("cannot set time on destination file %s", s->dst ? s->dst : ""); - } - -bad: - if (rsrcforkdata) - free(rsrcforkdata); - } -exit: - if (buffer) free(buffer); - return error; -} - -static int copyfile_pack_acl(copyfile_state_t s, void **buf, ssize_t *len) -{ - int ret = 0; - acl_t acl; - char *acl_text; - - if (filesec_get_property(s->fsec, FILESEC_ACL, &acl) < 0) - { - if (errno != ENOENT) - { - ret = -1; - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("getting acl"); - } - goto err; - } - - if ((acl_text = acl_to_text(acl, len)) != NULL) - { - *buf = malloc(*len); - memcpy(*buf, acl_text, *len); - acl_free(acl_text); - } - copyfile_debug(1, "copied acl (%ld) %p", *len, *buf); -err: - return ret; -} - -static int copyfile_pack_rsrcfork(copyfile_state_t s, attr_header_t *filehdr) -{ - int datasize; - char *databuf; - - /* Get the resource fork size */ - if ((datasize = fgetxattr(s->src_fd, XATTR_RESOURCEFORK_NAME, NULL, 0, 0, 0)) < 0) - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("skipping attr \"%s\" due to error %d", XATTR_RESOURCEFORK_NAME, errno); - return -1; - } - - if ((databuf = malloc(datasize)) == NULL) - { - copyfile_warn("malloc"); - return -1; - } - - if (fgetxattr(s->src_fd, XATTR_RESOURCEFORK_NAME, databuf, datasize, 0, 0) != datasize) - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("couldn't read entire resource fork"); - return -1; - } - - /* Write the resource fork to disk. */ - if (pwrite(s->dst_fd, databuf, datasize, filehdr->appledouble.entries[1].offset) != datasize) - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("couldn't write resource fork"); - } - copyfile_debug(1, "copied %d bytes of \"%s\" data @ offset 0x%08x", - datasize, XATTR_RESOURCEFORK_NAME, filehdr->appledouble.entries[1].offset); - filehdr->appledouble.entries[1].length = datasize; - free(databuf); - - return 0; -} - - -static int copyfile_pack(copyfile_state_t s) -{ - char *attrnamebuf = NULL, *endnamebuf; - void *databuf = NULL; - attr_header_t *filehdr, *endfilehdr; - attr_entry_t *entry; - ssize_t listsize = 0; - char *nameptr; - int namelen; - int entrylen; - ssize_t datasize; - int offset = 0; - int hasrsrcfork = 0; - int error = 0; - - filehdr = (attr_header_t *) calloc(1, ATTR_MAX_SIZE); - if (filehdr == NULL) { - error = -1; - goto exit; - } else { - endfilehdr = ((void*)filehdr) + ATTR_MAX_SIZE; - } - - attrnamebuf = calloc(1, ATTR_MAX_HDR_SIZE); - if (attrnamebuf == NULL) { - error = -1; - goto exit; - } else { - endnamebuf = ((char*)attrnamebuf) + ATTR_MAX_HDR_SIZE; - } - - /* - * Fill in the Apple Double Header defaults. - */ - filehdr->appledouble.magic = ADH_MAGIC; - filehdr->appledouble.version = ADH_VERSION; - filehdr->appledouble.numEntries = 2; - filehdr->appledouble.entries[0].type = AD_FINDERINFO; - filehdr->appledouble.entries[0].offset = offsetof(apple_double_header_t, finfo); - filehdr->appledouble.entries[0].length = FINDERINFOSIZE; - filehdr->appledouble.entries[1].type = AD_RESOURCE; - filehdr->appledouble.entries[1].offset = offsetof(apple_double_header_t, pad); - filehdr->appledouble.entries[1].length = 0; - bcopy(ADH_MACOSX, filehdr->appledouble.filler, sizeof(filehdr->appledouble.filler)); - - /* - * Fill in the initial Attribute Header. - */ - filehdr->magic = ATTR_HDR_MAGIC; - filehdr->debug_tag = s->sb.st_ino; - filehdr->data_start = sizeof(attr_header_t); - - /* - * Collect the attribute names. - */ - entry = (attr_entry_t *)((char *)filehdr + sizeof(attr_header_t)); - - /* - * Test if there are acls to copy - */ - if (COPYFILE_ACL & s->flags) - { - if (filesec_get_property(s->fsec, FILESEC_ACL, &datasize) < 0) - { - copyfile_debug(1, "no acl entries found (%d)", datasize < 0 ? errno : 0); - } else - { - offset = strlen(XATTR_SECURITY_NAME) + 1; - strcpy(attrnamebuf, XATTR_SECURITY_NAME); - } - } - - if (COPYFILE_XATTR & s->flags) - { - ssize_t left = ATTR_MAX_HDR_SIZE - offset; - if ((listsize = flistxattr(s->src_fd, attrnamebuf + offset, left, 0)) <= 0) - { - copyfile_debug(1, "no extended attributes found (%d)", errno); - } - if (listsize > left) - { - copyfile_debug(1, "extended attribute list too long"); - listsize = ATTR_MAX_HDR_SIZE; - } - - listsize += offset; - endnamebuf = attrnamebuf + listsize; - if (endnamebuf > (attrnamebuf + ATTR_MAX_HDR_SIZE)) { - error = -1; - goto exit; - } - - for (nameptr = attrnamebuf; nameptr XATTR_MAXNAMELEN + 1) { - namelen = XATTR_MAXNAMELEN + 1; - } - entry->namelen = namelen; - entry->flags = 0; - bcopy(nameptr, &entry->name[0], namelen); - copyfile_debug(2, "copied name [%s]", entry->name); - - entrylen = ATTR_ENTRY_LENGTH(namelen); - entry = (attr_entry_t *)(((char *)entry) + entrylen); - - if ((void*)entry > (void*)endfilehdr) { - error = -1; - goto exit; - } - - /* Update the attributes header. */ - filehdr->num_attrs++; - filehdr->data_start += entrylen; - } - } - - /* - * Collect the attribute data. - */ - entry = (attr_entry_t *)((char *)filehdr + sizeof(attr_header_t)); - - for (nameptr = attrnamebuf; nameptr < attrnamebuf + listsize; nameptr += namelen + 1) - { - namelen = strlen(nameptr); - - if (strcmp(nameptr, XATTR_SECURITY_NAME) == 0) - copyfile_pack_acl(s, &databuf, &datasize); - else - /* Check for Finder Info. */ - if (strcmp(nameptr, XATTR_FINDERINFO_NAME) == 0) - { - datasize = fgetxattr(s->src_fd, nameptr, (u_int8_t*)filehdr + filehdr->appledouble.entries[0].offset, 32, 0, 0); - if (datasize < 0) - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("skipping attr \"%s\" due to error %d", nameptr, errno); - } else if (datasize != 32) - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("unexpected size (%ld) for \"%s\"", datasize, nameptr); - } else - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn(" copied 32 bytes of \"%s\" data @ offset 0x%08x", - XATTR_FINDERINFO_NAME, filehdr->appledouble.entries[0].offset); - } - continue; /* finder info doesn't have an attribute entry */ - } else - /* Check for Resource Fork. */ - if (strcmp(nameptr, XATTR_RESOURCEFORK_NAME) == 0) - { - hasrsrcfork = 1; - continue; - } else - { - /* Just a normal attribute. */ - datasize = fgetxattr(s->src_fd, nameptr, NULL, 0, 0, 0); - if (datasize == 0) - goto next; - if (datasize < 0) - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("skipping attr \"%s\" due to error %d", nameptr, errno); - goto next; - } - if (datasize > XATTR_MAXATTRLEN) - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("skipping attr \"%s\" (too big)", nameptr); - goto next; - } - databuf = malloc(datasize); - if (databuf == NULL) { - error = -1; - continue; - } - datasize = fgetxattr(s->src_fd, nameptr, databuf, datasize, 0, 0); - } - - entry->length = datasize; - entry->offset = filehdr->data_start + filehdr->data_length; - - filehdr->data_length += datasize; - /* - * >>> WARNING <<< - * This assumes that the data is fits in memory (not - * the case when there are lots of attributes or one of - * the attributes is very large. - */ - if (entry->offset > ATTR_MAX_SIZE || - (entry->offset + datasize > ATTR_MAX_SIZE)) { - error = -1; - } else { - bcopy(databuf, (char*)filehdr + entry->offset, datasize); - } - free(databuf); - - copyfile_debug(1, "copied %ld bytes of \"%s\" data @ offset 0x%08x", datasize, nameptr, entry->offset); -next: - /* bump to next entry */ - entrylen = ATTR_ENTRY_LENGTH(entry->namelen); - entry = (attr_entry_t *)((char *)entry + entrylen); - } - - if (filehdr->data_length > 0) - { - /* Now we know where the resource fork data starts. */ - filehdr->appledouble.entries[1].offset = (filehdr->data_start + filehdr->data_length); - - /* We also know the size of the "Finder Info entry. */ - filehdr->appledouble.entries[0].length = - filehdr->appledouble.entries[1].offset - filehdr->appledouble.entries[0].offset; - - filehdr->total_size = filehdr->appledouble.entries[1].offset; - } - - /* Copy Resource Fork. */ - if (hasrsrcfork && (error = copyfile_pack_rsrcfork(s, filehdr))) - goto exit; - - /* Write the header to disk. */ - datasize = filehdr->appledouble.entries[1].offset; - - swap_adhdr(&filehdr->appledouble); - swap_attrhdr(filehdr); - - if (pwrite(s->dst_fd, filehdr, datasize, 0) != datasize) - { - if (COPYFILE_VERBOSE & s->flags) - copyfile_warn("couldn't write file header"); - error = -1; - goto exit; - } -exit: - if (filehdr) free(filehdr); - if (attrnamebuf) free(attrnamebuf); - - if (error) - return error; - else - return copyfile_stat(s); -} diff --git a/darwin/copyfile.h b/darwin/copyfile.h deleted file mode 100644 index f99b7fe..0000000 --- a/darwin/copyfile.h +++ /dev/null @@ -1,86 +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@ - */ -#ifndef _COPYFILE_H_ /* version 0.1 */ -#define _COPYFILE_H_ - -/* - * this is a proposed API to add to libSystem to faciliatate copying - * of files and their associated metadata. There are several open - * source projects that need modifications to support preserving - * extended attributes and acls and this API collapses several hundred - * lines of modifications into one or two calls. - * - * This implementation is incomplete and the interface may change in a - * future release. - */ - -/* private */ -#include -struct _copyfile_state; -typedef struct _copyfile_state * copyfile_state_t; -typedef uint32_t copyfile_flags_t; - -/* public */ - -/* receives: - * from path to source file system object - * to path to destination file system object - * state opaque blob for future extensibility - * Must be NULL in current implementation - * flags (described below) - * returns: - * int negative for error - */ - -int copyfile(const char *from, const char *to, copyfile_state_t state, copyfile_flags_t flags); -int copyfile_free(copyfile_state_t); -copyfile_state_t copyfile_init(void); - -/* Flag for clients to disable their use of copyfile() */ -#define COPYFILE_DISABLE_VAR "COPY_EXTENDED_ATTRIBUTES_DISABLE" - -/* flags for copyfile */ - -#define COPYFILE_ACL (1<<0) -#define COPYFILE_STAT (1<<1) -#define COPYFILE_XATTR (1<<2) -#define COPYFILE_DATA (1<<3) - -#define COPYFILE_SECURITY (COPYFILE_STAT | COPYFILE_ACL) -#define COPYFILE_METADATA (COPYFILE_SECURITY | COPYFILE_XATTR) -#define COPYFILE_ALL (COPYFILE_METADATA | COPYFILE_DATA) - -#define COPYFILE_CHECK (1<<16) /* return flags for xattr or acls if set */ -#define COPYFILE_EXCL (1<<17) /* fail if destination exists */ -#define COPYFILE_NOFOLLOW_SRC (1<<18) /* don't follow if source is a symlink */ -#define COPYFILE_NOFOLLOW_DST (1<<19) /* don't follow if dst is a symlink */ -#define COPYFILE_MOVE (1<<20) /* unlink src after copy */ -#define COPYFILE_UNLINK (1<<21) /* unlink dst before copy */ -#define COPYFILE_NOFOLLOW (COPYFILE_NOFOLLOW_SRC | COPYFILE_NOFOLLOW_DST) - -#define COPYFILE_PACK (1<<22) -#define COPYFILE_UNPACK (1<<23) - -#define COPYFILE_VERBOSE (1<<30) - -#endif /* _COPYFILE_H_ */ diff --git a/ppc/sys/__pthread_markcancel.s b/darwin/dirhelper.defs similarity index 69% rename from ppc/sys/__pthread_markcancel.s rename to darwin/dirhelper.defs index ad7a4e8..ff428ed 100644 --- a/ppc/sys/__pthread_markcancel.s +++ b/darwin/dirhelper.defs @@ -1,15 +1,15 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * 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, @@ -17,11 +17,19 @@ * 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 "SYS.h" +#include +#include -SYSCALL(__pthread_markcancel, 1) +subsystem dirhelper 47213; +serverprefix do_; +routine __dirhelper_create_user_local( + server_port : mach_port_t; + ServerAuditToken remote_creds : audit_token_t); +routine __dirhelper_idle_exit( + server_port : mach_port_t; + ServerAuditToken remote_creds : audit_token_t); diff --git a/i386/sys/sem_wait.s b/darwin/dirhelper_priv.h similarity index 57% rename from i386/sys/sem_wait.s rename to darwin/dirhelper_priv.h index 5a656e5..1473333 100644 --- a/i386/sys/sem_wait.s +++ b/darwin/dirhelper_priv.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2006, 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, @@ -17,11 +17,33 @@ * 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 -UNIX_SYSCALL(sem_wait, 1) - ret +#ifndef _DIRHELPER_PRIV_H_ +#define _DIRHELPER_PRIV_H_ + +#include +#include + +#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 "" + +typedef enum { + DIRHELPER_USER_LOCAL = 0, + DIRHELPER_USER_LOCAL_TEMP, + DIRHELPER_USER_LOCAL_CACHE, + DIRHELPER_USER_LOCAL_LAST = DIRHELPER_USER_LOCAL_CACHE +} dirhelper_which_t; + +__BEGIN_DECLS +char *__user_local_dirname(uid_t uid, dirhelper_which_t which, char *path, + size_t pathlen); +__END_DECLS +#endif /* _DIRHELPER_PRIV_H_ */ diff --git a/darwin/kvm.c b/darwin/kvm.c new file mode 100644 index 0000000..60ba30b --- /dev/null +++ b/darwin/kvm.c @@ -0,0 +1,107 @@ +/* + * 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 +#include + +int +kvm_close(void* kd) +{ + return (0); +} + +char** +kvm_getargv(void* kd, const void* p, int nchr) +{ + return (0); +} + +char** +kvm_getenvv(void* kd, const void* p, int nchr) +{ + return (0); +} + +char* +kvm_geterr(void* kd) +{ + return (0); +} + +int +kvm_getloadavg(void* kd, double loadagv[], int nelem) +{ + return (-1); +} + +char* +kvm_getfiles(void* kd, int op, int arg, int* cnt) +{ + if (cnt) *cnt = 0; + return (0); +} + +void* +kvm_getprocs(void* kd, int op, int arg, int* cnt) +{ + if (cnt) *cnt = 0; + return (0); +} + +int +kvm_nlist(void* kd, void* nl) +{ + return (-1); +} + +void* +kvm_open(const char* execfile, const char* corefile, const char* swapfile, int flags, const char* errstr) +{ + fprintf(stderr, "%s%s/dev/mem: No such file or directory", errstr ? errstr : "", errstr ? ": " : ""); + return (0); +} + +void* +kvm_openfiles(const char* execfile, const char* corefile, const char* swapfile, int flags, char* errout) +{ + if (errout) strcpy(errout, "/dev/mem: No such file or directory"); + return (0); +} + +int +kvm_read(void* kd, unsigned long addr, void* buf, unsigned int nbytes) +{ + return (-1); +} + +int +kvm_uread(void* kd, void* p, unsigned long uva, void* buf, size_t len) +{ + return (0); +} + +int +kvm_write(void* kd, unsigned long addr, const void* buf, unsigned int nbytes) +{ + return (0); +} diff --git a/darwin/libproc.c b/darwin/libproc.c new file mode 100644 index 0000000..ba2305c --- /dev/null +++ b/darwin/libproc.c @@ -0,0 +1,168 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "libproc.h" + +int __proc_info(int callnum, int pid, int flavor, uint64_t arg, void * buffer, int buffersize); + + + +int +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 ((retval = __proc_info(1, type, typeinfo,(uint64_t)0, buffer, buffersize)) == -1) + return(0); + } else { + errno = EINVAL; + retval = 0; + } + return(retval); +} + + +int +proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize) +{ + int retval; + + if ((retval = __proc_info(2, pid, flavor, arg, buffer, buffersize)) == -1) + return(0); + + return(retval); +} + + +int +proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize) +{ + int retval; + + if ((retval = __proc_info(3, pid, flavor, (uint64_t)fd, buffer, buffersize)) == -1) + return(0); + + return (retval); +} + + + +int +proc_name(int pid, void * buffer, uint32_t buffersize) +{ + int retval = 0, len; + struct proc_bsdinfo pbsd; + + + if (buffersize < 2*MAXCOMLEN) { + errno = ENOMEM; + return(0); + } + + retval = proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &pbsd, sizeof(struct proc_bsdinfo)); + if (retval != -1) { + bcopy(&pbsd.pbi_name, buffer, 2* 2*MAXCOMLEN); + len = strlen(&pbsd.pbi_name[0]); + return(len); + } + return(0); +} + +int +proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize) +{ + int retval = 0, len; + struct proc_regionwithpathinfo reginfo; + + if (buffersize < MAXPATHLEN) { + errno = ENOMEM; + return(0); + } + + retval = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, (uint64_t)address, ®info, sizeof(struct proc_regionwithpathinfo)); + if (retval != -1) { + len = strlen(®info.prp_vip.vip_path[0]); + if (len != 0) { + if (len > MAXPATHLEN) + len = MAXPATHLEN; + bcopy(®info.prp_vip.vip_path[0], buffer, len); + return(len); + } + return(0); + } + return(0); + +} + +int +proc_kmsgbuf(void * buffer, uint32_t buffersize) +{ + int retval; + + if ((retval = __proc_info(4, 0, 0, (uint64_t)0, buffer, buffersize)) == -1) + return(0); + return (retval); +} + +int +proc_pidpath(int pid, void * buffer, uint32_t buffersize) +{ + int retval, len; + + if (buffersize < PROC_PIDPATHINFO_SIZE) { + errno = ENOMEM; + return(0); + } + if (buffersize > PROC_PIDPATHINFO_MAXSIZE) { + errno = EOVERFLOW; + return(0); + } + + retval = __proc_info(2, pid, PROC_PIDPATHINFO, (uint64_t)0, buffer, buffersize); + if (retval != -1) { + len = strlen(buffer); + return(len); + } + return (0); +} + + +int proc_libversion(int *major, int * minor) +{ + + if (major != NULL) + *major = 1; + if (minor != NULL) + *minor = 1; + return(0); +} + diff --git a/darwin/libproc.h b/darwin/libproc.h new file mode 100644 index 0000000..adff020 --- /dev/null +++ b/darwin/libproc.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2006, 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@ + */ +#ifndef _LIBPROC_H_ +#define _LIBPROC_H_ + +#include +#include +#include +#include +#include +#include + +#include + +/* + * This header file contains private interfaces to obtain process information. + * These interfaces are subject to change in future releases. + */ + +/*! + @define PROC_LISTPIDSPATH_PATH_IS_VOLUME + @discussion This flag indicates that all processes that hold open + file references on the volume associated with the specified + path should be returned. + */ +#define PROC_LISTPIDSPATH_PATH_IS_VOLUME 1 + + +/*! + @define PROC_LISTPIDSPATH_EXCLUDE_EVTONLY + @discussion This flag indicates that file references that were opened + with the O_EVTONLY flag should be excluded from the matching + criteria. + */ +#define PROC_LISTPIDSPATH_EXCLUDE_EVTONLY 2 + +__BEGIN_DECLS + +int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize); + +/*! + @function proc_listpidspath + @discussion A function which will search through the current + processes looking for open file references which match + a specified path or volume. + @param type types of processes to be searched (see proc_listpids) + @param typeinfo adjunct information for type + @param path file or volume path + @param pathflags flags to control which files should be considered + during the process search. + @param buffer a C array of int-sized values to be filled with + process identifiers that hold an open file reference + matching the specified path or volume. Pass NULL to + obtain the minimum buffer size needed to hold the + currently active processes. + @param buffersize the size (in bytes) of the provided buffer. + @result the number of bytes of data returned in the provided buffer; + -1 if an error was encountered; + */ +int proc_listpidspath(uint32_t type, + uint32_t typeinfo, + const char *path, + uint32_t pathflags, + void *buffer, + int buffersize); + +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); + +__END_DECLS + +#endif /*_LIBPROC_H_ */ diff --git a/darwin/proc_listpidspath.c b/darwin/proc_listpidspath.c new file mode 100644 index 0000000..028a674 --- /dev/null +++ b/darwin/proc_listpidspath.c @@ -0,0 +1,498 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + + +typedef struct { + // process IDs + int *pids; + int pids_count; + size_t pids_size; + + // open file descriptors + struct proc_fdinfo *fds; + int fds_count; + size_t fds_size; + + // file/volume of interest + struct stat match_stat; + + // flags + uint32_t flags; + +} fdOpenInfo, *fdOpenInfoRef; + + +/* + * check_init + */ +static fdOpenInfoRef +check_init(const char *path, uint32_t flags) +{ + fdOpenInfoRef info; + int status; + + info = malloc(sizeof(*info)); + if (!info) + return NULL; + + info->pids = NULL; + info->pids_count = 0; + info->pids_size = 0; + + info->fds = NULL; + info->fds_count = 0; + info->fds_size = 0; + + status = stat(path, &info->match_stat); + if (status == -1) { + goto fail; + } + + info->flags = flags; + + return info; + + fail : + + free(info); + return NULL; +} + + +/* + * check_free + */ +static void +check_free(fdOpenInfoRef info) +{ + if (info->pids != NULL) { + free(info->pids); + } + + if (info->fds != NULL) { + free(info->fds); + } + + free(info); + + return; +} + + +/* + * check_file + * check if a process vnode is of interest + * + * in : vnode stat(2) + * out : -1 if error + * 0 if no match + * 1 if match + */ +static int +check_file(fdOpenInfoRef info, struct vinfo_stat *sb) +{ + if (sb->vst_dev == 0) { + // if no info + return 0; + } + + if (sb->vst_dev != info->match_stat.st_dev) { + // if not the requested filesystem + return 0; + } + + if (!(info->flags & PROC_LISTPIDSPATH_PATH_IS_VOLUME) && + (sb->vst_ino != info->match_stat.st_ino)) { + // if not the requested file + return 0; + } + + return 1; +} + + +/* + * check_process_vnodes + * check [process] current working directory + * check [process] root directory + * + * in : pid + * out : -1 if error + * 0 if no match + * 1 if match + */ +static int +check_process_vnodes(fdOpenInfoRef info, int pid) +{ + int buf_used; + int status; + struct proc_vnodepathinfo vpi; + + buf_used = proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)); + if (buf_used <= 0) { + if (errno == ESRCH) { + // if the process is gone + return 0; + } + return -1; + } else if (buf_used < sizeof(vpi)) { + // if we didn't get enough information + return -1; + } + + // processing current working directory + status = check_file(info, &vpi.pvi_cdir.vip_vi.vi_stat); + if (status != 0) { + // if error or match + return status; + } + + // processing root directory + status = check_file(info, &vpi.pvi_rdir.vip_vi.vi_stat); + if (status != 0) { + // if error or match + return status; + } + + return 0; +} + + +/* + * check_process_text + * check [process] text (memory) + * + * in : pid + * out : -1 if error + * 0 if no match + * 1 if match + */ +static int +check_process_text(fdOpenInfoRef info, int pid) +{ + uint64_t a = 0; + int status; + + while (1) { // for all memory regions + int buf_used; + struct proc_regionwithpathinfo rwpi; + + // processing next address + buf_used = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, a, &rwpi, sizeof(rwpi)); + if (buf_used <= 0) { + if ((errno == ESRCH) || (errno == EINVAL)) { + // if no more text information is available for this process. + break; + } + return -1; + } else if (buf_used < sizeof(rwpi)) { + // if we didn't get enough information + return -1; + } + + //if (rwpi.prp_vip.vip_path[0]) + status = check_file(info, &rwpi.prp_vip.vip_vi.vi_stat); + if (status != 0) { + // if error or match + return status; + } + + a = rwpi.prp_prinfo.pri_address + rwpi.prp_prinfo.pri_size; + } + + return 0; +} + + +/* + * check_process_fds + * check [process] open file descriptors + * + * in : pid + * out : -1 if error + * 0 if no match + * 1 if match + */ +static int +check_process_fds(fdOpenInfoRef info, int pid) +{ + int buf_used; + int i; + int status; + + // get list of open file descriptors + buf_used = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); + if (buf_used <= 0) { + return -1; + } + + while (1) { + if (buf_used > info->fds_size) { + // if we need to allocate [more] space + while (buf_used > info->fds_size) { + info->fds_size += (sizeof(struct proc_fdinfo) * 32); + } + + if (info->fds == NULL) { + info->fds = malloc(info->fds_size); + } else { + info->fds = reallocf(info->fds, info->fds_size); + } + if (info->fds == NULL) { + return -1; + } + } + + buf_used = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info->fds, info->fds_size); + if (buf_used <= 0) { + return -1; + } + + if ((buf_used + sizeof(struct proc_fdinfo)) >= info->fds_size) { + // if not enough room in the buffer for an extra fd + buf_used = info->fds_size; + continue; + } + + info->fds_count = buf_used / sizeof(struct proc_fdinfo); + break; + } + + // iterate through each file descriptor + for (i = 0; i < info->fds_count; i++) { + struct proc_fdinfo *fdp; + + fdp = &info->fds[i]; + switch (fdp->proc_fdtype) { + case PROX_FDTYPE_VNODE : { + int buf_used; + struct vnode_fdinfo vi; + + buf_used = proc_pidfdinfo(pid, fdp->proc_fd, PROC_PIDFDVNODEINFO, &vi, sizeof(vi)); + if (buf_used <= 0) { + if (errno == ENOENT) { + /* + * The file descriptor's vnode may have been revoked. This is a + * bit of a hack, since an ENOENT error might not always mean the + * descriptor's vnode has been revoked. As the libproc API + * matures, this code may need to be revisited. + */ + continue; + } + return -1; + } else if (buf_used < sizeof(vi)) { + // if we didn't get enough information + return -1; + } + + if ((info->flags & PROC_LISTPIDSPATH_EXCLUDE_EVTONLY) && + (vi.pfi.fi_openflags & O_EVTONLY)) { + // if this file should be excluded + continue; + } + + status = check_file(info, &vi.pvi.vi_stat); + if (status != 0) { + // if error or match + return status; + } + break; + } + default : + break; + } + } + + return 0; +} + + +/* + * check_process + * check [process] current working and root directories + * check [process] text (memory) + * check [process] open file descriptors + * + * in : pid + * out : -1 if error + * 0 if no match + * 1 if match + */ +static int +check_process(fdOpenInfoRef info, int pid) +{ + int status; + + // check root and current working directory + status = check_process_vnodes(info, pid); + if (status != 0) { + // if error or match + return status; + } + + // check process text (memory) + status = check_process_text(info, pid); + if (status != 0) { + // if error or match + return status; + } + + // check open file descriptors + status = check_process_fds(info, pid); + if (status != 0) { + // if error or match + return status; + } + + return 0; +} + + +/* + * proc_listpidspath + * + * in : type + * : typeinfo + * : path + * : pathflags + * : buffer + * : buffersize + * out : buffer filled with process IDs that have open file + * references that match the specified path or volume; + * return value is the bytes of the returned buffer + * that contains valid information. + */ +int +proc_listpidspath(uint32_t type, + uint32_t typeinfo, + const char *path, + uint32_t pathflags, + void *buffer, + int buffersize) +{ + int buf_used; + int *buf_next = (int *)buffer; + int i; + fdOpenInfoRef info; + int status = -1; + + if (buffer == NULL) { + // if this is a sizing request + return proc_listpids(type, typeinfo, NULL, 0); + } + + buffersize -= (buffersize % sizeof(int)); // make whole number of ints + if (buffersize < sizeof(int)) { + // if we can't even return a single PID + errno = ENOMEM; + return -1; + } + + // init + info = check_init(path, pathflags); + if (info == NULL) { + return -1; + } + + // get list of processes + buf_used = proc_listpids(type, typeinfo, NULL, 0); + if (buf_used <= 0) { + goto done; + } + + while (1) { + if (buf_used > info->pids_size) { + // if we need to allocate [more] space + while (buf_used > info->pids_size) { + info->pids_size += (sizeof(int) * 32); + } + + if (info->pids == NULL) { + info->pids = malloc(info->pids_size); + } else { + info->pids = reallocf(info->pids, info->pids_size); + } + if (info->pids == NULL) { + goto done; + } + } + + buf_used = proc_listpids(type, typeinfo, info->pids, info->pids_size); + if (buf_used <= 0) { + goto done; + } + + if ((buf_used + sizeof(int)) >= info->pids_size) { + // if not enough room in the buffer for an extra pid + buf_used = info->pids_size; + continue; + } + + info->pids_count = buf_used / sizeof(int); + break; + } + + // iterate through each process + buf_used = 0; + for (i = info->pids_count - 1; i >= 0; i--) { + int pid; + int status; + + pid = info->pids[i]; + if (pid == 0) { + continue; + } + + status = check_process(info, pid); + if (status != 1) { + // if not a match + continue; + } + + *buf_next++ = pid; + buf_used += sizeof(int); + + if (buf_used >= buffersize) { + // if we have filled the buffer + break; + } + } + + status = buf_used; + + done : + + // cleanup + check_free(info); + + return status; +} diff --git a/db/Makefile.inc b/db/Makefile.inc index 39357c7..1be825e 100644 --- a/db/Makefile.inc +++ b/db/Makefile.inc @@ -2,9 +2,11 @@ # $FreeBSD: src/lib/libc/db/Makefile.inc,v 1.4 2002/11/18 09:50:54 ru Exp $ # +.ifnmake autopatch .include "${.CURDIR}/db/btree/Makefile.inc" .include "${.CURDIR}/db/db/Makefile.inc" .include "${.CURDIR}/db/hash/Makefile.inc" .include "${.CURDIR}/db/man/Makefile.inc" .include "${.CURDIR}/db/mpool/Makefile.inc" .include "${.CURDIR}/db/recno/Makefile.inc" +.endif # !autopatch diff --git a/db/btree/Makefile.inc b/db/btree/Makefile.inc index f08b96f..d294367 100644 --- a/db/btree/Makefile.inc +++ b/db/btree/Makefile.inc @@ -10,9 +10,16 @@ FBSDMISRCS= bt_close.c bt_conv.c bt_debug.c bt_delete.c bt_get.c bt_open.c \ .for _src in ${FBSDMISRCS} CFLAGS-${_src:R}-fbsd.${_src:E} += -D__DBINTERFACE_PRIVATE .endfor +.for _src in bt_debug.c bt_open.c bt_overflow.c +CFLAGS-${_src:R}-fbsd.${_src:E} += -UDEBUG +.endfor FBSDHDRS= btree.h .include "Makefile.fbsd_end" # need to rename extern.h to make it unique -${SYMROOT}/bt_extern.h: ${.CURDIR}/db/btree/FreeBSD/extern.h _AUTOPATCHSYM -AUTOPATCHHDRS+= ${SYMROOT}/bt_extern.h +.ifmake autopatch +bt_extern.h: FreeBSD/extern.h _AUTOPATCHCUR +AUTOPATCHHDRS+= bt_extern.h +.endif # autopatch + +INSTBTREEPRIVHDRS_AUTOPATCH+= ${.CURDIR}/db/btree/bt_extern.h ${.CURDIR}/db/btree/btree.h diff --git a/db/btree/bt_close-fbsd.c b/db/btree/bt_close-fbsd.c new file mode 100644 index 0000000..c211d5b --- /dev/null +++ b/db/btree/bt_close-fbsd.c @@ -0,0 +1,186 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include +#include "btree.h" + +static int bt_meta(BTREE *); + +/* + * BT_CLOSE -- Close a btree. + * + * Parameters: + * dbp: pointer to access method + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__bt_close(dbp) + DB *dbp; +{ + BTREE *t; + int fd; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Sync the tree. */ + if (__bt_sync(dbp, 0) == RET_ERROR) + return (RET_ERROR); + + /* Close the memory pool. */ + if (mpool_close(t->bt_mp) == RET_ERROR) + return (RET_ERROR); + + /* Free random memory. */ + if (t->bt_cursor.key.data != NULL) { + free(t->bt_cursor.key.data); + t->bt_cursor.key.size = 0; + t->bt_cursor.key.data = NULL; + } + if (t->bt_rkey.data) { + free(t->bt_rkey.data); + t->bt_rkey.size = 0; + t->bt_rkey.data = NULL; + } + if (t->bt_rdata.data) { + free(t->bt_rdata.data); + t->bt_rdata.size = 0; + t->bt_rdata.data = NULL; + } + + fd = t->bt_fd; + free(t); + free(dbp); + return (_close(fd) ? RET_ERROR : RET_SUCCESS); +} + +/* + * BT_SYNC -- sync the btree to disk. + * + * Parameters: + * dbp: pointer to access method + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +int +__bt_sync(dbp, flags) + const DB *dbp; + u_int flags; +{ + BTREE *t; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Sync doesn't currently take any flags. */ + if (flags != 0) { + errno = EINVAL; + return (RET_ERROR); + } + + if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED)) + return (RET_SUCCESS); + + if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR) + return (RET_ERROR); + + if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS) + F_CLR(t, B_MODIFIED); + + return (status); +} + +/* + * BT_META -- write the tree meta data to disk. + * + * Parameters: + * t: tree + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +static int +bt_meta(t) + BTREE *t; +{ + BTMETA m; + void *p; + + if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL) + return (RET_ERROR); + + /* Fill in metadata. */ + m.magic = BTREEMAGIC; + m.version = BTREEVERSION; + m.psize = t->bt_psize; + m.free = t->bt_free; + m.nrecs = t->bt_nrecs; + m.flags = F_ISSET(t, SAVEMETA); + + memmove(p, &m, sizeof(BTMETA)); + mpool_put(t->bt_mp, p, MPOOL_DIRTY); + return (RET_SUCCESS); +} diff --git a/db/btree/bt_conv-fbsd.c b/db/btree/bt_conv-fbsd.c new file mode 100644 index 0000000..7496a3c --- /dev/null +++ b/db/btree/bt_conv-fbsd.c @@ -0,0 +1,223 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include + +#include +#include "btree.h" + +static void mswap(PAGE *); + +/* + * __BT_BPGIN, __BT_BPGOUT -- + * Convert host-specific number layout to/from the host-independent + * format stored on disk. + * + * Parameters: + * t: tree + * pg: page number + * h: page to convert + */ +void +__bt_pgin(t, pg, pp) + void *t; + pgno_t pg; + void *pp; +{ + PAGE *h; + indx_t i, top; + u_char flags; + char *p; + + if (!F_ISSET(((BTREE *)t), B_NEEDSWAP)) + return; + if (pg == P_META) { + mswap(pp); + return; + } + + h = pp; + M_32_SWAP(h->pgno); + M_32_SWAP(h->prevpg); + M_32_SWAP(h->nextpg); + M_32_SWAP(h->flags); + M_16_SWAP(h->lower); + M_16_SWAP(h->upper); + + top = NEXTINDEX(h); + if ((h->flags & P_TYPE) == P_BINTERNAL) + for (i = 0; i < top; i++) { + M_16_SWAP(h->linp[i]); + p = (char *)GETBINTERNAL(h, i); + P_32_SWAP(p); + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(pgno_t); + if (*(u_char *)p & P_BIGKEY) { + p += sizeof(u_char); + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + } + else if ((h->flags & P_TYPE) == P_BLEAF) + for (i = 0; i < top; i++) { + M_16_SWAP(h->linp[i]); + p = (char *)GETBLEAF(h, i); + P_32_SWAP(p); + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(u_int32_t); + flags = *(u_char *)p; + if (flags & (P_BIGKEY | P_BIGDATA)) { + p += sizeof(u_char); + if (flags & P_BIGKEY) { + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + if (flags & P_BIGDATA) { + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + } + } +} + +void +__bt_pgout(t, pg, pp) + void *t; + pgno_t pg; + void *pp; +{ + PAGE *h; + indx_t i, top; + u_char flags; + char *p; + + if (!F_ISSET(((BTREE *)t), B_NEEDSWAP)) + return; + if (pg == P_META) { + mswap(pp); + return; + } + + h = pp; + top = NEXTINDEX(h); + if ((h->flags & P_TYPE) == P_BINTERNAL) + for (i = 0; i < top; i++) { + p = (char *)GETBINTERNAL(h, i); + P_32_SWAP(p); + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(pgno_t); + if (*(u_char *)p & P_BIGKEY) { + p += sizeof(u_char); + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + M_16_SWAP(h->linp[i]); + } + else if ((h->flags & P_TYPE) == P_BLEAF) + for (i = 0; i < top; i++) { + p = (char *)GETBLEAF(h, i); + P_32_SWAP(p); + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(u_int32_t); + flags = *(u_char *)p; + if (flags & (P_BIGKEY | P_BIGDATA)) { + p += sizeof(u_char); + if (flags & P_BIGKEY) { + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + if (flags & P_BIGDATA) { + p += sizeof(u_int32_t); + P_32_SWAP(p); + p += sizeof(pgno_t); + P_32_SWAP(p); + } + } + M_16_SWAP(h->linp[i]); + } + + M_32_SWAP(h->pgno); + M_32_SWAP(h->prevpg); + M_32_SWAP(h->nextpg); + M_32_SWAP(h->flags); + M_16_SWAP(h->lower); + M_16_SWAP(h->upper); +} + +/* + * MSWAP -- Actually swap the bytes on the meta page. + * + * Parameters: + * p: page to convert + */ +static void +mswap(pg) + PAGE *pg; +{ + char *p; + + p = (char *)pg; + P_32_SWAP(p); /* magic */ + p += sizeof(u_int32_t); + P_32_SWAP(p); /* version */ + p += sizeof(u_int32_t); + P_32_SWAP(p); /* psize */ + p += sizeof(u_int32_t); + P_32_SWAP(p); /* free */ + p += sizeof(u_int32_t); + P_32_SWAP(p); /* nrecs */ + p += sizeof(u_int32_t); + P_32_SWAP(p); /* flags */ + p += sizeof(u_int32_t); +} diff --git a/db/btree/bt_debug-fbsd.c b/db/btree/bt_debug-fbsd.c new file mode 100644 index 0000000..bd95774 --- /dev/null +++ b/db/btree/bt_debug-fbsd.c @@ -0,0 +1,332 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include +#include +#include + +#include +#include "btree.h" + +#ifdef DEBUG +/* + * BT_DUMP -- Dump the tree + * + * Parameters: + * dbp: pointer to the DB + */ +void +__bt_dump(dbp) + DB *dbp; +{ + BTREE *t; + PAGE *h; + pgno_t i; + char *sep; + + t = dbp->internal; + (void)fprintf(stderr, "%s: pgsz %d", + F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize); + if (F_ISSET(t, R_RECNO)) + (void)fprintf(stderr, " keys %u", t->bt_nrecs); +#undef X +#define X(flag, name) \ + if (F_ISSET(t, flag)) { \ + (void)fprintf(stderr, "%s%s", sep, name); \ + sep = ", "; \ + } + if (t->flags != 0) { + sep = " flags ("; + X(R_FIXLEN, "FIXLEN"); + X(B_INMEM, "INMEM"); + X(B_NODUPS, "NODUPS"); + X(B_RDONLY, "RDONLY"); + X(R_RECNO, "RECNO"); + X(B_METADIRTY,"METADIRTY"); + (void)fprintf(stderr, ")\n"); + } +#undef X + + for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) { + __bt_dpage(h); + (void)mpool_put(t->bt_mp, h, 0); + } +} + +/* + * BT_DMPAGE -- Dump the meta page + * + * Parameters: + * h: pointer to the PAGE + */ +void +__bt_dmpage(h) + PAGE *h; +{ + BTMETA *m; + char *sep; + + m = (BTMETA *)h; + (void)fprintf(stderr, "magic %x\n", m->magic); + (void)fprintf(stderr, "version %u\n", m->version); + (void)fprintf(stderr, "psize %u\n", m->psize); + (void)fprintf(stderr, "free %u\n", m->free); + (void)fprintf(stderr, "nrecs %u\n", m->nrecs); + (void)fprintf(stderr, "flags %u", m->flags); +#undef X +#define X(flag, name) \ + if (m->flags & flag) { \ + (void)fprintf(stderr, "%s%s", sep, name); \ + sep = ", "; \ + } + if (m->flags) { + sep = " ("; + X(B_NODUPS, "NODUPS"); + X(R_RECNO, "RECNO"); + (void)fprintf(stderr, ")"); + } +} + +/* + * BT_DNPAGE -- Dump the page + * + * Parameters: + * n: page number to dump. + */ +void +__bt_dnpage(dbp, pgno) + DB *dbp; + pgno_t pgno; +{ + BTREE *t; + PAGE *h; + + t = dbp->internal; + if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) { + __bt_dpage(h); + (void)mpool_put(t->bt_mp, h, 0); + } +} + +/* + * BT_DPAGE -- Dump the page + * + * Parameters: + * h: pointer to the PAGE + */ +void +__bt_dpage(h) + PAGE *h; +{ + BINTERNAL *bi; + BLEAF *bl; + RINTERNAL *ri; + RLEAF *rl; + indx_t cur, top; + char *sep; + + (void)fprintf(stderr, " page %d: (", h->pgno); +#undef X +#define X(flag, name) \ + if (h->flags & flag) { \ + (void)fprintf(stderr, "%s%s", sep, name); \ + sep = ", "; \ + } + sep = ""; + X(P_BINTERNAL, "BINTERNAL") /* types */ + X(P_BLEAF, "BLEAF") + X(P_RINTERNAL, "RINTERNAL") /* types */ + X(P_RLEAF, "RLEAF") + X(P_OVERFLOW, "OVERFLOW") + X(P_PRESERVE, "PRESERVE"); + (void)fprintf(stderr, ")\n"); +#undef X + + (void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg); + if (h->flags & P_OVERFLOW) + return; + + top = NEXTINDEX(h); + (void)fprintf(stderr, " lower %3d upper %3d nextind %d\n", + h->lower, h->upper, top); + for (cur = 0; cur < top; cur++) { + (void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]); + switch (h->flags & P_TYPE) { + case P_BINTERNAL: + bi = GETBINTERNAL(h, cur); + (void)fprintf(stderr, + "size %03d pgno %03d", bi->ksize, bi->pgno); + if (bi->flags & P_BIGKEY) + (void)fprintf(stderr, " (indirect)"); + else if (bi->ksize) + (void)fprintf(stderr, + " {%.*s}", (int)bi->ksize, bi->bytes); + break; + case P_RINTERNAL: + ri = GETRINTERNAL(h, cur); + (void)fprintf(stderr, "entries %03d pgno %03d", + ri->nrecs, ri->pgno); + break; + case P_BLEAF: + bl = GETBLEAF(h, cur); + if (bl->flags & P_BIGKEY) + (void)fprintf(stderr, + "big key page %u size %u/", + *(pgno_t *)bl->bytes, + *(u_int32_t *)(bl->bytes + sizeof(pgno_t))); + else if (bl->ksize) + (void)fprintf(stderr, "%.*s/", + bl->ksize, bl->bytes); + if (bl->flags & P_BIGDATA) + (void)fprintf(stderr, + "big data page %u size %u", + *(pgno_t *)(bl->bytes + bl->ksize), + *(u_int32_t *)(bl->bytes + bl->ksize + + sizeof(pgno_t))); + else if (bl->dsize) + (void)fprintf(stderr, "%.*s", + (int)bl->dsize, bl->bytes + bl->ksize); + break; + case P_RLEAF: + rl = GETRLEAF(h, cur); + if (rl->flags & P_BIGDATA) + (void)fprintf(stderr, + "big data page %u size %u", + *(pgno_t *)rl->bytes, + *(u_int32_t *)(rl->bytes + sizeof(pgno_t))); + else if (rl->dsize) + (void)fprintf(stderr, + "%.*s", (int)rl->dsize, rl->bytes); + break; + } + (void)fprintf(stderr, "\n"); + } +} +#endif + +#ifdef STATISTICS +/* + * BT_STAT -- Gather/print the tree statistics + * + * Parameters: + * dbp: pointer to the DB + */ +void +__bt_stat(dbp) + DB *dbp; +{ + extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit; + extern u_long bt_sortsplit, bt_split; + BTREE *t; + PAGE *h; + pgno_t i, pcont, pinternal, pleaf; + u_long ifree, lfree, nkeys; + int levels; + + t = dbp->internal; + pcont = pinternal = pleaf = 0; + nkeys = ifree = lfree = 0; + for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) { + switch (h->flags & P_TYPE) { + case P_BINTERNAL: + case P_RINTERNAL: + ++pinternal; + ifree += h->upper - h->lower; + break; + case P_BLEAF: + case P_RLEAF: + ++pleaf; + lfree += h->upper - h->lower; + nkeys += NEXTINDEX(h); + break; + case P_OVERFLOW: + ++pcont; + break; + } + (void)mpool_put(t->bt_mp, h, 0); + } + + /* Count the levels of the tree. */ + for (i = P_ROOT, levels = 0 ;; ++levels) { + h = mpool_get(t->bt_mp, i, 0); + if (h->flags & (P_BLEAF|P_RLEAF)) { + if (levels == 0) + levels = 1; + (void)mpool_put(t->bt_mp, h, 0); + break; + } + i = F_ISSET(t, R_RECNO) ? + GETRINTERNAL(h, 0)->pgno : + GETBINTERNAL(h, 0)->pgno; + (void)mpool_put(t->bt_mp, h, 0); + } + + (void)fprintf(stderr, "%d level%s with %ld keys", + levels, levels == 1 ? "" : "s", nkeys); + if (F_ISSET(t, R_RECNO)) + (void)fprintf(stderr, " (%d header count)", t->bt_nrecs); + (void)fprintf(stderr, + "\n%u pages (leaf %d, internal %d, overflow %d)\n", + pinternal + pleaf + pcont, pleaf, pinternal, pcont); + (void)fprintf(stderr, "%ld cache hits, %ld 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", + ((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", + ((double)(pinternal - ifree) / pinternal) * 100, + pinternal - ifree, ifree); + if (bt_pfxsaved) + (void)fprintf(stderr, "prefix checking removed %lu bytes.\n", + bt_pfxsaved); +} +#endif diff --git a/db/btree/bt_delete-fbsd.c b/db/btree/bt_delete-fbsd.c new file mode 100644 index 0000000..6204464 --- /dev/null +++ b/db/btree/bt_delete-fbsd.c @@ -0,0 +1,659 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include +#include +#include + +#include +#include "btree.h" + +static int __bt_bdelete(BTREE *, const DBT *); +static int __bt_curdel(BTREE *, const DBT *, PAGE *, u_int); +static int __bt_pdelete(BTREE *, PAGE *); +static int __bt_relink(BTREE *, PAGE *); +static int __bt_stkacq(BTREE *, PAGE **, CURSOR *); + +/* + * __bt_delete + * Delete the item(s) referenced by a key. + * + * Return RET_SPECIAL if the key is not found. + */ +int +__bt_delete(dbp, key, flags) + const DB *dbp; + const DBT *key; + u_int flags; +{ + BTREE *t; + CURSOR *c; + PAGE *h; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Check for change to a read-only tree. */ + if (F_ISSET(t, B_RDONLY)) { + errno = EPERM; + return (RET_ERROR); + } + + switch (flags) { + case 0: + status = __bt_bdelete(t, key); + break; + case R_CURSOR: + /* + * If flags is R_CURSOR, delete the cursor. Must already + * have started a scan and not have already deleted it. + */ + c = &t->bt_cursor; + if (F_ISSET(c, CURS_INIT)) { + if (F_ISSET(c, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE)) + return (RET_SPECIAL); + if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL) + return (RET_ERROR); + + /* + * If the page is about to be emptied, we'll need to + * delete it, which means we have to acquire a stack. + */ + if (NEXTINDEX(h) == 1) + if (__bt_stkacq(t, &h, &t->bt_cursor)) + return (RET_ERROR); + + status = __bt_dleaf(t, NULL, h, c->pg.index); + + if (NEXTINDEX(h) == 0 && status == RET_SUCCESS) { + if (__bt_pdelete(t, h)) + return (RET_ERROR); + } else + mpool_put(t->bt_mp, + h, status == RET_SUCCESS ? MPOOL_DIRTY : 0); + break; + } + /* FALLTHROUGH */ + default: + errno = EINVAL; + return (RET_ERROR); + } + if (status == RET_SUCCESS) + F_SET(t, B_MODIFIED); + return (status); +} + +/* + * __bt_stkacq -- + * Acquire a stack so we can delete a cursor entry. + * + * Parameters: + * t: tree + * hp: pointer to current, pinned PAGE pointer + * c: pointer to the cursor + * + * Returns: + * 0 on success, 1 on failure + */ +static int +__bt_stkacq(t, hp, c) + BTREE *t; + PAGE **hp; + CURSOR *c; +{ + BINTERNAL *bi; + EPG *e; + EPGNO *parent; + PAGE *h; + indx_t index; + 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. + */ + h = *hp; + mpool_put(t->bt_mp, h, 0); + if ((e = __bt_search(t, &c->key, &exact)) == NULL) + return (1); + h = e->page; + + /* See if we got it in one shot. */ + if (h->pgno == c->pg.pgno) + goto ret; + + /* + * Move right, looking for the page. At each move we have to move + * up the stack until we don't have to move to the next page. If + * we have to change pages at an internal level, we have to fix the + * stack back up. + */ + while (h->pgno != c->pg.pgno) { + if ((nextpg = h->nextpg) == P_INVALID) + break; + mpool_put(t->bt_mp, h, 0); + + /* Move up the stack. */ + for (level = 0; (parent = BT_POP(t)) != NULL; ++level) { + /* Get the parent page. */ + if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) + return (1); + + /* Move to the next index. */ + if (parent->index != NEXTINDEX(h) - 1) { + index = parent->index + 1; + BT_PUSH(t, h->pgno, index); + break; + } + mpool_put(t->bt_mp, h, 0); + } + + /* Restore the stack. */ + while (level--) { + /* Push the next level down onto the stack. */ + bi = GETBINTERNAL(h, index); + pgno = bi->pgno; + BT_PUSH(t, pgno, 0); + + /* Lose the currently pinned page. */ + mpool_put(t->bt_mp, h, 0); + + /* Get the next level down. */ + if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL) + return (1); + index = 0; + } + mpool_put(t->bt_mp, h, 0); + if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL) + return (1); + } + + if (h->pgno == c->pg.pgno) + goto ret; + + /* Reacquire the original stack. */ + mpool_put(t->bt_mp, h, 0); + if ((e = __bt_search(t, &c->key, &exact)) == NULL) + return (1); + h = e->page; + + /* + * Move left, looking for the page. At each move we have to move + * up the stack until we don't have to change pages to move to the + * next page. If we have to change pages at an internal level, we + * have to fix the stack back up. + */ + while (h->pgno != c->pg.pgno) { + if ((prevpg = h->prevpg) == P_INVALID) + break; + mpool_put(t->bt_mp, h, 0); + + /* Move up the stack. */ + for (level = 0; (parent = BT_POP(t)) != NULL; ++level) { + /* Get the parent page. */ + if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) + return (1); + + /* Move to the next index. */ + if (parent->index != 0) { + index = parent->index - 1; + BT_PUSH(t, h->pgno, index); + break; + } + mpool_put(t->bt_mp, h, 0); + } + + /* Restore the stack. */ + while (level--) { + /* Push the next level down onto the stack. */ + bi = GETBINTERNAL(h, index); + pgno = bi->pgno; + + /* Lose the currently pinned page. */ + mpool_put(t->bt_mp, h, 0); + + /* Get the next level down. */ + if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL) + return (1); + + index = NEXTINDEX(h) - 1; + BT_PUSH(t, pgno, index); + } + 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); +} + +/* + * __bt_bdelete -- + * Delete all key/data pairs matching the specified key. + * + * Parameters: + * t: tree + * key: key to delete + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. + */ +static int +__bt_bdelete(t, key) + BTREE *t; + const DBT *key; +{ + EPG *e; + PAGE *h; + int deleted, exact, redo; + + deleted = 0; + + /* Find any matching record; __bt_search pins the page. */ +loop: if ((e = __bt_search(t, key, &exact)) == NULL) + return (deleted ? RET_SUCCESS : RET_ERROR); + if (!exact) { + mpool_put(t->bt_mp, e->page, 0); + return (deleted ? RET_SUCCESS : RET_SPECIAL); + } + + /* + * Delete forward, then delete backward, from the found key. If + * there are duplicates and we reach either side of the page, do + * the key search again, so that we get them all. + */ + redo = 0; + h = e->page; + do { + if (__bt_dleaf(t, key, h, e->index)) { + mpool_put(t->bt_mp, h, 0); + return (RET_ERROR); + } + if (F_ISSET(t, B_NODUPS)) { + if (NEXTINDEX(h) == 0) { + if (__bt_pdelete(t, h)) + return (RET_ERROR); + } else + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + return (RET_SUCCESS); + } + deleted = 1; + } while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0); + + /* Check for right-hand edge of the page. */ + if (e->index == NEXTINDEX(h)) + redo = 1; + + /* Delete from the key to the beginning of the page. */ + while (e->index-- > 0) { + if (__bt_cmp(t, key, e) != 0) + break; + if (__bt_dleaf(t, key, h, e->index) == RET_ERROR) { + mpool_put(t->bt_mp, h, 0); + return (RET_ERROR); + } + if (e->index == 0) + redo = 1; + } + + /* Check for an empty page. */ + if (NEXTINDEX(h) == 0) { + if (__bt_pdelete(t, h)) + return (RET_ERROR); + goto loop; + } + + /* Put the page. */ + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + + if (redo) + goto loop; + return (RET_SUCCESS); +} + +/* + * __bt_pdelete -- + * Delete a single page from the tree. + * + * Parameters: + * t: tree + * h: leaf page + * + * Returns: + * RET_SUCCESS, RET_ERROR. + * + * Side-effects: + * mpool_put's the page + */ +static int +__bt_pdelete(t, h) + BTREE *t; + PAGE *h; +{ + BINTERNAL *bi; + PAGE *pg; + EPGNO *parent; + indx_t cnt, index, *ip, offset; + u_int32_t nksize; + char *from; + + /* + * Walk the parent page stack -- a LIFO stack of the pages that were + * traversed when we searched for the page where the delete occurred. + * Each stack entry is a page number and a page index offset. The + * offset is for the page traversed on the search. We've just deleted + * a page, so we have to delete the key from the parent page. + * + * If the delete from the parent page makes it empty, this process may + * continue all the way up the tree. We stop if we reach the root page + * (which is never deleted, it's just not worth the effort) or if the + * delete does not empty the page. + */ + while ((parent = BT_POP(t)) != NULL) { + /* 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); + + /* Free any overflow pages. */ + if (bi->flags & P_BIGKEY && + __ovfl_delete(t, bi->bytes) == RET_ERROR) { + mpool_put(t->bt_mp, pg, 0); + return (RET_ERROR); + } + + /* + * Free the parent if it has only the one key and it's not the + * root page. If it's the rootpage, turn it back into an empty + * leaf page. + */ + if (NEXTINDEX(pg) == 1) + if (pg->pgno == P_ROOT) { + pg->lower = BTDATAOFF; + pg->upper = t->bt_psize; + pg->flags = P_BLEAF; + } else { + if (__bt_relink(t, pg) || __bt_free(t, pg)) + return (RET_ERROR); + continue; + } + else { + /* Pack remaining key items at the end of the page. */ + nksize = NBINTERNAL(bi->ksize); + from = (char *)pg + pg->upper; + memmove(from + nksize, from, (char *)bi - from); + pg->upper += nksize; + + /* Adjust indices' offsets, shift the indices down. */ + offset = pg->linp[index]; + for (cnt = index, ip = &pg->linp[0]; cnt--; ++ip) + if (ip[0] < offset) + ip[0] += nksize; + for (cnt = NEXTINDEX(pg) - index; --cnt; ++ip) + ip[0] = ip[1] < offset ? ip[1] + nksize : ip[1]; + pg->lower -= sizeof(indx_t); + } + + mpool_put(t->bt_mp, pg, MPOOL_DIRTY); + break; + } + + /* Free the leaf page, as long as it wasn't the root. */ + if (h->pgno == P_ROOT) { + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + return (RET_SUCCESS); + } + return (__bt_relink(t, h) || __bt_free(t, h)); +} + +/* + * __bt_dleaf -- + * Delete a single record from a leaf page. + * + * Parameters: + * t: tree + * key: referenced key + * h: page + * index: 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; +{ + BLEAF *bl; + indx_t cnt, *ip, offset; + u_int32_t nbytes; + void *to; + char *from; + + /* 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)) + return (RET_ERROR); + + /* If the entry uses overflow pages, make them available for reuse. */ + to = bl = GETBLEAF(h, index); + if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR) + return (RET_ERROR); + if (bl->flags & P_BIGDATA && + __ovfl_delete(t, bl->bytes + bl->ksize) == RET_ERROR) + return (RET_ERROR); + + /* Pack the remaining key/data items at the end of the page. */ + nbytes = NBLEAF(bl); + from = (char *)h + h->upper; + memmove(from + nbytes, from, (char *)to - from); + h->upper += nbytes; + + /* Adjust the indices' offsets, shift the indices down. */ + offset = h->linp[index]; + for (cnt = index, ip = &h->linp[0]; cnt--; ++ip) + if (ip[0] < offset) + ip[0] += nbytes; + for (cnt = NEXTINDEX(h) - index; --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.index; + + return (RET_SUCCESS); +} + +/* + * __bt_curdel -- + * Delete the cursor. + * + * Parameters: + * t: tree + * key: referenced key (or NULL) + * h: page + * index: 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; +{ + CURSOR *c; + EPG e; + PAGE *pg; + int curcopy, status; + + /* + * If there are duplicates, move forward or backward to one. + * Otherwise, copy the key into the cursor area. + */ + c = &t->bt_cursor; + F_CLR(c, CURS_AFTER | CURS_BEFORE | CURS_ACQUIRE); + + curcopy = 0; + if (!F_ISSET(t, B_NODUPS)) { + /* + * We're going to have to do comparisons. If we weren't + * provided a copy of the key, i.e. the user is deleting + * the current cursor position, get one. + */ + if (key == NULL) { + e.page = h; + e.index = index; + if ((status = __bt_ret(t, &e, + &c->key, &c->key, NULL, NULL, 1)) != RET_SUCCESS) + return (status); + curcopy = 1; + key = &c->key; + } + /* Check previous key, if not at the beginning of the page. */ + if (index > 0) { + e.page = h; + e.index = index - 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) { + e.page = h; + e.index = index + 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 ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL) + return (RET_ERROR); + e.page = pg; + e.index = NEXTINDEX(pg) - 1; + if (__bt_cmp(t, key, &e) == 0) { + F_SET(c, CURS_BEFORE); + goto dup1; + } + 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 ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) + return (RET_ERROR); + e.page = pg; + e.index = 0; + if (__bt_cmp(t, key, &e) == 0) { + F_SET(c, CURS_AFTER); +dup1: mpool_put(t->bt_mp, pg, 0); +dup2: c->pg.pgno = e.page->pgno; + c->pg.index = e.index; + return (RET_SUCCESS); + } + mpool_put(t->bt_mp, pg, 0); + } + } + e.page = h; + e.index = index; + if (curcopy || (status = + __bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) == RET_SUCCESS) { + F_SET(c, CURS_ACQUIRE); + return (RET_SUCCESS); + } + return (status); +} + +/* + * __bt_relink -- + * Link around a deleted page. + * + * Parameters: + * t: tree + * h: page to be deleted + */ +static int +__bt_relink(t, h) + BTREE *t; + PAGE *h; +{ + PAGE *pg; + + if (h->nextpg != P_INVALID) { + if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) + return (RET_ERROR); + pg->prevpg = h->prevpg; + mpool_put(t->bt_mp, pg, MPOOL_DIRTY); + } + if (h->prevpg != P_INVALID) { + if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL) + return (RET_ERROR); + pg->nextpg = h->nextpg; + mpool_put(t->bt_mp, pg, MPOOL_DIRTY); + } + return (0); +} diff --git a/db/btree/bt_extern.h b/db/btree/bt_extern.h new file mode 100644 index 0000000..478f6af --- /dev/null +++ b/db/btree/bt_extern.h @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 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. + * + * @(#)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 $ + */ + +int __bt_close(DB *); +int __bt_cmp(BTREE *, const DBT *, EPG *); +int __bt_crsrdel(BTREE *, EPGNO *); +int __bt_defcmp(const DBT *, const DBT *); +size_t __bt_defpfx(const DBT *, const DBT *); +int __bt_delete(const DB *, const DBT *, u_int); +int __bt_dleaf(BTREE *, const DBT *, PAGE *, u_int); +int __bt_fd(const DB *); +int __bt_free(BTREE *, PAGE *); +int __bt_get(const DB *, const DBT *, DBT *, u_int); +PAGE *__bt_new(BTREE *, pgno_t *); +void __bt_pgin(void *, pgno_t, void *); +void __bt_pgout(void *, pgno_t, void *); +int __bt_push(BTREE *, pgno_t, int); +int __bt_put(const DB *dbp, DBT *, const DBT *, u_int); +int __bt_ret(BTREE *, EPG *, DBT *, DBT *, DBT *, DBT *, int); +EPG *__bt_search(BTREE *, const DBT *, int *); +int __bt_seq(const DB *, DBT *, DBT *, u_int); +void __bt_setcur(BTREE *, pgno_t, u_int); +int __bt_split(BTREE *, PAGE *, + const DBT *, const DBT *, int, size_t, u_int32_t); +int __bt_sync(const DB *, u_int); + +int __ovfl_delete(BTREE *, void *); +int __ovfl_get(BTREE *, void *, size_t *, void **, size_t *); +int __ovfl_put(BTREE *, const DBT *, pgno_t *); + +#ifdef DEBUG +void __bt_dnpage(DB *, pgno_t); +void __bt_dpage(PAGE *); +void __bt_dump(DB *); +#endif +#ifdef STATISTICS +void __bt_stat(DB *); +#endif diff --git a/db/btree/bt_get-fbsd.c b/db/btree/bt_get-fbsd.c new file mode 100644 index 0000000..0d91ae4 --- /dev/null +++ b/db/btree/bt_get-fbsd.c @@ -0,0 +1,107 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include +#include +#include + +#include +#include "btree.h" + +/* + * __BT_GET -- Get a record from the btree. + * + * Parameters: + * dbp: pointer to access method + * key: key to find + * data: data to return + * flag: currently unused + * + * Returns: + * 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; +{ + BTREE *t; + EPG *e; + int exact, status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Get currently doesn't take any flags. */ + if (flags) { + errno = EINVAL; + return (RET_ERROR); + } + + if ((e = __bt_search(t, key, &exact)) == NULL) + return (RET_ERROR); + if (!exact) { + mpool_put(t->bt_mp, e->page, 0); + return (RET_SPECIAL); + } + + status = __bt_ret(t, e, NULL, NULL, data, &t->bt_rdata, 0); + + /* + * If the user is doing concurrent access, we copied the + * key/data, toss the page. + */ + if (F_ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e->page, 0); + else + t->bt_pinned = e->page; + return (status); +} diff --git a/db/btree/bt_open-fbsd.c b/db/btree/bt_open-fbsd.c new file mode 100644 index 0000000..c8a103a --- /dev/null +++ b/db/btree/bt_open-fbsd.c @@ -0,0 +1,449 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +/* + * Implementation of btree access method for 4.4BSD. + * + * The design here was originally based on that of the btree access method + * used in the Postgres database system at UC Berkeley. This implementation + * is wholly independent of the Postgres code. + */ + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include +#include "btree.h" + +#ifdef DEBUG +#undef MINPSIZE +#define MINPSIZE 128 +#endif + +static int byteorder(void); +static int nroot(BTREE *); +static int tmp(void); + +/* + * __BT_OPEN -- Open a btree. + * + * Creates and fills a DB struct, and calls the routine that actually + * opens the btree. + * + * Parameters: + * fname: filename (NULL for in-memory trees) + * flags: open flag bits + * mode: open permission bits + * b: BTREEINFO pointer + * + * Returns: + * NULL on failure, pointer to DB on success. + * + */ +DB * +__bt_open(fname, flags, mode, openinfo, dflags) + const char *fname; + int flags, mode, dflags; + const BTREEINFO *openinfo; +{ + struct stat sb; + BTMETA m; + BTREE *t; + BTREEINFO b; + DB *dbp; + pgno_t ncache; + ssize_t nr; + int machine_lorder; + + t = NULL; + + /* + * Intention is to make sure all of the user's selections are okay + * here and then use them without checking. Can't be complete, since + * we don't know the right page size, lorder or flags until the backing + * file is opened. Also, the file's page size can cause the cachesize + * to change. + */ + machine_lorder = byteorder(); + if (openinfo) { + b = *openinfo; + + /* Flags: R_DUP. */ + if (b.flags & ~(R_DUP)) + goto einval; + + /* + * Page size must be indx_t aligned and >= MINPSIZE. Default + * page size is set farther on, based on the underlying file + * transfer size. + */ + if (b.psize && + (b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 || + b.psize & (sizeof(indx_t) - 1) )) + goto einval; + + /* Minimum number of keys per page; absolute minimum is 2. */ + if (b.minkeypage) { + if (b.minkeypage < 2) + goto einval; + } else + b.minkeypage = DEFMINKEYPAGE; + + /* If no comparison, use default comparison and prefix. */ + if (b.compare == NULL) { + b.compare = __bt_defcmp; + if (b.prefix == NULL) + b.prefix = __bt_defpfx; + } + + if (b.lorder == 0) + b.lorder = machine_lorder; + } else { + b.compare = __bt_defcmp; + b.cachesize = 0; + b.flags = 0; + b.lorder = machine_lorder; + b.minkeypage = DEFMINKEYPAGE; + b.prefix = __bt_defpfx; + b.psize = 0; + } + + /* Check for the ubiquitous PDP-11. */ + if (b.lorder != BIG_ENDIAN && b.lorder != LITTLE_ENDIAN) + goto einval; + + /* Allocate and initialize DB and BTREE structures. */ + if ((t = (BTREE *)malloc(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; + t->bt_cmp = b.compare; + t->bt_pfx = b.prefix; + t->bt_rfd = -1; + + if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL) + goto err; + memset(t->bt_dbp, 0, sizeof(DB)); + if (t->bt_lorder != machine_lorder) + F_SET(t, B_NEEDSWAP); + + dbp->type = DB_BTREE; + dbp->internal = t; + dbp->close = __bt_close; + dbp->del = __bt_delete; + dbp->fd = __bt_fd; + dbp->get = __bt_get; + dbp->put = __bt_put; + dbp->seq = __bt_seq; + dbp->sync = __bt_sync; + + /* + * If no file name was supplied, this is an in-memory btree and we + * open a backing temporary file. Otherwise, it's a disk-based tree. + */ + if (fname) { + switch (flags & O_ACCMODE) { + case O_RDONLY: + F_SET(t, B_RDONLY); + break; + case O_RDWR: + break; + case O_WRONLY: + default: + goto einval; + } + + if ((t->bt_fd = _open(fname, flags, mode)) < 0) + goto err; + + } else { + if ((flags & O_ACCMODE) != O_RDWR) + goto einval; + if ((t->bt_fd = tmp()) == -1) + goto err; + F_SET(t, B_INMEM); + } + + if (_fcntl(t->bt_fd, F_SETFD, 1) == -1) + goto err; + + if (_fstat(t->bt_fd, &sb)) + goto err; + if (sb.st_size) { + if ((nr = _read(t->bt_fd, &m, sizeof(BTMETA))) < 0) + goto err; + if (nr != sizeof(BTMETA)) + goto eftype; + + /* + * Read in the meta-data. This can change the notion of what + * the lorder, page size and flags are, and, when the page size + * changes, the cachesize value can change too. If the user + * specified the wrong byte order for an existing database, we + * don't bother to return an error, we just clear the NEEDSWAP + * bit. + */ + if (m.magic == BTREEMAGIC) + F_CLR(t, B_NEEDSWAP); + else { + F_SET(t, B_NEEDSWAP); + M_32_SWAP(m.magic); + M_32_SWAP(m.version); + M_32_SWAP(m.psize); + M_32_SWAP(m.free); + M_32_SWAP(m.nrecs); + M_32_SWAP(m.flags); + } + if (m.magic != BTREEMAGIC || m.version != BTREEVERSION) + goto eftype; + if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 || + m.psize & (sizeof(indx_t) - 1) ) + goto eftype; + if (m.flags & ~SAVEMETA) + goto eftype; + b.psize = m.psize; + F_SET(t, m.flags); + t->bt_free = m.free; + t->bt_nrecs = m.nrecs; + } else { + /* + * Set the page size to the best value for I/O to this file. + * Don't overflow the page offset type. + */ + if (b.psize == 0) { + b.psize = sb.st_blksize; + if (b.psize < MINPSIZE) + b.psize = MINPSIZE; + if (b.psize > MAX_PAGE_OFFSET + 1) + b.psize = MAX_PAGE_OFFSET + 1; + } + + /* Set flag if duplicates permitted. */ + if (!(b.flags & R_DUP)) + F_SET(t, B_NODUPS); + + t->bt_free = P_INVALID; + t->bt_nrecs = 0; + F_SET(t, B_METADIRTY); + } + + t->bt_psize = b.psize; + + /* Set the cache size; must be a multiple of the page size. */ + if (b.cachesize && b.cachesize & (b.psize - 1) ) + b.cachesize += (~b.cachesize & (b.psize - 1) ) + 1; + if (b.cachesize < b.psize * MINCACHE) + b.cachesize = b.psize * MINCACHE; + + /* Calculate number of pages to cache. */ + ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize; + + /* + * The btree data structure requires that at least two keys can fit on + * a page, but other than that there's no fixed requirement. The user + * specified a minimum number per page, and we translated that into the + * number of bytes a key/data pair can use before being placed on an + * overflow page. This calculation includes the page header, the size + * of the index referencing the leaf item and the size of the leaf item + * structure. Also, don't let the user specify a minkeypage such that + * a key/data pair won't fit even if both key and data are on overflow + * pages. + */ + t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage - + (sizeof(indx_t) + NBLEAFDBT(0, 0)); + if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t)) + t->bt_ovflsize = + NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t); + + /* Initialize the buffer pool. */ + if ((t->bt_mp = + mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL) + goto err; + if (!F_ISSET(t, B_INMEM)) + mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t); + + /* Create a root page if new tree. */ + if (nroot(t) == RET_ERROR) + goto err; + + /* Global flags. */ + if (dflags & DB_LOCK) + F_SET(t, B_DB_LOCK); + if (dflags & DB_SHMEM) + F_SET(t, B_DB_SHMEM); + if (dflags & DB_TXN) + F_SET(t, B_DB_TXN); + + return (dbp); + +einval: errno = EINVAL; + goto err; + +eftype: errno = EFTYPE; + goto err; + +err: if (t) { + if (t->bt_dbp) + free(t->bt_dbp); + if (t->bt_fd != -1) + (void)_close(t->bt_fd); + free(t); + } + return (NULL); +} + +/* + * NROOT -- Create the root of a new tree. + * + * Parameters: + * t: tree + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +static int +nroot(t) + BTREE *t; +{ + PAGE *meta, *root; + pgno_t npg; + + if ((meta = mpool_get(t->bt_mp, 0, 0)) != NULL) { + mpool_put(t->bt_mp, meta, 0); + return (RET_SUCCESS); + } + if (errno != EINVAL) /* It's OK to not exist. */ + return (RET_ERROR); + errno = 0; + + if ((meta = mpool_new(t->bt_mp, &npg)) == NULL) + return (RET_ERROR); + + if ((root = mpool_new(t->bt_mp, &npg)) == NULL) + return (RET_ERROR); + + if (npg != P_ROOT) + return (RET_ERROR); + root->pgno = npg; + root->prevpg = root->nextpg = P_INVALID; + root->lower = BTDATAOFF; + root->upper = t->bt_psize; + root->flags = P_BLEAF; + memset(meta, 0, t->bt_psize); + mpool_put(t->bt_mp, meta, MPOOL_DIRTY); + mpool_put(t->bt_mp, root, MPOOL_DIRTY); + return (RET_SUCCESS); +} + +static int +tmp() +{ + sigset_t set, oset; + int fd; + char *envtmp = NULL; + char path[MAXPATHLEN]; + + if (issetugid() == 0) + envtmp = getenv("TMPDIR"); + (void)snprintf(path, + sizeof(path), "%s/bt.XXXXXXXXXX", envtmp ? envtmp : "/tmp"); + + (void)sigfillset(&set); + (void)_sigprocmask(SIG_BLOCK, &set, &oset); + if ((fd = mkstemp(path)) != -1) + (void)unlink(path); + (void)_sigprocmask(SIG_SETMASK, &oset, NULL); + return(fd); +} + +static int +byteorder() +{ + u_int32_t x; + u_char *p; + + x = 0x01020304; + p = (u_char *)&x; + switch (*p) { + case 1: + return (BIG_ENDIAN); + case 4: + return (LITTLE_ENDIAN); + default: + return (0); + } +} + +int +__bt_fd(dbp) + const DB *dbp; +{ + BTREE *t; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* In-memory database can't have a file descriptor. */ + if (F_ISSET(t, B_INMEM)) { + errno = ENOENT; + return (-1); + } + return (t->bt_fd); +} diff --git a/db/btree/bt_overflow-fbsd.c b/db/btree/bt_overflow-fbsd.c new file mode 100644 index 0000000..5e0f1ae --- /dev/null +++ b/db/btree/bt_overflow-fbsd.c @@ -0,0 +1,230 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include +#include +#include + +#include +#include "btree.h" + +/* + * Big key/data code. + * + * Big key and data entries are stored on linked lists of pages. The initial + * reference is byte string stored with the key or data and is the page number + * and size. The actual record is stored in a chain of pages linked by the + * nextpg field of the PAGE header. + * + * The first page of the chain has a special property. If the record is used + * by an internal page, it cannot be deleted and the P_PRESERVE bit will be set + * in the header. + * + * XXX + * A single DBT is written to each chain, so a lot of space on the last page + * is wasted. This is a fairly major bug for some data sets. + */ + +/* + * __OVFL_GET -- Get an overflow key/data item. + * + * Parameters: + * t: tree + * p: pointer to { pgno_t, u_int32_t } + * buf: storage address + * bufsz: storage size + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__ovfl_get(t, p, ssz, buf, bufsz) + BTREE *t; + void *p; + size_t *ssz; + void **buf; + size_t *bufsz; +{ + PAGE *h; + pgno_t pg; + size_t nb, plen; + u_int32_t sz; + + memmove(&pg, p, sizeof(pgno_t)); + memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t)); + *ssz = sz; + +#ifdef DEBUG + if (pg == P_INVALID || sz == 0) + abort(); +#endif + /* Make the buffer bigger as necessary. */ + if (*bufsz < sz) { + *buf = (char *)(*buf == NULL ? malloc(sz) : reallocf(*buf, sz)); + if (*buf == NULL) + return (RET_ERROR); + *bufsz = sz; + } + + /* + * Step through the linked list of pages, copying the data on each one + * into the buffer. Never copy more than the data's length. + */ + plen = t->bt_psize - BTDATAOFF; + for (p = *buf;; p = (char *)p + nb, pg = h->nextpg) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + + nb = MIN(sz, plen); + memmove(p, (char *)h + BTDATAOFF, nb); + mpool_put(t->bt_mp, h, 0); + + if ((sz -= nb) == 0) + break; + } + return (RET_SUCCESS); +} + +/* + * __OVFL_PUT -- Store an overflow key/data item. + * + * Parameters: + * t: tree + * data: DBT to store + * pgno: storage page number + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__ovfl_put(t, dbt, pg) + BTREE *t; + const DBT *dbt; + pgno_t *pg; +{ + PAGE *h, *last; + void *p; + pgno_t npg; + size_t nb, plen; + u_int32_t sz; + + /* + * Allocate pages and copy the key/data record into them. Store the + * number of the first page in the chain. + */ + plen = t->bt_psize - BTDATAOFF; + for (last = NULL, p = dbt->data, sz = dbt->size;; + p = (char *)p + plen, last = h) { + if ((h = __bt_new(t, &npg)) == NULL) + return (RET_ERROR); + + h->pgno = npg; + h->nextpg = h->prevpg = P_INVALID; + h->flags = P_OVERFLOW; + h->lower = h->upper = 0; + + nb = MIN(sz, plen); + memmove((char *)h + BTDATAOFF, p, nb); + + if (last) { + last->nextpg = h->pgno; + mpool_put(t->bt_mp, last, MPOOL_DIRTY); + } else + *pg = h->pgno; + + if ((sz -= nb) == 0) { + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + break; + } + } + return (RET_SUCCESS); +} + +/* + * __OVFL_DELETE -- Delete an overflow chain. + * + * Parameters: + * t: tree + * p: pointer to { pgno_t, u_int32_t } + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__ovfl_delete(t, p) + BTREE *t; + void *p; +{ + PAGE *h; + pgno_t pg; + size_t plen; + u_int32_t sz; + + memmove(&pg, p, sizeof(pgno_t)); + memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t)); + +#ifdef DEBUG + if (pg == P_INVALID || sz == 0) + abort(); +#endif + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + + /* Don't delete chains used by internal pages. */ + if (h->flags & P_PRESERVE) { + mpool_put(t->bt_mp, h, 0); + return (RET_SUCCESS); + } + + /* Step through the chain, calling the free routine for each page. */ + for (plen = t->bt_psize - BTDATAOFF;; sz -= plen) { + pg = h->nextpg; + __bt_free(t, h); + if (sz <= plen) + break; + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + } + return (RET_SUCCESS); +} diff --git a/db/btree/bt_page-fbsd.c b/db/btree/bt_page-fbsd.c new file mode 100644 index 0000000..3392709 --- /dev/null +++ b/db/btree/bt_page-fbsd.c @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 1990, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +#include + +#include +#include "btree.h" + +/* + * __bt_free -- + * Put a page on the freelist. + * + * Parameters: + * t: tree + * h: page to free + * + * Returns: + * RET_ERROR, RET_SUCCESS + * + * Side-effect: + * mpool_put's the page. + */ +int +__bt_free(t, h) + BTREE *t; + PAGE *h; +{ + /* Insert the page at the head of the free list. */ + h->prevpg = P_INVALID; + h->nextpg = t->bt_free; + t->bt_free = h->pgno; + F_SET(t, B_METADIRTY); + + /* Make sure the page gets written back. */ + return (mpool_put(t->bt_mp, h, MPOOL_DIRTY)); +} + +/* + * __bt_new -- + * Get a new page, preferably from the freelist. + * + * Parameters: + * t: tree + * npg: storage for page number. + * + * Returns: + * Pointer to a page, NULL on error. + */ +PAGE * +__bt_new(t, npg) + BTREE *t; + pgno_t *npg; +{ + PAGE *h; + + if (t->bt_free != P_INVALID && + (h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) { + *npg = t->bt_free; + t->bt_free = h->nextpg; + F_SET(t, B_METADIRTY); + return (h); + } + return (mpool_new(t->bt_mp, npg)); +} diff --git a/db/btree/bt_put-fbsd.c b/db/btree/bt_put-fbsd.c new file mode 100644 index 0000000..0dca165 --- /dev/null +++ b/db/btree/bt_put-fbsd.c @@ -0,0 +1,325 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include +#include +#include +#include + +#include +#include "btree.h" + +static EPG *bt_fast(BTREE *, const DBT *, const DBT *, int *); + +/* + * __BT_PUT -- Add a btree item to the tree. + * + * Parameters: + * dbp: pointer to access method + * key: key + * data: data + * flag: R_NOOVERWRITE + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is already in the + * tree and R_NOOVERWRITE specified. + */ +int +__bt_put(dbp, key, data, flags) + const DB *dbp; + DBT *key; + const DBT *data; + u_int flags; +{ + BTREE *t; + DBT tkey, tdata; + EPG *e; + PAGE *h; + indx_t index, nxtindex; + pgno_t pg; + u_int32_t nbytes, tmp; + int dflags, exact, status; + char *dest, db[NOVFLSIZE], kb[NOVFLSIZE]; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Check for change to a read-only tree. */ + if (F_ISSET(t, B_RDONLY)) { + errno = EPERM; + return (RET_ERROR); + } + + switch (flags) { + case 0: + case R_NOOVERWRITE: + break; + case R_CURSOR: + /* + * If flags is R_CURSOR, put the cursor. Must already + * have started a scan and not have already deleted it. + */ + if (F_ISSET(&t->bt_cursor, CURS_INIT) && + !F_ISSET(&t->bt_cursor, + CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE)) + break; + /* FALLTHROUGH */ + default: + errno = EINVAL; + return (RET_ERROR); + } + + /* + * If the key/data pair won't fit on a page, store it on overflow + * pages. Only put the key on the overflow page if the pair are + * still too big after moving the data to an overflow page. + * + * XXX + * If the insert fails later on, the overflow pages aren't recovered. + */ + dflags = 0; + if (key->size + data->size > t->bt_ovflsize) { + if (key->size > t->bt_ovflsize) { +storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR) + return (RET_ERROR); + tkey.data = kb; + tkey.size = NOVFLSIZE; + memmove(kb, &pg, sizeof(pgno_t)); + tmp = key->size; + memmove(kb + sizeof(pgno_t), + &tmp, sizeof(u_int32_t)); + dflags |= P_BIGKEY; + key = &tkey; + } + if (key->size + data->size > t->bt_ovflsize) { + if (__ovfl_put(t, data, &pg) == RET_ERROR) + return (RET_ERROR); + tdata.data = db; + tdata.size = NOVFLSIZE; + memmove(db, &pg, sizeof(pgno_t)); + tmp = data->size; + memmove(db + sizeof(pgno_t), + &tmp, sizeof(u_int32_t)); + dflags |= P_BIGDATA; + data = &tdata; + } + if (key->size + data->size > t->bt_ovflsize) + goto storekey; + } + + /* Replace the cursor. */ + 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; + goto delete; + } + + /* + * Find the key to delete, or, the location at which to insert. + * Bt_fast and __bt_search both pin the returned page. + */ + if (t->bt_order == NOT || (e = bt_fast(t, key, data, &exact)) == NULL) + if ((e = __bt_search(t, key, &exact)) == NULL) + return (RET_ERROR); + h = e->page; + index = e->index; + + /* + * Add the key/data pair to the tree. If an identical key is already + * in the tree, and R_NOOVERWRITE is set, an error is returned. If + * R_NOOVERWRITE is not set, the key is either added (if duplicates are + * permitted) or an error is returned. + */ + switch (flags) { + case R_NOOVERWRITE: + if (!exact) + break; + mpool_put(t->bt_mp, h, 0); + return (RET_SPECIAL); + default: + if (!exact || !F_ISSET(t, B_NODUPS)) + break; + /* + * !!! + * 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) { + mpool_put(t->bt_mp, h, 0); + return (RET_ERROR); + } + break; + } + + /* + * If not enough room, or the user has put a ceiling on the number of + * keys permitted in the page, split the page. The split code will + * insert the key and data and unpin the current page. If inserting + * into the offset array, shift the pointers up. + */ + nbytes = NBLEAFDBT(key->size, data->size); + if (h->upper - h->lower < nbytes + sizeof(indx_t)) { + if ((status = __bt_split(t, h, key, + data, dflags, nbytes, index)) != RET_SUCCESS) + return (status); + goto success; + } + + if (index < (nxtindex = NEXTINDEX(h))) + memmove(h->linp + index + 1, h->linp + index, + (nxtindex - index) * sizeof(indx_t)); + h->lower += sizeof(indx_t); + + h->linp[index] = 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.index; + + if (t->bt_order == NOT) { + if (h->nextpg == P_INVALID) { + if (index == NEXTINDEX(h) - 1) { + t->bt_order = FORWARD; + t->bt_last.index = index; + t->bt_last.pgno = h->pgno; + } + } else if (h->prevpg == P_INVALID) { + if (index == 0) { + t->bt_order = BACK; + t->bt_last.index = 0; + t->bt_last.pgno = h->pgno; + } + } + } + + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + +success: + if (flags == R_SETCURSOR) + __bt_setcur(t, e->page->pgno, e->index); + + F_SET(t, B_MODIFIED); + return (RET_SUCCESS); +} + +#ifdef STATISTICS +u_long bt_cache_hit, bt_cache_miss; +#endif + +/* + * BT_FAST -- Do a quick check for sorted data. + * + * Parameters: + * t: tree + * key: key to insert + * + * Returns: + * 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; +{ + PAGE *h; + u_int32_t nbytes; + int cmp; + + if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) { + t->bt_order = NOT; + return (NULL); + } + t->bt_cur.page = h; + t->bt_cur.index = t->bt_last.index; + + /* + * If won't fit in this page or have too many keys in this page, + * have to search to get split stack. + */ + nbytes = NBLEAFDBT(key->size, data->size); + if (h->upper - h->lower < nbytes + sizeof(indx_t)) + goto miss; + + if (t->bt_order == FORWARD) { + if (t->bt_cur.page->nextpg != P_INVALID) + goto miss; + if (t->bt_cur.index != NEXTINDEX(h) - 1) + goto miss; + if ((cmp = __bt_cmp(t, key, &t->bt_cur)) < 0) + goto miss; + t->bt_last.index = cmp ? ++t->bt_cur.index : t->bt_cur.index; + } else { + if (t->bt_cur.page->prevpg != P_INVALID) + goto miss; + if (t->bt_cur.index != 0) + goto miss; + if ((cmp = __bt_cmp(t, key, &t->bt_cur)) > 0) + goto miss; + t->bt_last.index = 0; + } + *exactp = cmp == 0; +#ifdef STATISTICS + ++bt_cache_hit; +#endif + return (&t->bt_cur); + +miss: +#ifdef STATISTICS + ++bt_cache_miss; +#endif + t->bt_order = NOT; + mpool_put(t->bt_mp, h, 0); + return (NULL); +} diff --git a/db/btree/bt_search-fbsd.c b/db/btree/bt_search-fbsd.c new file mode 100644 index 0000000..cee177d --- /dev/null +++ b/db/btree/bt_search-fbsd.c @@ -0,0 +1,215 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include + +#include +#include "btree.h" + +static int __bt_snext(BTREE *, PAGE *, const DBT *, int *); +static int __bt_sprev(BTREE *, PAGE *, const DBT *, int *); + +/* + * __bt_search -- + * Search a btree for a key. + * + * Parameters: + * t: tree to search + * key: key to find + * exactp: pointer to exact match flag + * + * Returns: + * The EPG for matching record, if any, or the EPG for the location + * of the key, if it were inserted into the tree, is entered into + * 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; +{ + PAGE *h; + indx_t base, index, lim; + pgno_t pg; + int cmp; + + BT_CLR(t); + for (pg = P_ROOT;;) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (NULL); + + /* 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); + if ((cmp = __bt_cmp(t, key, &t->bt_cur)) == 0) { + if (h->flags & P_BLEAF) { + *exactp = 1; + return (&t->bt_cur); + } + goto next; + } + if (cmp > 0) { + base = index + 1; + --lim; + } + } + + /* + * If it's a leaf page, we're almost done. If no duplicates + * are allowed, or we have an exact match, we're done. Else, + * it's possible that there were matching keys on this page, + * which later deleted, and we're on a page with no matches + * while there are matches on other pages. If at the start or + * end of a page, check the adjacent page. + */ + if (h->flags & P_BLEAF) { + if (!F_ISSET(t, B_NODUPS)) { + if (base == 0 && + h->prevpg != P_INVALID && + __bt_sprev(t, h, key, exactp)) + return (&t->bt_cur); + if (base == NEXTINDEX(h) && + h->nextpg != P_INVALID && + __bt_snext(t, h, key, exactp)) + return (&t->bt_cur); + } + *exactp = 0; + t->bt_cur.index = base; + return (&t->bt_cur); + } + + /* + * No match found. Base is the smallest index greater than + * key and may be zero or a last + 1 index. If it's non-zero, + * decrement by one, and record the internal page which should + * 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; + +next: BT_PUSH(t, h->pgno, index); + pg = GETBINTERNAL(h, index)->pgno; + mpool_put(t->bt_mp, h, 0); + } +} + +/* + * __bt_snext -- + * Check for an exact match after the key. + * + * Parameters: + * t: tree + * h: current page + * key: key + * exactp: pointer to exact match flag + * + * Returns: + * If an exact match found. + */ +static int +__bt_snext(t, h, key, exactp) + BTREE *t; + PAGE *h; + const DBT *key; + int *exactp; +{ + EPG e; + + /* + * Get the next page. The key is either an exact + * match, or not as good as the one we already have. + */ + if ((e.page = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) + return (0); + e.index = 0; + if (__bt_cmp(t, key, &e) == 0) { + mpool_put(t->bt_mp, h, 0); + t->bt_cur = e; + *exactp = 1; + return (1); + } + mpool_put(t->bt_mp, e.page, 0); + return (0); +} + +/* + * __bt_sprev -- + * Check for an exact match before the key. + * + * Parameters: + * t: tree + * h: current page + * key: key + * exactp: pointer to exact match flag + * + * Returns: + * If an exact match found. + */ +static int +__bt_sprev(t, h, key, exactp) + BTREE *t; + PAGE *h; + const DBT *key; + int *exactp; +{ + EPG e; + + /* + * Get the previous page. The key is either an exact + * match, or not as good as the one we already have. + */ + if ((e.page = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL) + return (0); + e.index = NEXTINDEX(e.page) - 1; + if (__bt_cmp(t, key, &e) == 0) { + mpool_put(t->bt_mp, h, 0); + t->bt_cur = e; + *exactp = 1; + return (1); + } + mpool_put(t->bt_mp, e.page, 0); + return (0); +} diff --git a/db/btree/bt_seq-fbsd.c b/db/btree/bt_seq-fbsd.c new file mode 100644 index 0000000..662e195 --- /dev/null +++ b/db/btree/bt_seq-fbsd.c @@ -0,0 +1,462 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include +#include +#include +#include + +#include +#include "btree.h" + +static int __bt_first(BTREE *, const DBT *, EPG *, int *); +static int __bt_seqadv(BTREE *, EPG *, int); +static int __bt_seqset(BTREE *, EPG *, DBT *, int); + +/* + * Sequential scan support. + * + * The tree can be scanned sequentially, starting from either end of the + * tree or from any specific key. A scan request before any scanning is + * done is initialized as starting from the least node. + */ + +/* + * __bt_seq -- + * Btree sequential scan interface. + * + * Parameters: + * dbp: pointer to access method + * key: key for positioning and return value + * data: data return value + * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV. + * + * Returns: + * 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; +{ + BTREE *t; + EPG e; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* + * If scan unitialized as yet, or starting at a specific record, set + * the scan to a specific key. Both __bt_seqset and __bt_seqadv pin + * the page the cursor references if they're successful. + */ + switch (flags) { + case R_NEXT: + case R_PREV: + if (F_ISSET(&t->bt_cursor, CURS_INIT)) { + status = __bt_seqadv(t, &e, flags); + break; + } + /* FALLTHROUGH */ + case R_FIRST: + case R_LAST: + case R_CURSOR: + status = __bt_seqset(t, &e, key, flags); + break; + default: + errno = EINVAL; + return (RET_ERROR); + } + + if (status == RET_SUCCESS) { + __bt_setcur(t, e.page->pgno, e.index); + + status = + __bt_ret(t, &e, key, &t->bt_rkey, data, &t->bt_rdata, 0); + + /* + * If the user is doing concurrent access, we copied the + * key/data, toss the page. + */ + if (F_ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e.page, 0); + else + t->bt_pinned = e.page; + } + return (status); +} + +/* + * __bt_seqset -- + * Set the sequential scan to a specific key. + * + * Parameters: + * t: tree + * ep: storage for returned key + * key: key for initial scan position + * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV + * + * Side effects: + * Pins the page the cursor references. + * + * Returns: + * 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; +{ + PAGE *h; + pgno_t pg; + int exact; + + /* + * Find the first, last or specific key in the tree and point the + * cursor at it. The cursor may not be moved until a new key has + * been found. + */ + switch (flags) { + case R_CURSOR: /* Keyed scan. */ + /* + * Find the first instance of the key or the smallest key + * which is greater than or equal to the specified key. + */ + if (key->data == NULL || key->size == 0) { + errno = EINVAL; + return (RET_ERROR); + } + return (__bt_first(t, key, ep, &exact)); + case R_FIRST: /* First record. */ + case R_NEXT: + /* Walk down the left-hand side of the tree. */ + for (pg = P_ROOT;;) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + + /* Check for an empty tree. */ + if (NEXTINDEX(h) == 0) { + mpool_put(t->bt_mp, h, 0); + return (RET_SPECIAL); + } + + if (h->flags & (P_BLEAF | P_RLEAF)) + break; + pg = GETBINTERNAL(h, 0)->pgno; + mpool_put(t->bt_mp, h, 0); + } + ep->page = h; + ep->index = 0; + break; + case R_LAST: /* Last record. */ + case R_PREV: + /* Walk down the right-hand side of the tree. */ + for (pg = P_ROOT;;) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + + /* Check for an empty tree. */ + if (NEXTINDEX(h) == 0) { + mpool_put(t->bt_mp, h, 0); + return (RET_SPECIAL); + } + + if (h->flags & (P_BLEAF | P_RLEAF)) + break; + pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno; + mpool_put(t->bt_mp, h, 0); + } + + ep->page = h; + ep->index = NEXTINDEX(h) - 1; + break; + } + return (RET_SUCCESS); +} + +/* + * __bt_seqadvance -- + * Advance the sequential scan. + * + * Parameters: + * t: tree + * flags: R_NEXT, R_PREV + * + * Side effects: + * Pins the page the new key/data record is on. + * + * Returns: + * 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; +{ + CURSOR *c; + PAGE *h; + indx_t index; + pgno_t pg; + int exact; + + /* + * There are a couple of states that we can be in. The cursor has + * been initialized by the time we get here, but that's all we know. + */ + c = &t->bt_cursor; + + /* + * The cursor was deleted where there weren't any duplicate records, + * so the key was saved. Find out where that key would go in the + * current tree. It doesn't matter if the returned key is an exact + * match or not -- if it's an exact match, the record was added after + * the delete so we can just return it. If not, as long as there's + * a record there, return it. + */ + if (F_ISSET(c, CURS_ACQUIRE)) + return (__bt_first(t, &c->key, ep, &exact)); + + /* Get the page referenced by the cursor. */ + if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL) + return (RET_ERROR); + + /* + * 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) { + case R_NEXT: /* Next record. */ + /* + * The cursor was deleted in duplicate records, and moved + * forward to a record that has yet to be returned. Clear + * that flag, and return the record. + */ + if (F_ISSET(c, CURS_AFTER)) + goto usecurrent; + index = c->pg.index; + if (++index == 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; + } + break; + case R_PREV: /* Previous record. */ + /* + * The cursor was deleted in duplicate records, and moved + * backward to a record that has yet to be returned. Clear + * that flag, and return the record. + */ + if (F_ISSET(c, CURS_BEFORE)) { +usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE); + ep->page = h; + ep->index = c->pg.index; + return (RET_SUCCESS); + } + index = c->pg.index; + if (index == 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; + } else + --index; + break; + } + + ep->page = h; + ep->index = index; + return (RET_SUCCESS); +} + +/* + * __bt_first -- + * Find the first entry. + * + * Parameters: + * t: the tree + * key: the key + * erval: return EPG + * exactp: pointer to exact match flag + * + * Returns: + * The first entry in the tree greater than or equal to key, + * 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; +{ + PAGE *h; + EPG *ep, save; + pgno_t pg; + + /* + * Find any matching record; __bt_search pins the page. + * + * If it's an exact match and duplicates are possible, walk backwards + * in the tree until we find the first one. Otherwise, make sure it's + * a valid key (__bt_search may return an index just past the end of a + * page) and return it. + */ + if ((ep = __bt_search(t, key, exactp)) == NULL) + return (0); + if (*exactp) { + if (F_ISSET(t, B_NODUPS)) { + *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 + * we go too far. + */ + save = *ep; + h = ep->page; + do { + if (save.page->pgno != ep->page->pgno) { + mpool_put(t->bt_mp, save.page, 0); + save = *ep; + } else + save.index = ep->index; + + /* + * Don't unpin the page the last (or original) match + * was on, but make sure it's unpinned if an error + * occurs. + */ + if (ep->index == 0) { + if (h->prevpg == P_INVALID) + break; + if (h->pgno != save.page->pgno) + mpool_put(t->bt_mp, h, 0); + if ((h = mpool_get(t->bt_mp, + h->prevpg, 0)) == NULL) { + if (h->pgno == save.page->pgno) + mpool_put(t->bt_mp, + save.page, 0); + return (RET_ERROR); + } + ep->page = h; + ep->index = NEXTINDEX(h); + } + --ep->index; + } while (__bt_cmp(t, key, ep) == 0); + + /* + * Reach here with the last page that was looked at pinned, + * which may or may not be the same as the last (or original) + * match page. If it's not useful, release it. + */ + if (h->pgno != save.page->pgno) + mpool_put(t->bt_mp, h, 0); + + *erval = save; + return (RET_SUCCESS); + } + + /* If at the end of a page, find the next entry. */ + if (ep->index == NEXTINDEX(ep->page)) { + h = ep->page; + 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); + ep->index = 0; + ep->page = h; + } + *erval = *ep; + return (RET_SUCCESS); +} + +/* + * __bt_setcur -- + * Set the cursor to an entry in the tree. + * + * Parameters: + * t: the tree + * pgno: page number + * index: page index + */ +void +__bt_setcur(t, pgno, index) + BTREE *t; + pgno_t pgno; + u_int index; +{ + /* Lose any already deleted key. */ + if (t->bt_cursor.key.data != NULL) { + free(t->bt_cursor.key.data); + t->bt_cursor.key.size = 0; + t->bt_cursor.key.data = NULL; + } + F_CLR(&t->bt_cursor, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE); + + /* Update the cursor. */ + t->bt_cursor.pg.pgno = pgno; + t->bt_cursor.pg.index = index; + F_SET(&t->bt_cursor, CURS_INIT); +} diff --git a/db/btree/bt_split-fbsd.c b/db/btree/bt_split-fbsd.c new file mode 100644 index 0000000..07373de --- /dev/null +++ b/db/btree/bt_split-fbsd.c @@ -0,0 +1,827 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include +#include +#include +#include + +#include +#include "btree.h" + +static int bt_broot(BTREE *, PAGE *, PAGE *, PAGE *); +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 int bt_rroot(BTREE *, PAGE *, PAGE *, PAGE *); +static recno_t rec_total(PAGE *); + +#ifdef STATISTICS +u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved; +#endif + +/* + * __BT_SPLIT -- Split the tree. + * + * Parameters: + * t: tree + * sp: page to split + * key: key to insert + * data: data to insert + * flags: BIGKEY/BIGDATA flags + * ilen: insert length + * skip: index to leave open + * + * Returns: + * 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; +{ + BINTERNAL *bi; + BLEAF *bl, *tbl; + DBT a, b; + EPGNO *parent; + PAGE *h, *l, *r, *lchild, *rchild; + indx_t nxtindex; + u_int16_t skip; + u_int32_t n, nbytes, nksize; + int parentsplit; + char *dest; + + /* + * Split the page into two pages, l and r. The split routines return + * a pointer to the page into which the key should be inserted and with + * skip set to the offset which should be used. Additionally, l and r + * are pinned. + */ + skip = argskip; + h = sp->pgno == P_ROOT ? + bt_root(t, sp, &l, &r, &skip, ilen) : + bt_page(t, sp, &l, &r, &skip, ilen); + if (h == NULL) + return (RET_ERROR); + + /* + * Insert the new key/data pair into the leaf page. (Key inserts + * always cause a leaf page to split first.) + */ + h->linp[skip] = h->upper -= ilen; + dest = (char *)h + h->upper; + if (F_ISSET(t, R_RECNO)) + WR_RLEAF(dest, data, flags) + else + WR_BLEAF(dest, key, data, flags) + + /* If the root page was split, make it look right. */ + if (sp->pgno == P_ROOT && + (F_ISSET(t, R_RECNO) ? + bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR) + goto err2; + + /* + * Now we walk the parent page stack -- a LIFO stack of the pages that + * were traversed when we searched for the page that split. Each stack + * entry is a page number and a page index offset. The offset is for + * the page traversed on the search. We've just split a page, so we + * have to insert a new key into the parent page. + * + * If the insert into the parent page causes it to split, may have to + * continue splitting all the way up the tree. We stop if the root + * splits or the page inserted into didn't have to split to hold the + * new key. Some algorithms replace the key for the old page as well + * as the new page. We don't, as there's no reason to believe that the + * first key on the old page is any better than the key we have, and, + * in the case of a key being placed at index 0 causing the split, the + * key is unavailable. + * + * There are a maximum of 5 pages pinned at any time. We keep the left + * and right pages pinned while working on the parent. The 5 are the + * two children, left parent and right parent (when the parent splits) + * and the root page or the overflow key page when calling bt_preserve. + * This code must make sure that all pins are released other than the + * root page or overflow page which is unlocked elsewhere. + */ + while ((parent = BT_POP(t)) != NULL) { + lchild = l; + rchild = r; + + /* Get the parent page. */ + 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. + */ + skip = parent->index + 1; + + /* + * Calculate the space needed on the parent page. + * + * Prefix trees: space hack when inserting into BINTERNAL + * pages. Retain only what's needed to distinguish between + * the new entry and the LAST entry on the page to its left. + * If the keys compare equal, retain the entire key. Note, + * we don't touch overflow keys, and the entire key must be + * retained for the next-to-left most key on the leftmost + * page of each level, or the search will fail. Applicable + * ONLY to internal pages that have leaf pages as children. + * Further reduction of the key between pairs of internal + * pages loses too much information. + */ + switch (rchild->flags & P_TYPE) { + case P_BINTERNAL: + bi = GETBINTERNAL(rchild, 0); + nbytes = NBINTERNAL(bi->ksize); + break; + case P_BLEAF: + bl = GETBLEAF(rchild, 0); + nbytes = NBINTERNAL(bl->ksize); + if (t->bt_pfx && !(bl->flags & P_BIGKEY) && + (h->prevpg != P_INVALID || skip > 1)) { + tbl = GETBLEAF(lchild, NEXTINDEX(lchild) - 1); + a.size = tbl->ksize; + a.data = tbl->bytes; + b.size = bl->ksize; + b.data = bl->bytes; + nksize = t->bt_pfx(&a, &b); + n = NBINTERNAL(nksize); + if (n < nbytes) { +#ifdef STATISTICS + bt_pfxsaved += nbytes - n; +#endif + nbytes = n; + } else + nksize = 0; + } else + nksize = 0; + break; + case P_RINTERNAL: + case P_RLEAF: + nbytes = NRINTERNAL; + break; + default: + abort(); + } + + /* Split the parent page if necessary or shift the indices. */ + if (h->upper - h->lower < nbytes + sizeof(indx_t)) { + sp = h; + h = h->pgno == P_ROOT ? + bt_root(t, h, &l, &r, &skip, nbytes) : + bt_page(t, h, &l, &r, &skip, nbytes); + if (h == NULL) + goto err1; + parentsplit = 1; + } else { + if (skip < (nxtindex = NEXTINDEX(h))) + memmove(h->linp + skip + 1, h->linp + skip, + (nxtindex - skip) * sizeof(indx_t)); + h->lower += sizeof(indx_t); + parentsplit = 0; + } + + /* Insert the key into the parent page. */ + switch (rchild->flags & P_TYPE) { + case P_BINTERNAL: + h->linp[skip] = h->upper -= nbytes; + dest = (char *)h + h->linp[skip]; + memmove(dest, bi, nbytes); + ((BINTERNAL *)dest)->pgno = rchild->pgno; + break; + case P_BLEAF: + h->linp[skip] = h->upper -= nbytes; + dest = (char *)h + h->linp[skip]; + WR_BINTERNAL(dest, nksize ? nksize : bl->ksize, + rchild->pgno, bl->flags & P_BIGKEY); + memmove(dest, bl->bytes, nksize ? nksize : bl->ksize); + if (bl->flags & P_BIGKEY && + bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR) + goto err1; + break; + case P_RINTERNAL: + /* + * Update the left page count. If split + * added at index 0, fix the correct page. + */ + if (skip > 0) + dest = (char *)h + h->linp[skip - 1]; + else + dest = (char *)l + l->linp[NEXTINDEX(l) - 1]; + ((RINTERNAL *)dest)->nrecs = rec_total(lchild); + ((RINTERNAL *)dest)->pgno = lchild->pgno; + + /* Update the right page count. */ + h->linp[skip] = h->upper -= nbytes; + dest = (char *)h + h->linp[skip]; + ((RINTERNAL *)dest)->nrecs = rec_total(rchild); + ((RINTERNAL *)dest)->pgno = rchild->pgno; + break; + case P_RLEAF: + /* + * Update the left page count. If split + * added at index 0, fix the correct page. + */ + if (skip > 0) + dest = (char *)h + h->linp[skip - 1]; + else + dest = (char *)l + l->linp[NEXTINDEX(l) - 1]; + ((RINTERNAL *)dest)->nrecs = NEXTINDEX(lchild); + ((RINTERNAL *)dest)->pgno = lchild->pgno; + + /* Update the right page count. */ + h->linp[skip] = h->upper -= nbytes; + dest = (char *)h + h->linp[skip]; + ((RINTERNAL *)dest)->nrecs = NEXTINDEX(rchild); + ((RINTERNAL *)dest)->pgno = rchild->pgno; + break; + default: + abort(); + } + + /* Unpin the held pages. */ + if (!parentsplit) { + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + break; + } + + /* If the root page was split, make it look right. */ + if (sp->pgno == P_ROOT && + (F_ISSET(t, R_RECNO) ? + bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR) + goto err1; + + mpool_put(t->bt_mp, lchild, MPOOL_DIRTY); + mpool_put(t->bt_mp, rchild, MPOOL_DIRTY); + } + + /* Unpin the held pages. */ + mpool_put(t->bt_mp, l, MPOOL_DIRTY); + mpool_put(t->bt_mp, r, MPOOL_DIRTY); + + /* Clear any pages left on the stack. */ + return (RET_SUCCESS); + + /* + * If something fails in the above loop we were already walking back + * up the tree and the tree is now inconsistent. Nothing much we can + * do about it but release any memory we're holding. + */ +err1: mpool_put(t->bt_mp, lchild, MPOOL_DIRTY); + mpool_put(t->bt_mp, rchild, MPOOL_DIRTY); + +err2: mpool_put(t->bt_mp, l, 0); + mpool_put(t->bt_mp, r, 0); + __dbpanic(t->bt_dbp); + return (RET_ERROR); +} + +/* + * BT_PAGE -- Split a non-root page of a btree. + * + * Parameters: + * t: tree + * h: root page + * lp: pointer to left page pointer + * rp: pointer to right page pointer + * skip: pointer to index to leave open + * ilen: insert length + * + * Returns: + * 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; +{ + PAGE *l, *r, *tp; + pgno_t npg; + +#ifdef STATISTICS + ++bt_split; +#endif + /* Put the new right page for the split into place. */ + if ((r = __bt_new(t, &npg)) == NULL) + return (NULL); + r->pgno = npg; + r->lower = BTDATAOFF; + r->upper = t->bt_psize; + r->nextpg = h->nextpg; + r->prevpg = h->pgno; + r->flags = h->flags & P_TYPE; + + /* + * If we're splitting the last page on a level because we're appending + * a key to it (skip is NEXTINDEX()), it's likely that the data is + * sorted. Adding an empty page on the side of the level is less work + * and can push the fill factor much higher than normal. If we're + * wrong it's no big deal, we'll just do the split the right way next + * time. It may look like it's equally easy to do a similar hack for + * reverse sorted data, that is, split the tree left, but it's not. + * Don't even try. + */ + if (h->nextpg == P_INVALID && *skip == NEXTINDEX(h)) { +#ifdef STATISTICS + ++bt_sortsplit; +#endif + h->nextpg = r->pgno; + r->lower = BTDATAOFF + sizeof(indx_t); + *skip = 0; + *lp = h; + *rp = r; + return (r); + } + + /* Put the new left page for the split into place. */ + if ((l = (PAGE *)malloc(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; + l->lower = BTDATAOFF; + l->upper = t->bt_psize; + l->flags = h->flags & P_TYPE; + + /* Fix up the previous pointer of the page after the split page. */ + if (h->nextpg != P_INVALID) { + if ((tp = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) { + free(l); + /* XXX mpool_free(t->bt_mp, r->pgno); */ + return (NULL); + } + tp->prevpg = r->pgno; + mpool_put(t->bt_mp, tp, MPOOL_DIRTY); + } + + /* + * Split right. The key/data pairs aren't sorted in the btree page so + * it's simpler to copy the data from the split page onto two new pages + * instead of copying half the data to the right page and compacting + * the left page in place. Since the left page can't change, we have + * to swap the original and the allocated left page after the split. + */ + tp = bt_psplit(t, h, l, r, skip, ilen); + + /* Move the new left page onto the old left page. */ + memmove(h, l, t->bt_psize); + if (tp == l) + tp = h; + free(l); + + *lp = h; + *rp = r; + return (tp); +} + +/* + * BT_ROOT -- Split the root page of a btree. + * + * Parameters: + * t: tree + * h: root page + * lp: pointer to left page pointer + * rp: pointer to right page pointer + * skip: pointer to index to leave open + * ilen: insert length + * + * Returns: + * 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; +{ + PAGE *l, *r, *tp; + pgno_t lnpg, rnpg; + +#ifdef STATISTICS + ++bt_split; + ++bt_rootsplit; +#endif + /* Put the new left and right pages for the split into place. */ + if ((l = __bt_new(t, &lnpg)) == NULL || + (r = __bt_new(t, &rnpg)) == NULL) + return (NULL); + l->pgno = lnpg; + r->pgno = rnpg; + l->nextpg = r->pgno; + r->prevpg = l->pgno; + l->prevpg = r->nextpg = P_INVALID; + l->lower = r->lower = BTDATAOFF; + l->upper = r->upper = t->bt_psize; + l->flags = r->flags = h->flags & P_TYPE; + + /* Split the root page. */ + tp = bt_psplit(t, h, l, r, skip, ilen); + + *lp = l; + *rp = r; + return (tp); +} + +/* + * BT_RROOT -- Fix up the recno root page after it has been split. + * + * Parameters: + * t: tree + * h: root page + * l: left page + * r: right page + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +static int +bt_rroot(t, h, l, r) + BTREE *t; + PAGE *h, *l, *r; +{ + char *dest; + + /* Insert the left and right keys, set the header information. */ + h->linp[0] = h->upper = t->bt_psize - NRINTERNAL; + dest = (char *)h + h->upper; + WR_RINTERNAL(dest, + l->flags & P_RLEAF ? NEXTINDEX(l) : rec_total(l), l->pgno); + + h->linp[1] = h->upper -= NRINTERNAL; + dest = (char *)h + h->upper; + WR_RINTERNAL(dest, + r->flags & P_RLEAF ? NEXTINDEX(r) : rec_total(r), r->pgno); + + h->lower = BTDATAOFF + 2 * sizeof(indx_t); + + /* Unpin the root page, set to recno internal page. */ + h->flags &= ~P_TYPE; + h->flags |= P_RINTERNAL; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + + return (RET_SUCCESS); +} + +/* + * BT_BROOT -- Fix up the btree root page after it has been split. + * + * Parameters: + * t: tree + * h: root page + * l: left page + * r: right page + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +static int +bt_broot(t, h, l, r) + BTREE *t; + PAGE *h, *l, *r; +{ + BINTERNAL *bi; + BLEAF *bl; + u_int32_t nbytes; + char *dest; + + /* + * If the root page was a leaf page, change it into an internal page. + * We copy the key we split on (but not the key's data, in the case of + * a leaf page) to the new root page. + * + * The btree comparison code guarantees that the left-most key on any + * level of the tree is never used, so it doesn't need to be filled in. + */ + nbytes = NBINTERNAL(0); + h->linp[0] = h->upper = t->bt_psize - nbytes; + dest = (char *)h + h->upper; + WR_BINTERNAL(dest, 0, l->pgno, 0); + + switch (h->flags & P_TYPE) { + case P_BLEAF: + bl = GETBLEAF(r, 0); + nbytes = NBINTERNAL(bl->ksize); + h->linp[1] = h->upper -= nbytes; + dest = (char *)h + h->upper; + WR_BINTERNAL(dest, bl->ksize, r->pgno, 0); + memmove(dest, bl->bytes, bl->ksize); + + /* + * If the key is on an overflow page, mark the overflow chain + * so it isn't deleted when the leaf copy of the key is deleted. + */ + if (bl->flags & P_BIGKEY && + bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR) + return (RET_ERROR); + break; + case P_BINTERNAL: + bi = GETBINTERNAL(r, 0); + nbytes = NBINTERNAL(bi->ksize); + h->linp[1] = h->upper -= nbytes; + dest = (char *)h + h->upper; + memmove(dest, bi, nbytes); + ((BINTERNAL *)dest)->pgno = r->pgno; + break; + default: + abort(); + } + + /* There are two keys on the page. */ + h->lower = BTDATAOFF + 2 * sizeof(indx_t); + + /* Unpin the root page, set to btree internal page. */ + h->flags &= ~P_TYPE; + h->flags |= P_BINTERNAL; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + + return (RET_SUCCESS); +} + +/* + * BT_PSPLIT -- Do the real work of splitting the page. + * + * Parameters: + * t: tree + * h: page to be split + * l: page to put lower half of data + * r: page to put upper half of data + * pskip: pointer to index to leave open + * ilen: insert length + * + * Returns: + * 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; +{ + BINTERNAL *bi; + BLEAF *bl; + CURSOR *c; + RLEAF *rl; + PAGE *rval; + void *src; + indx_t full, half, nxt, off, skip, top, used; + u_int32_t nbytes; + int bigkeycnt, isbigkey; + + /* + * Split the data to the left and right pages. Leave the skip index + * open. Additionally, make some effort not to split on an overflow + * key. This makes internal page processing faster and can save + * space as overflow keys used by internal pages are never deleted. + */ + bigkeycnt = 0; + skip = *pskip; + full = t->bt_psize - BTDATAOFF; + half = full / 2; + used = 0; + for (nxt = off = 0, top = NEXTINDEX(h); nxt < top; ++off) { + if (skip == off) { + nbytes = ilen; + isbigkey = 0; /* XXX: not really known. */ + } else + switch (h->flags & P_TYPE) { + case P_BINTERNAL: + src = bi = GETBINTERNAL(h, nxt); + nbytes = NBINTERNAL(bi->ksize); + isbigkey = bi->flags & P_BIGKEY; + break; + case P_BLEAF: + src = bl = GETBLEAF(h, nxt); + nbytes = NBLEAF(bl); + isbigkey = bl->flags & P_BIGKEY; + break; + case P_RINTERNAL: + src = GETRINTERNAL(h, nxt); + nbytes = NRINTERNAL; + isbigkey = 0; + break; + case P_RLEAF: + src = rl = GETRLEAF(h, nxt); + nbytes = NRLEAF(rl); + isbigkey = 0; + break; + default: + abort(); + } + + /* + * If the key/data pairs are substantial fractions of the max + * possible size for the page, it's possible to get situations + * where we decide to try and copy too much onto the left page. + * Make sure that doesn't happen. + */ + if ((skip <= off && used + nbytes + sizeof(indx_t) >= full) + || nxt == top - 1) { + --off; + break; + } + + /* Copy the key/data pair, if not the skipped index. */ + if (skip != off) { + ++nxt; + + l->linp[off] = l->upper -= nbytes; + memmove((char *)l + l->upper, src, nbytes); + } + + used += nbytes + sizeof(indx_t); + if (used >= half) { + if (!isbigkey || bigkeycnt == 3) + break; + else + ++bigkeycnt; + } + } + + /* + * Off is the last offset that's valid for the left page. + * Nxt is the first offset to be placed on the right page. + */ + l->lower += (off + 1) * sizeof(indx_t); + + /* + * If splitting the page that the cursor was on, the cursor has to be + * adjusted to point to the same record as before the split. If the + * cursor is at or past the skipped slot, the cursor is incremented by + * one. If the cursor is on the right page, it is decremented by the + * number of records split to the left page. + */ + c = &t->bt_cursor; + if (F_ISSET(c, CURS_INIT) && c->pg.pgno == h->pgno) { + if (c->pg.index >= skip) + ++c->pg.index; + if (c->pg.index < nxt) /* Left page. */ + c->pg.pgno = l->pgno; + else { /* Right page. */ + c->pg.pgno = r->pgno; + c->pg.index -= nxt; + } + } + + /* + * If the skipped index was on the left page, just return that page. + * Otherwise, adjust the skip index to reflect the new position on + * the right page. + */ + if (skip <= off) { + skip = MAX_PAGE_OFFSET; + rval = l; + } else { + rval = r; + *pskip -= nxt; + } + + for (off = 0; nxt < top; ++off) { + if (skip == nxt) { + ++off; + skip = MAX_PAGE_OFFSET; + } + switch (h->flags & P_TYPE) { + case P_BINTERNAL: + src = bi = GETBINTERNAL(h, nxt); + nbytes = NBINTERNAL(bi->ksize); + break; + case P_BLEAF: + src = bl = GETBLEAF(h, nxt); + nbytes = NBLEAF(bl); + break; + case P_RINTERNAL: + src = GETRINTERNAL(h, nxt); + nbytes = NRINTERNAL; + break; + case P_RLEAF: + src = rl = GETRLEAF(h, nxt); + nbytes = NRLEAF(rl); + break; + default: + abort(); + } + ++nxt; + r->linp[off] = r->upper -= nbytes; + memmove((char *)r + r->upper, src, nbytes); + } + r->lower += off * sizeof(indx_t); + + /* If the key is being appended to the page, adjust the index. */ + if (skip == top) + r->lower += sizeof(indx_t); + + return (rval); +} + +/* + * BT_PRESERVE -- Mark a chain of pages as used by an internal node. + * + * Chains of indirect blocks pointed to by leaf nodes get reclaimed when the + * record that references them gets deleted. Chains pointed to by internal + * pages never get deleted. This routine marks a chain as pointed to by an + * internal page. + * + * Parameters: + * t: tree + * pg: page number of first page in the chain. + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +static int +bt_preserve(t, pg) + BTREE *t; + pgno_t pg; +{ + PAGE *h; + + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + return (RET_ERROR); + h->flags |= P_PRESERVE; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + return (RET_SUCCESS); +} + +/* + * REC_TOTAL -- Return the number of recno entries below a page. + * + * Parameters: + * h: page + * + * Returns: + * The number of recno entries below a page. + * + * XXX + * These values could be set by the bt_psplit routine. The problem is that the + * entry has to be popped off of the stack etc. or the values have to be passed + * all the way back to bt_split/bt_rroot and it's not very clean. + */ +static recno_t +rec_total(h) + PAGE *h; +{ + recno_t recs; + indx_t nxt, top; + + for (recs = 0, nxt = 0, top = NEXTINDEX(h); nxt < top; ++nxt) + recs += GETRINTERNAL(h, nxt)->nrecs; + return (recs); +} diff --git a/db/btree/bt_utils-fbsd.c b/db/btree/bt_utils-fbsd.c new file mode 100644 index 0000000..e9acfb7 --- /dev/null +++ b/db/btree/bt_utils-fbsd.c @@ -0,0 +1,262 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include +#include +#include + +#include +#include "btree.h" + +/* + * __bt_ret -- + * Build return key/data pair. + * + * Parameters: + * t: tree + * e: key/data pair to be returned + * key: user's key structure (NULL if not to be filled in) + * rkey: memory area to hold key + * data: user's data structure (NULL if not to be filled in) + * rdata: memory area to hold data + * copy: always copy the key/data item + * + * Returns: + * 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; +{ + BLEAF *bl; + void *p; + + bl = GETBLEAF(e->page, e->index); + + /* + * We must copy big keys/data to make them contigous. Otherwise, + * leave the page pinned and don't copy unless the user specified + * concurrent access. + */ + if (key == NULL) + goto dataonly; + + if (bl->flags & P_BIGKEY) { + if (__ovfl_get(t, bl->bytes, + &key->size, &rkey->data, &rkey->size)) + return (RET_ERROR); + 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)); + if (p == NULL) + return (RET_ERROR); + rkey->data = p; + rkey->size = bl->ksize; + } + memmove(rkey->data, bl->bytes, bl->ksize); + key->size = bl->ksize; + key->data = rkey->data; + } else { + key->size = bl->ksize; + key->data = bl->bytes; + } + +dataonly: + if (data == NULL) + return (RET_SUCCESS); + + if (bl->flags & P_BIGDATA) { + if (__ovfl_get(t, bl->bytes + bl->ksize, + &data->size, &rdata->data, &rdata->size)) + return (RET_ERROR); + data->data = rdata->data; + } 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)); + if (p == NULL) + return (RET_ERROR); + rdata->data = p; + rdata->size = bl->dsize + 1; + } + memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize); + data->size = bl->dsize; + data->data = rdata->data; + } else { + data->size = bl->dsize; + data->data = bl->bytes + bl->ksize; + } + + return (RET_SUCCESS); +} + +/* + * __BT_CMP -- Compare a key to a given record. + * + * Parameters: + * t: tree + * k1: DBT pointer of first arg to comparison + * e: pointer to EPG for comparison + * + * Returns: + * < 0 if k1 is < record + * = 0 if k1 is = record + * > 0 if k1 is > record + */ +int +__bt_cmp(t, k1, e) + BTREE *t; + const DBT *k1; + EPG *e; +{ + BINTERNAL *bi; + BLEAF *bl; + DBT k2; + PAGE *h; + void *bigkey; + + /* + * The left-most key on internal pages, at any level of the tree, is + * guaranteed by the following code to be less than any user key. + * This saves us from having to update the leftmost key on an internal + * page when the user inserts a new key in the tree smaller than + * anything we've yet seen. + */ + h = e->page; + if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF)) + return (1); + + bigkey = NULL; + if (h->flags & P_BLEAF) { + bl = GETBLEAF(h, e->index); + if (bl->flags & P_BIGKEY) + bigkey = bl->bytes; + else { + k2.data = bl->bytes; + k2.size = bl->ksize; + } + } else { + bi = GETBINTERNAL(h, e->index); + if (bi->flags & P_BIGKEY) + bigkey = bi->bytes; + else { + k2.data = bi->bytes; + k2.size = bi->ksize; + } + } + + if (bigkey) { + if (__ovfl_get(t, bigkey, + &k2.size, &t->bt_rdata.data, &t->bt_rdata.size)) + return (RET_ERROR); + k2.data = t->bt_rdata.data; + } + return ((*t->bt_cmp)(k1, &k2)); +} + +/* + * __BT_DEFCMP -- Default comparison routine. + * + * Parameters: + * a: DBT #1 + * b: DBT #2 + * + * Returns: + * < 0 if a is < b + * = 0 if a is = b + * > 0 if a is > b + */ +int +__bt_defcmp(a, b) + const DBT *a, *b; +{ + size_t len; + u_char *p1, *p2; + + /* + * XXX + * If a size_t doesn't fit in an int, this routine can lose. + * What we need is an integral type which is guaranteed to be + * larger than a size_t, and there is no such thing. + */ + len = MIN(a->size, b->size); + for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2) + if (*p1 != *p2) + return ((int)*p1 - (int)*p2); + return ((int)a->size - (int)b->size); +} + +/* + * __BT_DEFPFX -- Default prefix routine. + * + * Parameters: + * a: DBT #1 + * b: DBT #2 + * + * Returns: + * Number of bytes needed to distinguish b from a. + */ +size_t +__bt_defpfx(a, b) + const DBT *a, *b; +{ + u_char *p1, *p2; + size_t cnt, len; + + cnt = 1; + len = MIN(a->size, b->size); + for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt) + if (*p1 != *p2) + return (cnt); + + /* a->size must be <= b->size, or they wouldn't be in this order. */ + return (a->size < b->size ? a->size + 1 : a->size); +} diff --git a/db/btree/btree.h b/db/btree/btree.h new file mode 100644 index 0000000..7153fb9 --- /dev/null +++ b/db/btree/btree.h @@ -0,0 +1,384 @@ +/*- + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * 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. + * + * @(#)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 $ + */ + +/* Macros to set/clear/test flags. */ +#define F_SET(p, f) (p)->flags |= (f) +#define F_CLR(p, f) (p)->flags &= ~(f) +#define F_ISSET(p, f) ((p)->flags & (f)) + +#include + +#define DEFMINKEYPAGE (2) /* Minimum keys per page */ +#define MINCACHE (5) /* Minimum cached pages */ +#define MINPSIZE (512) /* Minimum page size */ + +/* + * Page 0 of a btree file contains a copy of the meta-data. This page is also + * used as an out-of-band page, i.e. page pointers that point to nowhere point + * to page 0. Page 1 is the root of the btree. + */ +#define P_INVALID 0 /* Invalid tree page number. */ +#define P_META 0 /* Tree metadata page number. */ +#define P_ROOT 1 /* Tree root page number. */ + +/* + * There are five page layouts in the btree: btree internal pages (BINTERNAL), + * btree leaf pages (BLEAF), recno internal pages (RINTERNAL), recno leaf pages + * (RLEAF) and overflow pages. All five page types have a page header (PAGE). + * This implementation requires that values within structures NOT be padded. + * (ANSI C permits random padding.) If your compiler pads randomly you'll have + * to do some work to get this package to run. + */ +typedef struct _page { + pgno_t pgno; /* this page's page number */ + pgno_t prevpg; /* left sibling */ + pgno_t nextpg; /* right sibling */ + +#define P_BINTERNAL 0x01 /* btree internal page */ +#define P_BLEAF 0x02 /* leaf page */ +#define P_OVERFLOW 0x04 /* overflow page */ +#define P_RINTERNAL 0x08 /* recno internal page */ +#define P_RLEAF 0x10 /* leaf page */ +#define P_TYPE 0x1f /* type mask */ +#define P_PRESERVE 0x20 /* never delete this chain of pages */ + u_int32_t flags; + + indx_t lower; /* lower bound of free space on page */ + indx_t upper; /* upper bound of free space on page */ + indx_t linp[1]; /* indx_t-aligned VAR. LENGTH DATA */ +} PAGE; + +/* First and next index. */ +#define BTDATAOFF \ + (sizeof(pgno_t) + sizeof(pgno_t) + sizeof(pgno_t) + \ + sizeof(u_int32_t) + sizeof(indx_t) + sizeof(indx_t)) +#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) / sizeof(indx_t)) + +/* + * For pages other than overflow pages, there is an array of offsets into the + * rest of the page immediately following the page header. Each offset is to + * an item which is unique to the type of page. The h_lower offset is just + * past the last filled-in index. The h_upper offset is the first item on the + * page. Offsets are from the beginning of the page. + * + * If an item is too big to store on a single page, a flag is set and the item + * is a { page, size } pair such that the page is the first page of an overflow + * chain with size bytes of item. Overflow pages are simply bytes without any + * external structure. + * + * The page number and size fields in the items are pgno_t-aligned so they can + * be manipulated without copying. (This presumes that 32 bit items can be + * manipulated on this system.) + */ +#define LALIGN(n) (((n) + sizeof(pgno_t) - 1) & ~(sizeof(pgno_t) - 1)) +#define NOVFLSIZE (sizeof(pgno_t) + sizeof(u_int32_t)) + +/* + * For the btree internal pages, the item is a key. BINTERNALs are {key, pgno} + * pairs, such that the key compares less than or equal to all of the records + * on that page. For a tree without duplicate keys, an internal page with two + * consecutive keys, a and b, will have all records greater than or equal to a + * and less than b stored on the page associated with a. Duplicate keys are + * somewhat special and can cause duplicate internal and leaf page records and + * some minor modifications of the above rule. + */ +typedef struct _binternal { + u_int32_t ksize; /* key size */ + pgno_t pgno; /* page number stored on */ +#define P_BIGDATA 0x01 /* overflow data */ +#define P_BIGKEY 0x02 /* overflow key */ + u_char flags; + char bytes[1]; /* data */ +} BINTERNAL; + +/* Get the page's BINTERNAL structure at index indx. */ +#define GETBINTERNAL(pg, indx) \ + ((BINTERNAL *)((char *)(pg) + (pg)->linp[indx])) + +/* Get the number of bytes in the entry. */ +#define NBINTERNAL(len) \ + LALIGN(sizeof(u_int32_t) + sizeof(pgno_t) + sizeof(u_char) + (len)) + +/* Copy a BINTERNAL entry to the page. */ +#define WR_BINTERNAL(p, size, pgno, flags) { \ + *(u_int32_t *)p = size; \ + p += sizeof(u_int32_t); \ + *(pgno_t *)p = pgno; \ + p += sizeof(pgno_t); \ + *(u_char *)p = flags; \ + p += sizeof(u_char); \ +} + +/* + * For the recno internal pages, the item is a page number with the number of + * keys found on that page and below. + */ +typedef struct _rinternal { + recno_t nrecs; /* number of records */ + pgno_t pgno; /* page number stored below */ +} RINTERNAL; + +/* Get the page's RINTERNAL structure at index indx. */ +#define GETRINTERNAL(pg, indx) \ + ((RINTERNAL *)((char *)(pg) + (pg)->linp[indx])) + +/* Get the number of bytes in the entry. */ +#define NRINTERNAL \ + LALIGN(sizeof(recno_t) + sizeof(pgno_t)) + +/* Copy a RINTERAL entry to the page. */ +#define WR_RINTERNAL(p, nrecs, pgno) { \ + *(recno_t *)p = nrecs; \ + p += sizeof(recno_t); \ + *(pgno_t *)p = pgno; \ +} + +/* For the btree leaf pages, the item is a key and data pair. */ +typedef struct _bleaf { + u_int32_t ksize; /* size of key */ + u_int32_t dsize; /* size of data */ + u_char flags; /* P_BIGDATA, P_BIGKEY */ + char bytes[1]; /* data */ +} BLEAF; + +/* Get the page's BLEAF structure at index indx. */ +#define GETBLEAF(pg, indx) \ + ((BLEAF *)((char *)(pg) + (pg)->linp[indx])) + +/* Get the number of bytes in the entry. */ +#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize) + +/* Get the number of bytes in the user's key/data pair. */ +#define NBLEAFDBT(ksize, dsize) \ + LALIGN(sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_char) + \ + (ksize) + (dsize)) + +/* Copy a BLEAF entry to the page. */ +#define WR_BLEAF(p, key, data, flags) { \ + *(u_int32_t *)p = key->size; \ + p += sizeof(u_int32_t); \ + *(u_int32_t *)p = data->size; \ + p += sizeof(u_int32_t); \ + *(u_char *)p = flags; \ + p += sizeof(u_char); \ + memmove(p, key->data, key->size); \ + p += key->size; \ + memmove(p, data->data, data->size); \ +} + +/* For the recno leaf pages, the item is a data entry. */ +typedef struct _rleaf { + u_int32_t dsize; /* size of data */ + u_char flags; /* P_BIGDATA */ + char bytes[1]; +} RLEAF; + +/* Get the page's RLEAF structure at index indx. */ +#define GETRLEAF(pg, indx) \ + ((RLEAF *)((char *)(pg) + (pg)->linp[indx])) + +/* Get the number of bytes in the entry. */ +#define NRLEAF(p) NRLEAFDBT((p)->dsize) + +/* Get the number of bytes from the user's data. */ +#define NRLEAFDBT(dsize) \ + LALIGN(sizeof(u_int32_t) + sizeof(u_char) + (dsize)) + +/* Copy a RLEAF entry to the page. */ +#define WR_RLEAF(p, data, flags) { \ + *(u_int32_t *)p = data->size; \ + p += sizeof(u_int32_t); \ + *(u_char *)p = flags; \ + p += sizeof(u_char); \ + memmove(p, data->data, data->size); \ +} + +/* + * A record in the tree is either a pointer to a page and an index in the page + * or a page number and an index. These structures are used as a cursor, stack + * entry and search returns as well as to pass records to other routines. + * + * One comment about searches. Internal page searches must find the largest + * record less than key in the tree so that descents work. Leaf page searches + * must find the smallest record greater than key so that the returned index + * is the record's correct position for insertion. + */ +typedef struct _epgno { + pgno_t pgno; /* the page number */ + indx_t index; /* the index on the page */ +} EPGNO; + +typedef struct _epg { + PAGE *page; /* the (pinned) page */ + indx_t index; /* the index on the page */ +} EPG; + +/* + * About cursors. The cursor (and the page that contained the key/data pair + * that it referenced) can be deleted, which makes things a bit tricky. If + * there are no duplicates of the cursor key in the tree (i.e. B_NODUPS is set + * or there simply aren't any duplicates of the key) we copy the key that it + * referenced when it's deleted, and reacquire a new cursor key if the cursor + * is used again. If there are duplicates keys, we move to the next/previous + * key, and set a flag so that we know what happened. NOTE: if duplicate (to + * the cursor) keys are added to the tree during this process, it is undefined + * if they will be returned or not in a cursor scan. + * + * The flags determine the possible states of the cursor: + * + * CURS_INIT The cursor references *something*. + * CURS_ACQUIRE The cursor was deleted, and a key has been saved so that + * we can reacquire the right position in the tree. + * CURS_AFTER, CURS_BEFORE + * The cursor was deleted, and now references a key/data pair + * that has not yet been returned, either before or after the + * deleted key/data pair. + * XXX + * This structure is broken out so that we can eventually offer multiple + * cursors as part of the DB interface. + */ +typedef struct _cursor { + EPGNO pg; /* B: Saved tree reference. */ + DBT key; /* B: Saved key, or key.data == NULL. */ + recno_t rcursor; /* R: recno cursor (1-based) */ + +#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */ +#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */ +#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */ +#define CURS_INIT 0x08 /* RB: Cursor initialized. */ + u_int8_t flags; +} CURSOR; + +/* + * The metadata of the tree. The nrecs field is used only by the RECNO code. + * This is because the btree doesn't really need it and it requires that every + * put or delete call modify the metadata. + */ +typedef struct _btmeta { + u_int32_t magic; /* magic number */ + u_int32_t version; /* version */ + u_int32_t psize; /* page size */ + u_int32_t free; /* page number of first free page */ + u_int32_t nrecs; /* R: number of records */ + +#define SAVEMETA (B_NODUPS | R_RECNO) + u_int32_t flags; /* bt_flags & SAVEMETA */ +} BTMETA; + +/* The in-memory btree/recno data structure. */ +typedef struct _btree { + MPOOL *bt_mp; /* memory pool cookie */ + + DB *bt_dbp; /* pointer to enclosing DB */ + + EPG bt_cur; /* current (pinned) page */ + PAGE *bt_pinned; /* page pinned across calls */ + + CURSOR bt_cursor; /* cursor */ + +#define BT_PUSH(t, p, 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) +#define BT_CLR(t) (t->bt_sp = t->bt_stack) + EPGNO bt_stack[50]; /* stack of parent pages */ + EPGNO *bt_sp; /* current stack pointer */ + + DBT bt_rkey; /* returned key */ + DBT bt_rdata; /* returned data */ + + int bt_fd; /* tree file descriptor */ + + pgno_t bt_free; /* next free page */ + u_int32_t bt_psize; /* page size */ + indx_t bt_ovflsize; /* cut-off for key/data overflow */ + int bt_lorder; /* byte order */ + /* sorted order */ + enum { NOT, BACK, FORWARD } bt_order; + EPGNO bt_last; /* last insert */ + + /* B: key comparison function */ + int (*bt_cmp)(const DBT *, const DBT *); + /* B: prefix comparison function */ + size_t (*bt_pfx)(const DBT *, const DBT *); + /* R: recno input function */ + int (*bt_irec)(struct _btree *, recno_t); + + FILE *bt_rfp; /* R: record FILE pointer */ + int bt_rfd; /* R: record file descriptor */ + + caddr_t bt_cmap; /* R: current point in mapped space */ + caddr_t bt_smap; /* R: start of mapped space */ + caddr_t bt_emap; /* R: end of mapped space */ + size_t bt_msize; /* R: size of mapped region. */ + + recno_t bt_nrecs; /* R: number of records */ + size_t bt_reclen; /* R: fixed record length */ + u_char bt_bval; /* R: delimiting byte/pad character */ + +/* + * NB: + * B_NODUPS and R_RECNO are stored on disk, and may not be changed. + */ +#define B_INMEM 0x00001 /* in-memory tree */ +#define B_METADIRTY 0x00002 /* need to write metadata */ +#define B_MODIFIED 0x00004 /* tree modified */ +#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */ +#define B_RDONLY 0x00010 /* read-only tree */ + +#define B_NODUPS 0x00020 /* no duplicate keys permitted */ +#define R_RECNO 0x00080 /* record oriented tree */ + +#define R_CLOSEFP 0x00040 /* opened a file pointer */ +#define R_EOF 0x00100 /* end of input file reached. */ +#define R_FIXLEN 0x00200 /* fixed length records */ +#define R_MEMMAPPED 0x00400 /* memory mapped file. */ +#define R_INMEM 0x00800 /* in-memory file */ +#define R_MODIFIED 0x01000 /* modified file */ +#define R_RDONLY 0x02000 /* read-only file */ + +#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */ +#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */ +#define B_DB_TXN 0x10000 /* DB_TXN specified. */ + u_int32_t flags; +} BTREE; + +#include "bt_extern.h" diff --git a/db/db/db-fbsd.c b/db/db/db-fbsd.c new file mode 100644 index 0000000..9c65e55 --- /dev/null +++ b/db/db/db-fbsd.c @@ -0,0 +1,101 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/db/db/db.c,v 1.2 2002/03/22 21:52:01 obrien Exp $"); + +#include + +#include +#include +#include +#include + +#include + +DB * +dbopen(fname, flags, mode, type, openinfo) + const char *fname; + int flags, mode; + DBTYPE type; + const void *openinfo; +{ + +#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN) +#define USE_OPEN_FLAGS \ + (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \ + O_RDWR | O_SHLOCK | O_TRUNC) + + if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0) + switch (type) { + case DB_BTREE: + return (__bt_open(fname, flags & USE_OPEN_FLAGS, + mode, openinfo, flags & DB_FLAGS)); + case DB_HASH: + return (__hash_open(fname, flags & USE_OPEN_FLAGS, + mode, openinfo, flags & DB_FLAGS)); + case DB_RECNO: + return (__rec_open(fname, flags & USE_OPEN_FLAGS, + mode, openinfo, flags & DB_FLAGS)); + } + errno = EINVAL; + return (NULL); +} + +static int +__dberr() +{ + return (RET_ERROR); +} + +/* + * __DBPANIC -- Stop. + * + * Parameters: + * dbp: pointer to the DB structure. + */ +void +__dbpanic(dbp) + DB *dbp; +{ + /* The only thing that can succeed is a close. */ + dbp->del = (int (*)())__dberr; + dbp->fd = (int (*)())__dberr; + dbp->get = (int (*)())__dberr; + dbp->put = (int (*)())__dberr; + dbp->seq = (int (*)())__dberr; + dbp->sync = (int (*)())__dberr; +} diff --git a/db/hash/FreeBSD/hash.c.patch b/db/hash/FreeBSD/hash.c.patch index ba66eed..ad04e83 100644 --- a/db/hash/FreeBSD/hash.c.patch +++ b/db/hash/FreeBSD/hash.c.patch @@ -1,6 +1,11 @@ ---- /Volumes/XDisk/tmp/Libc/db/hash/FreeBSD/hash.c.orig 2004-09-09 22:41:41.000000000 -0700 -+++ /Volumes/XDisk/tmp/Libc/db/hash/FreeBSD/hash.c 2004-10-24 17:08:27.000000000 -0700 -@@ -58,7 +58,7 @@ +Index: hash.c +=================================================================== +RCS file: /cvs/root/Libc/db/hash/FreeBSD/hash.c,v +retrieving revision 1.3 +diff -u -d -b -w -p -u -r1.3 hash.c +--- hash.c 2004/11/25 19:37:57 1.3 ++++ hash.c 2004/12/10 20:34:43 +@@ -58,7 +58,7 @@ __FBSDID("$FreeBSD: src/lib/libc/db/hash #include #include "hash.h" #include "page.h" @@ -9,3 +14,13 @@ static int alloc_segs(HTAB *, int); static int flush_meta(HTAB *); +@@ -108,8 +108,7 @@ __hash_open(file, flags, mode, info, dfl + int bpages, hdrsize, new_table, nsegs, save_errno; + + if ((flags & O_ACCMODE) == O_WRONLY) { +- errno = EINVAL; +- return (NULL); ++ flags += O_RDWR - O_WRONLY; /* POSIX */ + } + + if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB)))) diff --git a/db/hash/FreeBSD/ndbm.c.patch b/db/hash/FreeBSD/ndbm.c.patch index 5e150ff..42d88ef 100644 --- a/db/hash/FreeBSD/ndbm.c.patch +++ b/db/hash/FreeBSD/ndbm.c.patch @@ -1,14 +1,16 @@ ---- ndbm.c.orig 2004-10-28 23:25:13.000000000 -0700 -+++ ndbm.c 2004-10-28 23:25:42.000000000 -0700 -@@ -51,6 +51,7 @@ +--- 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 @@ #include #include +#include ++#define _DBM ++typedef DB DBM; #include #include "hash.h" -@@ -62,7 +63,8 @@ +@@ -62,7 +65,8 @@ extern DBM * dbm_open(file, flags, mode) const char *file; @@ -18,7 +20,7 @@ { HASHINFO info; char path[MAXPATHLEN]; -@@ -128,10 +130,14 @@ +@@ -128,10 +132,14 @@ int status; datum retkey; DBT dbtretkey, dbtretdata; @@ -34,7 +36,7 @@ retkey.dptr = dbtretkey.data; retkey.dsize = dbtretkey.size; return (retkey); -@@ -146,13 +152,20 @@ +@@ -146,13 +154,20 @@ dbm_nextkey(db) DBM *db; { diff --git a/db/hash/Makefile.inc b/db/hash/Makefile.inc index 5276509..136ae02 100644 --- a/db/hash/Makefile.inc +++ b/db/hash/Makefile.inc @@ -9,9 +9,14 @@ FBSDMISRCS= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c \ .for _src in ${FBSDMISRCS} CFLAGS-${_src:R}-fbsd.${_src:E} += -D__DBINTERFACE_PRIVATE .endfor +.for _src in hash.c hash_bigkey.c hash_buf.c hash_page.c +CFLAGS-${_src:R}-fbsd.${_src:E} += -UDEBUG +.endfor FBSDHDRS= hash.h page.h .include "Makefile.fbsd_end" # need to rename extern.h to make it unique -${SYMROOT}/hash_extern.h: ${.CURDIR}/db/hash/FreeBSD/extern.h _AUTOPATCHSYM -AUTOPATCHHDRS+= ${SYMROOT}/hash_extern.h +.ifmake autopatch +hash_extern.h: FreeBSD/extern.h _AUTOPATCHCUR +AUTOPATCHHDRS+= hash_extern.h +.endif # autopatch diff --git a/db/hash/hash-fbsd.c b/db/hash/hash-fbsd.c new file mode 100644 index 0000000..8f492dc --- /dev/null +++ b/db/hash/hash-fbsd.c @@ -0,0 +1,1005 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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.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 $"); + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif +#include "un-namespace.h" + +#include +#include "hash.h" +#include "page.h" +#include "hash_extern.h" + +static int alloc_segs(HTAB *, int); +static int flush_meta(HTAB *); +static int hash_access(HTAB *, ACTION, DBT *, DBT *); +static int hash_close(DB *); +static int hash_delete(const DB *, const DBT *, u_int32_t); +static int hash_fd(const DB *); +static int hash_get(const DB *, const DBT *, DBT *, u_int32_t); +static int hash_put(const DB *, DBT *, const DBT *, u_int32_t); +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 int init_htab(HTAB *, int); +#if BYTE_ORDER == LITTLE_ENDIAN +static void swap_header(HTAB *); +static void swap_header_copy(HASHHDR *, HASHHDR *); +#endif + +/* Fast arithmetic, relying on powers of 2, */ +#define MOD(x, y) ((x) & ((y) - 1)) + +#define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; } + +/* Return values */ +#define SUCCESS (0) +#define ERROR (-1) +#define ABNORMAL (1) + +#ifdef HASH_STATISTICS +int hash_accesses, hash_collisions, hash_expansions, hash_overflows; +#endif + +/************************** 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 */ +{ + HTAB *hashp; + struct stat statbuf; + DB *dbp; + int bpages, hdrsize, new_table, nsegs, save_errno; + + if ((flags & O_ACCMODE) == O_WRONLY) { + flags += O_RDWR - O_WRONLY; /* POSIX */ + } + + if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB)))) + return (NULL); + hashp->fp = -1; + + /* + * Even if user wants write only, we need to be able to read + * the actual file, so we need to open it read/write. But, the + * field in the hashp structure needs to be accurate so that + * we can check accesses. + */ + 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); + } + if (new_table) { + if (!(hashp = init_hash(hashp, file, (HASHINFO *)info))) + RETURN_ERROR(errno, error1); + } else { + /* Table already exists */ + if (info && info->hash) + hashp->hash = info->hash; + else + hashp->hash = __default_hash; + + hdrsize = _read(hashp->fp, &hashp->hdr, sizeof(HASHHDR)); +#if BYTE_ORDER == LITTLE_ENDIAN + swap_header(hashp); +#endif + if (hdrsize == -1) + RETURN_ERROR(errno, error1); + if (hdrsize != sizeof(HASHHDR)) + RETURN_ERROR(EFTYPE, error1); + /* Verify file type, versions and hash function */ + if (hashp->MAGIC != HASHMAGIC) + RETURN_ERROR(EFTYPE, error1); +#define OLDHASHVERSION 1 + if (hashp->VERSION != HASHVERSION && + hashp->VERSION != OLDHASHVERSION) + RETURN_ERROR(EFTYPE, error1); + if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY) + RETURN_ERROR(EFTYPE, error1); + /* + * Figure out how many segments we need. Max_Bucket is the + * maximum bucket number, so the number of buckets is + * max_bucket + 1. + */ + 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 + * and errno will have been set. + */ + return (NULL); + /* Read in bitmaps */ + bpages = (hashp->SPARES[hashp->OVFL_POINT] + + (hashp->BSIZE << BYTE_SHIFT) - 1) >> + (hashp->BSHIFT + BYTE_SHIFT); + + hashp->nmaps = bpages; + (void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_int32_t *)); + } + + /* Initialize Buffer Manager */ + if (info && info->cachesize) + __buf_init(hashp, info->cachesize); + else + __buf_init(hashp, DEF_BUFSIZE); + + hashp->new_file = new_table; + hashp->save_file = file && (hashp->flags & O_RDWR); + hashp->cbucket = -1; + if (!(dbp = (DB *)malloc(sizeof(DB)))) { + save_errno = errno; + hdestroy(hashp); + errno = save_errno; + return (NULL); + } + dbp->internal = hashp; + dbp->close = hash_close; + dbp->del = hash_delete; + dbp->fd = hash_fd; + dbp->get = hash_get; + dbp->put = hash_put; + dbp->seq = hash_seq; + dbp->sync = hash_sync; + dbp->type = DB_HASH; + +#ifdef DEBUG + (void)fprintf(stderr, +"%s\n%s%p\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n", + "init_htab:", + "TABLE POINTER ", hashp, + "BUCKET SIZE ", hashp->BSIZE, + "BUCKET SHIFT ", hashp->BSHIFT, + "DIRECTORY SIZE ", hashp->DSIZE, + "SEGMENT SIZE ", hashp->SGSIZE, + "SEGMENT SHIFT ", hashp->SSHIFT, + "FILL FACTOR ", hashp->FFACTOR, + "MAX BUCKET ", hashp->MAX_BUCKET, + "OVFL POINT ", hashp->OVFL_POINT, + "LAST FREED ", hashp->LAST_FREED, + "HIGH MASK ", hashp->HIGH_MASK, + "LOW MASK ", hashp->LOW_MASK, + "NSEGS ", hashp->nsegs, + "NKEYS ", hashp->NKEYS); +#endif +#ifdef HASH_STATISTICS + hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0; +#endif + return (dbp); + +error1: + if (hashp != NULL) + (void)_close(hashp->fp); + +error0: + free(hashp); + errno = save_errno; + return (NULL); +} + +static int +hash_close(dbp) + DB *dbp; +{ + HTAB *hashp; + int retval; + + if (!dbp) + return (ERROR); + + hashp = (HTAB *)dbp->internal; + retval = hdestroy(hashp); + free(dbp); + return (retval); +} + +static int +hash_fd(dbp) + const DB *dbp; +{ + HTAB *hashp; + + if (!dbp) + return (ERROR); + + hashp = (HTAB *)dbp->internal; + if (hashp->fp == -1) { + errno = ENOENT; + return (-1); + } + return (hashp->fp); +} + +/************************** LOCAL CREATION ROUTINES **********************/ +static HTAB * +init_hash(hashp, file, info) + HTAB *hashp; + const char *file; + HASHINFO *info; +{ + struct stat statbuf; + int nelem; + + nelem = 1; + hashp->NKEYS = 0; + hashp->LORDER = BYTE_ORDER; + hashp->BSIZE = DEF_BUCKET_SIZE; + hashp->BSHIFT = DEF_BUCKET_SHIFT; + hashp->SGSIZE = DEF_SEGSIZE; + hashp->SSHIFT = DEF_SEGSIZE_SHIFT; + hashp->DSIZE = DEF_DIRSIZE; + hashp->FFACTOR = DEF_FFACTOR; + hashp->hash = __default_hash; + memset(hashp->SPARES, 0, sizeof(hashp->SPARES)); + memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS)); + + /* Fix bucket size to be optimal for file system */ + if (file != NULL) { + if (stat(file, &statbuf)) + return (NULL); + hashp->BSIZE = statbuf.st_blksize; + hashp->BSHIFT = __log2(hashp->BSIZE); + } + + if (info) { + if (info->bsize) { + /* Round pagesize up to power of 2 */ + hashp->BSHIFT = __log2(info->bsize); + hashp->BSIZE = 1 << hashp->BSHIFT; + if (hashp->BSIZE > MAX_BSIZE) { + errno = EINVAL; + return (NULL); + } + } + if (info->ffactor) + hashp->FFACTOR = info->ffactor; + if (info->hash) + hashp->hash = info->hash; + if (info->nelem) + nelem = info->nelem; + if (info->lorder) { + if (info->lorder != BIG_ENDIAN && + info->lorder != LITTLE_ENDIAN) { + errno = EINVAL; + return (NULL); + } + hashp->LORDER = info->lorder; + } + } + /* init_htab should destroy the table and set errno if it fails */ + if (init_htab(hashp, nelem)) + return (NULL); + else + return (hashp); +} +/* + * This calls alloc_segs which may run out of memory. Alloc_segs will destroy + * the table and set errno, so we just pass the error information along. + * + * Returns 0 on No Error + */ +static int +init_htab(hashp, nelem) + HTAB *hashp; + int nelem; +{ + int nbuckets, nsegs; + int l2; + + /* + * Divide number of elements by the fill factor and determine a + * desired number of buckets. Allocate space for the next greater + * power of two number of buckets. + */ + nelem = (nelem - 1) / hashp->FFACTOR + 1; + + l2 = __log2(MAX(nelem, 2)); + nbuckets = 1 << l2; + + hashp->SPARES[l2] = l2 + 1; + hashp->SPARES[l2 + 1] = l2 + 1; + hashp->OVFL_POINT = l2; + hashp->LAST_FREED = 2; + + /* First bitmap page is at: splitpoint l2 page offset 1 */ + if (__ibitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0)) + return (-1); + + hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1; + hashp->HIGH_MASK = (nbuckets << 1) - 1; + hashp->HDRPAGES = ((MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >> + hashp->BSHIFT) + 1; + + nsegs = (nbuckets - 1) / hashp->SGSIZE + 1; + nsegs = 1 << __log2(nsegs); + + if (nsegs > hashp->DSIZE) + hashp->DSIZE = nsegs; + return (alloc_segs(hashp, nsegs)); +} + +/********************** DESTROY/CLOSE ROUTINES ************************/ + +/* + * Flushes any changes to the file if necessary and destroys the hashp + * structure, freeing all allocated space. + */ +static int +hdestroy(hashp) + HTAB *hashp; +{ + int i, save_errno; + + save_errno = 0; + +#ifdef HASH_STATISTICS + (void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n", + hash_accesses, hash_collisions); + (void)fprintf(stderr, "hdestroy: expansions %ld\n", + hash_expansions); + (void)fprintf(stderr, "hdestroy: overflows %ld\n", + hash_overflows); + (void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n", + hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs); + + for (i = 0; i < NCACHED; i++) + (void)fprintf(stderr, + "spares[%d] = %d\n", i, hashp->SPARES[i]); +#endif + /* + * Call on buffer manager to free buffers, and if required, + * write them to disk. + */ + if (__buf_free(hashp, 1, hashp->save_file)) + save_errno = errno; + if (hashp->dir) { + free(*hashp->dir); /* Free initial segments */ + /* Free extra segments */ + while (hashp->exsegs--) + free(hashp->dir[--hashp->nsegs]); + free(hashp->dir); + } + if (flush_meta(hashp) && !save_errno) + save_errno = errno; + /* Free Bigmaps */ + for (i = 0; i < hashp->nmaps; i++) + if (hashp->mapp[i]) + free(hashp->mapp[i]); + + if (hashp->fp != -1) + (void)_close(hashp->fp); + + free(hashp); + + if (save_errno) { + errno = save_errno; + return (ERROR); + } + return (SUCCESS); +} +/* + * Write modified pages to disk + * + * Returns: + * 0 == OK + * -1 ERROR + */ +static int +hash_sync(dbp, flags) + const DB *dbp; + u_int32_t flags; +{ + HTAB *hashp; + + if (flags != 0) { + errno = EINVAL; + return (ERROR); + } + + if (!dbp) + return (ERROR); + + hashp = (HTAB *)dbp->internal; + if (!hashp->save_file) + return (0); + if (__buf_free(hashp, 0, 1) || flush_meta(hashp)) + return (ERROR); + hashp->new_file = 0; + return (0); +} + +/* + * Returns: + * 0 == OK + * -1 indicates that errno should be set + */ +static int +flush_meta(hashp) + HTAB *hashp; +{ + HASHHDR *whdrp; +#if BYTE_ORDER == LITTLE_ENDIAN + HASHHDR whdr; +#endif + int fp, i, wsize; + + if (!hashp->save_file) + return (0); + hashp->MAGIC = HASHMAGIC; + hashp->VERSION = HASHVERSION; + hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY)); + + fp = hashp->fp; + whdrp = &hashp->hdr; +#if BYTE_ORDER == LITTLE_ENDIAN + 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)) + return (-1); + else + if (wsize != sizeof(HASHHDR)) { + errno = EFTYPE; + hashp->error = errno; + return (-1); + } + for (i = 0; i < NCACHED; i++) + if (hashp->mapp[i]) + if (__put_page(hashp, (char *)hashp->mapp[i], + hashp->BITMAPS[i], 0, 1)) + return (-1); + return (0); +} + +/*******************************SEARCH ROUTINES *****************************/ +/* + * All the access routines return + * + * Returns: + * 0 on SUCCESS + * 1 to indicate an external ERROR (i.e. key not found, etc) + * -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; +{ + HTAB *hashp; + + hashp = (HTAB *)dbp->internal; + if (flag) { + hashp->error = errno = EINVAL; + return (ERROR); + } + return (hash_access(hashp, HASH_GET, (DBT *)key, data)); +} + +static int +hash_put(dbp, key, data, flag) + 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; + return (ERROR); + } + if ((hashp->flags & O_ACCMODE) == O_RDONLY) { + hashp->error = errno = EPERM; + return (ERROR); + } + return (hash_access(hashp, flag == R_NOOVERWRITE ? + HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data)); +} + +static int +hash_delete(dbp, key, flag) + const DB *dbp; + const DBT *key; + u_int32_t flag; /* Ignored */ +{ + HTAB *hashp; + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_CURSOR) { + hashp->error = errno = EINVAL; + return (ERROR); + } + if ((hashp->flags & O_ACCMODE) == O_RDONLY) { + hashp->error = errno = EPERM; + return (ERROR); + } + return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL)); +} + +/* + * Assume that hashp has been set in wrapper routine. + */ +static int +hash_access(hashp, action, key, val) + HTAB *hashp; + ACTION action; + DBT *key, *val; +{ + BUFHEAD *rbufp; + BUFHEAD *bufp, *save_bufp; + u_int16_t *bp; + int n, ndx, off, size; + char *kp; + u_int16_t pageno; + +#ifdef HASH_STATISTICS + hash_accesses++; +#endif + + off = hashp->BSIZE; + size = key->size; + kp = (char *)key->data; + rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0); + if (!rbufp) + return (ERROR); + save_bufp = rbufp; + + /* Pin the bucket chain */ + rbufp->flags |= BUF_PIN; + for (bp = (u_int16_t *)rbufp->page, n = *bp++, ndx = 1; ndx < n;) + if (bp[1] >= REAL_KEY) { + /* Real key/data pair */ + if (size == off - *bp && + memcmp(kp, rbufp->page + *bp, size) == 0) + goto found; + off = bp[1]; +#ifdef HASH_STATISTICS + hash_collisions++; +#endif + bp += 2; + ndx += 2; + } else if (bp[1] == OVFLPAGE) { + rbufp = __get_buf(hashp, *bp, rbufp, 0); + if (!rbufp) { + save_bufp->flags &= ~BUF_PIN; + return (ERROR); + } + /* FOR LOOP INIT */ + bp = (u_int16_t *)rbufp->page; + n = *bp++; + ndx = 1; + off = hashp->BSIZE; + } else if (bp[1] < REAL_KEY) { + if ((ndx = + __find_bigpair(hashp, rbufp, ndx, kp, size)) > 0) + goto found; + if (ndx == -2) { + bufp = rbufp; + if (!(pageno = + __find_last_page(hashp, &bufp))) { + ndx = 0; + rbufp = bufp; + break; /* FOR */ + } + rbufp = __get_buf(hashp, pageno, bufp, 0); + if (!rbufp) { + save_bufp->flags &= ~BUF_PIN; + return (ERROR); + } + /* FOR LOOP INIT */ + bp = (u_int16_t *)rbufp->page; + n = *bp++; + ndx = 1; + off = hashp->BSIZE; + } else { + save_bufp->flags &= ~BUF_PIN; + return (ERROR); + } + } + + /* Not found */ + switch (action) { + case HASH_PUT: + case HASH_PUTNEW: + if (__addel(hashp, rbufp, key, val)) { + save_bufp->flags &= ~BUF_PIN; + return (ERROR); + } else { + save_bufp->flags &= ~BUF_PIN; + return (SUCCESS); + } + case HASH_GET: + case HASH_DELETE: + default: + save_bufp->flags &= ~BUF_PIN; + return (ABNORMAL); + } + +found: + switch (action) { + case HASH_PUTNEW: + save_bufp->flags &= ~BUF_PIN; + return (ABNORMAL); + case HASH_GET: + bp = (u_int16_t *)rbufp->page; + if (bp[ndx + 1] < REAL_KEY) { + if (__big_return(hashp, rbufp, ndx, val, 0)) + return (ERROR); + } else { + val->data = (u_char *)rbufp->page + (int)bp[ndx + 1]; + val->size = bp[ndx] - bp[ndx + 1]; + } + break; + case HASH_PUT: + if ((__delpair(hashp, rbufp, ndx)) || + (__addel(hashp, rbufp, key, val))) { + save_bufp->flags &= ~BUF_PIN; + return (ERROR); + } + break; + case HASH_DELETE: + if (__delpair(hashp, rbufp, ndx)) + return (ERROR); + break; + default: + abort(); + } + save_bufp->flags &= ~BUF_PIN; + return (SUCCESS); +} + +static int +hash_seq(dbp, key, data, flag) + const DB *dbp; + DBT *key, *data; + u_int32_t flag; +{ + u_int32_t bucket; + BUFHEAD *bufp; + HTAB *hashp; + u_int16_t *bp, ndx; + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_FIRST && flag != R_NEXT) { + hashp->error = errno = EINVAL; + return (ERROR); + } +#ifdef HASH_STATISTICS + hash_accesses++; +#endif + if ((hashp->cbucket < 0) || (flag == R_FIRST)) { + hashp->cbucket = 0; + hashp->cndx = 1; + hashp->cpage = NULL; + } + + for (bp = NULL; !bp || !bp[0]; ) { + if (!(bufp = hashp->cpage)) { + for (bucket = hashp->cbucket; + bucket <= hashp->MAX_BUCKET; + bucket++, hashp->cndx = 1) { + bufp = __get_buf(hashp, bucket, NULL, 0); + if (!bufp) + return (ERROR); + hashp->cpage = bufp; + bp = (u_int16_t *)bufp->page; + if (bp[0]) + break; + } + hashp->cbucket = bucket; + if (hashp->cbucket > hashp->MAX_BUCKET) { + hashp->cbucket = -1; + return (ABNORMAL); + } + } else + bp = (u_int16_t *)hashp->cpage->page; + +#ifdef DEBUG + assert(bp); + assert(bufp); +#endif + while (bp[hashp->cndx + 1] == OVFLPAGE) { + bufp = hashp->cpage = + __get_buf(hashp, bp[hashp->cndx], bufp, 0); + if (!bufp) + return (ERROR); + bp = (u_int16_t *)(bufp->page); + hashp->cndx = 1; + } + if (!bp[0]) { + hashp->cpage = NULL; + ++hashp->cbucket; + } + } + ndx = hashp->cndx; + if (bp[ndx + 1] < REAL_KEY) { + if (__big_keydata(hashp, bufp, key, data, 1)) + return (ERROR); + } else { + 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); +} + +/********************************* UTILITIES ************************/ + +/* + * Returns: + * 0 ==> OK + * -1 ==> Error + */ +extern int +__expand_table(hashp) + HTAB *hashp; +{ + u_int32_t old_bucket, new_bucket; + int dirsize, new_segnum, spare_ndx; + +#ifdef HASH_STATISTICS + hash_expansions++; +#endif + new_bucket = ++hashp->MAX_BUCKET; + old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK); + + new_segnum = new_bucket >> hashp->SSHIFT; + + /* Check if we need a new segment */ + if (new_segnum >= hashp->nsegs) { + /* Check if we need to expand directory */ + if (new_segnum >= hashp->DSIZE) { + /* Reallocate directory */ + dirsize = hashp->DSIZE * sizeof(SEGMENT *); + if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1)) + return (-1); + hashp->DSIZE = dirsize << 1; + } + if ((hashp->dir[new_segnum] = + (SEGMENT)calloc(hashp->SGSIZE, sizeof(SEGMENT))) == NULL) + return (-1); + hashp->exsegs++; + hashp->nsegs++; + } + /* + * If the split point is increasing (MAX_BUCKET's log base 2 + * * increases), we need to copy the current contents of the spare + * split bucket to the next bucket. + */ + spare_ndx = __log2(hashp->MAX_BUCKET + 1); + if (spare_ndx > hashp->OVFL_POINT) { + hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT]; + hashp->OVFL_POINT = spare_ndx; + } + + if (new_bucket > hashp->HIGH_MASK) { + /* Starting a new doubling */ + hashp->LOW_MASK = hashp->HIGH_MASK; + hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK; + } + /* Relocate records to the new bucket */ + return (__split_page(hashp, old_bucket, new_bucket)); +} + +/* + * If realloc guarantees that the pointer is not destroyed if the realloc + * fails, then this routine can go away. + */ +static void * +hash_realloc(p_ptr, oldsize, newsize) + SEGMENT **p_ptr; + int oldsize, newsize; +{ + void *p; + + if ( (p = malloc(newsize)) ) { + memmove(p, *p_ptr, oldsize); + memset((char *)p + oldsize, 0, newsize - oldsize); + free(*p_ptr); + *p_ptr = p; + } + return (p); +} + +extern u_int32_t +__call_hash(hashp, k, len) + HTAB *hashp; + char *k; + int len; +{ + int n, bucket; + + n = hashp->hash(k, len); + bucket = n & hashp->HIGH_MASK; + if (bucket > hashp->MAX_BUCKET) + bucket = bucket & hashp->LOW_MASK; + return (bucket); +} + +/* + * Allocate segment table. On error, destroy the table and set errno. + * + * Returns 0 on success + */ +static int +alloc_segs(hashp, nsegs) + HTAB *hashp; + int nsegs; +{ + int i; + SEGMENT store; + + int save_errno; + + if ((hashp->dir = + (SEGMENT *)calloc(hashp->DSIZE, sizeof(SEGMENT *))) == NULL) { + save_errno = errno; + (void)hdestroy(hashp); + errno = save_errno; + return (-1); + } + /* Allocate segments */ + 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++) + hashp->dir[i] = &store[i << hashp->SSHIFT]; + return (0); +} + +#if BYTE_ORDER == LITTLE_ENDIAN +/* + * Hashp->hdr needs to be byteswapped. + */ +static void +swap_header_copy(srcp, destp) + HASHHDR *srcp, *destp; +{ + int i; + + P_32_COPY(srcp->magic, destp->magic); + P_32_COPY(srcp->version, destp->version); + P_32_COPY(srcp->lorder, destp->lorder); + P_32_COPY(srcp->bsize, destp->bsize); + P_32_COPY(srcp->bshift, destp->bshift); + P_32_COPY(srcp->dsize, destp->dsize); + P_32_COPY(srcp->ssize, destp->ssize); + P_32_COPY(srcp->sshift, destp->sshift); + P_32_COPY(srcp->ovfl_point, destp->ovfl_point); + P_32_COPY(srcp->last_freed, destp->last_freed); + P_32_COPY(srcp->max_bucket, destp->max_bucket); + P_32_COPY(srcp->high_mask, destp->high_mask); + P_32_COPY(srcp->low_mask, destp->low_mask); + P_32_COPY(srcp->ffactor, destp->ffactor); + P_32_COPY(srcp->nkeys, destp->nkeys); + P_32_COPY(srcp->hdrpages, destp->hdrpages); + P_32_COPY(srcp->h_charkey, destp->h_charkey); + for (i = 0; i < NCACHED; i++) { + P_32_COPY(srcp->spares[i], destp->spares[i]); + P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]); + } +} + +static void +swap_header(hashp) + HTAB *hashp; +{ + HASHHDR *hdrp; + int i; + + hdrp = &hashp->hdr; + + M_32_SWAP(hdrp->magic); + M_32_SWAP(hdrp->version); + M_32_SWAP(hdrp->lorder); + M_32_SWAP(hdrp->bsize); + M_32_SWAP(hdrp->bshift); + M_32_SWAP(hdrp->dsize); + M_32_SWAP(hdrp->ssize); + M_32_SWAP(hdrp->sshift); + M_32_SWAP(hdrp->ovfl_point); + M_32_SWAP(hdrp->last_freed); + M_32_SWAP(hdrp->max_bucket); + M_32_SWAP(hdrp->high_mask); + M_32_SWAP(hdrp->low_mask); + M_32_SWAP(hdrp->ffactor); + M_32_SWAP(hdrp->nkeys); + M_32_SWAP(hdrp->hdrpages); + M_32_SWAP(hdrp->h_charkey); + for (i = 0; i < NCACHED; i++) { + M_32_SWAP(hdrp->spares[i]); + M_16_SWAP(hdrp->bitmaps[i]); + } +} +#endif diff --git a/db/hash/hash.h b/db/hash/hash.h new file mode 100644 index 0000000..737b0f8 --- /dev/null +++ b/db/hash/hash.h @@ -0,0 +1,296 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + * + * @(#)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 $ + */ + +/* Operations */ +typedef enum { + HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT +} ACTION; + +/* Buffer Management structures */ +typedef struct _bufhead BUFHEAD; + +struct _bufhead { + BUFHEAD *prev; /* LRU links */ + BUFHEAD *next; /* LRU links */ + BUFHEAD *ovfl; /* Overflow page buffer header */ + u_int32_t addr; /* Address of this page */ + char *page; /* Actual page data */ + char flags; +#define BUF_MOD 0x0001 +#define BUF_DISK 0x0002 +#define BUF_BUCKET 0x0004 +#define BUF_PIN 0x0008 +}; + +#define IS_BUCKET(X) ((X) & BUF_BUCKET) + +typedef BUFHEAD **SEGMENT; + +/* Hash Table Information */ +typedef struct hashhdr { /* Disk resident portion */ + int magic; /* Magic NO for hash tables */ + int 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 + * 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 + * 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) */ +#define NCACHED 32 /* number of bit maps and spare + * points */ + int spares[NCACHED];/* spare pages for overflow */ + u_int16_t bitmaps[NCACHED]; /* address of overflow page + * bitmaps */ +} HASHHDR; + +typedef struct htab { /* Memory resident data structure */ + HASHHDR hdr; /* Header */ + int nsegs; /* Number of allocated segments */ + int exsegs; /* Number of extra allocated + * segments */ + u_int32_t /* Hash function */ + (*hash)(const void *, size_t); + int flags; /* Flag values */ + int fp; /* File pointer */ + char *tmp_buf; /* Temporary Buffer for BIG data */ + char *tmp_key; /* Temporary Buffer for BIG keys */ + BUFHEAD *cpage; /* Current page */ + int cbucket; /* Current bucket */ + int cndx; /* Index of next item on cpage */ + int error; /* Error Number -- for DBM + * compatibility */ + int new_file; /* Indicates if fd is backing store + * or no */ + int save_file; /* Indicates whether we need to flush + * file at + * exit */ + u_int32_t *mapp[NCACHED]; /* Pointers to page maps */ + int nmaps; /* Initial number of bitmaps */ + int nbufs; /* Number of buffers left to + * allocate */ + BUFHEAD bufhead; /* Header of buffer lru list */ + SEGMENT *dir; /* Hash Bucket directory */ + /* other flags */ + int nextkey_eof :1; /* dbm_nextkey() reached EOF */ +} HTAB; + +/* + * Constants + */ +#define MAX_BSIZE 65536 /* 2^16 */ +#define MIN_BUFFERS 6 +#define MINHDRSIZE 512 +#define DEF_BUFSIZE 65536 /* 64 K */ +#define DEF_BUCKET_SIZE 4096 +#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */ +#define DEF_SEGSIZE 256 +#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */ +#define DEF_DIRSIZE 256 +#define DEF_FFACTOR 65536 +#define MIN_FFACTOR 4 +#define SPLTMAX 8 +#define CHARKEY "%$sniglet^&" +#define NUMKEY 1038583 +#define BYTE_SHIFT 3 +#define INT_TO_BYTE 2 +#define INT_BYTE_SHIFT 5 +#define ALL_SET ((u_int32_t)0xFFFFFFFF) +#define ALL_CLEAR 0 + +#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3)) +#define ISMOD(X) ((u_int32_t)(ptrdiff_t)(X)&0x1) +#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x1)) +#define ISDISK(X) ((u_int32_t)(ptrdiff_t)(X)&0x2) +#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0x2)) + +#define BITS_PER_MAP 32 + +/* Given the address of the beginning of a big map, clear/set the nth bit */ +#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP))) +#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP))) +#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP))) + +/* Overflow management */ +/* + * Overflow page numbers are allocated per split point. At each doubling of + * the table, we can allocate extra pages. So, an overflow page number has + * the top 5 bits indicate which split point and the lower 11 bits indicate + * which page at that split point is indicated (pages within split points are + * numberered starting with 1). + */ + +#define SPLITSHIFT 11 +#define SPLITMASK 0x7FF +#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIFT) +#define OPAGENUM(N) ((N) & SPLITMASK) +#define OADDR_OF(S,O) ((u_int32_t)((u_int32_t)(S) << SPLITSHIFT) + (O)) + +#define BUCKET_TO_PAGE(B) \ + (B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((B)+1)-1] : 0) +#define OADDR_TO_PAGE(B) \ + BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B)); + +/* + * page.h contains a detailed description of the page format. + * + * Normally, keys and data are accessed from offset tables in the top of + * each page which point to the beginning of the key and data. There are + * four flag values which may be stored in these offset tables which indicate + * the following: + * + * + * OVFLPAGE Rather than a key data pair, this pair contains + * the address of an overflow page. The format of + * the pair is: + * OVERFLOW_PAGE_NUMBER OVFLPAGE + * + * PARTIAL_KEY This must be the first key/data pair on a page + * and implies that page contains only a partial key. + * That is, the key is too big to fit on a single page + * so it starts on this page and continues on the next. + * The format of the page is: + * KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE + * + * KEY_OFF -- offset of the beginning of the key + * PARTIAL_KEY -- 1 + * OVFL_PAGENO - page number of the next overflow page + * OVFLPAGE -- 0 + * + * FULL_KEY This must be the first key/data pair on the page. It + * is used in two cases. + * + * Case 1: + * There is a complete key on the page but no data + * (because it wouldn't fit). The next page contains + * the data. + * + * Page format it: + * KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE + * + * KEY_OFF -- offset of the beginning of the key + * FULL_KEY -- 2 + * OVFL_PAGENO - page number of the next overflow page + * OVFLPAGE -- 0 + * + * Case 2: + * This page contains no key, but part of a large + * data field, which is continued on the next page. + * + * Page format it: + * DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE + * + * KEY_OFF -- offset of the beginning of the data on + * this page + * FULL_KEY -- 2 + * OVFL_PAGENO - page number of the next overflow page + * OVFLPAGE -- 0 + * + * FULL_KEY_DATA + * This must be the first key/data pair on the page. + * There are two cases: + * + * Case 1: + * This page contains a key and the beginning of the + * data field, but the data field is continued on the + * next page. + * + * Page format is: + * KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF + * + * KEY_OFF -- offset of the beginning of the key + * FULL_KEY_DATA -- 3 + * OVFL_PAGENO - page number of the next overflow page + * DATA_OFF -- offset of the beginning of the data + * + * Case 2: + * This page contains the last page of a big data pair. + * There is no key, only the tail end of the data + * on this page. + * + * Page format is: + * DATA_OFF FULL_KEY_DATA + * + * DATA_OFF -- offset of the beginning of the data on + * this page + * FULL_KEY_DATA -- 3 + * OVFL_PAGENO - page number of the next overflow page + * OVFLPAGE -- 0 + * + * OVFL_PAGENO and OVFLPAGE are optional (they are + * not present if there is no next page). + */ + +#define OVFLPAGE 0 +#define PARTIAL_KEY 1 +#define FULL_KEY 2 +#define FULL_KEY_DATA 3 +#define REAL_KEY 4 + +/* Short hands for accessing structure */ +#define BSIZE hdr.bsize +#define BSHIFT hdr.bshift +#define DSIZE hdr.dsize +#define SGSIZE hdr.ssize +#define SSHIFT hdr.sshift +#define LORDER hdr.lorder +#define OVFL_POINT hdr.ovfl_point +#define LAST_FREED hdr.last_freed +#define MAX_BUCKET hdr.max_bucket +#define FFACTOR hdr.ffactor +#define HIGH_MASK hdr.high_mask +#define LOW_MASK hdr.low_mask +#define NKEYS hdr.nkeys +#define HDRPAGES hdr.hdrpages +#define SPARES hdr.spares +#define BITMAPS hdr.bitmaps +#define VERSION hdr.version +#define MAGIC hdr.magic +#define NEXT_FREE hdr.next_free +#define H_CHARKEY hdr.h_charkey diff --git a/db/hash/hash_bigkey-fbsd.c b/db/hash/hash_bigkey-fbsd.c new file mode 100644 index 0000000..e4d75a5 --- /dev/null +++ b/db/hash/hash_bigkey-fbsd.c @@ -0,0 +1,670 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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_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 $"); + +/* + * PACKAGE: hash + * DESCRIPTION: + * Big key/data handling for the hashing package. + * + * ROUTINES: + * External + * __big_keydata + * __big_split + * __big_insert + * __big_return + * __big_delete + * __find_last_page + * Internal + * collect_key + * collect_data + */ + +#include + +#include +#include +#include +#include + +#ifdef DEBUG +#include +#endif + +#include +#include "hash.h" +#include "page.h" +#include "hash_extern.h" + +static int collect_key(HTAB *, BUFHEAD *, int, DBT *, int); +static int collect_data(HTAB *, BUFHEAD *, int, int); + +/* + * Big_insert + * + * You need to do an insert and the key/data pair is too big + * + * Returns: + * 0 ==> OK + *-1 ==> ERROR + */ +extern int +__big_insert(hashp, bufp, key, val) + HTAB *hashp; + BUFHEAD *bufp; + const DBT *key, *val; +{ + u_int16_t *p; + int key_size, n, val_size; + u_int16_t space, move_bytes, off; + char *cp, *key_data, *val_data; + + cp = bufp->page; /* Character pointer of p. */ + p = (u_int16_t *)cp; + + key_data = (char *)key->data; + key_size = key->size; + val_data = (char *)val->data; + val_size = val->size; + + /* First move the Key */ + for (space = FREESPACE(p) - BIGOVERHEAD; key_size; + space = FREESPACE(p) - BIGOVERHEAD) { + move_bytes = MIN(space, key_size); + off = OFFSET(p) - move_bytes; + memmove(cp + off, key_data, move_bytes); + key_size -= move_bytes; + key_data += move_bytes; + n = p[0]; + p[++n] = off; + p[0] = ++n; + FREESPACE(p) = off - PAGE_META(n); + OFFSET(p) = off; + p[n] = PARTIAL_KEY; + bufp = __add_ovflpage(hashp, bufp); + if (!bufp) + return (-1); + n = p[0]; + if (!key_size) { + if (FREESPACE(p)) { + move_bytes = MIN(FREESPACE(p), val_size); + 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 - 2] = FULL_KEY_DATA; + FREESPACE(p) = FREESPACE(p) - move_bytes; + OFFSET(p) = off; + } else + p[n - 2] = FULL_KEY; + } + p = (u_int16_t *)bufp->page; + cp = bufp->page; + bufp->flags |= BUF_MOD; + } + + /* Now move the data */ + for (space = FREESPACE(p) - BIGOVERHEAD; val_size; + space = FREESPACE(p) - BIGOVERHEAD) { + move_bytes = MIN(space, val_size); + /* + * Here's the hack to make sure that if the data ends on the + * same page as the key ends, FREESPACE is at least one. + */ + if (space == val_size && val_size == val->size) + move_bytes--; + off = OFFSET(p) - move_bytes; + memmove(cp + off, val_data, move_bytes); + val_size -= move_bytes; + val_data += move_bytes; + n = p[0]; + p[++n] = off; + p[0] = ++n; + FREESPACE(p) = off - PAGE_META(n); + OFFSET(p) = off; + if (val_size) { + p[n] = FULL_KEY; + bufp = __add_ovflpage(hashp, bufp); + if (!bufp) + return (-1); + cp = bufp->page; + p = (u_int16_t *)cp; + } else + p[n] = FULL_KEY_DATA; + bufp->flags |= BUF_MOD; + } + return (0); +} + +/* + * Called when bufp's page contains a partial key (index should be 1) + * + * All pages in the big key/data pair except bufp are freed. We cannot + * free bufp because the page pointing to it is lost and we can't get rid + * of its pointer. + * + * Returns: + * 0 => OK + *-1 => ERROR + */ +extern int +__big_delete(hashp, bufp) + HTAB *hashp; + BUFHEAD *bufp; +{ + BUFHEAD *last_bfp, *rbufp; + u_int16_t *bp, pageno; + int key_done, n; + + rbufp = bufp; + last_bfp = NULL; + bp = (u_int16_t *)bufp->page; + pageno = 0; + key_done = 0; + + while (!key_done || (bp[2] != FULL_KEY_DATA)) { + if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) + key_done = 1; + + /* + * If there is freespace left on a FULL_KEY_DATA page, then + * the data is short and fits entirely on this page, and this + * is the last page. + */ + if (bp[2] == FULL_KEY_DATA && FREESPACE(bp)) + break; + pageno = bp[bp[0] - 1]; + rbufp->flags |= BUF_MOD; + rbufp = __get_buf(hashp, pageno, rbufp, 0); + if (last_bfp) + __free_ovflpage(hashp, last_bfp); + last_bfp = rbufp; + if (!rbufp) + return (-1); /* Error. */ + bp = (u_int16_t *)rbufp->page; + } + + /* + * If we get here then rbufp points to the last page of the big + * key/data pair. Bufp points to the first one -- it should now be + * empty pointing to the next page after this pair. Can't free it + * because we don't have the page pointing to it. + */ + + /* This is information from the last page of the pair. */ + n = bp[0]; + pageno = bp[n - 1]; + + /* Now, bp is the first page of the pair. */ + bp = (u_int16_t *)bufp->page; + if (n > 2) { + /* There is an overflow page. */ + bp[1] = pageno; + bp[2] = OVFLPAGE; + bufp->ovfl = rbufp->ovfl; + } else + /* This is the last page. */ + bufp->ovfl = NULL; + n -= 2; + bp[0] = n; + FREESPACE(bp) = hashp->BSIZE - PAGE_META(n); + OFFSET(bp) = hashp->BSIZE - 1; + + bufp->flags |= BUF_MOD; + if (rbufp) + __free_ovflpage(hashp, rbufp); + if (last_bfp != rbufp) + __free_ovflpage(hashp, last_bfp); + + hashp->NKEYS--; + return (0); +} +/* + * Returns: + * 0 = key not found + * -1 = get next overflow page + * -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; +{ + u_int16_t *bp; + char *p; + int ksize; + u_int16_t bytes; + char *kkey; + + bp = (u_int16_t *)bufp->page; + p = bufp->page; + ksize = size; + kkey = key; + + for (bytes = hashp->BSIZE - bp[ndx]; + bytes <= size && bp[ndx + 1] == PARTIAL_KEY; + bytes = hashp->BSIZE - bp[ndx]) { + if (memcmp(p + bp[ndx], kkey, bytes)) + return (-2); + kkey += bytes; + ksize -= bytes; + bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0); + if (!bufp) + return (-3); + p = bufp->page; + bp = (u_int16_t *)p; + ndx = 1; + } + + if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) { +#ifdef HASH_STATISTICS + ++hash_collisions; +#endif + return (-2); + } else + return (ndx); +} + +/* + * Given the buffer pointer of the first overflow page of a big pair, + * find the end of the big pair + * + * This will set bpp to the buffer header of the last page of the big pair. + * It will return the pageno of the overflow page following the last page + * 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; +{ + BUFHEAD *bufp; + u_int16_t *bp, pageno; + int n; + + bufp = *bpp; + bp = (u_int16_t *)bufp->page; + for (;;) { + n = bp[0]; + + /* + * This is the last page if: the tag is FULL_KEY_DATA and + * either only 2 entries OVFLPAGE marker is explicit there + * is freespace on the page. + */ + if (bp[2] == FULL_KEY_DATA && + ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp)))) + break; + + pageno = bp[n - 1]; + bufp = __get_buf(hashp, pageno, bufp, 0); + if (!bufp) + return (0); /* Need to indicate an error! */ + bp = (u_int16_t *)bufp->page; + } + + *bpp = bufp; + if (bp[0] > 2) + return (bp[3]); + else + return (0); +} + +/* + * 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; +{ + BUFHEAD *save_p; + u_int16_t *bp, len, off, save_addr; + char *tp; + + bp = (u_int16_t *)bufp->page; + while (bp[ndx + 1] == PARTIAL_KEY) { + bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!bufp) + return (-1); + bp = (u_int16_t *)bufp->page; + ndx = 1; + } + + if (bp[ndx + 1] == FULL_KEY) { + bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!bufp) + return (-1); + bp = (u_int16_t *)bufp->page; + save_p = bufp; + save_addr = save_p->addr; + off = bp[1]; + len = 0; + } else + if (!FREESPACE(bp)) { + /* + * This is a hack. We can't distinguish between + * FULL_KEY_DATA that contains complete data or + * incomplete data, so we require that if the data + * is complete, there is at least 1 byte of free + * space left. + */ + off = bp[bp[0]]; + len = bp[1] - off; + save_p = bufp; + save_addr = bufp->addr; + bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!bufp) + return (-1); + bp = (u_int16_t *)bufp->page; + } else { + /* The data is all on one page. */ + tp = (char *)bp; + off = bp[bp[0]]; + val->data = (u_char *)tp + off; + val->size = bp[1] - off; + if (set_current) { + if (bp[0] == 2) { /* No more buckets in + * chain */ + hashp->cpage = NULL; + hashp->cbucket++; + hashp->cndx = 1; + } else { + hashp->cpage = __get_buf(hashp, + bp[bp[0] - 1], bufp, 0); + if (!hashp->cpage) + return (-1); + hashp->cndx = 1; + if (!((u_int16_t *) + hashp->cpage->page)[0]) { + hashp->cbucket++; + hashp->cpage = NULL; + } + } + } + return (0); + } + + val->size = collect_data(hashp, bufp, (int)len, set_current); + if (val->size == -1) + return (-1); + if (save_p->addr != save_addr) { + /* We are pretty short on buffers. */ + errno = EINVAL; /* OUT OF BUFFERS */ + return (-1); + } + memmove(hashp->tmp_buf, (save_p->page) + off, len); + val->data = (u_char *)hashp->tmp_buf; + return (0); +} +/* + * Count how big the total datasize is by recursing through the pages. Then + * 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; +{ + u_int16_t *bp; + char *p; + BUFHEAD *xbp; + u_int16_t save_addr; + int mylen, totlen; + + p = bufp->page; + bp = (u_int16_t *)p; + mylen = hashp->BSIZE - bp[1]; + save_addr = bufp->addr; + + if (bp[2] == FULL_KEY_DATA) { /* End of Data */ + totlen = len + mylen; + if (hashp->tmp_buf) + free(hashp->tmp_buf); + if ((hashp->tmp_buf = (char *)malloc(totlen)) == NULL) + return (-1); + if (set) { + hashp->cndx = 1; + if (bp[0] == 2) { /* No more buckets in chain */ + hashp->cpage = NULL; + hashp->cbucket++; + } else { + hashp->cpage = + __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!hashp->cpage) + return (-1); + else if (!((u_int16_t *)hashp->cpage->page)[0]) { + hashp->cbucket++; + hashp->cpage = NULL; + } + } + } + } else { + xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!xbp || ((totlen = + collect_data(hashp, xbp, len + mylen, set)) < 1)) + return (-1); + } + if (bufp->addr != save_addr) { + errno = EINVAL; /* Out of buffers. */ + return (-1); + } + memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], mylen); + return (totlen); +} + +/* + * 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; +{ + key->size = collect_key(hashp, bufp, 0, val, set); + if (key->size == -1) + return (-1); + key->data = (u_char *)hashp->tmp_key; + return (0); +} + +/* + * Count how big the total key size is by recursing through the pages. Then + * 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; +{ + BUFHEAD *xbp; + char *p; + int mylen, totlen; + u_int16_t *bp, save_addr; + + p = bufp->page; + bp = (u_int16_t *)p; + mylen = hashp->BSIZE - bp[1]; + + save_addr = bufp->addr; + totlen = len + mylen; + if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */ + if (hashp->tmp_key != NULL) + free(hashp->tmp_key); + if ((hashp->tmp_key = (char *)malloc(totlen)) == NULL) + return (-1); + if (__big_return(hashp, bufp, 1, val, set)) + return (-1); + } else { + xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!xbp || ((totlen = + collect_key(hashp, xbp, totlen, val, set)) < 1)) + return (-1); + } + if (bufp->addr != save_addr) { + errno = EINVAL; /* MIS -- OUT OF BUFFERS */ + return (-1); + } + memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], mylen); + return (totlen); +} + +/* + * Returns: + * 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; +{ + BUFHEAD *tmpp; + u_int16_t *tp; + BUFHEAD *bp; + DBT key, val; + u_int32_t change; + u_int16_t free_space, n, off; + + bp = big_keyp; + + /* Now figure out where the big key/data goes */ + if (__big_keydata(hashp, big_keyp, &key, &val, 0)) + return (-1); + change = (__call_hash(hashp, key.data, key.size) != obucket); + + if ( (ret->next_addr = __find_last_page(hashp, &big_keyp)) ) { + if (!(ret->nextp = + __get_buf(hashp, ret->next_addr, big_keyp, 0))) + return (-1);; + } else + ret->nextp = NULL; + + /* Now make one of np/op point to the big key/data pair */ +#ifdef DEBUG + assert(np->ovfl == NULL); +#endif + if (change) + tmpp = np; + else + tmpp = op; + + tmpp->flags |= BUF_MOD; +#ifdef DEBUG1 + (void)fprintf(stderr, + "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr, + (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0)); +#endif + tmpp->ovfl = bp; /* one of op/np point to big_keyp */ + tp = (u_int16_t *)tmpp->page; +#ifdef DEBUG + assert(FREESPACE(tp) >= OVFLSIZE); +#endif + n = tp[0]; + off = OFFSET(tp); + free_space = FREESPACE(tp); + tp[++n] = (u_int16_t)addr; + tp[++n] = OVFLPAGE; + tp[0] = n; + OFFSET(tp) = off; + FREESPACE(tp) = free_space - OVFLSIZE; + + /* + * Finally, set the new and old return values. BIG_KEYP contains a + * pointer to the last page of the big key_data pair. Make sure that + * big_keyp has no following page (2 elements) or create an empty + * following page. + */ + + ret->newp = np; + ret->oldp = op; + + tp = (u_int16_t *)big_keyp->page; + big_keyp->flags |= BUF_MOD; + if (tp[0] > 2) { + /* + * There may be either one or two offsets on this page. If + * there is one, then the overflow page is linked on normally + * and tp[4] is OVFLPAGE. If there are two, tp[4] contains + * the second offset and needs to get stuffed in after the + * next overflow page is added. + */ + n = tp[4]; + free_space = FREESPACE(tp); + off = OFFSET(tp); + tp[0] -= 2; + FREESPACE(tp) = free_space + OVFLSIZE; + OFFSET(tp) = off; + tmpp = __add_ovflpage(hashp, big_keyp); + if (!tmpp) + return (-1); + tp[4] = n; + } else + tmpp = big_keyp; + + if (change) + ret->newp = tmpp; + else + ret->oldp = tmpp; + return (0); +} diff --git a/db/hash/hash_buf-fbsd.c b/db/hash/hash_buf-fbsd.c new file mode 100644 index 0000000..2710d75 --- /dev/null +++ b/db/hash/hash_buf-fbsd.c @@ -0,0 +1,356 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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_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 $"); + +/* + * PACKAGE: hash + * + * DESCRIPTION: + * Contains buffer management + * + * ROUTINES: + * External + * __buf_init + * __get_buf + * __buf_free + * __reclaim_buf + * Internal + * newbuf + */ + +#include + +#include +#include +#include + +#ifdef DEBUG +#include +#endif + +#include +#include "hash.h" +#include "page.h" +#include "hash_extern.h" + +static BUFHEAD *newbuf(HTAB *, u_int32_t, BUFHEAD *); + +/* Unlink B from its place in the lru */ +#define BUF_REMOVE(B) { \ + (B)->prev->next = (B)->next; \ + (B)->next->prev = (B)->prev; \ +} + +/* Insert B after P */ +#define BUF_INSERT(B, P) { \ + (B)->next = (P)->next; \ + (B)->prev = (P); \ + (P)->next = (B); \ + (B)->next->prev = (B); \ +} + +#define MRU hashp->bufhead.next +#define LRU hashp->bufhead.prev + +#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead) +#define LRU_INSERT(B) BUF_INSERT((B), LRU) + +/* + * We are looking for a buffer with address "addr". If prev_bp is NULL, then + * address is a bucket index. If prev_bp is not NULL, then it points to the + * page previous to an overflow page that we are trying to find. + * + * CAVEAT: The buffer header accessed via prev_bp's ovfl field may no longer + * 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 *bp; + u_int32_t is_disk_mask; + int is_disk, segment_ndx; + SEGMENT segp; + + is_disk = 0; + is_disk_mask = 0; + if (prev_bp) { + bp = prev_bp->ovfl; + if (!bp || (bp->addr != addr)) + bp = NULL; + if (!newpage) + is_disk = BUF_DISK; + } else { + /* Grab buffer out of directory */ + segment_ndx = addr & (hashp->SGSIZE - 1); + + /* valid segment ensured by __call_hash() */ + segp = hashp->dir[addr >> hashp->SSHIFT]; +#ifdef DEBUG + assert(segp != NULL); +#endif + bp = PTROF(segp[segment_ndx]); + is_disk_mask = ISDISK(segp[segment_ndx]); + is_disk = is_disk_mask || !hashp->new_file; + } + + if (!bp) { + bp = newbuf(hashp, addr, prev_bp); + if (!bp || + __get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0)) + return (NULL); + if (!prev_bp) + segp[segment_ndx] = + (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask); + } else { + BUF_REMOVE(bp); + MRU_INSERT(bp); + } + return (bp); +} + +/* + * We need a buffer for this page. Either allocate one, or evict a resident + * one (if we have as many buffers as we're allowed) and put this one in. + * + * 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; +{ + BUFHEAD *bp; /* The buffer we're going to use */ + BUFHEAD *xbp; /* Temp pointer */ + BUFHEAD *next_xbp; + SEGMENT segp; + int segment_ndx; + u_int16_t oaddr, *shortp; + + oaddr = 0; + bp = LRU; + /* + * If LRU buffer is pinned, the buffer pool is too small. We need to + * allocate more buffers. + */ + if (hashp->nbufs || (bp->flags & BUF_PIN)) { + /* Allocate a new one */ + if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL) + return (NULL); +#ifdef PURIFY + memset(bp, 0xff, sizeof(BUFHEAD)); +#endif + if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) { + free(bp); + return (NULL); + } +#ifdef PURIFY + memset(bp->page, 0xff, hashp->BSIZE); +#endif + if (hashp->nbufs) + hashp->nbufs--; + } else { + /* Kick someone out */ + BUF_REMOVE(bp); + /* + * If this is an overflow page with addr 0, it's already been + * flushed back in an overflow chain and initialized. + */ + if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) { + /* + * Set oaddr before __put_page so that you get it + * before bytes are swapped. + */ + shortp = (u_int16_t *)bp->page; + if (shortp[0]) + oaddr = shortp[shortp[0] - 1]; + if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page, + bp->addr, (int)IS_BUCKET(bp->flags), 0)) + return (NULL); + /* + * Update the pointer to this page (i.e. invalidate it). + * + * If this is a new file (i.e. we created it at open + * time), make sure that we mark pages which have been + * written to disk so we retrieve them from disk later, + * rather than allocating new pages. + */ + if (IS_BUCKET(bp->flags)) { + segment_ndx = bp->addr & (hashp->SGSIZE - 1); + segp = hashp->dir[bp->addr >> hashp->SSHIFT]; +#ifdef DEBUG + assert(segp != NULL); +#endif + + if (hashp->new_file && + ((bp->flags & BUF_MOD) || + ISDISK(segp[segment_ndx]))) + segp[segment_ndx] = (BUFHEAD *)BUF_DISK; + else + segp[segment_ndx] = NULL; + } + /* + * Since overflow pages can only be access by means of + * their bucket, free overflow pages associated with + * this bucket. + */ + for (xbp = bp; xbp->ovfl;) { + next_xbp = xbp->ovfl; + xbp->ovfl = 0; + xbp = next_xbp; + + /* Check that ovfl pointer is up date. */ + if (IS_BUCKET(xbp->flags) || + (oaddr != xbp->addr)) + break; + + shortp = (u_int16_t *)xbp->page; + if (shortp[0]) + /* set before __put_page */ + oaddr = shortp[shortp[0] - 1]; + if ((xbp->flags & BUF_MOD) && __put_page(hashp, + xbp->page, xbp->addr, 0, 0)) + return (NULL); + xbp->addr = 0; + xbp->flags = 0; + BUF_REMOVE(xbp); + LRU_INSERT(xbp); + } + } + } + + /* Now assign this buffer */ + bp->addr = addr; +#ifdef DEBUG1 + (void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n", + bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0); +#endif + bp->ovfl = NULL; + if (prev_bp) { + /* + * If prev_bp is set, this is an overflow page, hook it in to + * the buffer overflow links. + */ +#ifdef DEBUG1 + (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n", + prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0), + (bp ? bp->addr : 0)); +#endif + prev_bp->ovfl = bp; + bp->flags = 0; + } else + bp->flags = BUF_BUCKET; + MRU_INSERT(bp); + return (bp); +} + +extern void +__buf_init(hashp, nbytes) + HTAB *hashp; + int nbytes; +{ + BUFHEAD *bfp; + int npages; + + bfp = &(hashp->bufhead); + npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT; + npages = MAX(npages, MIN_BUFFERS); + + hashp->nbufs = npages; + bfp->next = bfp; + bfp->prev = bfp; + /* + * This space is calloc'd so these are already null. + * + * bfp->ovfl = NULL; + * bfp->flags = 0; + * bfp->page = NULL; + * bfp->addr = 0; + */ +} + +extern int +__buf_free(hashp, do_free, to_disk) + HTAB *hashp; + int do_free, to_disk; +{ + BUFHEAD *bp; + + /* Need to make sure that buffer manager has been initialized */ + if (!LRU) + return (0); + for (bp = LRU; bp != &hashp->bufhead;) { + /* Check that the buffer is valid */ + if (bp->addr || IS_BUCKET(bp->flags)) { + if (to_disk && (bp->flags & BUF_MOD) && + __put_page(hashp, bp->page, + bp->addr, IS_BUCKET(bp->flags), 0)) + return (-1); + } + /* Check if we are freeing stuff */ + if (do_free) { + if (bp->page) + free(bp->page); + BUF_REMOVE(bp); + free(bp); + bp = LRU; + } else + bp = bp->prev; + } + return (0); +} + +extern void +__reclaim_buf(hashp, bp) + HTAB *hashp; + BUFHEAD *bp; +{ + bp->ovfl = 0; + bp->addr = 0; + bp->flags = 0; + BUF_REMOVE(bp); + LRU_INSERT(bp); +} diff --git a/db/hash/hash_extern.h b/db/hash/hash_extern.h new file mode 100644 index 0000000..2259ac0 --- /dev/null +++ b/db/hash/hash_extern.h @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 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. + * + * @(#)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 $ + */ + +BUFHEAD *__add_ovflpage(HTAB *, BUFHEAD *); +int __addel(HTAB *, BUFHEAD *, const DBT *, const DBT *); +int __big_delete(HTAB *, BUFHEAD *); +int __big_insert(HTAB *, BUFHEAD *, const DBT *, const DBT *); +int __big_keydata(HTAB *, BUFHEAD *, DBT *, DBT *, int); +int __big_return(HTAB *, BUFHEAD *, int, DBT *, int); +int __big_split(HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *, + int, u_int32_t, SPLIT_RETURN *); +int __buf_free(HTAB *, int, int); +void __buf_init(HTAB *, int); +u_int32_t __call_hash(HTAB *, char *, int); +int __delpair(HTAB *, BUFHEAD *, int); +int __expand_table(HTAB *); +int __find_bigpair(HTAB *, BUFHEAD *, int, char *, int); +u_int16_t __find_last_page(HTAB *, BUFHEAD **); +void __free_ovflpage(HTAB *, BUFHEAD *); +BUFHEAD *__get_buf(HTAB *, u_int32_t, BUFHEAD *, int); +int __get_page(HTAB *, char *, u_int32_t, int, int, int); +int __ibitmap(HTAB *, int, int, int); +u_int32_t __log2(u_int32_t); +int __put_page(HTAB *, char *, u_int32_t, int, int); +void __reclaim_buf(HTAB *, BUFHEAD *); +int __split_page(HTAB *, u_int32_t, u_int32_t); + +/* Default hash routine. */ +extern u_int32_t (*__default_hash)(const void *, size_t); + +#ifdef HASH_STATISTICS +extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows; +#endif diff --git a/db/hash/hash_func-fbsd.c b/db/hash/hash_func-fbsd.c new file mode 100644 index 0000000..537b94f --- /dev/null +++ b/db/hash/hash_func-fbsd.c @@ -0,0 +1,214 @@ +/*- + * Copyright (c) 1990, 1993 + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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_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 $"); + +#include + +#include +#include "hash.h" +#include "page.h" +#include "hash_extern.h" + +static u_int32_t hash1(const void *, size_t) __unused; +static u_int32_t hash2(const void *, size_t) __unused; +static u_int32_t hash3(const void *, size_t) __unused; +static u_int32_t hash4(const void *, size_t); + +/* Global default hash function */ +u_int32_t (*__default_hash)(const void *, size_t) = hash4; + +/* + * HASH FUNCTIONS + * + * Assume that we've already split the bucket to which this key hashes, + * calculate that bucket, and check that in fact we did already split it. + * + * This came from ejb's hsearch. + */ + +#define PRIME1 37 +#define PRIME2 1048583 + +static u_int32_t +hash1(keyarg, len) + const void *keyarg; + size_t len; +{ + const u_char *key; + u_int32_t h; + + /* Convert string to integer */ + for (key = keyarg, h = 0; len--;) + h = h * PRIME1 ^ (*key++ - ' '); + h %= PRIME2; + return (h); +} + +/* + * Phong's linear congruential hash + */ +#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c)) + +static u_int32_t +hash2(keyarg, len) + const void *keyarg; + size_t len; +{ + const u_char *e, *key; + u_int32_t h; + u_char c; + + key = keyarg; + e = key + len; + for (h = 0; key != e;) { + c = *key++; + if (!c && key > e) + break; + dcharhash(h, c); + } + return (h); +} + +/* + * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte + * units. On the first time through the loop we get the "leftover bytes" + * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle + * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If + * this routine is heavily used enough, it's worth the ugly coding. + * + * OZ's original sdbm hash + */ +static u_int32_t +hash3(keyarg, len) + const void *keyarg; + size_t len; +{ + const u_char *key; + size_t loop; + u_int32_t h; + +#define HASHC h = *key++ + 65599 * h + + h = 0; + key = keyarg; + if (len > 0) { + loop = (len + 8 - 1) >> 3; + + switch (len & (8 - 1)) { + case 0: + do { + HASHC; + /* FALLTHROUGH */ + case 7: + HASHC; + /* FALLTHROUGH */ + case 6: + HASHC; + /* FALLTHROUGH */ + case 5: + HASHC; + /* FALLTHROUGH */ + case 4: + HASHC; + /* FALLTHROUGH */ + case 3: + HASHC; + /* FALLTHROUGH */ + case 2: + HASHC; + /* FALLTHROUGH */ + case 1: + HASHC; + } while (--loop); + } + } + return (h); +} + +/* Hash function from Chris Torek. */ +static u_int32_t +hash4(keyarg, len) + const void *keyarg; + size_t len; +{ + const u_char *key; + size_t loop; + u_int32_t h; + +#define HASH4a h = (h << 5) - h + *key++; +#define HASH4b h = (h << 5) + h + *key++; +#define HASH4 HASH4b + + h = 0; + key = keyarg; + if (len > 0) { + loop = (len + 8 - 1) >> 3; + + switch (len & (8 - 1)) { + case 0: + do { + HASH4; + /* FALLTHROUGH */ + case 7: + HASH4; + /* FALLTHROUGH */ + case 6: + HASH4; + /* FALLTHROUGH */ + case 5: + HASH4; + /* FALLTHROUGH */ + case 4: + HASH4; + /* FALLTHROUGH */ + case 3: + HASH4; + /* FALLTHROUGH */ + case 2: + HASH4; + /* FALLTHROUGH */ + case 1: + HASH4; + } while (--loop); + } + } + return (h); +} diff --git a/db/hash/hash_log2-fbsd.c b/db/hash/hash_log2-fbsd.c new file mode 100644 index 0000000..827dbef --- /dev/null +++ b/db/hash/hash_log2-fbsd.c @@ -0,0 +1,56 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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.2 2002/03/21 18:47:38 obrien Exp $"); + +#include + +#include + +u_int32_t +__log2(num) + 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 new file mode 100644 index 0000000..f64a1df --- /dev/null +++ b/db/hash/hash_page-fbsd.c @@ -0,0 +1,959 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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_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 $"); + +/* + * PACKAGE: hashing + * + * DESCRIPTION: + * Page manipulation for hashing package. + * + * ROUTINES: + * + * External + * __get_page + * __add_ovflpage + * Internal + * overflow_page + * open_temp + */ + +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif +#include "un-namespace.h" + +#include +#include "hash.h" +#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); + +#define PAGE_INIT(P) { \ + ((u_int16_t *)(P))[0] = 0; \ + ((u_int16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_int16_t); \ + ((u_int16_t *)(P))[2] = hashp->BSIZE; \ +} + +/* + * This is called AFTER we have verified that there is room on the page for + * the pair (PAIRFITS has returned true) so we go right ahead and start moving + * stuff on. + */ +static void +putpair(p, key, val) + char *p; + const DBT *key, *val; +{ + u_int16_t *bp, n, off; + + bp = (u_int16_t *)p; + + /* Enter the key first. */ + n = bp[0]; + + off = OFFSET(bp) - key->size; + memmove(p + off, key->data, key->size); + bp[++n] = off; + + /* Now the data. */ + off -= val->size; + memmove(p + off, val->data, val->size); + bp[++n] = off; + + /* Adjust page info. */ + bp[0] = n; + bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t)); + bp[n + 2] = off; +} + +/* + * Returns: + * 0 OK + * -1 error + */ +extern int +__delpair(hashp, bufp, ndx) + HTAB *hashp; + BUFHEAD *bufp; + int ndx; +{ + u_int16_t *bp, newoff; + int n; + u_int16_t pairlen; + + bp = (u_int16_t *)bufp->page; + n = bp[0]; + + if (bp[ndx + 1] < REAL_KEY) + return (__big_delete(hashp, bufp)); + if (ndx != 1) + newoff = bp[ndx - 1]; + else + newoff = hashp->BSIZE; + pairlen = newoff - bp[ndx + 1]; + + if (ndx != (n - 1)) { + /* Hard Case -- need to shuffle keys */ + int i; + char *src = bufp->page + (int)OFFSET(bp); + char *dst = src + (int)pairlen; + memmove(dst, src, bp[ndx + 1] - OFFSET(bp)); + + /* Now adjust the pointers */ + for (i = ndx + 2; i <= n; i += 2) { + if (bp[i + 1] == OVFLPAGE) { + bp[i - 2] = bp[i]; + bp[i - 1] = bp[i + 1]; + } else { + bp[i - 2] = bp[i] + pairlen; + bp[i - 1] = bp[i + 1] + pairlen; + } + } + } + /* Finally adjust the page data */ + bp[n] = OFFSET(bp) + pairlen; + bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t); + bp[0] = n - 2; + hashp->NKEYS--; + + bufp->flags |= BUF_MOD; + return (0); +} +/* + * Returns: + * 0 ==> OK + * -1 ==> Error + */ +extern int +__split_page(hashp, obucket, nbucket) + HTAB *hashp; + u_int32_t obucket, nbucket; +{ + BUFHEAD *new_bufp, *old_bufp; + u_int16_t *ino; + char *np; + DBT key, val; + int n, ndx, retval; + u_int16_t copyto, diff, off, moved; + char *op; + + copyto = (u_int16_t)hashp->BSIZE; + off = (u_int16_t)hashp->BSIZE; + old_bufp = __get_buf(hashp, obucket, NULL, 0); + if (old_bufp == NULL) + return (-1); + new_bufp = __get_buf(hashp, nbucket, NULL, 0); + if (new_bufp == NULL) + return (-1); + + old_bufp->flags |= (BUF_MOD | BUF_PIN); + new_bufp->flags |= (BUF_MOD | BUF_PIN); + + ino = (u_int16_t *)(op = old_bufp->page); + np = new_bufp->page; + + moved = 0; + + for (n = 1, ndx = 1; n < ino[0]; n += 2) { + if (ino[n + 1] < REAL_KEY) { + retval = ugly_split(hashp, obucket, old_bufp, new_bufp, + (int)copyto, (int)moved); + old_bufp->flags &= ~BUF_PIN; + new_bufp->flags &= ~BUF_PIN; + return (retval); + + } + key.data = (u_char *)op + ino[n]; + key.size = off - ino[n]; + + if (__call_hash(hashp, key.data, key.size) == obucket) { + /* Don't switch page */ + diff = copyto - off; + if (diff) { + copyto = ino[n + 1] + diff; + memmove(op + copyto, op + ino[n + 1], + off - ino[n + 1]); + ino[ndx] = copyto + ino[n] - ino[n + 1]; + ino[ndx + 1] = copyto; + } else + copyto = ino[n + 1]; + ndx += 2; + } else { + /* Switch page */ + val.data = (u_char *)op + ino[n + 1]; + val.size = ino[n] - ino[n + 1]; + putpair(np, &key, &val); + moved += 2; + } + + off = ino[n + 1]; + } + + /* Now clean up the page */ + ino[0] -= moved; + FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3); + OFFSET(ino) = copyto; + +#ifdef DEBUG3 + (void)fprintf(stderr, "split %d/%d\n", + ((u_int16_t *)np)[0] / 2, + ((u_int16_t *)op)[0] / 2); +#endif + /* unpin both pages */ + old_bufp->flags &= ~BUF_PIN; + new_bufp->flags &= ~BUF_PIN; + return (0); +} + +/* + * Called when we encounter an overflow or big key/data page during split + * handling. This is special cased since we have to begin checking whether + * the key/data pairs fit on their respective pages and because we may need + * overflow pages for both the old and new pages. + * + * The first page might be a page with regular key/data pairs in which case + * we have a regular overflow condition and just need to go on to the next + * page or it might be a big key/data pair in which case we need to fix the + * big key/data pair. + * + * Returns: + * 0 ==> success + * -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. */ +{ + 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; + SPLIT_RETURN ret; + u_int16_t n, off, ov_addr, scopyto; + char *cino; /* Character value of ino */ + + bufp = old_bufp; + ino = (u_int16_t *)old_bufp->page; + np = (u_int16_t *)new_bufp->page; + op = (u_int16_t *)old_bufp->page; + last_bfp = NULL; + scopyto = (u_int16_t)copyto; /* ANSI */ + + n = ino[0] - 1; + while (n < ino[0]) { + if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) { + if (__big_split(hashp, old_bufp, + new_bufp, bufp, bufp->addr, obucket, &ret)) + return (-1); + old_bufp = ret.oldp; + if (!old_bufp) + return (-1); + op = (u_int16_t *)old_bufp->page; + new_bufp = ret.newp; + if (!new_bufp) + return (-1); + np = (u_int16_t *)new_bufp->page; + bufp = ret.nextp; + if (!bufp) + return (0); + cino = (char *)bufp->page; + ino = (u_int16_t *)cino; + last_bfp = ret.nextp; + } else if (ino[n + 1] == OVFLPAGE) { + ov_addr = ino[n]; + /* + * Fix up the old page -- the extra 2 are the fields + * which contained the overflow information. + */ + ino[0] -= (moved + 2); + FREESPACE(ino) = + scopyto - sizeof(u_int16_t) * (ino[0] + 3); + OFFSET(ino) = scopyto; + + bufp = __get_buf(hashp, ov_addr, bufp, 0); + if (!bufp) + return (-1); + + ino = (u_int16_t *)bufp->page; + n = 1; + scopyto = hashp->BSIZE; + moved = 0; + + if (last_bfp) + __free_ovflpage(hashp, last_bfp); + last_bfp = bufp; + } + /* Move regular sized pairs of there are any */ + off = hashp->BSIZE; + for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) { + cino = (char *)ino; + key.data = (u_char *)cino + ino[n]; + key.size = off - ino[n]; + val.data = (u_char *)cino + ino[n + 1]; + val.size = ino[n] - ino[n + 1]; + off = ino[n + 1]; + + if (__call_hash(hashp, key.data, key.size) == obucket) { + /* Keep on old page */ + if (PAIRFITS(op, (&key), (&val))) + putpair((char *)op, &key, &val); + else { + old_bufp = + __add_ovflpage(hashp, old_bufp); + if (!old_bufp) + return (-1); + op = (u_int16_t *)old_bufp->page; + putpair((char *)op, &key, &val); + } + old_bufp->flags |= BUF_MOD; + } else { + /* Move to new page */ + if (PAIRFITS(np, (&key), (&val))) + putpair((char *)np, &key, &val); + else { + new_bufp = + __add_ovflpage(hashp, new_bufp); + if (!new_bufp) + return (-1); + np = (u_int16_t *)new_bufp->page; + putpair((char *)np, &key, &val); + } + new_bufp->flags |= BUF_MOD; + } + } + } + if (last_bfp) + __free_ovflpage(hashp, last_bfp); + return (0); +} + +/* + * Add the given pair to the page + * + * Returns: + * 0 ==> OK + * 1 ==> failure + */ +extern int +__addel(hashp, bufp, key, val) + HTAB *hashp; + BUFHEAD *bufp; + const DBT *key, *val; +{ + u_int16_t *bp, *sop; + int do_expand; + + bp = (u_int16_t *)bufp->page; + do_expand = 0; + while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY)) + /* Exception case */ + if (bp[2] == FULL_KEY_DATA && bp[0] == 2) + /* This is the last page of a big key/data pair + and we need to add another page */ + break; + else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) { + bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); + if (!bufp) + return (-1); + bp = (u_int16_t *)bufp->page; + } else + /* Try to squeeze key on this page */ + if (FREESPACE(bp) > PAIRSIZE(key, val)) { + squeeze_key(bp, key, val); + return (0); + } 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); + else { + do_expand = 1; + bufp = __add_ovflpage(hashp, bufp); + if (!bufp) + return (-1); + sop = (u_int16_t *)bufp->page; + + if (PAIRFITS(sop, key, val)) + putpair((char *)sop, key, val); + else + if (__big_insert(hashp, bufp, key, val)) + return (-1); + } + bufp->flags |= BUF_MOD; + /* + * If the average number of keys per bucket exceeds the fill factor, + * expand the table. + */ + hashp->NKEYS++; + if (do_expand || + (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR)) + return (__expand_table(hashp)); + return (0); +} + +/* + * + * Returns: + * pointer on success + * NULL on error + */ +extern BUFHEAD * +__add_ovflpage(hashp, bufp) + HTAB *hashp; + BUFHEAD *bufp; +{ + u_int16_t *sp; + u_int16_t ndx, ovfl_num; +#ifdef DEBUG1 + int tmp1, tmp2; +#endif + sp = (u_int16_t *)bufp->page; + + /* Check if we are dynamically determining the fill factor */ + if (hashp->FFACTOR == DEF_FFACTOR) { + hashp->FFACTOR = sp[0] >> 1; + if (hashp->FFACTOR < MIN_FFACTOR) + hashp->FFACTOR = MIN_FFACTOR; + } + bufp->flags |= BUF_MOD; + ovfl_num = overflow_page(hashp); +#ifdef DEBUG1 + tmp1 = bufp->addr; + tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0; +#endif + if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1))) + return (NULL); + bufp->ovfl->flags |= BUF_MOD; +#ifdef DEBUG1 + (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n", + tmp1, tmp2, bufp->ovfl->addr); +#endif + ndx = sp[0]; + /* + * Since a pair is allocated on a page only if there's room to add + * an overflow page, we know that the OVFL information will fit on + * the page. + */ + sp[ndx + 4] = OFFSET(sp); + sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE; + sp[ndx + 1] = ovfl_num; + sp[ndx + 2] = OVFLPAGE; + sp[0] = ndx + 2; +#ifdef HASH_STATISTICS + hash_overflows++; +#endif + return (bufp->ovfl); +} + +/* + * Returns: + * 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 fd, page, size; + int rsize; + u_int16_t *bp; + + fd = hashp->fp; + size = hashp->BSIZE; + + if ((fd == -1) || !is_disk) { + PAGE_INIT(p); + return (0); + } + if (is_bucket) + 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)) + return (-1); + bp = (u_int16_t *)p; + if (!rsize) + bp[0] = 0; /* We hit the EOF, so initialize a new page */ + else + if (rsize != size) { + errno = EFTYPE; + return (-1); + } + if (!is_bitmap && !bp[0]) { + PAGE_INIT(p); + } else + if (hashp->LORDER != BYTE_ORDER) { + int i, max; + + if (is_bitmap) { + max = hashp->BSIZE >> 2; /* divide by 4 */ + for (i = 0; i < max; i++) + M_32_SWAP(((int *)p)[i]); + } else { + M_16_SWAP(bp[0]); + max = bp[0] + 2; + for (i = 1; i <= max; i++) + M_16_SWAP(bp[i]); + } + } + return (0); +} + +/* + * Write page p to disk + * + * Returns: + * 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 fd, page, size; + int wsize, max; + + size = hashp->BSIZE; + if ((hashp->fp == -1) && open_temp(hashp)) + return (-1); + fd = hashp->fp; + + if (hashp->LORDER != BYTE_ORDER) { + int i; + + if (is_bitmap) { + max = hashp->BSIZE >> 2; /* divide by 4 */ + for (i = 0; i < max; i++) + M_32_SWAP(((int *)p)[i]); + } else { + max = ((u_int16_t *)p)[0] + 2; + for (i = 0; i <= max; i++) + M_16_SWAP(((u_int16_t *)p)[i]); + } + } + if (is_bucket) + 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)) + /* Errno is set */ + return (-1); + if (wsize != size) { + errno = EFTYPE; + return (-1); + } + /* 4485533 - reswap the in-memory copy */ + if (hashp->LORDER != BYTE_ORDER) { + int i; + + if (is_bitmap) { + for (i = 0; i < max; i++) + M_32_SWAP(((int *)p)[i]); + } else { + for (i = 0; i <= max; i++) + M_16_SWAP(((u_int16_t *)p)[i]); + } + } + return (0); +} + +#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1) +/* + * 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; +{ + u_int32_t *ip; + int clearbytes, clearints; + + if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL) + return (1); + hashp->nmaps++; + clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1; + clearbytes = clearints << INT_TO_BYTE; + (void)memset((char *)ip, 0, clearbytes); + (void)memset(((char *)ip) + clearbytes, 0xFF, + hashp->BSIZE - clearbytes); + ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK); + SETBIT(ip, 0); + hashp->BITMAPS[ndx] = (u_int16_t)pnum; + hashp->mapp[ndx] = ip; + return (0); +} + +static u_int32_t +first_free(map) + u_int32_t map; +{ + u_int32_t i, mask; + + mask = 0x1; + for (i = 0; i < BITS_PER_MAP; i++) { + if (!(mask & map)) + return (i); + mask = mask << 1; + } + return (i); +} + +static u_int16_t +overflow_page(hashp) + HTAB *hashp; +{ + u_int32_t *freep; + int max_free, offset, splitnum; + u_int16_t addr; + int bit, first_page, free_bit, free_page, i, in_use_bits, j; +#ifdef DEBUG2 + int tmp1, tmp2; +#endif + splitnum = hashp->OVFL_POINT; + max_free = hashp->SPARES[splitnum]; + + free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT); + free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1); + + /* Look through all the free maps to find the first free block */ + first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT); + for ( i = first_page; i <= free_page; i++ ) { + if (!(freep = (u_int32_t *)hashp->mapp[i]) && + !(freep = fetch_bitmap(hashp, i))) + return (0); + if (i == free_page) + in_use_bits = free_bit; + else + in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1; + + if (i == first_page) { + bit = hashp->LAST_FREED & + ((hashp->BSIZE << BYTE_SHIFT) - 1); + j = bit / BITS_PER_MAP; + bit = bit & ~(BITS_PER_MAP - 1); + } else { + bit = 0; + j = 0; + } + for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP) + if (freep[j] != ALL_SET) + goto found; + } + + /* No Free Page Found */ + hashp->LAST_FREED = hashp->SPARES[splitnum]; + hashp->SPARES[splitnum]++; + offset = hashp->SPARES[splitnum] - + (splitnum ? hashp->SPARES[splitnum - 1] : 0); + +#define OVMSG "HASH: Out of overflow pages. Increase page size\n" + if (offset > SPLITMASK) { + if (++splitnum >= NCACHED) { + (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + return (0); + } + hashp->OVFL_POINT = splitnum; + hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1]; + hashp->SPARES[splitnum-1]--; + offset = 1; + } + + /* Check if we need to allocate a new bitmap page */ + if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) { + free_page++; + if (free_page >= NCACHED) { + (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); + return (0); + } + /* + * This is tricky. The 1 indicates that you want the new page + * allocated with 1 clear bit. Actually, you are going to + * allocate 2 pages from this map. The first is going to be + * the map page, the second is the overflow page we were + * looking for. The init_bitmap routine automatically, sets + * the first bit of itself to indicate that the bitmap itself + * is in use. We would explicitly set the second bit, but + * don't have to if we tell init_bitmap not to leave it clear + * in the first place. + */ + if (__ibitmap(hashp, + (int)OADDR_OF(splitnum, offset), 1, free_page)) + return (0); + hashp->SPARES[splitnum]++; +#ifdef DEBUG2 + free_bit = 2; +#endif + offset++; + if (offset > SPLITMASK) { + if (++splitnum >= NCACHED) { + (void)_write(STDERR_FILENO, OVMSG, + sizeof(OVMSG) - 1); + return (0); + } + hashp->OVFL_POINT = splitnum; + hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1]; + hashp->SPARES[splitnum-1]--; + offset = 0; + } + } else { + /* + * Free_bit addresses the last used bit. Bump it to address + * the first available bit. + */ + free_bit++; + SETBIT(freep, free_bit); + } + + /* Calculate address of the new overflow page */ + addr = OADDR_OF(splitnum, offset); +#ifdef DEBUG2 + (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n", + addr, free_bit, free_page); +#endif + return (addr); + +found: + bit = bit + first_free(freep[j]); + SETBIT(freep, bit); +#ifdef DEBUG2 + tmp1 = bit; + tmp2 = i; +#endif + /* + * Bits are addressed starting with 0, but overflow pages are addressed + * beginning at 1. Bit is a bit addressnumber, so we need to increment + * it to convert it to a page number. + */ + bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT)); + if (bit >= hashp->LAST_FREED) + hashp->LAST_FREED = bit - 1; + + /* 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) + 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", + addr, tmp1, tmp2); +#endif + + /* Allocate and return the overflow page */ + return (addr); +} + +/* + * Mark this overflow page as free. + */ +extern void +__free_ovflpage(hashp, obufp) + HTAB *hashp; + BUFHEAD *obufp; +{ + u_int16_t addr; + u_int32_t *freep; + int bit_address, free_page, free_bit; + u_int16_t ndx; + + addr = obufp->addr; +#ifdef DEBUG1 + (void)fprintf(stderr, "Freeing %d\n", addr); +#endif + ndx = (((u_int16_t)addr) >> SPLITSHIFT); + bit_address = + (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1; + if (bit_address < hashp->LAST_FREED) + hashp->LAST_FREED = bit_address; + free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT)); + free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1); + + if (!(freep = hashp->mapp[free_page])) + freep = fetch_bitmap(hashp, free_page); +#ifdef DEBUG + /* + * This had better never happen. It means we tried to read a bitmap + * that has already had overflow pages allocated off it, and we + * failed to read it from the file. + */ + if (!freep) + assert(0); +#endif + CLRBIT(freep, free_bit); +#ifdef DEBUG2 + (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n", + obufp->addr, free_bit, free_page); +#endif + __reclaim_buf(hashp, obufp); +} + +/* + * Returns: + * 0 success + * -1 failure + */ +static int +open_temp(hashp) + HTAB *hashp; +{ + sigset_t set, oset; + static char namestr[] = "_hashXXXXXX"; + + /* 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); + (void)_fcntl(hashp->fp, F_SETFD, 1); + } + (void)_sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL); + return (hashp->fp != -1 ? 0 : -1); +} + +/* + * We have to know that the key will fit, but the last entry on the page is + * an overflow pair, so we need to shift things. + */ +static void +squeeze_key(sp, key, val) + u_int16_t *sp; + const DBT *key, *val; +{ + char *p; + u_int16_t free_space, n, off, pageno; + + p = (char *)sp; + n = sp[0]; + free_space = FREESPACE(sp); + off = OFFSET(sp); + + pageno = sp[n - 1]; + off -= key->size; + sp[n - 1] = off; + memmove(p + off, key->data, key->size); + off -= val->size; + sp[n] = off; + memmove(p + off, val->data, val->size); + sp[0] = n + 2; + sp[n + 1] = pageno; + sp[n + 2] = OVFLPAGE; + FREESPACE(sp) = free_space - PAIRSIZE(key, val); + OFFSET(sp) = off; +} + +static u_int32_t * +fetch_bitmap(hashp, ndx) + HTAB *hashp; + int ndx; +{ + if (ndx >= hashp->nmaps) + return (NULL); + if ((hashp->mapp[ndx] = (u_int32_t *)malloc(hashp->BSIZE)) == NULL) + return (NULL); + if (__get_page(hashp, + (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) { + free(hashp->mapp[ndx]); + return (NULL); + } + return (hashp->mapp[ndx]); +} + +#ifdef DEBUG4 +int +print_chain(addr) + int addr; +{ + BUFHEAD *bufp; + short *bp, oaddr; + + (void)fprintf(stderr, "%d ", addr); + bufp = __get_buf(hashp, addr, NULL, 0); + bp = (short *)bufp->page; + while (bp[0] && ((bp[bp[0]] == OVFLPAGE) || + ((bp[0] > 2) && bp[2] < REAL_KEY))) { + oaddr = bp[bp[0] - 1]; + (void)fprintf(stderr, "%d ", (int)oaddr); + bufp = __get_buf(hashp, (int)oaddr, bufp, 0); + bp = (short *)bufp->page; + } + (void)fprintf(stderr, "\n"); +} +#endif diff --git a/db/hash/ndbm-fbsd.c b/db/hash/ndbm-fbsd.c new file mode 100644 index 0000000..ba819d7 --- /dev/null +++ b/db/hash/ndbm-fbsd.c @@ -0,0 +1,246 @@ +/*- + * Copyright (c) 1990, 1993 + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +/* + * This package provides a dbm compatible interface to the new hashing + * package described in db(3). + */ + +#include + +#include +#include +#include + +#include +#define _DBM +typedef DB DBM; +#include +#include "hash.h" + +/* + * Returns: + * *DBM on success + * NULL on failure + */ +extern DBM * +dbm_open(file, flags, mode) + const char *file; + int flags; + mode_t mode; +{ + HASHINFO info; + char path[MAXPATHLEN]; + + info.bsize = 4096; + info.ffactor = 40; + info.nelem = 1; + info.cachesize = 0; + info.hash = NULL; + info.lorder = 0; + + if( strlen(file) >= sizeof(path) - strlen(DBM_SUFFIX)) { + errno = ENAMETOOLONG; + return(NULL); + } + (void)strcpy(path, file); + (void)strcat(path, DBM_SUFFIX); + return ((DBM *)__hash_open(path, flags, mode, &info, 0)); +} + +extern void +dbm_close(db) + DBM *db; +{ + (void)(db->close)(db); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +extern datum +dbm_fetch(db, key) + DBM *db; + datum key; +{ + datum retdata; + int status; + DBT dbtkey, dbtretdata; + + dbtkey.data = key.dptr; + dbtkey.size = key.dsize; + status = (db->get)(db, &dbtkey, &dbtretdata, 0); + if (status) { + dbtretdata.data = NULL; + dbtretdata.size = 0; + } + retdata.dptr = dbtretdata.data; + retdata.dsize = dbtretdata.size; + return (retdata); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +extern datum +dbm_firstkey(db) + DBM *db; +{ + int status; + datum retkey; + DBT dbtretkey, dbtretdata; + HTAB *htab = (HTAB *)(db->internal); + + status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST); + if (status) { + dbtretkey.data = NULL; + htab->nextkey_eof = 1; + } else + htab->nextkey_eof = 0; + retkey.dptr = dbtretkey.data; + retkey.dsize = dbtretkey.size; + return (retkey); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +extern datum +dbm_nextkey(db) + DBM *db; +{ + int status = 1; + datum retkey; + DBT dbtretkey, dbtretdata; + HTAB *htab = (HTAB *)(db->internal); + + if (htab->nextkey_eof) + dbtretkey.data = NULL; + else { + status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT); + if (status) { + dbtretkey.data = NULL; + htab->nextkey_eof = 1; + } + } + retkey.dptr = dbtretkey.data; + retkey.dsize = dbtretkey.size; + return (retkey); +} + +/* + * Returns: + * 0 on success + * <0 failure + */ +extern int +dbm_delete(db, key) + DBM *db; + datum key; +{ + int status; + DBT dbtkey; + + dbtkey.data = key.dptr; + dbtkey.size = key.dsize; + status = (db->del)(db, &dbtkey, 0); + if (status) + return (-1); + else + return (0); +} + +/* + * Returns: + * 0 on success + * <0 failure + * 1 if DBM_INSERT and entry exists + */ +extern int +dbm_store(db, key, data, flags) + DBM *db; + datum key, data; + int flags; +{ + DBT dbtkey, dbtdata; + + dbtkey.data = key.dptr; + dbtkey.size = key.dsize; + dbtdata.data = data.dptr; + dbtdata.size = data.dsize; + return ((db->put)(db, &dbtkey, &dbtdata, + (flags == DBM_INSERT) ? R_NOOVERWRITE : 0)); +} + +extern int +dbm_error(db) + DBM *db; +{ + HTAB *hp; + + hp = (HTAB *)db->internal; + return (hp->error); +} + +extern int +dbm_clearerr(db) + DBM *db; +{ + HTAB *hp; + + hp = (HTAB *)db->internal; + hp->error = 0; + return (0); +} + +extern int +dbm_dirfno(db) + DBM *db; +{ + return(((HTAB *)db->internal)->fp); +} diff --git a/db/hash/page.h b/db/hash/page.h new file mode 100644 index 0000000..2cf7460 --- /dev/null +++ b/db/hash/page.h @@ -0,0 +1,93 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + * + * @(#)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 $ + */ + +/* + * Definitions for hashing page file format. + */ + +/* + * routines dealing with a data page + * + * page format: + * +------------------------------+ + * p | n | keyoff | datoff | keyoff | + * +------------+--------+--------+ + * | datoff | free | ptr | --> | + * +--------+---------------------+ + * | F R E E A R E A | + * +--------------+---------------+ + * | <---- - - - | data | + * +--------+-----+----+----------+ + * | key | data | key | + * +--------+----------+----------+ + * + * Pointer to the free space is always: p[p[0] + 2] + * Amount of free space on the page is: p[p[0] + 1] + */ + +/* + * How many bytes required for this pair? + * 2 shorts in the table at the top of the page + room for the + * key and room for the data + * + * We prohibit entering a pair on a page unless there is also room to append + * an overflow page. The reason for this it that you can get in a situation + * where a single key/data pair fits on a page, but you can't append an + * overflow page and later you'd have to split the key/data and handle like + * a big pair. + * You might as well do this up front. + */ + +#define PAIRSIZE(K,D) (2*sizeof(u_int16_t) + (K)->size + (D)->size) +#define BIGOVERHEAD (4*sizeof(u_int16_t)) +#define KEYSIZE(K) (4*sizeof(u_int16_t) + (K)->size); +#define OVFLSIZE (2*sizeof(u_int16_t)) +#define FREESPACE(P) ((P)[(P)[0]+1]) +#define OFFSET(P) ((P)[(P)[0]+2]) +#define PAIRFITS(P,K,D) \ + (((P)[2] >= REAL_KEY) && \ + (PAIRSIZE((K),(D)) + OVFLSIZE) <= FREESPACE((P))) +#define PAGE_META(N) (((N)+3) * sizeof(u_int16_t)) + +typedef struct { + BUFHEAD *newp; + BUFHEAD *oldp; + BUFHEAD *nextp; + u_int16_t next_addr; +} SPLIT_RETURN; diff --git a/db/man/FreeBSD/dbm.3 b/db/man/FreeBSD/dbm.3 index 9585e63..f8cb6b8 100644 --- a/db/man/FreeBSD/dbm.3 +++ b/db/man/FreeBSD/dbm.3 @@ -104,7 +104,7 @@ is a typical value for is a typical value for .Fa mode . .Dv O_WRONLY -is not allowed in +is treated as O_RDWR in .Fa flags . The pointer returned by .Fn dbm_open diff --git a/db/man/FreeBSD/dbm.3.patch b/db/man/FreeBSD/dbm.3.patch new file mode 100644 index 0000000..02014ab --- /dev/null +++ b/db/man/FreeBSD/dbm.3.patch @@ -0,0 +1,192 @@ +--- 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 @@ + .Nm dbm_store + .Nd database access functions + .Sh SYNOPSIS +-.In fcntl.h + .In ndbm.h +-.Ft DBM * +-.Fn dbm_open "const char *base" "int flags" "int mode" ++.Ft int ++.Fo dbm_clearerr ++.Fa "DBM *db" ++.Fc + .Ft void +-.Fn dbm_close "DBM *db" ++.Fo dbm_close ++.Fa "DBM *db" ++.Fc + .Ft int +-.Fn dbm_store "DBM *db" "datum key" "datum data" "int flags" +-.Ft datum +-.Fn dbm_fetch "DBM *db" "datum key" ++.Fo dbm_delete ++.Fa "DBM *db" ++.Fa "datum key" ++.Fc ++.Ft int ++.Fo dbm_dirfno ++.Fa "DBM *db" ++.Fc + .Ft int +-.Fn dbm_delete "DBM *db" "datum key" ++.Fo dbm_error ++.Fa "DBM *db" ++.Fc + .Ft datum +-.Fn dbm_firstkey "DBM *db" ++.Fo dbm_fetch ++.Fa "DBM *db" ++.Fa "datum key" ++.Fc + .Ft datum +-.Fn dbm_nextkey "DBM *db" +-.Ft int +-.Fn dbm_error "DBM *db" +-.Ft int +-.Fn dbm_clearerr "DBM *db" ++.Fo dbm_firstkey ++.Fa "DBM *db" ++.Fc ++.Ft datum ++.Fo dbm_nextkey ++.Fa "DBM *db" ++.Fc ++.Ft DBM * ++.Fo dbm_open ++.Fa "const char *file" ++.Fa "int open_flags" ++.Fa "mode_t file_mode" ++.Fc + .Ft int +-.Fn dbm_dirfno "DBM *db" ++.Fo dbm_store ++.Fa "DBM *db" ++.Fa "datum key" ++.Fa "datum content" ++.Fa "int store_mode" ++.Fc + .Sh DESCRIPTION + Database access functions. + These functions are implemented using +@@ -74,38 +100,38 @@ + .Ed + .Pp + The +-.Fn dbm_open base flags mode ++.Fn dbm_open file open_flags file_mode + function +-opens or creates a database. ++opens or creates a database file. + The +-.Fa base ++.Fa file + argument + is the basename of the file containing + the database; the actual database has a + .Pa .db + suffix. + I.e., if +-.Fa base ++.Fa file + is + .Qq Li /home/me/mystuff + then the actual database is in the file + .Pa /home/me/mystuff.db . + The +-.Fa flags ++.Fa open_flags + and +-.Fa mode ++.Fa file_mode + arguments + are passed to + .Xr open 2 . + .Pq Dv O_RDWR | O_CREAT + is a typical value for +-.Fa flags ; ++.Fa open_flags ; + .Li 0660 + is a typical value for +-.Fa mode . ++.Fa file_mode . + .Dv O_WRONLY + is treated as O_RDWR 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. + .Pp + The +-.Fn dbm_store db key data flags ++.Fn dbm_store db key content store_mode + function + inserts or replaces an entry in the database. + The +-.Fa flags ++.Fa store_mode + argument + is either + .Dv DBM_INSERT + or + .Dv DBM_REPLACE . + If +-.Fa flags ++.Fa store_mode + is + .Dv DBM_INSERT + and the database already contains an entry for +@@ -153,7 +179,7 @@ + function + normally returns zero but returns 1 if the entry could not be + inserted (because +-.Fa flags ++.Fa store_mode + is + .Dv DBM_INSERT , + and an entry with +@@ -168,7 +194,7 @@ + returns + .Dv NULL + or the +-.Fa data ++.Fa content + corresponding to + .Fa key . + .Pp +@@ -223,10 +249,30 @@ + .Fn dbm_dirfno db + function + returns the file descriptor to the database. ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Pp ++The include file ++.In ndbm.h ++is necessary for all functions. ++.Pp ++.Ft DBM * ++.br ++.Fo dbm_open ++.Fa "const char *file" ++.Fa "int open_flags" ++.Fa "int file_mode" ++.Fc ; ++.Pp ++.Fa file_mode ++has type ++.Vt int . + .Sh SEE ALSO + .Xr open 2 , + .Xr dbopen 3 , +-.Xr hash 3 ++.Xr hash 3 , ++.Xr compat 5 + .Sh STANDARDS + These functions (except + .Fn dbm_dirfno ) diff --git a/db/man/Makefile.inc b/db/man/Makefile.inc index a17ae48..220233a 100644 --- a/db/man/Makefile.inc +++ b/db/man/Makefile.inc @@ -8,15 +8,25 @@ FBSDMAN3= btree.3 dbm.3 dbopen.3 hash.3 mpool.3 recno.3 .include "Makefile.fbsd_end" -MLINKS+= dbm.3 dbm_clearerr.3 -MLINKS+= dbm.3 dbm_close.3 -MLINKS+= dbm.3 dbm_delete.3 -MLINKS+= dbm.3 dbm_dirnfo.3 -MLINKS+= dbm.3 dbm_error.3 -MLINKS+= dbm.3 dbm_fetch.3 -MLINKS+= dbm.3 dbm_firstkey.3 -MLINKS+= dbm.3 dbm_nextkey.3 -MLINKS+= dbm.3 dbm_open.3 -MLINKS+= dbm.3 dbm_store.3 +MLINKS+= dbm.3 dbm_clearerr.3 \ + dbm.3 dbm_close.3 \ + dbm.3 dbm_delete.3 \ + dbm.3 dbm_dirfno.3 \ + dbm.3 dbm_error.3 \ + dbm.3 dbm_fetch.3 \ + dbm.3 dbm_firstkey.3 \ + dbm.3 dbm_nextkey.3 \ + dbm.3 dbm_open.3 \ + dbm.3 dbm_store.3 + MLINKS+= dbopen.3 db.3 + +MLINKS+= mpool.3 mpool_close.3 \ + mpool.3 mpool_filter.3 \ + mpool.3 mpool_get.3 \ + mpool.3 mpool_new.3 \ + mpool.3 mpool_open.3 \ + mpool.3 mpool_put.3 \ + mpool.3 mpool_sync.3 + .endif diff --git a/db/man/btree.3 b/db/man/btree.3 new file mode 120000 index 0000000..caa7263 --- /dev/null +++ b/db/man/btree.3 @@ -0,0 +1 @@ +./btree.3 \ No newline at end of file diff --git a/db/man/dbm.3 b/db/man/dbm.3 new file mode 100644 index 0000000..0e2f3a7 --- /dev/null +++ b/db/man/dbm.3 @@ -0,0 +1,280 @@ +.\" Copyright (c) 1999 Tim Singletary +.\" No copyright is claimed. +.\" +.\" 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/db/man/dbm.3,v 1.8 2003/09/08 19:57:13 ru Exp $ +.\" +.\" Note: The date here should be updated whenever a non-trivial +.\" change is made to the manual page. +.Dd July 7, 1999 +.Dt DBM 3 +.Os +.Sh NAME +.Nm dbm_clearerr , +.Nm dbm_close , +.Nm dbm_delete , +.Nm dbm_dirfno , +.Nm dbm_error , +.Nm dbm_fetch , +.Nm dbm_firstkey , +.Nm dbm_nextkey , +.Nm dbm_open , +.Nm dbm_store +.Nd database access functions +.Sh SYNOPSIS +.In ndbm.h +.Ft int +.Fo dbm_clearerr +.Fa "DBM *db" +.Fc +.Ft void +.Fo dbm_close +.Fa "DBM *db" +.Fc +.Ft int +.Fo dbm_delete +.Fa "DBM *db" +.Fa "datum key" +.Fc +.Ft int +.Fo dbm_dirfno +.Fa "DBM *db" +.Fc +.Ft int +.Fo dbm_error +.Fa "DBM *db" +.Fc +.Ft datum +.Fo dbm_fetch +.Fa "DBM *db" +.Fa "datum key" +.Fc +.Ft datum +.Fo dbm_firstkey +.Fa "DBM *db" +.Fc +.Ft datum +.Fo dbm_nextkey +.Fa "DBM *db" +.Fc +.Ft DBM * +.Fo dbm_open +.Fa "const char *file" +.Fa "int open_flags" +.Fa "mode_t file_mode" +.Fc +.Ft int +.Fo dbm_store +.Fa "DBM *db" +.Fa "datum key" +.Fa "datum content" +.Fa "int store_mode" +.Fc +.Sh DESCRIPTION +Database access functions. +These functions are implemented using +.Xr dbopen 3 +with a +.Xr hash 3 +database. +.Pp +.Vt datum +is declared in +.In ndbm.h : +.Bd -literal +typedef struct { + char *dptr; + int dsize; +} datum; +.Ed +.Pp +The +.Fn dbm_open file open_flags file_mode +function +opens or creates a database file. +The +.Fa file +argument +is the basename of the file containing +the database; the actual database has a +.Pa .db +suffix. +I.e., if +.Fa file +is +.Qq Li /home/me/mystuff +then the actual database is in the file +.Pa /home/me/mystuff.db . +The +.Fa open_flags +and +.Fa file_mode +arguments +are passed to +.Xr open 2 . +.Pq Dv O_RDWR | O_CREAT +is a typical value for +.Fa open_flags ; +.Li 0660 +is a typical value for +.Fa file_mode . +.Dv O_WRONLY +is treated as O_RDWR in +.Fa open_flags . +The pointer returned by +.Fn dbm_open +identifies the database and is the +.Fa db +argument to the other functions. +The +.Fn dbm_open +function +returns +.Dv NULL +and sets +.Va errno +if there were any errors. +.Pp +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 +function +inserts or replaces an entry in the database. +The +.Fa store_mode +argument +is either +.Dv DBM_INSERT +or +.Dv DBM_REPLACE . +If +.Fa store_mode +is +.Dv DBM_INSERT +and the database already contains an entry for +.Fa key , +that entry is not replaced. +Otherwise the entry is replaced or inserted. +The +.Fn dbm_store +function +normally returns zero but returns 1 if the entry could not be +inserted (because +.Fa store_mode +is +.Dv DBM_INSERT , +and an entry with +.Fa key +already exists) or returns -1 and sets +.Va errno +if there were any errors. +.Pp +The +.Fn dbm_fetch db key +function +returns +.Dv NULL +or the +.Fa content +corresponding to +.Fa key . +.Pp +The +.Fn dbm_delete db key +function +deletes the entry for +.Fa key . +The +.Fn dbm_delete +function +normally returns zero but returns 1 if there was no entry with +.Fa key +in the database or returns -1 and sets +.Va errno +if there were any errors. +.Pp +The +.Fn dbm_firstkey db +function +returns the first key in the database. +The +.Fn dbm_nextkey db +function +returns subsequent keys. +The +.Fn db_firstkey +function +must be called before +.Fn dbm_nextkey . +The order in which keys are returned is unspecified and may appear +random. +The +.Fn dbm_nextkey +function +returns +.Dv NULL +after all keys have been returned. +.Pp +The +.Fn dbm_error db +function +returns the +.Va errno +value of the most recent error. +The +.Fn dbm_clearerr db +function +resets this value to 0 and returns 0. +.Pp +The +.Fn dbm_dirfno db +function +returns the file descriptor to the database. +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +The include file +.In ndbm.h +is necessary for all functions. +.Pp +.Ft DBM * +.br +.Fo dbm_open +.Fa "const char *file" +.Fa "int open_flags" +.Fa "int file_mode" +.Fc ; +.Pp +.Fa file_mode +has type +.Vt int . +.Sh SEE ALSO +.Xr open 2 , +.Xr dbopen 3 , +.Xr hash 3 , +.Xr compat 5 +.Sh STANDARDS +These functions (except +.Fn dbm_dirfno ) +are included in the +.St -susv2 . diff --git a/db/man/dbopen.3 b/db/man/dbopen.3 new file mode 120000 index 0000000..25b88f0 --- /dev/null +++ b/db/man/dbopen.3 @@ -0,0 +1 @@ +./dbopen.3 \ No newline at end of file diff --git a/db/man/hash.3 b/db/man/hash.3 new file mode 120000 index 0000000..4158259 --- /dev/null +++ b/db/man/hash.3 @@ -0,0 +1 @@ +./hash.3 \ No newline at end of file diff --git a/db/man/mpool.3 b/db/man/mpool.3 new file mode 120000 index 0000000..b15f332 --- /dev/null +++ b/db/man/mpool.3 @@ -0,0 +1 @@ +./mpool.3 \ No newline at end of file diff --git a/db/man/recno.3 b/db/man/recno.3 new file mode 120000 index 0000000..346f3e2 --- /dev/null +++ b/db/man/recno.3 @@ -0,0 +1 @@ +./recno.3 \ No newline at end of file diff --git a/db/mpool/FreeBSD/mpool.c.patch b/db/mpool/FreeBSD/mpool.c.patch index 285ef07..ac39fe9 100644 --- a/db/mpool/FreeBSD/mpool.c.patch +++ b/db/mpool/FreeBSD/mpool.c.patch @@ -13,7 +13,7 @@ + if (mpool_write(mp, bp) == RET_ERROR) { + return (RET_ERROR); + } else { -+ /* 5126974: Re-run through the user's pgin filter. */ ++ /* 4874757: Re-run through the user's pgin filter. */ + if (mp->pgin != NULL) + (mp->pgin)(mp->pgcookie, bp->pgno, bp->page); + } diff --git a/db/mpool/Makefile.inc b/db/mpool/Makefile.inc index 96c5c75..e3ecef0 100644 --- a/db/mpool/Makefile.inc +++ b/db/mpool/Makefile.inc @@ -8,4 +8,7 @@ FBSDMISRCS= mpool.c .for _src in ${FBSDMISRCS} CFLAGS-${_src:R}-fbsd.${_src:E} += -D__DBINTERFACE_PRIVATE .endfor +.for _src in mpool.c +CFLAGS-${_src:R}-fbsd.${_src:E} += -UDEBUG +.endfor .include "Makefile.fbsd_end" diff --git a/db/mpool/mpool-fbsd.c b/db/mpool/mpool-fbsd.c new file mode 100644 index 0000000..0a697ad --- /dev/null +++ b/db/mpool/mpool-fbsd.c @@ -0,0 +1,468 @@ +/*- + * Copyright (c) 1990, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include + +#define __MPOOLINTERFACE_PRIVATE +#include + +static BKT *mpool_bkt(MPOOL *); +static BKT *mpool_look(MPOOL *, pgno_t); +static int mpool_write(MPOOL *, BKT *); + +/* + * mpool_open -- + * Initialize a memory pool. + */ +MPOOL * +mpool_open(key, fd, pagesize, maxcache) + void *key; + int fd; + pgno_t pagesize, maxcache; +{ + struct stat sb; + MPOOL *mp; + int entry; + + /* + * Get information about the file. + * + * XXX + * We don't currently handle pipes, although we should. + */ + if (_fstat(fd, &sb)) + return (NULL); + if (!S_ISREG(sb.st_mode)) { + errno = ESPIPE; + return (NULL); + } + + /* Allocate and initialize the MPOOL cookie. */ + if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL) + return (NULL); + TAILQ_INIT(&mp->lqh); + for (entry = 0; entry < HASHSIZE; ++entry) + TAILQ_INIT(&mp->hqh[entry]); + mp->maxcache = maxcache; + mp->npages = sb.st_size / pagesize; + mp->pagesize = pagesize; + mp->fd = fd; + return (mp); +} + +/* + * mpool_filter -- + * 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; +{ + mp->pgin = pgin; + mp->pgout = pgout; + mp->pgcookie = pgcookie; +} + +/* + * mpool_new -- + * Get a new page of memory. + */ +void * +mpool_new(mp, pgnoaddr) + MPOOL *mp; + pgno_t *pgnoaddr; +{ + struct _hqh *head; + BKT *bp; + + if (mp->npages == MAX_PAGE_NUMBER) { + (void)fprintf(stderr, "mpool_new: page allocation overflow.\n"); + abort(); + } +#ifdef STATISTICS + ++mp->pagenew; +#endif + /* + * Get a BKT from the cache. Assign a new page number, attach + * it to the head of the hash chain, the tail of the lru chain, + * and return. + */ + if ((bp = mpool_bkt(mp)) == NULL) + return (NULL); + *pgnoaddr = bp->pgno = mp->npages++; + bp->flags = MPOOL_PINNED; + + head = &mp->hqh[HASHKEY(bp->pgno)]; + TAILQ_INSERT_HEAD(head, bp, hq); + TAILQ_INSERT_TAIL(&mp->lqh, bp, q); + return (bp->page); +} + +/* + * mpool_get + * Get a page. + */ +void * +mpool_get(mp, pgno, flags) + MPOOL *mp; + pgno_t pgno; + u_int flags; /* XXX not used? */ +{ + struct _hqh *head; + BKT *bp; + off_t off; + int nr; + + /* Check for attempt to retrieve a non-existent page. */ + if (pgno >= mp->npages) { + errno = EINVAL; + return (NULL); + } + +#ifdef STATISTICS + ++mp->pageget; +#endif + + /* Check for a page that is cached. */ + if ((bp = mpool_look(mp, pgno)) != NULL) { +#ifdef DEBUG + if (bp->flags & MPOOL_PINNED) { + (void)fprintf(stderr, + "mpool_get: page %d already pinned\n", bp->pgno); + abort(); + } +#endif + /* + * Move the page to the head of the hash chain and the tail + * of the lru chain. + */ + head = &mp->hqh[HASHKEY(bp->pgno)]; + TAILQ_REMOVE(head, bp, hq); + TAILQ_INSERT_HEAD(head, bp, hq); + TAILQ_REMOVE(&mp->lqh, bp, q); + TAILQ_INSERT_TAIL(&mp->lqh, bp, q); + + /* Return a pinned page. */ + bp->flags |= MPOOL_PINNED; + return (bp->page); + } + + /* Get a page from the cache. */ + if ((bp = mpool_bkt(mp)) == NULL) + return (NULL); + + /* Read in the contents. */ +#ifdef STATISTICS + ++mp->pageread; +#endif + off = mp->pagesize * pgno; + nr = pread(mp->fd, bp->page, mp->pagesize, off); + if (nr != mp->pagesize) { + if (nr >= 0) + errno = EFTYPE; + return (NULL); + } + + /* Set the page number, pin the page. */ + bp->pgno = pgno; + bp->flags = MPOOL_PINNED; + + /* + * Add the page to the head of the hash chain and the tail + * of the lru chain. + */ + head = &mp->hqh[HASHKEY(bp->pgno)]; + TAILQ_INSERT_HEAD(head, bp, hq); + TAILQ_INSERT_TAIL(&mp->lqh, bp, q); + + /* Run through the user's filter. */ + if (mp->pgin != NULL) + (mp->pgin)(mp->pgcookie, bp->pgno, bp->page); + + return (bp->page); +} + +/* + * mpool_put + * Return a page. + */ +int +mpool_put(mp, page, flags) + MPOOL *mp; + void *page; + u_int flags; +{ + BKT *bp; + +#ifdef STATISTICS + ++mp->pageput; +#endif + bp = (BKT *)((char *)page - sizeof(BKT)); +#ifdef DEBUG + if (!(bp->flags & MPOOL_PINNED)) { + (void)fprintf(stderr, + "mpool_put: page %d not pinned\n", bp->pgno); + abort(); + } +#endif + bp->flags &= ~MPOOL_PINNED; + bp->flags |= flags & MPOOL_DIRTY; + return (RET_SUCCESS); +} + +/* + * mpool_close + * Close the buffer pool. + */ +int +mpool_close(mp) + MPOOL *mp; +{ + BKT *bp; + + /* Free up any space allocated to the lru pages. */ + while (!TAILQ_EMPTY(&mp->lqh)) { + bp = TAILQ_FIRST(&mp->lqh); + TAILQ_REMOVE(&mp->lqh, bp, q); + free(bp); + } + + /* Free the MPOOL cookie. */ + free(mp); + return (RET_SUCCESS); +} + +/* + * mpool_sync + * Sync the pool to disk. + */ +int +mpool_sync(mp) + MPOOL *mp; +{ + BKT *bp; + + /* Walk the lru chain, flushing any dirty pages to disk. */ + TAILQ_FOREACH(bp, &mp->lqh, q) { + if (bp->flags & MPOOL_DIRTY) + if (mpool_write(mp, bp) == RET_ERROR) { + return (RET_ERROR); + } else { + /* 4874757: Re-run through the user's pgin filter. */ + if (mp->pgin != NULL) + (mp->pgin)(mp->pgcookie, bp->pgno, bp->page); + } + } + + /* Sync the file descriptor. */ + return (_fsync(mp->fd) ? RET_ERROR : RET_SUCCESS); +} + +/* + * mpool_bkt + * Get a page from the cache (or create one). + */ +static BKT * +mpool_bkt(mp) + MPOOL *mp; +{ + struct _hqh *head; + BKT *bp; + + /* If under the max cached, always create a new page. */ + if (mp->curcache < mp->maxcache) + goto new; + + /* + * If the cache is max'd out, walk the lru list for a buffer we + * can flush. If we find one, write it (if necessary) and take it + * off any lists. If we don't find anything we grow the cache anyway. + * The cache never shrinks. + */ + TAILQ_FOREACH(bp, &mp->lqh, q) + if (!(bp->flags & MPOOL_PINNED)) { + /* Flush if dirty. */ + if (bp->flags & MPOOL_DIRTY && + mpool_write(mp, bp) == RET_ERROR) + return (NULL); +#ifdef STATISTICS + ++mp->pageflush; +#endif + /* Remove from the hash and lru queues. */ + head = &mp->hqh[HASHKEY(bp->pgno)]; + TAILQ_REMOVE(head, bp, hq); + TAILQ_REMOVE(&mp->lqh, bp, q); +#ifdef DEBUG + { void *spage; + spage = bp->page; + memset(bp, 0xff, sizeof(BKT) + mp->pagesize); + bp->page = spage; + } +#endif + return (bp); + } + +new: if ((bp = (BKT *)malloc(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; + return (bp); +} + +/* + * mpool_write + * Write a page to disk. + */ +static int +mpool_write(mp, bp) + MPOOL *mp; + BKT *bp; +{ + off_t off; + +#ifdef STATISTICS + ++mp->pagewrite; +#endif + + /* Run through the user's filter. */ + if (mp->pgout) + (mp->pgout)(mp->pgcookie, bp->pgno, bp->page); + + off = mp->pagesize * bp->pgno; + if (pwrite(mp->fd, bp->page, mp->pagesize, off) != mp->pagesize) + return (RET_ERROR); + + bp->flags &= ~MPOOL_DIRTY; + return (RET_SUCCESS); +} + +/* + * mpool_look + * Lookup a page in the cache. + */ +static BKT * +mpool_look(mp, pgno) + MPOOL *mp; + pgno_t pgno; +{ + struct _hqh *head; + BKT *bp; + + head = &mp->hqh[HASHKEY(pgno)]; + TAILQ_FOREACH(bp, head, hq) + if (bp->pgno == pgno) { +#ifdef STATISTICS + ++mp->cachehit; +#endif + return (bp); + } +#ifdef STATISTICS + ++mp->cachemiss; +#endif + return (NULL); +} + +#ifdef STATISTICS +/* + * mpool_stat + * Print out cache statistics. + */ +void +mpool_stat(mp) + MPOOL *mp; +{ + BKT *bp; + int cnt; + char *sep; + + (void)fprintf(stderr, "%u pages in the file\n", mp->npages); + (void)fprintf(stderr, + "page size %lu, cacheing %u pages of %u 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); + (void)fprintf(stderr, "%lu page allocs, %lu page flushes\n", + mp->pagealloc, mp->pageflush); + if (mp->cachehit + mp->cachemiss) + (void)fprintf(stderr, + "%.0f%% cache hit rate (%lu hits, %lu misses)\n", + ((double)mp->cachehit / (mp->cachehit + mp->cachemiss)) + * 100, mp->cachehit, mp->cachemiss); + (void)fprintf(stderr, "%lu page reads, %lu page writes\n", + mp->pageread, mp->pagewrite); + + sep = ""; + cnt = 0; + TAILQ_FOREACH(bp, &mp->lqh, q) { + (void)fprintf(stderr, "%s%d", sep, bp->pgno); + if (bp->flags & MPOOL_DIRTY) + (void)fprintf(stderr, "d"); + if (bp->flags & MPOOL_PINNED) + (void)fprintf(stderr, "P"); + if (++cnt == 10) { + sep = "\n"; + cnt = 0; + } else + sep = ", "; + + } + (void)fprintf(stderr, "\n"); +} +#endif diff --git a/db/recno/FreeBSD/extern.h.patch b/db/recno/FreeBSD/extern.h.patch index c0bce23..9a200e8 100644 --- a/db/recno/FreeBSD/extern.h.patch +++ b/db/recno/FreeBSD/extern.h.patch @@ -5,7 +5,7 @@ */ -#include "../btree/extern.h" -+#include "bt_extern.h" ++#include "../btree/bt_extern.h" int __rec_close(DB *); int __rec_delete(const DB *, const DBT *, u_int); diff --git a/db/recno/FreeBSD/recno.h.patch b/db/recno/FreeBSD/recno.h.patch index a3d1ec3..0226317 100644 --- a/db/recno/FreeBSD/recno.h.patch +++ b/db/recno/FreeBSD/recno.h.patch @@ -1,10 +1,8 @@ ---- recno.h.orig Fri Mar 22 15:41:40 2002 -+++ recno.h Sat Oct 18 19:48:16 2003 -@@ -36,5 +36,5 @@ - +--- 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 @@ enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */ --#include "../btree/btree.h" + #include "../btree/btree.h" -#include "extern.h" -+#include "btree.h" +#include "rec_extern.h" diff --git a/db/recno/Makefile.inc b/db/recno/Makefile.inc index f1de47b..70f2236 100644 --- a/db/recno/Makefile.inc +++ b/db/recno/Makefile.inc @@ -13,5 +13,7 @@ FBSDHDRS= recno.h .include "Makefile.fbsd_end" # need to rename extern.h to make it unique -${SYMROOT}/rec_extern.h: ${.CURDIR}/db/recno/FreeBSD/extern.h _AUTOPATCHSYM -AUTOPATCHHDRS+= ${SYMROOT}/rec_extern.h +.ifmake autopatch +rec_extern.h: FreeBSD/extern.h _AUTOPATCHCUR +AUTOPATCHHDRS+= rec_extern.h +.endif # autopatch diff --git a/db/recno/rec_close-fbsd.c b/db/recno/rec_close-fbsd.c new file mode 100644 index 0000000..fea96ae --- /dev/null +++ b/db/recno/rec_close-fbsd.c @@ -0,0 +1,188 @@ +/*- + * Copyright (c) 1990, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include + +#include +#include +#include +#include +#include "un-namespace.h" + +#include +#include "recno.h" + +/* + * __REC_CLOSE -- Close a recno tree. + * + * Parameters: + * dbp: pointer to access method + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_close(dbp) + DB *dbp; +{ + BTREE *t; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + if (__rec_sync(dbp, 0) == RET_ERROR) + return (RET_ERROR); + + /* Committed to closing. */ + status = RET_SUCCESS; + if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize)) + status = RET_ERROR; + + if (!F_ISSET(t, R_INMEM)) { + if (F_ISSET(t, R_CLOSEFP)) { + if (fclose(t->bt_rfp)) + status = RET_ERROR; + } else + if (_close(t->bt_rfd)) + status = RET_ERROR; + } + + if (__bt_close(dbp) == RET_ERROR) + status = RET_ERROR; + + return (status); +} + +/* + * __REC_SYNC -- sync the recno tree to disk. + * + * Parameters: + * dbp: pointer to access method + * + * Returns: + * RET_SUCCESS, RET_ERROR. + */ +int +__rec_sync(dbp, flags) + const DB *dbp; + u_int flags; +{ + struct iovec iov[2]; + BTREE *t; + DBT data, key; + off_t off; + recno_t scursor, trec; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + if (flags == R_RECNOSYNC) + return (__bt_sync(dbp, 0)); + + if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED)) + return (RET_SUCCESS); + + /* Read any remaining records into the tree. */ + if (!F_ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) + return (RET_ERROR); + + /* Rewind the file descriptor. */ + if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0) + return (RET_ERROR); + + /* Save the cursor. */ + scursor = t->bt_cursor.rcursor; + + key.size = sizeof(recno_t); + key.data = &trec; + + if (F_ISSET(t, R_FIXLEN)) { + /* + * We assume that fixed length records are all fixed length. + * Any that aren't are either EINVAL'd or corrected by the + * record put code. + */ + status = (dbp->seq)(dbp, &key, &data, R_FIRST); + while (status == RET_SUCCESS) { + if (_write(t->bt_rfd, data.data, data.size) != + 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_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) + return (RET_ERROR); + status = (dbp->seq)(dbp, &key, &data, R_NEXT); + } + } + + /* Restore the cursor. */ + t->bt_cursor.rcursor = scursor; + + if (status == RET_ERROR) + return (RET_ERROR); + if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1) + return (RET_ERROR); + if (ftruncate(t->bt_rfd, off)) + return (RET_ERROR); + F_CLR(t, R_MODIFIED); + return (RET_SUCCESS); +} diff --git a/db/recno/rec_delete-fbsd.c b/db/recno/rec_delete-fbsd.c new file mode 100644 index 0000000..1205594 --- /dev/null +++ b/db/recno/rec_delete-fbsd.c @@ -0,0 +1,199 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include + +#include +#include +#include + +#include +#include "recno.h" + +static int rec_rdelete(BTREE *, recno_t); + +/* + * __REC_DELETE -- Delete the item(s) referenced by a key. + * + * Parameters: + * dbp: pointer to access method + * key: key to delete + * flags: R_CURSOR if deleting what the cursor references + * + * Returns: + * 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; +{ + BTREE *t; + recno_t nrec; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + switch(flags) { + case 0: + if ((nrec = *(recno_t *)key->data) == 0) + goto einval; + if (nrec > t->bt_nrecs) + return (RET_SPECIAL); + --nrec; + status = rec_rdelete(t, nrec); + break; + case R_CURSOR: + if (!F_ISSET(&t->bt_cursor, CURS_INIT)) + goto einval; + if (t->bt_nrecs == 0) + return (RET_SPECIAL); + status = rec_rdelete(t, t->bt_cursor.rcursor - 1); + if (status == RET_SUCCESS) + --t->bt_cursor.rcursor; + break; + default: +einval: errno = EINVAL; + return (RET_ERROR); + } + + if (status == RET_SUCCESS) + F_SET(t, B_MODIFIED | R_MODIFIED); + return (status); +} + +/* + * REC_RDELETE -- Delete the data matching the specified key. + * + * Parameters: + * tree: tree + * nrec: record to delete + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. + */ +static int +rec_rdelete(t, nrec) + BTREE *t; + recno_t nrec; +{ + EPG *e; + PAGE *h; + int status; + + /* Find the record; __rec_search pins the page. */ + if ((e = __rec_search(t, nrec, SDELETE)) == NULL) + return (RET_ERROR); + + /* Delete the record. */ + h = e->page; + status = __rec_dleaf(t, h, e->index); + if (status != RET_SUCCESS) { + mpool_put(t->bt_mp, h, 0); + return (status); + } + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + return (RET_SUCCESS); +} + +/* + * __REC_DLEAF -- Delete a single record from a recno leaf page. + * + * Parameters: + * t: tree + * index: 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; +{ + RLEAF *rl; + indx_t *ip, cnt, offset; + u_int32_t nbytes; + char *from; + void *to; + + /* + * Delete a record from a recno leaf page. Internal records are never + * deleted from internal pages, regardless of the records that caused + * them to be added being deleted. Pages made empty by deletion are + * not reclaimed. They are, however, made available for reuse. + * + * Pack the remaining entries at the end of the page, shift the indices + * down, overwriting the deleted record and its index. If the record + * uses overflow pages, make them available for reuse. + */ + to = rl = GETRLEAF(h, index); + if (rl->flags & P_BIGDATA && __ovfl_delete(t, rl->bytes) == RET_ERROR) + return (RET_ERROR); + nbytes = NRLEAF(rl); + + /* + * Compress the key/data pairs. Compress and adjust the [BR]LEAF + * offsets. Reset the headers. + */ + from = (char *)h + h->upper; + 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) + if (ip[0] < offset) + ip[0] += nbytes; + for (cnt = &h->linp[NEXTINDEX(h)] - ip; --cnt; ++ip) + ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1]; + h->lower -= sizeof(indx_t); + --t->bt_nrecs; + return (RET_SUCCESS); +} diff --git a/db/recno/rec_extern.h b/db/recno/rec_extern.h new file mode 100644 index 0000000..a0e37cb --- /dev/null +++ b/db/recno/rec_extern.h @@ -0,0 +1,55 @@ +/*- + * 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. + * + * @(#)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 $ + */ + +#include "../btree/bt_extern.h" + +int __rec_close(DB *); +int __rec_delete(const DB *, const DBT *, u_int); +int __rec_dleaf(BTREE *, PAGE *, u_int32_t); +int __rec_fd(const DB *); +int __rec_fmap(BTREE *, recno_t); +int __rec_fout(BTREE *); +int __rec_fpipe(BTREE *, recno_t); +int __rec_get(const DB *, const DBT *, DBT *, u_int); +int __rec_iput(BTREE *, recno_t, const DBT *, u_int); +int __rec_put(const DB *dbp, DBT *, const DBT *, u_int); +int __rec_ret(BTREE *, EPG *, recno_t, DBT *, DBT *); +EPG *__rec_search(BTREE *, recno_t, enum SRCHOP); +int __rec_seq(const DB *, DBT *, DBT *, u_int); +int __rec_sync(const DB *, u_int); +int __rec_vmap(BTREE *, recno_t); +int __rec_vout(BTREE *); +int __rec_vpipe(BTREE *, recno_t); diff --git a/db/recno/rec_get-fbsd.c b/db/recno/rec_get-fbsd.c new file mode 100644 index 0000000..d9da658 --- /dev/null +++ b/db/recno/rec_get-fbsd.c @@ -0,0 +1,313 @@ +/*- + * Copyright (c) 1990, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "recno.h" + +/* + * __REC_GET -- Get a record from the btree. + * + * Parameters: + * dbp: pointer to access method + * key: key to find + * data: data to return + * flag: currently unused + * + * Returns: + * 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; +{ + BTREE *t; + EPG *e; + recno_t nrec; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Get currently doesn't take any flags, and keys of 0 are illegal. */ + if (flags || (nrec = *(recno_t *)key->data) == 0) { + errno = EINVAL; + return (RET_ERROR); + } + + /* + * If we haven't seen this record yet, try to find it in the + * original file. + */ + if (nrec > t->bt_nrecs) { + if (F_ISSET(t, R_EOF | R_INMEM)) + return (RET_SPECIAL); + if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS) + return (status); + } + + --nrec; + if ((e = __rec_search(t, nrec, SEARCH)) == NULL) + return (RET_ERROR); + + status = __rec_ret(t, e, 0, NULL, data); + if (F_ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e->page, 0); + else + t->bt_pinned = e->page; + return (status); +} + +/* + * __REC_FPIPE -- Get fixed length records from a pipe. + * + * Parameters: + * t: tree + * cnt: records to read + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_fpipe(t, top) + BTREE *t; + recno_t top; +{ + DBT data; + recno_t nrec; + size_t len; + int ch; + 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); + if (t->bt_rdata.data == NULL) + return (RET_ERROR); + t->bt_rdata.size = t->bt_reclen; + } + data.data = t->bt_rdata.data; + data.size = t->bt_reclen; + + for (nrec = t->bt_nrecs; nrec < top;) { + len = t->bt_reclen; + for (p = t->bt_rdata.data;; *p++ = ch) + if ((ch = getc(t->bt_rfp)) == EOF || !--len) { + if (ch != EOF) + *p = ch; + if (len != 0) + memset(p, t->bt_bval, len); + if (__rec_iput(t, + nrec, &data, 0) != RET_SUCCESS) + return (RET_ERROR); + ++nrec; + break; + } + if (ch == EOF) + break; + } + if (nrec < top) { + F_SET(t, R_EOF); + return (RET_SPECIAL); + } + return (RET_SUCCESS); +} + +/* + * __REC_VPIPE -- Get variable length records from a pipe. + * + * Parameters: + * t: tree + * cnt: records to read + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_vpipe(t, top) + BTREE *t; + recno_t top; +{ + DBT data; + recno_t nrec; + size_t len; + size_t sz; + int bval, ch; + u_char *p; + + bval = t->bt_bval; + for (nrec = t->bt_nrecs; nrec < top; ++nrec) { + for (p = t->bt_rdata.data, + sz = t->bt_rdata.size;; *p++ = ch, --sz) { + if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) { + data.data = t->bt_rdata.data; + data.size = p - (u_char *)t->bt_rdata.data; + if (ch == EOF && data.size == 0) + break; + if (__rec_iput(t, nrec, &data, 0) + != RET_SUCCESS) + return (RET_ERROR); + break; + } + 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); + if (t->bt_rdata.data == NULL) + return (RET_ERROR); + p = (u_char *)t->bt_rdata.data + len; + } + } + if (ch == EOF) + break; + } + if (nrec < top) { + F_SET(t, R_EOF); + return (RET_SPECIAL); + } + return (RET_SUCCESS); +} + +/* + * __REC_FMAP -- Get fixed length records from a file. + * + * Parameters: + * t: tree + * cnt: records to read + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_fmap(t, top) + BTREE *t; + recno_t top; +{ + DBT data; + recno_t nrec; + u_char *sp, *ep, *p; + 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); + if (t->bt_rdata.data == NULL) + return (RET_ERROR); + t->bt_rdata.size = t->bt_reclen; + } + data.data = t->bt_rdata.data; + data.size = t->bt_reclen; + + sp = (u_char *)t->bt_cmap; + ep = (u_char *)t->bt_emap; + for (nrec = t->bt_nrecs; nrec < top; ++nrec) { + if (sp >= ep) { + F_SET(t, R_EOF); + return (RET_SPECIAL); + } + len = t->bt_reclen; + for (p = t->bt_rdata.data; + sp < ep && len > 0; *p++ = *sp++, --len); + if (len != 0) + memset(p, t->bt_bval, len); + if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) + return (RET_ERROR); + } + t->bt_cmap = (caddr_t)sp; + return (RET_SUCCESS); +} + +/* + * __REC_VMAP -- Get variable length records from a file. + * + * Parameters: + * t: tree + * cnt: records to read + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_vmap(t, top) + BTREE *t; + recno_t top; +{ + DBT data; + u_char *sp, *ep; + recno_t nrec; + int bval; + + sp = (u_char *)t->bt_cmap; + ep = (u_char *)t->bt_emap; + bval = t->bt_bval; + + for (nrec = t->bt_nrecs; nrec < top; ++nrec) { + if (sp >= ep) { + F_SET(t, R_EOF); + return (RET_SPECIAL); + } + for (data.data = sp; sp < ep && *sp != bval; ++sp); + data.size = sp - (u_char *)data.data; + if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) + return (RET_ERROR); + ++sp; + } + t->bt_cmap = (caddr_t)sp; + return (RET_SUCCESS); +} diff --git a/db/recno/rec_open-fbsd.c b/db/recno/rec_open-fbsd.c new file mode 100644 index 0000000..a431f6f --- /dev/null +++ b/db/recno/rec_open-fbsd.c @@ -0,0 +1,245 @@ +/*- + * 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 + * Mike Olson. + * + * 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include +#include "recno.h" + +DB * +__rec_open(fname, flags, mode, openinfo, dflags) + const char *fname; + int flags, mode, dflags; + const RECNOINFO *openinfo; +{ + BTREE *t; + BTREEINFO btopeninfo; + DB *dbp; + PAGE *h; + struct stat sb; + int rfd, sverrno; + + /* Open the user's file -- if this fails, we're done. */ + if (fname != NULL && (rfd = _open(fname, flags, mode)) < 0) + return (NULL); + + /* Create a btree in memory (backed by disk). */ + dbp = NULL; + if (openinfo) { + if (openinfo->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT)) + goto einval; + btopeninfo.flags = 0; + btopeninfo.cachesize = openinfo->cachesize; + btopeninfo.maxkeypage = 0; + btopeninfo.minkeypage = 0; + btopeninfo.psize = openinfo->psize; + btopeninfo.compare = NULL; + btopeninfo.prefix = NULL; + btopeninfo.lorder = openinfo->lorder; + dbp = __bt_open(openinfo->bfname, + O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo, dflags); + } else + dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL, dflags); + if (dbp == NULL) + goto err; + + /* + * Some fields in the tree structure are recno specific. Fill them + * in and make the btree structure look like a recno structure. We + * don't change the bt_ovflsize value, it's close enough and slightly + * bigger. + */ + t = dbp->internal; + if (openinfo) { + if (openinfo->flags & R_FIXEDLEN) { + F_SET(t, R_FIXLEN); + t->bt_reclen = openinfo->reclen; + if (t->bt_reclen == 0) + goto einval; + } + t->bt_bval = openinfo->bval; + } else + t->bt_bval = '\n'; + + F_SET(t, R_RECNO); + if (fname == NULL) + F_SET(t, R_EOF | R_INMEM); + else + t->bt_rfd = rfd; + + if (fname != NULL) { + /* + * In 4.4BSD, stat(2) returns true for ISSOCK on pipes. + * Unfortunately, that's not portable, so we use lseek + * and check the errno values. + */ + errno = 0; + if (lseek(rfd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) { + switch (flags & O_ACCMODE) { + case O_RDONLY: + F_SET(t, R_RDONLY); + break; + default: + goto einval; + } +slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL) + goto err; + F_SET(t, R_CLOSEFP); + t->bt_irec = + F_ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe; + } else { + switch (flags & O_ACCMODE) { + case O_RDONLY: + F_SET(t, R_RDONLY); + break; + case O_RDWR: + break; + default: + goto einval; + } + + if (_fstat(rfd, &sb)) + goto err; + /* + * Kluge -- we'd like to test to see if the file is too + * big to mmap. Since, we don't know what size or type + * off_t's or size_t's are, what the largest unsigned + * integral type is, or what random insanity the local + * C compiler will perpetrate, doing the comparison in + * a portable way is flatly impossible. Hope that mmap + * fails if the file is too large. + */ + if (sb.st_size == 0) + F_SET(t, R_EOF); + else { +#ifdef MMAP_NOT_AVAILABLE + /* + * XXX + * Mmap doesn't work correctly on many current + * systems. In particular, it can fail subtly, + * with cache coherency problems. Don't use it + * for now. + */ + t->bt_msize = sb.st_size; + if ((t->bt_smap = mmap(NULL, t->bt_msize, + PROT_READ, MAP_PRIVATE, rfd, + (off_t)0)) == MAP_FAILED) + goto slow; + t->bt_cmap = t->bt_smap; + t->bt_emap = t->bt_smap + sb.st_size; + t->bt_irec = F_ISSET(t, R_FIXLEN) ? + __rec_fmap : __rec_vmap; + F_SET(t, R_MEMMAPPED); +#else + goto slow; +#endif + } + } + } + + /* Use the recno routines. */ + dbp->close = __rec_close; + dbp->del = __rec_delete; + dbp->fd = __rec_fd; + dbp->get = __rec_get; + dbp->put = __rec_put; + dbp->seq = __rec_seq; + dbp->sync = __rec_sync; + + /* If the root page was created, reset the flags. */ + if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL) + goto err; + if ((h->flags & P_TYPE) == P_BLEAF) { + F_CLR(h, P_TYPE); + F_SET(h, P_RLEAF); + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + } else + mpool_put(t->bt_mp, h, 0); + + if (openinfo && openinfo->flags & R_SNAPSHOT && + !F_ISSET(t, R_EOF | R_INMEM) && + t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) + goto err; + return (dbp); + +einval: errno = EINVAL; +err: sverrno = errno; + if (dbp != NULL) + (void)__bt_close(dbp); + if (fname != NULL) + (void)_close(rfd); + errno = sverrno; + return (NULL); +} + +int +__rec_fd(dbp) + const DB *dbp; +{ + BTREE *t; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* In-memory database can't have a file descriptor. */ + if (F_ISSET(t, R_INMEM)) { + errno = ENOENT; + return (-1); + } + return (t->bt_rfd); +} diff --git a/db/recno/rec_put-fbsd.c b/db/recno/rec_put-fbsd.c new file mode 100644 index 0000000..14cc811 --- /dev/null +++ b/db/recno/rec_put-fbsd.c @@ -0,0 +1,287 @@ +/*- + * Copyright (c) 1990, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +#include +#include +#include +#include + +#include +#include "recno.h" + +/* + * __REC_PUT -- Add a recno item to the tree. + * + * Parameters: + * dbp: pointer to access method + * key: key + * data: data + * flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE + * + * Returns: + * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is + * 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; +{ + BTREE *t; + DBT fdata, tdata; + recno_t nrec; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* + * If using fixed-length records, and the record is long, return + * EINVAL. If it's short, pad it out. Use the record data return + * memory, it's only short-term. + */ + if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) { + if (data->size > t->bt_reclen) + goto einval; + + if (t->bt_rdata.size < 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; + } + memmove(t->bt_rdata.data, data->data, data->size); + memset((char *)t->bt_rdata.data + data->size, + t->bt_bval, t->bt_reclen - data->size); + fdata.data = t->bt_rdata.data; + fdata.size = t->bt_reclen; + } else { + fdata.data = data->data; + fdata.size = data->size; + } + + switch (flags) { + case R_CURSOR: + if (!F_ISSET(&t->bt_cursor, CURS_INIT)) + goto einval; + nrec = t->bt_cursor.rcursor; + break; + case R_SETCURSOR: + if ((nrec = *(recno_t *)key->data) == 0) + goto einval; + break; + case R_IAFTER: + if ((nrec = *(recno_t *)key->data) == 0) { + nrec = 1; + flags = R_IBEFORE; + } + break; + case 0: + case R_IBEFORE: + if ((nrec = *(recno_t *)key->data) == 0) + goto einval; + break; + case R_NOOVERWRITE: + if ((nrec = *(recno_t *)key->data) == 0) + goto einval; + if (nrec <= t->bt_nrecs) + return (RET_SPECIAL); + break; + default: +einval: errno = EINVAL; + return (RET_ERROR); + } + + /* + * Make sure that records up to and including the put record are + * already in the database. If skipping records, create empty ones. + */ + if (nrec > t->bt_nrecs) { + if (!F_ISSET(t, R_EOF | R_INMEM) && + t->bt_irec(t, nrec) == RET_ERROR) + return (RET_ERROR); + if (nrec > t->bt_nrecs + 1) { + if (F_ISSET(t, R_FIXLEN)) { + if ((tdata.data = + (void *)malloc(t->bt_reclen)) == NULL) + return (RET_ERROR); + tdata.size = t->bt_reclen; + memset(tdata.data, t->bt_bval, tdata.size); + } else { + tdata.data = NULL; + tdata.size = 0; + } + while (nrec > t->bt_nrecs + 1) + if (__rec_iput(t, + t->bt_nrecs, &tdata, 0) != RET_SUCCESS) + return (RET_ERROR); + if (F_ISSET(t, R_FIXLEN)) + free(tdata.data); + } + } + + if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS) + return (status); + + switch (flags) { + case R_IAFTER: + nrec++; + break; + case R_SETCURSOR: + t->bt_cursor.rcursor = nrec; + break; + } + + F_SET(t, R_MODIFIED); + return (__rec_ret(t, NULL, nrec, key, NULL)); +} + +/* + * __REC_IPUT -- Add a recno item to the tree. + * + * Parameters: + * t: tree + * nrec: record number + * data: data + * + * Returns: + * RET_ERROR, RET_SUCCESS + */ +int +__rec_iput(t, nrec, data, flags) + BTREE *t; + recno_t nrec; + const DBT *data; + u_int flags; +{ + DBT tdata; + EPG *e; + PAGE *h; + indx_t index, nxtindex; + pgno_t pg; + u_int32_t nbytes; + int dflags, status; + char *dest, db[NOVFLSIZE]; + + /* + * If the data won't fit on a page, store it on indirect pages. + * + * XXX + * If the insert fails later on, these pages aren't recovered. + */ + if (data->size > t->bt_ovflsize) { + if (__ovfl_put(t, data, &pg) == RET_ERROR) + return (RET_ERROR); + tdata.data = db; + tdata.size = NOVFLSIZE; + *(pgno_t *)db = pg; + *(u_int32_t *)(db + sizeof(pgno_t)) = data->size; + dflags = P_BIGDATA; + data = &tdata; + } else + dflags = 0; + + /* __rec_search pins the returned page. */ + if ((e = __rec_search(t, nrec, + nrec > t->bt_nrecs || flags == R_IAFTER || flags == R_IBEFORE ? + SINSERT : SEARCH)) == NULL) + return (RET_ERROR); + + h = e->page; + index = e->index; + + /* + * Add the specified key/data pair to the tree. The R_IAFTER and + * R_IBEFORE flags insert the key after/before the specified key. + * + * Pages are split as required. + */ + switch (flags) { + case R_IAFTER: + ++index; + break; + case R_IBEFORE: + break; + default: + if (nrec < t->bt_nrecs && + __rec_dleaf(t, h, index) == RET_ERROR) { + mpool_put(t->bt_mp, h, 0); + return (RET_ERROR); + } + break; + } + + /* + * If not enough room, split the page. The split code will insert + * the key and data and unpin the current page. If inserting into + * 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 (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)); + h->lower += sizeof(indx_t); + + h->linp[index] = h->upper -= nbytes; + dest = (char *)h + h->upper; + WR_RLEAF(dest, data, dflags); + + ++t->bt_nrecs; + F_SET(t, B_MODIFIED); + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + + return (RET_SUCCESS); +} diff --git a/db/recno/rec_search-fbsd.c b/db/recno/rec_search-fbsd.c new file mode 100644 index 0000000..3353bfb --- /dev/null +++ b/db/recno/rec_search-fbsd.c @@ -0,0 +1,128 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include + +#include +#include + +#include +#include "recno.h" + +/* + * __REC_SEARCH -- Search a btree for a key. + * + * Parameters: + * t: tree to search + * recno: key to find + * op: search operation + * + * Returns: + * EPG for matching record, if any, or the EPG for the location of the + * key, if it were inserted into the tree. + * + * Returns: + * The EPG for matching record, if any, or the EPG for the location + * of the key, if it were inserted into the tree, is entered into + * 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; +{ + indx_t index; + PAGE *h; + EPGNO *parent; + RINTERNAL *r; + pgno_t pg; + indx_t top; + recno_t total; + int sverrno; + + BT_CLR(t); + for (pg = P_ROOT, total = 0;;) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + goto err; + if (h->flags & P_RLEAF) { + t->bt_cur.page = h; + 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) + break; + total += r->nrecs; + } + + BT_PUSH(t, pg, index - 1); + + pg = r->pgno; + switch (op) { + case SDELETE: + --GETRINTERNAL(h, (index - 1))->nrecs; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + break; + case SINSERT: + ++GETRINTERNAL(h, (index - 1))->nrecs; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + break; + case SEARCH: + mpool_put(t->bt_mp, h, 0); + break; + } + + } + /* Try and recover the tree. */ +err: sverrno = errno; + if (op != SEARCH) + while ((parent = BT_POP(t)) != NULL) { + if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL) + break; + if (op == SINSERT) + --GETRINTERNAL(h, parent->index)->nrecs; + else + ++GETRINTERNAL(h, parent->index)->nrecs; + mpool_put(t->bt_mp, h, MPOOL_DIRTY); + } + errno = sverrno; + return (NULL); +} diff --git a/db/recno/rec_seq-fbsd.c b/db/recno/rec_seq-fbsd.c new file mode 100644 index 0000000..6ed3384 --- /dev/null +++ b/db/recno/rec_seq-fbsd.c @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 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. + */ + +#include +#ifndef lint +/* 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 $"); + +#include + +#include +#include +#include +#include + +#include +#include "recno.h" + +/* + * __REC_SEQ -- Recno sequential scan interface. + * + * Parameters: + * dbp: pointer to access method + * key: key for positioning and return value + * data: data return value + * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV. + * + * Returns: + * 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; +{ + BTREE *t; + EPG *e; + recno_t nrec; + int status; + + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + switch(flags) { + case R_CURSOR: + if ((nrec = *(recno_t *)key->data) == 0) + goto einval; + break; + case R_NEXT: + if (F_ISSET(&t->bt_cursor, CURS_INIT)) { + nrec = t->bt_cursor.rcursor + 1; + break; + } + /* FALLTHROUGH */ + case R_FIRST: + nrec = 1; + break; + case R_PREV: + if (F_ISSET(&t->bt_cursor, CURS_INIT)) { + if ((nrec = t->bt_cursor.rcursor - 1) == 0) + return (RET_SPECIAL); + break; + } + /* FALLTHROUGH */ + case R_LAST: + if (!F_ISSET(t, R_EOF | R_INMEM) && + t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) + return (RET_ERROR); + nrec = t->bt_nrecs; + break; + default: +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) + return (status); + if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) + return (RET_SPECIAL); + } + + if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL) + return (RET_ERROR); + + F_SET(&t->bt_cursor, CURS_INIT); + t->bt_cursor.rcursor = nrec; + + status = __rec_ret(t, e, nrec, key, data); + if (F_ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e->page, 0); + else + t->bt_pinned = e->page; + return (status); +} diff --git a/db/recno/rec_utils-fbsd.c b/db/recno/rec_utils-fbsd.c new file mode 100644 index 0000000..81fa1d6 --- /dev/null +++ b/db/recno/rec_utils-fbsd.c @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 1990, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +#include +#include +#include + +#include +#include "recno.h" + +/* + * __rec_ret -- + * Build return data. + * + * Parameters: + * t: tree + * e: key/data pair to be returned + * nrec: record number + * key: user's key 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; +{ + RLEAF *rl; + void *p; + + if (key == NULL) + goto dataonly; + + /* 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))); + if (p == NULL) + return (RET_ERROR); + t->bt_rkey.data = p; + t->bt_rkey.size = sizeof(recno_t); + } + memmove(t->bt_rkey.data, &nrec, sizeof(recno_t)); + key->size = sizeof(recno_t); + key->data = t->bt_rkey.data; + +dataonly: + if (data == NULL) + return (RET_SUCCESS); + + /* + * We must copy big keys/data to make them contigous. Otherwise, + * leave the page pinned and don't copy unless the user specified + * concurrent access. + */ + rl = GETRLEAF(e->page, e->index); + if (rl->flags & P_BIGDATA) { + if (__ovfl_get(t, rl->bytes, + &data->size, &t->bt_rdata.data, &t->bt_rdata.size)) + return (RET_ERROR); + data->data = t->bt_rdata.data; + } 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)); + if (p == NULL) + return (RET_ERROR); + t->bt_rdata.data = p; + t->bt_rdata.size = rl->dsize + 1; + } + memmove(t->bt_rdata.data, rl->bytes, rl->dsize); + data->size = rl->dsize; + data->data = t->bt_rdata.data; + } else { + data->size = rl->dsize; + data->data = rl->bytes; + } + return (RET_SUCCESS); +} diff --git a/db/recno/recno.h b/db/recno/recno.h new file mode 100644 index 0000000..9a247bc --- /dev/null +++ b/db/recno/recno.h @@ -0,0 +1,40 @@ +/*- + * 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. + * + * @(#)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 $ + */ + +enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */ + +#include "../btree/btree.h" +#include "rec_extern.h" diff --git a/dpkg/control b/dpkg/control deleted file mode 100644 index 836adea..0000000 --- a/dpkg/control +++ /dev/null @@ -1,4 +0,0 @@ -Package: libc -Maintainer: Darwin Developers -Description: C library -Build-Depends: cctools, libsystem, gnumake, libinfo-hdrs, project-makefiles, pb-makefiles, system-cmds, shell-cmds, zsh, file-cmds, bootstrap-cmds, text-cmds, gcc, xnu, architecture, gnutar diff --git a/emulated/Makefile.inc b/emulated/Makefile.inc index 6b5ec84..3e5ac1c 100644 --- a/emulated/Makefile.inc +++ b/emulated/Makefile.inc @@ -1,11 +1,14 @@ .PATH: ${.CURDIR}/emulated MISRCS+=bsd_signal.c \ + lchflags.c \ + lchmod.c \ + lutimes.c \ statvfs.c \ tcgetsid.c .if ${LIB} == "c" -MAN3+= bsd_signal.3 statvfs.3 tcgetsid.3 +MAN3+= bsd_signal.3 lchflags.3 lchmod.3 lutimes.3 statvfs.3 tcgetsid.3 MLINKS+=statvfs.3 fstatvfs.3 diff --git a/emulated/bsd_signal.c b/emulated/bsd_signal.c index dc5100a..6e2847b 100644 --- a/emulated/bsd_signal.c +++ b/emulated/bsd_signal.c @@ -24,7 +24,7 @@ /* * bsd_signal() function, per POIX 1003.1-2003 */ -#include +#include void (*bsd_signal(int sig, void (*func)(int)))(int) diff --git a/emulated/lchflags.3 b/emulated/lchflags.3 new file mode 100644 index 0000000..585a1a9 --- /dev/null +++ b/emulated/lchflags.3 @@ -0,0 +1,52 @@ +.Dd Oct 31, 2005 +.Dt LCHFLAGS 3 +.Os +.Sh NAME +.Nm lchflags +.Nd set file flags +.Sh SYNOPSIS +.In sys/stat.h +.In unistd.h +.Ft int +.Fn lchflags "const char *path" "u_int flags" +.Sh DESCRIPTION +The file whose name is given by +.Fa path +has its flags changed to +.Fa flags . +See +.Xr chflags 2 +for the values of the +.Fa flags . +.Pp +The +.Fn lchflags +call is like +.Fn chflags +except when the named file is a symbolic link, +in which case +.Fn lchflags +will change the flags of the link itself, +rather than the file it points to. +.Sh NOTE +Instead of being a system call, +.Fn lchflags +is emulated using +.Xr setattrlist 2 . +Not all file systems support +.Xr setattrlist 2 . +.Sh RETURN VALUES +Upon successful completion, a value of 0 is returned. +Otherwise, -1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn lchflags +call may return the same errors as +.Xr chflags 2 +and +.Xr setattrlist 2 . +.Sh SEE ALSO +.Xr chflags 2 , +.Xr setattrlist 2 diff --git a/emulated/lchflags.c b/emulated/lchflags.c new file mode 100644 index 0000000..05c7be8 --- /dev/null +++ b/emulated/lchflags.c @@ -0,0 +1,44 @@ +/* + * 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 +#include +#include + +int +lchflags(const char *path, unsigned int flags) +{ + struct stat s; + struct attrlist a; + + if(lstat(path, &s) < 0) + return -1; + if((s.st_mode & S_IFMT) != S_IFLNK) + return chflags(path, flags); + bzero(&a, sizeof(a)); + a.bitmapcount = ATTR_BIT_MAP_COUNT; + a.commonattr = ATTR_CMN_FLAGS; + return setattrlist(path, &a, &flags, sizeof(unsigned int), FSOPT_NOFOLLOW); +} diff --git a/emulated/lchmod.3 b/emulated/lchmod.3 new file mode 100644 index 0000000..4c2c86b --- /dev/null +++ b/emulated/lchmod.3 @@ -0,0 +1,54 @@ +.Dd Oct 31, 2005 +.Dt LCHMOD 3 +.Os +.Sh NAME +.Nm lchmod +.Nd change mode of file +.Sh SYNOPSIS +.In sys/stat.h +.In unistd.h +.Ft int +.Fn lchmod "const char *path" "mode_t flags" +.Sh DESCRIPTION +The function +.Fn lchmod +sets the file permission bits of the file specified by the pathname +.Fa path +to +.Fa mode . +See +.Xr chmod 2 +for the values of the +.Fa flags . +.Pp +The +.Fn lchmod +call is like +.Fn chmod +except when the named file is a symbolic link, +in which case +.Fn lchmod +will change the flags of the link itself, +rather than the file it points to. +.Sh NOTE +Instead of being a system call, +.Fn lchmod +is emulated using +.Xr setattrlist 2 . +Not all file systems support +.Xr setattrlist 2 . +.Sh RETURN VALUES +Upon successful completion, a value of 0 is returned. +Otherwise, -1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn lchmod +call may return the same errors as +.Xr chmod 2 +and +.Xr setattrlist 2 . +.Sh SEE ALSO +.Xr chmod 2 , +.Xr setattrlist 2 diff --git a/emulated/lchmod.c b/emulated/lchmod.c new file mode 100644 index 0000000..50fda99 --- /dev/null +++ b/emulated/lchmod.c @@ -0,0 +1,46 @@ +/* + * 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 +#include +#include + +int +lchmod(const char *path, mode_t mode) +{ + struct stat s; + struct attrlist a; + int m; + + if(lstat(path, &s) < 0) + return -1; + if((s.st_mode & S_IFMT) != S_IFLNK) + return chmod(path, mode); + bzero(&a, sizeof(a)); + a.bitmapcount = ATTR_BIT_MAP_COUNT; + a.commonattr = ATTR_CMN_ACCESSMASK; + m = mode; + return setattrlist(path, &a, &m, sizeof(int), FSOPT_NOFOLLOW); +} diff --git a/emulated/lutimes.3 b/emulated/lutimes.3 new file mode 100644 index 0000000..06cd3fb --- /dev/null +++ b/emulated/lutimes.3 @@ -0,0 +1,62 @@ +.Dd Aug 13, 2006 +.Dt LUTIMES 3 +.Os +.Sh NAME +.Nm lutimes +.Nd set file access and modification times of symlink +.Sh SYNOPSIS +.In sys/time.h +.Ft int +.Fn lutimes "const char *path" "struct timeval times[2]" +.Sh DESCRIPTION +The access and modification times of the file named by +.Fa path +are changed as specified by the argument +.Fa times , +even if +.Fa path +specifies a symbolic link (for +.Xr utimes 2 +the times of the file referenced by the symbolic link are changed). +.Pp +If +.Fa times +is +.Dv NULL , +the access and modification times are set to the current time. +The caller must be the owner of the file, have permission to +write the file, or be the super-user. +.Pp +If +.Fa times +is +.Pf non- Dv NULL , +it is assumed to point to an array of two timeval structures. +The access time is set to the value of the first element, and the +modification time is set to the value of the second element. +The caller must be the owner of the file or be the super-user. +.Pp +In either case, the inode-change-time of the file is set to the current +time. +.Sh NOTE +Instead of being a system call, +.Fn lutimes +is emulated using +.Xr setattrlist 2 . +Not all file systems support +.Xr setattrlist 2 . +.Sh RETURN VALUES +Upon successful completion, a value of 0 is returned. +Otherwise, -1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn lutimes +call may return the same errors as +.Xr utimes 2 +and +.Xr setattrlist 2 . +.Sh SEE ALSO +.Xr utimes 2 , +.Xr setattrlist 2 diff --git a/emulated/lutimes.c b/emulated/lutimes.c new file mode 100644 index 0000000..fd5e8b4 --- /dev/null +++ b/emulated/lutimes.c @@ -0,0 +1,60 @@ +/* + * 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 +#include +#include +#include +#include + +int +lutimes(const char *path, const struct timeval *times) +{ + struct stat s; + struct attrlist a; + struct { + struct timespec mod; + struct timespec access; + } t; + + if(lstat(path, &s) < 0) + return -1; + if((s.st_mode & S_IFMT) != S_IFLNK) + return utimes(path, times); + bzero(&a, sizeof(a)); + a.bitmapcount = ATTR_BIT_MAP_COUNT; + a.commonattr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME; + if(times) { + TIMEVAL_TO_TIMESPEC(×[0], &t.access); + TIMEVAL_TO_TIMESPEC(×[1], &t.mod); + } else { + struct timeval now; + + if(gettimeofday(&now, NULL) < 0) + return -1; + TIMEVAL_TO_TIMESPEC(&now, &t.access); + TIMEVAL_TO_TIMESPEC(&now, &t.mod); + } + return setattrlist(path, &a, &t, sizeof(t), FSOPT_NOFOLLOW); +} diff --git a/emulated/statvfs.3 b/emulated/statvfs.3 index e29ef44..bcd9c44 100644 --- a/emulated/statvfs.3 +++ b/emulated/statvfs.3 @@ -32,17 +32,23 @@ .Dt STATVFS 3 .Os .Sh NAME -.Nm statvfs , -.Nm fstatvfs +.Nm fstatvfs , +.Nm statvfs .Nd retrieve file system information .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/statvfs.h .Ft int -.Fn statvfs "const char * restrict path" "struct statvfs * restrict buf" +.Fo fstatvfs +.Fa "int fildes" +.Fa "struct statvfs *buf" +.Fc .Ft int -.Fn fstatvfs "int fd" "struct statvfs *buf" +.Fo statvfs +.Fa "const char *restrict path" +.Fa "struct statvfs *restrict buf" +.Fc .Sh DESCRIPTION The .Fn statvfs @@ -135,10 +141,21 @@ The .Fn statvfs function fails if one or more of the following are true: .Bl -tag -width Er -.It Bq Er ENOTDIR -A component of the path prefix of -.Fa Path -is not a directory. +.It Bq Er EACCES +Search permission is denied for a component of the path prefix of +.Fa path . +.It Bq Er EFAULT +.Fa Buf +or +.Fa path +points to an invalid address. +.It Bq Er EIO +An +.Tn I/O +error occurred while reading from or writing to the file system. +.It Bq Er ELOOP +Too many symbolic links were encountered in translating +.Fa path . .It Bq Er ENAMETOOLONG The length of a component of .Fa path @@ -153,21 +170,10 @@ characters. The file referred to by .Fa path does not exist. -.It Bq Er EACCES -Search permission is denied for a component of the path prefix of -.Fa path . -.It Bq Er ELOOP -Too many symbolic links were encountered in translating -.Fa path . -.It Bq Er EFAULT -.Fa Buf -or -.Fa path -points to an invalid address. -.It Bq Er EIO -An -.Tn I/O -error occurred while reading from or writing to the file system. +.It Bq Er ENOTDIR +A component of the path prefix of +.Fa Path +is not a directory. .El .Pp The @@ -175,7 +181,7 @@ The functions fails if one or more of the following are true: .Bl -tag -width Er .It Bq Er EBADF -.Fa fd +.Fa fildes is not a valid open file descriptor. .It Bq Er EFAULT .Fa Buf diff --git a/emulated/tcgetsid.3 b/emulated/tcgetsid.3 index a88355a..429992a 100644 --- a/emulated/tcgetsid.3 +++ b/emulated/tcgetsid.3 @@ -27,7 +27,9 @@ .Sh SYNOPSIS .In termios.h .Ft pid_t -.Fn tcgetsid "int fildes" +.Fo tcgetsid +.Fa "int fildes" +.Fc .Sh DESCRIPTION The .Fn tcgetsid diff --git a/gdtoa/FreeBSD/_hdtoa.c.patch b/gdtoa/FreeBSD/_hdtoa.c.patch index de6da95..2982437 100644 --- a/gdtoa/FreeBSD/_hdtoa.c.patch +++ b/gdtoa/FreeBSD/_hdtoa.c.patch @@ -1,6 +1,15 @@ ---- _hdtoa.c.orig 2006-01-31 15:21:41.000000000 -0800 -+++ _hdtoa.c 2006-01-31 23:37:12.000000000 -0800 -@@ -223,6 +223,10 @@ +--- _hdtoa.c.orig 2006-08-14 16:12:46.000000000 -0700 ++++ _hdtoa.c 2006-08-14 23:02:39.000000000 -0700 +@@ -55,7 +55,7 @@ + *s = 1; + return (1); + } +- ++*s; ++ *s = 0; + } + ++*s; + return (0); +@@ -223,12 +223,17 @@ union IEEEl2bits u; char *s, *s0; int bufsize; @@ -11,7 +20,14 @@ u.e = e; *sign = u.bits.sign; -@@ -270,6 +274,19 @@ + + switch (fpclassify(e)) { + case FP_NORMAL: ++ case FP_SUPERNORMAL: + *decpt = u.bits.exp - LDBL_ADJ; + break; + case FP_ZERO: +@@ -270,6 +275,19 @@ */ for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--) *s = 0; @@ -31,7 +47,7 @@ for (; s > s0 + sigfigs - (LDBL_MANL_SIZE / 4) - 1 && s > s0; s--) { *s = u.bits.manl & 0xf; u.bits.manl >>= 4; -@@ -278,6 +295,7 @@ +@@ -278,6 +296,7 @@ *s = u.bits.manh & 0xf; u.bits.manh >>= 4; } @@ -39,7 +55,7 @@ /* * At this point, we have snarfed all the bits in the -@@ -285,7 +303,11 @@ +@@ -285,7 +304,11 @@ * (partial) nibble, which is dealt with by the next * statement. We also tack on the implicit normalization bit. */ diff --git a/gdtoa/FreeBSD/_ldtoa.c.patch b/gdtoa/FreeBSD/_ldtoa.c.patch index e7a5319..8f95773 100644 --- a/gdtoa/FreeBSD/_ldtoa.c.patch +++ b/gdtoa/FreeBSD/_ldtoa.c.patch @@ -1,9 +1,22 @@ --- _ldtoa.c.orig 2004-06-03 15:17:18.000000000 -0700 -+++ _ldtoa.c 2005-10-08 22:43:25.000000000 -0700 -@@ -61,14 +61,34 @@ ++++ _ldtoa.c 2005-10-09 00:09:11.000000000 -0700 +@@ -46,7 +46,7 @@ + __ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign, + char **rve) + { +- static FPI fpi = { ++ static FPI fpi0 = { + LDBL_MANT_DIG, /* nbits */ + LDBL_MIN_EXP - LDBL_MANT_DIG, /* emin */ + LDBL_MAX_EXP - LDBL_MANT_DIG, /* emax */ +@@ -61,28 +61,55 @@ char *ret; union IEEEl2bits u; uint32_t bits[(LDBL_MANT_DIG + 31) / 32]; ++ FPI *fpi = &fpi0, fpi1; ++#ifdef Honor_FLT_ROUNDS ++ int rounding = Flt_Rounds; ++#endif +#if defined(__ppc__) || defined(__ppc64__) + int type; +#endif /* defined(__ppc__) || defined(__ppc64__) */ @@ -33,9 +46,13 @@ case FP_NORMAL: + case FP_SUPERNORMAL: kind = STRTOG_Normal; ++/* For ppc/ppc64 and head-tail long double, the implicit bit is already there */ ++#if !defined(__ppc__) && !defined(__ppc64__) #ifdef LDBL_IMPLICIT_NBIT bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32); -@@ -77,12 +97,12 @@ + #endif /* LDBL_IMPLICIT_NBIT */ ++#endif /* !defined(__ppc__) && !defined(__ppc64__) */ + break; case FP_ZERO: kind = STRTOG_Zero; break; @@ -50,8 +67,19 @@ case FP_INFINITE: kind = STRTOG_Infinite; break; -@@ -96,5 +116,9 @@ - ret = gdtoa(&fpi, be, (ULong *)bits, &kind, mode, ndigits, decpt, rve); +@@ -93,8 +120,19 @@ + abort(); + } + +- ret = gdtoa(&fpi, be, (ULong *)bits, &kind, mode, ndigits, decpt, rve); ++#ifdef Honor_FLT_ROUNDS ++ if (rounding != fpi0.rounding) { ++ fpi1 = fpi0; /* for thread safety */ ++ fpi1.rounding = rounding; ++ fpi = &fpi1; ++ } ++#endif /* Honor_FLT_ROUNDS */ ++ ret = gdtoa(fpi, be, (ULong *)bits, &kind, mode, ndigits, decpt, rve); if (*decpt == -32768) *decpt = INT_MAX; +#if defined(__ppc__) || defined(__ppc64__) diff --git a/gdtoa/FreeBSD/gdtoa-gdtoa.c.patch b/gdtoa/FreeBSD/gdtoa-gdtoa.c.patch new file mode 100644 index 0000000..abf31e0 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-gdtoa.c.patch @@ -0,0 +1,15 @@ +--- gdtoa-gdtoa.c.orig 2007-03-26 22:44:56.000000000 -0700 ++++ gdtoa-gdtoa.c 2007-03-26 23:21:08.000000000 -0700 +@@ -479,8 +479,11 @@ + } + ++*s++; + } +- else ++ else { + inex = STRTOG_Inexlo; ++ while(*--s == '0'){} ++ s++; ++ } + break; + } + } diff --git a/gdtoa/FreeBSD/gdtoa-gethex.c.patch b/gdtoa/FreeBSD/gdtoa-gethex.c.patch index 05f7d60..a6a0c4a 100644 --- a/gdtoa/FreeBSD/gdtoa-gethex.c.patch +++ b/gdtoa/FreeBSD/gdtoa-gethex.c.patch @@ -1,5 +1,5 @@ ---- gdtoa-gethex.c.orig 2005-02-17 01:16:50.000000000 -0800 -+++ gdtoa-gethex.c 2005-02-17 01:27:10.000000000 -0800 +--- gdtoa-gethex.c.orig 2005-01-20 20:12:36.000000000 -0800 ++++ gdtoa-gethex.c 2005-03-23 15:45:22.000000000 -0800 @@ -29,6 +29,8 @@ /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -23,15 +23,73 @@ #endif { Bigint *b; -@@ -49,7 +51,10 @@ +@@ -49,7 +51,13 @@ ULong L, lostbits, *x; Long e, e1; #ifdef USE_LOCALE - unsigned char decimalpoint = *localeconv()->decimal_point; -+ unsigned char decimalpoint; ++ char *decimalpoint; ++ unsigned char *decimalpointend = NULL; ++ int decimalpointlen; + + NORMALIZE_LOCALE(loc); -+ decimalpoint = *localeconv_l(loc)->decimal_point; ++ decimalpoint = localeconv_l(loc)->decimal_point; ++ decimalpointlen = strlen(decimalpoint); #else #define decimalpoint '.' #endif +@@ -67,9 +75,18 @@ + e = 0; + if (!hexdig[*s]) { + zret = 1; ++#ifdef USE_LOCALE ++ if (strncmp((char *)s, decimalpoint, decimalpointlen) != 0) ++#else /* USE_LOCALE */ + if (*s != decimalpoint) ++#endif /* USE_LOCALE */ + goto pcheck; ++#ifdef USE_LOCALE ++ decpt = (s += decimalpointlen); ++ decimalpointend = s - 1; ++#else /* USE_LOCALE */ + decpt = ++s; ++#endif /* USE_LOCALE */ + if (!hexdig[*s]) + goto pcheck; + while(*s == '0') +@@ -81,8 +98,18 @@ + } + while(hexdig[*s]) + s++; +- if (*s == decimalpoint && !decpt) { ++#ifdef USE_LOCALE ++ if (strncmp((char *)s, decimalpoint, decimalpointlen) == 0 && !decpt) ++#else /* USE_LOCALE */ ++ if (*s == decimalpoint && !decpt) ++#endif /* USE_LOCALE */ ++ { ++#ifdef USE_LOCALE ++ decpt = (s += decimalpointlen); ++ decimalpointend = s - 1; ++#else /* USE_LOCALE */ + decpt = ++s; ++#endif /* USE_LOCALE */ + while(hexdig[*s]) + s++; + } +@@ -123,8 +150,15 @@ + n = 0; + L = 0; + while(s1 > s0) { ++#ifdef USE_LOCALE ++ if (--s1 == decimalpointend) { ++ s1 -= decimalpointlen - 1; ++ continue; ++ } ++#else /* USE_LOCALE */ + if (*--s1 == decimalpoint) + continue; ++#endif /* USE_LOCALE */ + if (n == 32) { + *x++ = L; + L = 0; diff --git a/gdtoa/FreeBSD/gdtoa-hexnan.c.patch b/gdtoa/FreeBSD/gdtoa-hexnan.c.patch new file mode 100644 index 0000000..23aa1aa --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-hexnan.c.patch @@ -0,0 +1,126 @@ +--- gdtoa-hexnan.c.orig 2005-01-20 20:12:36.000000000 -0800 ++++ gdtoa-hexnan.c 2005-06-10 17:43:17.000000000 -0700 +@@ -30,6 +30,7 @@ + * with " at " changed at "@" and " dot " changed to "."). */ + + #include "gdtoaimp.h" ++#include + + static void + #ifdef KR_headers +@@ -57,75 +58,53 @@ + hexnan( CONST char **sp, FPI *fpi, ULong *x0) + #endif + { +- ULong c, h, *x, *x1, *xe; ++ int nbits, len; ++ char *cp; + CONST char *s; +- int havedig, hd0, i, nbits; + +- 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; ++ if (sp == NULL || *sp == NULL || **sp != '(') ++ return STRTOG_NaN; + s = *sp; +- 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; +- } +- continue; +- } +- if (/*(*/ c == ')' && havedig) { +- *sp = s + 1; +- break; +- } ++ if ((cp = strchr(s + 1, ')')) == NULL) { ++ *sp += strlen(s); ++ cp = s + 1; ++ } ++ else { ++ len = cp - (s + 1); ++ cp = alloca(len + 1); ++ if (!cp) + return STRTOG_NaN; +- } +- havedig++; +- if (++i > 8) { +- if (x <= x0) +- continue; +- i = 1; +- *--x = 0; +- } +- *x = (*x << 4) | h & 0xf; ++ strlcpy(cp, s + 1, len + 1); ++ *sp += len + 2; + } +- 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); ++ nbits = fpi->nbits; ++ /* a hack */ ++ if (nbits == 52) { /* double */ ++ union IEEEd2bits u; ++ u.d = nan(cp); ++ x0[1] = u.bits.manh; ++ x0[0] = u.bits.manl; + } +- else { +- /* truncate high-order word if necessary */ +- if ( (i = nbits & (ULbits-1)) !=0) +- *xe &= ((ULong)0xffffffff) >> (ULbits - i); ++ else if (nbits < 52) { /* float */ ++ union IEEEf2bits u; ++ u.f = nanf(cp); ++ x0[0] = u.bits.man; + } +- for(x1 = xe;; --x1) { +- if (*x1 != 0) +- break; +- if (x1 == x0) { +- *x1 = 1; +- break; +- } ++ else { /* long double */ ++ union IEEEl2bits u; ++ u.e = nanl(cp); ++#if defined(__ppc__) || defined(__ppc64__) ++ x0[3] = (ULong)(u.bits.manh >> 44); ++ x0[2] = (ULong)(u.bits.manh >> 12); ++ x0[1] = ((ULong)u.bits.manh & 0xfff) << 20 | (ULong)(u.bits.manl >> 32); ++ x0[0] = (ULong)u.bits.manl; ++#elif defined(__i386__) || defined(__x86_64__) ++ x0[1] = (ULong)u.bits.manh; ++ x0[0] = (ULong)u.bits.manl; ++#else ++#error unsupported architecture ++#endif + } ++ + return STRTOG_NaNbits; + } diff --git a/gdtoa/FreeBSD/gdtoa-smisc.c.patch b/gdtoa/FreeBSD/gdtoa-smisc.c.patch new file mode 100644 index 0000000..b942b4c --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-smisc.c.patch @@ -0,0 +1,27 @@ +--- 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-strtod.c.patch b/gdtoa/FreeBSD/gdtoa-strtod.c.patch index 99db605..e4b67d7 100644 --- a/gdtoa/FreeBSD/gdtoa-strtod.c.patch +++ b/gdtoa/FreeBSD/gdtoa-strtod.c.patch @@ -1,5 +1,5 @@ ---- gdtoa-strtod.c.orig 2005-10-08 11:32:33.000000000 -0700 -+++ gdtoa-strtod.c 2005-10-08 11:38:17.000000000 -0700 +--- gdtoa-strtod.c.orig 2007-10-04 15:00:21.000000000 -0700 ++++ gdtoa-strtod.c 2007-10-04 15:02:41.000000000 -0700 @@ -29,6 +29,8 @@ /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -24,7 +24,21 @@ #endif { #ifdef Avoid_Underflow -@@ -126,7 +128,7 @@ +@@ -80,8 +82,12 @@ + int inexact, oldinexact; + #endif + #ifdef Honor_FLT_ROUNDS +- int rounding; ++ int rounding = Flt_Rounds; + #endif ++#ifdef USE_LOCALE ++ char *decimal_point; ++ int decimal_point_len; ++#endif /* USE_LOCALE */ + + sign = nz0 = nz = decpt = 0; + dval(rv) = 0.; +@@ -126,7 +132,7 @@ #else #define fpi1 fpi #endif @@ -33,18 +47,65 @@ case STRTOG_NoNumber: s = s00; sign = 0; -@@ -156,8 +158,9 @@ +@@ -156,14 +162,22 @@ else if (nd < 16) z = 10*z + c - '0'; nd0 = nd; + NORMALIZE_LOCALE(loc); #ifdef USE_LOCALE - if (c == *localeconv()->decimal_point) -+ if (c == *localeconv_l(loc)->decimal_point) ++ decimal_point = localeconv_l(loc)->decimal_point; ++ decimal_point_len = strlen(decimal_point); ++ if (strncmp(s, decimal_point, decimal_point_len) == 0) #else if (c == '.') #endif -@@ -980,3 +983,13 @@ + { + decpt = 1; ++#ifdef USE_LOCALE ++ s += decimal_point_len; ++ c = *s; ++#else + c = *++s; ++#endif + if (!nd) { + for(; c == '0'; c = *++s) + nz++; +@@ -379,7 +393,7 @@ + scale = 0; + #endif + #ifdef Honor_FLT_ROUNDS +- if ((rounding = Flt_Rounds) >= 2) { ++ if (rounding >= 2) { + if (sign) + rounding = rounding == 2 ? 0 : 2; + else +@@ -512,7 +526,11 @@ + + /* Put digits into bd: true value = bd * 10^e */ + +- bd0 = s2b(s0, nd0, nd, y); ++#ifdef USE_LOCALE ++ bd0 = s2b(s0, nd0, nd, y, decimal_point_len); ++#else ++ bd0 = s2b(s0, nd0, nd, y, 1); ++#endif + + for(;;) { + bd = Balloc(bd0->k); +@@ -956,7 +974,11 @@ + dval(rv) *= dval(rv0); + #ifndef NO_ERRNO + /* try to avoid the bug of testing an 8087 register value */ ++#if __DARWIN_UNIX03 ++ if (word0(rv) == 0 && word1(rv) == 0 || dval(rv) < DBL_MIN) ++#else /* !__DARWIN_UNIX03 */ + if (word0(rv) == 0 && word1(rv) == 0) ++#endif /* __DARWIN_UNIX03 */ + errno = ERANGE; + #endif + } +@@ -980,3 +1002,13 @@ return sign ? -dval(rv) : dval(rv); } diff --git a/gdtoa/FreeBSD/gdtoa-strtodg.c.patch b/gdtoa/FreeBSD/gdtoa-strtodg.c.patch index d60d887..6ea44dd 100644 --- a/gdtoa/FreeBSD/gdtoa-strtodg.c.patch +++ b/gdtoa/FreeBSD/gdtoa-strtodg.c.patch @@ -1,6 +1,6 @@ ---- gdtoa-strtodg.c.orig 2005-10-08 11:33:23.000000000 -0700 -+++ gdtoa-strtodg.c 2005-10-08 11:40:57.000000000 -0700 -@@ -29,6 +29,8 @@ +--- gdtoa-strtodg.c.orig 2007-10-04 15:00:21.000000000 -0700 ++++ gdtoa-strtodg.c 2007-10-04 17:49:06.000000000 -0700 +@@ -29,13 +29,29 @@ /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -9,7 +9,61 @@ #include "gdtoaimp.h" #ifdef USE_LOCALE -@@ -316,10 +318,10 @@ + #include "locale.h" + #endif + +- static CONST int ++#define fivesbits __fivesbits_D2A ++#define all_on __all_on_D2A ++#define set_ones __set_ones_D2A ++#define rvOK __rvOK_D2A ++#define mantbits __mantbits_D2A ++ ++#ifdef BUILDING_VARIANT ++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); ++#else /* !BUILDING_VARIANT */ ++ ++ __private_extern__ CONST int + fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, + 24, 26, 28, 31, 33, 35, 38, 40, 42, 45, + 47, 49, 52 +@@ -122,7 +138,7 @@ + return STRTOG_Inexlo; + } + +- static int ++ __private_extern__ int + #ifdef KR_headers + all_on(b, n) Bigint *b; int n; + #else +@@ -169,7 +185,7 @@ + return b; + } + +- static int ++ __private_extern__ int + rvOK + #ifdef KR_headers + (d, fpi, exp, bits, exact, rd, irv) +@@ -290,7 +306,7 @@ + return rv; + } + +- static int ++ __private_extern__ int + #ifdef KR_headers + mantbits(d) double d; + #else +@@ -313,13 +329,15 @@ + return P - 32 - lo0bits(&L); + } + ++#endif /* BUILDING_VARIANT */ ++ int strtodg #ifdef KR_headers @@ -23,7 +77,18 @@ #endif { int abe, abits, asub; -@@ -367,7 +369,7 @@ +@@ -332,6 +350,10 @@ + Long L; + ULong y, z; + Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; ++#ifdef USE_LOCALE ++ char *decimal_point; ++ int decimal_point_len; ++#endif /* USE_LOCALE */ + + irv = STRTOG_Zero; + denorm = sign = nz0 = nz = 0; +@@ -367,7 +389,7 @@ switch(s[1]) { case 'x': case 'X': @@ -32,18 +97,31 @@ if (irv == STRTOG_NoNumber) { s = s00; sign = 0; -@@ -389,8 +391,9 @@ +@@ -389,14 +411,22 @@ else if (nd < 16) z = 10*z + c - '0'; nd0 = nd; + NORMALIZE_LOCALE(loc); #ifdef USE_LOCALE - if (c == *localeconv()->decimal_point) -+ if (c == *localeconv_l(loc)->decimal_point) ++ decimal_point = localeconv_l(loc)->decimal_point; ++ decimal_point_len = strlen(decimal_point); ++ if (strncmp(s, decimal_point, decimal_point_len) == 0) #else if (c == '.') #endif -@@ -668,6 +671,9 @@ + { + decpt = 1; ++#ifdef USE_LOCALE ++ s += decimal_point_len; ++ c = *s; ++#else + c = *++s; ++#endif + if (!nd) { + for(; c == '0'; c = *++s) + nz++; +@@ -668,6 +698,9 @@ rvb->x[0] = 0; *exp = emin; irv = STRTOG_Underflow | STRTOG_Inexlo; @@ -53,3 +131,35 @@ goto ret; } rvb->x[0] = rvb->wds = rvbits = 1; +@@ -684,7 +717,11 @@ + + /* Put digits into bd: true value = bd * 10^e */ + +- bd0 = s2b(s0, nd0, nd, y); ++#ifdef USE_LOCALE ++ bd0 = s2b(s0, nd0, nd, y, decimal_point_len); ++#else ++ bd0 = s2b(s0, nd0, nd, y, 1); ++#endif + + for(;;) { + bd = Balloc(bd0->k); +@@ -824,7 +861,7 @@ + rvb = increment(rvb); + if ( (j = rvbits & kmask) !=0) + j = ULbits - j; +- if (hi0bits(rvb->x[(rvb->wds - 1) >> kshift]) ++ if (hi0bits(rvb->x[rvb->wds - 1]) + != j) + rvbits++; + irv = STRTOG_Normal | STRTOG_Inexhi; +@@ -1008,5 +1045,9 @@ + copybits(bits, nbits, rvb); + Bfree(rvb); + } ++#if !defined(NO_ERRNO) && __DARWIN_UNIX03 ++ if (irv & STRTOG_Underflow) ++ errno = ERANGE; ++#endif + return irv; + } diff --git a/gdtoa/FreeBSD/gdtoa-strtof.c.patch b/gdtoa/FreeBSD/gdtoa-strtof.c.patch index 754a83a..33db13a 100644 --- a/gdtoa/FreeBSD/gdtoa-strtof.c.patch +++ b/gdtoa/FreeBSD/gdtoa-strtof.c.patch @@ -1,6 +1,6 @@ ---- gdtoa-strtof.c.orig 2005-01-20 20:12:37.000000000 -0800 -+++ gdtoa-strtof.c 2005-02-17 12:49:28.000000000 -0800 -@@ -29,13 +29,15 @@ +--- gdtoa-strtof.c.orig 2007-04-03 12:19:28.000000000 -0700 ++++ gdtoa-strtof.c 2007-04-06 12:52:45.000000000 -0700 +@@ -29,24 +29,41 @@ /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -17,18 +17,36 @@ +strtof_l(CONST char *s, char **sp, locale_t loc) #endif { - static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; -@@ -44,7 +46,8 @@ +- static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; ++ static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + ULong bits[1]; + Long exp; int k; union { ULong L[1]; float f; } u; ++ FPI *fpi = &fpi0, fpi1; ++#ifdef Honor_FLT_ROUNDS ++ int rounding = Flt_Rounds; ++#endif - k = strtodg(s, sp, &fpi, &exp, bits); + NORMALIZE_LOCALE(loc); -+ k = strtodg(s, sp, &fpi, &exp, bits, loc); ++#ifdef Honor_FLT_ROUNDS ++ if (rounding != fpi0.rounding) { ++ fpi1 = fpi0; /* for thread safety */ ++ fpi1.rounding = rounding; ++ fpi = &fpi1; ++ } ++#endif /* Honor_FLT_ROUNDS */ ++ k = strtodg(s, sp, fpi, &exp, bits, loc); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: ++ u.L[0] = 0; ++ return u.f; // avoid setting sign ++ case STRTOG_Zero: -@@ -71,3 +74,13 @@ + u.L[0] = 0; + break; +@@ -71,3 +88,13 @@ u.L[0] |= 0x80000000L; return u.f; } diff --git a/gdtoa/FreeBSD/gdtoa-strtopdd.c.patch b/gdtoa/FreeBSD/gdtoa-strtopdd.c.patch index 6714472..39b904b 100644 --- a/gdtoa/FreeBSD/gdtoa-strtopdd.c.patch +++ b/gdtoa/FreeBSD/gdtoa-strtopdd.c.patch @@ -1,6 +1,6 @@ ---- gdtoa-strtopdd.c.orig 2005-01-20 20:12:37.000000000 -0800 -+++ gdtoa-strtopdd.c 2005-02-17 01:34:59.000000000 -0800 -@@ -29,13 +29,25 @@ +--- gdtoa-strtopdd.c.orig 2007-04-03 12:19:28.000000000 -0700 ++++ gdtoa-strtopdd.c 2007-04-06 12:53:25.000000000 -0700 +@@ -29,19 +29,31 @@ /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -21,14 +21,22 @@ int #ifdef KR_headers -strtopdd(s, sp, dd) CONST char *s; char **sp; double *dd; -+strtopdd(s, sp, dd, loc) CONST char *s; char **sp; double *dd; locale_t loc; ++strtopdd(s, sp, dd) CONST char *s; char **sp; double *dd; locale_t loc; #else -strtopdd(CONST char *s, char **sp, double *dd) +strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) #endif { #ifdef Sudden_Underflow -@@ -49,10 +61,13 @@ +- static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; ++ static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; + #else +- static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; ++ static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; + #endif + ULong bits[4]; + Long exp; +@@ -49,13 +61,30 @@ typedef union { double d[2]; ULong L[4]; @@ -37,13 +45,30 @@ +#endif /* __APPLE__ */ } U; U *u; ++ FPI *fpi = &fpi0, fpi1; ++#ifdef Honor_FLT_ROUNDS ++ int rounding = Flt_Rounds; ++#endif - rv = strtodg(s, sp, &fpi, &exp, bits); -+ rv = strtodg(s, sp, &fpi, &exp, bits, loc); ++#ifdef Honor_FLT_ROUNDS ++ if (rounding != fpi0.rounding) { ++ fpi1 = fpi0; /* for thread safety */ ++ fpi1.rounding = rounding; ++ fpi = &fpi1; ++ } ++#endif /* Honor_FLT_ROUNDS */ ++ rv = strtodg(s, sp, fpi, &exp, bits, loc); u = (U*)dd; switch(rv & STRTOG_Retmask) { case STRTOG_NoNumber: -@@ -101,6 +116,9 @@ ++ u->d[0] = u->d[1] = 0.; ++ return rv; // avoid setting sign ++ + case STRTOG_Zero: + u->d[0] = u->d[1] = 0.; + break; +@@ -101,6 +130,9 @@ } u->L[2+_1] = bits[0]; u->L[2+_0] = bits[1] & 0xfffff | exp << 20; @@ -53,7 +78,7 @@ break; case STRTOG_Denormal: -@@ -124,6 +142,9 @@ +@@ -124,6 +156,9 @@ 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]; @@ -63,7 +88,7 @@ break; partly_normal: -@@ -135,6 +156,9 @@ +@@ -135,6 +170,9 @@ 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]; @@ -73,7 +98,7 @@ break; } if (i == 0) { -@@ -142,6 +166,9 @@ +@@ -142,6 +180,9 @@ u->L[_1] = bits[1]; u->L[2+_0] = 0; u->L[2+_1] = bits[0]; @@ -83,7 +108,7 @@ break; } j = 32 - i; -@@ -150,6 +177,9 @@ +@@ -150,6 +191,9 @@ u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[2+_0] = 0; u->L[2+_1] = bits[0] & (1L << j) - 1; @@ -93,7 +118,7 @@ break; hardly_normal: -@@ -159,20 +189,38 @@ +@@ -159,20 +203,44 @@ u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[2+_0] = 0; u->L[2+_1] = bits[0] & (1L << j) - 1; @@ -114,12 +139,18 @@ case STRTOG_NaN: +#ifdef __APPLE__ -+ u->L[_0] = 0x7fffffff; -+ u->L[_1] = (ULong)-1; -+ u->L[2+_0] = u->L[2+_1] = 0; ++ u->L[0] = d_QNAN0; ++ u->L[1] = d_QNAN1; ++ u->L[2] = u->L[3] = 0; +#else /* __APPLE__ */ u->L[0] = u->L[2] = d_QNAN0; u->L[1] = u->L[3] = d_QNAN1; ++#endif /* __APPLE__ */ ++#ifdef __APPLE__ ++ case STRTOG_NaNbits: ++ u->L[0] = d_QNAN0 | ((bits[2] >> 20 | bits[3] << 12) & 0xfffff); ++ u->L[1] = d_QNAN1 | bits[1] >> 20 | bits[2] << 12; ++ u->L[2] = u->L[3] = 0; +#endif /* __APPLE__ */ } if (rv & STRTOG_Neg) { diff --git a/gdtoa/FreeBSD/gdtoa_strtopx.c.patch b/gdtoa/FreeBSD/gdtoa_strtopx.c.patch index f810e57..4c43027 100644 --- a/gdtoa/FreeBSD/gdtoa_strtopx.c.patch +++ b/gdtoa/FreeBSD/gdtoa_strtopx.c.patch @@ -1,5 +1,5 @@ ---- gdtoa_strtopx.c.orig 2005-01-20 20:12:37.000000000 -0800 -+++ gdtoa_strtopx.c 2005-10-08 17:10:15.000000000 -0700 +--- gdtoa_strtopx.c.orig 2007-04-03 12:19:28.000000000 -0700 ++++ gdtoa_strtopx.c 2007-04-06 12:52:09.000000000 -0700 @@ -29,6 +29,8 @@ /* Please send bug reports to David M. Gay (dmg at acm dot org, * with " at " changed at "@" and " dot " changed to "."). */ @@ -9,7 +9,7 @@ #include "gdtoaimp.h" #undef _0 -@@ -53,9 +55,9 @@ +@@ -53,20 +55,34 @@ int #ifdef KR_headers @@ -20,22 +20,40 @@ +strtopx(CONST char *s, char **sp, void *V, locale_t loc) #endif { - static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; -@@ -64,7 +66,7 @@ +- static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; ++ static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + ULong bits[2]; + Long exp; int k; UShort *L = (UShort*)V; ++ FPI *fpi = &fpi0, fpi1; ++#ifdef Honor_FLT_ROUNDS ++ int rounding = Flt_Rounds; ++#endif - k = strtodg(s, sp, &fpi, &exp, bits); -+ k = strtodg(s, sp, &fpi, &exp, bits, loc); ++#ifdef Honor_FLT_ROUNDS ++ if (rounding != fpi0.rounding) { ++ fpi1 = fpi0; /* for thread safety */ ++ fpi1.rounding = rounding; ++ fpi = &fpi1; ++ } ++#endif /* Honor_FLT_ROUNDS */ ++ k = strtodg(s, sp, fpi, &exp, bits, loc); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: ++ L[0] = L[1] = L[2] = L[3] = L[4] = 0; ++ return k; // avoid setting sign ++ case STRTOG_Zero: -@@ -87,7 +89,8 @@ + L[0] = L[1] = L[2] = L[3] = L[4] = 0; + break; +@@ -87,7 +103,8 @@ case STRTOG_Infinite: L[_0] = 0x7fff; - L[_1] = L[_2] = L[_3] = L[_4] = 0; -+ L[_1] = 0x8000; ++ L[_1] = 0x8000; /* 4306392: to match gcc */ + L[_2] = L[_3] = L[_4] = 0; break; diff --git a/gdtoa/FreeBSD/gdtoaimp.h.patch b/gdtoa/FreeBSD/gdtoaimp.h.patch index 4618eb3..4b7ee34 100644 --- a/gdtoa/FreeBSD/gdtoaimp.h.patch +++ b/gdtoa/FreeBSD/gdtoaimp.h.patch @@ -1,5 +1,5 @@ ---- gdtoaimp.h.orig 2005-01-20 20:12:37.000000000 -0800 -+++ gdtoaimp.h 2005-02-17 02:10:26.000000000 -0800 +--- gdtoaimp.h.orig 2007-10-04 15:00:21.000000000 -0700 ++++ gdtoaimp.h 2007-10-04 15:35:46.000000000 -0700 @@ -167,6 +167,7 @@ #ifndef GDTOAIMP_H_INCLUDED @@ -30,7 +30,18 @@ #undef IEEE_Arith #undef Avoid_Underflow #ifdef IEEE_MC68k -@@ -449,10 +456,16 @@ +@@ -233,6 +240,10 @@ + + #else /* ifndef Bad_float_h */ + #include "float.h" ++/* force the correct definition of FLT_ROUNDS */ ++extern int __fegetfltrounds( void ); ++#undef FLT_ROUNDS ++#define FLT_ROUNDS (__fegetfltrounds ()) + #endif /* Bad_float_h */ + + #ifdef IEEE_Arith +@@ -449,10 +460,16 @@ #define ALL_ON 0xffff #endif @@ -51,7 +62,7 @@ #define Kmax 15 -@@ -475,51 +488,89 @@ +@@ -475,51 +492,89 @@ #define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int)) #endif /* NO_STRING_H */ @@ -186,7 +197,7 @@ extern char *dtoa_result; extern CONST double bigtens[], tens[], tinytens[]; -@@ -542,8 +593,11 @@ +@@ -542,8 +597,11 @@ extern Bigint *diff ANSI((Bigint*, Bigint*)); extern char *dtoa ANSI((double d, int mode, int ndigits, int *decpt, int *sign, char **rve)); @@ -199,11 +210,15 @@ extern void hexdig_init_D2A(Void); extern int hexnan ANSI((CONST char**, FPI*, ULong*)); extern int hi0bits_D2A ANSI((ULong)); -@@ -563,8 +617,29 @@ - extern Bigint *s2b ANSI((CONST char*, int, int, ULong)); +@@ -560,11 +618,32 @@ + 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 strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*, locale_t)); ++ extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*, locale_t)) __DARWIN_ALIAS(strtodg); + + extern int strtoId ANSI((CONST char *, char **, double *, double *)); + extern int strtoIdd ANSI((CONST char *, char **, double *, double *)); diff --git a/gdtoa/Makefile.inc b/gdtoa/Makefile.inc index b3db9b7..50e8f90 100644 --- a/gdtoa/Makefile.inc +++ b/gdtoa/Makefile.inc @@ -2,14 +2,27 @@ CFLAGS += -I${.CURDIR}/gdtoa +.ifmake autopatch +ALL_ARCHS ?= i386 ppc ppc64 x86_64 +.for a in $(ALL_ARCHS) +.if exists(../${a}/stdlib/gdtoa.mk) +.include "../${a}/stdlib/gdtoa.mk" +.endif +.endfor +.else # !autopatch +.if exists(${.CURDIR}/${MACHINE_ARCH}/stdlib/gdtoa.mk) +.include "${.CURDIR}/${MACHINE_ARCH}/stdlib/gdtoa.mk" +.endif +.endif # autopatch +GDTOA_UNIQUE_SRCS != perl -e '@z = split(" ", "$(GDTOA_FBSDSRCS)"); $$, = "\n"; print @z' | sort -u + .include "Makefile.fbsd_begin" -FBSDMISRCS= _hdtoa.c _ldtoa.c glue.c \ +FBSDMISRCS= $(GDTOA_UNIQUE_SRCS) _hdtoa.c _ldtoa.c glue.c \ gdtoa-dmisc.c gdtoa-dtoa.c gdtoa-gdtoa.c gdtoa-gethex.c gdtoa-gmisc.c \ gdtoa-hd_init.c gdtoa-hexnan.c gdtoa-misc.c gdtoa-smisc.c \ gdtoa-strtod.c gdtoa-strtodg.c gdtoa-strtof.c gdtoa-strtord.c \ gdtoa-sum.c gdtoa-ulp.c -.if exists(${.CURDIR}/${MACHINE_ARCH}/stdlib/gdtoa.mk) -.include "${.CURDIR}/${MACHINE_ARCH}/stdlib/gdtoa.mk" -.endif FBSDHDRS= gdtoa.h gdtoaimp.h .include "Makefile.fbsd_end" + +LEGACYSRCS += gdtoa-strtof.c gdtoa-strtod.c gdtoa-strtodg.c diff --git a/gdtoa/_hdtoa-fbsd.c b/gdtoa/_hdtoa-fbsd.c new file mode 100644 index 0000000..0476f2e --- /dev/null +++ b/gdtoa/_hdtoa-fbsd.c @@ -0,0 +1,342 @@ +/*- + * Copyright (c) 2004, 2005 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/gdtoa/_hdtoa.c,v 1.3 2005/01/18 18:44:07 das Exp $"); + +#include +#include +#include +#include "fpmath.h" +#include "gdtoaimp.h" + +/* Strings values used by dtoa() */ +#define INFSTR "Infinity" +#define NANSTR "NaN" + +#define DBL_ADJ (DBL_MAX_EXP - 2 + ((DBL_MANT_DIG - 1) % 4)) +#define LDBL_ADJ (LDBL_MAX_EXP - 2 + ((LDBL_MANT_DIG - 1) % 4)) + +/* + * Round up the given digit string. If the digit string is fff...f, + * this procedure sets it to 100...0 and returns 1 to indicate that + * the exponent needs to be bumped. Otherwise, 0 is returned. + */ +static int +roundup(char *s0, int ndigits) +{ + char *s; + + for (s = s0 + ndigits - 1; *s == 0xf; s--) { + if (s == s0) { + *s = 1; + return (1); + } + *s = 0; + } + ++*s; + return (0); +} + +/* + * Round the given digit string to ndigits digits according to the + * current rounding mode. Note that this could produce a string whose + * value is not representable in the corresponding floating-point + * type. The exponent pointed to by decpt is adjusted if necessary. + */ +static void +dorounding(char *s0, int ndigits, int sign, int *decpt) +{ + int adjust = 0; /* do we need to adjust the exponent? */ + + switch (FLT_ROUNDS) { + case 0: /* toward zero */ + default: /* implementation-defined */ + break; + case 1: /* to nearest, halfway rounds to even */ + if ((s0[ndigits] > 8) || + (s0[ndigits] == 8 && s0[ndigits - 1] & 1)) + adjust = roundup(s0, ndigits); + break; + case 2: /* toward +inf */ + if (sign == 0) + adjust = roundup(s0, ndigits); + break; + case 3: /* toward -inf */ + if (sign != 0) + adjust = roundup(s0, ndigits); + break; + } + + if (adjust) + *decpt += 4; +} + +/* + * This procedure converts a double-precision number in IEEE format + * into a string of hexadecimal digits and an exponent of 2. Its + * behavior is bug-for-bug compatible with dtoa() in mode 2, with the + * following exceptions: + * + * - An ndigits < 0 causes it to use as many digits as necessary to + * represent the number exactly. + * - The additional xdigs argument should point to either the string + * "0123456789ABCDEF" or the string "0123456789abcdef", depending on + * which case is desired. + * - This routine does not repeat dtoa's mistake of setting decpt + * to 9999 in the case of an infinity or NaN. INT_MAX is used + * for this purpose instead. + * + * Note that the C99 standard does not specify what the leading digit + * should be for non-zero numbers. For instance, 0x1.3p3 is the same + * as 0x2.6p2 is the same as 0x4.cp3. This implementation chooses the + * first digit so that subsequent digits are aligned on nibble + * boundaries (before rounding). + * + * Inputs: d, xdigs, ndigits + * Outputs: decpt, sign, rve + */ +char * +__hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, + char **rve) +{ + static const int sigfigs = (DBL_MANT_DIG + 3) / 4; + union IEEEd2bits u; + char *s, *s0; + int bufsize; + + u.d = d; + *sign = u.bits.sign; + + switch (fpclassify(d)) { + case FP_NORMAL: + *decpt = u.bits.exp - DBL_ADJ; + break; + case FP_ZERO: + *decpt = 1; + return (nrv_alloc("0", rve, 1)); + case FP_SUBNORMAL: + u.d *= 0x1p514; + *decpt = u.bits.exp - (514 + DBL_ADJ); + break; + case FP_INFINITE: + *decpt = INT_MAX; + return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1)); + case FP_NAN: + *decpt = INT_MAX; + return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1)); + default: + abort(); + } + + /* FP_NORMAL or FP_SUBNORMAL */ + + if (ndigits == 0) /* dtoa() compatibility */ + ndigits = 1; + + /* + * For simplicity, we generate all the digits even if the + * caller has requested fewer. + */ + bufsize = (sigfigs > ndigits) ? sigfigs : ndigits; + s0 = rv_alloc(bufsize); + + /* + * We work from right to left, first adding any requested zero + * padding, then the least significant portion of the + * mantissa, followed by the most significant. The buffer is + * filled with the byte values 0x0 through 0xf, which are + * converted to xdigs[0x0] through xdigs[0xf] after the + * rounding phase. + */ + for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--) + *s = 0; + for (; s > s0 + sigfigs - (DBL_MANL_SIZE / 4) - 1 && s > s0; s--) { + *s = u.bits.manl & 0xf; + u.bits.manl >>= 4; + } + for (; s > s0; s--) { + *s = u.bits.manh & 0xf; + u.bits.manh >>= 4; + } + + /* + * At this point, we have snarfed all the bits in the + * mantissa, with the possible exception of the highest-order + * (partial) nibble, which is dealt with by the next + * statement. We also tack on the implicit normalization bit. + */ + *s = u.bits.manh | (1U << ((DBL_MANT_DIG - 1) % 4)); + + /* If ndigits < 0, we are expected to auto-size the precision. */ + if (ndigits < 0) { + for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--) + ; + } + + if (sigfigs > ndigits && s0[ndigits] != 0) + dorounding(s0, ndigits, u.bits.sign, decpt); + + s = s0 + ndigits; + if (rve != NULL) + *rve = s; + *s-- = '\0'; + for (; s >= s0; s--) + *s = xdigs[(unsigned int)*s]; + + return (s0); +} + +#if (LDBL_MANT_DIG > DBL_MANT_DIG) + +/* + * This is the long double version of __hdtoa(). + */ +char * +__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign, + char **rve) +{ + static const int sigfigs = (LDBL_MANT_DIG + 3) / 4; + union IEEEl2bits u; + char *s, *s0; + int bufsize; +#ifdef LDBL_HEAD_TAIL_PAIR + uint32_t bits[4]; + int i, pos; +#endif /* LDBL_HEAD_TAIL_PAIR */ + + u.e = e; + *sign = u.bits.sign; + + switch (fpclassify(e)) { + case FP_NORMAL: + case FP_SUPERNORMAL: + *decpt = u.bits.exp - LDBL_ADJ; + break; + case FP_ZERO: + *decpt = 1; + return (nrv_alloc("0", rve, 1)); + case FP_SUBNORMAL: + u.e *= 0x1p514L; + *decpt = u.bits.exp - (514 + LDBL_ADJ); + break; + case FP_INFINITE: + *decpt = INT_MAX; + return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1)); + case FP_NAN: + *decpt = INT_MAX; + return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1)); + default: + abort(); + } + + /* FP_NORMAL or FP_SUBNORMAL */ + + if (ndigits == 0) /* dtoa() compatibility */ + ndigits = 1; + + /* + * For simplicity, we generate all the digits even if the + * caller has requested fewer. + */ + bufsize = (sigfigs > ndigits) ? sigfigs : ndigits; + s0 = rv_alloc(bufsize); + + /* + * We work from right to left, first adding any requested zero + * padding, then the least significant portion of the + * mantissa, followed by the most significant. The buffer is + * filled with the byte values 0x0 through 0xf, which are + * converted to xdigs[0x0] through xdigs[0xf] after the + * rounding phase. + */ + for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--) + *s = 0; +#ifdef LDBL_HEAD_TAIL_PAIR + _ldbl2array32dd(u, bits); + i = 0; + pos = 8; + for (; s > s0; s--) { + *s = bits[i] & 0xf; + bits[i] >>= 4; + if (--pos <= 0) { + i++; + pos = 8; + } + } +#else /* LDBL_HEAD_TAIL_PAIR */ + for (; s > s0 + sigfigs - (LDBL_MANL_SIZE / 4) - 1 && s > s0; s--) { + *s = u.bits.manl & 0xf; + u.bits.manl >>= 4; + } + for (; s > s0; s--) { + *s = u.bits.manh & 0xf; + u.bits.manh >>= 4; + } +#endif /* LDBL_HEAD_TAIL_PAIR */ + + /* + * At this point, we have snarfed all the bits in the + * mantissa, with the possible exception of the highest-order + * (partial) nibble, which is dealt with by the next + * statement. We also tack on the implicit normalization bit. + */ +#ifdef LDBL_HEAD_TAIL_PAIR + *s = bits[i]; +#else /* LDBL_HEAD_TAIL_PAIR */ + *s = u.bits.manh | (1U << ((LDBL_MANT_DIG - 1) % 4)); +#endif /* LDBL_HEAD_TAIL_PAIR */ + + /* If ndigits < 0, we are expected to auto-size the precision. */ + if (ndigits < 0) { + for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--) + ; + } + + if (sigfigs > ndigits && s0[ndigits] != 0) + dorounding(s0, ndigits, u.bits.sign, decpt); + + s = s0 + ndigits; + if (rve != NULL) + *rve = s; + *s-- = '\0'; + for (; s >= s0; s--) + *s = xdigs[(unsigned int)*s]; + + return (s0); +} + +#else /* (LDBL_MANT_DIG == DBL_MANT_DIG) */ + +char * +__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign, + char **rve) +{ + + return (__hdtoa((double)e, xdigs, ndigits, decpt, sign, rve)); +} + +#endif /* (LDBL_MANT_DIG == DBL_MANT_DIG) */ diff --git a/gdtoa/FreeBSD/_ldbl_util.c b/gdtoa/_ldbl_util.c similarity index 89% rename from gdtoa/FreeBSD/_ldbl_util.c rename to gdtoa/_ldbl_util.c index 41357a5..1c55d27 100644 --- a/gdtoa/FreeBSD/_ldbl_util.c +++ b/gdtoa/_ldbl_util.c @@ -39,11 +39,11 @@ __private_extern__ void _ldbl2array32dd(union IEEEl2bits u, uint32_t *a) { - int bit, shift, highbit; + int bit, shift, highbit, dexp; uint64_t a64[2]; int64_t t64; - bzero(a64, 2 * sizeof(*a64)); + bzero(a64, sizeof(a64)); switch (__fpclassifyd(u.d[0])) { case FP_NORMAL: @@ -57,9 +57,17 @@ _ldbl2array32dd(union IEEEl2bits u, uint32_t *a) goto done; } + dexp = (int)u.bits.exp - (int)u.bits.exp2; + /* + * if the tail double is so small to not fit in LDBL_MANT_DIG bits, + * then just skip it. + */ + if (dexp >= LDBL_MANT_DIG) + goto done; + switch (__fpclassifyd(u.d[1])) { case FP_NORMAL: - bit = LDBL_MANT_DIG - (int)u.bits.exp + (int)u.bits.exp2 - 1; + bit = LDBL_MANT_DIG - dexp - 1; t64 = (1LL << bit); break; case FP_SUBNORMAL: diff --git a/gdtoa/_ldtoa-fbsd.c b/gdtoa/_ldtoa-fbsd.c new file mode 100644 index 0000000..dc99b3d --- /dev/null +++ b/gdtoa/_ldtoa-fbsd.c @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 2003 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/gdtoa/_ldtoa.c,v 1.2 2004/01/18 07:53:49 das Exp $"); + +#include +#include +#include +#include +#include +#include "fpmath.h" +#include "gdtoaimp.h" + +/* + * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(), + * except that the floating point argument is passed by reference. + * When dtoa() is passed a NaN or infinity, it sets expt to 9999. + * However, a long double could have a valid exponent of 9999, so we + * use INT_MAX in ldtoa() instead. + */ +char * +__ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign, + char **rve) +{ + static FPI fpi0 = { + LDBL_MANT_DIG, /* nbits */ + LDBL_MIN_EXP - LDBL_MANT_DIG, /* emin */ + LDBL_MAX_EXP - LDBL_MANT_DIG, /* emax */ + FPI_Round_near, /* rounding */ +#ifdef Sudden_Underflow /* unused, but correct anyway */ + 1 +#else + 0 +#endif + }; + int be, kind; + char *ret; + union IEEEl2bits u; + uint32_t bits[(LDBL_MANT_DIG + 31) / 32]; + FPI *fpi = &fpi0, fpi1; +#ifdef Honor_FLT_ROUNDS + int rounding = Flt_Rounds; +#endif +#if defined(__ppc__) || defined(__ppc64__) + int type; +#endif /* defined(__ppc__) || defined(__ppc64__) */ + + u.e = *ld; +#if defined(__ppc__) || defined(__ppc64__) + /* + * Subnormal head-tail doubles don't seem to be converted correctly + * by gdtoa. So we multiply by 10^32 to make them normal then + * subtract 32 from the exponent later. + */ + if ((type = __fpclassify(u.e)) == FP_NORMAL && __fpclassifyd(u.d[1]) == FP_SUBNORMAL) + type = FP_SUBNORMAL; + if (type == FP_SUBNORMAL) + u.e *= 1.0e32L; +#endif /* defined(__ppc__) || defined(__ppc64__) */ + *sign = u.bits.sign; + be = u.bits.exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1); + LDBL_TO_ARRAY32(u, bits); + +#if defined(__ppc__) || defined(__ppc64__) + switch (type) { + case FP_SUBNORMAL: +#else /* !defined(__ppc__) && !defined(__ppc64__) */ + switch (fpclassify(u.e)) { +#endif /* defined(__ppc__) || defined(__ppc64__) */ + case FP_NORMAL: + case FP_SUPERNORMAL: + kind = STRTOG_Normal; +/* For ppc/ppc64 and head-tail long double, the implicit bit is already there */ +#if !defined(__ppc__) && !defined(__ppc64__) +#ifdef LDBL_IMPLICIT_NBIT + bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32); +#endif /* LDBL_IMPLICIT_NBIT */ +#endif /* !defined(__ppc__) && !defined(__ppc64__) */ + break; + case FP_ZERO: + kind = STRTOG_Zero; + break; +#if !defined(__ppc__) && !defined(__ppc64__) + case FP_SUBNORMAL: + kind = STRTOG_Denormal; + be++; + break; +#endif /* !defined(__ppc__) && !defined(__ppc64__) */ + case FP_INFINITE: + kind = STRTOG_Infinite; + break; + case FP_NAN: + kind = STRTOG_NaN; + break; + default: + abort(); + } + +#ifdef Honor_FLT_ROUNDS + if (rounding != fpi0.rounding) { + fpi1 = fpi0; /* for thread safety */ + fpi1.rounding = rounding; + fpi = &fpi1; + } +#endif /* Honor_FLT_ROUNDS */ + ret = gdtoa(fpi, be, (ULong *)bits, &kind, mode, ndigits, decpt, rve); + if (*decpt == -32768) + *decpt = INT_MAX; +#if defined(__ppc__) || defined(__ppc64__) + else if (type == FP_SUBNORMAL) + *decpt -= 32; +#endif /* defined(__ppc__) || defined(__ppc64__) */ + return ret; +} diff --git a/gdtoa/arith.h b/gdtoa/arith.h index f1c936e..2ebf333 100644 --- a/gdtoa/arith.h +++ b/gdtoa/arith.h @@ -44,3 +44,5 @@ #else #error Unsupported architecture #endif + +#define Honor_FLT_ROUNDS diff --git a/gdtoa/gdtoa-dmisc-fbsd.c b/gdtoa/gdtoa-dmisc-fbsd.c new file mode 100644 index 0000000..ce170c7 --- /dev/null +++ b/gdtoa/gdtoa-dmisc-fbsd.c @@ -0,0 +1,216 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 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" + +#ifndef MULTIPLE_THREADS + char *dtoa_result; +#endif + + char * +#ifdef KR_headers +rv_alloc(i) int i; +#else +rv_alloc(int i) +#endif +{ + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; + j <<= 1) + k++; + r = (int*)Balloc(k); + *r = k; + return +#ifndef MULTIPLE_THREADS + dtoa_result = +#endif + (char *)(r+1); + } + + char * +#ifdef KR_headers +nrv_alloc(s, rve, n) char *s, **rve; int n; +#else +nrv_alloc(char *s, char **rve, int n) +#endif +{ + char *rv, *t; + + t = rv = rv_alloc(n); + while((*t = *s++) !=0) + t++; + if (rve) + *rve = t; + return rv; + } + +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + + void +#ifdef KR_headers +freedtoa(s) char *s; +#else +freedtoa(char *s) +#endif +{ + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b); +#ifndef MULTIPLE_THREADS + if (s == dtoa_result) + dtoa_result = 0; +#endif + } + + int +quorem +#ifdef KR_headers + (b, S) Bigint *b, *S; +#else + (Bigint *b, Bigint *S) +#endif +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & 0xffffffffUL) - borrow; + borrow = y >> 32 & 1UL; + *bx++ = y & 0xffffffffUL; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & 0xffffffffUL) - borrow; + borrow = y >> 32 & 1UL; + *bx++ = y & 0xffffffffUL; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; + } diff --git a/gdtoa/gdtoa-dtoa-fbsd.c b/gdtoa/gdtoa-dtoa-fbsd.c new file mode 100644 index 0000000..e808cc1 --- /dev/null +++ b/gdtoa/gdtoa-dtoa-fbsd.c @@ -0,0 +1,753 @@ +/**************************************************************** + +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" + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + + char * +dtoa +#ifdef KR_headers + (d, mode, ndigits, decpt, sign, rve) + double d; int mode, ndigits, *decpt, *sign; char **rve; +#else + (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) +#endif +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + double d2, ds, eps; + char *s, *s0; +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + 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) +#else + if (word0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; +#ifdef IEEE_Arith + 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 */ +#endif + if (!dval(d)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + +#ifdef SET_INEXACT + try_quick = oldinexact = get_inexact(); + inexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (*sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif + + b = d2b(dval(d), &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + 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; +#ifdef IBM + 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) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* 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 */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + 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]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + +#ifndef SET_INEXACT +#ifdef Check_FLT_ROUNDS + try_quick = Rounding == 1; +#else + try_quick = 1; +#endif +#endif /*SET_INEXACT*/ + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i); + +#ifdef Honor_FLT_ROUNDS + if (mode > 1 && rounding != 1) + leftright = 0; +#endif + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(d2) = dval(d); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(d) /= ds; + } + else if (( j1 = -k )!=0) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + 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)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = 0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = dval(d); + dval(d) -= L; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) + goto ret1; + if (1. - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + 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)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(d) > 0.5 + dval(eps)) + goto bump_up; + else if (dval(d) < 0.5 - dval(eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(d) = dval(d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + 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; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(d)) { +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } +#endif + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if (( j = b5 - m5 )!=0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) +#ifdef Honor_FLT_ROUNDS + && rounding == 1 +#endif + ) { + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * 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) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && mode != 1 && !(word1(d) & 1) +#ifdef Honor_FLT_ROUNDS + && rounding >= 1 +#endif + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; +#ifdef SET_INEXACT + else if (!b->x[0] && b->wds <= 1) + inexact = 0; +#endif + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || j == 0 && mode != 1 +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + ) { + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto accept_dig; + } +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } +#endif /*Honor_FLT_ROUNDS*/ + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || j1 == 0 && dig & 1) + && dig++ == '9') + goto round_9_up; + } + accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { +#ifdef Honor_FLT_ROUNDS + if (!rounding) + goto accept_dig; +#endif + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } +#ifdef Honor_FLT_ROUNDS + keep_dig: +#endif + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + +#ifdef Honor_FLT_ROUNDS + switch(rounding) { + case 0: goto trimzeros; + case 2: goto roundoff; + } +#endif + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || j == 0 && dig & 1) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + trimzeros: + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(d) = Exp_1 + (70 << Exp_shift); + word1(d) = 0; + dval(d) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; + } diff --git a/gdtoa/gdtoa-gdtoa-fbsd.c b/gdtoa/gdtoa-gdtoa-fbsd.c new file mode 100644 index 0000000..4a48887 --- /dev/null +++ b/gdtoa/gdtoa-gdtoa-fbsd.c @@ -0,0 +1,761 @@ +/**************************************************************** + +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" + + static Bigint * +#ifdef KR_headers +bitstob(bits, nbits, bbits) ULong *bits; int nbits; int *bbits; +#else +bitstob(ULong *bits, int nbits, int *bbits) +#endif +{ + int i, k; + Bigint *b; + ULong *be, *x, *x0; + + i = ULbits; + k = 0; + while(i < nbits) { + i <<= 1; + k++; + } +#ifndef Pack_32 + if (!k) + k = 1; +#endif + b = Balloc(k); + be = bits + ((nbits - 1) >> kshift); + x = x0 = b->x; + do { + *x++ = *bits & ALL_ON; +#ifdef Pack_16 + *x++ = (*bits >> 16) & ALL_ON; +#endif + } while(++bits <= be); + i = x - x0; + while(!x0[--i]) + if (!i) { + b->wds = 0; + *bbits = 0; + goto ret; + } + b->wds = i + 1; + *bbits = i*ULbits + 32 - hi0bits(b->x[i]); + ret: + return b; + } + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + + char * +gdtoa +#ifdef KR_headers + (fpi, be, bits, kindp, mode, ndigits, decpt, rve) + FPI *fpi; int be; ULong *bits; + int *kindp, mode, ndigits, *decpt; char **rve; +#else + (FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve) +#endif +{ + /* Arguments ndigits and decpt are similar to the second and third + arguments of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4-9 should give the same return values as 2-3, i.e., + 4 <= mode <= 9 ==> same return as mode + 2 + (mode & 1). These modes are mainly for + debugging; often they run slower but sometimes + faster than modes 2-3. + 4,5,8,9 ==> left-to-right digit generation. + 6-9 ==> don't try fast floating-point estimate + (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex; + int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits; + int rdir, s2, s5, spec_case, try_quick; + Long L; + Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S; + double d, d2, ds, eps; + char *s, *s0; + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + inex = 0; + kind = *kindp &= ~STRTOG_Inexact; + switch(kind & STRTOG_Retmask) { + case STRTOG_Zero: + goto ret_zero; + case STRTOG_Normal: + case STRTOG_Denormal: + break; + case STRTOG_Infinite: + *decpt = -32768; + return nrv_alloc("Infinity", rve, 8); + case STRTOG_NaN: + *decpt = -32768; + return nrv_alloc("NaN", rve, 3); + default: + return 0; + } + b = bitstob(bits, nbits = fpi->nbits, &bbits); + be0 = be; + if ( (i = trailz(b)) !=0) { + rshift(b, i); + be += i; + bbits -= i; + } + if (!b->wds) { + Bfree(b); + ret_zero: + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + + dval(d) = b2d(b, &i); + i = be + bbits - 1; + word0(d) &= Frac_mask1; + word0(d) |= Exp_11; +#ifdef IBM + 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) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ +#ifdef IBM + i <<= 2; + i += j; +#endif + ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + + /* correct assumption about exponent range */ + if ((j = i) < 0) + j = -j; + if ((j -= 1077) > 0) + ds += j * 7e-17; + + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; +#ifdef IBM + j = be + bbits - 1; + if ( (j1 = j & 3) !=0) + dval(d) *= 1 << j1; + word0(d) += j << Exp_shift - 2 & Exp_mask; +#else + word0(d) += (be + bbits - 1) << Exp_shift; +#endif + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + try_quick = 1; + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = (int)(nbits * .30103) + 3; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i); + + if ( (rdir = fpi->rounding - 1) !=0) { + if (rdir < 0) + rdir = 2; + if (kind & STRTOG_Neg) + rdir = 3 - rdir; + } + + /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */ + + if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir +#ifndef IMPRECISE_INEXACT + && k == 0 +#endif + ) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + d2 = dval(d); +#ifdef IBM + if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) + dval(d) /= 1 << j; +#endif + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + } + else { + ds = 1.; + if ( (j1 = -k) !=0) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + 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)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = ds*0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = (Long)(dval(d)/ds); + dval(d) -= L*ds; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) { + if (dval(d)) + inex = STRTOG_Inexlo; + goto ret1; + } + if (ds - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + 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; + *s++ = '0' + (int)L; + if (i == ilim) { + ds *= 0.5; + if (dval(d) > ds + dval(eps)) + goto bump_up; + else if (dval(d) < ds - dval(eps)) { + while(*--s == '0'){} + s++; + if (dval(d)) + inex = STRTOG_Inexlo; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(d) = d2; + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + 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; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (dval(d) == 0.) + break; + if (i == ilim) { + if (rdir) { + if (rdir == 1) + goto bump_up; + inex = STRTOG_Inexlo; + goto ret1; + } + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { + bump_up: + inex = STRTOG_Inexhi; + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + else { + inex = STRTOG_Inexlo; + while(*--s == '0'){} + s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + if (mode < 2) { + i = nbits - bbits; + if (be - i++ < fpi->emin) + /* denormal */ + i = be - fpi->emin + 1; + } + else { + j = ilim - 1; + if (m5 >= j) + m5 -= j; + else { + s5 += j -= m5; + b5 += j; + m5 = 0; + } + if ((i = ilim) < 0) { + m2 -= i; + i = 0; + } + } + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ( (j = b5 - m5) !=0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if (mode < 2) { + if (bbits == 1 && be0 > fpi->emin + 1) { + /* The special case */ + b2++; + s2++; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * 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) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && mode > 2) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + inex = STRTOG_Inexlo; + goto ret; + } + one_digit: + inex = STRTOG_Inexhi; + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, 1); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) { + if (dig == '9') + goto round_9_up; + if (j <= 0) { + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + } + else { + dig++; + inex = STRTOG_Inexhi; + } + *s++ = dig; + goto ret; + } +#endif + 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; + goto accept; + } + while (cmp(S,mhi) > 0) { + *s++ = dig; + mhi1 = multadd(mhi, 10, 0); + if (mlo == mhi) + mlo = mhi1; + mhi = mhi1; + b = multadd(b, 10, 0); + dig = quorem(b,S) + '0'; + } + if (dig++ == '9') + goto round_9_up; + inex = STRTOG_Inexhi; + goto accept; + } + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || j1 == 0 && dig & 1) + && dig++ == '9') + goto round_9_up; + inex = STRTOG_Inexhi; + } + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + accept: + *s++ = dig; + goto ret; + } + if (j1 > 0 && rdir != 2) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + inex = STRTOG_Inexhi; + goto roundoff; + } + inex = STRTOG_Inexhi; + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + + if (rdir) { + 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) { + roundoff: + inex = STRTOG_Inexhi; + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + chopzeros: + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + while(*--s == '0'){} + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + *kindp |= inex; + return s0; + } diff --git a/gdtoa/gdtoa-gethex-fbsd.c b/gdtoa/gdtoa-gethex-fbsd.c new file mode 100644 index 0000000..36d1d19 --- /dev/null +++ b/gdtoa/gdtoa-gethex-fbsd.c @@ -0,0 +1,281 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 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 "xlocale_private.h" + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + + int +#ifdef KR_headers +gethex(sp, fpi, exp, bp, sign, loc) + CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign; locale_t loc; +#else +gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t loc) +#endif +{ + Bigint *b; + CONST unsigned char *decpt, *s0, *s, *s1; + int esign, havedig, irv, k, n, nbits, up, zret; + ULong L, lostbits, *x; + Long e, e1; +#ifdef USE_LOCALE + char *decimalpoint; + unsigned char *decimalpointend = NULL; + int decimalpointlen; + + NORMALIZE_LOCALE(loc); + decimalpoint = localeconv_l(loc)->decimal_point; + decimalpointlen = strlen(decimalpoint); +#else +#define decimalpoint '.' +#endif + + if (!hexdig['0']) + hexdig_init_D2A(); + havedig = 0; + s0 = *(CONST unsigned char **)sp + 2; + while(s0[havedig] == '0') + havedig++; + s0 += havedig; + s = s0; + decpt = 0; + zret = 0; + e = 0; + if (!hexdig[*s]) { + zret = 1; +#ifdef USE_LOCALE + if (strncmp((char *)s, decimalpoint, decimalpointlen) != 0) +#else /* USE_LOCALE */ + if (*s != decimalpoint) +#endif /* USE_LOCALE */ + goto pcheck; +#ifdef USE_LOCALE + decpt = (s += decimalpointlen); + decimalpointend = s - 1; +#else /* USE_LOCALE */ + decpt = ++s; +#endif /* USE_LOCALE */ + if (!hexdig[*s]) + goto pcheck; + while(*s == '0') + s++; + if (hexdig[*s]) + zret = 0; + havedig = 1; + s0 = s; + } + while(hexdig[*s]) + s++; +#ifdef USE_LOCALE + if (strncmp((char *)s, decimalpoint, decimalpointlen) == 0 && !decpt) +#else /* USE_LOCALE */ + if (*s == decimalpoint && !decpt) +#endif /* USE_LOCALE */ + { +#ifdef USE_LOCALE + decpt = (s += decimalpointlen); + decimalpointend = s - 1; +#else /* USE_LOCALE */ + decpt = ++s; +#endif /* USE_LOCALE */ + while(hexdig[*s]) + s++; + } + if (decpt) + e = -(((Long)(s-decpt)) << 2); + pcheck: + s1 = s; + switch(*s) { + case 'p': + case 'P': + esign = 0; + switch(*++s) { + case '-': + esign = 1; + /* no break */ + case '+': + s++; + } + if ((n = hexdig[*s]) == 0 || n > 0x19) { + s = s1; + break; + } + e1 = n - 0x10; + while((n = hexdig[*++s]) !=0 && n <= 0x19) + e1 = 10*e1 + n - 0x10; + if (esign) + e1 = -e1; + e += e1; + } + *sp = (char*)s; + if (zret) + return havedig ? STRTOG_Zero : STRTOG_NoNumber; + n = s1 - s0 - 1; + for(k = 0; n > 7; n >>= 1) + k++; + b = Balloc(k); + x = b->x; + n = 0; + L = 0; + while(s1 > s0) { +#ifdef USE_LOCALE + if (--s1 == decimalpointend) { + s1 -= decimalpointlen - 1; + continue; + } +#else /* USE_LOCALE */ + if (*--s1 == decimalpoint) + continue; +#endif /* USE_LOCALE */ + if (n == 32) { + *x++ = L; + L = 0; + n = 0; + } + L |= (hexdig[*s1] & 0x0f) << n; + n += 4; + } + *x++ = L; + b->wds = n = x - b->x; + n = 32*n - hi0bits(L); + nbits = fpi->nbits; + lostbits = 0; + x = b->x; + if (n > nbits) { + n -= nbits; + if (any_on(b,n)) { + lostbits = 1; + k = n - 1; + if (x[k>>kshift] & 1 << (k & kmask)) { + lostbits = 2; + if (k > 1 && any_on(b,k-1)) + lostbits = 3; + } + } + rshift(b, n); + e += n; + } + else if (n < nbits) { + n = nbits - n; + b = lshift(b, n); + e -= n; + x = b->x; + } + if (e > fpi->emax) { + ovfl: + Bfree(b); + *bp = 0; + return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; + } + irv = STRTOG_Normal; + if (e < fpi->emin) { + irv = STRTOG_Denormal; + n = fpi->emin - e; + if (n >= nbits) { + switch (fpi->rounding) { + case FPI_Round_near: + if (n == nbits && (n < 2 || any_on(b,n-1))) + goto one_bit; + break; + case FPI_Round_up: + if (!sign) + goto one_bit; + break; + case FPI_Round_down: + if (sign) { + one_bit: + *exp = fpi->emin; + x[0] = b->wds = 1; + *bp = b; + return STRTOG_Denormal | STRTOG_Inexhi + | STRTOG_Underflow; + } + } + Bfree(b); + *bp = 0; + return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow; + } + k = n - 1; + if (lostbits) + lostbits = 1; + else if (k > 0) + lostbits = any_on(b,k); + if (x[k>>kshift] & 1 << (k & kmask)) + lostbits |= 2; + nbits -= n; + rshift(b,n); + e = fpi->emin; + } + if (lostbits) { + up = 0; + switch(fpi->rounding) { + case FPI_Round_zero: + break; + case FPI_Round_near: + if (lostbits & 2 + && (lostbits & 1) | x[0] & 1) + up = 1; + break; + case FPI_Round_up: + up = 1 - sign; + break; + case FPI_Round_down: + up = sign; + } + if (up) { + k = b->wds; + b = increment(b); + x = b->x; + if (irv == STRTOG_Denormal) { + if (nbits == fpi->nbits - 1 + && x[nbits >> kshift] & 1 << (nbits & kmask)) + irv = STRTOG_Normal; + } + else if (b->wds > k + || (n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n) { + rshift(b,1); + if (++e > fpi->emax) + goto ovfl; + } + irv |= STRTOG_Inexhi; + } + else + irv |= STRTOG_Inexlo; + } + *bp = b; + *exp = e; + return irv; + } diff --git a/gdtoa/gdtoa-gmisc-fbsd.c b/gdtoa/gdtoa-gmisc-fbsd.c new file mode 100644 index 0000000..8270ef9 --- /dev/null +++ b/gdtoa/gdtoa-gmisc-fbsd.c @@ -0,0 +1,86 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 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" + + void +#ifdef KR_headers +rshift(b, k) Bigint *b; int k; +#else +rshift(Bigint *b, int k) +#endif +{ + ULong *x, *x1, *xe, y; + int n; + + x = x1 = b->x; + n = k >> kshift; + if (n < b->wds) { + xe = x + b->wds; + x += n; + if (k &= kmask) { + n = ULbits - k; + y = *x++ >> k; + while(x < xe) { + *x1++ = (y | (*x << n)) & ALL_ON; + y = *x++ >> k; + } + if ((*x1 = y) !=0) + x1++; + } + else + while(x < xe) + *x1++ = *x++; + } + if ((b->wds = x1 - b->x) == 0) + b->x[0] = 0; + } + + int +#ifdef KR_headers +trailz(b) Bigint *b; +#else +trailz(Bigint *b) +#endif +{ + ULong L, *x, *xe; + int n = 0; + + x = b->x; + xe = x + b->wds; + for(n = 0; x < xe && !*x; x++) + n += ULbits; + if (x < xe) { + L = *x; + n += lo0bits(&L); + } + return n; + } diff --git a/gdtoa/gdtoa-hd_init-fbsd.c b/gdtoa/gdtoa-hd_init-fbsd.c new file mode 100644 index 0000000..fa6e18d --- /dev/null +++ b/gdtoa/gdtoa-hd_init-fbsd.c @@ -0,0 +1,55 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2000 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" + + unsigned char hexdig[256]; + + static void +#ifdef KR_headers +htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; +#else +htinit(unsigned char *h, unsigned char *s, int inc) +#endif +{ + int i, j; + for(i = 0; (j = s[i]) !=0; i++) + h[j] = i + inc; + } + + void +hexdig_init_D2A(Void) +{ +#define USC (unsigned char *) + htinit(hexdig, USC "0123456789", 0x10); + htinit(hexdig, USC "abcdef", 0x10 + 10); + htinit(hexdig, USC "ABCDEF", 0x10 + 10); + } diff --git a/gdtoa/gdtoa-hexnan-fbsd.c b/gdtoa/gdtoa-hexnan-fbsd.c new file mode 100644 index 0000000..6ba12a8 --- /dev/null +++ b/gdtoa/gdtoa-hexnan-fbsd.c @@ -0,0 +1,110 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2000 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" +#include + + static void +#ifdef KR_headers +L_shift(x, x1, i) ULong *x; ULong *x1; int i; +#else +L_shift(ULong *x, ULong *x1, int i) +#endif +{ + int j; + + i = 8 - i; + i <<= 2; + j = ULbits - i; + do { + *x |= x[1] << j; + x[1] >>= i; + } while(++x < x1); + } + + int +#ifdef KR_headers +hexnan(sp, fpi, x0) + CONST char **sp; FPI *fpi; ULong *x0; +#else +hexnan( CONST char **sp, FPI *fpi, ULong *x0) +#endif +{ + int nbits, len; + char *cp; + CONST char *s; + + if (sp == NULL || *sp == NULL || **sp != '(') + return STRTOG_NaN; + s = *sp; + if ((cp = strchr(s + 1, ')')) == NULL) { + *sp += strlen(s); + cp = s + 1; + } + else { + len = cp - (s + 1); + cp = alloca(len + 1); + if (!cp) + return STRTOG_NaN; + strlcpy(cp, s + 1, len + 1); + *sp += len + 2; + } + nbits = fpi->nbits; + /* a hack */ + if (nbits == 52) { /* double */ + union IEEEd2bits u; + u.d = nan(cp); + x0[1] = u.bits.manh; + x0[0] = u.bits.manl; + } + else if (nbits < 52) { /* float */ + union IEEEf2bits u; + u.f = nanf(cp); + x0[0] = u.bits.man; + } + else { /* long double */ + union IEEEl2bits u; + u.e = nanl(cp); +#if defined(__ppc__) || defined(__ppc64__) + x0[3] = (ULong)(u.bits.manh >> 44); + x0[2] = (ULong)(u.bits.manh >> 12); + x0[1] = ((ULong)u.bits.manh & 0xfff) << 20 | (ULong)(u.bits.manl >> 32); + x0[0] = (ULong)u.bits.manl; +#elif defined(__i386__) || defined(__x86_64__) + x0[1] = (ULong)u.bits.manh; + x0[0] = (ULong)u.bits.manl; +#else +#error unsupported architecture +#endif + } + + return STRTOG_NaNbits; + } diff --git a/gdtoa/gdtoa-misc-fbsd.c b/gdtoa/gdtoa-misc-fbsd.c new file mode 100644 index 0000000..b3ce7c9 --- /dev/null +++ b/gdtoa/gdtoa-misc-fbsd.c @@ -0,0 +1,865 @@ +/**************************************************************** + +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" + + static Bigint *freelist[Kmax+1]; +#ifndef Omit_Private_Memory +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; +#endif + + Bigint * +Balloc +#ifdef KR_headers + (k) int k; +#else + (int k) +#endif +{ + int x; + Bigint *rv; +#ifndef Omit_Private_Memory + unsigned int len; +#endif + + ACQUIRE_DTOA_LOCK(0); + if ( (rv = freelist[k]) !=0) { + freelist[k] = rv->next; + } + else { + x = 1 << k; +#ifdef Omit_Private_Memory + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else + rv = (Bigint*)MALLOC(len*sizeof(double)); +#endif + rv->k = k; + rv->maxwds = x; + } + FREE_DTOA_LOCK(0); + rv->sign = rv->wds = 0; + return rv; + } + + void +Bfree +#ifdef KR_headers + (v) Bigint *v; +#else + (Bigint *v) +#endif +{ + if (v) { + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); + } + } + + int +lo0bits +#ifdef KR_headers + (y) ULong *y; +#else + (ULong *y) +#endif +{ + register int k; + register ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; + } + + Bigint * +multadd +#ifdef KR_headers + (b, m, a) Bigint *b; int m, a; +#else + (Bigint *b, int m, int a) /* multiply by m and add a */ +#endif +{ + int i, wds; +#ifdef ULLong + ULong *x; + ULLong carry, y; +#else + ULong carry, *x, y; +#ifdef Pack_32 + ULong xi, z; +#endif +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = y & 0xffffffffUL; +#else +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = carry; + b->wds = wds; + } + return b; + } + + int +hi0bits_D2A +#ifdef KR_headers + (x) register ULong x; +#else + (register ULong x) +#endif +{ + register int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; + } + + Bigint * +i2b +#ifdef KR_headers + (i) int i; +#else + (int i) +#endif +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; + } + + Bigint * +mult +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; +#ifdef Pack_32 + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for(; xb < xbe; xc0++) { + if ( (y = *xb++) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = z & 0xffffffffUL; + } + while(x < xae); + *xc = carry; + } + } +#else +#ifdef Pack_32 + for(; xb < xbe; xb++, xc0++) { + if ( (y = *xb & 0xffff) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if ( (y = *xb >> 16) !=0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if ( (y = *xb++) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; + } + + static Bigint *p5s; + + Bigint * +pow5mult +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; + + if ( (i = k & 3) !=0) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if ((p5 = p5s) == 0) { + /* first time */ +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = p5s = i2b(625); + p5->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p5 = p5s = i2b(625); + p5->next = 0; +#endif + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if ((p51 = p5->next) == 0) { +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p51 = p5->next = mult(p5,p5); + p51->next = 0; +#endif + } + p5 = p51; + } + return b; + } + + Bigint * +lshift +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + + n = k >> kshift; + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; + if (k &= kmask) { +#ifdef Pack_32 + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z) !=0) + ++n1; +#else + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; +#endif + } + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; + } + + int +cmp +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; + } + + Bigint * +diff +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; +#ifdef Pack_32 + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & 1UL; + *xc++ = y & 0xffffffffUL; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & 1UL; + *xc++ = y & 0xffffffffUL; + } +#else +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; + } + + double +b2d +#ifdef KR_headers + (a, e) Bigint *a; int *e; +#else + (Bigint *a, int *e) +#endif +{ + ULong *xa, *xa0, w, y, z; + int k; + double d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> Ebits - k; + w = xa > xa0 ? *--xa : 0; + 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; + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> 32 - k; + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif + ret_d: +#ifdef VAX + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; +#endif + return dval(d); + } +#undef d0 +#undef d1 + + Bigint * +d2b +#ifdef KR_headers + (d, e, bits) double d; int *e, *bits; +#else + (double d, int *e, int *bits) +#endif +{ + Bigint *b; +#ifndef Sudden_Underflow + int i; +#endif + int de, k; + 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) +#endif + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ( (de = (int)(d0 >> Exp_shift)) !=0) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ( (y = d1) !=0) { + if ( (k = lo0bits(&y)) !=0) { + x[0] = y | z << 32 - k; + z >>= k; + } + else + x[0] = y; +#ifndef Sudden_Underflow + i = +#endif + 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 + i = +#endif + b->wds = 1; + k += 32; + } +#else + if ( (y = d1) !=0) { + if ( (k = lo0bits(&y)) !=0) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; + } +#undef d0 +#undef d1 + + CONST double +#ifdef IEEE_Arith +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 + }; +#else +#ifdef IBM +bigtens[] = { 1e16, 1e32, 1e64 }; +CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#else +bigtens[] = { 1e16, 1e32 }; +CONST double tinytens[] = { 1e-16, 1e-32 }; +#endif +#endif + + CONST double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif + }; + + char * +#ifdef KR_headers +strcp_D2A(a, b) char *a; char *b; +#else +strcp_D2A(char *a, CONST char *b) +#endif +{ + while(*a = *b++) + a++; + return a; + } + +#ifdef NO_STRING_H + + Char * +#ifdef KR_headers +memcpy_D2A(a, b, len) Char *a; Char *b; size_t len; +#else +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; + while(a < ae) + *a++ = *b++; + return a0; + } + +#endif /* NO_STRING_H */ diff --git a/gdtoa/gdtoa-smisc-fbsd.c b/gdtoa/gdtoa-smisc-fbsd.c new file mode 100644 index 0000000..b748c7e --- /dev/null +++ b/gdtoa/gdtoa-smisc-fbsd.c @@ -0,0 +1,191 @@ +/**************************************************************** + +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-strtod-fbsd.c b/gdtoa/gdtoa-strtod-fbsd.c new file mode 100644 index 0000000..bf9b093 --- /dev/null +++ b/gdtoa/gdtoa-strtod-fbsd.c @@ -0,0 +1,1014 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 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 "xlocale_private.h" + +#include "gdtoaimp.h" +#ifndef NO_FENV_H +#include +#endif + +#ifdef USE_LOCALE +#include "locale.h" +#endif + +#ifdef IEEE_Arith +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#undef tinytens +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, + 9007199254740992.e-256 + }; +#endif +#endif + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + + double +strtod_l +#ifdef KR_headers + (s00, se, loc) CONST char *s00; char **se; locale_t loc; +#else + (CONST char *s00, char **se, locale_t loc) +#endif +{ +#ifdef Avoid_Underflow + int scale; +#endif + 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; + Long L; + ULong y, z; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif +#ifdef Honor_FLT_ROUNDS + int rounding = Flt_Rounds; +#endif +#ifdef USE_LOCALE + char *decimal_point; + int decimal_point_len; +#endif /* USE_LOCALE */ + + sign = nz0 = nz = decpt = 0; + dval(rv) = 0.; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { +#ifndef NO_HEX_FP + { + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + Long exp; + ULong bits[2]; + switch(s[1]) { + case 'x': + case 'X': + { +#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) + FPI fpi1 = fpi; + switch(fegetround()) { + case FE_TOWARDZERO: fpi1.rounding = 0; break; + case FE_UPWARD: fpi1.rounding = 2; break; + case FE_DOWNWARD: fpi1.rounding = 3; + } +#else +#define fpi1 fpi +#endif + switch((i = gethex(&s, &fpi1, &exp, &bb, sign, loc)) & STRTOG_Retmask) { + case STRTOG_NoNumber: + s = s00; + sign = 0; + case STRTOG_Zero: + break; + default: + if (bb) { + copybits(bits, fpi.nbits, bb); + Bfree(bb); + } + ULtod(((U*)&rv)->L, bits, exp, i); + }} + goto ret; + } + } +#endif + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; + NORMALIZE_LOCALE(loc); +#ifdef USE_LOCALE + decimal_point = localeconv_l(loc)->decimal_point; + decimal_point_len = strlen(decimal_point); + if (strncmp(s, decimal_point, decimal_point_len) == 0) +#else + if (c == '.') +#endif + { + decpt = 1; +#ifdef USE_LOCALE + s += decimal_point_len; + c = *s; +#else + c = *++s; +#endif + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + ULong bits[2]; + static FPI fpinan = /* only 52 explicit bits */ + { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + if (!decpt) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(rv) = 0x7ff00000; + word1(rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { +#ifndef No_Hex_NaN + if (*s == '(' /*)*/ + && hexnan(&s, &fpinan, bits) + == STRTOG_NaNbits) { + word0(rv) = 0x7ff00000 | bits[1]; + word1(rv) = bits[0]; + } + else { +#endif + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; +#ifndef No_Hex_NaN + } +#endif + goto ret; + } + } +#endif /* INFNAN_CHECK */ + ret0: + s = s00; + sign = 0; + } + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + 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; + } + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT +#ifndef Honor_FLT_ROUNDS + && Flt_Rounds == 1 +#endif +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + e -= 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) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(rv), tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + +#ifdef IEEE_Arith +#ifdef SET_INEXACT + inexact = 1; + if (k <= DBL_DIG) + oldinexact = get_inexact(); +#endif +#ifdef Avoid_Underflow + scale = 0; +#endif +#ifdef Honor_FLT_ROUNDS + if (rounding >= 2) { + if (sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif +#endif /*IEEE_Arith*/ + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ( (i = e1 & 15) !=0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: +#ifndef NO_ERRNO + errno = ERANGE; +#endif + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith +#ifdef Honor_FLT_ROUNDS + switch(rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(rv) = Big0; + word1(rv) = Big1; + break; + default: + word0(rv) = Exp_mask; + word1(rv) = 0; + } +#else /*Honor_FLT_ROUNDS*/ + word0(rv) = Exp_mask; + word1(rv) = 0; +#endif /*Honor_FLT_ROUNDS*/ +#ifdef SET_INEXACT + /* set overflow bit */ + dval(rv0) = 1e300; + dval(rv0) *= dval(rv0); +#endif +#else /*IEEE_Arith*/ + word0(rv) = Big0; + word1(rv) = Big1; +#endif /*IEEE_Arith*/ + if (bd0) + goto retfree; + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + 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; + } + else + word0(rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ( (i = e1 & 15) !=0) + dval(rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + 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) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; zap j low bits */ + if (j >= 32) { + word1(rv) = 0; + if (j >= 53) + word0(rv) = (P+2)*Exp_msk1; + else + word0(rv) &= 0xffffffff << j-32; + } + else + word1(rv) &= 0xffffffff << j; + } +#else + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + 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]; +#endif + if (!dval(rv)) { + undfl: + dval(rv) = 0.; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + if (bd0) + goto retfree; + goto ret; + } +#ifndef Avoid_Underflow + word0(rv) = Tiny0; + word1(rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + +#ifdef USE_LOCALE + bd0 = s2b(s0, nd0, nd, y, decimal_point_len); +#else + bd0 = s2b(s0, nd0, nd, y, 1); +#endif + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) + bs2++; +#endif +#ifdef Avoid_Underflow + j = bbe - scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#else /*Avoid_Underflow*/ +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else /*Sudden_Underflow*/ + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (rounding) { + if (dsign) { + adj = 1.; + goto apply_adj; + } + } + else if (!dsign) { + 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 + if (y) +#endif + { + delta = lshift(delta,Log2P); + if (cmp(delta, bs) <= 0) + adj = -0.5; + } + } + apply_adj: +#ifdef Avoid_Underflow + 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; + dval(rv) += adj*ulp(dval(rv)); + word0(rv) -= P*Exp_msk1; + } + else +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + dval(rv) += adj*ulp(dval(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) { + if (!((rounding>>1) ^ dsign)) + y++; + adj = y; + } + } +#ifdef Avoid_Underflow + 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 (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + word0(rv) -= P*Exp_msk1; + goto cont; + } +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + goto cont; + } +#endif /*Honor_FLT_ROUNDS*/ + + if (i < 0) { + /* 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 +#ifdef IEEE_Arith +#ifdef Avoid_Underflow + || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 +#else + || (word0(rv) & Exp_mask) <= Exp_msk1 +#endif +#endif + ) { +#ifdef SET_INEXACT + if (!delta->x[0] && delta->wds <= 1) + inexact = 0; +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == ( +#ifdef Avoid_Underflow + (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) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(rv) = 0; +#ifdef Avoid_Underflow + dsign = 0; +#endif + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow /*{{*/ + L = word0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else +#ifdef Avoid_Underflow + if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) +#else + if (L <= Exp_msk1) +#endif /*Avoid_Underflow*/ +#endif /*IBM*/ + goto undfl; + L -= Exp_msk1; +#else /*Sudden_Underflow}{*/ +#ifdef Avoid_Underflow + if (scale) { + L = word0(rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + goto undfl; + } + } +#endif /*Avoid_Underflow*/ + L = (word0(rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}*/ + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(word1(rv) & LSB)) + break; +#endif + if (dsign) + dval(rv) += ulp(dval(rv)); +#ifndef ROUND_BIASED + else { + dval(rv) -= ulp(dval(rv)); +#ifndef Sudden_Underflow + if (!dval(rv)) + goto undfl; +#endif + } +#ifdef Avoid_Underflow + dsign = 1 - dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = aadj1 = 1.; + else if (word1(rv) || word0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(rv) == Tiny1 && !word0(rv)) + goto undfl; +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(Rounding) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (Flt_Rounds == 0) + aadj1 += 0.5; +#endif /*Check_FLT_ROUNDS*/ + } + 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) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) + goto ovfl; + word0(rv) = Big0; + word1(rv) = Big1; + goto cont; + } + else + word0(rv) += P*Exp_msk1; + } + else { +#ifdef Avoid_Underflow + if (scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = aadj) <= 0) + z = 1; + aadj = z; + aadj1 = dsign ? aadj : -aadj; + } + word0(aadj1) += (2*P+1)*Exp_msk1 - y; + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += 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; +#ifdef IBM + if ((word0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(rv0) == Tiny0 + && word1(rv0) == Tiny1) + goto undfl; + word0(rv) = Tiny0; + word1(rv) = Tiny1; + goto cont; + } + else + word0(rv) -= P*Exp_msk1; + } + else { + adj = aadj1 * ulp(dval(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., + * 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); + if (!dsign) + aadj1 = -aadj1; + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + } + z = word0(rv) & Exp_mask; +#ifndef SET_INEXACT +#ifdef Avoid_Underflow + if (!scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } +#endif + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(rv0) = Exp_1 + (70 << Exp_shift); + word1(rv0) = 0; + dval(rv0) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif +#ifdef Avoid_Underflow + if (scale) { + 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 __DARWIN_UNIX03 + if (word0(rv) == 0 && word1(rv) == 0 || dval(rv) < DBL_MIN) +#else /* !__DARWIN_UNIX03 */ + if (word0(rv) == 0 && word1(rv) == 0) +#endif /* __DARWIN_UNIX03 */ + errno = ERANGE; +#endif + } +#endif /* Avoid_Underflow */ +#ifdef SET_INEXACT + if (inexact && !(word0(rv) & Exp_mask)) { + /* set underflow bit */ + dval(rv0) = 1e-300; + dval(rv0) *= dval(rv0); + } +#endif + retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + ret: + if (se) + *se = (char *)s; + return sign ? -dval(rv) : dval(rv); + } + + double +strtod +#ifdef KR_headers + (s00, se) CONST char *s00; char **se; +#else + (CONST char *s00, char **se) +#endif +{ + return strtod_l(s00, se, __current_locale()); +} diff --git a/gdtoa/gdtoa-strtodg-fbsd.c b/gdtoa/gdtoa-strtodg-fbsd.c new file mode 100644 index 0000000..57b6864 --- /dev/null +++ b/gdtoa/gdtoa-strtodg-fbsd.c @@ -0,0 +1,1053 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 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 "xlocale_private.h" + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + +#define fivesbits __fivesbits_D2A +#define all_on __all_on_D2A +#define set_ones __set_ones_D2A +#define rvOK __rvOK_D2A +#define mantbits __mantbits_D2A + +#ifdef BUILDING_VARIANT +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); +#else /* !BUILDING_VARIANT */ + + __private_extern__ CONST int +fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, + 24, 26, 28, 31, 33, 35, 38, 40, 42, 45, + 47, 49, 52 +#ifdef VAX + , 54, 56 +#endif + }; + + Bigint * +#ifdef KR_headers +increment(b) Bigint *b; +#else +increment(Bigint *b) +#endif +{ + ULong *x, *xe; + Bigint *b1; +#ifdef Pack_16 + ULong carry = 1, y; +#endif + + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + do { + if (*x < (ULong)0xffffffffL) { + ++*x; + return b; + } + *x++ = 0; + } while(x < xe); +#else + do { + y = *x + carry; + carry = y >> 16; + *x++ = y & 0xffff; + if (!carry) + return b; + } while(x < xe); + if (carry) +#endif + { + if (b->wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1,b); + Bfree(b); + b = b1; + } + b->x[b->wds++] = 1; + } + return b; + } + + int +#ifdef KR_headers +decrement(b) Bigint *b; +#else +decrement(Bigint *b) +#endif +{ + ULong *x, *xe; +#ifdef Pack_16 + ULong borrow = 1, y; +#endif + + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + do { + if (*x) { + --*x; + break; + } + *x++ = 0xffffffffL; + } + while(x < xe); +#else + do { + y = *x - borrow; + borrow = (y & 0x10000) >> 16; + *x++ = y & 0xffff; + } while(borrow && x < xe); +#endif + return STRTOG_Inexlo; + } + + __private_extern__ int +#ifdef KR_headers +all_on(b, n) Bigint *b; int n; +#else +all_on(Bigint *b, int n) +#endif +{ + ULong *x, *xe; + + x = b->x; + xe = x + (n >> kshift); + while(x < xe) + if ((*x++ & ALL_ON) != ALL_ON) + return 0; + if (n &= kmask) + return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON; + return 1; + } + + Bigint * +#ifdef KR_headers +set_ones(b, n) Bigint *b; int n; +#else +set_ones(Bigint *b, int n) +#endif +{ + int k; + ULong *x, *xe; + + k = (n + ((1 << kshift) - 1)) >> kshift; + if (b->k < k) { + Bfree(b); + b = Balloc(k); + } + k = n >> kshift; + if (n &= kmask) + k++; + b->wds = k; + x = b->x; + xe = x + k; + while(x < xe) + *x++ = ALL_ON; + if (n) + x[-1] >>= ULbits - n; + return b; + } + + __private_extern__ int +rvOK +#ifdef KR_headers + (d, fpi, exp, bits, exact, rd, irv) + double 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) +#endif +{ + Bigint *b; + ULong carry, inex, lostbits; + int bdif, e, j, k, k1, nb, rv; + + carry = rv = 0; + b = d2b(d, &e, &bdif); + bdif -= nb = fpi->nbits; + e += bdif; + if (bdif <= 0) { + if (exact) + goto trunc; + goto ret; + } + if (P == nb) { + if ( +#ifndef IMPRECISE_INEXACT + exact && +#endif + fpi->rounding == +#ifdef RND_PRODQUOT + FPI_Round_near +#else + Flt_Rounds +#endif + ) goto trunc; + goto ret; + } + switch(rd) { + case 1: + goto trunc; + case 2: + break; + default: /* round near */ + k = bdif - 1; + if (k < 0) + goto trunc; + if (!k) { + if (!exact) + goto ret; + if (b->x[0] & 2) + break; + goto trunc; + } + if (b->x[k>>kshift] & ((ULong)1 << (k & kmask))) + break; + goto trunc; + } + /* "break" cases: round up 1 bit, then truncate; bdif > 0 */ + carry = 1; + trunc: + inex = lostbits = 0; + if (bdif > 0) { + if ( (lostbits = any_on(b, bdif)) !=0) + inex = STRTOG_Inexlo; + rshift(b, bdif); + if (carry) { + inex = STRTOG_Inexhi; + b = increment(b); + if ( (j = nb & kmask) !=0) + j = ULbits - j; + if (hi0bits(b->x[b->wds - 1]) != j) { + if (!lostbits) + lostbits = b->x[0] & 1; + rshift(b, 1); + e++; + } + } + } + else if (bdif < 0) + b = lshift(b, -bdif); + if (e < fpi->emin) { + k = fpi->emin - e; + e = fpi->emin; + if (k > nb || fpi->sudden_underflow) { + b->wds = inex = 0; + *irv = STRTOG_Underflow | STRTOG_Inexlo; + } + else { + k1 = k - 1; + if (k1 > 0 && !lostbits) + lostbits = any_on(b, k1); + if (!lostbits && !exact) + goto ret; + lostbits |= + carry = b->x[k1>>kshift] & (1 << (k1 & kmask)); + rshift(b, k); + *irv = STRTOG_Denormal; + if (carry) { + b = increment(b); + inex = STRTOG_Inexhi | STRTOG_Underflow; + } + else if (lostbits) + inex = STRTOG_Inexlo | STRTOG_Underflow; + } + } + else if (e > fpi->emax) { + e = fpi->emax + 1; + *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + b->wds = inex = 0; + } + *exp = e; + copybits(bits, nb, b); + *irv |= inex; + rv = 1; + ret: + Bfree(b); + return rv; + } + + __private_extern__ int +#ifdef KR_headers +mantbits(d) double d; +#else +mantbits(double d) +#endif +{ + ULong L; +#ifdef VAX + L = word1(d) << 16 | word1(d) >> 16; + if (L) +#else + if ( (L = word1(d)) !=0) +#endif + return P - lo0bits(&L); +#ifdef VAX + L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11; +#else + L = word0(d) | Exp_msk1; +#endif + return P - 32 - lo0bits(&L); + } + +#endif /* BUILDING_VARIANT */ + + int +strtodg +#ifdef KR_headers + (s00, se, fpi, exp, bits, loc) + CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits; locale_t loc; +#else + (CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits, locale_t loc) +#endif +{ + int abe, abits, asub; + int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm; + int dsign, e, e1, e2, emin, esign, finished, i, inex, irv; + 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; + Long L; + ULong y, z; + Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; +#ifdef USE_LOCALE + char *decimal_point; + int decimal_point_len; +#endif /* USE_LOCALE */ + + irv = STRTOG_Zero; + denorm = sign = nz0 = nz = 0; + dval(rv) = 0.; + rvb = 0; + nbits = fpi->nbits; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + sign = 0; + irv = STRTOG_NoNumber; + s = s00; + goto ret; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { +#ifndef NO_HEX_FP + switch(s[1]) { + case 'x': + case 'X': + irv = gethex(&s, fpi, exp, &rvb, sign, loc); + if (irv == STRTOG_NoNumber) { + s = s00; + sign = 0; + } + goto ret; + } +#endif + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + sudden_underflow = fpi->sudden_underflow; + s0 = s; + y = z = 0; + for(decpt = nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; + NORMALIZE_LOCALE(loc); +#ifdef USE_LOCALE + decimal_point = localeconv_l(loc)->decimal_point; + decimal_point_len = strlen(decimal_point); + if (strncmp(s, decimal_point, decimal_point_len) == 0) +#else + if (c == '.') +#endif + { + decpt = 1; +#ifdef USE_LOCALE + s += decimal_point_len; + c = *s; +#else + c = *++s; +#endif + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + irv = STRTOG_NoNumber; + s = s00; + goto ret; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + if (!decpt) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + irv = STRTOG_Infinite; + goto infnanexp; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + irv = STRTOG_NaN; + *exp = fpi->emax + 1; +#ifndef No_Hex_NaN + if (*s == '(') /*)*/ + irv = hexnan(&s, fpi, bits); +#endif + goto infnanexp; + } + } +#endif /* INFNAN_CHECK */ + irv = STRTOG_NoNumber; + s = s00; + } + goto ret; + } + + irv = STRTOG_Normal; + e1 = e -= nf; + rd = 0; + switch(fpi->rounding & 3) { + case FPI_Round_up: + rd = 2 - sign; + break; + case FPI_Round_zero: + rd = 1; + break; + case FPI_Round_down: + rd = 1 + sign; + } + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(rv) = y; + if (k > 9) + 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)) + goto ret; + } + else if (e > 0) { + if (e <= Ten_pmax) { +#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)) + goto ret; + e1 -= e; + goto rv_notOK; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e2 = e - i; + e1 -= 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) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto rv_notOK; + word0(adj) += P*Exp_msk1; + dval(rv) = dval(adj); +#else + /* rv = */ rounded_product(dval(rv), tens[e2]); +#endif + if (rvOK(dval(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)) + goto ret; + e1 -= e; + } +#endif + } + rv_notOK: + e1 += nd - k; + + /* Get starting approximation = rv * 10**e1 */ + + e2 = 0; + if (e1 > 0) { + if ( (i = e1 & 15) !=0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + 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; + } + 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]; + } + } + else if (e1 < 0) { + e1 = -e1; + if ( (i = e1 & 15) !=0) + dval(rv) /= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + 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; + } + 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]; + } + } +#ifdef IBM + /* e2 is a correction to the (base 2) exponent of the return + * value, reflecting adjustments above to avoid overflow in the + * native arithmetic. For native IBM (base 16) arithmetic, we + * must multiply e2 by 4 to change from base 16 to 2. + */ + e2 <<= 2; +#endif + rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */ + rve += e2; + if ((j = rvbits - nbits) > 0) { + rshift(rvb, j); + rvbits = nbits; + rve += j; + } + bb0 = 0; /* trailing zero bits in rvb */ + e2 = rve + rvbits - nbits; + if (e2 > fpi->emax + 1) + goto huge; + rve1 = rve + rvbits - nbits; + if (e2 < (emin = fpi->emin)) { + denorm = 1; + j = rve - emin; + if (j > 0) { + rvb = lshift(rvb, j); + rvbits += j; + } + else if (j < 0) { + rvbits += j; + if (rvbits <= 0) { + if (rvbits < -1) { + ufl: + rvb->wds = 0; + rvb->x[0] = 0; + *exp = emin; + irv = STRTOG_Underflow | STRTOG_Inexlo; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + goto ret; + } + rvb->x[0] = rvb->wds = rvbits = 1; + } + else + rshift(rvb, -j); + } + rve = rve1 = emin; + if (sudden_underflow && e2 + 1 < emin) + goto ufl; + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + +#ifdef USE_LOCALE + bd0 = s2b(s0, nd0, nd, y, decimal_point_len); +#else + bd0 = s2b(s0, nd0, nd, y, 1); +#endif + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = Balloc(rvb->k); + Bcopy(bb, rvb); + bbbits = rvbits - bb0; + bbe = rve + bb0; + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; + j = nbits + 1 - bbbits; + i = bbe + bbbits - nbits; + if (i < emin) /* denormal */ + j += i - emin; + bb2 += j; + bd2 += j; + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + bb2 -= bb0; + if (bb2 > 0) + bb = lshift(bb, bb2); + else if (bb2 < 0) + rshift(bb, -bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + asub = 1; + inex = STRTOG_Inexhi; + delta = diff(bb, bd); + if (delta->wds <= 1 && !delta->x[0]) + break; + dsign = delta->sign; + delta->sign = finished = 0; + L = 0; + i = cmp(delta, bs); + if (rd && i <= 0) { + irv = STRTOG_Normal; + if ( (finished = dsign ^ (rd&1)) !=0) { + if (dsign != 0) { + irv |= STRTOG_Inexhi; + goto adj1; + } + irv |= STRTOG_Inexlo; + if (rve1 == emin) + goto adj1; + for(i = 0, j = nbits; j >= ULbits; + i++, j -= ULbits) { + if (rvb->x[i] & ALL_ON) + goto adj1; + } + if (j > 1 && lo0bits(rvb->x + i) < j - 1) + goto adj1; + rve = rve1 - 1; + rvb = set_ones(rvb, rvbits = nbits); + break; + } + irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi; + break; + } + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + irv = dsign + ? STRTOG_Normal | STRTOG_Inexlo + : STRTOG_Normal | STRTOG_Inexhi; + if (dsign || bbbits > 1 || denorm || rve1 == emin) + break; + delta = lshift(delta,1); + if (cmp(delta, bs) > 0) { + irv = STRTOG_Normal | STRTOG_Inexlo; + goto drop_down; + } + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if (denorm && all_on(rvb, rvbits)) { + /*boundary case -- increment exponent*/ + rvb->wds = 1; + rvb->x[0] = 1; + rve = emin + nbits - (rvbits = 1); + irv = STRTOG_Normal | STRTOG_Inexhi; + denorm = 0; + break; + } + irv = STRTOG_Normal | STRTOG_Inexlo; + } + else if (bbbits == 1) { + irv = STRTOG_Normal; + drop_down: + /* boundary case -- decrement exponent */ + if (rve1 == emin) { + irv = STRTOG_Normal | STRTOG_Inexhi; + if (rvb->wds == 1 && rvb->x[0] == 1) + sudden_underflow = 1; + break; + } + rve -= nbits; + rvb = set_ones(rvb, rvbits = nbits); + break; + } + else + irv = STRTOG_Normal | STRTOG_Inexhi; + if (bbbits < nbits && !denorm || !(rvb->x[0] & 1)) + break; + if (dsign) { + rvb = increment(rvb); + if ( (j = rvbits & kmask) !=0) + j = ULbits - j; + if (hi0bits(rvb->x[rvb->wds - 1]) + != j) + rvbits++; + irv = STRTOG_Normal | STRTOG_Inexhi; + } + else { + if (bbbits == 1) + goto undfl; + decrement(rvb); + irv = STRTOG_Normal | STRTOG_Inexlo; + } + break; + } + if ((dval(adj) = ratio(delta, bs)) <= 2.) { + adj1: + inex = STRTOG_Inexlo; + if (dsign) { + asub = 0; + inex = STRTOG_Inexhi; + } + else if (denorm && bbbits <= 1) { + undfl: + rvb->wds = 0; + rve = emin; + irv = STRTOG_Underflow | STRTOG_Inexlo; + break; + } + adj0 = dval(adj) = 1.; + } + else { + adj0 = dval(adj) *= 0.5; + if (dsign) { + asub = 0; + inex = STRTOG_Inexlo; + } + if (dval(adj) < 2147483647.) { + L = adj0; + adj0 -= L; + switch(rd) { + case 0: + if (adj0 >= .5) + goto inc_L; + break; + case 1: + if (asub && adj0 > 0.) + goto inc_L; + break; + case 2: + if (!asub && adj0 > 0.) { + inc_L: + L++; + inex = STRTOG_Inexact - inex; + } + } + dval(adj) = L; + } + } + y = rve + rvbits; + + /* adj *= ulp(dval(rv)); */ + /* if (asub) rv -= adj; else rv += adj; */ + + if (!denorm && rvbits < nbits) { + rvb = lshift(rvb, j = nbits - rvbits); + rve -= j; + rvbits = nbits; + } + ab = d2b(dval(adj), &abe, &abits); + if (abe < 0) + rshift(ab, -abe); + else if (abe > 0) + ab = lshift(ab, abe); + rvb0 = rvb; + if (asub) { + /* rv -= adj; */ + j = hi0bits(rvb->x[rvb->wds-1]); + rvb = diff(rvb, ab); + k = rvb0->wds - 1; + if (denorm) + /* do nothing */; + else if (rvb->wds <= k + || hi0bits( rvb->x[k]) > + hi0bits(rvb0->x[k])) { + /* unlikely; can only have lost 1 high bit */ + if (rve1 == emin) { + --rvbits; + denorm = 1; + } + else { + rvb = lshift(rvb, 1); + --rve; + --rve1; + L = finished = 0; + } + } + } + else { + rvb = sum(rvb, ab); + k = rvb->wds - 1; + if (k >= rvb0->wds + || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) { + if (denorm) { + if (++rvbits == nbits) + denorm = 0; + } + else { + rshift(rvb, 1); + rve++; + rve1++; + L = 0; + } + } + } + Bfree(ab); + Bfree(rvb0); + if (finished) + break; + + 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) { + if (adj0 > tol) { + irv |= inex; + break; + } + } + else if (dval(adj) > tol && adj0 < 1. - tol) { + irv |= inex; + break; + } + } + bb0 = denorm ? 0 : trailz(rvb); + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } + if (!denorm && (j = nbits - rvbits)) { + if (j > 0) + rvb = lshift(rvb, j); + else + rshift(rvb, -j); + rve -= j; + } + *exp = rve; + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + if (rve > fpi->emax) { + huge: + rvb->wds = 0; + irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + infnanexp: + *exp = fpi->emax + 1; + } + ret: + if (denorm) { + if (sudden_underflow) { + rvb->wds = 0; + irv = STRTOG_Underflow | STRTOG_Inexlo; + } + else { + irv = (irv & ~STRTOG_Retmask) | + (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero); + if (irv & STRTOG_Inexact) + irv |= STRTOG_Underflow; + } + } + if (se) + *se = (char *)s; + if (sign) + irv |= STRTOG_Neg; + if (rvb) { + copybits(bits, nbits, rvb); + Bfree(rvb); + } +#if !defined(NO_ERRNO) && __DARWIN_UNIX03 + if (irv & STRTOG_Underflow) + errno = ERANGE; +#endif + return irv; + } diff --git a/gdtoa/gdtoa-strtof-fbsd.c b/gdtoa/gdtoa-strtof-fbsd.c new file mode 100644 index 0000000..b618031 --- /dev/null +++ b/gdtoa/gdtoa-strtof-fbsd.c @@ -0,0 +1,100 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 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 "xlocale_private.h" + +#include "gdtoaimp.h" + + float +#ifdef KR_headers +strtof_l(s, sp, loc) CONST char *s; char **sp; locale_t loc; +#else +strtof_l(CONST char *s, char **sp, locale_t loc) +#endif +{ + static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + ULong bits[1]; + Long exp; + int k; + union { ULong L[1]; float f; } u; + FPI *fpi = &fpi0, fpi1; +#ifdef Honor_FLT_ROUNDS + int rounding = Flt_Rounds; +#endif + + NORMALIZE_LOCALE(loc); +#ifdef Honor_FLT_ROUNDS + if (rounding != fpi0.rounding) { + fpi1 = fpi0; /* for thread safety */ + fpi1.rounding = rounding; + fpi = &fpi1; + } +#endif /* Honor_FLT_ROUNDS */ + k = strtodg(s, sp, fpi, &exp, bits, loc); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + u.L[0] = 0; + return u.f; // avoid setting sign + + case STRTOG_Zero: + u.L[0] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + break; + + case STRTOG_Denormal: + u.L[0] = bits[0]; + break; + + case STRTOG_Infinite: + u.L[0] = 0x7f800000; + break; + + case STRTOG_NaN: + u.L[0] = f_QNAN; + } + if (k & STRTOG_Neg) + u.L[0] |= 0x80000000L; + return u.f; + } + + float +#ifdef KR_headers +strtof(s, sp) CONST char *s; char **sp; +#else +strtof(CONST char *s, char **sp) +#endif +{ + return strtof_l(s, sp, __current_locale()); +} diff --git a/gdtoa/gdtoa-strtopdd-fbsd.c b/gdtoa/gdtoa-strtopdd-fbsd.c new file mode 100644 index 0000000..a1f2ad0 --- /dev/null +++ b/gdtoa/gdtoa-strtopdd-fbsd.c @@ -0,0 +1,246 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 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 "xlocale_private.h" + +#include "gdtoaimp.h" + +#ifdef __APPLE__ +/* + * IEEE specifies that the most significant (head) double is required to + * be equal to the long double rounded to the nearest double, so that means + * the tail double might be the opposite sign as the head. We can do this + * adding (long double)0 to the number, which will fix it up. + */ +#define fixLDBL(x) ((x) += 0.L) +#endif /* __APPLE__ */ + + int +#ifdef KR_headers +strtopdd(s, sp, dd) CONST char *s; char **sp; double *dd; locale_t loc; +#else +strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; +#else + static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; +#endif + ULong bits[4]; + Long exp; + int i, j, rv; + typedef union { + double d[2]; + ULong L[4]; +#ifdef __APPLE__ + long double ld; +#endif /* __APPLE__ */ + } U; + U *u; + FPI *fpi = &fpi0, fpi1; +#ifdef Honor_FLT_ROUNDS + int rounding = Flt_Rounds; +#endif + +#ifdef Honor_FLT_ROUNDS + if (rounding != fpi0.rounding) { + fpi1 = fpi0; /* for thread safety */ + fpi1.rounding = rounding; + fpi = &fpi1; + } +#endif /* Honor_FLT_ROUNDS */ + rv = strtodg(s, sp, fpi, &exp, bits, loc); + u = (U*)dd; + switch(rv & STRTOG_Retmask) { + case STRTOG_NoNumber: + u->d[0] = u->d[1] = 0.; + return rv; // avoid setting sign + + case STRTOG_Zero: + u->d[0] = u->d[1] = 0.; + break; + + 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; + exp += 0x3ff + 52; + if (bits[1] &= 0x1fffff) { + i = hi0bits(bits[1]) - 11; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i > 0) { + bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[0] = bits[0] << i & 0xffffffffL; + } + } + else if (bits[0]) { + i = hi0bits(bits[0]) + 21; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i < 32) { + bits[1] = bits[0] >> 32 - i; + bits[0] = bits[0] << i & 0xffffffffL; + } + else { + bits[1] = bits[0] << i - 32; + bits[0] = 0; + } + } + else { + u->L[2] = u->L[3] = 0; + break; + } + u->L[2+_1] = bits[0]; + u->L[2+_0] = bits[1] & 0xfffff | exp << 20; +#ifdef __APPLE__ + fixLDBL(u->ld); +#endif /* __APPLE__ */ + break; + + case STRTOG_Denormal: + if (bits[3]) + goto nearly_normal; + if (bits[2]) + goto partly_normal; + if (bits[1] & 0xffe00000) + goto hardly_normal; + /* completely denormal */ + u->L[2] = u->L[3] = 0; + u->L[_1] = bits[0]; + u->L[_0] = bits[1]; + break; + + 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[_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); +#endif /* __APPLE__ */ + break; + + partly_normal: + i = hi0bits(bits[2]) - 11; + 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[2+_1] = bits[0]; +#ifdef __APPLE__ + fixLDBL(u->ld); +#endif /* __APPLE__ */ + break; + } + if (i == 0) { + u->L[_0] = bits[2] & 0xfffff | 33 << 20; + u->L[_1] = bits[1]; + u->L[2+_0] = 0; + u->L[2+_1] = bits[0]; +#ifdef __APPLE__ + fixLDBL(u->ld); +#endif /* __APPLE__ */ + break; + } + j = 32 - i; + 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; +#ifdef __APPLE__ + fixLDBL(u->ld); +#endif /* __APPLE__ */ + break; + + hardly_normal: + j = 11 - hi0bits(bits[1]); + i = 32 - j; + 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; +#ifdef __APPLE__ + fixLDBL(u->ld); +#endif /* __APPLE__ */ + break; + + case STRTOG_Infinite: +#ifdef __APPLE__ + u->L[_0] = 0x7ff00000; + u->L[_1] = u->L[2+_0] = u->L[2+_1] = 0; +#else /* __APPLE__ */ + u->L[_0] = u->L[2+_0] = 0x7ff00000; + u->L[_1] = u->L[2+_1] = 0; +#endif /* __APPLE__ */ + break; + + case STRTOG_NaN: +#ifdef __APPLE__ + u->L[0] = d_QNAN0; + u->L[1] = d_QNAN1; + u->L[2] = u->L[3] = 0; +#else /* __APPLE__ */ + u->L[0] = u->L[2] = d_QNAN0; + u->L[1] = u->L[3] = d_QNAN1; +#endif /* __APPLE__ */ +#ifdef __APPLE__ + case STRTOG_NaNbits: + u->L[0] = d_QNAN0 | ((bits[2] >> 20 | bits[3] << 12) & 0xfffff); + u->L[1] = d_QNAN1 | bits[1] >> 20 | bits[2] << 12; + u->L[2] = u->L[3] = 0; +#endif /* __APPLE__ */ + } + if (rv & STRTOG_Neg) { + u->L[ _0] |= 0x80000000L; +#ifdef __APPLE__ + u->L[2+_0] ^= 0x80000000L; +#else /* __APPLE__ */ + u->L[2+_0] |= 0x80000000L; +#endif /* __APPLE__ */ + } + return rv; + } diff --git a/gdtoa/gdtoa-strtord-fbsd.c b/gdtoa/gdtoa-strtord-fbsd.c new file mode 100644 index 0000000..2500488 --- /dev/null +++ b/gdtoa/gdtoa-strtord-fbsd.c @@ -0,0 +1,69 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 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" + + void +#ifdef KR_headers +ULtod(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtod(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = 0; + break; + + case STRTOG_Denormal: + L[_1] = bits[0]; + L[_0] = bits[1]; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_1] = bits[0]; + L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); + break; + + case STRTOG_Infinite: + L[_0] = 0x7ff00000; + L[_1] = 0; + break; + + case STRTOG_NaN: + L[0] = d_QNAN0; + L[1] = d_QNAN1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } diff --git a/gdtoa/gdtoa-sum-fbsd.c b/gdtoa/gdtoa-sum-fbsd.c new file mode 100644 index 0000000..dc0c88b --- /dev/null +++ b/gdtoa/gdtoa-sum-fbsd.c @@ -0,0 +1,98 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 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 * +#ifdef KR_headers +sum(a, b) Bigint *a; Bigint *b; +#else +sum(Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + ULong carry, *xc, *xa, *xb, *xe, y; +#ifdef Pack_32 + ULong z; +#endif + + if (a->wds < b->wds) { + c = b; b = a; a = c; + } + c = Balloc(a->k); + c->wds = a->wds; + carry = 0; + xa = a->x; + xb = b->x; + xc = c->x; + xe = xc + b->wds; +#ifdef Pack_32 + do { + y = (*xa & 0xffff) + (*xb & 0xffff) + carry; + carry = (y & 0x10000) >> 16; + z = (*xa++ >> 16) + (*xb++ >> 16) + carry; + carry = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xc < xe); + xe += a->wds - b->wds; + while(xc < xe) { + y = (*xa & 0xffff) + carry; + carry = (y & 0x10000) >> 16; + z = (*xa++ >> 16) + carry; + carry = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ + *xb++ + carry; + carry = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xc < xe); + xe += a->wds - b->wds; + while(xc < xe) { + y = *xa++ + carry; + carry = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif + if (carry) { + if (c->wds == c->maxwds) { + b = Balloc(c->k + 1); + Bcopy(b, c); + Bfree(c); + c = b; + } + c->x[c->wds++] = 1; + } + return c; + } diff --git a/gdtoa/gdtoa-ulp-fbsd.c b/gdtoa/gdtoa-ulp-fbsd.c new file mode 100644 index 0000000..7810a5c --- /dev/null +++ b/gdtoa/gdtoa-ulp-fbsd.c @@ -0,0 +1,70 @@ +/**************************************************************** + +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" + + double +ulp +#ifdef KR_headers + (x) double x; +#else + (double x) +#endif +{ + Long L; + double a; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + 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; + } + else { + word0(a) = 0; + L -= Exp_shift; + word1(a) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif + return a; + } diff --git a/gdtoa/gdtoa.h b/gdtoa/gdtoa.h new file mode 100644 index 0000000..ee6a9e5 --- /dev/null +++ b/gdtoa/gdtoa.h @@ -0,0 +1,153 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 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 "."). */ + +#ifndef GDTOA_H_INCLUDED +#define GDTOA_H_INCLUDED + +#include "arith.h" + +#ifndef Long +#define Long long +#endif +#ifndef ULong +typedef unsigned Long ULong; +#endif +#ifndef UShort +typedef unsigned short UShort; +#endif + +#ifndef ANSI +#ifdef KR_headers +#define ANSI(x) () +#define Void /*nothing*/ +#else +#define ANSI(x) x +#define Void void +#endif +#endif /* ANSI */ + +#ifndef CONST +#ifdef KR_headers +#define CONST /* blank */ +#else +#define CONST const +#endif +#endif /* CONST */ + + enum { /* return values from strtodg */ + STRTOG_Zero = 0, + STRTOG_Normal = 1, + STRTOG_Denormal = 2, + STRTOG_Infinite = 3, + STRTOG_NaN = 4, + STRTOG_NaNbits = 5, + STRTOG_NoNumber = 6, + STRTOG_Retmask = 7, + + /* The following may be or-ed into one of the above values. */ + + STRTOG_Neg = 0x08, + STRTOG_Inexlo = 0x10, + STRTOG_Inexhi = 0x20, + STRTOG_Inexact = 0x30, + STRTOG_Underflow= 0x40, + STRTOG_Overflow = 0x80 + }; + + typedef struct +FPI { + int nbits; + int emin; + int emax; + int rounding; + int sudden_underflow; + } FPI; + +enum { /* FPI.rounding values: same as FLT_ROUNDS */ + FPI_Round_zero = 0, + FPI_Round_near = 1, + FPI_Round_up = 2, + FPI_Round_down = 3 + }; + +#ifdef __cplusplus +extern "C" { +#endif + +extern char* dtoa ANSI((double d, int mode, int ndigits, int *decpt, + int *sign, char **rve)); +extern char* gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, + int mode, int ndigits, int *decpt, char **rve)); +extern void freedtoa ANSI((char*)); +extern float strtof ANSI((CONST char *, char **)); +extern double strtod ANSI((CONST char *, char **)); +extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*)); + +extern char* g_ddfmt ANSI((char*, double*, int, unsigned)); +extern char* g_dfmt ANSI((char*, double*, int, unsigned)); +extern char* g_ffmt ANSI((char*, float*, int, unsigned)); +extern char* g_Qfmt ANSI((char*, void*, int, unsigned)); +extern char* g_xfmt ANSI((char*, void*, int, unsigned)); +extern char* g_xLfmt ANSI((char*, void*, int, unsigned)); + +extern int strtoId ANSI((CONST char*, char**, double*, double*)); +extern int strtoIdd ANSI((CONST char*, char**, double*, double*)); +extern int strtoIf ANSI((CONST char*, char**, float*, float*)); +extern int strtoIQ ANSI((CONST char*, char**, void*, void*)); +extern int strtoIx ANSI((CONST char*, char**, void*, void*)); +extern int strtoIxL ANSI((CONST char*, char**, void*, void*)); +extern int strtord ANSI((CONST char*, char**, int, double*)); +extern int strtordd ANSI((CONST char*, char**, int, double*)); +extern int strtorf ANSI((CONST char*, char**, int, float*)); +extern int strtorQ ANSI((CONST char*, char**, int, void*)); +extern int strtorx ANSI((CONST char*, char**, int, void*)); +extern int strtorxL ANSI((CONST char*, char**, int, void*)); +#if 1 +extern int strtodI ANSI((CONST char*, char**, double*)); +extern int strtopd ANSI((CONST char*, char**, double*)); +extern int strtopdd ANSI((CONST char*, char**, double*)); +extern int strtopf ANSI((CONST char*, char**, float*)); +extern int strtopQ ANSI((CONST char*, char**, void*)); +extern int strtopx ANSI((CONST char*, char**, void*)); +extern int strtopxL ANSI((CONST char*, char**, void*)); +#else +#define strtopd(s,se,x) strtord(s,se,1,x) +#define strtopdd(s,se,x) strtordd(s,se,1,x) +#define strtopf(s,se,x) strtorf(s,se,1,x) +#define strtopQ(s,se,x) strtorQ(s,se,1,x) +#define strtopx(s,se,x) strtorx(s,se,1,x) +#define strtopxL(s,se,x) strtorxL(s,se,1,x) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* GDTOA_H_INCLUDED */ diff --git a/gdtoa/gdtoa_strtopx-fbsd.c b/gdtoa/gdtoa_strtopx-fbsd.c new file mode 100644 index 0000000..5ef49b2 --- /dev/null +++ b/gdtoa/gdtoa_strtopx-fbsd.c @@ -0,0 +1,120 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 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 "xlocale_private.h" + +#include "gdtoaimp.h" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + int +#ifdef KR_headers +strtopx(s, sp, V, loc) CONST char *s; char **sp; void *V; locale_t loc; +#else +strtopx(CONST char *s, char **sp, void *V, locale_t loc) +#endif +{ + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + ULong bits[2]; + Long exp; + int k; + UShort *L = (UShort*)V; + FPI *fpi = &fpi0, fpi1; +#ifdef Honor_FLT_ROUNDS + int rounding = Flt_Rounds; +#endif + +#ifdef Honor_FLT_ROUNDS + if (rounding != fpi0.rounding) { + fpi1 = fpi0; /* for thread safety */ + fpi1.rounding = rounding; + fpi = &fpi1; + } +#endif /* Honor_FLT_ROUNDS */ + k = strtodg(s, sp, fpi, &exp, bits, loc); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + L[0] = L[1] = L[2] = L[3] = L[4] = 0; + return k; // avoid setting sign + + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = L[4] = 0; + break; + + case STRTOG_Denormal: + L[_0] = 0; + goto normal_bits; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_0] = exp + 0x3fff + 63; + normal_bits: + L[_4] = (UShort)bits[0]; + L[_3] = (UShort)(bits[0] >> 16); + L[_2] = (UShort)bits[1]; + L[_1] = (UShort)(bits[1] >> 16); + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff; + L[_1] = 0x8000; /* 4306392: to match gcc */ + L[_2] = L[_3] = L[_4] = 0; + break; + + case STRTOG_NaN: + L[0] = ldus_QNAN0; + L[1] = ldus_QNAN1; + L[2] = ldus_QNAN2; + L[3] = ldus_QNAN3; + L[4] = ldus_QNAN4; + } + if (k & STRTOG_Neg) + L[_0] |= 0x8000; + return k; + } diff --git a/gdtoa/gdtoaimp.h b/gdtoa/gdtoaimp.h new file mode 100644 index 0000000..c98a956 --- /dev/null +++ b/gdtoa/gdtoaimp.h @@ -0,0 +1,694 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2000 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. + +****************************************************************/ + +/* This is a variation on dtoa.c that converts arbitary binary + floating-point formats to and from decimal notation. It uses + double-precision arithmetic internally, so there are still + various #ifdefs that adapt the calculations to the native + double-precision arithmetic (any of IEEE, VAX D_floating, + or IBM mainframe arithmetic). + + Please send bug reports to David M. Gay (dmg at acm dot org, + with " at " changed at "@" and " dot " changed to "."). + */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_8087 for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_MC68k for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define Sudden_Underflow for IEEE-format machines without gradual + * underflow (i.e., that flush to zero on underflow). + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #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. + * #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, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. When converting IEEE double precision values, the + * longest string gdtoa can return is about 751 bytes long. For + * conversions by strtod of strings of 800 digits and all gdtoa + * 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). + * 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 and spaces; + * if there is only one string of hexadecimal digits, it is taken + * for the fraction bits of the resulting NaN; if there are two or + * more strings of hexadecimal digits, each string is assigned + * to the next available sequence of 32-bit words of fractions + * bits (starting with the most significant), right-aligned in + * each sequence. + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define IMPRECISE_INEXACT if you do not care about the setting of + * the STRTOG_Inexact bits in the special case of doing IEEE double + * precision conversions (which could also be done by the strtog in + * dtoa.c). + * #define NO_HEX_FP to disable recognition of C9x's hexadecimal + * floating-point constants. + * #define -DNO_ERRNO to suppress setting errno (in strtod.c and + * strtodg.c). + * #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. + */ + +#ifndef GDTOAIMP_H_INCLUDED +#define GDTOAIMP_H_INCLUDED +#include +#include "gdtoa.h" +#include "gd_qnan.h" + +#ifdef DEBUG +#include "stdio.h" +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#include "limits.h" +#include "stdlib.h" +#include "string.h" +#include "libc_private.h" +#include "spinlock.h" + +#ifdef KR_headers +#define Char char +#else +#define Char void +#endif + +#ifdef MALLOC +extern Char *MALLOC ANSI((size_t)); +#else +#define MALLOC malloc +#endif + +#define INFNAN_CHECK +#define USE_LOCALE + +#undef IEEE_Arith +#undef Avoid_Underflow +#ifdef IEEE_MC68k +#define IEEE_Arith +#endif +#ifdef IEEE_8087 +#define IEEE_Arith +#endif + +#include "errno.h" +#ifdef Bad_float_h + +#ifdef IEEE_Arith +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#define DBL_MAX 1.7976931348623157e+308 +#endif + +#ifdef IBM +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 75 +#define DBL_MAX_EXP 63 +#define FLT_RADIX 16 +#define DBL_MAX 7.2370055773322621e+75 +#endif + +#ifdef VAX +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define FLT_RADIX 2 +#define DBL_MAX 1.7014118346046923e+38 +#define n_bigtens 2 +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include "float.h" +/* force the correct definition of FLT_ROUNDS */ +extern int __fegetfltrounds( void ); +#undef FLT_ROUNDS +#define FLT_ROUNDS (__fegetfltrounds ()) +#endif /* Bad_float_h */ + +#ifdef IEEE_Arith +#define Scale_Bit 0x10 +#define n_bigtens 5 +#endif + +#ifdef IBM +#define n_bigtens 3 +#endif + +#ifdef VAX +#define n_bigtens 2 +#endif + +#ifndef __MATH_H__ +#include "math.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 +Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. +#endif + +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] +#else +#define word0(x) ((ULong *)&x)[0] +#define word1(x) ((ULong *)&x)[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 */ + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_8087) + defined(VAX) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ +((unsigned short *)a)[0] = (unsigned short)c, a++) +#else +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ +((unsigned short *)a)[1] = (unsigned short)c, a++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#ifdef IEEE_Arith +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#else /* ifndef IEEE_Arith */ +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#undef Flt_Rounds +#define Flt_Rounds 0 +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#undef Flt_Rounds +#define Flt_Rounds 1 +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif /* IBM, VAX */ +#endif /* IEEE_Arith */ + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +#ifdef KR_headers +extern double rnd_prod(), rnd_quot(); +#else +extern double rnd_prod(double, double), rnd_quot(double, double); +#endif +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#undef Pack_16 +#ifndef Pack_32 +#define Pack_32 +#endif + +#ifdef NO_LONG_LONG +#undef ULLong +#ifdef Just_16 +#undef Pack_32 +#define Pack_16 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#endif +#else /* long long available */ +#ifndef Llong +#define Llong long long +#endif +#ifndef ULLong +#define ULLong unsigned Llong +#endif +#endif /* NO_LONG_LONG */ + +#ifdef Pack_32 +#define ULbits 32 +#define kshift 5 +#define kmask 31 +#define ALL_ON 0xffffffff +#else +#define ULbits 16 +#define kshift 4 +#define kmask 15 +#define ALL_ON 0xffff +#endif + +#define MULTIPLE_THREADS +extern spinlock_t __gdtoa_locks[2]; +#define ACQUIRE_DTOA_LOCK(n) do { \ + if (__isthreaded) \ + _SPINLOCK(&__gdtoa_locks[n]); \ +} while(0) +#define FREE_DTOA_LOCK(n) do { \ + if (__isthreaded) \ + _SPINUNLOCK(&__gdtoa_locks[n]); \ +} while(0) + +#define Kmax 15 + + struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; + }; + + typedef struct Bigint Bigint; + +#ifdef NO_STRING_H +#ifdef DECLARE_SIZE_T +typedef unsigned int size_t; +#endif +extern void memcpy_D2A ANSI((void*, const void*, size_t)); +#define Bcopy(x,y) memcpy_D2A(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int)) +#else /* !NO_STRING_H */ +#define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int)) +#endif /* NO_STRING_H */ + +/* + * Paranoia: Protect exported symbols, including ones in files we don't + * compile right now. The standard strtof and strtod survive. + */ +#define dtoa __dtoa +#define gdtoa __gdtoa +#define freedtoa __freedtoa +#define strtodg __strtodg +#define g_ddfmt __g_ddfmt +#define g_dfmt __g_dfmt +#define g_ffmt __g_ffmt +#define g_Qfmt __g_Qfmt +#define g_xfmt __g_xfmt +#define g_xLfmt __g_xLfmt +#define strtoId __strtoId +#define strtoIdd __strtoIdd +#define strtoIf __strtoIf +#define strtoIQ __strtoIQ +#define strtoIx __strtoIx +#define strtoIxL __strtoIxL +#define strtord __strtord +#define strtordd __strtordd +#define strtorf __strtorf +#define strtorQ __strtorQ +#define strtorx __strtorx +#define strtorxL __strtorxL +#define strtodI __strtodI +#define strtopd __strtopd +#define strtopdd __strtopdd +#define strtopf __strtopf +#define strtopQ __strtopQ +#define strtopx __strtopx +#define strtopxL __strtopxL + +/* Protect gdtoa-internal symbols */ +#define Balloc __Balloc_D2A +#define Bfree __Bfree_D2A +#define ULtoQ __ULtoQ_D2A +#define ULtof __ULtof_D2A +#define ULtod __ULtod_D2A +#define ULtodd __ULtodd_D2A +#define ULtox __ULtox_D2A +#define ULtoxL __ULtoxL_D2A +#define any_on __any_on_D2A +#define b2d __b2d_D2A +#define bigtens __bigtens_D2A +#define cmp __cmp_D2A +#define copybits __copybits_D2A +#define d2b __d2b_D2A +#define decrement __decrement_D2A +#define diff __diff_D2A +#define dtoa_result __dtoa_result_D2A +#define g__fmt __g__fmt_D2A +#define gethex __gethex_D2A +#define hexdig __hexdig_D2A +#define hexdig_init_D2A __hexdig_init_D2A +#define hexnan __hexnan_D2A +#define hi0bits __hi0bits_D2A +#define hi0bits_D2A __hi0bits_D2A +#define i2b __i2b_D2A +#define increment __increment_D2A +#define lo0bits __lo0bits_D2A +#define lshift __lshift_D2A +#define match __match_D2A +#define mult __mult_D2A +#define multadd __multadd_D2A +#define nrv_alloc __nrv_alloc_D2A +#define pow5mult __pow5mult_D2A +#define quorem __quorem_D2A +#define ratio __ratio_D2A +#define rshift __rshift_D2A +#define rv_alloc __rv_alloc_D2A +#define s2b __s2b_D2A +#define set_ones __set_ones_D2A +#define strcp __strcp_D2A +#define strcp_D2A __strcp_D2A +#define strtoIg __strtoIg_D2A +#define sum __sum_D2A +#define tens __tens_D2A +#define tinytens __tinytens_D2A +#define tinytens __tinytens_D2A +#define trailz __trailz_D2A +#define ulp __ulp_D2A + + extern char *dtoa_result; + extern CONST double bigtens[], tens[], tinytens[]; + extern unsigned char hexdig[]; + + extern Bigint *Balloc ANSI((int)); + extern void Bfree ANSI((Bigint*)); + extern void ULtof ANSI((ULong*, ULong*, Long, int)); + extern void ULtod ANSI((ULong*, ULong*, Long, int)); + extern void ULtodd ANSI((ULong*, ULong*, Long, int)); + extern void ULtoQ ANSI((ULong*, ULong*, Long, int)); + extern void ULtox ANSI((UShort*, ULong*, Long, int)); + extern void ULtoxL ANSI((ULong*, ULong*, Long, int)); + extern ULong any_on ANSI((Bigint*, int)); + extern double b2d ANSI((Bigint*, int*)); + extern int cmp ANSI((Bigint*, Bigint*)); + extern void copybits ANSI((ULong*, int, Bigint*)); + extern Bigint *d2b ANSI((double, int*, int*)); + extern int decrement ANSI((Bigint*)); + extern Bigint *diff ANSI((Bigint*, Bigint*)); + extern char *dtoa ANSI((double d, int mode, int ndigits, + int *decpt, int *sign, char **rve)); + extern void freedtoa ANSI((char*)); + extern char *gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, + int mode, int ndigits, int *decpt, char **rve)); + extern char *g__fmt ANSI((char*, char*, char*, int, ULong)); + extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int, locale_t)); + extern void hexdig_init_D2A(Void); + extern int hexnan ANSI((CONST char**, FPI*, ULong*)); + extern int hi0bits_D2A ANSI((ULong)); + extern Bigint *i2b ANSI((int)); + extern Bigint *increment ANSI((Bigint*)); + extern int lo0bits ANSI((ULong*)); + extern Bigint *lshift ANSI((Bigint*, int)); + extern int match ANSI((CONST char**, char*)); + extern Bigint *mult ANSI((Bigint*, Bigint*)); + extern Bigint *multadd ANSI((Bigint*, int, int)); + extern char *nrv_alloc ANSI((char*, char **, int)); + extern Bigint *pow5mult ANSI((Bigint*, int)); + extern int quorem ANSI((Bigint*, Bigint*)); + 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, int)); + extern Bigint *set_ones ANSI((Bigint*, int)); + extern char *strcp ANSI((char*, const char*)); + extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*, locale_t)) __DARWIN_ALIAS(strtodg); + + extern int strtoId ANSI((CONST char *, char **, double *, double *)); + extern int strtoIdd ANSI((CONST char *, char **, double *, double *)); + extern int strtoIf ANSI((CONST char *, char **, float *, float *)); + extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*)); + extern int strtoIQ ANSI((CONST char *, char **, void *, void *)); + extern int strtoIx ANSI((CONST char *, char **, void *, void *)); + extern int strtoIxL ANSI((CONST char *, char **, void *, void *)); + extern double strtod ANSI((const char *s00, char **se)); + extern double strtod_l ANSI((const char *s00, char **se, locale_t)); + extern int strtopQ ANSI((CONST char *, char **, Void *)); + extern int strtopf ANSI((CONST char *, char **, float *)); + extern int strtopd ANSI((CONST char *, char **, double *)); + extern int strtopdd ANSI((CONST char *, char **, double *, locale_t)); + extern int strtopx ANSI((CONST char *, char **, Void *, locale_t)); + extern int strtopxL ANSI((CONST char *, char **, Void *)); + extern int strtord ANSI((CONST char *, char **, int, double *)); + extern int strtordd ANSI((CONST char *, char **, int, double *)); + extern int strtorf ANSI((CONST char *, char **, int, float *)); + extern int strtorQ ANSI((CONST char *, char **, int, void *)); + extern int strtorx ANSI((CONST char *, char **, int, void *)); + extern int strtorxL ANSI((CONST char *, char **, int, void *)); + extern Bigint *sum ANSI((Bigint*, Bigint*)); + extern int trailz ANSI((Bigint*)); + extern double ulp ANSI((double)); + +#ifdef __cplusplus +} +#endif +/* + * NAN_WORD0 and NAN_WORD1 are only referenced in strtod.c. Prior to + * 20050115, they used to be hard-wired here (to 0x7ff80000 and 0, + * respectively), but now are determined by compiling and running + * qnan.c to generate gd_qnan.h, which specifies d_QNAN0 and d_QNAN1. + * Formerly gdtoaimp.h recommended supplying suitable -DNAN_WORD0=... + * and -DNAN_WORD1=... values if necessary. This should still work. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + */ +#ifdef IEEE_Arith +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#ifndef NAN_WORD0 +#define NAN_WORD0 d_QNAN0 +#endif +#ifndef NAN_WORD1 +#define NAN_WORD1 d_QNAN1 +#endif +#else +#define _0 1 +#define _1 0 +#ifndef NAN_WORD0 +#define NAN_WORD0 d_QNAN1 +#endif +#ifndef NAN_WORD1 +#define NAN_WORD1 d_QNAN0 +#endif +#endif +#else +#undef INFNAN_CHECK +#endif + +#undef SI +#ifdef Sudden_Underflow +#define SI 1 +#else +#define SI 0 +#endif + +#endif /* GDTOAIMP_H_INCLUDED */ diff --git a/gdtoa/glue-fbsd.c b/gdtoa/glue-fbsd.c new file mode 100644 index 0000000..0db1914 --- /dev/null +++ b/gdtoa/glue-fbsd.c @@ -0,0 +1,10 @@ +/* + * Machine-independent glue to integrate David Gay's gdtoa + * package into libc. + * + * $FreeBSD: src/lib/libc/gdtoa/glue.c,v 1.1 2003/03/12 20:29:58 das Exp $ + */ + +#include "spinlock.h" + +spinlock_t __gdtoa_locks[2]; diff --git a/gdtoa/machdep_ldisdd-fbsd.c b/gdtoa/machdep_ldisdd-fbsd.c new file mode 100644 index 0000000..130559a --- /dev/null +++ b/gdtoa/machdep_ldisdd-fbsd.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2003 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. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * is a head/tail pair of doubles + */ + +#include + +#include "xlocale_private.h" + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ +#ifdef LDBL_COMPAT + return (long double)strtod_l(s, sp, __current_locale()); +#else /* LDBL_COMPAT */ + long double result; + + strtopdd(s, sp, (double *)&result, __current_locale()); + return result; +#endif /* LDBL_COMPAT */ +} + +long double +strtold_l(const char * __restrict s, char ** __restrict sp, locale_t loc) +{ +#ifdef LDBL_COMPAT + NORMALIZE_LOCALE(loc); + return (long double)strtod_l(s, sp, loc); +#else /* LDBL_COMPAT */ + long double result; + + NORMALIZE_LOCALE(loc); + strtopdd(s, sp, (double *)&result, loc); + return result; +#endif /* LDBL_COMPAT */ +} diff --git a/gdtoa/machdep_ldisx-fbsd.c b/gdtoa/machdep_ldisx-fbsd.c new file mode 100644 index 0000000..64b14d4 --- /dev/null +++ b/gdtoa/machdep_ldisx-fbsd.c @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2003 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. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * is an IEEE extended precision number. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gdtoa/machdep_ldisx.c,v 1.2 2003/04/09 05:58:43 das Exp $"); + +#include "xlocale_private.h" + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtopx(s, sp, &result, __current_locale()); + return result; +} + +long double +strtold_l(const char * __restrict s, char ** __restrict sp, locale_t loc) +{ + long double result; + + NORMALIZE_LOCALE(loc); + strtopx(s, sp, &result, loc); + return result; +} diff --git a/gen/FreeBSD/_rand48.c.patch b/gen/FreeBSD/_rand48.c.patch new file mode 100644 index 0000000..6e4caca --- /dev/null +++ b/gen/FreeBSD/_rand48.c.patch @@ -0,0 +1,40 @@ +--- _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 @@ + + #include "rand48.h" + +-unsigned short _rand48_seed[3] = { +- RAND48_SEED_0, +- RAND48_SEED_1, +- RAND48_SEED_2 +-}; +-unsigned short _rand48_mult[3] = { +- RAND48_MULT_0, +- RAND48_MULT_1, +- RAND48_MULT_2 +-}; +-unsigned short _rand48_add = RAND48_ADD; +- +-void +-_dorand48(unsigned short xseed[3]) +-{ +- unsigned long accu; +- unsigned short temp[2]; +- +- accu = (unsigned long) _rand48_mult[0] * (unsigned long) xseed[0] + +- (unsigned long) _rand48_add; +- temp[0] = (unsigned short) accu; /* lower 16 bits */ +- accu >>= sizeof(unsigned short) * 8; +- accu += (unsigned long) _rand48_mult[0] * (unsigned long) xseed[1] + +- (unsigned long) _rand48_mult[1] * (unsigned long) xseed[0]; +- temp[1] = (unsigned short) accu; /* middle 16 bits */ +- accu >>= sizeof(unsigned short) * 8; +- accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0]; +- xseed[0] = temp[0]; +- xseed[1] = temp[1]; +- xseed[2] = (unsigned short) accu; +-} ++uint48 _rand48_seed = RAND48_SEED; ++uint48 _rand48_mult = RAND48_MULT; ++uint48 _rand48_add = RAND48_ADD; diff --git a/gen/FreeBSD/alarm.3.patch b/gen/FreeBSD/alarm.3.patch new file mode 100644 index 0000000..fa80522 --- /dev/null +++ b/gen/FreeBSD/alarm.3.patch @@ -0,0 +1,13 @@ +--- _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 @@ + .Lb libc + .Sh SYNOPSIS + .In unistd.h +-.Ft unsigned int +-.Fn alarm "unsigned int seconds" ++.Ft unsigned ++.Fn alarm "unsigned seconds" + .Sh DESCRIPTION + .Bf -symbolic + This interface is made obsolete by diff --git a/gen/FreeBSD/arc4random.3 b/gen/FreeBSD/arc4random.3 new file mode 100644 index 0000000..3e2aaa3 --- /dev/null +++ b/gen/FreeBSD/arc4random.3 @@ -0,0 +1,107 @@ +.\" $OpenBSD: arc4random.3,v 1.2 1997/04/27 22:40:25 angelos Exp $ +.\" Copyright 1997 Niels Provos +.\" 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 Niels Provos. +.\" 4. 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 ``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. +.\" +.\" Manual page, using -mandoc macros +.\" $FreeBSD: src/lib/libc/gen/arc4random.3,v 1.16 2003/07/31 06:18:24 das Exp $ +.\" +.Dd April 15, 1997 +.Dt ARC4RANDOM 3 +.Os +.Sh NAME +.Nm arc4random , +.Nm arc4random_stir , +.Nm arc4random_addrandom +.Nd arc4 random number generator +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft u_int32_t +.Fn arc4random "void" +.Ft void +.Fn arc4random_stir "void" +.Ft void +.Fn arc4random_addrandom "unsigned char *dat" "int datlen" +.Sh DESCRIPTION +The +.Fn arc4random +function uses the key stream generator employed by the +arc4 cipher, which uses 8*8 8 bit S-Boxes. +The S-Boxes +can be in about +.if t 2\u\s71700\s10\d +.if n (2**1700) +states. +The +.Fn arc4random +function returns pseudo-random numbers in the range of 0 to +.if t 2\u\s731\s10\d\(mi1, +.if n (2**32)\(mi1, +and therefore has twice the range of +.Xr rand 3 +and +.Xr random 3 . +.Pp +The +.Fn arc4random_stir +function reads data from +.Pa /dev/urandom +and uses it to permute the S-Boxes via +.Fn arc4random_addrandom . +.Pp +There is no need to call +.Fn arc4random_stir +before using +.Fn arc4random , +since +.Fn arc4random +automatically initializes itself. +.Sh EXAMPLES +The following produces a drop-in replacement for the traditional +.Fn rand +and +.Fn random +functions using +.Fn arc4random : +.Pp +.Dl "#define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))" +.Sh SEE ALSO +.Xr rand 3 , +.Xr random 3 , +.Xr srandomdev 3 +.Sh HISTORY +.Pa RC4 +has been designed by RSA Data Security, Inc. +It was posted anonymously +to the USENET and was confirmed to be equivalent by several sources who +had access to the original cipher. +Since +.Pa RC4 +used to be a trade secret, the cipher is now referred to as +.Pa ARC4 . diff --git a/gen/arc4random.c b/gen/FreeBSD/arc4random.c similarity index 61% rename from gen/arc4random.c rename to gen/FreeBSD/arc4random.c index 55b496f..7d882b8 100644 --- a/gen/arc4random.c +++ b/gen/FreeBSD/arc4random.c @@ -1,27 +1,3 @@ -/* - * 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@ - */ -/* $FreeBSD: src/lib/libc/gen/arc4random.c,v 1.4 2000/01/27 23:06:13 jasone Exp $ */ - /* * Arc4 random number generator for OpenBSD. * Copyright 1996 David Mazieres . @@ -47,11 +23,19 @@ * RC4 is a registered trademark of RSA Laboratories. */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.10 2004/03/24 14:44:57 green Exp $"); + +#include "namespace.h" +#include +#include #include #include #include -#include -#include +#include + +#include "libc_private.h" +#include "un-namespace.h" struct arc4_stream { u_int8_t i; @@ -59,10 +43,28 @@ struct arc4_stream { u_int8_t s[256]; }; +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; + +#define RANDOMDEV "/dev/urandom" +#define THREAD_LOCK() \ + do { \ + if (__isthreaded) \ + _pthread_mutex_lock(&arc4random_mtx); \ + } while (0) + +#define THREAD_UNLOCK() \ + do { \ + if (__isthreaded) \ + _pthread_mutex_unlock(&arc4random_mtx); \ + } while (0) + +static struct arc4_stream rs; static int rs_initialized; -static struct arc4_stream *rs = NULL; +static int rs_stired; + +static inline u_int8_t arc4_getbyte(struct arc4_stream *); +static void arc4_stir(struct arc4_stream *); -static inline void arc4_init(struct arc4_stream *) __attribute__((always_inline)); static inline void arc4_init(as) struct arc4_stream *as; @@ -75,7 +77,6 @@ arc4_init(as) as->j = 0; } -static inline void arc4_addrandom(struct arc4_stream *, u_char *, int) __attribute__((always_inline)); static inline void arc4_addrandom(as, dat, datlen) struct arc4_stream *as; @@ -99,7 +100,7 @@ static void arc4_stir(as) struct arc4_stream *as; { - int fd; + int fd, n; struct { struct timeval tv; pid_t pid; @@ -108,18 +109,27 @@ arc4_stir(as) gettimeofday(&rdat.tv, NULL); rdat.pid = getpid(); - fd = open("/dev/urandom", O_RDONLY, 0); + fd = _open(RANDOMDEV, O_RDONLY, 0); if (fd >= 0) { - (void) read(fd, rdat.rnd, sizeof(rdat.rnd)); - close(fd); - } + (void) _read(fd, rdat.rnd, sizeof(rdat.rnd)); + _close(fd); + } /* fd < 0? Ah, what the heck. We'll just take whatever was on the * stack... */ arc4_addrandom(as, (void *) &rdat, sizeof(rdat)); + + /* + * Throw away the first N bytes of output, as suggested in the + * paper "Weaknesses in the Key Scheduling Algorithm of RC4" + * by Fluher, Mantin, and Shamir. N=1024 is based on + * suggestions in the paper "(Not So) Random Shuffles of RC4" + * by Ilya Mironov. + */ + for (n = 0; n < 1024; n++) + arc4_getbyte(as); } -static inline u_int8_t arc4_getbyte(struct arc4_stream *) __attribute__((always_inline)); static inline u_int8_t arc4_getbyte(as) struct arc4_stream *as; @@ -132,35 +142,49 @@ arc4_getbyte(as) sj = as->s[as->j]; as->s[as->i] = sj; as->s[as->j] = si; + return (as->s[(si + sj) & 0xff]); } -static inline u_int32_t arc4_getword(struct arc4_stream *) __attribute__((always_inline)); static inline u_int32_t arc4_getword(as) struct arc4_stream *as; { u_int32_t val; + val = arc4_getbyte(as) << 24; val |= arc4_getbyte(as) << 16; val |= arc4_getbyte(as) << 8; val |= arc4_getbyte(as); - return val; + + return (val); } -void -arc4random_stir() +static void +arc4_check_init(void) { - if ( rs == NULL ) { - rs = malloc( sizeof(struct arc4_stream) ); - if( rs == NULL ) - return ; /* Hmmm. */ - } if (!rs_initialized) { - arc4_init(rs); + arc4_init(&rs); rs_initialized = 1; } - arc4_stir(rs); +} + +static void +arc4_check_stir(void) +{ + if (!rs_stired) { + arc4_stir(&rs); + rs_stired = 1; + } +} + +void +arc4random_stir() +{ + THREAD_LOCK(); + arc4_check_init(); + arc4_stir(&rs); + THREAD_UNLOCK(); } void @@ -168,17 +192,25 @@ arc4random_addrandom(dat, datlen) u_char *dat; int datlen; { - if (!rs_initialized) - arc4random_stir(); - arc4_addrandom(rs, dat, datlen); + THREAD_LOCK(); + arc4_check_init(); + arc4_check_stir(); + arc4_addrandom(&rs, dat, datlen); + THREAD_UNLOCK(); } u_int32_t arc4random() { - if (!rs_initialized) - arc4random_stir(); - return arc4_getword(rs); + u_int32_t rnd; + + THREAD_LOCK(); + arc4_check_init(); + arc4_check_stir(); + rnd = arc4_getword(&rs); + THREAD_UNLOCK(); + + return (rnd); } #if 0 diff --git a/gen/FreeBSD/arc4random.c.patch b/gen/FreeBSD/arc4random.c.patch new file mode 100644 index 0000000..8931f1b --- /dev/null +++ b/gen/FreeBSD/arc4random.c.patch @@ -0,0 +1,11 @@ +--- 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/basename.3.patch b/gen/FreeBSD/basename.3.patch new file mode 100644 index 0000000..e365028 --- /dev/null +++ b/gen/FreeBSD/basename.3.patch @@ -0,0 +1,44 @@ +--- basename.3 2004-11-25 11:38:00.000000000 -0800 ++++ basename.3.edit 2006-07-12 10:54:25.000000000 -0700 +@@ -36,7 +36,9 @@ + .Sh SYNOPSIS + .In libgen.h + .Ft char * +-.Fn basename "const char *path" ++.Fo basename ++.Fa "char *path" ++.Fc + .Sh DESCRIPTION + The + .Fn basename +@@ -81,12 +83,27 @@ + The + .Fn basename + function +-returns a pointer to internal static storage space that will be overwritten +-by subsequent calls. ++returns a pointer to internal static storage space ++that will be overwritten by subsequent calls. ++The function may modify the string pointed to by ++.Fa path . ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Pp ++.Ft char * ++.br ++.Fo basename ++.Fa "const char *path" ++.Fc ; ++.Pp ++In legacy mode, ++.Fa path ++will not be changed. + .Sh SEE ALSO + .Xr basename 1 , + .Xr dirname 1 , +-.Xr dirname 3 ++.Xr dirname 3 , ++.Xr compat 5 + .Sh STANDARDS + The + .Fn basename diff --git a/gen/FreeBSD/basename.c.patch b/gen/FreeBSD/basename.c.patch new file mode 100644 index 0000000..6b39a01 --- /dev/null +++ b/gen/FreeBSD/basename.c.patch @@ -0,0 +1,18 @@ +Index: basename.c +=================================================================== +RCS file: /cvs/root/Libc/gen/FreeBSD/basename.c,v +retrieving revision 1.2 +diff -u -d -b -w -p -u -r1.2 basename.c +--- basename.c 2003/05/20 22:21:01 1.2 ++++ basename.c 2004/12/10 18:48:36 +@@ -39,6 +39,10 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/bas + #include + #include + ++#if __DARWIN_UNIX03 ++#define const /**/ ++#endif ++ + char * + basename(path) + const char *path; diff --git a/gen/FreeBSD/closedir.c.patch b/gen/FreeBSD/closedir.c.patch new file mode 100644 index 0000000..2f4be68 --- /dev/null +++ b/gen/FreeBSD/closedir.c.patch @@ -0,0 +1,12 @@ +--- 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 @@ + + if (__isthreaded) + _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); ++#if !__DARWIN_UNIX03 + _seekdir(dirp, dirp->dd_rewind); /* free seekdir storage */ ++#endif /* __DARWIN_UNIX03 */ + fd = dirp->dd_fd; + dirp->dd_fd = -1; + dirp->dd_loc = 0; diff --git a/gen/FreeBSD/ctermid.3.patch b/gen/FreeBSD/ctermid.3.patch new file mode 100644 index 0000000..1c392db --- /dev/null +++ b/gen/FreeBSD/ctermid.3.patch @@ -0,0 +1,54 @@ +--- _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 @@ + .Dt CTERMID 3 + .Os + .Sh NAME +-.Nm ctermid ++.Nm ctermid , ++.Nm ctermid_r + .Nd generate terminal pathname + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In stdio.h + .Ft char * +-.Fn ctermid "char *buf" ++.Fn ctermid "char *s" + .Ft char * +-.Fn ctermid_r "char *buf" ++.Fn ctermid_r "char *s" + .Sh DESCRIPTION + The + .Fn ctermid +-function generates a string, that, when used as a pathname, refers to ++function generates a string that, when used as a pathname, refers to + the current controlling terminal of the calling process. + .Pp + If +-.Fa buf ++.Fa s + is the + .Dv NULL + pointer, a pointer to a static area is returned. + Otherwise, the pathname is copied into the memory referenced by +-.Fa buf . ++.Fa s . + The argument +-.Fa buf ++.Fa s + is assumed to be at least + .Dv L_ctermid + (as defined in the include +@@ -72,9 +73,9 @@ + .Fn ctermid_r + function + provides the same functionality as +-.Fn ctermid ++.Fn ctermid , + except that if +-.Fa buf ++.Fa s + is a + .Dv NULL + pointer, diff --git a/gen/FreeBSD/daemon.3.patch b/gen/FreeBSD/daemon.3.patch new file mode 100644 index 0000000..3a7d273 --- /dev/null +++ b/gen/FreeBSD/daemon.3.patch @@ -0,0 +1,11 @@ +--- 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 @@ + .Fn daemon + function is for programs wishing to detach themselves from the + controlling terminal and run in the background as system daemons. ++On Mac OS X, the use of this API is discouraged in favor of using ++.Xr launchd 8 . + .Pp + Unless the argument + .Fa nochdir diff --git a/gen/FreeBSD/daemon.c.patch b/gen/FreeBSD/daemon.c.patch new file mode 100644 index 0000000..095cf26 --- /dev/null +++ b/gen/FreeBSD/daemon.c.patch @@ -0,0 +1,58 @@ +--- 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 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/gen/daemon.c,v 1.6 2003/11/10 22:01:42 ghelmer Exp $"); + ++#ifndef VARIANT_PRE1050 ++#include ++#include ++#endif /* !VARIANT_PRE1050 */ + #include "namespace.h" + #include + #include +@@ -45,6 +49,33 @@ + #include + #include "un-namespace.h" + ++#ifndef VARIANT_PRE1050 ++static void ++move_to_root_bootstrap(void) ++{ ++ mach_port_t parent_port = 0; ++ mach_port_t previous_port = 0; ++ ++ do { ++ if (previous_port) { ++ mach_port_deallocate(mach_task_self(), previous_port); ++ previous_port = parent_port; ++ } else { ++ previous_port = bootstrap_port; ++ } ++ ++ if (bootstrap_parent(previous_port, &parent_port) != 0) { ++ return; ++ } ++ } while (parent_port != previous_port); ++ ++ task_set_bootstrap_port(mach_task_self(), parent_port); ++ bootstrap_port = parent_port; ++} ++#endif /* !VARIANT_PRE1050 */ ++ ++int daemon(int, int) __DARWIN_1050(daemon); ++ + int + daemon(nochdir, noclose) + int nochdir, noclose; +@@ -60,7 +91,9 @@ + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + osa_ok = _sigaction(SIGHUP, &sa, &osa); +- ++#ifndef VARIANT_PRE1050 ++ move_to_root_bootstrap(); ++#endif /* !VARIANT_PRE1050 */ + switch (fork()) { + case -1: + return (-1); diff --git a/gen/FreeBSD/dirname.3.patch b/gen/FreeBSD/dirname.3.patch new file mode 100644 index 0000000..ee49f42 --- /dev/null +++ b/gen/FreeBSD/dirname.3.patch @@ -0,0 +1,42 @@ +--- 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 @@ + .Sh SYNOPSIS + .In libgen.h + .Ft char * +-.Fn dirname "const char *path" ++.Fo dirname ++.Fa "char *path" ++.Fc + .Sh DESCRIPTION + The + .Fn dirname +@@ -88,12 +90,25 @@ + .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. ++if portability is desired, ++this should be taken into account when writing code which calls this function. ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Pp ++.Ft char * ++.br ++.Fo dirname ++.Fa "const char *path" ++.Fc ; ++.Pp ++In legacy mode, ++.Fa path ++will not be changed. + .Sh SEE ALSO + .Xr basename 1 , + .Xr dirname 1 , +-.Xr basename 3 ++.Xr basename 3 , ++.Xr compat 5 + .Sh STANDARDS + The + .Fn dirname diff --git a/gen/FreeBSD/dirname.c.patch b/gen/FreeBSD/dirname.c.patch new file mode 100644 index 0000000..213726d --- /dev/null +++ b/gen/FreeBSD/dirname.c.patch @@ -0,0 +1,18 @@ +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 + #include + #include + ++#if __DARWIN_UNIX03 ++#define const /**/ ++#endif ++ + char * + dirname(path) + const char *path; diff --git a/gen/FreeBSD/drand48.c.patch b/gen/FreeBSD/drand48.c.patch new file mode 100644 index 0000000..31e01bb --- /dev/null +++ b/gen/FreeBSD/drand48.c.patch @@ -0,0 +1,16 @@ +--- 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 @@ + + #include "rand48.h" + +-extern unsigned short _rand48_seed[3]; +- + double + drand48(void) + { +- return erand48(_rand48_seed); ++ ERAND48_BEGIN; ++ _DORAND48(_rand48_seed); ++ ERAND48_END(_rand48_seed); + } diff --git a/gen/FreeBSD/erand48.c.patch b/gen/FreeBSD/erand48.c.patch new file mode 100644 index 0000000..d18f27c --- /dev/null +++ b/gen/FreeBSD/erand48.c.patch @@ -0,0 +1,15 @@ +--- 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 @@ + double + erand48(unsigned short xseed[3]) + { +- _dorand48(xseed); +- return ldexp((double) xseed[0], -48) + +- ldexp((double) xseed[1], -32) + +- ldexp((double) xseed[2], -16); ++ uint48 tmp; ++ ERAND48_BEGIN; ++ DORAND48(tmp, xseed); ++ ERAND48_END(tmp); + } diff --git a/gen/FreeBSD/err.c.patch b/gen/FreeBSD/err.c.patch index 849edd2..95cee40 100644 --- a/gen/FreeBSD/err.c.patch +++ b/gen/FreeBSD/err.c.patch @@ -1,6 +1,11 @@ ---- err.c.orig 2004-08-30 09:45:37.000000000 -0700 -+++ err.c 2004-08-30 09:58:06.000000000 -0700 -@@ -48,8 +48,15 @@ +--- err.c.orig 2006-12-15 11:18:17.000000000 -0800 ++++ err.c 2006-12-15 11:46:52.000000000 -0800 +@@ -44,12 +44,85 @@ + #include + #include + #include ++#include + #include "un-namespace.h" #include "libc_private.h" @@ -10,15 +15,80 @@ + +__private_extern__ FILE *_e_err_file; /* file to use for error output */ +__private_extern__ void (*_e_err_exit)(int); ++__private_extern__ void _e_visprintf(FILE * __restrict, const char * __restrict, va_list); + +#else /* !BUILDING_VARIANT */ + +__private_extern__ FILE *_e_err_file = NULL; /* file to use for error output */ +__private_extern__ void (*_e_err_exit)(int) = NULL; ++ ++/* ++ * zero means pass as is ++ * 255 means use \nnn (octal) ++ * otherwise use \x (x is value) ++ * (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', ++ /* BS HT NL VT NP CR SO SI */ ++ 'b', 't', 'n', '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 */ ++ 255, 255, 255, 255, 255, 255, 255, 255, ++ /* the rest are zero */ ++}; ++ ++/* ++ * Make characters visible. If we can't allocate enough ++ * memory, we fall back on vfprintf(). ++ */ ++__private_extern__ void ++_e_visprintf(FILE * __restrict stream, const char * __restrict format, va_list ap) ++{ ++ int failed = 0; ++ char *str, *visstr; ++ va_list backup; ++ ++ va_copy(backup, ap); ++ vasprintf(&str, format, ap); ++ if (str != NULL) { ++ if ((visstr = malloc(4 * strlen(str) + 1)) != NULL) { ++ unsigned char *fp = (unsigned char *)str; ++ unsigned char *tp = (unsigned char *)visstr; ++ while(*fp) { ++ switch(escape[*fp]) { ++ case 0: ++ *tp++ = *fp; ++ break; ++ case 255: ++ sprintf(tp, "\\%03o", *fp); ++ tp += 4; ++ break; ++ default: ++ *tp++ = '\\'; ++ *tp++ = escape[*fp]; ++ break; ++ } ++ fp++; ++ } ++ *tp = 0; ++ fputs(visstr, stream); ++ free(visstr); ++ } else ++ failed = 1; ++ free(str); ++ } else ++ failed = 1; ++ if (failed) ++ vfprintf(stream, format, backup); ++ va_end(backup); ++} /* * This is declared to take a `void *' so that the caller is not required -@@ -60,16 +67,17 @@ +@@ -60,16 +133,17 @@ err_set_file(void *fp) { if (fp) @@ -39,7 +109,7 @@ __weak_reference(_err, err); -@@ -107,16 +115,16 @@ +@@ -107,16 +181,16 @@ const char *fmt; va_list ap; { @@ -51,7 +121,7 @@ if (fmt != NULL) { - vfprintf(err_file, fmt, ap); - fprintf(err_file, ": "); -+ vfprintf(_e_err_file, fmt, ap); ++ _e_visprintf(_e_err_file, fmt, ap); + fprintf(_e_err_file, ": "); } - fprintf(err_file, "%s\n", strerror(code)); @@ -63,7 +133,7 @@ exit(eval); } -@@ -135,14 +143,14 @@ +@@ -135,14 +209,14 @@ const char *fmt; va_list ap; { @@ -77,14 +147,14 @@ - fprintf(err_file, "\n"); - if (err_exit) - err_exit(eval); -+ vfprintf(_e_err_file, fmt, ap); ++ _e_visprintf(_e_err_file, fmt, ap); + fprintf(_e_err_file, "\n"); + if (_e_err_exit) + _e_err_exit(eval); exit(eval); } -@@ -180,14 +188,14 @@ +@@ -180,14 +254,14 @@ const char *fmt; va_list ap; { @@ -96,7 +166,7 @@ if (fmt != NULL) { - vfprintf(err_file, fmt, ap); - fprintf(err_file, ": "); -+ vfprintf(_e_err_file, fmt, ap); ++ _e_visprintf(_e_err_file, fmt, ap); + fprintf(_e_err_file, ": "); } - fprintf(err_file, "%s\n", strerror(code)); @@ -104,7 +174,7 @@ } void -@@ -204,10 +212,10 @@ +@@ -204,10 +278,10 @@ const char *fmt; va_list ap; { @@ -116,6 +186,6 @@ if (fmt != NULL) - vfprintf(err_file, fmt, ap); - fprintf(err_file, "\n"); -+ vfprintf(_e_err_file, fmt, ap); ++ _e_visprintf(_e_err_file, fmt, ap); + fprintf(_e_err_file, "\n"); } diff --git a/gen/FreeBSD/exec.3.patch b/gen/FreeBSD/exec.3.patch index 3cdc895..96cdf19 100644 --- a/gen/FreeBSD/exec.3.patch +++ b/gen/FreeBSD/exec.3.patch @@ -1,23 +1,78 @@ ---- exec.3.orig 2003-09-10 12:24:32.000000000 -0700 -+++ exec.3 2004-10-24 17:12:17.000000000 -0700 -@@ -39,7 +39,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 @@ + .Os + .Sh NAME .Nm execl , - .Nm execlp , +-.Nm execlp , .Nm execle , -.Nm exect , ++.Nm execlp , .Nm execv , .Nm execvp , .Nm execvP -@@ -62,8 +61,6 @@ +@@ -50,25 +49,43 @@ + .In unistd.h + .Vt extern char **environ ; + .Ft int +-.Fn execl "const char *path" "const char *arg" ... /* "(char *)0" */ +-.Ft int +-.Fn execlp "const char *file" "const char *arg" ... /* "(char *)0" */ ++.Fo execl ++.Fa "const char *path" ++.Fa "const char *arg0" ++.Fa ... /* "(char *)0" */ ++.Fc + .Ft int + .Fo execle +-.Fa "const char *path" "const char *arg" ... ++.Fa "const char *path" ++.Fa "const char *arg0" ++.Fa ... + .Fa /* + .Bk -words + .Fa "(char *)0" "char *const envp[]" */ .Ek .Fc .Ft int -.Fn exect "const char *path" "char *const argv[]" "char *const envp[]" --.Ft int - .Fn execv "const char *path" "char *const argv[]" ++.Fo execlp ++.Fa "const char *file" ++.Fa "const char *arg0" ++.Fa ... /* "(char *)0" */ ++.Fc .Ft int - .Fn execvp "const char *file" "char *const argv[]" -@@ -106,7 +103,6 @@ +-.Fn execv "const char *path" "char *const argv[]" ++.Fo execv ++.Fa "const char *path" ++.Fa "char *const argv[]" ++.Fc + .Ft int +-.Fn execvp "const char *file" "char *const argv[]" ++.Fo execvp ++.Fa "const char *file" ++.Fa "char *const argv[]" ++.Fc + .Ft int +-.Fn execvP "const char *file" "const char *search_path" "char *const argv[]" ++.Fo execvP ++.Fa "const char *file" ++.Fa "const char *search_path" ++.Fa "char *const argv[]" ++.Fc + .Sh DESCRIPTION + The + .Nm exec +@@ -84,7 +101,7 @@ + is to be executed. + .Pp + The +-.Fa "const char *arg" ++.Fa "const char *arg0" + and subsequent ellipses in the + .Fn execl , + .Fn execlp , +@@ -106,7 +123,6 @@ pointer. .Pp The @@ -25,18 +80,20 @@ .Fn execv , .Fn execvp , and -@@ -123,9 +119,7 @@ +@@ -123,10 +139,8 @@ .Pp The .Fn execle -and -.Fn exect -functions also specify the environment of the executed process by following -+function also specify the environment of the executed process by following - the +-the ++function also specifies the environment of the executed process ++by following the .Dv NULL pointer that terminates the list of arguments in the argument list -@@ -203,11 +197,6 @@ + or the pointer to the argv array with an additional argument. +@@ -203,11 +217,6 @@ 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.) @@ -48,7 +105,16 @@ .Sh RETURN VALUES If any of the .Fn exec -@@ -237,10 +226,8 @@ +@@ -225,7 +234,7 @@ + .Fn execl , + .Fn execle , + .Fn execlp , +-.Fn execvp ++.Fn execvp , + and + .Fn execvP + functions +@@ -237,11 +246,8 @@ .Xr malloc 3 . .Pp The @@ -56,7 +122,39 @@ -and .Fn execv -functions -+function - may fail and set +-may fail and set ++function may fail and set .Va errno for any of the errors specified for the library function + .Xr execve 2 . +@@ -249,7 +255,6 @@ + .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 @@ + .Fn execl , + .Fn execv , + .Fn execle , +-.Fn execlp ++.Fn execlp , + and + .Fn execvp + functions diff --git a/gen/FreeBSD/fmtmsg.c.patch b/gen/FreeBSD/fmtmsg.c.patch new file mode 100644 index 0000000..2e2f322 --- /dev/null +++ b/gen/FreeBSD/fmtmsg.c.patch @@ -0,0 +1,101 @@ +--- 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 @@ + #include + #include + #include ++#include ++#include + + /* Default value for MSGVERB. */ + #define DFLT_MSGVERB "label:severity:text:action:tag" +@@ -55,6 +57,9 @@ + { + FILE *fp; + char *env, *msgverb, *output; ++ int ret = MM_OK; ++ ++ if (action == NULL) action = ""; + + if (class & MM_PRINT) { + if ((env = getenv("MSGVERB")) != NULL && *env != '\0' && +@@ -76,8 +81,12 @@ + free(msgverb); + return (MM_NOTOK); + } +- if (*output != '\0') +- fprintf(stderr, "%s", output); ++ if (*output != '\0') { ++ int out_len = fprintf(stderr, "%s", output); ++ if (out_len < 0) { ++ ret = MM_NOMSG; ++ } ++ } + free(msgverb); + free(output); + } +@@ -87,16 +96,58 @@ + if (output == NULL) + return (MM_NOCON); + if (*output != '\0') { +- if ((fp = fopen("/dev/console", "a")) == NULL) { +- free(output); +- return (MM_NOCON); ++ ++/* ++// /-------------\ ++// / \ ++// / \ ++// / \ ++// | XXXX XXXX | ++// | XXXX XXXX | ++// | XXX XXX | ++// \ X / ++// --\ XXX /-- ++// | | XXX | | ++// | | | | ++// | I I I I I I I | ++// | I I I I I I | ++// \ / ++// -- -- ++// \-------/ ++// ++// DO NOT INTEGRATE THIS CHANGE ++// ++// Integrating it means DEATH. ++// (see Revelation 6:8 for full details) ++ ++ XXX this is a *huge* kludge to pass the SuSv3 tests, ++ I don't think of it as cheating because they are ++ looking in the wrong place (/realdev/console) to do ++ their testing, but they can't look in the "right" ++ place for various reasons */ ++ char *cpath = "/dev/console"; ++ struct stat sb; ++ int rc = stat("/realdev/console", &sb); ++ if (rc == 0 && (sb.st_mode & S_IFDIR)) { ++ cpath = "/realdev/console"; ++ } ++ /* XXX thus ends the kludge - changes after ++ this point may be safely integrated */ ++ ++ if ((fp = fopen(cpath, "a")) == NULL) { ++ if (ret == MM_OK) { ++ ret = MM_NOCON; ++ } else { ++ ret = MM_NOTOK; ++ } ++ } else { ++ fprintf(fp, "%s", output); ++ fclose(fp); + } +- fprintf(fp, "%s", output); +- fclose(fp); + } + free(output); + } +- return (MM_OK); ++ return (ret); + } + + #define INSERT_COLON \ diff --git a/gen/FreeBSD/fnmatch.3.patch b/gen/FreeBSD/fnmatch.3.patch new file mode 100644 index 0000000..1a4522c --- /dev/null +++ b/gen/FreeBSD/fnmatch.3.patch @@ -0,0 +1,11 @@ +--- _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 @@ + function returns zero if + .Fa string + matches the pattern specified by +-.Fa pattern , ++.Fa pattern ; + otherwise, it returns the value + .Dv FNM_NOMATCH . + .Sh SEE ALSO diff --git a/gen/FreeBSD/fnmatch.c.patch b/gen/FreeBSD/fnmatch.c.patch index b46433b..5145423 100644 --- a/gen/FreeBSD/fnmatch.c.patch +++ b/gen/FreeBSD/fnmatch.c.patch @@ -1,5 +1,5 @@ --- fnmatch.c.orig 2004-11-25 11:38:00.000000000 -0800 -+++ fnmatch.c 2005-02-25 00:23:44.000000000 -0800 ++++ fnmatch.c 2005-03-30 14:33:09.000000000 -0800 @@ -40,6 +40,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.16 2004/07/29 03:13:10 tjr Exp $"); @@ -9,18 +9,25 @@ /* * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. * Compares a filename or pathname to a pattern. -@@ -70,8 +72,8 @@ +@@ -66,12 +68,15 @@ + + #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); -+static int rangematch(const char *, wchar_t, int, char **, mbstate_t *, locale_t); ++__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); int fnmatch(pattern, string, flags) -@@ -80,14 +82,15 @@ +@@ -80,27 +85,32 @@ { static const mbstate_t initial; @@ -37,22 +44,28 @@ + locale_t loc; { const char *stringstart; - char *newp; -@@ -96,11 +99,11 @@ +- char *newp; ++ char *newp, *news; + char c; + wchar_t pc, sc; size_t pclen, sclen; for (stringstart = string;;) { - 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) ++#if __DARWIN_UNIX03 ++ return (RETURN_ERROR); ++#else /* !__DARWIN_UNIX03 */ return (FNM_NOMATCH); ++#endif /* __DARWIN_UNIX03 */ pattern += pclen; - sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs); + sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, &strmbs, loc); if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*string; sclen = 1; -@@ -150,10 +153,10 @@ +@@ -150,10 +160,10 @@ /* General case, use recursion. */ while (sc != EOS) { if (!fnmatch1(pattern, string, @@ -66,16 +79,28 @@ if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*string; -@@ -176,7 +179,7 @@ +@@ -175,35 +185,45 @@ + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) return (FNM_NOMATCH); - switch (rangematch(pattern, sc, flags, &newp, +- switch (rangematch(pattern, sc, flags, &newp, - &patmbs)) { -+ &patmbs, loc)) { ++ switch (rangematch(pattern, sc, string + sclen, flags, ++ &newp, &news, &patmbs, &strmbs, loc)) { case RANGE_ERROR: ++#if __DARWIN_UNIX03 ++ return (RETURN_ERROR); ++#else /* !__DARWIN_UNIX03 */ goto norm; ++#endif /* __DARWIN_UNIX03 */ case RANGE_MATCH: -@@ -189,8 +192,8 @@ + pattern = newp; ++ string = news; + break; + case RANGE_NOMATCH: + return (FNM_NOMATCH); + } +- string += sclen; break; case '\\': if (!(flags & FNM_NOESCAPE)) { @@ -84,9 +109,20 @@ + pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX, + &patmbs, loc); if (pclen == (size_t)-1 || pclen == (size_t)-2) ++#if __DARWIN_UNIX03 ++ return (RETURN_ERROR); ++#else /* !__DARWIN_UNIX03 */ return (FNM_NOMATCH); ++#endif /* __DARWIN_UNIX03 */ if (pclen == 0) -@@ -203,7 +206,7 @@ + pc = '\\'; + pattern += pclen; + } + /* FALLTHROUGH */ + default: ++#if !__DARWIN_UNIX03 + norm: ++#endif /* !__DARWIN_UNIX03 */ if (pc == sc) ; else if ((flags & FNM_CASEFOLD) && @@ -95,22 +131,38 @@ ; else return (FNM_NOMATCH); -@@ -215,12 +218,13 @@ +@@ -214,18 +234,22 @@ + /* NOTREACHED */ } - static int +-static int -rangematch(pattern, test, flags, newp, patmbs) -+rangematch(pattern, test, flags, newp, patmbs, loc) - const char *pattern; +- const char *pattern; ++#ifndef BUILDING_VARIANT ++__private_extern__ int ++rangematch(pattern, test, string, flags, newp, news, patmbs, strmbs, loc) ++ const char *pattern, *string; wchar_t test; int flags; - char **newp; - mbstate_t *patmbs; +- char **newp; +- mbstate_t *patmbs; ++ char **newp, **news; ++ mbstate_t *patmbs, *strmbs; + locale_t loc; { - int negate, ok; +- int negate, ok; ++ int negate, ok, special; wchar_t c, c2; -@@ -238,7 +242,7 @@ +- size_t pclen; +- const char *origpat; ++ wchar_t buf[STR_LEN]; /* STR_LEN defined in collate.h */ ++ size_t pclen, sclen, len; ++ const char *origpat, *cp, *savestring; ++ mbstate_t save; + + /* + * A bracket expression starting with an unquoted circumflex +@@ -238,7 +262,7 @@ ++pattern; if (flags & FNM_CASEFOLD) @@ -119,15 +171,126 @@ /* * A right bracket shall lose its special meaning and represent -@@ -258,20 +262,20 @@ +@@ -248,8 +272,8 @@ + ok = 0; + origpat = pattern; + for (;;) { ++ c = 0; + if (*pattern == ']' && pattern > origpat) { +- pattern++; + break; + } else if (*pattern == '\0') { + return (RANGE_ERROR); +@@ -258,39 +282,188 @@ return (RANGE_NOMATCH); } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) pattern++; - pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs); -+ pclen = mbrtowc_l(&c, pattern, MB_LEN_MAX, patmbs, loc); - if (pclen == (size_t)-1 || pclen == (size_t)-2) - return (RANGE_NOMATCH); - pattern += pclen; +- if (pclen == (size_t)-1 || pclen == (size_t)-2) +- return (RANGE_NOMATCH); +- pattern += pclen; ++ else if (*pattern == '[' && ((special = *(pattern + 1)) == '.' || special == '=' || special == ':')) { ++ cp = (pattern += 2); ++ while(cp = strchr(cp, special)) { ++ if (*(cp + 1) == ']') ++ break; ++ cp++; ++ } ++ if (!cp) ++ return (RANGE_ERROR); ++ if (special == '.') { ++treat_like_collating_symbol: ++ len = __collate_collating_symbol(buf, STR_LEN, pattern, cp - pattern, patmbs, loc); ++ if (len == (size_t)-1 || len == 0) ++ return (RANGE_ERROR); ++ pattern = cp + 2; ++ if (len > 1) { ++ wchar_t *wp, sc; ++ /* no multi-character collation symbols as start of range */ ++ if (*(cp + 2) == '-' && *(cp + 3) != EOS ++ && *(cp + 3) != ']') ++ return (RANGE_ERROR); ++ wp = buf; ++ if (test != *wp++) ++ continue; ++ if (len == 1) { ++ ok = 1; ++ break; ++ } ++ memcpy(&save, strmbs, sizeof(save)); ++ savestring = string; ++ while (--len > 0) { ++ sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, strmbs, loc); ++ if (sclen == (size_t)-1 || sclen == (size_t)-2) { ++ sc = (unsigned char)*string; ++ sclen = 1; ++ memset(&strmbs, 0, sizeof(strmbs)); ++ } ++ if (sc != *wp++) { ++ memcpy(strmbs, &save, sizeof(save)); ++ string = savestring; ++ break; ++ } ++ string += sclen; ++ } ++ if (len == 0) { ++ ok = 1; ++ break; ++ } ++ continue; /* no match */ ++ } ++ c = *buf; ++ } else if (special == '=') { ++ int ec; ++ memcpy(&save, patmbs, sizeof(save)); ++ ec = __collate_equiv_class(pattern, cp - pattern, patmbs, loc); ++ if (ec < 0) ++ return (RANGE_ERROR); ++ if (ec == 0) { ++ memcpy(patmbs, &save, sizeof(save)); ++ goto treat_like_collating_symbol; ++ } ++ pattern = cp + 2; ++ /* no equivalence classes as start of range */ ++ if (*(cp + 2) == '-' && *(cp + 3) != EOS && ++ *(cp + 3) != ']') ++ return (RANGE_ERROR); ++ len = __collate_equiv_match(ec, NULL, 0, test, string, strlen(string), strmbs, &sclen, loc); ++ if (len < 0) ++ return (RANGE_ERROR); ++ if (len > 0) { ++ ok = 1; ++ string += sclen; ++ break; ++ } ++ continue; ++ } else { /* special == ':' */ ++ wctype_t charclass; ++ char name[CHARCLASS_NAME_MAX + 1]; ++ /* no character classes as start of range */ ++ if (*(cp + 2) == '-' && *(cp + 3) != EOS && ++ *(cp + 3) != ']') ++ return (RANGE_ERROR); ++ /* assume character class names are ascii */ ++ if (cp - pattern > CHARCLASS_NAME_MAX) ++ return (RANGE_ERROR); ++ strlcpy(name, pattern, cp - pattern + 1); ++ pattern = cp + 2; ++ if ((charclass = wctype(name)) == 0) ++ return (RANGE_ERROR); ++ if (iswctype_l(test, charclass, loc)) { ++ ok = 1; ++ break; ++ } ++ continue; ++ } ++ } ++ if (!c) { ++ pclen = mbrtowc_l(&c, pattern, MB_LEN_MAX, patmbs, loc); ++ if (pclen == (size_t)-1 || pclen == (size_t)-2) ++ return (RANGE_ERROR); ++ pattern += pclen; ++ } if (flags & FNM_CASEFOLD) - c = towlower(c); @@ -141,11 +304,32 @@ - pclen = mbrtowc(&c2, pattern, MB_LEN_MAX, patmbs); + pclen = mbrtowc_l(&c2, pattern, MB_LEN_MAX, patmbs, loc); if (pclen == (size_t)-1 || pclen == (size_t)-2) - return (RANGE_NOMATCH); +- return (RANGE_NOMATCH); ++ return (RANGE_ERROR); pattern += pclen; -@@ -279,12 +283,12 @@ + if (c2 == EOS) return (RANGE_ERROR); ++ if (c2 == '[' && (special = *pattern) == '.' || special == '=' || special == ':') { ++ /* no equivalence classes or character classes as end of range */ ++ if (special == '=' || special == ':') ++ return (RANGE_ERROR); ++ cp = ++pattern; ++ while(cp = strchr(cp, special)) { ++ if (*(cp + 1) == ']') ++ break; ++ cp++; ++ } ++ if (!cp) ++ return (RANGE_ERROR); ++ len = __collate_collating_symbol(buf, STR_LEN, pattern, cp - pattern, patmbs, loc); ++ /* no multi-character collation symbols as end of range */ ++ if (len != 1) ++ return (RANGE_ERROR); ++ pattern = cp + 2; ++ c2 = *buf; ++ } ++ if (flags & FNM_CASEFOLD) - c2 = towlower(c2); + c2 = towlower_l(c2, loc); @@ -155,8 +339,48 @@ c <= test && test <= c2 : - __collate_range_cmp(c, test) <= 0 - && __collate_range_cmp(test, c2) <= 0 +- ) + __collate_range_cmp(c, test, loc) <= 0 + && __collate_range_cmp(test, c2, loc) <= 0 - ) ++ ) { ok = 1; - } else if (c == test) +- } else if (c == test) ++ break; ++ } ++ } else if (c == test) { + ok = 1; ++ break; ++ } + } ++ /* go to end of bracket expression */ ++ special = 0; ++ while(*pattern != ']') { ++ if (*pattern == 0) ++ return (RANGE_ERROR); ++ if (*pattern == special) { ++ if (*++pattern == ']') { ++ special = 0; ++ pattern++; ++ } ++ continue; ++ } ++ if (!special && *pattern == '[') { ++ special = *++pattern; ++ if (special != '.' && special != '=' && special != ':') ++ special = 0; ++ else ++ pattern++; ++ continue; ++ } ++ pclen = mbrtowc_l(&c, pattern, MB_LEN_MAX, patmbs, loc); ++ if (pclen == (size_t)-1 || pclen == (size_t)-2) ++ return (RANGE_ERROR); ++ pattern += pclen; ++ } + +- *newp = (char *)pattern; ++ *newp = (char *)++pattern; ++ *news = (char *)string; + return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); + } ++#endif /* BUILDING_VARIANT */ diff --git a/gen/FreeBSD/fpclassify.3.patch b/gen/FreeBSD/fpclassify.3.patch deleted file mode 100644 index 14e438c..0000000 --- a/gen/FreeBSD/fpclassify.3.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- /Volumes/XDisk/tmp/Libc/gen/FreeBSD/fpclassify.3.orig 2004-07-08 23:37:44.000000000 -0700 -+++ /Volumes/XDisk/tmp/Libc/gen/FreeBSD/fpclassify.3 2004-10-24 17:08:28.000000000 -0700 -@@ -107,15 +107,6 @@ - macros conform to - .St -isoC-99 . - .Sh HISTORY --The --.Fn fpclassify , --.Fn isfinite , --.Fn isinf , --.Fn isnan , --and --.Fn isnormal --macros were added in --.Fx 5.1 . - .Bx 3 - introduced - .Fn isinf diff --git a/gen/FreeBSD/ftok.3.patch b/gen/FreeBSD/ftok.3.patch new file mode 100644 index 0000000..bf415a8 --- /dev/null +++ b/gen/FreeBSD/ftok.3.patch @@ -0,0 +1,57 @@ +--- ftok.3 2004-11-25 11:38:00.000000000 -0800 ++++ ftok.3.edit 2006-07-12 11:19:51.000000000 -0700 +@@ -33,7 +33,6 @@ + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS +-.In sys/types.h + .In sys/ipc.h + .Ft key_t + .Fn ftok "const char *path" "int id" +@@ -42,10 +41,10 @@ + .Fn ftok + function attempts to create a unique key suitable for use with the + .Xr msgget 3 , +-.Xr semget 2 ++.Xr semget 2 , + and + .Xr shmget 2 +-functions given the ++functions, given the + .Fa path + of an existing file and a user-selectable + .Fa id . +@@ -63,10 +62,18 @@ + function will return -1 if + .Fa path + does not exist or if it cannot be accessed by the calling process. ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Pp ++The include file ++.In sys/types.h ++is necessary. + .Sh SEE ALSO + .Xr semget 2 , + .Xr shmget 2 , +-.Xr msgget 3 ++.Xr msgget 3 , ++.Xr compat 5 + .Sh HISTORY + The + .Fn ftok +@@ -75,9 +82,9 @@ + .Sh AUTHORS + .An Thorsten Lockert Aq tholo@sigmasoft.com + .Sh BUGS +-The returned key is computed based on the device minor number and inode of the +-specified +-.Fa path ++The returned key is computed based on the device minor number and inode ++of the specified ++.Fa path , + in combination with the lower 8 bits of the given + .Fa id . +-Thus it is quite possible for the routine to return duplicate keys. ++Thus, it is quite possible for the routine to return duplicate keys. diff --git a/gen/FreeBSD/getcontext.3 b/gen/FreeBSD/getcontext.3 new file mode 100644 index 0000000..c2963ad --- /dev/null +++ b/gen/FreeBSD/getcontext.3 @@ -0,0 +1,121 @@ +.\" Copyright (c) 2002 Packet Design, LLC. +.\" All rights reserved. +.\" +.\" Subject to the following obligations and disclaimer of warranty, +.\" use and redistribution of this software, in source or object code +.\" forms, with or without modifications are expressly permitted by +.\" Packet Design; provided, however, that: +.\" +.\" (i) Any and all reproductions of the source or object code +.\" must include the copyright notice above and the following +.\" disclaimer of warranties; and +.\" (ii) No rights are granted, in any manner or form, to use +.\" Packet Design trademarks, including the mark "PACKET DESIGN" +.\" on advertising, endorsements, or otherwise except as such +.\" appears in the above copyright notice or in the software. +.\" +.\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND +.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO +.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING +.\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED +.\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, +.\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE, +.\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS +.\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, +.\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE +.\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE +.\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL +.\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF +.\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 PACKET DESIGN IS ADVISED OF +.\" THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD: src/lib/libc/gen/getcontext.3,v 1.3 2004/12/03 14:10:04 rse Exp $ +.\" +.Dd September 10, 2002 +.Dt GETCONTEXT 3 +.Os +.Sh NAME +.Nm getcontext , setcontext +.Nd get and set user thread context +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ucontext.h +.Ft int +.Fn getcontext "ucontext_t *ucp" +.Ft int +.Fn setcontext "const ucontext_t *ucp" +.Sh DESCRIPTION +The +.Fn getcontext +function +saves the current thread's execution context in the structure pointed to by +.Fa ucp . +This saved context may then later be restored by calling +.Fn setcontext . +.Pp +The +.Fn setcontext +function +makes a previously saved thread context the current thread context, i.e., +the current context is lost and +.Fn setcontext +does not return. +Instead, execution continues in the context specified by +.Fa ucp , +which must have been previously initialized by a call to +.Fn getcontext , +.Xr makecontext 3 , +or by being passed as an argument to a signal handler (see +.Xr sigaction 2 ) . +.Pp +If +.Fa ucp +was initialized by +.Fn getcontext , +then execution continues as if the original +.Fn getcontext +call had just returned (again). +.Pp +If +.Fa ucp +was initialized by +.Xr makecontext 3 , +execution continues with the invocation of the function specified to +.Xr makecontext 3 . +When that function returns, +.Fa "ucp->uc_link" +determines what happens next: +if +.Fa "ucp->uc_link" +is +.Dv NULL , +the process exits; +otherwise, +.Fn setcontext "ucp->uc_link" +is implicitly invoked. +.Pp +If +.Fa ucp +was initialized by the invocation of a signal handler, execution continues +at the point the thread was interrupted by the signal. +.Sh RETURN VALUES +If successful, +.Fn getcontext +returns zero and +.Fn setcontext +does not return; otherwise \-1 is returned. +.Sh ERRORS +No errors are defined for +.Fn getcontext +or +.Fn setcontext . +.Sh SEE ALSO +.Xr sigaction 2 , +.Xr sigaltstack 2 , +.Xr makecontext 3 , +.Xr ucontext 3 diff --git a/gen/FreeBSD/getcwd.c.patch b/gen/FreeBSD/getcwd.c.patch index ac2f9cd..ccf6071 100644 --- a/gen/FreeBSD/getcwd.c.patch +++ b/gen/FreeBSD/getcwd.c.patch @@ -1,6 +1,6 @@ ---- getcwd.c.orig 2006-01-19 18:35:45.000000000 -0800 -+++ getcwd.c 2006-02-08 17:53:41.000000000 -0800 -@@ -54,7 +54,81 @@ +--- 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 @@ (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) @@ -43,7 +43,9 @@ + } + } else + b = buf; -+ + +-char * +-getcwd(pt, size) + err = fcntl(fd, F_GETPATH, b); + if (err) { + save = errno; @@ -80,10 +82,16 @@ + } + return 0; +} - - char * - getcwd(pt, size) -@@ -91,31 +165,23 @@ ++ ++__private_extern__ char * ++__private_getcwd(pt, size, usegetpath) + char *pt; + size_t size; ++ int usegetpath; + { + struct dirent *dp; + DIR *dir = NULL; +@@ -91,31 +166,25 @@ } ept = pt + size; } else { @@ -92,7 +100,7 @@ return (NULL); ept = pt + ptsize; } - if (__getcwd(pt, ept - pt) == 0) { +- if (__getcwd(pt, ept - pt) == 0) { - if (*pt != '/') { - bpt = pt; - ept = pt + strlen(pt) - 1; @@ -102,10 +110,13 @@ - *ept-- = c; - } - } - return (pt); -- } -+ } else if (errno == ERANGE) /* failed because buffer too small */ -+ return NULL; +- return (pt); ++ if (usegetpath) { ++ if (__getcwd(pt, ept - pt) == 0) { ++ return (pt); ++ } else if (errno == ERANGE) /* failed because buffer too small */ ++ return NULL; + } bpt = ept - 1; *bpt = '\0'; @@ -120,3 +131,15 @@ goto err; eup = up + MAXPATHLEN; bup = up; +@@ -259,3 +328,11 @@ + errno = save_errno; + return (NULL); + } ++ ++char * ++getcwd(pt, size) ++ char *pt; ++ size_t size; ++{ ++ return __private_getcwd(pt, size, 1); ++} diff --git a/gen/FreeBSD/gethostname.3.patch b/gen/FreeBSD/gethostname.3.patch new file mode 100644 index 0000000..695847a --- /dev/null +++ b/gen/FreeBSD/gethostname.3.patch @@ -0,0 +1,11 @@ +--- _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 @@ + specifies the size of the + .Fa name + array. +-The returned name is null-terminated unless insufficient space is provided. ++The returned name is null-terminated, unless insufficient space is provided. + .Pp + The + .Fn sethostname diff --git a/gen/FreeBSD/gethostname.c.patch b/gen/FreeBSD/gethostname.c.patch new file mode 100644 index 0000000..018f8bb --- /dev/null +++ b/gen/FreeBSD/gethostname.c.patch @@ -0,0 +1,33 @@ +--- gethostname.c.orig 2004-11-25 11:38:01.000000000 -0800 ++++ gethostname.c 2005-09-15 09:46:13.000000000 -0700 +@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/get + + #include + #include ++#include + + #include + +@@ -54,10 +55,22 @@ gethostname(name, namelen) + + mib[0] = CTL_KERN; + mib[1] = KERN_HOSTNAME; ++ if (namelen < MAXHOSTNAMELEN + 1) { ++ char local_buf[MAXHOSTNAMELEN + 1]; ++ size_t local_len = sizeof(local_buf); ++ if (sysctl(mib, 2, local_buf, &local_len, NULL, 0) == -1) { ++ if (errno == ENOMEM) ++ errno = ENAMETOOLONG; ++ return (-1); ++ } ++ strncpy(name, local_buf, namelen); ++ name[namelen - 1] = 0; ++ } else { + if (sysctl(mib, 2, name, &namelen, NULL, 0) == -1) { + if (errno == ENOMEM) + errno = ENAMETOOLONG; + return (-1); ++ } + } + return (0); + } diff --git a/gen/FreeBSD/getlogin.c.patch b/gen/FreeBSD/getlogin.c.patch index 859d595..d3b63f9 100644 --- a/gen/FreeBSD/getlogin.c.patch +++ b/gen/FreeBSD/getlogin.c.patch @@ -1,6 +1,32 @@ ---- /Volumes/XDisk/tmp/Libc/gen/FreeBSD/getlogin.c.orig 2003-10-29 02:45:01.000000000 -0800 -+++ /Volumes/XDisk/tmp/Libc/gen/FreeBSD/getlogin.c 2004-10-24 17:08:28.000000000 -0700 -@@ -87,7 +87,7 @@ +--- 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 @@ + #define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&logname_mutex) + #define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&logname_mutex) + +-extern int _getlogin(char *, int); ++extern int __getlogin(char *, int); + + int _logname_valid; /* known to setlogin() */ + static pthread_mutex_t logname_mutex = PTHREAD_MUTEX_INITIALIZER; +@@ -64,7 +63,7 @@ + static char logname[MAXLOGNAME]; + + if (_logname_valid == 0) { +- if (_getlogin(logname, sizeof(logname)) < 0) { ++ if (__getlogin(logname, sizeof(logname)) < 0) { + *status = errno; + return (NULL); + } +@@ -87,7 +86,7 @@ } int diff --git a/gen/FreeBSD/getmntinfo.3.patch b/gen/FreeBSD/getmntinfo.3.patch new file mode 100644 index 0000000..f0e51e1 --- /dev/null +++ b/gen/FreeBSD/getmntinfo.3.patch @@ -0,0 +1,89 @@ +--- getmntinfo.3.orig 2007-01-21 11:53:36.000000000 -0800 ++++ getmntinfo.3 2007-01-21 17:19:17.000000000 -0800 +@@ -46,14 +46,22 @@ + .In sys/mount.h + .Ft int + .Fn getmntinfo "struct statfs **mntbufp" "int flags" ++.Ft int ++.Fn getmntinfo64 "struct statfs64 **mntbufp" "int flags" + .Sh DESCRIPTION + The + .Fn getmntinfo + function + returns an array of +-.Fn statfs ++.Ft statfs + structures describing each currently mounted file system (see + .Xr statfs 2 ) . ++Likewise, the ++.Fn getmntinfo64 ++function ++returns an array of ++.Ft statfs64 ++structures describing each currently mounted file system. + .Pp + The + .Fn getmntinfo +@@ -61,11 +69,20 @@ + passes its + .Fa flags + argument transparently to +-.Xr getfsstat 2 . ++.Xr getfsstat 2 , ++while the ++.Fn getmntinfo64 ++function ++passes its ++.Fa flags ++argument transparently to ++.Fn getfsstat64 . + .Sh RETURN VALUES + On successful completion, + .Fn getmntinfo +-returns a count of the number of elements in the array. ++and ++.Fn getmntinfo64 ++return a count of the number of elements in the array. + The pointer to the array is stored into + .Fa mntbufp . + .Pp +@@ -76,11 +93,15 @@ + .Fa mntbufp + will be unmodified, any information previously returned by + .Fn getmntinfo ++or ++.Fn getmntinfo64 + will be lost. + .Sh ERRORS + The + .Fn getmntinfo +-function ++and ++.Fn getmntinfo64 ++functions + may fail and set errno for any of the errors specified for the library + routines + .Xr getfsstat 2 +@@ -99,15 +120,21 @@ + .Sh BUGS + The + .Fn getmntinfo +-function writes the array of structures to an internal static object ++and ++.Fn getmntinfo64 ++functions write the array of structures to an internal static object + and returns + a pointer to that object. + Subsequent calls to + .Fn getmntinfo ++and ++.Fn getmntinfo64 + will modify the same object. + .Pp + The memory allocated by + .Fn getmntinfo ++and ++.Fn getmntinfo64 + cannot be + .Xr free 3 Ns 'd + by the application. diff --git a/gen/FreeBSD/getmntinfo64.c.patch b/gen/FreeBSD/getmntinfo64.c.patch new file mode 100644 index 0000000..4663c82 --- /dev/null +++ b/gen/FreeBSD/getmntinfo64.c.patch @@ -0,0 +1,37 @@ +--- getmntinfo.c.orig 2007-01-21 11:53:36.000000000 -0800 ++++ getmntinfo.c 2007-01-21 17:05:23.000000000 -0800 +@@ -46,25 +46,25 @@ + * Return information about mounted filesystems. + */ + int +-getmntinfo(mntbufp, flags) +- struct statfs **mntbufp; ++getmntinfo64(mntbufp, flags) ++ struct statfs64 **mntbufp; + int flags; + { +- static struct statfs *mntbuf; ++ static struct statfs64 *mntbuf; + static int mntsize; + static long bufsize; + +- if (mntsize <= 0 && (mntsize = getfsstat(0, 0, MNT_NOWAIT)) < 0) ++ if (mntsize <= 0 && (mntsize = getfsstat64(0, 0, MNT_NOWAIT)) < 0) + return (0); +- if (bufsize > 0 && (mntsize = getfsstat(mntbuf, bufsize, flags)) < 0) ++ if (bufsize > 0 && (mntsize = getfsstat64(mntbuf, bufsize, flags)) < 0) + return (0); +- while (bufsize <= mntsize * sizeof(struct statfs)) { ++ while (bufsize <= mntsize * sizeof(struct statfs64)) { + if (mntbuf) + free(mntbuf); +- bufsize = (mntsize + 1) * sizeof(struct statfs); +- if ((mntbuf = (struct statfs *)malloc(bufsize)) == 0) ++ bufsize = (mntsize + 1) * sizeof(struct statfs64); ++ if ((mntbuf = (struct statfs64 *)malloc(bufsize)) == 0) + return (0); +- if ((mntsize = getfsstat(mntbuf, bufsize, flags)) < 0) ++ if ((mntsize = getfsstat64(mntbuf, bufsize, flags)) < 0) + return (0); + } + *mntbufp = mntbuf; diff --git a/gen/FreeBSD/glob.3.patch b/gen/FreeBSD/glob.3.patch new file mode 100644 index 0000000..a39326f --- /dev/null +++ b/gen/FreeBSD/glob.3.patch @@ -0,0 +1,42 @@ +--- glob.3 2004-11-25 11:38:01.000000000 -0800 ++++ glob.3.edit 2006-09-05 14:47:53.000000000 -0700 +@@ -46,9 +46,16 @@ + .Sh SYNOPSIS + .In glob.h + .Ft int +-.Fn glob "const char *pattern" "int flags" "int (*errfunc)(const char *, int)" "glob_t *pglob" ++.Fo glob ++.Fa "const char *restrict pattern" ++.Fa "int flags" ++.Fa "int (*errfunc)(const char *epath, int eerno)" ++.Fa "glob_t *restrict pglob" ++.Fc + .Ft void +-.Fn globfree "glob_t *pglob" ++.Fo globfree ++.Fa "glob_t *pglob" ++.Fc + .Sh DESCRIPTION + The + .Fn glob +@@ -337,7 +344,7 @@ + On successful completion, + .Fn glob + returns zero. +-In addition the fields of ++In addition, the fields of + .Fa pglob + contain the values described below: + .Bl -tag -width GLOB_NOCHECK +@@ -418,6 +425,11 @@ + g.gl_pathv[1] = "-l"; + execvp("ls", g.gl_pathv); + .Ed ++.Sh CAVEATS ++The ++.Fn glob ++function will not match filenames that begin with a period ++unless this is specifically requested (e.g., by ".*"). + .Sh SEE ALSO + .Xr sh 1 , + .Xr fnmatch 3 , diff --git a/gen/FreeBSD/glob.c.patch b/gen/FreeBSD/glob.c.patch index cc94b54..904b155 100644 --- a/gen/FreeBSD/glob.c.patch +++ b/gen/FreeBSD/glob.c.patch @@ -1,5 +1,5 @@ --- glob.c.orig 2004-11-25 11:38:01.000000000 -0800 -+++ glob.c 2005-02-24 16:02:34.000000000 -0800 ++++ glob.c 2006-07-04 12:47:05.000000000 -0700 @@ -40,6 +40,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/gen/glob.c,v 1.22 2004/07/29 03:48:52 tjr Exp $"); @@ -9,15 +9,35 @@ /* * glob(3) -- a superset of the one defined in POSIX 1003.2. * -@@ -144,24 +146,24 @@ +@@ -142,29 +144,42 @@ + #define M_SET META('[') + #define ismeta(c) (((c)&M_QUOTE) != 0) ++static int g_lstat(Char *, struct stat *, glob_t *, locale_t); ++static int g_stat(Char *, struct stat *, glob_t *, locale_t); ++ ++#define g_Ctoc __gl_g_Ctoc ++#define glob0 __gl_glob0 ++#define glob2_32 __gl_glob0_32 ++#define glob2_64 __gl_glob0_64 ++#define glob3 __gl_glob3 ++#define globexp1 __gl_globexp1 ++#define globextend __gl_globextend ++__private_extern__ int g_Ctoc(const Char *, char *, u_int, locale_t); ++__private_extern__ int glob0(const Char *, glob_t *, int *, locale_t); ++__private_extern__ int glob2_32(Char *, Char *, Char *, Char *, glob_t *, int *, locale_t); ++__private_extern__ int glob2_64(Char *, Char *, Char *, Char *, glob_t *, int *, locale_t); ++__private_extern__ int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, int *, locale_t); ++__private_extern__ int globexp1(const Char *, glob_t *, int *, locale_t); ++__private_extern__ int globextend(const Char *, glob_t *, int *, locale_t); ++ ++#ifndef BUILDING_VARIANT ++#define glob2(a,b,c,d,e,f,g) (((e)->gl_flags & GLOB_INODE64) ? glob2_64((a),(b),(c),(d),(e),(f),(g)) : glob2_32((a),(b),(c),(d),(e),(f),(g))) static int compare(const void *, const void *); -static int g_Ctoc(const Char *, char *, u_int); -static int g_lstat(Char *, struct stat *, glob_t *); -static DIR *g_opendir(Char *, glob_t *); -+static int g_Ctoc(const Char *, char *, u_int, locale_t); -+static int g_lstat(Char *, struct stat *, glob_t *, locale_t); +static DIR *g_opendir(Char *, glob_t *, locale_t); static Char *g_strchr(Char *, wchar_t); #ifdef notdef @@ -29,24 +49,22 @@ -static int glob2(Char *, Char *, Char *, Char *, glob_t *, int *); -static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, int *); -static int globextend(const Char *, glob_t *, int *); -+static int g_stat(Char *, struct stat *, glob_t *, locale_t); -+static int glob0(const Char *, glob_t *, int *, locale_t); +static int glob1(Char *, glob_t *, int *, locale_t); -+static int glob2(Char *, Char *, Char *, Char *, glob_t *, int *, locale_t); -+static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, int *, locale_t); -+static int globextend(const Char *, glob_t *, int *, locale_t); static const Char * globtilde(const Char *, Char *, size_t, glob_t *); -static int globexp1(const Char *, glob_t *, int *); -static int globexp2(const Char *, const Char *, glob_t *, int *, int *); -static int match(Char *, Char *, Char *); -+static int globexp1(const Char *, glob_t *, int *, locale_t); +static int globexp2(const Char *, const Char *, glob_t *, int *, int *, locale_t); +static int match(Char *, Char *, Char *, locale_t); #ifdef DEBUG static void qprintf(const char *, Char *); #endif -@@ -178,6 +180,8 @@ ++#endif /* !BUILDING_VARIANT */ + + int + glob(pattern, flags, errfunc, pglob) +@@ -178,6 +193,8 @@ mbstate_t mbs; wchar_t wc; size_t clen; @@ -55,7 +73,20 @@ patnext = (u_char *) pattern; if (!(flags & GLOB_APPEND)) { -@@ -200,8 +204,8 @@ +@@ -192,7 +209,12 @@ + limit = ARG_MAX; + } else + limit = 0; ++#if __DARWIN_64_BIT_INO_T + pglob->gl_flags = flags & ~GLOB_MAGCHAR; ++ pglob->gl_flags |= GLOB_INODE64; ++#else /* !__DARWIN_64_BIT_INO_T */ ++ pglob->gl_flags = flags & ~(GLOB_MAGCHAR | GLOB_INODE64); ++#endif /* __DARWIN_64_BIT_INO_T */ + pglob->gl_errfunc = errfunc; + pglob->gl_matchc = 0; + +@@ -200,8 +222,8 @@ bufend = bufnext + MAXPATHLEN - 1; if (flags & GLOB_NOESCAPE) { memset(&mbs, 0, sizeof(mbs)); @@ -66,7 +97,7 @@ if (clen == (size_t)-1 || clen == (size_t)-2) return (GLOB_NOMATCH); else if (clen == 0) -@@ -212,7 +216,7 @@ +@@ -212,7 +234,7 @@ } else { /* Protect the quoted characters. */ memset(&mbs, 0, sizeof(mbs)); @@ -75,7 +106,7 @@ if (*patnext == QUOTE) { if (*++patnext == EOS) { *bufnext++ = QUOTE | M_PROTECT; -@@ -221,7 +225,7 @@ +@@ -221,7 +243,7 @@ prot = M_PROTECT; } else prot = 0; @@ -84,7 +115,7 @@ if (clen == (size_t)-1 || clen == (size_t)-2) return (GLOB_NOMATCH); else if (clen == 0) -@@ -233,9 +237,9 @@ +@@ -233,34 +255,36 @@ *bufnext = EOS; if (flags & GLOB_BRACE) @@ -95,12 +126,15 @@ + return glob0(patbuf, pglob, &limit, loc); } ++#ifndef BUILDING_VARIANT /* -@@ -244,23 +248,24 @@ + * Expand recursively a glob {} pattern. When there is no more expansion + * invoke the standard globbing routine to glob the rest of the magic * characters */ - static int +-static int -globexp1(pattern, pglob, limit) ++__private_extern__ int +globexp1(pattern, pglob, limit, loc) const Char *pattern; glob_t *pglob; @@ -125,7 +159,7 @@ } -@@ -270,10 +275,11 @@ +@@ -270,10 +294,11 @@ * If it fails then it tries to glob the rest of the pattern and returns. */ static int @@ -138,7 +172,7 @@ { int i; Char *lm, *ls; -@@ -310,7 +316,7 @@ +@@ -310,7 +335,7 @@ /* Non matching braces; just glob the pattern */ if (i != 0 || *pe == EOS) { @@ -147,7 +181,7 @@ return 0; } -@@ -357,7 +363,7 @@ +@@ -357,7 +382,7 @@ #ifdef DEBUG qprintf("globexp2:", patbuf); #endif @@ -156,11 +190,13 @@ /* move after the comma, to the next string */ pl = pm + 1; -@@ -447,10 +453,11 @@ +@@ -446,14 +471,16 @@ + * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. */ - static int +-static int -glob0(pattern, pglob, limit) ++__private_extern__ int +glob0(pattern, pglob, limit, loc) const Char *pattern; glob_t *pglob; @@ -168,8 +204,24 @@ + locale_t loc; { const Char *qpatnext; - int c, err, oldpathc; -@@ -512,7 +519,7 @@ +- int c, err, oldpathc; ++ Char c; ++ int err, oldpathc; + Char *bufnext, patbuf[MAXPATHLEN]; + + qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); +@@ -462,6 +489,10 @@ + + /* We don't need to check for buffer overflow any more. */ + while ((c = *qpatnext++) != EOS) { ++ if (c & M_PROTECT) { ++ *bufnext++ = CHAR(c); ++ continue; ++ } /* else */ + switch (c) { + case LBRACKET: + c = *qpatnext; +@@ -512,7 +543,7 @@ qprintf("glob0:", patbuf); #endif @@ -178,7 +230,7 @@ return(err); /* -@@ -525,7 +532,7 @@ +@@ -525,7 +556,7 @@ if (((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) @@ -187,7 +239,12 @@ else return(GLOB_NOMATCH); } -@@ -543,10 +550,11 @@ +@@ -539,14 +570,15 @@ + compare(p, q) + const void *p, *q; + { +- return(strcmp(*(char **)p, *(char **)q)); ++ return(strcoll(*(char **)p, *(char **)q)); } static int @@ -200,21 +257,28 @@ { Char pathbuf[MAXPATHLEN]; -@@ -554,7 +562,7 @@ +@@ -554,19 +586,25 @@ if (*pattern == EOS) return(0); return(glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, - pattern, pglob, limit)); + pattern, pglob, limit, loc)); } ++#endif /* !BUILDING_VARIANT */ /* -@@ -563,10 +571,11 @@ + * The functions glob2 and glob3 are mutually recursive; there is one level + * of recursion for each segment in the pattern that contains one or more * meta characters. */ - static int +-static int -glob2(pathbuf, pathend, pathend_last, pattern, pglob, limit) -+glob2(pathbuf, pathend, pathend_last, pattern, pglob, limit, loc) ++__private_extern__ int ++#if __DARWIN_64_BIT_INO_T ++glob2_64(pathbuf, pathend, pathend_last, pattern, pglob, limit, loc) ++#else /* !__DARWIN_64_BIT_INO_T */ ++glob2_32(pathbuf, pathend, pathend_last, pattern, pglob, limit, loc) ++#endif /* __DARWIN_64_BIT_INO_T */ Char *pathbuf, *pathend, *pathend_last, *pattern; glob_t *pglob; int *limit; @@ -222,7 +286,7 @@ { struct stat sb; Char *p, *q; -@@ -579,13 +588,13 @@ +@@ -579,13 +617,13 @@ for (anymeta = 0;;) { if (*pattern == EOS) { /* End of pattern? */ *pathend = EOS; @@ -238,7 +302,7 @@ S_ISDIR(sb.st_mode)))) { if (pathend + 1 > pathend_last) return (GLOB_ABORTED); -@@ -593,7 +602,7 @@ +@@ -593,7 +631,7 @@ *pathend = EOS; } ++pglob->gl_matchc; @@ -247,7 +311,7 @@ } /* Find end of next segment, copy tentatively to pathend. */ -@@ -617,16 +626,17 @@ +@@ -617,16 +655,18 @@ } } else /* Need expansion, recurse. */ return(glob3(pathbuf, pathend, pathend_last, pattern, p, @@ -257,8 +321,10 @@ /* NOTREACHED */ } - static int +-static int -glob3(pathbuf, pathend, pathend_last, pattern, restpattern, pglob, limit) ++#ifndef BUILDING_VARIANT ++__private_extern__ int +glob3(pathbuf, pathend, pathend_last, pattern, restpattern, pglob, limit, loc) Char *pathbuf, *pathend, *pathend_last, *pattern, *restpattern; glob_t *pglob; @@ -267,7 +333,7 @@ { struct dirent *dp; DIR *dirp; -@@ -646,10 +656,10 @@ +@@ -646,15 +686,16 @@ *pathend = EOS; errno = 0; @@ -278,9 +344,17 @@ - if (g_Ctoc(pathbuf, buf, sizeof(buf))) + if (g_Ctoc(pathbuf, buf, sizeof(buf), loc)) return (GLOB_ABORTED); - if (pglob->gl_errfunc(buf, errno) || - pglob->gl_flags & GLOB_ERR) -@@ -679,7 +689,7 @@ +- if (pglob->gl_errfunc(buf, errno) || +- pglob->gl_flags & GLOB_ERR) ++ if (pglob->gl_errfunc(buf, errno)) + return (GLOB_ABORTED); + } ++ if (pglob->gl_flags & GLOB_ERR) ++ return (GLOB_ABORTED); + return(0); + } + +@@ -679,7 +720,7 @@ dc = pathend; sc = (u_char *) dp->d_name; while (dc < pathend_last) { @@ -289,7 +363,7 @@ if (clen == (size_t)-1 || clen == (size_t)-2) { wc = *sc; clen = 1; -@@ -689,12 +699,12 @@ +@@ -689,12 +730,12 @@ break; sc += clen; } @@ -304,11 +378,13 @@ if (err) break; } -@@ -722,10 +732,11 @@ +@@ -721,11 +762,12 @@ + * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and * gl_pathv points to (gl_offs + gl_pathc + 1) items. */ - static int +-static int -globextend(path, pglob, limit) ++__private_extern__ int +globextend(path, pglob, limit, loc) const Char *path; glob_t *pglob; @@ -317,7 +393,7 @@ { char **pathv; int i; -@@ -760,9 +771,9 @@ +@@ -760,9 +802,9 @@ for (p = path; *p++;) continue; @@ -329,7 +405,7 @@ free(copy); return (GLOB_NOSPACE); } -@@ -777,8 +788,9 @@ +@@ -777,8 +819,9 @@ * pattern causes a recursion level. */ static int @@ -340,7 +416,7 @@ { int ok, negate_range; Char c, k; -@@ -790,7 +802,7 @@ +@@ -790,7 +833,7 @@ if (pat == patend) return(1); do @@ -349,7 +425,7 @@ return(1); while (*name++ != EOS); return(0); -@@ -806,10 +818,10 @@ +@@ -806,10 +849,10 @@ ++pat; while (((c = *pat++) & M_MASK) != M_END) if ((*pat & M_MASK) == M_RNG) { @@ -363,7 +439,7 @@ ) ok = 1; pat += 2; -@@ -846,16 +858,17 @@ +@@ -846,16 +889,17 @@ } static DIR * @@ -383,8 +459,11 @@ return (NULL); } -@@ -866,14 +879,15 @@ +@@ -864,16 +908,18 @@ + + return(opendir(buf)); } ++#endif /* !BUILDING_VARIANT */ static int -g_lstat(fn, sb, pglob) @@ -401,7 +480,7 @@ errno = ENAMETOOLONG; return (-1); } -@@ -883,14 +897,15 @@ +@@ -883,14 +929,15 @@ } static int @@ -419,11 +498,21 @@ errno = ENAMETOOLONG; return (-1); } -@@ -912,17 +927,19 @@ +@@ -899,6 +946,7 @@ + return(stat(buf, sb)); } - static int ++#ifndef BUILDING_VARIANT + static Char * + g_strchr(str, ch) + Char *str; +@@ -911,18 +959,20 @@ + return (NULL); + } + +-static int -g_Ctoc(str, buf, len) ++__private_extern__ int +g_Ctoc(str, buf, len, loc) const Char *str; char *buf; @@ -442,3 +531,8 @@ if (clen == (size_t)-1) return (1); if (*str == L'\0') +@@ -954,3 +1004,4 @@ + (void)printf("\n"); + } + #endif ++#endif /* !BUILDING_VARIANT */ diff --git a/gen/FreeBSD/isatty.c.patch b/gen/FreeBSD/isatty.c.patch index c7bc48f..9ae1d70 100644 --- a/gen/FreeBSD/isatty.c.patch +++ b/gen/FreeBSD/isatty.c.patch @@ -1,11 +1,12 @@ ---- isatty.c.orig Thu Jan 31 16:57:29 2002 -+++ isatty.c Sun May 18 00:50:20 2003 -@@ -39,14 +39,19 @@ +--- isatty.c.orig 2003-05-20 15:21:02.000000000 -0700 ++++ isatty.c 2005-06-02 13:46:32.000000000 -0700 +@@ -39,14 +39,21 @@ #include #include +#include +#include ++#include int isatty(fd) @@ -16,9 +17,10 @@ struct termios t; - retval = (tcgetattr(fd, &t) != -1); -+ if(ioctl(fd, FIODTYPE, &type) != -1) -+ retval = (type == D_TTY); -+ else ++ if(ioctl(fd, FIODTYPE, &type) != -1) { ++ if((retval = (type == D_TTY)) == 0) ++ errno = ENOTTY; ++ } else + retval = (tcgetattr(fd, &t) != -1); return(retval); } diff --git a/gen/FreeBSD/isgreater.3.patch b/gen/FreeBSD/isgreater.3.patch index f65e8ce..9131a7e 100644 --- a/gen/FreeBSD/isgreater.3.patch +++ b/gen/FreeBSD/isgreater.3.patch @@ -1,5 +1,30 @@ ---- isgreater.3.orig Fri Oct 3 17:12:54 2003 -+++ isgreater.3 Fri Nov 7 15:44:33 2003 +--- _SB/Libc/gen/FreeBSD/isgreater.3 2003-11-12 00:44:46.000000000 -0800 ++++ _SB/Libc/gen/FreeBSD/isgreater.3.edit 2006-06-28 16:55:51.000000000 -0700 +@@ -55,11 +55,11 @@ + .Fn islessequal , + and + .Fn islessgreater +-take arguments ++takes arguments + .Fa x + and + .Fa y +-and return a non-zero value if and only if its nominal ++and returns a non-zero value if and only if its nominal + relation on + .Fa x + and +@@ -74,8 +74,8 @@ + macro takes arguments + .Fa x + and +-.Fa y +-and returns non-zero if and only if neither ++.Fa y , ++returning non-zero if and only if neither + .Fa x + nor + .Fa y @@ -97,6 +97,3 @@ .Fn isunordered macros conform to diff --git a/gen/FreeBSD/jrand48.c.patch b/gen/FreeBSD/jrand48.c.patch new file mode 100644 index 0000000..c1bc3df --- /dev/null +++ b/gen/FreeBSD/jrand48.c.patch @@ -0,0 +1,12 @@ +--- 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 @@ + long + jrand48(unsigned short xseed[3]) + { +- _dorand48(xseed); +- return ((long) xseed[2] << 16) + (long) xseed[1]; ++ uint48 tmp; ++ DORAND48(tmp, xseed); ++ return (int)((tmp >> 16) & 0xffffffff); + } diff --git a/gen/FreeBSD/lcong48.c.patch b/gen/FreeBSD/lcong48.c.patch new file mode 100644 index 0000000..3146983 --- /dev/null +++ b/gen/FreeBSD/lcong48.c.patch @@ -0,0 +1,23 @@ +--- 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 @@ + + #include "rand48.h" + +-extern unsigned short _rand48_seed[3]; +-extern unsigned short _rand48_mult[3]; +-extern unsigned short _rand48_add; +- + void + lcong48(unsigned short p[7]) + { +- _rand48_seed[0] = p[0]; +- _rand48_seed[1] = p[1]; +- _rand48_seed[2] = p[2]; +- _rand48_mult[0] = p[3]; +- _rand48_mult[1] = p[4]; +- _rand48_mult[2] = p[5]; ++ LOADRAND48(_rand48_seed, &p[0]); ++ LOADRAND48(_rand48_mult, &p[3]); + _rand48_add = p[6]; + } diff --git a/gen/FreeBSD/lockf.3.patch b/gen/FreeBSD/lockf.3.patch new file mode 100644 index 0000000..417bd14 --- /dev/null +++ b/gen/FreeBSD/lockf.3.patch @@ -0,0 +1,80 @@ +--- 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 @@ + .Sh SYNOPSIS + .In unistd.h + .Ft int +-.Fn lockf "int filedes" "int function" "off_t size" ++.Fn lockf "int fildes" "int function" "off_t size" + .Sh DESCRIPTION + The + .Fn lockf +@@ -56,10 +56,10 @@ + .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. +-All the locks for a process are removed when the process terminates. ++All of the locks for a process are removed when the process terminates. + .Pp + The argument +-.Fa filedes ++.Fa fildes + is an open file descriptor. + The file descriptor must have been opened either for write-only + .Dv ( O_WRONLY ) +@@ -214,7 +214,7 @@ + and the section is already locked by another process. + .It Bq Er EBADF + The argument +-.Fa filedes ++.Fa fildes + is not a valid open file descriptor. + .Pp + The argument +@@ -224,7 +224,7 @@ + or + .Dv F_TLOCK , + and +-.Fa filedes ++.Fa fildes + is not a valid file descriptor open for writing. + .It Bq Er EDEADLK + The argument +@@ -243,25 +243,29 @@ + The argument + .Fa function + is not one of +-.Dv F_ULOCK , + .Dv F_LOCK , +-.Dv F_TLOCK ++.Dv F_TEST , ++.Dv F_TLOCK , + or +-.Dv F_TEST . ++.Dv F_ULOCK . + .Pp + The argument +-.Fa filedes +-refers to a file that does not support locking. ++.Fa fildes ++refers to a file that does not support advisory locking. + .It Bq Er ENOLCK + The argument + .Fa function + is +-.Dv F_ULOCK , +-.Dv F_LOCK +-or ++.Dv F_LOCK , + .Dv F_TLOCK , ++or ++.Dv F_ULOCK + and satisfying the lock or unlock request would result in the number + of locked regions in the system exceeding a system-imposed limit. ++.It Bq Er EOPNOTSUPP ++The argument ++.Fa fildes ++refers to a socket; these do not support advisory locking. + .El + .Sh SEE ALSO + .Xr fcntl 2 , diff --git a/gen/FreeBSD/lockf.c.patch b/gen/FreeBSD/lockf.c.patch new file mode 100644 index 0000000..4d31bc7 --- /dev/null +++ b/gen/FreeBSD/lockf.c.patch @@ -0,0 +1,51 @@ +--- 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 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/gen/lockf.c,v 1.8 2002/02/01 00:57:29 obrien Exp $"); + ++#ifdef VARIANT_CANCELABLE ++int __fcntl(int, int, void *); ++#else /* !VARIANT_CANCELABLE */ ++int __fcntl_nocancel(int, int, void *); ++#endif /* VARIANT_CANCELABLE */ ++ ++ + #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 @@ + break; + case F_TEST: + fl.l_type = F_WRLCK; +- if (_fcntl(filedes, F_GETLK, &fl) == -1) ++#ifdef VARIANT_CANCELABLE ++ if (__fcntl(filedes, F_GETLK, &fl) == -1) + return (-1); ++#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()) + return (0); + errno = EAGAIN; +@@ -85,5 +98,10 @@ + /* NOTREACHED */ + } + +- return (_fcntl(filedes, cmd, &fl)); ++#ifdef VARIANT_CANCELABLE ++ return (__fcntl(filedes, cmd, &fl)); ++#else /* !VARIANT_CANCELABLE */ ++ return (__fcntl_nocancel(filedes, cmd, &fl)); ++#endif /* VARIANT_CANCELABLE */ + } ++ diff --git a/gen/FreeBSD/lrand48.c.patch b/gen/FreeBSD/lrand48.c.patch new file mode 100644 index 0000000..1b1734e --- /dev/null +++ b/gen/FreeBSD/lrand48.c.patch @@ -0,0 +1,16 @@ +--- 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 @@ + + #include "rand48.h" + +-extern unsigned short _rand48_seed[3]; +- + long + lrand48(void) + { +- _dorand48(_rand48_seed); +- return ((long) _rand48_seed[2] << 15) + ((long) _rand48_seed[1] >> 1); ++ _DORAND48(_rand48_seed); ++ return (_rand48_seed >> 17) & 0x7fffffff; + } diff --git a/gen/FreeBSD/makecontext.3 b/gen/FreeBSD/makecontext.3 new file mode 100644 index 0000000..36e3ce8 --- /dev/null +++ b/gen/FreeBSD/makecontext.3 @@ -0,0 +1,120 @@ +.\" Copyright (c) 2002 Packet Design, LLC. +.\" All rights reserved. +.\" +.\" Subject to the following obligations and disclaimer of warranty, +.\" use and redistribution of this software, in source or object code +.\" forms, with or without modifications are expressly permitted by +.\" Packet Design; provided, however, that: +.\" +.\" (i) Any and all reproductions of the source or object code +.\" must include the copyright notice above and the following +.\" disclaimer of warranties; and +.\" (ii) No rights are granted, in any manner or form, to use +.\" Packet Design trademarks, including the mark "PACKET DESIGN" +.\" on advertising, endorsements, or otherwise except as such +.\" appears in the above copyright notice or in the software. +.\" +.\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND +.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO +.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING +.\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED +.\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, +.\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE, +.\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS +.\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, +.\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE +.\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE +.\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL +.\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF +.\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 PACKET DESIGN IS ADVISED OF +.\" THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD: src/lib/libc/gen/makecontext.3,v 1.4 2002/12/19 09:40:21 ru Exp $ +.\" +.Dd September 10, 2002 +.Dt MAKECONTEXT 3 +.Os +.Sh NAME +.Nm makecontext , swapcontext +.Nd modify and exchange user thread contexts +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ucontext.h +.Ft void +.Fo makecontext +.Fa "ucontext_t *ucp" +.Fa "void \*[lp]*func\*[rp]\*[lp]void\*[rp]" +.Fa "int argc" ... +.Fc +.Ft int +.Fn swapcontext "ucontext_t *oucp" "const ucontext_t *ucp" +.Sh DESCRIPTION +The +.Fn makecontext +function +modifies the user thread context pointed to by +.Fa ucp , +which must have previously been initialized by a call to +.Xr getcontext 3 +and had a stack allocated for it. +The context is modified so that it will continue execution by invoking +.Fn func +with the arguments provided. +The +.Fa argc +argument +must be equal to the number of additional arguments provided to +.Fn makecontext +and also equal to the number of arguments to +.Fn func , +or else the behavior is undefined. +.Pp +The +.Fa "ucp->uc_link" +argument +must be initialized before calling +.Fn makecontext +and determines the action to take when +.Fn func +returns: +if equal to +.Dv NULL , +the process exits; +otherwise, +.Fn setcontext "ucp->uc_link" +is implicitly invoked. +.Pp +The +.Fn swapcontext +function +saves the current thread context in +.Fa "*oucp" +and makes +.Fa "*ucp" +the currently active context. +.Sh RETURN VALUES +If successful, +.Fn swapcontext +returns zero; +otherwise \-1 is returned and the global variable +.Va errno +is set appropriately. +.Sh ERRORS +The +.Fn swapcontext +function +will fail if: +.Bl -tag -width Er +.It Bq Er ENOMEM +There is not enough stack space in +.Fa ucp +to complete the operation. +.El +.Sh SEE ALSO +.Xr setcontext 3 , +.Xr ucontext 3 diff --git a/gen/FreeBSD/mrand48.c.patch b/gen/FreeBSD/mrand48.c.patch new file mode 100644 index 0000000..97ee465 --- /dev/null +++ b/gen/FreeBSD/mrand48.c.patch @@ -0,0 +1,16 @@ +--- 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 @@ + + #include "rand48.h" + +-extern unsigned short _rand48_seed[3]; +- + long + mrand48(void) + { +- _dorand48(_rand48_seed); +- return ((long) _rand48_seed[2] << 16) + (long) _rand48_seed[1]; ++ _DORAND48(_rand48_seed); ++ return (int)((_rand48_seed >> 16) & 0xffffffff); + } diff --git a/gen/FreeBSD/nice.c.patch b/gen/FreeBSD/nice.c.patch new file mode 100644 index 0000000..6ce1320 --- /dev/null +++ b/gen/FreeBSD/nice.c.patch @@ -0,0 +1,39 @@ +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 + #include + #include + #include +- ++#if __DARWIN_UNIX03 ++#include ++#endif /* __DARWIN_UNIX03 */ + /* + * Backwards compatible nice. + */ +@@ -50,11 +52,18 @@ int + nice(incr) + int incr; + { +- int prio; ++ int prio, rv; + + errno = 0; + prio = getpriority(PRIO_PROCESS, 0); + if (prio == -1 && errno) + return (-1); +- return (setpriority(PRIO_PROCESS, 0, prio + incr)); ++#if __DARWIN_UNIX03 ++ if (prio + incr > NZERO-1) ++ incr = NZERO-1-prio; ++#endif /* __DARWIN_UNIX03 */ ++ rv = setpriority(PRIO_PROCESS, 0, prio + incr); ++ if (rv == -1 && errno == EACCES) ++ errno = EPERM; ++ return (rv == -1) ? rv : getpriority(PRIO_PROCESS, 0); + } diff --git a/gen/FreeBSD/nrand48.c.patch b/gen/FreeBSD/nrand48.c.patch new file mode 100644 index 0000000..06935d5 --- /dev/null +++ b/gen/FreeBSD/nrand48.c.patch @@ -0,0 +1,12 @@ +--- 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 @@ + long + nrand48(unsigned short xseed[3]) + { +- _dorand48(xseed); +- return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1); ++ uint48 tmp; ++ DORAND48(tmp, xseed); ++ return (tmp >> 17) & 0x7fffffff; + } diff --git a/gen/FreeBSD/opendir.c.patch b/gen/FreeBSD/opendir.c.patch index d26bc38..d4ddb1e 100644 --- a/gen/FreeBSD/opendir.c.patch +++ b/gen/FreeBSD/opendir.c.patch @@ -1,5 +1,5 @@ ---- opendir.c.orig 2004-11-25 11:38:01.000000000 -0800 -+++ opendir.c 2006-05-03 23:21:10.000000000 -0700 +--- 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 @@ #include #include @@ -40,7 +40,30 @@ if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 || (dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL) goto fail; -@@ -269,7 +258,7 @@ +@@ -154,7 +143,11 @@ + ddptr = buf + (len - space); + } + ++#if __DARWIN_64_BIT_INO_T ++ n = __getdirentries64(fd, ddptr, space, &dirp->dd_td->seekoff); ++#else /* !__DARWIN_64_BIT_INO_T */ + n = _getdirentries(fd, ddptr, space, &dirp->dd_seek); ++#endif /* __DARWIN_64_BIT_INO_T */ + if (n > 0) { + ddptr += n; + space -= n; +@@ -262,14 +255,18 @@ + dirp->dd_buf = malloc(dirp->dd_len); + if (dirp->dd_buf == NULL) + goto fail; ++#if __DARWIN_64_BIT_INO_T ++ dirp->dd_td->seekoff = 0; ++#else /* !__DARWIN_64_BIT_INO_T */ + dirp->dd_seek = 0; ++#endif /* __DARWIN_64_BIT_INO_T */ + flags &= ~DTF_REWIND; + } + dirp->dd_loc = 0; dirp->dd_fd = fd; dirp->dd_flags = flags; diff --git a/gen/FreeBSD/pause.c.patch b/gen/FreeBSD/pause.c.patch new file mode 100644 index 0000000..07f2f75 --- /dev/null +++ b/gen/FreeBSD/pause.c.patch @@ -0,0 +1,28 @@ +--- 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 @@ + #if defined(LIBC_SCCS) && !defined(lint) + static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93"; + #endif /* LIBC_SCCS and not lint */ ++ ++/* For the cancelable variant, we call the cancelable sigsuspend */ ++#ifdef VARIANT_CANCELABLE ++#undef __DARWIN_NON_CANCELABLE ++#define __DARWIN_NON_CANCELABLE 0 ++#endif /* VARIANT_CANCELABLE */ ++ + #include + __FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); + +@@ -46,7 +53,10 @@ + int + __pause() + { +- return sigpause(sigblock(0L)); ++ sigset_t set; ++ ++ sigprocmask(0, NULL, &set); ++ return sigsuspend(&set); + } + __weak_reference(__pause, pause); + __weak_reference(__pause, _pause); diff --git a/gen/FreeBSD/popen.3.patch b/gen/FreeBSD/popen.3.patch new file mode 100644 index 0000000..c495449 --- /dev/null +++ b/gen/FreeBSD/popen.3.patch @@ -0,0 +1,96 @@ +--- _SB/Libc/gen/FreeBSD/popen.3 2004-11-25 11:38:01.000000000 -0800 ++++ _SB/Libc/gen/FreeBSD/popen.3.edit 2006-06-28 16:55:51.000000000 -0700 +@@ -36,8 +36,8 @@ + .Dt POPEN 3 + .Os + .Sh NAME +-.Nm popen , +-.Nm pclose ++.Nm pclose , ++.Nm popen + .Nd process + .Tn I/O + .Sh LIBRARY +@@ -45,16 +45,20 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft FILE * +-.Fn popen "const char *command" "const char *type" ++.Fo popen ++.Fa "const char *command" ++.Fa "const char *mode" ++.Fc + .Ft int +-.Fn pclose "FILE *stream" ++.Fo pclose ++.Fa "FILE *stream" ++.Fc + .Sh DESCRIPTION + The + .Fn popen + function + .Dq opens +-a process by creating a bidirectional pipe +-forking, ++a process by creating a bidirectional pipe, forking, + and invoking the shell. + Any streams opened by previous + .Fn popen +@@ -62,18 +66,18 @@ + Historically, + .Fn popen + was implemented with a unidirectional pipe; +-hence many implementations of ++hence, many implementations of + .Fn popen + only allow the +-.Fa type ++.Fa mode + argument to specify reading or writing, not both. +-Since ++Because + .Fn popen + is now implemented using a bidirectional pipe, the +-.Fa type ++.Fa mode + argument may request a bidirectional data flow. + The +-.Fa type ++.Fa mode + argument is a pointer to a null-terminated string + which must be + .Ql r +@@ -88,7 +92,7 @@ + argument is a pointer to a null-terminated string + containing a shell command line. + This command is passed to +-.Pa /bin/sh ++.Pa /bin/sh , + using the + .Fl c + flag; interpretation, if any, is performed by the shell. +@@ -97,7 +101,7 @@ + .Fn popen + is a normal standard + .Tn I/O +-stream in all respects ++stream in all respects, + save that it must be closed with + .Fn pclose + rather than +@@ -115,12 +119,12 @@ + .Pp + Note that output + .Fn popen +-streams are fully buffered by default. ++streams are fully buffered, by default. + .Pp + The + .Fn pclose +-function waits for the associated process to terminate +-and returns the exit status of the command ++function waits for the associated process to terminate; ++it returns the exit status of the command, + as returned by + .Xr wait4 2 . + .Sh RETURN VALUES diff --git a/gen/FreeBSD/popen.c.patch b/gen/FreeBSD/popen.c.patch index 9a2785c..de0c05e 100644 --- a/gen/FreeBSD/popen.c.patch +++ b/gen/FreeBSD/popen.c.patch @@ -1,14 +1,16 @@ --- popen.c.orig 2003-05-20 15:21:02.000000000 -0700 -+++ popen.c 2005-09-17 16:08:55.000000000 -0700 -@@ -43,6 +43,7 @@ ++++ popen.c 2005-09-14 15:53:35.000000000 -0700 +@@ -43,7 +43,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop #include "namespace.h" #include #include +- +#include - ++#include /* fwide() */ #include #include -@@ -55,11 +56,14 @@ + #include +@@ -55,11 +56,14 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop #include "un-namespace.h" #include "libc_private.h" @@ -24,7 +26,7 @@ pid_t pid; } *pidlist; static pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER; -@@ -77,20 +81,18 @@ +@@ -77,20 +81,24 @@ popen(command, type) char *argv[4]; struct pid *p; @@ -32,24 +34,30 @@ - * Lite2 introduced two-way popen() pipes using _socketpair(). - * FreeBSD's pipe() is bidirectional, so we use that. - */ - if (strchr(type, '+')) { +- if (strchr(type, '+')) { ++ if (type == NULL) { ++ errno = EINVAL; ++ return (NULL); ++ } ++ if (strcmp(type, "r+") == 0) { twoway = 1; type = "r+"; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pdes) < 0) + return (NULL); } else { twoway = 0; - if ((*type != 'r' && *type != 'w') || type[1]) +- if ((*type != 'r' && *type != 'w') || type[1]) ++ if ((*type != 'r' && *type != 'w') || type[1]) { ++ errno = EINVAL; return (NULL); -+ if (pipe(pdes) < 0) -+ return (NULL); } -- if (pipe(pdes) < 0) -- return (NULL); + if (pipe(pdes) < 0) + return (NULL); ++ } if ((cur = malloc(sizeof(struct pid))) == NULL) { (void)_close(pdes[0]); -@@ -104,7 +106,7 @@ +@@ -104,7 +112,7 @@ popen(command, type) argv[3] = NULL; THREAD_LOCK(); @@ -58,7 +66,7 @@ case -1: /* Error. */ THREAD_UNLOCK(); (void)_close(pdes[0]); -@@ -138,7 +140,7 @@ +@@ -138,7 +146,7 @@ popen(command, type) (void)_close(pdes[1]); } for (p = pidlist; p; p = p->next) { @@ -67,7 +75,7 @@ } _execve(_PATH_BSHELL, argv, environ); _exit(127); -@@ -149,9 +151,11 @@ +@@ -149,9 +157,11 @@ popen(command, type) /* Parent; assume fdopen can't fail. */ if (*type == 'r') { iop = fdopen(pdes[0], type); @@ -79,3 +87,12 @@ (void)_close(pdes[0]); } +@@ -162,7 +172,7 @@ popen(command, type) + cur->next = pidlist; + pidlist = cur; + THREAD_UNLOCK(); +- ++ fwide(iop, -1); /* byte stream */ + return (iop); + } + diff --git a/gen/FreeBSD/pselect.3.patch b/gen/FreeBSD/pselect.3.patch index 33bbca8..b435243 100644 --- a/gen/FreeBSD/pselect.3.patch +++ b/gen/FreeBSD/pselect.3.patch @@ -1,6 +1,6 @@ ---- pselect.3.orig Wed Dec 18 02:13:54 2002 -+++ pselect.3 Fri May 2 16:46:17 2003 -@@ -37,7 +37,7 @@ +--- _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 +@@ -37,15 +37,15 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -9,3 +9,43 @@ .Ft int .Fo pselect .Fa "int nfds" +-.Fa "fd_set * restrict readfds" +-.Fa "fd_set * restrict writefds" +-.Fa "fd_set * restrict exceptfds" +-.Fa "const struct timespec * restrict timeout" +-.Fa "const sigset_t * restrict newsigmask" ++.Fa "fd_set *restrict readfds" ++.Fa "fd_set *restrict writefds" ++.Fa "fd_set *restrict errorfds" ++.Fa "const struct timespec *restrict timeout" ++.Fa "const sigset_t *restrict sigmask" + .Fc + .Sh DESCRIPTION + The +@@ -57,7 +57,7 @@ + The + .Fa nfds , readfds , writefds , + and +-.Fa exceptfds ++.Fa errorfds + arguments are all identical to the analogous arguments of + .Fn select . + The +@@ -65,7 +65,7 @@ + argument in + .Fn pselect + points to a +-.Vt "const struct timespec" ++.Vt "const struct timespec" , + rather than the (modifiable) + .Vt "struct timeval" + used by +@@ -76,7 +76,7 @@ + .Fn pselect + should wait indefinitely. + Finally, +-.Fa newsigmask ++.Fa sigmask + specifies a signal mask which is set while waiting for input. + When + .Fn pselect diff --git a/gen/FreeBSD/pselect.c.patch b/gen/FreeBSD/pselect.c.patch index 3195aeb..b72ccfc 100644 --- a/gen/FreeBSD/pselect.c.patch +++ b/gen/FreeBSD/pselect.c.patch @@ -1,6 +1,18 @@ ---- pselect.c.orig Sat Oct 12 09:13:37 2002 -+++ pselect.c Fri May 16 14:11:39 2003 -@@ -31,8 +31,10 @@ +--- pselect.c.orig 2007-08-19 17:38:56.000000000 -0700 ++++ pselect.c 2007-08-19 19:15:50.000000000 -0700 +@@ -27,12 +27,22 @@ + * SUCH DAMAGE. + */ + ++#if defined(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050) ++#undef __DARWIN_NON_CANCELABLE ++#endif /* VARIANT_CANCELABLE */ ++ ++#ifdef VARIANT_DARWINEXTSN ++#define _DARWIN_UNLIMITED_SELECT ++#endif /* VARIANT_DARWINEXTSN */ ++ + #include __FBSDID("$FreeBSD: src/lib/libc/gen/pselect.c,v 1.6 2002/10/12 16:13:37 mike Exp $"); #include "namespace.h" diff --git a/gen/FreeBSD/rand48.3.patch b/gen/FreeBSD/rand48.3.patch new file mode 100644 index 0000000..7b06dd0 --- /dev/null +++ b/gen/FreeBSD/rand48.3.patch @@ -0,0 +1,109 @@ +--- _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 +@@ -18,51 +18,68 @@ + .Sh NAME + .Nm drand48 , + .Nm erand48 , ++.Nm jrand48 , ++.Nm lcong48 , + .Nm lrand48 , +-.Nm nrand48 , + .Nm mrand48 , +-.Nm jrand48 , +-.Nm srand48 , ++.Nm nrand48 , + .Nm seed48 , +-.Nm lcong48 ++.Nm srand48 + .Nd pseudo random number generators and initialization routines + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In stdlib.h + .Ft double +-.Fn drand48 void ++.Fo drand48 ++.Fa void ++.Fc + .Ft double +-.Fn erand48 "unsigned short xseed[3]" ++.Fo erand48 ++.Fa "unsigned short xsubi[3]" ++.Fc + .Ft long +-.Fn lrand48 void ++.Fo jrand48 ++.Fa "unsigned short xsubi[3]" ++.Fc ++.Ft void ++.Fo lcong48 ++.Fa "unsigned short param[7]" ++.Fc + .Ft long +-.Fn nrand48 "unsigned short xseed[3]" ++.Fo lrand48 ++.Fa void ++.Fc + .Ft long +-.Fn mrand48 void ++.Fo mrand48 ++.Fa void ++.Fc + .Ft long +-.Fn jrand48 "unsigned short xseed[3]" +-.Ft void +-.Fn srand48 "long seed" ++.Fo nrand48 ++.Fa "unsigned short xsubi[3]" ++.Fc + .Ft "unsigned short *" +-.Fn seed48 "unsigned short xseed[3]" ++.Fo seed48 ++.Fa "unsigned short seed16v[3]" ++.Fc + .Ft void +-.Fn lcong48 "unsigned short p[7]" ++.Fo srand48 ++.Fa "long seedval" ++.Fc + .Sh DESCRIPTION + The + .Fn rand48 +-family of functions generates pseudo-random numbers using a linear ++family of functions generates pseudo-random numbers, using a linear + congruential algorithm working on integers 48 bits in size. + The + particular formula employed is +-r(n+1) = (a * r(n) + c) mod m +-where the default values are +-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 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. + .Pp +-For all the six generator routines described next, the first ++For the six generator routines described next, the first + computational step is to perform a single iteration of the algorithm. + .Pp + The +@@ -124,7 +141,7 @@ + .Fn drand48 , + .Fn lrand48 , + and +-.Fn mrand48 ++.Fn mrand48 , + 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 @@ + .Fn seed48 + function + returns a pointer to an array of 3 shorts which contains the old seed. +-This array is statically allocated, thus its contents are lost after ++This array is statically allocated; thus, its contents are lost after + each new call to + .Fn seed48 . + .Pp diff --git a/gen/FreeBSD/rand48.h.patch b/gen/FreeBSD/rand48.h.patch new file mode 100644 index 0000000..c305cb7 --- /dev/null +++ b/gen/FreeBSD/rand48.h.patch @@ -0,0 +1,67 @@ +--- rand48.h.orig 2003-05-20 15:21:02.000000000 -0700 ++++ rand48.h 2005-11-03 14:06:17.000000000 -0800 +@@ -19,8 +19,6 @@ + #include + #include + +-void _dorand48(unsigned short[3]); +- + #define RAND48_SEED_0 (0x330e) + #define RAND48_SEED_1 (0xabcd) + #define RAND48_SEED_2 (0x1234) +@@ -29,4 +27,55 @@ + #define RAND48_MULT_2 (0x0005) + #define RAND48_ADD (0x000b) + ++typedef unsigned long long uint48; ++ ++extern uint48 _rand48_seed; ++extern uint48 _rand48_mult; ++extern uint48 _rand48_add; ++ ++#define TOUINT48(x,y,z) \ ++ ((uint48)(x) + (((uint48)(y)) << 16) + (((uint48)(z)) << 32)) ++ ++#define RAND48_SEED TOUINT48(RAND48_SEED_0, RAND48_SEED_1, RAND48_SEED_2) ++#define RAND48_MULT TOUINT48(RAND48_MULT_0, RAND48_MULT_1, RAND48_MULT_2) ++ ++#define LOADRAND48(l,x) \ ++ (l) = TOUINT48((x)[0], (x)[1], (x)[2]) ++ ++#define STORERAND48(l,x) \ ++ (x)[0] = (unsigned short)(l); \ ++ (x)[1] = (unsigned short)((l) >> 16); \ ++ (x)[2] = (unsigned short)((l) >> 32) ++ ++#define _DORAND48(l) \ ++ (l) = (l) * _rand48_mult + _rand48_add ++ ++#define DORAND48(l,x) \ ++ LOADRAND48(l, x); \ ++ _DORAND48(l); \ ++ STORERAND48(l, x) ++ ++#include "fpmath.h" ++ ++/* ++ * Optimization for speed: avoid int-to-double conversion. Assume doubles ++ * are IEEE-754 and insert the bits directly. To normalize, the (1 << 52) ++ * is the hidden bit, which the first set bit is shifted to. ++ */ ++#define ERAND48_BEGIN \ ++ union { \ ++ union IEEEd2bits ieee; \ ++ unsigned long long l; \ ++ } u; \ ++ int s ++ ++#define ERAND48_END(x) \ ++ u.l = ((x) & 0xffffffffffffULL); \ ++ if (u.l == 0) \ ++ return 0.0; \ ++ u.l <<= 5; \ ++ for(s = 0; !(u.l & (1LL << 52)); s++, u.l <<= 1) {} \ ++ u.ieee.bits.exp = 1022 - s; \ ++ return u.ieee.d ++ + #endif /* _RAND48_H_ */ diff --git a/gen/FreeBSD/readdir.c.patch b/gen/FreeBSD/readdir.c.patch new file mode 100644 index 0000000..56c8c12 --- /dev/null +++ b/gen/FreeBSD/readdir.c.patch @@ -0,0 +1,27 @@ +--- 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 @@ + #include + #include + #include ++#include + #include "un-namespace.h" + ++#include "telldir.h" + #include "libc_private.h" + + /* +@@ -63,8 +65,13 @@ + dirp->dd_loc = 0; + } + if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) { ++#if __DARWIN_64_BIT_INO_T ++ dirp->dd_size = __getdirentries64(dirp->dd_fd, ++ dirp->dd_buf, dirp->dd_len, &dirp->dd_td->seekoff); ++#else /* !__DARWIN_64_BIT_INO_T */ + dirp->dd_size = _getdirentries(dirp->dd_fd, + dirp->dd_buf, dirp->dd_len, &dirp->dd_seek); ++#endif /* __DARWIN_64_BIT_INO_T */ + if (dirp->dd_size <= 0) + return (NULL); + } diff --git a/gen/FreeBSD/seed48.c.patch b/gen/FreeBSD/seed48.c.patch new file mode 100644 index 0000000..036fa2b --- /dev/null +++ b/gen/FreeBSD/seed48.c.patch @@ -0,0 +1,30 @@ +--- 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 @@ + + #include "rand48.h" + +-extern unsigned short _rand48_seed[3]; +-extern unsigned short _rand48_mult[3]; +-extern unsigned short _rand48_add; +- + unsigned short * + seed48(unsigned short xseed[3]) + { + static unsigned short sseed[3]; + +- sseed[0] = _rand48_seed[0]; +- sseed[1] = _rand48_seed[1]; +- sseed[2] = _rand48_seed[2]; +- _rand48_seed[0] = xseed[0]; +- _rand48_seed[1] = xseed[1]; +- _rand48_seed[2] = xseed[2]; +- _rand48_mult[0] = RAND48_MULT_0; +- _rand48_mult[1] = RAND48_MULT_1; +- _rand48_mult[2] = RAND48_MULT_2; ++ STORERAND48(_rand48_seed, sseed); ++ LOADRAND48(_rand48_seed, xseed); ++ _rand48_mult = RAND48_MULT; + _rand48_add = RAND48_ADD; + return sseed; + } diff --git a/gen/FreeBSD/setprogname.c.patch b/gen/FreeBSD/setprogname.c.patch index 19cc554..862a270 100644 --- a/gen/FreeBSD/setprogname.c.patch +++ b/gen/FreeBSD/setprogname.c.patch @@ -1,5 +1,5 @@ ---- setprogname.c.orig 2003-05-20 15:21:02.000000000 -0700 -+++ setprogname.c 2005-10-26 00:58:44.000000000 -0700 +--- setprogname.c.orig 2005-10-19 15:16:49.000000000 -0700 ++++ setprogname.c 2005-10-19 15:17:10.000000000 -0700 @@ -3,6 +3,10 @@ #include @@ -22,12 +22,12 @@ p = strrchr(progname, '/'); if (p != NULL) - __progname = p + 1; -+ __progname = (char *)(++p); ++ __progname = (char *)(p + 1); else - __progname = progname; + __progname = (char *)(p = progname); + -+ strlcpy(&buf[0], p, sizeof(buf)); ++ strlcpy(&buf[0], (char *)(p), sizeof(buf)); + + mib[0] = CTL_KERN; + mib[1] = KERN_PROCNAME; diff --git a/gen/FreeBSD/siginterrupt.3.patch b/gen/FreeBSD/siginterrupt.3.patch new file mode 100644 index 0000000..071ae27 --- /dev/null +++ b/gen/FreeBSD/siginterrupt.3.patch @@ -0,0 +1,13 @@ +--- _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 @@ + This library routine uses an extension of the + .Xr sigaction 2 + system call that is not available in +-.Bx 4.2 , +-hence it should not be used if backward compatibility is needed. ++.Bx 4.2 ; ++hence, it should not be used if backward compatibility is needed. + .Sh RETURN VALUES + .Rv -std siginterrupt + .Sh ERRORS diff --git a/gen/FreeBSD/signal.3.patch b/gen/FreeBSD/signal.3.patch index 1989c65..dd821a6 100644 --- a/gen/FreeBSD/signal.3.patch +++ b/gen/FreeBSD/signal.3.patch @@ -1,5 +1,5 @@ ---- /Volumes/XDisk/tmp/Libc/gen/FreeBSD/signal.3.orig 2004-07-03 15:30:08.000000000 -0700 -+++ /Volumes/XDisk/tmp/Libc/gen/FreeBSD/signal.3 2004-10-24 17:08:28.000000000 -0700 +--- 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" @@ -11,3 +11,58 @@ .Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp" ; .Ft sig_t .Fn signal "int sig" "sig_t func" +@@ -62,9 +60,9 @@ + .Xr sigaction 2 + facility. + .Pp +-Signals allow the manipulation of a process from outside its +-domain as well as allowing the process to manipulate itself or +-copies of itself (children). ++Signals allow the manipulation of a process from outside its domain, ++as well as allowing the process to manipulate itself ++or copies of itself (children). + 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 @@ + when a process resumes after being stopped, + when the status of child processes changes, + or when input is ready at the control terminal. +-Most signals result in the termination of the process receiving them +-if no action +-is taken; some signals instead cause the process receiving them +-to be stopped, or are simply discarded if the process has not +-requested otherwise. ++Most signals result in the termination of the process receiving them, ++if no action is taken; ++some signals instead cause the process receiving them to be stopped, ++or are simply discarded if the process has not requested otherwise. + Except for the + .Dv SIGKILL + and +@@ -135,7 +132,6 @@ + .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" +-.It 32 Ta Dv SIGTHR Ta "terminate process" Ta "thread interrupt" + .El + .Pp + The +@@ -151,7 +147,7 @@ + A + .Dv SIG_DFL + resets the default action. +-To ignore the signal ++To ignore the signal, + .Fa func + should be + .Dv SIG_IGN . +@@ -185,7 +181,7 @@ + .Xr write 2 , + .Xr sendto 2 , + .Xr recvfrom 2 , +-.Xr sendmsg 2 ++.Xr sendmsg 2 , + and + .Xr recvmsg 2 + on a communications channel or a low speed device diff --git a/gen/FreeBSD/signbit.3.patch b/gen/FreeBSD/signbit.3.patch index c2f2e91..6fa0fb5 100644 --- a/gen/FreeBSD/signbit.3.patch +++ b/gen/FreeBSD/signbit.3.patch @@ -1,6 +1,18 @@ ---- signbit.3.orig Fri Oct 3 17:12:55 2003 -+++ signbit.3 Fri Nov 7 15:40:35 2003 -@@ -50,8 +50,3 @@ +--- _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 +@@ -40,8 +40,9 @@ + The + .Fn signbit + macro takes an argument of +-.Fa x +-and returns non-zero if the value of its sign is negative, otherwise 0. ++.Fa x . ++It returns non-zero if the value of the argument's sign is negative, ++otherwise 0. + .Sh SEE ALSO + .Xr fpclassify 3 , + .Xr math 3 +@@ -50,8 +51,3 @@ .Fn signbit macro conforms to .St -isoC-99 . diff --git a/gen/FreeBSD/sleep.c.patch b/gen/FreeBSD/sleep.c.patch new file mode 100644 index 0000000..4c6b2dc --- /dev/null +++ b/gen/FreeBSD/sleep.c.patch @@ -0,0 +1,14 @@ +--- 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 @@ + * SUCH DAMAGE. + */ + ++#ifdef VARIANT_CANCELABLE ++#undef __DARWIN_NON_CANCELABLE ++#define __DARWIN_NON_CANCELABLE 0 ++#endif /* VARIANT_CANCELABLE */ ++ + #if defined(LIBC_SCCS) && !defined(lint) + static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; + #endif /* LIBC_SCCS and not lint */ diff --git a/gen/FreeBSD/srand48.c.patch b/gen/FreeBSD/srand48.c.patch new file mode 100644 index 0000000..e109d25 --- /dev/null +++ b/gen/FreeBSD/srand48.c.patch @@ -0,0 +1,23 @@ +--- srand48.c.orig 2003-05-20 15:21:03.000000000 -0700 ++++ srand48.c 2005-11-03 13:50:51.000000000 -0800 +@@ -13,18 +13,10 @@ + + #include "rand48.h" + +-extern unsigned short _rand48_seed[3]; +-extern unsigned short _rand48_mult[3]; +-extern unsigned short _rand48_add; +- + void + srand48(long seed) + { +- _rand48_seed[0] = RAND48_SEED_0; +- _rand48_seed[1] = (unsigned short) seed; +- _rand48_seed[2] = (unsigned short) (seed >> 16); +- _rand48_mult[0] = RAND48_MULT_0; +- _rand48_mult[1] = RAND48_MULT_1; +- _rand48_mult[2] = RAND48_MULT_2; ++ _rand48_seed = TOUINT48(RAND48_SEED_0, (unsigned short) seed, (unsigned short) (seed >> 16)); ++ _rand48_mult = RAND48_MULT; + _rand48_add = RAND48_ADD; + } diff --git a/gen/FreeBSD/sysconf.c.patch b/gen/FreeBSD/sysconf.c.patch index 695a38e..a392a42 100644 --- a/gen/FreeBSD/sysconf.c.patch +++ b/gen/FreeBSD/sysconf.c.patch @@ -1,5 +1,5 @@ ---- sysconf.c 2004-04-15 16:50:28.000000000 -0700 -+++ /Volumes/dee/Len/Build/Libc-3845788.roots/Libc-3845788.sym/sysconf-fbsd.c 2004-11-30 18:08:26.000000000 -0800 +--- sysconf.c.orig 2007-04-03 12:19:23.000000000 -0700 ++++ sysconf.c 2007-04-05 11:33:36.000000000 -0700 @@ -45,6 +45,8 @@ #include #include @@ -9,17 +9,6 @@ #include #include -@@ -53,8 +55,8 @@ - #include - #include - --#include "../stdlib/atexit.h" --#include "../stdtime/tzfile.h" -+#include "atexit.h" -+#include "tzfile.h" - - #define _PATH_ZONEINFO TZDIR /* from tzfile.h */ - @@ -75,8 +77,9 @@ int name; { @@ -31,7 +20,7 @@ long defaultresult; const char *path; -@@ -254,76 +257,94 @@ +@@ -254,76 +257,91 @@ return (_POSIX_TIMERS); #endif case _SC_AIO_LISTIO_MAX: @@ -90,10 +79,7 @@ - mib[0] = CTL_P1003_1B; - mib[1] = CTL_P1003_1B_SEM_NSEMS_MAX; - goto yesno; -+ mib[0] = CTL_KERN; -+ mib[1] = KERN_SYSV; -+ mib[2] = KSYSV_SEMMNS; -+ return (sysctl(mib, 3, &value, &len, NULL, 0) == -1 ? -1 : value); ++ return (sysctlbyname("kern.sysv.semmns", &value, &len, NULL, 0) == -1 ? -1 : value); + case _SC_SEM_VALUE_MAX: +#if SEM_VALUE_MAX == 0 @@ -149,7 +135,7 @@ case _SC_ADVISORY_INFO: #if _POSIX_ADVISORY_INFO == 0 #error "_POSIX_ADVISORY_INFO" -@@ -348,18 +369,10 @@ +@@ -348,18 +366,12 @@ #else return (_POSIX_CPUTIME); #endif @@ -162,14 +148,16 @@ -#endif -#if _POSIX_THREAD_SAFE_FUNCTIONS > -1 case _SC_GETGR_R_SIZE_MAX: ++/* return sizeof(group) + group_name_max + group_passwd_max + max_group_member*(MAXLOGNAME+1); */ ++ return 4096; /* INT_MAX is too big for Perl */ case _SC_GETPW_R_SIZE_MAX: -#error "somebody needs to implement this" -#endif -+ return (-1); ++ return 4096; case _SC_HOST_NAME_MAX: return (MAXHOSTNAMELEN - 1); /* does not include \0 */ case _SC_LOGIN_NAME_MAX: -@@ -370,10 +383,8 @@ +@@ -370,10 +382,8 @@ #else return (_POSIX_MONOTONIC_CLOCK); #endif @@ -181,7 +169,7 @@ case _SC_READER_WRITER_LOCKS: return (_POSIX_READER_WRITER_LOCKS); case _SC_REGEXP: -@@ -410,10 +421,16 @@ +@@ -410,10 +420,16 @@ return (_POSIX_THREAD_PROCESS_SHARED); case _SC_THREAD_SAFE_FUNCTIONS: return (_POSIX_THREAD_SAFE_FUNCTIONS); @@ -198,7 +186,7 @@ case _SC_TIMEOUTS: return (_POSIX_TIMEOUTS); case _SC_THREADS: -@@ -425,16 +442,14 @@ +@@ -425,16 +441,14 @@ #else return (_POSIX_TRACE); #endif @@ -216,9 +204,12 @@ goto do_NAME_MAX; case _SC_TYPED_MEMORY_OBJECTS: #if _POSIX_TYPED_MEMORY_OBJECTS == 0 -@@ -493,9 +508,13 @@ +@@ -491,11 +505,15 @@ + return (_V6_LPBIG_OFFBIG); + #endif case _SC_ATEXIT_MAX: - return (ATEXIT_SIZE); +- return (ATEXIT_SIZE); ++ return (INT_MAX); /* unlimited */ case _SC_IOV_MAX: +#ifdef KERN_IOV_MAX mib[0] = CTL_KERN; @@ -230,7 +221,7 @@ case _SC_XOPEN_CRYPT: return (_XOPEN_CRYPT); case _SC_XOPEN_ENH_I18N: -@@ -531,7 +550,8 @@ +@@ -531,7 +549,8 @@ #endif case _SC_XOPEN_SHM: sverrno = errno; @@ -240,7 +231,7 @@ 0) == -1) { errno = sverrno; return (-1); -@@ -568,11 +588,25 @@ +@@ -568,11 +587,37 @@ return (_POSIX_IPV6); #endif @@ -263,6 +254,18 @@ + return (_XBS5_LP64_OFF64); + case _SC_XBS5_LPBIG_OFFBIG: + return (_XBS5_LPBIG_OFFBIG); ++ case _SC_SS_REPL_MAX: ++ return (_POSIX_SS_REPL_MAX); ++ case _SC_TRACE_EVENT_NAME_MAX: ++ return (_POSIX_TRACE_EVENT_NAME_MAX); ++ case _SC_TRACE_NAME_MAX: ++ return (_POSIX_TRACE_NAME_MAX); ++ case _SC_TRACE_SYS_MAX: ++ return (_POSIX_TRACE_SYS_MAX); ++ case _SC_TRACE_USER_EVENT_MAX: ++ return (_POSIX_TRACE_USER_EVENT_MAX); ++ case _SC_PASS_MAX: ++ return (PASS_MAX); default: errno = EINVAL; diff --git a/gen/FreeBSD/sysctl.3.patch b/gen/FreeBSD/sysctl.3.patch index c04f544..9f9d985 100644 --- a/gen/FreeBSD/sysctl.3.patch +++ b/gen/FreeBSD/sysctl.3.patch @@ -1,5 +1,5 @@ ---- sysctl.3.orig 2004-07-02 16:52:10.000000000 -0700 -+++ sysctl.3 2004-10-24 17:35:54.000000000 -0700 +--- sysctl.3.orig 2006-08-17 22:44:01.000000000 -0700 ++++ sysctl.3 2006-08-17 22:45:34.000000000 -0700 @@ -182,13 +182,21 @@ } .Ed @@ -33,3 +33,29 @@ .El .Pp For example, the following retrieves the maximum number of processes allowed +@@ -453,16 +462,6 @@ + .It "KERN_PROC_UID A user ID" + .It "KERN_PROC_RUID A real user ID" + .El +-.Pp +-If the third level name is KERN_PROC_ARGS then the command line argument +-array is returned in a flattened form, i.e., zero-terminated arguments +-follow each other. +-The total size of array is returned. +-It is also possible for a process to set its own process title this way. +-.Bl -column "Third level nameXXXXXX" "Fourth level is:XXXXXX" -offset indent +-.It Sy "Third level name Fourth level is:" +-.It "KERN_PROC_ARGS A process ID" +-.El + .It Li KERN_PROF + Return profiling information about the kernel. + If the kernel is not compiled for profiling, +@@ -845,7 +844,7 @@ + definitions for second level network identifiers + .It In sys/gmon.h + definitions for third level profiling identifiers +-.It In vm/vm_param.h ++.It In mach/vm_param.h + definitions for second level virtual memory identifiers + .It In netinet/in.h + definitions for third level IPv4/IPv6 identifiers and diff --git a/gen/FreeBSD/telldir.c.patch b/gen/FreeBSD/telldir.c.patch index 254dd9b..a5de764 100644 --- a/gen/FreeBSD/telldir.c.patch +++ b/gen/FreeBSD/telldir.c.patch @@ -1,5 +1,5 @@ ---- telldir.c.orig 2003-05-20 15:21:03.000000000 -0700 -+++ telldir.c 2004-11-19 17:18:44.000000000 -0800 +--- 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 @@ * cookie may be used only once before it is freed. This option * is used to avoid having memory usage grow without bound. @@ -10,7 +10,7 @@ /* * return a pointer into a directory -@@ -65,14 +67,32 @@ +@@ -65,14 +67,41 @@ { struct ddloc *lp; @@ -18,8 +18,13 @@ + if (__isthreaded) + _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { -+ if ((lp->loc_seek == dirp->dd_seek) && -+ (lp->loc_loc == dirp->dd_loc)) ++ if ( ++#if __DARWIN_64_BIT_INO_T ++ (lp->loc_seek == dirp->dd_td->seekoff) ++#else /* !__DARWIN_64_BIT_INO_T */ ++ (lp->loc_seek == dirp->dd_seek) ++#endif /* __DARWIN_64_BIT_INO_T */ ++ && (lp->loc_loc == dirp->dd_loc)) + goto found; + } + if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) { @@ -34,7 +39,11 @@ _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); +#endif /* __DARWIN_UNIX03 */ lp->loc_index = dirp->dd_td->td_loccnt++; ++#if __DARWIN_64_BIT_INO_T ++ lp->loc_seek = dirp->dd_td->seekoff; ++#else /* !__DARWIN_64_BIT_INO_T */ lp->loc_seek = dirp->dd_seek; ++#endif /* __DARWIN_64_BIT_INO_T */ lp->loc_loc = dirp->dd_loc; LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe); +#if __DARWIN_UNIX03 @@ -43,7 +52,28 @@ if (__isthreaded) _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); return (lp->loc_index); -@@ -106,13 +126,14 @@ +@@ -96,23 +125,34 @@ + } + if (lp == NULL) + return; +- if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek) ++ if (lp->loc_loc == dirp->dd_loc && ++#if __DARWIN_64_BIT_INO_T ++ lp->loc_seek == dirp->dd_td->seekoff ++#else /* !__DARWIN_64_BIT_INO_T */ ++ lp->loc_seek == dirp->dd_seek ++#endif /* __DARWIN_64_BIT_INO_T */ ++ ) + goto found; + (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET); ++#if __DARWIN_64_BIT_INO_T ++ dirp->dd_td->seekoff = lp->loc_seek; ++#else /* !__DARWIN_64_BIT_INO_T */ + dirp->dd_seek = lp->loc_seek; ++#endif /* __DARWIN_64_BIT_INO_T */ + dirp->dd_loc = 0; + while (dirp->dd_loc < lp->loc_loc) { + dp = _readdir_unlocked(dirp); if (dp == NULL) break; } @@ -59,7 +89,7 @@ /* * Reclaim memory for telldir cookies which weren't used. */ -@@ -131,3 +152,4 @@ +@@ -131,3 +171,4 @@ } LIST_INIT(&dirp->dd_td->td_locq); } diff --git a/gen/FreeBSD/telldir.h.patch b/gen/FreeBSD/telldir.h.patch index f01a6d5..6d53d68 100644 --- a/gen/FreeBSD/telldir.h.patch +++ b/gen/FreeBSD/telldir.h.patch @@ -1,11 +1,34 @@ ---- telldir.h.orig 2003-05-20 15:21:03.000000000 -0700 -+++ telldir.h 2004-11-19 17:43:13.000000000 -0800 -@@ -61,6 +61,7 @@ +--- telldir.h.orig 2007-01-24 14:10:41.000000000 -0800 ++++ telldir.h 2007-01-25 01:18:29.000000000 -0800 +@@ -46,7 +46,11 @@ + struct ddloc { + LIST_ENTRY(ddloc) loc_lqe; /* entry in list */ + long loc_index; /* key associated with structure */ ++#if __DARWIN_64_BIT_INO_T ++ __darwin_off_t loc_seek; /* returned by lseek */ ++#else /* !__DARWIN_64_BIT_INO_T */ + long loc_seek; /* magic cookie returned by getdirentries */ ++#endif /* __DARWIN_64_BIT_INO_T */ + long loc_loc; /* offset of entry in buffer */ + }; - struct dirent *_readdir_unlocked(DIR *); +@@ -57,10 +61,17 @@ + struct _telldir { + LIST_HEAD(, ddloc) td_locq; /* list of locations */ + long td_loccnt; /* index of entry for sequential readdir's */ ++#if __DARWIN_64_BIT_INO_T ++ __darwin_off_t seekoff; /* 64-bit seek offset */ ++#endif /* __DARWIN_64_BIT_INO_T */ + }; + +-struct dirent *_readdir_unlocked(DIR *); ++#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); void _reclaim_telldir(DIR *); -void _seekdir(DIR *, long); -+void _seekdir(DIR *, long) __DARWIN_ALIAS(_seekdir); -+long telldir(DIR *) __DARWIN_ALIAS(telldir); ++void _seekdir(DIR *, long) __DARWIN_ALIAS_I(_seekdir); ++long telldir(DIR *) __DARWIN_ALIAS_I(telldir); #endif diff --git a/gen/FreeBSD/termios.c.patch b/gen/FreeBSD/termios.c.patch new file mode 100644 index 0000000..16d32ef --- /dev/null +++ b/gen/FreeBSD/termios.c.patch @@ -0,0 +1,90 @@ +--- 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 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/gen/termios.c,v 1.13 2002/05/28 16:59:39 alfred Exp $"); + ++#if __DARWIN_UNIX03 ++#ifdef VARIANT_CANCELABLE ++#include ++ ++extern void _pthread_testcancel(pthread_t thread, int isconforming); ++#endif /* VARIANT_CANCELABLE */ ++#endif /* __DARWIN_UNIX03 */ ++ + #include "namespace.h" + #include + #include +@@ -48,6 +56,7 @@ + #include + #include "un-namespace.h" + ++#ifndef BUILDING_VARIANT + int + tcgetattr(fd, t) + int fd; +@@ -87,6 +96,9 @@ + { + int s; + ++ if (isatty(fd) == 0) ++ return (-1); ++ + s = pgrp; + return (_ioctl(fd, TIOCSPGRP, &s)); + } +@@ -97,6 +109,9 @@ + { + int s; + ++ if (isatty(fd) == 0) ++ return ((pid_t)-1); ++ + if (_ioctl(fd, TIOCGPGRP, &s) < 0) + return ((pid_t)-1); + +@@ -183,17 +198,24 @@ + return (-1); + return (0); + } ++#endif /* BUILDING_VARIANT */ + + int + __tcdrain(fd) + int fd; + { ++#if __DARWIN_UNIX03 ++#ifdef VARIANT_CANCELABLE ++ _pthread_testcancel(pthread_self(), 1); ++#endif /* VARIANT_CANCELABLE */ ++#endif /* __DARWIN_UNIX03 */ + return (_ioctl(fd, TIOCDRAIN, 0)); + } + + __weak_reference(__tcdrain, tcdrain); + __weak_reference(__tcdrain, _tcdrain); + ++#ifndef BUILDING_VARIANT + int + tcflush(fd, which) + int fd, which; +@@ -230,16 +252,13 @@ + case TCOON: + return (_ioctl(fd, TIOCSTART, 0)); + case TCION: ++ return (_ioctl(fd, TIOCIXON, 0)); + case TCIOFF: +- if (tcgetattr(fd, &term) == -1) +- return (-1); +- c = term.c_cc[action == TCIOFF ? VSTOP : VSTART]; +- if (c != _POSIX_VDISABLE && _write(fd, &c, sizeof(c)) == -1) +- return (-1); +- return (0); ++ return (_ioctl(fd, TIOCIXOFF, 0)); + default: + errno = EINVAL; + return (-1); + } + /* NOTREACHED */ + } ++#endif /* BUILDING_VARIANT */ diff --git a/gen/FreeBSD/time.c.patch b/gen/FreeBSD/time.c.patch new file mode 100644 index 0000000..6433f6f --- /dev/null +++ b/gen/FreeBSD/time.c.patch @@ -0,0 +1,26 @@ +--- time.c.orig 2004-11-25 11:38:01.000000000 -0800 ++++ time.c 2005-03-24 14:09:30.000000000 -0800 +@@ -39,6 +39,7 @@ + + #include + #include ++#include + + time_t + time(t) +@@ -46,12 +47,15 @@ + { + struct timeval tt; + time_t retval; ++ fenv_t fenv; + ++ fegetenv(&fenv); /* 3965505 - need to preserve floating point enviroment */ + if (gettimeofday(&tt, (struct timezone *)0) < 0) + retval = -1; + else + retval = tt.tv_sec; + if (t != NULL) + *t = retval; ++ fesetenv(&fenv); + return (retval); + } diff --git a/gen/FreeBSD/times.3.patch b/gen/FreeBSD/times.3.patch new file mode 100644 index 0000000..619223e --- /dev/null +++ b/gen/FreeBSD/times.3.patch @@ -0,0 +1,22 @@ +--- _SB/Libc/gen/FreeBSD/times.3 2003-05-20 15:21:03.000000000 -0700 ++++ _SB/Libc/gen/FreeBSD/times.3.edit 2006-06-28 16:55:51.000000000 -0700 +@@ -43,7 +43,9 @@ + .Sh SYNOPSIS + .In sys/times.h + .Ft clock_t +-.Fn times "struct tms *tp" ++.Fo times ++.Fa "struct tms *buffer" ++.Fc + .Sh DESCRIPTION + .Bf -symbolic + This interface is obsoleted by +@@ -61,7 +63,7 @@ + Time. + .Pp + It also fills in the structure pointed to by +-.Fa tp ++.Fa buffer + with time-accounting information. + .Pp + The diff --git a/gen/FreeBSD/ttyname.3.patch b/gen/FreeBSD/ttyname.3.patch new file mode 100644 index 0000000..16e368b --- /dev/null +++ b/gen/FreeBSD/ttyname.3.patch @@ -0,0 +1,72 @@ +--- _SB/Libc/gen/FreeBSD/ttyname.3 2003-05-20 15:21:03.000000000 -0700 ++++ _SB/Libc/gen/FreeBSD/ttyname.3.edit 2006-06-28 16:55:51.000000000 -0700 +@@ -36,20 +36,26 @@ + .Dt TTYNAME 3 + .Os + .Sh NAME +-.Nm ttyname , + .Nm isatty , ++.Nm ttyname , + .Nm ttyslot + .Nd get name of associated terminal (tty) from file descriptor + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In unistd.h +-.Ft char * +-.Fn ttyname "int fd" + .Ft int +-.Fn isatty "int fd" ++.Fo isatty ++.Fa "int fildes" ++.Fc ++.Ft char * ++.Fo ttyname ++.Fa "int fildes" ++.Fc + .Ft int +-.Fn ttyslot void ++.Fo ttyslot ++.Fa void ++.Fc + .Sh DESCRIPTION + These functions operate on the system file descriptors for terminal + type devices. +@@ -70,7 +76,7 @@ + .Fn isatty + function + determines if the file descriptor +-.Fa fd ++.Fa fildes + refers to a valid + terminal type device. + .Pp +@@ -80,7 +86,7 @@ + gets the related device name of + a file descriptor for which + .Fn isatty +-is true ++is true. + .Pp + The + .Fn ttyslot +@@ -94,16 +100,14 @@ + function + returns the null terminated name if the device is found and + .Fn isatty +-is true; otherwise +-a ++is true; otherwise, a + .Dv NULL + pointer is returned. + .Pp + The + .Fn ttyslot +-function +-returns the unit number of the device file if found; otherwise +-the value zero is returned. ++function returns the unit number of the device file if found; ++otherwise, the value zero is returned. + .Sh FILES + .Bl -tag -width /etc/ttys -compact + .It Pa /dev/\(** diff --git a/gen/FreeBSD/ttyname.c.patch b/gen/FreeBSD/ttyname.c.patch index 4a7d2e9..e9a5571 100644 --- a/gen/FreeBSD/ttyname.c.patch +++ b/gen/FreeBSD/ttyname.c.patch @@ -1,17 +1,10 @@ -Index: ttyname.c -=================================================================== -RCS file: /cvs/root/Libc/gen/FreeBSD/ttyname.c,v -retrieving revision 1.3 -diff -u -d -b -w -p -u -r1.3 ttyname.c ---- ttyname.c 2004/11/25 19:38:02 1.3 -+++ ttyname.c 2004/12/12 03:51:44 -@@ -48,10 +48,14 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/tty +--- ttyname.c.orig 2007-02-05 14:38:48.000000000 -0800 ++++ ttyname.c 2007-02-05 14:40:13.000000000 -0800 +@@ -48,10 +48,12 @@ #include #include #include -+#if __DARWIN_UNIX03 +#include -+#endif /* __DARWIN_UNIX03 */ #include "un-namespace.h" #include "libc_private.h" @@ -20,7 +13,15 @@ diff -u -d -b -w -p -u -r1.3 ttyname.c static char buf[sizeof(_PATH_DEV) + MAXNAMLEN]; static char *ttyname_threaded(int fd); static char *ttyname_unthreaded(int fd); -@@ -71,31 +75,54 @@ ttyname(int fd) +@@ -59,6 +61,7 @@ + static pthread_mutex_t ttyname_lock = PTHREAD_MUTEX_INITIALIZER; + static pthread_key_t ttyname_key; + static int ttyname_init = 0; ++extern int __pthread_tsd_first; + + char * + ttyname(int fd) +@@ -71,31 +74,63 @@ ret = ttyname_threaded(fd); return (ret); } @@ -36,9 +37,9 @@ diff -u -d -b -w -p -u -r1.3 ttyname.c { struct stat sb; - char *rval; - -- rval = NULL; - +- rval = NULL; + +#if __DARWIN_UNIX03 + if (_fstat(fd, &sb) < 0) + return (EBADF); @@ -47,23 +48,30 @@ diff -u -d -b -w -p -u -r1.3 ttyname.c - return (rval); + return (ENOTTY); /* Must be a character device. */ +- if (_fstat(fd, &sb) || !S_ISCHR(sb.st_mode)) +- return (rval); + if (!S_ISCHR(sb.st_mode)) + return (ENOTTY); -+ /* Must have enough room */ -+ if (len <= sizeof(_PATH_DEV)) + /* Must have enough room */ + if (len <= sizeof(_PATH_DEV)) +- return (rval); + return (ERANGE); +#else /* !__DARWIN_UNIX03 */ + /* Must be a terminal. */ + if (!isatty(fd)) + return (NULL); + /* Must be a character device. */ - if (_fstat(fd, &sb) || !S_ISCHR(sb.st_mode)) -- return (rval); ++ if (_fstat(fd, &sb)) + return (NULL); - /* Must have enough room */ - if (len <= sizeof(_PATH_DEV)) -- return (rval); ++ if (!S_ISCHR(sb.st_mode)) { ++ errno = ENOTTY; + return (NULL); ++ } ++ /* Must have enough room */ ++ if (len <= sizeof(_PATH_DEV)) { ++ errno = ERANGE; ++ return (NULL); ++ } +#endif /* __DARWIN_UNIX03 */ - strcpy(buf, _PATH_DEV); @@ -77,7 +85,10 @@ diff -u -d -b -w -p -u -r1.3 ttyname.c + return (ERANGE); + return (0); +#else /* !__DARWIN_UNIX03 */ ++ { ++ errno = ERANGE; + return (NULL); ++ } + return (thrbuf); +#endif /* __DARWIN_UNIX03 */ } @@ -86,7 +97,30 @@ diff -u -d -b -w -p -u -r1.3 ttyname.c static char * ttyname_threaded(int fd) { -@@ -124,7 +151,11 @@ ttyname_threaded(int fd) +@@ -104,8 +139,12 @@ + if (ttyname_init == 0) { + _pthread_mutex_lock(&ttyname_lock); + if (ttyname_init == 0) { +- if (_pthread_key_create(&ttyname_key, free)) { ++ /* __PTK_LIBC_TTYNAME_KEY */ ++ ttyname_key = __pthread_tsd_first+1; ++ if (pthread_key_init_np(ttyname_key, free)) { ++ int save = errno; + _pthread_mutex_unlock(&ttyname_lock); ++ errno = save; + return (NULL); + } + ttyname_init = 1; +@@ -117,14 +156,20 @@ + if ((buf = _pthread_getspecific(ttyname_key)) == NULL) { + if ((buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) { + if (_pthread_setspecific(ttyname_key, buf) != 0) { ++ int save = errno; + free(buf); ++ errno = save; + return (NULL); + } + } else { return (NULL); } } @@ -98,15 +132,26 @@ diff -u -d -b -w -p -u -r1.3 ttyname.c } static char * -@@ -141,7 +172,9 @@ ttyname_unthreaded(int fd) +@@ -137,11 +182,19 @@ + 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); ++ if (!S_ISCHR(sb.st_mode)) { ++ errno = ENOTTY; ++ return (NULL); ++ } strcpy(buf, _PATH_DEV); - devname_r(sb.st_rdev, S_IFCHR, - buf + strlen(buf), sizeof(buf) - strlen(buf)); + if (devname_r(sb.st_rdev, S_IFCHR, -+ buf + strlen(buf), sizeof(buf) - strlen(buf)) == NULL) ++ buf + strlen(buf), sizeof(buf) - strlen(buf)) == NULL) { ++ errno = ERANGE; + return (NULL); ++ } return (buf); } +#endif /* !BUILDING_VARIANT */ diff --git a/gen/FreeBSD/ualarm.3.patch b/gen/FreeBSD/ualarm.3.patch new file mode 100644 index 0000000..b09aacd --- /dev/null +++ b/gen/FreeBSD/ualarm.3.patch @@ -0,0 +1,47 @@ +--- _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 @@ + .Sh SYNOPSIS + .In unistd.h + .Ft useconds_t +-.Fn ualarm "useconds_t microseconds" "useconds_t interval" ++.Fo ualarm ++.Fa "useconds_t useconds" ++.Fa "useconds_t interval" ++.Fc + .Sh DESCRIPTION + .Bf -symbolic + This is a simplified interface to +@@ -54,7 +57,7 @@ + .Fn ualarm + function + waits a count of +-.Fa microseconds ++.Fa useconds + before asserting the terminating signal + .Dv SIGALRM . + System activity or time used in processing the call may cause a slight +@@ -67,17 +70,17 @@ + signal will be sent + to the process every + .Fa interval +-microseconds after the timer expires (e.g.\& after +-.Fa microseconds ++microseconds after the timer expires (e.g., after ++.Fa useconds + number of microseconds have passed). + .Pp +-Due to ++Due to a + .Xr setitimer 2 +-restriction the maximum number of +-.Fa microseconds ++restriction, the maximum number of ++.Fa useconds + and + .Fa interval +-is limited to 100000000000000 ++is limited to 100,000,000,000,000 + (in case this value fits in the unsigned integer). + .Sh RETURN VALUES + When the signal has successfully been caught, diff --git a/gen/FreeBSD/ucontext.3 b/gen/FreeBSD/ucontext.3 new file mode 100644 index 0000000..86210de --- /dev/null +++ b/gen/FreeBSD/ucontext.3 @@ -0,0 +1,107 @@ +.\" Copyright (c) 2002 Packet Design, LLC. +.\" All rights reserved. +.\" +.\" Subject to the following obligations and disclaimer of warranty, +.\" use and redistribution of this software, in source or object code +.\" forms, with or without modifications are expressly permitted by +.\" Packet Design; provided, however, that: +.\" +.\" (i) Any and all reproductions of the source or object code +.\" must include the copyright notice above and the following +.\" disclaimer of warranties; and +.\" (ii) No rights are granted, in any manner or form, to use +.\" Packet Design trademarks, including the mark "PACKET DESIGN" +.\" on advertising, endorsements, or otherwise except as such +.\" appears in the above copyright notice or in the software. +.\" +.\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND +.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO +.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING +.\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED +.\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, +.\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE, +.\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS +.\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, +.\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE +.\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE +.\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL +.\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF +.\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 PACKET DESIGN IS ADVISED OF +.\" THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD: src/lib/libc/gen/ucontext.3,v 1.3 2004/07/03 22:30:08 ru Exp $ +.\" +.Dd September 10, 2002 +.Dt UCONTEXT 3 +.Os +.Sh NAME +.Nm ucontext +.Nd user thread context +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ucontext.h +.Sh DESCRIPTION +The +.Vt ucontext_t +type is a structure type suitable for holding the context for a user +thread of execution. +A thread's context includes its stack, saved registers, and list of +blocked signals. +.Pp +The +.Vt ucontext_t +structure contains at least these fields: +.Pp +.Bl -tag -width ".Va mcontext_t\ \ uc_mcontext" -offset 3n -compact +.It Va "ucontext_t *uc_link" +context to assume when this one returns +.It Va "sigset_t uc_sigmask" +signals being blocked +.It Va "stack_t uc_stack" +stack area +.It Va "mcontext_t uc_mcontext" +saved registers +.El +.Pp +The +.Va uc_link +field points to the context to resume when this context's entry point +function returns. +If +.Va uc_link +is equal to +.Dv NULL , +then the process exits when this context returns. +.Pp +The +.Va uc_mcontext +field is machine-dependent and should be treated as opaque by +portable applications. +.Pp +The following functions are defined to manipulate +.Vt ucontext_t +structures: +.Pp +.Bl -item -offset 3n -compact +.It +.Ft int +.Fn getcontext "ucontext_t *" ; +.It +.Ft int +.Fn setcontext "const ucontext_t *" ; +.It +.Ft void +.Fn makecontext "ucontext_t *" "void \*[lp]*\*[rp]\*[lp]void\*[rp]" int ... ; +.It +.Ft int +.Fn swapcontext "ucontext_t *" "const ucontext_t *" ; +.El +.Sh SEE ALSO +.Xr sigaltstack 2 , +.Xr getcontext 3 , +.Xr makecontext 3 diff --git a/gen/FreeBSD/ulimit.3.patch b/gen/FreeBSD/ulimit.3.patch new file mode 100644 index 0000000..effba16 --- /dev/null +++ b/gen/FreeBSD/ulimit.3.patch @@ -0,0 +1,40 @@ +--- _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 +@@ -34,28 +34,31 @@ + .Sh SYNOPSIS + .In ulimit.h + .Ft long +-.Fn ulimit "int cmd" "..." ++.Fo ulimit ++.Fa "int cmd" ++.Fa "..." ++.Fc + .Sh DESCRIPTION + The + .Fn ulimit + function will get and set process limits. +-Currently this is limited to the maximum file size. ++Currently, this is limited to the maximum file size. + The + .Fa cmd + argument is one of the following: + .Bl -tag -width ".Dv UL_GETFSIZE" + .It Dv UL_GETFSIZE +-will return the maximum file size in units of 512 blocks of +-the current process. ++will return the maximum file size of the current process, ++in units of 512-byte blocks. + .It Dv UL_SETFSIZE + will attempt to set the maximum file size of the current +-process and its children with the second argument expressed as a long. ++process and its children, using the second argument (expressed as a long). + .El + .Sh RETURN VALUES + Upon successful completion, + .Fn ulimit + returns the value requested; +-otherwise the value \-1 is returned and the global variable ++otherwise, the value \-1 is returned and the global variable + .Va errno + is set to indicate the error. + .Sh ERRORS diff --git a/gen/FreeBSD/usleep.3.patch b/gen/FreeBSD/usleep.3.patch index 2a8a214..470d185 100644 --- a/gen/FreeBSD/usleep.3.patch +++ b/gen/FreeBSD/usleep.3.patch @@ -1,6 +1,6 @@ ---- /Volumes/XDisk/tmp/Libc/gen/FreeBSD/usleep.3.orig 2002-12-28 16:59:09.000000000 -0800 -+++ /Volumes/XDisk/tmp/Libc/gen/FreeBSD/usleep.3 2004-10-24 17:08:28.000000000 -0700 -@@ -37,7 +37,7 @@ +--- _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 @@ .Os .Sh NAME .Nm usleep @@ -9,21 +9,41 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -@@ -47,12 +47,13 @@ + .In unistd.h + .Ft int +-.Fn usleep "useconds_t microseconds" ++.Fo usleep ++.Fa "useconds_t useconds" ++.Fc .Sh DESCRIPTION The .Fn usleep -function suspends execution of the calling process until either -+function suspends execution of the calling thread until either - .Fa microseconds +-.Fa microseconds -microseconds have elapsed or a signal is delivered to the process and its -+microseconds have elapsed or a signal is delivered to the thread and its - action is to invoke a signal-catching function or to terminate the +-action is to invoke a signal-catching function or to terminate the -process. -System activity may lengthen the sleep by an indeterminate amount. -+thread or process. ++function suspends execution of the calling thread until either ++.Fa useconds ++microseconds have elapsed ++or a signal is delivered to the thread whose action ++is to invoke a signal-catching function ++or to terminate the thread or process. +The actual time slept may be longer, due to system latencies +and possible limitations in the timer resolution of the hardware. .Pp - This function is implemented using - .Xr nanosleep 2 +-This function is implemented using +-.Xr nanosleep 2 ++This function is implemented, using ++.Xr nanosleep 2 , + by pausing for +-.Fa microseconds ++.Fa useconds + microseconds or until a signal occurs. + Consequently, in this implementation, +-sleeping has no effect on the state of process timers, ++sleeping has no effect on the state of process timers + and there is no special handling for SIGALRM. + .Sh RETURN VALUES + .Rv -std usleep diff --git a/gen/FreeBSD/usleep.c.patch b/gen/FreeBSD/usleep.c.patch new file mode 100644 index 0000000..5957746 --- /dev/null +++ b/gen/FreeBSD/usleep.c.patch @@ -0,0 +1,14 @@ +--- 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 @@ + * SUCH DAMAGE. + */ + ++#ifdef VARIANT_CANCELABLE ++#undef __DARWIN_NON_CANCELABLE ++#define __DARWIN_NON_CANCELABLE 0 ++#endif /* VARIANT_CANCELABLE */ ++ + #if defined(LIBC_SCCS) && !defined(lint) + static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; + #endif /* LIBC_SCCS and not lint */ diff --git a/gen/FreeBSD/utime.3.patch b/gen/FreeBSD/utime.3.patch new file mode 100644 index 0000000..c9de60f --- /dev/null +++ b/gen/FreeBSD/utime.3.patch @@ -0,0 +1,46 @@ +--- _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 @@ + .Sh SYNOPSIS + .In utime.h + .Ft int +-.Fn utime "const char *file" "const struct utimbuf *timep" ++.Fo utime ++.Fa "const char *path" ++.Fa "const struct utimbuf *times" ++.Fc + .Sh DESCRIPTION + .Bf -symbolic + This interface is obsoleted by +@@ -52,22 +55,22 @@ + .Pp + The + .Fn utime +-function sets the access and modification times of the named file from +-the structures in the argument array +-.Fa timep . ++function sets the access and modification times of the named file, ++based on the structures in the argument array ++.Fa times . + .Pp + If the times are specified (the +-.Fa timep ++.Fa times + argument is +-.Pf non- Dv NULL ) ++.Pf non- Dv NULL ) , + the caller must be the owner of the file or be the super-user. + .Pp + If the times are not specified (the +-.Fa timep ++.Fa times + argument is +-.Dv NULL ) +-the caller must be the owner of the file, have permission to write +-the file, or be the super-user. ++.Dv NULL ) , ++the caller must be the owner of the file, ++have permission to write the file, or be the super-user. + .Sh ERRORS + The + .Fn utime diff --git a/gen/FreeBSD/wait.c.patch b/gen/FreeBSD/wait.c.patch new file mode 100644 index 0000000..23446fb --- /dev/null +++ b/gen/FreeBSD/wait.c.patch @@ -0,0 +1,24 @@ +--- 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 @@ + #include + #include "un-namespace.h" + ++#ifdef VARIANT_CANCELABLE ++int __wait4(pid_t, int *, int , struct rusage *); ++#else /* !VARIANT_CANCELABLE */ ++int __wait4_nocancel(pid_t, int *, int , struct rusage *); ++#endif /* VARIANT_CANCELABLE */ ++ + pid_t + __wait(int *istat) + { +- return (_wait4(WAIT_ANY, istat, 0, (struct rusage *)0)); ++#ifdef VARIANT_CANCELABLE ++ return (__wait4(WAIT_ANY, istat, 0, (struct rusage *)0)); ++#else /* !VARIANT_CANCELABLE */ ++ return (__wait4_nocancel(WAIT_ANY, istat, 0, (struct rusage *)0)); ++#endif /* VARIANT_CANCELABLE */ + } + + __weak_reference(__wait, wait); diff --git a/gen/FreeBSD/waitpid.c.patch b/gen/FreeBSD/waitpid.c.patch new file mode 100644 index 0000000..7129f8d --- /dev/null +++ b/gen/FreeBSD/waitpid.c.patch @@ -0,0 +1,35 @@ +--- 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 @@ + #include + #include "un-namespace.h" + ++#if __DARWIN_UNIX03 ++#include ++#endif /* __DARWIN_UNIX03 */ ++#ifdef VARIANT_CANCELABLE ++int __wait4(pid_t, int *, int , struct rusage *); ++#else /* !VARIANT_CANCELABLE */ ++int __wait4_nocancel(pid_t, int *, int , struct rusage *); ++#endif /* VARIANT_CANCELABLE */ ++ + pid_t + __waitpid(pid_t pid, int *istat, int options) + { +- return (_wait4(pid, istat, options, (struct rusage *)0)); ++#if __DARWIN_UNIX03 ++ /* POSIX: Validate waitpid() options before calling wait4() */ ++ if ((options & (WCONTINUED | WNOHANG | WUNTRACED)) != options) { ++ errno = EINVAL; ++ return ((pid_t)-1); ++ } ++#endif /* __DARWIN_UNIX03 */ ++ ++#ifdef VARIANT_CANCELABLE ++ return (__wait4(pid, istat, options, (struct rusage *)0)); ++#else /* !VARIANT_CANCELABLE */ ++ return (__wait4_nocancel(pid, istat, options, (struct rusage *)0)); ++#endif /* VARIANT_CANCELABLE */ + } + + __weak_reference(__waitpid, waitpid); diff --git a/gen/Makefile.inc b/gen/Makefile.inc index a3b7f89..cfa4911 100644 --- a/gen/Makefile.inc +++ b/gen/Makefile.inc @@ -1,33 +1,56 @@ # @(#)Makefile.inc 8.6 (Berkeley) 5/4/95 # $FreeBSD: src/lib/libc/gen/Makefile.inc,v 1.80 2001/08/17 22:09:15 dd Exp $ +.ifnmake autopatch # machine-dependent gen sources .if exists(${.CURDIR}/${MACHINE_ARCH}/gen/Makefile.inc) .include "${.CURDIR}/${MACHINE_ARCH}/gen/Makefile.inc" .endif +.endif # !autopatch # machine-independent gen sources .PATH: ${.CURDIR}/gen -CFLAGS += -I${.CURDIR}/pthreads +CFLAGS += -I${.CURDIR}/gen -MISRCS += NSSystemDirectories.c OSSystemInfo.c arc4random.c asl.c \ +GENMIGDEFS += asl_ipc.defs +GENMIGHDRS += ${GENMIGDEFS:.defs=.h} +GENMIGSRCS += ${GENMIGDEFS:.defs=User.c} + +MISRCS += ${GENMIGSRCS} NSSystemDirectories.c OSSystemInfo.c \ + asl.c asl_util.c \ + backtrace.c \ cache.c confstr.c crypt.c devname.c disklabel.c errlst.c \ filesec.c fts.c \ get_compat.c getloadavg.c getttyent.c getusershell.c getvfsbyname.c \ isinf.c isnan.c \ malloc.c nanosleep.c nftw.c nlist.c scalable_malloc.c setlogin.c \ - sigsetops.c simple_dprintf.c stack_logging.c strtofflags.c syslog.c \ - uname.c wordexp.c zone.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 zone.c + +# Force these files to build after the mig stuff +asl.So asl.po asl.do asl.o: asl_ipcUser.c +utmpx-darwin.So utmpx-darwin.po utmpx-darwin.do utmpx-darwin.o: asl_ipcUser.c + +CLEANFILES += ${GENMIGHDRS} ${GENMIGSRCS} ${GENMIGDEFS:.defs=Server.c} + +PRECFLAGS-asl.c = -I${OBJROOT} +LOCALHDRS += ${.CURDIR}/gen/asl_private.h ${.CURDIR}/gen/_simple.h ${.CURDIR}/gen/stack_logging.h + +CFLAGS-confstr.c += -I${.CURDIR}/darwin -CFLAGS-asl.c = -I${.CURDIR}/gen -LOCALHDRS += ${.CURDIR}/gen/asl_private.h +CFLAGS-glob-fbsd.c += -UDEBUG + +# 4840357: workaround for compiler failure building libc_debug.a +.if make(lib${LIB}_debug.a) +CFLAGS-scalable_malloc.c += -funit-at-a-time +.endif # also build 64-bit long double versions (ppc only) LDBLSRCS += asl.c err.c syslog.c .include "Makefile.fbsd_begin" -FBSDMISRCS = _rand48.c alarm.c assert.c \ +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 \ fmtcheck.c fmtmsg.c fnmatch.c ftok.c \ @@ -42,8 +65,23 @@ FBSDMISRCS = _rand48.c alarm.c assert.c \ telldir.c termios.c time.c times.c \ ttyname.c ttyslot.c ualarm.c ulimit.c unvis.c usleep.c utime.c vis.c \ wait.c wait3.c waitpid.c -.ifndef LP64 -FBSDMISRCS += timezone.c + +# special case: getmntinfo64-fbsd.c is derived from getmntinfo.c with getmntinfo64.c.patch +.ifmake autopatch +AUTOPATCHSRCS+= getmntinfo64-fbsd.c +getmntinfo64-fbsd.c: FreeBSD/getmntinfo.c + cp ${.ALLSRC} ${.TARGET} + patch ${.TARGET} ${.ALLSRC:S/getmntinfo/getmntinfo64/}.patch +.else # !autopatch +MISRCS+= getmntinfo64.c +.endif # autopatch + +PRE1050SRCS+= daemon.c +.ifdef LP64 +PRE1050SRCS+= pselect.c +.else # !LP64 +# only patch timezone.c; don't build in base variant, but in other variants +FBSDPATCHSRCS += timezone.c .endif FBSDHDRS = rand48.h telldir.h .include "Makefile.fbsd_end" @@ -51,127 +89,306 @@ FBSDHDRS = rand48.h telldir.h .include "Makefile.nbsd_begin" NBSDMISRCS = utmpx.c .include "Makefile.nbsd_end" -CFLAGS-utmpx-nbsd.c += -DUTMP_COMPAT # private header files -INSTHDRS += ${.CURDIR}/gen/get_compat.h +INSTHDRS += ${.CURDIR}/gen/get_compat.h \ + ${.CURDIR}/gen/execinfo.h PRIV_INSTHDRS += ${.CURDIR}/gen/stack_logging.h -UNIX03SRCS += closedir.c crypt.c nanosleep.c nftw.c opendir.c rewinddir.c \ - seekdir.c telldir.c ttyname.c +LEGACYSRCS += clock.c closedir.c confstr.c crypt.c fnmatch.c \ + lockf.c nanosleep.c nftw.c nice.c opendir.c \ + pause.c pselect.c rewinddir.c \ + seekdir.c sleep.c telldir.c termios.c timezone.c ttyname.c \ + usleep.c wait.c waitpid.c +INODE32SRCS += fts.c getmntinfo.c glob.c nftw.c opendir.c \ + readdir.c rewinddir.c scandir.c seekdir.c telldir.c +CANCELABLESRCS += lockf.c nanosleep.c pause.c pselect.c sleep.c termios.c \ + usleep.c wait.c waitpid.c +CANCELABLE-DARWINEXTSNSRCS += pselect.c +DARWINEXTSNSRCS += pselect.c + +# include __dirent.h to rename DIR structure elements +.for _src in closedir-fbsd.c opendir-fbsd.c readdir-fbsd.c rewinddir-fbsd.c \ + scandir-fbsd.c seekdir-fbsd.c telldir-fbsd.c +CFLAGS-${_src} += -I${.CURDIR}/gen -include __dirent.h +.endfor + +# ppc optimizer hacks: +#drand48-fbsd.c is better with -O1 than -Os. +#erand48-fbsd.c is better with -O3 than -Os. +.if !make(lib${LIB}_debug.a) +.if (${MACHINE_ARCH} == ppc) +OPTIMIZE-drand48-fbsd.c += -O1 +OPTIMIZE-erand48-fbsd.c += -O3 +.endif +.endif + +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +CFLAGS-clock-fbsd.c += -DLIBC_ALIAS_CLOCK +CFLAGS-closedir-fbsd.c += -DLIBC_ALIAS_CLOSEDIR +CFLAGS-confstr.c += -DLIBC_ALIAS_CONFSTR +CFLAGS-crypt.c += -DLIBC_ALIAS_ENCRYPT -DLIBC_ALIAS_SETKEY +CFLAGS-fnmatch-fbsd.c += -DLIBC_ALIAS_FNMATCH +CFLAGS-fts.c += -DLIBC_ALIAS_FTS_CHILDREN -DLIBC_ALIAS_FTS_CLOSE -DLIBC_ALIAS_FTS_OPEN -DLIBC_ALIAS_FTS_READ -DLIBC_ALIAS_FTS_SET +CFLAGS-glob-fbsd.c += -DLIBC_ALIAS_GLOB +CFLAGS-lockf-fbsd.c += -DLIBC_ALIAS_LOCKF +CFLAGS-nanosleep.c += -DLIBC_ALIAS_NANOSLEEP +CFLAGS-nftw.c += -DLIBC_ALIAS_FTW -DLIBC_ALIAS_NFTW +CFLAGS-nice-fbsd.c += -DLIBC_ALIAS_NICE +CFLAGS-opendir-fbsd.c += -DLIBC_ALIAS___OPENDIR2 -DLIBC_ALIAS_OPENDIR +CFLAGS-rewinddir-fbsd.c += -DLIBC_ALIAS_REWINDDIR +CFLAGS-pause-fbsd.c += -DLIBC_ALIAS_PAUSE +CFLAGS-seekdir-fbsd.c += -DLIBC_ALIAS_SEEKDIR +CFLAGS-sleep-fbsd.c += -DLIBC_ALIAS_SLEEP +CFLAGS-telldir-fbsd.c += -DLIBC_ALIAS__SEEKDIR -DLIBC_ALIAS_TELLDIR +CFLAGS-termios-fbsd.c += -DLIBC_ALIAS_TCDRAIN +CFLAGS-ttyname-fbsd.c += -DLIBC_ALIAS_TTYNAME_R +CFLAGS-usleep-fbsd.c += -DLIBC_ALIAS_USLEEP +CFLAGS-wait-fbsd.c += -DLIBC_ALIAS_WAIT +CFLAGS-waitpid-fbsd.c += -DLIBC_ALIAS_WAITPID .if ${LIB} == "c" -MAN3 += arc4random.3 asl.3 confstr.3 crypt.3 devname.3 directory.3 fts.3 ftw.3 \ - getdomainname.3 getfsent.3 getgrent.3 getgrouplist.3 getloadavg.3 \ - getnetgrent.3 getobjformat.3 getpwent.3 getttyent.3 \ - getusershell.3 getvfsbyname.3 initgroups.3 \ - malloc.3 nlist.3 pwcache.3 setjmp.3 sigsetops.3 \ - strtofflags.3 syslog.3 tcgetpgrp.3 tcsendbreak.3 \ - tcsetattr.3 tcsetpgrp.3 tzset.3 uname.3 valloc.3 wordexp.3 intro.3 +MAN3 += asl.3 \ + backtrace.3 \ + confstr.3 crypt.3 devname.3 directory.3 fts.3 ftw.3 \ + getdomainname.3 getloadavg.3 \ + getttyent.3 getusershell.3 getvfsbyname.3 \ + malloc.3 malloc_size.3 nlist.3 \ + pwcache.3 setjmp.3 sigsetops.3 strtofflags.3 syslog.3 \ + tcgetpgrp.3 tcsendbreak.3 tcsetattr.3 tcsetpgrp.3 tzset.3 \ + uname.3 wordexp.3 intro.3 MAN5 += compat.5 .include "Makefile.fbsd_begin" -FBSDMAN3= alarm.3 basename.3 clock.3 ctermid.3 daemon.3 dirname.3 err.3 exec.3 \ - fmtcheck.3 fmtmsg.3 fnmatch.3 fpclassify.3 ftok.3 \ - getbsize.3 getcap.3 getcwd.3 \ +FBSDMAN3= alarm.3 arc4random.3 basename.3 clock.3 ctermid.3 \ + daemon.3 dirname.3 err.3 exec.3 \ + fmtcheck.3 fmtmsg.3 fnmatch.3 ftok.3 \ + getbsize.3 getcap.3 getcontext.3 getcwd.3 \ gethostname.3 getmntinfo.3 getpagesize.3 getpass.3 \ - getpeereid.3 getprogname.3 \ - glob.3 isgreater.3 \ - lockf.3 nice.3 pause.3 popen.3 pselect.3 psignal.3 raise.3 rand48.3 \ - readpassphrase.3 scandir.3 setmode.3 \ + getpeereid.3 getprogname.3 glob.3 \ + isgreater.3 lockf.3 makecontext.3 nice.3 \ + pause.3 popen.3 pselect.3 psignal.3 \ + raise.3 rand48.3 readpassphrase.3 \ + scandir.3 setmode.3 \ siginterrupt.3 signal.3 signbit.3 sleep.3 \ stringlist.3 sysconf.3 sysctl.3 \ - time.3 times.3 timezone.3 ttyname.3 ualarm.3 \ - ulimit.3 unvis.3 usleep.3 utime.3 vis.3 + time.3 times.3 timezone.3 ttyname.3 \ + ualarm.3 ucontext.3 ulimit.3 unvis.3 usleep.3 utime.3 \ + vis.3 .include "Makefile.fbsd_end" .include "Makefile.nbsd_begin" -NBSDMAN3= endutxent.3 +NBSDMAN3= endutxent.3 getlastlogx.3 +NBSDMAN5= utmpx.5 .include "Makefile.nbsd_end" -MLINKS+=arc4random.3 arc4random_addrandom.3 arc4random.3 arc4random_stir.3 -MLINKS+=asl.3 asl_open.3 asl.3 asl_close.3 asl.3 asl_new.3 asl.3 asl_free.3 \ - asl.3 asl_set.3 asl.3 asl_set_query.3 asl.3 asl_get.3 asl.3 asl_unset.3 \ - asl.3 asl_log.3 asl.3 asl_vlog.3 asl.3 asl_send.3 asl.3 asl_key.3 \ - asl.3 asl_add_log_file.3 asl.3 asl_remove_log_file.3 \ - asl.3 asl_set_cutoff_level.3 asl.3 asl_search.3 asl.3 aslresponse_next.3 \ - asl.3 aslresponse_free.3 -MLINKS+=ctermid.3 ctermid_r.3 -MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3 crypt.3 des_setkey.3 \ - crypt.3 des_cipher.3 -MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \ - directory.3 readdir.3 directory.3 readdir_r.3 directory.3 rewinddir.3 \ - directory.3 seekdir.3 directory.3 telldir.3 -MLINKS+=endutxent.3 getutxent.3 endutxent.3 getutxid.3 \ - endutxent.3 getutxline.3 endutxent.3 pututxline.3 \ - endutxent.3 setutxent.3 -MLINKS+=err.3 err_set_exit.3 err.3 err_set_file.3 err.3 errc.3 err.3 errx.3 \ - err.3 verr.3 err.3 verrc.3 err.3 verrx.3 err.3 vwarn.3 err.3 vwarnc.3 \ - err.3 vwarnx.3 err.3 warnc.3 err.3 warn.3 err.3 warnx.3 -MLINKS+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 \ - exec.3 execv.3 exec.3 execvp.3 -MLINKS+=fpclassify.3 isfinite.3 fpclassify.3 isinf.3 fpclassify.3 isnan.3 \ - fpclassify.3 isnormal.3 -MLINKS+=fts.3 fts_children.3 fts.3 fts_close.3 fts.3 fts_open.3 \ - fts.3 fts_read.3 fts.3 fts_set.3 -MLINKS+=ftw.3 nftw.3 -MLINKS+=getcap.3 cgetcap.3 getcap.3 cgetclose.3 getcap.3 cgetent.3 \ - getcap.3 cgetfirst.3 getcap.3 cgetmatch.3 getcap.3 cgetnext.3 \ - getcap.3 cgetnum.3 getcap.3 cgetset.3 getcap.3 cgetstr.3 \ - getcap.3 cgetustr.3 -MLINKS+=getcwd.3 getwd.3 -MLINKS+=getdomainname.3 setdomainname.3 -MLINKS+=getfsent.3 endfsent.3 getfsent.3 getfsfile.3 getfsent.3 getfsspec.3 \ - getfsent.3 getfstype.3 getfsent.3 setfsent.3 -MLINKS+=getgrent.3 endgrent.3 getgrent.3 getgrgid.3 getgrent.3 getgrnam.3 \ - getgrent.3 setgrent.3 getgrent.3 setgroupent.3 -MLINKS+=gethostname.3 sethostname.3 -MLINKS+=getnetgrent.3 endnetgrent.3 getnetgrent.3 innetgr.3 \ - getnetgrent.3 setnetgrent.3 -MLINKS+=getprogname.3 setprogname.3 -MLINKS+=getpwent.3 endpwent.3 getpwent.3 getpwnam.3 getpwent.3 getpwuid.3 \ - getpwent.3 setpassent.3 getpwent.3 setpwent.3 getpwent.3 setpwfile.3 -MLINKS+=getttyent.3 endttyent.3 getttyent.3 getttynam.3 \ - getttyent.3 isdialuptty.3 getttyent.3 isnettty.3 \ - getttyent.3 setttyent.3 -MLINKS+=getusershell.3 endusershell.3 getusershell.3 setusershell.3 -MLINKS+=glob.3 globfree.3 -MLINKS+=isgreater.3 isgreaterequal.3 isgreater.3 isless.3 \ - isgreater.3 islessequal.3 isgreater.3 islessgreater.3 \ - isgreater.3 isunordered.3 -MLINKS+=malloc.3 calloc.3 malloc.3 valloc.3 malloc.3 realloc.3 malloc.3 free.3 \ - malloc.3 malloc_size.3 malloc.3 malloc_good_size.3 malloc.3 reallocf.3 -MLINKS+=popen.3 pclose.3 -MLINKS+=psignal.3 sys_siglist.3 psignal.3 sys_signame.3 -MLINKS+=psignal.3 strsignal.3 psignal.3 sys_siglist.3 psignal.3 sys_signame.3 -MLINKS+=pwcache.3 group_from_gid.3 pwcache.3 user_from_uid.3 -MLINKS+=rand48.3 _rand48.3 rand48.3 drand48.3 rand48.3 erand48.3 \ - rand48.3 jrand48.3 rand48.3 lcong48.3 rand48.3 lrand48.3 \ - rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 seed48.3 \ - rand48.3 srand48.3 -MLINKS+=scandir.3 alphasort.3 -MLINKS+=strtofflags.3 fflagstostr.3 -MLINKS+=setjmp.3 _longjmp.3 setjmp.3 _setjmp.3 setjmp.3 longjmp.3 \ - setjmp.3 longjmperr.3 setjmp.3 longjmperror.3 \ - setjmp.3 siglongjmp.3 setjmp.3 sigsetjmp.3 -MLINKS+=setmode.3 getmode.3 -MLINKS+=sigsetops.3 sigaddset.3 sigsetops.3 sigdelset.3 \ - sigsetops.3 sigemptyset.3 sigsetops.3 sigfillset.3 \ - sigsetops.3 sigismember.3 -MLINKS+=stringlist.3 sl_add.3 stringlist.3 sl_find.3 \ - stringlist.3 sl_free.3 stringlist.3 sl_init.3 -MLINKS+=sysctl.3 sysctlbyname.3 sysctl.3 sysctlnametomib.3 -MLINKS+=syslog.3 closelog.3 syslog.3 openlog.3 syslog.3 setlogmask.3 \ - syslog.3 vsyslog.3 -MLINKS+=tcsendbreak.3 tcdrain.3 tcsendbreak.3 tcflow.3 tcsendbreak.3 tcflush.3 -MLINKS+=tcsetattr.3 cfgetispeed.3 tcsetattr.3 cfgetospeed.3 \ - tcsetattr.3 cfmakeraw.3 tcsetattr.3 cfsetispeed.3 \ - tcsetattr.3 cfsetospeed.3 tcsetattr.3 cfsetspeed.3 \ - tcsetattr.3 tcgetattr.3 -MLINKS+=ttyname.3 isatty.3 ttyname.3 ttyslot.3 -MLINKS+=tzset.3 tzsetwall.3 -MLINKS+=unvis.3 strunvis.3 unvis.3 strunvisx.3 -MLINKS+=vis.3 strvis.3 vis.3 strvisx.3 +MLINKS+= arc4random.3 arc4random_addrandom.3 \ + arc4random.3 arc4random_stir.3 + +MLINKS+= asl.3 asl_add_log_file.3 \ + asl.3 asl_close.3 \ + asl.3 asl_free.3 \ + asl.3 asl_get.3 \ + asl.3 asl_key.3 \ + asl.3 asl_log.3 \ + asl.3 asl_new.3 \ + asl.3 asl_open.3 \ + asl.3 asl_remove_log_file.3 \ + asl.3 asl_search.3 \ + asl.3 asl_send.3 \ + asl.3 asl_set.3 \ + asl.3 asl_set_filter.3 \ + asl.3 asl_set_query.3 \ + asl.3 asl_unset.3 \ + asl.3 asl_vlog.3 \ + asl.3 aslresponse_free.3 \ + asl.3 aslresponse_next.3 + +MLINKS+= backtrace.3 backtrace_symbols.3 \ + backtrace.3 backtrace_symbols_fd.3 + +MLINKS+= crypt.3 encrypt.3 \ + crypt.3 setkey.3 + +MLINKS+= ctermid.3 ctermid_r.3 + +MLINKS+= devname.3 devname_r.3 + +MLINKS+= directory.3 closedir.3 \ + directory.3 dirfd.3 \ + directory.3 opendir.3 \ + directory.3 readdir.3 \ + directory.3 readdir_r.3 \ + directory.3 rewinddir.3 \ + directory.3 seekdir.3 \ + directory.3 telldir.3 + +MLINKS+= endutxent.3 getutxent.3 \ + endutxent.3 getutxid.3 \ + endutxent.3 getutxline.3 \ + endutxent.3 pututxline.3 \ + endutxent.3 setutxent.3 + +MLINKS+= err.3 err_set_exit.3 \ + err.3 err_set_file.3 \ + err.3 errc.3 \ + err.3 errx.3 \ + err.3 verr.3 \ + err.3 verrc.3 \ + err.3 verrx.3 \ + err.3 vwarn.3 \ + err.3 vwarnc.3 \ + err.3 vwarnx.3 \ + err.3 warn.3 \ + err.3 warnc.3 \ + err.3 warnx.3 + +MLINKS+= exec.3 execl.3 \ + exec.3 execle.3 \ + exec.3 execlp.3 \ + exec.3 execv.3 \ + exec.3 execvp.3 + +MLINKS+= fts.3 fts_children.3 \ + fts.3 fts_close.3 \ + fts.3 fts_open.3 \ + fts.3 fts_read.3 \ + fts.3 fts_set.3 + +MLINKS+= ftw.3 nftw.3 + +MLINKS+= getcap.3 cgetcap.3 \ + getcap.3 cgetclose.3 \ + getcap.3 cgetent.3 \ + getcap.3 cgetfirst.3 \ + getcap.3 cgetmatch.3 \ + getcap.3 cgetnext.3 \ + getcap.3 cgetnum.3 \ + getcap.3 cgetset.3 \ + getcap.3 cgetstr.3 \ + getcap.3 cgetustr.3 + +MLINKS+= getcontext.3 setcontext.3 + +MLINKS+= getcwd.3 getwd.3 + +MLINKS+= getdomainname.3 setdomainname.3 + +MLINKS+= getlastlogx.3 getlastlogxbyname.3 \ + getlastlogx.3 getutmp.3 \ + getlastlogx.3 getutmpx.3 \ + getlastlogx.3 utmpxname.3 + +MLINKS+= gethostname.3 sethostname.3 + +MLINKS+= getprogname.3 setprogname.3 + +MLINKS+= getttyent.3 endttyent.3 \ + getttyent.3 getttynam.3 \ + getttyent.3 setttyent.3 + +MLINKS+= getusershell.3 endusershell.3 \ + getusershell.3 setusershell.3 + +MLINKS+= glob.3 globfree.3 + +MLINKS+= isgreater.3 isgreaterequal.3 \ + isgreater.3 isless.3 \ + isgreater.3 islessequal.3 \ + isgreater.3 islessgreater.3 \ + isgreater.3 isunordered.3 + +MLINKS+= malloc.3 calloc.3 \ + malloc.3 free.3 \ + malloc.3 realloc.3 \ + malloc.3 reallocf.3 \ + malloc.3 valloc.3 + +MLINKS+= makecontext.3 swapcontext.3 + +MLINKS+= malloc_size.3 malloc_good_size.3 + +MLINKS+= popen.3 pclose.3 + +MLINKS+= psignal.3 sys_siglist.3 \ + psignal.3 sys_signame.3 + +MLINKS+= psignal.3 strsignal.3 \ + psignal.3 sys_siglist.3 \ + psignal.3 sys_signame.3 + +MLINKS+= pwcache.3 group_from_gid.3 \ + pwcache.3 user_from_uid.3 + +MLINKS+= rand48.3 _rand48.3 \ + rand48.3 drand48.3 \ + rand48.3 erand48.3 \ + rand48.3 jrand48.3 \ + rand48.3 lcong48.3 \ + rand48.3 lrand48.3 \ + rand48.3 mrand48.3 \ + rand48.3 nrand48.3 \ + rand48.3 seed48.3 \ + rand48.3 srand48.3 + +MLINKS+= scandir.3 alphasort.3 + +MLINKS+= strtofflags.3 fflagstostr.3 + +MLINKS+= setjmp.3 _longjmp.3 \ + setjmp.3 _setjmp.3 \ + setjmp.3 longjmp.3 \ + setjmp.3 longjmperr.3 \ + setjmp.3 longjmperror.3 \ + setjmp.3 siglongjmp.3 \ + setjmp.3 sigsetjmp.3 + +MLINKS+= setmode.3 getmode.3 + +MLINKS+= sigsetops.3 sigaddset.3 \ + sigsetops.3 sigdelset.3 \ + sigsetops.3 sigemptyset.3 \ + sigsetops.3 sigfillset.3 \ + sigsetops.3 sigismember.3 + +MLINKS+= stringlist.3 sl_add.3 \ + stringlist.3 sl_find.3 \ + stringlist.3 sl_free.3 \ + stringlist.3 sl_init.3 + +MLINKS+= sysctl.3 sysctlbyname.3 \ + sysctl.3 sysctlnametomib.3 + +MLINKS+= syslog.3 closelog.3 \ + syslog.3 openlog.3 \ + syslog.3 setlogmask.3 \ + syslog.3 vsyslog.3 + +MLINKS+= tcsendbreak.3 tcdrain.3 \ + tcsendbreak.3 tcflow.3 \ + tcsendbreak.3 tcflush.3 + +MLINKS+= tcsetattr.3 cfgetispeed.3 \ + tcsetattr.3 cfgetospeed.3 \ + tcsetattr.3 cfmakeraw.3 \ + tcsetattr.3 cfsetispeed.3 \ + tcsetattr.3 cfsetospeed.3 \ + tcsetattr.3 cfsetspeed.3 \ + tcsetattr.3 tcgetattr.3 + +MLINKS+= ttyname.3 isatty.3 \ + ttyname.3 ttyslot.3 + +MLINKS+= tzset.3 tzsetwall.3 + +MLINKS+= unvis.3 strunvis.3 \ + unvis.3 strunvisx.3 + +MLINKS+= vis.3 strvis.3 \ + vis.3 strvisx.3 + +MLINKS+= wordexp.3 wordfree.3 .endif diff --git a/gen/NSSystemDirectories.c b/gen/NSSystemDirectories.c index d084e2e..31ab409 100644 --- a/gen/NSSystemDirectories.c +++ b/gen/NSSystemDirectories.c @@ -26,7 +26,7 @@ #import // Names of directories; index into this with NSSearchPathDirectory - 1 -#define numDirs 14 +#define numDirs 15 static const struct { unsigned char invalidDomainMask; // Domains in which this dir does not appear unsigned char alternateDomainMask; // Domains in which this dir uses the alternate domain path @@ -45,7 +45,8 @@ static const struct { {0xe, 0, "Documents/Autosaved"}, // Only valid in user domain; not public API yet {0xe, 0, "Desktop"}, // Only valid in user domain {0, 0, "Library/Caches"}, - {0, 0, "Library/Application Support"} + {0, 0, "Library/Application Support"}, + {0xe, 0, "Downloads"}, // Only valid in user domain }; // Unpublicized values for NSSearchPathDirectory diff --git a/gen/NetBSD/endutxent.3.patch b/gen/NetBSD/endutxent.3.patch index c1dbb27..81978c9 100644 --- a/gen/NetBSD/endutxent.3.patch +++ b/gen/NetBSD/endutxent.3.patch @@ -1,15 +1,38 @@ ---- endutxent.3.orig 2004-07-13 09:02:01.000000000 -0700 -+++ endutxent.3 2004-08-05 15:41:50.000000000 -0700 +--- endutxent.3.orig 2007-04-08 18:49:40.000000000 -0700 ++++ endutxent.3 2007-04-08 19:03:43.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. .\" -.Dd September 26, 2002 -+.Dd July 13, 2004 ++.Dd June 29, 2006 .Dt ENDUTXENT 3 .Os .Sh NAME -@@ -105,20 +105,14 @@ +@@ -54,11 +54,11 @@ + .Ft struct utmpx * + .Fn getutxent void + .Ft struct utmpx * +-.Fn getutxid "const struct utmpx *" ++.Fn getutxid "const struct utmpx *id" + .Ft struct utmpx * +-.Fn getutxline "const struct utmpx *" ++.Fn getutxline "const struct utmpx *line" + .Ft struct utmpx * +-.Fn pututxline "const struct utmpx *" ++.Fn pututxline "const struct utmpx *utx" + .Ft void + .Fn setutxent void + .Sh DESCRIPTION +@@ -98,6 +98,7 @@ + .Xr utmpx 5 + entry line to the accounting database, replacing a previous entry for + the same user if it exists. ++Only the superuser may write to the accounting database. + .Ss The utmpx structure + The + .Nm utmpx +@@ -105,27 +106,21 @@ .Pp .Bd -literal struct utmpx { @@ -38,7 +61,15 @@ }; .Ed .Pp -@@ -143,8 +137,7 @@ + Valid entries for + .Fa ut_type + are: +-.Bl -tag -width LOGIN_PROCESSXX -compact -offset indent ++.Bl -tag -width ".Dv LOGIN_PROCESSXX" -compact -offset indent + .It Dv BOOT_TIME + Time of a system boot. + .It Dv DEAD_PROCESS +@@ -143,11 +138,115 @@ Time before system clock change. .It Dv RUN_LVL Run level. @@ -47,12 +78,160 @@ +Provided for compatibility, not used. .It Dv USER_PROCESS A user process. ++.It Dv SHUTDOWN_TIME ++Time of system shutdown (extension to the standards). .El -@@ -163,7 +156,6 @@ ++.Pp ++For each value of ++.Fa ut_type , ++the other fields with meaningful values are as follows: ++.Bl -tag -width ".Dv LOGIN_PROCESSXX" -compact -offset indent ++.It Dv BOOT_TIME ++.Fa ut_tv ++.It Dv DEAD_PROCESS ++.Fa ut_id , ++.Fa ut_pid , ++.Fa ut_tv ++.It Dv EMPTY ++(no others) ++.It Dv INIT_PROCESS ++.Fa ut_id , ++.Fa ut_pid , ++.Fa ut_tv ++.It Dv LOGIN_PROCESS ++.Fa ut_id , ++.Fa ut_user ++(implementation-defined name of the login process), ++.Fa ut_pid , ++.Fa ut_tv ++.It Dv NEW_TIME ++.Fa ut_tv ++.It Dv OLD_TIME ++.Fa ut_tv ++.It Dv RUN_LVL ++(no used) ++.It Dv USER_PROCESS ++.Fa ut_id , ++.Fa ut_user ++(login name of the user), ++.Fa ut_line , ++.Fa ut_pid , ++.Fa ut_host ++(hostname of remote user) ++.Fa ut_tv ++.It Dv SHUTDOWN_TIME ++.Fa ut_tv ++.El ++.Ss Other extensions to the standards ++The ++.Fa ut_tv ++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 ++.Fa ut_type ++value, other fields are automatically filled in (as specified in the ++meaningful fields table above). ++In particular, the ++.Fa ut_id ++field will be set using the convention of the last four characters of the ++.Fa ut_line ++field (itself filled in automatically from the tty name of the device connected ++to the standard input, output or error, whichever is available). ++Note that it is more efficient to fill in as many values as are already ++available beforehand, rather than have then automatically filled in. ++.It Dv UTMPX_DEAD_IF_CORRESPONDING_MASK ++When ++.Fa ut_type ++value is ++.Dv DEAD_PROCESS, a call to ++.Fn pututxline ++will succeed only if a corresponding entry already exists with a ++.Fa ut_type ++value of ++.Dv USER_PROCESS . ++.El ++.Pp ++Note that the above mask values do not show up in any file format, or in ++any subsequent reads of the data. ++.Pp ++To support ++.Pa wtmpx ++and ++.Pa lastlogx ++equivalent capability, ++.Fn pututxline ++automatically writes to the appropriate files. ++Additional APIs to read these files is available in ++.Xr endutxent_wtmp 3 ++and ++.Xr getlastlogx 3 . ++.Ss Backward compatibility ++Successful calls to ++.Fn pututxline ++will automatically write equivalent entries into the ++.Pa utmp , ++.Pa wtmp ++and ++.Pa lastlog ++files. ++Programs that read these old files should work as expected. ++However, directly writing to these files does not make corresponding ++entries in ++.Pa utmpx ++and the ++.Pa wtmpx ++and ++.Pa lastlogx ++equivalent files, so such write-access is deprecated. + .Sh RETURN VALUES + .Fn getutxent + returns the next entry, or +@@ -159,11 +258,45 @@ + return the matching structure on success, or + .Dv NULL + if no match was found. ++.Pp + .Fn pututxline returns the structure that was successfully written, or - .Dv NULL . +-.Dv NULL . ++.Dv NULL ++is returned and the global variable ++.Va errno ++is set to indicate the error. ++.Sh ERRORS ++No errors are defined for the ++.Fn endutxent , ++.Fn getutxent , ++.Fn getutxid , ++.Fn getutxline , ++and ++.Fn setutxent ++functions. ++.Pp ++The ++.Fn pututxline ++function may fail if: ++.Bl -tag -width Er ++.It Bq Er EPERM ++The process does not have appropriate privileges. ++.It Bq Er EINVAL ++The ++.Dv UTMPX_DEAD_IF_CORRESPONDING_MASK ++flags was specified along with ++.Dv DEAD_PROCESS , ++but no corresponding entry with ++.Dv USER_PROCESS ++was found. ++.El ++.Pp ++Other errors may be returned if ++.Dv UTMPX_AUTOFILL_MASK ++was specified, and a field could not be auto-filled. .Sh SEE ALSO -.Xr logwtmpx 3 , ++.Xr endutxent_wtmp 3 , ++.Xr getlastlogx 3 , .Xr utmpx 5 .Sh STANDARDS The diff --git a/gen/NetBSD/getlastlogx.3 b/gen/NetBSD/getlastlogx.3 new file mode 100644 index 0000000..78fbd5e --- /dev/null +++ b/gen/NetBSD/getlastlogx.3 @@ -0,0 +1,180 @@ +.\" $NetBSD: getlastlogx.3,v 1.1 2003/08/26 17:37:51 wiz 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. +.\" 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. +.\" +.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/NetBSD/getlastlogx.3.patch b/gen/NetBSD/getlastlogx.3.patch new file mode 100644 index 0000000..0f1b420 --- /dev/null +++ b/gen/NetBSD/getlastlogx.3.patch @@ -0,0 +1,149 @@ +--- getlastlogx.3.orig 2006-01-11 18:20:07.000000000 -0800 ++++ getlastlogx.3 2006-01-04 18:02:57.000000000 -0800 +@@ -34,42 +34,33 @@ + .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + .\" POSSIBILITY OF SUCH DAMAGE. + .\" +-.Dd August 26, 2003 ++.Dd Dec 26, 2005 + .Dt GETLASTLOGX 3 + .Os + .Sh NAME + .Nm getlastlogx , ++.Nm getlastlogxbyname , + .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" ++.Fn getlastlogx "uid_t uid" "struct lastlogx *ll" ++.Ft struct lastlogx * ++.Fn getlastlogxbyname "const char *name" "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 +@@ -81,8 +72,12 @@ + and should be + .Fn free Ns d + by the caller. +-.Pp + The ++.Fn getlastlogxbyname ++function is similar to ++.Fn getlastlogx , ++except the user name is passed. ++.Pp + .Fn getutmp + function fills out the entries in the struct utmp + .Fa u +@@ -99,16 +94,6 @@ + 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: +@@ -117,21 +102,8 @@ + 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 +@@ -141,11 +113,15 @@ + .Fa fname . + .Sh RETURN VALUES + .Fn getlastlogx +-returns the found entry on success, or ++and ++.Fn getlastlogxbyname ++return 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 ++or ++.Fa name , ++or could not allocate the necessary space (in case + .Fa \&ll + was + .Dv NULL ) . +@@ -154,27 +130,17 @@ + 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/NetBSD/utmpx.5.patch b/gen/NetBSD/utmpx.5.patch index ac63fde..768fb89 100644 --- a/gen/NetBSD/utmpx.5.patch +++ b/gen/NetBSD/utmpx.5.patch @@ -1,6 +1,11 @@ ---- utmpx.5.orig 2004-07-13 09:15:18.000000000 -0700 -+++ utmpx.5 2004-08-05 15:33:40.000000000 -0700 -@@ -38,23 +38,16 @@ +--- 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 .Dt UTMPX 5 .Os .Sh NAME @@ -11,11 +16,9 @@ .Nd user accounting database .Sh SYNOPSIS .In utmpx.h - .Sh DESCRIPTION - The +@@ -49,89 +47,51 @@ .Aq Pa utmpx.h --header defines the structures and functions for logging user. -+header defines the structure and functions for logging user. + header defines the structures and functions for logging user. Currently logged in users are tracked in -.Pa /var/run/utmpx , -a list of all logins and logouts, as well as all shutdowns, reboots @@ -23,20 +26,37 @@ -.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 files are not automatically created if they do not exist; they - must be created manually. - .Pp -@@ -62,76 +55,18 @@ + The interface to the .Nm utmpx file is described in .Xr endutxent 3 . --.Pp ++The file is not automatically created if they do not exist; it ++must be created manually. + .Pp -The -.Nm wtmpx -file can grow rapidly on busy systems, and is normally rotated with -.Xr newsyslog 8 . --.Pp ++Traditionally, separate files would be used to store the running log of ++the logins and logouts ++.Pf ( Pa wtmpx ) , ++and the last login of each user ++.Pf ( Pa lastlogx ) . ++With the availability of the Apple system log facility ++.Xr asl 3 , ++these separate files can be replace with log entries, which are automatically ++generated when ++.Nm utmpx ++entries are written. ++The API to access the logins and logouts is described in ++.Xr endutxent_wtmp 3 ++while the last login info is accessible with ++.Xr getlastlogx 3 . + .Pp -In the event of a date change, a shutdown, or a reboot, the following -items are logged in the -.Nm wtmpx @@ -71,16 +91,21 @@ -.Fa ut_name -(see -.Xr shutdown 8 --and ++For compatibility, changes to ++.Nm utmpx ++are reflected in ++.Xr utmp 3 ++(in the ++.Pa utmp , ++.Pa wtmp + and -.Xr reboot 8 ) , -using -.Xr logwtmpx 3 . -.Pp -.El -+For compatibility, changes to -+.Nm utmpx -+are reflected in -+.Xr utmp 3 , ++.Pa lastlog ++files), +but not the other way around. .Sh FILES -.Bl -tag -width /var/log/lastlogx -compact @@ -104,10 +129,13 @@ -.Xr rwho 1 , -.Xr w 1 , -.Xr who 1 , ++.Xr asl 3 , .Xr endutxent 3 , -.Xr logwtmpx 3 , -.Xr ac 8 , -.Xr init 8 , -.Xr newsyslog 8 , -.Xr reboot 8 ++.Xr endutxent_wtmp 3 , ++.Xr getlastlogx 3 , +.Xr utmp 5 diff --git a/gen/NetBSD/utmpx.c.patch b/gen/NetBSD/utmpx.c.patch index 093e963..b4816c9 100644 --- a/gen/NetBSD/utmpx.c.patch +++ b/gen/NetBSD/utmpx.c.patch @@ -1,53 +1,316 @@ ---- utmpx.c.orig 2004-07-13 13:02:37.000000000 -0700 -+++ utmpx.c 2004-08-05 15:25:10.000000000 -0700 -@@ -50,7 +50,6 @@ +--- utmpx.c.orig 2006-02-06 00:43:57.000000000 -0800 ++++ utmpx.c 2006-02-06 00:51:52.000000000 -0800 +@@ -49,34 +49,27 @@ + #include #include - #include +-#include -#include - #include +-#include #include #include -@@ -63,6 +62,13 @@ + #include + #include + #include + #include +-/* don't define earlier, has side effects in fcntl.h */ +-#define __LIBC12_SOURCE__ #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 -+#ifdef UTMP_COMPAT -+#include -+#include -+ -+static void _utmp_compat(const struct utmpx *); -+#endif /* UTMP_COMPAT */ -+ - __warn_references(getlastlogx, - "warning: reference to compatibility getlastlogx(); include for correct reference") - __warn_references(lastlogxname, -@@ -72,7 +78,6 @@ + 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? */ + +-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"; - static struct utmpx *utmp_update(const struct utmpx *); + void + setutxent() +@@ -85,7 +78,11 @@ + (void)memset(&ut, 0, sizeof(ut)); + if (fp == NULL) + return; ++#ifdef __LP64__ ++ (void)fseeko(fp, (off_t)sizeof(struct utmpx32), SEEK_SET); ++#else /* __LP64__ */ + (void)fseeko(fp, (off_t)sizeof(ut), SEEK_SET); ++#endif /* __LP64__ */ + } + + +@@ -105,6 +102,9 @@ + struct utmpx * + getutxent() + { ++#ifdef __LP64__ ++ struct utmpx32 ut32; ++#endif /* __LP64__ */ + + if (fp == NULL) { + struct stat st; +@@ -124,42 +124,80 @@ + + if (st.st_size == 0) { + /* new file, add signature record */ ++#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) ++#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) ++#endif /* __LP64__ */ + goto failclose; + } else { + /* old file, read signature record */ ++#ifdef __LP64__ ++ if (fread(&ut32, sizeof(ut32), 1, fp) != 1) ++#else /* __LP64__ */ + if (fread(&ut, sizeof(ut), 1, fp) != 1) ++#endif /* __LP64__ */ + goto failclose; +- if (memcmp(ut.ut_user, vers, sizeof(vers)) != 0 || ++#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) ++#endif /* __LP64__ */ + goto failclose; + } + } -@@ -270,6 +275,9 @@ ++#ifdef __LP64__ ++ if (fread(&ut32, sizeof(ut32), 1, fp) != 1) ++#else /* __LP64__ */ + if (fread(&ut, sizeof(ut), 1, fp) != 1) ++#endif /* __LP64__ */ goto fail; - u = memcpy(&ut, &temp, sizeof(ut)); ++#ifdef __LP64__ ++ _utmpx32_64(&ut32, &ut); ++#endif /* __LP64__ */ + return &ut; + failclose: + (void)fclose(fp); ++ fp = NULL; + fail: + (void)memset(&ut, 0, sizeof(ut)); + return NULL; + } + +- + struct utmpx * + getutxid(const struct utmpx *utx) + { ++ struct utmpx temp; ++ const struct utmpx *ux; + + _DIAGASSERT(utx != NULL); + + if (utx->ut_type == EMPTY) + return NULL; + ++ /* make a copy as needed, and auto-fill if requested */ ++ ux = _utmpx_working_copy(utx, &temp, 1); ++ if (!ux) ++ return NULL; ++ ++ return _getutxid(ux); ++} ++ ++ ++static struct utmpx * ++_getutxid(const struct utmpx *utx) ++{ ++ + do { + if (ut.ut_type == EMPTY) + continue; +@@ -225,30 +263,68 @@ + struct utmpx * + pututxline(const struct utmpx *utx) + { +- struct utmpx temp, *u = NULL; +- int gotlock = 0; ++ struct utmpx *ux; + + _DIAGASSERT(utx != NULL); + +- if (utx == NULL) ++ if (utx == NULL) { ++ errno = EINVAL; + return NULL; ++ } + +- if (strcmp(_PATH_UTMPX, utfile) == 0) +- if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) +- return utmp_update(utx); ++ if ((ux = _pututxline(utx)) != NULL && utfile_system) { ++ _utmpx_asl(ux); /* the equivalent of wtmpx and lastlogx */ +#ifdef UTMP_COMPAT -+ _utmp_compat(u); ++ _write_utmp_compat(ux); +#endif /* UTMP_COMPAT */ ++ } ++ return ux; ++} + ++__private_extern__ struct utmpx * ++_pututxline(const struct utmpx *utx) ++{ ++ struct utmpx temp, *u = NULL, *x; ++ const struct utmpx *ux; ++#ifdef __LP64__ ++ struct utmpx32 ut32; ++#endif /* __LP64__ */ ++ int gotlock = 0; + +- (void)memcpy(&temp, utx, sizeof(temp)); ++ if (utfile_system) ++ if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) { ++ errno = EPERM; ++ return NULL; ++ } + + if (fp == NULL) { + (void)getutxent(); +- if (fp == NULL || readonly) ++ if (fp == NULL || readonly) { ++ errno = EPERM; + return NULL; ++ } + } + +- if (getutxid(&temp) == NULL) { ++ /* make a copy as needed, and auto-fill if requested */ ++ ux = _utmpx_working_copy(utx, &temp, 0); ++ if (!ux) ++ return NULL; ++ ++ if ((x = _getutxid(ux)) == NULL) { + setutxent(); +- if (getutxid(&temp) == NULL) { ++ if ((x = _getutxid(ux)) == NULL) { ++ /* ++ * utx->ut_type has any original mask bits, while ++ * ux->ut_type has those mask bits removed. If we ++ * are trying to record a dead process, and ++ * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, then since ++ * there is no matching entry, we return NULL. ++ */ ++ if (ux->ut_type == DEAD_PROCESS && ++ (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK)) { ++ errno = EINVAL; ++ return NULL; ++ } + if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1) + return NULL; + gotlock++; +@@ -258,99 +334,66 @@ + } + + if (!gotlock) { ++ /* ++ * utx->ut_type has any original mask bits, while ++ * ux->ut_type has those mask bits removed. If we ++ * are trying to record a dead process, if ++ * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, but the found ++ * entry is not a (matching) USER_PROCESS, then return NULL. ++ */ ++ if (ux->ut_type == DEAD_PROCESS && ++ (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK) && ++ x->ut_type != USER_PROCESS) { ++ errno = EINVAL; ++ return NULL; ++ } + /* we are not appending */ ++#ifdef __LP64__ ++ if (fseeko(fp, -(off_t)sizeof(ut32), SEEK_CUR) == -1) ++#else /* __LP64__ */ + if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1) ++#endif /* __LP64__ */ + return NULL; + } + +- if (fwrite(&temp, sizeof (temp), 1, fp) != 1) ++#ifdef __LP64__ ++ _utmpx64_32(ux, &ut32); ++ if (fwrite(&ut32, sizeof (ut32), 1, fp) != 1) ++#else /* __LP64__ */ ++ if (fwrite(ux, sizeof (*ux), 1, fp) != 1) ++#endif /* __LP64__ */ + goto fail; + + if (fflush(fp) == -1) + goto fail; + +- u = memcpy(&ut, &temp, sizeof(ut)); ++ u = memcpy(&ut, ux, sizeof(ut)); ++ notify_post(UTMPX_CHANGE_NOTIFICATION); fail: if (gotlock) { ++ int save = errno; if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1) -@@ -308,185 +316,50 @@ - + return NULL; ++ errno = save; + } + return u; } --/* -- * The following are extensions and not part of the X/Open spec. -- */ --int + +-static struct utmpx * +-utmp_update(const struct utmpx *utx) +-{ +- char buf[sizeof(*utx) * 4 + 1]; +- pid_t pid; +- int status; +- +- _DIAGASSERT(utx != NULL); +- +- (void)strvisx(buf, (const char *)(const void *)utx, sizeof(*utx), +- VIS_WHITE); +- switch (pid = fork()) { +- case 0: +- (void)execl(_PATH_UTMP_UPDATE, +- strrchr(_PATH_UTMP_UPDATE, '/') + 1, buf, NULL); +- exit(1); +- /*NOTREACHED*/ +- case -1: +- return NULL; +- default: +- if (waitpid(pid, &status, 0) == -1) +- return NULL; +- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) +- return memcpy(&ut, utx, sizeof(ut)); +- return NULL; +- } +- +-} +- + /* + * The following are extensions and not part of the X/Open spec. + */ + int -updwtmpx(const char *file, const struct utmpx *utx) -{ - int fd; @@ -66,25 +329,7 @@ - (void)memcpy(ut.ut_user, vers, sizeof(vers)); - if (write(fd, &ut, sizeof(ut)) == -1) - goto failed; -+#ifdef UTMP_COMPAT -+static void -+_utmp_compat(const struct utmpx *ux) -+{ -+ struct utmp u; -+ int fd, slot; -+ struct ttyent *ttyp; -+ -+ switch (ux->ut_type) { -+ case INIT_PROCESS: -+ case LOGIN_PROCESS: -+ case USER_PROCESS: -+ break; -+ case DEAD_PROCESS: -+ logout(ux->ut_line); -+ return; -+ default: -+ return; - } +- } - if (write(fd, utx, sizeof(*utx)) == -1) - goto failed; - if (close(fd) == -1) @@ -100,55 +345,62 @@ - - -int --utmpxname(const char *fname) --{ -- size_t len; -- + utmpxname(const char *fname) + { + size_t len; + - _DIAGASSERT(fname != NULL); -- -- len = strlen(fname); -- -- if (len >= sizeof(utfile)) -- return 0; -- -- /* must end in x! */ -- if (fname[len - 1] != 'x') -- return 0; -- -- (void)strlcpy(utfile, fname, sizeof(utfile)); -- endutxent(); -- return 1; --} -- -- --void --getutmp(const struct utmpx *ux, struct utmp *u) --{ -- ++ if (fname == NULL) { ++ strcpy(utfile, _PATH_UTMPX); ++ utfile_system = 1; ++ endutxent(); ++ return 1; ++ } + + len = strlen(fname); + +@@ -363,6 +406,7 @@ + + (void)strlcpy(utfile, fname, sizeof(utfile)); + endutxent(); ++ utfile_system = 0; + return 1; + } + +@@ -371,10 +415,8 @@ + getutmp(const struct utmpx *ux, struct utmp *u) + { + - _DIAGASSERT(ux != NULL); - _DIAGASSERT(u != NULL); - - (void)memcpy(u->ut_name, ux->ut_name, sizeof(u->ut_name)); -- (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; --} -- --void --getutmpx(const struct utmp *u, struct utmpx *ux) --{ -- ++ bzero(u, sizeof(*u)); ++ (void)memcpy(u->ut_name, ux->ut_user, sizeof(u->ut_name)); + (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 +426,15 @@ + getutmpx(const struct utmp *u, struct utmpx *ux) + { + - _DIAGASSERT(ux != NULL); - _DIAGASSERT(u != NULL); - - (void)memcpy(ux->ut_name, u->ut_name, sizeof(u->ut_name)); -- (void)memcpy(ux->ut_line, u->ut_line, sizeof(u->ut_line)); -- (void)memcpy(ux->ut_host, u->ut_host, sizeof(u->ut_host)); -- ux->ut_tv.tv_sec = u->ut_time; -- ux->ut_tv.tv_usec = 0; ++ bzero(ux, sizeof(*ux)); ++ (void)memcpy(ux->ut_user, u->ut_name, sizeof(u->ut_name)); ++ ux->ut_user[sizeof(u->ut_name)] = 0; + (void)memcpy(ux->ut_line, u->ut_line, sizeof(u->ut_line)); ++ ux->ut_line[sizeof(u->ut_line)] = 0; + (void)memcpy(ux->ut_host, u->ut_host, sizeof(u->ut_host)); ++ ux->ut_host[sizeof(u->ut_host)] = 0; + ux->ut_tv.tv_sec = u->ut_time; + ux->ut_tv.tv_usec = 0; - (void)memset(&ux->ut_ss, 0, sizeof(ux->ut_ss)); - ux->ut_pid = 0; -- ux->ut_type = USER_PROCESS; ++ ux->ut_pid = getpid(); + ux->ut_type = USER_PROCESS; - ux->ut_session = 0; - ux->ut_exit.e_termination = 0; - ux->ut_exit.e_exit = 0; @@ -204,21 +456,8 @@ - if (data.size != sizeof(*ll)) { - errno = EFTYPE; - goto error; -+ /* do equivalent of ttyslot(), but using ux->ut_slot */ -+ setttyent(); -+ slot = 1; -+ for(;;) { -+ if ((ttyp = getttyent()) == NULL) { -+ endttyent(); -+ return; -+ } -+ if (!strcmp(ttyp->ty_name, ux->ut_line)) { -+ endttyent(); -+ break; -+ } -+ slot++; - } - +- } +- - if (ll == NULL) - if ((ll = malloc(sizeof(*ll))) == NULL) - goto done; @@ -256,16 +495,4 @@ - - (db->close)(db); - return error; -+ /* now write utmp */ -+ (void)memset(&u, 0, sizeof(u)); -+ strncpy(u.ut_line, ux->ut_line, UT_LINESIZE); -+ strncpy(u.ut_name, ux->ut_user, UT_NAMESIZE); -+ strncpy(u.ut_host, ux->ut_host, UT_HOSTSIZE); -+ u.ut_time = ux->ut_tv.tv_sec; -+ if ((fd = open(_PATH_UTMP, O_WRONLY|O_CREAT, 0644)) >= 0) { -+ (void)lseek(fd, (off_t)(slot * sizeof(struct utmp)), L_SET); -+ (void)write(fd, &u, sizeof(struct utmp)); -+ (void)close(fd); -+ } } -+#endif /* UTMP_COMPAT */ diff --git a/gen/__dirent.h b/gen/__dirent.h new file mode 100644 index 0000000..8c3407c --- /dev/null +++ b/gen/__dirent.h @@ -0,0 +1,16 @@ +/* + * We need to prefix the elements of DIR with double-underscore to use + * the implementation namespace. We could patch all the *dir.c code, + * but it is easier to use #defines to rename the elements. This file + * then gets included by all the *dir.c. + */ +#define dd_fd __dd_fd +#define dd_loc __dd_loc +#define dd_size __dd_size +#define dd_buf __dd_buf +#define dd_len __dd_len +#define dd_seek __dd_seek +#define dd_rewind __dd_rewind +#define dd_flags __dd_flags +#define dd_lock __dd_lock +#define dd_td __dd_td diff --git a/gen/_rand48-fbsd.c b/gen/_rand48-fbsd.c new file mode 100644 index 0000000..da4d69e --- /dev/null +++ b/gen/_rand48-fbsd.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/_rand48.c,v 1.2 2002/03/22 21:52:05 obrien Exp $"); + +#include "rand48.h" + +uint48 _rand48_seed = RAND48_SEED; +uint48 _rand48_mult = RAND48_MULT; +uint48 _rand48_add = RAND48_ADD; diff --git a/gen/_simple.c b/gen/_simple.c new file mode 100644 index 0000000..9b8aeb1 --- /dev/null +++ b/gen/_simple.c @@ -0,0 +1,689 @@ +/* + * Copyright (c) 2005, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_simple.h" + +#define VM_PAGE_SIZE 4096 +#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 + +typedef struct _BUF { + char *buf; + char *ptr; + char *end; + int fd; + void (*full)(struct _BUF *); +} BUF; + +typedef struct _SBUF { + BUF b; + jmp_buf j; +} SBUF; + +static int asl_socket; +static pthread_once_t asl_socket_once = PTHREAD_ONCE_INIT; + +/* private extern exports from asl.c */ +const char *_asl_escape(unsigned char); +int _asl_server_socket(int *, struct sockaddr_un *); + +/* flush the buffer */ +static void +_flush(BUF *b) +{ + char *buf = b->buf; + int n = b->ptr - buf; + int w; + + while(n > 0) { + w = write(b->fd, buf, n); + if(w < 0) { + if(errno == EINTR || errno == EAGAIN) + continue; + break; + } + n -= w; + buf += n; + } +} + +/* flush the buffer and reset the pointer */ +static void +_flush_reset(BUF *b) +{ + _flush(b); + b->ptr = b->buf; +} + +/* enlarge the buffer */ +static void +_enlarge(BUF *b) +{ + vm_address_t new; + vm_size_t sold, snew; + intptr_t diff; + + new = (vm_address_t)(b->end + 1); + if(vm_allocate(mach_task_self(), &new, VM_PAGE_SIZE, 0) == 0) { + /* page is adjacent */ + b->end += VM_PAGE_SIZE; + return; + } + sold = SBUF_SIZE(b); + snew = (sold + VM_PAGE_SIZE) & ~(VM_PAGE_SIZE - 1); + if(vm_allocate(mach_task_self(), &new, snew, 1) != 0) + longjmp(((SBUF *)b)->j, 1); /* out of memory */ + diff = new - (vm_address_t)b->buf; + memcpy((void *)new, b->buf, sold); + if((intptr_t)(b->buf) & (VM_PAGE_SIZE - 1)) { + sold &= ~(VM_PAGE_SIZE - 1); + b->buf = (char *)((intptr_t)(b->buf + VM_PAGE_SIZE) & ~(VM_PAGE_SIZE - 1)); + b->end = (char *)(new + snew - 1); + } else + b->end += diff + VM_PAGE_SIZE; + if(sold > 0) { + vm_deallocate(mach_task_self(), (vm_address_t)b->buf, sold); + } + b->buf = (char *)new; + b->ptr += diff; +} + +static inline void put_s(BUF *, _esc_func, const char *); +/* output a single character */ +static inline void +put_c(BUF *b, _esc_func esc, unsigned char c) +{ + const char *cp; + + if(esc && (cp = esc(c)) != NULL) + put_s(b, NULL, cp); + else { + if(b->ptr >= b->end) + b->full(b); + *b->ptr++ = c; + } +} + +/* output a null-terminated string */ +static inline void +put_s(BUF *b, _esc_func esc, const char *str) +{ + while(*str) + put_c(b, esc, *str++); +} + +/* output a string of the specified size */ +static inline void +put_n(BUF *b, _esc_func esc, const char *str, int n) +{ + while(n-- > 0) + put_c(b, esc, *str++); +} + +/* + * Output the signed decimal string representing the number in "in". "width" is + * the minimum field width, and "zero" is a boolean value, true for zero padding + * (otherwise blank padding). + */ +static void +dec(BUF *b, _esc_func esc, long long in, int width, int zero) +{ + char buf[32]; + char *cp = buf + sizeof(buf); + int pad; + int neg = 0; + unsigned long long n = (unsigned long long)in; + + if(in < 0) { + neg++; + width--; + n = ~n + 1; + } + *--cp = 0; + if(n) { + while(n) { + *--cp = (n % 10) + '0'; + n /= 10; + } + } else + *--cp = '0'; + if(neg && zero) { + put_c(b, esc, '-'); + neg = 0; + } + pad = width - strlen(cp); + zero = zero ? '0' : ' '; + while(pad-- > 0) + put_c(b, esc, zero); + if(neg) + put_c(b, esc, '-'); + put_s(b, esc, cp); +} + +/* + * Output the hex string representing the number in "n". "width" is the + * minimum field width, and "zero" is a boolean value, true for zero padding + * (otherwise blank padding). "upper" is a boolean value, true for upper + * case hex characters, lower case otherwise. "p" is a boolean value, true + * if 0x should be prepended (for %p), otherwise nothing. + */ +static char _h[] = "0123456789abcdef"; +static char _H[] = "0123456789ABCDEF"; +static char _0x[] = "0x"; + +static void +hex(BUF *b, _esc_func esc, unsigned long long n, int width, int zero, int upper, int p) +{ + char buf[32]; + char *cp = buf + sizeof(buf); + char *h = upper ? _H : _h; + + *--cp = 0; + if(n) { + while(n) { + *--cp = h[n & 0xf]; + n >>= 4; + } + } else + *--cp = '0'; + if(p) { + width -= 2; + if(zero) { + put_s(b, esc, _0x); + p = 0; + } + } + width -= strlen(cp); + zero = zero ? '0' : ' '; + while(width-- > 0) + put_c(b, esc, zero); + if(p) + put_s(b, esc, _0x); + put_s(b, esc, cp); +} + +/* + * Output the unsigned decimal string representing the number in "n". "width" + * is the minimum field width, and "zero" is a boolean value, true for zero + * padding (otherwise blank padding). + */ +static void +udec(BUF *b, _esc_func esc, unsigned long long n, int width, int zero) +{ + char buf[32]; + char *cp = buf + sizeof(buf); + int pad; + + *--cp = 0; + if(n) { + while(n) { + *--cp = (n % 10) + '0'; + n /= 10; + } + } else + *--cp = '0'; + pad = width - strlen(cp); + zero = zero ? '0' : ' '; + while(pad-- > 0) + put_c(b, esc, zero); + put_s(b, esc, cp); +} + +/* + * Output the unsigned decimal string representing the number in "n", rounded + * to the nearest MB, KB or b. "width" is the minimum field width, and "zero" + * is a boolean value, true for zero padding (otherwise blank padding). + */ +static void +ydec(BUF *b, _esc_func esc, unsigned long long n, int width, int zero) +{ + if(n >= 10 * (1 << 20)) { + n += (1 << 19); + udec(b, esc, n >> 20, width, zero); + put_s(b, esc, "MB"); + } else if (n >= 10 * (1 << 10)) { + n += (1 << 9); + udec(b, esc, n >> 10, width, zero); + put_s(b, esc, "KB"); + } else { + udec(b, esc, n, width, zero); + put_s(b, esc, "b"); + } +} + +/* + * The actual engine for all the _simple_*printf routines. + */ +static void +__simple_bprintf(BUF *b, _esc_func esc, const char *fmt, va_list ap) +{ + while(*fmt) { + int lflag, zero, width; + char *cp; + if(!(cp = strchr(fmt, '%'))) { + put_s(b, esc, fmt); + break; + } + put_n(b, esc, fmt, cp - fmt); + fmt = cp + 1; + if(*fmt == '%') { + put_c(b, esc, '%'); + fmt++; + continue; + } + lflag = zero = width = 0; + for(;;) { + switch(*fmt) { + case '0': + zero++; + fmt++; + /* drop through */ + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + while(*fmt >= '0' && *fmt <= '9') + width = 10 * width + (*fmt++ - '0'); + continue; + case 'c': + zero = zero ? '0' : ' '; + width--; + while(width-- > 0) + put_c(b, esc, zero); + put_c(b, esc, va_arg(ap, int)); + break; + case 'd': case 'i': + switch(lflag) { + case 0: + dec(b, esc, va_arg(ap, int), width, zero); + break; + case 1: + dec(b, esc, va_arg(ap, long), width, zero); + break; + default: + dec(b, esc, va_arg(ap, long long), width, zero); + break; + } + break; + case 'l': + lflag++; + fmt++; + continue; + case 'p': + hex(b, esc, (unsigned long)va_arg(ap, void *), width, zero, 0, 1); + break; + case 's': + cp = va_arg(ap, char *); + width -= strlen(cp); + zero = zero ? '0' : ' '; + while(width-- > 0) + put_c(b, esc, zero); + put_s(b, esc, cp); + break; + case 'u': + switch(lflag) { + case 0: + udec(b, esc, va_arg(ap, unsigned int), width, zero); + break; + case 1: + udec(b, esc, va_arg(ap, unsigned long), width, zero); + break; + default: + udec(b, esc, va_arg(ap, unsigned long long), width, zero); + break; + } + break; + case 'X': case 'x': + switch(lflag) { + case 0: + hex(b, esc, va_arg(ap, unsigned int), width, zero, + *fmt == 'X', 0); + break; + case 1: + hex(b, esc, va_arg(ap, unsigned long), width, zero, + *fmt == 'X', 0); + break; + default: + hex(b, esc, va_arg(ap, unsigned long long), width, zero, + *fmt == 'X', 0); + break; + } + break; + case 'y': + switch(lflag) { + case 0: + ydec(b, esc, va_arg(ap, unsigned int), width, zero); + break; + case 1: + ydec(b, esc, va_arg(ap, unsigned long), width, zero); + break; + default: + ydec(b, esc, va_arg(ap, unsigned long long), width, zero); + break; + } + break; + default: + put_c(b, esc, *fmt); + break; + } + break; + } + fmt++; + } +} + +/* + * A simplified vfprintf variant. The format string is interpreted with + * arguments from the va_list, and the results are written to the given + * file descriptor. + */ +void +_simple_vdprintf(int fd, const char *fmt, va_list ap) +{ + BUF b; + char buf[MYBUFSIZE]; + + b.buf = buf; + b.fd = fd; + b.ptr = b.buf; + b.end = b.buf + MYBUFSIZE; + b.full = _flush_reset; + __simple_bprintf(&b, NULL, fmt, ap); + _flush(&b); +} + +/* + * A simplified fprintf variant. The format string is interpreted with + * arguments from the variable argument list, and the results are written + * to the given file descriptor. + */ +void +_simple_dprintf(int fd, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + _simple_vdprintf(fd, fmt, ap); + va_end(ap); +} + +/* + * A simplified string allocate routine. Pass the opaque pointer to structure + * to _simple_*sprintf() routines. Use _simple_string() to retrieve the + * current string (the string is guaranteed to be null terminated only on + * the call to _simple_string()). Use _simple_sfree() to free the structure + * and string memory. + */ +_SIMPLE_STRING +_simple_salloc(void) +{ + SBUF *b; + + if(vm_allocate(mach_task_self(), (vm_address_t *)&b, VM_PAGE_SIZE, 1)) + return NULL; + b->b.ptr = b->b.buf = (char *)b + sizeof(SBUF); + b->b.end = (char *)b + VM_PAGE_SIZE - 1; + b->b.full = _enlarge; + return (_SIMPLE_STRING)b; +} + +/* + * The format string is interpreted with arguments from the va_list, and the + * results are appended to the string maintained by the opaque structure, as + * returned by a previous call to _simple_salloc(). Non-zero is returned on + * out-of-memory error. + */ +int +_simple_vsprintf(_SIMPLE_STRING b, const char *fmt, va_list ap) +{ + return _simple_vesprintf(b, NULL, fmt, ap); +} + +/* + * The format string is interpreted with arguments from the variable argument + * list, and the results are appended to the string maintained by the opaque + * structure, as returned by a previous call to _simple_salloc(). Non-zero is + * returned on out-of-memory error. + */ +int +_simple_sprintf(_SIMPLE_STRING b, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = _simple_vesprintf(b, NULL, fmt, ap); + va_end(ap); + return ret; +} + +/* + * Like _simple_vsprintf(), except __esc is a function to call on each + * character; the function returns NULL if the character should be passed + * as is, otherwise, the returned character string is used instead. + */ +int +_simple_vesprintf(_SIMPLE_STRING b, _esc_func esc, const char *fmt, va_list ap) +{ + if(setjmp(((SBUF *)b)->j)) + return -1; + __simple_bprintf((BUF *)b, esc, fmt, ap); + return 0; +} + +/* + * Like _simple_sprintf(), except __esc is a function to call on each + * character; the function returns NULL if the character should be passed + * as is, otherwise, the returned character string is used instead. + */ +int _simple_esprintf(_SIMPLE_STRING b, _esc_func esc, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = _simple_vesprintf(b, esc, fmt, ap); + va_end(ap); + return ret; +} + +/* + * Return the null terminated string from the opaque structure, as returned + * by a previous call to _simple_salloc(). + */ +char * +_simple_string(_SIMPLE_STRING b) +{ + *((BUF *)b)->ptr = 0; + return ((BUF *)b)->buf; +} + +/* + * Reposition the pointer to the first null in the buffer. After a call to + * _simple_string, the buffer can be modified, and shrunk. + */ +void +_simple_sresize(_SIMPLE_STRING b) +{ + ((BUF *)b)->ptr = ((BUF *)b)->buf + strlen(((BUF *)b)->buf); +} + +/* + * Append the null-terminated string to the string associated with the opaque + * structure. Non-zero is returned on out-of-memory error. + */ +int +_simple_sappend(_SIMPLE_STRING b, const char *str) +{ + return _simple_esappend(b, NULL, str); +} + +/* + * Like _simple_sappend(), except __esc is a function to call on each + * character; the function returns NULL if the character should be passed + * as is, otherwise, the returned character string is used instead. + */ +int _simple_esappend(_SIMPLE_STRING b, _esc_func esc, const char *str) +{ + if(setjmp(((SBUF *)b)->j)) + return -1; + put_s((BUF *)b, esc, str); + return 0; +} + +/* + * Write the string associated with the opaque structure to the file descriptor. + */ +void +_simple_put(_SIMPLE_STRING b, int fd) +{ + ((BUF *)b)->fd = fd; + _flush((BUF *)b); +} + +/* + * Write the string associated with the opaque structure and a trailing newline, + * to the file descriptor. + */ +void +_simple_putline(_SIMPLE_STRING b, int fd) +{ + ((BUF *)b)->fd = fd; + *((BUF *)b)->ptr++ = '\n'; + _flush((BUF *)b); + ((BUF *)b)->ptr--; +} + +/* + * Free the opaque structure, and the associated string. + */ +void +_simple_sfree(_SIMPLE_STRING b) +{ + vm_size_t s; + + 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; + } else + s = ((SBUF *)b)->b.end - (char *)b + 1; + vm_deallocate(mach_task_self(), (vm_address_t)b, s); +} + +/* + * Simplified ASL log interface; does not use malloc. Unfortunately, this + * requires knowledge of the format used by ASL. + */ +static void +socket_init(void) +{ + struct sockaddr_un server; + _asl_server_socket(&asl_socket, &server); +} + +void +_simple_asl_log(int level, const char *facility, const char *message) +{ + _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(_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); +} diff --git a/gen/_simple.h b/gen/_simple.h new file mode 100644 index 0000000..62182d5 --- /dev/null +++ b/gen/_simple.h @@ -0,0 +1,129 @@ +/* + * 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 +#include + +typedef void *_SIMPLE_STRING; +typedef const char *_esc_func(unsigned char); + +__BEGIN_DECLS +/* + * A simplified vfprintf variant. The format string is interpreted with + * arguments from the va_list, and the results are written to the given + * file descriptor. + */ +void _simple_vdprintf(int __fd, const char *__fmt, va_list __ap); + +/* + * A simplified fprintf variant. The format string is interpreted with + * arguments from the variable argument list, and the results are written + * to the given file descriptor. + */ +void _simple_dprintf(int __fd, const char *__fmt, ...); + +/* + * A simplified string allocate routine. Pass the opaque pointer to structure + * to _simple_*sprintf() routines. Use _simple_string() to retrieve the + * current string (the string is guaranteed to be null terminated only on + * the call to _simple_string()). Use _simple_sfree() to free the structure + * and string memory. + */ +_SIMPLE_STRING _simple_salloc(void); + +/* + * The format string is interpreted with arguments from the va_list, and the + * results are appended to the string maintained by the opaque structure, as + * returned by a previous call to _simple_salloc(). Non-zero is returned on + * out-of-memory error. + */ +int _simple_vsprintf(_SIMPLE_STRING __b, const char *__fmt, va_list __ap); + +/* + * The format string is interpreted with arguments from the variable argument + * list, and the results are appended to the string maintained by the opaque + * structure, as returned by a previous call to _simple_salloc(). Non-zero is + * returned on out-of-memory error. + */ +int _simple_sprintf(_SIMPLE_STRING __b, const char *__fmt, ...); + +/* + * Like _simple_vsprintf(), except __esc is a function to call on each + * character; the function returns NULL if the character should be passed + * as is, otherwise, the returned character string is used instead. + */ +int _simple_vesprintf(_SIMPLE_STRING __b, _esc_func __esc, const char *__fmt, va_list __ap); + +/* + * Like _simple_sprintf(), except __esc is a function to call on each + * character; the function returns NULL if the character should be passed + * as is, otherwise, the returned character string is used instead. + */ +int _simple_esprintf(_SIMPLE_STRING __b, _esc_func __esc, const char *__fmt, ...); + +/* + * Return the null terminated string from the opaque structure, as returned + * by a previous call to _simple_salloc(). + */ +char *_simple_string(_SIMPLE_STRING __b); + +/* + * Reposition the pointer to the first null in the buffer. After a call to + * _simple_string, the buffer can be modified, and shrunk. + */ +void _simple_sresize(_SIMPLE_STRING __b); + +/* + * Append the null-terminated string to the string associated with the opaque + * structure. Non-zero is returned on out-of-memory error. + */ +int _simple_sappend(_SIMPLE_STRING __b, const char *__str); + +/* + * Like _simple_sappend(), except __esc is a function to call on each + * character; the function returns NULL if the character should be passed + * as is, otherwise, the returned character string is used instead. + */ +int _simple_esappend(_SIMPLE_STRING __b, _esc_func __esc, const char *__str); + +/* + * Write the string associated with the opaque structure to the file descriptor. + */ +void _simple_put(_SIMPLE_STRING __b, int __fd); + +/* + * Write the string associated with the opaque structure and a trailing newline, + * to the file descriptor. + */ +void _simple_putline(_SIMPLE_STRING __b, int __fd); + +/* + * Free the opaque structure, and the associated string. + */ +void _simple_sfree(_SIMPLE_STRING __b); + +/* + * Simplified ASL log interface; does not use malloc. Unfortunately, this + * requires knowledge of the format used by ASL. + */ +void _simple_asl_log(int __level, const char *__facility, const char *__message); diff --git a/gen/alarm-fbsd.c b/gen/alarm-fbsd.c new file mode 100644 index 0000000..58cce20 --- /dev/null +++ b/gen/alarm-fbsd.c @@ -0,0 +1,61 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +/* + * Backwards compatible alarm. + */ +#include +#include + +unsigned int +alarm(secs) + unsigned int secs; +{ + struct itimerval it, oitv; + struct itimerval *itp = ⁢ + + timerclear(&itp->it_interval); + itp->it_value.tv_sec = secs; + itp->it_value.tv_usec = 0; + if (setitimer(ITIMER_REAL, itp, &oitv) < 0) + return (-1); + if (oitv.it_value.tv_usec) + oitv.it_value.tv_sec++; + return (oitv.it_value.tv_sec); +} diff --git a/gen/alarm.3 b/gen/alarm.3 new file mode 100644 index 0000000..ed12c10 --- /dev/null +++ b/gen/alarm.3 @@ -0,0 +1,98 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd April 19, 1994 +.Dt ALARM 3 +.Os +.Sh NAME +.Nm alarm +.Nd set signal timer alarm +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft unsigned +.Fn alarm "unsigned seconds" +.Sh DESCRIPTION +.Bf -symbolic +This interface is made obsolete by +.Xr setitimer 2 . +.Ef +.Pp +The +.Fn alarm +function sets a timer to deliver the signal +.Dv SIGALRM +to the calling process after the specified number of +.Fa seconds . +If an alarm has already been set with +.Fn alarm +but has not been delivered, another call to +.Fn alarm +will supersede the prior call. +The request +.Fn alarm "0" +voids the current +alarm and the signal SIGALRM will not be delivered. +.Pp +Due to +.Xr setitimer 2 +restriction the maximum number of +.Fa seconds +allowed is 100000000. +.Sh RETURN VALUES +The return value of +.Fn alarm +is the amount of time left on the timer from a previous call to +.Fn alarm . +If no alarm is currently set, the return value is 0. +.Sh SEE ALSO +.Xr setitimer 2 , +.Xr sigaction 2 , +.Xr sigpause 2 , +.Xr sigvec 2 , +.Xr signal 3 , +.Xr sleep 3 , +.Xr ualarm 3 , +.Xr usleep 3 +.\" .Sh STANDARDS +.\" The +.\" .Fn alarm +.\" function conforms to +.\" .St -p1003.1-90 . +.Sh HISTORY +An +.Fn alarm +function appeared in +.At v7 . diff --git a/gen/arc4random-fbsd.c b/gen/arc4random-fbsd.c new file mode 100644 index 0000000..4728787 --- /dev/null +++ b/gen/arc4random-fbsd.c @@ -0,0 +1,235 @@ +/* + * Arc4 random number generator for OpenBSD. + * Copyright 1996 David Mazieres . + * + * 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). + */ + +/* + * 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 + * which is a trade secret). The same algorithm is used as a stream + * cipher called "arcfour" in Tatu Ylonen's ssh package. + * + * Here the stream cipher has been modified always to include the time + * when initializing the state. That makes it impossible to + * regenerate the same random sequence twice, so this can't be used + * for encryption, but will generate good random numbers. + * + * RC4 is a registered trademark of RSA Laboratories. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.10 2004/03/24 14:44:57 green Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include + +#include "libc_private.h" +#include "un-namespace.h" + +struct arc4_stream { + u_int8_t i; + u_int8_t j; + u_int8_t s[256]; +}; + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; + +#define RANDOMDEV "/dev/urandom" +#define THREAD_LOCK() \ + do { \ + if (__isthreaded) \ + _pthread_mutex_lock(&arc4random_mtx); \ + } while (0) + +#define THREAD_UNLOCK() \ + do { \ + if (__isthreaded) \ + _pthread_mutex_unlock(&arc4random_mtx); \ + } while (0) + +static struct arc4_stream rs; +static int rs_initialized; +static int rs_stired; + +static inline u_int8_t arc4_getbyte(struct arc4_stream *); +static void arc4_stir(struct arc4_stream *); + +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 inline void +arc4_addrandom(as, dat, datlen) + struct arc4_stream *as; + u_char *dat; + int datlen; +{ + int n; + u_int8_t si; + + as->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; + } +} + +static void +arc4_stir(as) + struct arc4_stream *as; +{ + 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(); + fd = _open(RANDOMDEV, O_RDONLY, 0); + if (fd >= 0) { + (void) _read(fd, rdat.rnd, sizeof(rdat.rnd)); + _close(fd); + } + /* fd < 0? Ah, what the heck. We'll just take whatever was on the + * stack... */ + + arc4_addrandom(as, (u_char *) &rdat, sizeof(rdat)); + + /* + * Throw away the first N bytes of output, as suggested in the + * paper "Weaknesses in the Key Scheduling Algorithm of RC4" + * by Fluher, Mantin, and Shamir. N=1024 is based on + * suggestions in the paper "(Not So) Random Shuffles of RC4" + * by Ilya Mironov. + */ + for (n = 0; n < 1024; n++) + arc4_getbyte(as); +} + +static inline u_int8_t +arc4_getbyte(as) + struct arc4_stream *as; +{ + 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; + + return (as->s[(si + sj) & 0xff]); +} + +static inline u_int32_t +arc4_getword(as) + struct arc4_stream *as; +{ + u_int32_t val; + + val = arc4_getbyte(as) << 24; + val |= arc4_getbyte(as) << 16; + val |= arc4_getbyte(as) << 8; + val |= arc4_getbyte(as); + + return (val); +} + +static void +arc4_check_init(void) +{ + if (!rs_initialized) { + arc4_init(&rs); + rs_initialized = 1; + } +} + +static void +arc4_check_stir(void) +{ + if (!rs_stired) { + arc4_stir(&rs); + rs_stired = 1; + } +} + +void +arc4random_stir() +{ + THREAD_LOCK(); + arc4_check_init(); + arc4_stir(&rs); + THREAD_UNLOCK(); +} + +void +arc4random_addrandom(dat, datlen) + u_char *dat; + int datlen; +{ + THREAD_LOCK(); + arc4_check_init(); + arc4_check_stir(); + arc4_addrandom(&rs, dat, datlen); + THREAD_UNLOCK(); +} + +u_int32_t +arc4random() +{ + u_int32_t rnd; + + THREAD_LOCK(); + arc4_check_init(); + arc4_check_stir(); + rnd = arc4_getword(&rs); + THREAD_UNLOCK(); + + return (rnd); +} + +#if 0 +/*-------- Test code for i386 --------*/ +#include +#include +int +main(int argc, char **argv) +{ + const int iter = 1000000; + int i; + pctrval v; + + v = rdtsc(); + for (i = 0; i < iter; i++) + arc4random(); + v = rdtsc() - v; + v /= iter; + + printf("%qd cycles\n", v); +} +#endif diff --git a/gen/arc4random.3 b/gen/arc4random.3 deleted file mode 100644 index 85e6eb0..0000000 --- a/gen/arc4random.3 +++ /dev/null @@ -1,89 +0,0 @@ -.\" $OpenBSD: arc4random.3,v 1.2 1997/04/27 22:40:25 angelos Exp $ -.\" Copyright 1997 Niels Provos -.\" 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 Niels Provos. -.\" 4. 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 ``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. -.\" -.\" Manual page, using -mandoc macros -.\" $FreeBSD: src/lib/libc/gen/arc4random.3,v 1.12 2001/10/01 16:08:50 ru Exp $ -.\" -.Dd April 15, 1997 -.Dt ARC4RANDOM 3 -.Os -.Sh NAME -.Nm arc4random , -.Nm arc4random_stir , -.Nm arc4random_addrandom -.Nd arc4 random number generator -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In stdlib.h -.Ft u_int32_t -.Fn arc4random "void" -.Ft void -.Fn arc4random_stir "void" -.Ft void -.Fn arc4random_addrandom "unsigned char *dat" "int datlen" -.Sh DESCRIPTION -The -.Fn arc4random -function uses the key stream generator employed by the -arc4 cipher, which uses 8*8 8 bit S-Boxes. -The S-Boxes -can be in about -.if t 2\u\s71700\s10\d -.if n (2**1700) -states. -.Pp -The -.Fn arc4random_stir -function reads data from -.Pa /dev/urandom -and uses it to permute the S-Boxes via -.Fn arc4random_addrandom . -.Pp -There is no need to call -.Fn arc4random_stir -before using -.Fn arc4random , -since -.Fn arc4random -automatically initializes itself. -.Sh SEE ALSO -.Xr rand 3 , -.Xr random 3 , -.Xr srandomdev 3 -.Sh HISTORY -.Pa RC4 -has been designed by RSA Data Security, Inc. -It was posted anonymously -to the USENET and was confirmed to be equivalent by several sources who -had access to the original cipher. -Since -.Pa RC4 -used to be a trade secret, the cipher is now referred to as -.Pa ARC4 . diff --git a/gen/arc4random.3 b/gen/arc4random.3 new file mode 120000 index 0000000..c4c8a0f --- /dev/null +++ b/gen/arc4random.3 @@ -0,0 +1 @@ +./arc4random.3 \ No newline at end of file diff --git a/gen/asl.3 b/gen/asl.3 index 1bb63d4..1ebef2b 100644 --- a/gen/asl.3 +++ b/gen/asl.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2005 Apple Computer +.\" Copyright (c) 2005-2007 Apple Inc. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -26,105 +26,174 @@ .\" SUCH DAMAGE. .\" .\" -.Dd January 5, 2005 +.Dd January 11, 2007 .Dt asl 3 .Os "Mac OS X" .Sh NAME -.Nm asl_open , +.Nm asl_add_log_file , .Nm asl_close , -.Nm asl_new , .Nm asl_free , -.Nm asl_set , -.Nm asl_set_query , .Nm asl_get , -.Nm asl_unset , -.Nm asl_log , -.Nm asl_vlog , -.Nm asl_send , .Nm asl_key , -.Nm asl_add_log_file , +.Nm asl_log , +.Nm asl_new , +.Nm asl_open , .Nm asl_remove_log_file , -.Nm asl_set_cutoff_level , .Nm asl_search , -.Nm aslresponse_next , -.Nm aslresponse_free +.Nm asl_send , +.Nm asl_set , +.Nm asl_set_filter , +.Nm asl_set_query , +.Nm asl_unset , +.Nm asl_vlog , +.Nm aslresponse_free , +.Nm aslresponse_next .Nd system log message sending and searching functions .Sh SYNOPSIS .Fd #include -.Ft aslclient -.Fn asl_open "const char *ident, const char *facility, uint32_t opts" +.\" +.Ft int +.Fo asl_add_log_file +.Fa "aslclient asl" +.Fa "int fd" +.Fc .Ft void -.Fn asl_close "aslclient asl" -.Ft aslmsg -.Fn asl_new "uint32_t type" +.Fo asl_close +.Fa "aslclient asl" +.Fc .Ft void -.Fn asl_free "aslmsg msg" -.Ft int -.Fn asl_set "aslmsg msg, const char *key, const char *value" -.Ft int -.Fn asl_set_query "aslmsg msg, const char *key, const char *value, uint32_t op" +.Fo asl_free +.Fa "aslmsg msg" +.Fc .Ft const char * -.Fn asl_key "aslmsg msg, uint32_t n" +.Fo asl_get +.Fa "aslmsg msg" +.Fa "const char *key" +.Fc .Ft const char * -.Fn asl_get "aslmsg msg, const char *key" +.Fo asl_key +.Fa "aslmsg msg" +.Fa "uint32_t n" +.Fc .Ft int -.Fn asl_unset "aslmsg msg, const char *key" +.Fo asl_log +.Fa "aslclient asl" +.Fa "aslmsg msg" +.Fa "int level" +.Fa "const char *format" +.Fa "..." +.Fc +.Ft aslmsg +.Fo asl_new +.Fa "uint32_t type" +.Fc +.Ft aslclient +.Fo asl_open +.Fa "const char *ident" +.Fa "const char *facility" +.Fa "uint32_t opts" +.Fc .Ft int -.Fn asl_log "aslclient asl, aslmsg msg, int level, const char *format, ..." +.Fo asl_remove_log_file +.Fa "aslclient asl" +.Fa "int fd" +.Fc +.Ft aslresponse +.Fo asl_search +.Fa "aslclient asl" +.Fa "aslmsg msg" +.Fc .Ft int -.Fn asl_vlog "aslclient asl, aslmsg msg, int level, const char *format, va_list ap" +.Fo asl_send +.Fa "aslclient asl" +.Fa "aslmsg msg" +.Fc .Ft int -.Fn asl_send "aslclient asl, aslmsg msg" +.Fo asl_set +.Fa "aslmsg msg" +.Fa "const char *key" +.Fa "const char *value" +.Fc .Ft int -.Fn asl_add_log_file "aslclient asl, int fd" +.Fo asl_set_filter +.Fa "aslclient asl" +.Fa "int f" +.Fc .Ft int -.Fn asl_remove_log_file "aslclient asl, int fd" +.Fo asl_set_query +.Fa "aslmsg msg" +.Fa "const char *key" +.Fa "const char *value" +.Fa "uint32_t op" +.Fc .Ft int -.Fn asl_set_filter "aslclient asl, int f" -.Ft aslresponse -.Fn asl_search "aslclient asl, aslmsg msg" -.Ft aslmsg -.Fn aslresponse_next "aslresponse r" +.Fo asl_unset +.Fa "aslmsg msg" +.Fa "const char *key" +.Fc +.Ft int +.Fo asl_vlog +.Fa "aslclient asl" +.Fa "aslmsg msg" +.Fa "int level" +.Fa "const char *format" +.Fa "va_list ap" +.Fc .Ft void -.Fn aslresponse_free "aslresponse a" +.Fo aslresponse_free +.Fa "aslresponse a" +.Fc +.Ft aslmsg +.Fo aslresponse_next +.Fa "aslresponse r" +.Fc .Sh DESCRIPTION -These routines provide an interface to the Apple system log facility. +These routines provide an interface to the Apple System Log facility. They are intended to be a replacement for the .Xr syslog 3 API, which will continue to be supported for backwards compatibility. -The new API allows client applications to create flexible, structured messages and send them to the +The new API allows client applications +to create flexible, structured messages and send them to the .Nm syslogd server, where they may undergo additional processing. -Messages received by the server are saved in a data store (subject to input filtering constraints). -This API permits clients to create queries and search the message data store for matching messages. +Messages received by the server are saved in a data store +(subject to input filtering constraints). +This API permits clients to create queries +and search the message data store for matching messages. .Ss MESSAGES At the core of this API is the aslmsg structure. -Although the structure is opaque and may not be directly manipulated, it contains a list of key/value pairs. +Although the structure is opaque and may not be directly manipulated, +it contains a list of key/value pairs. All keys and values are NULL-terminated C language character strings. UTF-8 encoding may be used for non-ASCII characters. .Pp -Message structures are generally used to send log messages, and are created thusly: +Message structures are generally used to send log messages, +and are created thusly: .Pp aslmsg m = asl_new(ASL_TYPE_MSG); .Pp -Another message type, ASL_TYPE_QUERY, is used to create queries when searching the data store. +Another message type, ASL_TYPE_QUERY, +is used to create queries when searching the data store. Query type messages and searching are described in detail in the .Sx SEARCHING section below. -For the remainder of this section, the messages described will be of the ASL_TYPE_MSG variety. +For the remainder of this section, +the messages described will be of the ASL_TYPE_MSG variety. .Pp -Each aslmsg contains a default set of keys and values associated with them. +Each aslmsg contains a default set of keys +and values that are associated with them. These keys are listed in the asl.h header file. They are: .Pp - #define ASL_KEY_TIME "Time" - #define ASL_KEY_HOST "Host" - #define ASL_KEY_SENDER "Sender" - #define ASL_KEY_PID "PID" - #define ASL_KEY_UID "UID" - #define ASL_KEY_GID "GID" - #define ASL_KEY_LEVEL "Level" - #define ASL_KEY_MSG "Message" + #define ASL_KEY_TIME "Time" + #define ASL_KEY_HOST "Host" + #define ASL_KEY_SENDER "Sender" + #define ASL_KEY_FACILITY "Facility" + #define ASL_KEY_PID "PID" + #define ASL_KEY_UID "UID" + #define ASL_KEY_GID "GID" + #define ASL_KEY_LEVEL "Level" + #define ASL_KEY_MSG "Message" .Pp Many of these correspond to equivalent parts of messages described in the .Xr syslog 3 @@ -136,12 +205,12 @@ the ASL_KEY_PID is the client's process ID number, and so on. .Pp Note the addition of the UID and GID keys. The values for UID and GID are set in library code by the message sender. -The server will attempt to confirm the values, but no claim is made that these -values cannot be maliciously overridden in an attempt to deceive a log message -reader as to the identity of the sender of a message. +The server will attempt to confirm the values, +but no claim is made that these values cannot be maliciously overridden +in an attempt to deceive a log message reader +as to the identity of the sender of a message. The contents of log messages must be regarded as insecure. .Pp -Also note the absence of a Facility key. The .Xr asl 3 API does not require a process to choose a facility name. @@ -150,25 +219,35 @@ The server will use a default value of .Dq user if a facility is not set. -However, a client may set a facility name using: +However, a client may set a facility name as an argument in the +.Nm asl_open +call, or by setting a specific value for the ASL_KEY_FACILITY in a message: .Pp - asl_set(m, "Facility", "UsefulService"); + asl_set(m, ASL_KEY_FACILITY, "com.somename.greatservice"); .Pp An application may choose any facility name at will. -.Pp -Default values are set in the message for each of the keys listed above except for -ASL_KEY_MSG, which may be explicitly set at any time using the +Different facility names may be attached to different messages, perhaps to distinguish different subsystems in log messages. +Developers are encouraged to adopt a +.Dq Reverse ICANN +naming convention to avoid conflicting facility names. +.Pp +Default values are set in the message for each of the keys listed above, +except for ASL_KEY_MSG, +which may be explicitly set at any time using the .Nm asl_set routine, or implicitly set at the time the message is sent using the .Nm asl_log or .Nm asl_vlog routines. -These two routines also have an integer level parameter for specifying the log priority. +These two routines also have an integer-level parameter +for specifying the log priority. The ASL_KEY_LEVEL value is set accordingly. -Finally, the value associated with ASL_KEY_TIME is set in the sending routine. +Finally, the value associated with ASL_KEY_TIME +is set in the sending routine. .Pp -Although it may appear that there is significant overhead required to send a log message using this API, +Although it may appear that there is significant overhead required +to send a log message using this API, the opposite is actually true. A simple .Dq Hello World @@ -182,24 +261,27 @@ Both .Nm asl_log and .Nm asl_vlog -will provide the appropriate default values when passed a NULL aslmsg argument. +will provide the appropriate default values +when passed a NULL aslmsg argument. .Pp .Pp In this example, the aslclient argument is NULL. This is sufficient for a single-threaded application, or for an application which only sends log messages from a single thread. -When logging from multiple threads, each thread must open a separate client handle using +When logging from multiple threads, +each thread must open a separate client handle using .Nm asl_open . The client handle may then be closed when it is no longer required using .Nm asl_close . .Pp -When an application requires additional keys and values to be associated with each log message, +When an application requires additional keys and values +to be associated with each log message, a single message structure may be allocated and set up as .Dq template message of sorts: .Pp aslmsg m = asl_new(ASL_TYPE_MSG); - asl_set(m, "Facility", "Spy vs. Spy"); + asl_set(m, ASL_KEY_FACILITY, "com.secrets.r.us"); asl_set(m, "Clearance", "Top Secret"); ... asl_log(NULL, m, ASL_LEVEL_NOTICE, "Message One"); @@ -212,7 +294,24 @@ and .Dq Clearance keys so that they are used in each call to .Nm asl_log , -while the log level and the message text are taken from the calling parameters. +while the log level and the message text +are taken from the calling parameters. +.Pp +The +.Ar format +argument to +.Nm asl_log +and +.Nm asl_vlog +is identical to +.Xr printf 3 , +and may include +.Ql %m , +which is replaced by the current error message +(as denoted by the global variable +.Va errno ; +see +.Xr strerror 3 . ) .Pp Key/value pairs may be removed from a message structure with .Nm asl_unset . @@ -226,13 +325,54 @@ routine is used by and .Nm asl_vlog to transmit a message to the server. -This routine sets the value associated with ASL_KEY_TIME and send the message. -It may be called directly if all of a message's key/value pairs have been created using +This routine sets the value associated with ASL_KEY_TIME +and sends the message. +It may be called directly if all of a message's key/value pairs +have been created using .Nm asl_set . +.Ss SECURITY +Messages that are sent to the +.Nm syslogd +server may be saved in a message store. +The store may be searched using +.Nm asl_search , +as described below. +By default, all messages are readable by any user. +However, some applications may wish to restrict read access +for some messages. +To accomodate this, +a client may set a value for the "ReadUID" and "ReadGID" keys. +These keys may be associated with a value +containing an ASCII representation of a numeric UID or GID. +Only the root user (UID 0), +the user with the given UID, +or a member of the group with the given GID +may fetch access-controlled messages from the database. +.Pp +Although the ASL system does not require a "Facility" key in a message, +many processes specify a "Facility" value similar +to the common usage of the BSD +.Nm syslog +API, although developers are encouraged to adopt facility names that make sense for their application. +A +.Dq Reverse ICANN +naming convention (e.g. "com.apple.system.syslog") should be adopted to avoid conflicting names. +The ASL system generally allows any string to be used as a facility value, +with one exception. +The value "com.apple.system", +or any string that has "com.apple.system" as a prefix, +may only be used by processes running with the UID 0. +This allows system processes to log messages that can not be "spoofed" by user processes. +Non-UID 0 client processes that specify "com.apple.system" as a facility, will be assigned the value "user" +by the +.Nm syslogd +server. .Ss CLIENT HANDLES When logging is done from a single thread, -a NULL value may be used in any of the routines that require an aslclient argument. -In this case the library will open an internal client handle on behalf of the application. +a NULL value may be used in any of the routines +that require an aslclient argument. +In this case, the library will open an internal client handle +on behalf of the application. .Pp If multiple threads must do logging, or if client options are desired, @@ -245,7 +385,7 @@ the routine may be given an ident argument, which becomes the default value for the ASL_KEY_SENDER key, and a facility argument, -which becomes the default facility name for the application. +which becomes the value associated with the ASL_KEY_FACILITY key. .Pp Several options are available when creating a client handle. They are: @@ -265,8 +405,9 @@ for additional details on filter controls. .Pp A client handle is closed and it's resources released using .Nm asl_close . -Note that if additional file descriptors were added to the handle either using the -ASL_OPT_STDERR option or afterwards with the +Note that if additional file descriptors were added to the handle, +either using the ASL_OPT_STDERR option +or afterwards with the .Nm asl_add_log_file routine, those file descriptors are not closed by .Nm asl_close . @@ -276,21 +417,35 @@ If a client handle is opened with the ASL_OPT_STDERR option to a copy of each log message will be sent to stderr. Additional output streams may be include using .Nm asl_add_log_file . -File descriptors may be removed from the list of outputs associated with a client handle with +.Pp +Messages sent to stderr or other files are printed in the "standard" message format +also used as a default format by the +.Xr syslog 1 +command line utility. +The +.Xr strvis 3 +encoding with the VIS_CSTYLE, VIS_TAB, and VIS_NL options is used to print the message. +.Pp +File descriptors may be removed from the list of outputs associated +with a client handle with .Nm asl_remove_log_file . This routine simply removes the file descriptor from the output list. The file is not closed as a result. .Pp -The ASL_OPT_STDERR option may not be unset after a client handle has been opened. +The ASL_OPT_STDERR option may not be unset +after a client handle has been opened. .Pp In the present release of Mac OS X, a .Dq raw -format is used to format messages sent to file descriptors added to a client handle. +format is used to format messages +that are sent to file descriptors +that have been added to a client handle. Each message is preceded by a 10-character field containing a message length. The message length is padded with leading white space. The length gives the string length of the remainder of the output string. Following the length is a space character, and then the message. -The message is encoded as a set of key/value pairs enclosed in square brackets, +The message is encoded as a set of key/value pairs +enclosed in square brackets, which are themselves separated by a space character. The key is separated from the value by space character. Embedded closing square brackets are escaped by a backslash. @@ -300,7 +455,8 @@ The output is terminated by a trailing newline and a NUL character. .Ss SEARCHING The .Nm syslogd -server archives received messages in a data store that may be searched using the +server archives received messages in a data store +that may be searched using the .Nm asl_search , .Nm aslresponse_next , and @@ -329,7 +485,8 @@ Like other messages, ASL_TYPE_QUERY messages contain keys and values. They also associate an operation with each key and value. The operation is used to decide if a message matches the query. The simplest operation is ASL_QUERY_OP_EQUAL, which tests for equality. -For example, the following code snippet searches for messages with a Sender value equal to +For example, the following code snippet searches for messages +with a Sender value equal to .Dq MyApp . .Pp aslmsg m; @@ -364,8 +521,8 @@ Regular expression search uses library. Patterns are compiled using the REG_EXTENDED and REG_NOSUB options. .Pp -Modifiers that change the behavior of these operations may also be specified -by ORing the modifier value with the operation. +Modifiers that change the behavior of these operations +may also be specified by ORing the modifier value with the operation. The modifiers are: .Pp .Bl -tag -width "ASL_QUERY_OP_SUBSTRING" -compact @@ -382,8 +539,10 @@ values are converted to integer using .Nm atoi .El .Pp -The only modifier that is checked for ASL_QUERY_OP_REGEX search is ASL_QUERY_OP_CASEFOLD. -This causes the regular expression to be compiled with the REG_ICASE option. +The only modifier that is checked +for ASL_QUERY_OP_REGEX search is ASL_QUERY_OP_CASEFOLD. +This causes the regular expression to be compiled +with the REG_ICASE option. .Pp If a query message contains more than one set of key/value/operation triples, the result will be a logical AND. For example, to find messages from @@ -434,19 +593,25 @@ Clients may set a filter mask value with The mask specifies which messages should be sent to the .Nm syslogd daemon by specifying a yes/no setting for each priority level. -Clients typically set a filter mask to avoid sending relatively unimportant messages. -For example, Debug or Info priority level messages are generally only useful for debugging operations. -By setting a filter mask, a process can improve performance by avoiding -sending messages that are in most cases unnecessary. +Clients typically set a filter mask +to avoid sending relatively unimportant messages. +For example, Debug or Info priority level messages +are generally only useful for debugging operations. +By setting a filter mask, a process can improve performance +by avoiding sending messages that are in most cases unnecessary. +.Pp +.Nm asl_set_filter returns the previous value of the filter, i.e. the value of the filter before the routine was called. .Pp As a convenience, the macros ASL_FILTER_MASK(level) and ASL_FILTER_MASK_UPTO(level) may be used to construct a bit mask corresponding to a given priority level, -or corresponding to a bit mask for all priority levels from ASL_LEVEL_EMERG to a -given input level. +or corresponding to a bit mask for all priority levels +from ASL_LEVEL_EMERG to a given input level. .Pp The default filter mask is ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE). -This means that by default, and in the absence of remote-control changes (described below), -ASL_LEVEL_DEBUG and ASL_LEVEL_INFO priority level messages are not sent to the +This means that by default, +and in the absence of remote-control changes (described below), +ASL_LEVEL_DEBUG and ASL_LEVEL_INFO priority level messages +are not sent to the .Mn syslogd server. .Pp @@ -457,20 +622,24 @@ as described above. The Apple System Log facility also manages a .Dq master filter mask. -The master filter mask usually has a value that indicates to the library that it is +The master filter mask usually has a value +that indicates to the library that it is .Dq off , and thus it has no effect. -However, the mask filter mask may be enabled by giving it a value using the +However, the mask filter mask may be enabled +by giving it a value using the .Nm syslog command, using the .Fl c 0 option. When the master filter mask has been set, it takes precedence over the client's filter mask. -The client's mask is unmodified, and will become active again if remote-control filtering is disabled. +The client's mask is unmodified, +and will become active again if remote-control filtering is disabled. .Pp In addition to the master filter mask, -The Apple System Log facility also manages a per-client remote-control filter mask. +The Apple System Log facility +also manages a per-client remote-control filter mask. Like the master filter mask, the per-client mask is usually .Dq off , having no effect on a client. @@ -478,21 +647,27 @@ If a per-client filter mask is set using the .Nm syslog command, using the .Fl c Ar process -option, then it takes precedence over both the client's filter mask and the master filter mask. -As is the case with the master filter mask, a per-client mask ceases having any effect when if is disabled. +option, then it takes precedence +over both the client's filter mask and the master filter mask. +As is the case with the master filter mask, +a per-client mask ceases having any effect when if is disabled. .Pp The ASL_OPT_NO_REMOTE option to .Nm asl_open -causes both the master and per-client remote-control masks to be ignored in the library. -In that case, only the client's own filter mask is used to determine which messages are -sent to the server. -This may be useful for Applications that produce log messages that should never be filtered -due to security considerations. -Note that root (administrator) access is required to set or change the master filter mask, -and that only root may change a per-client remote-control filter mask for a root (UID 0) process. +causes both the master and per-client remote-control masks +to be ignored in the library. +In that case, only the client's own filter mask +is used to determine which messages are sent to the server. +This may be useful for Applications that produce log messages +that should never be filtered, due to security considerations. +Note that root (administrator) access is required +to set or change the master filter mask, +and that only root may change a per-client remote-control filter mask +for a root (UID 0) process. .Sh HISTORY These functions first appeared in Mac OS X 10.4. .Sh SEE ALSO -.Xr syslogd 8 , -.Xr syslog 1 +.Xr syslog 1 , +.Xr strvis 3 , +.Xr syslogd 8 diff --git a/gen/asl.c b/gen/asl.c index 4253574..a5d07fc 100644 --- a/gen/asl.c +++ b/gen/asl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004-2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,6 +23,7 @@ */ #include +#include #include #include #include @@ -37,9 +38,15 @@ #include #include #include +#include +#include +#include +#include +#include #include +#include -#define _PATH_ASL_IN "/var/run/asl_input" +#define ASL_SERVICE_NAME "com.apple.system.logger" #define streq(A, B) (strcmp(A, B) == 0) #define strcaseeq(A, B) (strcasecmp(A, B) == 0) @@ -52,15 +59,51 @@ #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 ENCODE_NONE 0 +#define ENCODE_VIS 1 +#define ENCODE_ASL 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__ asl_client_t *_asl_open_default(); /* notify SPI */ -uint32_t notify_get_state(int token, int *state); uint32_t notify_register_plain(const char *name, int *out_token); +/* from asl_util.c */ +int _asl_server_socket(int *sock, struct sockaddr_un *server); +int asl_is_utf8(const char *str); +uint8_t *asl_b64_encode(const uint8_t *buf, size_t len); + +/* 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, + 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"; + typedef struct { int notify_count; @@ -74,27 +117,14 @@ typedef struct #ifndef BUILDING_VARIANT __private_extern__ _asl_global_t _asl_global = {0, -1, -1, NULL, PTHREAD_MUTEX_INITIALIZER, NULL}; +static mach_port_t asl_server_port = MACH_PORT_NULL; + static int _asl_connect(asl_client_t *asl) { - uint32_t len, status; - if (asl->sock >= 0) return 0; - asl->sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (asl->sock < 0) return -1; - - memset(&(asl->server), 0, sizeof(struct sockaddr_un)); - asl->server.sun_family = AF_UNIX; - - strcpy(asl->server.sun_path, _PATH_ASL_IN); - len = sizeof(asl->server.sun_len) + sizeof(asl->server.sun_family) + strlen(asl->server.sun_path) + 1; - asl->server.sun_len = strlen(_PATH_ASL_IN) + 1; - - status = connect(asl->sock, (const struct sockaddr *)&(asl->server), len); - - if (status < 0) return -1; - return 0; + return _asl_server_socket(&asl->sock, &asl->server); } static int @@ -155,7 +185,7 @@ _asl_notify_close() 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); _asl_global.notify_token = -1; @@ -197,6 +227,12 @@ asl_open(const char *ident, const char *facility, uint32_t opts) if (ident != NULL) { asl->name = strdup(ident); + if (asl->name == NULL) + { + close(asl->sock); + free(asl); + return NULL; + } } else { @@ -207,14 +243,29 @@ asl_open(const char *ident, const char *facility, uint32_t opts) if (x != NULL) x++; else x = name; asl->name = strdup(x); + if (asl->name == NULL) + { + close(asl->sock); + free(asl); + return NULL; + } } } + 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) + { + close(asl->sock); + free(asl); + return NULL; + } if (!(asl->options & ASL_OPT_NO_REMOTE)) _asl_notify_open(1); + if (asl->options & ASL_OPT_STDERR) asl_add_output((aslclient)asl, fileno(stderr), ASL_MSG_FMT_STD, ASL_TIME_FMT_LCL); + return (aslclient)asl; } @@ -222,6 +273,7 @@ void asl_close(aslclient ac) { asl_client_t *asl; + uint32_t i; asl = (asl_client_t *)ac; if (asl == NULL) return; @@ -232,6 +284,18 @@ asl_close(aslclient ac) 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); + } + memset(asl, 0, sizeof(asl_client_t)); free(asl); } @@ -260,7 +324,7 @@ _asl_open_default() _asl_notify_open(0); pthread_mutex_unlock(&_asl_global.lock); - + return _asl_global.asl; } @@ -282,24 +346,194 @@ _asl_msg_index(asl_msg_t *msg, const char *k) } static void -_asl_append_string(char **m, uint32_t *x, char *s, uint32_t encode, uint32_t escspace) +_asl_encode_char(char **m, uint32_t *x, uint32_t c, uint32_t encode, uint32_t encode_space) { - uint32_t i, n; + char *p; + int meta; + + meta = 0; + + p = *m + *x - 1; + + /* 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'; + *x = *x + 4; + return; + } + + *p++ = '\\'; + *p++ = 'M'; + *p = '\0'; + *x = *x + 2; + c &= 0x7f; + meta = 1; + } + + /* space is either ' ' or \s */ + if (c == 32) + { + if (encode_space == 0) + { + *p++ = ' '; + *p = '\0'; + *x = *x + 1; + return; + } + + *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 ] ane escaped in ASL encoding */ + if ((encode == ENCODE_ASL) && (meta == 0) && ((c == 91) || (c == 93))) + { + *p++ = '\\'; + *p++ = c; + *p = '\0'; + *x = *x + 2; + return; + } + + /* DEL is \^? */ + if (c == 127) + { + if (meta == 0) + { + *p++ = '\\'; + *x = *x + 1; + } + + *p++ = '^'; + *p++ = '?'; + *p = '\0'; + *x = *x + 2; + return; + } + + /* 33-126 are printable (add a '-' prefix for meta) */ + if ((c >= 33) && (c <= 126)) + { + if (meta == 1) + { + *p++ = '-'; + *x = *x + 1; + } + + *p++ = c; + *p = '\0'; + *x = *x + 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'; + *x = *x + 2; + return; + } + + /* 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; + } + + return; +} + +static void +_asl_append_string(char **m, uint32_t *x, const char *s, uint32_t encode, uint32_t escspace) +{ + uint32_t i, n, spextra; + uint8_t c; if (m == NULL) return; if (x == NULL) return; if (s == NULL) return; + if (encode == ENCODE_NONE) + { + 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; + } + + spextra = 0; + + if (escspace != 0) spextra = 1; + n = 0; - if (encode == 0) n = strlen(s); - else + for (i = 0; s[i] != '\0'; i++) { - for (i = 0; s[i] != '\0'; i++) + c = s[i]; + + if (c >= 128) + { + n += 4; + } + else if ((c == 91) || (c == 93)) + { + if (encode == ENCODE_ASL) n += 2; + else n += 1; + } + else { - if (s[i] == '\\') n++; - else if (s[i] == ']') n++; - else if ((escspace != 0) && (s[i] == ' ')) n++; - n++; + n += char_encode_len[c]; + if (c == 32) n += spextra; } } @@ -312,33 +546,165 @@ _asl_append_string(char **m, uint32_t *x, char *s, uint32_t encode, uint32_t esc } else { - *m = realloc(*m, n + (*x)); + *m = reallocf(*m, n + (*x)); } - if (encode == 0) + if (*m == NULL) return; + + for (i = 0; s[i] != '\0'; i++) { - memcpy((*m) + (*x) - 1, s, n + 1); - *x += n; - return; + c = s[i]; + _asl_encode_char(m, x, c, encode, escspace); } - n = *x - 1; - for (i = 0; s[i] != '\0'; i++) + 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++) { - if ((s[i] == '\\') || (s[i] == ']') || ((escspace != 0) && (s[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 { - (*m)[n++] = '\\'; - (*m)[n++] = s[i]; + p = *m + *x - 1; + *p++ = c; + *p = '\0'; + *x = *x + 1; } - else if (s[i] == '\n') (*m)[n++] = ';'; - else (*m)[n++] = s[i]; } - (*m)[n++] = '\0'; + 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; - *x = n; + if (tag == XML_TAG_KEY) + { + _asl_append_string(m, x, "\t\t", ENCODE_NONE, 0); + _asl_append_xml_string(m, x, s); + _asl_append_string(m, x, "\n", ENCODE_NONE, 0); + return; + } - return; + if (tag == XML_TAG_STRING) + { + _asl_append_string(m, x, "\t\t", ENCODE_NONE, 0); + _asl_append_xml_string(m, x, s); + _asl_append_string(m, x, "\n", ENCODE_NONE, 0); + return; + } + + if (tag == XML_TAG_DATA) + { + _asl_append_string(m, x, "\t\t", ENCODE_NONE, 0); + b64 = (char *)asl_b64_encode((uint8_t *)s, strlen(s)); + if (b64 != NULL) + { + _asl_append_string(m, x, b64, ENCODE_NONE, 0); + free(b64); + } + _asl_append_string(m, x, "\n", ENCODE_NONE, 0); + return; + } } static void @@ -350,12 +716,12 @@ _asl_append_op(char **m, uint32_t *x, uint32_t op) if (m == NULL) return; if (x == NULL) return; - if (op == ASL_QUERY_OP_NULL) return _asl_append_string(m, x, ".", 0, 0); + if (op == ASL_QUERY_OP_NULL) return _asl_append_string(m, x, ".", ENCODE_NONE, 0); i = 0; if (op & ASL_QUERY_OP_CASEFOLD) opstr[i++] = 'C'; - if (op & ASL_QUERY_OP_CASEFOLD) opstr[i++] = 'R'; + if (op & ASL_QUERY_OP_REGEX) opstr[i++] = 'R'; if (op & ASL_QUERY_OP_NUMERIC) opstr[i++] = 'N'; @@ -395,10 +761,101 @@ _asl_append_op(char **m, uint32_t *x, uint32_t op) break; } - if (i == 0) return _asl_append_string(m, x, ".", 0, 0); + if (i == 0) return _asl_append_string(m, x, ".", ENCODE_NONE, 0); opstr[i++] = '\0'; - return _asl_append_string(m, x, opstr, 0, 0); + return _asl_append_string(m, x, opstr, 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, " [", ENCODE_NONE, 0); + else _asl_append_string(&out, &outlen, "[", ENCODE_NONE, 0); + + _asl_append_string(&out, &outlen, msg->key[i], 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, " ", ENCODE_NONE, 0); + _asl_append_string(&out, &outlen, s, ENCODE_ASL, 0); + } + } + else if (msg->val[i] != NULL) + { + _asl_append_string(&out, &outlen, " ", ENCODE_NONE, 0); + _asl_append_string(&out, &outlen, msg->val[i], ENCODE_ASL, 0); + } + + _asl_append_string(&out, &outlen, "]", ENCODE_NONE, 0); + } + + _asl_append_string(&out, &outlen, "\n", ENCODE_NONE, 0); + + *len = outlen; + return out; } char * @@ -417,7 +874,7 @@ asl_msg_to_string(asl_msg_t *msg, uint32_t *len) if (msg->type == ASL_TYPE_QUERY) { - _asl_append_string(&out, &outlen, "Q ", 0, 0); + _asl_append_string(&out, &outlen, "Q ", ENCODE_NONE, 0); if (out == NULL) return NULL; } @@ -432,24 +889,24 @@ asl_msg_to_string(asl_msg_t *msg, uint32_t *len) { if (msg->key[i] == NULL) continue; - if (i > 0) _asl_append_string(&out, &outlen, " [", 0, 0); - else _asl_append_string(&out, &outlen, "[", 0, 0); + if (i > 0) _asl_append_string(&out, &outlen, " [", ENCODE_NONE, 0); + else _asl_append_string(&out, &outlen, "[", ENCODE_NONE, 0); if (msg->type == ASL_TYPE_QUERY) { _asl_append_op(&out, &outlen, msg->op[i]); - _asl_append_string(&out, &outlen, " ", 0, 0); + _asl_append_string(&out, &outlen, " ", ENCODE_NONE, 0); } - _asl_append_string(&out, &outlen, msg->key[i], 1, 1); + _asl_append_string(&out, &outlen, msg->key[i], ENCODE_ASL, 1); if (msg->val[i] != NULL) { - _asl_append_string(&out, &outlen, " ", 0, 0); - _asl_append_string(&out, &outlen, msg->val[i], 1, 0); + _asl_append_string(&out, &outlen, " ", ENCODE_NONE, 0); + _asl_append_string(&out, &outlen, msg->val[i], ENCODE_ASL, 0); } - _asl_append_string(&out, &outlen, "]", 0, 0); + _asl_append_string(&out, &outlen, "]", ENCODE_NONE, 0); } *len = outlen; @@ -469,7 +926,7 @@ _asl_msg_op_from_string(char *o) { 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_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; @@ -487,8 +944,8 @@ _asl_msg_op_from_string(char *o) static char * _asl_msg_get_next_word(char **p, uint32_t *tt, uint32_t spacedel) { - char *start, *out; - uint32_t i, esc, len, n; + char *str, *out, c, oval; + uint32_t i, len, n, outlen; *tt = TOKEN_NULL; @@ -508,6 +965,8 @@ _asl_msg_get_next_word(char **p, uint32_t *tt, uint32_t spacedel) if (**p == '\0') return NULL; if (**p == '\n') return NULL; + str = *p; + /* opening [ */ if (**p == '[') { @@ -515,33 +974,64 @@ _asl_msg_get_next_word(char **p, uint32_t *tt, uint32_t spacedel) (*p)++; out = malloc(2); + if (out == NULL) return NULL; + out[0] = '['; out[1] = '\0'; return out; } - start = *p; + /* 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) && (**p == ' ')) || (**p == ']') || (**p == '\0')) break; + if (((spacedel != 0) && (c == ' ')) || (c == ']') || (c == '\0')) break; - esc = 0; - if (**p == '\\') esc = 1; - (*p)++; + 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; + } + } - /* skip over escaped chars so len is correct */ - if ((esc == 1) && ((**p == ' ') || (**p == ']') || (**p == '\\'))) (*p)++; 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; @@ -549,18 +1039,134 @@ _asl_msg_get_next_word(char **p, uint32_t *tt, uint32_t spacedel) *tt = TOKEN_INT; - out = malloc(len + 1); + out = malloc(outlen + 1); + if (out == NULL) return NULL; - for (n = 0, i = 0; n < len; i++) + n = 0; + for (i = 0; i < len; i++) { - if ((start[i] == '\\') && ((start[i+1] == ' ') || (start[i+1] == ']') || (start[i+1] == '\\'))) + 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 ((start[i] < '0') || (start[i] > '9')) *tt = TOKEN_WORD; - out[n++] = start[i]; + if ((c < '0') || (c > '9')) *tt = TOKEN_WORD; + out[n++] = c; + } } out[n] = '\0'; @@ -574,7 +1180,7 @@ 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; @@ -600,8 +1206,9 @@ asl_msg_from_string(const char *buf) msg = calloc(1, sizeof(asl_msg_t)); if (msg == NULL) return NULL; + msg->type = type; - + /* OPEN WORD [WORD [WORD]] CLOSE */ while (k != NULL) { @@ -687,6 +1294,100 @@ asl_msg_from_string(const char *buf) 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) { @@ -756,7 +1457,9 @@ _asl_msg_op_test(uint32_t op, char *q, char *m, uint32_t n) if (op & ASL_QUERY_OP_CASEFOLD) rflags |= REG_ICASE; if (regcomp(&rex, q, rflags) != 0) return 0; - return (regexec(&rex, m, 0, NULL, 0) == 0); + cmp = regexec(&rex, m, 0, NULL, 0); + regfree(&rex); + return (cmp == 0); } if (op & ASL_QUERY_OP_NUMERIC) @@ -816,7 +1519,7 @@ _asl_msg_test_op_substr(uint32_t op, char *q, char *m) if (lq > lm) return 0; d = lm - lq; - for (i = 0; i < d; i++) + for (i = 0; i <= d; i++) { if (_asl_msg_op_test(op, q, m + i, lq) != 0) return 1; } @@ -869,44 +1572,109 @@ _asl_msg_test_op(uint32_t op, char *q, char *m) return _asl_msg_op_test(op, q, m, 0); } +static int +_asl_msg_test_time_op(uint32_t op, char *q, char *m) +{ + time_t tq, tm; + char *vq, *vm; + struct tm gtime; + uint32_t t, do_numeric; + int cmp; + + do_numeric = 1; + + if ((op & ASL_QUERY_OP_PREFIX) || (op & ASL_QUERY_OP_SUFFIX) || (op & ASL_QUERY_OP_REGEX) || (op & ASL_QUERY_OP_CASEFOLD)) do_numeric = 0; + + tq = asl_parse_time(q); + if (tq < 0) return _asl_msg_test_op(op, q, m); + + tm = asl_parse_time(m); + if (tm < 0) return _asl_msg_test_op(op, q, m); + + if (do_numeric == 1) + { + t = op & ASL_QUERY_OP_TRUE; + switch (t) + { + 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; + default: + return 0; + } + + return 0; + } + + memset(>ime, 0, sizeof(struct tm)); + gmtime_r(&tq, >ime); + + /* Canonical form: YYYY.MM.DD hh:mm:ss UTC */ + vq = NULL; + asprintf(&vq, "%d.%02d.%02d %02d:%02d:%02d UTC", gtime.tm_year + 1900, gtime.tm_mon + 1, gtime.tm_mday, gtime.tm_hour, gtime.tm_min, gtime.tm_sec); + if (vq == NULL) return 0; + + memset(>ime, 0, sizeof(struct tm)); + gmtime_r(&tm, >ime); + + /* Canonical form: YYYY.MM.DD hh:mm:ss UTC */ + vm = NULL; + asprintf(&vm, "%d.%02d.%02d %02d:%02d:%02d UTC", gtime.tm_year + 1900, gtime.tm_mon + 1, gtime.tm_mday, gtime.tm_hour, gtime.tm_min, gtime.tm_sec); + if (vm == NULL) return 0; + + cmp = _asl_msg_test_op(op, q, m); + + free(vq); + free(vm); + + return cmp; +} + static int _asl_msg_test(asl_msg_t *q, asl_msg_t *m) { uint32_t i, j; - int cmp, freeval; + int cmp; char *val; - struct tm gtime; - time_t tick; - + for (i = 0; i < q->count; i++) { j = _asl_msg_index(m, q->key[i]); if (j == (uint32_t)-1) return 0; if (q->val[i] == NULL) continue; + if (q->op == NULL) continue; + if ((q->op[i] & ASL_QUERY_OP_TRUE) == ASL_QUERY_OP_TRUE) continue; if (m->val[j] == NULL) return 0; val = q->val[i]; - freeval = 0; - + + cmp = 1; if (streq(q->key[i], ASL_KEY_TIME)) { - tick = asl_parse_time(val); - if (tick != -1) - { - memset(>ime, 0, sizeof(struct tm)); - gmtime_r(&tick, >ime); - - /* Canonical form: YYYY.MM.DD hh:mm:ss UTC */ - val = NULL; - asprintf(&val, "%d.%02d.%02d %02d:%02d:%02d UTC", gtime.tm_year + 1900, gtime.tm_mon + 1, gtime.tm_mday, gtime.tm_hour, gtime.tm_min, gtime.tm_sec); - freeval = 1; } + cmp = _asl_msg_test_time_op(q->op[i], q->val[i], m->val[j]); + } + else + { + cmp = _asl_msg_test_op(q->op[i], val, m->val[j]); } - - cmp = _asl_msg_test_op(q->op[i], val, m->val[j]); - if ((freeval == 1) && (val != NULL)) free(val); if (cmp == 0) return 0; } @@ -925,31 +1693,12 @@ asl_msg_cmp(asl_msg_t *a, asl_msg_t *b) return _asl_msg_test(b, a); } -static char * -_get_line_from_file(FILE *f) -{ - char *s, *out; - size_t len; - - out = fgetln(f, &len); - if (out == NULL) return NULL; - if (len == 0) return NULL; - - if (out[len] != '\n') len++; - - s = malloc(len); - memcpy(s, out, len - 1); - - s[len] = '\0'; - return s; -} - /* * asl_add_file: write log messages to the given file descriptor * Log messages will be written to this file as well as to the server. */ int -asl_add_log_file(aslclient ac, int fd) +asl_add_output(aslclient ac, int fd, const char *mfmt, const char *tfmt) { uint32_t i; int use_global_lock; @@ -969,6 +1718,15 @@ asl_add_log_file(aslclient ac, int fd) { if (asl->fd_list[i] == fd) { + /* update message format and time format */ + if (asl->fd_mfmt[i] != NULL) free(asl->fd_mfmt[i]); + asl->fd_mfmt[i] = NULL; + if (mfmt != NULL) asl->fd_mfmt[i] = strdup(mfmt); + + if (asl->fd_tfmt[i] != NULL) free(asl->fd_tfmt[i]); + asl->fd_tfmt[i] = NULL; + if (tfmt != NULL) asl->fd_tfmt[i] = strdup(tfmt); + if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); return 0; } @@ -977,30 +1735,47 @@ asl_add_log_file(aslclient ac, int fd) if (asl->fd_count == 0) { asl->fd_list = (int *)calloc(1, sizeof(int)); + asl->fd_mfmt = (char **)calloc(1, sizeof(char *)); + asl->fd_tfmt = (char **)calloc(1, sizeof(char *)); } else { - asl->fd_list = (int *)realloc(asl->fd_list, (1 + asl->fd_count) * sizeof(int)); + asl->fd_list = (int *)reallocf(asl->fd_list, (1 + asl->fd_count) * sizeof(int)); + asl->fd_mfmt = (char **)reallocf(asl->fd_mfmt, (1 + asl->fd_count) * sizeof(char *)); + asl->fd_tfmt = (char **)reallocf(asl->fd_tfmt, (1 + asl->fd_count) * sizeof(char *)); } - if (asl->fd_list == NULL) + if ((asl->fd_list == NULL) || (asl->fd_mfmt == NULL) || (asl->fd_tfmt == NULL)) { + if (asl->fd_list != NULL) free(asl->fd_list); + if (asl->fd_mfmt != NULL) free(asl->fd_mfmt); + if (asl->fd_tfmt != NULL) free(asl->fd_tfmt); + if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); return -1; } asl->fd_list[asl->fd_count] = fd; + if (mfmt != NULL) asl->fd_mfmt[asl->fd_count] = strdup(mfmt); + if (tfmt != NULL) asl->fd_tfmt[asl->fd_count] = strdup(tfmt); + asl->fd_count++; if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); return 0; } +int +asl_add_log_file(aslclient ac, int fd) +{ + return asl_add_output(ac, fd, ASL_MSG_FMT_STD, ASL_TIME_FMT_LCL); +} + /* - * asl_remove_file: stop writing log messages to the given file descriptor + * asl_remove_output: stop writing log messages to the given file descriptor */ int -asl_remove_log_file(aslclient ac, int fd) +asl_remove_output(aslclient ac, int fd) { uint32_t i; int x, use_global_lock; @@ -1015,7 +1790,7 @@ asl_remove_log_file(aslclient ac, int fd) pthread_mutex_lock(&_asl_global.lock); use_global_lock = 1; } - + if (asl->fd_count == 0) { if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); @@ -1038,19 +1813,53 @@ asl_remove_log_file(aslclient ac, int fd) return 0; } - for (i = x + 1; i < asl->fd_count; i++, x++) asl->fd_list[x] = asl->fd_list[i]; + if (asl->fd_mfmt[x] != NULL) free(asl->fd_mfmt[x]); + if (asl->fd_tfmt[x] != NULL) free(asl->fd_tfmt[x]); + + for (i = x + 1; i < asl->fd_count; i++, x++) + { + asl->fd_list[x] = asl->fd_list[i]; + asl->fd_mfmt[x] = asl->fd_mfmt[i]; + asl->fd_tfmt[x] = asl->fd_tfmt[i]; + } + asl->fd_count--; if (asl->fd_count == 0) { free(asl->fd_list); asl->fd_list = NULL; + asl->fd_mfmt = NULL; + asl->fd_tfmt = NULL; } else { - asl->fd_list = (int *)realloc(asl->fd_list, asl->fd_count * sizeof(int)); - if (asl->fd_list == NULL) + asl->fd_list = (int *)reallocf(asl->fd_list, asl->fd_count * sizeof(int)); + asl->fd_mfmt = (char **)reallocf(asl->fd_mfmt, asl->fd_count * sizeof(char *)); + asl->fd_tfmt = (char **)reallocf(asl->fd_tfmt, asl->fd_count * sizeof(char *)); + + if ((asl->fd_list == NULL) || (asl->fd_mfmt == NULL) || (asl->fd_tfmt == NULL)) { + if (asl->fd_list != NULL) + { + free(asl->fd_list); + asl->fd_list = NULL; + } + + 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); + asl->fd_mfmt = NULL; + } + + 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); + asl->fd_tfmt = NULL; + } + asl->fd_count = 0; if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); return -1; @@ -1061,12 +1870,18 @@ asl_remove_log_file(aslclient ac, int fd) return 0; } +int +asl_remove_log_file(aslclient ac, int fd) +{ + return asl_remove_output(ac, fd); +} + int asl_set_filter(aslclient ac, int f) { int last, use_global_lock; asl_client_t *asl; - + use_global_lock = 0; asl = (asl_client_t *)ac; if (asl == NULL) @@ -1076,7 +1891,7 @@ asl_set_filter(aslclient ac, int f) pthread_mutex_lock(&_asl_global.lock); use_global_lock = 1; } - + last = asl->filter; asl->filter = f; @@ -1109,7 +1924,6 @@ asl_new(uint32_t type) { uint32_t i; asl_msg_t *msg; - char *name, *x; msg = calloc(1, sizeof(asl_msg_t)); if (msg == NULL) return NULL; @@ -1160,7 +1974,7 @@ asl_new(uint32_t type) asl_free(msg); return NULL; } - + i++; msg->key[i] = strdup(ASL_KEY_SENDER); if (msg->key[i] == NULL) @@ -1168,42 +1982,7 @@ asl_new(uint32_t type) asl_free(msg); return NULL; } - - /* Get the value for ASL_KEY_SENDER from cache */ - if (_asl_global.sender == NULL) - { - name = *(*_NSGetArgv()); - if (name != NULL) - { - x = strrchr(name, '/'); - if (x != NULL) x++; - 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) - { - msg->val[i] = strdup("Unknown"); - if (msg->val[i] == NULL) - { - asl_free(msg); - return NULL; - } - } - else - { - msg->val[i] = strdup(_asl_global.sender); - if (msg->val[i] == NULL) - { - asl_free(msg); - return NULL; - } - } - i++; msg->key[i] = strdup(ASL_KEY_PID); if (msg->key[i] == NULL) @@ -1211,7 +1990,7 @@ asl_new(uint32_t type) asl_free(msg); return NULL; } - + i++; msg->key[i] = strdup(ASL_KEY_UID); if (msg->key[i] == NULL) @@ -1219,7 +1998,7 @@ asl_new(uint32_t type) asl_free(msg); return NULL; } - + i++; msg->key[i] = strdup(ASL_KEY_GID); if (msg->key[i] == NULL) @@ -1227,7 +2006,7 @@ asl_new(uint32_t type) asl_free(msg); return NULL; } - + i++; msg->key[i] = strdup(ASL_KEY_LEVEL); if (msg->key[i] == NULL) @@ -1235,7 +2014,7 @@ asl_new(uint32_t type) asl_free(msg); return NULL; } - + i++; msg->key[i] = strdup(ASL_KEY_MSG); if (msg->key[i] == NULL) @@ -1243,7 +2022,7 @@ asl_new(uint32_t type) asl_free(msg); return NULL; } - + return (aslmsg)msg; } @@ -1298,7 +2077,7 @@ asl_vlog(aslclient ac, aslmsg a, int level, const char *format, va_list ap) asl = _asl_open_default(); if (asl == NULL) return -1; } - + saved_errno = errno; if (format == NULL) return -1; @@ -1329,113 +2108,407 @@ asl_vlog(aslclient ac, aslmsg a, int level, const char *format, va_list ap) asl_set(msg, ASL_KEY_LEVEL, str); free(str); - /* insert strerror for %m */ - len = 0; - elen = 0; - estr = strdup(strerror(saved_errno)); - expand = 0; + /* 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) + { + elen = strlen(estr); + + for (i = 0; format[i] != '\0'; i++) + { + if (format[i] == '%') + { + if (format[i+1] == '\0') len++; + else if (format[i+1] == 'm') + { + expand = 1; + len += elen; + i++; + } + else + { + len += 2; + i++; + } + } + else len++; + } + } + + fmt = (char *)format; + + if (expand != 0) + { + fmt = malloc(len + 1); + if (fmt == NULL) + { + if (estr != NULL) free(estr); + return -1; + } + + len = 0; + + for (i = 0; format[i] != '\0'; i++) + { + if (format[i] == '%') + { + if (format[i+1] == '\0') + { + } + else if (format[i+1] == 'm') + { + memcpy(fmt+len, estr, elen); + len += elen; + i++; + } + else + { + fmt[len++] = format[i++]; + fmt[len++] = format[i]; + } + } + else fmt[len++] = format[i]; + } + + 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; + } + + asl_set(msg, ASL_KEY_MSG, str); + free(str); + + status = asl_send(ac, (aslmsg)msg); + + if ((msg != NULL) && (my_msg != 0)) asl_free(msg); + return status; +} + +/* + * asl_log: log a message with a particular log level + * msg: an aslmsg + * level: the log level + * format: A formating string followed by a list of arguments, like printf() + * returns 0 for success, non-zero for failure + */ +int +asl_log(aslclient ac, aslmsg a, int level, const char *format, ...) +{ + va_list ap; + int status; + + if (format == NULL) return -1; + + va_start(ap, format); + status = asl_vlog(ac, a, level, format, ap); + va_end(ap); + + return status; +} + +#ifndef BUILDING_VARIANT + +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(aslmsg msg, const char *mfmt, const char *tfmt, 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; + + 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; + + _asl_append_string(&out, len, mstr, ENCODE_VIS, 0); + _asl_append_string(&out, len, "\n", ENCODE_NONE, 0); + + return out; + } + + 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 = 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) + { + lstr = asl_get(msg, ASL_KEY_LEVEL); + if (lstr != NULL) level = atoi(lstr); + } + + if (tstr == NULL) + { + _asl_append_string(&out, len, "0", ENCODE_NONE, 0); + } + else + { + _asl_append_string(&out, len, tstr, ENCODE_NONE, 0); + free(tstr); + } + + _asl_append_string(&out, len, " ", ENCODE_NONE, 0); + + if (hstr == NULL) _asl_append_string(&out, len, "unknown", ENCODE_NONE, 0); + else _asl_append_string(&out, len, hstr, ENCODE_VIS, 0); + + _asl_append_string(&out, len, " ", ENCODE_NONE, 0); + + if (sstr == NULL) _asl_append_string(&out, len, "unknown", ENCODE_NONE, 0); + else _asl_append_string(&out, len, sstr, ENCODE_VIS, 0); + + if ((pstr != NULL) && (strcmp(pstr, "-1"))) + { + _asl_append_string(&out, len, "[", ENCODE_NONE, 0); + _asl_append_string(&out, len, pstr, ENCODE_NONE, 0); + _asl_append_string(&out, len, "]", ENCODE_NONE, 0); + } + + if ((rprc != NULL) || (rpid != NULL)) _asl_append_string(&out, len, " (", ENCODE_NONE, 0); + + if (rprc != NULL) _asl_append_string(&out, len, rprc, ENCODE_VIS, 0); + if (rpid != NULL) + { + _asl_append_string(&out, len, "[", ENCODE_NONE, 0); + _asl_append_string(&out, len, rpid, ENCODE_NONE, 0); + _asl_append_string(&out, len, "]", ENCODE_NONE, 0); + } + + if ((rprc != NULL) || (rpid != NULL)) _asl_append_string(&out, len, ")", ENCODE_NONE, 0); + + if (mf == MFMT_STD) + { + _asl_append_string(&out, len, " <", ENCODE_NONE, 0); + _asl_append_string(&out, len, _asl_level_string(level), ENCODE_NONE, 0); + _asl_append_string(&out, len, ">", ENCODE_NONE, 0); + } + + _asl_append_string(&out, len, ": ", ENCODE_NONE, 0); + + if (mstr != NULL) _asl_append_string(&out, len, mstr, ENCODE_VIS, 0); - if (estr != NULL) + _asl_append_string(&out, len, "\n", ENCODE_NONE, 0); + return out; + } + + if (mf == MFMT_XML) { - elen = strlen(estr); + _asl_append_string(&out, len, "\t\n", ENCODE_NONE, 0); - for (i = 0; format[i] != '\0'; i++) + for (i = 0; i < msg->count; i++) { - if (format[i] == '%') + if (asl_is_utf8(msg->key[i]) == 1) { - if (format[i+1] == '\0') len++; - else if (format[i+1] == 'm') + _asl_append_xml_tag(&out, len, XML_TAG_KEY, msg->key[i]); + if (!strcmp(msg->key[i], ASL_KEY_TIME)) { - expand = 1; - len += elen; - i++; + tstr = _asl_time_string(tf, msg->val[i]); + _asl_append_xml_tag(&out, len, XML_TAG_STRING, tstr); + if (tstr != NULL) free(tstr); } - else + else { - len += 2; - i++; + 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]); } } - else len++; } + + _asl_append_string(&out, len, "\t\n", ENCODE_NONE, 0); + + return out; } - fmt = (char *)format; + c[1] = '\0'; - if (expand != 0) + for (i = 0; mfmt[i] != '\0'; i++) { - fmt = malloc(len + 1); - len = 0; - - for (i = 0; format[i] != '\0'; i++) + if (mfmt[i] == '$') { - if (format[i] == '%') + i++; + paren = 0; + + if (mfmt[i] == '(') { - if (format[i+1] == '\0') - { - } - else if (format[i+1] == 'm') - { - memcpy(fmt+len, estr, elen); - len += elen; - i++; - } - else - { - fmt[len++] = format[i++]; - fmt[len++] = format[i]; - } + paren = 1; + i++; } - else fmt[len++] = format[i]; - } - fmt[len] = '\0'; - } + k = calloc(1, 1); + if (k == NULL) + { + if (out != NULL) free(out); + return NULL; + } - if (estr != NULL) free(estr); + l = 0; - vasprintf(&str, fmt, ap); - if (expand != 0) free(fmt); + 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 (str == NULL) - { - if ((msg != NULL) && (my_msg != 0)) asl_free(msg); - return -1; - } + if (c[0] == '\0') break; - asl_set(msg, ASL_KEY_MSG, str); - free(str); + k = reallocf(k, l + 1); + if (k == NULL) + { + if (out != NULL) free(out); + return NULL; + } - status = asl_send(ac, (aslmsg)msg); + k[l] = c[0]; + k[l + 1] = '\0'; + l++; + } - if ((msg != NULL) && (my_msg != 0)) asl_free(msg); - return status; -} + if (paren == 1) j++; + i = j; + if (l > 0) + { + v = asl_get(msg, k); + if (v != NULL) + { + if (!strcmp(k, ASL_KEY_TIME)) + { + tstr = _asl_time_string(tf, v); + _asl_append_string(&out, len, tstr, ENCODE_NONE, 0); + if (tstr != NULL) free(tstr); + } + else + { + _asl_append_string(&out, len, (char *)v, ENCODE_NONE, 0); + } + } + } + free(k); + } -/* - * asl_log: log a message with a particular log level - * msg: an aslmsg - * level: the log level - * format: A formating string followed by a list of arguments, like printf() - * returns 0 for success, non-zero for failure - */ -int -asl_log(aslclient ac, aslmsg a, int level, const char *format, ...) -{ - va_list ap; - int status; + if (mfmt[i] == '\\') + { + i++; + if (mfmt[i] == '$') _asl_append_string(&out, len, "$", ENCODE_NONE, 0); + else if (mfmt[i] == 'e') _asl_append_string(&out, len, "\e", ENCODE_NONE, 0); + else if (mfmt[i] == 's') _asl_append_string(&out, len, " ", ENCODE_NONE, 0); + else if (mfmt[i] == 'a') _asl_append_string(&out, len, "\a", ENCODE_NONE, 0); + else if (mfmt[i] == 'b') _asl_append_string(&out, len, "\b", ENCODE_NONE, 0); + else if (mfmt[i] == 'f') _asl_append_string(&out, len, "\f", ENCODE_NONE, 0); + else if (mfmt[i] == 'n') _asl_append_string(&out, len, "\n", ENCODE_NONE, 0); + else if (mfmt[i] == 'r') _asl_append_string(&out, len, "\r", ENCODE_NONE, 0); + else if (mfmt[i] == 't') _asl_append_string(&out, len, "\t", ENCODE_NONE, 0); + else if (mfmt[i] == 'v') _asl_append_string(&out, len, "\v", ENCODE_NONE, 0); + else if (mfmt[i] == '\'') _asl_append_string(&out, len, "\'", ENCODE_NONE, 0); + else if (mfmt[i] == '\\') _asl_append_string(&out, len, "\\", 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(&out, len, c, ENCODE_NONE, 0); + } + continue; + } - if (format == NULL) return -1; + if (mfmt[i] == '\0') break; + c[0] = mfmt[i]; + _asl_append_string(&out, len, c, ENCODE_NONE, 0); + } - va_start(ap, format); - status = asl_vlog(ac, a, level, format, ap); - va_end(ap); + _asl_append_string(&out, len, "\n", ENCODE_NONE, 0); - return status; + return out; } -#ifndef BUILDING_VARIANT - /* * asl_send: send a message * This routine may be used instead of asl_log() or asl_vlog() if asl_set() @@ -1446,13 +2519,17 @@ asl_log(aslclient ac, aslmsg a, int level, const char *format, ...) int asl_send(aslclient ac, aslmsg msg) { - char *str, *out; - uint32_t i, len, level, lmask, outstatus, filter; + char *str, *out_raw, *out; + uint32_t i, len, level, lmask, outstatus, filter, senderx, facilityx; + uint64_t v64; const char *val; + char *name, *x; time_t tick; int status, rc_filter; asl_client_t *asl; int use_global_lock; + asl_msg_t *mt; + char hname[_POSIX_HOST_NAME_MAX]; use_global_lock = 0; asl = (asl_client_t *)ac; @@ -1471,7 +2548,7 @@ asl_send(aslclient ac, aslmsg msg) if (val != NULL) level = atoi(val); lmask = ASL_FILTER_MASK(level); - + filter = asl->filter; rc_filter = 0; @@ -1481,20 +2558,24 @@ asl_send(aslclient ac, aslmsg msg) if (_asl_global.notify_token >= 0) { - status = notify_get_state(_asl_global.notify_token, &i); - if ((status == NOTIFY_STATUS_OK) && (i != 0)) + v64 = 0; + + status = notify_get_state(_asl_global.notify_token, &v64); + if ((status == NOTIFY_STATUS_OK) && (v64 != 0)) { - filter = i; + filter = v64; rc_filter = 1; } } if ((rc_filter == 0) && (_asl_global.master_token >= 0)) { - status = notify_get_state(_asl_global.master_token, &i); - if ((status == NOTIFY_STATUS_OK) && (i != 0)) + v64 = 0; + + status = notify_get_state(_asl_global.master_token, &v64); + if ((status == NOTIFY_STATUS_OK) && (v64 != 0)) { - filter = i; + filter = v64; } } @@ -1502,17 +2583,23 @@ asl_send(aslclient ac, aslmsg msg) } /* - * Time, PID, UID, and GID values get set here + * Time, Host, PID, UID, and GID values get set here */ str = NULL; tick = time(NULL); - asprintf(&str, "%u", tick); + asprintf(&str, "%lu", tick); if (str != NULL) { asl_set(msg, ASL_KEY_TIME, str); free(str); } + memset(&hname, 0, _POSIX_HOST_NAME_MAX); + if (gethostname(hname, _POSIX_HOST_NAME_MAX) == 0) + { + asl_set(msg, ASL_KEY_HOST, hname); + } + str = NULL; asprintf(&str, "%u", getpid()); if (str != NULL) @@ -1537,13 +2624,62 @@ asl_send(aslclient ac, aslmsg msg) free(str); } - len = 0; - str = asl_msg_to_string((asl_msg_t *)msg, &len); - if (str == NULL) return -1; + senderx = (uint32_t)-1; + facilityx = (uint32_t)-1; + mt = (asl_msg_t *)msg; - asprintf(&out, "%10u %s\n", len+1, str); - free(str); - if (out == NULL) return -1; + for (i = 0; (i < mt->count) && ((senderx == (uint32_t)-1) || (facilityx == (uint32_t)-1)); i++) + { + if (mt->key[i] == NULL) continue; + if (streq(mt->key[i], ASL_KEY_SENDER)) senderx = i; + else if (streq(mt->key[i], ASL_KEY_FACILITY)) facilityx = i; + } + + /* + * Set Sender if needed + */ + if ((senderx == (uint32_t)-1) || (mt->val[senderx] == NULL)) + { + if ((ac != NULL) && (ac->name != NULL)) + { + /* Use the Sender name from the client handle */ + asl_set(msg, ASL_KEY_SENDER, ac->name); + } + else + { + /* Get the value for ASL_KEY_SENDER from cache */ + if (_asl_global.sender == NULL) + { + name = *(*_NSGetArgv()); + if (name != NULL) + { + x = strrchr(name, '/'); + if (x != NULL) x++; + 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(msg, ASL_KEY_SENDER, _asl_global.sender); + else asl_set(msg, ASL_KEY_SENDER, "Unknown"); + } + } + + /* + * Set Facility + */ + if ((facilityx == (uint32_t)-1) || (mt->val[facilityx] == NULL)) + { + if ((ac != NULL) && (ac->facility != NULL)) + { + /* Use the Facility name from the client handle */ + asl_set(msg, ASL_KEY_FACILITY, ac->facility); + } + } outstatus = 0; @@ -1551,36 +2687,58 @@ asl_send(aslclient ac, aslmsg msg) if ((filter != 0) && ((filter & lmask) != 0)) { - if (asl->sock == -1) _asl_connect(asl); + len = 0; + out_raw = asl_msg_to_string((asl_msg_t *)msg, &len); - status = write(asl->sock, out, len + 12); - if (status < 0) + if ((out_raw != NULL) && (len != 0)) { - /* Write failed - try resetting */ - asl->sock = -1; - _asl_connect(asl); - status = write(asl->sock, out, len + 12); - if (status < 0) outstatus = -1; + asprintf(&out, "%10u %s\n", len + 1, out_raw); + if (out != NULL) + { + if (asl->sock == -1) _asl_connect(asl); + + if (asl->sock >= 0) + { + status = write(asl->sock, out, len + 12); + if (status < 0) + { + /* Write failed - try resetting */ + close(asl->sock); + asl->sock = -1; + _asl_connect(asl); + if (asl->sock >= 0) status = write(asl->sock, out, len + 12); + if (status < 0) outstatus = -1; + } + } + else outstatus = -1; + + free(out); + } + + free(out_raw); } } - if (asl->options & ASL_OPT_STDERR) fprintf(stderr, "%s", out); - for (i = 0; i < asl->fd_count; i++) { if (asl->fd_list[i] < 0) continue; - status = write(asl->fd_list[i], out, len + 12); + + len = 0; + out = asl_format_message(msg, asl->fd_mfmt[i], asl->fd_tfmt[i], &len); + if (out == NULL) continue; + + status = write(asl->fd_list[i], out, len - 1); if (status < 0) { asl->fd_list[i] = -1; outstatus = -1; } + + free(out); } if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - free(out); - return outstatus; } @@ -1622,6 +2780,34 @@ asl_free(aslmsg a) free(msg); } +/* + * Called if there's a malloc error while manipulating a message in asl_set_query. + * Cleans up the key, kap, and op fields, sets count to zero. + */ +static void +_asl_clear_msg(asl_msg_t *msg) +{ + uint32_t i; + + if (msg == NULL) return; + + 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]); + } + + if (msg->key != NULL) free(msg->key); + if (msg->val != NULL) free(msg->val); + if (msg->op != NULL) free(msg->op); + + msg->key = NULL; + msg->val = NULL; + msg->op = NULL; + + msg->count = 0; +} + /* * asl_set_query: set arbitrary parameters of a query * Similar to als_set, but allows richer query operations. @@ -1632,7 +2818,8 @@ asl_free(aslmsg a) * 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) +int +asl_set_query(aslmsg a, const char *key, const char *val, uint32_t op) { uint32_t i; char *dk, *dv; @@ -1656,14 +2843,46 @@ int asl_set_query(aslmsg a, const char *key, const char *val, uint32_t op) asprintf(&dv, "%d", i); if (dv == NULL) return -1; } - else if (!strcasecmp(val, ASL_STRING_EMERG)) dv = strdup("0"); - else if (!strcasecmp(val, ASL_STRING_ALERT)) dv = strdup("1"); - else if (!strcasecmp(val, ASL_STRING_CRIT)) dv = strdup("2"); - else if (!strcasecmp(val, ASL_STRING_ERR)) dv = strdup("3"); - else if (!strcasecmp(val, ASL_STRING_WARNING)) dv = strdup("4"); - else if (!strcasecmp(val, ASL_STRING_NOTICE)) dv = strdup("5"); - else if (!strcasecmp(val, ASL_STRING_INFO)) dv = strdup("6"); - else if (!strcasecmp(val, ASL_STRING_DEBUG)) dv = strdup("7"); + 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; } @@ -1692,14 +2911,14 @@ int asl_set_query(aslmsg a, const char *key, const char *val, uint32_t op) msg->key = (char **)calloc(1, sizeof(char *)); if (msg->key == NULL) { - asl_free(msg); + _asl_clear_msg(msg); return -1; } msg->val = (char **)calloc(1, sizeof(char *)); if (msg->val == NULL) { - asl_free(msg); + _asl_clear_msg(msg); return -1; } @@ -1708,33 +2927,33 @@ int asl_set_query(aslmsg a, const char *key, const char *val, uint32_t op) msg->op = (uint32_t *)calloc(1, sizeof(uint32_t)); if (msg->op == NULL) { - asl_free(msg); + _asl_clear_msg(msg); return -1; } } } else { - msg->key = (char **)realloc(msg->key, (msg->count + 1) * sizeof(char *)); + msg->key = (char **)reallocf(msg->key, (msg->count + 1) * sizeof(char *)); if (msg->key == NULL) { - asl_free(msg); + _asl_clear_msg(msg); return -1; } - msg->val = (char **)realloc(msg->val, (msg->count + 1) * sizeof(char *)); + msg->val = (char **)reallocf(msg->val, (msg->count + 1) * sizeof(char *)); if (msg->val == NULL) { - asl_free(msg); + _asl_clear_msg(msg); return -1; } if (msg->type == ASL_TYPE_QUERY) { - msg->op = (uint32_t *)realloc(msg->op, (msg->count + 1) * sizeof(uint32_t)); + msg->op = (uint32_t *)reallocf(msg->op, (msg->count + 1) * sizeof(uint32_t)); if (msg->op == NULL) { - asl_free(msg); + _asl_clear_msg(msg); return -1; } } @@ -1742,7 +2961,7 @@ int asl_set_query(aslmsg a, const char *key, const char *val, uint32_t op) dk = strdup(key); if (dk == NULL) return -1; - + msg->key[msg->count] = dk; msg->val[msg->count] = dv; if (msg->op != NULL) msg->op[msg->count] = op; @@ -1812,15 +3031,15 @@ asl_unset(aslmsg a, const char *key) } else { - msg->key = (char **)realloc(msg->key, msg->count * sizeof(char *)); + msg->key = (char **)reallocf(msg->key, msg->count * sizeof(char *)); if (msg->key == NULL) return -1; - msg->val = (char **)realloc(msg->val, msg->count * sizeof(char *)); + msg->val = (char **)reallocf(msg->val, msg->count * sizeof(char *)); if (msg->val == NULL) return -1; if (msg->op != NULL) { - msg->op = (uint32_t *)realloc(msg->op, msg->count * sizeof(uint32_t)); + msg->op = (uint32_t *)reallocf(msg->op, msg->count * sizeof(uint32_t)); if (msg->op == NULL) return -1; } } @@ -1834,7 +3053,7 @@ asl_unset(aslmsg a, const char *key) /* * asl_search: Search for messages matching the criteria described - * by the aslmsg . The caller should set the attributes to match using + * by the aslmsg. The caller should set the attributes to match using * asl_set_query() or asl_set(). The operatoin ASL_QUERY_OP_EQUAL is * used for attributes set with asl_set(). * a: an aslmsg @@ -1844,45 +3063,105 @@ asl_unset(aslmsg a, const char *key) aslresponse asl_search(aslclient ac, aslmsg a) { - FILE *log; - asl_msg_t *q, *m; - asl_search_result_t *res; - char *str; + asl_search_result_t *batch, *out; + char *qstr, *str, *res; + uint32_t i, j, len, reslen, status; + uint64_t cmax, qmin; + kern_return_t kstatus; + security_token_t sec; + caddr_t vmstr; + + if (a == NULL) return 0; + + len = 0; + qstr = asl_msg_to_string((asl_msg_t *)a, &len); - q = (asl_msg_t *)a; + str = NULL; + if (qstr == NULL) + { + asprintf(&str, "0\n"); + len = 3; + } + else + { + asprintf(&str, "1\n%s\n", qstr); + len += 4; + free(qstr); + } - if (q == NULL) return 0; + if (str == NULL) return NULL; - log = fopen(_PATH_ASL_OUT, "r"); - if (log == NULL) return NULL; + if (asl_server_port == MACH_PORT_NULL) + { + kstatus = bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &asl_server_port); + if (kstatus != KERN_SUCCESS) return NULL; + } - res = (asl_search_result_t *)calloc(1, sizeof(asl_search_result_t)); + /* + * Fetch a batch of results each time through the loop. + * Fetching many small batches rebuces the load on syslogd. + */ + out = NULL; + qmin = 0; + cmax = 0; - while (NULL != (str = _get_line_from_file(log))) + forever { - m = asl_msg_from_string(str); - if (m == NULL) continue; - if (asl_msg_cmp(q, m) == 0) + res = NULL; + reslen = 0; + sec.val[0] = -1; + sec.val[1] = -1; + status = 0; + + kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&vmstr, len, TRUE); + if (kstatus != KERN_SUCCESS) return NULL; + + memmove(vmstr, str, len); + + kstatus = _asl_server_query(asl_server_port, vmstr, len, qmin, FETCH_BATCH, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec); + if (kstatus != KERN_SUCCESS) break; + if (res == NULL) break; + + batch = asl_list_from_string(res); + vm_deallocate(mach_task_self(), (vm_address_t)res, reslen); + + if (batch == NULL) break; + if (batch->count == 0) { - asl_free(m); - continue; + aslresponse_free(batch); + break; } - if (res->count == 0) + if (out == NULL) out = (asl_search_result_t *)calloc(1, sizeof(asl_search_result_t)); + if (out == NULL) { - res->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *)); + aslresponse_free(batch); + break; } - else + + if (out->count == 0) out->msg = (asl_msg_t **)calloc(batch->count, sizeof(asl_msg_t *)); + else out->msg = (asl_msg_t **)reallocf(out->msg, (out->count + batch->count) * sizeof(asl_msg_t *)); + if (out->msg == NULL) { - res->msg = (asl_msg_t **)realloc(res->msg, (res->count + 1) * sizeof(asl_msg_t *)); + aslresponse_free(batch); + free(out); + free(str); + return NULL; } - res->msg[res->count] = m; - res->count++; + for (i = 0, j = out->count; i < batch->count; i++, j++) out->msg[j] = batch->msg[i]; + + out->count += batch->count; + free(batch->msg); + free(batch); + + if (i < FETCH_BATCH) break; + + if (cmax > qmin) qmin = cmax; } - fclose(log); - return res; + free(str); + return out; } /* @@ -1919,7 +3198,7 @@ aslresponse_free(aslresponse r) res = (asl_search_result_t *)r; if (res == NULL) return; - for (i = 0; i < res->count; i++) free(res->msg[i]); + for (i = 0; i < res->count; i++) asl_free(res->msg[i]); free(res->msg); free(res); } @@ -2047,9 +3326,9 @@ _month_num(char *s) time_t asl_parse_time(const char *in) { - int len, y, status, rflags, factor; + int len, y, status, rflags; struct tm t; - time_t tick, delta; + 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; @@ -2076,7 +3355,7 @@ asl_parse_time(const char *in) if (status != 0) return -1; init_ctime = 1; } - + if (init_abs == 0) { memset(&rex_abs, 0, sizeof(regex_t)); @@ -2084,7 +3363,7 @@ asl_parse_time(const char *in) if (status != 0) return -1; init_abs = 1; } - + if (init_rel == 0) { memset(&rex_rel, 0, sizeof(regex_t)); @@ -2101,9 +3380,11 @@ asl_parse_time(const char *in) * Absolute time (number of seconds since the epoch) */ str = strdup(in); + if (str == NULL) return -1; + if ((str[len-2] == 's') || (str[len-2] == 'S')) str[len-2] = '\0'; - tick = atoi(str); + tick = atol(str); free(str); return tick; @@ -2114,9 +3395,10 @@ asl_parse_time(const char *in) * Reletive time (number of seconds before or after right now) */ str = strdup(in); - + if (str == NULL) return -1; + factor = 1; - + if ((str[len-2] == 's') || (str[len-2] == 'S')) { str[len-2] = '\0'; @@ -2141,9 +3423,9 @@ asl_parse_time(const char *in) str[len-2] = '\0'; factor = SECONDS_PER_WEEK; } - + tick = time(NULL); - delta = factor * atoi(str); + delta = factor * atol(str); tick += delta; free(str); @@ -2154,6 +3436,7 @@ asl_parse_time(const char *in) { memset(&t, 0, sizeof(struct tm)); str = strdup(in); + if (str == NULL) return -1; /* Get year */ x = str; @@ -2169,25 +3452,25 @@ asl_parse_time(const char *in) /* Get day */ x = p + 1; - p = strchr(x, ' '); + p = strchr(x, ' '); *p = '\0'; t.tm_mday = atoi(x); /* Get hour */ for (x = p + 1; *x == ' '; x++); - p = strchr(x, ':'); + p = strchr(x, ':'); *p = '\0'; t.tm_hour = atoi(x); /* Get minutes */ x = p + 1; - p = strchr(x, ':'); + p = strchr(x, ':'); *p = '\0'; t.tm_min = atoi(x); /* Get seconds */ x = p + 1; - p = strchr(x, ' '); + p = strchr(x, ' '); *p = '\0'; t.tm_sec = atoi(x); @@ -2204,6 +3487,7 @@ asl_parse_time(const char *in) memset(&t, 0, sizeof(struct tm)); str = strdup(in); + if (str == NULL) return -1; t.tm_year = y; t.tm_mon = _month_num(str); @@ -2216,20 +3500,20 @@ asl_parse_time(const char *in) /* Get hour */ for (x = p + 1; *x == ' '; x++); - p = strchr(x, ':'); + p = strchr(x, ':'); *p = '\0'; t.tm_hour = atoi(x); - + /* Get minutes */ x = p + 1; - p = strchr(x, ':'); + p = strchr(x, ':'); *p = '\0'; t.tm_min = atoi(x); - + /* Get seconds */ x = p + 1; t.tm_sec = atoi(x); - + t.tm_isdst = -1; free(str); @@ -2246,15 +3530,15 @@ asl_syslog_syslog(int pri, const char *fmt, ...) { va_list ap; asl_msg_t *m; - + if (fmt == NULL) return; - + m = asl_new(ASL_TYPE_MSG); - + va_start(ap, fmt); asl_vlog(NULL, m, pri, fmt, ap); va_end(ap); - + asl_free(m); } @@ -2262,7 +3546,7 @@ __private_extern__ void asl_syslog_vsyslog(int pri, const char *fmt, va_list ap) { asl_msg_t *m; - + m = asl_new(ASL_TYPE_MSG); asl_vlog(NULL, m, pri, fmt, ap); asl_free(m); @@ -2278,7 +3562,7 @@ asl_syslog_openlog(const char *ident, int flags, int facility) if (flags & LOG_NDELAY) opts |= ASL_OPT_NO_DELAY; if (flags & LOG_PERROR) opts |= ASL_OPT_STDERR; - + fname = asl_syslog_faciliy_num_to_name(facility); if (fname == NULL) fname = "user"; diff --git a/gen/asl_ipc.defs b/gen/asl_ipc.defs new file mode 100644 index 0000000..7d8cce9 --- /dev/null +++ b/gen/asl_ipc.defs @@ -0,0 +1,45 @@ +#include +#include + +subsystem asl_ipc 1; +serverprefix _; + +import ; + +type ooline_data = ^ array [] of MACH_MSG_TYPE_BYTE + ctype : caddr_t; + +routine _asl_server_query +( + server : mach_port_t; + request : ooline_data, dealloc; + startid : uint64_t; + count : int; + flags : int; + out reply : ooline_data, dealloc; + out lastid : uint64_t; + out status : int; + SecToken token : security_token_t +); + +routine _asl_server_query_timeout +( + server : mach_port_t; + request : ooline_data, dealloc; + startid : uint64_t; + count : int; + flags : int; + WaitTime timeout: natural_t; + out reply : ooline_data, dealloc; + out lastid : uint64_t; + out status : int; + SecToken token : security_token_t +); + +routine _asl_server_prune +( + server : mach_port_t; + request : ooline_data, dealloc; + out status : int; + SecToken token : security_token_t +); diff --git a/gen/asl_private.h b/gen/asl_private.h index 4977bda..913f9ce 100644 --- a/gen/asl_private.h +++ b/gen/asl_private.h @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2007 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. + * + * 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@ + */ #include #include #include @@ -13,6 +36,19 @@ #define NOTIFY_PREFIX_SYSTEM "com.apple.system.syslog" #define NOTIFY_PREFIX_USER "user.syslog" +#define ASL_MSG_FMT_RAW "raw" +#define ASL_MSG_FMT_STD "std" +#define ASL_MSG_FMT_BSD "bsd" +#define ASL_MSG_FMT_XML "xml" +#define ASL_MSG_FMT_MSG "msg" + +#define ASL_TIME_FMT_SEC "sec" +#define ASL_TIME_FMT_UTC "utc" +#define ASL_TIME_FMT_LCL "lcl" + +#define ASL_KEY_REF_PID "RefPID" +#define ASL_KEY_REF_PROC "RefProc" + typedef struct __aslclient { uint32_t options; @@ -28,6 +64,8 @@ typedef struct __aslclient int notify_master_token; uint32_t fd_count; int *fd_list; + char **fd_mfmt; + char **fd_tfmt; uint32_t reserved1; void *reserved2; } asl_client_t; @@ -47,3 +85,13 @@ typedef struct __aslresponse uint32_t curr; 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); +int asl_remove_output(aslclient asl, int fd); +char *asl_format_message(aslmsg msg, const char *msg_fmt, const char *time_fmt, uint32_t *outlen); + +__END_DECLS + diff --git a/gen/asl_util.c b/gen/asl_util.c new file mode 100644 index 0000000..a7240a6 --- /dev/null +++ b/gen/asl_util.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2006-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 OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * These routines needs to be separate from asl.c, so that dyld can build + * and suck in these without the rest of asl. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define _PATH_ASL_IN "/var/run/asl_input" + +static uint8_t *b64charset = (uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +__private_extern__ int +_asl_server_socket(int *sock, struct sockaddr_un *server) +{ + socklen_t len; + int status, flags; + + *sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (*sock < 0) return -1; + + memset(server, 0, sizeof(struct sockaddr_un)); + server->sun_family = AF_UNIX; + + strcpy(server->sun_path, _PATH_ASL_IN); + server->sun_len = strlen(server->sun_path) + 1; + len = sizeof(server->sun_len) + sizeof(server->sun_family) + server->sun_len; + + status = connect(*sock, (const struct sockaddr *)server, len); + + if (status < 0) + { + close(*sock); + *sock = -1; + return -1; + } + + /* set close-on-exec flag */ + fcntl(*sock, F_SETFD, 1); + + /* set non-blocking flag */ + flags = fcntl(*sock, F_GETFL, 0); + if (flags >= 0) fcntl(*sock, F_SETFL, flags | O_NONBLOCK); + + return 0; +} + +__private_extern__ const char * +_asl_escape(unsigned char c) +{ + switch(c) + { + case '\\': + return "\\\\"; + case '[': + return "\\["; + case ']': + return "\\]"; + case '\n': + return "\\n"; + } + return NULL; +} + +static int +asl_is_utf8_char(const unsigned char *p, int *state, int *ctype) +{ + switch (*state) + { + case 0: + { + *ctype = 0; + + if (*p >= 0x80) + { + *state = 1; + if ((*p >= 0xc2) && (*p <= 0xdf)) *ctype = 1; + else if (*p == 0xe0) *ctype = 2; + else if ((*p >= 0xe1) && (*p <= 0xef)) *ctype = 3; + else if (*p == 0xf0) *ctype = 4; + else if ((*p >= 0xf1) && (*p <= 0xf3)) *ctype = 5; + else if (*p == 0xf4) *ctype = 6; + else return 0; + } + + break; + } + + case 1: + { + switch (*ctype) + { + case 1: + { + if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0; + else return 0; + break; + } + + case 2: + { + if ((*p >= 0xa0) && (*p <= 0xbf)) *state = 2; + else return 0; + break; + } + + case 3: + { + if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2; + else return 0; + break; + } + + case 4: + { + if ((*p >= 0x90) && (*p <= 0xbf)) *state = 2; + else return 0; + break; + } + + case 5: + { + if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2; + else return 0; + break; + } + + case 6: + { + if ((*p >= 0x80) && (*p <= 0x8f)) *state = 2; + else return 0; + break; + } + + default: return 0; + } + + break; + } + + case 2: + { + if ((*ctype >= 2) && (*ctype <= 3)) + { + if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0; + else return 0; + } + else if ((*ctype >= 4) && (*ctype <= 6)) + { + if ((*p >= 0x80) && (*p <= 0xbf)) *state = 3; + else return 0; + } + else + { + return 0; + } + + break; + } + + case 3: + { + if ((*ctype >= 4) && (*ctype <= 6)) + { + if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0; + else return 0; + } + else + { + return 0; + } + + break; + } + + default: return 0; + } + + return 1; +} + +__private_extern__ int +asl_is_utf8(const char *str) +{ + const unsigned char *p; + int flag = 1; + int state = 0; + int ctype = 0; + + if (str == NULL) return flag; + + for (p = (const unsigned char *)str; (*p != '\0') && (flag == 1); p++) + { + flag = asl_is_utf8_char(p, &state, &ctype); + } + + return flag; +} + +__private_extern__ uint8_t * +asl_b64_encode(const uint8_t *buf, size_t len) +{ + uint8_t *out; + uint8_t b; + size_t i0, i1, i2, j, outlen; + + if (buf == NULL) return NULL; + if (len == 0) return NULL; + + outlen = ((len + 2) / 3) * 4; + out = (uint8_t *)malloc(outlen + 1); + if (out == NULL) + { + errno = ENOMEM; + return NULL; + } + + out[outlen] = 0; + + i0 = 0; + i1 = 1; + i2 = 2; + j = 0; + + while (i2 < len) + { + b = buf[i0] >> 2; + out[j++] = b64charset[b]; + + b = ((buf[i0] & 0x03) << 4) | (buf[i1] >> 4); + out[j++] = b64charset[b]; + + b = ((buf[i1] & 0x0f) << 2) | ((buf[i2] & 0xc0) >> 6); + out[j++] = b64charset[b]; + + b = buf[i2] & 0x3f; + out[j++] = b64charset[b]; + + i0 += 3; + i1 = i0 + 1; + i2 = i1 + 1; + } + + if (i0 < len) + { + b = buf[i0] >> 2; + out[j++] = b64charset[b]; + + b = (buf[i0] & 0x03) << 4; + + if (i1 < len) b |= (buf[i1] >> 4); + out[j++] = b64charset[b]; + + if (i1 >= len) + { + out[j++] = '='; + out[j++] = '='; + return out; + } + + b = (buf[i1] & 0x0f) << 2; + out[j++] = b64charset[b]; + out[j++] = '='; + } + + return out; +} diff --git a/gen/assert-fbsd.c b/gen/assert-fbsd.c new file mode 100644 index 0000000..8dc39b7 --- /dev/null +++ b/gen/assert-fbsd.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1992, 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[] = "@(#)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 $"); + +#include +#include +#include + +void +__assert_rtn(func, file, line, failedexpr) + const char *func, *file; + int line; + const char *failedexpr; +{ + if (func == NULL) + (void)fprintf(stderr, + "Assertion failed: (%s), file %s, line %d.\n", failedexpr, + file, line); + else + (void)fprintf(stderr, + "Assertion failed: (%s), function %s, file %s, line %d.\n", + failedexpr, func, file, line); + abort(); + /* NOTREACHED */ +} diff --git a/gen/backtrace.3 b/gen/backtrace.3 new file mode 100644 index 0000000..0e7f682 --- /dev/null +++ b/gen/backtrace.3 @@ -0,0 +1,106 @@ +.\" Copyright (c) 2007 Apple 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. Neither the name of Apple Inc. ("Apple") 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 APPLE 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. +.\" +.\" +.Dd February 15, 2007 +.Dt backtrace 3 +.Os "Mac OS X" +.Sh NAME +.Nm backtrace , +.Nm backtrace_symbols , +.Nm backtrace_symbols_fd +.Nd call stack backtrace and display functions +.Sh SYNOPSIS +.In execinfo.h +.Ft int +.Fo backtrace +.Fa "void** array" +.Fa "int size" +.Fc +.Ft char** +.Fo backtrace_symbols +.Fa "void* const* array" +.Fa "int size" +.Fc +.Ft void +.Fo backtrace_symbols_fd +.Fa "void* const* array" +.Fa "int size" +.Fa "int fd" +.Fc +.Sh DESCRIPTION +These routines provide a mechanism to examine the current thread's call stack. +.Pp +.Fn backtrace +writes the function return addresses of the current call stack to the array of +pointers referenced by +.Fa array . +At most, +.Fa size +pointers are written. The number of pointers actually written to +.Fa array +is returned. +.Pp +.Fn backtrace_symbols +attempts to transform a call stack obtained by +.Fn backtrace +into an array of human-readable strings using +.Fn dladdr . +The array of strings returned has +.Fa size +elements. It is allocated using +.Fn malloc +and should be released using +.Fn free . +There is no need to free the individual strings in the array. +.Pp +.Fn backtrace_symbols_fd +performs the same operation as +.Fn backtrace_symbols , +but the resulting strings are immediately written to the file descriptor +.Fa fd , +and are not returned. +.Sh EXAMPLE +.Pp + #include + #include + ... + void* callstack[128]; + int i, frames = backtrace(callstack, 128); + char** strs = backtrace_symbols(callstack, frames); + for (i = 0; i < frames; ++i) { + printf("%s\\n", strs[i]); + } + free(strs); + ... +.Pp +.Sh HISTORY +These functions first appeared in +Mac OS X 10.5. +.Sh SEE ALSO +.Xr dladdr 3 , +.Xr malloc 3 diff --git a/gen/backtrace.c b/gen/backtrace.c new file mode 100644 index 0000000..d71143d --- /dev/null +++ b/gen/backtrace.c @@ -0,0 +1,141 @@ +/* + * 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 +#include + +#include +#include +#include +#include + +#include "stack_logging.h" +#include "execinfo.h" + +int backtrace(void** buffer, int size) { + extern void _thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb, unsigned skip); + unsigned int num_frames; + _thread_stack_pcs((vm_address_t*)buffer, size, &num_frames, 1); + while (num_frames >= 1 && buffer[num_frames-1] == NULL) num_frames -= 1; + return num_frames; +} + +#if __LP64__ +#define _BACKTRACE_FORMAT "%-4d%-35s 0x%016x %s + %u" +#define _BACKTRACE_FORMAT_SIZE 82 +#else +#define _BACKTRACE_FORMAT "%-4d%-35s 0x%08x %s + %u" +#define _BACKTRACE_FORMAT_SIZE 65 +#endif + + +static int _backtrace_snprintf(char* buf, size_t size, int frame, const void* addr, const Dl_info* info) { + char symbuf[19]; + const char* image = "???"; + const char* symbol = symbuf; + + if (info->dli_fname) { + image = strrchr(info->dli_fname, '/') + 1; + if (image == NULL) image = info->dli_fname; + } + + if (info->dli_sname) { + symbol = info->dli_sname; + } else { + snprintf(symbuf, sizeof(symbuf), "0x%x", info->dli_saddr); + } + + return snprintf(buf, size, + _BACKTRACE_FORMAT, + frame, + image, + addr, + symbol, + addr - info->dli_saddr) + 1; +} + +char** backtrace_symbols(void* const* buffer, int size) { + int i; + size_t total_bytes; + char** result; + char** ptrs; + intptr_t strs; + Dl_info* info = calloc(size, sizeof (Dl_info)); + + if (info == NULL) return NULL; + + // Compute the total size for the block that is returned. + // The block will contain size number of pointers to the + // symbol descriptions. + + total_bytes = sizeof(char*) * 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); + } + + result = (char**)malloc(total_bytes); + if (result == NULL) { + free(info); + return NULL; + } + + // 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) { + ptrs[i] = (char*)strs; + strs += _backtrace_snprintf((char*)strs, total_bytes, i, buffer[i], &info[i]); + } + + free(info); + + return result; +} + +void backtrace_symbols_fd(void* const* buffer, int size, int fd) { + int i; + char buf[BUFSIZ]; + Dl_info info; + struct iovec iov[2]; + + iov[0].iov_base = buf; + + iov[1].iov_base = "\n"; + iov[1].iov_len = 1; + + for (i = 0; i < size; ++i) { + memset(&info, 0, sizeof(info)); + dladdr(buffer[i], &info); + + iov[0].iov_len = _backtrace_snprintf(buf, sizeof(buf), i, buffer[i], &info); + + writev(fd, iov, 2); + } +} diff --git a/gen/basename-fbsd.c b/gen/basename-fbsd.c new file mode 100644 index 0000000..3de44fb --- /dev/null +++ b/gen/basename-fbsd.c @@ -0,0 +1,88 @@ +/* + * 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. + * + * 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. + */ + +#if 0 +#ifndef lint +static char rcsid[] = "$OpenBSD: basename.c,v 1.4 1999/05/30 17:10:30 espie Exp $"; +#endif /* not lint */ +#endif +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/basename.c,v 1.7 2002/12/30 01:41:14 marcel Exp $"); + +#include +#include +#include +#include +#include + +#if __DARWIN_UNIX03 +#define const /**/ +#endif + +char * +basename(path) + const char *path; +{ + static char *bname = NULL; + const char *endp, *startp; + + if (bname == NULL) { + bname = (char *)malloc(MAXPATHLEN); + if (bname == NULL) + return(NULL); + } + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + (void)strcpy(bname, "."); + return(bname); + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* All slashes becomes "/" */ + if (endp == path && *endp == '/') { + (void)strcpy(bname, "/"); + return(bname); + } + + /* Find the start of the base */ + startp = endp; + while (startp > path && *(startp - 1) != '/') + startp--; + + if (endp - startp + 2 > MAXPATHLEN) { + errno = ENAMETOOLONG; + return(NULL); + } + (void)strncpy(bname, startp, endp - startp + 1); + bname[endp - startp + 1] = '\0'; + return(bname); +} diff --git a/gen/basename.3 b/gen/basename.3 new file mode 100644 index 0000000..a9300b3 --- /dev/null +++ b/gen/basename.3 @@ -0,0 +1,120 @@ +.\" +.\" 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. +.\" +.\" 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. +.\" +.\" $OpenBSD: basename.3,v 1.12 2000/04/18 03:01:25 aaron Exp $ +.\" $FreeBSD: src/lib/libc/gen/basename.3,v 1.7 2004/07/02 23:52:10 ru Exp $ +.\" +.Dd August 17, 1997 +.Dt BASENAME 3 +.Os +.Sh NAME +.Nm basename +.Nd extract the base portion of a pathname +.Sh SYNOPSIS +.In libgen.h +.Ft char * +.Fo basename +.Fa "char *path" +.Fc +.Sh DESCRIPTION +The +.Fn basename +function +returns the last component from the pathname pointed to by +.Fa path , +deleting any trailing +.Sq \&/ +characters. +If +.Fa path +consists entirely of +.Sq \&/ +characters, a pointer to the string +.Qq \&/ +is returned. +If +.Fa path +is a null pointer or the empty string, a pointer to the string +.Qq \&. +is returned. +.Sh RETURN VALUES +On successful completion, +.Fn basename +returns a pointer to the last component of +.Fa path . +.Pp +If +.Fn basename +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 +The +.Fn basename +function +returns a pointer to internal static storage space +that will be overwritten by subsequent calls. +The function may modify the string pointed to by +.Fa path . +.Sh LEGACY SYNOPSIS +.Fd #include +.Pp +.Ft char * +.br +.Fo basename +.Fa "const char *path" +.Fc ; +.Pp +In legacy mode, +.Fa path +will not be changed. +.Sh SEE ALSO +.Xr basename 1 , +.Xr dirname 1 , +.Xr dirname 3 , +.Xr compat 5 +.Sh STANDARDS +The +.Fn basename +function conforms to +.St -xpg4.2 . +.Sh HISTORY +The +.Fn basename +function first appeared in +.Ox 2.2 +and +.Fx 4.2 . +.Sh AUTHORS +.An "Todd C. Miller" Aq Todd.Miller@courtesan.com diff --git a/gen/cache.c b/gen/cache.c index f570a55..c47d481 100644 --- a/gen/cache.c +++ b/gen/cache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -26,16 +26,27 @@ #include #include #include +#include -static const unsigned int kCacheOptionsSyncForExecution = 0x1; -extern void sys_icache_invalidate(void *, size_t); int -sys_cache_control(unsigned int options, caddr_t start, size_t len) +sys_cache_control(int function, void *start, size_t len) { - if (options == kCacheOptionsSyncForExecution) { - sys_icache_invalidate(start, len); - return 0; - } - return ENOTSUP; + int status = 0; + + switch( function ) { + + case kCacheFunctionPrepareForExecution: + sys_icache_invalidate(start, len); + break; + + case kCacheFunctionFlushDcache: + sys_dcache_flush(start, len); + break; + + default: + status = ENOTSUP; + } + + return status; } diff --git a/gen/clock-fbsd.c b/gen/clock-fbsd.c new file mode 100644 index 0000000..ddfccbe --- /dev/null +++ b/gen/clock-fbsd.c @@ -0,0 +1,59 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include +#include +#include + +/* + * Convert usec to clock ticks; could do (usec * CLOCKS_PER_SEC) / 1000000, + * but this would overflow if we switch to nanosec. + */ +#define CONVTCK(r) ((r).tv_sec * CLOCKS_PER_SEC \ + + (r).tv_usec / (1000000 / CLOCKS_PER_SEC)) + +clock_t +clock() +{ + struct rusage ru; + + if (getrusage(RUSAGE_SELF, &ru)) + return ((clock_t) -1); + return((clock_t)((CONVTCK(ru.ru_utime) + CONVTCK(ru.ru_stime)))); +} diff --git a/gen/clock.3 b/gen/clock.3 new file mode 120000 index 0000000..8eb0ebf --- /dev/null +++ b/gen/clock.3 @@ -0,0 +1 @@ +./clock.3 \ No newline at end of file diff --git a/gen/closedir-fbsd.c b/gen/closedir-fbsd.c new file mode 100644 index 0000000..61753c2 --- /dev/null +++ b/gen/closedir-fbsd.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 1983, 1993 + * 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" +#include "telldir.h" + +/* + * close a directory. + */ +int +closedir(dirp) + DIR *dirp; +{ + int fd; + + if (__isthreaded) + _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); +#if !__DARWIN_UNIX03 + _seekdir(dirp, dirp->dd_rewind); /* free seekdir storage */ +#endif /* __DARWIN_UNIX03 */ + fd = dirp->dd_fd; + dirp->dd_fd = -1; + dirp->dd_loc = 0; + 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); + } + free((void *)dirp); + return(_close(fd)); +} diff --git a/gen/compat.5 b/gen/compat.5 index 9347a31..b70ff88 100644 --- a/gen/compat.5 +++ b/gen/compat.5 @@ -1,4 +1,4 @@ -.Dd October 7, 2004 +.Dd October 23, 2005 .Os Darwin .Dt COMPAT 5 .Sh NAME @@ -8,9 +8,12 @@ .Ev COMMAND_MODE=legacy|unix2003 .Lp .Fd #define _POSIX_C_SOURCE -.Fd #define _APPLE_C_SOURE +.Fd #define _DARWIN_C_SOURCE .Fd #define _NONSTD_SOURCE -.Fd #define __LP64__ +.Fd defined(__LP64__) +.Lp +.In sys/cdefs.h +.Fd defined(_DARWIN_FEATURE_UNIX_CONFORMANCE) .Sh DESCRIPTION Setting the environment variable .Ev COMMAND_MODE @@ -22,53 +25,83 @@ to the value unix03 causes utility programs to obey the .St -susv3 standards even if doing so would alter the behavior of flags used in 10.3. .Pp -.Ev COMMAND_MODE's -value is case insensitive and if it is unset or set to something other than legacy or unix03 it behaves as if it were set to unix03. -.Pp +The value of +.Ev COMMAND_MODE +is case insensitive and if it is unset or set to something other than legacy or unix03 it behaves as if it were set to unix03. +.Sh 32-BIT 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. .Pp -Defining any of -.Dv _POSIX_C_SOURCE, -.Dv _APPLE_C_SOURE, +Defining +.Dv _POSIX_C_SOURCE or -.Dv __LP64__ -causes library and kernel calls to conform to -.St -susv3 -standards even if doing so would alter the behavior of functions used in 10.3. Defining +.Dv _DARWIN_C_SOURCE +causes library and kernel calls to conform to the SUSv3 +standards even if doing so would alter the behavior of functions used in 10.3. +Defining .Dv _POSIX_C_SOURCE -also removes functions, types, and other interfaces that are not part of -.St -susv3 -from the normal C namespace, while -.Dv _APPLE_C_SOURE -does not. +also removes functions, types, and other interfaces that are not part of SUSv3 +from the normal C namespace, unless +.Dv _DARWIN_C_SOURCE +is also defined (i.e., +.Dv _DARWIN_C_SOURCE +is +.Dv _POSIX_C_SOURCE +with non-POSIX extensions). +In any of these cases, the +.Dv _DARWIN_FEATURE_UNIX_CONFORMANCE +feature macro will be defined to the SUS conformance level (it is undefined +otherwise). .Pp -Failing to define any of those symbols currently acts as if you have defined +Starting in Mac OS X 10.5, if none of the macros +.Dv _NONSTD_SOURCE , +.Dv _POSIX_C_SOURCE +or +.Dv _DARWIN_C_SOURCE +are defined, and the environment variable +.Ev MACOSX_DEPLOYMENT_TARGET +is either undefined or set to 10.5 or greater (or equivalently, the +.Xr gcc 1 +option +.Fl mmacosx-version-min +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 +.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 -but it is expected that in a future OS X release the default behavior will change to be as if -.Dv _APPLE_C_SOURE -were defined. +will cause a compilation error. .Sh STANDARDS With COMMAND_MODE set to unix2003 utility functions conform to -.St -susv3 +.St -susv3 . .Pp With -.Dv _POSIX_C_SOURCE, -.Dv _APPLE_C_SOURE, +.Dv _POSIX_C_SOURCE , +.Dv _DARWIN_C_SOURCE , or -.Dv __LP64__ +.Dv __LP64__ , system and library calls conform to -.St -susv3 +.St -susv3 . .Sh BUGS -Different parts of a program can be compiled with different compatibility settings. The resultant program will normally work as expected, for example a regex created by the -.St -susv3 +Different parts of a program can be compiled with different compatibility +settings. +The resultant program will normally work as expected, for example a regex +created by the SUSv3 .Fn regcomp 3 can be passed to the legacy .Fn regfree 3 with no unexpected results. Some cases are less clear cut, for example -what does the programmer intend when they use the -.Fn -susv3 +what does the programmer intend when they use the SUSv3 .Fn regcomp 3 to compile a regex, but the legacy .Fn regexec 3 diff --git a/gen/confstr.3 b/gen/confstr.3 index ccecf7e..b207ecf 100644 --- a/gen/confstr.3 +++ b/gen/confstr.3 @@ -93,7 +93,7 @@ environment variable that finds all the standard utilities. .Sh RETURN VALUES If the call to .Fn confstr -is not successful, \-1 is returned and +is not successful, 0 is returned and .Va errno is set appropriately. Otherwise, if the variable does not have a configuration defined value, @@ -124,6 +124,12 @@ The value of the .Fa name argument is invalid. .El +.Sh LEGACY ERRORS +If the call to +.Fn confstr +is not successful, \-1 (rather than 0) is returned and +.Va errno +is set appropriately. .Sh SEE ALSO .Xr getconf 1 , .Xr pathconf 2 , diff --git a/gen/confstr.c b/gen/confstr.c index 3165a09..90f69ec 100644 --- a/gen/confstr.c +++ b/gen/confstr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -63,6 +63,16 @@ #include #include +#include + +extern char *_dirhelper(dirhelper_which_t which, char *path, size_t pathlen); + +#if __DARWIN_UNIX03 +#define CONFSTR_ERR_RET 0 +#else /* !__DARWIN_UNIX03 */ +#define CONFSTR_ERR_RET -1 +#endif /* __DARWIN_UNIX03 */ + size_t confstr(name, buf, len) int name; @@ -78,15 +88,15 @@ confstr(name, buf, len) mib[0] = CTL_USER; mib[1] = USER_CS_PATH; if (sysctl(mib, 2, NULL, &tlen, NULL, 0) == -1) - return (-1); + return (CONFSTR_ERR_RET); if (len != 0 && buf != NULL) { if ((p = malloc(tlen)) == NULL) - return (-1); + return (CONFSTR_ERR_RET); if (sysctl(mib, 2, p, &tlen, NULL, 0) == -1) { sverrno = errno; free(p); errno = sverrno; - return (-1); + return (CONFSTR_ERR_RET); } /* * POSIX 1003.2 requires partial return of @@ -156,6 +166,33 @@ docopy: strlcpy(buf, p, len); return (strlen(p) + 1); + case _CS_DARWIN_USER_DIR: + if ((p = alloca(PATH_MAX)) == NULL) { + errno = ENOMEM; + return (CONFSTR_ERR_RET); + } + if (_dirhelper(DIRHELPER_USER_LOCAL, p, PATH_MAX) == NULL) + return (CONFSTR_ERR_RET); + goto docopy; + + case _CS_DARWIN_USER_TEMP_DIR: + if ((p = alloca(PATH_MAX)) == NULL) { + errno = ENOMEM; + return (CONFSTR_ERR_RET); + } + if (_dirhelper(DIRHELPER_USER_LOCAL_TEMP, p, PATH_MAX) == NULL) + return (CONFSTR_ERR_RET); + goto docopy; + + case _CS_DARWIN_USER_CACHE_DIR: + if ((p = alloca(PATH_MAX)) == NULL) { + errno = ENOMEM; + return (CONFSTR_ERR_RET); + } + if (_dirhelper(DIRHELPER_USER_LOCAL_CACHE, p, PATH_MAX) == NULL) + return (CONFSTR_ERR_RET); + goto docopy; + default: errno = EINVAL; return (0); diff --git a/gen/crypt.3 b/gen/crypt.3 index 26befb9..e307144 100644 --- a/gen/crypt.3 +++ b/gen/crypt.3 @@ -36,23 +36,26 @@ .Os "FreeSec 1.0" .Sh NAME .Nm crypt , -.Nm setkey , .Nm encrypt , -.Nm des_setkey , -.Nm des_cipher , +.Nm setkey .Nd DES encryption .Sh SYNOPSIS .Fd #include -.Ft char -.Fn *crypt "const char *key" "const char *setting" +.Ft char * +.Fo crypt +.Fa "const char *key" +.Fa "const char *salt" +.Fc .Ft void -.Fn setkey "char *key" +.Fo encrypt +.Fa "char *block" +.Fa "int edflag" +.Fc +.Fd #include .Ft void -.Fn encrypt "char *block" "int flag" -.Ft int -.Fn des_setkey "const char *key" -.Ft int -.Fn des_cipher "const char *in" "char *out" "long salt" "int count" +.Fo setkey +.Fa "const char *key" +.Fc .Sh DESCRIPTION The .Fn crypt @@ -66,8 +69,8 @@ is a .Dv null Ns -terminated string, typically a user's typed password. The second is in one of two forms: -if it begins with an underscore (``_'') then an extended format is used -in interpreting both the key and the setting, as outlined below. +if it begins with an underscore (``_''), an extended format is used +in interpreting both the key and the salt value, as outlined below. .Ss Extended crypt: .Pp The @@ -79,7 +82,9 @@ the first group of 56 bits becomes the initial DES key. For each additional group, the XOR of the encryption of the current DES key with itself and the group bits becomes the next DES key. .Pp -The setting is a 9-character array consisting of an underscore followed +The +.Ar salt +is a 9-character array consisting of an underscore, followed by 4 bytes of iteration count and 4 bytes of salt. These are encoded as printable characters, 6 bits per character, least significant character first. @@ -95,10 +100,10 @@ each character is used to form the 56-bit .Tn DES key. .Pp -The setting is a 2-character array of the ASCII-encoded salt. -Thus only 12 bits of +The .Fa salt -are used. +is a 2-character array of the ASCII-encoded salt. +Thus, only 12 bits of salt are used. .Fa count is set to 25. .Ss Algorithm: @@ -120,29 +125,27 @@ are swapped in the .Tn DES E-box output). .Pp -The DES key is used to encrypt a 64-bit constant using +The DES key is used to encrypt a 64-bit constant, using .Ar count iterations of .Tn DES . The value returned is a .Dv null Ns -terminated string, 20 or 13 bytes (plus null) in length, consisting of the -.Ar setting +.Ar salt , followed by the encoded 64-bit encryption. .Pp The functions, -.Fn encrypt , -.Fn setkey , -.Fn des_setkey +.Fn encrypt and -.Fn des_cipher +.Fn setkey provide access to the .Tn DES algorithm itself. .Fn setkey is passed a 64-byte array of binary values (numeric 0 or 1). A 56-bit key is extracted from this array by dividing the -array into groups of 8, and ignoring the last bit in each group. +array into groups of 8 and ignoring the last bit in each group. That bit is reserved for a byte parity check by DES, but is ignored by these functions. .Pp @@ -152,66 +155,56 @@ argument to .Fn encrypt is also a 64-byte array of binary values. If the value of -.Fa flag +.Fa edflag is 0, .Fa block -is encrypted otherwise it is decrypted. +is encrypted; otherwise, it is decrypted. The result is returned in the original array -.Fa block +.Fa block , after using the key specified by .Fn setkey to process it. .Pp -The argument to -.Fn des_setkey -is a character array of length 8. -The least significant bit (the parity bit) in each character is ignored, -and the remaining bits are concatenated to form a 56-bit key. -The function -.Fn des_cipher -encrypts (or decrypts if -.Fa count -is negative) the 64-bits stored in the 8 characters at -.Fa in -using -.Xr abs 3 -of -.Fa count -iterations of -.Tn DES -and stores the 64-bit result in the 8 characters at -.Fa out -(which may be the same as -.Fa in -). -The -.Fa salt -specifies perturbations to the -.Tn DES -E-box output as described above. -.Pp The function .Fn crypt returns a pointer to the encrypted value on success, and NULL on failure. -The functions -.Fn setkey , -.Fn encrypt , -.Fn des_setkey , -and -.Fn des_cipher -return 0 on success and 1 on failure. .Pp The -.Fn crypt , -.Fn setkey +.Fn crypt and -.Fn des_setkey +.Fn setkey functions all manipulate the same key space. .Sh SEE ALSO .Xr login 1 , .Xr passwd 1 , .Xr getpass 3 , +.Xr compat 5 , .Xr passwd 5 +.Sh LEGACY SYNOPSIS +.Fd #include +.Pp +.Ft int +.br +.Fo encrypt +.Fa "char *block" +.Fa "int edflag" +.Fc ; +.Pp +The function +.Fn encrypt +returns 0 on success and 1 on failure. +.Pp +.Ft void +.br +.Fo setkey +.Fa "const char *key" +.Fc ; +.Pp +The include file +.In unistd.h +is necessary and sufficient for the +.Fn setkey +function. .Sh BUGS The .Fn crypt diff --git a/gen/crypt.c b/gen/crypt.c index 6fe5751..4c6b742 100644 --- a/gen/crypt.c +++ b/gen/crypt.c @@ -342,6 +342,11 @@ STATIC void permute(cp, out, p, chars_in) #endif /* BUILDING_VARIANT */ #endif /* LARGEDATA */ +#ifndef BUILDING_VARIANT +__private_extern__ int __crypt_des_setkey_called = 0; +#else /* BUILDING_VARIANT */ +__private_extern__ int __crypt_des_setkey_called; +#endif /* BUILDING_VARIANT */ /* ===== (mostly) Standard DES Tables ==================== */ @@ -639,6 +644,7 @@ __private_extern__ int __crypt_des_setkey(key) PERM6464(K,K0,K1,(unsigned char *)key,ptabp); STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); } + __crypt_des_setkey_called = 1; return (0); } @@ -983,6 +989,12 @@ int encrypt(block, flag) register int i, j, k; C_block cblock; + /* Prevent encrypt from crashing if setkey was never called. + * This does not make a good cypher */ + if (!__crypt_des_setkey_called) { + cblock.b32.i0 = cblock.b32.i1 = 0; + __crypt_des_setkey((char *)cblock.b); + } for (i = 0; i < 8; i++) { k = 0; for (j = 0; j < 8; j++) { diff --git a/gen/ctermid-fbsd.c b/gen/ctermid-fbsd.c new file mode 100644 index 0000000..6b2c682 --- /dev/null +++ b/gen/ctermid-fbsd.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include +#include +#include + +char * +ctermid(char *s) +{ + static char def[] = _PATH_TTY; + + if (s) { + bcopy(def, s, sizeof(_PATH_TTY)); + return(s); + } + return(def); +} + + +char * +ctermid_r(char *s) +{ + return (s) ? ctermid(s) : NULL; +} diff --git a/gen/ctermid.3 b/gen/ctermid.3 new file mode 100644 index 0000000..c51c8a9 --- /dev/null +++ b/gen/ctermid.3 @@ -0,0 +1,112 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt CTERMID 3 +.Os +.Sh NAME +.Nm ctermid , +.Nm ctermid_r +.Nd generate terminal pathname +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft char * +.Fn ctermid "char *s" +.Ft char * +.Fn ctermid_r "char *s" +.Sh DESCRIPTION +The +.Fn ctermid +function generates a string that, when used as a pathname, refers to +the current controlling terminal of the calling process. +.Pp +If +.Fa s +is the +.Dv NULL +pointer, a pointer to a static area is returned. +Otherwise, the pathname is copied into the memory referenced by +.Fa s . +The argument +.Fa s +is assumed to be at least +.Dv L_ctermid +(as defined in the include +file +.In stdio.h ) +bytes long. +.Pp +The +.Fn ctermid_r +function +provides the same functionality as +.Fn ctermid , +except that if +.Fa s +is a +.Dv NULL +pointer, +.Dv NULL +is returned. +.Pp +The current implementation simply returns +.Ql /dev/tty . +.Sh RETURN VALUES +Upon successful completion, a +.Pf non- Dv NULL +pointer is returned. +Otherwise, a +.Dv NULL +pointer is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The current implementation detects no error conditions. +.Sh SEE ALSO +.Xr ttyname 3 +.Sh STANDARDS +The +.Fn ctermid +function conforms to +.St -p1003.1-88 . +.Sh BUGS +By default the +.Fn ctermid +function +writes all information to an internal static object. +Subsequent calls to +.Fn ctermid +will modify the same object. diff --git a/gen/daemon-fbsd.c b/gen/daemon-fbsd.c new file mode 100644 index 0000000..b85c24a --- /dev/null +++ b/gen/daemon-fbsd.c @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#ifndef VARIANT_PRE1050 +#include +#include +#endif /* !VARIANT_PRE1050 */ +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#ifndef VARIANT_PRE1050 +static void +move_to_root_bootstrap(void) +{ + mach_port_t parent_port = 0; + mach_port_t previous_port = 0; + + do { + if (previous_port) { + mach_port_deallocate(mach_task_self(), previous_port); + previous_port = parent_port; + } else { + previous_port = bootstrap_port; + } + + if (bootstrap_parent(previous_port, &parent_port) != 0) { + return; + } + } while (parent_port != previous_port); + + task_set_bootstrap_port(mach_task_self(), parent_port); + bootstrap_port = parent_port; +} +#endif /* !VARIANT_PRE1050 */ + +int daemon(int, int) __DARWIN_1050(daemon); + +int +daemon(nochdir, noclose) + int nochdir, noclose; +{ + struct sigaction osa, sa; + int fd; + pid_t newgrp; + int oerrno; + int osa_ok; + + /* A SIGHUP may be thrown when the parent exits below. */ + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + osa_ok = _sigaction(SIGHUP, &sa, &osa); +#ifndef VARIANT_PRE1050 + move_to_root_bootstrap(); +#endif /* !VARIANT_PRE1050 */ + switch (fork()) { + case -1: + return (-1); + case 0: + break; + default: + _exit(0); + } + + newgrp = setsid(); + oerrno = errno; + if (osa_ok != -1) + _sigaction(SIGHUP, &osa, NULL); + + if (newgrp == -1) { + errno = oerrno; + return (-1); + } + + if (!nochdir) + (void)chdir("/"); + + if (!noclose && (fd = _open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)_dup2(fd, STDIN_FILENO); + (void)_dup2(fd, STDOUT_FILENO); + (void)_dup2(fd, STDERR_FILENO); + if (fd > 2) + (void)_close(fd); + } + return (0); +} diff --git a/gen/daemon.3 b/gen/daemon.3 new file mode 100644 index 0000000..cd4931f --- /dev/null +++ b/gen/daemon.3 @@ -0,0 +1,118 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 9, 1993 +.Dt DAEMON 3 +.Os +.Sh NAME +.Nm daemon +.Nd run in the background +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn daemon "int nochdir" "int noclose" +.Sh DESCRIPTION +The +.Fn daemon +function is for programs wishing to detach themselves from the +controlling terminal and run in the background as system daemons. +On Mac OS X, the use of this API is discouraged in favor of using +.Xr launchd 8 . +.Pp +Unless the argument +.Fa nochdir +is non-zero, +.Fn daemon +changes the current working directory to the root +.Pq Pa / . +.Pp +Unless the argument +.Fa noclose +is non-zero, +.Fn daemon +will redirect standard input, standard output, and standard error to +.Pa /dev/null . +.Sh RETURN VALUES +.Rv -std daemon +.Sh ERRORS +The +.Fn daemon +function may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr fork 2 +and +.Xr setsid 2 . +.Sh SEE ALSO +.Xr fork 2 , +.Xr setsid 2 , +.Xr sigaction 2 +.Sh HISTORY +The +.Fn daemon +function first appeared in +.Bx 4.4 . +.Sh CAVEATS +Unless the +.Fa noclose +argument is non-zero, +.Fn daemon +will close the first three file descriptors and redirect them to +.Pa /dev/null . +Normally, these correspond to standard input, standard output, and +standard error. +However, if any of those file descriptors refer to something else, they +will still be closed, resulting in incorrect behavior of the calling program. +This can happen if any of standard input, standard output, or standard +error have been closed before the program was run. +Programs using +.Fn daemon +should therefore either call +.Fn daemon +before opening any files or sockets, or verify that any file +descriptors obtained have values greater than 2. +.Pp +The +.Fn daemon +function temporarily ignores +.Dv SIGHUP +while calling +.Xr setsid 2 +to prevent a parent session group leader's calls to +.Xr fork 2 +and then +.Xr _exit 2 +from prematurely terminating the child process. diff --git a/gen/devname.3 b/gen/devname.3 index 3a14aeb..057e82f 100644 --- a/gen/devname.3 +++ b/gen/devname.3 @@ -36,7 +36,8 @@ .Dt DEVNAME 3 .Os .Sh NAME -.Nm devname +.Nm devname , +.Nm devname_r .Nd get device name .Sh LIBRARY .Lb libc @@ -44,9 +45,17 @@ .In sys/stat.h .In stdlib.h .Ft char * -.Fn devname "dev_t dev" "mode_t type" +.Fo devname +.Fa "dev_t dev" +.Fa "mode_t type" +.Fc .Ft char * -.Fn devname_r "dev_t dev" "mode_t type" "char *buf" "int len" +.Fo devname_r +.Fa "dev_t dev" +.Fa "mode_t type" +.Fa "char *buf" +.Fa "int len" +.Fc .Sh DESCRIPTION The .Fn devname diff --git a/gen/directory.3 b/gen/directory.3 index 347767e..df63d69 100644 --- a/gen/directory.3 +++ b/gen/directory.3 @@ -36,53 +36,52 @@ .Dt DIRECTORY 3 .Os .Sh NAME +.Nm closedir , +.Nm dirfd , .Nm opendir , .Nm readdir , .Nm readdir_r , -.Nm telldir , -.Nm seekdir , .Nm rewinddir , -.Nm closedir , -.Nm dirfd +.Nm seekdir , +.Nm telldir .Nd directory operations .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In sys/types.h .In dirent.h +.Ft int +.Fn closedir "DIR *dirp" +.Ft int +.Fn dirfd "DIR *dirp" .Ft DIR * -.Fn opendir "const char *filename" +.Fn opendir "const char *dirname" .Ft struct dirent * .Fn readdir "DIR *dirp" .Ft int -.Fn readdir_r "DIR *dirp" "struct dirent *entry" "struct dirent **result" -.Ft long -.Fn telldir "DIR *dirp" -.Ft void -.Fn seekdir "DIR *dirp" "long loc" +.Fn readdir_r "DIR *restrict dirp" "struct dirent *restrict entry" \ + "struct dirent **restrict result" .Ft void .Fn rewinddir "DIR *dirp" -.Ft int -.Fn closedir "DIR *dirp" -.Ft int -.Fn dirfd "DIR *dirp" +.Ft void +.Fn seekdir "DIR *dirp" "long loc" +.Ft long +.Fn telldir "DIR *dirp" .Sh DESCRIPTION The .Fn opendir function opens the directory named by -.Fa filename , +.Fa dirname , associates a .Em directory stream -with it -and -returns a pointer to be used to identify the +with it, +and returns a pointer to be used to identify the .Em directory stream in subsequent operations. The pointer .Dv NULL is returned if -.Fa filename -cannot be accessed, or if it cannot +.Fa dirname +cannot be accessed or if it cannot .Xr malloc 3 enough memory to hold the whole thing. .Pp @@ -104,7 +103,7 @@ buffer to store the results in. If the read succeeds, .Fa result is pointed at the .Fa entry ; -upon reaching the end of the directory +upon reaching the end of the directory, .Fa result is set to .Dv NULL . @@ -120,8 +119,8 @@ Values returned by .Fn telldir are good only for the lifetime of the .Dv DIR -pointer, -.Fa dirp , +pointer (e.g., +.Fa dirp ) from which they are derived. If the directory is closed and then reopened, prior values returned by .Fn telldir @@ -180,21 +179,28 @@ while ((dp = readdir(dirp)) != NULL) (void)closedir(dirp); return NOT_FOUND; .Ed +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +.In sys/types.h +is necessary for these functions. .Sh SEE ALSO .Xr close 2 , .Xr lseek 2 , .Xr open 2 , .Xr read 2 , +.Xr compat 5 , .Xr dir 5 .Sh HISTORY The +.Fn closedir , +.Fn dirfd , .Fn opendir , .Fn readdir , -.Fn telldir , -.Fn seekdir , .Fn rewinddir , -.Fn closedir , +.Fn seekdir , and -.Fn dirfd +.Fn telldir functions appeared in .Bx 4.2 . diff --git a/gen/dirname-fbsd.c b/gen/dirname-fbsd.c new file mode 100644 index 0000000..e1c575b --- /dev/null +++ b/gen/dirname-fbsd.c @@ -0,0 +1,91 @@ +/* + * 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. + * + * 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. + */ + +#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 $"); + +#include +#include +#include +#include +#include + +#if __DARWIN_UNIX03 +#define const /**/ +#endif + +char * +dirname(path) + const char *path; +{ + static char *bname = NULL; + const char *endp; + + if (bname == NULL) { + bname = (char *)malloc(MAXPATHLEN); + if (bname == NULL) + return(NULL); + } + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + (void)strcpy(bname, "."); + return(bname); + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* Find the start of the dir */ + while (endp > path && *endp != '/') + endp--; + + /* Either the dir is "/" or there are no slashes */ + if (endp == path) { + (void)strcpy(bname, *endp == '/' ? "/" : "."); + return(bname); + } else { + do { + endp--; + } while (endp > path && *endp == '/'); + } + + if (endp - path + 2 > MAXPATHLEN) { + errno = ENAMETOOLONG; + return(NULL); + } + (void)strncpy(bname, path, endp - path + 1); + bname[endp - path + 1] = '\0'; + return(bname); +} diff --git a/gen/dirname.3 b/gen/dirname.3 new file mode 100644 index 0000000..2caa872 --- /dev/null +++ b/gen/dirname.3 @@ -0,0 +1,125 @@ +.\" +.\" 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. +.\" +.\" 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. +.\" +.\" $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 $ +.\" +.Dd August 17, 1997 +.Dt DIRNAME 3 +.Os +.Sh NAME +.Nm dirname +.Nd extract the directory part of a pathname +.Sh SYNOPSIS +.In libgen.h +.Ft char * +.Fo dirname +.Fa "char *path" +.Fc +.Sh DESCRIPTION +The +.Fn dirname +function +is the converse of +.Xr basename 3 ; +it returns a pointer to the parent directory of the pathname pointed to by +.Fa path . +Any trailing +.Sq \&/ +characters are not counted as part of the directory +name. +If +.Fa path +is a null pointer, the empty string, or contains no +.Sq \&/ +characters, +.Fn dirname +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 +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 ; +if portability is desired, +this should be taken into account when writing code which calls this function. +.Sh LEGACY SYNOPSIS +.Fd #include +.Pp +.Ft char * +.br +.Fo dirname +.Fa "const char *path" +.Fc ; +.Pp +In legacy mode, +.Fa path +will not be changed. +.Sh SEE ALSO +.Xr basename 1 , +.Xr dirname 1 , +.Xr basename 3 , +.Xr compat 5 +.Sh STANDARDS +The +.Fn dirname +function conforms to +.St -xpg4.2 . +.Sh HISTORY +The +.Fn dirname +function first appeared in +.Ox 2.2 +and +.Fx 4.2 . +.Sh AUTHORS +.An "Todd C. Miller" Aq Todd.Miller@courtesan.com diff --git a/gen/drand48-fbsd.c b/gen/drand48-fbsd.c new file mode 100644 index 0000000..52e9693 --- /dev/null +++ b/gen/drand48-fbsd.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/drand48.c,v 1.2 2002/03/22 21:52:05 obrien Exp $"); + +#include "rand48.h" + +double +drand48(void) +{ + ERAND48_BEGIN; + _DORAND48(_rand48_seed); + ERAND48_END(_rand48_seed); +} diff --git a/gen/endutxent.3 b/gen/endutxent.3 new file mode 100644 index 0000000..84382a6 --- /dev/null +++ b/gen/endutxent.3 @@ -0,0 +1,342 @@ +.\" $NetBSD: endutxent.3,v 1.4 2004/05/04 02:38:35 atatat 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. +.\" 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. +.\" +.Dd June 29, 2006 +.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 *id" +.Ft struct utmpx * +.Fn getutxline "const struct utmpx *line" +.Ft struct utmpx * +.Fn pututxline "const struct utmpx *utx" +.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. +Only the superuser may write to the accounting database. +.Ss The utmpx structure +The +.Nm utmpx +structure has the following definition: +.Pp +.Bd -literal +struct utmpx { + char ut_user[_UTX_USERSIZE]; /* login name */ + char ut_id[_UTX_IDSIZE]; /* id */ + char ut_line[_UTX_LINESIZE]; /* tty name */ + pid_t ut_pid; /* process id creating the entry */ + short ut_type; /* type of this entry */ + struct timeval ut_tv; /* time entry was created */ + char ut_host[_UTX_HOSTSIZE]; /* host name */ + __uint32_t ut_pad[16]; /* reserved for future use */ +}; +.Ed +.Pp +Valid entries for +.Fa ut_type +are: +.Bl -tag -width ".Dv 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. +.It Dv USER_PROCESS +A user process. +.It Dv SHUTDOWN_TIME +Time of system shutdown (extension to the standards). +.El +.Pp +For each value of +.Fa ut_type , +the other fields with meaningful values are as follows: +.Bl -tag -width ".Dv LOGIN_PROCESSXX" -compact -offset indent +.It Dv BOOT_TIME +.Fa ut_tv +.It Dv DEAD_PROCESS +.Fa ut_id , +.Fa ut_pid , +.Fa ut_tv +.It Dv EMPTY +(no others) +.It Dv INIT_PROCESS +.Fa ut_id , +.Fa ut_pid , +.Fa ut_tv +.It Dv LOGIN_PROCESS +.Fa ut_id , +.Fa ut_user +(implementation-defined name of the login process), +.Fa ut_pid , +.Fa ut_tv +.It Dv NEW_TIME +.Fa ut_tv +.It Dv OLD_TIME +.Fa ut_tv +.It Dv RUN_LVL +(no used) +.It Dv USER_PROCESS +.Fa ut_id , +.Fa ut_user +(login name of the user), +.Fa ut_line , +.Fa ut_pid , +.Fa ut_host +(hostname of remote user) +.Fa ut_tv +.It Dv SHUTDOWN_TIME +.Fa ut_tv +.El +.Ss Other extensions to the standards +The +.Fa ut_tv +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 +.Fa ut_type +value, other fields are automatically filled in (as specified in the +meaningful fields table above). +In particular, the +.Fa ut_id +field will be set using the convention of the last four characters of the +.Fa ut_line +field (itself filled in automatically from the tty name of the device connected +to the standard input, output or error, whichever is available). +Note that it is more efficient to fill in as many values as are already +available beforehand, rather than have then automatically filled in. +.It Dv UTMPX_DEAD_IF_CORRESPONDING_MASK +When +.Fa ut_type +value is +.Dv DEAD_PROCESS, a call to +.Fn pututxline +will succeed only if a corresponding entry already exists with a +.Fa ut_type +value of +.Dv USER_PROCESS . +.El +.Pp +Note that the above mask values do not show up in any file format, or in +any subsequent reads of the data. +.Pp +To support +.Pa wtmpx +and +.Pa lastlogx +equivalent capability, +.Fn pututxline +automatically writes to the appropriate files. +Additional APIs to read these files is available in +.Xr endutxent_wtmp 3 +and +.Xr getlastlogx 3 . +.Ss Backward compatibility +Successful calls to +.Fn pututxline +will automatically write equivalent entries into the +.Pa utmp , +.Pa wtmp +and +.Pa lastlog +files. +Programs that read these old files should work as expected. +However, directly writing to these files does not make corresponding +entries in +.Pa utmpx +and the +.Pa wtmpx +and +.Pa lastlogx +equivalent files, so such write-access is deprecated. +.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. +.Pp +.Fn pututxline +returns the structure that was successfully written, or +.Dv NULL +is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +No errors are defined for the +.Fn endutxent , +.Fn getutxent , +.Fn getutxid , +.Fn getutxline , +and +.Fn setutxent +functions. +.Pp +The +.Fn pututxline +function may fail if: +.Bl -tag -width Er +.It Bq Er EPERM +The process does not have appropriate privileges. +.It Bq Er EINVAL +The +.Dv UTMPX_DEAD_IF_CORRESPONDING_MASK +flags was specified along with +.Dv DEAD_PROCESS , +but no corresponding entry with +.Dv USER_PROCESS +was found. +.El +.Pp +Other errors may be returned if +.Dv UTMPX_AUTOFILL_MASK +was specified, and a field could not be auto-filled. +.Sh SEE ALSO +.Xr endutxent_wtmp 3 , +.Xr getlastlogx 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/erand48-fbsd.c b/gen/erand48-fbsd.c new file mode 100644 index 0000000..9887547 --- /dev/null +++ b/gen/erand48-fbsd.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/erand48.c,v 1.2 2002/03/22 21:52:05 obrien Exp $"); + +#include "rand48.h" + +double +erand48(unsigned short xseed[3]) +{ + uint48 tmp; + ERAND48_BEGIN; + DORAND48(tmp, xseed); + ERAND48_END(tmp); +} diff --git a/gen/err-fbsd.c b/gen/err-fbsd.c new file mode 100644 index 0000000..5137bb9 --- /dev/null +++ b/gen/err-fbsd.c @@ -0,0 +1,287 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" + +#ifdef BUILDING_VARIANT + +__private_extern__ FILE *_e_err_file; /* file to use for error output */ +__private_extern__ void (*_e_err_exit)(int); +__private_extern__ void _e_visprintf(FILE * __restrict, const char * __restrict, va_list); + +#else /* !BUILDING_VARIANT */ + +__private_extern__ FILE *_e_err_file = NULL; /* file to use for error output */ +__private_extern__ void (*_e_err_exit)(int) = NULL; + +/* + * zero means pass as is + * 255 means use \nnn (octal) + * otherwise use \x (x is value) + * (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', + /* BS HT NL VT NP CR SO SI */ + 'b', 't', 'n', '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 */ + 255, 255, 255, 255, 255, 255, 255, 255, + /* the rest are zero */ +}; + +/* + * Make characters visible. If we can't allocate enough + * memory, we fall back on vfprintf(). + */ +__private_extern__ void +_e_visprintf(FILE * __restrict stream, const char * __restrict format, va_list ap) +{ + int failed = 0; + char *str, *visstr; + va_list backup; + + va_copy(backup, ap); + vasprintf(&str, format, ap); + if (str != NULL) { + if ((visstr = malloc(4 * strlen(str) + 1)) != NULL) { + unsigned char *fp = (unsigned char *)str; + unsigned char *tp = (unsigned char *)visstr; + while(*fp) { + switch(escape[*fp]) { + case 0: + *tp++ = *fp; + break; + case 255: + sprintf(tp, "\\%03o", *fp); + tp += 4; + break; + default: + *tp++ = '\\'; + *tp++ = escape[*fp]; + break; + } + fp++; + } + *tp = 0; + fputs(visstr, stream); + free(visstr); + } else + failed = 1; + free(str); + } else + failed = 1; + if (failed) + vfprintf(stream, format, backup); + va_end(backup); +} + +/* + * This is declared to take a `void *' so that the caller is not required + * to include first. However, it is really a `FILE *', and the + * manual page documents it as such. + */ +void +err_set_file(void *fp) +{ + if (fp) + _e_err_file = fp; + else + _e_err_file = stderr; +} + +void +err_set_exit(void (*ef)(int)) +{ + _e_err_exit = ef; +} +#endif /* !BUILDING_VARIANT */ + +__weak_reference(_err, err); + +void +_err(int eval, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrc(eval, errno, fmt, ap); + va_end(ap); +} + +void +verr(eval, fmt, ap) + int eval; + const char *fmt; + va_list ap; +{ + verrc(eval, errno, fmt, ap); +} + +void +errc(int eval, int code, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrc(eval, code, fmt, ap); + va_end(ap); +} + +void +verrc(eval, code, fmt, ap) + int eval; + int code; + const char *fmt; + va_list ap; +{ + if (_e_err_file == 0) + err_set_file((FILE *)0); + fprintf(_e_err_file, "%s: ", _getprogname()); + if (fmt != NULL) { + _e_visprintf(_e_err_file, fmt, ap); + fprintf(_e_err_file, ": "); + } + fprintf(_e_err_file, "%s\n", strerror(code)); + if (_e_err_exit) + _e_err_exit(eval); + exit(eval); +} + +void +errx(int eval, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrx(eval, fmt, ap); + va_end(ap); +} + +void +verrx(eval, fmt, ap) + int eval; + const char *fmt; + va_list ap; +{ + if (_e_err_file == 0) + err_set_file((FILE *)0); + fprintf(_e_err_file, "%s: ", _getprogname()); + if (fmt != NULL) + _e_visprintf(_e_err_file, fmt, ap); + fprintf(_e_err_file, "\n"); + if (_e_err_exit) + _e_err_exit(eval); + exit(eval); +} + +__weak_reference(_warn, warn); + +void +_warn(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnc(errno, fmt, ap); + va_end(ap); +} + +void +vwarn(fmt, ap) + const char *fmt; + va_list ap; +{ + vwarnc(errno, fmt, ap); +} + +void +warnc(int code, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnc(code, fmt, ap); + va_end(ap); +} + +void +vwarnc(code, fmt, ap) + int code; + const char *fmt; + va_list ap; +{ + if (_e_err_file == 0) + err_set_file((FILE *)0); + fprintf(_e_err_file, "%s: ", _getprogname()); + if (fmt != NULL) { + _e_visprintf(_e_err_file, fmt, ap); + fprintf(_e_err_file, ": "); + } + fprintf(_e_err_file, "%s\n", strerror(code)); +} + +void +warnx(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnx(fmt, ap); + va_end(ap); +} + +void +vwarnx(fmt, ap) + const char *fmt; + va_list ap; +{ + if (_e_err_file == 0) + err_set_file((FILE *)0); + fprintf(_e_err_file, "%s: ", _getprogname()); + if (fmt != NULL) + _e_visprintf(_e_err_file, fmt, ap); + fprintf(_e_err_file, "\n"); +} diff --git a/gen/err.3 b/gen/err.3 new file mode 120000 index 0000000..7683dbe --- /dev/null +++ b/gen/err.3 @@ -0,0 +1 @@ +./err.3 \ No newline at end of file diff --git a/gen/errlst.c b/gen/errlst.c index 2a16946..66916da 100644 --- a/gen/errlst.c +++ b/gen/errlst.c @@ -181,6 +181,7 @@ const char *const sys_errlist[] = { "Protocol error", /* 100 - EPROTO */ "STREAM ioctl timeout", /* 101 - ETIME */ "Operation not supported on socket", /* 102 - EOPNOTSUPP */ + "Policy not found", /* 103 - ENOPOLICY */ }; const int sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]); diff --git a/gen/errno_-fbsd.c b/gen/errno_-fbsd.c new file mode 100644 index 0000000..7d98857 --- /dev/null +++ b/gen/errno_-fbsd.c @@ -0,0 +1,30 @@ +/*- + * Copyright (c) 2002 Peter Wemm + * 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/gen/errno.c,v 1.1 2002/10/09 08:04:24 peter Exp $"); + +int errno; diff --git a/gen/exec-fbsd.c b/gen/exec-fbsd.c new file mode 100644 index 0000000..54a0548 --- /dev/null +++ b/gen/exec-fbsd.c @@ -0,0 +1,277 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "un-namespace.h" + +#include +#define environ (*_NSGetEnviron()) + +int +execl(const char *name, const char *arg, ...) +{ + va_list ap; + char **argv; + int n; + + va_start(ap, arg); + n = 1; + while (va_arg(ap, char *) != NULL) + n++; + va_end(ap); + argv = alloca((n + 1) * sizeof(*argv)); + if (argv == NULL) { + errno = ENOMEM; + return (-1); + } + va_start(ap, arg); + n = 1; + argv[0] = (char *)arg; + while ((argv[n] = va_arg(ap, char *)) != NULL) + n++; + va_end(ap); + return (_execve(name, argv, environ)); +} + +int +execle(const char *name, const char *arg, ...) +{ + va_list ap; + char **argv, **envp; + int n; + + va_start(ap, arg); + n = 1; + while (va_arg(ap, char *) != NULL) + n++; + va_end(ap); + argv = alloca((n + 1) * sizeof(*argv)); + if (argv == NULL) { + errno = ENOMEM; + return (-1); + } + va_start(ap, arg); + n = 1; + argv[0] = (char *)arg; + while ((argv[n] = va_arg(ap, char *)) != NULL) + n++; + envp = va_arg(ap, char **); + va_end(ap); + return (_execve(name, argv, envp)); +} + +int +execlp(const char *name, const char *arg, ...) +{ + va_list ap; + char **argv; + int n; + + va_start(ap, arg); + n = 1; + while (va_arg(ap, char *) != NULL) + n++; + va_end(ap); + argv = alloca((n + 1) * sizeof(*argv)); + if (argv == NULL) { + errno = ENOMEM; + return (-1); + } + va_start(ap, arg); + n = 1; + argv[0] = (char *)arg; + while ((argv[n] = va_arg(ap, char *)) != NULL) + n++; + va_end(ap); + return (execvp(name, argv)); +} + +int +execv(name, argv) + const char *name; + char * const *argv; +{ + (void)_execve(name, argv, environ); + return (-1); +} + +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)); +} + +int +execvP(name, path, argv) + const char *name; + const char *path; + char * const *argv; +{ + char **memp; + int cnt, lp, ln; + char *p; + int eacces, save_errno; + char *bp, *cur, buf[MAXPATHLEN]; + struct stat sb; + + eacces = 0; + + /* If it's an absolute or relative path name, it's easy. */ + if (index(name, '/')) { + bp = (char *)name; + cur = NULL; + goto retry; + } + bp = buf; + + /* If it's an empty path name, fail in the usual POSIX way. */ + if (*name == '\0') { + errno = ENOENT; + return (-1); + } + + cur = alloca(strlen(path) + 1); + if (cur == NULL) { + errno = ENOMEM; + return (-1); + } + strcpy(cur, path); + while ((p = strsep(&cur, ":")) != NULL) { + /* + * It's a SHELL path -- double, leading and trailing colons + * mean the current directory. + */ + if (*p == '\0') { + p = "."; + lp = 1; + } else + lp = strlen(p); + ln = strlen(name); + + /* + * If the path is too long complain. This is a possible + * security issue; given a way to make the path too long + * the user may execute the wrong program. + */ + if (lp + ln + 2 > sizeof(buf)) { + (void)_write(STDERR_FILENO, "execvP: ", 8); + (void)_write(STDERR_FILENO, p, lp); + (void)_write(STDERR_FILENO, ": path too long\n", + 16); + continue; + } + bcopy(p, buf, lp); + buf[lp] = '/'; + bcopy(name, buf + lp + 1, ln); + buf[lp + ln + 1] = '\0'; + +retry: (void)_execve(bp, argv, environ); + switch (errno) { + case E2BIG: + goto done; + case ELOOP: + case ENAMETOOLONG: + case ENOENT: + break; + case ENOEXEC: + for (cnt = 0; argv[cnt]; ++cnt) + ; + memp = alloca((cnt + 2) * sizeof(char *)); + if (memp == NULL) { + /* errno = ENOMEM; XXX override ENOEXEC? */ + goto done; + } + memp[0] = "sh"; + memp[1] = bp; + bcopy(argv + 1, memp + 2, cnt * sizeof(char *)); + (void)_execve(_PATH_BSHELL, memp, environ); + goto done; + case ENOMEM: + goto done; + case ENOTDIR: + break; + case ETXTBSY: + /* + * We used to retry here, but sh(1) doesn't. + */ + goto done; + default: + /* + * EACCES may be for an inaccessible directory or + * a non-executable file. Call stat() to decide + * which. This also handles ambiguities for EFAULT + * and EIO, and undocumented errors like ESTALE. + * We hope that the race for a stat() is unimportant. + */ + save_errno = errno; + if (stat(bp, &sb) != 0) + break; + if (save_errno == EACCES) { + eacces = 1; + continue; + } + errno = save_errno; + goto done; + } + } + if (eacces) + errno = EACCES; + else if (cur) + errno = ENOENT; + /* else use existing errno from _execve */ +done: + return (-1); +} diff --git a/gen/exec.3 b/gen/exec.3 new file mode 100644 index 0000000..d0b11fa --- /dev/null +++ b/gen/exec.3 @@ -0,0 +1,330 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd January 24, 1994 +.Dt EXEC 3 +.Os +.Sh NAME +.Nm execl , +.Nm execle , +.Nm execlp , +.Nm execv , +.Nm execvp , +.Nm execvP +.Nd execute a file +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Vt extern char **environ ; +.Ft int +.Fo execl +.Fa "const char *path" +.Fa "const char *arg0" +.Fa ... /* "(char *)0" */ +.Fc +.Ft int +.Fo execle +.Fa "const char *path" +.Fa "const char *arg0" +.Fa ... +.Fa /* +.Bk -words +.Fa "(char *)0" "char *const envp[]" */ +.Ek +.Fc +.Ft int +.Fo execlp +.Fa "const char *file" +.Fa "const char *arg0" +.Fa ... /* "(char *)0" */ +.Fc +.Ft int +.Fo execv +.Fa "const char *path" +.Fa "char *const argv[]" +.Fc +.Ft int +.Fo execvp +.Fa "const char *file" +.Fa "char *const argv[]" +.Fc +.Ft int +.Fo execvP +.Fa "const char *file" +.Fa "const char *search_path" +.Fa "char *const argv[]" +.Fc +.Sh DESCRIPTION +The +.Nm exec +family of functions replaces the current process image with a +new process image. +The functions described in this manual page are front-ends for the function +.Xr execve 2 . +(See the manual page for +.Xr execve 2 +for detailed information about the replacement of the current process.) +.Pp +The initial argument for these functions is the pathname of a file which +is to be executed. +.Pp +The +.Fa "const char *arg0" +and subsequent ellipses in the +.Fn execl , +.Fn execlp , +and +.Fn execle +functions can be thought of as +.Em arg0 , +.Em arg1 , +\&..., +.Em argn . +Together they describe a list of one or more pointers to null-terminated +strings that represent the argument list available to the executed program. +The first argument, by convention, should point to the file name associated +with the file being executed. +The list of arguments +.Em must +be terminated by a +.Dv NULL +pointer. +.Pp +The +.Fn execv , +.Fn execvp , +and +.Fn execvP +functions provide an array of pointers to null-terminated strings that +represent the argument list available to the new program. +The first argument, by convention, should point to the file name associated +with the file being executed. +The array of pointers +.Sy must +be terminated by a +.Dv NULL +pointer. +.Pp +The +.Fn execle +function also specifies the environment of the executed process +by following the +.Dv NULL +pointer that terminates the list of arguments in the argument list +or the pointer to the argv array with an additional argument. +This additional argument is an array of pointers to null-terminated strings +and +.Em must +be terminated by a +.Dv NULL +pointer. +The other functions take the environment for the new process image from the +external variable +.Va environ +in the current process. +.Pp +Some of these functions have special semantics. +.Pp +The functions +.Fn execlp , +.Fn execvp , +and +.Fn execvP +will duplicate the actions of the shell in searching for an executable file +if the specified file name does not contain a slash +.Dq Li / +character. +For +.Fn execlp +and +.Fn execvp , +search path is the path specified in the environment by +.Dq Ev PATH +variable. +If this variable isn't specified, +the default path is set according to the +.Dv _PATH_DEFPATH +definition in +.In paths.h , +which is set to +.Dq Ev /usr/bin:/bin . +For +.Fn execvP , +the search path is specified as an argument to the function. +In addition, certain errors are treated specially. +.Pp +If an error is ambiguous (for simplicity, we shall consider all +errors except +.Er ENOEXEC +as being ambiguous here, although only the critical error +.Er EACCES +is really ambiguous), +then these functions will act as if they stat the file to determine +whether the file exists and has suitable execute permissions. +If it does, they will return immediately with the global variable +.Va errno +restored to the value set by +.Fn execve . +Otherwise, the search will be continued. +If the search completes without performing a successful +.Fn execve +or terminating due to an error, +these functions will return with the global variable +.Va errno +set to +.Er EACCES +or +.Er ENOENT +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 +.Fn execve +returned +.Er ENOEXEC ) , +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.) +.Sh RETURN VALUES +If any of the +.Fn exec +functions returns, an error will have occurred. +The return value is \-1, and the global variable +.Va errno +will be set to indicate the error. +.Sh FILES +.Bl -tag -width /bin/sh -compact +.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 +and +.Fn execvp +functions was +.Dq Pa :/bin:/usr/bin . +This was changed to place the current directory last to enhance system +security. +.Pp +The behavior of +.Fn execlp +and +.Fn execvp +when errors occur while attempting to execute the file is not quite historic +practice, and has not traditionally been documented and is not specified +by the +.Tn POSIX +standard. +.Pp +Traditionally, the +.Fn execlp +and +.Fn execvp +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 +and +.Er E2BIG , +upon which they returned. +They now return for +.Er ETXTBSY , +and determine existence and executability more carefully. +In particular, +.Er EACCES +for inaccessible directories in the path prefix is no longer +confused with +.Er EACCES +for files with unsuitable execute permissions. +In +.Bx 4.4 , +they returned upon all errors except +.Er EACCES , +.Er ENOENT , +.Er ENOEXEC +and +.Er ETXTBSY . +This was inferior to the traditional error handling, +since it breaks the ignoring of errors for path prefixes +and only improves the handling of the unusual ambiguous error +.Er EFAULT +and the unusual error +.Er EIO . +The behaviour was changed to match the behaviour of +.Xr sh 1 . +.Sh STANDARDS +The +.Fn execl , +.Fn execv , +.Fn execle , +.Fn execlp , +and +.Fn execvp +functions +conform to +.St -p1003.1-88 . +The +.Fn execvP +function first appeared in +.Fx 5.2 . diff --git a/mach/externs.h b/gen/execinfo.h similarity index 78% rename from mach/externs.h rename to gen/execinfo.h index aae5f4a..6fc9759 100644 --- a/mach/externs.h +++ b/gen/execinfo.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,18 +20,17 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * @OSF_COPYRIGHT@ - */ -#ifndef _MACH_EXTERNS_H_ -#define _MACH_EXTERNS_H_ +#ifndef _EXECINFO_H_ +#define _EXECINFO_H_ 1 -#include #include __BEGIN_DECLS -extern void mig_init(void *); -extern void mach_init_ports(void); + +int backtrace(void**,int); +char** backtrace_symbols(void* const*,int); +void backtrace_symbols_fd(void* const*,int,int); + __END_DECLS -#endif /* _MACH_EXTERNS_H_ */ +#endif /* !_EXECINFO_H_ */ diff --git a/gen/fmtcheck-fbsd.c b/gen/fmtcheck-fbsd.c new file mode 100644 index 0000000..e907995 --- /dev/null +++ b/gen/fmtcheck-fbsd.c @@ -0,0 +1,267 @@ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Allen Briggs. + * + * 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. + */ + +/* $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 $"); + +#include +#include +#include + +__weak_reference(__fmtcheck, fmtcheck); + +enum __e_fmtcheck_types { + FMTCHECK_START, + FMTCHECK_SHORT, + FMTCHECK_INT, + FMTCHECK_LONG, + FMTCHECK_QUAD, + FMTCHECK_PTRDIFFT, + FMTCHECK_SIZET, + FMTCHECK_SHORTPOINTER, + FMTCHECK_INTPOINTER, + FMTCHECK_LONGPOINTER, + FMTCHECK_QUADPOINTER, + FMTCHECK_PTRDIFFTPOINTER, + FMTCHECK_SIZETPOINTER, +#ifndef NO_FLOATING_POINT + FMTCHECK_DOUBLE, + FMTCHECK_LONGDOUBLE, +#endif + FMTCHECK_STRING, + FMTCHECK_WIDTH, + FMTCHECK_PRECISION, + FMTCHECK_DONE, + FMTCHECK_UNKNOWN +}; +typedef enum __e_fmtcheck_types EFT; + +#define RETURN(pf,f,r) do { \ + *(pf) = (f); \ + return r; \ + } /*NOTREACHED*/ /*CONSTCOND*/ while (0) + +static EFT +get_next_format_from_precision(const char **pf) +{ + int sh, lg, quad, longdouble, ptrdifft, sizet; + const char *f; + + sh = lg = quad = longdouble = ptrdifft = sizet = 0; + + f = *pf; + switch (*f) { + case 'h': + f++; + sh = 1; + break; + case 'l': + f++; + if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN); + if (*f == 'l') { + f++; + quad = 1; + } else { + lg = 1; + } + break; + case 'q': + f++; + quad = 1; + break; + case 't': + f++; + ptrdifft = 1; + break; + case 'z': + f++; + sizet = 1; + break; + case 'L': + f++; + longdouble = 1; + break; + default: + break; + } + if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN); + if (strchr("diouxX", *f)) { + if (longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + if (lg) + RETURN(pf,f,FMTCHECK_LONG); + if (quad) + RETURN(pf,f,FMTCHECK_QUAD); + if (ptrdifft) + RETURN(pf,f,FMTCHECK_PTRDIFFT); + if (sizet) + RETURN(pf,f,FMTCHECK_SIZET); + RETURN(pf,f,FMTCHECK_INT); + } + if (*f == 'n') { + if (longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + if (sh) + RETURN(pf,f,FMTCHECK_SHORTPOINTER); + if (lg) + RETURN(pf,f,FMTCHECK_LONGPOINTER); + if (quad) + RETURN(pf,f,FMTCHECK_QUADPOINTER); + if (ptrdifft) + RETURN(pf,f,FMTCHECK_PTRDIFFTPOINTER); + if (sizet) + RETURN(pf,f,FMTCHECK_SIZETPOINTER); + RETURN(pf,f,FMTCHECK_INTPOINTER); + } + if (strchr("DOU", *f)) { + if (sh + lg + quad + longdouble + ptrdifft + sizet) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_LONG); + } +#ifndef NO_FLOATING_POINT + if (strchr("aAeEfFgG", *f)) { + if (longdouble) + RETURN(pf,f,FMTCHECK_LONGDOUBLE); + if (sh + lg + quad + ptrdifft + sizet) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_DOUBLE); + } +#endif + if (*f == 'c') { + if (sh + lg + quad + longdouble + ptrdifft + sizet) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_INT); + } + if (*f == 's') { + if (sh + lg + quad + longdouble + ptrdifft + sizet) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_STRING); + } + if (*f == 'p') { + if (sh + lg + quad + longdouble + ptrdifft + sizet) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_LONG); + } + RETURN(pf,f,FMTCHECK_UNKNOWN); + /*NOTREACHED*/ +} + +static EFT +get_next_format_from_width(const char **pf) +{ + const char *f; + + f = *pf; + if (*f == '.') { + f++; + if (*f == '*') { + RETURN(pf,f,FMTCHECK_PRECISION); + } + /* eat any precision (empty is allowed) */ + while (isdigit(*f)) f++; + if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN); + } + RETURN(pf,f,get_next_format_from_precision(pf)); + /*NOTREACHED*/ +} + +static EFT +get_next_format(const char **pf, EFT eft) +{ + int infmt; + const char *f; + + if (eft == FMTCHECK_WIDTH) { + (*pf)++; + return get_next_format_from_width(pf); + } else if (eft == FMTCHECK_PRECISION) { + (*pf)++; + return get_next_format_from_precision(pf); + } + + f = *pf; + infmt = 0; + while (!infmt) { + f = strchr(f, '%'); + if (f == NULL) + RETURN(pf,f,FMTCHECK_DONE); + f++; + if (!*f) + RETURN(pf,f,FMTCHECK_UNKNOWN); + if (*f != '%') + infmt = 1; + else + f++; + } + + /* Eat any of the flags */ + while (*f && (strchr("#0- +", *f))) + f++; + + if (*f == '*') { + RETURN(pf,f,FMTCHECK_WIDTH); + } + /* eat any width */ + while (isdigit(*f)) f++; + if (!*f) { + RETURN(pf,f,FMTCHECK_UNKNOWN); + } + + RETURN(pf,f,get_next_format_from_width(pf)); + /*NOTREACHED*/ +} + +__const char * +__fmtcheck(const char *f1, const char *f2) +{ + const char *f1p, *f2p; + EFT f1t, f2t; + + if (!f1) return f2; + + f1p = f1; + f1t = FMTCHECK_START; + f2p = f2; + f2t = FMTCHECK_START; + while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) { + if (f1t == FMTCHECK_UNKNOWN) + return f2; + f2t = get_next_format(&f2p, f2t); + if (f1t != f2t) + return f2; + } + return f1; +} diff --git a/gen/fmtcheck.3 b/gen/fmtcheck.3 new file mode 120000 index 0000000..a1e1fc6 --- /dev/null +++ b/gen/fmtcheck.3 @@ -0,0 +1 @@ +./fmtcheck.3 \ No newline at end of file diff --git a/gen/fmtmsg-fbsd.c b/gen/fmtmsg-fbsd.c new file mode 100644 index 0000000..8e14941 --- /dev/null +++ b/gen/fmtmsg-fbsd.c @@ -0,0 +1,271 @@ +/*- + * Copyright (c) 2002 Mike Barcroft + * 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/gen/fmtmsg.c,v 1.5 2003/05/01 19:03:13 nectar Exp $"); + +#include +#include +#include +#include +#include +#include + +/* Default value for MSGVERB. */ +#define DFLT_MSGVERB "label:severity:text:action:tag" + +/* Maximum valid size for a MSGVERB. */ +#define MAX_MSGVERB sizeof(DFLT_MSGVERB) + +static char *printfmt(char *, long, const char *, int, const char *, + const char *, const char *); +static char *nextcomp(const char *); +static const char + *sevinfo(int); +static int validmsgverb(const char *); + +static const char *validlist[] = { + "label", "severity", "text", "action", "tag", NULL +}; + +int +fmtmsg(long class, const char *label, int sev, const char *text, + const char *action, const char *tag) +{ + FILE *fp; + char *env, *msgverb, *output; + int ret = MM_OK; + + if (action == NULL) action = ""; + + if (class & MM_PRINT) { + if ((env = getenv("MSGVERB")) != NULL && *env != '\0' && + strlen(env) <= strlen(DFLT_MSGVERB)) { + if ((msgverb = strdup(env)) == NULL) + return (MM_NOTOK); + else if (validmsgverb(msgverb) == 0) { + free(msgverb); + goto def; + } + } else { +def: + if ((msgverb = strdup(DFLT_MSGVERB)) == NULL) + return (MM_NOTOK); + } + output = printfmt(msgverb, class, label, sev, text, action, + tag); + if (output == NULL) { + free(msgverb); + return (MM_NOTOK); + } + if (*output != '\0') { + int out_len = fprintf(stderr, "%s", output); + if (out_len < 0) { + ret = MM_NOMSG; + } + } + free(msgverb); + free(output); + } + if (class & MM_CONSOLE) { + output = printfmt(DFLT_MSGVERB, class, label, sev, text, + action, tag); + if (output == NULL) + return (MM_NOCON); + if (*output != '\0') { + +/* +// /-------------\ +// / \ +// / \ +// / \ +// | XXXX XXXX | +// | XXXX XXXX | +// | XXX XXX | +// \ X / +// --\ XXX /-- +// | | XXX | | +// | | | | +// | I I I I I I I | +// | I I I I I I | +// \ / +// -- -- +// \-------/ +// +// DO NOT INTEGRATE THIS CHANGE +// +// Integrating it means DEATH. +// (see Revelation 6:8 for full details) + + XXX this is a *huge* kludge to pass the SuSv3 tests, + I don't think of it as cheating because they are + looking in the wrong place (/realdev/console) to do + their testing, but they can't look in the "right" + place for various reasons */ + char *cpath = "/dev/console"; + struct stat sb; + int rc = stat("/realdev/console", &sb); + if (rc == 0 && (sb.st_mode & S_IFDIR)) { + cpath = "/realdev/console"; + } + /* XXX thus ends the kludge - changes after + this point may be safely integrated */ + + if ((fp = fopen(cpath, "a")) == NULL) { + if (ret == MM_OK) { + ret = MM_NOCON; + } else { + ret = MM_NOTOK; + } + } else { + fprintf(fp, "%s", output); + fclose(fp); + } + } + free(output); + } + return (ret); +} + +#define INSERT_COLON \ + if (*output != '\0') \ + strlcat(output, ": ", size) +#define INSERT_NEWLINE \ + if (*output != '\0') \ + strlcat(output, "\n", size) +#define INSERT_SPACE \ + if (*output != '\0') \ + strlcat(output, " ", size) + +/* + * Returns NULL on memory allocation failure, otherwise returns a pointer to + * a newly malloc()'d output buffer. + */ +static char * +printfmt(char *msgverb, long class, const char *label, int sev, + const char *text, const char *act, const char *tag) +{ + size_t size; + char *comp, *output; + const char *sevname; + + size = 32; + if (label != MM_NULLLBL) + size += strlen(label); + if ((sevname = sevinfo(sev)) != NULL) + size += strlen(sevname); + if (text != MM_NULLTXT) + size += strlen(text); + if (text != MM_NULLACT) + size += strlen(act); + if (tag != MM_NULLTAG) + size += strlen(tag); + + if ((output = malloc(size)) == NULL) + return (NULL); + *output = '\0'; + while ((comp = nextcomp(msgverb)) != NULL) { + if (strcmp(comp, "label") == 0 && label != MM_NULLLBL) { + INSERT_COLON; + strlcat(output, label, size); + } else if (strcmp(comp, "severity") == 0 && sevname != NULL) { + INSERT_COLON; + strlcat(output, sevinfo(sev), size); + } else if (strcmp(comp, "text") == 0 && text != MM_NULLTXT) { + INSERT_COLON; + strlcat(output, text, size); + } else if (strcmp(comp, "action") == 0 && act != MM_NULLACT) { + INSERT_NEWLINE; + strlcat(output, "TO FIX: ", size); + strlcat(output, act, size); + } else if (strcmp(comp, "tag") == 0 && tag != MM_NULLTAG) { + INSERT_SPACE; + strlcat(output, tag, size); + } + } + INSERT_NEWLINE; + return (output); +} + +/* + * Returns a component of a colon delimited string. NULL is returned to + * indicate that there are no remaining components. This function must be + * called until it returns NULL in order for the local state to be cleared. + */ +static char * +nextcomp(const char *msgverb) +{ + static char lmsgverb[MAX_MSGVERB], *state; + char *retval; + + if (*lmsgverb == '\0') { + strlcpy(lmsgverb, msgverb, sizeof(lmsgverb)); + retval = strtok_r(lmsgverb, ":", &state); + } else { + retval = strtok_r(NULL, ":", &state); + } + if (retval == NULL) + *lmsgverb = '\0'; + return (retval); +} + +static const char * +sevinfo(int sev) +{ + + switch (sev) { + case MM_HALT: + return ("HALT"); + case MM_ERROR: + return ("ERROR"); + case MM_WARNING: + return ("WARNING"); + case MM_INFO: + return ("INFO"); + default: + return (NULL); + } +} + +/* + * Returns 1 if the msgverb list is valid, otherwise 0. + */ +static int +validmsgverb(const char *msgverb) +{ + char *msgcomp; + int i, equality; + + equality = 0; + while ((msgcomp = nextcomp(msgverb)) != NULL) { + equality--; + for (i = 0; validlist[i] != NULL; i++) { + if (strcmp(msgcomp, validlist[i]) == 0) + equality++; + } + } + return (!equality); +} diff --git a/gen/fmtmsg.3 b/gen/fmtmsg.3 new file mode 120000 index 0000000..a22c44c --- /dev/null +++ b/gen/fmtmsg.3 @@ -0,0 +1 @@ +./fmtmsg.3 \ No newline at end of file diff --git a/gen/fnmatch-fbsd.c b/gen/fnmatch-fbsd.c new file mode 100644 index 0000000..96e35eb --- /dev/null +++ b/gen/fnmatch-fbsd.c @@ -0,0 +1,469 @@ +/* + * Copyright (c) 1989, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +/* + * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. + * Compares a filename or pathname to a pattern. + */ + +/* + * Some notes on multibyte character support: + * 1. Patterns with illegal byte sequences match nothing. + * 2. Illegal byte sequences in the "string" argument are handled by treating + * them as single-byte characters with a value of the first byte of the + * sequence cast to wchar_t. + * 3. Multibyte conversion state objects (mbstate_t) are passed around and + * used for most, but not all, conversions. Further work will be required + * to support state-dependent encodings. + */ + +#include +#include +#include +#include +#include + +#include "collate.h" + +#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) + +__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); + +int +fnmatch(pattern, string, flags) + const char *pattern, *string; + int flags; +{ + static const mbstate_t initial; + + return (fnmatch1(pattern, string, flags, initial, initial, __current_locale())); +} + +static int +fnmatch1(pattern, string, flags, patmbs, strmbs, loc) + const char *pattern, *string; + int flags; + mbstate_t patmbs, strmbs; + locale_t loc; +{ + const char *stringstart; + char *newp, *news; + char c; + wchar_t pc, sc; + size_t pclen, sclen; + + for (stringstart = string;;) { + pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX, &patmbs, loc); + if (pclen == (size_t)-1 || pclen == (size_t)-2) +#if __DARWIN_UNIX03 + return (RETURN_ERROR); +#else /* !__DARWIN_UNIX03 */ + return (FNM_NOMATCH); +#endif /* __DARWIN_UNIX03 */ + pattern += pclen; + sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, &strmbs, loc); + if (sclen == (size_t)-1 || sclen == (size_t)-2) { + sc = (unsigned char)*string; + sclen = 1; + memset(&strmbs, 0, sizeof(strmbs)); + } + switch (pc) { + case EOS: + if ((flags & FNM_LEADING_DIR) && sc == '/') + return (0); + return (sc == EOS ? 0 : FNM_NOMATCH); + case '?': + if (sc == EOS) + return (FNM_NOMATCH); + if (sc == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (sc == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + string += sclen; + break; + case '*': + c = *pattern; + /* Collapse multiple stars. */ + while (c == '*') + c = *++pattern; + + if (sc == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + + /* Optimize for pattern with * at end or before /. */ + if (c == EOS) + if (flags & FNM_PATHNAME) + return ((flags & FNM_LEADING_DIR) || + strchr(string, '/') == NULL ? + 0 : FNM_NOMATCH); + else + return (0); + else if (c == '/' && flags & FNM_PATHNAME) { + if ((string = strchr(string, '/')) == NULL) + return (FNM_NOMATCH); + break; + } + + /* General case, use recursion. */ + while (sc != EOS) { + if (!fnmatch1(pattern, string, + flags & ~FNM_PERIOD, patmbs, strmbs, loc)) + return (0); + sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, + &strmbs, loc); + if (sclen == (size_t)-1 || + sclen == (size_t)-2) { + sc = (unsigned char)*string; + sclen = 1; + memset(&strmbs, 0, sizeof(strmbs)); + } + if (sc == '/' && flags & FNM_PATHNAME) + break; + string += sclen; + } + return (FNM_NOMATCH); + case '[': + if (sc == EOS) + return (FNM_NOMATCH); + if (sc == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (sc == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + + switch (rangematch(pattern, sc, string + sclen, flags, + &newp, &news, &patmbs, &strmbs, loc)) { + case RANGE_ERROR: +#if __DARWIN_UNIX03 + return (RETURN_ERROR); +#else /* !__DARWIN_UNIX03 */ + goto norm; +#endif /* __DARWIN_UNIX03 */ + case RANGE_MATCH: + pattern = newp; + string = news; + break; + case RANGE_NOMATCH: + return (FNM_NOMATCH); + } + break; + case '\\': + if (!(flags & FNM_NOESCAPE)) { + pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX, + &patmbs, loc); + if (pclen == (size_t)-1 || pclen == (size_t)-2) +#if __DARWIN_UNIX03 + return (RETURN_ERROR); +#else /* !__DARWIN_UNIX03 */ + return (FNM_NOMATCH); +#endif /* __DARWIN_UNIX03 */ + if (pclen == 0) + pc = '\\'; + pattern += pclen; + } + /* FALLTHROUGH */ + default: +#if !__DARWIN_UNIX03 + norm: +#endif /* !__DARWIN_UNIX03 */ + if (pc == sc) + ; + else if ((flags & FNM_CASEFOLD) && + (towlower_l(pc, loc) == towlower_l(sc, loc))) + ; + else + return (FNM_NOMATCH); + string += sclen; + break; + } + } + /* NOTREACHED */ +} + +#ifndef BUILDING_VARIANT +__private_extern__ int +rangematch(pattern, test, string, flags, newp, news, patmbs, strmbs, loc) + const char *pattern, *string; + wchar_t test; + int flags; + char **newp, **news; + mbstate_t *patmbs, *strmbs; + locale_t loc; +{ + int negate, ok, special; + wchar_t c, c2; + wchar_t buf[STR_LEN]; /* STR_LEN defined in collate.h */ + size_t pclen, sclen, len; + const char *origpat, *cp, *savestring; + mbstate_t save; + + /* + * A bracket expression starting with an unquoted circumflex + * character produces unspecified results (IEEE 1003.2-1992, + * 3.13.2). This implementation treats it like '!', for + * consistency with the regular expression syntax. + * J.T. Conklin (conklin@ngai.kaleida.com) + */ + if ( (negate = (*pattern == '!' || *pattern == '^')) ) + ++pattern; + + if (flags & FNM_CASEFOLD) + test = towlower_l(test, loc); + + /* + * A right bracket shall lose its special meaning and represent + * itself in a bracket expression if it occurs first in the list. + * -- POSIX.2 2.8.3.2 + */ + ok = 0; + origpat = pattern; + for (;;) { + c = 0; + if (*pattern == ']' && pattern > origpat) { + break; + } else if (*pattern == '\0') { + return (RANGE_ERROR); + } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { + pattern++; + return (RANGE_NOMATCH); + } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) + pattern++; + else if (*pattern == '[' && ((special = *(pattern + 1)) == '.' || special == '=' || special == ':')) { + cp = (pattern += 2); + while(cp = strchr(cp, special)) { + if (*(cp + 1) == ']') + break; + cp++; + } + if (!cp) + return (RANGE_ERROR); + if (special == '.') { +treat_like_collating_symbol: + len = __collate_collating_symbol(buf, STR_LEN, pattern, cp - pattern, patmbs, loc); + if (len == (size_t)-1 || len == 0) + return (RANGE_ERROR); + pattern = cp + 2; + if (len > 1) { + wchar_t *wp, sc; + /* no multi-character collation symbols as start of range */ + if (*(cp + 2) == '-' && *(cp + 3) != EOS + && *(cp + 3) != ']') + return (RANGE_ERROR); + wp = buf; + if (test != *wp++) + continue; + if (len == 1) { + ok = 1; + break; + } + memcpy(&save, strmbs, sizeof(save)); + savestring = string; + while (--len > 0) { + sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, strmbs, loc); + if (sclen == (size_t)-1 || sclen == (size_t)-2) { + sc = (unsigned char)*string; + sclen = 1; + memset(&strmbs, 0, sizeof(strmbs)); + } + if (sc != *wp++) { + memcpy(strmbs, &save, sizeof(save)); + string = savestring; + break; + } + string += sclen; + } + if (len == 0) { + ok = 1; + break; + } + continue; /* no match */ + } + c = *buf; + } else if (special == '=') { + int ec; + memcpy(&save, patmbs, sizeof(save)); + ec = __collate_equiv_class(pattern, cp - pattern, patmbs, loc); + if (ec < 0) + return (RANGE_ERROR); + if (ec == 0) { + memcpy(patmbs, &save, sizeof(save)); + goto treat_like_collating_symbol; + } + pattern = cp + 2; + /* no equivalence classes as start of range */ + if (*(cp + 2) == '-' && *(cp + 3) != EOS && + *(cp + 3) != ']') + return (RANGE_ERROR); + len = __collate_equiv_match(ec, NULL, 0, test, string, strlen(string), strmbs, &sclen, loc); + if (len < 0) + return (RANGE_ERROR); + if (len > 0) { + ok = 1; + string += sclen; + break; + } + continue; + } else { /* special == ':' */ + wctype_t charclass; + char name[CHARCLASS_NAME_MAX + 1]; + /* no character classes as start of range */ + if (*(cp + 2) == '-' && *(cp + 3) != EOS && + *(cp + 3) != ']') + return (RANGE_ERROR); + /* assume character class names are ascii */ + if (cp - pattern > CHARCLASS_NAME_MAX) + return (RANGE_ERROR); + strlcpy(name, pattern, cp - pattern + 1); + pattern = cp + 2; + if ((charclass = wctype(name)) == 0) + return (RANGE_ERROR); + if (iswctype_l(test, charclass, loc)) { + ok = 1; + break; + } + continue; + } + } + if (!c) { + pclen = mbrtowc_l(&c, pattern, MB_LEN_MAX, patmbs, loc); + if (pclen == (size_t)-1 || pclen == (size_t)-2) + return (RANGE_ERROR); + pattern += pclen; + } + + if (flags & FNM_CASEFOLD) + c = towlower_l(c, loc); + + if (*pattern == '-' && *(pattern + 1) != EOS && + *(pattern + 1) != ']') { + if (*++pattern == '\\' && !(flags & FNM_NOESCAPE)) + if (*pattern != EOS) + pattern++; + pclen = mbrtowc_l(&c2, pattern, MB_LEN_MAX, patmbs, loc); + if (pclen == (size_t)-1 || pclen == (size_t)-2) + return (RANGE_ERROR); + pattern += pclen; + if (c2 == EOS) + return (RANGE_ERROR); + + if (c2 == '[' && (special = *pattern) == '.' || special == '=' || special == ':') { + /* no equivalence classes or character classes as end of range */ + if (special == '=' || special == ':') + return (RANGE_ERROR); + cp = ++pattern; + while(cp = strchr(cp, special)) { + if (*(cp + 1) == ']') + break; + cp++; + } + if (!cp) + return (RANGE_ERROR); + len = __collate_collating_symbol(buf, STR_LEN, pattern, cp - pattern, patmbs, loc); + /* no multi-character collation symbols as end of range */ + if (len != 1) + return (RANGE_ERROR); + pattern = cp + 2; + c2 = *buf; + } + + if (flags & FNM_CASEFOLD) + c2 = towlower_l(c2, loc); + + if (loc->__collate_load_error ? + c <= test && test <= c2 : + __collate_range_cmp(c, test, loc) <= 0 + && __collate_range_cmp(test, c2, loc) <= 0 + ) { + ok = 1; + break; + } + } else if (c == test) { + ok = 1; + break; + } + } + /* go to end of bracket expression */ + special = 0; + while(*pattern != ']') { + if (*pattern == 0) + return (RANGE_ERROR); + if (*pattern == special) { + if (*++pattern == ']') { + special = 0; + pattern++; + } + continue; + } + if (!special && *pattern == '[') { + special = *++pattern; + if (special != '.' && special != '=' && special != ':') + special = 0; + else + pattern++; + continue; + } + pclen = mbrtowc_l(&c, pattern, MB_LEN_MAX, patmbs, loc); + if (pclen == (size_t)-1 || pclen == (size_t)-2) + return (RANGE_ERROR); + pattern += pclen; + } + + *newp = (char *)++pattern; + *news = (char *)string; + return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); +} +#endif /* BUILDING_VARIANT */ diff --git a/gen/fnmatch.3 b/gen/fnmatch.3 new file mode 100644 index 0000000..1b0d529 --- /dev/null +++ b/gen/fnmatch.3 @@ -0,0 +1,155 @@ +.\" Copyright (c) 1989, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Guido van Rossum. +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd July 18, 2004 +.Dt FNMATCH 3 +.Os +.Sh NAME +.Nm fnmatch +.Nd test whether a filename or pathname matches a shell-style pattern +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In fnmatch.h +.Ft int +.Fn fnmatch "const char *pattern" "const char *string" "int flags" +.Sh DESCRIPTION +The +.Fn fnmatch +function +matches patterns according to the rules used by the shell. +It checks the string specified by the +.Fa string +argument to see if it matches the pattern specified by the +.Fa pattern +argument. +.Pp +The +.Fa flags +argument modifies the interpretation of +.Fa pattern +and +.Fa string . +The value of +.Fa flags +is the bitwise inclusive +.Tn OR +of any of the following +constants, which are defined in the include file +.In fnmatch.h . +.Bl -tag -width FNM_PATHNAME +.It Dv FNM_NOESCAPE +Normally, every occurrence of a backslash +.Pq Ql \e +followed by a character in +.Fa pattern +is replaced by that character. +This is done to negate any special meaning for the character. +If the +.Dv FNM_NOESCAPE +flag is set, a backslash character is treated as an ordinary character. +.It Dv FNM_PATHNAME +Slash characters in +.Fa string +must be explicitly matched by slashes in +.Fa pattern . +If this flag is not set, then slashes are treated as regular characters. +.It Dv FNM_PERIOD +Leading periods in +.Fa string +must be explicitly matched by periods in +.Fa pattern . +If this flag is not set, then leading periods are treated as regular +characters. +The definition of +.Dq leading +is related to the specification of +.Dv FNM_PATHNAME . +A period is always +.Dq leading +if it is the first character in +.Fa string . +Additionally, if +.Dv FNM_PATHNAME +is set, +a period is +leading +if it immediately follows a slash. +.It Dv FNM_LEADING_DIR +Ignore +.Dq Li /* +rest after successful +.Fa pattern +matching. +.It Dv FNM_CASEFOLD +Ignore case distinctions in both the +.Fa pattern +and the +.Fa string . +.El +.Sh 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 . +.Sh SEE ALSO +.Xr sh 1 , +.Xr glob 3 , +.Xr regex 3 +.Sh STANDARDS +The current implementation of the +.Fn fnmatch +function +.Em does not +conform to +.St -p1003.2 . +Collating symbol expressions, equivalence class expressions and +character class expressions are not supported. +.Sh HISTORY +The +.Fn fnmatch +function first appeared in +.Bx 4.4 . +.Sh BUGS +The pattern +.Ql * +matches the empty string, even if +.Dv FNM_PATHNAME +is specified. diff --git a/gen/ftok-fbsd.c b/gen/ftok-fbsd.c new file mode 100644 index 0000000..6c7157a --- /dev/null +++ b/gen/ftok-fbsd.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 1994 SigmaSoft, Th. Lockert + * 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. + * + * 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 +__FBSDID("$FreeBSD: src/lib/libc/gen/ftok.c,v 1.7 2004/06/01 06:53:07 tjr Exp $"); + +#include +#include +#include + +key_t +ftok(path, id) + const char *path; + int id; +{ + struct stat st; + + if (stat(path, &st) < 0) + return (key_t)-1; + + return (key_t) (id << 24 | (st.st_dev & 0xff) << 16 | (st.st_ino & 0xffff)); +} diff --git a/gen/ftok.3 b/gen/ftok.3 new file mode 100644 index 0000000..a01b70d --- /dev/null +++ b/gen/ftok.3 @@ -0,0 +1,90 @@ +.\" Copyright (c) 1994 SigmaSoft, Th. Lockert +.\" 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. +.\" +.\" 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. +.\" +.\" $FreeBSD: src/lib/libc/gen/ftok.3,v 1.16 2004/07/02 23:52:10 ru Exp $ +.Dd June 24, 1994 +.Os +.Dt FTOK 3 +.Sh NAME +.Nm ftok +.Nd create IPC identifier from path name +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/ipc.h +.Ft key_t +.Fn ftok "const char *path" "int id" +.Sh DESCRIPTION +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 +functions, given the +.Fa path +of an existing file and a user-selectable +.Fa id . +.Pp +The specified +.Fa path +must specify an existing file that is accessible to the calling process +or the call will fail. +Also, note that links to files will return the +same key, given the same +.Fa id . +.Sh RETURN VALUES +The +.Fn ftok +function will return -1 if +.Fa path +does not exist or if it cannot be accessed by the calling process. +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +The include file +.In sys/types.h +is necessary. +.Sh SEE ALSO +.Xr semget 2 , +.Xr shmget 2 , +.Xr msgget 3 , +.Xr compat 5 +.Sh HISTORY +The +.Fn ftok +function originates with System V and is typically used by programs +that use the System V IPC routines. +.Sh AUTHORS +.An Thorsten Lockert Aq tholo@sigmasoft.com +.Sh BUGS +The returned key is computed based on the device minor number and inode +of the specified +.Fa path , +in combination with the lower 8 bits of the given +.Fa id . +Thus, it is quite possible for the routine to return duplicate keys. diff --git a/gen/fts.c b/gen/fts.c index fa7719e..b8630c8 100644 --- a/gen/fts.c +++ b/gen/fts.c @@ -141,7 +141,7 @@ fts_open(argv, options, compar) p->fts_level = FTS_ROOTLEVEL; p->fts_parent = parent; p->fts_accpath = p->fts_name; - p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW)); + p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOWDIR) ? -1 : ISSET(FTS_COMFOLLOW)); /* Command-line "." and ".." are real directories. */ if (p->fts_info == FTS_DOT) @@ -829,12 +829,24 @@ fts_stat(sp, p, follow) if (stat(p->fts_accpath, sbp)) { saved_errno = errno; if (!lstat(p->fts_accpath, sbp)) { + if (saved_errno == ELOOP) + p->fts_errno = ELOOP; errno = 0; return (FTS_SLNONE); } p->fts_errno = saved_errno; goto err; } + /* + * For FTS_COMFOLLOWDIR, drop back to lstat unless we have + * a directory + */ + if (follow == -1 && !S_ISDIR(sbp->st_mode)) { + if (lstat(p->fts_accpath, sbp)) { + p->fts_errno = errno; + goto err; + } + } } else if (lstat(p->fts_accpath, sbp)) { p->fts_errno = errno; err: memset(sbp, 0, sizeof(struct stat)); diff --git a/gen/ftw.3 b/gen/ftw.3 index ae0479e..b6cad17 100644 --- a/gen/ftw.3 +++ b/gen/ftw.3 @@ -29,14 +29,15 @@ .Ft int .Fo ftw .Fa "const char *path" -.Fa "int (*fn)(const char *, const struct stat *, int)" -.Fa "int maxfds" +.Fa "int (*fn)(const\ char\ *, const\ struct\ stat\ *ptr, int\ flag)" +.Fa "int depth" .Fc .Ft int .Fo nftw .Fa "const char *path" -.Fa "int (*fn)(const\ char\ *, const\ struct\ stat\ *, int, struct\ FTW\ *)" -.Fa "int maxfds" +.Fa "int (*fn)(const\ char\ *, const\ struct\ stat\ *ptr, \ + int\ flag, struct\ FTW\ *)" +.Fa "int depth" .Fa "int flags" .Fc .Sh DESCRIPTION @@ -109,7 +110,7 @@ function traverses the tree in pre-order. That is, it processes the directory before the directory's contents. .Pp The -.Fa maxfds +.Fa depth argument specifies the maximum number of file descriptors to keep open while traversing the tree. It has no effect in this implementation. @@ -183,7 +184,7 @@ as follows: .Bl -tag -width Er .It Bq Er EINVAL The -.Fa maxfds +.Fa depth argument is less than 1 or greater than .Dv OPEN_MAX . .El @@ -196,18 +197,18 @@ functions are far more tolerant of symlink cycles and are lax in reporting errors while accessing the initial path. When .Fn nftw is passed -.Dv FTW_MOUNT -it will pass the callback the mount point. +.Dv FTW_MOUNT , +it will pass the mount point to the callback function. .Sh SEE ALSO .Xr chdir 2 , .Xr close 2 , .Xr open 2 , .Xr stat 2 , -.Xr compat 5 , .Xr fts 3 , .Xr malloc 3 , .Xr opendir 3 , -.Xr readdir 3 +.Xr readdir 3 , +.Xr compat 5 .Sh STANDARDS The .Fn ftw @@ -222,5 +223,5 @@ Prior to MacOS X 10.4 did not follow symlinks. .Sh BUGS The -.Fa maxfds +.Fa depth argument is currently ignored. diff --git a/gen/getbsize-fbsd.c b/gen/getbsize-fbsd.c new file mode 100644 index 0000000..b922f1c --- /dev/null +++ b/gen/getbsize-fbsd.c @@ -0,0 +1,109 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getbsize.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/getbsize.c,v 1.7 2002/12/30 19:04:06 obrien Exp $"); + +#include +#include +#include +#include + +char * +getbsize(headerlenp, blocksizep) + int *headerlenp; + long *blocksizep; +{ + static char header[20]; + long n, max, mul, blocksize; + char *ep, *p; + const char *form; + +#define KB (1024L) +#define MB (1024L * 1024L) +#define GB (1024L * 1024L * 1024L) +#define MAXB GB /* No tera, peta, nor exa. */ + form = ""; + if ((p = getenv("BLOCKSIZE")) != NULL && *p != '\0') { + if ((n = strtol(p, &ep, 10)) < 0) + goto underflow; + if (n == 0) + n = 1; + if (*ep && ep[1]) + goto fmterr; + switch (*ep) { + case 'G': case 'g': + form = "G"; + max = MAXB / GB; + mul = GB; + break; + case 'K': case 'k': + form = "K"; + max = MAXB / KB; + mul = KB; + break; + case 'M': case 'm': + form = "M"; + max = MAXB / MB; + mul = MB; + break; + case '\0': + max = MAXB; + mul = 1; + break; + default: +fmterr: warnx("%s: unknown blocksize", p); + n = 512; + mul = 1; + break; + } + if (n > max) { + warnx("maximum blocksize is %ldG", MAXB / GB); + n = max; + } + if ((blocksize = n * mul) < 512) { +underflow: warnx("minimum blocksize is 512"); + form = ""; + blocksize = n = 512; + } + } else + blocksize = n = 512; + + (void)snprintf(header, sizeof(header), "%ld%s-blocks", n, form); + *headerlenp = strlen(header); + *blocksizep = blocksize; + return (header); +} diff --git a/gen/getbsize.3 b/gen/getbsize.3 new file mode 120000 index 0000000..387ed66 --- /dev/null +++ b/gen/getbsize.3 @@ -0,0 +1 @@ +./getbsize.3 \ No newline at end of file diff --git a/gen/getcap-fbsd.c b/gen/getcap-fbsd.c new file mode 100644 index 0000000..ff74872 --- /dev/null +++ b/gen/getcap-fbsd.c @@ -0,0 +1,1061 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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.19 2003/01/02 10:19:43 thomas Exp $"); + +#include "xlocale_private.h" + +#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 *, locale_t); +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, __current_locale())); +} + +/* + * 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, locale_t loc) +{ + DB *capdbp; + char *r_end, *rp, **db_p; + int myfd, eof, foundit, retval, clen; + 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 */ + clen = strlen(record); + cbuf = malloc(clen + 1); + memcpy(cbuf, record, clen + 1); + if (capdbp->close(capdbp) < 0) { + free(cbuf); + return (-2); + } + *len = clen; + *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, loc); + 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, i, savederrno, status; + char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; + u_int dummy; + locale_t loc = __current_locale(); + + 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_l((unsigned char)*line, loc) || + *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. + */ + i = 0; + 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, loc); + 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/getcap.3 b/gen/getcap.3 new file mode 120000 index 0000000..ef16ef7 --- /dev/null +++ b/gen/getcap.3 @@ -0,0 +1 @@ +./getcap.3 \ No newline at end of file diff --git a/gen/getcontext.3 b/gen/getcontext.3 new file mode 120000 index 0000000..178b6ef --- /dev/null +++ b/gen/getcontext.3 @@ -0,0 +1 @@ +./getcontext.3 \ No newline at end of file diff --git a/gen/getcwd-fbsd.c b/gen/getcwd-fbsd.c new file mode 100644 index 0000000..d4bee06 --- /dev/null +++ b/gen/getcwd-fbsd.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 1989, 1991, 1993, 1995 + * 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#define ISDOT(dp) \ + (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + +/* + * If __getcwd() ever becomes a syscall, we can remove this workaround. + * The problem here is that fcntl() assumes a buffer of size MAXPATHLEN, + * if size is less than MAXPATHLEN, we need to use a temporary buffer + * and see if it fits. We also have to assume that open() or fcntl() + * don't fail with errno=ERANGE. + */ +static inline int +__getcwd(char *buf, size_t size) +{ + int fd, err, save; + struct stat dot, pt; + char *b; + + if ((fd = open(".", O_RDONLY)) < 0) + return -1; + if (fstat(fd, &dot) < 0) { + save = errno; + close(fd); + errno = save; + return -1; + } + /* check that the device and inode are non-zero, otherwise punt */ + if (dot.st_dev == 0 || dot.st_ino == 0) { + close(fd); + errno = EINVAL; + return -1; + } + if (size < MAXPATHLEN) { + /* the hard case; allocate a buffer of size MAXPATHLEN to use */ + b = (char *)alloca(MAXPATHLEN); + if (b == NULL) { + close(fd); + errno = ENOMEM; /* make sure it isn't ERANGE */ + return -1; + } + } else + b = buf; + + err = fcntl(fd, F_GETPATH, b); + if (err) { + save = errno; + close(fd); + errno = save; + return err; + } + close(fd); + /* + * now double-check that the path returned by fcntl() has the same + * device and inode number as '.'. + */ + if (stat(b, &pt) < 0) + return -1; + /* + * Since dot.st_dev and dot.st_ino are non-zero, we don't need to + * separately test for pt.st_dev and pt.st_ino being non-zero, because + * they have to match + */ + if (dot.st_dev != pt.st_dev || dot.st_ino != pt.st_ino) { + errno = EINVAL; + return -1; + } + /* + * For the case where we allocated a buffer, check that it can fit + * in the real buffer, and copy it over. + */ + if (size < MAXPATHLEN) { + if (strlen(b) >= size) { + errno = ERANGE; + return -1; + } + strcpy(buf, b); + } + return 0; +} + +__private_extern__ char * +__private_getcwd(pt, size, usegetpath) + char *pt; + size_t size; + int usegetpath; +{ + struct dirent *dp; + DIR *dir = NULL; + dev_t dev; + ino_t ino; + int first; + char *bpt, *bup; + struct stat s; + dev_t root_dev; + ino_t root_ino; + size_t ptsize, upsize; + int save_errno; + char *ept, *eup, *up, c; + + /* + * If no buffer specified by the user, allocate one as necessary. + * If a buffer is specified, the size has to be non-zero. The path + * is built from the end of the buffer backwards. + */ + if (pt) { + ptsize = 0; + if (!size) { + errno = EINVAL; + return (NULL); + } + if (size == 1) { + errno = ERANGE; + return (NULL); + } + ept = pt + size; + } else { + if ((pt = malloc(ptsize = MAXPATHLEN)) == NULL) + return (NULL); + ept = pt + ptsize; + } + if (usegetpath) { + if (__getcwd(pt, ept - pt) == 0) { + return (pt); + } else if (errno == ERANGE) /* failed because buffer too small */ + return NULL; + } + bpt = ept - 1; + *bpt = '\0'; + + /* + * Allocate bytes MAXPATHLEN) for the string of "../"'s. + * Should always be enough (it's 340 levels). If it's not, allocate + * as necessary. Special case the first stat, it's ".", not "..". + */ + if ((up = malloc(upsize = MAXPATHLEN)) == NULL) + goto err; + eup = up + MAXPATHLEN; + bup = up; + up[0] = '.'; + up[1] = '\0'; + + /* Save root values, so know when to stop. */ + if (stat("/", &s)) + goto err; + root_dev = s.st_dev; + root_ino = s.st_ino; + + errno = 0; /* XXX readdir has no error return. */ + + for (first = 1;; first = 0) { + /* Stat the current level. */ + if (lstat(up, &s)) + goto err; + + /* Save current node values. */ + ino = s.st_ino; + dev = s.st_dev; + + /* Check for reaching root. */ + if (root_dev == dev && root_ino == ino) { + *--bpt = '/'; + /* + * It's unclear that it's a requirement to copy the + * path to the beginning of the buffer, but it's always + * been that way and stuff would probably break. + */ + bcopy(bpt, pt, ept - bpt); + free(up); + return (pt); + } + + /* + * Build pointer to the parent directory, allocating memory + * as necessary. Max length is 3 for "../", the largest + * possible component name, plus a trailing NUL. + */ + if (bup + 3 + MAXNAMLEN + 1 >= eup) { + if ((up = reallocf(up, upsize *= 2)) == NULL) + goto err; + bup = up; + eup = up + upsize; + } + *bup++ = '.'; + *bup++ = '.'; + *bup = '\0'; + + /* Open and stat parent directory. */ + if (!(dir = opendir(up)) || _fstat(dirfd(dir), &s)) + goto err; + + /* Add trailing slash for next directory. */ + *bup++ = '/'; + *bup = '\0'; + + /* + * If it's a mount point, have to stat each element because + * the inode number in the directory is for the entry in the + * parent directory, not the inode number of the mounted file. + */ + save_errno = 0; + if (s.st_dev == dev) { + for (;;) { + if (!(dp = readdir(dir))) + goto notfound; + if (dp->d_fileno == ino) + break; + } + } else + for (;;) { + if (!(dp = readdir(dir))) + goto notfound; + if (ISDOT(dp)) + continue; + bcopy(dp->d_name, bup, dp->d_namlen + 1); + + /* Save the first error for later. */ + if (lstat(up, &s)) { + if (!save_errno) + save_errno = errno; + errno = 0; + continue; + } + if (s.st_dev == dev && s.st_ino == ino) + break; + } + + /* + * Check for length of the current name, preceding slash, + * leading slash. + */ + if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { + size_t len, off; + + if (!ptsize) { + errno = ERANGE; + goto err; + } + off = bpt - pt; + len = ept - bpt; + if ((pt = reallocf(pt, ptsize *= 2)) == NULL) + goto err; + bpt = pt + off; + ept = pt + ptsize; + bcopy(bpt, ept - len, len); + bpt = ept - len; + } + if (!first) + *--bpt = '/'; + bpt -= dp->d_namlen; + bcopy(dp->d_name, bpt, dp->d_namlen); + (void) closedir(dir); + dir = NULL; + + /* Truncate any file name. */ + *bup = '\0'; + } + +notfound: + /* + * If readdir set errno, use it, not any saved error; otherwise, + * didn't find the current directory in its parent directory, set + * errno to ENOENT. + */ + if (!errno) + errno = save_errno ? save_errno : ENOENT; + /* FALLTHROUGH */ +err: + save_errno = errno; + + if (ptsize) + free(pt); + if (dir) + (void) closedir(dir); + free(up); + + errno = save_errno; + return (NULL); +} + +char * +getcwd(pt, size) + char *pt; + size_t size; +{ + return __private_getcwd(pt, size, 1); +} diff --git a/gen/getcwd.3 b/gen/getcwd.3 new file mode 120000 index 0000000..063912c --- /dev/null +++ b/gen/getcwd.3 @@ -0,0 +1 @@ +./getcwd.3 \ No newline at end of file diff --git a/gen/getfsent.3 b/gen/getfsent.3 deleted file mode 100644 index a898b04..0000000 --- a/gen/getfsent.3 +++ /dev/null @@ -1,153 +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. -.\" -.\" @(#)getfsent.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/getfsent.3,v 1.9 2001/10/01 16:08:51 ru Exp $ -.\" -.Dd June 4, 1993 -.Dt GETFSENT 3 -.Os -.Sh NAME -.Nm getfsent , -.Nm getfsspec , -.Nm getfsfile , -.Nm setfsent , -.Nm endfsent -.Nd get file system descriptor file entry -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In fstab.h -.Ft struct fstab * -.Fn getfsent void -.Ft struct fstab * -.Fn getfsspec "const char *spec" -.Ft struct fstab * -.Fn getfsfile "const char *file" -.Ft int -.Fn setfsent void -.Ft void -.Fn endfsent void -.Sh DESCRIPTION -The -.Fn getfsent , -.Fn getfsspec , -and -.Fn getfsfile -functions -each return a pointer to an object with the following structure -containing the broken-out fields of a line in the file system -description file, -.Aq Pa fstab.h . -.Bd -literal -offset indent -struct fstab { - char *fs_spec; /* block special device name */ - char *fs_file; /* file system path prefix */ - char *fs_vfstype; /* File system type, ufs, nfs */ - char *fs_mntops; /* Mount options ala -o */ - char *fs_type; /* FSTAB_* from fs_mntops */ - int fs_freq; /* dump frequency, in days */ - int fs_passno; /* pass number on parallel fsck */ -}; -.Ed -.Pp -The fields have meanings described in -.Xr fstab 5 . -.Pp -The -.Fn setfsent -function -opens the file (closing any previously opened file) or rewinds it -if it is already open. -.Pp -The -.Fn endfsent -function -closes the file. -.Pp -The -.Fn getfsspec -and -.Fn getfsfile -functions -search the entire file (opening it if necessary) for a matching special -file name or file system file name. -.Pp -For programs wishing to read the entire database, -.Fn getfsent -reads the next entry (opening the file if necessary). -.Pp -All entries in the file with a type field equivalent to -.Dv FSTAB_XX -are ignored. -.Sh RETURN VALUES -The -.Fn getfsent , -.Fn getfsspec , -and -.Fn getfsfile -functions -return a -.Dv NULL -pointer on -.Dv EOF -or error. -The -.Fn setfsent -function -returns 0 on failure, 1 on success. -The -.Fn endfsent -function -returns nothing. -.Sh FILES -.Bl -tag -width /etc/fstab -compact -.It Pa /etc/fstab -.El -.Sh SEE ALSO -.Xr fstab 5 -.Sh HISTORY -The -.Fn getfsent -function appeared in -.Bx 4.0 ; -the -.Fn endfsent , -.Fn getfsfile , -.Fn getfsspec , -and -.Fn setfsent -functions appeared in -.Bx 4.3 . -.Sh BUGS -These functions use static data storage; -if the data is needed for future use, it should be -copied before any subsequent calls overwrite it. diff --git a/gen/getgrent.3 b/gen/getgrent.3 deleted file mode 100644 index 11d8e67..0000000 --- a/gen/getgrent.3 +++ /dev/null @@ -1,197 +0,0 @@ -.\" Copyright (c) 1989, 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. -.\" -.\" From: @(#)getgrent.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/getgrent.3,v 1.16 2001/10/01 16:08:51 ru Exp $ -.\" -.Dd September 29, 1994 -.Dt GETGRENT 3 -.Os -.Sh NAME -.Nm getgrent , -.Nm getgrnam , -.Nm getgrgid , -.Nm setgroupent , -.\" .Nm setgrfile , -.Nm setgrent , -.Nm endgrent -.Nd group database operations -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In grp.h -.Ft struct group * -.Fn getgrent void -.Ft struct group * -.Fn getgrnam "const char *name" -.Ft struct group * -.Fn getgrgid "gid_t gid" -.Ft int -.Fn setgroupent "int stayopen" -.\" .Ft void -.\" .Fn setgrfile "const char *name" -.Ft int -.Fn setgrent void -.Ft void -.Fn endgrent void -.Sh DESCRIPTION -These functions operate on the group database file -.Pa /etc/group -which is described -in -.Xr group 5 . -Each line of the database is defined by the structure -.Ar group -found in the include -file -.Aq Pa grp.h : -.Bd -literal -offset indent -struct group { - char *gr_name; /* group name */ - char *gr_passwd; /* group password */ - int gr_gid; /* group id */ - char **gr_mem; /* group members */ -}; -.Ed -.Pp -The functions -.Fn getgrnam -and -.Fn getgrgid -search the group database for the given group name pointed to by -.Ar name -or the group id pointed to by -.Ar gid , -respectively, returning the first one encountered. Identical group -names or group gids may result in undefined behavior. -.Pp -The -.Fn getgrent -function -sequentially reads the group database and is intended for programs -that wish to step through the complete list of groups. -.Pp -All three routines will open the group file for reading, if necessary. -.Pp -The -.Fn setgroupent -function -opens the file, or rewinds it if it is already open. If -.Fa stayopen -is non-zero, file descriptors are left open, significantly speeding -functions subsequent calls. This functionality is unnecessary for -.Fn getgrent -as it doesn't close its file descriptors by default. It should also -be noted that it is dangerous for long-running programs to use this -functionality as the group file may be updated. -.Pp -The -.Fn setgrent -function -is identical to -.Fn setgroupent -with an argument of zero. -.Pp -The -.Fn endgrent -function -closes any open files. -.Sh RETURN VALUES -The functions -.Fn getgrent , -.Fn getgrnam , -and -.Fn getgrgid , -return a pointer to the group entry if successful; if end-of-file -is reached or an error occurs a null pointer is returned. -The functions -.Fn setgroupent -and -.Fn setgrent -return the value 1 if successful, otherwise the value -0 is returned. -The functions -.Fn endgrent -and -.Fn setgrfile -have no return value. -.Sh FILES -.Bl -tag -width /etc/group -compact -.It Pa /etc/group -group database file -.El -.Sh SEE ALSO -.Xr getpwent 3 , -.Xr yp 4 , -.Xr group 5 -.Sh HISTORY -The functions -.Fn endgrent , -.Fn getgrent , -.Fn getgrnam , -.Fn getgrgid , -and -.Fn setgrent -appeared in -.At v7 . -The functions -.Fn setgrfile -and -.Fn setgroupent -appeared in -.Bx 4.3 Reno . -.Sh COMPATIBILITY -The historic function -.Fn setgrfile , -which allowed the specification of alternate password databases, has -been deprecated and is no longer available. -.Sh BUGS -The functions -.Fn getgrent , -.Fn getgrnam , -.Fn getgrgid , -.Fn setgroupent -and -.Fn setgrent -leave their results in an internal static object and return -a pointer to that object. -Subsequent calls to -the same function -will modify the same object. -.Pp -The functions -.Fn getgrent , -.Fn endgrent , -.Fn setgroupent , -and -.Fn setgrent -are fairly useless in a networked environment and should be -avoided, if possible. diff --git a/gen/gethostname-fbsd.c b/gen/gethostname-fbsd.c new file mode 100644 index 0000000..5ca394d --- /dev/null +++ b/gen/gethostname-fbsd.c @@ -0,0 +1,76 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include +#include +#include + +#include + +int +gethostname(name, namelen) + char *name; + size_t namelen; +{ + int mib[2]; + + /* Kluge to avoid ABI breakage. */ + namelen = (int)namelen; + + mib[0] = CTL_KERN; + mib[1] = KERN_HOSTNAME; + if (namelen < MAXHOSTNAMELEN + 1) { + char local_buf[MAXHOSTNAMELEN + 1]; + size_t local_len = sizeof(local_buf); + if (sysctl(mib, 2, local_buf, &local_len, NULL, 0) == -1) { + if (errno == ENOMEM) + errno = ENAMETOOLONG; + return (-1); + } + strncpy(name, local_buf, namelen); + name[namelen - 1] = 0; + } else { + if (sysctl(mib, 2, name, &namelen, NULL, 0) == -1) { + if (errno == ENOMEM) + errno = ENAMETOOLONG; + return (-1); + } + } + return (0); +} diff --git a/gen/gethostname.3 b/gen/gethostname.3 new file mode 100644 index 0000000..c02b9b5 --- /dev/null +++ b/gen/gethostname.3 @@ -0,0 +1,135 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 18, 2003 +.Dt GETHOSTNAME 3 +.Os +.Sh NAME +.Nm gethostname , +.Nm sethostname +.Nd get/set name of current host +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn gethostname "char *name" "size_t namelen" +.Ft int +.Fn sethostname "const char *name" "int namelen" +.Sh DESCRIPTION +The +.Fn gethostname +function +returns the standard host name for the current processor, as +previously set by +.Fn sethostname . +The +.Fa namelen +argument +specifies the size of the +.Fa name +array. +The returned name is null-terminated, unless insufficient space is provided. +.Pp +The +.Fn sethostname +function +sets the name of the host machine to be +.Fa name , +which has length +.Fa namelen . +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 +characters, not including the trailing null, currently 255. +.Sh RETURN VALUES +.Rv -std +.Sh ERRORS +The following errors may be returned by these calls: +.Bl -tag -width Er +.It Bq Er EFAULT +The +.Fa name +or +.Fa namelen +argument gave an +invalid address. +.It Bq Er ENAMETOOLONG +The current host name is longer than +.Fa namelen . +(For +.Fn gethostname +only.) +.It Bq Er EPERM +The caller tried to set the host name and was not the super-user. +.El +.Sh SEE ALSO +.Xr sysconf 3 , +.Xr sysctl 3 +.Sh STANDARDS +The +.Fn gethostname +function conforms to +.St -p1003.1-2001 . +Callers should be aware that +.Brq Dv 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 +.In sys/param.h +as +.Dv MAXHOSTNAMELEN , +and counted the terminating null. +The +.Fn sethostname +function and the error returns for +.Fn gethostname +are not standardized. +.Sh HISTORY +The +.Fn gethostname +function appeared in +.Bx 4.2 . +The +.Fa namelen +argument to +.Fn gethostname +was changed to +.Vt size_t +in +.Fx 5.2 +for alignment with +.St -p1003.1-2001 . diff --git a/gen/getlastlogx.3 b/gen/getlastlogx.3 new file mode 100644 index 0000000..47ef108 --- /dev/null +++ b/gen/getlastlogx.3 @@ -0,0 +1,146 @@ +.\" $NetBSD: getlastlogx.3,v 1.1 2003/08/26 17:37:51 wiz 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. +.\" 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. +.\" +.Dd Dec 26, 2005 +.Dt GETLASTLOGX 3 +.Os +.Sh NAME +.Nm getlastlogx , +.Nm getlastlogxbyname , +.Nm getutmp , +.Nm getutmpx , +.Nm utmpxname +.Nd user accounting database functions +.Sh SYNOPSIS +.In utmpx.h +.Ft struct lastlogx * +.Fn getlastlogx "uid_t uid" "struct lastlogx *ll" +.Ft struct lastlogx * +.Fn getlastlogxbyname "const char *name" "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 utmpxname "const char *fname" +.Sh DESCRIPTION +The +.Fn getlastlogx +function looks up the entry for the user with user id +.Fa uid +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. +The +.Fn getlastlogxbyname +function is similar to +.Fn getlastlogx , +except the user name is passed. +.Pp +.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 +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 */ +}; +.Ed +.Pp +The +.Fn utmpxname +function sets the default +.Xr utmpx 5 +database file name to +.Fa fname . +.Sh RETURN VALUES +.Fn getlastlogx +and +.Fn getlastlogxbyname +return the found entry on success, or +.Dv NULL +if it could not open the database, could not find an entry matching +.Fa uid +or +.Fa name , +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 . +.Sh SEE ALSO +.Xr endutxent 3 , +.Xr utmpx 5 +.Sh HISTORY +The functions +.Fn getutmp , +.Fn getutmpx , +and +.Fn utmpxname +first appeared in +.Tn Solaris . +.Nm getlastlogx +first appeared in +.Nx 2.0 . diff --git a/gen/getlogin-fbsd.c b/gen/getlogin-fbsd.c new file mode 100644 index 0000000..b639fe1 --- /dev/null +++ b/gen/getlogin-fbsd.c @@ -0,0 +1,105 @@ +/* + * 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[] = "@(#)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 $"); + +#include +#include +#include +#include +#include +#include +#include "namespace.h" +#include +#include "un-namespace.h" + +#include "libc_private.h" + +#define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&logname_mutex) +#define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&logname_mutex) + +extern int __getlogin(char *, int); + +int _logname_valid; /* known to setlogin() */ +static pthread_mutex_t logname_mutex = PTHREAD_MUTEX_INITIALIZER; + +static char * +getlogin_basic(int *status) +{ + static char logname[MAXLOGNAME]; + + if (_logname_valid == 0) { + if (__getlogin(logname, sizeof(logname)) < 0) { + *status = errno; + return (NULL); + } + _logname_valid = 1; + } + *status = 0; + return (*logname ? logname : NULL); +} + +char * +getlogin(void) +{ + char *result; + int status; + + THREAD_LOCK(); + result = getlogin_basic(&status); + THREAD_UNLOCK(); + return (result); +} + +int +getlogin_r(char *logname, size_t namelen) +{ + char *result; + int len; + int status; + + THREAD_LOCK(); + result = getlogin_basic(&status); + if (status == 0) { + if ((len = strlen(result) + 1) > namelen) + status = ERANGE; + else + strncpy(logname, result, len); + } + THREAD_UNLOCK(); + return (status); +} diff --git a/gen/getmntinfo-fbsd.c b/gen/getmntinfo-fbsd.c new file mode 100644 index 0000000..383df1e --- /dev/null +++ b/gen/getmntinfo-fbsd.c @@ -0,0 +1,72 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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.4 2002/02/01 00:57:29 obrien 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/getmntinfo.3 b/gen/getmntinfo.3 new file mode 100644 index 0000000..f7fb48e --- /dev/null +++ b/gen/getmntinfo.3 @@ -0,0 +1,140 @@ +.\" Copyright (c) 1989, 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 9, 1993 +.Dt GETMNTINFO 3 +.Os +.Sh NAME +.Nm getmntinfo +.Nd get information about mounted file systems +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/param.h +.In sys/ucred.h +.In sys/mount.h +.Ft int +.Fn getmntinfo "struct statfs **mntbufp" "int flags" +.Ft int +.Fn getmntinfo64 "struct statfs64 **mntbufp" "int flags" +.Sh DESCRIPTION +The +.Fn getmntinfo +function +returns an array of +.Ft statfs +structures describing each currently mounted file system (see +.Xr statfs 2 ) . +Likewise, the +.Fn getmntinfo64 +function +returns an array of +.Ft statfs64 +structures describing each currently mounted file system. +.Pp +The +.Fn getmntinfo +function +passes its +.Fa flags +argument transparently to +.Xr getfsstat 2 , +while the +.Fn getmntinfo64 +function +passes its +.Fa flags +argument transparently to +.Fn getfsstat64 . +.Sh RETURN VALUES +On successful completion, +.Fn getmntinfo +and +.Fn getmntinfo64 +return a count of the number of elements in the array. +The pointer to the array is stored into +.Fa mntbufp . +.Pp +If an error occurs, zero is returned and the external variable +.Va errno +is set to indicate the error. +Although the pointer +.Fa mntbufp +will be unmodified, any information previously returned by +.Fn getmntinfo +or +.Fn getmntinfo64 +will be lost. +.Sh ERRORS +The +.Fn getmntinfo +and +.Fn getmntinfo64 +functions +may fail and set errno for any of the errors specified for the library +routines +.Xr getfsstat 2 +or +.Xr malloc 3 . +.Sh SEE ALSO +.Xr getfsstat 2 , +.Xr mount 2 , +.Xr statfs 2 , +.Xr mount 8 +.Sh HISTORY +The +.Fn getmntinfo +function first appeared in +.Bx 4.4 . +.Sh BUGS +The +.Fn getmntinfo +and +.Fn getmntinfo64 +functions write the array of structures to an internal static object +and returns +a pointer to that object. +Subsequent calls to +.Fn getmntinfo +and +.Fn getmntinfo64 +will modify the same object. +.Pp +The memory allocated by +.Fn getmntinfo +and +.Fn getmntinfo64 +cannot be +.Xr free 3 Ns 'd +by the application. diff --git a/gen/getmntinfo64-fbsd.c b/gen/getmntinfo64-fbsd.c new file mode 100644 index 0000000..48717e1 --- /dev/null +++ b/gen/getmntinfo64-fbsd.c @@ -0,0 +1,72 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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.4 2002/02/01 00:57:29 obrien Exp $"); + +#include +#include +#include +#include + +/* + * Return information about mounted filesystems. + */ +int +getmntinfo64(mntbufp, flags) + struct statfs64 **mntbufp; + int flags; +{ + static struct statfs64 *mntbuf; + static int mntsize; + static long bufsize; + + if (mntsize <= 0 && (mntsize = getfsstat64(0, 0, MNT_NOWAIT)) < 0) + return (0); + if (bufsize > 0 && (mntsize = getfsstat64(mntbuf, bufsize, flags)) < 0) + return (0); + while (bufsize <= mntsize * sizeof(struct statfs64)) { + if (mntbuf) + free(mntbuf); + bufsize = (mntsize + 1) * sizeof(struct statfs64); + if ((mntbuf = (struct statfs64 *)malloc(bufsize)) == 0) + return (0); + if ((mntsize = getfsstat64(mntbuf, bufsize, flags)) < 0) + return (0); + } + *mntbufp = mntbuf; + return (mntsize); +} diff --git a/gen/getnetgrent.3 b/gen/getnetgrent.3 deleted file mode 100644 index 7124aef..0000000 --- a/gen/getnetgrent.3 +++ /dev/null @@ -1,133 +0,0 @@ -.\" Copyright (c) 1992, 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. -.\" -.\" @(#)getnetgrent.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/getnetgrent.3,v 1.10 2001/10/01 16:08:51 ru Exp $ -.\" -.Dd June 4, 1993 -.Dt GETNETGRENT 3 -.Os -.Sh NAME -.Nm getnetgrent , -.Nm innetgr , -.Nm setnetgrent , -.Nm endnetgrent -.Nd netgroup database operations -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In netdb.h -.Ft int -.Fn getnetgrent "char **host" "char **user" "char **domain" -.Ft int -.Fn innetgr "const char *netgroup" "const char *host" "const char *user" "const char *domain" -.Ft void -.Fn setnetgrent "const char *netgroup" -.Ft void -.Fn endnetgrent void -.Sh DESCRIPTION -These functions operate on the netgroup database file -.Pa /etc/netgroup -which is described -in -.Xr netgroup 5 . -The database defines a set of netgroups, each made up of one or more triples: -.Bd -literal -offset indent -(host, user, domain) -.Ed -that defines a combination of host, user and domain. -Any of the three fields may be specified as ``wildcards'' that match any -string. -.Pp -The function -.Fn getnetgrent -sets the three pointer arguments to the strings of the next member of the -current netgroup. -If any of the string pointers are -.Sy (char *)0 -that field is considered a wildcard. -.Pp -The functions -.Fn setnetgrent -and -.Fn endnetgrent -set the current netgroup and terminate the current netgroup respectively. -If -.Fn setnetgrent -is called with a different netgroup than the previous call, an implicit -.Fn endnetgrent -is implied. -.Fn Setnetgrent -also sets the offset to the first member of the netgroup. -.Pp -The function -.Fn innetgr -searches for a match of all fields within the specified group. -If any of the -.Sy host , -.Sy user , -or -.Sy domain -arguments are -.Sy (char *)0 -those fields will match any string value in the netgroup member. -.Sh RETURN VALUES -The function -.Fn getnetgrent -returns 0 for ``no more netgroup members'' and 1 otherwise. -The function -.Fn innetgr -returns 1 for a successful match and 0 otherwise. -The functions -.Fn setnetgrent -and -.Fn endnetgrent -have no return value. -.Sh FILES -.Bl -tag -width /etc/netgroup -compact -.It Pa /etc/netgroup -netgroup database file -.El -.Sh SEE ALSO -.Xr netgroup 5 -.Sh COMPATIBILITY -The netgroup members have three string fields to maintain compatibility -with other vendor implementations, however it is not obvious what use the -.Sy domain -string has within -.Bx . -.Sh BUGS -The function -.Fn getnetgrent -returns pointers to dynamically allocated data areas that are freed when -the function -.Fn endnetgrent -is called. diff --git a/gen/getobjformat.3 b/gen/getobjformat.3 deleted file mode 100644 index ce1144c..0000000 --- a/gen/getobjformat.3 +++ /dev/null @@ -1,128 +0,0 @@ -.\" Copyright (c) 1998 John D. Polstra -.\" 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/gen/getobjformat.3,v 1.8 2001/10/01 16:08:51 ru Exp $ -.\" -.Dd September 7, 1998 -.Dt GETOBJFORMAT 3 -.Os -.Sh NAME -.Nm getobjformat -.Nd get preferred object file format -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In objformat.h -.Ft int -.Fn getobjformat "char *buf" "size_t bufsize" "int *argcp" "char **argv" -.Sh DESCRIPTION -.Fn getobjformat -queries several sources to determine the preferred object file -format, and copies its name into a buffer provided by the caller. -.Pp -The object file format is determined as follows. If -.Va argv -is -.No non- Ns Ev NULL -and an explicit command line argument such as -.Fl aout -or -.Fl elf -is present, then that determines the object file format. -.Pp -Otherwise, if the variable -.Ev OBJFORMAT -is set in the environment, the object file format is taken from its -value. -.Pp -Otherwise, if the file -.Pa /etc/objformat -is readable and contains a line of the form -.Ql OBJFORMAT=xxx , -the object file format is taken from there. -.Pp -Otherwise, a built-in system default object file format is returned. -.Pp -.Va buf -points to a user-supplied buffer into which the name of the object -file format is copied. -.Va bufsize -gives the size of the buffer in bytes. The string placed in -.Va buf -is always null-terminated. It is an error if the buffer is too -small to hold the null-terminated name. -.Pp -.Va argv -points to a -.Dv NULL Ns -terminated -argument vector to be scanned for object -format options. -.Va argv -may be -.Dv NULL , -in which case the argument vector is not scanned. -.Pp -If -.Va argcp -is non-NULL, any object format options are deleted from the -argument vector, and the updated argument count is stored into -the integer referenced by -.Va argcp . -If -.Va argcp -is -.Dv NULL , -the argument vector is left unchanged. -.Sh RETURN VALUES -On success, -.Fn getobjformat -returns the length of the object file format name, not counting the -null terminator. -If the supplied buffer is too small to hold the object file format -and its null terminator, -.Fn getobjformat -returns -1. In that case, the contents of the buffer and argument -vector supplied by the caller are indeterminate. -.Sh ENVIRONMENT -.Bl -tag -width OBJFORMAT -.It Ev OBJFORMAT -If the environment variable -.Ev OBJFORMAT -is set, it overrides the default object file format. -.Ev OBJFORMAT takes precedence over -.Pa /etc/objformat . -.El -.Sh FILES -.Bl -tag -width /etc/objformat -compact -.It Pa /etc/objformat -If present, specifies the object file format to use. Syntax is -.Ql OBJFORMAT=xxx . -.El -.Sh SEE ALSO -.Xr objformat 1 -.Sh HISTORY -The -.Fn getobjformat -function first appeared in -.Fx 3.0 . diff --git a/gen/getpagesize-fbsd.c b/gen/getpagesize-fbsd.c new file mode 100644 index 0000000..3c8881e --- /dev/null +++ b/gen/getpagesize-fbsd.c @@ -0,0 +1,66 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include +#include + +/* + * This is unlikely to change over the running time of any + * program, so we cache the result to save some syscalls. + * + * NB: This function may be called from malloc(3) at initialization + * NB: so must not result in a malloc(3) related call! + */ + +int +getpagesize() +{ + int mib[2]; + static int value; + size_t size; + + if (!value) { + mib[0] = CTL_HW; + mib[1] = HW_PAGESIZE; + size = sizeof value; + if (sysctl(mib, 2, &value, &size, NULL, 0) == -1) + return (-1); + } + return (value); +} diff --git a/gen/getpagesize.3 b/gen/getpagesize.3 new file mode 120000 index 0000000..fbeaba6 --- /dev/null +++ b/gen/getpagesize.3 @@ -0,0 +1 @@ +./getpagesize.3 \ No newline at end of file diff --git a/gen/getpass.3 b/gen/getpass.3 new file mode 120000 index 0000000..c9ce40a --- /dev/null +++ b/gen/getpass.3 @@ -0,0 +1 @@ +./getpass.3 \ No newline at end of file diff --git a/gen/getpeereid-fbsd.c b/gen/getpeereid-fbsd.c new file mode 100644 index 0000000..5608c48 --- /dev/null +++ b/gen/getpeereid-fbsd.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2001 Dima Dorfman. + * 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/gen/getpeereid.c,v 1.6 2002/12/16 13:42:13 maxim Exp $"); + +#include +#include +#include +#include + +#include +#include + +int +getpeereid(int s, uid_t *euid, gid_t *egid) +{ + struct xucred xuc; + socklen_t xuclen; + int error; + + xuclen = sizeof(xuc); + error = getsockopt(s, 0, LOCAL_PEERCRED, &xuc, &xuclen); + if (error != 0) + return (error); + if (xuc.cr_version != XUCRED_VERSION) + return (EINVAL); + *euid = xuc.cr_uid; + *egid = xuc.cr_gid; + return (0); +} diff --git a/gen/getpeereid.3 b/gen/getpeereid.3 new file mode 120000 index 0000000..222f1b4 --- /dev/null +++ b/gen/getpeereid.3 @@ -0,0 +1 @@ +./getpeereid.3 \ No newline at end of file diff --git a/gen/getprogname-fbsd.c b/gen/getprogname-fbsd.c new file mode 100644 index 0000000..a736f65 --- /dev/null +++ b/gen/getprogname-fbsd.c @@ -0,0 +1,19 @@ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/getprogname.c,v 1.4 2002/03/29 22:43:41 markm Exp $"); + +#include "namespace.h" +#include +#include +#define __progname (*_NSGetProgname()) +#include "un-namespace.h" + +#include "libc_private.h" + +__weak_reference(_getprogname, getprogname); + +const char * +_getprogname(void) +{ + + return (__progname); +} diff --git a/gen/getprogname.3 b/gen/getprogname.3 new file mode 100644 index 0000000..b7b9c99 --- /dev/null +++ b/gen/getprogname.3 @@ -0,0 +1,93 @@ +.\" +.\" Copyright (c) 2001 Christopher G. Demetriou +.\" 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 for the +.\" NetBSD Project. See http://www.netbsd.org/ for +.\" information about NetBSD. +.\" 4. 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 ``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. +.\" +.\" $FreeBSD: src/lib/libc/gen/getprogname.3,v 1.5 2001/10/01 16:08:51 ru Exp $ +.\" +.Dd May 1, 2001 +.Dt GETPROGNAME 3 +.Os +.Sh NAME +.Nm getprogname , +.Nm setprogname +.Nd get or set the program name +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft const char * +.Fn getprogname "void" +.Ft void +.Fn setprogname "const char *progname" +.Sh DESCRIPTION +The +.Fn getprogname +and +.Fn setprogname +functions manipulate the name of the current program. +They are used by error-reporting routines to produce +consistent output. +.Pp +The +.Fn getprogname +function returns the name of the program. +If the name has not been set yet, it will return +.Dv NULL . +.Pp +The +.Fn setprogname +function sets the name of the program to be the last component of the +.Fa progname +argument. +Since a pointer to the given string is kept as the program name, +it should not be modified for the rest of the program's lifetime. +.Pp +In +.Fx , +the name of the program is set by the start-up code that is run before +.Fn main ; +thus, +running +.Fn setprogname +is not necessary. +Programs that desire maximum portability should still call it; +on another operating system, +these functions may be implemented in a portability library. +Calling +.Fn setprogname +allows the aforementioned library to learn the program name without +modifications to the start-up code. +.Sh SEE ALSO +.Xr err 3 +.Sh HISTORY +These functions first appeared in +.Nx 1.6 , +and made their way into +.Fx 4.4 . diff --git a/gen/getpwent.3 b/gen/getpwent.3 deleted file mode 100644 index 9c7badf..0000000 --- a/gen/getpwent.3 +++ /dev/null @@ -1,242 +0,0 @@ -.\" Copyright (c) 1988, 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. -.\" -.\" From: @(#)getpwent.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/gen/getpwent.3,v 1.18 2001/10/01 16:08:51 ru Exp $ -.\" -.Dd September 20, 1994 -.Dt GETPWENT 3 -.Os -.Sh NAME -.Nm getpwent , -.Nm getpwnam , -.Nm getpwuid , -.Nm setpassent , -.Nm setpwent , -.Nm endpwent -.Nd password database operations -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In pwd.h -.Ft struct passwd * -.Fn getpwent void -.Ft struct passwd * -.Fn getpwnam "const char *login" -.Ft struct passwd * -.Fn getpwuid "uid_t uid" -.Ft int -.Fn setpassent "int stayopen" -.Ft int -.Fn setpwent void -.Ft void -.Fn endpwent void -.Sh DESCRIPTION -These functions -operate on the password database file -which is described -in -.Xr passwd 5 . -Each entry in the database is defined by the structure -.Ar passwd -found in the include -file -.Aq Pa pwd.h : -.Bd -literal -offset indent -struct passwd { - char *pw_name; /* user name */ - char *pw_passwd; /* encrypted password */ - uid_t pw_uid; /* user uid */ - gid_t pw_gid; /* user gid */ - time_t pw_change; /* password change time */ - char *pw_class; /* user access class */ - char *pw_gecos; /* Honeywell login info */ - char *pw_dir; /* home directory */ - char *pw_shell; /* default shell */ - time_t pw_expire; /* account expiration */ - int pw_fields; /* internal: fields filled in */ -}; -.Ed -.Pp -The functions -.Fn getpwnam -and -.Fn getpwuid -search the password database for the given login name or user uid, -respectively, always returning the first one encountered. -.Pp -The -.Fn getpwent -function -sequentially reads the password database and is intended for programs -that wish to process the complete list of users. -.Pp -The -.Fn setpassent -function -accomplishes two purposes. -First, it causes -.Fn getpwent -to ``rewind'' to the beginning of the database. -Additionally, if -.Fa stayopen -is non-zero, file descriptors are left open, significantly speeding -up subsequent accesses for all of the routines. -(This latter functionality is unnecessary for -.Fn getpwent -as it doesn't close its file descriptors by default.) -.Pp -It is dangerous for long-running programs to keep the file descriptors -open as the database will become out of date if it is updated while the -program is running. -.Pp -The -.Fn setpwent -function -is identical to -.Fn setpassent -with an argument of zero. -.Pp -The -.Fn endpwent -function -closes any open files. -.Pp -As of Mac OS X 10.3, there are now different per-user behaviours of -this function, based on the AuthenticationAuthority value -stored for the queried user in DirectoryServices. -.Pp -If the queried user is still a legacy crypt password user or now -has an AuthenticationAuthority value containing ``;basic;'', -these routines will behave in their standard BSD fashion. -These functions will ``shadow'' the password file, e.g.\& -allow only certain programs to have access to the encrypted password. -If the process which calls them has an effective uid of 0, the encrypted -password will be returned, otherwise, the password field of the returned -structure will point to the string -.Ql * . -.Pp -By default in Mac OS X 10.3 and later all users will have an -AuthenticationAuthority with the value ``;ShadowHash;''. -These users will have a visible password value of ``********''. -These functions -will have no access to the encrypted password whatsoever. -Setting or changing -an user password must be done entirely through the DirectoryService APIs -for this default user. -.Pp -There also exists an ``Apple Password Server'' user whose password -value is also ``********'' and with an AuthenticationAuthority that -contains the value ";ApplePasswordServer;" among other data. -There is no getpwnam access to the password for this user either -and again set/change password can be done through the DirectoryService API. -.Pp -Finally in support of local user caching there is a local cached user -whose password is also ``********'' and has an AuthenticationAuthority -value containing ``;LocalCachedUser;'' among other data. -These functions also provide no access to the password for this user -and set/change password functionality is through the DirectoryService API. -.Pp -.Sh RETURN VALUES -The functions -.Fn getpwent , -.Fn getpwnam , -and -.Fn getpwuid , -return a valid pointer to a passwd structure on success -and a null pointer if end-of-file is reached or an error occurs. -The -.Fn setpassent -and -.Fn setpwent -functions return 0 on failure and 1 on success. -The -.Fn endpwent -function -has no return value. -.Sh FILES -.Bl -tag -width /etc/master.passwd -compact -.It Pa /etc/pwd.db -The insecure password database file -.It Pa /etc/spwd.db -The secure password database file -.It Pa /etc/master.passwd -The current password file -.It Pa /etc/passwd -A Version 7 format password file -.El -.Sh SEE ALSO -.Xr getlogin 2 , -.Xr getgrent 3 , -.Xr yp 4 , -.Xr passwd 5 , -.Xr pwd_mkdb 8 , -.Xr vipw 8 -.Sh HISTORY -The -.Fn getpwent , -.Fn getpwnam , -.Fn getpwuid , -.Fn setpwent , -and -.Fn endpwent -functions appeared in -.At v7 . -The -.Fn setpassent -function appeared in -.Bx 4.3 Reno . -.Sh COMPATIBILITY -The historic function -.Xr setpwfile 3 , -which allowed the specification of alternate password databases, -has been deprecated and is no longer available. -.Sh BUGS -The functions -.Fn getpwent , -.Fn getpwnam , -and -.Fn getpwuid , -leave their results in an internal static object and return -a pointer to that object. -Subsequent calls to -the same function -will modify the same object. -.Pp -The functions -.Fn getpwent , -.Fn endpwent , -.Fn setpassent , -and -.Fn setpwent -are fairly useless in a networked environment and should be -avoided, if possible. diff --git a/gen/getttyent.3 b/gen/getttyent.3 index 56d7a5d..7bd9ae2 100644 --- a/gen/getttyent.3 +++ b/gen/getttyent.3 @@ -41,9 +41,6 @@ .Nm setttyent , .Nm endttyent .Nd get ttys file entry -.Nm isdialuptty , -.Nm isnettty -.Nd determine tty type from ttys file entry .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -56,10 +53,6 @@ .Fn setttyent void .Ft int .Fn endttyent void -.Ft int -.Fn isdialuptty "const char *name" -.Ft int -.Fn isnettty "const char *name" .Sh DESCRIPTION The .Fn getttyent , @@ -110,14 +103,8 @@ on this entry). Allow users with a uid of 0 to login on this terminal. .It Dv TTY_DIALUP Identifies a tty as a dialin line. -If this flag is set, then -.Fn isdialuptty -will return a non-zero value. .It Dv TTY_NETWORK Identifies a tty used for network connections. -If this flag is set, then -.Fn isnettty -will return a non-zero value. .El .It Fa ty_window The command to execute for a window system associated with the line. @@ -177,14 +164,6 @@ function and .Fn endttyent return 0 on failure and 1 on success. -.Pp -The routines -.Fn isdialuptty -and -.Fn isnettty -return non-zero if the dialup or network flag is set for the -tty entry relating to the tty named by the parameter, and -zero otherwise. .Sh FILES .Bl -tag -width /etc/ttys -compact .It Pa /etc/ttys diff --git a/gen/getttyent.c b/gen/getttyent.c index ca623a9..def6fa3 100644 --- a/gen/getttyent.c +++ b/gen/getttyent.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -60,6 +60,8 @@ #include #include #include +#include +#include static char zapchar; static FILE *tf; @@ -71,7 +73,7 @@ getttynam(tty) register struct ttyent *t; setttyent(); - while (t = getttyent()) + while ((t = getttyent()) != NULL) if (!strcmp(tty, t->ty_name)) break; endttyent(); @@ -80,15 +82,52 @@ getttynam(tty) static char *skip(), *value(); +/* + * 4372480: Support for sequences in the tty name. Expressions like [000-999] + * for decimal sequences and [0x0-0xf] for hexidecimal sequences causes a + * sequence of all combinations of names to be returned by getttyent(). + * + * There is also a slot=nn option, which will cause getttyent() to return + * non-existent ttyent structs until the slot number nn is reached. Note, slot + * numbers begin at 1. + */ +struct seq { + int first; + int count; + int index; + char fmt[NAME_MAX + 17]; +}; + +static char brapat[] = "\\[(.*)]"; +static regex_t brapreg; +static char decpat[] = "^([0-9]+)-([0-9]+)$"; +static regex_t decpreg; +static char hexpat[] = "^0x([0-9a-f]+)-0x([0-9a-f]+)$"; +static regex_t hexpreg; +static struct seq *seq = NULL; +static int slot; + struct ttyent * getttyent() { static struct ttyent tty; + static struct ttyent nonexistent = { + "\01", /* this shouldn't match anything */ + NULL, + NULL, + 0, + NULL, + NULL, + NULL + }; register int c; register char *p; #define MAXLINELENGTH 1024 static char *line = NULL; locale_t loc = __current_locale(); + int newslot, hex; + long b, e; + regmatch_t match[3], save, bracket; if ( line == NULL ) { line = malloc(MAXLINELENGTH); @@ -98,6 +137,36 @@ getttyent() if (!tf && !setttyent()) return (NULL); + +restart: + if (slot < seq->first) { + /* + * the slot= option was set, and we are returning non-existent + * entries until we catch up. + */ + slot++; + return &nonexistent; + } + + if (seq->count > 0) { + /* + * generate the next tty name; the rest of the tty entries + * is the same. + */ + sprintf(tty.ty_name, seq->fmt, seq->index++); + slot++; + seq->count--; + return &tty; + } + + if (slot == seq->first) { + /* + * this was a regular entry with slot= + */ + slot++; + return &tty; + } + for (;;) { if (!fgets(p = line, MAXLINELENGTH, tf)) return (NULL); @@ -132,6 +201,7 @@ getttyent() #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace_l(p[sizeof(e) - 1], loc) #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' + newslot = -1; for (; *p; p = skip(p)) { if (scmp(_TTYS_OFF)) tty.ty_status &= ~TTY_ON; @@ -145,7 +215,11 @@ getttyent() tty.ty_onerror = value(p); else if (vcmp(_TTYS_ONOPTION)) tty.ty_onoption = value(p); - else + else if (vcmp(_TTYS_SLOT)) { + char *slotstr = value(p); + if (slotstr) + newslot = atoi(slotstr); + } else break; } @@ -155,8 +229,64 @@ getttyent() tty.ty_comment = p; if (*p == 0) tty.ty_comment = 0; - if (p = index(p, '\n')) + if ((p = index(p, '\n')) != NULL) *p = '\0'; + + /* check if tty.tyname has a sequence */ + if (regexec(&brapreg, tty.ty_name, 3, match, 0) != 0) + goto out; + + /* + * save the range of the bracketed range, so we can find the strings + * before and after + */ + bracket = match[0]; + /* use REG_STARTEND to limit matching with the bracketed range */ + match[0] = save = match[1]; + if (regexec(&decpreg, tty.ty_name, 3, match, REG_STARTEND) == 0) { + /* a decimal range */ + b = strtol(tty.ty_name + match[1].rm_so, NULL, 10); + e = strtol(tty.ty_name + match[2].rm_so, NULL, 10); + hex = 0; + } else { + match[0] = save; + if (regexec(&hexpreg, tty.ty_name, 3, match, REG_STARTEND) == 0) { + /* a hexidecimal range */ + b = strtol(tty.ty_name + match[1].rm_so, NULL, 16); + e = strtol(tty.ty_name + match[2].rm_so, NULL, 16); + hex = 1; + } else + goto out; + } + if (b > e) /* skip */ + goto restart; + + /* seq->first is already less than slot, so just leave it */ + seq->count = e - b + 1; + seq->index = b; + /* + * The fmt string contains the characters before the bracket, the + * a format specifier (either decimal or hex) and any characters + * after the bracket. Note that the length of the lower range is + * use as a minimum digit length, with zero fill, so the format + * specifier will look something like %03d. + */ + sprintf(seq->fmt, "%.*s%%0%d%c%s", + (int)bracket.rm_so, tty.ty_name, + (int)(match[1].rm_eo - match[1].rm_so), + hex ? 'x' : 'd', + tty.ty_name + bracket.rm_eo); + +out: + if (newslot > slot) { + /* set up to skip until newslot */ + seq->first = newslot; + goto restart; + } + if (seq->count > 0) /* restart if we are doing a sequence */ + goto restart; + /* regular single value return */ + slot++; return (&tty); } @@ -212,10 +342,33 @@ int setttyent() { + /* initialize seq and the three regexp patterns */ + if (!seq) { + if (regcomp(&brapreg, brapat, REG_EXTENDED) != 0) + return 0; + if (regcomp(&decpreg, decpat, REG_EXTENDED) != 0) { + regfree(&brapreg); + return 0; + } + if (regcomp(&hexpreg, hexpat, REG_EXTENDED | REG_ICASE) != 0) { + regfree(&decpreg); + regfree(&brapreg); + return 0; + } + if ((seq = malloc(sizeof(struct seq))) == NULL) { + regfree(&hexpreg); + regfree(&decpreg); + regfree(&brapreg); + return 0; + } + } + seq->first = seq->count = 0; + slot = 1; + if (tf) { (void)rewind(tf); return (1); - } else if (tf = fopen(_PATH_TTYS, "r")) + } else if ((tf = fopen(_PATH_TTYS, "r")) != NULL) return (1); return (0); } diff --git a/gen/getvfsbyname.3 b/gen/getvfsbyname.3 index 3b38bc1..98582c2 100644 --- a/gen/getvfsbyname.3 +++ b/gen/getvfsbyname.3 @@ -66,9 +66,6 @@ the name of the filesystem the filesystem type number assigned by the kernel .It vfc_refcount the number of active mount points using the filesystem -.It vfc_flags -flag bits as described in -.Xr getvfsent 3 .El .Sh RETURN VALUES .Rv -std getvfsbyname @@ -86,7 +83,6 @@ specifies a filesystem that is unknown or not configured in the kernel. .El .Sh SEE ALSO .Xr mount 2 , -.Xr getvfsent 3 , .Xr sysctl 3 , .Xr mount 8 , .Xr sysctl 8 diff --git a/gen/getvfsbyname.c b/gen/getvfsbyname.c index 8bfab48..39a296e 100644 --- a/gen/getvfsbyname.c +++ b/gen/getvfsbyname.c @@ -85,7 +85,7 @@ getvfsbyname(fsname, vfcp) for (cnt = 0; cnt < maxtypenum; cnt++) { name[3] = cnt; if (sysctl(name, 4, vfcp, &buflen, (void *)0, (size_t)0) < 0) { - if (errno != EOPNOTSUPP) + if (errno != ENOTSUP) return (-1); continue; } diff --git a/gen/glob-fbsd.c b/gen/glob-fbsd.c new file mode 100644 index 0000000..49d0cbb --- /dev/null +++ b/gen/glob-fbsd.c @@ -0,0 +1,1007 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * 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[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/glob.c,v 1.22 2004/07/29 03:48:52 tjr Exp $"); + +#include "xlocale_private.h" + +/* + * glob(3) -- a superset of the one defined in POSIX 1003.2. + * + * The [!...] convention to negate a range is supported (SysV, Posix, ksh). + * + * Optional extra services, controlled by flags not defined by POSIX: + * + * GLOB_QUOTE: + * Escaping convention: \ inhibits any special meaning the following + * character might have (except \ at end of string is retained). + * GLOB_MAGCHAR: + * Set in gl_flags if pattern contained a globbing character. + * GLOB_NOMAGIC: + * Same as GLOB_NOCHECK, but it will only append pattern if it did + * not contain any magic characters. [Used in csh style globbing] + * GLOB_ALTDIRFUNC: + * Use alternately specified directory access functions. + * GLOB_TILDE: + * expand ~user/foo to the /home/dir/of/user/foo + * GLOB_BRACE: + * expand {1,2}{a,b} to 1a 1b 2a 2b + * gl_matchc: + * Number of matches in the current invocation of glob. + */ + +/* + * Some notes on multibyte character support: + * 1. Patterns with illegal byte sequences match nothing - even if + * GLOB_NOCHECK is specified. + * 2. Illegal byte sequences in filenames are handled by treating them as + * single-byte characters with a value of the first byte of the sequence + * cast to wchar_t. + * 3. State-dependent encodings are not currently supported. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "collate.h" + +#define DOLLAR '$' +#define DOT '.' +#define EOS '\0' +#define LBRACKET '[' +#define NOT '!' +#define QUESTION '?' +#define QUOTE '\\' +#define RANGE '-' +#define RBRACKET ']' +#define SEP '/' +#define STAR '*' +#define TILDE '~' +#define UNDERSCORE '_' +#define LBRACE '{' +#define RBRACE '}' +#define SLASH '/' +#define COMMA ',' + +#ifndef DEBUG + +#define M_QUOTE 0x8000000000ULL +#define M_PROTECT 0x4000000000ULL +#define M_MASK 0xffffffffffULL +#define M_CHAR 0x00ffffffffULL + +typedef uint_fast64_t Char; + +#else + +#define M_QUOTE 0x80 +#define M_PROTECT 0x40 +#define M_MASK 0xff +#define M_CHAR 0x7f + +typedef char Char; + +#endif + + +#define CHAR(c) ((Char)((c)&M_CHAR)) +#define META(c) ((Char)((c)|M_QUOTE)) +#define M_ALL META('*') +#define M_END META(']') +#define M_NOT META('!') +#define M_ONE META('?') +#define M_RNG META('-') +#define M_SET META('[') +#define ismeta(c) (((c)&M_QUOTE) != 0) + +static int g_lstat(Char *, struct stat *, glob_t *, locale_t); +static int g_stat(Char *, struct stat *, glob_t *, locale_t); + +#define g_Ctoc __gl_g_Ctoc +#define glob0 __gl_glob0 +#define glob2_32 __gl_glob0_32 +#define glob2_64 __gl_glob0_64 +#define glob3 __gl_glob3 +#define globexp1 __gl_globexp1 +#define globextend __gl_globextend +__private_extern__ int g_Ctoc(const Char *, char *, u_int, locale_t); +__private_extern__ int glob0(const Char *, glob_t *, int *, locale_t); +__private_extern__ int glob2_32(Char *, Char *, Char *, Char *, glob_t *, int *, locale_t); +__private_extern__ int glob2_64(Char *, Char *, Char *, Char *, glob_t *, int *, locale_t); +__private_extern__ int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, int *, locale_t); +__private_extern__ int globexp1(const Char *, glob_t *, int *, locale_t); +__private_extern__ int globextend(const Char *, glob_t *, int *, locale_t); + +#ifndef BUILDING_VARIANT +#define glob2(a,b,c,d,e,f,g) (((e)->gl_flags & GLOB_INODE64) ? glob2_64((a),(b),(c),(d),(e),(f),(g)) : glob2_32((a),(b),(c),(d),(e),(f),(g))) + +static int compare(const void *, const void *); +static DIR *g_opendir(Char *, glob_t *, locale_t); +static Char *g_strchr(Char *, wchar_t); +#ifdef notdef +static Char *g_strcat(Char *, const Char *); +#endif +static int glob1(Char *, glob_t *, int *, locale_t); +static const Char * + globtilde(const Char *, Char *, size_t, glob_t *); +static int globexp2(const Char *, const Char *, glob_t *, int *, int *, locale_t); +static int match(Char *, Char *, Char *, locale_t); +#ifdef DEBUG +static void qprintf(const char *, Char *); +#endif +#endif /* !BUILDING_VARIANT */ + +int +glob(pattern, flags, errfunc, pglob) + const char *pattern; + int flags, (*errfunc)(const char *, int); + glob_t *pglob; +{ + const u_char *patnext; + int limit; + Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot; + mbstate_t mbs; + wchar_t wc; + size_t clen; + locale_t loc = __current_locale(); + int mb_cur_max = MB_CUR_MAX_L(loc); + + patnext = (u_char *) pattern; + if (!(flags & GLOB_APPEND)) { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + if (!(flags & GLOB_DOOFFS)) + pglob->gl_offs = 0; + } + if (flags & GLOB_LIMIT) { + limit = pglob->gl_matchc; + if (limit == 0) + limit = ARG_MAX; + } else + limit = 0; +#if __DARWIN_64_BIT_INO_T + pglob->gl_flags = flags & ~GLOB_MAGCHAR; + pglob->gl_flags |= GLOB_INODE64; +#else /* !__DARWIN_64_BIT_INO_T */ + pglob->gl_flags = flags & ~(GLOB_MAGCHAR | GLOB_INODE64); +#endif /* __DARWIN_64_BIT_INO_T */ + pglob->gl_errfunc = errfunc; + pglob->gl_matchc = 0; + + bufnext = patbuf; + bufend = bufnext + MAXPATHLEN - 1; + if (flags & GLOB_NOESCAPE) { + memset(&mbs, 0, sizeof(mbs)); + while (bufend - bufnext >= mb_cur_max) { + clen = mbrtowc_l(&wc, (const char *)patnext, MB_LEN_MAX, &mbs, loc); + if (clen == (size_t)-1 || clen == (size_t)-2) + return (GLOB_NOMATCH); + else if (clen == 0) + break; + *bufnext++ = wc; + patnext += clen; + } + } else { + /* Protect the quoted characters. */ + memset(&mbs, 0, sizeof(mbs)); + while (bufend - bufnext >= mb_cur_max) { + if (*patnext == QUOTE) { + if (*++patnext == EOS) { + *bufnext++ = QUOTE | M_PROTECT; + continue; + } + prot = M_PROTECT; + } else + prot = 0; + clen = mbrtowc_l(&wc, (const char *)patnext, MB_LEN_MAX, &mbs, loc); + if (clen == (size_t)-1 || clen == (size_t)-2) + return (GLOB_NOMATCH); + else if (clen == 0) + break; + *bufnext++ = wc | prot; + patnext += clen; + } + } + *bufnext = EOS; + + if (flags & GLOB_BRACE) + return globexp1(patbuf, pglob, &limit, loc); + else + return glob0(patbuf, pglob, &limit, loc); +} + +#ifndef BUILDING_VARIANT +/* + * Expand recursively a glob {} pattern. When there is no more expansion + * invoke the standard globbing routine to glob the rest of the magic + * characters + */ +__private_extern__ int +globexp1(pattern, pglob, limit, loc) + const Char *pattern; + glob_t *pglob; + int *limit; + locale_t loc; +{ + const Char* ptr = pattern; + int rv; + + /* Protect a single {}, for find(1), like csh */ + if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) + return glob0(pattern, pglob, limit, loc); + + while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) + if (!globexp2(ptr, pattern, pglob, &rv, limit, loc)) + return rv; + + return glob0(pattern, pglob, limit, loc); +} + + +/* + * Recursive brace globbing helper. Tries to expand a single brace. + * If it succeeds then it invokes globexp1 with the new pattern. + * If it fails then it tries to glob the rest of the pattern and returns. + */ +static int +globexp2(ptr, pattern, pglob, rv, limit, loc) + const Char *ptr, *pattern; + glob_t *pglob; + int *rv, *limit; + locale_t loc; +{ + int i; + Char *lm, *ls; + const Char *pe, *pm, *pl; + Char patbuf[MAXPATHLEN]; + + /* copy part up to the brace */ + for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) + continue; + *lm = EOS; + ls = lm; + + /* Find the balanced brace */ + for (i = 0, pe = ++ptr; *pe; pe++) + if (*pe == LBRACKET) { + /* Ignore everything between [] */ + for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) + continue; + if (*pe == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pe = pm; + } + } + else if (*pe == LBRACE) + i++; + else if (*pe == RBRACE) { + if (i == 0) + break; + i--; + } + + /* Non matching braces; just glob the pattern */ + if (i != 0 || *pe == EOS) { + *rv = glob0(patbuf, pglob, limit, loc); + return 0; + } + + for (i = 0, pl = pm = ptr; pm <= pe; pm++) + switch (*pm) { + case LBRACKET: + /* Ignore everything between [] */ + for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) + continue; + if (*pm == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pm = pl; + } + break; + + case LBRACE: + i++; + break; + + case RBRACE: + if (i) { + i--; + break; + } + /* FALLTHROUGH */ + case COMMA: + if (i && *pm == COMMA) + break; + else { + /* Append the current string */ + for (lm = ls; (pl < pm); *lm++ = *pl++) + continue; + /* + * Append the rest of the pattern after the + * closing brace + */ + for (pl = pe + 1; (*lm++ = *pl++) != EOS;) + continue; + + /* Expand the current pattern */ +#ifdef DEBUG + qprintf("globexp2:", patbuf); +#endif + *rv = globexp1(patbuf, pglob, limit, loc); + + /* move after the comma, to the next string */ + pl = pm + 1; + } + break; + + default: + break; + } + *rv = 0; + return 0; +} + + + +/* + * expand tilde from the passwd file. + */ +static const Char * +globtilde(pattern, patbuf, patbuf_len, pglob) + const Char *pattern; + Char *patbuf; + size_t patbuf_len; + glob_t *pglob; +{ + struct passwd *pwd; + char *h; + const Char *p; + Char *b, *eb; + + if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) + return pattern; + + /* + * Copy up to the end of the string or / + */ + eb = &patbuf[patbuf_len - 1]; + for (p = pattern + 1, h = (char *) patbuf; + h < (char *)eb && *p && *p != SLASH; *h++ = *p++) + continue; + + *h = EOS; + + if (((char *) patbuf)[0] == EOS) { + /* + * handle a plain ~ or ~/ by expanding $HOME first (iff + * we're not running setuid or setgid) and then trying + * the password file + */ + if (issetugid() != 0 || + (h = getenv("HOME")) == NULL) { + if (((h = getlogin()) != NULL && + (pwd = getpwnam(h)) != NULL) || + (pwd = getpwuid(getuid())) != NULL) + h = pwd->pw_dir; + else + return pattern; + } + } + else { + /* + * Expand a ~user + */ + if ((pwd = getpwnam((char*) patbuf)) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + + /* Copy the home directory */ + for (b = patbuf; b < eb && *h; *b++ = *h++) + continue; + + /* Append the rest of the pattern */ + while (b < eb && (*b++ = *p++) != EOS) + continue; + *b = EOS; + + return patbuf; +} + + +/* + * The main glob() routine: compiles the pattern (optionally processing + * quotes), calls glob1() to do the real pattern matching, and finally + * sorts the list (unless unsorted operation is requested). Returns 0 + * if things went well, nonzero if errors occurred. + */ +__private_extern__ int +glob0(pattern, pglob, limit, loc) + const Char *pattern; + glob_t *pglob; + int *limit; + locale_t loc; +{ + const Char *qpatnext; + Char c; + int err, oldpathc; + Char *bufnext, patbuf[MAXPATHLEN]; + + qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); + oldpathc = pglob->gl_pathc; + bufnext = patbuf; + + /* We don't need to check for buffer overflow any more. */ + while ((c = *qpatnext++) != EOS) { + if (c & M_PROTECT) { + *bufnext++ = CHAR(c); + continue; + } /* else */ + switch (c) { + case LBRACKET: + c = *qpatnext; + if (c == NOT) + ++qpatnext; + if (*qpatnext == EOS || + g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { + *bufnext++ = LBRACKET; + if (c == NOT) + --qpatnext; + break; + } + *bufnext++ = M_SET; + if (c == NOT) + *bufnext++ = M_NOT; + c = *qpatnext++; + do { + *bufnext++ = CHAR(c); + if (*qpatnext == RANGE && + (c = qpatnext[1]) != RBRACKET) { + *bufnext++ = M_RNG; + *bufnext++ = CHAR(c); + qpatnext += 2; + } + } while ((c = *qpatnext++) != RBRACKET); + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_END; + break; + case QUESTION: + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_ONE; + break; + case STAR: + pglob->gl_flags |= GLOB_MAGCHAR; + /* collapse adjacent stars to one, + * to avoid exponential behavior + */ + if (bufnext == patbuf || bufnext[-1] != M_ALL) + *bufnext++ = M_ALL; + break; + default: + *bufnext++ = CHAR(c); + break; + } + } + *bufnext = EOS; +#ifdef DEBUG + qprintf("glob0:", patbuf); +#endif + + if ((err = glob1(patbuf, pglob, limit, loc)) != 0) + return(err); + + /* + * If there was no match we are going to append the pattern + * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified + * and the pattern did not contain any magic characters + * GLOB_NOMAGIC is there just for compatibility with csh. + */ + if (pglob->gl_pathc == oldpathc) { + if (((pglob->gl_flags & GLOB_NOCHECK) || + ((pglob->gl_flags & GLOB_NOMAGIC) && + !(pglob->gl_flags & GLOB_MAGCHAR)))) + return(globextend(pattern, pglob, limit, loc)); + else + return(GLOB_NOMATCH); + } + if (!(pglob->gl_flags & GLOB_NOSORT)) + qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, + pglob->gl_pathc - oldpathc, sizeof(char *), compare); + return(0); +} + +static int +compare(p, q) + const void *p, *q; +{ + return(strcoll(*(char **)p, *(char **)q)); +} + +static int +glob1(pattern, pglob, limit, loc) + Char *pattern; + glob_t *pglob; + int *limit; + locale_t loc; +{ + Char pathbuf[MAXPATHLEN]; + + /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ + if (*pattern == EOS) + return(0); + return(glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, + pattern, pglob, limit, loc)); +} +#endif /* !BUILDING_VARIANT */ + +/* + * The functions glob2 and glob3 are mutually recursive; there is one level + * of recursion for each segment in the pattern that contains one or more + * meta characters. + */ +__private_extern__ int +#if __DARWIN_64_BIT_INO_T +glob2_64(pathbuf, pathend, pathend_last, pattern, pglob, limit, loc) +#else /* !__DARWIN_64_BIT_INO_T */ +glob2_32(pathbuf, pathend, pathend_last, pattern, pglob, limit, loc) +#endif /* __DARWIN_64_BIT_INO_T */ + Char *pathbuf, *pathend, *pathend_last, *pattern; + glob_t *pglob; + int *limit; + locale_t loc; +{ + struct stat sb; + Char *p, *q; + int anymeta; + + /* + * Loop over pattern segments until end of pattern or until + * segment with meta character found. + */ + for (anymeta = 0;;) { + if (*pattern == EOS) { /* End of pattern? */ + *pathend = EOS; + if (g_lstat(pathbuf, &sb, pglob, loc)) + return(0); + + if (((pglob->gl_flags & GLOB_MARK) && + pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) + || (S_ISLNK(sb.st_mode) && + (g_stat(pathbuf, &sb, pglob, loc) == 0) && + S_ISDIR(sb.st_mode)))) { + if (pathend + 1 > pathend_last) + return (GLOB_ABORTED); + *pathend++ = SEP; + *pathend = EOS; + } + ++pglob->gl_matchc; + return(globextend(pathbuf, pglob, limit, loc)); + } + + /* Find end of next segment, copy tentatively to pathend. */ + q = pathend; + p = pattern; + while (*p != EOS && *p != SEP) { + if (ismeta(*p)) + anymeta = 1; + if (q + 1 > pathend_last) + return (GLOB_ABORTED); + *q++ = *p++; + } + + if (!anymeta) { /* No expansion, do next segment. */ + pathend = q; + pattern = p; + while (*pattern == SEP) { + if (pathend + 1 > pathend_last) + return (GLOB_ABORTED); + *pathend++ = *pattern++; + } + } else /* Need expansion, recurse. */ + return(glob3(pathbuf, pathend, pathend_last, pattern, p, + pglob, limit, loc)); + } + /* NOTREACHED */ +} + +#ifndef BUILDING_VARIANT +__private_extern__ int +glob3(pathbuf, pathend, pathend_last, pattern, restpattern, pglob, limit, loc) + Char *pathbuf, *pathend, *pathend_last, *pattern, *restpattern; + glob_t *pglob; + int *limit; + locale_t loc; +{ + struct dirent *dp; + DIR *dirp; + int err; + char buf[MAXPATHLEN]; + + /* + * The readdirfunc declaration can't be prototyped, because it is + * assigned, below, to two functions which are prototyped in glob.h + * and dirent.h as taking pointers to differently typed opaque + * structures. + */ + struct dirent *(*readdirfunc)(); + + if (pathend > pathend_last) + return (GLOB_ABORTED); + *pathend = EOS; + errno = 0; + + if ((dirp = g_opendir(pathbuf, pglob, loc)) == NULL) { + /* TODO: don't call for ENOENT or ENOTDIR? */ + if (pglob->gl_errfunc) { + if (g_Ctoc(pathbuf, buf, sizeof(buf), loc)) + return (GLOB_ABORTED); + if (pglob->gl_errfunc(buf, errno)) + return (GLOB_ABORTED); + } + if (pglob->gl_flags & GLOB_ERR) + return (GLOB_ABORTED); + return(0); + } + + err = 0; + + /* Search directory for matching names. */ + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + readdirfunc = pglob->gl_readdir; + else + readdirfunc = readdir; + while ((dp = (*readdirfunc)(dirp))) { + u_char *sc; + Char *dc; + wchar_t wc; + size_t clen; + mbstate_t mbs; + + /* Initial DOT must be matched literally. */ + if (dp->d_name[0] == DOT && *pattern != DOT) + continue; + memset(&mbs, 0, sizeof(mbs)); + dc = pathend; + sc = (u_char *) dp->d_name; + while (dc < pathend_last) { + clen = mbrtowc_l(&wc, (const char *)sc, MB_LEN_MAX, &mbs, loc); + if (clen == (size_t)-1 || clen == (size_t)-2) { + wc = *sc; + clen = 1; + memset(&mbs, 0, sizeof(mbs)); + } + if ((*dc++ = wc) == EOS) + break; + sc += clen; + } + if (!match(pathend, pattern, restpattern, loc)) { + *pathend = EOS; + continue; + } + err = glob2(pathbuf, --dc, pathend_last, restpattern, + pglob, limit, loc); + if (err) + break; + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir)(dirp); + else + closedir(dirp); + return(err); +} + + +/* + * Extend the gl_pathv member of a glob_t structure to accomodate a new item, + * add the new item, and update gl_pathc. + * + * This assumes the BSD realloc, which only copies the block when its size + * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic + * behavior. + * + * Return 0 if new item added, error code if memory couldn't be allocated. + * + * Invariant of the glob_t structure: + * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and + * gl_pathv points to (gl_offs + gl_pathc + 1) items. + */ +__private_extern__ int +globextend(path, pglob, limit, loc) + const Char *path; + glob_t *pglob; + int *limit; + locale_t loc; +{ + char **pathv; + int i; + u_int newsize, len; + char *copy; + const Char *p; + + if (*limit && pglob->gl_pathc > *limit) { + errno = 0; + return (GLOB_NOSPACE); + } + + newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); + pathv = pglob->gl_pathv ? + realloc((char *)pglob->gl_pathv, newsize) : + malloc(newsize); + if (pathv == NULL) { + if (pglob->gl_pathv) { + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + } + return(GLOB_NOSPACE); + } + + if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { + /* first time around -- clear initial gl_offs items */ + pathv += pglob->gl_offs; + for (i = pglob->gl_offs; --i >= 0; ) + *--pathv = NULL; + } + pglob->gl_pathv = pathv; + + for (p = path; *p++;) + continue; + len = MB_CUR_MAX_L(loc) * (size_t)(p - path); /* XXX overallocation */ + if ((copy = malloc(len)) != NULL) { + if (g_Ctoc(path, copy, len, loc)) { + free(copy); + return (GLOB_NOSPACE); + } + pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; + } + pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + return(copy == NULL ? GLOB_NOSPACE : 0); +} + +/* + * pattern matching function for filenames. Each occurrence of the * + * pattern causes a recursion level. + */ +static int +match(name, pat, patend, loc) + Char *name, *pat, *patend; + locale_t loc; +{ + int ok, negate_range; + Char c, k; + + while (pat < patend) { + c = *pat++; + switch (c & M_MASK) { + case M_ALL: + if (pat == patend) + return(1); + do + if (match(name, pat, patend, loc)) + return(1); + while (*name++ != EOS); + return(0); + case M_ONE: + if (*name++ == EOS) + return(0); + break; + case M_SET: + ok = 0; + if ((k = *name++) == EOS) + return(0); + if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) + ++pat; + while (((c = *pat++) & M_MASK) != M_END) + if ((*pat & M_MASK) == M_RNG) { + if (loc->__collate_load_error ? + CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) : + __collate_range_cmp(CHAR(c), CHAR(k), loc) <= 0 + && __collate_range_cmp(CHAR(k), CHAR(pat[1]), loc) <= 0 + ) + ok = 1; + pat += 2; + } else if (c == k) + ok = 1; + if (ok == negate_range) + return(0); + break; + default: + if (*name++ != c) + return(0); + break; + } + } + return(*name == EOS); +} + +/* Free allocated data belonging to a glob_t structure. */ +void +globfree(pglob) + glob_t *pglob; +{ + int i; + char **pp; + + if (pglob->gl_pathv != NULL) { + pp = pglob->gl_pathv + pglob->gl_offs; + for (i = pglob->gl_pathc; i--; ++pp) + if (*pp) + free(*pp); + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + } +} + +static DIR * +g_opendir(str, pglob, loc) + Char *str; + glob_t *pglob; + locale_t loc; +{ + char buf[MAXPATHLEN]; + + if (!*str) + strcpy(buf, "."); + else { + if (g_Ctoc(str, buf, sizeof(buf), loc)) + return (NULL); + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_opendir)(buf)); + + return(opendir(buf)); +} +#endif /* !BUILDING_VARIANT */ + +static int +g_lstat(fn, sb, pglob, loc) + Char *fn; + struct stat *sb; + glob_t *pglob; + locale_t loc; +{ + char buf[MAXPATHLEN]; + + if (g_Ctoc(fn, buf, sizeof(buf), loc)) { + errno = ENAMETOOLONG; + return (-1); + } + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_lstat)(buf, sb)); + return(lstat(buf, sb)); +} + +static int +g_stat(fn, sb, pglob, loc) + Char *fn; + struct stat *sb; + glob_t *pglob; + locale_t loc; +{ + char buf[MAXPATHLEN]; + + if (g_Ctoc(fn, buf, sizeof(buf), loc)) { + errno = ENAMETOOLONG; + return (-1); + } + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_stat)(buf, sb)); + return(stat(buf, sb)); +} + +#ifndef BUILDING_VARIANT +static Char * +g_strchr(str, ch) + Char *str; + wchar_t ch; +{ + do { + if (*str == ch) + return (str); + } while (*str++); + return (NULL); +} + +__private_extern__ int +g_Ctoc(str, buf, len, loc) + const Char *str; + char *buf; + u_int len; + locale_t loc; +{ + mbstate_t mbs; + size_t clen; + int mb_cur_max = MB_CUR_MAX_L(loc); + + memset(&mbs, 0, sizeof(mbs)); + while (len >= mb_cur_max) { + clen = wcrtomb_l(buf, *str, &mbs, loc); + if (clen == (size_t)-1) + return (1); + if (*str == L'\0') + return (0); + str++; + buf += clen; + len -= clen; + } + return (1); +} + +#ifdef DEBUG +static void +qprintf(str, s) + const char *str; + Char *s; +{ + Char *p; + + (void)printf("%s:\n", str); + for (p = s; *p; p++) + (void)printf("%c", CHAR(*p)); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", *p & M_PROTECT ? '"' : ' '); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", ismeta(*p) ? '_' : ' '); + (void)printf("\n"); +} +#endif +#endif /* !BUILDING_VARIANT */ diff --git a/gen/glob.3 b/gen/glob.3 new file mode 100644 index 0000000..5c3b3d0 --- /dev/null +++ b/gen/glob.3 @@ -0,0 +1,487 @@ +.\" Copyright (c) 1989, 1991, 1993, 1994 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Guido van Rossum. +.\" 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. +.\" +.\" @(#)glob.3 8.3 (Berkeley) 4/16/94 +.\" $FreeBSD: src/lib/libc/gen/glob.3,v 1.30 2004/09/01 23:28:27 tjr Exp $ +.\" +.Dd September 1, 2004 +.Dt GLOB 3 +.Os +.Sh NAME +.Nm glob , +.Nm globfree +.Nd generate pathnames matching a pattern +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In glob.h +.Ft int +.Fo glob +.Fa "const char *restrict pattern" +.Fa "int flags" +.Fa "int (*errfunc)(const char *epath, int eerno)" +.Fa "glob_t *restrict pglob" +.Fc +.Ft void +.Fo globfree +.Fa "glob_t *pglob" +.Fc +.Sh DESCRIPTION +The +.Fn glob +function +is a pathname generator that implements the rules for file name pattern +matching used by the shell. +.Pp +The include file +.In glob.h +defines the structure type +.Fa glob_t , +which contains at least the following fields: +.Bd -literal +typedef struct { + int gl_pathc; /* count of total paths so far */ + int gl_matchc; /* count of paths matching pattern */ + int gl_offs; /* reserved at beginning of gl_pathv */ + int gl_flags; /* returned flags */ + char **gl_pathv; /* list of paths matching pattern */ +} glob_t; +.Ed +.Pp +The argument +.Fa pattern +is a pointer to a pathname pattern to be expanded. +The +.Fn glob +argument +matches all accessible pathnames against the pattern and creates +a list of the pathnames that match. +In order to have access to a pathname, +.Fn glob +requires search permission on every component of a path except the last +and read permission on each directory of any filename component of +.Fa pattern +that contains any of the special characters +.Ql * , +.Ql ?\& +or +.Ql \&[ . +.Pp +The +.Fn glob +argument +stores the number of matched pathnames into the +.Fa gl_pathc +field, and a pointer to a list of pointers to pathnames into the +.Fa gl_pathv +field. +The first pointer after the last pathname is +.Dv NULL . +If the pattern does not match any pathnames, the returned number of +matched paths is set to zero. +.Pp +It is the caller's responsibility to create the structure pointed to by +.Fa pglob . +The +.Fn glob +function allocates other space as needed, including the memory pointed +to by +.Fa gl_pathv . +.Pp +The argument +.Fa flags +is used to modify the behavior of +.Fn glob . +The value of +.Fa flags +is the bitwise inclusive +.Tn OR +of any of the following +values defined in +.In glob.h : +.Bl -tag -width GLOB_ALTDIRFUNC +.It Dv GLOB_APPEND +Append pathnames generated to the ones from a previous call (or calls) +to +.Fn glob . +The value of +.Fa gl_pathc +will be the total matches found by this call and the previous call(s). +The pathnames are appended to, not merged with the pathnames returned by +the previous call(s). +Between calls, the caller must not change the setting of the +.Dv GLOB_DOOFFS +flag, nor change the value of +.Fa gl_offs +when +.Dv GLOB_DOOFFS +is set, nor (obviously) call +.Fn globfree +for +.Fa pglob . +.It Dv GLOB_DOOFFS +Make use of the +.Fa gl_offs +field. +If this flag is set, +.Fa gl_offs +is used to specify how many +.Dv NULL +pointers to prepend to the beginning +of the +.Fa gl_pathv +field. +In other words, +.Fa gl_pathv +will point to +.Fa gl_offs +.Dv NULL +pointers, +followed by +.Fa gl_pathc +pathname pointers, followed by a +.Dv NULL +pointer. +.It Dv GLOB_ERR +Causes +.Fn glob +to return when it encounters a directory that it cannot open or read. +Ordinarily, +.Fn glob +continues to find matches. +.It Dv GLOB_MARK +Each pathname that is a directory that matches +.Fa pattern +has a slash +appended. +.It Dv GLOB_NOCHECK +If +.Fa pattern +does not match any pathname, then +.Fn glob +returns a list +consisting of only +.Fa pattern , +with the number of total pathnames set to 1, and the number of matched +pathnames set to 0. +The effect of backslash escaping is present in the pattern returned. +.It Dv GLOB_NOESCAPE +By default, a backslash +.Pq Ql \e +character is used to escape the following character in the pattern, +avoiding any special interpretation of the character. +If +.Dv GLOB_NOESCAPE +is set, backslash escaping is disabled. +.It Dv GLOB_NOSORT +By default, the pathnames are sorted in ascending +.Tn ASCII +order; +this flag prevents that sorting (speeding up +.Fn glob ) . +.El +.Pp +The following values may also be included in +.Fa flags , +however, they are non-standard extensions to +.St -p1003.2 . +.Bl -tag -width GLOB_ALTDIRFUNC +.It Dv GLOB_ALTDIRFUNC +The following additional fields in the pglob structure have been +initialized with alternate functions for glob to use to open, read, +and close directories and to get stat information on names found +in those directories. +.Bd -literal +void *(*gl_opendir)(const char * name); +struct dirent *(*gl_readdir)(void *); +void (*gl_closedir)(void *); +int (*gl_lstat)(const char *name, struct stat *st); +int (*gl_stat)(const char *name, struct stat *st); +.Ed +.Pp +This extension is provided to allow programs such as +.Xr restore 8 +to provide globbing from directories stored on tape. +.It Dv GLOB_BRACE +Pre-process the pattern string to expand +.Ql {pat,pat,...} +strings like +.Xr csh 1 . +The pattern +.Ql {} +is left unexpanded for historical reasons (and +.Xr csh 1 +does the same thing to +ease typing +of +.Xr find 1 +patterns). +.It Dv GLOB_MAGCHAR +Set by the +.Fn glob +function if the pattern included globbing characters. +See the description of the usage of the +.Fa gl_matchc +structure member for more details. +.It Dv GLOB_NOMAGIC +Is the same as +.Dv GLOB_NOCHECK +but it only appends the +.Fa pattern +if it does not contain any of the special characters ``*'', ``?'' or ``[''. +.Dv GLOB_NOMAGIC +is provided to simplify implementing the historic +.Xr csh 1 +globbing behavior and should probably not be used anywhere else. +.It Dv GLOB_TILDE +Expand patterns that start with +.Ql ~ +to user name home directories. +.It Dv GLOB_LIMIT +Limit the total number of returned pathnames to the value provided in +.Fa gl_matchc +(default +.Dv ARG_MAX ) . +This option should be set for programs +that can be coerced into a denial of service attack +via patterns that expand to a very large number of matches, +such as a long string of +.Ql */../*/.. . +.El +.Pp +If, during the search, a directory is encountered that cannot be opened +or read and +.Fa errfunc +is +.Pf non- Dv NULL , +.Fn glob +calls +.Fa \*(lp*errfunc\*(rp Ns ( Fa path , errno ) . +This may be unintuitive: a pattern like +.Ql */Makefile +will try to +.Xr stat 2 +.Ql foo/Makefile +even if +.Ql foo +is not a directory, resulting in a +call to +.Fa errfunc . +The error routine can suppress this action by testing for +.Er ENOENT +and +.Er ENOTDIR ; +however, the +.Dv GLOB_ERR +flag will still cause an immediate +return when this happens. +.Pp +If +.Fa errfunc +returns non-zero, +.Fn glob +stops the scan and returns +.Dv GLOB_ABORTED +after setting +.Fa gl_pathc +and +.Fa gl_pathv +to reflect any paths already matched. +This also happens if an error is encountered and +.Dv GLOB_ERR +is set in +.Fa flags , +regardless of the return value of +.Fa errfunc , +if called. +If +.Dv GLOB_ERR +is not set and either +.Fa errfunc +is +.Dv NULL +or +.Fa errfunc +returns zero, the error is ignored. +.Pp +The +.Fn globfree +function frees any space associated with +.Fa pglob +from a previous call(s) to +.Fn glob . +.Sh RETURN VALUES +On successful completion, +.Fn glob +returns zero. +In addition, the fields of +.Fa pglob +contain the values described below: +.Bl -tag -width GLOB_NOCHECK +.It Fa gl_pathc +contains the total number of matched pathnames so far. +This includes other matches from previous invocations of +.Fn glob +if +.Dv GLOB_APPEND +was specified. +.It Fa gl_matchc +contains the number of matched pathnames in the current invocation of +.Fn glob . +.It Fa gl_flags +contains a copy of the +.Fa flags +argument with the bit +.Dv GLOB_MAGCHAR +set if +.Fa pattern +contained any of the special characters ``*'', ``?'' or ``['', cleared +if not. +.It Fa gl_pathv +contains a pointer to a +.Dv NULL Ns -terminated +list of matched pathnames. +However, if +.Fa gl_pathc +is zero, the contents of +.Fa gl_pathv +are undefined. +.El +.Pp +If +.Fn glob +terminates due to an error, it sets errno and returns one of the +following non-zero constants, which are defined in the include +file +.In glob.h : +.Bl -tag -width GLOB_NOCHECK +.It Dv GLOB_NOSPACE +An attempt to allocate memory failed, or if +.Fa errno +was 0 +.Dv GLOB_LIMIT +was specified in the flags and +.Fa pglob\->gl_matchc +or more patterns were matched. +.It Dv GLOB_ABORTED +The scan was stopped because an error was encountered and either +.Dv GLOB_ERR +was set or +.Fa \*(lp*errfunc\*(rp\*(lp\*(rp +returned non-zero. +.It Dv GLOB_NOMATCH +The pattern did not match a pathname and +.Dv GLOB_NOCHECK +was not set. +.El +.Pp +The arguments +.Fa pglob\->gl_pathc +and +.Fa pglob\->gl_pathv +are still set as specified above. +.Sh EXAMPLES +A rough equivalent of +.Ql "ls -l *.c *.h" +can be obtained with the +following code: +.Bd -literal -offset indent +glob_t g; + +g.gl_offs = 2; +glob("*.c", GLOB_DOOFFS, NULL, &g); +glob("*.h", GLOB_DOOFFS | GLOB_APPEND, NULL, &g); +g.gl_pathv[0] = "ls"; +g.gl_pathv[1] = "-l"; +execvp("ls", g.gl_pathv); +.Ed +.Sh CAVEATS +The +.Fn glob +function will not match filenames that begin with a period +unless this is specifically requested (e.g., by ".*"). +.Sh SEE ALSO +.Xr sh 1 , +.Xr fnmatch 3 , +.Xr regexp 3 +.Sh STANDARDS +The current implementation of the +.Fn glob +function +.Em does not +conform to +.St -p1003.2 . +Collating symbol expressions, equivalence class expressions and +character class expressions are not supported. +.Pp +The flags +.Dv GLOB_ALTDIRFUNC , +.Dv GLOB_BRACE , +.Dv GLOB_LIMIT , +.Dv GLOB_MAGCHAR , +.Dv GLOB_NOMAGIC , +and +.Dv GLOB_TILDE , +and the fields +.Fa gl_matchc +and +.Fa gl_flags +are extensions to the +.Tn POSIX +standard and +should not be used by applications striving for strict +conformance. +.Sh HISTORY +The +.Fn glob +and +.Fn globfree +functions first appeared in +.Bx 4.4 . +.Sh BUGS +Patterns longer than +.Dv MAXPATHLEN +may cause unchecked errors. +.Pp +The +.Fn glob +argument +may fail and set errno for any of the errors specified for the +library routines +.Xr stat 2 , +.Xr closedir 3 , +.Xr opendir 3 , +.Xr readdir 3 , +.Xr malloc 3 , +and +.Xr free 3 . diff --git a/gen/intro.3 b/gen/intro.3 index d5d0f64..c01d940 100644 --- a/gen/intro.3 +++ b/gen/intro.3 @@ -32,7 +32,7 @@ .\" @(#)intro.3 8.1 (Berkeley) 6/5/93 .\" $FreeBSD: src/share/man/man3/intro.3,v 1.14 2001/08/07 15:48:38 ru Exp $ .\" -.Dd June 5, 1993 +.Dd Aug 17, 2006 .Dt INTRO 3 .Os .Sh NAME @@ -42,36 +42,25 @@ This section provides an overview of the C library functions, their error returns and other common definitions and concepts. -Most of these functions are available from the C library, -.Em libc . -.\" (see -.\" .Xr libc 3 ) . -Other libraries, such as the math library, -.Em libm , +Most of these functions are available from the System library, +.Em libSystem . +Other libraries must be indicated at compile time with the .Fl l option of the compiler. -.\" .Pp -.\" A subset of the -.\" .Xr libc functions -.\" are available from Fortran; -.\" they are described separately in -.\" .Xr intro 3f . .Pp The various libraries (followed by the loader flag): -.Bl -tag -width "libc (-lc)" -.It Xr libc Pq Fl l Ns Ar c +.Bl -tag -width "libSystem (-lSystem)" +.It Xr libSystem Pq Fl l Ns Ar System Standard C library functions. -.\" (See -.\" .Xr libc 3 . ) When using the C compiler .Xr cc 1 , it is not necessary to supply the loader flag -.Fl l Ns Ar c +.Fl l Ns Ar System for these functions. There are several `libraries' or groups of functions included inside of -.Xr libc : +.Xr libSystem : the standard .Tn I/O routines, @@ -81,53 +70,30 @@ string operators, character tests and character operators, des encryption routines, storage allocation, time functions, signal handling and more. +.Pp +For compatibility with other systems, which provide these capabilities in +separate libraries (such as +.Xr libc ) , +symbolic links are provided for +.Fl l Ns Ar c , +.Fl l Ns Ar dbm , +.Fl l Ns Ar dl , +.Fl l Ns Ar info , +.Fl l Ns Ar m , +.Fl l Ns Ar poll , +.Fl l Ns Ar pthread +and +.Fl l Ns Ar rpcsvc ; +they all point to +.Xr libSystem . .It Xr libcurses Pq Fl l Ns Ar curses Fl l Ns Ar termcap Terminal independent screen management routines for two dimensional non-bitmap display terminals. (See .Xr ncurses 3 . ) -.It Xr libcompat Pq Fl l Ns Ar compat -Functions which are obsolete but are available for compatibility with -.Bx 4.3 . -In particular, -a number of system call interfaces provided in previous releases of -.Bx -have been included for source code compatibility. -Use of these routines should, for the most part, be avoided. -The manual page entry for each compatibility routine -indicates the proper interface to use. -.It Xr libkvm Pq Fl l Ns Ar kvm -Functions used to access kernel memory are in this library. They can be used -against both a running system and a crash dump. -(See -.Xr kvm 3 . ) .It Xr libl Pq Fl l Ns Ar l The library for .Xr lex 1 . -.\" .It Xr libln -.It Xr libm Pq Fl l Ns Ar m -The math library, -.Em libm . -The math library is loaded as needed by the Pascal compiler, -.\" .Xr pc 1 , -but not by the C compiler which requires the -.Fl l Ns Ar m -flag. -(See -.Xr math 3 . ) -.It Xr libmp Pq Fl l Ns Ar mp -.\" .It Xr libom -.\" Old math library. -.\" .It Xr libplot Pq Fl l Ns Ar plot -.\" Device independent plotting functions. -.\" (See -.\" .Xr plot 3 . ) -.\" .It Xr libplotf77 Pq Fl l Ns Ar plotf77 -.\" The device independent plotting functions for fortran. -.\" (See -.\" .Xr plot 3 . ) -.\" .It Xr libresolv Pq Fl l Ns Ar resolv -.\" Routines for network address resolution. .It Xr libtermcap Pq Fl l Ns Ar termcap The terminal independent operation library package. (See @@ -138,15 +104,13 @@ The library for .Xr yacc 1 . .El .Sh FILES -.Bl -tag -width /usr/lib/libm_p.a -compact -.It Pa /usr/lib/libc.a -the C library -.It Pa /usr/lib/libc_p.a -the C library compiled for profiling -.It Pa /usr/lib/libm.a -the math library -.It Pa /usr/lib/libm_p.a -the math library compiled for profiling +.Bl -tag -width /usr/lib/libSystem_profile.dylib -compact +.It Pa /usr/lib/libSystem.dylib +the main System library +.It Pa /usr/lib/libSystem_debug.dylib +the main System library compiled with debug support +.It Pa /usr/lib/libSystem_profile.dylib +the main System library compiled for profiling .El .Sh SEE ALSO .\" .Xr libc 3 , @@ -154,7 +118,6 @@ the math library compiled for profiling .Xr ld 1 , .Xr nm 1 , .Xr intro 2 , -.Xr math 3 , .Xr stdio 3 .\" .Sh LIST OF FUNCTIONS .\" .Bl -column "strncasecmpxxx" "system" diff --git a/gen/isatty-fbsd.c b/gen/isatty-fbsd.c new file mode 100644 index 0000000..b10040b --- /dev/null +++ b/gen/isatty-fbsd.c @@ -0,0 +1,59 @@ +/* + * 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[] = "@(#)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 $"); + +#include +#include +#include +#include +#include + +int +isatty(fd) + int fd; +{ + int retval, type; + struct termios t; + + if(ioctl(fd, FIODTYPE, &type) != -1) { + if((retval = (type == D_TTY)) == 0) + errno = ENOTTY; + } else + retval = (tcgetattr(fd, &t) != -1); + return(retval); +} diff --git a/gen/FreeBSD/fpclassify.3 b/gen/isgreater.3 similarity index 50% rename from gen/FreeBSD/fpclassify.3 rename to gen/isgreater.3 index 8ca38b2..e52eceb 100644 --- a/gen/FreeBSD/fpclassify.3 +++ b/gen/isgreater.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2003 Mike Barcroft +.\" Copyright (c) 2003 David Schultz .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,106 +22,78 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/fpclassify.3,v 1.5 2004/07/09 06:37:44 das Exp $ +.\" $FreeBSD: src/lib/libc/gen/isgreater.3,v 1.2 2003/06/01 19:19:59 ru Exp $ .\" -.Dd July 8, 2004 -.Dt FPCLASSIFY 3 +.Dd February 12, 2003 +.Dt ISGREATER 3 .Os .Sh NAME -.Nm fpclassify , isfinite , isinf , isnan , isnormal -.Nd "classify a floating-point number" +.Nm isgreater , isgreaterequal , isless , islessequal , +.Nm islessgreater , isunordered +.Nd "compare two floating-point numbers" .Sh LIBRARY -.Lb libm +.Lb libc .Sh SYNOPSIS .In math.h .Ft int -.Fn fpclassify "real-floating x" +.Fn isgreater "real-floating x" "real-floating y" .Ft int -.Fn isfinite "real-floating x" +.Fn isgreaterequal "real-floating x" "real-floating y" .Ft int -.Fn isinf "real-floating x" +.Fn isless "real-floating x" "real-floating y" .Ft int -.Fn isnan "real-floating x" +.Fn islessequal "real-floating x" "real-floating y" .Ft int -.Fn isnormal "real-floating x" +.Fn islessgreater "real-floating x" "real-floating y" +.Ft int +.Fn isunordered "real-floating x" "real-floating y" .Sh DESCRIPTION -The -.Fn fpclassify -macro takes an argument of -.Fa x -and returns one of the following manifest constants. -.Bl -tag -width ".Dv FP_SUBNORMAL" -.It Dv FP_INFINITE -Indicates that -.Fa x -is an infinite number. -.It Dv FP_NAN -Indicates that -.Fa x -is not a number (NaN). -.It Dv FP_NORMAL -Indicates that -.Fa x -is a normalized number. -.It Dv FP_SUBNORMAL -Indicates that +Each of the macros +.Fn isgreater , +.Fn isgreaterequal , +.Fn isless , +.Fn islessequal , +and +.Fn islessgreater +takes arguments .Fa x -is a denormalized number. -.It Dv FP_ZERO -Indicates that +and +.Fa y +and returns a non-zero value if and only if its nominal +relation on .Fa x -is zero (0 or \-0). -.El +and +.Fa y +is true. +These macros always return zero if either +argument is not a number (NaN), but unlike the corresponding C +operators, they never raise a floating point exception. .Pp The -.Fn isfinite -macro returns a non-zero value if and only if its argument has -a finite (zero, subnormal, or normal) value. -The -.Fn isinf , -.Fn isnan , +.Fn isunordered +macro takes arguments +.Fa x and -.Fn isnormal -macros return non-zero if and only if +.Fa y , +returning non-zero if and only if neither .Fa x -is an infinity, NaN, -or a non-zero normalized number, respectively. -.Pp -The symbol -.Fn isnanf -is provided as an alias to -.Fn isnan -for compatibility, and its use is deprecated. +nor +.Fa y +are NaNs. +For any pair of floating-point values, one +of the relationships (less, greater, equal, unordered) holds. .Sh SEE ALSO -.Xr isgreater 3 , +.Xr fpclassify 3 , .Xr math 3 , .Xr signbit 3 .Sh STANDARDS The -.Fn fpclassify , -.Fn isfinite , -.Fn isinf , -.Fn isnan , +.Fn isgreater , +.Fn isgreaterequal , +.Fn isless , +.Fn islessequal , +.Fn islessgreater , and -.Fn isnormal +.Fn isunordered macros conform to .St -isoC-99 . -.Sh HISTORY -The -.Fn fpclassify , -.Fn isfinite , -.Fn isinf , -.Fn isnan , -and -.Fn isnormal -macros were added in -.Fx 5.1 . -.Bx 3 -introduced -.Fn isinf -and -.Fn isnan -functions, which accepted -.Vt double -arguments; these have been superseded by the macros -described above. diff --git a/gen/jrand48-fbsd.c b/gen/jrand48-fbsd.c new file mode 100644 index 0000000..40d6a6f --- /dev/null +++ b/gen/jrand48-fbsd.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/jrand48.c,v 1.2 2002/03/22 21:52:05 obrien Exp $"); + +#include "rand48.h" + +long +jrand48(unsigned short xseed[3]) +{ + uint48 tmp; + DORAND48(tmp, xseed); + return (int)((tmp >> 16) & 0xffffffff); +} diff --git a/gen/lcong48-fbsd.c b/gen/lcong48-fbsd.c new file mode 100644 index 0000000..8a13d64 --- /dev/null +++ b/gen/lcong48-fbsd.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/lcong48.c,v 1.2 2002/03/22 21:52:05 obrien Exp $"); + +#include "rand48.h" + +void +lcong48(unsigned short p[7]) +{ + LOADRAND48(_rand48_seed, &p[0]); + LOADRAND48(_rand48_mult, &p[3]); + _rand48_add = p[6]; +} diff --git a/gen/lockf-fbsd.c b/gen/lockf-fbsd.c new file mode 100644 index 0000000..daa89df --- /dev/null +++ b/gen/lockf-fbsd.c @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * 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. + * 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. + */ + +/* $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 $"); + +#ifdef VARIANT_CANCELABLE +int __fcntl(int, int, void *); +#else /* !VARIANT_CANCELABLE */ +int __fcntl_nocancel(int, int, void *); +#endif /* VARIANT_CANCELABLE */ + + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" + +int +lockf(filedes, function, size) + 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; + + switch (function) { + case F_ULOCK: + cmd = F_SETLK; + fl.l_type = F_UNLCK; + break; + case F_LOCK: + cmd = F_SETLKW; + fl.l_type = F_WRLCK; + break; + case F_TLOCK: + cmd = F_SETLK; + fl.l_type = F_WRLCK; + break; + case F_TEST: + fl.l_type = F_WRLCK; +#ifdef VARIANT_CANCELABLE + if (__fcntl(filedes, F_GETLK, &fl) == -1) + return (-1); +#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()) + return (0); + errno = EAGAIN; + return (-1); + /* NOTREACHED */ + default: + errno = EINVAL; + return (-1); + /* NOTREACHED */ + } + +#ifdef VARIANT_CANCELABLE + return (__fcntl(filedes, cmd, &fl)); +#else /* !VARIANT_CANCELABLE */ + return (__fcntl_nocancel(filedes, cmd, &fl)); +#endif /* VARIANT_CANCELABLE */ +} + diff --git a/gen/lockf.3 b/gen/lockf.3 new file mode 100644 index 0000000..f4cecd1 --- /dev/null +++ b/gen/lockf.3 @@ -0,0 +1,277 @@ +.\" $NetBSD: lockf.3,v 1.2 1998/02/05 18:47:28 perry Exp $ +.\" +.\" Copyright (c) 1997 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Klaus Klein and S.P. Zeidler. +.\" +.\" 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/gen/lockf.3,v 1.13 2004/07/02 23:52:10 ru Exp $ +.\" +.Dd December 19, 1997 +.Dt LOCKF 3 +.Os +.Sh NAME +.Nm lockf +.Nd record locking on files +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn lockf "int fildes" "int function" "off_t size" +.Sh DESCRIPTION +The +.Fn lockf +function allows sections of a file to be locked with advisory-mode locks. +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. +All of the locks for a process are removed when the process terminates. +.Pp +The argument +.Fa fildes +is an open file descriptor. +The file descriptor must have been opened either for write-only +.Dv ( O_WRONLY ) +or read/write +.Dv ( O_RDWR ) +operation. +.Pp +The +.Fa function +argument is a control value which specifies the action to be taken. +The permissible values for +.Fa function +are as follows: +.Bl -tag -width F_ULOCKXX -compact -offset indent +.It Sy Function +.Sy Description +.It Dv F_ULOCK +unlock locked sections +.It Dv F_LOCK +lock a section for exclusive use +.It Dv F_TLOCK +test and lock a section for exclusive use +.It Dv F_TEST +test a section for locks by other processes +.El +.Pp +.Dv F_ULOCK +removes locks from a section of the file; +.Dv F_LOCK +and +.Dv F_TLOCK +both lock a section of a file if the section is available; +.Dv F_TEST +detects if a lock by another process is present on the specified section. +.Pp +The +.Fa size +argument is the number of contiguous bytes to be locked or +unlocked. +The section to be locked or unlocked starts at the current +offset in the file and extends forward for a positive size or backward +for a negative size (the preceding bytes up to but not including the +current offset). +However, it is not permitted to lock a section that +starts or extends before the beginning of the file. +If +.Fa size +is 0, the section from the current offset through the largest possible +file offset is locked (that is, from the current offset through the +present or any future end-of-file). +.Pp +The sections locked with +.Dv F_LOCK +or +.Dv F_TLOCK +may, in whole or in part, contain or be contained by a previously +locked section for the same process. +When this occurs, or if adjacent +locked sections would occur, the sections are combined into a single +locked section. +If the request would cause the number of locks to +exceed a system-imposed limit, the request will fail. +.Pp +.Dv F_LOCK +and +.Dv F_TLOCK +requests differ only by the action taken if the section is not +available. +.Dv F_LOCK +blocks the calling process until the section is available. +.Dv F_TLOCK +makes the function fail if the section is already locked by another +process. +.Pp +File locks are released on first close by the locking process of any +file descriptor for the file. +.Pp +.Dv F_ULOCK +requests release (wholly or in part) one or more locked sections +controlled by the process. +Locked sections will be unlocked starting +at the current file offset through +.Fa size +bytes or to the end of file if size is 0. +When all of a locked section +is not released (that is, when the beginning or end of the area to be +unlocked falls within a locked section), the remaining portions of +that section are still locked by the process. +Releasing the center +portion of a locked section will cause the remaining locked beginning +and end portions to become two separate locked sections. +If the +request would cause the number of locks in the system to exceed a +system-imposed limit, the request will fail. +.Pp +An +.Dv F_ULOCK +request in which size is non-zero and the offset of the last byte of +the requested section is the maximum value for an object of type +off_t, when the process has an existing lock in which size is 0 and +which includes the last byte of the requested section, will be treated +as a request to unlock from the start of the requested section with a +size equal to 0. +Otherwise an +.Dv F_ULOCK +request will attempt to unlock only the requested section. +.Pp +A potential for deadlock occurs if a process controlling a locked +region is put to sleep by attempting to lock the locked region of +another process. +This implementation detects that sleeping until a +locked region is unlocked would cause a deadlock and fails with an +.Er EDEADLK +error. +.Pp +The +.Fn lockf , +.Xr fcntl 2 , +and +.Xr flock 2 +locks are compatible. +Processes using different locking interfaces can cooperate +over the same file safely. +However, only one of such interfaces should be used within +the same process. +If a file is locked by a process through +.Xr flock 2 , +any record within the file will be seen as locked +from the viewpoint of another process using +.Xr fcntl 2 +or +.Fn lockf , +and vice versa. +.Pp +Blocking on a section is interrupted by any signal. +.Sh RETURN VALUES +.Rv -std lockf +In the case of a failure, existing locks are not changed. +.Sh ERRORS +The +.Fn lockf +function +will fail if: +.Bl -tag -width Er +.It Bq Er EAGAIN +The argument +.Fa function +is +.Dv F_TLOCK +or +.Dv F_TEST +and the section is already locked by another process. +.It Bq Er EBADF +The argument +.Fa fildes +is not a valid open file descriptor. +.Pp +The argument +.Fa function +is +.Dv F_LOCK +or +.Dv F_TLOCK , +and +.Fa fildes +is not a valid file descriptor open for writing. +.It Bq Er EDEADLK +The argument +.Fa function +is +.Dv F_LOCK +and a deadlock is detected. +.It Bq Er EINTR +The argument +.Fa function +is F_LOCK +and +.Fn lockf +was interrupted by the delivery of a signal. +.It Bq Er EINVAL +The argument +.Fa function +is not one of +.Dv F_LOCK , +.Dv F_TEST , +.Dv F_TLOCK , +or +.Dv F_ULOCK . +.Pp +The argument +.Fa fildes +refers to a file that does not support advisory locking. +.It Bq Er ENOLCK +The argument +.Fa function +is +.Dv F_LOCK , +.Dv F_TLOCK , +or +.Dv F_ULOCK +and satisfying the lock or unlock request would result in the number +of locked regions in the system exceeding a system-imposed limit. +.It Bq Er EOPNOTSUPP +The argument +.Fa fildes +refers to a socket; these do not support advisory locking. +.El +.Sh SEE ALSO +.Xr fcntl 2 , +.Xr flock 2 +.Sh STANDARDS +The +.Fn lockf +function conforms to +.St -xpg4.2 . diff --git a/gen/lrand48-fbsd.c b/gen/lrand48-fbsd.c new file mode 100644 index 0000000..3b01e85 --- /dev/null +++ b/gen/lrand48-fbsd.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/lrand48.c,v 1.2 2002/03/22 21:52:05 obrien Exp $"); + +#include "rand48.h" + +long +lrand48(void) +{ + _DORAND48(_rand48_seed); + return (_rand48_seed >> 17) & 0x7fffffff; +} diff --git a/gen/makecontext.3 b/gen/makecontext.3 new file mode 120000 index 0000000..1f19f44 --- /dev/null +++ b/gen/makecontext.3 @@ -0,0 +1 @@ +./makecontext.3 \ No newline at end of file diff --git a/gen/malloc.3 b/gen/malloc.3 index 9d38da1..bbaa9aa 100644 --- a/gen/malloc.3 +++ b/gen/malloc.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2002 Apple Computer, Inc. All rights reserved. +.\" Copyright (c) 2006 Apple Computer, Inc. All rights reserved. .\" .\" @APPLE_LICENSE_HEADER_START@ .\" @@ -18,30 +18,46 @@ .\" .\" @APPLE_LICENSE_HEADER_END@ .\" -.Dd November 21, 2002 +.Dd May 23, 2006 .Dt MALLOC 3 .Os .Sh NAME -.Nm malloc , calloc , valloc , realloc , reallocf , free , malloc_size , malloc_good_size +.Nm calloc , +.Nm free , +.Nm malloc , +.Nm realloc , +.Nm reallocf , +.Nm valloc .Nd memory allocation .Sh SYNOPSIS .In stdlib.h .Ft void * -.Fn malloc "size_t size" +.Fo calloc +.Fa "size_t count" +.Fa "size_t size" +.Fc +.Ft void +.Fo free +.Fa "void *ptr" +.Fc .Ft void * -.Fn calloc "size_t count" "size_t size" +.Fo malloc +.Fa "size_t size" +.Fc .Ft void * -.Fn valloc "size_t size" +.Fo realloc +.Fa "void *ptr" +.Fa "size_t size" +.Fc .Ft void * -.Fn realloc "void *ptr" "size_t size" +.Fo reallocf +.Fa "void *ptr" +.Fa "size_t size" +.Fc .Ft void * -.Fn reallocf "void *ptr" "size_t size" -.Ft void -.Fn free "void *ptr" -.Ft size_t -.Fn malloc_size "void *ptr" -.Ft size_t -.Fn malloc_good_size "size_t size" +.Fo valloc +.Fa "size_t size" +.Fc .Sh DESCRIPTION The .Fn malloc , @@ -52,27 +68,17 @@ and .Fn reallocf functions allocate memory. The allocated memory is aligned such that it can be used for any data type, -including AltiVec-related types. +including AltiVec- and SSE-related types. The .Fn free function frees allocations that were created via the preceding allocation functions. -The -.Fn malloc_size -and -.Fn malloc_good_size -functions provide information related to the amount of padding space at the end -of allocations. .Pp The .Fn malloc function allocates .Fa size bytes of memory and returns a pointer to the allocated memory. -.Fn malloc -returns a -.Dv NULL -pointer if there is an error. .Pp The .Fn calloc @@ -82,10 +88,6 @@ objects that are .Fa size bytes of memory each and returns a pointer to the allocated memory. The allocated memory is filled with bytes of value zero. -.Fn calloc -returns a -.Dv NULL -pointer if there is an error. .Pp The .Fn valloc @@ -93,10 +95,6 @@ function allocates .Fa size bytes of memory and returns a pointer to the allocated memory. The allocated memory is aligned on a page boundary. -.Fn valloc -returns a -.Dv NULL -pointer if there is an error. .Pp The .Fn realloc @@ -104,7 +102,7 @@ function tries to change the size of the allocation pointed to by .Fa ptr to .Fa size , -and return +and returns .Fa ptr . If there is not enough room to enlarge the memory allocation pointed to by .Fa ptr , @@ -113,12 +111,23 @@ creates a new allocation, copies as much of the old data pointed to by .Fa ptr as will fit to the new allocation, frees the old allocation, and returns a pointer to the allocated memory. +If +.Fa ptr +is +.Dv NULL , .Fn realloc -returns a -.Dv NULL -pointer if there is an error, and the allocation pointed to by +is identical to a call to +.Fn malloc +for +.Fa size +bytes. +If +.Fa size +is zero and .Fa ptr -is still valid. +is not +.Dv NULL , +a new, minimum sized object is allocated and the original object is freed. .Pp The .Fn reallocf @@ -135,25 +144,12 @@ The .Fn free function deallocates the memory allocation pointed to by .Fa ptr . -.Pp -The -.Fn malloc_size -function -returns the size of the memory block that backs the allocation pointed to by -.Fa ptr . -The memory block size is always at least as large as the allocation it backs, -and may be larger. -.Pp -The -.Fn malloc_good_size -function rounds -.Fa size -up to a value that the allocator implementation can allocate without adding any -padding and returns that rounded up value. .Sh RETURN VALUES -If successful, the -.Fn malloc , +If successful, .Fn calloc , +.Fn malloc , +.Fn realloc , +.Fn reallocf , and .Fn valloc functions return a pointer to allocated memory. @@ -164,17 +160,12 @@ pointer and set to .Er ENOMEM . .Pp -If successful, the -.Fn realloc -and -.Fn reallocf -functions return a pointer to allocated memory. -If there is an error, it returns a -.Dv NULL -pointer and sets -.Va errno -to -.Er ENOMEM . +For +.Fn realloc , +the input pointer is still valid if reallocation failed. +For +.Fn reallocf , +the input pointer will have been freed if reallocation failed. .Pp The .Fn free @@ -254,12 +245,16 @@ When is set and this is set to a non-zero value, causes .Xr abort 3 to be called if a heap corruption is detected, instead of any sleeping. -.It Ev MallocBadFreeAbort -If set to a non-zero value, causes +.It Ev MallocErrorAbort +If set, causes .Xr abort 3 -to be called if the pointer passed to +to be called if an error was encountered in +.Xr malloc 3 +or .Xr free 3 -was previously freed, or is otherwise illegal. +, such as a calling +.Xr free 3 +on a pointer previously freed. .It Ev MallocHelp If set, print a list of environment variables that are paid heed to by the allocation-related functions, along with short descriptions. @@ -269,5 +264,6 @@ The list should correspond to this documentation. .Sh SEE ALSO .Xr leaks 1 , .Xr malloc_history 1 , -.Xr abort 3 -.Pa /Developer/Documentation/ReleaseNotes/DeveloperTools/MallocOptions.html +.Xr abort 3 , +.Xr malloc_size 3 +.Pa /Developer/ADC Reference Library/releasenotes/DeveloperTools/MallocOptions.html diff --git a/gen/malloc.c b/gen/malloc.c index 44e7705..50bdbae 100644 --- a/gen/malloc.c +++ b/gen/malloc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2006, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -33,17 +33,34 @@ #import #import #import +#import +#import #import "scalable_malloc.h" #import "stack_logging.h" +#import "malloc_printf.h" +#import "_simple.h" + +/* + * MALLOC_ABSOLUTE_MAX_SIZE - There are many instances of addition to a + * user-specified size_t, which can cause overflow (and subsequent crashes) + * for values near SIZE_T_MAX. Rather than add extra "if" checks everywhere + * this occurs, it is easier to just set an absolute maximum request size, + * and immediately return an error if the requested size exceeds this maximum. + * Of course, values less than this absolute max can fail later if the value + * is still too large for the available memory. The largest value added + * seems to be PAGE_SIZE (in the macro round_page()), so to be safe, we set + * the maximum to be 2 * PAGE_SIZE less than SIZE_T_MAX. + */ +#define MALLOC_ABSOLUTE_MAX_SIZE (SIZE_T_MAX - (2 * PAGE_SIZE)) #define USE_SLEEP_RATHER_THAN_ABORT 0 #define INITIAL_ZONES 8 // After this number, we reallocate for new zones -typedef void (malloc_logger_t)(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_frames_to_skip); +typedef void (malloc_logger_t)(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip); -static pthread_lock_t _malloc_lock; +__private_extern__ pthread_lock_t _malloc_lock = 0; // initialized in __libc_init static malloc_zone_t *initial_malloc_zones[INITIAL_ZONES] = {0}; /* The following variables are exported for the benefit of performance tools */ @@ -57,12 +74,24 @@ unsigned malloc_check_start = 0; // 0 means don't check unsigned malloc_check_counter = 0; unsigned malloc_check_each = 1000; +/* global flag to suppress ASL logging e.g. for syslogd */ +int _malloc_no_asl_log = 0; + static int malloc_check_sleep = 100; // default 100 second sleep static int malloc_check_abort = 0; // default is to sleep, not abort -static int malloc_free_abort = 0; // default is not to abort +static int malloc_debug_file = STDERR_FILENO; +/* + * State indicated by malloc_def_zone_state + * 0 - the default zone has not yet been created + * 1 - a Malloc* environment variable has been set + * 2 - the default zone has been created and an environment variable scan done + * 3 - a new default zone has been created and another environment variable scan + */ +__private_extern__ int malloc_def_zone_state = 0; +__private_extern__ malloc_zone_t *__zone0 = NULL; -static int malloc_debug_file; +static const char Malloc_Facility[] = "com.apple.Libsystem.malloc"; #define MALLOC_LOCK() LOCK(_malloc_lock) #define MALLOC_UNLOCK() UNLOCK(_malloc_lock) @@ -77,41 +106,97 @@ static int malloc_debug_file; 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) { - // locates the proper zone - // if zone found fills returnedSize; else returns NULL - // See comment in malloc_zone_register() about clients non locking to call this function - // Speed is critical for this function - unsigned index = malloc_num_zones; + // Returns a zone which may contain ptr, or NULL. + // Speed is critical for this function, so it is not guaranteed to return + // the zone which contains ptr. For N zones, zones 1 through N - 1 are + // checked to see if they contain ptr. If so, the zone containing ptr is + // returned. Otherwise the last zone is returned, since it is the last zone + // in which ptr may reside. Clients should call zone->size(ptr) on the + // return value to determine whether or not ptr is an allocated object. + // This behavior optimizes for the case where ptr is an allocated object, + // and there is only one zone. + unsigned index, limit = malloc_num_zones; + if (limit == 0) + return NULL; + malloc_zone_t **zones = malloc_zones; - while (index--) { - malloc_zone_t *zone = *zones++; - size_t size; - size = zone->size(zone, ptr); + for (index = 0; index < limit - 1; ++index, ++zones) { + malloc_zone_t *zone = *zones; + size_t size = zone->size(zone, ptr); if (size) { if (returned_size) *returned_size = size; return zone; } } - return NULL; + return malloc_zones[index]; +} + +__private_extern__ __attribute__((noinline)) void +malloc_error_break(void) { + // Provides a non-inlined place for various malloc error procedures to call + // that will be called after an error message appears. It does not make + // sense for developers to call this function, so it is marked + // __private_extern__ to prevent it from becoming API. } /********* Creation and destruction ************/ +static void set_flags_from_environment(void); + +// malloc_zone_register_while_locked may drop the lock temporarily +static void +malloc_zone_register_while_locked(malloc_zone_t *zone) { + /* Note that given the sequencing it is always safe to first get the number of zones, then get malloc_zones without taking the lock, if all you need is to iterate through the list */ + if (malloc_num_zones >= INITIAL_ZONES) { + malloc_zone_t **zones = malloc_zones; + malloc_zone_t *pzone = malloc_zones[0]; + boolean_t copy = malloc_num_zones == INITIAL_ZONES; + if (copy) zones = NULL; // to avoid realloc on something not allocated + MALLOC_UNLOCK(); + zones = pzone->realloc(pzone, zones, (malloc_num_zones + 1) * sizeof(malloc_zone_t *)); // we leak initial_malloc_zones, not worth tracking it + MALLOC_LOCK(); + if (copy) memcpy(zones, malloc_zones, malloc_num_zones * sizeof(malloc_zone_t *)); + malloc_zones = zones; + } + malloc_zones[malloc_num_zones] = zone; + malloc_num_zones++; // note that we do this after setting malloc_num_zones, so enumerations without taking the lock are safe + // _malloc_printf(ASL_LEVEL_INFO, "Registered %p malloc_zones at address %p is %p [%d zones]\n", zone, &malloc_zones, malloc_zones, malloc_num_zones); +} + static void _malloc_initialize(void) { - // guaranteed to be called only once - (void)malloc_create_zone(0, 0); - malloc_set_zone_name(malloc_zones[0], "DefaultMallocZone"); - LOCK_INIT(_malloc_lock); - // malloc_printf("%d registered zones\n", malloc_num_zones); - // malloc_printf("malloc_zones is at %p; malloc_num_zones is at %p\n", (unsigned)&malloc_zones, (unsigned)&malloc_num_zones); + MALLOC_LOCK(); + if (malloc_def_zone_state < 2) { + unsigned n; + malloc_zone_t *zone; + + malloc_def_zone_state += 2; + set_flags_from_environment(); // will only set flags up to two times + n = malloc_num_zones; + zone = create_scalable_zone(0, malloc_debug_flags); + //malloc_zone_register_while_locked may drop the lock temporarily + malloc_zone_register_while_locked(zone); + malloc_set_zone_name(zone, "DefaultMallocZone"); + if (n != 0) { // make the default first, for efficiency + 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_zones[0] = malloc_zones[n]; + malloc_zones[n] = hold; + } + // _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); + } + MALLOC_UNLOCK(); } static inline malloc_zone_t *inline_malloc_default_zone(void) __attribute__((always_inline)); static inline malloc_zone_t * inline_malloc_default_zone(void) { - if (!malloc_num_zones) _malloc_initialize(); - // malloc_printf("In inline_malloc_default_zone with %d %d\n", malloc_num_zones, malloc_has_debug_zone); + if (malloc_def_zone_state < 2) _malloc_initialize(); + // _malloc_printf(ASL_LEVEL_INFO, "In inline_malloc_default_zone with %d %d\n", malloc_num_zones, malloc_has_debug_zone); return malloc_zones[0]; } @@ -120,11 +205,49 @@ malloc_default_zone(void) { return inline_malloc_default_zone(); } +// For debugging, allow stack logging to both memory and disk to compare their results. static void -set_flags_from_environment(void) { - const char *flag; - int fd; +stack_logging_log_stack_debug(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip) +{ + __disk_stack_logging_log_stack(type_flags, zone_ptr, size, ptr_arg, return_val, num_hot_to_skip); + stack_logging_log_stack(type_flags, zone_ptr, size, ptr_arg, return_val, num_hot_to_skip); +} +static void +set_flags_from_environment(void) { + const char *flag; + int fd; + char **env = * _NSGetEnviron(); + char **p; + char *c; + + if (malloc_debug_file != STDERR_FILENO) { + close(malloc_debug_file); + malloc_debug_file = STDERR_FILENO; + } + malloc_debug_flags = 0; + stack_logging_enable_logging = 0; + stack_logging_dontcompact = 0; + malloc_logger = NULL; + malloc_check_start = 0; + malloc_check_each = 1000; + malloc_check_abort = 0; + malloc_check_sleep = 100; + /* + * Given that all environment variables start with "Malloc" we optimize by scanning quickly + * first the environment, therefore avoiding repeated calls to getenv(). + * If we are setu/gid these flags are ignored to prevent a malicious invoker from changing + * our behaviour. + */ + for (p = env; (c = *p) != NULL; ++p) { + if (!strncmp(c, "Malloc", 6)) { + if (issetugid()) + return; + break; + } + } + if (c == NULL) + return; flag = getenv("MallocLogFile"); if (flag) { fd = open(flag, O_WRONLY|O_APPEND|O_CREAT, 0644); @@ -137,37 +260,58 @@ set_flags_from_environment(void) { } if (getenv("MallocGuardEdges")) { malloc_debug_flags = SCALABLE_MALLOC_ADD_GUARD_PAGES; - malloc_printf("protecting edges\n"); + _malloc_printf(ASL_LEVEL_INFO, "protecting edges\n"); if (getenv("MallocDoNotProtectPrelude")) { malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_PRELUDE; - malloc_printf("... but not protecting prelude guard page\n"); + _malloc_printf(ASL_LEVEL_INFO, "... but not protecting prelude guard page\n"); } if (getenv("MallocDoNotProtectPostlude")) { malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE; - malloc_printf("... but not protecting postlude guard page\n"); + _malloc_printf(ASL_LEVEL_INFO, "... but not protecting postlude guard page\n"); } } flag = getenv("MallocStackLogging"); if (!flag) { flag = getenv("MallocStackLoggingNoCompact"); stack_logging_dontcompact = 1; - } + } + // For debugging, the MallocStackLogging or MallocStackLoggingNoCompact environment variables can be set to + // values of "memory", "disk", or "both" to control which stack logging mechanism to use. Those strings appear + // in the flag variable, and the strtoul() call below will return 0, so then we can do string comparison on the + // value of flag. The default stack logging now is disk stack logging, since memory stack logging is not 64-bit-aware. if (flag) { - unsigned val = strtoul(flag, NULL, 0); + unsigned long val = strtoul(flag, NULL, 0); if (val == 1) val = 0; if (val == -1) val = 0; - malloc_logger = (val) ? (void *)val : stack_logging_log_stack; + if (val) { + malloc_logger = (void *)val; + _malloc_printf(ASL_LEVEL_INFO, "recording stacks using recorder %p\n", malloc_logger); + } else if (strcmp(flag,"memory") == 0) { + malloc_logger = stack_logging_log_stack; + _malloc_printf(ASL_LEVEL_INFO, "recording malloc stacks in memory using standard recorder\n"); + } else if (strcmp(flag,"both") == 0) { + malloc_logger = stack_logging_log_stack_debug; + _malloc_printf(ASL_LEVEL_INFO, "recording malloc stacks to both memory and disk for comparison debugging\n"); + } else { // the default is to log to disk + malloc_logger = __disk_stack_logging_log_stack; + _malloc_printf(ASL_LEVEL_INFO, "recording malloc stacks to disk using standard recorder\n"); + } stack_logging_enable_logging = 1; - if (malloc_logger == stack_logging_log_stack) { - malloc_printf("recording stacks using standard recorder\n"); - } else { - malloc_printf("recording stacks using recorder %p\n", malloc_logger); + if (stack_logging_dontcompact) { + if (malloc_logger == __disk_stack_logging_log_stack) { + _malloc_printf(ASL_LEVEL_INFO, "stack logging compaction turned off; size of log files on disk can increase rapidly\n"); + } else { + _malloc_printf(ASL_LEVEL_INFO, "stack logging compaction turned off; VM can increase rapidly\n"); + } } - if (stack_logging_dontcompact) malloc_printf("stack logging compaction turned off; VM can increase rapidly\n"); } if (getenv("MallocScribble")) { malloc_debug_flags |= SCALABLE_MALLOC_DO_SCRIBBLE; - malloc_printf("enabling scribbling to detect mods to free blocks\n"); + _malloc_printf(ASL_LEVEL_INFO, "enabling scribbling to detect mods to free blocks\n"); + } + if (getenv("MallocErrorAbort")) { + malloc_debug_flags |= SCALABLE_MALLOC_ABORT_ON_ERROR; + _malloc_printf(ASL_LEVEL_INFO, "enabling abort() on bad malloc or free\n"); } flag = getenv("MallocCheckHeapStart"); if (flag) { @@ -180,29 +324,26 @@ set_flags_from_environment(void) { if (malloc_check_each == 0) malloc_check_each = 1; if (malloc_check_each == -1) malloc_check_each = 1; } - malloc_printf("checks heap after %dth operation and each %d operations\n", malloc_check_start, malloc_check_each); + _malloc_printf(ASL_LEVEL_INFO, "checks heap after %dth operation and each %d operations\n", malloc_check_start, malloc_check_each); flag = getenv("MallocCheckHeapAbort"); if (flag) malloc_check_abort = strtol(flag, NULL, 0); if (malloc_check_abort) - malloc_printf("will abort on heap corruption\n"); + _malloc_printf(ASL_LEVEL_INFO, "will abort on heap corruption\n"); else { flag = getenv("MallocCheckHeapSleep"); if (flag) malloc_check_sleep = strtol(flag, NULL, 0); if (malloc_check_sleep > 0) - malloc_printf("will sleep for %d seconds on heap corruption\n", malloc_check_sleep); + _malloc_printf(ASL_LEVEL_INFO, "will sleep for %d seconds on heap corruption\n", malloc_check_sleep); else if (malloc_check_sleep < 0) - malloc_printf("will sleep once for %d seconds on heap corruption\n", -malloc_check_sleep); + _malloc_printf(ASL_LEVEL_INFO, "will sleep once for %d seconds on heap corruption\n", -malloc_check_sleep); else - malloc_printf("no sleep on heap corruption\n"); + _malloc_printf(ASL_LEVEL_INFO, "no sleep on heap corruption\n"); } } - flag = getenv("MallocBadFreeAbort"); - if (flag) - malloc_free_abort = strtol(flag, NULL, 0); if (getenv("MallocHelp")) { - malloc_printf( + _malloc_printf(ASL_LEVEL_INFO, "environment variables that can be set for debug:\n" "- MallocLogFile to create/append messages to file instead of stderr\n" "- MallocGuardEdges to add 2 guard pages for each large block\n" @@ -216,7 +357,7 @@ set_flags_from_environment(void) { "- MallocCheckHeapEach to repeat the checking of the heap after operations\n" "- MallocCheckHeapSleep to sleep seconds on heap corruption\n" "- MallocCheckHeapAbort to abort on heap corruption if is non-zero\n" - "- MallocBadFreeAbort to abort on a bad free if is non-zero\n" + "- MallocErrorAbort to abort on a bad malloc or free\n" "- MallocHelp - this help!\n"); } } @@ -226,27 +367,11 @@ malloc_create_zone(vm_size_t start_size, unsigned flags) { malloc_zone_t *zone; - if (!malloc_num_zones) { - char **env = * _NSGetEnviron(); - char **p; - char *c; - - malloc_debug_file = STDERR_FILENO; - - /* - * Given that all environment variables start with "Malloc" we optimize by scanning quickly - * first the environment, therefore avoiding repeated calls to getenv(). - * If we are setu/gid these flags are ignored to prevent a malicious invoker from changing - * our behaviour. - */ - for (p = env; (c = *p) != NULL; ++p) { - if (!strncmp(c, "Malloc", 6)) { - if (!issetugid()) - set_flags_from_environment(); - break; - } - } + /* start_size doesn't seemed to actually be used, but we test anyways */ + if (start_size > MALLOC_ABSOLUTE_MAX_SIZE) { + return NULL; } + if (malloc_def_zone_state < 2) _malloc_initialize(); zone = create_scalable_zone(start_size, malloc_debug_flags); malloc_zone_register(zone); return zone; @@ -258,6 +383,16 @@ malloc_destroy_zone(malloc_zone_t *zone) { zone->destroy(zone); } +/* called from the {put,set,unset}env routine */ +__private_extern__ void +__malloc_check_env_name(const char *name) +{ + MALLOC_LOCK(); + if(malloc_def_zone_state == 2 && strncmp(name, "Malloc", 6) == 0) + malloc_def_zone_state = 1; + MALLOC_UNLOCK(); +} + /********* Block creation and manipulation ************/ static void @@ -265,16 +400,29 @@ internal_check(void) { static vm_address_t *frames = NULL; static unsigned num_frames; if (malloc_zone_check(NULL)) { - malloc_printf("MallocCheckHeap: PASSED check at %dth operation\n", malloc_check_counter-1); + _malloc_printf(ASL_LEVEL_NOTICE, "MallocCheckHeap: PASSED check at %dth operation\n", malloc_check_counter-1); if (!frames) vm_allocate(mach_task_self(), (void *)&frames, vm_page_size, 1); thread_stack_pcs(frames, vm_page_size/sizeof(vm_address_t) - 1, &num_frames); } else { malloc_printf("*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter-1); if (frames) { unsigned index = 1; - malloc_printf("Stack for last operation where the malloc check succeeded: "); - while (index < num_frames) malloc_printf("%p ", frames[index++]); - malloc_printf("\n(Use 'atos' for a symbolic stack)\n"); + _SIMPLE_STRING b = _simple_salloc(); + if (b) { + _simple_sappend(b, "Stack for last operation where the malloc check succeeded: "); + while (index < num_frames) _simple_sprintf(b, "%p ", frames[index++]); + malloc_printf("%s\n(Use 'atos' for a symbolic stack)\n", _simple_string(b)); + _simple_sfree(b); + } else { + /* + * Should only get here if vm_allocate() can't get a single page of + * memory, implying _simple_asl_log() would also fail. So we just + * print to the file descriptor. + */ + _malloc_printf(MALLOC_PRINTF_NOLOG, "Stack for last operation where the malloc check succeeded: "); + while (index < num_frames) _malloc_printf(MALLOC_PRINTF_NOLOG, "%p ", frames[index++]); + _malloc_printf(MALLOC_PRINTF_NOLOG, "\n(Use 'atos' for a symbolic stack)\n"); + } } if (malloc_check_each > 1) { unsigned recomm_each = (malloc_check_each > 10) ? malloc_check_each/10 : 1; @@ -284,11 +432,11 @@ internal_check(void) { if (malloc_check_abort) abort(); if (malloc_check_sleep > 0) { - malloc_printf("*** Sleeping for %d seconds to leave time to attach\n", + _malloc_printf(ASL_LEVEL_NOTICE, "*** Sleeping for %d seconds to leave time to attach\n", malloc_check_sleep); sleep(malloc_check_sleep); } else if (malloc_check_sleep < 0) { - malloc_printf("*** Sleeping once for %d seconds to leave time to attach\n", + _malloc_printf(ASL_LEVEL_NOTICE, "*** Sleeping once for %d seconds to leave time to attach\n", -malloc_check_sleep); sleep(-malloc_check_sleep); malloc_check_sleep = 0; @@ -303,8 +451,11 @@ malloc_zone_malloc(malloc_zone_t *zone, size_t size) { if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } + if (size > MALLOC_ABSOLUTE_MAX_SIZE) { + return NULL; + } ptr = zone->malloc(zone, size); - if (malloc_logger) malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (unsigned)zone, size, 0, (unsigned)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; } @@ -314,8 +465,11 @@ malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) { if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } + if (size > MALLOC_ABSOLUTE_MAX_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, (unsigned)zone, num_items * size, 0, (unsigned)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; } @@ -325,8 +479,11 @@ malloc_zone_valloc(malloc_zone_t *zone, size_t size) { if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } + if (size > MALLOC_ABSOLUTE_MAX_SIZE) { + return NULL; + } ptr = zone->valloc(zone, size); - if (malloc_logger) malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (unsigned)zone, size, 0, (unsigned)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; } @@ -336,14 +493,17 @@ malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) { if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } + if (size > MALLOC_ABSOLUTE_MAX_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, (unsigned)zone, (unsigned)ptr, size, (unsigned)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, (unsigned)zone, (unsigned)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(); } @@ -353,32 +513,21 @@ malloc_zone_free(malloc_zone_t *zone, void *ptr) { malloc_zone_t * malloc_zone_from_ptr(const void *ptr) { malloc_zone_t *zone; - if (!ptr) return NULL; + if (!ptr) + return NULL; zone = find_registered_zone(ptr, NULL); + if (zone && zone->size(zone, ptr)) return zone; + return NULL; } /********* Functions for zone implementors ************/ void malloc_zone_register(malloc_zone_t *zone) { - /* Note that given the sequencing it is always safe to first get the number of zones, then get malloc_zones without taking the lock, if all you need is to iterate through the list */ MALLOC_LOCK(); - if (malloc_num_zones >= INITIAL_ZONES) { - malloc_zone_t **zones = malloc_zones; - malloc_zone_t *pzone = malloc_zones[0]; - boolean_t copy = malloc_num_zones == INITIAL_ZONES; - if (copy) zones = NULL; // to avoid realloc on something not allocated - MALLOC_UNLOCK(); - zones = pzone->realloc(pzone, zones, (malloc_num_zones + 1) * sizeof(malloc_zone_t *)); // we leak initial_malloc_zones, not worth tracking it - MALLOC_LOCK(); - if (copy) memcpy(zones, malloc_zones, malloc_num_zones * sizeof(malloc_zone_t *)); - malloc_zones = zones; - } - malloc_zones[malloc_num_zones] = zone; - malloc_num_zones++; // note that we do this after setting malloc_num_zones, so enumerations without taking the lock are safe + malloc_zone_register_while_locked(zone); MALLOC_UNLOCK(); - // malloc_printf("Registered %p malloc_zones at address %p is %p [%d zones]\n", zone, &malloc_zones, malloc_zones, malloc_num_zones); } void @@ -416,25 +565,58 @@ malloc_get_zone_name(malloc_zone_t *zone) { } /* - * XXX malloc_printf now uses _simple_{,v}dprintf. It only deals with a + * XXX malloc_printf now uses _simple_*printf. It only deals with a * subset of printf format specifiers, but it doesn't call malloc. */ -void _simple_dprintf(int, const char *, ...); -void _simple_vdprintf(int, const char *, va_list); + +__private_extern__ void +_malloc_vprintf(int flags, const char *format, va_list ap) +{ + _SIMPLE_STRING b; + + if (_malloc_no_asl_log || (flags & MALLOC_PRINTF_NOLOG) || (b = _simple_salloc()) == NULL) { + if (!(flags & MALLOC_PRINTF_NOPREFIX)) { + if (__is_threaded) { + /* XXX somewhat rude 'knowing' that pthread_t is a pointer */ + _simple_dprintf(malloc_debug_file, "%s(%d,%p) malloc: ", getprogname(), getpid(), (void *)pthread_self()); + } else { + _simple_dprintf(malloc_debug_file, "%s(%d) malloc: ", getprogname(), getpid()); + } + } + _simple_vdprintf(malloc_debug_file, format, ap); + return; + } + if (!(flags & MALLOC_PRINTF_NOPREFIX)) { + if (__is_threaded) { + /* XXX somewhat rude 'knowing' that pthread_t is a pointer */ + _simple_sprintf(b, "%s(%d,%p) malloc: ", getprogname(), getpid(), (void *)pthread_self()); + } else { + _simple_sprintf(b, "%s(%d) malloc: ", getprogname(), getpid()); + } + } + _simple_vsprintf(b, format, ap); + _simple_put(b, malloc_debug_file); + _simple_asl_log(flags & MALLOC_PRINTF_LEVEL_MASK, Malloc_Facility, _simple_string(b)); + _simple_sfree(b); +} + +__private_extern__ void +_malloc_printf(int flags, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + _malloc_vprintf(flags, format, ap); + va_end(ap); +} void malloc_printf(const char *format, ...) { va_list ap; - if (__is_threaded) { - /* XXX somewhat rude 'knowing' that pthread_t is a pointer */ - _simple_dprintf(malloc_debug_file, "%s(%d,%p) malloc: ", getprogname(), getpid(), (void *)pthread_self()); - } else { - _simple_dprintf(malloc_debug_file, "%s(%d) malloc: ", getprogname(), getpid()); - } va_start(ap, format); - _simple_vdprintf(malloc_debug_file, format, ap); + _malloc_vprintf(ASL_LEVEL_ERR, format, ap); va_end(ap); } @@ -465,32 +647,47 @@ free(void *ptr) { malloc_zone_t *zone; if (!ptr) return; zone = find_registered_zone(ptr, NULL); - if (zone) { + if (zone) malloc_zone_free(zone, ptr); - } else { - malloc_printf("*** Deallocation of a pointer not malloced: %p; " - "This could be a double free(), or free() called with the middle of an allocated block; " - "Try setting environment variable MallocHelp to see tools to help debug\n", ptr); - if (malloc_free_abort) - abort(); - } } void * -realloc(void *old_ptr, size_t new_size) { - void *retval; +realloc(void *in_ptr, size_t new_size) { + void *retval; + void *old_ptr; malloc_zone_t *zone; - size_t old_size = 0; + size_t old_size = 0; + + // SUSv3: "If size is 0 and ptr is not a null pointer, the object + // pointed to is freed. If the space cannot be allocated, the object + // shall remain unchanged." Also "If size is 0, either a null pointer + // or a unique pointer that can be successfully passed to free() shall + // be returned." We choose to allocate a minimum size object by calling + // malloc_zone_malloc with zero size, which matches "If ptr is a null + // pointer, realloc() shall be equivalent to malloc() for the specified + // size." So we only free the original memory if the allocation succeeds. + old_ptr = (new_size == 0) ? NULL : in_ptr; if (!old_ptr) { 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(); + if (zone && (old_size == 0)) + old_size = zone->size(zone, old_ptr); + if (zone && (old_size >= new_size)) + return old_ptr; + /* + * if old_size is still 0 here, it means that either zone was NULL or + * the call to zone->size() returned 0, indicating the pointer is not + * not in that zone. In this case, just use the default zone. + */ + if (old_size == 0) + zone = inline_malloc_default_zone(); retval = malloc_zone_realloc(zone, old_ptr, new_size); } if (retval == NULL) { errno = ENOMEM; + } else if (new_size == 0) { + free(in_ptr); } return retval; } @@ -515,7 +712,13 @@ size_t malloc_size(const void *ptr) { size_t size = 0; if (!ptr) return size; - (void)find_registered_zone(ptr, &size); + malloc_zone_t *zone = find_registered_zone(ptr, &size); + /* + * If we found a zone, and size is 0 then we need to check to see if that + * zone contains ptr. If size is nonzero, then we know zone contains ptr. + */ + if (zone && (size == 0)) + size = zone->size(zone, ptr); return size; } @@ -538,7 +741,7 @@ malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsig if (malloc_logger) { unsigned index = 0; while (index < batched) { - malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (unsigned)zone, size, 0, (unsigned)results[index], 0); + malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)results[index], 0); index++; } } @@ -553,7 +756,7 @@ malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num) { if (malloc_logger) { unsigned index = 0; while (index < num) { - malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (unsigned)zone, (unsigned)to_be_freed[index], 0, 0, 0); + malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)to_be_freed[index], 0, 0, 0); index++; } } @@ -621,7 +824,7 @@ void malloc_zone_print_ptr_info(void *ptr) { malloc_zone_t *zone; if (!ptr) return; - zone = find_registered_zone(ptr, NULL); + zone = malloc_zone_from_ptr(ptr); if (zone) { printf("ptr %p in registered zone %p\n", ptr, zone); } else { @@ -660,7 +863,7 @@ malloc_zone_print(malloc_zone_t *zone, boolean_t verbose) { void malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) { if (!zone) { - memset(stats, 0, sizeof(stats)); + memset(stats, 0, sizeof(*stats)); unsigned index = 0; while (index < malloc_num_zones) { zone = malloc_zones[index++]; diff --git a/ppc/sys/getegid.s b/gen/malloc_printf.h similarity index 71% rename from ppc/sys/getegid.s rename to gen/malloc_printf.h index bc1d151..5f10683 100644 --- a/ppc/sys/getegid.s +++ b/gen/malloc_printf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,11 +20,14 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ -#import +#import -#import "SYS.h" +extern void malloc_printf(const char *fmt, ...); -SYSCALL(getegid,0) +#define MALLOC_PRINTF_LEVEL_MASK 0x0f +#define MALLOC_PRINTF_NOLOG 0x10 +#define MALLOC_PRINTF_NOPREFIX 0x20 +extern void _malloc_printf(int flags, const char *fmt, ...); +extern void _malloc_vprintf(int flags, const char *fmt, va_list ap); diff --git a/gen/malloc_size.3 b/gen/malloc_size.3 new file mode 100644 index 0000000..378db96 --- /dev/null +++ b/gen/malloc_size.3 @@ -0,0 +1,55 @@ +.\" Copyright (c) 2006 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 May 23, 2006 +.Dt MALLOC_SIZE 3 +.Os +.Sh NAME +.Nm malloc_good_size , +.Nm malloc_size +.Nd memory allocation information +.Sh SYNOPSIS +.In malloc/malloc.h +.Ft size_t +.Fo malloc_good_size +.Fa "size_t size" +.Fc +.Ft size_t +.Fo malloc_size +.Fa "const void *ptr" +.Fc +.Sh DESCRIPTION +The +.Fn malloc_size +function returns the size of the memory block +that backs the allocation pointed to by +.Fa ptr . +The memory block size is always at least as large +as the allocation it backs, and may be larger. +.Pp +The +.Fn malloc_good_size +function rounds +.Fa size +up to a value that the allocator implementation can allocate +without adding any padding; +it then returns that rounded-up value. +.Sh SEE ALSO +.Xr malloc 3 diff --git a/gen/mrand48-fbsd.c b/gen/mrand48-fbsd.c new file mode 100644 index 0000000..5453ceb --- /dev/null +++ b/gen/mrand48-fbsd.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/mrand48.c,v 1.2 2002/03/22 21:52:05 obrien Exp $"); + +#include "rand48.h" + +long +mrand48(void) +{ + _DORAND48(_rand48_seed); + return (int)((_rand48_seed >> 16) & 0xffffffff); +} diff --git a/gen/nanosleep.c b/gen/nanosleep.c index 52547c5..ae732f8 100644 --- a/gen/nanosleep.c +++ b/gen/nanosleep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2003, 2006, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -28,12 +28,21 @@ #include -#ifdef BUILDING_VARIANT +#if __DARWIN_UNIX03 #include "pthread_internals.h" +#include extern int __unix_conforming; extern mach_port_t clock_port; extern semaphore_t clock_sem; +#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, time_t tv_sec, __int32_t tv_nsec); +#define SEMWAIT_SIGNAL __semwait_signal +#else /* !VARIANT_CANCELABLE */ +extern int __semwait_signal_nocancel(int cond_sem, int mutex_sem, int timeout, int relative, time_t tv_sec, __int32_t tv_nsec); +#define SEMWAIT_SIGNAL __semwait_signal_nocancel +#endif /* VARIANT_CANCELABLE */ int nanosleep(const struct timespec *requested_time, struct timespec *remaining_time) { @@ -44,20 +53,25 @@ nanosleep(const struct timespec *requested_time, struct timespec *remaining_time if (__unix_conforming == 0) __unix_conforming = 1; - + +#ifdef VARIANT_CANCELABLE + _pthread_testcancel(pthread_self(), 1); +#endif /* VARIANT_CANCELABLE */ + if ((requested_time == NULL) || (requested_time->tv_sec < 0) || (requested_time->tv_nsec >= NSEC_PER_SEC)) { errno = EINVAL; return -1; } + if (remaining_time != NULL) { kret = clock_get_time(clock_port, ¤t); if (kret != KERN_SUCCESS) { - fprintf(stderr, "clock_get_time() failed: %s\n", mach_error_string(ret)); + fprintf(stderr, "clock_get_time() failed: %s\n", mach_error_string(kret)); return -1; } } - ret = __semwait_signal(clock_sem, MACH_PORT_NULL, 1, 1, requested_time->tv_sec, requested_time->tv_nsec); + ret = SEMWAIT_SIGNAL(clock_sem, MACH_PORT_NULL, 1, 1, requested_time->tv_sec, requested_time->tv_nsec); if (ret < 0) { if (errno == ETIMEDOUT) { return 0; @@ -82,47 +96,173 @@ nanosleep(const struct timespec *requested_time, struct timespec *remaining_time } -#else /* BUILDING_VARIANT */ +#else /* !__DARWIN_UNIX03 */ + +typedef struct { + uint64_t high; + uint64_t low; +} uint128_t; + +/* 128-bit addition: acc += add */ +static inline void +add128_128(uint128_t *acc, uint128_t *add) +{ + acc->high += add->high; + acc->low += add->low; + if(acc->low < add->low) + acc->high++; // carry +} + +/* 128-bit subtraction: acc -= sub */ +static inline void +sub128_128(uint128_t *acc, uint128_t *sub) +{ + acc->high -= sub->high; + if(acc->low < sub->low) + acc->high--; // borrow + acc->low -= sub->low; +} + +#define TWO64 (((double)(1ULL << 32)) * ((double)(1ULL << 32))) + +static inline double +uint128_double(uint128_t *u) +{ + return TWO64 * u->high + u->low; // may loses precision +} + +/* 64x64 -> 128 bit multiplication */ +static inline void +mul64x64(uint64_t x, uint64_t y, uint128_t *prod) +{ + uint128_t add; + /* + * Split the two 64-bit multiplicands into 32-bit parts: + * x => 2^32 * x1 + x2 + * y => 2^32 * y1 + y2 + */ + uint32_t x1 = (uint32_t)(x >> 32); + uint32_t x2 = (uint32_t)x; + uint32_t y1 = (uint32_t)(y >> 32); + uint32_t y2 = (uint32_t)y; + /* + * direct multiplication: + * x * y => 2^64 * (x1 * y1) + 2^32 (x1 * y2 + x2 * y1) + (x2 * y2) + * The first and last terms are direct assignmenet into the uint128_t + * structure. Then we add the middle two terms separately, to avoid + * 64-bit overflow. (We could use the Karatsuba algorithm to save + * one multiply, but it is harder to deal with 64-bit overflows.) + */ + prod->high = (uint64_t)x1 * (uint64_t)y1; + prod->low = (uint64_t)x2 * (uint64_t)y2; + add.low = (uint64_t)x1 * (uint64_t)y2; + add.high = (add.low >> 32); + add.low <<= 32; + add128_128(prod, &add); + add.low = (uint64_t)x2 * (uint64_t)y1; + add.high = (add.low >> 32); + add.low <<= 32; + add128_128(prod, &add); +} + +/* calculate (x * y / divisor), using 128-bit internal calculations */ +static int +muldiv128(uint64_t x, uint64_t y, uint64_t divisor, uint64_t *res) +{ + uint128_t temp; + uint128_t divisor128 = {0, divisor}; + uint64_t result = 0; + double recip; + + /* calculate (x * y) */ + mul64x64(x, y, &temp); + /* + * Now divide by the divisor. We use floating point to calculate an + * approximate answer and update the results. Then we iterate and + * calculate a correction from the difference. + */ + recip = 1.0 / ((double)divisor); + while(temp.high || temp.low >= divisor) { + uint128_t backmul; + uint64_t uapprox; + double approx = uint128_double(&temp) * recip; + + if(approx > __LONG_LONG_MAX__) + return 0; // answer overflows 64-bits + uapprox = (uint64_t)approx; + mul64x64(uapprox, divisor, &backmul); + /* + * Because we are using unsigned integers, we need to approach the + * answer from the lesser side. So if our estimate is too large + * we need to decrease it until it is smaller. + */ + while(backmul.high > temp.high || backmul.high == temp.high && backmul.low > temp.low) { + sub128_128(&backmul, &divisor128); + uapprox--; + } + sub128_128(&temp, &backmul); + result += uapprox; + } + *res = result; + return 1; +} int nanosleep(const struct timespec *requested_time, struct timespec *remaining_time) { kern_return_t ret; - mach_timespec_t remain; - mach_timespec_t current; - uint64_t end; - static double ratio = 0.0, rratio; + uint64_t end, units; + static struct mach_timebase_info info = {0, 0}; + static int unity; if ((requested_time == NULL) || (requested_time->tv_sec < 0) || (requested_time->tv_nsec > NSEC_PER_SEC)) { errno = EINVAL; return -1; } - if (ratio == 0.0) { - struct mach_timebase_info info; + if (info.denom == 0) { ret = mach_timebase_info(&info); if (ret != KERN_SUCCESS) { fprintf(stderr, "mach_timebase_info() failed: %s\n", mach_error_string(ret)); errno = EAGAIN; return -1; } - ratio = (double)info.numer / ((double)info.denom * NSEC_PER_SEC); - rratio = (double)info.denom / (double)info.numer; + /* If numer == denom == 1 (as in intel), no conversion needed */ + unity = (info.numer == info.denom); } - /* use rratio to avoid division */ - end = mach_absolute_time() + (uint64_t)(((double)requested_time->tv_sec * NSEC_PER_SEC + (double)requested_time->tv_nsec) * rratio); + if(unity) + units = (uint64_t)requested_time->tv_sec * NSEC_PER_SEC; + else if(!muldiv128((uint64_t)info.denom * NSEC_PER_SEC, + (uint64_t)requested_time->tv_sec, + (uint64_t)info.numer, + &units)) + { + errno = EINVAL; + return -1; + } + end = mach_absolute_time() + + units + + (uint64_t)info.denom * requested_time->tv_nsec / info.numer; ret = mach_wait_until(end); if (ret != KERN_SUCCESS) { if (ret == KERN_ABORTED) { errno = EINTR; if (remaining_time != NULL) { uint64_t now = mach_absolute_time(); - double delta; - if (now > end) - now = end; - delta = (end - now) * ratio; - remaining_time->tv_sec = delta; - remaining_time->tv_nsec = NSEC_PER_SEC * (delta - remaining_time->tv_sec); + if (now >= end) { + remaining_time->tv_sec = 0; + remaining_time->tv_nsec = 0; + } else { + if(unity) + units = (end - now); + else + muldiv128((uint64_t)info.numer, + (end - now), + (uint64_t)info.denom, + &units); // this can't overflow + remaining_time->tv_sec = units / NSEC_PER_SEC; + remaining_time->tv_nsec = units % NSEC_PER_SEC; + } } } else { errno = EINVAL; @@ -133,4 +273,4 @@ nanosleep(const struct timespec *requested_time, struct timespec *remaining_time } -#endif /* BUILDING_VARIANT */ +#endif /* __DARWIN_UNIX03 */ diff --git a/gen/nftw.c b/gen/nftw.c index 7cb3746..fdcb821 100644 --- a/gen/nftw.c +++ b/gen/nftw.c @@ -175,9 +175,13 @@ both_ftw(const char *path, case FTS_DC: #if __DARWIN_UNIX03 /* Unix03 says nftw should break cycles and not return - errors in physical mode (which is definitly what it + errors in non-physical mode (which is definitly what it says ftw can't do) */ if (nfn && !(ftwflags & FTW_PHYS)) { + /* 4489297 - when FTW_DEPTH is set, skip + the link also */ + if (postorder) + continue; fnflag = FTW_D; break; } diff --git a/gen/nice-fbsd.c b/gen/nice-fbsd.c new file mode 100644 index 0000000..519ceb6 --- /dev/null +++ b/gen/nice-fbsd.c @@ -0,0 +1,69 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include +#include +#include +#include +#include +#if __DARWIN_UNIX03 +#include +#endif /* __DARWIN_UNIX03 */ +/* + * Backwards compatible nice. + */ +int +nice(incr) + int incr; +{ + int prio, rv; + + errno = 0; + prio = getpriority(PRIO_PROCESS, 0); + if (prio == -1 && errno) + return (-1); +#if __DARWIN_UNIX03 + if (prio + incr > NZERO-1) + incr = NZERO-1-prio; +#endif /* __DARWIN_UNIX03 */ + rv = setpriority(PRIO_PROCESS, 0, prio + incr); + if (rv == -1 && errno == EACCES) + errno = EPERM; + return (rv == -1) ? rv : getpriority(PRIO_PROCESS, 0); +} diff --git a/gen/nice.3 b/gen/nice.3 new file mode 120000 index 0000000..79148b9 --- /dev/null +++ b/gen/nice.3 @@ -0,0 +1 @@ +./nice.3 \ No newline at end of file diff --git a/gen/nlist.c b/gen/nlist.c index 0d2e0a4..96a1cac 100644 --- a/gen/nlist.c +++ b/gen/nlist.c @@ -21,7 +21,8 @@ * @APPLE_LICENSE_HEADER_END@ */ /* - * + * 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 diff --git a/gen/nrand48-fbsd.c b/gen/nrand48-fbsd.c new file mode 100644 index 0000000..1790b23 --- /dev/null +++ b/gen/nrand48-fbsd.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/nrand48.c,v 1.2 2002/03/22 21:52:05 obrien Exp $"); + +#include "rand48.h" + +long +nrand48(unsigned short xseed[3]) +{ + uint48 tmp; + DORAND48(tmp, xseed); + return (tmp >> 17) & 0x7fffffff; +} diff --git a/gen/opendir-fbsd.c b/gen/opendir-fbsd.c new file mode 100644 index 0000000..836600f --- /dev/null +++ b/gen/opendir-fbsd.c @@ -0,0 +1,284 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "telldir.h" +/* + * Open a directory. + */ +DIR * +opendir(name) + const char *name; +{ + + return (__opendir2(name, DTF_HIDEW|DTF_NODUP)); +} + +DIR * +__opendir2(name, flags) + const char *name; + int flags; +{ + DIR *dirp; + int fd; + int incr; + int saved_errno; + int unionstack; + + /* + * Use O_DIRECTORY to only open directories (because opening of + * special files may be harmful). errno is set to ENOTDIR if + * not a directory. + */ + if ((fd = _open(name, O_RDONLY | O_NONBLOCK | O_DIRECTORY)) == -1) + return (NULL); + dirp = NULL; + if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 || + (dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL) + goto fail; + + dirp->dd_td = (struct _telldir *)((char *)dirp + sizeof(DIR)); + LIST_INIT(&dirp->dd_td->td_locq); + dirp->dd_td->td_loccnt = 0; + + /* + * Use the system page size if that is a multiple of DIRBLKSIZ. + * Hopefully this can be a big win someday by allowing page + * trades to user space to be done by _getdirentries(). + */ + incr = getpagesize(); + if ((incr % DIRBLKSIZ) != 0) + incr = DIRBLKSIZ; + + /* + * Determine whether this directory is the top of a union stack. + */ + if (flags & DTF_NODUP) { + struct statfs sfb; + + if (_fstatfs(fd, &sfb) < 0) + goto fail; + unionstack = !strcmp(sfb.f_fstypename, "unionfs") + || (sfb.f_flags & MNT_UNION); + } else { + unionstack = 0; + } + + if (unionstack) { + int len = 0; + int space = 0; + char *buf = 0; + char *ddptr = 0; + char *ddeptr; + int n; + struct dirent **dpv; + + /* + * The strategy here is to read all the directory + * entries into a buffer, sort the buffer, and + * remove duplicate entries by setting the inode + * number to zero. + */ + + do { + /* + * Always make at least DIRBLKSIZ bytes + * available to _getdirentries + */ + if (space < DIRBLKSIZ) { + space += incr; + len += incr; + buf = reallocf(buf, len); + if (buf == NULL) + goto fail; + ddptr = buf + (len - space); + } + +#if __DARWIN_64_BIT_INO_T + n = __getdirentries64(fd, ddptr, space, &dirp->dd_td->seekoff); +#else /* !__DARWIN_64_BIT_INO_T */ + n = _getdirentries(fd, ddptr, space, &dirp->dd_seek); +#endif /* __DARWIN_64_BIT_INO_T */ + if (n > 0) { + ddptr += n; + space -= n; + } + } while (n > 0); + + ddeptr = ddptr; + flags |= __DTF_READALL; + + /* + * Re-open the directory. + * This has the effect of rewinding back to the + * top of the union stack and is needed by + * programs which plan to fchdir to a descriptor + * which has also been read -- see fts.c. + */ + if (flags & DTF_REWIND) { + (void)_close(fd); + if ((fd = _open(name, O_RDONLY)) == -1) { + saved_errno = errno; + free(buf); + free(dirp); + errno = saved_errno; + return (NULL); + } + } + + /* + * There is now a buffer full of (possibly) duplicate + * names. + */ + dirp->dd_buf = buf; + + /* + * Go round this loop twice... + * + * Scan through the buffer, counting entries. + * On the second pass, save pointers to each one. + * Then sort the pointers and remove duplicate names. + */ + for (dpv = 0;;) { + n = 0; + ddptr = buf; + while (ddptr < ddeptr) { + struct dirent *dp; + + dp = (struct dirent *) ddptr; + if ((long)dp & 03L) + break; + if ((dp->d_reclen <= 0) || + (dp->d_reclen > (ddeptr + 1 - ddptr))) + break; + ddptr += dp->d_reclen; + if (dp->d_fileno) { + if (dpv) + dpv[n] = dp; + n++; + } + } + + if (dpv) { + struct dirent *xp; + + /* + * This sort must be stable. + */ + mergesort(dpv, n, sizeof(*dpv), alphasort); + + dpv[n] = NULL; + xp = NULL; + + /* + * Scan through the buffer in sort order, + * zapping the inode number of any + * duplicate names. + */ + for (n = 0; dpv[n]; n++) { + struct dirent *dp = dpv[n]; + + if ((xp == NULL) || + strcmp(dp->d_name, xp->d_name)) { + xp = dp; + } else { + dp->d_fileno = 0; + } + if (dp->d_type == DT_WHT && + (flags & DTF_HIDEW)) + dp->d_fileno = 0; + } + + free(dpv); + break; + } else { + dpv = malloc((n+1) * sizeof(struct dirent *)); + if (dpv == NULL) + break; + } + } + + dirp->dd_len = len; + dirp->dd_size = ddptr - dirp->dd_buf; + } else { + dirp->dd_len = incr; + dirp->dd_size = 0; + dirp->dd_buf = malloc(dirp->dd_len); + if (dirp->dd_buf == NULL) + goto fail; +#if __DARWIN_64_BIT_INO_T + dirp->dd_td->seekoff = 0; +#else /* !__DARWIN_64_BIT_INO_T */ + dirp->dd_seek = 0; +#endif /* __DARWIN_64_BIT_INO_T */ + flags &= ~DTF_REWIND; + } + + dirp->dd_loc = 0; + dirp->dd_fd = fd; + dirp->dd_flags = flags; + dirp->dd_lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + + /* + * Set up seek point for rewinddir. + */ + dirp->dd_rewind = telldir(dirp); + + return (dirp); + +fail: + saved_errno = errno; + free(dirp); + (void)_close(fd); + errno = saved_errno; + return (NULL); +} diff --git a/gen/pause-fbsd.c b/gen/pause-fbsd.c new file mode 100644 index 0000000..819dcaa --- /dev/null +++ b/gen/pause-fbsd.c @@ -0,0 +1,62 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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 */ + +/* For the cancelable variant, we call the cancelable sigsuspend */ +#ifdef VARIANT_CANCELABLE +#undef __DARWIN_NON_CANCELABLE +#define __DARWIN_NON_CANCELABLE 0 +#endif /* VARIANT_CANCELABLE */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); + +#include +#include + +/* + * Backwards compatible pause. + */ +int +__pause() +{ + sigset_t set; + + sigprocmask(0, NULL, &set); + return sigsuspend(&set); +} +__weak_reference(__pause, pause); +__weak_reference(__pause, _pause); diff --git a/gen/pause.3 b/gen/pause.3 new file mode 120000 index 0000000..bf777f1 --- /dev/null +++ b/gen/pause.3 @@ -0,0 +1 @@ +./pause.3 \ No newline at end of file diff --git a/gen/popen-fbsd.c b/gen/popen-fbsd.c new file mode 100644 index 0000000..14a5c4a --- /dev/null +++ b/gen/popen-fbsd.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software written by Ken Arnold and + * published in UNIX Review, Vol. 6, No. 8. + * + * 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include /* fwide() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" + +#include +#define environ (*_NSGetEnviron()) + +/* 3516149 - store file descriptor and use that to close to prevent blocking */ +static struct pid { + struct pid *next; + FILE *fp; + int fd; + pid_t pid; +} *pidlist; +static pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER; + +#define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&pidlist_mutex) +#define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&pidlist_mutex) + +FILE * +popen(command, type) + const char *command, *type; +{ + struct pid *cur; + FILE *iop; + int pdes[2], pid, twoway; + char *argv[4]; + struct pid *p; + + if (type == NULL) { + errno = EINVAL; + return (NULL); + } + if (strcmp(type, "r+") == 0) { + twoway = 1; + type = "r+"; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pdes) < 0) + return (NULL); + } else { + twoway = 0; + if ((*type != 'r' && *type != 'w') || type[1]) { + errno = EINVAL; + return (NULL); + } + if (pipe(pdes) < 0) + return (NULL); + } + + if ((cur = malloc(sizeof(struct pid))) == NULL) { + (void)_close(pdes[0]); + (void)_close(pdes[1]); + return (NULL); + } + + argv[0] = "sh"; + argv[1] = "-c"; + argv[2] = (char *)command; + argv[3] = NULL; + + THREAD_LOCK(); + switch (pid = fork()) { + case -1: /* Error. */ + THREAD_UNLOCK(); + (void)_close(pdes[0]); + (void)_close(pdes[1]); + free(cur); + return (NULL); + /* NOTREACHED */ + case 0: /* Child. */ + if (*type == 'r') { + /* + * The _dup2() to STDIN_FILENO is repeated to avoid + * writing to pdes[1], which might corrupt the + * parent's copy. This isn't good enough in + * general, since the _exit() is no return, so + * the compiler is free to corrupt all the local + * variables. + */ + (void)_close(pdes[0]); + if (pdes[1] != STDOUT_FILENO) { + (void)_dup2(pdes[1], STDOUT_FILENO); + (void)_close(pdes[1]); + if (twoway) + (void)_dup2(STDOUT_FILENO, STDIN_FILENO); + } else if (twoway && (pdes[1] != STDIN_FILENO)) + (void)_dup2(pdes[1], STDIN_FILENO); + } else { + if (pdes[0] != STDIN_FILENO) { + (void)_dup2(pdes[0], STDIN_FILENO); + (void)_close(pdes[0]); + } + (void)_close(pdes[1]); + } + for (p = pidlist; p; p = p->next) { + (void)_close(p->fd); + } + _execve(_PATH_BSHELL, argv, environ); + _exit(127); + /* NOTREACHED */ + } + THREAD_UNLOCK(); + + /* Parent; assume fdopen can't fail. */ + if (*type == 'r') { + iop = fdopen(pdes[0], type); + cur->fd = pdes[0]; + (void)_close(pdes[1]); + } else { + iop = fdopen(pdes[1], type); + cur->fd = pdes[1]; + (void)_close(pdes[0]); + } + + /* Link into list of file descriptors. */ + cur->fp = iop; + cur->pid = pid; + THREAD_LOCK(); + cur->next = pidlist; + pidlist = cur; + THREAD_UNLOCK(); + fwide(iop, -1); /* byte stream */ + return (iop); +} + +/* + * pclose -- + * Pclose returns -1 if stream is not associated with a `popened' command, + * if already `pclosed', or waitpid returns an error. + */ +int +pclose(iop) + FILE *iop; +{ + struct pid *cur, *last; + int pstat; + pid_t pid; + + /* + * Find the appropriate file pointer and remove it from the list. + */ + THREAD_LOCK(); + for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next) + if (cur->fp == iop) + break; + if (cur == NULL) { + THREAD_UNLOCK(); + return (-1); + } + if (last == NULL) + pidlist = cur->next; + else + last->next = cur->next; + THREAD_UNLOCK(); + + (void)fclose(iop); + + do { + pid = _wait4(cur->pid, &pstat, 0, (struct rusage *)0); + } while (pid == -1 && errno == EINTR); + + free(cur); + + return (pid == -1 ? -1 : pstat); +} diff --git a/gen/popen.3 b/gen/popen.3 new file mode 100644 index 0000000..5f4a8c6 --- /dev/null +++ b/gen/popen.3 @@ -0,0 +1,205 @@ +.\" 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. +.\" +.\" @(#)popen.3 8.2 (Berkeley) 5/3/95 +.\" $FreeBSD: src/lib/libc/gen/popen.3,v 1.16 2003/06/08 10:01:51 charnier Exp $ +.\" +.Dd May 3, 1995 +.Dt POPEN 3 +.Os +.Sh NAME +.Nm pclose , +.Nm popen +.Nd process +.Tn I/O +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft FILE * +.Fo popen +.Fa "const char *command" +.Fa "const char *mode" +.Fc +.Ft int +.Fo pclose +.Fa "FILE *stream" +.Fc +.Sh DESCRIPTION +The +.Fn popen +function +.Dq opens +a process by creating a bidirectional pipe, forking, +and invoking the shell. +Any streams opened by previous +.Fn popen +calls in the parent process are closed in the new child process. +Historically, +.Fn popen +was implemented with a unidirectional pipe; +hence, many implementations of +.Fn popen +only allow the +.Fa mode +argument to specify reading or writing, not both. +Because +.Fn popen +is now implemented using a bidirectional pipe, the +.Fa mode +argument may request a bidirectional data flow. +The +.Fa mode +argument is a pointer to a null-terminated string +which must be +.Ql r +for reading, +.Ql w +for writing, or +.Ql r+ +for reading and writing. +.Pp +The +.Fa command +argument is a pointer to a null-terminated string +containing a shell command line. +This command is passed to +.Pa /bin/sh , +using the +.Fl c +flag; interpretation, if any, is performed by the shell. +.Pp +The return value from +.Fn popen +is a normal standard +.Tn I/O +stream in all respects, +save that it must be closed with +.Fn pclose +rather than +.Fn fclose . +Writing to such a stream +writes to the standard input of the command; +the command's standard output is the same as that of the process that called +.Fn popen , +unless this is altered by the command itself. +Conversely, reading from a +.Dq popened +stream reads the command's standard output, and +the command's standard input is the same as that of the process that called +.Fn popen . +.Pp +Note that output +.Fn popen +streams are fully buffered, by default. +.Pp +The +.Fn pclose +function waits for the associated process to terminate; +it returns the exit status of the command, +as returned by +.Xr wait4 2 . +.Sh RETURN VALUES +The +.Fn popen +function returns +.Dv NULL +if the +.Xr fork 2 +or +.Xr pipe 2 +calls fail, +or if it cannot allocate memory. +.Pp +The +.Fn pclose +function +returns \-1 if +.Fa stream +is not associated with a +.Dq popened +command, if +.Fa stream +already +.Dq pclosed , +or if +.Xr wait4 2 +returns an error. +.Sh ERRORS +The +.Fn popen +function does not reliably set +.Va errno . +.Sh SEE ALSO +.Xr sh 1 , +.Xr fork 2 , +.Xr pipe 2 , +.Xr wait4 2 , +.Xr fclose 3 , +.Xr fflush 3 , +.Xr fopen 3 , +.Xr stdio 3 , +.Xr system 3 +.Sh BUGS +Since the standard input of a command opened for reading +shares its seek offset with the process that called +.Fn popen , +if the original process has done a buffered read, +the command's input position may not be as expected. +Similarly, the output from a command opened for writing +may become intermingled with that of the original process. +The latter can be avoided by calling +.Xr fflush 3 +before +.Fn popen . +.Pp +Failure to execute the shell +is indistinguishable from the shell's failure to execute command, +or an immediate exit of the command. +The only hint is an exit status of 127. +.Pp +The +.Fn popen +function +always calls +.Xr sh 1 , +never calls +.Xr csh 1 . +.Sh HISTORY +A +.Fn popen +and a +.Fn pclose +function appeared in +.At v7 . +.Pp +Bidirectional functionality was added in +.Fx 2.2.6 . diff --git a/gen/pselect-fbsd.c b/gen/pselect-fbsd.c new file mode 100644 index 0000000..4bc62fc --- /dev/null +++ b/gen/pselect-fbsd.c @@ -0,0 +1,88 @@ +/* + * Copyright 2000 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. 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(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050) +#undef __DARWIN_NON_CANCELABLE +#endif /* VARIANT_CANCELABLE */ + +#ifdef VARIANT_DARWINEXTSN +#define _DARWIN_UNLIMITED_SELECT +#endif /* VARIANT_DARWINEXTSN */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/pselect.c,v 1.6 2002/10/12 16:13:37 mike Exp $"); + +#include "namespace.h" +#include +#include +#include +#include + +#include +#include +#include "un-namespace.h" + +__weak_reference(__pselect, pselect); + +/* + * Emulate the POSIX 1003.1g-2000 `pselect' interface. This is the + * same as the traditional BSD `select' function, except that it uses + * a timespec rather than a timeval, doesn't modify the timeout argument, + * and allows the user to specify a signal mask to apply during the select. + */ +int +__pselect(int count, fd_set * __restrict rfds, fd_set * __restrict wfds, + fd_set * __restrict efds, const struct timespec * __restrict timo, + const sigset_t * __restrict mask) +{ + sigset_t omask; + struct timeval tvtimo, *tvp; + int rv, sverrno; + + if (timo) { + TIMESPEC_TO_TIMEVAL(&tvtimo, timo); + tvp = &tvtimo; + } else + tvp = 0; + + if (mask != 0) { + rv = _sigprocmask(SIG_SETMASK, mask, &omask); + if (rv != 0) + return rv; + } + + rv = _select(count, rfds, wfds, efds, tvp); + if (mask != 0) { + sverrno = errno; + _sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0); + errno = sverrno; + } + + return rv; +} diff --git a/gen/pselect.3 b/gen/pselect.3 new file mode 100644 index 0000000..615a399 --- /dev/null +++ b/gen/pselect.3 @@ -0,0 +1,127 @@ +.\" +.\" Copyright 2002 Massachusetts Institute of Technology +.\" +.\" Permission to use, copy, modify, and distribute this software and +.\" its documentation for any purpose and without fee is hereby +.\" granted, provided that both the above copyright notice and this +.\" permission notice appear in all copies, that both the above +.\" copyright notice and this permission notice appear in all +.\" supporting documentation, and that the name of M.I.T. not be used +.\" in advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. M.I.T. makes +.\" no representations about the suitability of this software for any +.\" purpose. It is provided "as is" without express or implied +.\" warranty. +.\" +.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS +.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, +.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT +.\" SHALL M.I.T. 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/gen/pselect.3,v 1.4 2002/12/18 10:13:54 ru Exp $ +.\" +.Dd June 16, 2002 +.Dt PSELECT 3 +.Os +.Sh NAME +.Nm pselect +.Nd synchronous I/O multiplexing a la POSIX.1g +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fo pselect +.Fa "int nfds" +.Fa "fd_set *restrict readfds" +.Fa "fd_set *restrict writefds" +.Fa "fd_set *restrict errorfds" +.Fa "const struct timespec *restrict timeout" +.Fa "const sigset_t *restrict sigmask" +.Fc +.Sh DESCRIPTION +The +.Fn pselect +function was introduced by +.St -p1003.1g-2000 +as a slightly stronger version of +.Xr select 2 . +The +.Fa nfds , readfds , writefds , +and +.Fa errorfds +arguments are all identical to the analogous arguments of +.Fn select . +The +.Fa timeout +argument in +.Fn pselect +points to a +.Vt "const struct timespec" , +rather than the (modifiable) +.Vt "struct timeval" +used by +.Fn select ; +as in +.Fn select , +a null pointer may be passed to indicate that +.Fn pselect +should wait indefinitely. +Finally, +.Fa sigmask +specifies a signal mask which is set while waiting for input. +When +.Fn pselect +returns, the original signal mask is restored. +.Pp +See +.Xr select 2 +for a more detailed discussion of the semantics of this interface, and +for macros used to manipulate the +.Vt "fd_set" +data type. +.Sh IMPLEMENTATION NOTES +The +.Fn pselect +function is implemented in the C library as a wrapper around +.Fn select . +.Sh RETURN VALUES +The +.Fn pselect +function returns the same values and under the same conditions as +.Fn select . +.Sh ERRORS +The +.Fn pselect +function may fail for any of the reasons documented for +.Xr select 2 +and (if a signal mask is provided) +.Xr sigprocmask 2 . +.Sh SEE ALSO +.Xr kqueue 2 , +.Xr poll 2 , +.Xr select 2 , +.Xr sigprocmask 2 +.Sh STANDARDS +The +.Fn pselect +function conforms to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn pselect +function first appeared in +.Fx 5.0 . +.Sh AUTHORS +The +.Fn pselect +function and this manual page were written by +.An Garrett Wollman Aq wollman@FreeBSD.org . diff --git a/gen/psignal-fbsd.c b/gen/psignal-fbsd.c new file mode 100644 index 0000000..832e04b --- /dev/null +++ b/gen/psignal-fbsd.c @@ -0,0 +1,67 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +/* + * Print the name of the signal indicated + * along with the supplied message. + */ +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" + +void +psignal(sig, s) + unsigned int sig; + const char *s; +{ + const char *c; + + if (sig < NSIG) + c = sys_siglist[sig]; + else + c = "Unknown signal"; + if (s != NULL && *s != '\0') { + (void)_write(STDERR_FILENO, s, strlen(s)); + (void)_write(STDERR_FILENO, ": ", 2); + } + (void)_write(STDERR_FILENO, c, strlen(c)); + (void)_write(STDERR_FILENO, "\n", 1); +} diff --git a/gen/psignal.3 b/gen/psignal.3 new file mode 120000 index 0000000..7550220 --- /dev/null +++ b/gen/psignal.3 @@ -0,0 +1 @@ +./psignal.3 \ No newline at end of file diff --git a/string/FreeBSD/ffs.c b/gen/raise-fbsd.c similarity index 85% rename from string/FreeBSD/ffs.c rename to gen/raise-fbsd.c index ef4d0f0..4a94cb9 100644 --- a/string/FreeBSD/ffs.c +++ b/gen/raise-fbsd.c @@ -32,24 +32,20 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ffs.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)raise.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/ffs.c,v 1.7 2004/01/14 07:46:36 des Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/raise.c,v 1.4 2003/07/19 05:22:56 davidxu Exp $"); -#include +#include +#include + +__weak_reference(__raise, raise); +__weak_reference(__raise, _raise); -/* - * Find First Set bit - */ int -ffs(int mask) +__raise(s) + int s; { - int bit; - - if (mask == 0) - return(0); - for (bit = 1; !(mask & 1); bit++) - mask = (unsigned int)mask >> 1; - return (bit); + return(kill(getpid(), s)); } diff --git a/gen/raise.3 b/gen/raise.3 new file mode 120000 index 0000000..87dfefd --- /dev/null +++ b/gen/raise.3 @@ -0,0 +1 @@ +./raise.3 \ No newline at end of file diff --git a/gen/rand48.3 b/gen/rand48.3 new file mode 100644 index 0000000..223b2a9 --- /dev/null +++ b/gen/rand48.3 @@ -0,0 +1,201 @@ +.\" Copyright (c) 1993 Martin Birgmeier +.\" All rights reserved. +.\" +.\" You may redistribute unmodified or modified versions of this source +.\" code provided that the above copyright notice and this and the +.\" following conditions are retained. +.\" +.\" This software is provided ``as is'', and comes with no warranties +.\" of any kind. I shall in no event be liable for anything that happens +.\" 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 $ +.\" +.Dd October 8, 1993 +.Dt RAND48 3 +.Os +.Sh NAME +.Nm drand48 , +.Nm erand48 , +.Nm jrand48 , +.Nm lcong48 , +.Nm lrand48 , +.Nm mrand48 , +.Nm nrand48 , +.Nm seed48 , +.Nm srand48 +.Nd pseudo random number generators and initialization routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft double +.Fo drand48 +.Fa void +.Fc +.Ft double +.Fo erand48 +.Fa "unsigned short xsubi[3]" +.Fc +.Ft long +.Fo jrand48 +.Fa "unsigned short xsubi[3]" +.Fc +.Ft void +.Fo lcong48 +.Fa "unsigned short param[7]" +.Fc +.Ft long +.Fo lrand48 +.Fa void +.Fc +.Ft long +.Fo mrand48 +.Fa void +.Fc +.Ft long +.Fo nrand48 +.Fa "unsigned short xsubi[3]" +.Fc +.Ft "unsigned short *" +.Fo seed48 +.Fa "unsigned short seed16v[3]" +.Fc +.Ft void +.Fo srand48 +.Fa "long seedval" +.Fc +.Sh DESCRIPTION +The +.Fn rand48 +family of functions generates pseudo-random numbers, using a linear +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 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. +.Pp +For the six generator routines described next, the first +computational step is to perform a single iteration of the algorithm. +.Pp +The +.Fn drand48 +and +.Fn erand48 +functions +return values of type double. +The full 48 bits of r(n+1) are +loaded into the mantissa of the returned value, with the exponent set +such that the values produced lie in the interval [0.0, 1.0). +.Pp +The +.Fn lrand48 +and +.Fn nrand48 +functions +return values of type long in the range +[0, 2**31-1]. +The high-order (31) bits of +r(n+1) are loaded into the lower bits of the returned value, with +the topmost (sign) bit set to zero. +.Pp +The +.Fn mrand48 +and +.Fn jrand48 +functions +return values of type long in the range +[-2**31, 2**31-1]. +The high-order (32) bits of +r(n+1) are loaded into the returned value. +.Pp +The +.Fn drand48 , +.Fn lrand48 , +and +.Fn mrand48 +functions +use an internal buffer to store r(n). +For these functions +the initial value of r(0) = 0x1234abcd330e = 20017429951246. +.Pp +On the other hand, +.Fn erand48 , +.Fn nrand48 , +and +.Fn jrand48 +use a user-supplied buffer to store the seed r(n), +which consists of an array of 3 shorts, where the zeroth member +holds the least significant bits. +.Pp +All functions share the same multiplicand and addend. +.Pp +The +.Fn srand48 +function +is used to initialize the internal buffer r(n) of +.Fn drand48 , +.Fn lrand48 , +and +.Fn mrand48 , +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 +reset to the default values given above. +.Pp +The +.Fn seed48 +function +also initializes the internal buffer r(n) of +.Fn drand48 , +.Fn lrand48 , +and +.Fn mrand48 , +but here all 48 bits of the seed can be specified in an array of 3 shorts, +where the zeroth member specifies the lowest bits. +Again, +the constant multiplicand and addend of the algorithm are +reset to the default values given above. +The +.Fn seed48 +function +returns a pointer to an array of 3 shorts which contains the old seed. +This array is statically allocated; thus, its contents are lost after +each new call to +.Fn seed48 . +.Pp +Finally, +.Fn lcong48 +allows full control over the multiplicand and addend used in +.Fn drand48 , +.Fn erand48 , +.Fn lrand48 , +.Fn nrand48 , +.Fn mrand48 , +and +.Fn jrand48 , +and the seed used in +.Fn drand48 , +.Fn lrand48 , +and +.Fn mrand48 . +An array of 7 shorts is passed as argument; the first three shorts are +used to initialize the seed; the second three are used to initialize the +multiplicand; and the last short is used to initialize the addend. +It is thus not possible to use values greater than 0xffff as the addend. +.Pp +Note that all three methods of seeding the random number generator +always also set the multiplicand and addend for any of the six +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 diff --git a/gen/rand48.h b/gen/rand48.h new file mode 100644 index 0000000..e799eba --- /dev/null +++ b/gen/rand48.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + * + * $FreeBSD: src/lib/libc/gen/rand48.h,v 1.2 2002/02/01 01:32:19 obrien Exp $ + */ + +#ifndef _RAND48_H_ +#define _RAND48_H_ + +#include +#include + +#define RAND48_SEED_0 (0x330e) +#define RAND48_SEED_1 (0xabcd) +#define RAND48_SEED_2 (0x1234) +#define RAND48_MULT_0 (0xe66d) +#define RAND48_MULT_1 (0xdeec) +#define RAND48_MULT_2 (0x0005) +#define RAND48_ADD (0x000b) + +typedef unsigned long long uint48; + +extern uint48 _rand48_seed; +extern uint48 _rand48_mult; +extern uint48 _rand48_add; + +#define TOUINT48(x,y,z) \ + ((uint48)(x) + (((uint48)(y)) << 16) + (((uint48)(z)) << 32)) + +#define RAND48_SEED TOUINT48(RAND48_SEED_0, RAND48_SEED_1, RAND48_SEED_2) +#define RAND48_MULT TOUINT48(RAND48_MULT_0, RAND48_MULT_1, RAND48_MULT_2) + +#define LOADRAND48(l,x) \ + (l) = TOUINT48((x)[0], (x)[1], (x)[2]) + +#define STORERAND48(l,x) \ + (x)[0] = (unsigned short)(l); \ + (x)[1] = (unsigned short)((l) >> 16); \ + (x)[2] = (unsigned short)((l) >> 32) + +#define _DORAND48(l) \ + (l) = (l) * _rand48_mult + _rand48_add + +#define DORAND48(l,x) \ + LOADRAND48(l, x); \ + _DORAND48(l); \ + STORERAND48(l, x) + +#include "fpmath.h" + +/* + * Optimization for speed: avoid int-to-double conversion. Assume doubles + * are IEEE-754 and insert the bits directly. To normalize, the (1 << 52) + * is the hidden bit, which the first set bit is shifted to. + */ +#define ERAND48_BEGIN \ + union { \ + union IEEEd2bits ieee; \ + unsigned long long l; \ + } u; \ + int s + +#define ERAND48_END(x) \ + u.l = ((x) & 0xffffffffffffULL); \ + if (u.l == 0) \ + return 0.0; \ + u.l <<= 5; \ + for(s = 0; !(u.l & (1LL << 52)); s++, u.l <<= 1) {} \ + u.ieee.bits.exp = 1022 - s; \ + return u.ieee.d + +#endif /* _RAND48_H_ */ diff --git a/gen/readdir-fbsd.c b/gen/readdir-fbsd.c new file mode 100644 index 0000000..6cf30d6 --- /dev/null +++ b/gen/readdir-fbsd.c @@ -0,0 +1,141 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "telldir.h" +#include "libc_private.h" + +/* + * get next entry in a directory. + */ +struct dirent * +_readdir_unlocked(dirp) + DIR *dirp; +{ + struct dirent *dp; + + for (;;) { + if (dirp->dd_loc >= dirp->dd_size) { + if (dirp->dd_flags & __DTF_READALL) + return (NULL); + dirp->dd_loc = 0; + } + if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) { +#if __DARWIN_64_BIT_INO_T + dirp->dd_size = __getdirentries64(dirp->dd_fd, + dirp->dd_buf, dirp->dd_len, &dirp->dd_td->seekoff); +#else /* !__DARWIN_64_BIT_INO_T */ + dirp->dd_size = _getdirentries(dirp->dd_fd, + dirp->dd_buf, dirp->dd_len, &dirp->dd_seek); +#endif /* __DARWIN_64_BIT_INO_T */ + if (dirp->dd_size <= 0) + return (NULL); + } + dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc); + if ((long)dp & 03L) /* bogus pointer check */ + return (NULL); + if (dp->d_reclen <= 0 || + dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) + return (NULL); + dirp->dd_loc += dp->d_reclen; + if (dp->d_ino == 0) + continue; + if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) + continue; + return (dp); + } +} + +struct dirent * +readdir(dirp) + DIR *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); + } + else + dp = _readdir_unlocked(dirp); + return (dp); +} + +int +readdir_r(dirp, entry, result) + DIR *dirp; + struct dirent *entry; + struct dirent **result; +{ + struct dirent *dp; + int saved_errno; + + saved_errno = errno; + errno = 0; + if (__isthreaded) { + _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + if ((dp = _readdir_unlocked(dirp)) != NULL) + memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); + _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + } + else if ((dp = _readdir_unlocked(dirp)) != NULL) + memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); + + if (errno != 0) { + if (dp == NULL) + return (errno); + } else + errno = saved_errno; + + if (dp != NULL) + *result = entry; + else + *result = NULL; + + return (0); +} diff --git a/gen/readpassphrase-fbsd.c b/gen/readpassphrase-fbsd.c new file mode 100644 index 0000000..45ac15f --- /dev/null +++ b/gen/readpassphrase-fbsd.c @@ -0,0 +1,181 @@ +/* $OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $ */ + +/* + * Copyright (c) 2000 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. + * + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/readpassphrase.c,v 1.6 2002/03/09 03:16:41 green Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +static volatile sig_atomic_t signo; + +static void handler(int); + +char * +readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) +{ + ssize_t nr; + int input, output, save_errno; + char ch, *p, *end; + struct termios term, oterm; + struct sigaction sa, saveint, savehup, savequit, saveterm; + struct sigaction savetstp, savettin, savettou; + locale_t loc = __current_locale(); + + /* I suppose we could alloc on demand in this case (XXX). */ + if (bufsiz == 0) { + errno = EINVAL; + return(NULL); + } + +restart: + /* + * Read and write to /dev/tty if available. If not, read from + * stdin and write to stderr unless a tty is required. + */ + if ((input = output = _open(_PATH_TTY, O_RDWR)) == -1) { + if (flags & RPP_REQUIRE_TTY) { + errno = ENOTTY; + return(NULL); + } + input = STDIN_FILENO; + output = STDERR_FILENO; + } + + /* + * Catch signals that would otherwise cause the user to end + * up with echo turned off in the shell. Don't worry about + * things like SIGALRM and SIGPIPE for now. + */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; /* don't restart system calls */ + sa.sa_handler = handler; + (void)_sigaction(SIGINT, &sa, &saveint); + (void)_sigaction(SIGHUP, &sa, &savehup); + (void)_sigaction(SIGQUIT, &sa, &savequit); + (void)_sigaction(SIGTERM, &sa, &saveterm); + (void)_sigaction(SIGTSTP, &sa, &savetstp); + (void)_sigaction(SIGTTIN, &sa, &savettin); + (void)_sigaction(SIGTTOU, &sa, &savettou); + + /* Turn off echo if possible. */ + if (tcgetattr(input, &oterm) == 0) { + memcpy(&term, &oterm, sizeof(term)); + if (!(flags & RPP_ECHO_ON)) + term.c_lflag &= ~(ECHO | ECHONL); + if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) + term.c_cc[VSTATUS] = _POSIX_VDISABLE; + (void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); + } else { + memset(&term, 0, sizeof(term)); + memset(&oterm, 0, sizeof(oterm)); + } + + (void)_write(output, prompt, strlen(prompt)); + end = buf + bufsiz - 1; + for (p = buf; (nr = _read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { + if (p < end) { + if ((flags & RPP_SEVENBIT)) + ch &= 0x7f; + if (isalpha_l(ch, loc)) { + if ((flags & RPP_FORCELOWER)) + ch = tolower_l(ch, loc); + if ((flags & RPP_FORCEUPPER)) + ch = toupper_l(ch, loc); + } + *p++ = ch; + } + } + *p = '\0'; + save_errno = errno; + if (!(term.c_lflag & ECHO)) + (void)_write(output, "\n", 1); + + /* Restore old terminal settings and signals. */ + if (memcmp(&term, &oterm, sizeof(term)) != 0) + (void)tcsetattr(input, TCSANOW|TCSASOFT, &oterm); + (void)_sigaction(SIGINT, &saveint, NULL); + (void)_sigaction(SIGHUP, &savehup, NULL); + (void)_sigaction(SIGQUIT, &savequit, NULL); + (void)_sigaction(SIGTERM, &saveterm, NULL); + (void)_sigaction(SIGTSTP, &savetstp, NULL); + (void)_sigaction(SIGTTIN, &savettin, NULL); + (void)_sigaction(SIGTTOU, &savettou, NULL); + if (input != STDIN_FILENO) + (void)_close(input); + + /* + * If we were interrupted by a signal, resend it to ourselves + * now that we have restored the signal handlers. + */ + if (signo) { + kill(getpid(), signo); + switch (signo) { + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: + signo = 0; + goto restart; + } + } + + errno = save_errno; + return(nr == -1 ? NULL : buf); +} + +char * +getpass(const char *prompt) +{ + static char buf[_PASSWORD_LEN + 1]; + + if (readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF) == NULL) + buf[0] = '\0'; + return(buf); +} + +static void handler(int s) +{ + + signo = s; +} diff --git a/gen/readpassphrase.3 b/gen/readpassphrase.3 new file mode 120000 index 0000000..ce01f5d --- /dev/null +++ b/gen/readpassphrase.3 @@ -0,0 +1 @@ +./readpassphrase.3 \ No newline at end of file diff --git a/gen/rewinddir-fbsd.c b/gen/rewinddir-fbsd.c new file mode 100644 index 0000000..dae75cc --- /dev/null +++ b/gen/rewinddir-fbsd.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include +#include + +#include "telldir.h" + +void +rewinddir(dirp) + DIR *dirp; +{ + + _seekdir(dirp, dirp->dd_rewind); + dirp->dd_rewind = telldir(dirp); +} diff --git a/gen/scalable_malloc.c b/gen/scalable_malloc.c index 386aab4..6ac0ae6 100644 --- a/gen/scalable_malloc.c +++ b/gen/scalable_malloc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -24,6 +24,8 @@ /* Author: Bertrand Serlet, August 1999 */ #include "scalable_malloc.h" +#include "malloc_printf.h" +#include "_simple.h" #include @@ -31,6 +33,8 @@ #include #include #include +#include +#include /********************* DEFINITIONS ************************/ @@ -65,13 +69,14 @@ do { \ typedef unsigned short msize_t; // a size in multiples of SHIFT_SMALL_QUANTUM or SHIFT_TINY_QUANTUM -/* - * Note that in the LP64 case, this is 24 bytes, necessitating the 32-byte tiny grain size. - */ +typedef union { + void *p; + uintptr_t u; +} ptr_union; + typedef struct { - uintptr_t checksum; - void *previous; - void *next; + ptr_union previous; + ptr_union next; } free_list_t; typedef struct { @@ -86,12 +91,6 @@ typedef unsigned char grain_t; #define CHECK_REGIONS (1 << 31) -#ifdef __LP64__ -# define CHECKSUM_MAGIC 0xdeadbeef0badc0de -#else -# define CHECKSUM_MAGIC 0x357B -#endif - #define MAX_RECORDER_BUFFER 256 /********************* DEFINITIONS for tiny ************************/ @@ -100,17 +99,21 @@ typedef unsigned char grain_t; * Memory in the Tiny range is allocated from regions (heaps) pointed to by the szone's tiny_regions * pointer. * - * Each region is laid out as a heap (1MB in 32-bit mode, 2MB in 64-bit mode), followed by a header - * block. The header block is arranged: + * Each region is laid out as a heap, followed by a header block, all within + * a 1MB (2^20) block. This means there are 64520 16-byte blocks and the header is + * 16138 bytes, making the total 1048458 bytes, leaving 118 bytes unused. + * The header block is arranged: * - * 0x0 + * 0xfc080 * header bits - * 0x2000 + * 0xfe001 * 0xffffffff pad word - * 0x2004 + * 0xfe005 * in-use bits - * 0x4004 + * 0xfff86 * pad word (not written) + * 0xfff8a-0xfffff + * unused * * Each bitfield comprises NUM_TINY_BLOCKS bits, and refers to the corresponding TINY_QUANTUM block * within the heap. @@ -120,67 +123,58 @@ typedef unsigned char grain_t; * in-use bit is set for the header if the block has been handed out (allocated). If the header * bit is not set, the in-use bit is invalid. * - * The szone maintains an array of 32 freelists, each of which is used to hold free objects - * of the corresponding quantum size. + * The szone maintains an array of 32 freelists, each of which is used to hold + * free objects of the corresponding quantum size. * - * A free block is laid out as: + * A free block is laid out depending on its size, in order to fit all free + * blocks in 16 bytes, on both 32 and 64 bit platforms. One quantum blocks do + * not store their size in the block, instead relying on the header information + * to determine their size. Blocks of two or more quanta have room to store + * their size in the block, and store it both after the 'next' pointer, and in + * the last 2 bytes of the block. * + * 1-quantum block * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 - * checksum - * 0x4 0x08 - * previous - * 0x8 0x10 - * next - * 0xc 0x18 - * size (in quantum counts) - * end - 2 end - 2 - * size (in quantum counts) - * end end + * 0x0 0x0 : previous + * 0x4 0x08 : next + * end end + * + * >1-quantum block + * Offset (32-bit mode) (64-bit mode) + * 0x0 0x0 : previous + * 0x4 0x08 : next + * 0x8 0x10 : size (in quantum counts) + * end - 2 end - 2 : size (in quantum counts) + * end end * * All fields are pointer-sized, except for the size which is an unsigned short. * */ -#ifdef __LP64__ -# define SHIFT_TINY_QUANTUM 5 // Required to fit free_list_t -#else -# define SHIFT_TINY_QUANTUM 4 // Required for AltiVec -#endif +#define SHIFT_TINY_QUANTUM 4 // Required for AltiVec #define TINY_QUANTUM (1 << SHIFT_TINY_QUANTUM) #define FOLLOWING_TINY_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_TINY_QUANTUM)) #define NUM_TINY_SLOTS 32 // number of slots for free-lists -#define SHIFT_NUM_TINY_BLOCKS 16 -#define NUM_TINY_BLOCKS (1 << SHIFT_NUM_TINY_BLOCKS) -#define TINY_BLOCKS_ALIGN (SHIFT_NUM_TINY_BLOCKS + SHIFT_TINY_QUANTUM) +#define NUM_TINY_BLOCKS 64520 +#define SHIFT_TINY_CEIL_BLOCKS 16 // ceil(log2(NUM_TINY_BLOCKS)) +#define NUM_TINY_CEIL_BLOCKS (1 << SHIFT_TINY_CEIL_BLOCKS) +#define TINY_BLOCKS_ALIGN (SHIFT_TINY_CEIL_BLOCKS + SHIFT_TINY_QUANTUM) /* * Enough room for the data, followed by the bit arrays (2-bits per block) plus 2 words of padding * as our bitmap operators overflow, plus rounding to the nearest page. */ -#define TINY_REGION_SIZE ((NUM_TINY_BLOCKS * TINY_QUANTUM + (NUM_TINY_BLOCKS >> 2) + 8 + vm_page_size - 1) & ~ (vm_page_size - 1)) - -/* - * Obtain the size of a free tiny block (in msize_t units). - */ -#ifdef __LP64__ -# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[14]) -#else -# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[6]) -#endif -/* - * The size is also kept at the very end of a free block. - */ -#define TINY_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] +#define TINY_HEADER_SIZE ((NUM_TINY_BLOCKS >> 2) + 8) +#define TINY_REGION_SIZE ((NUM_TINY_BLOCKS * TINY_QUANTUM + TINY_HEADER_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1)) /* * Beginning and end pointers for a region's heap. */ #define TINY_REGION_ADDRESS(region) ((void *)(region)) -#define TINY_REGION_END(region) (TINY_REGION_ADDRESS(region) + (1 << TINY_BLOCKS_ALIGN)) +#define TINY_REGION_END(region) (TINY_REGION_ADDRESS(region) + (NUM_TINY_BLOCKS * TINY_QUANTUM)) /* * Locate the heap base for a pointer known to be within a tiny region. @@ -193,10 +187,18 @@ typedef unsigned char grain_t; #define TINY_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_TINY_QUANTUM) #define TINY_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_TINY_QUANTUM) +#ifdef __LP64__ +# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[8]) +#else +# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[4]) +#endif +#define TINY_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] + /* * Locate the block header for a pointer known to be within a tiny region. */ -#define TINY_BLOCK_HEADER_FOR_PTR(_p) ((void *)(((((uintptr_t)(_p)) >> TINY_BLOCKS_ALIGN) + 1) << TINY_BLOCKS_ALIGN)) +#define TINY_HEADER_START (NUM_TINY_BLOCKS * TINY_QUANTUM) +#define TINY_BLOCK_HEADER_FOR_PTR(_p) ((void *)((uintptr_t)TINY_REGION_FOR_PTR(_p) + TINY_HEADER_START)) /* * Locate the inuse map for a given block header pointer. @@ -206,11 +208,7 @@ typedef unsigned char grain_t; /* * Compute the bitmap index for a pointer known to be within a tiny region. */ -#define TINY_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1)) - -typedef void *tiny_region_t; - -#define INITIAL_NUM_TINY_REGIONS 24 // must be even for szone to be aligned +#define TINY_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_CEIL_BLOCKS - 1)) #define TINY_CACHE 1 // This governs a last-free cache of 1 that bypasses the free-list @@ -224,8 +222,10 @@ typedef void *tiny_region_t; * Memory in the Small range is allocated from regions (heaps) pointed to by the szone's small_regions * pointer. * - * Each region is laid out as a heap (8MB in 32-bit and 64-bit mode), followed by the metadata array. + * Each region is laid out as a heap, followed by the metadata array, all within an 8MB (2^23) block. * The array is arranged as an array of shorts, one for each SMALL_QUANTUM in the heap. + * This means there are 16320 512-blocks and the array is 16320*2 bytes, which totals 8388480, leaving + * 128 bytes unused. * * The MSB of each short is set for the first quantum in a free block. The low 15 bits encode the * block size (in SMALL_QUANTUM units), or are zero if the quantum is not the first in a block. @@ -236,16 +236,10 @@ typedef void *tiny_region_t; * A free block is laid out as: * * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 - * checksum - * 0x4 0x08 - * previous - * 0x8 0x10 - * next - * 0xc 0x18 - * size (in quantum counts) - * end - 2 end - 2 - * size (in quantum counts) + * 0x0 0x0 : previous + * 0x4 0x08 : next + * 0x8 0x10 : size (in quantum counts) + * end - 2 end - 2 : size (in quantum counts) * end end * * All fields are pointer-sized, except for the size which is an unsigned short. @@ -265,10 +259,12 @@ typedef void *tiny_region_t; * We can only represent up to 1<<15 for msize; but we choose to stay even below that to avoid the * convention msize=0 => msize = (1<<15) */ -#define SHIFT_NUM_SMALL_BLOCKS 14 -#define NUM_SMALL_BLOCKS (1 << SHIFT_NUM_SMALL_BLOCKS) -#define SMALL_BLOCKS_ALIGN (SHIFT_NUM_SMALL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23 -#define SMALL_REGION_SIZE (NUM_SMALL_BLOCKS * SMALL_QUANTUM + NUM_SMALL_BLOCKS * 2) // data + meta data +#define NUM_SMALL_BLOCKS 16320 +#define SHIFT_SMALL_CEIL_BLOCKS 14 // ceil(log2(NUM_SMALL_BLOCKs)) +#define NUM_SMALL_CEIL_BLOCKS (1 << SHIFT_SMALL_CEIL_BLOCKS) +#define SMALL_BLOCKS_ALIGN (SHIFT_SMALL_CEIL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23 +#define SMALL_ARRAY_SIZE (NUM_SMALL_BLOCKS * 2) +#define SMALL_REGION_SIZE ((NUM_SMALL_BLOCKS * SMALL_QUANTUM + SMALL_ARRAY_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1)) // data + meta data #define SMALL_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] @@ -280,7 +276,7 @@ typedef void *tiny_region_t; #define SMALL_REGION_ADDRESS(region) ((unsigned char *)region) -#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region) + (1 << SMALL_BLOCKS_ALIGN)) +#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region) + (NUM_SMALL_BLOCKS * SMALL_QUANTUM)) /* * Locate the heap base for a pointer known to be within a small region. @@ -290,12 +286,13 @@ typedef void *tiny_region_t; /* * Locate the metadata base for a pointer known to be within a small region. */ -#define SMALL_META_HEADER_FOR_PTR(_p) ((msize_t *)(((((uintptr_t)(_p)) >> SMALL_BLOCKS_ALIGN) + 1) << SMALL_BLOCKS_ALIGN)) +#define SMALL_HEADER_START (NUM_SMALL_BLOCKS * SMALL_QUANTUM) +#define SMALL_META_HEADER_FOR_PTR(_p) ((msize_t *)((uintptr_t)SMALL_REGION_FOR_PTR(_p) + SMALL_HEADER_START)) /* * Compute the metadata index for a pointer known to be within a small region. */ -#define SMALL_META_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_BLOCKS - 1)) +#define SMALL_META_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_CEIL_BLOCKS - 1)) /* * Find the metadata word for a pointer known to be within a small region. @@ -312,10 +309,6 @@ typedef void *tiny_region_t; */ #define SMALL_PTR_SIZE(_p) (*SMALL_METADATA_FOR_PTR(_p) & ~SMALL_IS_FREE) -typedef void * small_region_t; - -#define INITIAL_NUM_SMALL_REGIONS 6 // must be even for szone to be aligned - #define PROTECT_SMALL 0 // Should be 0: 1 is too slow for normal use #define SMALL_CACHE 1 @@ -323,7 +316,7 @@ typedef void * small_region_t; #warning SMALL_CACHE turned off #endif -/********************* DEFINITIONS for large ************************/ +/********************* DEFINITIONS for large and huge ***********************/ #define LARGE_THRESHOLD (15 * 1024) // at or above this use "large" @@ -359,10 +352,15 @@ typedef void * small_region_t; #define LARGE_ENTRY_IS_EMPTY(entry) (((entry).address_and_num_pages) == 0) typedef compact_range_t large_entry_t; +typedef vm_range_t huge_entry_t; -/********************* DEFINITIONS for huge ************************/ +/******************************************************************************* + * Definitions for region hash + ******************************************************************************/ -typedef vm_range_t huge_entry_t; +typedef void * region_t; + +#define INITIAL_NUM_REGIONS 63 // Must be odd to hash well /********************* zone itself ************************/ @@ -373,8 +371,10 @@ typedef struct { void *log_address; /* Regions for tiny objects */ - unsigned num_tiny_regions; - tiny_region_t *tiny_regions; + size_t num_tiny_regions; + size_t num_tiny_regions_allocated; + region_t *tiny_regions; // hashed by location + region_t *last_tiny_region; void *last_tiny_free; // low SHIFT_TINY_QUANTUM indicate the msize unsigned tiny_bitmap; // cache of the 32 free lists free_list_t *tiny_free_list[NUM_TINY_SLOTS]; // 31 free lists for 1*TINY_QUANTUM to 31*TINY_QUANTUM plus 1 for larger than 32*SMALL_QUANTUM @@ -383,8 +383,10 @@ typedef struct { size_t num_bytes_in_tiny_objects; /* Regions for small objects */ - unsigned num_small_regions; - small_region_t *small_regions; + size_t num_small_regions; + size_t num_small_regions_allocated; + region_t *small_regions; // hashed by location + region_t *last_small_region; void *last_small_free; // low SHIFT_SMALL_QUANTUM indicate the msize unsigned small_bitmap; // cache of the free list free_list_t *small_free_list[NUM_SMALL_SLOTS]; @@ -404,21 +406,29 @@ typedef struct { size_t num_bytes_in_huge_objects; /* Initial region list */ - tiny_region_t initial_tiny_regions[INITIAL_NUM_TINY_REGIONS]; - small_region_t initial_small_regions[INITIAL_NUM_SMALL_REGIONS]; + region_t initial_tiny_regions[INITIAL_NUM_REGIONS]; + region_t initial_small_regions[INITIAL_NUM_REGIONS]; } szone_t; +#define SZONE_PAGED_SIZE ((sizeof(szone_t) + vm_page_size - 1) & ~ (vm_page_size - 1)) + #if DEBUG_MALLOC || DEBUG_CLIENT static void szone_sleep(void); #endif -static void szone_error(szone_t *szone, const char *msg, const void *ptr); -static void protect(szone_t *szone, void *address, size_t size, unsigned protection, unsigned debug_flags); +__private_extern__ void malloc_error_break(void); + +// msg prints after fmt, ... +static void szone_error(szone_t *szone, const char *msg, const void *ptr, const char *fmt, ...) __printflike(4, 5); + +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 deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags); static kern_return_t _szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr); static INLINE void free_list_checksum(szone_t *szone, free_list_t *ptr, const char *msg) ALWAYSINLINE; static INLINE void free_list_set_checksum(szone_t *szone, free_list_t *ptr) ALWAYSINLINE; +static INLINE uintptr_t free_list_checksum_ptr(void *p) ALWAYSINLINE; +static INLINE void * free_list_unchecksum_ptr(ptr_union ptr) ALWAYSINLINE; static unsigned free_list_count(const free_list_t *ptr); static INLINE msize_t get_tiny_meta_header(const void *ptr, boolean_t *is_free) ALWAYSINLINE; @@ -427,19 +437,19 @@ static INLINE void set_tiny_meta_header_middle(const void *ptr) ALWAYSINLINE; static INLINE void set_tiny_meta_header_free(const void *ptr, msize_t msize) ALWAYSINLINE; static INLINE boolean_t tiny_meta_header_is_free(const void *ptr) ALWAYSINLINE; static INLINE void *tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) ALWAYSINLINE; -static INLINE void tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) ALWAYSINLINE; -static INLINE void tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize) ALWAYSINLINE; -static INLINE tiny_region_t *tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE; -static INLINE void tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msize) ALWAYSINLINE; +static void tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize); +static void tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize); +static INLINE region_t *tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE; +static INLINE void tiny_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize) ALWAYSINLINE; static void *tiny_malloc_from_region_no_lock(szone_t *szone, msize_t msize); static INLINE boolean_t try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE; -static boolean_t tiny_check_region(szone_t *szone, tiny_region_t *region); -static kern_return_t tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned short num_regions, size_t tiny_bytes_free_at_end, memory_reader_t reader, vm_range_recorder_t recorder); -static INLINE void *tiny_malloc_from_free_list(szone_t *szone, msize_t msize) ALWAYSINLINE; +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, memory_reader_t reader, vm_range_recorder_t recorder); +static void *tiny_malloc_from_free_list(szone_t *szone, msize_t msize); 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, tiny_region_t *tiny_region) ALWAYSINLINE; +static INLINE void free_tiny(szone_t *szone, void *ptr, region_t *tiny_region) ALWAYSINLINE; static void print_tiny_free_list(szone_t *szone); -static void print_tiny_region(boolean_t verbose, tiny_region_t region, size_t bytes_at_end); +static void print_tiny_region(boolean_t verbose, region_t region, 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; @@ -447,20 +457,25 @@ static INLINE void small_meta_header_set_in_use(msize_t *meta_headers, msize_t i static INLINE void small_meta_header_set_middle(msize_t *meta_headers, msize_t index) ALWAYSINLINE; static void small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize); static void small_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize); -static INLINE small_region_t *small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE; -static INLINE void small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t msize) ALWAYSINLINE; +static INLINE region_t *small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE; +static INLINE void small_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize) ALWAYSINLINE; static void *small_malloc_from_region_no_lock(szone_t *szone, msize_t msize); static INLINE boolean_t try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE; -static boolean_t szone_check_small_region(szone_t *szone, small_region_t *region); -static kern_return_t small_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned short num_regions, size_t small_bytes_free_at_end, memory_reader_t reader, vm_range_recorder_t recorder); -static INLINE void *small_malloc_from_free_list(szone_t *szone, msize_t msize) ALWAYSINLINE; +static boolean_t szone_check_small_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, memory_reader_t reader, vm_range_recorder_t recorder); +static void *small_malloc_from_free_list(szone_t *szone, msize_t msize); static INLINE void *small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE; static INLINE void *small_malloc_cleared_no_lock(szone_t *szone, msize_t msize) ALWAYSINLINE; -static INLINE void free_small(szone_t *szone, void *ptr, small_region_t *small_region) ALWAYSINLINE; +static INLINE void free_small(szone_t *szone, void *ptr, region_t *small_region) ALWAYSINLINE; static void print_small_free_list(szone_t *szone); -static void print_small_region(szone_t *szone, boolean_t verbose, small_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_end); static boolean_t small_free_list_check(szone_t *szone, grain_t grain); +static region_t * hash_lookup_region_no_lock(region_t *regions, size_t num_entries, region_t r); +static void hash_region_insert_no_lock(region_t *regions, size_t num_entries, region_t r); +static region_t * hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries); +static region_t * hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, size_t *new_size); + #if DEBUG_MALLOC static void large_debug_print(szone_t *szone); #endif @@ -469,13 +484,13 @@ static void large_entry_insert_no_lock(szone_t *szone, large_entry_t range); static INLINE void large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) ALWAYSINLINE; static INLINE large_entry_t *large_entries_alloc_no_lock(szone_t *szone, unsigned num) ALWAYSINLINE; static void large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate); -static void large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate); +static large_entry_t * large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate); static vm_range_t large_free_no_lock(szone_t *szone, large_entry_t *entry); static 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); static huge_entry_t *huge_entry_for_pointer_no_lock(szone_t *szone, const void *ptr); static boolean_t huge_entry_append(szone_t *szone, huge_entry_t huge); static kern_return_t huge_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t huge_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder); -static void *large_and_huge_malloc(szone_t *szone, unsigned num_pages); +static void *large_and_huge_malloc(szone_t *szone, size_t num_pages); static INLINE void free_large_or_huge(szone_t *szone, void *ptr) ALWAYSINLINE; static INLINE int try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE; @@ -546,23 +561,52 @@ szone_sleep(void) { if (getenv("MallocErrorSleep")) { - malloc_printf("*** sleeping to help debug\n"); + _malloc_printf(ASL_LEVEL_NOTICE, "*** sleeping to help debug\n"); sleep(3600); // to help debug } } #endif -static void -szone_error(szone_t *szone, const char *msg, const void *ptr) +// msg prints after fmt, ... +static __attribute__((noinline)) void +szone_error(szone_t *szone, const char *msg, const void *ptr, const char *fmt, ...) { + va_list ap; + _SIMPLE_STRING b = _simple_salloc(); if (szone) SZONE_UNLOCK(szone); - if (ptr) { - malloc_printf("*** error for object %p: %s\n", ptr, msg); + if (b) { + if (fmt) { + va_start(ap, fmt); + _simple_vsprintf(b, fmt, ap); + va_end(ap); + } + if (ptr) { + _simple_sprintf(b, "*** error for object %p: %s\n", ptr, msg); + } else { + _simple_sprintf(b, "*** error: %s\n", msg); + } + malloc_printf("%s*** set a breakpoint in malloc_error_break to debug\n", _simple_string(b)); + _simple_sfree(b); } else { - malloc_printf("*** error: %s\n", msg); + /* + * Should only get here if vm_allocate() can't get a single page of + * memory, implying _simple_asl_log() would also fail. So we just + * print to the file descriptor. + */ + if (fmt) { + va_start(ap, fmt); + _malloc_vprintf(MALLOC_PRINTF_NOLOG, fmt, ap); + va_end(ap); + } + if (ptr) { + _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error for object %p: %s\n", ptr, msg); + } else { + _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error: %s\n", msg); + } + _malloc_printf(MALLOC_PRINTF_NOLOG, "*** set a breakpoint in malloc_error_break to debug\n"); } - malloc_printf("*** set a breakpoint in szone_error to debug\n"); + malloc_error_break(); #if DEBUG_MALLOC szone_print(szone, 1); szone_sleep(); @@ -570,10 +614,11 @@ szone_error(szone_t *szone, const char *msg, const void *ptr) #if DEBUG_CLIENT szone_sleep(); #endif + if (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_ERROR) abort(); } static void -protect(szone_t *szone, void *address, size_t size, unsigned protection, unsigned debug_flags) +protect(void *address, size_t size, unsigned protection, unsigned debug_flags) { kern_return_t err; @@ -597,43 +642,39 @@ static void * allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label) { // align specifies a desired alignment (as a log) or 0 if no alignment requested - kern_return_t err; - vm_address_t vm_addr; + void *vm_addr; uintptr_t addr, aligned_address; boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; size_t allocation_size = round_page(size); size_t delta; - + 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; - err = vm_allocate(mach_task_self(), &vm_addr, allocation_size, vm_page_label | 1); - if (err) { - malloc_printf("*** vm_allocate(size=%lld) failed (error code=%d)\n", (long long)size, err); - szone_error(szone, "can't allocate region", NULL); - return NULL; + vm_addr = mmap(0, allocation_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, VM_MAKE_TAG(vm_page_label), 0); + if ((uintptr_t)vm_addr == -1) { + szone_error(szone, "can't allocate region", NULL, "*** mmap(size=%lld) failed (error code=%d)\n", (long long)allocation_size, errno); + return NULL; } addr = (uintptr_t)vm_addr; if (align) { aligned_address = (addr + ((uintptr_t)1 << align) - 1) & ~ (((uintptr_t)1 << align) - 1); if (aligned_address != addr) { delta = aligned_address - addr; - err = vm_deallocate(mach_task_self(), (vm_address_t)addr, delta); - if (err) - malloc_printf("*** freeing unaligned header failed with %d\n", err); + if (munmap((void *)addr, delta) == -1) + malloc_printf("*** freeing unaligned header failed with %d\n", errno); addr = aligned_address; allocation_size -= delta; } if (allocation_size > size) { - err = vm_deallocate(mach_task_self(), (vm_address_t)addr + size, allocation_size - size); - if (err) - malloc_printf("*** freeing unaligned footer failed with %d\n", err); + if (munmap((void *)(addr + size), allocation_size - size) == -1) + malloc_printf("*** freeing unaligned footer failed with %d\n", errno); } } if (add_guard_pages) { addr += (uintptr_t)1 << vm_page_shift; - protect(szone, (void *)addr, size, 0, debug_flags); + protect((void *)addr, size, 0, debug_flags); } return (void *)addr; } @@ -641,16 +682,16 @@ allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_ static void deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags) { - kern_return_t err; - boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; + int err; + boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; if (add_guard_pages) { addr -= 1 << vm_page_shift; size += 2 * (1 << vm_page_shift); } - err = vm_deallocate(mach_task_self(), (vm_address_t)addr, size); - if (err && szone) - szone_error(szone, "Can't deallocate_pages region", addr); + err = munmap(addr, size); + if ((err == -1) && szone) + szone_error(szone, "Can't deallocate_pages region", addr, NULL); } static kern_return_t @@ -660,28 +701,61 @@ _szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void ** return 0; } +/********************* FREE LIST UTILITIES ************************/ + +// A free list entry is comprised of a pair of pointers, previous and next. +// Because the free list entries are previously freed objects, there is a +// non-zero chance that a misbehaved program will write to an allocated object +// after it has called free() on the pointer. This write would then potentially +// corrupt the previous and next pointers, leading to a crash. In order to +// detect this case, we take advantage of the fact that pointers are known to +// be at least 16 byte aligned, and thus have at least 4 trailing zero bits. +// When an entry is added to the free list, the previous and next pointers are +// shifted right by 2 bits, and then have the high and low 2 bits set, to act +// as guard bits. Before accessing a free list object, we verify that these +// bits are still set, and log an error if they are not. + static INLINE void free_list_checksum(szone_t *szone, free_list_t *ptr, const char *msg) { - // We always checksum, as testing whether to do it (based on szone->debug_flags) is as fast as - // doing it - // XXX not necessarily true for LP64 case - if (ptr->checksum != (((uintptr_t)ptr->previous) ^ ((uintptr_t)ptr->next) ^ CHECKSUM_MAGIC)) { -#if DEBUG_MALLOC - malloc_printf("*** incorrect checksum: %s\n", msg); + uintptr_t ptrs = ptr->previous.u & ptr->next.u; + +#ifdef __LP64__ + ptrs = (ptrs << 2) | (ptrs >> (64-2)); +#else + ptrs = (ptrs << 2) | (ptrs >> (32-2)); #endif - szone_error(szone, "incorrect checksum for freed object " - "- object was probably modified after being freed, break at szone_error to debug", ptr); - } + + if ((ptrs & 15) != 15) + szone_error(szone, "incorrect checksum for freed object " + "- object was probably modified after being freed.", ptr, NULL); +} + +static INLINE uintptr_t +free_list_checksum_ptr(void *p) +{ + ptr_union ptr; + ptr.p = p; + +#ifdef __LP64__ + return (ptr.u >> 2) | 0xC000000000000003ULL; +#else + return (ptr.u >> 2) | 0xC0000003U; +#endif +} + +static INLINE void * +free_list_unchecksum_ptr(ptr_union ptr) +{ + uintptr_t u = (ptr.u >> 2) << 4; + return (void *)u; } static INLINE void free_list_set_checksum(szone_t *szone, free_list_t *ptr) { - // We always set checksum, as testing whether to do it (based on - // szone->debug_flags) is slower than just doing it - // XXX not necessarily true for LP64 case - ptr->checksum = ((uintptr_t)ptr->previous) ^ ((uintptr_t)ptr->next) ^ CHECKSUM_MAGIC; + ptr->previous.u = free_list_checksum_ptr(ptr->previous.p); + ptr->next.u = free_list_checksum_ptr(ptr->next.p); } static unsigned @@ -690,8 +764,8 @@ free_list_count(const free_list_t *ptr) unsigned count = 0; while (ptr) { - count++; - ptr = ptr->next; + count++; + ptr = free_list_unchecksum_ptr(ptr->next); } return count; } @@ -702,8 +776,8 @@ free_list_count(const free_list_t *ptr) #define BITMAP32_CLR(bitmap,bit) (bitmap &= ~ (1 << (bit))) #define BITMAP32_BIT(bitmap,bit) ((bitmap >> (bit)) & 1) -#define BITMAP32_FFS(bitmap) (ffs(bitmap)) - // returns bit # of first bit that's one, starting at 1 (returns 0 if !bitmap) +/* returns bit # of least-significant one bit, starting at 0 (undefined if !bitmap) */ +#define BITMAP32_CTZ(bitmap) (__builtin_ctz(bitmap)) /********************* TINY FREE LIST UTILITIES ************************/ @@ -721,40 +795,65 @@ free_list_count(const free_list_t *ptr) #define BITARRAY_BIT(bits,index) (((bits[index>>3]) >> (index & 7)) & 1) // Following is for start<8 and end<=start+32 -#define BITARRAY_MCLR_LESS_32(bits,start,end) \ -do { \ - unsigned char *_bits = (bits); \ - unsigned _end = (end); \ - switch (_end >> 3) { \ - case 4: _bits[4] &= ~ ((1 << (_end - 32)) - 1); _end = 32; \ - case 3: _bits[3] &= ~ ((1 << (_end - 24)) - 1); _end = 24; \ - case 2: _bits[2] &= ~ ((1 << (_end - 16)) - 1); _end = 16; \ - case 1: _bits[1] &= ~ ((1 << (_end - 8)) - 1); _end = 8; \ - case 0: _bits[0] &= ~ ((1 << _end) - (1 << (start))); \ - } \ -} while (0) +static void ALWAYSINLINE +bitarray_mclr(void *bits, unsigned start, unsigned end) { + unsigned word = OSReadLittleInt32(bits, 0); + unsigned mask = (0xFFFFFFFFU >> (31 - start)) >> 1; + + if (end > 31) { + unsigned char *bytes = (unsigned char *)bits; + bytes[4] &= ~((1 << (end - 32)) - 1); + } else { + mask |= (0xFFFFFFFF << end); + } + OSWriteLittleInt32(bits, 0, word & mask); +} -#if 0 // Simple but slow version -#warning Slow version in effect -#define BITARRAY_MCLR(bits,index,num) \ -do { \ - unsigned _ctr = (num); \ - unsigned _cur = (index); \ - \ - while (_ctr--) {BITARRAY_CLR(bits,_cur); _cur++; } \ -} while (0) -#else +/* + * Obtain the size of a free tiny block (in msize_t units). + */ +static msize_t +get_tiny_free_size(const void *ptr) +{ + void *next_block = (void *)((uintptr_t)ptr + TINY_QUANTUM); + void *region_end = TINY_REGION_END(TINY_REGION_FOR_PTR(ptr)); -// Following is for num <= 32 -#define BITARRAY_MCLR(bits,index,num) \ -do { \ - unsigned _index = (index); \ - unsigned char *_rebased = (bits) + (_index >> 3); \ - \ - _index &= 7; \ - BITARRAY_MCLR_LESS_32(_rebased, _index, _index + (num)); \ -} while (0) -#endif + // check whether the next block is outside the tiny region or a block header + // if so, then the size of this block is one, and there is no stored size. + if (next_block < region_end) + { + unsigned char *next_header = TINY_BLOCK_HEADER_FOR_PTR(next_block); + msize_t next_index = TINY_INDEX_FOR_PTR(next_block); + + if (!BITARRAY_BIT(next_header, next_index)) + return TINY_FREE_SIZE(ptr); + } + return 1; +} + +/* + * Get the size of the previous free block, which is stored in the last two + * bytes of the block. If the previous block is not free, then the result is + * undefined. + */ +static msize_t +get_tiny_previous_free_msize(const void *ptr) +{ + // check whether the previous block is in the tiny region and a block header + // if so, then the size of the previous block is one, and there is no stored + // size. + if (ptr != TINY_REGION_FOR_PTR(ptr)) + { + void *prev_block = (void *)((uintptr_t)ptr - TINY_QUANTUM); + unsigned char *prev_header = TINY_BLOCK_HEADER_FOR_PTR(prev_block); + msize_t prev_index = TINY_INDEX_FOR_PTR(prev_block); + if (BITARRAY_BIT(prev_header, prev_index)) + return 1; + return TINY_PREVIOUS_MSIZE(ptr); + } + // don't read possibly unmapped memory before the beginning of the region + return 0; +} static INLINE msize_t get_tiny_meta_header(const void *ptr, boolean_t *is_free) @@ -774,11 +873,11 @@ get_tiny_meta_header(const void *ptr, boolean_t *is_free) index &= 7; *is_free = 0; if (!BITMAP32_BIT(*block_header, index)) - return 0; + return 0; in_use = TINY_INUSE_FOR_HEADER(block_header); if (!BITMAP32_BIT(*in_use, index)) { - *is_free = 1; - return TINY_FREE_SIZE(ptr); + *is_free = 1; + return get_tiny_free_size(ptr); } uint32_t *addr = (uint32_t *)((uintptr_t)block_header & ~3); uint32_t word0 = OSReadLittleInt32(addr, 0) >> index; @@ -821,8 +920,8 @@ set_tiny_meta_header_in_use(const void *ptr, msize_t msize) block_header += byte_index; in_use += byte_index; index &= 7; end_bit = index + clr_msize; - BITARRAY_MCLR_LESS_32(block_header, index, end_bit); - BITARRAY_MCLR_LESS_32(in_use, index, end_bit); + bitarray_mclr(block_header, index, end_bit); + bitarray_mclr(in_use, index, end_bit); } BITARRAY_SET(block_header, index+clr_msize); // we set the block_header bit for the following block to reaffirm next block is a block #if DEBUG_MALLOC @@ -853,7 +952,6 @@ set_tiny_meta_header_middle(const void *ptr) BITARRAY_CLR(block_header, index); BITARRAY_CLR(in_use, index); - TINY_FREE_SIZE(ptr) = 0; } static INLINE void @@ -873,19 +971,26 @@ set_tiny_meta_header_free(const void *ptr, msize_t msize) malloc_printf("setting header for tiny free %p msize too large: %d\n", ptr, msize); } #endif - BITARRAY_SET(block_header, index); BITARRAY_CLR(in_use, index); - TINY_FREE_SIZE(ptr) = msize; - // mark the end of this block - if (msize) { // msize==0 => the whole region is free - void *follower = FOLLOWING_TINY_PTR(ptr, msize); - TINY_PREVIOUS_MSIZE(follower) = msize; + BITARRAY_SET(block_header, index); + BITARRAY_CLR(in_use, index); + // mark the end of this block if msize is > 1. For msize == 0, the whole + // region is free, so there is no following block. For msize == 1, there is + // no space to write the size on 64 bit systems. The size for 1 quantum + // blocks is computed from the metadata bitmaps. + if (msize > 1) { + void *follower = FOLLOWING_TINY_PTR(ptr, msize); + TINY_PREVIOUS_MSIZE(follower) = msize; + TINY_FREE_SIZE(ptr) = msize; + } + if (msize == 0) { + TINY_FREE_SIZE(ptr) = msize; } #if DEBUG_MALLOC boolean_t ff; msize_t mf = get_tiny_meta_header(ptr, &ff); if ((msize != mf) || !ff) { - malloc_printf("setting header for tiny free %p : %d\n", ptr, msize); - malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff); + malloc_printf("setting header for tiny free %p : %u\n", ptr, msize); + malloc_printf("reading header for tiny %p : %u %u\n", ptr, mf, ff); } #endif } @@ -893,8 +998,6 @@ set_tiny_meta_header_free(const void *ptr, msize_t msize) static INLINE boolean_t tiny_meta_header_is_free(const void *ptr) { - // returns msize and is_free shifted by 16 - // may return 0 for the msize component (meaning 65536) unsigned char *block_header; unsigned char *in_use; msize_t index; @@ -923,129 +1026,124 @@ tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) index = TINY_INDEX_FOR_PTR(ptr); if (!index) - return NULL; - if ((previous_msize = TINY_PREVIOUS_MSIZE(ptr)) > index) - return NULL; + return NULL; + if ((previous_msize = get_tiny_previous_free_msize(ptr)) > index) + return NULL; previous_index = index - previous_msize; previous_ptr = (void *)(TINY_REGION_FOR_PTR(ptr) + TINY_BYTES_FOR_MSIZE(previous_index)); - if (TINY_FREE_SIZE(previous_ptr) != previous_msize) - return NULL; - if (!BITARRAY_BIT(block_header, previous_index)) - return NULL; + return NULL; if (BITARRAY_BIT(in_use, previous_index)) - return NULL; + return NULL; + if (get_tiny_free_size(previous_ptr) != previous_msize) + return NULL; // conservative check did match true check *prev_msize = previous_msize; return previous_ptr; } -static INLINE void +/* + * Adds an item to the proper free list, and also marks the meta-header of the + * block properly. + * Assumes szone has been locked + */ +static void tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) { - // Adds an item to the proper free list - // Also marks the meta-header of the block properly - // Assumes szone has been locked grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1; free_list_t *free_ptr = ptr; free_list_t *free_head = szone->tiny_free_list[slot]; #if DEBUG_MALLOC if (LOG(szone,ptr)) { - malloc_printf("in tiny_free_list_add_ptr(), ptr=%p, msize=%d\n", ptr, msize); + malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); } - if (((unsigned)ptr) & (TINY_QUANTUM - 1)) { - szone_error(szone, "tiny_free_list_add_ptr: Unaligned ptr", ptr); + if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { + szone_error(szone, "tiny_free_list_add_ptr: Unaligned ptr", ptr, NULL); } #endif set_tiny_meta_header_free(ptr, msize); if (free_head) { - free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); + free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); #if DEBUG_MALLOC - if (free_head->previous) { - malloc_printf("ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, free_head, free_head->previous); - szone_error(szone, "tiny_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr); - } - if (! tiny_meta_header_is_free(free_head)) { - malloc_printf("ptr=%p slot=%d free_head=%p\n", ptr, slot, free_head); - szone_error(szone, "tiny_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr); - } + if (free_list_unchecksum_ptr(free_head->previous)) { + szone_error(szone, "tiny_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr, + "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, free_head, free_head->previous.p); + } + if (! tiny_meta_header_is_free(free_head)) { + szone_error(szone, "tiny_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr, + "ptr=%p slot=%d free_head=%p\n", ptr, slot, free_head); + } #endif - free_head->previous = free_ptr; - free_list_set_checksum(szone, free_head); + free_head->previous.u = free_list_checksum_ptr(free_ptr); } else { - BITMAP32_SET(szone->tiny_bitmap, slot); + BITMAP32_SET(szone->tiny_bitmap, slot); } - free_ptr->previous = NULL; - free_ptr->next = free_head; + free_ptr->previous.p = NULL; + free_ptr->next.p = free_head; free_list_set_checksum(szone, free_ptr); szone->tiny_free_list[slot] = free_ptr; } +/* + * Removes the item pointed to by ptr in the proper free list. + * Assumes szone has been locked + */ static INLINE void tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize) { - // Removes item in the proper free list - // msize could be read, but all callers have it so we pass it in - // Assumes szone has been locked grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1; - free_list_t *free_ptr = ptr; - free_list_t *next = free_ptr->next; - free_list_t *previous = free_ptr->previous; + free_list_t *free_ptr = ptr, *next, *previous; + free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__); + + next = free_list_unchecksum_ptr(free_ptr->next); + previous = free_list_unchecksum_ptr(free_ptr->previous); #if DEBUG_MALLOC if (LOG(szone,ptr)) { - malloc_printf("In tiny_free_list_remove_ptr(), ptr=%p, msize=%d\n", ptr, msize); + malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); } #endif - free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__); - if (!previous) { - // The block to remove is the head of the free list + if (!previous) { + // The block to remove is the head of the free list #if DEBUG_MALLOC - if (szone->tiny_free_list[slot] != ptr) { - malloc_printf("ptr=%p slot=%d msize=%d szone->tiny_free_list[slot]=%p\n", - ptr, slot, msize, szone->tiny_free_list[slot]); - szone_error(szone, "tiny_free_list_remove_ptr: Internal invariant broken (szone->tiny_free_list[slot])", ptr); - return; - } + if (szone->tiny_free_list[slot] != ptr) { + szone_error(szone, "tiny_free_list_remove_ptr: Internal invariant broken (szone->tiny_free_list[slot])", ptr, + "ptr=%p slot=%d msize=%d szone->tiny_free_list[slot]=%p\n", + ptr, slot, msize, szone->tiny_free_list[slot]); + return; + } #endif - szone->tiny_free_list[slot] = next; - if (!next) BITMAP32_CLR(szone->tiny_bitmap, slot); + szone->tiny_free_list[slot] = next; + if (!next) BITMAP32_CLR(szone->tiny_bitmap, slot); } else { - previous->next = next; - free_list_set_checksum(szone, previous); + // We know free_ptr is already checksummed, so we don't need to do it + // again. + previous->next = free_ptr->next; } if (next) { - next->previous = previous; - free_list_set_checksum(szone, next); + // We know free_ptr is already checksummed, so we don't need to do it + // again. + next->previous = free_ptr->previous; } } /* - * Find the tiny region containing (ptr) (if any). - * - * We take advantage of the knowledge that tiny regions are always (1 << TINY_BLOCKS_ALIGN) aligned. + * tiny_region_for_ptr_no_lock - Returns the tiny region containing the pointer, + * or NULL if not found. */ -static INLINE tiny_region_t * +static INLINE region_t * tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) { - tiny_region_t *region; - tiny_region_t rbase; - int i; - - /* mask off irrelevant lower bits */ - rbase = TINY_REGION_FOR_PTR(ptr); - /* iterate over allocated regions - XXX not terribly efficient for large number of regions */ - for (i = szone->num_tiny_regions, region = szone->tiny_regions; i > 0; i--, region++) - if (rbase == *region) - return(region); - return(NULL); + return hash_lookup_region_no_lock(szone->tiny_regions, + szone->num_tiny_regions_allocated, + TINY_REGION_FOR_PTR(ptr)); } static INLINE void -tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msize) +tiny_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize) { size_t original_size = TINY_BYTES_FOR_MSIZE(msize); void *next_block = ((char *)ptr + original_size); @@ -1061,63 +1159,71 @@ tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msiz malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); } if (! msize) { - malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - szone_error(szone, "trying to free tiny block that is too small", ptr); + szone_error(szone, "trying to free tiny block that is too small", ptr, + "in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); } #endif // We try to coalesce this block with the preceeding one previous = tiny_previous_preceding_free(ptr, &previous_msize); if (previous) { #if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone,previous)) { - malloc_printf("in tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); - } + if (LOG(szone, ptr) || LOG(szone,previous)) { + malloc_printf("in tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); + } #endif - tiny_free_list_remove_ptr(szone, previous, previous_msize); - ptr = previous; - msize += previous_msize; + // clear the meta_header since this is no longer the start of a block + set_tiny_meta_header_middle(ptr); + tiny_free_list_remove_ptr(szone, previous, previous_msize); + ptr = previous; + msize += previous_msize; } // We try to coalesce with the next block if ((next_block < TINY_REGION_END(*region)) && tiny_meta_header_is_free(next_block)) { - // The next block is free, we coalesce - next_msize = TINY_FREE_SIZE(next_block); + next_msize = get_tiny_free_size(next_block); #if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone, next_block)) { - malloc_printf("in tiny_free_no_lock(), for ptr=%p, msize=%d coalesced forward=%p next_msize=%d\n", - ptr, msize, next_block, next_msize); - } + if (LOG(szone, ptr) || LOG(szone, next_block)) { + malloc_printf("in tiny_free_no_lock(), for ptr=%p, msize=%d coalesced forward=%p next_msize=%d\n", + ptr, msize, next_block, next_msize); + } #endif - if (next_msize >= NUM_TINY_SLOTS) { - // we take a short cut here to avoid removing next_block from the slot 31 freelist and then adding ptr back to slot 31 - msize += next_msize; - big_free_block = (free_list_t *)next_block; - after_next_block = big_free_block->next; - before_next_block = big_free_block->previous; - free_list_checksum(szone, big_free_block, __PRETTY_FUNCTION__); - if (!before_next_block) { - szone->tiny_free_list[NUM_TINY_SLOTS-1] = ptr; - } else { - before_next_block->next = ptr; - free_list_set_checksum(szone, before_next_block); - } - if (after_next_block) { - after_next_block->previous = ptr; - free_list_set_checksum(szone, after_next_block); - } - ((free_list_t *)ptr)->previous = before_next_block; - ((free_list_t *)ptr)->next = after_next_block; - free_list_set_checksum(szone, ptr); - set_tiny_meta_header_free(ptr, msize); - set_tiny_meta_header_middle(big_free_block); // clear the meta_header to enable coalescing backwards - goto tiny_free_ending; - } - tiny_free_list_remove_ptr(szone, next_block, next_msize); - set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards - msize += next_msize; - } + // If we are coalescing with the next block, and the next block is in + // the last slot of the free list, then we optimize this case here to + // avoid removing next_block from the slot 31 and then adding ptr back + // to slot 31. + if (next_msize >= NUM_TINY_SLOTS) { + msize += next_msize; + big_free_block = (free_list_t *)next_block; + free_list_checksum(szone, big_free_block, __PRETTY_FUNCTION__); + after_next_block = free_list_unchecksum_ptr(big_free_block->next); + before_next_block = free_list_unchecksum_ptr(big_free_block->previous); + if (!before_next_block) { + szone->tiny_free_list[NUM_TINY_SLOTS-1] = ptr; + } else { + before_next_block->next.u = free_list_checksum_ptr(ptr); + } + if (after_next_block) { + after_next_block->previous.u = free_list_checksum_ptr(ptr); + } + // we don't need to checksum these since they are already checksummed + ((free_list_t *)ptr)->previous = big_free_block->previous; + ((free_list_t *)ptr)->next = big_free_block->next; + + // clear the meta_header to enable coalescing backwards + set_tiny_meta_header_middle(big_free_block); + set_tiny_meta_header_free(ptr, msize); + goto tiny_free_ending; + } + tiny_free_list_remove_ptr(szone, next_block, next_msize); + 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) { memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize)); } +#endif tiny_free_list_add_ptr(szone, ptr, msize); tiny_free_ending: // When in proper debug mode we write on the memory to help debug memory smashers @@ -1125,42 +1231,68 @@ tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msiz szone->num_bytes_in_tiny_objects -= original_size; // we use original_size and not msize to avoid double counting the coalesced blocks } +// Allocates from the last region or a freshly allocated region static void * tiny_malloc_from_region_no_lock(szone_t *szone, msize_t msize) { - tiny_region_t last_region, *new_regions; - void *last_block, *ptr, *aligned_address; - - // Allocates from the last region or a freshly allocated region - // Before anything we transform the tiny_bytes_free_at_end - if any - to a regular free block + void *last_block, *ptr, *aligned_address; + unsigned char *last_header; + msize_t last_msize, last_index; + + // Before anything we transform any remaining tiny_bytes_free_at_end into a + // regular free block. We take special care here to update the bitfield + // information, since we are bypassing the normal free codepath. If there + // is more than one quanta worth of memory in tiny_bytes_free_at_end, then + // there will be two block headers: + // 1) header for the free space at end, msize = 1 + // 2) header inserted by set_tiny_meta_header_in_use after block + // We must clear the second one so that when the free block's size is + // queried, we do not think the block is only 1 quantum in size because + // of the second set header bit. if (szone->tiny_bytes_free_at_end) { - last_region = szone->tiny_regions[szone->num_tiny_regions-1]; - last_block = TINY_REGION_END(last_region) - szone->tiny_bytes_free_at_end; - tiny_free_list_add_ptr(szone, last_block, TINY_MSIZE_FOR_BYTES(szone->tiny_bytes_free_at_end)); - szone->tiny_bytes_free_at_end = 0; + last_block = TINY_REGION_END(szone->last_tiny_region) - szone->tiny_bytes_free_at_end; + last_msize = TINY_MSIZE_FOR_BYTES(szone->tiny_bytes_free_at_end); + last_header = TINY_BLOCK_HEADER_FOR_PTR(last_block); + last_index = TINY_INDEX_FOR_PTR(last_block); + + if (last_index != (NUM_TINY_BLOCKS - 1)) + BITARRAY_CLR(last_header, last_index + 1); + + tiny_free_list_add_ptr(szone, last_block, last_msize); + szone->tiny_bytes_free_at_end = 0; } // time to create a new region - aligned_address = allocate_pages(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_TINY)); - if (!aligned_address) { - // out of memory! - return NULL; - } + aligned_address = allocate_pages(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, 0, VM_MEMORY_MALLOC_TINY); + if (!aligned_address) // out of memory! + return NULL; // We set the padding after block_header to be all 1 - ((uint32_t *)(aligned_address + (1 << TINY_BLOCKS_ALIGN) + (NUM_TINY_BLOCKS >> 3)))[0] = ~0; - if (szone->num_tiny_regions == INITIAL_NUM_TINY_REGIONS) { - // XXX logic here fails after initial reallocation of tiny regions is exhausted (approx 4GB of - // tiny allocations) - new_regions = small_malloc_from_region_no_lock(szone, 16); // 16 * 512 bytes is plenty of tiny regions (more than 4,000) - if (!new_regions) return NULL; - memcpy(new_regions, szone->tiny_regions, INITIAL_NUM_TINY_REGIONS * sizeof(tiny_region_t)); - szone->tiny_regions = new_regions; // we set the pointer after it's all ready to enable enumeration from another thread without locking - } - szone->tiny_regions[szone->num_tiny_regions] = aligned_address; - szone->num_tiny_regions ++; // we set the number after the pointer is all ready to enable enumeration from another thread without taking the lock + ((uint32_t *)(aligned_address + TINY_HEADER_START + (NUM_TINY_BLOCKS >> 3)))[0] = ~0; + + // Check to see if the hash ring of tiny regions needs to grow. Try to + // avoid the hash ring becoming too dense. + if (szone->num_tiny_regions_allocated < (2 * szone->num_tiny_regions)) { + region_t *new_regions; + size_t new_size; + new_regions = hash_regions_grow_no_lock(szone, szone->tiny_regions, + szone->num_tiny_regions_allocated, + &new_size); + // Do not deallocate the current tiny_regions allocation since someone may + // be iterating it. Instead, just leak it. + szone->tiny_regions = new_regions; + szone->num_tiny_regions_allocated = new_size; + } + // Insert the new region into the hash ring, and update malloc statistics + hash_region_insert_no_lock(szone->tiny_regions, + szone->num_tiny_regions_allocated, + aligned_address); + szone->last_tiny_region = aligned_address; + + szone->num_tiny_regions++; ptr = aligned_address; set_tiny_meta_header_in_use(ptr, msize); szone->num_tiny_objects++; szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(msize); + // We put a header on the last block so that it appears in use (for coalescing, etc...) set_tiny_meta_header_in_use(ptr + TINY_BYTES_FOR_MSIZE(msize), 1); szone->tiny_bytes_free_at_end = TINY_BYTES_FOR_MSIZE(NUM_TINY_BLOCKS - msize); @@ -1198,7 +1330,7 @@ try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new SZONE_UNLOCK(szone); return 0; // next_block is in use; } - next_msize = TINY_FREE_SIZE(next_block); + next_msize = get_tiny_free_size(next_block); if (old_size + TINY_MSIZE_FOR_BYTES(next_msize) < new_size) { SZONE_UNLOCK(szone); return 0; // even with next block, not enough @@ -1224,24 +1356,25 @@ try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new } static boolean_t -tiny_check_region(szone_t *szone, tiny_region_t *region) +tiny_check_region(szone_t *szone, region_t region) { - uintptr_t start, ptr, region_end, follower; - boolean_t prev_free = 0; - boolean_t is_free; - msize_t msize; - free_list_t *free_head; + uintptr_t start, ptr, region_end; + boolean_t prev_free = 0; + boolean_t is_free; + msize_t msize; + free_list_t *free_head; + void *follower, *previous, *next; /* establish region limits */ - start = (uintptr_t)TINY_REGION_ADDRESS(*region); + start = (uintptr_t)TINY_REGION_ADDRESS(region); ptr = start; - region_end = (uintptr_t)TINY_REGION_END(*region); + region_end = (uintptr_t)TINY_REGION_END(region); /* * The last region may have a trailing chunk which has not been converted into inuse/freelist * blocks yet. */ - if (region == szone->tiny_regions + szone->num_tiny_regions - 1) + if (region == szone->last_tiny_region) region_end -= szone->tiny_bytes_free_at_end; @@ -1296,28 +1429,30 @@ tiny_check_region(szone_t *szone, tiny_region_t *region) */ free_head = (free_list_t *)ptr; free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); - if (free_head->previous && !tiny_meta_header_is_free(free_head->previous)) { + previous = free_list_unchecksum_ptr(free_head->previous); + next = free_list_unchecksum_ptr(free_head->next); + if (previous && !tiny_meta_header_is_free(previous)) { malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n", - ptr, free_head->previous); + ptr, previous); return 0; } - if (free_head->next && !tiny_meta_header_is_free(free_head->next)) { + if (next && !tiny_meta_header_is_free(next)) { malloc_printf("*** invariant broken for %p (next in free list %p is not a free pointer)\n", - ptr, free_head->next); + ptr, next); return 0; } /* * Check the free block's trailing size value. */ - follower = (uintptr_t)FOLLOWING_TINY_PTR(ptr, msize); - if ((follower != region_end) && (TINY_PREVIOUS_MSIZE(follower) != msize)) { + follower = FOLLOWING_TINY_PTR(ptr, msize); + if (((uintptr_t)follower != region_end) && (get_tiny_previous_free_msize(follower) != msize)) { malloc_printf("*** invariant broken for tiny free %p followed by %p in region [%p-%p] " "(end marker incorrect) should be %d; in fact %d\n", - ptr, follower, TINY_REGION_ADDRESS(*region), region_end, msize, TINY_PREVIOUS_MSIZE(follower)); + ptr, follower, TINY_REGION_ADDRESS(region), region_end, msize, get_tiny_previous_free_msize(follower)); return 0; } /* move to next block */ - ptr = follower; + ptr = (uintptr_t)follower; } } /* @@ -1330,7 +1465,7 @@ tiny_check_region(szone_t *szone, tiny_region_t *region) /* * Check the trailing block's integrity. */ - if (region == szone->tiny_regions + szone->num_tiny_regions - 1) { + if (region == szone->last_tiny_region) { if (szone->tiny_bytes_free_at_end) { msize = get_tiny_meta_header((void *)ptr, &is_free); if (is_free || (msize != 1)) { @@ -1342,215 +1477,254 @@ tiny_check_region(szone_t *szone, tiny_region_t *region) } static kern_return_t -tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned short num_regions, size_t tiny_bytes_free_at_end, memory_reader_t reader, vm_range_recorder_t recorder) +tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, vm_range_recorder_t recorder) { - tiny_region_t *regions; - unsigned index = 0; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - kern_return_t err; - tiny_region_t region; - vm_range_t range; - vm_range_t admin_range; - vm_range_t ptr_range; - unsigned char *mapped_region; - unsigned char *block_header; - unsigned char *in_use; - unsigned block_index; - unsigned block_limit; - boolean_t is_free; - msize_t msize; - void *mapped_ptr; - unsigned bit; - - err = reader(task, region_address, sizeof(tiny_region_t) * num_regions, (void **)®ions); - if (err) return err; - while (index < num_regions) { - // unsigned num_in_use = 0; - // unsigned num_free = 0; - region = regions[index]; - range.address = (vm_address_t)TINY_REGION_ADDRESS(region); - range.size = (vm_size_t)TINY_REGION_SIZE; - if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { - admin_range.address = range.address + (1 << TINY_BLOCKS_ALIGN); - admin_range.size = range.size - (1 << TINY_BLOCKS_ALIGN); - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); - } - if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { - ptr_range.address = range.address; - ptr_range.size = 1 << TINY_BLOCKS_ALIGN; - recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); - } - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - err = reader(task, range.address, range.size, (void **)&mapped_region); - if (err) - return err; - block_header = (unsigned char *)(mapped_region + (1 << TINY_BLOCKS_ALIGN)); - in_use = block_header + (NUM_TINY_BLOCKS >> 3) + 4; - block_index = 0; - block_limit = NUM_TINY_BLOCKS; - if (index == num_regions - 1) - block_limit -= TINY_MSIZE_FOR_BYTES(tiny_bytes_free_at_end); - while (block_index < block_limit) { - is_free = !BITARRAY_BIT(in_use, block_index); - if (is_free) { - mapped_ptr = mapped_region + TINY_BYTES_FOR_MSIZE(block_index); - msize = TINY_FREE_SIZE(mapped_ptr); - if (!msize) - break; - } else { - msize = 1; - bit = block_index + 1; - while (! BITARRAY_BIT(block_header, bit)) { - bit++; - msize ++; - } - buffer[count].address = range.address + TINY_BYTES_FOR_MSIZE(block_index); - buffer[count].size = TINY_BYTES_FOR_MSIZE(msize); - count++; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } - block_index += msize; - } - } - index++; - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - } - return 0; + size_t num_regions = szone->num_tiny_regions_allocated; + void *last_tiny_free = szone->last_tiny_free; + size_t index; + region_t *regions; + vm_range_t buffer[MAX_RECORDER_BUFFER]; + unsigned count = 0; + kern_return_t err; + region_t region; + vm_range_t range; + vm_range_t admin_range; + vm_range_t ptr_range; + unsigned char *mapped_region; + unsigned char *block_header; + unsigned char *in_use; + unsigned block_index; + unsigned block_limit; + boolean_t is_free; + msize_t msize; + void *mapped_ptr; + unsigned bit; + vm_address_t last_tiny_free_ptr = 0; + msize_t last_tiny_free_msize = 0; + + if (last_tiny_free) { + last_tiny_free_ptr = (uintptr_t) last_tiny_free & ~(TINY_QUANTUM - 1); + last_tiny_free_msize = (uintptr_t) last_tiny_free & (TINY_QUANTUM - 1); + } + + err = reader(task, (vm_address_t)szone->tiny_regions, sizeof(region_t) * num_regions, (void **)®ions); + if (err) return err; + for (index = 0; index < num_regions; ++index) { + region = regions[index]; + if (region) { + range.address = (vm_address_t)TINY_REGION_ADDRESS(region); + range.size = (vm_size_t)TINY_REGION_SIZE; + if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { + admin_range.address = range.address + TINY_HEADER_START; + admin_range.size = TINY_HEADER_SIZE; + recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); + } + if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { + ptr_range.address = range.address; + ptr_range.size = NUM_TINY_BLOCKS * TINY_QUANTUM; + recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); + } + if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + err = reader(task, range.address, range.size, (void **)&mapped_region); + if (err) + return err; + + block_header = (unsigned char *)(mapped_region + TINY_HEADER_START); + in_use = TINY_INUSE_FOR_HEADER(block_header); + block_index = 0; + block_limit = NUM_TINY_BLOCKS; + if (region == szone->last_tiny_region) + block_limit -= TINY_MSIZE_FOR_BYTES(szone->tiny_bytes_free_at_end); + + while (block_index < block_limit) { + vm_size_t block_offset = TINY_BYTES_FOR_MSIZE(block_index); + is_free = !BITARRAY_BIT(in_use, block_index); + if (is_free) { + mapped_ptr = mapped_region + block_offset; + + // mapped_region, the address at which 'range' in 'task' has been + // mapped into our process, is not necessarily aligned to + // TINY_BLOCKS_ALIGN. + // + // Since the code in get_tiny_free_size() assumes the pointer came + // from a properly aligned tiny region, and mapped_region is not + // necessarily aligned, then do the size calculation directly. + // If the next bit is set in the header bitmap, then the size is one + // quantum. Otherwise, read the size field. + if (!BITARRAY_BIT(block_header, block_index+1)) + msize = TINY_FREE_SIZE(mapped_ptr); + else + msize = 1; + + if (!msize) + break; + } else if (range.address + block_offset != last_tiny_free_ptr) { + msize = 1; + bit = block_index + 1; + while (! BITARRAY_BIT(block_header, bit)) { + bit++; + msize ++; + } + buffer[count].address = range.address + block_offset; + buffer[count].size = TINY_BYTES_FOR_MSIZE(msize); + count++; + if (count >= MAX_RECORDER_BUFFER) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + count = 0; + } + } else { + // Block is not free but it matches last_tiny_free_ptr so even + // though it is not marked free in the bitmap, we treat it as if + // it is and move on + msize = last_tiny_free_msize; + } + block_index += msize; + } + } + } + } + if (count) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + } + return 0; } -static INLINE void * +static void * tiny_malloc_from_free_list(szone_t *szone, msize_t msize) { // Assumes we've locked the region free_list_t *ptr; - msize_t this_msize; - grain_t slot = msize - 1; + msize_t this_msize; + grain_t slot = msize - 1; free_list_t **free_list = szone->tiny_free_list; free_list_t **the_slot = free_list + slot; free_list_t *next; free_list_t **limit; unsigned bitmap; - msize_t leftover_msize; + msize_t leftover_msize; free_list_t *leftover_ptr; - /* - * Look for an exact match by checking the freelist for this msize. - */ + // Assumes locked + CHECK_LOCKED(szone, __PRETTY_FUNCTION__); + + // Look for an exact match by checking the freelist for this msize. + // ptr = *the_slot; if (ptr) { - next = ptr->next; - if (next) { - next->previous = NULL; - free_list_set_checksum(szone, next); - } - *the_slot = next; - this_msize = msize; + next = free_list_unchecksum_ptr(ptr->next); + if (next) { + next->previous = ptr->previous; + } else { + BITMAP32_CLR(szone->tiny_bitmap, slot); + } + *the_slot = next; + this_msize = msize; #if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), exact match ptr=%p, this_msize=%d\n", ptr, this_msize); - } + if (LOG(szone, ptr)) { + malloc_printf("in tiny_malloc_from_free_list(), exact match ptr=%p, this_msize=%d\n", ptr, this_msize); + } #endif - goto return_tiny_alloc; + goto return_tiny_alloc; } - /* - * Iterate over freelists for larger blocks looking for the next-largest block. - */ + // Mask off the bits representing slots holding free blocks smaller than the + // size we need. If there are no larger free blocks, try allocating from + // the free space at the end of the tiny region. bitmap = szone->tiny_bitmap & ~ ((1 << slot) - 1); if (!bitmap) - goto try_tiny_malloc_from_end; - slot = BITMAP32_FFS(bitmap) - 1; + goto try_tiny_malloc_from_end; + + slot = BITMAP32_CTZ(bitmap); limit = free_list + NUM_TINY_SLOTS - 1; free_list += slot; + + // Iterate over freelists looking for free blocks, starting at first list + // which is not empty, and contains blocks which are large enough to satisfy + // our request. while (free_list < limit) { - // try bigger grains - ptr = *free_list; - if (ptr) { - next = ptr->next; - if (next) { - next->previous = NULL; - free_list_set_checksum(szone, next); - } - *free_list = next; - this_msize = TINY_FREE_SIZE(ptr); -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), bigger grain ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize); - } -#endif - goto add_leftover_and_proceed; - } - free_list++; - } - // we are now looking at the last slot (31) + ptr = *free_list; + if (ptr) { + next = free_list_unchecksum_ptr(ptr->next); + *free_list = next; + this_msize = get_tiny_free_size(ptr); + if (next) { + next->previous = ptr->previous; + } else { + BITMAP32_CLR(szone->tiny_bitmap, this_msize - 1); + } + goto add_leftover_and_proceed; + } + free_list++; + } + + // We are now looking at the last slot, which contains blocks equal to, or + // due to coalescing of free blocks, larger than 31 * tiny quantum size. + // If the last freelist is not empty, and the head contains a block that is + // larger than our request, then the remainder is put back on the free list. ptr = *limit; if (ptr) { - this_msize = TINY_FREE_SIZE(ptr); - next = ptr->next; - if (this_msize - msize >= NUM_TINY_SLOTS) { - // the leftover will go back to the free list, so we optimize by modifying the free list rather than removing the head and then adding back - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); - *limit = leftover_ptr; - if (next) { - next->previous = leftover_ptr; - free_list_set_checksum(szone, next); - } - leftover_ptr->next = next; - leftover_ptr->previous = NULL; - free_list_set_checksum(szone, leftover_ptr); - set_tiny_meta_header_free(leftover_ptr, leftover_msize); + free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); + this_msize = get_tiny_free_size(ptr); + next = free_list_unchecksum_ptr(ptr->next); + if (this_msize - msize >= NUM_TINY_SLOTS) { + // the leftover will go back to the free list, so we optimize by + // modifying the free list rather than a pop and push of the head + leftover_msize = this_msize - msize; + leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); + *limit = leftover_ptr; + if (next) { + next->previous.u = free_list_checksum_ptr(leftover_ptr); + } + leftover_ptr->previous = ptr->previous; + leftover_ptr->next = ptr->next; + set_tiny_meta_header_free(leftover_ptr, leftover_msize); #if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize); - } + if (LOG(szone,ptr)) { + malloc_printf("in tiny_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize); + } #endif - this_msize = msize; - goto return_tiny_alloc; - } - *limit = next; - if (next) { - next->previous = NULL; - free_list_set_checksum(szone, next); - } - goto add_leftover_and_proceed; + this_msize = msize; + goto return_tiny_alloc; + } + if (next) { + next->previous = ptr->previous; + } + *limit = next; + goto add_leftover_and_proceed; } + try_tiny_malloc_from_end: // Let's see if we can use szone->tiny_bytes_free_at_end if (szone->tiny_bytes_free_at_end >= TINY_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)(TINY_REGION_END(szone->tiny_regions[szone->num_tiny_regions-1]) - szone->tiny_bytes_free_at_end); - szone->tiny_bytes_free_at_end -= TINY_BYTES_FOR_MSIZE(msize); - if (szone->tiny_bytes_free_at_end) { - // let's add an in use block after ptr to serve as boundary - set_tiny_meta_header_in_use((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize), 1); - } - this_msize = msize; + ptr = (free_list_t *)(TINY_REGION_END(szone->last_tiny_region) - szone->tiny_bytes_free_at_end); + szone->tiny_bytes_free_at_end -= TINY_BYTES_FOR_MSIZE(msize); + if (szone->tiny_bytes_free_at_end) { + // let's add an in use block after ptr to serve as boundary + set_tiny_meta_header_in_use((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize), 1); + } + this_msize = msize; #if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), from end ptr=%p, msize=%d\n", ptr, msize); - } + if (LOG(szone, ptr)) { + malloc_printf("in tiny_malloc_from_free_list(), from end ptr=%p, msize=%d\n", ptr, msize); + } #endif - goto return_tiny_alloc; + goto return_tiny_alloc; } return NULL; + add_leftover_and_proceed: if (!this_msize || (this_msize > msize)) { - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); + leftover_msize = this_msize - msize; + leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); #if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); - } + if (LOG(szone,ptr)) { + malloc_printf("in tiny_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); + } #endif - tiny_free_list_add_ptr(szone, leftover_ptr, leftover_msize); - this_msize = msize; + tiny_free_list_add_ptr(szone, leftover_ptr, leftover_msize); + this_msize = msize; } + return_tiny_alloc: szone->num_tiny_objects++; szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(this_msize); @@ -1571,7 +1745,7 @@ tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_reques #if DEBUG_MALLOC if (!msize) { - szone_error(szone, "invariant broken (!msize) in allocation (region)", NULL); + szone_error(szone, "invariant broken (!msize) in allocation (region)", NULL, NULL); return(NULL); } #endif @@ -1616,7 +1790,7 @@ tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_reques } static INLINE void -free_tiny(szone_t *szone, void *ptr, tiny_region_t *tiny_region) +free_tiny(szone_t *szone, void *ptr, region_t *tiny_region) { msize_t msize; boolean_t is_free; @@ -1630,13 +1804,13 @@ free_tiny(szone_t *szone, void *ptr, tiny_region_t *tiny_region) ptr2 = szone->last_tiny_free; /* check that we don't already have this pointer in the cache */ if (ptr == (void *)((uintptr_t)ptr2 & ~ (TINY_QUANTUM - 1))) { - szone_error(szone, "double free", ptr); + szone_error(szone, "double free", ptr, NULL); return; } #endif /* TINY_CACHE */ msize = get_tiny_meta_header(ptr, &is_free); if (is_free) { - szone_error(szone, "double free", ptr); + szone_error(szone, "double free", ptr, NULL); return; } #if DEBUG_MALLOC @@ -1647,7 +1821,9 @@ free_tiny(szone_t *szone, void *ptr, tiny_region_t *tiny_region) #endif #if TINY_CACHE if (msize < TINY_QUANTUM) { // to see if the bits fit in the last 4 bits - szone->last_tiny_free = (void *)(((uintptr_t)ptr) | msize); + if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) + memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize)); + szone->last_tiny_free = (void *)(((uintptr_t)ptr) | msize); if (!ptr2) { SZONE_UNLOCK(szone); CHECK(szone, __PRETTY_FUNCTION__); @@ -1657,7 +1833,7 @@ free_tiny(szone_t *szone, void *ptr, tiny_region_t *tiny_region) ptr = (void *)(((uintptr_t)ptr2) & ~(TINY_QUANTUM - 1)); tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); if (!tiny_region) { - szone_error(szone, "double free (tiny cache)", ptr); + szone_error(szone, "double free (tiny cache)", ptr, NULL); } } #endif @@ -1671,19 +1847,24 @@ print_tiny_free_list(szone_t *szone) { grain_t slot = 0; free_list_t *ptr; - - malloc_printf("tiny free sizes: "); - while (slot < NUM_TINY_SLOTS) { - ptr = szone->tiny_free_list[slot]; - if (ptr) { - malloc_printf("%s%y[%d]; ", (slot == NUM_TINY_SLOTS-1) ? ">=" : "", (slot+1)*TINY_QUANTUM, free_list_count(ptr)); + _SIMPLE_STRING b = _simple_salloc(); + + if (b) { + _simple_sappend(b, "tiny free sizes: "); + while (slot < NUM_TINY_SLOTS) { + ptr = szone->tiny_free_list[slot]; + if (ptr) { + _simple_sprintf(b, "%s%y[%d]; ", (slot == NUM_TINY_SLOTS-1) ? ">=" : "", (slot+1)*TINY_QUANTUM, free_list_count(ptr)); + } + slot++; } - slot++; + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); } } static void -print_tiny_region(boolean_t verbose, tiny_region_t region, size_t bytes_at_end) +print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_end) { unsigned counts[1024]; unsigned in_use = 0; @@ -1693,6 +1874,7 @@ print_tiny_region(boolean_t verbose, tiny_region_t region, size_t bytes_at_end) boolean_t is_free; msize_t msize; unsigned ci; + _SIMPLE_STRING b; memset(counts, 0, 1024 * sizeof(unsigned)); while (current < limit) { @@ -1715,16 +1897,19 @@ print_tiny_region(boolean_t verbose, tiny_region_t region, size_t bytes_at_end) } current += TINY_BYTES_FOR_MSIZE(msize); } - malloc_printf("Tiny region [%p-%p, %y]\t", (void *)start, TINY_REGION_END(region), (int)TINY_REGION_SIZE); - malloc_printf("In_use=%d ", in_use); - if (bytes_at_end) malloc_printf("untouched=%y ", bytes_at_end); - if (verbose && in_use) { - malloc_printf("\tSizes in use: "); - for (ci = 0; ci < 1024; ci++) - if (counts[ci]) - malloc_printf("%d[%d]", TINY_BYTES_FOR_MSIZE(ci), counts[ci]); + if ((b = _simple_salloc()) != NULL) { + _simple_sprintf(b, "Tiny region [%p-%p, %y]\t", (void *)start, TINY_REGION_END(region), (int)TINY_REGION_SIZE); + _simple_sprintf(b, "In_use=%d ", in_use); + if (bytes_at_end) _simple_sprintf(b, "untouched=%ly", bytes_at_end); + if (verbose && in_use) { + _simple_sappend(b, "\n\tSizes in use: "); + for (ci = 0; ci < 1024; ci++) + if (counts[ci]) + _simple_sprintf(b, "%d[%d]", TINY_BYTES_FOR_MSIZE(ci), counts[ci]); + } + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); } - malloc_printf("\n"); } static boolean_t @@ -1737,27 +1922,27 @@ tiny_free_list_check(szone_t *szone, grain_t slot) CHECK_LOCKED(szone, __PRETTY_FUNCTION__); while (ptr) { - free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); - is_free = tiny_meta_header_is_free(ptr); - if (! is_free) { - malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - return 0; - } - if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { - malloc_printf("*** inaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - return 0; - } - if (!tiny_region_for_ptr_no_lock(szone, ptr)) { - malloc_printf("*** itr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr); - return 0; - } - if (ptr->previous != previous) { - malloc_printf("*** irevious incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr); - return 0; - } - previous = ptr; - ptr = ptr->next; - count++; + free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); + is_free = tiny_meta_header_is_free(ptr); + if (! is_free) { + malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); + return 0; + } + if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { + malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); + return 0; + } + if (!tiny_region_for_ptr_no_lock(szone, ptr)) { + malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr); + return 0; + } + if (free_list_unchecksum_ptr(ptr->previous) != previous) { + malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr); + return 0; + } + previous = ptr; + ptr = free_list_unchecksum_ptr(ptr->next); + count++; } return 1; } @@ -1771,7 +1956,6 @@ 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) { - meta_headers[index] = msize | SMALL_IS_FREE; } @@ -1782,7 +1966,6 @@ small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msi static INLINE void small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) { - meta_headers[index] = msize; } @@ -1792,7 +1975,6 @@ small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize static INLINE void small_meta_header_set_middle(msize_t *meta_headers, msize_t index) { - meta_headers[index] = 0; } @@ -1802,42 +1984,39 @@ small_meta_header_set_middle(msize_t *meta_headers, msize_t index) static void small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) { - grain_t grain = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1; + grain_t slot = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1; free_list_t *free_ptr = ptr; - free_list_t *free_head = szone->small_free_list[grain]; + free_list_t *free_head = szone->small_free_list[slot]; void *follower; - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); #if DEBUG_MALLOC if (LOG(szone,ptr)) { - malloc_printf("in small_free_list_add_ptr(), ptr=%p, msize=%d\n", ptr, msize); + malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); } if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { - szone_error(szone, "small_free_list_add_ptr: Unaligned ptr", ptr); + szone_error(szone, "small_free_list_add_ptr: Unaligned ptr", ptr, NULL); } #endif if (free_head) { - free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); + free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); #if DEBUG_MALLOC - if (free_head->previous) { - malloc_printf("ptr=%p grain=%d free_head=%p previous=%p\n", - ptr, grain, free_head, free_head->previous); - szone_error(szone, "small_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr); - } - if (!SMALL_PTR_IS_FREE(free_head)) { - malloc_printf("ptr=%p grain=%d free_head=%p\n", ptr, grain, free_head); - szone_error(szone, "small_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr); - } + if (free_list_unchecksum_ptr(free_head->previous)) { + szone_error(szone, "small_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr, + "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, free_head, free_head->previous.p); + } + if (!SMALL_PTR_IS_FREE(free_head)) { + szone_error(szone, "small_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr, + "ptr=%p slot=%d free_head=%p\n", ptr, slot, free_head); + } #endif - free_head->previous = free_ptr; - free_list_set_checksum(szone, free_head); + free_head->previous.u = free_list_checksum_ptr(free_ptr); } else { - BITMAP32_SET(szone->small_bitmap, grain); + BITMAP32_SET(szone->small_bitmap, slot); } - free_ptr->previous = NULL; - free_ptr->next = free_head; + free_ptr->previous.p = NULL; + free_ptr->next.p = free_head; free_list_set_checksum(szone, free_ptr); - szone->small_free_list[grain] = free_ptr; + szone->small_free_list[slot] = free_ptr; follower = ptr + SMALL_BYTES_FOR_MSIZE(msize); SMALL_PREVIOUS_MSIZE(follower) = msize; } @@ -1848,58 +2027,52 @@ small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) static void small_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize) { - grain_t grain = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1; - free_list_t *free_ptr = ptr; - free_list_t *next = free_ptr->next; - free_list_t *previous = free_ptr->previous; + grain_t slot = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1; + free_list_t *free_ptr = ptr, *next, *previous; + free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__); + + next = free_list_unchecksum_ptr(free_ptr->next); + previous = free_list_unchecksum_ptr(free_ptr->previous); - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); #if DEBUG_MALLOC if (LOG(szone,ptr)) { - malloc_printf("in small_free_list_remove_ptr(), ptr=%p, msize=%d\n", ptr, msize); + malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); } #endif - free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__); - if (!previous) { + if (!previous) { + // The block to remove is the head of the free list #if DEBUG_MALLOC - if (szone->small_free_list[grain] != ptr) { - malloc_printf("ptr=%p grain=%d msize=%d szone->small_free_list[grain]=%p\n", - ptr, grain, msize, szone->small_free_list[grain]); - szone_error(szone, "small_free_list_remove_ptr: Internal invariant broken (szone->small_free_list[grain])", ptr); - return; - } + if (szone->small_free_list[slot] != ptr) { + szone_error(szone, "small_free_list_remove_ptr: Internal invariant broken (szone->small_free_list[grain])", ptr, + "ptr=%p slot=%d msize=%d szone->small_free_list[slot]=%p\n", + ptr, slot, msize, szone->small_free_list[slot]); + return; + } #endif - szone->small_free_list[grain] = next; - if (!next) BITMAP32_CLR(szone->small_bitmap, grain); + szone->small_free_list[slot] = next; + if (!next) BITMAP32_CLR(szone->small_bitmap, slot); } else { - previous->next = next; - free_list_set_checksum(szone, previous); + // We know free_ptr is already checksummed, so we don't need to do it + // again. + previous->next = free_ptr->next; } if (next) { - next->previous = previous; - free_list_set_checksum(szone, next); + // We know free_ptr is already checksummed, so we don't need to do it + // again. + next->previous = free_ptr->previous; } } -static INLINE small_region_t * +static INLINE region_t * small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) { - small_region_t *region; - small_region_t rbase; - int i; - - /* find assumed heap/region base */ - rbase = SMALL_REGION_FOR_PTR(ptr); - - /* scan existing regions for a match */ - for (i = szone->num_small_regions, region = szone->small_regions; i > 0; i--, region++) - if (rbase == *region) - return(region); - return(NULL); + return hash_lookup_region_no_lock(szone->small_regions, + szone->num_small_regions_allocated, + SMALL_REGION_FOR_PTR(ptr)); } static INLINE void -small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t msize) +small_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize) { msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); unsigned index = SMALL_META_INDEX_FOR_PTR(ptr); @@ -1916,8 +2089,8 @@ small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t ms malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); } if (! msize) { - malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - szone_error(szone, "trying to free small block that is too small", ptr); + szone_error(szone, "trying to free small block that is too small", ptr, + "in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); } #endif // We try to coalesce this block with the preceeding one @@ -1951,7 +2124,7 @@ small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t ms } if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) { if (!msize) { - szone_error(szone, "incorrect size information - block header was damaged", ptr); + szone_error(szone, "incorrect size information - block header was damaged", ptr, NULL); } else { memset(ptr, 0x55, SMALL_BYTES_FOR_MSIZE(msize)); } @@ -1965,55 +2138,57 @@ small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t ms static void * small_malloc_from_region_no_lock(szone_t *szone, msize_t msize) { - small_region_t last_region; void *last_block; void *ptr; void *new_address; msize_t *meta_headers; msize_t index ; - size_t region_capacity; - msize_t new_msize; - small_region_t *new_regions; msize_t msize_left; // Allocates from the last region or a freshly allocated region CHECK_LOCKED(szone, __PRETTY_FUNCTION__); // Before anything we transform the small_bytes_free_at_end - if any - to a regular free block if (szone->small_bytes_free_at_end) { - last_region = szone->small_regions[szone->num_small_regions - 1]; - last_block = (void *)(SMALL_REGION_END(last_region) - szone->small_bytes_free_at_end); - small_free_list_add_ptr(szone, last_block, SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end)); - *SMALL_METADATA_FOR_PTR(last_block) = SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end) | SMALL_IS_FREE; - szone->small_bytes_free_at_end = 0; + last_block = (void *)(SMALL_REGION_END(szone->last_small_region) - szone->small_bytes_free_at_end); + small_free_list_add_ptr(szone, last_block, SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end)); + *SMALL_METADATA_FOR_PTR(last_block) = SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end) | SMALL_IS_FREE; + szone->small_bytes_free_at_end = 0; } // time to create a new region - new_address = allocate_pages(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_SMALL)); - if (!new_address) { - // out of memory! - return NULL; - } + new_address = allocate_pages(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, + 0, VM_MEMORY_MALLOC_SMALL); + if (!new_address) + return NULL; + ptr = new_address; meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); index = 0; - if (szone->num_small_regions == INITIAL_NUM_SMALL_REGIONS) { - // time to grow the number of regions - region_capacity = (1 << (32 - SMALL_BLOCKS_ALIGN)) - 20; // that is for sure the maximum number of small regions we can have - new_msize = (region_capacity * sizeof(small_region_t) + SMALL_QUANTUM - 1) / SMALL_QUANTUM; - new_regions = ptr; - small_meta_header_set_in_use(meta_headers, index, new_msize); - szone->num_small_objects++; - szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(new_msize); - memcpy(new_regions, szone->small_regions, INITIAL_NUM_SMALL_REGIONS * sizeof(small_region_t)); - // We intentionally leak the previous regions pointer to avoid multi-threading crashes if - // another thread was reading it (unlocked) while we are changing it. - szone->small_regions = new_regions; // note we set this pointer after it's all set - ptr += SMALL_BYTES_FOR_MSIZE(new_msize); - index = new_msize; - } - szone->small_regions[szone->num_small_regions] = new_address; - // we bump the number of regions AFTER we have changes the regions pointer to enable finding a - // small region without taking the lock - // XXX naive assumption assumes memory ordering coherence between this and other CPUs + + // Check to see if the hash ring of small regions needs to grow. Try to + // avoid the hash ring becoming too dense. + if (szone->num_small_regions_allocated < (2 * szone->num_small_regions)) { + region_t *new_regions; + size_t new_size; + new_regions = hash_regions_grow_no_lock(szone, szone->small_regions, + szone->num_small_regions_allocated, + &new_size); + // Do not deallocate the current small_regions allocation since someone + // may be iterating it. Instead, just leak it. + szone->small_regions = new_regions; + szone->num_small_regions_allocated = new_size; + } + // Insert the new region into the hash ring, and update malloc statistics + hash_region_insert_no_lock(szone->small_regions, + szone->num_small_regions_allocated, + new_address); + szone->last_small_region = new_address; + + // we bump the number of regions AFTER we have changes the regions pointer + // to enable finding a small region without taking the lock + // + // FIXME: naive assumption assumes memory ordering coherence between this + // and other CPUs. This also applies to the near-identical code in + // tiny_malloc_from_region_no_lock. szone->num_small_regions++; small_meta_header_set_in_use(meta_headers, index, msize); msize_left = NUM_SMALL_BLOCKS - index; @@ -2047,7 +2222,7 @@ try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t ne } #if DEBUG_MALLOC if ((uintptr_t)next_block & (SMALL_QUANTUM - 1)) { - szone_error(szone, "internal invariant broken in realloc(next_block)", next_block); + szone_error(szone, "internal invariant broken in realloc(next_block)", next_block, NULL); } if (meta_headers[index] != old_msize) malloc_printf("*** try_realloc_small_in_place incorrect old %d %d\n", @@ -2096,20 +2271,21 @@ try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t ne } static boolean_t -szone_check_small_region(szone_t *szone, small_region_t *region) +szone_check_small_region(szone_t *szone, region_t region) { - unsigned char *ptr = SMALL_REGION_ADDRESS(*region); + unsigned char *ptr = SMALL_REGION_ADDRESS(region); msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - unsigned char *region_end = SMALL_REGION_END(*region); + unsigned char *region_end = SMALL_REGION_END(region); msize_t prev_free = 0; unsigned index; msize_t msize_and_free; msize_t msize; free_list_t *free_head; + void *previous, *next; msize_t *follower; CHECK_LOCKED(szone, __PRETTY_FUNCTION__); - if (region == szone->small_regions + szone->num_small_regions - 1) region_end -= szone->small_bytes_free_at_end; + if (region == szone->last_small_region) region_end -= szone->small_bytes_free_at_end; while (ptr < region_end) { index = SMALL_META_INDEX_FOR_PTR(ptr); msize_and_free = meta_headers[index]; @@ -2117,8 +2293,8 @@ szone_check_small_region(szone_t *szone, small_region_t *region) // block is in use msize = msize_and_free; if (!msize) { - malloc_printf("*** invariant broken: null msize ptr=%p region#=%d num_small_regions=%d end=%p\n", - ptr, region - szone->small_regions, szone->num_small_regions, (void *)region_end); + malloc_printf("*** invariant broken: null msize ptr=%p num_small_regions=%d end=%p\n", + ptr, szone->num_small_regions, region_end); return 0; } if (msize > (LARGE_THRESHOLD / SMALL_QUANTUM)) { @@ -2142,19 +2318,21 @@ szone_check_small_region(szone_t *szone, small_region_t *region) return 0; } free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); - if (free_head->previous && !SMALL_PTR_IS_FREE(free_head->previous)) { + previous = free_list_unchecksum_ptr(free_head->previous); + next = free_list_unchecksum_ptr(free_head->next); + if (previous && !SMALL_PTR_IS_FREE(previous)) { malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n", ptr, free_head->previous); return 0; } - if (free_head->next && !SMALL_PTR_IS_FREE(free_head->next)) { + if (next && !SMALL_PTR_IS_FREE(next)) { malloc_printf("*** invariant broken for %p (next is not a free pointer)\n", ptr); return 0; } if (SMALL_PREVIOUS_MSIZE(follower) != msize) { malloc_printf("*** invariant broken for small free %p followed by %p in region [%p-%p] " "(end marker incorrect) should be %d; in fact %d\n", - ptr, follower, SMALL_REGION_ADDRESS(*region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower)); + ptr, follower, SMALL_REGION_ADDRESS(region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower)); return 0; } ptr = (unsigned char *)follower; @@ -2165,148 +2343,183 @@ szone_check_small_region(szone_t *szone, small_region_t *region) } static kern_return_t -small_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned short num_regions, size_t small_bytes_free_at_end, memory_reader_t reader, vm_range_recorder_t recorder) +small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, vm_range_recorder_t recorder) { - small_region_t *regions; - unsigned index = 0; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - kern_return_t err; - small_region_t region; - vm_range_t range; - vm_range_t admin_range; - vm_range_t ptr_range; - unsigned char *mapped_region; - msize_t *block_header; - unsigned block_index; - unsigned block_limit; - msize_t msize_and_free; - msize_t msize; - - err = reader(task, region_address, sizeof(small_region_t) * num_regions, (void **)®ions); - if (err) return err; - while (index < num_regions) { - region = regions[index]; - range.address = (vm_address_t)SMALL_REGION_ADDRESS(region); - range.size = SMALL_REGION_SIZE; - if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { - admin_range.address = range.address + (1 << SMALL_BLOCKS_ALIGN); - admin_range.size = range.size - (1 << SMALL_BLOCKS_ALIGN); - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); - } - if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { - ptr_range.address = range.address; - ptr_range.size = 1 << SMALL_BLOCKS_ALIGN; - recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); - } - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - err = reader(task, range.address, range.size, (void **)&mapped_region); - if (err) return err; - block_header = (msize_t *)(mapped_region + (1 << SMALL_BLOCKS_ALIGN)); - block_index = 0; - block_limit = NUM_SMALL_BLOCKS; - if (index == num_regions - 1) - block_limit -= SMALL_MSIZE_FOR_BYTES(small_bytes_free_at_end); - while (block_index < block_limit) { - msize_and_free = block_header[block_index]; - msize = msize_and_free & ~ SMALL_IS_FREE; - if (! (msize_and_free & SMALL_IS_FREE)) { - // Block in use - buffer[count].address = range.address + SMALL_BYTES_FOR_MSIZE(block_index); - buffer[count].size = SMALL_BYTES_FOR_MSIZE(msize); - count++; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } - block_index += msize; - } - } - index++; - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - } - return 0; + size_t num_regions = szone->num_small_regions_allocated; + void *last_small_free = szone->last_small_free; + size_t index; + region_t *regions; + vm_range_t buffer[MAX_RECORDER_BUFFER]; + unsigned count = 0; + kern_return_t err; + region_t region; + vm_range_t range; + vm_range_t admin_range; + vm_range_t ptr_range; + unsigned char *mapped_region; + msize_t *block_header; + unsigned block_index; + unsigned block_limit; + msize_t msize_and_free; + msize_t msize; + vm_address_t last_small_free_ptr = 0; + msize_t last_small_free_msize = 0; + + if (last_small_free) { + last_small_free_ptr = (uintptr_t)last_small_free & ~(SMALL_QUANTUM - 1); + last_small_free_msize = (uintptr_t)last_small_free & (SMALL_QUANTUM - 1); + } + + err = reader(task, (vm_address_t)szone->small_regions, sizeof(region_t) * num_regions, (void **)®ions); + if (err) return err; + for (index = 0; index < num_regions; ++index) { + region = regions[index]; + if (region) { + range.address = (vm_address_t)SMALL_REGION_ADDRESS(region); + range.size = SMALL_REGION_SIZE; + if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { + admin_range.address = range.address + SMALL_HEADER_START; + admin_range.size = SMALL_ARRAY_SIZE; + recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); + } + if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { + ptr_range.address = range.address; + ptr_range.size = NUM_SMALL_BLOCKS * SMALL_QUANTUM; + recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); + } + if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + err = reader(task, range.address, range.size, (void **)&mapped_region); + if (err) return err; + block_header = (msize_t *)(mapped_region + SMALL_HEADER_START); + block_index = 0; + block_limit = NUM_SMALL_BLOCKS; + if (region == szone->last_small_region) + block_limit -= SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end); + while (block_index < block_limit) { + msize_and_free = block_header[block_index]; + msize = msize_and_free & ~ SMALL_IS_FREE; + if (! (msize_and_free & SMALL_IS_FREE) && + range.address + SMALL_BYTES_FOR_MSIZE(block_index) != last_small_free_ptr) { + // Block in use + buffer[count].address = range.address + SMALL_BYTES_FOR_MSIZE(block_index); + buffer[count].size = SMALL_BYTES_FOR_MSIZE(msize); + count++; + if (count >= MAX_RECORDER_BUFFER) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + count = 0; + } + } + block_index += msize; + } + } + } + } + if (count) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + } + return 0; } -static INLINE void * +static void * small_malloc_from_free_list(szone_t *szone, msize_t msize) { - grain_t grain = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1; - unsigned bitmap = szone->small_bitmap & ~ ((1 << grain) - 1); - void *ptr; - msize_t this_msize; - free_list_t **free_list; - free_list_t **limit; - free_list_t *next; - msize_t leftover_msize; - void *leftover_ptr; - msize_t *meta_headers; - unsigned leftover_index; + free_list_t *ptr; + msize_t this_msize; + grain_t slot = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1; + free_list_t **free_list = szone->small_free_list; + free_list_t *next; + free_list_t **limit; + unsigned bitmap = szone->small_bitmap & ~ ((1 << slot) - 1); + msize_t leftover_msize; + free_list_t *leftover_ptr; + msize_t *meta_headers; + unsigned leftover_index; // Assumes locked CHECK_LOCKED(szone, __PRETTY_FUNCTION__); - if (!bitmap) goto try_small_from_end; - grain = BITMAP32_FFS(bitmap) - 1; - // first try the small grains - limit = szone->small_free_list + NUM_SMALL_SLOTS - 1; - free_list = szone->small_free_list + grain; + // Mask off the bits representing slots holding free blocks smaller than the + // size we need. If there are no larger free blocks, try allocating from + // the free space at the end of the tiny region. + if (!bitmap) + goto try_small_from_end; + + slot = BITMAP32_CTZ(bitmap); + limit = free_list + NUM_SMALL_SLOTS - 1; + free_list += slot; + + // Iterate over freelists looking for free blocks, starting at first list + // which is not empty, and contains blocks which are large enough to satisfy + // our request. while (free_list < limit) { - // try bigger grains - ptr = *free_list; - if (ptr) { - next = ((free_list_t *)ptr)->next; - if (next) { - next->previous = NULL; - free_list_set_checksum(szone, next); - } - *free_list = next; - this_msize = SMALL_PTR_SIZE(ptr); - goto add_leftover_and_proceed; - } - free_list++; - } - // We now check the large grains for one that is big enough - ptr = *free_list; + ptr = *free_list; + if (ptr) { + next = free_list_unchecksum_ptr(ptr->next); + *free_list = next; + this_msize = SMALL_PTR_SIZE(ptr); + if (next) { + next->previous = ptr->previous; + } else { + BITMAP32_CLR(szone->small_bitmap, this_msize - 1); + } + goto add_leftover_and_proceed; + } + free_list++; + } + + // We are now looking at the last slot, which contains blocks equal to, or + // due to coalescing of free blocks, larger than 31 * small quantum size. + // If the last freelist is not empty, and the head contains a block that is + // larger than our request, then the remainder is put back on the free list. + // + // FIXME: This code doesn't have the optimization from the 'tiny' codepath + // that optimizes for the this_msize >= 2 * num slots + // FIXME: this code also seems somewhat bogus. There's a check for + // this_msize >= msize, but by definition we can't ask for a small + // block larger than 31 small quanta, and every free block in this + // slot has to be at least that large. + ptr = *limit; while (ptr) { - this_msize = SMALL_PTR_SIZE(ptr); - if (this_msize >= msize) { - small_free_list_remove_ptr(szone, ptr, this_msize); - goto add_leftover_and_proceed; - } - ptr = ((free_list_t *)ptr)->next; + free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); + next = free_list_unchecksum_ptr(ptr->next); + this_msize = SMALL_PTR_SIZE(ptr); + if (this_msize >= msize) { + small_free_list_remove_ptr(szone, ptr, this_msize); + goto add_leftover_and_proceed; + } + ptr = next; } + try_small_from_end: // Let's see if we can use szone->small_bytes_free_at_end if (szone->small_bytes_free_at_end >= SMALL_BYTES_FOR_MSIZE(msize)) { - ptr = (void *)(SMALL_REGION_END(szone->small_regions[szone->num_small_regions-1]) - szone->small_bytes_free_at_end); - szone->small_bytes_free_at_end -= SMALL_BYTES_FOR_MSIZE(msize); - if (szone->small_bytes_free_at_end) { - // let's mark this block as in use to serve as boundary - *SMALL_METADATA_FOR_PTR(ptr + SMALL_BYTES_FOR_MSIZE(msize)) = SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end); - } - this_msize = msize; - goto return_small_alloc; + ptr = (free_list_t *)(SMALL_REGION_END(szone->last_small_region) - szone->small_bytes_free_at_end); + szone->small_bytes_free_at_end -= SMALL_BYTES_FOR_MSIZE(msize); + if (szone->small_bytes_free_at_end) { + // let's mark this block as in use to serve as boundary + *SMALL_METADATA_FOR_PTR((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)) = SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end); + } + this_msize = msize; + goto return_small_alloc; } return NULL; + add_leftover_and_proceed: if (this_msize > msize) { - leftover_msize = this_msize - msize; - leftover_ptr = ptr + SMALL_BYTES_FOR_MSIZE(msize); + leftover_msize = this_msize - msize; + leftover_ptr = (free_list_t *)((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)); #if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); - } + if (LOG(szone,ptr)) { + malloc_printf("in small_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); + } #endif - small_free_list_add_ptr(szone, leftover_ptr, leftover_msize); - meta_headers = SMALL_META_HEADER_FOR_PTR(leftover_ptr); - leftover_index = SMALL_META_INDEX_FOR_PTR(leftover_ptr); - small_meta_header_set_is_free(meta_headers, leftover_index, leftover_msize); - this_msize = msize; + small_free_list_add_ptr(szone, leftover_ptr, leftover_msize); + meta_headers = SMALL_META_HEADER_FOR_PTR(leftover_ptr); + leftover_index = SMALL_META_INDEX_FOR_PTR(leftover_ptr); + small_meta_header_set_is_free(meta_headers, leftover_index, leftover_msize); + this_msize = msize; } + return_small_alloc: szone->num_small_objects++; szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(this_msize); @@ -2383,38 +2596,43 @@ small_malloc_cleared_no_lock(szone_t *szone, msize_t msize) } static INLINE void -free_small(szone_t *szone, void *ptr, small_region_t *small_region) +free_small(szone_t *szone, void *ptr, region_t *small_region) { - msize_t msize_and_free; + msize_t msize = SMALL_PTR_SIZE(ptr); #if SMALL_CACHE void *ptr2; #endif // ptr is known to be in small_region - msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); - if (msize_and_free & SMALL_IS_FREE) { - szone_error(szone, "Object already freed being freed", ptr); - return; - } - CHECK(szone, __PRETTY_FUNCTION__); SZONE_LOCK(szone); #if SMALL_CACHE ptr2 = szone->last_small_free; - szone->last_small_free = (void *)(((uintptr_t)ptr) | msize_and_free); + /* check that we don't already have this pointer in the cache */ + if (ptr == (void *)((uintptr_t)ptr2 & ~ (SMALL_QUANTUM - 1))) { + szone_error(szone, "double free", ptr, NULL); + return; + } +#endif + if (SMALL_PTR_IS_FREE(ptr)) { + szone_error(szone, "double free", ptr, NULL); + return; + } +#if SMALL_CACHE + szone->last_small_free = (void *)(((uintptr_t)ptr) | msize); if (!ptr2) { SZONE_UNLOCK(szone); CHECK(szone, __PRETTY_FUNCTION__); return; } - msize_and_free = (uintptr_t)ptr2 & (SMALL_QUANTUM - 1); + msize = (uintptr_t)ptr2 & (SMALL_QUANTUM - 1); ptr = (void *)(((uintptr_t)ptr2) & ~ (SMALL_QUANTUM - 1)); small_region = small_region_for_ptr_no_lock(szone, ptr); if (!small_region) { - szone_error(szone, "double free (small cache)", ptr); + szone_error(szone, "double free (small cache)", ptr, NULL); return; } #endif - small_free_no_lock(szone, small_region, ptr, msize_and_free); + small_free_no_lock(szone, small_region, ptr, msize); SZONE_UNLOCK(szone); CHECK(szone, __PRETTY_FUNCTION__); } @@ -2424,28 +2642,33 @@ print_small_free_list(szone_t *szone) { grain_t grain = 0; free_list_t *ptr; + _SIMPLE_STRING b = _simple_salloc(); - malloc_printf("small free sizes: "); - while (grain < NUM_SMALL_SLOTS) { - ptr = szone->small_free_list[grain]; - if (ptr) { - malloc_printf("%s%y[%d]; ", (grain == NUM_SMALL_SLOTS-1) ? ">=" : "", (grain + 1) * SMALL_QUANTUM, free_list_count(ptr)); + if (b) { + _simple_sappend(b, "small free sizes: "); + while (grain < NUM_SMALL_SLOTS) { + ptr = szone->small_free_list[grain]; + if (ptr) { + _simple_sprintf(b, "%s%y[%d]; ", (grain == NUM_SMALL_SLOTS-1) ? ">=" : "", (grain + 1) * SMALL_QUANTUM, free_list_count(ptr)); + } + grain++; } - grain++; + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); } - malloc_printf("\n"); } static void -print_small_region(szone_t *szone, boolean_t verbose, small_region_t *region, size_t bytes_at_end) +print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_end) { unsigned counts[1024]; unsigned in_use = 0; - void *start = SMALL_REGION_ADDRESS(*region); - void *limit = SMALL_REGION_END(*region) - bytes_at_end; + void *start = SMALL_REGION_ADDRESS(region); + void *limit = SMALL_REGION_END(region) - bytes_at_end; msize_t msize_and_free; msize_t msize; unsigned ci; + _SIMPLE_STRING b; memset(counts, 0, 1024 * sizeof(unsigned)); while (start < limit) { @@ -2459,17 +2682,20 @@ print_small_region(szone_t *szone, boolean_t verbose, small_region_t *region, si } start += SMALL_BYTES_FOR_MSIZE(msize); } - malloc_printf("Small region [%p-%p, %y]\tIn_use=%d ", - SMALL_REGION_ADDRESS(*region), SMALL_REGION_END(*region), (int)SMALL_REGION_SIZE, in_use); - if (bytes_at_end) - malloc_printf("Untouched=%y ", bytes_at_end); - if (verbose && in_use) { - malloc_printf("\n\tSizes in use: "); - for (ci = 0; ci < 1024; ci++) - if (counts[ci]) - malloc_printf("%d[%d] ", SMALL_BYTES_FOR_MSIZE(ci), counts[ci]); + if ((b = _simple_salloc()) != NULL) { + _simple_sprintf(b, "Small region [%p-%p, %y]\tIn_use=%d ", + SMALL_REGION_ADDRESS(region), SMALL_REGION_END(region), (int)SMALL_REGION_SIZE, in_use); + if (bytes_at_end) + _simple_sprintf(b, "Untouched=%ly", bytes_at_end); + if (verbose && in_use) { + _simple_sappend(b, "\n\tSizes in use: "); + for (ci = 0; ci < 1024; ci++) + if (counts[ci]) + _simple_sprintf(b, "%d[%d] ", SMALL_BYTES_FOR_MSIZE(ci), counts[ci]); + } + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); } - malloc_printf("\n"); } static boolean_t @@ -2482,32 +2708,127 @@ small_free_list_check(szone_t *szone, grain_t grain) CHECK_LOCKED(szone, __PRETTY_FUNCTION__); while (ptr) { - msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); - count++; - if (!(msize_and_free & SMALL_IS_FREE)) { - malloc_printf("*** in-use ptr in free list grain=%d count=%d ptr=%p\n", grain, count, ptr); - return 0; - } - if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { - malloc_printf("*** unaligned ptr in free list grain=%d count=%d ptr=%p\n", grain, count, ptr); - return 0; - } - if (!small_region_for_ptr_no_lock(szone, ptr)) { - malloc_printf("*** ptr not in szone grain=%d count=%d ptr=%p\n", grain, count, ptr); - return 0; - } - free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); - if (ptr->previous != previous) { - malloc_printf("*** previous incorrectly set grain=%d count=%d ptr=%p\n", grain, count, ptr); - return 0; - } - previous = ptr; - ptr = ptr->next; + msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); + count++; + if (!(msize_and_free & SMALL_IS_FREE)) { + malloc_printf("*** in-use ptr in free list grain=%d count=%d ptr=%p\n", grain, count, ptr); + return 0; + } + if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { + malloc_printf("*** unaligned ptr in free list grain=%d count=%d ptr=%p\n", grain, count, ptr); + return 0; + } + if (!small_region_for_ptr_no_lock(szone, ptr)) { + malloc_printf("*** ptr not in szone grain=%d count=%d ptr=%p\n", grain, count, ptr); + return 0; + } + free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); + if (free_list_unchecksum_ptr(ptr->previous) != previous) { + malloc_printf("*** previous incorrectly set grain=%d count=%d ptr=%p\n", grain, count, ptr); + return 0; + } + previous = ptr; + ptr = free_list_unchecksum_ptr(ptr->next); } return 1; } -/********************* LARGE ENTRY UTILITIES ************************/ +/******************************************************************************* + * Region hash implementation + * + * This is essentially a duplicate of the existing Large allocator hash, minus + * the ability to remove entries. The two should be combined eventually. + ******************************************************************************/ +#pragma mark region hash + +/* + * hash_lookup_region_no_lock - Scan a hash ring looking for an entry for a + * given region. + * + * FIXME: If consecutive queries of the same region are likely, a one-entry + * cache would likely be a significant performance win here. + */ +static region_t * +hash_lookup_region_no_lock(region_t *regions, size_t num_entries, region_t r) { + size_t index, hash_index; + region_t *entry; + + if (!num_entries) + return 0; + + index = hash_index = ((uintptr_t)r >> 20) % num_entries; + do { + entry = regions + index; + if (*entry == 0) + return 0; + if (*entry == r) + return entry; + if (++index == num_entries) + index = 0; + } while (index != hash_index); + return 0; +} + +/* + * hash_region_insert_no_lock - Insert a region into the hash ring. + */ +static void +hash_region_insert_no_lock(region_t *regions, size_t num_entries, region_t r) { + size_t index, hash_index; + region_t *entry; + + index = hash_index = ((uintptr_t)r >> 20) % num_entries; + do { + entry = regions + index; + if (*entry == 0) { + *entry = r; + return; + } + if (++index == num_entries) + index = 0; + } while (index != hash_index); +} + +/* + * hash_regions_alloc_no_lock - Allocate space for a number of entries. This + * must be a VM allocation as to avoid recursing between allocating a new small + * region, and asking the small region to allocate space for the new list of + * regions. + */ +static region_t * +hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries) +{ + size_t size = num_entries * sizeof(region_t); + return allocate_pages(szone, round_page(size), 0, 0, VM_MEMORY_MALLOC); +} + +/* + * hash_regions_grow_no_lock - Grow the hash ring, and rehash the entries. + * Return the new region and new size to update the szone. Do not deallocate + * the old entries since someone may still be allocating them. + */ +static region_t * +hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, + size_t *new_size) +{ + // double in size and allocate memory for the regions + *new_size = old_size * 2 + 1; + region_t *new_regions = hash_regions_alloc_no_lock(szone, *new_size); + + // rehash the entries into the new list + size_t index; + for (index = 0; index < old_size; ++index) { + region_t r = regions[index]; + if (r != 0) + hash_region_insert_no_lock(new_regions, *new_size, r); + } + return new_regions; +} + +/******************************************************************************* + * Large allocator implementation + ******************************************************************************/ +#pragma mark large allocator #if DEBUG_MALLOC @@ -2517,12 +2838,16 @@ large_debug_print(szone_t *szone) unsigned num_large_entries = szone->num_large_entries; unsigned index = num_large_entries; large_entry_t *range; + _SIMPLE_STRING b = _simple_salloc(); - for (index = 0, range = szone->large_entries; index < szone->num_large_entries; index++, range++) - if (!LARGE_ENTRY_IS_EMPTY(*range)) - malloc_printf("%d: %p(%y); ", index, LARGE_ENTRY_ADDRESS(*range), LARGE_ENTRY_SIZE(*range)); + if (b) { + for (index = 0, range = szone->large_entries; index < szone->num_large_entries; index++, range++) + if (!LARGE_ENTRY_IS_EMPTY(*range)) + _simple_sprintf(b, "%d: %p(%y); ", index, LARGE_ENTRY_ADDRESS(*range), LARGE_ENTRY_SIZE(*range)); - malloc_printf("\n"); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); + } } #endif @@ -2606,7 +2931,7 @@ large_entries_alloc_no_lock(szone_t *szone, unsigned num) // Note that we allocate memory (via a system call) under a spin lock // That is certainly evil, however it's very rare in the lifetime of a process // The alternative would slow down the normal case - return (void *)allocate_pages(szone, round_page(size), 0, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_LARGE)); + return allocate_pages(szone, round_page(size), 0, 0, VM_MEMORY_MALLOC_LARGE); } else { return small_malloc_cleared_no_lock(szone, SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1)); } @@ -2618,7 +2943,7 @@ large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, // returns range to deallocate size_t size = num * sizeof(large_entry_t); boolean_t is_vm_allocation = size >= LARGE_THRESHOLD; - small_region_t *region; + region_t *region; msize_t msize_and_free; if (is_vm_allocation) { @@ -2629,14 +2954,14 @@ large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, region = small_region_for_ptr_no_lock(szone, entries); msize_and_free = *SMALL_METADATA_FOR_PTR(entries); if (msize_and_free & SMALL_IS_FREE) { - szone_error(szone, "object already freed being freed", entries); + szone_error(szone, "object already freed being freed", entries, NULL); return; } small_free_no_lock(szone, region, entries, msize_and_free); } } -static void +static large_entry_t * large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate) { // sets range_to_deallocate @@ -2647,6 +2972,10 @@ large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate) unsigned index = old_num_entries; large_entry_t oldRange; + // if the allocation of new entries failed, bail + if (new_entries == NULL) + return NULL; + szone->num_large_entries = new_num_entries; szone->large_entries = new_entries; @@ -2662,6 +2991,7 @@ large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate) } else { range_to_deallocate->size = 0; } + return new_entries; } // frees the specific entry in the size table @@ -2676,7 +3006,7 @@ large_free_no_lock(szone_t *szone, large_entry_t *entry) szone->num_large_objects_in_use--; szone->num_bytes_in_large_objects -= range.size; if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) { - protect(szone, (void *)range.address, range.size, VM_PROT_READ | VM_PROT_WRITE, szone->debug_flags); + protect((void *)range.address, range.size, VM_PROT_READ | VM_PROT_WRITE, szone->debug_flags); range.address -= vm_page_size; range.size += 2 * vm_page_size; } @@ -2808,7 +3138,7 @@ huge_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_addres } static void * -large_and_huge_malloc(szone_t *szone, unsigned num_pages) +large_and_huge_malloc(szone_t *szone, size_t num_pages) { void *addr; vm_range_t range_to_deallocate; @@ -2821,7 +3151,7 @@ large_and_huge_malloc(szone_t *szone, unsigned num_pages) size = (size_t)num_pages << vm_page_shift; range_to_deallocate.size = 0; if (num_pages >= (1 << vm_page_shift)) { - addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MAKE_TAG(VM_MEMORY_MALLOC_HUGE)); + addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MEMORY_MALLOC_HUGE); if (addr == NULL) return NULL; huge_entry.size = size; @@ -2832,10 +3162,10 @@ large_and_huge_malloc(szone_t *szone, unsigned num_pages) szone->num_bytes_in_huge_objects += size; } else { - addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MAKE_TAG(VM_MEMORY_MALLOC_LARGE)); + addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MEMORY_MALLOC_LARGE); #if DEBUG_MALLOC if (LOG(szone, addr)) - malloc_printf("in szone_malloc true large allocation at %p for %y\n", (void *)addr, size); + malloc_printf("in szone_malloc true large allocation at %p for %ly\n", (void *)addr, size); #endif SZONE_LOCK(szone); if (addr == NULL) { @@ -2852,7 +3182,11 @@ large_and_huge_malloc(szone_t *szone, unsigned num_pages) if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) { // density of hash table too high; grow table // we do that under lock to avoid a race - large_entries_grow_no_lock(szone, &range_to_deallocate); + large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate); + if (entries == NULL) { + SZONE_UNLOCK(szone); + return NULL; + } } large_entry.address_and_num_pages = (uintptr_t)addr | num_pages; #if DEBUG_MALLOC @@ -2907,7 +3241,7 @@ free_large_or_huge(szone_t *szone, void *ptr) #if DEBUG_MALLOC large_debug_print(szone); #endif - szone_error(szone, "pointer being freed was not allocated", ptr); + szone_error(szone, "pointer being freed was not allocated", ptr, NULL); return; } SZONE_UNLOCK(szone); // we release the lock asap @@ -2969,7 +3303,7 @@ try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, s /* extend existing large entry */ large_entry = large_entry_for_pointer_no_lock(szone, ptr); if (!large_entry) { - szone_error(szone, "large entry reallocated is not properly in table", ptr); + szone_error(szone, "large entry reallocated is not properly in table", ptr, NULL); /* XXX will cause fault on next reference to entry */ } large_entry->address_and_num_pages = (uintptr_t)ptr | (new_size >> vm_page_shift); @@ -2978,7 +3312,7 @@ try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, s /* extend existing huge entry */ huge_entry = huge_entry_for_pointer_no_lock(szone, ptr); if (!huge_entry) { - szone_error(szone, "huge entry reallocated is not properly in table", ptr); + szone_error(szone, "huge entry reallocated is not properly in table", ptr, NULL); /* XXX will cause fault on next reference to huge_entry */ } huge_entry->size = new_size; @@ -2990,7 +3324,6 @@ try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, s large_entry = large_entry_for_pointer_no_lock(szone, ptr); saved_entry = *large_entry; // in case we need to put it back large_free_no_lock(szone, large_entry); - szone->num_bytes_in_large_objects -= old_size; /* and get a huge entry */ huge.address = (vm_address_t)ptr; @@ -3013,8 +3346,8 @@ try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, s static void szone_free(szone_t *szone, void *ptr) { - tiny_region_t *tiny_region; - small_region_t *small_region; + region_t *tiny_region; + region_t *small_region; #if DEBUG_MALLOC if (LOG(szone, ptr)) @@ -3026,10 +3359,14 @@ szone_free(szone_t *szone, void *ptr) * Try to free to a tiny region. */ if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) { - szone_error(szone, "Non-aligned pointer being freed", ptr); + szone_error(szone, "Non-aligned pointer being freed", ptr, NULL); return; } if ((tiny_region = tiny_region_for_ptr_no_lock(szone, ptr)) != NULL) { + if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) { + szone_error(szone, "Pointer to metadata being freed", ptr, NULL); + return; + } free_tiny(szone, ptr, tiny_region); return; } @@ -3038,17 +3375,21 @@ szone_free(szone_t *szone, void *ptr) * Try to free to a small region. */ if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) { - szone_error(szone, "Non-aligned pointer being freed (2)", ptr); + szone_error(szone, "Non-aligned pointer being freed (2)", ptr, NULL); return; } if ((small_region = small_region_for_ptr_no_lock(szone, ptr)) != NULL) { + if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) { + szone_error(szone, "Pointer to metadata being freed (2)", ptr, NULL); + return; + } free_small(szone, ptr, small_region); return; } /* check that it's a legal large/huge allocation */ if ((uintptr_t)ptr & (vm_page_size - 1)) { - szone_error(szone, "non-page-aligned, non-allocated pointer being freed", ptr); + szone_error(szone, "non-page-aligned, non-allocated pointer being freed", ptr, NULL); return; } free_large_or_huge(szone, ptr); @@ -3059,7 +3400,6 @@ szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_request { void *ptr; msize_t msize; - unsigned num_pages; if (size <= 31*TINY_QUANTUM) { // think tiny @@ -3074,11 +3414,11 @@ szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_request ptr = small_malloc_should_clear(szone, msize, cleared_requested); } else { // large or huge - num_pages = round_page(size) >> vm_page_shift; + size_t num_pages = round_page(size) >> vm_page_shift; if (num_pages == 0) /* Overflowed */ ptr = 0; else - ptr = large_and_huge_malloc(szone, num_pages); + ptr = large_and_huge_malloc(szone, num_pages); } #if DEBUG_MALLOC if (LOG(szone, ptr)) @@ -3101,14 +3441,17 @@ szone_malloc(szone_t *szone, size_t size) { static void * szone_calloc(szone_t *szone, size_t num_items, size_t size) { - return szone_malloc_should_clear(szone, num_items * size, 1); + size_t total_bytes = num_items * size; + if ((num_items > 1) && (size != 0) && ((total_bytes / size) != num_items)) + return NULL; + return szone_malloc_should_clear(szone, total_bytes, 1); } static void * szone_valloc(szone_t *szone, size_t size) { void *ptr; - unsigned num_pages; + size_t num_pages; num_pages = round_page(size) >> vm_page_shift; ptr = large_and_huge_malloc(szone, num_pages); @@ -3142,6 +3485,8 @@ szone_size(szone_t *szone, const void *ptr) if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) return 0; if (tiny_region_for_ptr_no_lock(szone, ptr)) { + if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) + return 0; msize = get_tiny_meta_header(ptr, &is_free); return (is_free) ? 0 : TINY_BYTES_FOR_MSIZE(msize); } @@ -3152,6 +3497,8 @@ szone_size(szone_t *szone, const void *ptr) if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) return 0; if (small_region_for_ptr_no_lock(szone, ptr)) { + if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) + return 0; msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); return (msize_and_free & SMALL_IS_FREE) ? 0 : SMALL_BYTES_FOR_MSIZE(msize_and_free); } @@ -3198,7 +3545,7 @@ szone_realloc(szone_t *szone, void *ptr, size_t new_size) } old_size = szone_size(szone, ptr); if (!old_size) { - szone_error(szone, "pointer being reallocated was not allocated", ptr); + szone_error(szone, "pointer being reallocated was not allocated", ptr, NULL); return NULL; } /* we never shrink an allocation */ @@ -3257,45 +3604,42 @@ szone_realloc(szone_t *szone, void *ptr, size_t new_size) return new_ptr; } -// given a size, returns pointers capable of holding that size -// returns the number of pointers allocated -// may return 0 - this function will do best attempts, but just that +// given a size, returns the number of pointers allocated capable of holding +// that size, up to the limit specified by the 'count' argument. These pointers +// are stored in the 'results' array, which must be allocated by the caller. +// may return zero, since this function is only a best attempt at allocating +// the pointers. clients should be prepared to call malloc for any additional +// blocks they need. static unsigned szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) { - msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - size_t chunk_size = TINY_BYTES_FOR_MSIZE(msize); - free_list_t **free_list = szone->tiny_free_list + msize - 1; - free_list_t *ptr = *free_list; - unsigned found = 0; + msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); + unsigned found = 0; + // only bother implementing this for tiny if (size > 31*TINY_QUANTUM) - return 0; // only bother implementing this for tiny + return 0; + // make sure to return objects at least one quantum in size if (!msize) - msize = 1; + msize = 1; + CHECK(szone, __PRETTY_FUNCTION__); - SZONE_LOCK(szone); // might as well lock right here to avoid concurrency issues - while (found < count) { - if (!ptr) - break; - *results++ = ptr; - found++; - set_tiny_meta_header_in_use(ptr, msize); - ptr = ptr->next; + + // We must lock the zone now, since tiny_malloc_from_free_list assumes that + // the caller has done so. + SZONE_LOCK(szone); + + // with the zone locked, allocate objects from the free list until all + // sufficiently large objects have been exhausted, or we have met our quota + // of objects to allocate. + while (found < count) { + void *ptr = tiny_malloc_from_free_list(szone, msize); + if (!ptr) + break; + + *results++ = ptr; + found++; } - if (ptr) { - ptr->previous = NULL; - free_list_set_checksum(szone, ptr); - } - *free_list = ptr; - - // Note that we could allocate from the free lists for larger msize - // But that may un-necessarily fragment - so we might as well let the client do that - // We could also allocate from szone->tiny_bytes_free_at_end - // But that means we'll "eat-up" the untouched area faster, increasing the working set - // So we just return what we have and just that - szone->num_tiny_objects += found; - szone->num_bytes_in_tiny_objects += chunk_size * found; SZONE_UNLOCK(szone); return found; } @@ -3305,7 +3649,7 @@ szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) { unsigned cc = 0; void *ptr; - tiny_region_t *tiny_region; + region_t *tiny_region; boolean_t is_free; msize_t msize; @@ -3317,15 +3661,19 @@ szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) SZONE_LOCK(szone); while (cc < count) { ptr = to_be_freed[cc]; - /* XXX this really slows us down */ - tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); - if (tiny_region) { - // this is a tiny pointer - msize = get_tiny_meta_header(ptr, &is_free); - if (is_free) - break; // a double free; let the standard free deal with it - tiny_free_no_lock(szone, tiny_region, ptr, msize); - to_be_freed[cc] = NULL; + if (ptr) { + /* XXX this really slows us down */ + tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); + if (tiny_region) { + // this is a tiny pointer + if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) + break; // pointer to metadata; let the standard free deal with it + msize = get_tiny_meta_header(ptr, &is_free); + if (is_free) + break; // a double free; let the standard free deal with it + tiny_free_no_lock(szone, tiny_region, ptr, msize); + to_be_freed[cc] = NULL; + } } cc++; } @@ -3341,13 +3689,10 @@ szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) static void szone_destroy(szone_t *szone) { - unsigned index; - small_region_t pended_region = 0; + size_t index; large_entry_t *large; vm_range_t range_to_deallocate; huge_entry_t *huge; - tiny_region_t tiny_region; - small_region_t small_region; /* destroy large entries */ index = szone->num_large_entries; @@ -3373,28 +3718,26 @@ szone_destroy(szone_t *szone) } /* destroy tiny regions */ - index = szone->num_tiny_regions; - while (index--) { - tiny_region = szone->tiny_regions[index]; - deallocate_pages(szone, TINY_REGION_ADDRESS(tiny_region), TINY_REGION_SIZE, 0); - } - /* destroy small regions; region 0 must go last as it contains the szone */ - index = szone->num_small_regions; - while (index--) { - small_region = szone->small_regions[index]; - /* - * If we've allocated more than the basic set of small regions, avoid destroying the - * region that contains the array. - */ - if ((index > 0) && - (SMALL_REGION_FOR_PTR(szone->small_regions) == SMALL_REGION_ADDRESS(small_region))) { - pended_region = small_region; - } else { - deallocate_pages(szone, (void *)SMALL_REGION_ADDRESS(small_region), SMALL_REGION_SIZE, 0); - } - } - if (pended_region) - deallocate_pages(NULL, (void *)SMALL_REGION_ADDRESS(pended_region), SMALL_REGION_SIZE, 0); + for (index = 0; index < szone->num_tiny_regions_allocated; ++index) + if (szone->tiny_regions[index]) + deallocate_pages(szone, szone->tiny_regions[index], TINY_REGION_SIZE, 0); + + /* destroy small regions */ + for (index = 0; index < szone->num_small_regions_allocated; ++index) + if (szone->small_regions[index]) + deallocate_pages(szone, szone->small_regions[index], SMALL_REGION_SIZE, 0); + + /* destroy region hash rings, if any */ + if (szone->tiny_regions != szone->initial_tiny_regions) { + size_t size = round_page(szone->num_tiny_regions_allocated * sizeof(region_t)); + deallocate_pages(szone, szone->tiny_regions, size, 0); + } + if (szone->small_regions != szone->initial_small_regions) { + size_t size = round_page(szone->num_small_regions_allocated * sizeof(region_t)); + deallocate_pages(szone, szone->small_regions, size, 0); + } + /* Now destroy the separate szone region */ + deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES); } static size_t @@ -3429,71 +3772,66 @@ unsigned szone_check_modulo = 1; static boolean_t szone_check_all(szone_t *szone, const char *function) { - int index; - tiny_region_t *tiny; - small_region_t *small; - + size_t index; + SZONE_LOCK(szone); CHECK_LOCKED(szone, __PRETTY_FUNCTION__); /* check tiny regions - chould check region count */ - for (index = szone->num_tiny_regions - 1, tiny = szone->tiny_regions; - index >= 0; - index--, tiny++) { - if (!tiny_check_region(szone, tiny)) { - SZONE_UNLOCK(szone); - szone->debug_flags &= ~ CHECK_REGIONS; - malloc_printf("*** tiny region %d incorrect szone_check_all(%s) counter=%d\n", - szone->num_tiny_regions - index, function, szone_check_counter); - szone_error(szone, "check: tiny region incorrect", NULL); - return 0; - } + for (index = 0; index < szone->num_tiny_regions_allocated; ++index) { + region_t tiny = szone->tiny_regions[index]; + if (tiny && !tiny_check_region(szone, tiny)) { + SZONE_UNLOCK(szone); + szone->debug_flags &= ~ CHECK_REGIONS; + szone_error(szone, "check: tiny region incorrect", NULL, + "*** tiny region %d incorrect szone_check_all(%s) counter=%d\n", + index, function, szone_check_counter); + return 0; + } + } + /* check tiny free lists */ + for (index = 0; index < NUM_TINY_SLOTS; ++index) { + if (!tiny_free_list_check(szone, index)) { + SZONE_UNLOCK(szone); + szone->debug_flags &= ~ CHECK_REGIONS; + szone_error(szone, "check: tiny free list incorrect", NULL, + "*** tiny free list incorrect (slot=%d) szone_check_all(%s) counter=%d\n", + index, function, szone_check_counter); + return 0; + } } - - for (index = NUM_TINY_SLOTS - 1; index >= 0; index--) { - if (!tiny_free_list_check(szone, index)) { - SZONE_UNLOCK(szone); - szone->debug_flags &= ~ CHECK_REGIONS; - malloc_printf("*** tiny free list incorrect (slot=%d) szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - szone_error(szone, "check: tiny free list incorrect", NULL); - return 0; - } - } - /* check small regions - could check region count */ - for (index = szone->num_small_regions - 1, small = szone->small_regions; - index >= 0; - index--, small++) { - if (!szone_check_small_region(szone, small)) { - SZONE_UNLOCK(szone); - szone->debug_flags &= ~ CHECK_REGIONS; - malloc_printf("*** small region %d incorrect szone_check_all(%s) counter=%d\n", - szone->num_small_regions, index, function, szone_check_counter); - szone_error(szone, "check: small region incorrect", NULL); - return 0; - } - } - for (index = NUM_SMALL_SLOTS - 1; index >= 0; index--) { - if (!small_free_list_check(szone, index)) { - SZONE_UNLOCK(szone); - szone->debug_flags &= ~ CHECK_REGIONS; - malloc_printf("*** small free list incorrect (grain=%d) szone_check_all(%s) counter=%d\n", index, function, szone_check_counter); - szone_error(szone, "check: small free list incorrect", NULL); - return 0; - } + for (index = 0; index < szone->num_small_regions_allocated; ++index) { + region_t small = szone->small_regions[index]; + if (small && !szone_check_small_region(szone, small)) { + SZONE_UNLOCK(szone); + szone->debug_flags &= ~ CHECK_REGIONS; + szone_error(szone, "check: small region incorrect", NULL, + "*** small region %d incorrect szone_check_all(%s) counter=%d\n", + index, function, szone_check_counter); + return 0; + } + } + /* check small free lists */ + for (index = 0; index < NUM_SMALL_SLOTS; ++index) { + if (!small_free_list_check(szone, index)) { + SZONE_UNLOCK(szone); + szone->debug_flags &= ~ CHECK_REGIONS; + szone_error(szone, "check: small free list incorrect", NULL, + "*** small free list incorrect (grain=%d) szone_check_all(%s) counter=%d\n", + index, function, szone_check_counter); + return 0; + } } SZONE_UNLOCK(szone); - // szone_print(szone, 1); return 1; } static boolean_t szone_check(szone_t *szone) { - if ((++szone_check_counter % 10000) == 0) - malloc_printf("at szone_check counter=%d\n", szone_check_counter); + _malloc_printf(ASL_LEVEL_NOTICE, "at szone_check counter=%d\n", szone_check_counter); if (szone_check_counter < szone_check_start) return 1; if (szone_check_counter % szone_check_modulo) @@ -3510,11 +3848,9 @@ szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_a if (!reader) reader = _szone_default_reader; err = reader(task, zone_address, sizeof(szone_t), (void **)&szone); if (err) return err; - err = tiny_in_use_enumerator(task, context, type_mask, - (vm_address_t)szone->tiny_regions, szone->num_tiny_regions, szone->tiny_bytes_free_at_end , reader, recorder); + err = tiny_in_use_enumerator(task, context, type_mask, szone, reader, recorder); if (err) return err; - err = small_in_use_enumerator(task, context, type_mask, - (vm_address_t)szone->small_regions, szone->num_small_regions, szone->small_bytes_free_at_end , reader, recorder); + err = small_in_use_enumerator(task, context, type_mask, szone, reader, recorder); if (err) return err; err = large_in_use_enumerator(task, context, type_mask, (vm_address_t)szone->large_entries, szone->num_large_entries, reader, @@ -3553,35 +3889,42 @@ scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) static void szone_print(szone_t *szone, boolean_t verbose) { - unsigned info[13]; - unsigned index = 0; - tiny_region_t *region; - - SZONE_LOCK(szone); - scalable_zone_info((void *)szone, info, 13); - malloc_printf("Scalable zone %p: inUse=%d(%y) touched=%y allocated=%y flags=%d\n", - szone, info[0], info[1], info[2], info[3], info[12]); - malloc_printf("\ttiny=%d(%y) small=%d(%y) large=%d(%y) huge=%d(%y)\n", - info[4], info[5], info[6], info[7], info[8], info[9], info[10], info[11]); - // tiny - malloc_printf("%d tiny regions: \n", szone->num_tiny_regions); - while (index < szone->num_tiny_regions) { - region = szone->tiny_regions + index; - print_tiny_region(verbose, *region, (index == szone->num_tiny_regions - 1) ? szone->tiny_bytes_free_at_end : 0); - index++; - } - if (verbose) print_tiny_free_list(szone); - // small - malloc_printf("%d small regions: \n", szone->num_small_regions); - index = 0; - while (index < szone->num_small_regions) { - region = szone->small_regions + index; - print_small_region(szone, verbose, region, (index == szone->num_small_regions - 1) ? szone->small_bytes_free_at_end : 0); - index++; - } - if (verbose) - print_small_free_list(szone); - SZONE_UNLOCK(szone); + unsigned info[13]; + size_t index; + region_t region; + + SZONE_LOCK(szone); + scalable_zone_info((void *)szone, info, 13); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, + "Scalable zone %p: inUse=%d(%y) touched=%y allocated=%y flags=%d\n", + szone, info[0], info[1], info[2], info[3], info[12]); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, + "\ttiny=%d(%y) small=%d(%y) large=%d(%y) huge=%d(%y)\n", + info[4], info[5], info[6], info[7], info[8], info[9], info[10], info[11]); + // tiny + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, + "%d tiny regions:\n", szone->num_tiny_regions); + for (index = 0; index < szone->num_tiny_regions_allocated; ++index) { + region = szone->tiny_regions[index]; + if (region) + print_tiny_region(verbose, region, (region == szone->last_tiny_region) ? + szone->tiny_bytes_free_at_end : 0); + } + if (verbose) + print_tiny_free_list(szone); + // small + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, + "%d small regions:\n", szone->num_small_regions); + for (index = 0; index < szone->num_small_regions_allocated; ++index) { + region = szone->small_regions[index]; + if (region) + print_small_region(szone, verbose, region, + (region == szone->last_small_region) ? + szone->small_bytes_free_at_end : 0); + } + if (verbose) + print_small_free_list(szone); + SZONE_UNLOCK(szone); } static void @@ -3673,9 +4016,6 @@ malloc_zone_t * create_scalable_zone(size_t initial_size, unsigned debug_flags) { szone_t *szone; - size_t msize; - size_t msize_used; - msize_t free_msize; /* * Sanity-check our build-time assumptions about the size of a page. @@ -3687,14 +4027,19 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) exit(-1); } - /* get memory for the zone */ - szone = allocate_pages(NULL, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC)); + /* 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); if (!szone) - return NULL; + return NULL; /* set up the szone structure */ szone->tiny_regions = szone->initial_tiny_regions; szone->small_regions = szone->initial_small_regions; - msize_used = msize; szone->num_small_objects++; + szone->num_tiny_regions_allocated = INITIAL_NUM_REGIONS; + szone->num_small_regions_allocated = INITIAL_NUM_REGIONS; szone->basic_zone.version = 3; szone->basic_zone.size = (void *)szone_size; szone->basic_zone.malloc = (void *)szone_malloc; @@ -3707,17 +4052,8 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) szone->basic_zone.batch_free = (void *)szone_batch_free; szone->basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; szone->debug_flags = debug_flags; - - /* as the szone is allocated out of the first tiny, region, reflect that allocation */ - szone->small_regions[0] = szone; - szone->num_small_regions = 1; - msize = SMALL_MSIZE_FOR_BYTES(sizeof(szone_t) + SMALL_QUANTUM - 1); - free_msize = NUM_SMALL_BLOCKS - msize; - *SMALL_METADATA_FOR_PTR(szone) = msize; - *(SMALL_METADATA_FOR_PTR(szone) + msize) = free_msize; - szone->small_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(free_msize); - LOCK_INIT(szone->lock); + #if 0 #warning CHECK_REGIONS enabled debug_flags |= CHECK_REGIONS; @@ -3744,12 +4080,13 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) * 3) Original szone-based freezedrying code. * 4) Fresher malloc with tiny zone * 5) 32/64bit compatible malloc + * 6) Metadata within 1MB and 8MB region for tiny and small * * No version backward compatibility is provided, but the version number does * make it possible for malloc_jumpstart() to return an error if the application * was freezedried with an older version of malloc. */ -#define MALLOC_FREEZEDRY_VERSION 5 +#define MALLOC_FREEZEDRY_VERSION 6 typedef struct { unsigned version; diff --git a/gen/scalable_malloc.h b/gen/scalable_malloc.h index 6484875..e6f4b02 100644 --- a/gen/scalable_malloc.h +++ b/gen/scalable_malloc.h @@ -31,7 +31,9 @@ // do not protect postlude page #define SCALABLE_MALLOC_DO_SCRIBBLE (1 << 3) // write 0x55 onto free blocks - +#define SCALABLE_MALLOC_ABORT_ON_ERROR (1 << 4) + // call abort() on a malloc or free error, such as a double free + extern malloc_zone_t *create_scalable_zone(size_t initial_size, unsigned debug_flags); /* Create a new zone that scales for small objects or large objects */ diff --git a/gen/scandir-fbsd.c b/gen/scandir-fbsd.c new file mode 100644 index 0000000..cf79bce --- /dev/null +++ b/gen/scandir-fbsd.c @@ -0,0 +1,150 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +/* + * Scan the directory dirname calling select to make a list of selected + * directory entries then sort using qsort and compare routine dcomp. + * Returns the number of entries and a pointer to a list of pointers to + * struct dirent (through namelist). Returns -1 if there were any errors. + */ + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" + +/* + * The DIRSIZ macro is the minimum record length which will hold the directory + * entry. This requires the amount of space in struct dirent without the + * d_name field, plus enough space for the name and a terminating nul byte + * (dp->d_namlen + 1), rounded up to a 4 byte boundary. + */ +#undef DIRSIZ +#define DIRSIZ(dp) \ + ((sizeof(struct dirent) - sizeof(dp)->d_name) + \ + (((dp)->d_namlen + 1 + 3) &~ 3)) + +int +scandir(dirname, namelist, select, dcomp) + const char *dirname; + struct dirent ***namelist; + int (*select)(struct dirent *); + int (*dcomp)(const void *, const void *); +{ + 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); + names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *)); + if (names == NULL) + goto fail; + + while ((d = readdir(dirp)) != NULL) { + if (select != NULL && !(*select)(d)) + continue; /* just selected names */ + /* + * Make a minimum size copy of the data + */ + p = (struct dirent *)malloc(DIRSIZ(d)); + if (p == NULL) + goto fail; + p->d_fileno = d->d_fileno; + p->d_type = d->d_type; + p->d_reclen = d->d_reclen; + p->d_namlen = d->d_namlen; + bcopy(d->d_name, p->d_name, p->d_namlen + 1); + /* + * Check to make sure the array has space left and + * 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 *)); + if (names2 == NULL) { + free(p); + goto fail; + } + names = names2; + arraysz += inc; + } + names[nitems++] = p; + } + closedir(dirp); + if (nitems && dcomp != NULL) + qsort(names, nitems, sizeof(struct dirent *), dcomp); + *namelist = names; + return(nitems); + +fail: + while (nitems > 0) + free(names[--nitems]); + free(names); + closedir(dirp); + return -1; +} + +/* + * Alphabetic order comparison routine for those who want it. + */ +int +alphasort(d1, d2) + const void *d1; + const void *d2; +{ + return(strcmp((*(struct dirent **)d1)->d_name, + (*(struct dirent **)d2)->d_name)); +} diff --git a/gen/scandir.3 b/gen/scandir.3 new file mode 120000 index 0000000..0bc5c17 --- /dev/null +++ b/gen/scandir.3 @@ -0,0 +1 @@ +./scandir.3 \ No newline at end of file diff --git a/gen/seed48-fbsd.c b/gen/seed48-fbsd.c new file mode 100644 index 0000000..73d63ff --- /dev/null +++ b/gen/seed48-fbsd.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/seed48.c,v 1.2 2002/03/22 21:52:05 obrien Exp $"); + +#include "rand48.h" + +unsigned short * +seed48(unsigned short xseed[3]) +{ + static unsigned short sseed[3]; + + STORERAND48(_rand48_seed, sseed); + LOADRAND48(_rand48_seed, xseed); + _rand48_mult = RAND48_MULT; + _rand48_add = RAND48_ADD; + return sseed; +} diff --git a/gen/seekdir-fbsd.c b/gen/seekdir-fbsd.c new file mode 100644 index 0000000..5385819 --- /dev/null +++ b/gen/seekdir-fbsd.c @@ -0,0 +1,63 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" +#include "telldir.h" + +/* + * Seek to an entry in a directory. + * _seekdir is in telldir.c so that it can share opaque data structures. + */ +void +seekdir(dirp, loc) + DIR *dirp; + long loc; +{ + if (__isthreaded) + _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + _seekdir(dirp, loc); + if (__isthreaded) + _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); +} diff --git a/gen/sethostname-fbsd.c b/gen/sethostname-fbsd.c new file mode 100644 index 0000000..3a15727 --- /dev/null +++ b/gen/sethostname-fbsd.c @@ -0,0 +1,53 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include +#include + +int +sethostname(const char *name, int namelen) +{ + int mib[2]; + + mib[0] = CTL_KERN; + mib[1] = KERN_HOSTNAME; + if (sysctl(mib, 2, NULL, NULL, (void *)name, namelen) == -1) + return (-1); + return (0); +} diff --git a/gen/setjmp.3 b/gen/setjmp.3 index 7707734..9f37028 100644 --- a/gen/setjmp.3 +++ b/gen/setjmp.3 @@ -40,32 +40,50 @@ .Dt SETJMP 3 .Os .Sh NAME -.Nm sigsetjmp , -.Nm siglongjmp , -.Nm setjmp , -.Nm longjmp , -.Nm _setjmp , .Nm _longjmp , -.Nm longjmperror +.Nm _setjmp , +.Nm longjmp , +.Nm longjmperror , +.Nm setjmp , +.Nm siglongjmp , +.Nm sigsetjmp .Nd non-local jumps .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In setjmp.h -.Ft int -.Fn sigsetjmp "sigjmp_buf env" "int savemask" .Ft void -.Fn siglongjmp "sigjmp_buf env" "int val" +.Fo _longjmp +.Fa "jmp_buf env" +.Fa "int val" +.Fc .Ft int -.Fn setjmp "jmp_buf env" +.Fo _setjmp +.Fa "jmp_buf env" +.Fc .Ft void -.Fn longjmp "jmp_buf env" "int val" -.Ft int -.Fn _setjmp "jmp_buf env" +.Fo longjmp +.Fa "jmp_buf env" +.Fa "int val" +.Fc .Ft void -.Fn _longjmp "jmp_buf env" "int val" +.Fo longjmperror +.Fa void +.Fc +.Ft int +.Fo setjmp +.Fa "jmp_buf env" +.Fc .Ft void -.Fn longjmperror void +.Fo siglongjmp +.Fa "sigjmp_buf env" +.Fa "int val" +.Fc +.Ft int +.Fo sigsetjmp +.Fa "sigjmp_buf env" +.Fa "int savemask" +.Fc .Sh DESCRIPTION The .Fn sigsetjmp , @@ -83,14 +101,15 @@ invocations of the .Fn setjmp function. -They then return so that program execution continues as if the corresponding -invocation of the +They then return, so that program execution continues +as if the corresponding invocation of the .Fn setjmp -call had just returned the value specified by +call had just returned the value specified by .Fa val , instead of 0. .Pp -Pairs of calls may be intermixed, i.e. both +Pairs of calls may be intermixed +(i.e., both .Fn sigsetjmp and .Fn siglongjmp @@ -98,13 +117,13 @@ and .Fn setjmp and .Fn longjmp -combinations may be used in the same program, however, individual -calls may not, e.g. the +combinations may be used in the same program); however, individual +calls may not (e.g. the .Fa env argument to .Fn setjmp may not be passed to -.Fn siglongjmp . +.Fn siglongjmp ) . .Pp The .Fn longjmp @@ -136,7 +155,7 @@ The function pairs save and restore the signal mask if the argument .Fa savemask -is non-zero, otherwise only the register set and the stack are saved. +is non-zero; otherwise, only the register set and the stack are saved. .Sh ERRORS If the contents of the .Fa env @@ -147,7 +166,7 @@ routine calls the routine .Fn longjmperror 3 . If .Fn longjmperror -returns the program is aborted (see +returns, the program is aborted (see .Xr abort 3 ) . The default version of .Fn longjmperror diff --git a/gen/setlogin.c b/gen/setlogin.c index 174dea7..eb3495a 100644 --- a/gen/setlogin.c +++ b/gen/setlogin.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -56,11 +56,11 @@ #include -extern int _setlogin(const char* name); +extern int __setlogin(const char* name); extern int _logname_valid; /* shared with getlogin() */ int setlogin(const char* name) { - return (_logname_valid = _setlogin(name)); + return (_logname_valid = __setlogin(name)); } diff --git a/gen/setmode-fbsd.c b/gen/setmode-fbsd.c new file mode 100644 index 0000000..3e4a6ee --- /dev/null +++ b/gen/setmode-fbsd.c @@ -0,0 +1,459 @@ +/* + * Copyright (c) 1989, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Dave Borman at Cray Research, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include + +#ifdef SETMODE_DEBUG +#include +#endif +#include "un-namespace.h" + +#define SET_LEN 6 /* initial # of bitcmd struct to malloc */ +#define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */ + +typedef struct bitcmd { + char cmd; + char cmd2; + mode_t bits; +} BITCMD; + +#define CMD2_CLR 0x01 +#define CMD2_SET 0x02 +#define CMD2_GBITS 0x04 +#define CMD2_OBITS 0x08 +#define CMD2_UBITS 0x10 + +static BITCMD *addcmd(BITCMD *, int, int, int, u_int); +static void compress_mode(BITCMD *); +#ifdef SETMODE_DEBUG +static void dumpmode(BITCMD *); +#endif + +/* + * 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. + * Note that there is no '=' command; a strict assignment is just a '-' (clear + * bits) followed by a '+' (set bits). + */ +mode_t +getmode(bbox, omode) + const void *bbox; + mode_t omode; +{ + const BITCMD *set; + mode_t clrval, newmode, value; + + set = (const BITCMD *)bbox; + newmode = omode; + for (value = 0;; set++) + switch(set->cmd) { + /* + * When copying the user, group or other bits around, we "know" + * where the bits are in the mode so that we can do shifts to + * copy them around. If we don't use shifts, it gets real + * grundgy with lots of single bit checks and bit sets. + */ + case 'u': + value = (newmode & S_IRWXU) >> 6; + goto common; + + case 'g': + value = (newmode & S_IRWXG) >> 3; + goto common; + + case 'o': + value = newmode & S_IRWXO; +common: if (set->cmd2 & CMD2_CLR) { + clrval = + (set->cmd2 & CMD2_SET) ? S_IRWXO : value; + if (set->cmd2 & CMD2_UBITS) + newmode &= ~((clrval<<6) & set->bits); + if (set->cmd2 & CMD2_GBITS) + newmode &= ~((clrval<<3) & set->bits); + if (set->cmd2 & CMD2_OBITS) + newmode &= ~(clrval & set->bits); + } + if (set->cmd2 & CMD2_SET) { + if (set->cmd2 & CMD2_UBITS) + newmode |= (value<<6) & set->bits; + if (set->cmd2 & CMD2_GBITS) + newmode |= (value<<3) & set->bits; + if (set->cmd2 & CMD2_OBITS) + newmode |= value & set->bits; + } + break; + + case '+': + newmode |= set->bits; + break; + + case '-': + newmode &= ~set->bits; + break; + + case 'X': + if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH)) + newmode |= set->bits; + break; + + case '\0': + default: +#ifdef SETMODE_DEBUG + (void)printf("getmode:%04o -> %04o\n", omode, newmode); +#endif + return (newmode); + } +} + +#define ADDCMD(a, b, c, d) \ + if (set >= endset) { \ + BITCMD *newset; \ + setlen += SET_LEN_INCR; \ + newset = realloc(saveset, sizeof(BITCMD) * setlen); \ + if (!newset) { \ + if (saveset) \ + free(saveset); \ + saveset = NULL; \ + return (NULL); \ + } \ + set = newset + (set - saveset); \ + saveset = newset; \ + endset = newset + (setlen - 2); \ + } \ + set = addcmd(set, (a), (b), (c), (d)) + +#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) + +void * +setmode(p) + const char *p; +{ + int perm, who; + char op, *ep; + BITCMD *set, *saveset, *endset; + sigset_t sigset, sigoset; + mode_t mask; + int equalopdone=0, permXbits, setlen; + long perml; + + if (!*p) + return (NULL); + + /* + * Get a copy of the mask for the permissions that are mask relative. + * Flip the bits, we want what's not set. Since it's possible that + * the caller is opening files inside a signal handler, protect them + * as best we can. + */ + sigfillset(&sigset); + (void)_sigprocmask(SIG_BLOCK, &sigset, &sigoset); + (void)umask(mask = umask(0)); + mask = ~mask; + (void)_sigprocmask(SIG_SETMASK, &sigoset, NULL); + + setlen = SET_LEN + 2; + + if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL) + return (NULL); + saveset = set; + endset = set + (setlen - 2); + + /* + * If an absolute number, get it and return; disallow non-octal digits + * or illegal bits. + */ + if (isdigit((unsigned char)*p)) { + perml = strtol(p, &ep, 8); + if (*ep || perml < 0 || perml & ~(STANDARD_BITS|S_ISTXT)) { + free(saveset); + return (NULL); + } + perm = (mode_t)perml; + ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask); + set->cmd = 0; + return (saveset); + } + + /* + * Build list of structures to set/clear/copy bits as described by + * each clause of the symbolic mode. + */ + for (;;) { + /* First, find out which bits might be modified. */ + for (who = 0;; ++p) { + switch (*p) { + case 'a': + who |= STANDARD_BITS; + break; + case 'u': + who |= S_ISUID|S_IRWXU; + break; + case 'g': + who |= S_ISGID|S_IRWXG; + break; + case 'o': + who |= S_IRWXO; + break; + default: + goto getop; + } + } + +getop: if ((op = *p++) != '+' && op != '-' && op != '=') { + free(saveset); + return (NULL); + } + if (op == '=') + equalopdone = 0; + + who &= ~S_ISTXT; + for (perm = 0, permXbits = 0;; ++p) { + switch (*p) { + case 'r': + perm |= S_IRUSR|S_IRGRP|S_IROTH; + break; + case 's': + /* If only "other" bits ignore set-id. */ + if (!who || who & ~S_IRWXO) + perm |= S_ISUID|S_ISGID; + break; + case 't': + /* If only "other" bits ignore sticky. */ + if (!who || who & ~S_IRWXO) { + who |= S_ISTXT; + perm |= S_ISTXT; + } + break; + case 'w': + perm |= S_IWUSR|S_IWGRP|S_IWOTH; + break; + case 'X': + permXbits = S_IXUSR|S_IXGRP|S_IXOTH; + break; + case 'x': + perm |= S_IXUSR|S_IXGRP|S_IXOTH; + break; + case 'u': + case 'g': + case 'o': + /* + * When ever we hit 'u', 'g', or 'o', we have + * to flush out any partial mode that we have, + * and then do the copying of the mode bits. + */ + if (perm) { + ADDCMD(op, who, perm, mask); + perm = 0; + } + if (op == '=') + equalopdone = 1; + if (op == '+' && permXbits) { + ADDCMD('X', who, permXbits, mask); + permXbits = 0; + } + ADDCMD(*p, who, op, mask); + break; + + default: + /* + * Add any permissions that we haven't already + * done. + */ + if (perm || (op == '=' && !equalopdone)) { + if (op == '=') + equalopdone = 1; + ADDCMD(op, who, perm, mask); + perm = 0; + } + if (permXbits) { + ADDCMD('X', who, permXbits, mask); + permXbits = 0; + } + goto apply; + } + } + +apply: if (!*p) + break; + if (*p != ',') + goto getop; + ++p; + } + set->cmd = 0; +#ifdef SETMODE_DEBUG + (void)printf("Before compress_mode()\n"); + dumpmode(saveset); +#endif + compress_mode(saveset); +#ifdef SETMODE_DEBUG + (void)printf("After compress_mode()\n"); + dumpmode(saveset); +#endif + return (saveset); +} + +static BITCMD * +addcmd(set, op, who, oparg, mask) + BITCMD *set; + int oparg, who; + int op; + u_int mask; +{ + switch (op) { + case '=': + set->cmd = '-'; + set->bits = who ? who : STANDARD_BITS; + set++; + + op = '+'; + /* FALLTHROUGH */ + case '+': + case '-': + case 'X': + set->cmd = op; + set->bits = (who ? who : mask) & oparg; + break; + + case 'u': + case 'g': + case 'o': + set->cmd = op; + if (who) { + set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) | + ((who & S_IRGRP) ? CMD2_GBITS : 0) | + ((who & S_IROTH) ? CMD2_OBITS : 0); + set->bits = (mode_t)~0; + } else { + set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS; + set->bits = mask; + } + + if (oparg == '+') + set->cmd2 |= CMD2_SET; + else if (oparg == '-') + set->cmd2 |= CMD2_CLR; + else if (oparg == '=') + set->cmd2 |= CMD2_SET|CMD2_CLR; + break; + } + return (set + 1); +} + +#ifdef SETMODE_DEBUG +static void +dumpmode(set) + BITCMD *set; +{ + for (; set->cmd; ++set) + (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n", + set->cmd, set->bits, set->cmd2 ? " cmd2:" : "", + set->cmd2 & CMD2_CLR ? " CLR" : "", + set->cmd2 & CMD2_SET ? " SET" : "", + set->cmd2 & CMD2_UBITS ? " UBITS" : "", + set->cmd2 & CMD2_GBITS ? " GBITS" : "", + set->cmd2 & CMD2_OBITS ? " OBITS" : ""); +} +#endif + +/* + * Given an array of bitcmd structures, compress by compacting consecutive + * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u', + * 'g' and 'o' commands continue to be separate. They could probably be + * compacted, but it's not worth the effort. + */ +static void +compress_mode(set) + BITCMD *set; +{ + BITCMD *nset; + int setbits, clrbits, Xbits, op; + + for (nset = set;;) { + /* Copy over any 'u', 'g' and 'o' commands. */ + while ((op = nset->cmd) != '+' && op != '-' && op != 'X') { + *set++ = *nset++; + if (!op) + return; + } + + for (setbits = clrbits = Xbits = 0;; nset++) { + if ((op = nset->cmd) == '-') { + clrbits |= nset->bits; + setbits &= ~nset->bits; + Xbits &= ~nset->bits; + } else if (op == '+') { + setbits |= nset->bits; + clrbits &= ~nset->bits; + Xbits &= ~nset->bits; + } else if (op == 'X') + Xbits |= nset->bits & ~setbits; + else + break; + } + if (clrbits) { + set->cmd = '-'; + set->cmd2 = 0; + set->bits = clrbits; + set++; + } + if (setbits) { + set->cmd = '+'; + set->cmd2 = 0; + set->bits = setbits; + set++; + } + if (Xbits) { + set->cmd = 'X'; + set->cmd2 = 0; + set->bits = Xbits; + set++; + } + } +} diff --git a/gen/setmode.3 b/gen/setmode.3 new file mode 120000 index 0000000..cbe4269 --- /dev/null +++ b/gen/setmode.3 @@ -0,0 +1 @@ +./setmode.3 \ No newline at end of file diff --git a/gen/setprogname-fbsd.c b/gen/setprogname-fbsd.c new file mode 100644 index 0000000..19ad084 --- /dev/null +++ b/gen/setprogname-fbsd.c @@ -0,0 +1,33 @@ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/setprogname.c,v 1.8 2002/03/29 22:43:41 markm Exp $"); + +#include +#include +#include +#include +#include +#define __progname (*_NSGetProgname()) + +#include "libc_private.h" + +void +setprogname(const char *progname) +{ + const char *p; + char buf[2*MAXCOMLEN+1]; + int mib[2]; + + p = strrchr(progname, '/'); + if (p != NULL) + __progname = (char *)(p + 1); + else + __progname = (char *)(p = progname); + + strlcpy(&buf[0], (char *)(p), sizeof(buf)); + + mib[0] = CTL_KERN; + mib[1] = KERN_PROCNAME; + + /* ignore errors as this is not a hard error */ + sysctl(mib, 2, NULL, NULL, &buf[0], 2*MAXCOMLEN); +} diff --git a/gen/siginterrupt-fbsd.c b/gen/siginterrupt-fbsd.c new file mode 100644 index 0000000..8c719f8 --- /dev/null +++ b/gen/siginterrupt-fbsd.c @@ -0,0 +1,67 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" + +/* + * Set signal state to prevent restart of system calls + * after an instance of the indicated signal. + */ +int +siginterrupt(sig, flag) + int sig, flag; +{ + extern sigset_t _sigintr; + struct sigaction sa; + int ret; + + if ((ret = _sigaction(sig, (struct sigaction *)0, &sa)) < 0) + return (ret); + if (flag) { + sigaddset(&_sigintr, sig); + sa.sa_flags &= ~SA_RESTART; + } else { + sigdelset(&_sigintr, sig); + sa.sa_flags |= SA_RESTART; + } + return (_sigaction(sig, &sa, (struct sigaction *)0)); +} diff --git a/gen/siginterrupt.3 b/gen/siginterrupt.3 new file mode 100644 index 0000000..0b1f2d4 --- /dev/null +++ b/gen/siginterrupt.3 @@ -0,0 +1,124 @@ +.\" Copyright (c) 1985, 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt SIGINTERRUPT 3 +.Os +.Sh NAME +.Nm siginterrupt +.Nd allow signals to interrupt system calls +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Ft int +.Fn siginterrupt "int sig" "int flag" +.Sh DESCRIPTION +The +.Fn siginterrupt +function +is used to change the system call restart +behavior when a system call is interrupted by the specified signal. +If the flag is false (0), then system calls will be restarted if +they are interrupted by the specified signal +and no data has been transferred yet. +System call restart has been the default behavior since +.Bx 4.2 , +and is the default behaviour for +.Xr signal 3 +on +.Fx . +.Pp +If the flag is true (1), +then restarting of system calls is disabled. +If a system call is interrupted by the specified signal +and no data has been transferred, +the system call will return \-1 with the global variable +.Va errno +set to +.Er EINTR . +Interrupted system calls that have started transferring +data will return the amount of data actually transferred. +System call interrupt is the signal behavior found on +.Bx 4.1 +and +.At V +systems. +.Pp +Note that the new +.Bx 4.2 +signal handling semantics are not +altered in any other way. +Most notably, signal handlers always remain installed until +explicitly changed by a subsequent +.Xr sigaction 2 +call, and the signal mask operates as documented in +.Xr sigaction 2 . +Programs may switch between restartable and interruptible +system call operation as often as desired in the execution of a program. +.Pp +Issuing a +.Fn siginterrupt 3 +call during the execution of a signal handler will cause +the new action to take place on the next signal to be caught. +.Sh NOTES +This library routine uses an extension of the +.Xr sigaction 2 +system call that is not available in +.Bx 4.2 ; +hence, it should not be used if backward compatibility is needed. +.Sh RETURN VALUES +.Rv -std siginterrupt +.Sh ERRORS +The +.Fn siginterrupt +call fails if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sig +argument +is not a valid signal number. +.El +.Sh SEE ALSO +.Xr sigaction 2 , +.Xr sigblock 2 , +.Xr sigpause 2 , +.Xr sigsetmask 2 , +.Xr signal 3 +.Sh HISTORY +The +.Fn siginterrupt +function appeared in +.Bx 4.3 . diff --git a/gen/siglist-fbsd.c b/gen/siglist-fbsd.c new file mode 100644 index 0000000..8452535 --- /dev/null +++ b/gen/siglist-fbsd.c @@ -0,0 +1,111 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include +#include + +const char *const sys_signame[NSIG] = { + "Signal 0", + "hup", /* SIGHUP */ + "int", /* SIGINT */ + "quit", /* SIGQUIT */ + "ill", /* SIGILL */ + "trap", /* SIGTRAP */ + "abrt", /* SIGABRT */ + "emt", /* SIGEMT */ + "fpe", /* SIGFPE */ + "kill", /* SIGKILL */ + "bus", /* SIGBUS */ + "segv", /* SIGSEGV */ + "sys", /* SIGSYS */ + "pipe", /* SIGPIPE */ + "alrm", /* SIGALRM */ + "term", /* SIGTERM */ + "urg", /* SIGURG */ + "stop", /* SIGSTOP */ + "tstp", /* SIGTSTP */ + "cont", /* SIGCONT */ + "chld", /* SIGCHLD */ + "ttin", /* SIGTTIN */ + "ttou", /* SIGTTOU */ + "io", /* SIGIO */ + "xcpu", /* SIGXCPU */ + "xfsz", /* SIGXFSZ */ + "vtalrm", /* SIGVTALRM */ + "prof", /* SIGPROF */ + "winch", /* SIGWINCH */ + "info", /* SIGINFO */ + "usr1", /* SIGUSR1 */ + "usr2" /* SIGUSR2 */ +}; + +const char *const sys_siglist[NSIG] = { + "Signal 0", + "Hangup", /* SIGHUP */ + "Interrupt", /* SIGINT */ + "Quit", /* SIGQUIT */ + "Illegal instruction", /* SIGILL */ + "Trace/BPT trap", /* SIGTRAP */ + "Abort trap", /* SIGABRT */ + "EMT trap", /* SIGEMT */ + "Floating point exception", /* SIGFPE */ + "Killed", /* SIGKILL */ + "Bus error", /* SIGBUS */ + "Segmentation fault", /* SIGSEGV */ + "Bad system call", /* SIGSYS */ + "Broken pipe", /* SIGPIPE */ + "Alarm clock", /* SIGALRM */ + "Terminated", /* SIGTERM */ + "Urgent I/O condition", /* SIGURG */ + "Suspended (signal)", /* SIGSTOP */ + "Suspended", /* SIGTSTP */ + "Continued", /* SIGCONT */ + "Child exited", /* SIGCHLD */ + "Stopped (tty input)", /* SIGTTIN */ + "Stopped (tty output)", /* SIGTTOU */ + "I/O possible", /* SIGIO */ + "Cputime limit exceeded", /* SIGXCPU */ + "Filesize limit exceeded", /* SIGXFSZ */ + "Virtual timer expired", /* SIGVTALRM */ + "Profiling timer expired", /* SIGPROF */ + "Window size changes", /* SIGWINCH */ + "Information request", /* SIGINFO */ + "User defined signal 1", /* SIGUSR1 */ + "User defined signal 2" /* SIGUSR2 */ +}; diff --git a/gen/signal-fbsd.c b/gen/signal-fbsd.c new file mode 100644 index 0000000..f0764f7 --- /dev/null +++ b/gen/signal-fbsd.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1985, 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +/* + * Almost backwards compatible signal. + */ +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" + +sigset_t _sigintr; /* shared with siginterrupt */ + +extern int _sigaction_nobind (int sig, const struct sigaction *nsv, struct sigaction *osv); + +static sig_t +signal__(s, a, bind) + int s; + sig_t a; + int bind; +{ + struct sigaction sa, osa; + + sa.sa_handler = a; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (!sigismember(&_sigintr, s)) + sa.sa_flags |= SA_RESTART; +#if defined(__DYNAMIC__) + if (bind) { +#endif /* __DYNAMIC__ */ + if (_sigaction(s, &sa, &osa) < 0) + return (SIG_ERR); +#if defined(__DYNAMIC__) + } else { + if (_sigaction_nobind(s, &sa, &osa) < 0) + return (SIG_ERR); + } +#endif /* __DYNAMIC__ */ + return (osa.sa_handler); +} + +sig_t +signal(s, a) + int s; + sig_t a; +{ + return signal__(s, a, 1); +} + +#if defined(__DYNAMIC__) +sig_t +_signal_nobind(s, a) + int s; + sig_t a; +{ + return signal__(s, a, 0); +} +#endif /* __DYNAMIC__ */ diff --git a/gen/signal.3 b/gen/signal.3 new file mode 100644 index 0000000..dee3357 --- /dev/null +++ b/gen/signal.3 @@ -0,0 +1,269 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 7, 2004 +.Dt SIGNAL 3 +.Os +.Sh NAME +.Nm signal +.Nd simplified software signal facilities +.Sh LIBRARY +.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" +.Pp +or in the equivalent but easier to read typedef'd version: +.Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp" ; +.Ft sig_t +.Fn signal "int sig" "sig_t func" +.Sh DESCRIPTION +This +.Fn signal +facility +is a simplified interface to the more general +.Xr sigaction 2 +facility. +.Pp +Signals allow the manipulation of a process from outside its domain, +as well as allowing the process to manipulate itself +or copies of itself (children). +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 +an irrecoverable error or might be the result of a user at a terminal +typing the `interrupt' character. +Signals are used when a process is stopped because it wishes to access +its control terminal while in the background (see +.Xr tty 4 ) . +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. +Most signals result in the termination of the process receiving them, +if no action is taken; +some signals instead cause the process receiving them to be stopped, +or are simply discarded if the process has not requested otherwise. +Except for the +.Dv SIGKILL +and +.Dv SIGSTOP +signals, the +.Fn signal +function allows for a signal to be caught, to be ignored, or to generate +an interrupt. +These signals are defined in the file +.In signal.h : +.Bl -column No ".Dv SIGVTALRM" "create core image" +.It Sy "No Name Default Action Description" +.It 1 Ta Dv SIGHUP Ta "terminate process" Ta "terminal line hangup" +.It 2 Ta Dv SIGINT Ta "terminate process" Ta "interrupt program" +.It 3 Ta Dv SIGQUIT Ta "create core image" Ta "quit program" +.It 4 Ta Dv SIGILL Ta "create core image" Ta "illegal instruction" +.It 5 Ta Dv SIGTRAP Ta "create core image" Ta "trace trap" +.It 6 Ta Dv SIGABRT Ta "create core image" Ta "abort program" +(formerly +.Dv SIGIOT ) +.It 7 Ta Dv SIGEMT Ta "create core image" Ta "emulate instruction executed" +.It 8 Ta Dv SIGFPE Ta "create core image" Ta "floating-point exception" +.It 9 Ta Dv SIGKILL Ta "terminate process" Ta "kill program" +.It 10 Ta Dv SIGBUS Ta "create core image" Ta "bus error" +.It 11 Ta Dv SIGSEGV Ta "create core image" Ta "segmentation violation" +.It 12 Ta Dv SIGSYS Ta "create core image" Ta "non-existent system call invoked" +.It 13 Ta Dv SIGPIPE Ta "terminate process" Ta "write on a pipe with no reader" +.It 14 Ta Dv SIGALRM Ta "terminate process" Ta "real-time timer expired" +.It 15 Ta Dv SIGTERM Ta "terminate process" Ta "software termination signal" +.It 16 Ta Dv SIGURG Ta "discard signal" Ta "urgent condition present on socket" +.It 17 Ta Dv SIGSTOP Ta "stop process" Ta "stop (cannot be caught or ignored)" +.It 18 Ta Dv SIGTSTP Ta "stop process" Ta "stop signal generated from keyboard" +.It 19 Ta Dv SIGCONT Ta "discard signal" Ta "continue after stop" +.It 20 Ta Dv SIGCHLD Ta "discard signal" Ta "child status has changed" +.It 21 Ta Dv SIGTTIN Ta "stop process" Ta "background read attempted from" +control terminal +.It 22 Ta Dv SIGTTOU Ta "stop process" Ta "background write attempted to" +control terminal +.It 23 Ta Dv SIGIO Ta "discard signal" Ta Tn "I/O" +is possible on a descriptor (see +.Xr fcntl 2 ) +.It 24 Ta Dv SIGXCPU Ta "terminate process" Ta "cpu time limit exceeded (see" +.Xr setrlimit 2 ) +.It 25 Ta Dv SIGXFSZ Ta "terminate process" Ta "file size limit exceeded (see" +.Xr setrlimit 2 ) +.It 26 Ta Dv SIGVTALRM Ta "terminate process" Ta "virtual time alarm (see" +.Xr setitimer 2 ) +.It 27 Ta Dv SIGPROF Ta "terminate process" Ta "profiling timer alarm (see" +.Xr setitimer 2 ) +.It 28 Ta Dv SIGWINCH Ta "discard signal" Ta "Window size change" +.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" +.El +.Pp +The +.Fa sig +argument specifies which signal was received. +The +.Fa func +procedure allows a user to choose the action upon receipt of a signal. +To set the default action of the signal to occur as listed above, +.Fa func +should be +.Dv SIG_DFL . +A +.Dv SIG_DFL +resets the default action. +To ignore the signal, +.Fa func +should be +.Dv SIG_IGN . +This will cause subsequent instances of the signal to be ignored +and pending instances to be discarded. +If +.Dv SIG_IGN +is not used, +further occurrences of the signal are +automatically blocked and +.Fa func +is called. +.Pp +The handled signal is unblocked when the +function returns and +the process continues from where it left off when the signal occurred. +.Bf -symbolic +Unlike previous signal facilities, the handler +func() remains installed after a signal has been delivered. +.Ef +.Pp +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 +.Dv SA_RESTART +flag with +.Xr sigaction 2 . ) +The affected system calls include +.Xr read 2 , +.Xr write 2 , +.Xr sendto 2 , +.Xr recvfrom 2 , +.Xr sendmsg 2 , +and +.Xr recvmsg 2 +on a communications channel or a low speed device +and during a +.Xr ioctl 2 +or +.Xr wait 2 . +However, calls that have already committed are not restarted, +but instead return a partial success (for example, a short read count). +These semantics could be changed with +.Xr siginterrupt 3 . +.Pp +When a process which has installed signal handlers forks, +the child process inherits the signals. +All caught signals may be reset to their default action by a call +to the +.Xr execve 2 +function; +ignored signals remain ignored. +.Pp +If a process explicitly specifies +.Dv SIG_IGN +as the action for the signal +.Dv SIGCHLD , +the system will not create zombie processes when children +of the calling process exit. +As a consequence, the system will discard the exit status +from the child processes. +If the calling process subsequently issues a call to +.Xr wait 2 +or equivalent, it will block until all of the calling process's +children terminate, and then return a value of \-1 with +.Va errno +set to +.Er ECHILD . +.Pp +See +.Xr sigaction 2 +for a list of functions +that are considered safe for use in signal handlers. +.Sh RETURN VALUES +The previous action is returned on a successful call. +Otherwise, SIG_ERR is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn signal +function +will fail and no action will take place if one of the +following occur: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sig +argument +is not a valid signal number. +.It Bq Er EINVAL +An attempt is made to ignore or supply a handler for +.Dv SIGKILL +or +.Ev SIGSTOP . +.El +.Sh SEE ALSO +.Xr kill 1 , +.Xr kill 2 , +.Xr ptrace 2 , +.Xr sigaction 2 , +.Xr sigaltstack 2 , +.Xr sigprocmask 2 , +.Xr sigsuspend 2 , +.Xr wait 2 , +.Xr fpsetmask 3 , +.Xr setjmp 3 , +.Xr siginterrupt 3 , +.Xr tty 4 +.Sh HISTORY +This +.Fn signal +facility appeared in +.Bx 4.0 . +The option to avoid the creation of child zombies through ignoring +.Dv SIGCHLD +appeared in +.Fx 5.0 . diff --git a/gen/signbit.3 b/gen/signbit.3 new file mode 100644 index 0000000..7d9c8d8 --- /dev/null +++ b/gen/signbit.3 @@ -0,0 +1,53 @@ +.\" Copyright (c) 2003 Mike Barcroft +.\" 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/gen/signbit.3,v 1.3 2003/02/24 22:53:20 ru Exp $ +.\" +.Dd February 11, 2003 +.Dt SIGNBIT 3 +.Os +.Sh NAME +.Nm signbit +.Nd "determine whether a floating-point number's sign is negative" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In math.h +.Ft int +.Fn signbit "real-floating x" +.Sh DESCRIPTION +The +.Fn signbit +macro takes an argument of +.Fa x . +It returns non-zero if the value of the argument's sign is negative, +otherwise 0. +.Sh SEE ALSO +.Xr fpclassify 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn signbit +macro conforms to +.St -isoC-99 . diff --git a/gen/sigsetops.3 b/gen/sigsetops.3 index 5c8f0dd..76e8a17 100644 --- a/gen/sigsetops.3 +++ b/gen/sigsetops.3 @@ -36,10 +36,10 @@ .Dt SIGSETOPS 3 .Os .Sh NAME -.Nm sigemptyset , -.Nm sigfillset , .Nm sigaddset , .Nm sigdelset , +.Nm sigemptyset , +.Nm sigfillset , .Nm sigismember .Nd manipulate signal sets .Sh LIBRARY @@ -47,17 +47,30 @@ .Sh SYNOPSIS .In signal.h .Ft int -.Fn sigemptyset "sigset_t *set" +.Fo sigaddset +.Fa "sigset_t *set" +.Fa "int signo" +.Fc .Ft int -.Fn sigfillset "sigset_t *set" +.Fo sigdelset +.Fa "sigset_t *set" +.Fa "int signo" +.Fc .Ft int -.Fn sigaddset "sigset_t *set" "int signo" +.Fo sigemptyset +.Fa "sigset_t *set" +.Fc .Ft int -.Fn sigdelset "sigset_t *set" "int signo" +.Fo sigfillset +.Fa "sigset_t *set" +.Fc .Ft int -.Fn sigismember "const sigset_t *set" "int signo" +.Fo sigismember +.Fa "const sigset_t *set" +.Fa "int signo" +.Fc .Sh DESCRIPTION -These functions manipulate signal sets stored in a +These functions manipulate signal sets, stored in a .Fa sigset_t . Either .Fn sigemptyset @@ -106,7 +119,7 @@ if the signal is a member of the set, 0 otherwise. The other functions return 0. .Sh ERRORS -Currently no errors are detected. +Currently, no errors are detected. .Sh SEE ALSO .Xr kill 2 , .Xr sigaction 2 , diff --git a/gen/sigsetops.c b/gen/sigsetops.c index 827e3c6..842dc79 100644 --- a/gen/sigsetops.c +++ b/gen/sigsetops.c @@ -88,6 +88,8 @@ sigaddset(set, signo) errno = EINVAL; return(-1); } + if (signo == 0) + return(0); *set |= sigmask(signo); return (0); } @@ -101,6 +103,8 @@ sigdelset(set, signo) errno = EINVAL; return(-1); } + if (signo == 0) + return(0); *set &= ~sigmask(signo); return (0); } @@ -114,5 +118,7 @@ sigismember(set, signo) errno = EINVAL; return(-1); } + if (signo == 0) + return(0); return ((*set & sigmask(signo)) != 0); } diff --git a/gen/simple_dprintf.c b/gen/simple_dprintf.c deleted file mode 100644 index 5c87942..0000000 --- a/gen/simple_dprintf.c +++ /dev/null @@ -1,321 +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 -#include -#include - -/* we use a small buffer to minimize stack usage constraints */ -#define MYBUFSIZE 32 - -typedef struct { - char buf[MYBUFSIZE]; - char *ptr; - char *end; - int fd; -} BUF; - -/* flush the buffer and reset the pointer */ -static inline void -flush(BUF *b) -{ - char *buf = b->buf; - int n = b->ptr - buf; - int w; - - while(n > 0) { - w = write(b->fd, buf, n); - if(w < 0) { - if(errno == EINTR || errno == EAGAIN) - continue; - break; - } - n -= w; - buf += n; - } - b->ptr = b->buf; -} - -/* output a single character */ -static inline void -put_c(BUF *b, int c) -{ - if(b->ptr >= b->end) - flush(b); - *b->ptr++ = c; -} - -/* output a null-terminated string */ -static inline void -put_s(BUF *b, const char *str) -{ - while(*str) - put_c(b, *str++); -} - -/* output a string of the specified size */ -static inline void -put_n(BUF *b, const char *str, int n) -{ - while(n-- > 0) - put_c(b, *str++); -} - -/* - * Output the signed decimal string representing the number in "in". "width" is - * the minimum field width, and "zero" is a boolean value, true for zero padding - * (otherwise blank padding). - */ -static void -dec(BUF *b, long long in, int width, int zero) -{ - char buf[32]; - char *cp = buf + sizeof(buf); - int pad; - int neg = 0; - unsigned long long n = (unsigned long long)in; - - if(in < 0) { - neg++; - width--; - n = ~n + 1; - } - *--cp = 0; - if(n) { - while(n) { - *--cp = (n % 10) + '0'; - n /= 10; - } - } else - *--cp = '0'; - if(neg && zero) { - put_c(b, '-'); - neg = 0; - } - pad = width - strlen(cp); - zero = zero ? '0' : ' '; - while(pad-- > 0) - put_c(b, zero); - if(neg) - put_c(b, '-'); - put_s(b, cp); -} - -/* - * Output the hex string representing the number in "i". "width" is the - * minimum field width, and "zero" is a boolean value, true for zero padding - * (otherwise blank padding). "upper" is a boolean value, true for upper - * case hex characters, lower case otherwise. "p" is a boolean value, true - * if 0x should be prepended (for %p), otherwise nothing. - */ -static char _h[] = "0123456789abcdef"; -static char _H[] = "0123456789ABCDEF"; -static char _0x[] = "0x"; - -static void -hex(BUF *b, unsigned long long n, int width, int zero, int upper, int p) -{ - char buf[32]; - char *cp = buf + sizeof(buf); - char *h = upper ? _H : _h; - - *--cp = 0; - if(n) { - while(n) { - *--cp = h[n & 0xf]; - n >>= 4; - } - } else - *--cp = '0'; - if(p) { - width -= 2; - if(zero) { - put_s(b, _0x); - p = 0; - } - } - width -= strlen(cp); - zero = zero ? '0' : ' '; - while(width-- > 0) - put_c(b, zero); - if(p) - put_s(b, _0x); - put_s(b, cp); -} - -/* - * Output the unsigned decimal string representing the number in "in". "width" - * is the minimum field width, and "zero" is a boolean value, true for zero - * padding (otherwise blank padding). - */ -static void -udec(BUF *b, unsigned long long n, int width, int zero) -{ - char buf[32]; - char *cp = buf + sizeof(buf); - int pad; - - *--cp = 0; - if(n) { - while(n) { - *--cp = (n % 10) + '0'; - n /= 10; - } - } else - *--cp = '0'; - pad = width - strlen(cp); - zero = zero ? '0' : ' '; - while(pad-- > 0) - put_c(b, zero); - put_s(b, cp); -} - -/* - * A simplified vfprintf variant. The format string is interpreted with - * arguments for the va_list, and the results are written to the given - * file descriptor. - */ -void -_simple_vdprintf(int fd, const char *fmt, va_list ap) -{ - BUF b; - - b.fd = fd; - b.ptr = b.buf; - b.end = b.buf + MYBUFSIZE; - while(*fmt) { - int lflag, zero, width; - char *cp; - if(!(cp = strchr(fmt, '%'))) { - put_s(&b, fmt); - break; - } - put_n(&b, fmt, cp - fmt); - fmt = cp + 1; - if(*fmt == '%') { - put_c(&b, '%'); - fmt++; - continue; - } - lflag = zero = width = 0; - for(;;) { - switch(*fmt) { - case '0': - zero++; - fmt++; - /* drop through */ - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - while(*fmt >= '0' && *fmt <= '9') - width = 10 * width + (*fmt++ - '0'); - continue; - case 'c': - zero = zero ? '0' : ' '; - width--; - while(width-- > 0) - put_c(&b, zero); - put_c(&b, va_arg(ap, int)); - break; - case 'd': case 'i': - switch(lflag) { - case 0: - dec(&b, va_arg(ap, int), width, zero); - break; - case 1: - dec(&b, va_arg(ap, long), width, zero); - break; - default: - dec(&b, va_arg(ap, long long), width, zero); - break; - } - break; - case 'l': - lflag++; - fmt++; - continue; - case 'p': - hex(&b, (unsigned long)va_arg(ap, void *), width, zero, 0, 1); - break; - case 's': - cp = va_arg(ap, char *); - width -= strlen(cp); - zero = zero ? '0' : ' '; - while(width-- > 0) - put_c(&b, zero); - put_s(&b, cp); - break; - case 'u': - switch(lflag) { - case 0: - udec(&b, va_arg(ap, unsigned int), width, zero); - break; - case 1: - udec(&b, va_arg(ap, unsigned long), width, zero); - break; - default: - udec(&b, va_arg(ap, unsigned long long), width, zero); - break; - } - break; - case 'X': case 'x': - switch(lflag) { - case 0: - hex(&b, va_arg(ap, unsigned int), width, zero, - *fmt == 'X', 0); - break; - case 1: - hex(&b, va_arg(ap, unsigned long), width, zero, - *fmt == 'X', 0); - break; - default: - hex(&b, va_arg(ap, unsigned long long), width, zero, - *fmt == 'X', 0); - break; - } - break; - default: - put_c(&b, *fmt); - break; - } - break; - } - fmt++; - } - flush(&b); -} - -/* - * A simplified fprintf variant. The format string is interpreted with - * arguments for the variable argument list, and the results are written - * to the given file descriptor. - */ -void -_simple_dprintf(int fd, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - _simple_vdprintf(fd, format, ap); - va_end(ap); -} diff --git a/gen/sleep-fbsd.c b/gen/sleep-fbsd.c new file mode 100644 index 0000000..773b54b --- /dev/null +++ b/gen/sleep-fbsd.c @@ -0,0 +1,77 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + */ + +#ifdef VARIANT_CANCELABLE +#undef __DARWIN_NON_CANCELABLE +#define __DARWIN_NON_CANCELABLE 0 +#endif /* VARIANT_CANCELABLE */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" + +unsigned int +__sleep(seconds) + unsigned int seconds; +{ + struct timespec time_to_sleep; + struct timespec time_remaining; + + /* + * Avoid overflow when `seconds' is huge. This assumes that + * the maximum value for a time_t is >= INT_MAX. + */ + if (seconds > INT_MAX) + return (seconds - INT_MAX + __sleep(INT_MAX)); + + time_to_sleep.tv_sec = seconds; + time_to_sleep.tv_nsec = 0; + if (_nanosleep(&time_to_sleep, &time_remaining) != -1) + return (0); + if (errno != EINTR) + return (seconds); /* best guess */ + return (time_remaining.tv_sec + + (time_remaining.tv_nsec != 0)); /* round up */ +} + +__weak_reference(__sleep, sleep); +__weak_reference(__sleep, _sleep); diff --git a/gen/sleep.3 b/gen/sleep.3 new file mode 100644 index 0000000..00cd85e --- /dev/null +++ b/gen/sleep.3 @@ -0,0 +1,87 @@ +.\" Copyright (c) 1986, 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. +.\" +.\" @(#)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 $ +.\" +.Dd February 13, 1998 +.Dt SLEEP 3 +.Os +.Sh NAME +.Nm sleep +.Nd suspend thread execution for an interval measured in seconds +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft unsigned int +.Fn sleep "unsigned int seconds" +.Sh DESCRIPTION +The +.Fn sleep +function suspends execution of the calling thread until either +.Fa seconds +seconds have elapsed or a signal is delivered to the thread and its +action is to invoke a signal-catching function or to terminate the +thread or process. +System activity may lengthen the sleep by an indeterminate amount. +.Pp +This function is implemented using +.Xr nanosleep 2 +by pausing for +.Fa seconds +seconds or until a signal occurs. +Consequently, in this implementation, +sleeping has no effect on the state of process timers, +and there is no special handling for SIGALRM. +.Sh RETURN VALUES +If the +.Fn sleep +function returns because the requested time has elapsed, the value +returned will be zero. +If the +.Fn sleep +function returns due to the delivery of a signal, the value returned +will be the unslept amount (the requested time minus the time actually +slept) in seconds. +.Sh SEE ALSO +.Xr nanosleep 2 , +.Xr usleep 3 +.Sh STANDARDS +The +.Fn sleep +function conforms to +.St -p1003.1-90 . +.Sh HISTORY +A +.Fn sleep +function appeared in +.At v7 . diff --git a/gen/srand48-fbsd.c b/gen/srand48-fbsd.c new file mode 100644 index 0000000..c9f8426 --- /dev/null +++ b/gen/srand48-fbsd.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include "rand48.h" + +void +srand48(long seed) +{ + _rand48_seed = TOUINT48(RAND48_SEED_0, (unsigned short) seed, (unsigned short) (seed >> 16)); + _rand48_mult = RAND48_MULT; + _rand48_add = RAND48_ADD; +} diff --git a/gen/stack_logging.c b/gen/stack_logging.c index 257d118..6c66890 100644 --- a/gen/stack_logging.c +++ b/gen/stack_logging.c @@ -24,6 +24,7 @@ /* Bertrand from vmutils -> CF -> System */ #import "stack_logging.h" +#import "malloc_printf.h" #import #import @@ -33,6 +34,8 @@ #import extern void spin_lock(int *); +extern void spin_unlock(int *); +extern void thread_stack_pcs(vm_address_t *, unsigned, unsigned *); static inline void *allocate_pages(unsigned) __attribute__((always_inline)); static inline void *allocate_pages(unsigned bytes) { @@ -55,76 +58,6 @@ static inline void copy_pages(const void *source, void *dest, unsigned bytes) { if (vm_copy(mach_task_self(), (vm_address_t)source, bytes, (vm_address_t)dest)) memmove(dest, source, bytes); } -/*************** Recording stack ***********/ - -// The three functions below are marked as noinline to ensure consistent inlining across -// all versions of GCC and all compiler flags. The malloc stack logging code expects -// these functions to not be inlined. -// For details, see . -// -// The performance cost of not inlining these functions is negligible, and they're only -// called when MallocStackLogging is set anyway, so they won't affect normal usage. - -static __attribute__((noinline)) void *first_frame_address(void) { -#if defined(__i386__) || defined(__x86_64__) - return __builtin_frame_address(0); -#elif defined(__ppc__) || defined(__ppc64__) - void *addr; -#warning __builtin_frame_address IS BROKEN IN BEAKER: RADAR #2340421 - __asm__ volatile("mr %0, r1" : "=r" (addr)); - return addr; -#else -#warning first_frame_address WILL NOT BE FUNCTIONAL ON THIS ARCHITECTURE - return NULL; -#endif -} - -static __attribute__((noinline)) void *next_frame_address(void *addr) { - void *ret; -#if defined(__MACH__) && (defined(__i386__) || defined(__x86_64__)) - __asm__ volatile("mov (%1),%0" : "=r" (ret) : "r" (addr)); -#elif defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)) - __asm__ volatile("lwz %0,0x0(%1)" : "=r" (ret) : "b" (addr)); -#elif defined(__hpux__) - __asm__ volatile("ldw 0x0(%1),%0" : "=r" (ret) : "r" (addr)); -#elif defined(__svr4__) - __asm__ volatile("ta 0x3"); - __asm__ volatile("ld [%1 + 56],%0" : "=r" (ret) : "r" (addr)); -#else -#error Unknown architecture -#endif - return ret; -} - -#if defined(__i386__) || defined(__x86_64__) || defined (__m68k__) -#define FP_LINK_OFFSET 1 -#elif defined(__ppc__) || defined(__ppc64__) -#define FP_LINK_OFFSET 2 -#elif defined(__hppa__) -#define FP_LINK_OFFSET -5 -#elif defined(__sparc__) -#define FP_LINK_OFFSET 14 -#else -#error ********** Unimplemented architecture -#endif - -__attribute__((noinline)) void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb) { - void *addr; - addr = first_frame_address(); - *nb = 0; - while ((addr >= (void *)0x800) && (max--)) { - vm_address_t fp_link = (vm_address_t)(((unsigned *)addr)+FP_LINK_OFFSET); - void *addr2; - buffer[*nb] = *((vm_address_t *)fp_link); - (*nb)++; - addr2 = next_frame_address(addr); -#if defined(__ppc__) || defined(__ppc64__) - if ((unsigned)addr2 <= (unsigned)addr) break; // catch bozo frames -#endif - addr = addr2; - } -} - /*************** Uniquing stack ***********/ #define MAX_COLLIDE 8 @@ -186,6 +119,8 @@ int stack_logging_enable_logging = 0; int stack_logging_dontcompact = 0; +static int stack_logging_spin_lock = 0; + static stack_logging_record_list_t *GrowLogRecords(stack_logging_record_list_t *records, unsigned desiredNumRecords) { stack_logging_record_list_t *new_records; unsigned old_size = records->overall_num_bytes; @@ -241,7 +176,7 @@ void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsign stack_logging_log_stack(stack_logging_type_dealloc, arg1, 0, 0, 0, num_hot_to_skip+1); return; } - printf("*** Unknown logging type: 0x%x\n", type); + fprintf(stderr, "*** Unknown logging type: 0x%x\n", type); } if (type == stack_logging_flag_set_handle_size) { if (!arg1) return; @@ -268,8 +203,7 @@ void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsign if (!arg1) return; // free(nil) } prepare_to_log_stack(); - spin_lock(&stack_logging_the_record_list->lock); - stack_logging_enable_logging = 0; + spin_lock(&stack_logging_spin_lock); stack_logging_the_record_list = GrowLogRecords(stack_logging_the_record_list, stack_logging_the_record_list->num_records + 1); rec = stack_logging_the_record_list->records + stack_logging_the_record_list->num_records; // We take care of the common case of alloc-dealloc @@ -299,8 +233,7 @@ void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsign 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 stack_logging_the_record_list->num_records++; } - stack_logging_enable_logging = 1; - stack_logging_the_record_list->lock = 0; + spin_unlock(&stack_logging_spin_lock); } static kern_return_t default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) { diff --git a/gen/stack_logging.h b/gen/stack_logging.h index 6bd3aa1..bfb89df 100644 --- a/gen/stack_logging.h +++ b/gen/stack_logging.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,7 @@ #import -#define stack_logging_type_free 0 +#define stack_logging_type_free 0 #define stack_logging_type_generic 1 /* anything that is not allocation/deallocation */ #define stack_logging_type_alloc 2 /* malloc, realloc, etc... */ #define stack_logging_type_dealloc 4 /* free, realloc, etc... */ @@ -37,7 +37,42 @@ #define stack_logging_flag_set_handle_size 256 /* (Handle, newSize) treated specially */ /* Macro used to disguise addresses so that leak finding can work */ -#define STACK_LOGGING_DISGUISE(address) (((unsigned)address) ^ 0x00005555) /* nicely idempotent */ +#define STACK_LOGGING_DISGUISE(address) ((address) ^ 0x00005555) /* nicely idempotent */ + +extern int stack_logging_enable_logging; /* when clear, no logging takes place */ +extern int stack_logging_dontcompact; /* default is to compact; when set does not compact alloc/free logs; useful for tracing history */ + + +extern void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_to_skip); + /* This is the old log-to-memory logger, which is now deprecated. It remains for compatibility with performance tools that haven't been updated to disk_stack_logging_log_stack() yet. */ + +extern void __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip); + /* Fits as the malloc_logger; logs malloc/free/realloc events and can log custom events if called directly */ + + +/* 64-bit-aware stack log access. As new SPI, these routines are prefixed with double-underscore to avoid conflict with Libsystem clients. */ + +typedef struct { + uint32_t type_flags; + uint64_t stack_identifier; + uint64_t argument; + mach_vm_address_t address; +} mach_stack_logging_record_t; + +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 */ + +extern 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); + /* Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies enumerator to all records */ + +extern 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); + /* Given a uniqued_stack fills stack_frames_buffer */ + + +#pragma mark - +#pragma mark Legacy + +/* The following is the old 32-bit-only, in-process-memory stack logging. This is deprecated and clients should move to the above 64-bit-aware disk stack logging SPI. */ typedef struct { unsigned type; @@ -60,20 +95,9 @@ typedef struct { stack_logging_record_t records[0]; /* records follow here */ } stack_logging_record_list_t; -extern unsigned stack_logging_get_unique_stack(unsigned **table, unsigned *table_num_pages, unsigned *stack_entries, unsigned count, unsigned num_hot_to_skip); - /* stack_entries are from hot to cold */ - extern stack_logging_record_list_t *stack_logging_the_record_list; /* This is the global variable containing all logs */ -extern int stack_logging_enable_logging; - /* when clear, no logging takes place */ - -extern int stack_logging_dontcompact; - /* default is to compact; when set does not compact alloc/free logs; useful for tracing history */ - -extern void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_to_skip); - extern kern_return_t stack_logging_get_frames(task_t task, memory_reader_t reader, vm_address_t address, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames); /* Gets the last record in stack_logging_the_record_list about address */ @@ -86,6 +110,8 @@ extern kern_return_t stack_logging_enumerate_records(task_t task, memory_reader_ extern kern_return_t stack_logging_frames_for_uniqued_stack(task_t task, memory_reader_t reader, unsigned uniqued_stack, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames); /* Given a uniqued_stack fills stack_frames_buffer */ + + extern void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *num); /* Convenience to fill buffer with the PCs of the frames, starting with the hot frames; num: returned number of frames diff --git a/gen/stack_logging_disk.c b/gen/stack_logging_disk.c new file mode 100644 index 0000000..45624a7 --- /dev/null +++ b/gen/stack_logging_disk.c @@ -0,0 +1,1674 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "stack_logging.h" +#include "malloc_printf.h" +#include "_simple.h" // as included by malloc.c, this defines ASL_LEVEL_INFO + +#pragma mark - +#pragma mark Defines + +#ifdef TEST_DISK_STACK_LOGGING +#define _malloc_printf fprintf +#undef ASL_LEVEL_INFO +#define ASL_LEVEL_INFO stderr +#endif + +#define STACK_LOGGING_THREAD_HASH_SIZE 2048 // must be an even power of two +#define STACK_LOGGING_MAX_STACK_SIZE 512 +#define STACK_LOGGING_BLOCK_WRITING_SIZE 8192 +#define STACK_LOGGING_NUMBER_RECENT_BACKTRACES 50 +#define STACK_LOGGING_FORCE_FULL_BACKTRACE_EVERY 100 +#define STACK_LOGGING_MAX_THREAD_COLLISIONS 3 +#define STACK_LOGGING_MIN_SAME_FRAMES 3 +#define STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED 3 +#define STACK_LOGGING_REMOTE_CACHE_DEFAULT_COLLISION_ALLOWANCE 5 +#define STACK_LOGGING_REMOTE_CACHE_DEFAULT_NODE_CAPACITY 1 << 14 // <2mb for 32->32, ~3mb for (32->64 || 64->32), ~4mb for 64->64 +#define STACK_LOGGING_REMOTE_CACHE_COLLISION_GROWTH_RATE 3 +#define STACK_LOGGING_REMOTE_LINKS_PER_BLOCK (1 << 20) // this sets a maximum number of malloc/frees that can be read in to: 1^30; + // this means if the .index file is >24gb, remote access will start to fail. + // note: at this point, the .stack file will probably be ~56gb on top of that and + // it'll also be using around 20 gb of memory in the analyzing process... + // all of these are 64-bit stats; the 32-bit analyzing process limits are lower. + // in short, if you want to analyze a process making > 1 billion malloc/frees + // (after compaction), bump this number slightly. + +#pragma mark - +#pragma mark Macros + +#define STACK_LOGGING_FLAGS(longlongvar) (uint8_t)((uint64_t)(longlongvar) >> 56) +#define STACK_LOGGING_OFFSET(longlongvar) ((longlongvar) & 0x00FFFFFFFFFFFFFFull) +#define STACK_LOGGING_OFFSET_AND_FLAGS(longlongvar, realshortvar) (((uint64_t)(longlongvar) & 0x00FFFFFFFFFFFFFFull) | ((uint64_t)(realshortvar) << 56)) + +#pragma mark - +#pragma mark Types + +#pragma mark - stack_logging_backtrace_event +typedef struct { + int16_t offset_delta; // may want to expand this one; should always be < 0. + uint16_t num_identical_frames; + uint16_t num_new_hot_frames; // count of backtrace[] +} stack_logging_backtrace_event; + +#pragma mark - stack_logging_index_event +typedef struct { + uintptr_t argument; + uintptr_t address; + uint64_t offset_and_flags; // top 8 bits are actually the flags! +} stack_logging_index_event; + +#pragma mark - stack_logging_index_event32 +typedef struct { + uint32_t argument; + uint32_t address; + uint64_t offset_and_flags; // top 8 bits are actually the flags! +} stack_logging_index_event32; + +#pragma mark - stack_logging_index_event64 +typedef struct { + uint64_t argument; + uint64_t address; + uint64_t offset_and_flags; // top 8 bits are actually the flags! +} stack_logging_index_event64; + +#pragma mark - thread_backtrace_history +// for management of previous backtraces (by thread): +typedef struct { + vm_address_t thread; + uint32_t hash_pos; + uint64_t logging_index; + int64_t logging_offset; + uint32_t full_backtrace_countdown; + uint32_t backtrace_length; + uintptr_t *backtrace; +} thread_backtrace_history; + +#pragma mark - stack_buffer_shared_memory +// for storing/looking up allocations that haven't yet be written to disk; consistent size across 32/64-bit processes. +// It's important that these fields don't change alignment due to the architecture because they may be accessed from an +// analyzing process with a different arch - hence the pragmas. +#pragma pack(push,4) +typedef struct { + uint64_t start_index_offset; + uint64_t start_stack_offset; + uint32_t next_free_index_buffer_offset; + uint32_t next_free_stack_buffer_offset; + char index_buffer[STACK_LOGGING_BLOCK_WRITING_SIZE]; + char stack_buffer[STACK_LOGGING_BLOCK_WRITING_SIZE]; +} stack_buffer_shared_memory; +#pragma pack(pop) + +#pragma mark - index_ll_node +// linked-list node in table for allocations of a single address +typedef struct index_ll_node { + struct index_ll_node *next; + uint64_t index_file_offset; +} index_ll_node; + +#pragma mark - remote_index_node32 +// 32-bit target process address slot in table +typedef struct { + uint32_t address; + index_ll_node *linked_list; + index_ll_node *last_link; +} remote_index_node32; + +#pragma mark - remote_index_node64 +// 64-bit target process variant +typedef struct { + uint64_t address; + index_ll_node *linked_list; + index_ll_node *last_link; +} remote_index_node64; + +#pragma mark - remote_index_cache +// for caching index information client-side: +typedef struct { + size_t cache_size; + size_t cache_node_capacity; + uint32_t collision_allowance; + uint64_t cache_node_count; // Debug only. + uint64_t cache_llnode_count; // Debug only. + size_t in_use_node_size; // sizeof(remote_index_node32) || sizeof(remote_index_node64) + void *table_memory; // this can be malloced; it's on the client side. + remote_index_node32 *casted_table32; // represents table memory as 32-bit. + remote_index_node64 *casted_table64; // ditto, 64-bit + stack_buffer_shared_memory *shmem; // shared memory + stack_buffer_shared_memory snapshot; // memory snapshot of the remote process' shared memory + uint32_t last_pre_written_index_size; + uint64_t last_index_file_offset; + index_ll_node *blocks[1024]; + uint32_t current_block; + uint32_t next_block_index; +} remote_index_cache; + +#pragma mark - remote_task_file_streams +// for reading stack history information from remote processes: +typedef struct { + task_t remote_task; + pid_t remote_pid; + int32_t task_is_64_bit; + int32_t in_use_count; + FILE *index_file_stream; + FILE *stack_file_stream; + remote_index_cache *cache; +} remote_task_file_streams; + +#pragma mark - +#pragma mark Constants + +static stack_buffer_shared_memory *pre_write_buffers; +static char *pre_write_backtrace_event_buffer = NULL; +static char *pre_write_index_buffer = NULL; + +static OSSpinLock stack_logging_lock = OS_SPINLOCK_INIT; +static uint64_t current_logging_index = 0; +static int64_t total_offset = 0; + +// single-thread access variables +static vm_address_t stack_buffer[STACK_LOGGING_NUMBER_RECENT_BACKTRACES][STACK_LOGGING_MAX_STACK_SIZE]; +static thread_backtrace_history thread_buffer[STACK_LOGGING_THREAD_HASH_SIZE]; +static int32_t current_stack_buffer = 0; +static uintptr_t last_logged_malloc_address = 0; +static uint32_t last_logged_backtrace_offset_diff = 0; +static thread_backtrace_history compaction_saved_differencing_history; + +// Constants to define stack logging directory and path names. +// Files will get written to /tmp/stack-logs...XXXXXX/stack-logs.{index,stacks} +// The directory is securely created with mkdtemp() and the files inside it just have static names for simplicity. +static const char *temporary_directory = "/tmp"; +static const char *stack_logging_directory_base_name = "stack-logs."; +static const char *index_file_name = "stack-logs.index"; +static const char *stack_file_name = "stack-logs.stacks"; + +static char stack_logs_directory[PATH_MAX]; +static char index_file_path[PATH_MAX]; +static char stack_file_path[PATH_MAX]; +static int index_file_descriptor = -1; +static int stack_file_descriptor = -1; + +// for accessing remote log files +static remote_task_file_streams remote_fds[STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED]; +static uint32_t next_remote_task_fd = 0; +static uint32_t remote_task_fd_count = 0; +static OSSpinLock remote_fd_list_lock = OS_SPINLOCK_INIT; + +// activation variables + +static int logging_use_compaction = 1; // set this to zero to always disable compaction. + +// We set malloc_logger to NULL to disable logging, if we encounter errors +// during file writing +typedef void (malloc_logger_t)(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip); +extern malloc_logger_t *malloc_logger; + +#pragma mark - +#pragma mark Disk Stack Logging + +static void delete_log_files(void); // pre-declare + +static void +append_int(char * filename, pid_t pid) +{ + unsigned int value; + size_t len; + unsigned int i; + unsigned int count; + + len = strlen(filename); + + count = 0; + value = pid; + while (value > 0) { + value /= 10; + count ++; + } + + filename[len + count] = 0; + + value = pid; + for(i = 0 ; i < count ; i ++) { + filename[len + count - 1 - i] = '0' + value % 10; + value /= 10; + } +} + +// If successful, returns path to directory that was created. Otherwise returns NULL. +static char * +create_log_files(void) +{ + pid_t pid = getpid(); + const char *progname = getprogname(); + char path_name[PATH_MAX]; + char *created_directory = NULL; + + // WARNING! use of snprintf can induce malloc() calls + strlcpy(stack_logs_directory, temporary_directory, PATH_MAX); + strlcat(stack_logs_directory, "/", PATH_MAX); + strlcat(stack_logs_directory, stack_logging_directory_base_name, PATH_MAX); + append_int(stack_logs_directory, pid); + if (progname && progname[0] != '\0') { + strlcat(stack_logs_directory, ".", PATH_MAX); + strlcat(stack_logs_directory, progname, PATH_MAX); + } + strlcat(stack_logs_directory, ".XXXXXX", PATH_MAX); + + // Securely make temporary directory for the log files, then create the files. + if (mkdtemp(stack_logs_directory) == stack_logs_directory) { + strlcpy(path_name, stack_logs_directory, PATH_MAX); + strlcat(path_name, "/", PATH_MAX); + strlcat(path_name, index_file_name, PATH_MAX); + strlcpy(index_file_path, path_name, PATH_MAX); + index_file_descriptor = open(path_name, O_WRONLY | O_TRUNC | O_CREAT, 0600); + + strlcpy(path_name, stack_logs_directory, PATH_MAX); + strlcat(path_name, "/", PATH_MAX); + strlcat(path_name, stack_file_name, PATH_MAX); + strlcpy(stack_file_path, path_name, PATH_MAX); + stack_file_descriptor = open(path_name, O_WRONLY | O_TRUNC | O_CREAT, 0600); + + if (index_file_descriptor == -1 || stack_file_descriptor == -1) { + _malloc_printf(ASL_LEVEL_INFO, "unable to create stack log files in directory %s\n", stack_logs_directory); + delete_log_files(); + created_directory = NULL; + } else { + _malloc_printf(ASL_LEVEL_INFO, "stack logs being written into %s\n", stack_logs_directory); + created_directory = stack_logs_directory; + } + } else { + _malloc_printf(ASL_LEVEL_INFO, "unable to create stack log directory %s\n", stack_logs_directory); + created_directory = NULL; + } + return created_directory; +} + +// This function may be called from either the target process when exiting, or from either the the target process or +// a stack log analysis process, when reaping orphaned stack log files. +// Returns -1 if the files exist and they couldn't be removed, returns 0 otherwise. +static int +delete_log_files_in_directory(char *logdir) +{ + char path_name[PATH_MAX]; + int unlink_count = 0; + int failure_count = 0; + struct stat statbuf; + + if (logdir == NULL || logdir[0] == '\0') return 0; + + strlcpy(path_name, logdir, PATH_MAX); + strlcat(path_name, "/", PATH_MAX); + strlcat(path_name, index_file_name, PATH_MAX); + if (unlink(path_name) == 0) { + unlink_count++; + } else if (stat(path_name, &statbuf) == 0) { + failure_count++; + } + + strlcpy(path_name, logdir, PATH_MAX); + strlcat(path_name, "/", PATH_MAX); + strlcat(path_name, stack_file_name, PATH_MAX); + if (unlink(path_name) == 0) { + unlink_count++; + } else if (stat(path_name, &statbuf) == 0) { + failure_count++; + } + + if (rmdir(logdir) == -1) failure_count++; + + return (failure_count > 0) ? -1 : 0; +} + +// This function will be called from atexit() in the target process. +static void +delete_log_files(void) +{ + if (stack_logs_directory == NULL || stack_logs_directory[0] == '\0') return; + + if (delete_log_files_in_directory(stack_logs_directory) == 0) { + _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", stack_logs_directory); + stack_file_path[0] = '\0'; + index_file_path[0] = '\0'; + } else { + _malloc_printf(ASL_LEVEL_INFO, "unable to delete stack logs from %s\n", stack_logs_directory); + } +} + +static bool +is_process_running(pid_t pid) +{ + struct kinfo_proc kpt[1]; + size_t size = sizeof(struct kinfo_proc); + int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; + + sysctl(mib, 4, kpt, &size, NULL, 0); // size is either 1 or 0 entries when we ask for a single pid + + return (size==sizeof(struct kinfo_proc)); +} + +// The log files can be quite large and aren't too useful after the process that created them no longer exists. +// Normally they should get removed when the process exits, but if the process crashed the log files might remain. +// So, reap any stack log files for processes that no longer exist. +// +// lf the remove_for_this_pid flag is set, then any log files that already exist for the current process will also be deleted. +// Those log files are probably the result of this process having been exec'ed from another one (without a fork()). +// The remove_for_this_pid flag is only set for a target process (one just starting logging); a stack logging "client" +// process reaps log files too, but if we're using stack logging on the client process itself, then we don't want to remove +// its own log files. +static void +reap_orphaned_log_files(bool remove_for_this_pid) +{ + DIR *dp; + struct dirent *entry; + int prefix_length; + char prefix_name[PATH_MAX]; + char pathname[PATH_MAX]; + pid_t current_pid = getpid(); + + if ((dp = opendir(temporary_directory)) == NULL) { + return; + } + + strlcpy(prefix_name, stack_logging_directory_base_name, PATH_MAX); + prefix_length = strlen(prefix_name); + + while ( (entry = readdir(dp)) != NULL ) { + if ( entry->d_type == DT_DIR && ( strncmp( entry->d_name, prefix_name, prefix_length) == 0 ) ) { + long pid = strtol(&entry->d_name[prefix_length], (char **)NULL, 10); + if ( (! is_process_running(pid)) || (remove_for_this_pid && pid == current_pid) ) { + strlcpy(pathname, temporary_directory, PATH_MAX); + strlcat(pathname, "/", PATH_MAX); + strlcat(pathname, entry->d_name, PATH_MAX); + if (delete_log_files_in_directory(pathname) == 0) { + if (remove_for_this_pid && pid == current_pid) { + _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", pathname); + } else { + _malloc_printf(ASL_LEVEL_INFO, "process %d no longer exists, stack logs deleted from %s\n", pid, pathname); + } + } + } + } + } + closedir(dp); +} + +/* + * Since there a many errors that could cause stack logging to get disabled, this is a convenience method + * for disabling any future logging in this process and for informing the user. + */ +static void +disable_stack_logging(void) +{ + _malloc_printf(ASL_LEVEL_INFO, "stack logging disabled due to previous errors.\n"); + stack_logging_enable_logging = 0; + malloc_logger = NULL; +} + +/* A wrapper around write() that will try to reopen the index/stack file and + * write to it if someone closed it underneath us (e.g. the process we just + * started decide to close all file descriptors except stin/err/out). Some + * programs like to do that and calling abort() on them is rude. + */ +static ssize_t +robust_write(int fd, const void *buf, size_t nbyte) { + extern int errno; + ssize_t written = write(fd, buf, nbyte); + if (written == -1 && errno == EBADF) { + char *file_to_reopen = NULL; + int *fd_to_reset = NULL; + + // descriptor was closed on us. We need to reopen it + if (fd == index_file_descriptor) { + file_to_reopen = index_file_path; + fd_to_reset = &index_file_descriptor; + } + else if (fd == stack_file_descriptor) { + file_to_reopen = stack_file_path; + fd_to_reset = &stack_file_descriptor; + } else { + // We don't know about this file. Return (and abort()). + _malloc_printf(ASL_LEVEL_INFO, "Unknown file descriptor (it's neither the index file, nor the stacks file)\n"); + return -1; + } + + // The file *should* already exist. If not, fail. + fd = open(file_to_reopen, O_WRONLY | O_APPEND); + if (fd < 3) { + // If we somehow got stdin/out/err, we need to relinquish them and + // get another fd. + int fds_to_close[3] = { 0 }; + while (fd < 3) { + if (fd == -1) { + _malloc_printf(ASL_LEVEL_INFO, "unable to re-open stack log file %s\n", file_to_reopen); + delete_log_files(); + return -1; + } + fds_to_close[fd] = 1; + fd = dup(fd); + } + + // We have an fd we like. Close the ones we opened. + if (fds_to_close[0]) close(0); + if (fds_to_close[1]) close(1); + if (fds_to_close[2]) close(2); + } + + *fd_to_reset = fd; + written = write(fd, buf, nbyte); + } + return written; +} + +static void +flush_data(void) +{ + ssize_t written; // signed size_t + size_t remaining; + char * p; + + if (index_file_descriptor == -1) { + if (create_log_files() == NULL) { + return; + } + } + + // Write the events before the index so that hopefully the events will be on disk if the index refers to them. + p = pre_write_backtrace_event_buffer; + remaining = (size_t)pre_write_buffers->next_free_stack_buffer_offset; + while (remaining > 0) { + written = robust_write(stack_file_descriptor, p, remaining); + if (written == -1) { + _malloc_printf(ASL_LEVEL_INFO, "Unable to write to stack logging file %s (%s)\n", stack_file_path, strerror(errno)); + disable_stack_logging(); + return; + } + p += written; + remaining -= written; + } + p = pre_write_index_buffer; + remaining = (size_t)pre_write_buffers->next_free_index_buffer_offset; + 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)); + disable_stack_logging(); + return; + } + p += written; + remaining -= written; + } + + pre_write_buffers->start_stack_offset += pre_write_buffers->next_free_stack_buffer_offset; + pre_write_buffers->start_index_offset += pre_write_buffers->next_free_index_buffer_offset; + pre_write_buffers->next_free_index_buffer_offset = pre_write_buffers->next_free_stack_buffer_offset = 0; +} + +static void +prepare_to_log_stacks(void) +{ + if (!pre_write_buffers) { + last_logged_malloc_address = 0ul; + logging_use_compaction = (stack_logging_dontcompact ? 0 : logging_use_compaction); + + // Create a shared memory region to hold the pre-write index and stack buffers. This will allow remote analysis processes to access + // these buffers to get logs for even the most recent allocations. The remote process will need to pause this process to assure that + // the contents of these buffers don't change while being inspected. + char shmem_name_string[PATH_MAX]; + strlcpy(shmem_name_string, stack_logging_directory_base_name, (size_t)PATH_MAX); + append_int(shmem_name_string, getpid()); + + int shmid = shm_open(shmem_name_string, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + if (shmid < 0) { + // Failed to create shared memory region; turn off stack logging. + _malloc_printf(ASL_LEVEL_INFO, "error while allocating shared memory for disk-based stack logging output buffers\n"); + disable_stack_logging(); + return; + } + + size_t full_shared_mem_size = sizeof(stack_buffer_shared_memory); + ftruncate(shmid, (off_t)full_shared_mem_size); + 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) { + _malloc_printf(ASL_LEVEL_INFO, "error mapping in shared memory for disk-based stack logging output buffers\n"); + disable_stack_logging(); + return; + } + + // Store and use the buffer offsets in shared memory so that they can be accessed remotely + pre_write_buffers->start_index_offset = pre_write_buffers->start_stack_offset = 0ull; + pre_write_buffers->next_free_index_buffer_offset = pre_write_buffers->next_free_stack_buffer_offset = 0; + pre_write_backtrace_event_buffer = pre_write_buffers->stack_buffer; + pre_write_index_buffer = pre_write_buffers->index_buffer; + + // malloc() can be called by the following, so these need to be done outside the stack_logging_lock but after the buffers have been set up. + atexit(delete_log_files); // atexit() can call malloc() + reap_orphaned_log_files(true); // this calls opendir() which calls malloc() + + // this call to flush data ensures that the log files (while possibly empty) exist; analyzing processes will rely on this assumption. + flush_data(); + } +} + +void +__disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip) +{ + if (!stack_logging_enable_logging) return; + + // check incoming data + if (type_flags & stack_logging_type_alloc && type_flags & stack_logging_type_dealloc) { + uintptr_t swapper = size; + size = ptr_arg; + ptr_arg = swapper; + if (ptr_arg == return_val) return; // realloc had no effect, skipping + + if (ptr_arg == 0) { // realloc(NULL, size) same as malloc(size) + type_flags ^= stack_logging_type_dealloc; + } else { + // realloc(arg1, arg2) -> result is same as free(arg1); malloc(arg2) -> result + __disk_stack_logging_log_stack(stack_logging_type_dealloc, zone_ptr, ptr_arg, (uintptr_t)0, (uintptr_t)0, num_hot_to_skip + 1); + __disk_stack_logging_log_stack(stack_logging_type_alloc, zone_ptr, size, (uintptr_t)0, return_val, num_hot_to_skip + 1); + return; + } + } + if (type_flags & stack_logging_type_dealloc) { + if (size) { + ptr_arg = size; + size = 0; + } else return; // free(nil) + } + if (type_flags & stack_logging_type_alloc && return_val == 0) return; // alloc that failed + + type_flags &= 0x7; + + // now actually begin + prepare_to_log_stacks(); + + // since there could have been a fatal (to stack logging) error such as the log files not being created, check this variable before continuing + if (!stack_logging_enable_logging) return; + vm_address_t self_thread = (vm_address_t)pthread_self(); // use pthread_self() rather than mach_thread_self() to avoid system call + + // lock and enter + OSSpinLockLock(&stack_logging_lock); + + // compaction + if (last_logged_malloc_address && (type_flags & stack_logging_type_dealloc) && STACK_LOGGING_DISGUISE(ptr_arg) == last_logged_malloc_address) { + // *waves hand* the last allocation never occurred + pre_write_buffers->next_free_index_buffer_offset -= (uint32_t)sizeof(stack_logging_index_event); + pre_write_buffers->next_free_stack_buffer_offset -= last_logged_backtrace_offset_diff; + total_offset -= (int64_t)last_logged_backtrace_offset_diff; + last_logged_malloc_address = 0ul; + + // not going to subtract from the current_stack_buffer or current_logging_index indecies; + // there is no intention to restore the previously held stack. the differencing history + // must be reset to its previous value, though. + thread_buffer[compaction_saved_differencing_history.hash_pos] = compaction_saved_differencing_history; + + OSSpinLockUnlock(&stack_logging_lock); + return; + } + + // locate previous backtrace for this thread + short difference = 1; + + uint32_t collisions = STACK_LOGGING_MAX_THREAD_COLLISIONS; + uint32_t hashed_thread = self_thread & (STACK_LOGGING_THREAD_HASH_SIZE-1); + while (thread_buffer[hashed_thread].thread && thread_buffer[hashed_thread].thread != self_thread) { + if (--collisions == 0) { + difference = 0; + break; + } + hashed_thread++; + } + + // gather stack + uint32_t count; + thread_stack_pcs(stack_buffer[current_stack_buffer], STACK_LOGGING_MAX_STACK_SIZE, &count); + stack_buffer[current_stack_buffer][count++] = self_thread + 1; // stuffing thread # in the coldest slot. Add 1 to match what the old stack logging did. + num_hot_to_skip += 2; + if (count <= num_hot_to_skip) { + // Oops! Didn't get a valid backtrace from thread_stack_pcs(). + OSSpinLockUnlock(&stack_logging_lock); + return; + } + + // easy access variables + thread_backtrace_history *historical = &thread_buffer[hashed_thread]; + vm_address_t *frames = stack_buffer[current_stack_buffer]; + + // increment as necessary + current_logging_index++; + current_stack_buffer++; + if (current_stack_buffer == STACK_LOGGING_NUMBER_RECENT_BACKTRACES) current_stack_buffer = 0; + + // difference (if possible) + if (historical->logging_index + STACK_LOGGING_NUMBER_RECENT_BACKTRACES <= current_logging_index) difference = 0; + else if (historical->full_backtrace_countdown == 0) difference = 0; + + uint32_t sameness = 0; + if (difference) { + uint32_t old_count = historical->backtrace_length; + int32_t new_count = (int32_t)count; + while (old_count-- && new_count-- > (int32_t)num_hot_to_skip) { + if (historical->backtrace[old_count] == frames[new_count]) sameness++; + else break; + } + + if (sameness < STACK_LOGGING_MIN_SAME_FRAMES) { // failure; pretend nothing was the same + difference = 0; + } + } + + // create events for byte storage + count -= num_hot_to_skip; + stack_logging_backtrace_event current_event; + current_event.num_identical_frames = (difference ? sameness : 0); + current_event.num_new_hot_frames = (difference ? count - sameness : count); + current_event.offset_delta = (difference ? historical->logging_offset - total_offset : 0); + int64_t this_offset_change = sizeof(stack_logging_backtrace_event) + (current_event.num_new_hot_frames * sizeof(uintptr_t)); + + stack_logging_index_event current_index; + if (type_flags & stack_logging_type_alloc) { + current_index.address = STACK_LOGGING_DISGUISE(return_val); + current_index.argument = size; + if (logging_use_compaction) { + last_logged_malloc_address = current_index.address; // disguised + last_logged_backtrace_offset_diff = (uint32_t)this_offset_change; + compaction_saved_differencing_history = *historical; + } + } else { + current_index.address = STACK_LOGGING_DISGUISE(ptr_arg); + current_index.argument = 0ul; + last_logged_malloc_address = 0ul; + } + current_index.offset_and_flags = STACK_LOGGING_OFFSET_AND_FLAGS(total_offset, type_flags); + + // prepare for differencing next time + historical->backtrace = (uintptr_t*)(frames + num_hot_to_skip); + historical->backtrace_length = count; + if (difference) historical->full_backtrace_countdown--; + else historical->full_backtrace_countdown = STACK_LOGGING_FORCE_FULL_BACKTRACE_EVERY; + historical->logging_index = current_logging_index; + historical->logging_offset = total_offset; + historical->thread = self_thread; + historical->hash_pos = hashed_thread; + + // flush the data buffer to disk if necessary + if (pre_write_buffers->next_free_stack_buffer_offset + this_offset_change >= STACK_LOGGING_BLOCK_WRITING_SIZE) { + flush_data(); + } else if (pre_write_buffers->next_free_index_buffer_offset + sizeof(stack_logging_index_event) >= STACK_LOGGING_BLOCK_WRITING_SIZE) { + flush_data(); + } + + // store bytes in buffers + memcpy(pre_write_index_buffer+pre_write_buffers->next_free_index_buffer_offset, ¤t_index, sizeof(stack_logging_index_event)); + memcpy(pre_write_backtrace_event_buffer+pre_write_buffers->next_free_stack_buffer_offset, ¤t_event, sizeof(stack_logging_backtrace_event)); + memcpy(pre_write_backtrace_event_buffer+pre_write_buffers->next_free_stack_buffer_offset+sizeof(stack_logging_backtrace_event), frames+num_hot_to_skip, (size_t)this_offset_change - sizeof(stack_logging_backtrace_event)); + pre_write_buffers->next_free_index_buffer_offset += (uint32_t)sizeof(stack_logging_index_event); + pre_write_buffers->next_free_stack_buffer_offset += (uint32_t)this_offset_change; + total_offset += this_offset_change; + + OSSpinLockUnlock(&stack_logging_lock); +} + +#pragma mark - +#pragma mark Remote Stack Log Access + +#pragma mark - Design notes: + +/* + +this first one will look through the index, find the "stack_identifier" (i.e. the offset in the log file), and call the third function listed here. +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 *num_frames); + // Gets the last allocation record about address + +if !address, will load both index and stack logs and iterate through (expensive) +else will load just index, search for stack, and then use third function here to retrieve. (also expensive) +extern 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); + // Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies enumerator to all records + +this function will load the stack file, look for the stack, and follow up to STACK_LOGGING_FORCE_FULL_BACKTRACE_EVERY references to reconstruct. +extern 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); + // Given a uniqued_stack fills stack_frames_buffer + +*/ + +#pragma mark - caching + +static inline size_t hash_index_32(uint32_t address, size_t max_pos) __attribute__((always_inline)); +static inline size_t hash_index_32(uint32_t address, size_t max_pos) { +// return (((OSSwapInt32(address >> 2) << 3) & 0x96AAAA98) ^ (address >> 2)) % (max_pos-1); + return (address >> 2) % (max_pos-1); // simplicity rules. +} + +static inline size_t hash_index_64(uint64_t address, size_t max_pos) __attribute__((always_inline)); +static inline size_t hash_index_64(uint64_t address, size_t max_pos) { +// return (size_t)((((OSSwapInt64(address >> 3) << 2) & 0x54AA0A0AAA54ull) ^ (address >> 3)) % (max_pos - 1)); + return (size_t)((address >> 3) % (max_pos-1)); // simplicity rules. +} + +static void +transfer_node_ll32(remote_index_cache *cache, remote_index_node32 *old_node) +{ + uint32_t collisions = 0; + size_t pos = hash_index_32(old_node->address, cache->cache_node_capacity); + do { + if (cache->casted_table32[pos].address == old_node->address) { // hit like this shouldn't happen. + fprintf(stderr, "impossible collision! two address==address lists! (transfer_node_ll32)\n"); + break; + } else if (cache->casted_table32[pos].address == 0) { // empty + cache->casted_table32[pos] = *old_node; + break; + } else { + pos++; + if (pos >= cache->cache_node_capacity) pos = 0; + } + collisions++; + } while (collisions <= cache->collision_allowance); + + if (collisions > cache->collision_allowance) { + fprintf(stderr, "reporting bad hash function! disk stack logging reader %lu bit. (transfer_node_ll32)\n", sizeof(void*)*8); + } +} + +static void +transfer_node_ll64(remote_index_cache *cache, remote_index_node64 *old_node) +{ + uint32_t collisions = 0; + size_t pos = hash_index_64(old_node->address, cache->cache_node_capacity); + do { + if (cache->casted_table64[pos].address == old_node->address) { // hit! + fprintf(stderr, "impossible collision! two address==address lists! (transfer_node_ll64)\n"); + break; + } else if (cache->casted_table64[pos].address == 0) { // empty + cache->casted_table64[pos] = *old_node; + break; + } else { + pos++; + if (pos >= cache->cache_node_capacity) pos = 0; + } + collisions++; + } while (collisions <= cache->collision_allowance); + + if (collisions > cache->collision_allowance) { + fprintf(stderr, "reporting bad hash function! disk stack logging reader %lu bit. (transfer_node_ll64)\n", sizeof(void*)*8); + } +} + +static void +expand_cache(remote_index_cache *cache) +{ + // keep old stats + size_t old_node_capacity = cache->cache_node_capacity; + uint64_t old_node_count = cache->cache_node_count; + uint64_t old_llnode_count = cache->cache_llnode_count; + void *old_table = cache->table_memory; + + // double size + cache->cache_size <<= 1; + cache->cache_node_capacity <<= 1; + cache->collision_allowance += STACK_LOGGING_REMOTE_CACHE_COLLISION_GROWTH_RATE; + cache->table_memory = (void*)calloc(cache->cache_node_capacity, cache->in_use_node_size); + if (cache->casted_table32) cache->casted_table32 = cache->table_memory; + else cache->casted_table64 = cache->table_memory; + + // repopulate (expensive!) + size_t i; + if (cache->casted_table32) { // if target is 32-bit + remote_index_node32 *casted_old_table = (remote_index_node32*)old_table; + for (i = 0; i < old_node_capacity; i++) { + if (casted_old_table[i].address) { + transfer_node_ll32(cache, &casted_old_table[i]); + } + } + } else { + remote_index_node64 *casted_old_table = (remote_index_node64*)old_table; + for (i = 0; i < old_node_capacity; i++) { + if (casted_old_table[i].address) { + transfer_node_ll64(cache, &casted_old_table[i]); + } + } + } + + cache->cache_node_count = old_node_count; + cache->cache_llnode_count = old_llnode_count; + free(old_table); +// printf("cache expanded to %0.2f mb (eff: %3.0f%%, capacity: %lu, nodes: %llu, llnodes: %llu)\n", ((float)(cache->cache_size))/(1 << 20), ((float)(cache->cache_node_count)*100.0)/((float)(cache->cache_node_capacity)), cache->cache_node_capacity, cache->cache_node_count, cache->cache_llnode_count); +} + +static void +insert_node32(remote_index_cache *cache, uint32_t address, uint64_t index_file_offset) +{ + uint32_t collisions = 0; + size_t pos = hash_index_32(address, cache->cache_node_capacity); + + if (cache->next_block_index >= STACK_LOGGING_REMOTE_LINKS_PER_BLOCK) { + cache->next_block_index = 0; + cache->current_block++; + cache->blocks[cache->current_block] = (index_ll_node*)malloc(STACK_LOGGING_REMOTE_LINKS_PER_BLOCK*sizeof(index_ll_node)); +/* printf("node buffer added. total nodes: %ul (%u buffers, %0.2f mb)\n", STACK_LOGGING_REMOTE_LINKS_PER_BLOCK*(cache->current_block+1), + cache->current_block+1, ((float)(STACK_LOGGING_REMOTE_LINKS_PER_BLOCK*sizeof(index_ll_node)*(cache->current_block+1)))/(1 << 20)); +*/ + } + index_ll_node *new_node = &cache->blocks[cache->current_block][cache->next_block_index++]; + new_node->index_file_offset = index_file_offset; + new_node->next = NULL; + + bool inserted = false; + while (!inserted) { + if (cache->casted_table32[pos].address == address) { // hit! + cache->casted_table32[pos].last_link->next = new_node; // insert at end + cache->casted_table32[pos].last_link = new_node; + inserted = true; + break; + } else if (cache->casted_table32[pos].address == 0) { // empty + cache->casted_table32[pos].address = address; + cache->casted_table32[pos].linked_list = new_node; + cache->casted_table32[pos].last_link = new_node; + cache->cache_node_count++; + inserted = true; + break; + } else { + pos++; + if (pos >= cache->cache_node_capacity) pos = 0; + } + collisions++; + if (collisions > cache->collision_allowance) { + expand_cache(cache); + pos = hash_index_32(address, cache->cache_node_capacity); + collisions = 0; + } + } + + cache->cache_llnode_count++; + +} + +static void +insert_node64(remote_index_cache *cache, uint64_t address, uint64_t index_file_offset) +{ + uint32_t collisions = 0; + size_t pos = hash_index_64(address, cache->cache_node_capacity); + + if (cache->next_block_index >= STACK_LOGGING_REMOTE_LINKS_PER_BLOCK) { + cache->next_block_index = 0; + cache->current_block++; + cache->blocks[cache->current_block] = (index_ll_node*)malloc(STACK_LOGGING_REMOTE_LINKS_PER_BLOCK*sizeof(index_ll_node)); + } + index_ll_node *new_node = &cache->blocks[cache->current_block][cache->next_block_index++]; + new_node->index_file_offset = index_file_offset; + new_node->next = NULL; + + bool inserted = false; + while (!inserted) { + if (cache->casted_table64[pos].address == address) { // hit! + cache->casted_table64[pos].last_link->next = new_node; // insert at end + cache->casted_table64[pos].last_link = new_node; + inserted = true; + break; + } else if (cache->casted_table64[pos].address == 0) { // empty + cache->casted_table64[pos].address = address; + cache->casted_table64[pos].linked_list = new_node; + cache->casted_table64[pos].last_link = new_node; + inserted = true; + break; + } else { + pos++; + if (pos >= cache->cache_node_capacity) pos = 0; + } + collisions++; + if (collisions > cache->collision_allowance) { + expand_cache(cache); + pos = hash_index_64(address, cache->cache_node_capacity); + collisions = 0; + } + } + +} + +static void +update_cache_for_file_streams(remote_task_file_streams *descriptors) +{ + remote_index_cache *cache = descriptors->cache; + + // create from scratch if necessary. + if (!cache) { + descriptors->cache = cache = (remote_index_cache*)calloc((size_t)1, sizeof(remote_index_cache)); + cache->cache_node_capacity = STACK_LOGGING_REMOTE_CACHE_DEFAULT_NODE_CAPACITY; + cache->collision_allowance = STACK_LOGGING_REMOTE_CACHE_DEFAULT_COLLISION_ALLOWANCE; + cache->cache_node_count = cache->cache_llnode_count = 0; + cache->last_index_file_offset = 0; + cache->next_block_index = 0; + cache->current_block = 0; + cache->blocks[0] = (index_ll_node*)malloc(STACK_LOGGING_REMOTE_LINKS_PER_BLOCK*sizeof(index_ll_node)); + cache->in_use_node_size = (descriptors->task_is_64_bit ? sizeof(remote_index_node64) : sizeof(remote_index_node32)); + cache->cache_size = cache->cache_node_capacity*cache->in_use_node_size; + cache->table_memory = (void*)calloc(cache->cache_node_capacity, cache->in_use_node_size); + if (descriptors->task_is_64_bit) cache->casted_table64 = (remote_index_node64*)(cache->table_memory); + else cache->casted_table32 = (remote_index_node32*)(cache->table_memory); + + // now map in the shared memory, if possible + char shmem_name_string[PATH_MAX]; + strlcpy(shmem_name_string, stack_logging_directory_base_name, (size_t)PATH_MAX); + append_int(shmem_name_string, descriptors->remote_pid); + + int shmid = shm_open(shmem_name_string, O_RDWR, S_IRUSR | S_IWUSR); + if (shmid >= 0) { + cache->shmem = mmap(0, sizeof(stack_buffer_shared_memory), PROT_READ | PROT_WRITE, MAP_SHARED, shmid, (off_t)0); + close(shmid); + } + + if (shmid < 0 || cache->shmem == NULL) { + // 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"); + } + } + + // suspend and see how much updating there is to do. there are three scenarios, listed below + bool update_snapshot = false; + if (descriptors->remote_task != mach_task_self()) { + task_suspend(descriptors->remote_task); + } + + struct stat file_statistics; + fstat(fileno(descriptors->index_file_stream), &file_statistics); + size_t read_size = (descriptors->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); + uint64_t read_this_update = 0; + + // the delta indecies is a complex number; there are three cases: + // 1. there is no shared memory (or we can't connect); diff the last_index_file_offset from the filesize. + // 2. the only updates have been in shared memory; disk file didn't change at all. delta_indecies should be zero, scan snapshot only. + // 3. the updates have flushed to disk, meaning that most likely there is new data on disk that wasn't read from shared memory. + // correct delta_indecies for the pre-scanned amount and read the new data from disk and shmem. + uint64_t delta_indecies = (file_statistics.st_size - cache->last_index_file_offset) / read_size; + uint32_t last_snapshot_scan_index = 0; + if (delta_indecies && cache->shmem) { + // case 3: add cache scanned to known from disk and recalc + cache->last_index_file_offset += cache->snapshot.next_free_index_buffer_offset; + delta_indecies = (file_statistics.st_size - cache->last_index_file_offset) / read_size; + update_snapshot = true; + } else if (cache->shmem) { + // case 2: set the last snapshot scan count so we don't rescan something we've seen. + last_snapshot_scan_index = cache->snapshot.next_free_index_buffer_offset / (uint32_t)read_size; + } + + // no update necessary for the file; check if need a snapshot. + if (delta_indecies == 0) { + if (cache->shmem && !update_snapshot) { + update_snapshot = (cache->shmem->next_free_index_buffer_offset != cache->snapshot.next_free_index_buffer_offset); + } + } + + // 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 + // 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) { + memcpy(&cache->snapshot, cache->shmem, sizeof(stack_buffer_shared_memory)); + } + + // resume + if (descriptors->remote_task != mach_task_self()) { + task_resume(descriptors->remote_task); + } + + if (!update_snapshot && delta_indecies == 0) return; // absolutely no updating needed. + + FILE *the_index = (descriptors->index_file_stream); + + // prepare for the read; target process could be 32 or 64 bit. + + stack_logging_index_event32 *target_32_index = NULL; + stack_logging_index_event64 *target_64_index = NULL; + + // perform the update from the file + uint32_t i; + if (delta_indecies) { + char bufferSpace[4096]; // 4 kb + target_32_index = (stack_logging_index_event32*)bufferSpace; + target_64_index = (stack_logging_index_event64*)bufferSpace; + size_t number_slots = (size_t)(4096/read_size); + + size_t read_count = 0; + if (fseeko(the_index, (off_t)(cache->last_index_file_offset), SEEK_SET)) { + fprintf(stderr, "error while attempting to cache information from remote stack index file. (update_cache_for_file_streams)\n"); + } + off_t current_index_position = cache->last_index_file_offset; + do { + number_slots = MIN(delta_indecies - read_this_update, number_slots); + read_count = fread(bufferSpace, read_size, number_slots, the_index); + if (descriptors->task_is_64_bit) { + for (i = 0; i < read_count; i++) { + insert_node64(cache, STACK_LOGGING_DISGUISE(target_64_index[i].address), (uint64_t)current_index_position); + read_this_update++; + current_index_position += read_size; + } + } else { + for (i = 0; i < read_count; i++) { + insert_node32(cache, STACK_LOGGING_DISGUISE(target_32_index[i].address), (uint64_t)current_index_position); + read_this_update++; + current_index_position += read_size; + } + } + } while (read_count); + + if (read_this_update < delta_indecies) { + fprintf(stderr, "insufficient data in remote stack index file; expected more records.\n"); + } + cache->last_index_file_offset += read_this_update * read_size; + } + + if (update_snapshot) { + target_32_index = (stack_logging_index_event32*)(cache->snapshot.index_buffer); + target_64_index = (stack_logging_index_event64*)(cache->snapshot.index_buffer); + + uint32_t free_snapshot_scan_index = cache->snapshot.next_free_index_buffer_offset / (uint32_t)read_size; + off_t current_index_position = cache->snapshot.start_index_offset; + if (descriptors->task_is_64_bit) { + for (i = last_snapshot_scan_index; i < free_snapshot_scan_index; i++) { + insert_node64(cache, STACK_LOGGING_DISGUISE(target_64_index[i].address), (uint64_t)(current_index_position + (i * read_size))); + } + } else { + for (i = last_snapshot_scan_index; i < free_snapshot_scan_index; i++) { + insert_node32(cache, STACK_LOGGING_DISGUISE(target_32_index[i].address), (uint64_t)(current_index_position + (i * read_size))); + } + } + } + +} + +static void +destroy_cache_for_file_streams(remote_task_file_streams *descriptors) +{ + uint32_t i; + for (i = 0; i <= descriptors->cache->current_block; i++) { + free(descriptors->cache->blocks[i]); // clears the linked list nodes. + } + if (descriptors->cache->shmem) { + munmap(descriptors->cache->shmem, sizeof(stack_buffer_shared_memory)); + } + free(descriptors->cache->table_memory); + free(descriptors->cache); + descriptors->cache = NULL; +} + +#pragma mark - internal + +// 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. +static void +open_log_files(pid_t pid, remote_task_file_streams *this_task_streams) +{ + DIR *dp; + struct dirent *entry; + int prefix_length; + char prefix_name[PATH_MAX]; + char pathname[PATH_MAX]; + + reap_orphaned_log_files(false); // reap any left-over log files (for non-existant processes, but not for this analysis process) + + if ((dp = opendir(temporary_directory)) == NULL) { + return; + } + + // It's OK to use snprintf in this routine since it should only be called by the clients + // of stack logging, and thus calls to malloc are OK. + snprintf(prefix_name, PATH_MAX, "%s%d.", stack_logging_directory_base_name, pid); // make sure to use "%s%d." rather than just "%s%d" to match the whole pid + prefix_length = strlen(prefix_name); + + while ( (entry = readdir(dp)) != NULL ) { + if ( strncmp( entry->d_name, prefix_name, prefix_length) == 0 ) { + snprintf(pathname, PATH_MAX, "%s/%s/%s", temporary_directory, entry->d_name, index_file_name); + this_task_streams->index_file_stream = fopen(pathname, "r"); + + snprintf(pathname, PATH_MAX, "%s/%s/%s", temporary_directory, entry->d_name, stack_file_name); + this_task_streams->stack_file_stream = fopen(pathname, "r"); + + break; + } + } + closedir(dp); +} + +static remote_task_file_streams* +retain_file_streams_for_task(task_t task) +{ + OSSpinLockLock(&remote_fd_list_lock); + + // see if they're already in use + uint32_t i = 0; + for (i = 0; i < remote_task_fd_count; i++) { + if (remote_fds[i].remote_task == task) { + remote_fds[i].in_use_count++; + OSSpinLockUnlock(&remote_fd_list_lock); + return &remote_fds[i]; + } + } + + // open them + uint32_t failures = 0; + if (remote_task_fd_count == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) { + while (remote_fds[next_remote_task_fd].in_use_count > 0) { + next_remote_task_fd++; + if (next_remote_task_fd == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) next_remote_task_fd = 0; + failures++; + if (failures >= STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) { + OSSpinLockUnlock(&remote_fd_list_lock); + return NULL; + } + } + fclose(remote_fds[next_remote_task_fd].index_file_stream); + fclose(remote_fds[next_remote_task_fd].stack_file_stream); + destroy_cache_for_file_streams(&remote_fds[next_remote_task_fd]); + } + + pid_t pid; + kern_return_t err = pid_for_task(task, &pid); + if (err != KERN_SUCCESS) { + OSSpinLockUnlock(&remote_fd_list_lock); + return NULL; + } + + remote_task_file_streams *this_task_streams = &remote_fds[next_remote_task_fd]; + + open_log_files(pid, this_task_streams); + + // check if opens failed + if (this_task_streams->index_file_stream == NULL || this_task_streams->stack_file_stream == NULL) { + if (this_task_streams->index_file_stream) fclose(this_task_streams->index_file_stream); + if (this_task_streams->stack_file_stream) fclose(this_task_streams->stack_file_stream); + OSSpinLockUnlock(&remote_fd_list_lock); + return NULL; + } + + // check if target pid is running 64-bit + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; + struct kinfo_proc processInfo; + size_t bufsize = sizeof(processInfo); + if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, &bufsize, NULL, (size_t)0) == 0 && bufsize > 0) { + this_task_streams->task_is_64_bit = processInfo.kp_proc.p_flag & P_LP64; + } else { + this_task_streams->task_is_64_bit = 0; + } + + // otherwise set vars and go + this_task_streams->in_use_count = 1; + this_task_streams->remote_task = task; + this_task_streams->remote_pid = pid; + next_remote_task_fd++; + if (next_remote_task_fd == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) next_remote_task_fd = 0; + remote_task_fd_count = MIN(remote_task_fd_count + 1, STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED); + + OSSpinLockUnlock(&remote_fd_list_lock); + return this_task_streams; +} + +static void +release_file_streams_for_task(task_t task) +{ + OSSpinLockLock(&remote_fd_list_lock); + + // decrement in-use count + uint32_t i = 0; + for (i = 0; i < remote_task_fd_count; i++) { + if (remote_fds[i].remote_task == task) { + remote_fds[i].in_use_count--; + break; + } + } + + OSSpinLockUnlock(&remote_fd_list_lock); +} + +#pragma mark - 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) +{ + remote_task_file_streams *remote_fd = retain_file_streams_for_task(task); + if (remote_fd == NULL) { + return KERN_FAILURE; + } + + update_cache_for_file_streams(remote_fd); + + uint32_t collisions = 0; + uint64_t located_file_position = 0; + bool found = false; + size_t hash = 0; + if (remote_fd->task_is_64_bit) { + hash = hash_index_64(address, remote_fd->cache->cache_node_capacity); + do { + if (remote_fd->cache->casted_table64[hash].address == address) { // hit! + located_file_position = remote_fd->cache->casted_table64[hash].last_link->index_file_offset; + found = true; + break; + } else if (remote_fd->cache->casted_table64[hash].address == 0) { // failure! + break; + } + hash++; + if (hash >= remote_fd->cache->cache_node_capacity) hash = 0; + } while (collisions <= remote_fd->cache->collision_allowance); + } else { + hash = hash_index_32((uint32_t)address, remote_fd->cache->cache_node_capacity); + do { + if (remote_fd->cache->casted_table32[hash].address == (uint32_t)address) { // hit! + located_file_position = remote_fd->cache->casted_table32[hash].last_link->index_file_offset; + found = true; + break; + } else if (remote_fd->cache->casted_table32[hash].address == 0) { // failure! + break; + } + hash++; + if (hash >= remote_fd->cache->cache_node_capacity) hash = 0; + } while (collisions <= remote_fd->cache->collision_allowance); + } + + if (found) { + // prepare for the read; target process could be 32 or 64 bit. + stack_logging_index_event32 *target_32_index = NULL; + stack_logging_index_event64 *target_64_index = NULL; + + if (located_file_position >= remote_fd->cache->last_index_file_offset) { + // must be in shared memory + if (remote_fd->cache->shmem) { + if (remote_fd->task_is_64_bit) { + target_64_index = (stack_logging_index_event64*)(remote_fd->cache->snapshot.index_buffer + (located_file_position - remote_fd->cache->snapshot.start_index_offset)); + located_file_position = STACK_LOGGING_OFFSET(target_64_index->offset_and_flags); + } else { + target_32_index = (stack_logging_index_event32*)(remote_fd->cache->snapshot.index_buffer + (located_file_position - remote_fd->cache->snapshot.start_index_offset)); + located_file_position = STACK_LOGGING_OFFSET(target_32_index->offset_and_flags); + } + } else { + found = false; + } + + } else { + // it's written to disk + char bufferSpace[128]; + + size_t read_size = (remote_fd->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); + fseeko(remote_fd->index_file_stream, (off_t)located_file_position, SEEK_SET); + size_t read_count = fread(bufferSpace, read_size, (size_t)1, remote_fd->index_file_stream); + if (read_count) { + if (remote_fd->task_is_64_bit) { + target_64_index = (stack_logging_index_event64*)bufferSpace; + located_file_position = STACK_LOGGING_OFFSET(target_64_index->offset_and_flags); + } else { + target_32_index = (stack_logging_index_event32*)bufferSpace; + located_file_position = STACK_LOGGING_OFFSET(target_32_index->offset_and_flags); + } + } else { + found = false; + } + } + } + + release_file_streams_for_task(task); + + if (!found) { + return KERN_FAILURE; + } + + return __mach_stack_logging_frames_for_uniqued_stack(task, located_file_position, stack_frames_buffer, max_stack_frames, count); +} + + +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); + if (remote_fd == NULL) { + return KERN_FAILURE; + } + + bool reading_all_addresses = (address == 0 ? true : false); + mach_stack_logging_record_t pass_record; + kern_return_t err = KERN_SUCCESS; + + if (reading_all_addresses) { // just stupidly read the index file from disk + + // update (read index file once and only once) + update_cache_for_file_streams(remote_fd); + + FILE *the_index = (remote_fd->index_file_stream); + + // prepare for the read; target process could be 32 or 64 bit. + char bufferSpace[2048]; // 2 kb + stack_logging_index_event32 *target_32_index = (stack_logging_index_event32*)bufferSpace; + stack_logging_index_event64 *target_64_index = (stack_logging_index_event64*)bufferSpace; + uint32_t target_addr_32 = (uint32_t)STACK_LOGGING_DISGUISE((uint32_t)address); + uint64_t target_addr_64 = STACK_LOGGING_DISGUISE((uint64_t)address); + size_t read_size = (remote_fd->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); + size_t number_slots = (size_t)(2048/read_size); + uint64_t total_slots = remote_fd->cache->last_index_file_offset / read_size; + + // perform the search + size_t read_count = 0; + int64_t current_file_offset = 0; + uint32_t i; + do { + // at this point, we need to read index events; read them from the file until it's necessary to grab them from the shared memory snapshot + // and crop file reading to the point where we last scanned + number_slots = (size_t)MIN(number_slots, total_slots); + + // if out of file to read (as of the time we entered this function), try to use shared memory snapshot + if (number_slots == 0) { + if (remote_fd->cache->shmem && remote_fd->cache->snapshot.start_index_offset + remote_fd->cache->snapshot.next_free_index_buffer_offset > (uint64_t)current_file_offset) { + // use shared memory + target_32_index = (stack_logging_index_event32*)remote_fd->cache->snapshot.index_buffer; + target_64_index = (stack_logging_index_event64*)remote_fd->cache->snapshot.index_buffer; + read_count = (uint32_t)(remote_fd->cache->snapshot.start_index_offset + remote_fd->cache->snapshot.next_free_index_buffer_offset - current_file_offset) / read_size; + current_file_offset += read_count * read_size; + } else { + break; + } + } else { + // get and save index (enumerator could modify) + fseeko(the_index, current_file_offset, SEEK_SET); + read_count = fread(bufferSpace, read_size, number_slots, the_index); + current_file_offset = ftello(the_index); + total_slots -= read_count; + } + + if (remote_fd->task_is_64_bit) { + for (i = 0; i < read_count; i++) { + if (reading_all_addresses || target_64_index[i].address == target_addr_64) { + pass_record.address = STACK_LOGGING_DISGUISE(target_64_index[i].address); + pass_record.argument = target_64_index[i].argument; + pass_record.stack_identifier = STACK_LOGGING_OFFSET(target_64_index[i].offset_and_flags); + pass_record.type_flags = STACK_LOGGING_FLAGS(target_64_index[i].offset_and_flags); + enumerator(pass_record, context); + } + } + } else { + for (i = 0; i < read_count; i++) { + if (reading_all_addresses || target_32_index[i].address == target_addr_32) { + pass_record.address = STACK_LOGGING_DISGUISE(target_32_index[i].address); + pass_record.argument = target_32_index[i].argument; + pass_record.stack_identifier = STACK_LOGGING_OFFSET(target_32_index[i].offset_and_flags); + pass_record.type_flags = STACK_LOGGING_FLAGS(target_32_index[i].offset_and_flags); + enumerator(pass_record, context); + } + } + } + } while (read_count); + + } else { // searching for a single address' history + + // update (read index file once and only once) + update_cache_for_file_streams(remote_fd); + + // get linked-list of events + uint32_t collisions = 0; + uint64_t located_file_position = 0; + size_t hash = 0; + index_ll_node *index_position_linked_list = NULL; + if (remote_fd->task_is_64_bit) { + hash = hash_index_64(address, remote_fd->cache->cache_node_capacity); + do { + if (remote_fd->cache->casted_table64[hash].address == address) { // hit! + index_position_linked_list = remote_fd->cache->casted_table64[hash].linked_list; + break; + } else if (remote_fd->cache->casted_table64[hash].address == 0) { // failure! + break; + } + hash++; + if (hash >= remote_fd->cache->cache_node_capacity) hash = 0; + } while (collisions <= remote_fd->cache->collision_allowance); + } else { + hash = hash_index_32((uint32_t)address, remote_fd->cache->cache_node_capacity); + do { + if (remote_fd->cache->casted_table32[hash].address == (uint32_t)address) { // hit! + index_position_linked_list = remote_fd->cache->casted_table32[hash].linked_list; + break; + } else if (remote_fd->cache->casted_table32[hash].address == 0) { // failure! + break; + } + hash++; + if (hash >= remote_fd->cache->cache_node_capacity) hash = 0; + } while (collisions <= remote_fd->cache->collision_allowance); + } + + // if we got something, run it + char bufferSpace[128]; + size_t read_count = 0; + stack_logging_index_event32 *target_32_index = (stack_logging_index_event32*)bufferSpace; + stack_logging_index_event64 *target_64_index = (stack_logging_index_event64*)bufferSpace; + size_t read_size = (remote_fd->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); + while (index_position_linked_list) { + located_file_position = index_position_linked_list->index_file_offset; + + if (located_file_position >= remote_fd->cache->snapshot.start_index_offset) { + if (remote_fd->cache->shmem && located_file_position >= remote_fd->cache->snapshot.start_index_offset && remote_fd->cache->snapshot.start_index_offset + remote_fd->cache->snapshot.next_free_index_buffer_offset > (uint64_t)located_file_position) { + // use shared memory + target_32_index = (stack_logging_index_event32*)(remote_fd->cache->snapshot.index_buffer + located_file_position - remote_fd->cache->snapshot.start_index_offset); + target_64_index = (stack_logging_index_event64*)target_32_index; + read_count = 1; + } else { + err = KERN_FAILURE; + break; + } + } else { + fseeko(remote_fd->index_file_stream, (off_t)located_file_position, SEEK_SET); + read_count = fread(bufferSpace, read_size, (size_t)1, remote_fd->index_file_stream); + if (!read_count) { + err = KERN_FAILURE; + break; + } + } + if (remote_fd->task_is_64_bit) { + pass_record.address = STACK_LOGGING_DISGUISE(target_64_index[0].address); + pass_record.argument = target_64_index[0].argument; + pass_record.stack_identifier = STACK_LOGGING_OFFSET(target_64_index[0].offset_and_flags); + pass_record.type_flags = STACK_LOGGING_FLAGS(target_64_index[0].offset_and_flags); + enumerator(pass_record, context); + } else { + pass_record.address = STACK_LOGGING_DISGUISE(target_32_index[0].address); + pass_record.argument = target_32_index[0].argument; + pass_record.stack_identifier = STACK_LOGGING_OFFSET(target_32_index[0].offset_and_flags); + pass_record.type_flags = STACK_LOGGING_FLAGS(target_32_index[0].offset_and_flags); + enumerator(pass_record, context); + } + index_position_linked_list = index_position_linked_list->next; + } + + } + + release_file_streams_for_task(task); + return err; +} + + +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); + if (remote_fd == NULL) { + return KERN_FAILURE; + } + + // prepare for initial read + FILE *stack_fd; + stack_fd = (remote_fd->stack_file_stream); + char bytes_buffer[16]; + stack_logging_backtrace_event *target_stack_event = (stack_logging_backtrace_event*)bytes_buffer; + size_t read_size = sizeof(stack_logging_backtrace_event); + size_t read_count = 0; + off_t reading_offset = (off_t)stack_identifier; + + // get a temporary spot for the backtrace frames to go and reference the stack space such that the reference + // can be later pointed at the shared memory snapshot and data read from there. + uint64_t temp_frames_buffer[STACK_LOGGING_MAX_STACK_SIZE]; + uint64_t *big_frames = (uint64_t*)temp_frames_buffer; + uint32_t *small_frames = (uint32_t*)temp_frames_buffer; + size_t target_frame_size = (remote_fd->task_is_64_bit ? sizeof(uint64_t) : sizeof(uint32_t)); + char *snapshot_backtrace_location = NULL; + + int done = 0; + int32_t total_frames = -1; + int32_t hot_frames_read = 0; + size_t new_hot_frames = 0; + int32_t number_needed_hot_frames_in_event; + size_t number_hot_frames_to_skip; + int32_t i; + bool skip_file_read; + + while (!done) { + + // not in cache; read record Ð from disk if possible, shared memory snapshot if necessary. + if (remote_fd->cache->shmem && reading_offset >= (off_t)(remote_fd->cache->snapshot.start_stack_offset)) { + // must read from shared memory; the record isn't on disk yet + snapshot_backtrace_location = (remote_fd->cache->snapshot.stack_buffer + (reading_offset - remote_fd->cache->snapshot.start_stack_offset)); + *target_stack_event = *(stack_logging_backtrace_event*)snapshot_backtrace_location; + big_frames = (uint64_t*)(snapshot_backtrace_location + sizeof(stack_logging_backtrace_event)); + small_frames = (uint32_t*)big_frames; + skip_file_read = true; + } else { + // the record's on disk + i = fseeko(stack_fd, reading_offset, SEEK_SET); + if (i != 0) break; // unable to seek to the target position + read_count = fread(target_stack_event, read_size, (size_t)1, stack_fd); + if (read_count == 0) break; + + big_frames = (uint64_t*)temp_frames_buffer; + small_frames = (uint32_t*)temp_frames_buffer; + skip_file_read = false; + } + + if (total_frames < 0) { + total_frames = target_stack_event->num_new_hot_frames + target_stack_event->num_identical_frames; + if (total_frames > (int32_t)max_stack_frames) break; // don't know what to do with this; we'll just KERN_FAILURE. + } + + // do the math to find how many frames to apply from previous event + new_hot_frames = target_stack_event->num_new_hot_frames; + number_needed_hot_frames_in_event = total_frames - hot_frames_read - target_stack_event->num_identical_frames; + number_hot_frames_to_skip = new_hot_frames - number_needed_hot_frames_in_event; + + // read and apply the important frames of this one + if (number_needed_hot_frames_in_event > 0) { + if (!skip_file_read) { + read_count = fread(temp_frames_buffer, target_frame_size, new_hot_frames, stack_fd); + if (read_count < new_hot_frames) break; + } + + if (remote_fd->task_is_64_bit) { + for (i = 0; i < number_needed_hot_frames_in_event; i++) { + stack_frames_buffer[hot_frames_read++] = big_frames[i+number_hot_frames_to_skip]; + } + } else { + for (i = 0; i < number_needed_hot_frames_in_event; i++) { + stack_frames_buffer[hot_frames_read++] = small_frames[i+number_hot_frames_to_skip]; + } + } + } + + reading_offset += target_stack_event->offset_delta; + + if (hot_frames_read == total_frames) done = 1; + else if (target_stack_event->offset_delta == 0) { + fprintf(stderr, "incomplete stack record (identifier: 0x%qx)\n", reading_offset); + break; + } + } + + release_file_streams_for_task(task); + + if (done) { + *count = hot_frames_read; + return KERN_SUCCESS; + } else { + return KERN_FAILURE; + } +} + + +#ifdef TEST_DISK_STACK_LOGGING + +// cc -o stack_logging_disk stack_logging_disk.c -DTEST_DISK_STACK_LOGGING + +#include + +main() +{ + int status; + int i; + + fprintf(stderr, "master test process is %d\n", getpid()); + fprintf(stderr, "sizeof stack_buffer: %d\n", sizeof(stack_buffer)); + fprintf(stderr, "sizeof thread_buffer: %d\n", sizeof(thread_buffer)); + fprintf(stderr, "sizeof stack_logs_directory: %d\n", sizeof(stack_logs_directory)); + fprintf(stderr, "sizeof remote_fds: %d\n", sizeof(remote_fds)); + fprintf(stderr, "address of pre_write_backtrace_event_buffer: %p\n", &pre_write_backtrace_event_buffer); + fprintf(stderr, "address of logging_use_compaction: %p\n", &logging_use_compaction); + // fprintf(stderr, "size of all global data: %d\n", (logging_use_compaction) - (pre_write_backtrace_event_buffer) + sizeof(logging_use_compaction)); + + create_log_files(); + + // create a few child processes and exit them cleanly so their logs should get cleaned up + fprintf(stderr, "\ncreating child processes and exiting cleanly\n"); + for (i = 0; i < 3; i++) { + if (fork() == 0) { + fprintf(stderr, "\nin child processes %d\n", getpid()); + create_log_files(); + fprintf(stderr, "exiting child processes %d\n", getpid()); + exit(1); + } + wait(&status); + } + + // create a few child processes and abruptly _exit them, leaving their logs around + fprintf(stderr, "\ncreating child processes and exiting abruptly, leaving logs around\n"); + for (i = 0; i < 3; i++) { + if (fork() == 0) { + fprintf(stderr, "\nin child processes %d\n", getpid()); + create_log_files(); + fprintf(stderr, "exiting child processes %d\n", getpid()); + _exit(1); + } + wait(&status); + } + + // this should reap any remaining logs + fprintf(stderr, "\nexiting master test process %d\n", getpid()); + delete_log_files(); +} + +#endif diff --git a/gen/stringlist-fbsd.c b/gen/stringlist-fbsd.c new file mode 100644 index 0000000..1d977e4 --- /dev/null +++ b/gen/stringlist-fbsd.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1994 Christos Zoulas + * 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 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. + * + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#define _SL_CHUNKSIZE 20 + +/* + * sl_init(): Initialize a string list + */ +StringList * +sl_init() +{ + StringList *sl; + + sl = malloc(sizeof(StringList)); + if (sl == NULL) + _err(1, "stringlist: %m"); + + sl->sl_cur = 0; + sl->sl_max = _SL_CHUNKSIZE; + sl->sl_str = malloc(sl->sl_max * sizeof(char *)); + if (sl->sl_str == NULL) + _err(1, "stringlist: %m"); + return sl; +} + + +/* + * sl_add(): Add an item to the string list + */ +int +sl_add(sl, name) + StringList *sl; + char *name; +{ + if (sl->sl_cur == sl->sl_max - 1) { + sl->sl_max += _SL_CHUNKSIZE; + sl->sl_str = reallocf(sl->sl_str, sl->sl_max * sizeof(char *)); + if (sl->sl_str == NULL) + return (-1); + } + sl->sl_str[sl->sl_cur++] = name; + return (0); +} + + +/* + * sl_free(): Free a stringlist + */ +void +sl_free(sl, all) + StringList *sl; + int all; +{ + size_t i; + + if (sl == NULL) + return; + if (sl->sl_str) { + if (all) + for (i = 0; i < sl->sl_cur; i++) + free(sl->sl_str[i]); + free(sl->sl_str); + } + free(sl); +} + + +/* + * sl_find(): Find a name in the string list + */ +char * +sl_find(sl, name) + StringList *sl; + char *name; +{ + size_t i; + + for (i = 0; i < sl->sl_cur; i++) + if (strcmp(sl->sl_str[i], name) == 0) + return sl->sl_str[i]; + + return NULL; +} diff --git a/gen/stringlist.3 b/gen/stringlist.3 new file mode 120000 index 0000000..7a75e09 --- /dev/null +++ b/gen/stringlist.3 @@ -0,0 +1 @@ +./stringlist.3 \ No newline at end of file diff --git a/gen/strtofflags.3 b/gen/strtofflags.3 index 355e81a..ed790c6 100644 --- a/gen/strtofflags.3 +++ b/gen/strtofflags.3 @@ -44,9 +44,15 @@ .Sh SYNOPSIS .In unistd.h .Ft char * -.Fn fflagstostr "u_long flags" +.Fo fflagstostr +.Fa "unsigned long flags" +.Fc .Ft int -.Fn strtofflags "char **stringp" "u_long *setp" "u_long *clrp" +.Fo strtofflags +.Fa "char **stringp" +.Fa "unsigned long *setp" +.Fa "unsigned long *clrp" +.Fc .Sh DESCRIPTION The .Fn fflagstostr diff --git a/gen/strtofflags.c b/gen/strtofflags.c index 4e19ba3..50a3771 100644 --- a/gen/strtofflags.c +++ b/gen/strtofflags.c @@ -89,6 +89,7 @@ static struct { { "nouimmutable", UF_IMMUTABLE, 0 }, { "nodump", UF_NODUMP, 1 }, { "noopaque", UF_OPAQUE, 0 }, + { "nohidden", UF_HIDDEN, 0 }, }; #define longestflaglen 12 #define nmappings (sizeof(mapping) / sizeof(mapping[0])) diff --git a/gen/sysconf-fbsd.c b/gen/sysconf-fbsd.c new file mode 100644 index 0000000..7f84622 --- /dev/null +++ b/gen/sysconf-fbsd.c @@ -0,0 +1,627 @@ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Sean Eric Fagan of Cygnus Support. + * + * 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[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/sysconf.c,v 1.20 2002/11/17 08:54:29 dougb Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include /* we just need the limits */ +#include +#include + +#include "../stdlib/atexit.h" +#include "../stdtime/tzfile.h" + +#define _PATH_ZONEINFO TZDIR /* from tzfile.h */ + +/* + * sysconf -- + * get configurable system variables. + * + * XXX + * POSIX 1003.1 (ISO/IEC 9945-1, 4.8.1.3) states that the variable values + * not change during the lifetime of the calling process. This would seem + * to require that any change to system limits kill all running processes. + * A workaround might be to cache the values when they are first retrieved + * and then simply return the cached value on subsequent calls. This is + * less useful than returning up-to-date values, however. + */ +long +sysconf(name) + int name; +{ + struct rlimit rl; + quad_t qdvalue; /* for kern.sysv.shmmin */ + size_t len; + int mib[3], sverrno, value; + long defaultresult; + const char *path; + + len = sizeof(value); + defaultresult = -1; + + switch (name) { + case _SC_ARG_MAX: + mib[0] = CTL_KERN; + mib[1] = KERN_ARGMAX; + break; + case _SC_CHILD_MAX: + if (getrlimit(RLIMIT_NPROC, &rl) != 0) + return (-1); + if (rl.rlim_cur == RLIM_INFINITY) + return (-1); + if (rl.rlim_cur > LONG_MAX) { + errno = EOVERFLOW; + return (-1); + } + return ((long)rl.rlim_cur); + case _SC_CLK_TCK: + return (CLK_TCK); + case _SC_NGROUPS_MAX: + mib[0] = CTL_KERN; + mib[1] = KERN_NGROUPS; + break; + case _SC_OPEN_MAX: + case _SC_STREAM_MAX: /* assume fds run out before memory does */ + if (getrlimit(RLIMIT_NOFILE, &rl) != 0) + return (-1); + if (rl.rlim_cur == RLIM_INFINITY) + return (-1); + if (rl.rlim_cur > LONG_MAX) { + errno = EOVERFLOW; + return (-1); + } + return ((long)rl.rlim_cur); + case _SC_JOB_CONTROL: + return (_POSIX_JOB_CONTROL); + case _SC_SAVED_IDS: + /* XXX - must be 1 */ + mib[0] = CTL_KERN; + mib[1] = KERN_SAVED_IDS; + goto yesno; + case _SC_VERSION: + mib[0] = CTL_KERN; + mib[1] = KERN_POSIX1; + break; + case _SC_BC_BASE_MAX: + return (BC_BASE_MAX); + case _SC_BC_DIM_MAX: + return (BC_DIM_MAX); + case _SC_BC_SCALE_MAX: + return (BC_SCALE_MAX); + case _SC_BC_STRING_MAX: + return (BC_STRING_MAX); + case _SC_COLL_WEIGHTS_MAX: + return (COLL_WEIGHTS_MAX); + case _SC_EXPR_NEST_MAX: + return (EXPR_NEST_MAX); + case _SC_LINE_MAX: + return (LINE_MAX); + case _SC_RE_DUP_MAX: + return (RE_DUP_MAX); + case _SC_2_VERSION: + /* + * This is something of a lie, but it would be silly at + * this point to try to deduce this from the contents + * of the filesystem. + */ + return (_POSIX2_VERSION); + case _SC_2_C_BIND: + return (_POSIX2_C_BIND); + case _SC_2_C_DEV: + return (_POSIX2_C_DEV); + case _SC_2_CHAR_TERM: + return (_POSIX2_CHAR_TERM); + case _SC_2_FORT_DEV: + return (_POSIX2_FORT_DEV); + case _SC_2_FORT_RUN: + return (_POSIX2_FORT_RUN); + case _SC_2_LOCALEDEF: + return (_POSIX2_LOCALEDEF); + case _SC_2_SW_DEV: + return (_POSIX2_SW_DEV); + case _SC_2_UPE: + return (_POSIX2_UPE); + case _SC_TZNAME_MAX: + path = _PATH_ZONEINFO; +do_NAME_MAX: + sverrno = errno; + errno = 0; + value = pathconf(path, _PC_NAME_MAX); + if (value == -1 && errno != 0) + return (-1); + errno = sverrno; + return (value); + + case _SC_ASYNCHRONOUS_IO: +#if _POSIX_ASYNCHRONOUS_IO == 0 + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_ASYNCHRONOUS_IO; + break; +#else + return (_POSIX_ASYNCHRONOUS_IO); +#endif + case _SC_MAPPED_FILES: + return (_POSIX_MAPPED_FILES); + case _SC_MEMLOCK: + return (_POSIX_MEMLOCK); + case _SC_MEMLOCK_RANGE: + return (_POSIX_MEMLOCK_RANGE); + case _SC_MEMORY_PROTECTION: + return (_POSIX_MEMORY_PROTECTION); + case _SC_MESSAGE_PASSING: +#if _POSIX_MESSAGE_PASSING == 0 + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_MESSAGE_PASSING; + goto yesno; +#else + return (_POSIX_MESSAGE_PASSING); +#endif + case _SC_PRIORITIZED_IO: +#if _POSIX_PRIORITIZED_IO == 0 + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_PRIORITIZED_IO; + goto yesno; +#else + return (_POSIX_PRIORITIZED_IO); +#endif + case _SC_PRIORITY_SCHEDULING: +#if _POSIX_PRIORITY_SCHEDULING == 0 + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_PRIORITY_SCHEDULING; + goto yesno; +#else + return (_POSIX_PRIORITY_SCHEDULING); +#endif + case _SC_REALTIME_SIGNALS: +#if _POSIX_REALTIME_SIGNALS == 0 + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_REALTIME_SIGNALS; + goto yesno; +#else + return (_POSIX_REALTIME_SIGNALS); +#endif + case _SC_SEMAPHORES: +#if _POSIX_SEMAPHORES == 0 + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_SEMAPHORES; + goto yesno; +#else + return (_POSIX_SEMAPHORES); +#endif + case _SC_FSYNC: + return (_POSIX_FSYNC); + + case _SC_SHARED_MEMORY_OBJECTS: + return (_POSIX_SHARED_MEMORY_OBJECTS); + case _SC_SYNCHRONIZED_IO: +#if _POSIX_SYNCHRONIZED_IO == 0 + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_SYNCHRONIZED_IO; + goto yesno; +#else + return (_POSIX_SYNCHRONIZED_IO); +#endif + case _SC_TIMERS: +#if _POSIX_TIMERS == 0 + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_TIMERS; + goto yesno; +#else + return (_POSIX_TIMERS); +#endif + case _SC_AIO_LISTIO_MAX: + case _SC_AIO_MAX: + mib[0] = CTL_KERN;; + mib[1] = KERN_AIOMAX; + break; + + case _SC_AIO_PRIO_DELTA_MAX: +#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_AIO_PRIO_DELTA_MAX) + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_AIO_PRIO_DELTA_MAX; + break; +#else + return (-1); +#endif + case _SC_DELAYTIMER_MAX: +#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_DELAYTIMER_MAX) + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_DELAYTIMER_MAX; + goto yesno; +#else + return (-1); +#endif + case _SC_MQ_OPEN_MAX: +#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_MQ_OPEN_MAX) + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_MQ_OPEN_MAX; + goto yesno; +#else + return (-1); +#endif + case _SC_PAGESIZE: + defaultresult = getpagesize(); +#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_PAGESIZE) + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_PAGESIZE; + goto yesno; +#else + return defaultresult; +#endif + case _SC_RTSIG_MAX: +#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_RTSIG_MAX) + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_RTSIG_MAX; + goto yesno; +#else + return (-1); +#endif + case _SC_SEM_NSEMS_MAX: + return (sysctlbyname("kern.sysv.semmns", &value, &len, NULL, 0) == -1 ? -1 : value); + + case _SC_SEM_VALUE_MAX: +#if SEM_VALUE_MAX == 0 + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_SEM_VALUE_MAX; + goto yesno; +#else + return (SEM_VALUE_MAX); +#endif + case _SC_SIGQUEUE_MAX: +#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_SIGQUEUE_MAX) + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_SIGQUEUE_MAX; + goto yesno; +#else + return (-1); +#endif + case _SC_TIMER_MAX: +#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_TIMER_MAX) + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_TIMER_MAX; +#else + return (-1); +#endif + +yesno: if (sysctl(mib, 2, &value, &len, NULL, 0) == -1) + return (-1); + if (value == 0) + return (defaultresult); + return (value); + case _SC_2_PBS: + case _SC_2_PBS_ACCOUNTING: + case _SC_2_PBS_CHECKPOINT: + case _SC_2_PBS_LOCATE: + case _SC_2_PBS_MESSAGE: + case _SC_2_PBS_TRACK: + return -1; + case _SC_ADVISORY_INFO: +#if _POSIX_ADVISORY_INFO == 0 +#error "_POSIX_ADVISORY_INFO" +#else + return (_POSIX_ADVISORY_INFO); +#endif + case _SC_BARRIERS: +#if _POSIX_BARRIERS == 0 +#error "_POSIX_BARRIERS" +#else + return (_POSIX_BARRIERS); +#endif + case _SC_CLOCK_SELECTION: +#if _POSIX_CLOCK_SELECTION == 0 +#error "_POSIX_CLOCK_SELECTION" +#else + return (_POSIX_CLOCK_SELECTION); +#endif + case _SC_CPUTIME: +#if _POSIX_CPUTIME == 0 +#error "_POSIX_CPUTIME" +#else + return (_POSIX_CPUTIME); +#endif + case _SC_FILE_LOCKING: + case _SC_GETGR_R_SIZE_MAX: +/* return sizeof(group) + group_name_max + group_passwd_max + max_group_member*(MAXLOGNAME+1); */ + return 4096; /* INT_MAX is too big for Perl */ + case _SC_GETPW_R_SIZE_MAX: + return 4096; + case _SC_HOST_NAME_MAX: + return (MAXHOSTNAMELEN - 1); /* does not include \0 */ + case _SC_LOGIN_NAME_MAX: + return (MAXLOGNAME); + case _SC_MONOTONIC_CLOCK: +#if _POSIX_MONOTONIC_CLOCK == 0 +#error "_POSIX_MONOTONIC_CLOCK" +#else + return (_POSIX_MONOTONIC_CLOCK); +#endif + case _SC_MQ_PRIO_MAX: + return (-1); + case _SC_READER_WRITER_LOCKS: + return (_POSIX_READER_WRITER_LOCKS); + case _SC_REGEXP: + return (_POSIX_REGEXP); + case _SC_SHELL: + return (_POSIX_SHELL); + case _SC_SPAWN: + return (_POSIX_SPAWN); + case _SC_SPIN_LOCKS: + return (_POSIX_SPIN_LOCKS); + case _SC_SPORADIC_SERVER: +#if _POSIX_SPORADIC_SERVER == 0 +#error "_POSIX_SPORADIC_SERVER" +#else + return (_POSIX_SPORADIC_SERVER); +#endif + case _SC_THREAD_ATTR_STACKADDR: + return (_POSIX_THREAD_ATTR_STACKADDR); + case _SC_THREAD_ATTR_STACKSIZE: + return (_POSIX_THREAD_ATTR_STACKSIZE); + case _SC_THREAD_CPUTIME: + return (_POSIX_THREAD_CPUTIME); + case _SC_THREAD_DESTRUCTOR_ITERATIONS: + return (PTHREAD_DESTRUCTOR_ITERATIONS); + case _SC_THREAD_KEYS_MAX: + return (PTHREAD_KEYS_MAX); + case _SC_THREAD_PRIO_INHERIT: + return (_POSIX_THREAD_PRIO_INHERIT); + case _SC_THREAD_PRIO_PROTECT: + return (_POSIX_THREAD_PRIO_PROTECT); + case _SC_THREAD_PRIORITY_SCHEDULING: + return (_POSIX_THREAD_PRIORITY_SCHEDULING); + case _SC_THREAD_PROCESS_SHARED: + return (_POSIX_THREAD_PROCESS_SHARED); + case _SC_THREAD_SAFE_FUNCTIONS: + return (_POSIX_THREAD_SAFE_FUNCTIONS); + case _SC_THREAD_SPORADIC_SERVER: + return (_POSIX_THREAD_SPORADIC_SERVER); + case _SC_THREAD_STACK_MIN: + return (PTHREAD_STACK_MIN); + case _SC_THREAD_THREADS_MAX: +#ifdef PTHREAD_THREADS_MAX + return (PTHREAD_THREADS_MAX); /* XXX wrong type! */ +#else + return (-1); +#endif + case _SC_TIMEOUTS: + return (_POSIX_TIMEOUTS); + case _SC_THREADS: + return (_POSIX_THREADS); + case _SC_TRACE: +#if _POSIX_TRACE == 0 +#error "_POSIX_TRACE" + /* While you're implementing this, also do the ones below. */ +#else + return (_POSIX_TRACE); +#endif + case _SC_TRACE_EVENT_FILTER: + return (_POSIX_TRACE_EVENT_FILTER); + case _SC_TRACE_INHERIT: + return (_POSIX_TRACE_INHERIT); + case _SC_TRACE_LOG: + return (_POSIX_TRACE_LOG); + case _SC_TTY_NAME_MAX: + path = "/"; // should be _PATH_DEV (PR-3624562) + goto do_NAME_MAX; + case _SC_TYPED_MEMORY_OBJECTS: +#if _POSIX_TYPED_MEMORY_OBJECTS == 0 +#error "_POSIX_TYPED_MEMORY_OBJECTS" +#else + return (_POSIX_TYPED_MEMORY_OBJECTS); +#endif + case _SC_V6_ILP32_OFF32: +#if _V6_ILP32_OFF32 == 0 + if (sizeof(int) * CHAR_BIT == 32 && + sizeof(int) == sizeof(long) && + sizeof(long) == sizeof(void *) && + sizeof(void *) == sizeof(off_t)) + return 1; + else + return -1; +#else + return (_V6_ILP32_OFF32); +#endif + case _SC_V6_ILP32_OFFBIG: +#if _V6_ILP32_OFFBIG == 0 + if (sizeof(int) * CHAR_BIT == 32 && + sizeof(int) == sizeof(long) && + sizeof(long) == sizeof(void *) && + sizeof(off_t) * CHAR_BIT >= 64) + return 1; + else + return -1; +#else + return (_V6_ILP32_OFFBIG); +#endif + case _SC_V6_LP64_OFF64: +#if _V6_LP64_OFF64 == 0 + if (sizeof(int) * CHAR_BIT == 32 && + sizeof(long) * CHAR_BIT == 64 && + sizeof(long) == sizeof(void *) && + sizeof(void *) == sizeof(off_t)) + return 1; + else + return -1; +#else + return (_V6_LP64_OFF64); +#endif + case _SC_V6_LPBIG_OFFBIG: +#if _V6_LPBIG_OFFBIG == 0 + if (sizeof(int) * CHAR_BIT >= 32 && + sizeof(long) * CHAR_BIT >= 64 && + sizeof(void *) * CHAR_BIT >= 64 && + sizeof(off_t) * CHAR_BIT >= 64) + return 1; + else + return -1; +#else + return (_V6_LPBIG_OFFBIG); +#endif + case _SC_ATEXIT_MAX: + return (INT_MAX); /* unlimited */ + case _SC_IOV_MAX: +#ifdef KERN_IOV_MAX + mib[0] = CTL_KERN; + mib[1] = KERN_IOV_MAX; + break; +#else + return (IOV_MAX); +#endif + case _SC_XOPEN_CRYPT: + return (_XOPEN_CRYPT); + case _SC_XOPEN_ENH_I18N: + return (_XOPEN_ENH_I18N); + case _SC_XOPEN_LEGACY: + return (_XOPEN_LEGACY); + case _SC_XOPEN_REALTIME: +#if _XOPEN_REALTIME == 0 + sverrno = errno; + value = sysconf(_SC_ASYNCHRONOUS_IO) > 0 && + sysconf(_SC_MEMLOCK) > 0 && + sysconf(_SC_MEMLOCK_RANGE) > 0 && + sysconf(_SC_MESSAGE_PASSING) > 0 && + sysconf(_SC_PRIORITY_SCHEDULING) > 0 && + sysconf(_SC_REALTIME_SIGNALS) > 0 && + sysconf(_SC_SEMAPHORES) > 0 && + sysconf(_SC_SHARED_MEMORY_OBJECTS) > 0 && + sysconf(_SC_SYNCHRONIZED_IO) > 0 && + sysconf(_SC_TIMERS) > 0; + errno = sverrno; + if (value) + return (200112L); + else + return (-1); +#else + return (_XOPEN_REALTIME); +#endif + case _SC_XOPEN_REALTIME_THREADS: +#if _XOPEN_REALTIME_THREADS == 0 +#error "_XOPEN_REALTIME_THREADS" +#else + return (_XOPEN_REALTIME_THREADS); +#endif + case _SC_XOPEN_SHM: + sverrno = errno; + len = sizeof(qdvalue); + if (sysctlbyname("kern.sysv.shmmin", &qdvalue, &len, NULL, + 0) == -1) { + errno = sverrno; + return (-1); + } + errno = sverrno; + return (1); + case _SC_XOPEN_STREAMS: + return (_XOPEN_STREAMS); + case _SC_XOPEN_UNIX: + return (_XOPEN_UNIX); +#ifdef _XOPEN_VERSION + case _SC_XOPEN_VERSION: + return (_XOPEN_VERSION); +#endif +#ifdef _XOPEN_XCU_VERSION + case _SC_XOPEN_XCU_VERSION: + return (_XOPEN_XCU_VERSION); +#endif + case _SC_SYMLOOP_MAX: + return (MAXSYMLINKS); + case _SC_RAW_SOCKETS: + return (_POSIX_RAW_SOCKETS); + case _SC_IPV6: +#if _POSIX_IPV6 == 0 + sverrno = errno; + value = socket(PF_INET6, SOCK_DGRAM, 0); + errno = sverrno; + if (value >= 0) { + close(value); + return (200112L); + } else + return (0); +#else + return (_POSIX_IPV6); +#endif + +#ifdef _SC_NPROCESSORS_CONF + case _SC_NPROCESSORS_CONF: +#endif +#ifdef _SC_NPROCESSORS_ONLN + case _SC_NPROCESSORS_ONLN: +#endif +#if defined(_SC_NPROCESSORS_CONF) || defined(_SC_NPROCESSORS_ONLN) + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + break; +#endif + case _SC_XBS5_ILP32_OFF32: + return (_XBS5_ILP32_OFF32); + case _SC_XBS5_ILP32_OFFBIG: + return (_XBS5_ILP32_OFFBIG); + case _SC_XBS5_LP64_OFF64: + return (_XBS5_LP64_OFF64); + case _SC_XBS5_LPBIG_OFFBIG: + return (_XBS5_LPBIG_OFFBIG); + case _SC_SS_REPL_MAX: + return (_POSIX_SS_REPL_MAX); + case _SC_TRACE_EVENT_NAME_MAX: + return (_POSIX_TRACE_EVENT_NAME_MAX); + case _SC_TRACE_NAME_MAX: + return (_POSIX_TRACE_NAME_MAX); + case _SC_TRACE_SYS_MAX: + return (_POSIX_TRACE_SYS_MAX); + case _SC_TRACE_USER_EVENT_MAX: + return (_POSIX_TRACE_USER_EVENT_MAX); + case _SC_PASS_MAX: + return (PASS_MAX); + + default: + errno = EINVAL; + return (-1); + } + return (sysctl(mib, 2, &value, &len, NULL, 0) == -1 ? -1 : value); +} diff --git a/gen/sysconf.3 b/gen/sysconf.3 new file mode 120000 index 0000000..c7e48c6 --- /dev/null +++ b/gen/sysconf.3 @@ -0,0 +1 @@ +./sysconf.3 \ No newline at end of file diff --git a/gen/sysctl-fbsd.c b/gen/sysctl-fbsd.c new file mode 100644 index 0000000..b6c89a0 --- /dev/null +++ b/gen/sysctl-fbsd.c @@ -0,0 +1,187 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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.5 2003/02/16 17:29:09 nectar 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) + 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 new file mode 100644 index 0000000..542e645 --- /dev/null +++ b/gen/sysctl.3 @@ -0,0 +1,866 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd January 23, 2001 +.Dt SYSCTL 3 +.Os +.Sh NAME +.Nm sysctl , +.Nm sysctlbyname , +.Nm sysctlnametomib +.Nd get or set system information +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/sysctl.h +.Ft int +.Fn sysctl "int *name" "u_int namelen" "void *oldp" "size_t *oldlenp" "void *newp" "size_t newlen" +.Ft int +.Fn sysctlbyname "const char *name" "void *oldp" "size_t *oldlenp" "void *newp" "size_t newlen" +.Ft int +.Fn sysctlnametomib "const char *name" "int *mibp" "size_t *sizep" +.Sh DESCRIPTION +The +.Fn sysctl +function retrieves system information and allows processes with +appropriate privileges to set system information. +The information available from +.Fn sysctl +consists of integers, strings, and tables. +Information may be retrieved and set from the command interface +using the +.Xr sysctl 8 +utility. +.Pp +Unless explicitly noted below, +.Fn sysctl +returns a consistent snapshot of the data requested. +Consistency is obtained by locking the destination +buffer into memory so that the data may be copied out without blocking. +Calls to +.Fn sysctl +are serialized to avoid deadlock. +.Pp +The state is described using a ``Management Information Base'' (MIB) +style name, listed in +.Fa name , +which is a +.Fa namelen +length array of integers. +.Pp +The +.Fn sysctlbyname +function accepts an ASCII representation of the name and internally +looks up the integer name vector. +Apart from that, it behaves the same +as the standard +.Fn sysctl +function. +.Pp +The information is copied into the buffer specified by +.Fa oldp . +The size of the buffer is given by the location specified by +.Fa oldlenp +before the call, +and that location gives the amount of data copied after a successful call +and after a call that returns with the error code +.Er ENOMEM . +If the amount of data available is greater +than the size of the buffer supplied, +the call supplies as much data as fits in the buffer provided +and returns with the error code +.Er ENOMEM . +If the old value is not desired, +.Fa oldp +and +.Fa oldlenp +should be set to NULL. +.Pp +The size of the available data can be determined by calling +.Fn sysctl +with the +.Dv NULL +argument for +.Fa oldp . +The size of the available data will be returned in the location pointed to by +.Fa oldlenp . +For some operations, the amount of space may change often. +For these operations, +the system attempts to round up so that the returned size is +large enough for a call to return the data shortly thereafter. +.Pp +To set a new value, +.Fa newp +is set to point to a buffer of length +.Fa newlen +from which the requested value is to be taken. +If a new value is not to be set, +.Fa newp +should be set to NULL and +.Fa newlen +set to 0. +.Pp +The +.Fn sysctlnametomib +function accepts an ASCII representation of the name, +looks up the integer name vector, +and returns the numeric representation in the mib array pointed to by +.Fa mibp . +The number of elements in the mib array is given by the location specified by +.Fa sizep +before the call, +and that location gives the number of entries copied after a successful call. +The resulting +.Fa mib +and +.Fa size +may be used in subsequent +.Fn sysctl +calls to get the data associated with the requested ASCII name. +This interface is intended for use by applications that want to +repeatedly request the same variable (the +.Fn sysctl +function runs in about a third the time as the same request made via the +.Fn sysctlbyname +function). +The +.Fn sysctlnametomib +function is also useful for fetching mib prefixes and then adding +a final component. +For example, to fetch process information +for processes with pid's less than 100: +.Pp +.Bd -literal -offset indent -compact +int i, mib[4]; +size_t len; +struct kinfo_proc kp; + +/* Fill out the first three components of the mib */ +len = 4; +sysctlnametomib("kern.proc.pid", mib, &len); + +/* Fetch and print entries for pid's < 100 */ +for (i = 0; i < 100; i++) { + mib[3] = i; + len = sizeof(kp); + if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1) + perror("sysctl"); + else if (len > 0) + printkproc(&kp); +} +.Ed +.Pp +Note: Implementation of +.Fn printkproc +-- to print whatever data deemed necessary from the large +.Vt kinfo_proc +structure ( +.In sysctl.h +) -- is left as an exercise for the reader. +.Pp +The top level names are defined with a CTL_ prefix in +.In sys/sysctl.h , +and are as follows. +The next and subsequent levels down are found in the include files +listed here, and described in separate sections below. +.Pp +.Bl -column CTLXMACHDEP "Next level names" -offset indent +.It Sy "Name Next level names Description" +.It "CTL_DEBUG sys/sysctl.h Debugging" +.It "CTL_VFS sys/mount.h File system" +.It "CTL_HW sys/sysctl.h Generic CPU, I/O" +.It "CTL_KERN sys/sysctl.h High kernel limits" +.It "CTL_MACHDEP sys/sysctl.h Machine dependent" +.It "CTL_NET sys/socket.h Networking" +.It "CTL_USER sys/sysctl.h User-level" +.It "CTL_VM sys/resources.h Virtual memory (struct loadavg)" +.It "CTL_VM sys/vmmeter.h Virtual memory (struct vmtotal)" +.El +.Pp +For example, the following retrieves the maximum number of processes allowed +in the system: +.Pp +.Bd -literal -offset indent -compact +int mib[2], maxproc; +size_t len; + +mib[0] = CTL_KERN; +mib[1] = KERN_MAXPROC; +len = sizeof(maxproc); +sysctl(mib, 2, &maxproc, &len, NULL, 0); +.Ed +.Pp +To retrieve the standard search path for the system utilities: +.Pp +.Bd -literal -offset indent -compact +int mib[2]; +size_t len; +char *p; + +mib[0] = CTL_USER; +mib[1] = USER_CS_PATH; +sysctl(mib, 2, NULL, &len, NULL, 0); +p = malloc(len); +sysctl(mib, 2, p, &len, NULL, 0); +.Ed +.Ss CTL_DEBUG +The debugging variables vary from system to system. +A debugging variable may be added or deleted without need to recompile +.Fn sysctl +to know about it. +Each time it runs, +.Fn sysctl +gets the list of debugging variables from the kernel and +displays their current values. +The system defines twenty +.Pq Vt "struct ctldebug" +variables named +.Va debug0 +through +.Va debug19 . +They are declared as separate variables so that they can be +individually initialized at the location of their associated variable. +The loader prevents multiple use of the same variable by issuing errors +if a variable is initialized in more than one place. +For example, to export the variable +.Va dospecialcheck +as a debugging variable, the following declaration would be used: +.Pp +.Bd -literal -offset indent -compact +int dospecialcheck = 1; +struct ctldebug debug5 = { "dospecialcheck", &dospecialcheck }; +.Ed +.Ss CTL_VFS +A distinguished second level name, VFS_GENERIC, +is used to get general information about all file systems. +One of its third level identifiers is VFS_MAXTYPENUM +that gives the highest valid file system type number. +Its other third level identifier is VFS_CONF that +returns configuration information about the file system +type given as a fourth level identifier (see +.Xr getvfsbyname 3 +as an example of its use). +The remaining second level identifiers are the +file system type number returned by a +.Xr statfs 2 +call or from VFS_CONF. +The third level identifiers available for each file system +are given in the header file that defines the mount +argument structure for that file system. +.Ss CTL_HW +The string and integer information available for the CTL_HW level +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +.Bl -column "Second level nameXXXXXX" integerXXX -offset indent +.It Sy "Second level name Type Changeable" +.It "HW_MACHINE string no" +.It "HW_MODEL string no" +.It "HW_NCPU integer no" +.It "HW_BYTEORDER integer no" +.It "HW_PHYSMEM integer no" +.It "HW_USERMEM integer no" +.It "HW_PAGESIZE integer no" +.It "HW_FLOATINGPOINT integer no" +.It "HW_MACHINE_ARCH string no" +.\".It "HW_DISKNAMES integer no" +.\".It "HW_DISKSTATS integer no" +.El +.Pp +.Bl -tag -width 6n +.It Li HW_MACHINE +The machine class. +.It Li HW_MODEL +The machine model +.It Li HW_NCPU +The number of cpus. +.It Li HW_BYTEORDER +The byteorder (4,321, or 1,234). +.It Li HW_PHYSMEM +The bytes of physical memory. +.It Li HW_USERMEM +The bytes of non-kernel memory. +.It Li HW_PAGESIZE +The software page size. +.It Li HW_FLOATINGPOINT +Nonzero if the floating point support is in hardware. +.It Li HW_MACHINE_ARCH +The machine dependent architecture type. +.\".It Fa HW_DISKNAMES +.\".It Fa HW_DISKSTATS +.El +.Ss CTL_KERN +The string and integer information available for the CTL_KERN level +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +The types of data currently available are process information, +system vnodes, the open file entries, routing table entries, +virtual memory statistics, load average history, and clock rate +information. +.Bl -column "KERNXMAXFILESPERPROCXXX" "struct clockrateXXX" -offset indent +.It Sy "Second level name Type Changeable" +.It "KERN_ARGMAX integer no" +.It "KERN_BOOTFILE string yes" +.It "KERN_BOOTTIME struct timeval no" +.It "KERN_CLOCKRATE struct clockinfo no" +.It "KERN_FILE struct file no" +.It "KERN_HOSTID integer yes" +.It "KERN_HOSTNAME string yes" +.It "KERN_JOB_CONTROL integer no" +.It "KERN_MAXFILES integer yes" +.It "KERN_MAXFILESPERPROC integer yes" +.It "KERN_MAXPROC integer no" +.It "KERN_MAXPROCPERUID integer yes" +.It "KERN_MAXVNODES integer yes" +.It "KERN_NGROUPS integer no" +.It "KERN_NISDOMAINNAME string yes" +.It "KERN_OSRELDATE integer no" +.It "KERN_OSRELEASE string no" +.It "KERN_OSREV integer no" +.It "KERN_OSTYPE string no" +.It "KERN_POSIX1 integer no" +.It "KERN_PROC struct proc no" +.It "KERN_PROF node not applicable" +.It "KERN_QUANTUM integer yes" +.It "KERN_SAVED_IDS integer no" +.It "KERN_SECURELVL integer raise only" +.It "KERN_UPDATEINTERVAL integer no" +.It "KERN_VERSION string no" +.It "KERN_VNODE struct vnode no" +.El +.Pp +.Bl -tag -width 6n +.It Li KERN_ARGMAX +The maximum bytes of argument to +.Xr execve 2 . +.It Li KERN_BOOTFILE +The full pathname of the file from which the kernel was loaded. +.It Li KERN_BOOTTIME +A +.Va struct timeval +structure is returned. +This structure contains the time that the system was booted. +.It Li KERN_CLOCKRATE +A +.Va struct clockinfo +structure is returned. +This structure contains the clock, statistics clock and profiling clock +frequencies, the number of micro-seconds per hz tick and the skew rate. +.It Li KERN_FILE +Return the entire file table. +The returned data consists of a single +.Va struct filehead +followed by an array of +.Va struct file , +whose size depends on the current number of such objects in the system. +.It Li KERN_HOSTID +Get or set the host id. +.It Li KERN_HOSTNAME +Get or set the hostname. +.It Li KERN_JOB_CONTROL +Return 1 if job control is available on this system, otherwise 0. +.It Li KERN_MAXFILES +The maximum number of files that may be open in the system. +.It Li KERN_MAXFILESPERPROC +The maximum number of files that may be open for a single process. +This limit only applies to processes with an effective uid of nonzero +at the time of the open request. +Files that have already been opened are not affected if the limit +or the effective uid is changed. +.It Li KERN_MAXPROC +The maximum number of concurrent processes the system will allow. +.It Li KERN_MAXPROCPERUID +The maximum number of concurrent processes the system will allow +for a single effective uid. +This limit only applies to processes with an effective uid of nonzero +at the time of a fork request. +Processes that have already been started are not affected if the limit +is changed. +.It Li KERN_MAXVNODES +The maximum number of vnodes available on the system. +.It Li KERN_NGROUPS +The maximum number of supplemental groups. +.It Li KERN_NISDOMAINNAME +The name of the current YP/NIS domain. +.It Li KERN_OSRELDATE +The kernel release version in the format +.Ar M Ns Ar mm Ns Ar R Ns Ar xx , +where +.Ar M +is the major version, +.Ar mm +is the two digit minor version, +.Ar R +is 0 if release branch, otherwise 1, +and +.Ar xx +is updated when the available APIs change. +.Pp +The userland release version is available from +.In osreldate.h ; +parse this file if you need to get the release version of +the currently installed userland. +.It Li KERN_OSRELEASE +The system release string. +.It Li KERN_OSREV +The system revision string. +.It Li KERN_OSTYPE +The system type string. +.It Li KERN_POSIX1 +The version of +.St -p1003.1 +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 +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: +.Bl -column "Third level nameXXXXXX" "Fourth level is:XXXXXX" -offset indent +.It "Third level name Fourth level is:" +.It "KERN_PROC_ALL None" +.It "KERN_PROC_PID A process ID" +.It "KERN_PROC_PGRP A process group" +.It "KERN_PROC_TTY A tty device" +.It "KERN_PROC_UID A user ID" +.It "KERN_PROC_RUID A real user ID" +.El +.It Li KERN_PROF +Return profiling information about the kernel. +If the kernel is not compiled for profiling, +attempts to retrieve any of the KERN_PROF values will +fail with +.Er ENOENT . +The third level names for the string and integer profiling information +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +.Bl -column "GPROFXGMONPARAMXXX" "struct gmonparamXXX" -offset indent +.It Sy "Third level name Type Changeable" +.It "GPROF_STATE integer yes" +.It "GPROF_COUNT u_short[\|] yes" +.It "GPROF_FROMS u_short[\|] yes" +.It "GPROF_TOS struct tostruct yes" +.It "GPROF_GMONPARAM struct gmonparam no" +.El +.Pp +The variables are as follows: +.Bl -tag -width 6n +.It Li GPROF_STATE +Returns GMON_PROF_ON or GMON_PROF_OFF to show that profiling +is running or stopped. +.It Li GPROF_COUNT +Array of statistical program counter counts. +.It Li GPROF_FROMS +Array indexed by program counter of call-from points. +.It Li GPROF_TOS +Array of +.Va struct tostruct +describing destination of calls and their counts. +.It Li GPROF_GMONPARAM +Structure giving the sizes of the above arrays. +.El +.It Li KERN_QUANTUM +The maximum period of time, in microseconds, for which a process is allowed +to run without being preempted if other processes are in the run queue. +.It Li KERN_SAVED_IDS +Returns 1 if saved set-group and saved set-user ID is available. +.It Li KERN_SECURELVL +The system security level. +This level may be raised by processes with appropriate privilege. +It may not be lowered. +.It Li KERN_VERSION +The system version string. +.It Li KERN_VNODE +Return the entire vnode table. +Note, the vnode table is not necessarily a consistent snapshot of +the system. +The returned data consists of an array whose size depends on the +current number of such objects in the system. +Each element of the array contains the kernel address of a vnode +.Va struct vnode * +followed by the vnode itself +.Va struct vnode . +.El +.Ss CTL_MACHDEP +The set of variables defined is architecture dependent. +The following variables are defined for the i386 architecture. +.Bl -column "CONSOLE_DEVICEXXX" "struct bootinfoXXX" -offset indent +.It Sy "Second level name Type Changeable" +.It Li "CPU_CONSDEV dev_t no" +.It Li "CPU_ADJKERNTZ int yes" +.It Li "CPU_DISRTCSET int yes" +.It Li "CPU_BOOTINFO struct bootinfo no" +.It Li "CPU_WALLCLOCK int yes" +.El +.Ss CTL_NET +The string and integer information available for the CTL_NET level +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +.Bl -column "Second level nameXXXXXX" "routing messagesXXX" -offset indent +.It Sy "Second level name Type Changeable" +.It "PF_ROUTE routing messages no" +.It "PF_INET IPv4 values yes" +.It "PF_INET6 IPv6 values yes" +.El +.Pp +.Bl -tag -width 6n +.It Li PF_ROUTE +Return the entire routing table or a subset of it. +The data is returned as a sequence of routing messages (see +.Xr route 4 +for the header file, format and meaning). +The length of each message is contained in the message header. +.Pp +The third level name is a protocol number, which is currently always 0. +The fourth level name is an address family, which may be set to 0 to +select all address families. +The fifth and sixth level names are as follows: +.Bl -column "Fifth level nameXXXXXX" "Sixth level is:XXX" -offset indent +.It Sy "Fifth level name Sixth level is:" +.It "NET_RT_FLAGS rtflags" +.It "NET_RT_DUMP None" +.It "NET_RT_IFLIST 0 or if_index" +.It "NET_RT_IFMALIST 0 or if_index" +.El +.Pp +The +.Dv NET_RT_IFMALIST +name returns information about multicast group memberships on all interfaces +if 0 is specified, or for the interface specified by +.Va if_index . +.It Li PF_INET +Get or set various global information about the IPv4 +(Internet Protocol version 4). +The third level name is the protocol. +The fourth level name is the variable name. +The currently defined protocols and names are: +.Bl -column ProtocolXX VariableXX TypeXX ChangeableXX +.It Sy "Protocol Variable Type Changeable" +.It "icmp bmcastecho integer yes" +.It "icmp maskrepl integer yes" +.It "ip forwarding integer yes" +.It "ip redirect integer yes" +.It "ip ttl integer yes" +.It "udp checksum integer yes" +.El +.Pp +The variables are as follows: +.Bl -tag -width 6n +.It Li icmp.bmcastecho +Returns 1 if an ICMP echo request to a broadcast or multicast address is +to be answered. +.It Li icmp.maskrepl +Returns 1 if ICMP network mask requests are to be answered. +.It Li ip.forwarding +Returns 1 when IP forwarding is enabled for the host, +meaning that the host is acting as a router. +.It Li ip.redirect +Returns 1 when ICMP redirects may be sent by the host. +This option is ignored unless the host is routing IP packets, +and should normally be enabled on all systems. +.It Li ip.ttl +The maximum time-to-live (hop count) value for an IP packet sourced by +the system. +This value applies to normal transport protocols, not to ICMP. +.It Li udp.checksum +Returns 1 when UDP checksums are being computed and checked. +Disabling UDP checksums is strongly discouraged. +.Pp +For variables net.inet.*.ipsec, please refer to +.Xr ipsec 4 . +.El +.It Li PF_INET6 +Get or set various global information about the IPv6 +(Internet Protocol version 6). +The third level name is the protocol. +The fourth level name is the variable name. +.Pp +For variables net.inet6.* please refer to +.Xr inet6 4 . +For variables net.inet6.*.ipsec6, please refer to +.Xr ipsec 4 . +.El +.Ss CTL_USER +The string and integer information available for the CTL_USER level +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +.Bl -column "USER_COLL_WEIGHTS_MAXXXX" "integerXXX" -offset indent +.It Sy "Second level name Type Changeable" +.It "USER_BC_BASE_MAX integer no" +.It "USER_BC_DIM_MAX integer no" +.It "USER_BC_SCALE_MAX integer no" +.It "USER_BC_STRING_MAX integer no" +.It "USER_COLL_WEIGHTS_MAX integer no" +.It "USER_CS_PATH string no" +.It "USER_EXPR_NEST_MAX integer no" +.It "USER_LINE_MAX integer no" +.It "USER_POSIX2_CHAR_TERM integer no" +.It "USER_POSIX2_C_BIND integer no" +.It "USER_POSIX2_C_DEV integer no" +.It "USER_POSIX2_FORT_DEV integer no" +.It "USER_POSIX2_FORT_RUN integer no" +.It "USER_POSIX2_LOCALEDEF integer no" +.It "USER_POSIX2_SW_DEV integer no" +.It "USER_POSIX2_UPE integer no" +.It "USER_POSIX2_VERSION integer no" +.It "USER_RE_DUP_MAX integer no" +.It "USER_STREAM_MAX integer no" +.It "USER_TZNAME_MAX integer no" +.El +.Bl -tag -width 6n +.Pp +.It Li USER_BC_BASE_MAX +The maximum ibase/obase values in the +.Xr bc 1 +utility. +.It Li USER_BC_DIM_MAX +The maximum array size in the +.Xr bc 1 +utility. +.It Li USER_BC_SCALE_MAX +The maximum scale value in the +.Xr bc 1 +utility. +.It Li USER_BC_STRING_MAX +The maximum string length in the +.Xr bc 1 +utility. +.It Li USER_COLL_WEIGHTS_MAX +The maximum number of weights that can be assigned to any entry of +the LC_COLLATE order keyword in the locale definition file. +.It Li USER_CS_PATH +Return a value for the +.Ev PATH +environment variable that finds all the standard utilities. +.It Li USER_EXPR_NEST_MAX +The maximum number of expressions that can be nested within +parenthesis by the +.Xr expr 1 +utility. +.It Li USER_LINE_MAX +The maximum length in bytes of a text-processing utility's input +line. +.It Li USER_POSIX2_CHAR_TERM +Return 1 if the system supports at least one terminal type capable of +all operations described in +.St -p1003.2 , +otherwise 0. +.It Li USER_POSIX2_C_BIND +Return 1 if the system's C-language development facilities support the +C-Language Bindings Option, otherwise 0. +.It Li USER_POSIX2_C_DEV +Return 1 if the system supports the C-Language Development Utilities Option, +otherwise 0. +.It Li USER_POSIX2_FORT_DEV +Return 1 if the system supports the FORTRAN Development Utilities Option, +otherwise 0. +.It Li USER_POSIX2_FORT_RUN +Return 1 if the system supports the FORTRAN Runtime Utilities Option, +otherwise 0. +.It Li USER_POSIX2_LOCALEDEF +Return 1 if the system supports the creation of locales, otherwise 0. +.It Li USER_POSIX2_SW_DEV +Return 1 if the system supports the Software Development Utilities Option, +otherwise 0. +.It Li USER_POSIX2_UPE +Return 1 if the system supports the User Portability Utilities Option, +otherwise 0. +.It Li USER_POSIX2_VERSION +The version of +.St -p1003.2 +with which the system attempts to comply. +.It Li USER_RE_DUP_MAX +The maximum number of repeated occurrences of a regular expression +permitted when using interval notation. +.It Li USER_STREAM_MAX +The minimum maximum number of streams that a process may have open +at any one time. +.It Li USER_TZNAME_MAX +The minimum maximum number of types supported for the name of a +timezone. +.El +.Ss CTL_VM +The string and integer information available for the CTL_VM level +is detailed below. +The changeable column shows whether a process with appropriate +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" +.It "VM_METER struct vmtotal no" +.It "VM_PAGEOUT_ALGORITHM integer yes" +.It "VM_SWAPPING_ENABLED integer maybe" +.It "VM_V_CACHE_MAX integer yes" +.It "VM_V_CACHE_MIN integer yes" +.It "VM_V_FREE_MIN integer yes" +.It "VM_V_FREE_RESERVED integer yes" +.It "VM_V_FREE_TARGET integer yes" +.It "VM_V_INACTIVE_TARGET integer yes" +.It "VM_V_PAGEOUT_FREE_MIN integer yes" +.El +.Pp +.Bl -tag -width 6n +.It Li VM_LOADAVG +Return the load average history. +The returned data consists of a +.Va struct loadavg . +.It Li VM_METER +Return the system wide virtual memory statistics. +The returned data consists of a +.Va struct vmtotal . +.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. +.It Li VM_SWAPPING_ENABLED +1 if process swapping is enabled or 0 if disabled. +This variable is +permanently set to 0 if the kernel was built with swapping disabled. +.It Li VM_V_CACHE_MAX +Maximum desired size of the cache queue. +.It Li VM_V_CACHE_MIN +Minimum desired size of the cache queue. +If the cache queue size +falls very far below this value, the pageout daemon is awakened. +.It Li VM_V_FREE_MIN +Minimum amount of memory (cache memory plus free memory) +required to be available before a process waiting on memory will be +awakened. +.It Li VM_V_FREE_RESERVED +Processes will awaken the pageout daemon and wait for memory if the +number of free and cached pages drops below this value. +.It Li VM_V_FREE_TARGET +The total amount of free memory (including cache memory) that the +pageout daemon tries to maintain. +.It Li VM_V_INACTIVE_TARGET +The desired number of inactive pages that the pageout daemon should +achieve when it runs. +Inactive pages can be quickly inserted into +process address space when needed. +.It Li VM_V_PAGEOUT_FREE_MIN +If the amount of free and cache memory falls below this value, the +pageout daemon will enter "memory conserving mode" to avoid deadlock. +.El +.Sh RETURN VALUES +.Rv -std +.Sh ERRORS +The following errors may be reported: +.Bl -tag -width Er +.It Bq Er EFAULT +The buffer +.Fa name , +.Fa oldp , +.Fa newp , +or length pointer +.Fa oldlenp +contains an invalid address. +.It Bq Er EINVAL +The +.Fa name +array is less than two or greater than CTL_MAXNAME. +.It Bq Er EINVAL +A non-null +.Fa newp +is given and its specified length in +.Fa newlen +is too large or too small. +.It Bq Er ENOMEM +The length pointed to by +.Fa oldlenp +is too short to hold the requested value. +.It Bq Er ENOMEM +The smaller of either the length pointed to by +.Fa oldlenp +or the estimated size of the returned data exceeds the +system limit on locked memory. +.It Bq Er ENOMEM +Locking the buffer +.Fa oldp , +or a portion of the buffer if the estimated size of the data +to be returned is smaller, +would cause the process to exceed its per-process locked memory limit. +.It Bq Er ENOTDIR +The +.Fa name +array specifies an intermediate rather than terminal name. +.It Bq Er EISDIR +The +.Fa name +array specifies a terminal name, but the actual name is not terminal. +.It Bq Er ENOENT +The +.Fa name +array specifies a value that is unknown. +.It Bq Er EPERM +An attempt is made to set a read-only value. +.It Bq Er EPERM +A process without appropriate privilege attempts to set a value. +.El +.Sh FILES +.Bl -tag -width -compact +.It In sys/sysctl.h +definitions for top level identifiers, second level kernel and hardware +identifiers, and user level identifiers +.It In sys/socket.h +definitions for second level network identifiers +.It In sys/gmon.h +definitions for third level profiling identifiers +.It In mach/vm_param.h +definitions for second level virtual memory identifiers +.It In netinet/in.h +definitions for third level IPv4/IPv6 identifiers and +fourth level IPv4/v6 identifiers +.It In netinet/icmp_var.h +definitions for fourth level ICMP identifiers +.It In netinet/icmp6.h +definitions for fourth level ICMPv6 identifiers +.It In netinet/udp_var.h +definitions for fourth level UDP identifiers +.El +.Sh SEE ALSO +.Xr sysconf 3 , +.Xr sysctl 8 +.Sh HISTORY +The +.Fn sysctl +function first appeared in +.Bx 4.4 . diff --git a/gen/sysctlbyname-fbsd.c b/gen/sysctlbyname-fbsd.c new file mode 100644 index 0000000..e949a5c --- /dev/null +++ b/gen/sysctlbyname-fbsd.c @@ -0,0 +1,39 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/sysctlbyname.c,v 1.5 2002/02/01 00:57:29 obrien Exp $"); + +#include +#include +#include + +int +sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp, + size_t newlen) +{ + int name2oid_oid[2]; + int real_oid[CTL_MAXNAME+2]; + int error; + size_t oidlen; + + name2oid_oid[0] = 0; /* This is magic & undocumented! */ + name2oid_oid[1] = 3; + + oidlen = sizeof(real_oid); + error = sysctl(name2oid_oid, 2, real_oid, &oidlen, (void *)name, + strlen(name)); + if (error < 0) + return error; + oidlen /= sizeof (int); + error = sysctl(real_oid, oidlen, oldp, oldlenp, newp, newlen); + return (error); +} + diff --git a/gen/sysctlnametomib-fbsd.c b/gen/sysctlnametomib-fbsd.c new file mode 100644 index 0000000..1a932ec --- /dev/null +++ b/gen/sysctlnametomib-fbsd.c @@ -0,0 +1,55 @@ +/* + * Copyright 2001 The FreeBSD Project. 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 FREEBSD PROJECT ``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 FREEBSD PROJECT 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/gen/sysctlnametomib.c,v 1.4 2003/01/04 00:11:11 tjr Exp $"); + +#include +#include +#include + +/* + * This function uses a presently undocumented interface to the kernel + * to walk the tree and get the type so it can print the value. + * This interface is under work and consideration, and should probably + * be killed with a big axe by the first person who can find the time. + * (be aware though, that the proper interface isn't as obvious as it + * may seem, there are various conflicting requirements. + */ +int +sysctlnametomib(const char *name, int *mibp, size_t *sizep) +{ + int oid[2]; + int error; + + oid[0] = 0; + oid[1] = 3; + + *sizep *= sizeof (int); + error = sysctl(oid, 2, mibp, sizep, (void *)name, strlen(name)); + *sizep /= sizeof (int); + return (error); +} diff --git a/gen/syslog.3 b/gen/syslog.3 index 39ea2cc..c2e4ced 100644 --- a/gen/syslog.3 +++ b/gen/syslog.3 @@ -36,27 +36,44 @@ .Dt SYSLOG 3 .Os .Sh NAME -.Nm syslog , -.Nm vsyslog , -.Nm openlog , .Nm closelog , -.Nm setlogmask +.Nm openlog , +.Nm setlogmask , +.Nm syslog , +.Nm vsyslog .Nd control system log .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In syslog.h -.In stdarg.h .Ft void -.Fn syslog "int priority" "const char *message" "..." +.Fo closelog +.Fa void +.Fc .Ft void -.Fn vsyslog "int priority" "const char *message" "va_list args" +.Fo openlog +.Fa "const char *ident" +.Fa "int logopt" +.Fa "int facility" +.Fc +.Ft int +.Fo setlogmask +.Fa "int maskpri" +.Fc .Ft void -.Fn openlog "const char *ident" "int logopt" "int facility" +.Fo syslog +.Fa "int priority" +.Fa "const char *message" +.Fa "..." +.Fc +.In syslog.h +.In stdarg.h .Ft void -.Fn closelog void -.Ft int -.Fn setlogmask "int maskpri" +.Fo vsyslog +.Fa "int priority" +.Fa "const char *message" +.Fa "va_list args" +.Fc .Sh DESCRIPTION The .Fn syslog @@ -81,6 +98,12 @@ see .Xr strerror 3 . ) A trailing newline is added if none is present. .Pp +Newlines and other non-printable characters embedded in the message string are printed in an alternate format. +This prevents someone from using non-printable characters to construct misleading log messages in an output file. +Newlines are printed as "\\n", +tabs are printed as "\\t". +Other control characters are printed using a caret ("^") representation, for example "^M" for carriage return. +.Pp The .Fn vsyslog function @@ -177,10 +200,6 @@ The same as .Dv LOG_AUTH , but logged to a file readable only by selected individuals. -.It Dv LOG_CONSOLE -Messages written to -.Pa /dev/console -by the kernel console output driver. .It Dv LOG_CRON The cron daemon: .Xr cron 8 . @@ -253,7 +272,7 @@ The default allows all priorities to be logged. The routines .Fn closelog , .Fn openlog , -.Fn syslog +.Fn syslog , and .Fn vsyslog return no value. @@ -273,8 +292,14 @@ syslog(LOG_INFO, "Connection from host %d", CallingHost); syslog(LOG_INFO|LOG_LOCAL2, "foobar error: %m"); .Ed +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +These include files are necessary for all functions. .Sh SEE ALSO .Xr logger 1 , +.Xr compat 5 , .Xr syslogd 8 .Sh HISTORY These diff --git a/gen/syslog.c b/gen/syslog.c index e7e54c8..a84e294 100644 --- a/gen/syslog.c +++ b/gen/syslog.c @@ -54,6 +54,7 @@ */ #include +#include #include #include #include @@ -65,10 +66,13 @@ #include #include #include +#include #include #include #include #include +#include +#include #ifdef __STDC__ #include @@ -79,6 +83,7 @@ #include #define LOG_NO_NOTIFY 0x1000 +#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID #ifdef BUILDING_VARIANT __private_extern__ int _sl_LogFile; /* fd for log */ @@ -108,8 +113,8 @@ __private_extern__ void _sl_init_notify(); #define NOTIFY_STATE_OFFSET 1000 /* notify SPI */ -uint32_t notify_get_state(int token, int *state); uint32_t notify_register_plain(const char *name, int *out_token); +const char *asl_syslog_faciliy_num_to_name(int); /* * syslog, vsyslog -- @@ -137,29 +142,31 @@ syslog(pri, fmt, va_alist) } void -vsyslog(pri, fmt, ap) - int pri; - register const char *fmt; - va_list ap; +vsyslog(int pri, const char *fmt, va_list ap) { - register int cnt; - register char ch, *p, *t; - time_t now; - int fd, saved_errno, filter, cval, rc_filter, primask; -#define TBUF_LEN 2048 -#define FMT_LEN 1024 - char *stdp, tbuf[TBUF_LEN], fmt_cpy[FMT_LEN]; - int tbuf_left, fmt_left, prlen; - struct tm tm; - -#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID + int status, i, saved_errno, filter, rc_filter; + time_t tick; + pid_t pid; + uint32_t elen, count; + char *p, *str, *expanded, *err_str, hname[MAXHOSTNAMELEN+1]; + uint64_t cval; + int fd, mask, level, facility; + aslmsg msg; + + saved_errno = errno; + /* Check for invalid bits. */ - if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) + if (pri & ~(LOG_PRIMASK | LOG_FACMASK)) { syslog(INTERNALLOG, "syslog: unknown facility/priority: %x", pri); - pri &= LOG_PRIMASK|LOG_FACMASK; + pri &= (LOG_PRIMASK | LOG_FACMASK); } + level = LOG_PRI(pri); + facility = pri & LOG_FACMASK; + + if (facility == 0) facility = _sl_LogFacility; + /* Get remote-control priority filter */ filter = _sl_LogMask; rc_filter = 0; @@ -189,136 +196,201 @@ vsyslog(pri, fmt, ap) } } - primask = LOG_MASK(LOG_PRI(pri)); - if ((primask & filter) == 0) return; - - saved_errno = errno; - - /* Set default facility if none specified. */ - if ((pri & LOG_FACMASK) == 0) pri |= _sl_LogFacility; + mask = LOG_MASK(level); + if ((mask & filter) == 0) return; /* Build the message. */ - - /* - * Although it's tempting, we can't ignore the possibility of - * overflowing the buffer when assembling the "fixed" portion - * of the message. Strftime's "%h" directive expands to the - * locale's abbreviated month name, but if the user has the - * ability to construct to his own locale files, it may be - * arbitrarily long. - */ - (void)time(&now); + msg = asl_new(ASL_TYPE_MSG); - p = tbuf; - tbuf_left = TBUF_LEN; - -#define DEC() \ - do { \ - if (prlen >= tbuf_left) \ - prlen = tbuf_left - 1; \ - p += prlen; \ - tbuf_left -= prlen; \ - } while (0) + if (_sl_LogTag == NULL) _sl_LogTag = *(*_NSGetArgv()); + if (_sl_LogTag != NULL) + { + asl_set(msg, ASL_KEY_SENDER, _sl_LogTag); + } - prlen = snprintf(p, tbuf_left, "<%d>", pri); - DEC(); + str = (char *)asl_syslog_faciliy_num_to_name(facility); + if (str != NULL) asl_set(msg, ASL_KEY_FACILITY, str); - prlen = strftime(p, tbuf_left, "%h %e %T ", localtime_r(&now, &tm)); - DEC(); + str = NULL; + tick = time(NULL); + asprintf(&str, "%lu", tick); + if (str != NULL) + { + asl_set(msg, ASL_KEY_TIME, str); + free(str); + } - if (_sl_LogStat & LOG_PERROR) stdp = p; + str = NULL; + pid = getpid(); + asprintf(&str, "%u", pid); + if (str != NULL) + { + asl_set(msg, ASL_KEY_PID, str); + free(str); + } - if (_sl_LogTag == NULL) _sl_LogTag = *(*_NSGetArgv()); + str = NULL; + asprintf(&str, "%d", getuid()); + if (str != NULL) + { + asl_set(msg, ASL_KEY_UID, str); + free(str); + } - if (_sl_LogTag != NULL) + str = NULL; + asprintf(&str, "%u", getgid()); + if (str != NULL) { - prlen = snprintf(p, tbuf_left, "%s", _sl_LogTag); - DEC(); + asl_set(msg, ASL_KEY_GID, str); + free(str); } - if (_sl_LogStat & LOG_PID) + str = NULL; + asprintf(&str, "%u", level); + if (str != NULL) { - prlen = snprintf(p, tbuf_left, "[%d]", getpid()); - DEC(); + asl_set(msg, ASL_KEY_LEVEL, str); + free(str); } - if (_sl_LogTag != NULL) + 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 (tbuf_left > 1) - { - *p++ = ':'; - tbuf_left--; - } - if (tbuf_left > 1) - { - *p++ = ' '; - tbuf_left--; - } + if ((fmt[i] == '%') && (fmt[i+1] == 'm')) count++; } - /* - * We wouldn't need this mess if printf handled %m, or if - * strerror() had been invented before syslog(). - */ - for (t = fmt_cpy, fmt_left = FMT_LEN; (ch = *fmt); ++fmt) + expanded = NULL; + elen = 0; + err_str = NULL; + + /* deal with malloc failures gracefully */ + if (count > 0) { - if (ch == '%' && fmt[1] == 'm') + err_str = strdup(strerror(saved_errno)); + if (err_str == NULL) count = 0; + else { - ++fmt; - prlen = snprintf(t, fmt_left, "%s", strerror(saved_errno)); - if (prlen >= fmt_left) prlen = fmt_left - 1; - t += prlen; - fmt_left -= prlen; + elen = strlen(err_str); + expanded = malloc(i + (count * elen)); + if (expanded == NULL) count = 0; } - else + } + + if (expanded == NULL) expanded = (char *)fmt; + if (count > 0) + { + p = expanded; + + for (i = 0; fmt[i] != '\0'; i++) { - if (fmt_left > 1) + if ((fmt[i] == '%') && (fmt[i+1] == 'm')) { - *t++ = ch; - fmt_left--; + memcpy(p, err_str, elen); + p += elen; + i++; + } + else + { + *p++ = fmt[i]; } } + + *p = '\0'; } - *t = '\0'; + if (err_str != NULL) free(err_str); - prlen = vsnprintf(p, tbuf_left, fmt_cpy, ap); - DEC(); - cnt = p - tbuf; + vasprintf(&str, expanded, ap); + if (count > 0) free(expanded); - /* Output to stderr if requested. */ - if (_sl_LogStat & LOG_PERROR) + if (str != NULL) { - struct iovec iov[2]; + 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, 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); + } + } - iov[0].iov_base = stdp; - iov[0].iov_len = cnt - (stdp - tbuf); - iov[1].iov_base = "\n"; - iov[1].iov_len = 1; - (void)writev(STDERR_FILENO, iov, 2); + free(str); } /* Get connected, output the message to the local logger. */ - if (_sl_connected == 0) openlog(_sl_LogTag, _sl_LogStat | LOG_NDELAY, 0); - if (send(_sl_LogFile, tbuf, cnt, 0) >= 0) return; + str = asl_format_message(msg, ASL_MSG_FMT_RAW, ASL_TIME_FMT_SEC, &count); + if (str != NULL) + { + p = NULL; + asprintf(&p, "%10u %s", count, str); + free(str); + + if (p != NULL) + { + count += 12; + if (_sl_connected == 0) openlog(_sl_LogTag, _sl_LogStat | LOG_NDELAY, 0); + + status = send(_sl_LogFile, p, count, 0); + if (status< 0) + { + closelog(); + openlog(_sl_LogTag, _sl_LogStat | LOG_NDELAY, 0); + status = send(_sl_LogFile, p, count, 0); + } + + if (status >= 0) + { + free(p); + asl_free(msg); + return; + } + + free(p); + } + } /* - * Output the message to the console; don't worry about blocking, - * if console blocks everything will. Make sure the error reported - * is the one from the syslogd failure. + * Output the message to the console. */ - if (_sl_LogStat & LOG_CONS && (fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) + if (_sl_LogStat & LOG_CONS && (fd = open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) { - struct iovec iov[2]; - - p = strchr(tbuf, '>') + 1; - iov[0].iov_base = p; - iov[0].iov_len = cnt - (p - tbuf); - iov[1].iov_base = "\r\n"; - iov[1].iov_len = 2; - (void)writev(fd, iov, 2); - (void)close(fd); + count = 0; + + p = asl_format_message(msg, ASL_MSG_FMT_STD, ASL_TIME_FMT_LCL, &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); } #ifndef BUILDING_VARIANT @@ -331,29 +403,29 @@ _sl_init_notify() int status; char *notify_name; const char *prefix; - + if (_sl_LogStat & LOG_NO_NOTIFY) { _sl_NotifyMaster = -2; _sl_NotifyToken = -2; return; } - + if (_sl_NotifyMaster == -1) { status = notify_register_plain(NOTIFY_SYSTEM_MASTER, &_sl_NotifyMaster); if (status != NOTIFY_STATUS_OK) _sl_NotifyMaster = -2; } - + if (_sl_NotifyToken == -1) { _sl_NotifyToken = -2; - + notify_name = NULL; prefix = NOTIFY_PREFIX_USER; if (getuid() == 0) prefix = NOTIFY_PREFIX_SYSTEM; asprintf(¬ify_name, "%s.%d", prefix, getpid()); - + if (notify_name != NULL) { status = notify_register_plain(notify_name, &_sl_NotifyToken); @@ -404,8 +476,10 @@ openlog(ident, logstat, logfac) void closelog() { - (void)close(_sl_LogFile); - _sl_LogFile = -1; + if (_sl_LogFile >= 0) { + (void)close(_sl_LogFile); + _sl_LogFile = -1; + } _sl_connected = 0; } diff --git a/gen/tcgetpgrp.3 b/gen/tcgetpgrp.3 index b155763..9df905f 100644 --- a/gen/tcgetpgrp.3 +++ b/gen/tcgetpgrp.3 @@ -41,10 +41,11 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In sys/types.h .In unistd.h .Ft pid_t -.Fn tcgetpgrp "int fd" +.Fo tcgetpgrp +.Fa "int fildes" +.Fc .Sh DESCRIPTION The .Fn tcgetpgrp @@ -62,18 +63,26 @@ is set to indicate the error, as follows: .Bl -tag -width Er .It Bq Er EBADF The -.Fa fd +.Fa fildes argument is not a valid file descriptor. .It Bq Er ENOTTY The calling process does not have a controlling terminal or the underlying terminal device represented by -.Fa fd +.Fa fildes is not the controlling terminal. .El +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +The include file +.In sys/types.h +is necessary. .Sh SEE ALSO .Xr setpgid 2 , .Xr setsid 2 , -.Xr tcsetpgrp 3 +.Xr tcsetpgrp 3 , +.Xr compat 5 .Sh STANDARDS The .Fn tcgetpgrp diff --git a/gen/tcsendbreak.3 b/gen/tcsendbreak.3 index e47779a..cb0cc41 100644 --- a/gen/tcsendbreak.3 +++ b/gen/tcsendbreak.3 @@ -36,35 +36,47 @@ .Dt TCSENDBREAK 3 .Os .Sh NAME -.Nm tcsendbreak , .Nm tcdrain , +.Nm tcflow , .Nm tcflush , -.Nm tcflow +.Nm tcsendbreak .Nd line control functions .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In termios.h .Ft int -.Fn tcdrain "int fd" +.Fo tcdrain +.Fa "int fildes" +.Fc .Ft int -.Fn tcflow "int fd" "int action" +.Fo tcflow +.Fa "int fildes" +.Fa "int action" +.Fc .Ft int -.Fn tcflush "int fd" "int action" +.Fo tcflush +.Fa "int fildes" +.Fa "int action" +.Fc .Ft int -.Fn tcsendbreak "int fd" "int len" +.Fo tcsendbreak +.Fa "int fildes" +.Fa "int duration" +.Fc .Sh DESCRIPTION The .Fn tcdrain function waits until all output written to the terminal referenced by -.Fa fd +.Fa fildes has been transmitted to the terminal. .Pp The .Fn tcflow -function suspends transmission of data to or the reception of data from +function suspends transmission of data to, +or the reception of data from, the terminal referenced by -.Fa fd +.Fa fildes , depending on the value of .Fa action . The value of @@ -94,7 +106,7 @@ section of The .Fn tcflush function discards any data written to the terminal referenced by -.Fa fd +.Fa fildes which has not been transmitted to the terminal, or any data received from the terminal but not yet read, depending on the value of .Fa action . @@ -114,9 +126,9 @@ The .Fn tcsendbreak function transmits a continuous stream of zero-valued bits for four-tenths of a second to the terminal referenced by -.Fa fd . +.Fa fildes . The -.Fa len +.Fa duration parameter is ignored in this implementation. .Sh RETURN VALUES Upon successful completion, all of these functions return a value of zero. @@ -127,20 +139,20 @@ is set to indicate the error, as follows: .Bl -tag -width Er .It Bq Er EBADF The -.Fa fd +.Fa fildes argument is not a valid file descriptor. +.It Bq Er EINTR +A signal interrupted the +.Fn tcdrain +function. .It Bq Er EINVAL The .Fa action argument is not a proper value. .It Bq Er ENOTTY The file associated with -.Fa fd +.Fa fildes is not a terminal. -.It Bq Er EINTR -A signal interrupted the -.Fn tcdrain -function. .El .Sh SEE ALSO .Xr tcsetattr 3 , diff --git a/gen/tcsetattr.3 b/gen/tcsetattr.3 index a1a43cf..b4b77b3 100644 --- a/gen/tcsetattr.3 +++ b/gen/tcsetattr.3 @@ -37,11 +37,11 @@ .Os .Sh NAME .Nm cfgetispeed , -.Nm cfsetispeed , .Nm cfgetospeed , +.Nm cfmakeraw , +.Nm cfsetispeed , .Nm cfsetospeed , .Nm cfsetspeed , -.Nm cfmakeraw , .Nm tcgetattr , .Nm tcsetattr .Nd manipulating the termios structure @@ -50,25 +50,47 @@ .Sh SYNOPSIS .In termios.h .Ft speed_t -.Fn cfgetispeed "const struct termios *t" -.Ft int -.Fn cfsetispeed "struct termios *t" "speed_t speed" +.Fo cfgetispeed +.Fa "const struct termios *termios_p" +.Fc .Ft speed_t -.Fn cfgetospeed "const struct termios *t" +.Fo cfgetospeed +.Fa "const struct termios *termios_p" +.Fc +.Ft void +.Fo cfmakeraw +.Fa "struct termios *termios_p" +.Fc .Ft int -.Fn cfsetospeed "struct termios *t" "speed_t speed" +.Fo cfsetispeed +.Fa "struct termios *termios_p" +.Fa "speed_t speed" +.Fc .Ft int -.Fn cfsetspeed "struct termios *t" "speed_t speed" -.Ft void -.Fn cfmakeraw "struct termios *t" +.Fo cfsetospeed +.Fa "struct termios *termios_p" +.Fa "speed_t speed" +.Fc +.Ft int +.Fo cfsetspeed +.Fa "struct termios *termios_p" +.Fa "speed_t speed" +.Fc .Ft int -.Fn tcgetattr "int fd" "struct termios *t" +.Fo tcgetattr +.Fa "int fildes" +.Fa "struct termios *termios_p" +.Fc .Ft int -.Fn tcsetattr "int fd" "int action" "const struct termios *t" +.Fo tcsetattr +.Fa "int fildes" +.Fa "int optional_actions" +.Fa "const struct termios *termios_p" +.Fc .Sh DESCRIPTION The .Fn cfmakeraw , -.Fn tcgetattr +.Fn tcgetattr , and .Fn tcsetattr functions are provided for getting and setting the termios structure. @@ -77,17 +99,18 @@ The .Fn cfgetispeed , .Fn cfsetispeed , .Fn cfgetospeed , -.Fn cfsetospeed +.Fn cfsetospeed , and .Fn cfsetspeed functions are provided for getting and setting the baud rate values in the termios structure. -The effects of the functions on the terminal as described below -do not become effective, nor are all errors detected, until the +As described below, +the effects of the functions on the terminal do not become effective, +nor are all errors detected, until the .Fn tcsetattr function is called. -Certain values for baud rates set in the termios structure and passed to -.Fn tcsetattr +Certain values for baud rates, set in the termios structure and passed to +.Fn tcsetattr , have special meanings. These are discussed in the portion of the manual page that describes the .Fn tcsetattr @@ -96,10 +119,10 @@ function. The input and output baud rates are found in the termios structure. The unsigned integer .Li speed_t -is typdef'd in the include file +is typedef'd in the include file .Aq Pa termios.h . The value of the integer corresponds directly to the baud rate being -represented, however, the following symbolic values are defined. +represented; however, the following symbolic values are defined: .Bd -literal #define B0 0 #define B50 50 @@ -126,24 +149,24 @@ represented, however, the following symbolic values are defined. The .Fn cfgetispeed function returns the input baud rate in the termios structure referenced by -.Fa tp . +.Fa termios_p . .Pp The .Fn cfsetispeed function sets the input baud rate in the termios structure referenced by -.Fa tp +.Fa termios_p to .Fa speed . .Pp The .Fn cfgetospeed function returns the output baud rate in the termios structure referenced by -.Fa tp . +.Fa termios_p . .Pp The .Fn cfsetospeed function sets the output baud rate in the termios structure referenced by -.Fa tp +.Fa termios_p to .Fa speed . .Pp @@ -151,7 +174,7 @@ The .Fn cfsetspeed function sets both the input and output baud rate in the termios structure referenced by -.Fa tp +.Fa termios_p to .Fa speed . .Pp @@ -174,11 +197,11 @@ a SIGTTOU signal. If the calling process is blocking or ignoring SIGTTOU signals, the process is allowed to perform the operation and the SIGTTOU signal is not sent. .Pp -In all the functions, although -.Fa fd +In all of the functions, although +.Fa fildes is an open file descriptor, the functions affect the underlying terminal -file, not just the open file description associated with the particular -file descriptor. +file, not just the open file description that is associated +with the particular file descriptor. .Pp The .Fn cfmakeraw @@ -186,8 +209,8 @@ function sets the flags stored in the termios structure to a state disabling all input and output processing, giving a .Dq raw I/O path . It should be noted that there is no function to reverse this effect. -This is because there are a variety of processing options that could be -re-enabled and the correct method is for an application to snapshot the +Because a variety of processing options could be re-enabled, +the correct method is for an application to snapshot the current terminal state using the function .Fn tcgetattr , setting raw mode with @@ -202,19 +225,20 @@ The .Fn tcgetattr function copies the parameters associated with the terminal referenced by -.Fa fd +.Fa fildes in the termios structure referenced by -.Fa tp . -This function is allowed from a background process, however, the terminal -attributes may be subsequently changed by a foreground process. +.Fa termios_p . +This function is allowed from a background process; +however, the terminal attributes may be subsequently changed +by a foreground process. .Pp The .Fn tcsetattr function sets the parameters associated with the terminal from the termios structure referenced by -.Fa tp . +.Fa termios_p . The -.Fa action +.Fa optional_actions field is created by .Em or Ns 'ing the following values, as specified in the include file @@ -224,21 +248,21 @@ the following values, as specified in the include file The change occurs immediately. .It Fa TCSADRAIN The change occurs after all output written to -.Fa fd +.Fa fildes has been transmitted to the terminal. This value of -.Fa action +.Fa optional_actions should be used when changing parameters that affect output. .It Fa TCSAFLUSH The change occurs after all output written to -.Fa fd +.Fa fildes has been transmitted to the terminal. Additionally, any input that has been received but not read is discarded. .It Fa TCSASOFT If this value is .Em or Ns 'ed into the -.Fa action +.Fa optional_actions value, the values of the .Em c_cflag , .Em c_ispeed , @@ -278,7 +302,7 @@ is set to indicate the error, as follows: .Bl -tag -width Er .It Bq Er EBADF The -.Fa fd +.Fa fildes argument to .Fn tcgetattr or @@ -290,14 +314,14 @@ The function was interrupted by a signal. .It Bq Er EINVAL The -.Fa action +.Fa optional_actions argument to the .Fn tcsetattr function was not valid, or an attempt was made to change an attribute represented in the termios structure to an unsupported value. .It Bq Er ENOTTY The file associated with the -.Fa fd +.Fa fildes argument to .Fn tcgetattr or @@ -313,7 +337,7 @@ The .Fn cfsetispeed , .Fn cfgetospeed , .Fn cfsetospeed , -.Fn tcgetattr +.Fn tcgetattr , and .Fn tcsetattr functions are expected to be compliant with the diff --git a/gen/tcsetpgrp.3 b/gen/tcsetpgrp.3 index b50e6a8..ef6ff36 100644 --- a/gen/tcsetpgrp.3 +++ b/gen/tcsetpgrp.3 @@ -41,23 +41,25 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In sys/types.h .In unistd.h .Ft int -.Fn tcsetpgrp "int fd" "pid_t pgrp_id" +.Fo tcsetpgrp +.Fa "int fildes" +.Fa "pid_t pgid_id" +.Fc .Sh DESCRIPTION If the process has a controlling terminal, the .Fn tcsetpgrp function sets the foreground process group ID associated with the terminal device to -.Fa pgrp_id . +.Fa pgid_id . The terminal device associated with -.Fa fd +.Fa fildes must be the controlling terminal of the calling process and the controlling terminal must be currently associated with the session of the calling process. The value of -.Fa pgrp_id +.Fa pgid_id must be the same as the process group ID of a process in the same session as the calling process. .Sh RETURN VALUES @@ -69,28 +71,36 @@ function will fail if: .Bl -tag -width Er .It Bq Er EBADF The -.Fa fd +.Fa fildes argument is not a valid file descriptor. .It Bq Er EINVAL An invalid value of -.Fa pgrp_id +.Fa pgid_id was specified. .It Bq Er ENOTTY The calling process does not have a controlling terminal, or the file represented by -.Fa fd +.Fa fildes is not the controlling terminal, or the controlling terminal is no longer associated with the session of the calling process. .It Bq Er EPERM The -.Fa pgrp_id +.Fa pgid_id argument does not match the process group ID of a process in the same session as the calling process. .El +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +The include file +.In sys/types.h +is necessary. .Sh SEE ALSO .Xr setpgid 2 , .Xr setsid 2 , -.Xr tcgetpgrp 3 +.Xr tcgetpgrp 3 , +.Xr compat 5 .Sh STANDARDS The .Fn tcsetpgrp diff --git a/gen/telldir-fbsd.c b/gen/telldir-fbsd.c new file mode 100644 index 0000000..6ed1288 --- /dev/null +++ b/gen/telldir-fbsd.c @@ -0,0 +1,174 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" +#include "telldir.h" + +/* + * The option SINGLEUSE may be defined to say that a telldir + * cookie may be used only once before it is freed. This option + * is used to avoid having memory usage grow without bound. + */ +#if !__DARWIN_UNIX03 +#define SINGLEUSE +#endif /* !__DARWIN_UNIX03 */ + +/* + * return a pointer into a directory + */ +long +telldir(dirp) + DIR *dirp; +{ + struct ddloc *lp; + +#if __DARWIN_UNIX03 + if (__isthreaded) + _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { + if ( +#if __DARWIN_64_BIT_INO_T + (lp->loc_seek == dirp->dd_td->seekoff) +#else /* !__DARWIN_64_BIT_INO_T */ + (lp->loc_seek == dirp->dd_seek) +#endif /* __DARWIN_64_BIT_INO_T */ + && (lp->loc_loc == dirp->dd_loc)) + goto found; + } + if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) { + if (__isthreaded) + _pthread_mutex_unlock((pthread_mutex_t *)&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); +#endif /* __DARWIN_UNIX03 */ + lp->loc_index = dirp->dd_td->td_loccnt++; +#if __DARWIN_64_BIT_INO_T + lp->loc_seek = dirp->dd_td->seekoff; +#else /* !__DARWIN_64_BIT_INO_T */ + lp->loc_seek = dirp->dd_seek; +#endif /* __DARWIN_64_BIT_INO_T */ + lp->loc_loc = dirp->dd_loc; + LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe); +#if __DARWIN_UNIX03 +found: +#endif /* __DARWIN_UNIX03 */ + if (__isthreaded) + _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + return (lp->loc_index); +} + +/* + * seek to an entry in a directory. + * Only values returned by "telldir" should be passed to seekdir. + */ +void +_seekdir(dirp, loc) + DIR *dirp; + long loc; +{ + struct ddloc *lp; + struct dirent *dp; + + LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { + if (lp->loc_index == loc) + break; + } + if (lp == NULL) + return; + if (lp->loc_loc == dirp->dd_loc && +#if __DARWIN_64_BIT_INO_T + lp->loc_seek == dirp->dd_td->seekoff +#else /* !__DARWIN_64_BIT_INO_T */ + lp->loc_seek == dirp->dd_seek +#endif /* __DARWIN_64_BIT_INO_T */ + ) + goto found; + (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET); +#if __DARWIN_64_BIT_INO_T + dirp->dd_td->seekoff = lp->loc_seek; +#else /* !__DARWIN_64_BIT_INO_T */ + dirp->dd_seek = lp->loc_seek; +#endif /* __DARWIN_64_BIT_INO_T */ + dirp->dd_loc = 0; + while (dirp->dd_loc < lp->loc_loc) { + dp = _readdir_unlocked(dirp); + if (dp == NULL) + break; + } +found:; +#ifdef SINGLEUSE + LIST_REMOVE(lp, loc_lqe); + free((caddr_t)lp); +#endif +} + +#ifndef BUILDING_VARIANT +/* + * Reclaim memory for telldir cookies which weren't used. + */ +void +_reclaim_telldir(dirp) + DIR *dirp; +{ + struct ddloc *lp; + struct ddloc *templp; + + lp = LIST_FIRST(&dirp->dd_td->td_locq); + while (lp != NULL) { + templp = lp; + lp = LIST_NEXT(lp, loc_lqe); + free(templp); + } + LIST_INIT(&dirp->dd_td->td_locq); +} +#endif /* !BUILDING_VARIANT */ diff --git a/gen/telldir.h b/gen/telldir.h new file mode 100644 index 0000000..379cd09 --- /dev/null +++ b/gen/telldir.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Copyright (c) 2000 + * Daniel Eischen. 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. + * + * $FreeBSD: src/lib/libc/gen/telldir.h,v 1.2 2001/01/24 12:59:24 deischen Exp $ + */ + +#ifndef _TELLDIR_H_ +#define _TELLDIR_H_ + +#include + +/* + * One of these structures is malloced to describe the current directory + * position each time telldir is called. It records the current magic + * cookie returned by getdirentries and the offset within the buffer + * associated with that return value. + */ +struct ddloc { + LIST_ENTRY(ddloc) loc_lqe; /* entry in list */ + long loc_index; /* key associated with structure */ +#if __DARWIN_64_BIT_INO_T + __darwin_off_t loc_seek; /* returned by lseek */ +#else /* !__DARWIN_64_BIT_INO_T */ + long loc_seek; /* magic cookie returned by getdirentries */ +#endif /* __DARWIN_64_BIT_INO_T */ + long loc_loc; /* offset of entry in buffer */ +}; + +/* + * One of these structures is malloced for each DIR to record telldir + * positions. + */ +struct _telldir { + LIST_HEAD(, ddloc) td_locq; /* list of locations */ + long td_loccnt; /* index of entry for sequential readdir's */ +#if __DARWIN_64_BIT_INO_T + __darwin_off_t seekoff; /* 64-bit seek offset */ +#endif /* __DARWIN_64_BIT_INO_T */ +}; + +#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); +void _reclaim_telldir(DIR *); +void _seekdir(DIR *, long) __DARWIN_ALIAS_I(_seekdir); +long telldir(DIR *) __DARWIN_ALIAS_I(telldir); + +#endif diff --git a/gen/termios-fbsd.c b/gen/termios-fbsd.c new file mode 100644 index 0000000..4168a4e --- /dev/null +++ b/gen/termios-fbsd.c @@ -0,0 +1,264 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#if __DARWIN_UNIX03 +#ifdef VARIANT_CANCELABLE +#include + +extern void _pthread_testcancel(pthread_t thread, int isconforming); +#endif /* VARIANT_CANCELABLE */ +#endif /* __DARWIN_UNIX03 */ + +#include "namespace.h" +#include +#include +#include +#include + +#include +#include +#include +#include "un-namespace.h" + +#ifndef BUILDING_VARIANT +int +tcgetattr(fd, t) + int fd; + struct termios *t; +{ + + return (_ioctl(fd, TIOCGETA, t)); +} + +int +tcsetattr(fd, opt, t) + int fd, opt; + const struct termios *t; +{ + struct termios localterm; + + if (opt & TCSASOFT) { + localterm = *t; + localterm.c_cflag |= CIGNORE; + t = &localterm; + } + switch (opt & ~TCSASOFT) { + case TCSANOW: + return (_ioctl(fd, TIOCSETA, t)); + case TCSADRAIN: + return (_ioctl(fd, TIOCSETAW, t)); + case TCSAFLUSH: + return (_ioctl(fd, TIOCSETAF, t)); + default: + errno = EINVAL; + return (-1); + } +} + +int +tcsetpgrp(int fd, pid_t pgrp) +{ + int s; + + if (isatty(fd) == 0) + return (-1); + + s = pgrp; + return (_ioctl(fd, TIOCSPGRP, &s)); +} + +pid_t +tcgetpgrp(fd) + int fd; +{ + int s; + + if (isatty(fd) == 0) + return ((pid_t)-1); + + if (_ioctl(fd, TIOCGPGRP, &s) < 0) + return ((pid_t)-1); + + return ((pid_t)s); +} + +speed_t +cfgetospeed(t) + const struct termios *t; +{ + + return (t->c_ospeed); +} + +speed_t +cfgetispeed(t) + const struct termios *t; +{ + + return (t->c_ispeed); +} + +int +cfsetospeed(t, speed) + struct termios *t; + speed_t speed; +{ + + t->c_ospeed = speed; + return (0); +} + +int +cfsetispeed(t, speed) + struct termios *t; + speed_t speed; +{ + + t->c_ispeed = speed; + return (0); +} + +int +cfsetspeed(t, speed) + struct termios *t; + speed_t speed; +{ + + t->c_ispeed = t->c_ospeed = speed; + return (0); +} + +/* + * Make a pre-existing termios structure into "raw" mode: character-at-a-time + * mode with no characters interpreted, 8-bit data path. + */ +void +cfmakeraw(t) + struct termios *t; +{ + + t->c_iflag &= ~(IMAXBEL|IXOFF|INPCK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IGNPAR); + t->c_iflag |= IGNBRK; + t->c_oflag &= ~OPOST; + t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH|TOSTOP|PENDIN); + t->c_cflag &= ~(CSIZE|PARENB); + t->c_cflag |= CS8|CREAD; + t->c_cc[VMIN] = 1; + t->c_cc[VTIME] = 0; +} + +int +tcsendbreak(fd, len) + int fd, len; +{ + struct timeval sleepytime; + + sleepytime.tv_sec = 0; + sleepytime.tv_usec = 400000; + if (_ioctl(fd, TIOCSBRK, 0) == -1) + return (-1); + (void)_select(0, 0, 0, 0, &sleepytime); + if (_ioctl(fd, TIOCCBRK, 0) == -1) + return (-1); + return (0); +} +#endif /* BUILDING_VARIANT */ + +int +__tcdrain(fd) + int fd; +{ +#if __DARWIN_UNIX03 +#ifdef VARIANT_CANCELABLE + _pthread_testcancel(pthread_self(), 1); +#endif /* VARIANT_CANCELABLE */ +#endif /* __DARWIN_UNIX03 */ + return (_ioctl(fd, TIOCDRAIN, 0)); +} + +__weak_reference(__tcdrain, tcdrain); +__weak_reference(__tcdrain, _tcdrain); + +#ifndef BUILDING_VARIANT +int +tcflush(fd, which) + int fd, which; +{ + int com; + + switch (which) { + case TCIFLUSH: + com = FREAD; + break; + case TCOFLUSH: + com = FWRITE; + break; + case TCIOFLUSH: + com = FREAD | FWRITE; + break; + default: + errno = EINVAL; + return (-1); + } + return (_ioctl(fd, TIOCFLUSH, &com)); +} + +int +tcflow(fd, action) + int fd, action; +{ + struct termios term; + u_char c; + + switch (action) { + case TCOOFF: + return (_ioctl(fd, TIOCSTOP, 0)); + case TCOON: + return (_ioctl(fd, TIOCSTART, 0)); + case TCION: + return (_ioctl(fd, TIOCIXON, 0)); + case TCIOFF: + return (_ioctl(fd, TIOCIXOFF, 0)); + default: + errno = EINVAL; + return (-1); + } + /* NOTREACHED */ +} +#endif /* BUILDING_VARIANT */ diff --git a/gen/thread_stack_pcs.c b/gen/thread_stack_pcs.c new file mode 100644 index 0000000..91363aa --- /dev/null +++ b/gen/thread_stack_pcs.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 1999, 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@ + */ + +/* Bertrand from vmutils -> CF -> System */ + +#include +#include +#include +#include + +#if defined(__i386__) || defined(__x86_64__) +#define FP_LINK_OFFSET 1 +#elif defined(__ppc__) || defined(__ppc64__) +#define FP_LINK_OFFSET 2 +#else +#error ********** Unimplemented architecture +#endif + +#define INSTACK(a) ((a) >= stackbot && (a) <= stacktop) +#if defined(__ppc__) || defined(__ppc64__) || defined(__x86_64__) +#define ISALIGNED(a) ((((uintptr_t)(a)) & 0xf) == 0) +#elif defined(__i386__) +#define ISALIGNED(a) ((((uintptr_t)(a)) & 0xf) == 8) +#endif + +__private_extern__ __attribute__((noinline)) +void +_thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb, unsigned skip) +{ + void *frame, *next; + pthread_t self = pthread_self(); + void *stacktop = pthread_get_stackaddr_np(self); + void *stackbot = stacktop - pthread_get_stacksize_np(self); + + *nb = 0; + + /* make sure return address is never out of bounds */ + stacktop -= (FP_LINK_OFFSET + 1) * sizeof(void *); + + /* + * The original implementation called the first_frame_address() function, + * which returned the stack frame pointer. The problem was that in ppc, + * it was a leaf function, so no new stack frame was set up with + * optimization turned on (while a new stack frame was set up without + * optimization). We now inline the code to get the stack frame pointer, + * so we are consistent about the stack frame. + */ +#if defined(__i386__) || defined(__x86_64__) + frame = __builtin_frame_address(0); +#elif defined(__ppc__) || defined(__ppc64__) + /* __builtin_frame_address IS BROKEN IN BEAKER: RADAR #2340421 */ + __asm__ volatile("mr %0, r1" : "=r" (frame)); +#endif + if(!INSTACK(frame) || !ISALIGNED(frame)) + return; +#if defined(__ppc__) || defined(__ppc64__) + /* back up the stack pointer up over the current stack frame */ + next = *(void **)frame; + if(!INSTACK(next) || !ISALIGNED(next) || next <= frame) + return; + frame = next; +#endif + while (skip--) { + next = *(void **)frame; + if(!INSTACK(next) || !ISALIGNED(next) || next <= frame) + return; + frame = next; + } + while (max--) { + buffer[*nb] = *(vm_address_t *)(((void **)frame) + FP_LINK_OFFSET); + (*nb)++; + next = *(void **)frame; + if(!INSTACK(next) || !ISALIGNED(next) || next <= frame) + return; + frame = next; + } +} + +void +thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb) +{ + _thread_stack_pcs(buffer, max, nb, 0); + + // The following prevents thread_stack_pcs() from getting tail-call-optimized into _thread_stack_pcs() on 64-bit environments, + // thus making the "number of hot frames to skip" be more predictable, giving more consistent backtraces. + // See "stack logging: frames keep getting truncated" for why this is necessary. + __asm__ volatile(""); +} diff --git a/gen/time-fbsd.c b/gen/time-fbsd.c new file mode 100644 index 0000000..08921d0 --- /dev/null +++ b/gen/time-fbsd.c @@ -0,0 +1,61 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include +#include +#include + +time_t +time(t) + time_t *t; +{ + struct timeval tt; + time_t retval; + fenv_t fenv; + + fegetenv(&fenv); /* 3965505 - need to preserve floating point enviroment */ + if (gettimeofday(&tt, (struct timezone *)0) < 0) + retval = -1; + else + retval = tt.tv_sec; + if (t != NULL) + *t = retval; + fesetenv(&fenv); + return (retval); +} diff --git a/gen/time.3 b/gen/time.3 new file mode 100644 index 0000000..ffebc88 --- /dev/null +++ b/gen/time.3 @@ -0,0 +1,105 @@ +.\" Copyright (c) 1989, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd July 18, 2003 +.Dt TIME 3 +.Os +.Sh NAME +.Nm time +.Nd get time of day +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In time.h +.Ft time_t +.Fn time "time_t *tloc" +.Sh DESCRIPTION +The +.Fn time +function +returns the value of time in seconds since 0 hours, 0 minutes, +0 seconds, January 1, 1970, Coordinated Universal Time, +without including leap seconds. +If an error occurs, +.Fn time +returns the value +.Po Vt time_t Pc Ns \-1 . +.Pp +The return value is also stored in +.No \&* Ns Va tloc , +provided that +.Va tloc +is non-null. +.Sh ERRORS +The +.Fn time +function may fail for any of the reasons described in +.Xr gettimeofday 2 . +.Sh SEE ALSO +.Xr gettimeofday 2 , +.Xr ctime 3 +.Sh STANDARDS +The +.Nm +function conforms to +.St -p1003.1-2001 . +.Sh BUGS +Neither +.St -isoC-99 +nor +.St -p1003.1-2001 +requires +.Fn time +to set +.Va errno +on failure; thus, it is impossible for an application to distinguish +the valid time value \-1 (representing the last UTC second of 1969) +from the error return value. +.Pp +Systems conforming to earlier versions of the C and +.Tn POSIX +standards (including older versions of +.Fx ) +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/times-fbsd.c b/gen/times-fbsd.c new file mode 100644 index 0000000..5bdc607 --- /dev/null +++ b/gen/times-fbsd.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)times.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/times.c,v 1.2 2002/02/01 01:08:48 obrien Exp $"); + +#include +#include +#include +#include + +/* + * Convert usec to clock ticks; could do (usec * CLK_TCK) / 1000000, + * but this would overflow if we switch to nanosec. + */ +#define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) + +clock_t +times(tp) + struct tms *tp; +{ + struct rusage ru; + struct timeval t; + + if (getrusage(RUSAGE_SELF, &ru) < 0) + return ((clock_t)-1); + tp->tms_utime = CONVTCK(ru.ru_utime); + tp->tms_stime = CONVTCK(ru.ru_stime); + if (getrusage(RUSAGE_CHILDREN, &ru) < 0) + return ((clock_t)-1); + tp->tms_cutime = CONVTCK(ru.ru_utime); + tp->tms_cstime = CONVTCK(ru.ru_stime); + if (gettimeofday(&t, (struct timezone *)0)) + return ((clock_t)-1); + return ((clock_t)(CONVTCK(t))); +} diff --git a/gen/times.3 b/gen/times.3 new file mode 100644 index 0000000..f8e5f01 --- /dev/null +++ b/gen/times.3 @@ -0,0 +1,146 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)times.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: src/lib/libc/gen/times.3,v 1.10 2001/10/01 16:08:51 ru Exp $ +.\" +.Dd June 4, 1993 +.Dt TIMES 3 +.Os +.Sh NAME +.Nm times +.Nd process times +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/times.h +.Ft clock_t +.Fo times +.Fa "struct tms *buffer" +.Fc +.Sh DESCRIPTION +.Bf -symbolic +This interface is obsoleted by +.Xr getrusage 2 +and +.Xr gettimeofday 2 . +.Ef +.Pp +The +.Fn times +function returns the value of time in +.Dv CLK_TCK Ns 's +of a second since +0 hours, 0 minutes, 0 seconds, January 1, 1970, Coordinated Universal +Time. +.Pp +It also fills in the structure pointed to by +.Fa buffer +with time-accounting information. +.Pp +The +.Vt tms +structure is defined as follows: +.Bd -literal -offset indent +struct tms { + clock_t tms_utime; + clock_t tms_stime; + clock_t tms_cutime; + clock_t tms_cstime; +}; +.Ed +.Pp +The elements of this structure are defined as follows: +.Bl -tag -width ".Va tms_cutime" +.It Va tms_utime +The +.Tn CPU +time charged for the execution of user instructions. +.It Va tms_stime +The +.Tn CPU +time charged for execution by the system on behalf of +the process. +.It Va tms_cutime +The sum of the +.Va tms_utime Ns s +and +.Va tms_cutime Ns s +of the child processes. +.It Va tms_cstime +The sum of the +.Fa tms_stime Ns s +and +.Fa tms_cstime Ns s +of the child processes. +.El +.Pp +All times are in +.Dv CLK_TCK Ns 's +of a second. +.Pp +The times of a terminated child process are included in the +.Va tms_cutime +and +.Va tms_cstime +elements of the parent when one of the +.Xr wait 2 +functions returns the process ID of the terminated child to the parent. +If an error occurs, +.Fn times +returns the value +.Pq Po Vt clock_t Pc Ns \-1 , +and sets +.Va errno +to indicate the error. +.Sh ERRORS +The +.Fn times +function +may fail and set the global variable +.Va errno +for any of the errors specified for the library +routines +.Xr getrusage 2 +and +.Xr gettimeofday 2 . +.Sh SEE ALSO +.Xr time 1 , +.Xr getrusage 2 , +.Xr gettimeofday 2 , +.Xr wait 2 , +.Xr clocks 7 +.Sh STANDARDS +The +.Fn times +function +conforms to +.St -p1003.1-88 . diff --git a/gen/timezone-fbsd.c b/gen/timezone-fbsd.c new file mode 100644 index 0000000..8d8139a --- /dev/null +++ b/gen/timezone-fbsd.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1987, 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[] = "@(#)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 $"); + +#include +#include +#include +#include +#include +#define TZ_MAX_CHARS 255 + +char *_tztab(); + +/* + * timezone -- + * The arguments are the number of minutes of time you are westward + * from Greenwich and whether DST is in effect. It returns a string + * giving the name of the local timezone. Should be replaced, in the + * application code, by a call to localtime. + */ + +static char czone[TZ_MAX_CHARS]; /* space for zone name */ + +char * +timezone(zone, dst) + int zone, + dst; +{ + char *beg, + *end; + + if ( (beg = getenv("TZNAME")) ) { /* set in environment */ + if ( (end = index(beg, ',')) ) {/* "PST,PDT" */ + if (dst) + return(++end); + *end = '\0'; + (void)strncpy(czone,beg,sizeof(czone) - 1); + czone[sizeof(czone) - 1] = '\0'; + *end = ','; + return(czone); + } + return(beg); + } + return(_tztab(zone,dst)); /* default: table or created zone */ +} + +static struct zone { + int offset; + char *stdzone; + char *dlzone; +} zonetab[] = { + {-1*60, "MET", "MET DST"}, /* Middle European */ + {-2*60, "EET", "EET DST"}, /* Eastern European */ + {4*60, "AST", "ADT"}, /* Atlantic */ + {5*60, "EST", "EDT"}, /* Eastern */ + {6*60, "CST", "CDT"}, /* Central */ + {7*60, "MST", "MDT"}, /* Mountain */ + {8*60, "PST", "PDT"}, /* Pacific */ +#ifdef notdef + /* there's no way to distinguish this from WET */ + {0, "GMT", 0}, /* Greenwich */ +#endif + {0*60, "WET", "WET DST"}, /* Western European */ + {-10*60,"EST", "EST"}, /* Aust: Eastern */ + {-10*60+30,"CST", "CST"}, /* Aust: Central */ + {-8*60, "WST", 0}, /* Aust: Western */ + {-1} +}; + +/* + * _tztab -- + * check static tables or create a new zone name; broken out so that + * we can make a guess as to what the zone is if the standard tables + * aren't in place in /etc. DO NOT USE THIS ROUTINE OUTSIDE OF THE + * STANDARD LIBRARY. + */ +char * +_tztab(zone,dst) + int zone; + int dst; +{ + struct zone *zp; + char sign; + + for (zp = zonetab; zp->offset != -1;++zp) /* static tables */ + if (zp->offset == zone) { + if (dst && zp->dlzone) + return(zp->dlzone); + if (!dst && zp->stdzone) + return(zp->stdzone); + } + + if (zone < 0) { /* create one */ + zone = -zone; + sign = '+'; + } + else + sign = '-'; + (void)snprintf(czone, sizeof(czone), + "GMT%c%d:%02d",sign,zone / 60,zone % 60); + return(czone); +} diff --git a/gen/timezone.3 b/gen/timezone.3 new file mode 120000 index 0000000..39479a8 --- /dev/null +++ b/gen/timezone.3 @@ -0,0 +1 @@ +./timezone.3 \ No newline at end of file diff --git a/gen/ttyname-fbsd.c b/gen/ttyname-fbsd.c new file mode 100644 index 0000000..8b61551 --- /dev/null +++ b/gen/ttyname-fbsd.c @@ -0,0 +1,200 @@ +/* + * 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[] = "@(#)ttyname.c 8.2 (Berkeley) 1/27/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/ttyname.c,v 1.16 2004/01/06 18:26:14 nectar Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" + +#ifndef BUILDING_VARIANT +static char buf[sizeof(_PATH_DEV) + MAXNAMLEN]; +static char *ttyname_threaded(int fd); +static char *ttyname_unthreaded(int fd); + +static pthread_mutex_t ttyname_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_key_t ttyname_key; +static int ttyname_init = 0; +extern int __pthread_tsd_first; + +char * +ttyname(int fd) +{ + char *ret; + + if (__isthreaded == 0) + ret = ttyname_unthreaded(fd); + else + ret = ttyname_threaded(fd); + return (ret); +} +#endif /* !BUILDING_VARIANT */ + +#if __DARWIN_UNIX03 +int +#else /* !__DARWIN_UNIX03 */ +char * +#endif /* __DARWIN_UNIX03 */ +ttyname_r(int fd, char *thrbuf, size_t len) +{ + struct stat sb; + +#if __DARWIN_UNIX03 + if (_fstat(fd, &sb) < 0) + return (EBADF); + /* Must be a terminal. */ + if (!isatty(fd)) + return (ENOTTY); + /* Must be a character device. */ + if (!S_ISCHR(sb.st_mode)) + return (ENOTTY); + /* Must have enough room */ + if (len <= sizeof(_PATH_DEV)) + return (ERANGE); +#else /* !__DARWIN_UNIX03 */ + /* Must be a terminal. */ + if (!isatty(fd)) + return (NULL); + /* Must be a character device. */ + if (_fstat(fd, &sb)) + return (NULL); + if (!S_ISCHR(sb.st_mode)) { + errno = ENOTTY; + return (NULL); + } + /* Must have enough room */ + if (len <= sizeof(_PATH_DEV)) { + errno = ERANGE; + return (NULL); + } +#endif /* __DARWIN_UNIX03 */ + + strcpy(thrbuf, _PATH_DEV); + if (devname_r(sb.st_rdev, S_IFCHR, + thrbuf + strlen(thrbuf), len - strlen(thrbuf)) == NULL) +#if __DARWIN_UNIX03 + return (ERANGE); + return (0); +#else /* !__DARWIN_UNIX03 */ + { + errno = ERANGE; + return (NULL); + } + return (thrbuf); +#endif /* __DARWIN_UNIX03 */ +} + +#ifndef BUILDING_VARIANT +static char * +ttyname_threaded(int fd) +{ + char *buf; + + if (ttyname_init == 0) { + _pthread_mutex_lock(&ttyname_lock); + if (ttyname_init == 0) { + /* __PTK_LIBC_TTYNAME_KEY */ + ttyname_key = __pthread_tsd_first+1; + if (pthread_key_init_np(ttyname_key, free)) { + int save = errno; + _pthread_mutex_unlock(&ttyname_lock); + errno = save; + return (NULL); + } + ttyname_init = 1; + } + _pthread_mutex_unlock(&ttyname_lock); + } + + /* Must have thread specific data field to put data */ + if ((buf = _pthread_getspecific(ttyname_key)) == NULL) { + if ((buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) { + if (_pthread_setspecific(ttyname_key, buf) != 0) { + int save = errno; + free(buf); + errno = save; + return (NULL); + } + } else { + return (NULL); + } + } +#if __DARWIN_UNIX03 + return (ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN) == 0 ? buf : NULL); +#else /* !__DARWIN_UNIX03 */ + return (ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN)); +#endif /* __DARWIN_UNIX03 */ +} + +static char * +ttyname_unthreaded(int fd) +{ + struct stat sb; + struct termios ttyb; + + /* Must be a terminal. */ + if (tcgetattr(fd, &ttyb) < 0) + return (NULL); + /* Must be a character device. */ + if (_fstat(fd, &sb)) + return (NULL); + if (!S_ISCHR(sb.st_mode)) { + errno = ENOTTY; + return (NULL); + } + + strcpy(buf, _PATH_DEV); + if (devname_r(sb.st_rdev, S_IFCHR, + buf + strlen(buf), sizeof(buf) - strlen(buf)) == NULL) { + errno = ERANGE; + return (NULL); + } + return (buf); +} +#endif /* !BUILDING_VARIANT */ diff --git a/gen/ttyname.3 b/gen/ttyname.3 new file mode 100644 index 0000000..0012549 --- /dev/null +++ b/gen/ttyname.3 @@ -0,0 +1,135 @@ +.\" 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. +.\" +.\" @(#)ttyname.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: src/lib/libc/gen/ttyname.3,v 1.10 2002/12/18 13:33:02 ru Exp $ +.\" +.Dd June 4, 1993 +.Dt TTYNAME 3 +.Os +.Sh NAME +.Nm isatty , +.Nm ttyname , +.Nm ttyslot +.Nd get name of associated terminal (tty) from file descriptor +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fo isatty +.Fa "int fildes" +.Fc +.Ft char * +.Fo ttyname +.Fa "int fildes" +.Fc +.Ft int +.Fo ttyslot +.Fa void +.Fc +.Sh DESCRIPTION +These functions operate on the system file descriptors for terminal +type devices. +These descriptors are not related to the standard +.Tn I/O +.Dv FILE +typedef, but refer to the special device files found in +.Pa /dev +and named +.Pa /dev/tty Ns Ar xx +and for which an entry exists +in the initialization file +.Pa /etc/ttys . +(See +.Xr ttys 5 . ) +.Pp +The +.Fn isatty +function +determines if the file descriptor +.Fa fildes +refers to a valid +terminal type device. +.Pp +The +.Fn ttyname +function +gets the related device name of +a file descriptor for which +.Fn isatty +is true. +.Pp +The +.Fn ttyslot +function +fetches the current process' control terminal number from the +.Xr ttys 5 +file entry. +.Sh RETURN VALUES +The +.Fn ttyname +function +returns the null terminated name if the device is found and +.Fn isatty +is true; otherwise, a +.Dv NULL +pointer is returned. +.Pp +The +.Fn ttyslot +function returns the unit number of the device file if found; +otherwise, the value zero is returned. +.Sh FILES +.Bl -tag -width /etc/ttys -compact +.It Pa /dev/\(** +.It Pa /etc/ttys +.El +.Sh SEE ALSO +.Xr ioctl 2 , +.Xr ttys 5 +.Sh HISTORY +A +.Fn isatty , +.Fn ttyname , +and +.Fn ttyslot +function +appeared in +.At v7 . +.Sh BUGS +The +.Fn ttyname +function leaves its result in an internal static object and returns +a pointer to that object. +Subsequent calls to +.Fn ttyname +will modify the same object. diff --git a/gen/ttyslot-fbsd.c b/gen/ttyslot-fbsd.c new file mode 100644 index 0000000..0d7359c --- /dev/null +++ b/gen/ttyslot-fbsd.c @@ -0,0 +1,70 @@ +/* + * 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[] = "@(#)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 $"); + +#include +#include +#include +#include + +int +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; + for (slot = 1; (ttyp = getttyent()); ++slot) + if (!strcmp(ttyp->ty_name, p)) { + endttyent(); + return(slot); + } + break; + } + endttyent(); + return(0); +} diff --git a/gen/tzset.3 b/gen/tzset.3 index 0d718f0..a681179 100644 --- a/gen/tzset.3 +++ b/gen/tzset.3 @@ -47,9 +47,13 @@ .Sh SYNOPSIS .In time.h .Ft void -.Fn tzset void +.Fo tzset +.Fa void +.Fc .Ft void -.Fn tzsetwall void +.Fo tzsetwall +.Fa void +.Fc .Sh DESCRIPTION The .Fn tzset @@ -66,13 +70,13 @@ does not appear in the environment, the best available approximation to local wall clock time, as specified by the .Xr tzfile 5 Ns -format file -.Pa /etc/localtime +.Pa /etc/localtime , is used. .Pp If .Ev TZ -appears in the environment but its value is a null string, Coordinated -Universal Time +appears in the environment but its value is a null string, +Coordinated Universal Time .Pq Tn UTC is used (without leap second correction). .Pp @@ -84,7 +88,7 @@ the rest of its value is used as a pathname of a .Xr tzfile 5 Ns -format file from which to read the time conversion information. If the first character of the pathname is a slash -.Pq Ql / +.Pq Ql / , it is used as an absolute pathname; otherwise, it is used as a pathname relative to the system time conversion information directory. diff --git a/gen/ualarm-fbsd.c b/gen/ualarm-fbsd.c new file mode 100644 index 0000000..a9200ae --- /dev/null +++ b/gen/ualarm-fbsd.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1985, 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[] = "@(#)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 $"); + +#include +#include + +#define USPS 1000000 /* # of microseconds in a second */ + +/* + * Generate a SIGALRM signal in ``usecs'' microseconds. + * If ``reload'' is non-zero, keep generating SIGALRM + * every ``reload'' microseconds after the first signal. + */ +useconds_t +ualarm(usecs, reload) + useconds_t usecs; + useconds_t reload; +{ + struct itimerval new, old; + + new.it_interval.tv_usec = reload % USPS; + new.it_interval.tv_sec = reload / USPS; + + new.it_value.tv_usec = usecs % USPS; + new.it_value.tv_sec = usecs / USPS; + + if (setitimer(ITIMER_REAL, &new, &old) == 0) + return (old.it_value.tv_sec * USPS + old.it_value.tv_usec); + /* else */ + return (-1); +} diff --git a/gen/ualarm.3 b/gen/ualarm.3 new file mode 100644 index 0000000..ede1ea2 --- /dev/null +++ b/gen/ualarm.3 @@ -0,0 +1,104 @@ +.\" Copyright (c) 1986, 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. +.\" +.\" 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 $ +.\" +.Dd April 19, 1994 +.Dt UALARM 3 +.Os +.Sh NAME +.Nm ualarm +.Nd schedule signal after specified time +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft useconds_t +.Fo ualarm +.Fa "useconds_t useconds" +.Fa "useconds_t interval" +.Fc +.Sh DESCRIPTION +.Bf -symbolic +This is a simplified interface to +.Xr setitimer 2 . +.Ef +.Pp +The +.Fn ualarm +function +waits a count of +.Fa useconds +before asserting the terminating signal +.Dv SIGALRM . +System activity or time used in processing the call may cause a slight +delay. +.Pp +If the +.Fa interval +argument is non-zero, the +.Dv SIGALRM +signal will be sent +to the process every +.Fa interval +microseconds after the timer expires (e.g., after +.Fa useconds +number of microseconds have passed). +.Pp +Due to a +.Xr setitimer 2 +restriction, the maximum number of +.Fa useconds +and +.Fa interval +is limited to 100,000,000,000,000 +(in case this value fits in the unsigned integer). +.Sh RETURN VALUES +When the signal has successfully been caught, +.Fn ualarm +returns the amount of time left on the clock. +.Sh NOTES +A microsecond is 0.000001 seconds. +.Sh SEE ALSO +.Xr getitimer 2 , +.Xr setitimer 2 , +.Xr sigpause 2 , +.Xr sigvec 2 , +.Xr alarm 3 , +.Xr signal 3 , +.Xr sleep 3 , +.Xr usleep 3 +.Sh HISTORY +The +.Fn ualarm +function appeared in +.Bx 4.3 . diff --git a/gen/ucontext.3 b/gen/ucontext.3 new file mode 120000 index 0000000..2defc9a --- /dev/null +++ b/gen/ucontext.3 @@ -0,0 +1 @@ +./ucontext.3 \ No newline at end of file diff --git a/gen/ulimit-fbsd.c b/gen/ulimit-fbsd.c new file mode 100644 index 0000000..d25ff47 --- /dev/null +++ b/gen/ulimit-fbsd.c @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 2002 Kyle Martin + * 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/gen/ulimit.c,v 1.3 2003/01/04 01:11:49 tjr Exp $ + */ + +#include +#include +#include + +#include +#include +#include +#include + +long +ulimit(int cmd, ...) +{ + struct rlimit limit; + va_list ap; + long arg; + + if (cmd == UL_GETFSIZE) { + if (getrlimit(RLIMIT_FSIZE, &limit) == -1) + return (-1); + limit.rlim_cur /= 512; + if (limit.rlim_cur > LONG_MAX) + return (LONG_MAX); + return ((long)limit.rlim_cur); + } else if (cmd == UL_SETFSIZE) { + va_start(ap, cmd); + arg = va_arg(ap, long); + va_end(ap); + limit.rlim_max = limit.rlim_cur = (rlim_t)arg * 512; + + /* The setrlimit() function sets errno to EPERM if needed. */ + if (setrlimit(RLIMIT_FSIZE, &limit) == -1) + return (-1); + if (arg * 512 > LONG_MAX) + return (LONG_MAX); + return (arg); + } else { + errno = EINVAL; + return (-1); + } +} diff --git a/gen/ulimit.3 b/gen/ulimit.3 new file mode 100644 index 0000000..f19e152 --- /dev/null +++ b/gen/ulimit.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 2002 Kyle Martin. 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 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/gen/ulimit.3,v 1.5 2003/01/04 01:11:49 tjr Exp $ +.\" +.Dd January 4, 2003 +.Dt ULIMIT 3 +.Os +.Sh NAME +.Nm ulimit +.Nd get and set process limits +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ulimit.h +.Ft long +.Fo ulimit +.Fa "int cmd" +.Fa "..." +.Fc +.Sh DESCRIPTION +The +.Fn ulimit +function will get and set process limits. +Currently, this is limited to the maximum file size. +The +.Fa cmd +argument is one of the following: +.Bl -tag -width ".Dv UL_GETFSIZE" +.It Dv UL_GETFSIZE +will return the maximum file size of the current process, +in units of 512-byte blocks. +.It Dv UL_SETFSIZE +will attempt to set the maximum file size of the current +process and its children, using the second argument (expressed as a long). +.El +.Sh RETURN VALUES +Upon successful completion, +.Fn ulimit +returns the value requested; +otherwise, the value \-1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn ulimit +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The command specified was invalid. +.It Bq Er EPERM +The limit specified to +.Fn ulimit +would have raised the maximum limit value, +and the caller is not the super-user. +.El +.Sh SEE ALSO +.Xr getrlimit 2 +.Sh STANDARDS +The +.Fn ulimit +function conforms to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn ulimit +function first appeared in +.Fx 5.0 . +.Sh BUGS +The +.Fn ulimit +function provides limited precision for +setting and retrieving process limits. +If there is a need for greater precision than the +type +.Vt long +provides, the +.Xr getrlimit 2 +and +.Xr setrlimit 2 +functions should be considered. diff --git a/gen/uname.c b/gen/uname.c index c5b2a14..c4ebb07 100644 --- a/gen/uname.c +++ b/gen/uname.c @@ -1,25 +1,3 @@ -/* - * 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) 1994 * The Regents of the University of California. All rights reserved. diff --git a/gen/unvis-fbsd.c b/gen/unvis-fbsd.c new file mode 100644 index 0000000..02984c0 --- /dev/null +++ b/gen/unvis-fbsd.c @@ -0,0 +1,300 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include +#include + +/* + * decode driven by state machine + */ +#define S_GROUND 0 /* haven't seen escape char */ +#define S_START 1 /* start decoding special sequence */ +#define S_META 2 /* metachar started (M) */ +#define S_META1 3 /* metachar more, regular char (-) */ +#define S_CTRL 4 /* control char started (^) */ +#define S_OCTAL2 5 /* octal digit 2 */ +#define S_OCTAL3 6 /* octal digit 3 */ +#define S_HEX2 7 /* hex digit 2 */ + +#define S_HTTP 0x080 /* %HEXHEX escape */ + +#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +#define ishex(c) ((((u_char)(c)) >= '0' && ((u_char)(c)) <= '9') || (((u_char)(c)) >= 'a' && ((u_char)(c)) <= 'f')) + +/* + * unvis - decode characters previously encoded by vis + */ +int +unvis(char *cp, int c, int *astate, int flag) +{ + locale_t loc = __current_locale(); + + if (flag & UNVIS_END) { + if (*astate == S_OCTAL2 || *astate == S_OCTAL3) { + *astate = S_GROUND; + return (UNVIS_VALID); + } + return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); + } + + switch (*astate & ~S_HTTP) { + + case S_GROUND: + *cp = 0; + if (c == '\\') { + *astate = S_START; + return (0); + } + if (flag & VIS_HTTPSTYLE && c == '%') { + *astate = S_START | S_HTTP; + return (0); + } + *cp = c; + return (UNVIS_VALID); + + case S_START: + if (*astate & S_HTTP) { + if (ishex(tolower_l(c, loc))) { + *cp = isdigit_l(c, loc) ? (c - '0') : (tolower_l(c, loc) - 'a'); + *astate = S_HEX2; + return (0); + } + } + switch(c) { + case '\\': + *cp = c; + *astate = S_GROUND; + return (UNVIS_VALID); + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + *cp = (c - '0'); + *astate = S_OCTAL2; + return (0); + case 'M': + *cp = 0200; + *astate = S_META; + return (0); + case '^': + *astate = S_CTRL; + return (0); + case 'n': + *cp = '\n'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'r': + *cp = '\r'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'b': + *cp = '\b'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'a': + *cp = '\007'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'v': + *cp = '\v'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 't': + *cp = '\t'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'f': + *cp = '\f'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 's': + *cp = ' '; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'E': + *cp = '\033'; + *astate = S_GROUND; + return (UNVIS_VALID); + case '\n': + /* + * hidden newline + */ + *astate = S_GROUND; + return (UNVIS_NOCHAR); + case '$': + /* + * hidden marker + */ + *astate = S_GROUND; + return (UNVIS_NOCHAR); + } + *astate = S_GROUND; + return (UNVIS_SYNBAD); + + case S_META: + if (c == '-') + *astate = S_META1; + else if (c == '^') + *astate = S_CTRL; + else { + *astate = S_GROUND; + return (UNVIS_SYNBAD); + } + return (0); + + case S_META1: + *astate = S_GROUND; + *cp |= c; + return (UNVIS_VALID); + + case S_CTRL: + if (c == '?') + *cp |= 0177; + else + *cp |= c & 037; + *astate = S_GROUND; + return (UNVIS_VALID); + + case S_OCTAL2: /* second possible octal digit */ + if (isoctal(c)) { + /* + * yes - and maybe a third + */ + *cp = (*cp << 3) + (c - '0'); + *astate = S_OCTAL3; + return (0); + } + /* + * no - done with current sequence, push back passed char + */ + *astate = S_GROUND; + return (UNVIS_VALIDPUSH); + + case S_OCTAL3: /* third possible octal digit */ + *astate = S_GROUND; + if (isoctal(c)) { + *cp = (*cp << 3) + (c - '0'); + return (UNVIS_VALID); + } + /* + * we were done, push back passed char + */ + return (UNVIS_VALIDPUSH); + + case S_HEX2: /* second mandatory hex digit */ + if (ishex(tolower_l(c, loc))) { + *cp = (isdigit_l(c, loc) ? (*cp << 4) + (c - '0') : (*cp << 4) + (tolower_l(c, loc) - 'a' + 10)); + } + *astate = S_GROUND; + return (UNVIS_VALID); + + default: + /* + * decoder in unknown state - (probably uninitialized) + */ + *astate = S_GROUND; + return (UNVIS_SYNBAD); + } +} + +/* + * strunvis - decode src into dst + * + * Number of chars decoded into dst is returned, -1 on error. + * Dst is null terminated. + */ + +int +strunvis(char *dst, const char *src) +{ + char c; + char *start = dst; + int state = 0; + + while ( (c = *src++) ) { + again: + switch (unvis(dst, c, &state, 0)) { + case UNVIS_VALID: + dst++; + break; + case UNVIS_VALIDPUSH: + dst++; + goto again; + case 0: + case UNVIS_NOCHAR: + break; + default: + return (-1); + } + } + if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) + dst++; + *dst = '\0'; + return (dst - start); +} + +int +strunvisx(char *dst, const char *src, int flag) +{ + char c; + char *start = dst; + int state = 0; + + while ( (c = *src++) ) { + again: + switch (unvis(dst, c, &state, flag)) { + case UNVIS_VALID: + dst++; + break; + case UNVIS_VALIDPUSH: + dst++; + goto again; + case 0: + case UNVIS_NOCHAR: + break; + default: + return (-1); + } + } + if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) + dst++; + *dst = '\0'; + return (dst - start); +} diff --git a/gen/unvis.3 b/gen/unvis.3 new file mode 120000 index 0000000..7571719 --- /dev/null +++ b/gen/unvis.3 @@ -0,0 +1 @@ +./unvis.3 \ No newline at end of file diff --git a/gen/usleep-fbsd.c b/gen/usleep-fbsd.c new file mode 100644 index 0000000..5ad2cd2 --- /dev/null +++ b/gen/usleep-fbsd.c @@ -0,0 +1,59 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + */ + +#ifdef VARIANT_CANCELABLE +#undef __DARWIN_NON_CANCELABLE +#define __DARWIN_NON_CANCELABLE 0 +#endif /* VARIANT_CANCELABLE */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" + +int +usleep(useconds) + useconds_t useconds; +{ + struct timespec time_to_sleep; + + time_to_sleep.tv_nsec = (useconds % 1000000) * 1000; + time_to_sleep.tv_sec = useconds / 1000000; + return (_nanosleep(&time_to_sleep, NULL)); +} diff --git a/gen/usleep.3 b/gen/usleep.3 new file mode 100644 index 0000000..acee9a3 --- /dev/null +++ b/gen/usleep.3 @@ -0,0 +1,88 @@ +.\" Copyright (c) 1986, 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. +.\" +.\" @(#)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 $ +.\" +.Dd February 13, 1998 +.Dt USLEEP 3 +.Os +.Sh NAME +.Nm usleep +.Nd suspend thread execution for an interval measured in microseconds +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fo usleep +.Fa "useconds_t useconds" +.Fc +.Sh DESCRIPTION +The +.Fn usleep +function suspends execution of the calling thread until either +.Fa useconds +microseconds have elapsed +or a signal is delivered to the thread whose action +is to invoke a signal-catching function +or to terminate the thread or process. +The actual time slept may be longer, due to system latencies +and possible limitations in the timer resolution of the hardware. +.Pp +This function is implemented, using +.Xr nanosleep 2 , +by pausing for +.Fa useconds +microseconds or until a signal occurs. +Consequently, in this implementation, +sleeping has no effect on the state of process timers +and there is no special handling for SIGALRM. +.Sh RETURN VALUES +.Rv -std usleep +.Sh ERRORS +The +.Fn usleep +function +will fail if: +.Bl -tag -width Er +.It Bq Er EINTR +A signal was delivered to the process and its +action was to invoke a signal-catching function. +.El +.Sh SEE ALSO +.Xr nanosleep 2 , +.Xr sleep 3 +.Sh HISTORY +The +.Fn usleep +function appeared in +.Bx 4.3 . diff --git a/gen/utime-fbsd.c b/gen/utime-fbsd.c new file mode 100644 index 0000000..cefa020 --- /dev/null +++ b/gen/utime-fbsd.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include + +#include + +int +utime(path, times) + const char *path; + const struct utimbuf *times; +{ + struct timeval tv[2], *tvp; + + if (times) { + tv[0].tv_sec = times->actime; + tv[1].tv_sec = times->modtime; + tv[0].tv_usec = tv[1].tv_usec = 0; + tvp = tv; + } else + tvp = NULL; + return (utimes(path, tvp)); +} diff --git a/gen/utime.3 b/gen/utime.3 new file mode 100644 index 0000000..92e8467 --- /dev/null +++ b/gen/utime.3 @@ -0,0 +1,93 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt UTIME 3 +.Os +.Sh NAME +.Nm utime +.Nd set file times +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In utime.h +.Ft int +.Fo utime +.Fa "const char *path" +.Fa "const struct utimbuf *times" +.Fc +.Sh DESCRIPTION +.Bf -symbolic +This interface is obsoleted by +.Xr utimes 2 . +.Ef +.Pp +The +.Fn utime +function sets the access and modification times of the named file, +based on the structures in the argument array +.Fa times . +.Pp +If the times are specified (the +.Fa times +argument is +.Pf non- Dv NULL ) , +the caller must be the owner of the file or be the super-user. +.Pp +If the times are not specified (the +.Fa times +argument is +.Dv NULL ) , +the caller must be the owner of the file, +have permission to write the file, or be the super-user. +.Sh ERRORS +The +.Fn utime +function may fail and set +.Va errno +for any of the errors specified for the library function +.Xr utimes 2 . +.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 . diff --git a/gen/utmpx-darwin.c b/gen/utmpx-darwin.c new file mode 100644 index 0000000..312f4e5 --- /dev/null +++ b/gen/utmpx-darwin.c @@ -0,0 +1,1172 @@ +/* + * Copyright (c) 2005 Apple Computer, 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@ + */ +#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 + +#ifdef UTMP_COMPAT +#include +#endif /* UTMP_COMPAT */ + +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 *); +static void utmpx2msg(const struct utmpx *, aslmsg); + +static mach_port_t asl_server_port = MACH_PORT_NULL; +static int pw_size = 0; + +#define ASL_SERVICE_NAME "com.apple.system.logger" +#define FACILITY "Facility" +#define WTMP_COUNT 32 + +/* ASL timeout in milliseconds */ +#define ASL_QUERY_TIMEOUT 4000 + +/* indirection causes argument to be substituted before stringification */ +#define STR(x) __STRING(x) + +static char * +_pwnam_r(const char *user, struct passwd *pw) +{ + struct passwd *p; + char *buf; + + if (pw_size <= 0) { + pw_size = sysconf(_SC_GETPW_R_SIZE_MAX); + if (pw_size <= 0) + return NULL; + } + if ((buf = malloc(pw_size)) == NULL) + return NULL; + + getpwnam_r(user, pw, buf, pw_size, &p); + if (!p) { + free(buf); + return NULL; + } + return buf; +} + +static char * +_pwuid_r(uid_t uid, struct passwd *pw) +{ + struct passwd *p; + char *buf; + + if (pw_size <= 0) { + pw_size = sysconf(_SC_GETPW_R_SIZE_MAX); + if (pw_size <= 0) + return NULL; + } + if ((buf = malloc(pw_size)) == NULL) + return NULL; + + getpwuid_r(uid, pw, buf, pw_size, &p); + if (!p) { + free(buf); + return NULL; + } + return buf; +} + +struct lastlogx * +getlastlogx(uid_t uid, struct lastlogx *lx) +{ + char *buf; + struct passwd pw; + struct lastlogx *l; + + if ((buf = _pwuid_r(uid, &pw)) == NULL) + return NULL; + + l = getlastlogxbyname(pw.pw_name, lx); + free(buf); + return l; +} + +struct lastlogx * +getlastlogxbyname(const char *user, struct lastlogx *lx) +{ + aslmsg q; + asl_msg_t *m[1]; + asl_search_result_t s, *l; + char *qstr, *res; + uint32_t len, reslen, status; + uint64_t cmax; + security_token_t sec; + caddr_t vmstr; + struct lastlogx *result = NULL; + mach_port_t port; + + if (!user || !*user) + return NULL; + + if (bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &port) != KERN_SUCCESS) + return NULL; + + /* + * We search for the last LASTLOG_FACILITY entry that has the + * ut_user entry matching the user's name. + */ + if ((q = asl_new(ASL_TYPE_QUERY)) == NULL) + goto out; + asl_set_query(q, FACILITY, LASTLOG_FACILITY, ASL_QUERY_OP_EQUAL); + asl_set_query(q, "ut_user", user, ASL_QUERY_OP_EQUAL); + m[0] = q; + s.count = 1; + s.msg = m; + + len = 0; + qstr = asl_list_to_string(&s, &len); + asl_free(q); + + if (qstr == NULL) + goto out; + + /* the server frees this memory */ + if (vm_allocate(mach_task_self(), (vm_address_t *)&vmstr, len, TRUE) != KERN_SUCCESS) { + free(qstr); + goto out; + } + + strcpy(vmstr, qstr); + free(qstr); + + res = NULL; + reslen = 0; + cmax = 0; + sec.val[0] = -1; + sec.val[1] = -1; + status = 0; + + _asl_server_query_timeout(port, vmstr, len, -1, 1, 1, ASL_QUERY_TIMEOUT, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec); + + if (res == NULL) + goto out; + l = asl_list_from_string(res); + vm_deallocate(mach_task_self(), (vm_address_t)res, reslen); + q = aslresponse_next(l); + if (q == NULL) { + aslresponse_free(l); + goto out; + } + + if (lx == NULL) { + if ((lx = (struct lastlogx *)malloc(sizeof(*lx))) == NULL) { + aslresponse_free(l); + goto out; + } + } + msg2lastlogx(q, lx); + aslresponse_free(l); + result = lx; +out: + mach_port_deallocate(mach_task_self(), port); + return result; +} + +#define IGET(e,p) if ((cp = asl_get(m, __STRING(ut_##e))) != NULL) \ + u->p##_##e = strtol(cp, NULL, 10); +#define LGET(e,p) IGET(e,p) +#define SGET(e,p) if ((cp = asl_get(m, __STRING(ut_##e))) != NULL) \ + strncpy(u->p##_##e, cp, sizeof(u->p##_##e)) + +/* fill in a struct lastlogx from a aslmsg */ +static void +msg2lastlogx(const aslmsg m, struct lastlogx *u) +{ + const char *cp; + + bzero(u, sizeof(*u)); + SGET(line, ll); + LGET(tv.tv_sec, ll); + IGET(tv.tv_usec, ll); + SGET(host, ll); +} + +/* fill in a struct utmpx from a aslmsg */ +static void +msg2utmpx(const aslmsg m, struct utmpx *u) +{ + const char *cp; + + bzero(u, sizeof(*u)); + SGET(user, ut); + SGET(id, ut); + SGET(line, ut); + IGET(pid, ut); + IGET(type, ut); + LGET(tv.tv_sec, ut); + IGET(tv.tv_usec, ut); + SGET(host, ut); +} + +/* fill in a aslmsg from a struct utmpx */ +static void +utmpx2msg(const struct utmpx *u, aslmsg m) +{ + char buf[_UTX_HOSTSIZE + 1]; /* the largest string in struct utmpx */ + 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); \ + asl_set(m, #e, buf); } +#define SSET(e) if (*(u->e)) { \ + strncpy(buf, u->e, sizeof(u->e)); \ + buf[sizeof(u->e)] = 0; \ + asl_set(m, #e, buf); \ + } + + SSET(ut_user); + cp = u->ut_id + sizeof(u->ut_id); + while(--cp >= u->ut_id && isprint(*cp)) {} + if(cp < u->ut_id) { + SSET(ut_id); + } else { + snprintf(buf, sizeof(buf), "0x%02x 0x%02x 0x%02x 0x%02x", + (unsigned)u->ut_id[0], (unsigned)u->ut_id[1], + (unsigned)u->ut_id[2], (unsigned)u->ut_id[3]); + asl_set(m, "ut_id", buf); + } + SSET(ut_line); + if (u->ut_pid > 0) + ISET(ut_pid); + ISET(ut_type); + LSET(ut_tv.tv_sec); + ISET(ut_tv.tv_usec); + SSET(ut_host); +} + +static const char *utmpx_types[] = { + "EMPTY", /* 0 */ + "RUN_LVL", /* 1 */ + "BOOT_TIME", /* 2 */ + "OLD_TIME", /* 3 */ + "NEW_TIME", /* 4 */ + "INIT_PROCESS", /* 5 */ + "LOGIN_PROCESS", /* 6 */ + "USER_PROCESS", /* 7 */ + "DEAD_PROCESS", /* 8 */ + "ACCOUNTING", /* 9 */ + "SIGNATURE", /* 10 */ + "SHUTDOWN_TIME", /* 11 */ +}; + +/* send a struct utmpx record using asl */ +__private_extern__ void +_utmpx_asl(const struct utmpx *u) +{ + aslclient asl = asl_open(NULL, NULL, ASL_OPT_NO_REMOTE); /* could be NULL, but still works */ + aslmsg m; + char msg[64]; + + if (u->ut_type == EMPTY) + return; + if ((m = asl_new(ASL_TYPE_MSG)) == NULL) { + asl_close(asl); + return; + } + /* + * If the ut_type is USER_PROCESS, we use the LASTLOG_FACILITY, + * otherwise we use the UTMPX_FACILITY. This makes it easy to + * search for lastlog entries, but for wtmp, we have to search + * for both facilities. + */ + if (u->ut_type == USER_PROCESS) + asl_set(m, FACILITY, LASTLOG_FACILITY); + else + asl_set(m, FACILITY, UTMPX_FACILITY); + asl_set(m, ASL_KEY_LEVEL, STR(ASL_LEVEL_NOTICE)); + utmpx2msg(u, m); + + /* Make a visible message for system.log */ + switch (u->ut_type) { + case BOOT_TIME: + case OLD_TIME: + case NEW_TIME: + case SHUTDOWN_TIME: + sprintf(msg, "%s: %ld %d", utmpx_types[u->ut_type], u->ut_tv.tv_sec, u->ut_tv.tv_usec); + break; + case INIT_PROCESS: + case LOGIN_PROCESS: + sprintf(msg, "%s: %d", utmpx_types[u->ut_type], (int)u->ut_pid); + break; + case USER_PROCESS: + case DEAD_PROCESS: + sprintf(msg, "%s: %d %.*s", utmpx_types[u->ut_type], (int)u->ut_pid, (int)sizeof(u->ut_line), u->ut_line); + break; + default: + if (u->ut_type >= 0 && u->ut_type < (sizeof(utmpx_types) / sizeof(*utmpx_types))) + sprintf(msg, "%s", utmpx_types[u->ut_type]); + else + sprintf(msg, "ut_type=%d", (int)u->ut_type); + break; + } + asl_set(m, ASL_KEY_MSG, msg); + asl_send(asl, m); + asl_free(m); + if (asl) + asl_close(asl); +} + +#define UT_USER (1 << 0) +#define UT_ID (1 << 1) +#define UT_LINE (1 << 2) +#define UT_PID (1 << 3) +#define UT_TV (1 << 4) + +__private_extern__ const struct utmpx * +_utmpx_working_copy(const struct utmpx *utx, struct utmpx *temp, int onlyid) +{ + int which; + static char idzero[_UTX_IDSIZE]; + + if ((utx->ut_type & (UTMPX_AUTOFILL_MASK | UTMPX_DEAD_IF_CORRESPONDING_MASK)) == 0) + return utx; + memcpy(temp, utx, sizeof(*temp)); + temp->ut_type &= ~(UTMPX_AUTOFILL_MASK | UTMPX_DEAD_IF_CORRESPONDING_MASK); + + if ((utx->ut_type & UTMPX_AUTOFILL_MASK) == 0) + return temp; + + which = UT_TV; /* they all need time */ + switch(temp->ut_type) { + case EMPTY: + return temp; + case USER_PROCESS: + which |= (UT_USER | UT_LINE | UT_PID); + /* Set UT_ID if ut_id isn't there */ + if (memcmp(temp->ut_id, idzero, sizeof(temp->ut_id)) == 0) + which |= UT_ID; + break; + case INIT_PROCESS: + which |= UT_PID; + break; + case LOGIN_PROCESS: + which |= (UT_USER | UT_PID); + break; + case DEAD_PROCESS: + which |= UT_PID; + /* Set UT_ID if ut_id isn't there. We will also need UT_LINE */ + if (memcmp(temp->ut_id, idzero, sizeof(temp->ut_id)) == 0) + which |= (UT_ID | UT_LINE); + break; + } + /* + * If onlyid is set: if ut_id isn't set but is needed, then set + * which to (UT_LINE | UT_ID), otherwise zero + */ + if (onlyid) + which = (which & UT_ID) ? (UT_LINE | UT_ID) : 0; + if ((which & UT_LINE) && !*temp->ut_line) { + char buf[256]; + char *cp; +#if __DARWIN_UNIX03 + int err; + + err = ttyname_r(0, buf, sizeof(buf)); + if (err) + err = ttyname_r(1, buf, sizeof(buf)); + if (err) + err = ttyname_r(2, buf, sizeof(buf)); + if (err) + return NULL; +#else /* !__DARWIN_UNIX03 */ + cp = ttyname_r(0, buf, sizeof(buf)); + if (!cp) + cp = ttyname_r(1, buf, sizeof(buf)); + if (!cp) + cp = ttyname_r(2, buf, sizeof(buf)); + if (!cp) + return NULL; +#endif /* __DARWIN_UNIX03 */ + cp = strrchr(buf, '/'); + if (cp) + cp++; + else + cp = buf; + strncpy(temp->ut_line, cp, sizeof(temp->ut_line)); + } + /* UT_ID is set only if we already know we need to add it */ + if ((which & UT_ID)) { + char *cp; + int i = sizeof(temp->ut_line); + + for(cp = temp->ut_line; i > 0 && *cp; i--) + cp++; + i = cp - temp->ut_line; + if(i >= sizeof(temp->ut_id)) + memcpy(temp->ut_id, cp - sizeof(temp->ut_id), sizeof(temp->ut_id)); + else + memcpy(temp->ut_id, temp->ut_line, i); + } + if ((which & UT_PID) && !temp->ut_pid) + temp->ut_pid = getpid(); + if ((which & UT_USER) && !*temp->ut_user) { + char *buf; + struct passwd pw; + + if ((buf = _pwuid_r(getuid(), &pw)) == NULL) + return NULL; + strncpy(temp->ut_user, pw.pw_name, sizeof(temp->ut_user)); + free(buf); + } + if ((which & UT_TV) && !temp->ut_tv.tv_sec && !temp->ut_tv.tv_usec) + gettimeofday(&temp->ut_tv, NULL); + return temp; +} + +/* + * We can read from either asl or from a file, so we need to switch between + * the two. + */ +static void end_asl(void); +static void end_file(void); +static struct utmpx *get_asl(void); +static struct utmpx *get_file(void); +static void set_asl(int); +static void set_file(int); + +enum {WTMP_ASL, WTMP_FILE}; + +static struct { + int which; + void (*end)(void); + struct utmpx *(*get)(void); + void (*set)(int); +} wtmp_func = { + WTMP_ASL, + end_asl, + get_asl, + set_asl +}; +static struct { + uint64_t start; + int dir; + asl_search_result_t *res; + char *str; + uint32_t len; + char inited; + char done; +} wtmp_asl = {-1, 1}; +static struct { + int fd; + int dir; + char file[MAXPATHLEN]; + off_t off; + size_t count; +#ifdef __LP64__ + struct utmpx32 *buf; + struct utmpx32 *next; +#else /* __LP64__ */ + struct utmpx *buf; + struct utmpx *next; +#endif /* __LP64__ */ + int left; +} wtmp_file = {-1, -1}; + +void +endutxent_wtmp(void) +{ + wtmp_func.end(); +} + +struct utmpx * +getutxent_wtmp(void) +{ + return wtmp_func.get(); +} + +void +setutxent_wtmp(int dir) +{ + wtmp_func.set(dir); +} + +/* use the given file, or if NULL, read from asl */ +int +wtmpxname(const char *fname) +{ + size_t len; + + if (fname == NULL) { + if (wtmp_func.which == WTMP_ASL) { + end_asl(); + return 1; + } + end_file(); + wtmp_func.which = WTMP_ASL; + wtmp_func.end = end_asl; + wtmp_func.get = get_asl; + wtmp_func.set = set_asl; + return 1; + } + + len = strlen(fname); + if (len >= sizeof(wtmp_file.file)) + 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; + } + wtmp_func.which = WTMP_FILE; + wtmp_func.end = end_file; + wtmp_func.get = get_file; + wtmp_func.set = set_file; + return 1; +} + +static void +end_asl(void) +{ + if (wtmp_asl.res) { + aslresponse_free(wtmp_asl.res); + wtmp_asl.res = NULL; + } + wtmp_asl.inited = 0; + wtmp_asl.done = 0; + if (asl_server_port != MACH_PORT_NULL) { + mach_port_deallocate(mach_task_self(), asl_server_port); + asl_server_port = MACH_PORT_NULL; + } +} + +static void +end_file(void) +{ + if (wtmp_file.fd >= 0) { + close(wtmp_file.fd); + wtmp_file.fd = -1; + } + if (wtmp_file.buf) { + free(wtmp_file.buf); + wtmp_file.buf = NULL; + } +} + +static struct utmpx * +get_asl(void) +{ + aslmsg q; + char *res; + uint32_t reslen, status; + security_token_t sec; + caddr_t vmstr; + static struct utmpx utx; + +get_asl_repeat: + if (wtmp_asl.res) { + if ((q = aslresponse_next(wtmp_asl.res)) != NULL) { + msg2utmpx(q, &utx); + return &utx; + } + aslresponse_free(wtmp_asl.res); + wtmp_asl.res = NULL; + } else if (!wtmp_asl.inited) { + set_asl(-1); + if (!wtmp_asl.inited) + return NULL; + } + + if (wtmp_asl.done) + return NULL; + + if (asl_server_port == MACH_PORT_NULL) { + if (bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &asl_server_port) != KERN_SUCCESS) { +get_asl_done: + wtmp_asl.done = 1; + return NULL; + } + } + + /* the server frees this memory */ + if (vm_allocate(mach_task_self(), (vm_address_t *)&vmstr, wtmp_asl.len, TRUE) != KERN_SUCCESS) + goto get_asl_done; + + /* the search string is defined in set_asl */ + strcpy(vmstr, wtmp_asl.str); + + res = NULL; + reslen = 0; + sec.val[0] = -1; + sec.val[1] = -1; + status = 0; + + _asl_server_query_timeout(asl_server_port, vmstr, wtmp_asl.len, wtmp_asl.start, WTMP_COUNT, wtmp_asl.dir, ASL_QUERY_TIMEOUT, (caddr_t *)&res, &reslen, &wtmp_asl.start, (int *)&status, &sec); + + if (res == NULL) + goto get_asl_done; + wtmp_asl.res = asl_list_from_string(res); + vm_deallocate(mach_task_self(), (vm_address_t)res, reslen); + if(!wtmp_asl.res) + goto get_asl_done; + goto get_asl_repeat; +} + +static struct utmpx * +get_file(void) +{ + int n, r; + char *cp; +#ifdef __LP64__ + static struct utmpx ux; +#endif /* __LP64__ */ + +get_file_repeat: + if (wtmp_file.left > 0) { +#ifdef __LP64__ + struct utmpx32 *u = wtmp_file.next; +#else /* __LP64__ */ + struct utmpx *u = wtmp_file.next; +#endif /* __LP64__ */ + wtmp_file.next += wtmp_file.dir; + wtmp_file.left--; +#ifdef __LP64__ + _utmpx32_64(u, &ux); + return &ux; +#else /* __LP64__ */ + return u; +#endif /* __LP64__ */ + } else if (wtmp_file.fd < 0) { + set_file(-1); /* keep current read direction */ + if (wtmp_file.fd < 0) + return NULL; + goto get_file_repeat; + } + if (wtmp_file.count <= 0) + return NULL; + +#ifdef __LP64__ + n = WTMP_COUNT * sizeof(struct utmpx32); +#else /* __LP64__ */ + n = WTMP_COUNT * sizeof(struct utmpx); +#endif /* __LP64__ */ + if (wtmp_file.dir > 0) + wtmp_file.next = wtmp_file.buf; + else { + wtmp_file.next = wtmp_file.buf + WTMP_COUNT - 1; + wtmp_file.off -= n; + if (lseek(wtmp_file.fd, wtmp_file.off, SEEK_SET) < 0) { +get_file_done: + wtmp_file.count = 0; + return NULL; + } + } + + cp = (char *)wtmp_file.buf; + do { + if((r = read(wtmp_file.fd, cp, n)) <= 0) { + if (r < 0 && (errno == EINTR || errno == EAGAIN)) + continue; + goto get_file_done; + } + cp += r; + } while((n -= r) > 0); + + wtmp_file.left = WTMP_COUNT; + wtmp_file.count -= WTMP_COUNT; + + goto get_file_repeat; +} + +/* + * This sets the directions for both asl and reading from a file. If forward + * is negative, skip. + */ +static void +_set_dir(int forward) +{ + if (forward < 0) + return; + if (forward) { + wtmp_asl.dir = 0; + wtmp_asl.start = 0; + wtmp_file.dir = 1; + } else { + wtmp_asl.dir = 1; + wtmp_asl.start = -1; + wtmp_file.dir = -1; + } +} + +static void +set_asl(int forward) +{ + _set_dir(forward); + if (!wtmp_asl.str) { + aslmsg q0, q1; + asl_msg_t *m[2]; + asl_search_result_t s; + + /* + * Create a search string that matches either UTMPX_FACILITY + * or LASTLOG_FACILITY. + */ + if ((q0 = asl_new(ASL_TYPE_QUERY)) == NULL) + return; + if ((q1 = asl_new(ASL_TYPE_QUERY)) == NULL) { + asl_free(q0); + return; + } + 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; + s.count = 2; + s.msg = m; + + wtmp_asl.len = 0; + wtmp_asl.str = asl_list_to_string(&s, &wtmp_asl.len); + asl_free(q1); + asl_free(q0); + if(!wtmp_asl.str) + return; + } + if (wtmp_asl.res) { + aslresponse_free(wtmp_asl.res); + wtmp_asl.res = NULL; + } + wtmp_asl.inited = 1; + wtmp_asl.done = 0; +} + +static void +set_file(int forward) +{ + struct stat s; + size_t c; + int n, r; + char *cp; + + _set_dir(forward); +#ifdef __LP64__ + if (wtmp_file.buf == NULL && + (wtmp_file.buf = (struct utmpx32 *)malloc(WTMP_COUNT * sizeof(struct utmpx32))) == NULL) +#else /* __LP64__ */ + if (wtmp_file.buf == NULL && + (wtmp_file.buf = (struct utmpx *)malloc(WTMP_COUNT * sizeof(struct utmpx))) == NULL) +#endif /* __LP64__ */ + return; + if (wtmp_file.fd >= 0) + close(wtmp_file.fd); + if ((wtmp_file.fd = open(wtmp_file.file, O_RDONLY, 0)) < 0) + return; + if (fstat(wtmp_file.fd, &s) < 0) + goto set_file_error; + /* + * We must have a file at least 2 sizeof(struct utmpx) in size, + * with the first struct utmpx matching a signature record. + */ +#ifdef __LP64__ + if ((wtmp_file.count = s.st_size / sizeof(struct utmpx32)) <= 1) +#else /* __LP64__ */ + if ((wtmp_file.count = s.st_size / sizeof(struct utmpx)) <= 1) +#endif /* __LP64__ */ + goto set_file_error; +#ifdef __LP64__ + if (read(wtmp_file.fd, wtmp_file.buf, sizeof(struct utmpx32)) != sizeof(struct utmpx32)) +#else /* __LP64__ */ + if (read(wtmp_file.fd, wtmp_file.buf, sizeof(struct utmpx)) != sizeof(struct utmpx)) +#endif /* __LP64__ */ + goto set_file_error; + if (strcmp(wtmp_file.buf->ut_user, _utmpx_vers) != 0 || + wtmp_file.buf->ut_type != SIGNATURE) + goto set_file_error; + wtmp_file.count--; + + /* + * We will first read any records modulo WTMP_COUNT (or WTMP_COUNT), + * either at the beginning or the end, so that all subsequent reads + * must contain WTMP_COUNT records. + */ + c = WTMP_COUNT * ((wtmp_file.count - 1) / WTMP_COUNT); + wtmp_file.left = wtmp_file.count - c; + wtmp_file.count -= wtmp_file.left; + + /* Seek to the end for reverse reading */ + if (wtmp_file.dir < 0) { +#ifdef __LP64__ + wtmp_file.off = (c + 1) * sizeof(struct utmpx32); +#else /* __LP64__ */ + wtmp_file.off = (c + 1) * sizeof(struct utmpx); +#endif /* __LP64__ */ + if (lseek(wtmp_file.fd, wtmp_file.off, SEEK_SET) < 0) + goto set_file_error; + } +#ifdef __LP64__ + n = wtmp_file.left * sizeof(struct utmpx32); +#else /* __LP64__ */ + n = wtmp_file.left * sizeof(struct utmpx); +#endif /* __LP64__ */ + cp = (char *)wtmp_file.buf; + do { + if((r = read(wtmp_file.fd, cp, n)) <= 0) { + if (r < 0 && (errno == EINTR || errno == EAGAIN)) + continue; + goto set_file_error; + } + cp += r; + } while((n -= r) > 0); + + /* Point to either the beginning or end of the buffer */ + if(wtmp_file.dir > 0) + wtmp_file.next = wtmp_file.buf; + else + wtmp_file.next = wtmp_file.buf + wtmp_file.left - 1; + return; + +set_file_error: + wtmp_file.left = 0; + close(wtmp_file.fd); + wtmp_file.fd = -1; + return; +} + +#ifdef __LP64__ +/* + * these routines assume natural alignment so that struct utmpx32 has + * the same size and layout as the 32-bit struct utmpx + */ +__private_extern__ void +_utmpx32_64(const struct utmpx32 *u32, struct utmpx *u) +{ + bzero(u, sizeof(*u)); + memcpy(u, u32, offsetof(struct utmpx, ut_type) + sizeof(u->ut_type)); + u->ut_tv.tv_sec = u32->ut_tv.tv_sec; + u->ut_tv.tv_usec = u32->ut_tv.tv_usec; + memcpy((char *)u + offsetof(struct utmpx, ut_host), + (char *)u32 + offsetof(struct utmpx32, ut_host), + sizeof(struct utmpx) - offsetof(struct utmpx, ut_host)); +} + +__private_extern__ void +_utmpx64_32(const struct utmpx *u, struct utmpx32 *u32) +{ + bzero(u32, sizeof(*u32)); + memcpy(u32, u, offsetof(struct utmpx32, ut_type) + sizeof(u32->ut_type)); + u32->ut_tv.tv_sec = u->ut_tv.tv_sec; + u32->ut_tv.tv_usec = u->ut_tv.tv_usec; + memcpy((char *)u32 + offsetof(struct utmpx32, ut_host), + (char *)u + offsetof(struct utmpx, ut_host), + sizeof(struct utmpx32) - offsetof(struct utmpx32, ut_host)); +} +#endif /* __LP64__ */ + +#ifdef UTMP_COMPAT +#ifdef __LP64__ +__private_extern__ void +_getutmp32(const struct utmpx *ux, struct utmp32 *u) +{ + + bzero(u, sizeof(*u)); + (void)memcpy(u->ut_name, ux->ut_user, sizeof(u->ut_name)); + (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; +} +#endif /* __LP64__ */ + +/* + * _utmp_compat converts a struct utmpx to a struct utmp, using the conventions + * described in utmp(5). It then returns a value that specifies what + * combination of utmp, wtmp and lastlog to write. UTMP_COMPAT_UTMP1 will + * write utmp only if a matching record with the same ut_line value is found; + * UTMP_COMPAT_UTMP0 replaces an existing record or writes a new one. + */ +__private_extern__ int +#ifdef __LP64__ +_utmp_compat(const struct utmpx *ux, struct utmp32 *u) +#else /* __LP64__ */ +_utmp_compat(const struct utmpx *ux, struct utmp *u) +#endif /* __LP64__ */ +{ +#ifdef __LP64__ + _getutmp32(ux, u); +#else /* __LP64__ */ + getutmp(ux, u); +#endif /* __LP64__ */ + + switch (ux->ut_type) { + case BOOT_TIME: + case SHUTDOWN_TIME: + bzero(u->ut_line, sizeof(u->ut_line)); + u->ut_line[0] = '~'; + bzero(u->ut_name, sizeof(u->ut_name)); + strcpy(u->ut_name, (ux->ut_type == BOOT_TIME ? "reboot" : "shutdown")); + return UTMP_COMPAT_WTMP; + case OLD_TIME: + case NEW_TIME: + bzero(u->ut_line, sizeof(u->ut_line)); + u->ut_line[0] = (ux->ut_type == OLD_TIME ? '|' : '{'); + bzero(u->ut_name, sizeof(u->ut_name)); + strcpy(u->ut_name, "date"); + return UTMP_COMPAT_WTMP; + case USER_PROCESS: + return UTMP_COMPAT_UTMP0 | UTMP_COMPAT_WTMP | UTMP_COMPAT_LASTLOG; + case DEAD_PROCESS: + bzero(u->ut_name, sizeof(u->ut_name)); + bzero(u->ut_host, sizeof(u->ut_host)); + return UTMP_COMPAT_UTMP1 | UTMP_COMPAT_WTMP; + } + return 0; /* skip */; +} + +/* + * Write _PATH_LASTLOG given a struct utmp record. We use + * advisory record locking. + */ +__private_extern__ void +#ifdef __LP64__ +_write_lastlog(const struct utmp32 *u, const struct utmpx *ux) +#else /* __LP64__ */ +_write_lastlog(const struct utmp *u, const struct utmpx *ux) +#endif /* __LP64__ */ +{ + int fd; +#ifdef __LP64__ + struct lastlog32 l; +#else /* __LP64__ */ + struct lastlog l; +#endif /* __LP64__ */ + struct flock lock; + struct passwd pw; + // sizeof(ux->ut_user) > sizeof(u->ut_name) + char name[sizeof(ux->ut_user) + 1]; + char *buf; + off_t off; + int retry = 10; + + if (ux) { + if(!*ux->ut_user) + return; + strncpy(name, ux->ut_user, sizeof(ux->ut_user)); + name[sizeof(ux->ut_user)] = 0; + } else { + if (!*u->ut_name) + return; + strncpy(name, u->ut_name, sizeof(u->ut_name)); + name[sizeof(u->ut_name)] = 0; + } + if ((buf = _pwnam_r(name, &pw)) == NULL) + return; +#ifdef __LP64__ + off = (off_t)pw.pw_uid * sizeof(struct lastlog32); +#else /* __LP64__ */ + off = (off_t)pw.pw_uid * sizeof(struct lastlog); +#endif /* __LP64__ */ + free(buf); + + if ((fd = open(_PATH_LASTLOG, O_WRONLY, 0)) < 0) + return; + (void)lseek(fd, off, SEEK_SET); + bzero(&lock, sizeof(lock)); + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = off; +#ifdef __LP64__ + lock.l_len = sizeof(struct lastlog32); +#else /* __LP64__ */ + lock.l_len = sizeof(struct lastlog); +#endif /* __LP64__ */ + /* try to lock, but give up after retry times, and write anyways */ + while(retry-- > 0) { + if (fcntl(fd, F_SETLK, &lock) == 0) + break; + usleep(10000); + } + l.ll_time = u->ut_time; + strncpy(l.ll_line, u->ut_line, sizeof(l.ll_line)); + strncpy(l.ll_host, u->ut_host, sizeof(l.ll_host)); + (void) write(fd, &l, sizeof(l)); + lock.l_type = F_UNLCK; + (void) fcntl(fd, F_SETLK, &lock); + (void) close(fd); +} + +/* + * Write _PATH_UTMP, given a struct utmp, depending on the value of + * "mustexist". + */ +__private_extern__ void +#ifdef __LP64__ +_write_utmp(const struct utmp32 *u, int mustexist) +#else /* __LP64__ */ +_write_utmp(const struct utmp *u, int mustexist) +#endif /* __LP64__ */ +{ + int fd, slot; + struct ttyent *ttyp; +#ifdef __LP64__ + struct utmp32 tmp; +#else /* __LP64__ */ + struct utmp tmp; +#endif /* __LP64__ */ + int found = 0; + static struct { + char line[sizeof(u->ut_line)]; + int slot; + } cache; + + if ((fd = open(_PATH_UTMP, O_RDWR, 0)) < 0) + return; + + if (!strncmp(cache.line, u->ut_line, sizeof(u->ut_line))) { + slot = cache.slot; + found++; + } + /* do equivalent of ttyslot(), but using u->ut_line */ + if (!found) { + setttyent(); + slot = 1; + for(;;) { + if ((ttyp = getttyent()) == NULL) + break; + if (!strncmp(ttyp->ty_name, u->ut_line, sizeof(u->ut_line))) { + strncpy(cache.line, u->ut_line, sizeof(u->ut_line)); + cache.slot = slot; + found++; + break; + } + slot++; + } + endttyent(); + } + + if (!found) { /* no assigned slot */ +#ifdef __LP64__ + (void)lseek(fd, (off_t)slot * sizeof(struct utmp32), SEEK_SET); +#else /* __LP64__ */ + (void)lseek(fd, (off_t)slot * sizeof(struct utmp), SEEK_SET); +#endif /* __LP64__ */ + for(;;) { + if (read(fd, &tmp, sizeof(tmp)) != sizeof(tmp)) + break; + if (!strncmp(tmp.ut_line, u->ut_line, sizeof(u->ut_line))) { + strncpy(cache.line, u->ut_line, sizeof(u->ut_line)); + cache.slot = slot; + found++; + break; + } + slot++; + } + } + + if (!found && mustexist) { + (void)close(fd); + return; + } +#ifdef __LP64__ + (void)lseek(fd, (off_t)slot * sizeof(struct utmp32), SEEK_SET); + (void)write(fd, u, sizeof(struct utmp32)); +#else /* __LP64__ */ + (void)lseek(fd, (off_t)slot * sizeof(struct utmp), SEEK_SET); + (void)write(fd, u, sizeof(struct utmp)); +#endif /* __LP64__ */ + (void)close(fd); +} + +/* + * Write all the necessary files (utmp, wtmp, lastlog), depending on the + * given struct utmpx. + */ +__private_extern__ void +_write_utmp_compat(const struct utmpx *ux) +{ +#ifdef __LP64__ + struct utmp32 u; +#else /* __LP64__ */ + struct utmp u; +#endif /* __LP64__ */ + int which; + + which = _utmp_compat(ux, &u); + if (which & UTMP_COMPAT_UTMP0) + _write_utmp(&u, 0); + else if (which & UTMP_COMPAT_UTMP1) + _write_utmp(&u, 1); + if (which & UTMP_COMPAT_WTMP) + _write_wtmp(&u); + if (which & UTMP_COMPAT_LASTLOG) + _write_lastlog(&u, ux); +} + +/* Append a struct wtmp to _PATH_WTMP */ +__private_extern__ void +#ifdef __LP64__ +_write_wtmp(const struct utmp32 *u) +#else /* __LP64__ */ +_write_wtmp(const struct utmp *u) +#endif /* __LP64__ */ +{ + int fd; + struct stat buf; + + if ((fd = open(_PATH_WTMP, O_WRONLY | O_APPEND, 0)) < 0) + return; + if (fstat(fd, &buf) == 0) { + if (write(fd, u, sizeof(*u)) != sizeof(*u)) + (void) ftruncate(fd, buf.st_size); + } + (void) close(fd); +} +#endif /* UTMP_COMPAT */ diff --git a/gen/utmpx-darwin.h b/gen/utmpx-darwin.h new file mode 100644 index 0000000..d4bc7e6 --- /dev/null +++ b/gen/utmpx-darwin.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2005 Apple Computer, 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@ + */ + +#ifdef UTMP_COMPAT +#define UTMP_COMPAT_UTMP0 0x01 +#define UTMP_COMPAT_UTMP1 0x02 +#define UTMP_COMPAT_WTMP 0x04 +#define UTMP_COMPAT_LASTLOG 0x08 +#endif /* UTMP_COMPAT */ + +#define LASTLOG_FACILITY "com.apple.system.lastlog" +#define UTMPX_FACILITY "com.apple.system.utmpx" + +extern int utfile_system; /* are we using _PATH_UTMPX? */ + +#ifdef __LP64__ +#define __need_struct_timeval32 +#include <_structs.h> + +/* + * these structures assume natural alignment so they are the same size + * and layout as their 32-bit counterpart + */ +#ifdef UTMP_COMPAT +struct lastlog32 { + __int32_t ll_time; + char ll_line[UT_LINESIZE]; + char ll_host[UT_HOSTSIZE]; +}; + +struct utmp32 { + char ut_line[UT_LINESIZE]; + char ut_name[UT_NAMESIZE]; + char ut_host[UT_HOSTSIZE]; + __int32_t ut_time; +}; +#endif /* UTMP_COMPAT */ + +struct utmpx32 { + char ut_user[_UTX_USERSIZE]; /* login name */ + char ut_id[_UTX_IDSIZE]; /* id */ + char ut_line[_UTX_LINESIZE]; /* tty name */ + pid_t ut_pid; /* process id creating the entry */ + short ut_type; /* type of this entry */ + struct timeval32 ut_tv; /* time entry was created */ + char ut_host[_UTX_HOSTSIZE]; /* host name */ + __uint32_t ut_pad[16]; /* reserved for future use */ +}; +#endif /* __LP64__ */ + +struct utmpx *_pututxline(const struct utmpx *); +#ifdef __LP64__ +void _utmpx32_64(const struct utmpx32 *, struct utmpx *); +void _utmpx64_32(const struct utmpx *, struct utmpx32 *); +#endif /* __LP64__ */ +void _utmpx_asl(const struct utmpx *); +const struct utmpx *_utmpx_working_copy(const struct utmpx *, struct utmpx *, int); + +#ifdef UTMP_COMPAT +#ifdef __LP64__ +void _getutmp32(const struct utmpx *, struct utmp32 *); +int _utmp_compat(const struct utmpx *, struct utmp32 *); +void _write_lastlog(const struct utmp32 *, const struct utmpx *); +void _write_utmp(const struct utmp32 *, int); +#else /* __LP64__ */ +int _utmp_compat(const struct utmpx *, struct utmp *); +void _write_lastlog(const struct utmp *, const struct utmpx *); +void _write_utmp(const struct utmp *, int); +#endif /* __LP64__ */ +void _write_utmp_compat(const struct utmpx *); +#ifdef __LP64__ +void _write_wtmp(const struct utmp32 *); +#else /* __LP64__ */ +void _write_wtmp(const struct utmp *); +#endif /* __LP64__ */ +#endif /* UTMP_COMPAT */ diff --git a/gen/utmpx-nbsd.c b/gen/utmpx-nbsd.c new file mode 100644 index 0000000..57a3426 --- /dev/null +++ b/gen/utmpx-nbsd.c @@ -0,0 +1,440 @@ +/* $NetBSD: utmpx.c,v 1.21 2003/09/06 16:42:10 wiz Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + */ +#include + +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: utmpx.c,v 1.21 2003/09/06 16:42:10 wiz Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#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? */ + +static struct utmpx *_getutxid(const struct utmpx *); + +__private_extern__ const char _utmpx_vers[] = "utmpx-1.00"; + +void +setutxent() +{ + + (void)memset(&ut, 0, sizeof(ut)); + if (fp == NULL) + return; +#ifdef __LP64__ + (void)fseeko(fp, (off_t)sizeof(struct utmpx32), SEEK_SET); +#else /* __LP64__ */ + (void)fseeko(fp, (off_t)sizeof(ut), SEEK_SET); +#endif /* __LP64__ */ +} + + +void +endutxent() +{ + + (void)memset(&ut, 0, sizeof(ut)); + if (fp != NULL) { + (void)fclose(fp); + fp = NULL; + readonly = 0; + } +} + + +struct utmpx * +getutxent() +{ +#ifdef __LP64__ + struct utmpx32 ut32; +#endif /* __LP64__ */ + + if (fp == NULL) { + struct stat st; + + if ((fp = fopen(utfile, "r+")) == NULL) + if ((fp = fopen(utfile, "w+")) == NULL) { + if ((fp = fopen(utfile, "r")) == NULL) + goto fail; + else + readonly = 1; + } + + + /* get file size in order to check if new file */ + if (fstat(fileno(fp), &st) == -1) + goto failclose; + + if (st.st_size == 0) { + /* new file, add signature record */ +#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) +#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) +#endif /* __LP64__ */ + goto failclose; + } else { + /* old file, read signature record */ +#ifdef __LP64__ + if (fread(&ut32, sizeof(ut32), 1, fp) != 1) +#else /* __LP64__ */ + if (fread(&ut, sizeof(ut), 1, 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) +#endif /* __LP64__ */ + goto failclose; + } + } + +#ifdef __LP64__ + if (fread(&ut32, sizeof(ut32), 1, fp) != 1) +#else /* __LP64__ */ + if (fread(&ut, sizeof(ut), 1, fp) != 1) +#endif /* __LP64__ */ + goto fail; + +#ifdef __LP64__ + _utmpx32_64(&ut32, &ut); +#endif /* __LP64__ */ + return &ut; +failclose: + (void)fclose(fp); + fp = NULL; +fail: + (void)memset(&ut, 0, sizeof(ut)); + return NULL; +} + +struct utmpx * +getutxid(const struct utmpx *utx) +{ + struct utmpx temp; + const struct utmpx *ux; + + _DIAGASSERT(utx != NULL); + + if (utx->ut_type == EMPTY) + return NULL; + + /* make a copy as needed, and auto-fill if requested */ + ux = _utmpx_working_copy(utx, &temp, 1); + if (!ux) + return NULL; + + return _getutxid(ux); +} + + +static struct utmpx * +_getutxid(const struct utmpx *utx) +{ + + do { + if (ut.ut_type == EMPTY) + continue; + switch (utx->ut_type) { + case EMPTY: + return NULL; + case RUN_LVL: + case BOOT_TIME: + case OLD_TIME: + case NEW_TIME: + if (ut.ut_type == utx->ut_type) + return &ut; + break; + case INIT_PROCESS: + case LOGIN_PROCESS: + case USER_PROCESS: + case DEAD_PROCESS: + switch (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; + break; + default: + break; + } + break; + default: + return NULL; + } + } while (getutxent() != NULL); + return NULL; +} + + +struct utmpx * +getutxline(const struct utmpx *utx) +{ + + _DIAGASSERT(utx != NULL); + + do { + switch (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) + return &ut; + break; + default: + break; + } + } while (getutxent() != NULL); + return NULL; +} + + +struct utmpx * +pututxline(const struct utmpx *utx) +{ + struct utmpx *ux; + + _DIAGASSERT(utx != NULL); + + if (utx == NULL) { + errno = EINVAL; + return NULL; + } + + if ((ux = _pututxline(utx)) != NULL && utfile_system) { + _utmpx_asl(ux); /* the equivalent of wtmpx and lastlogx */ +#ifdef UTMP_COMPAT + _write_utmp_compat(ux); +#endif /* UTMP_COMPAT */ + } + return ux; +} + +__private_extern__ struct utmpx * +_pututxline(const struct utmpx *utx) +{ + struct utmpx temp, *u = NULL, *x; + const struct utmpx *ux; +#ifdef __LP64__ + struct utmpx32 ut32; +#endif /* __LP64__ */ + int gotlock = 0; + + if (utfile_system) + if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) { + errno = EPERM; + return NULL; + } + + if (fp == NULL) { + (void)getutxent(); + if (fp == NULL || readonly) { + errno = EPERM; + return NULL; + } + } + + /* make a copy as needed, and auto-fill if requested */ + ux = _utmpx_working_copy(utx, &temp, 0); + if (!ux) + return NULL; + + if ((x = _getutxid(ux)) == NULL) { + setutxent(); + if ((x = _getutxid(ux)) == NULL) { + /* + * utx->ut_type has any original mask bits, while + * ux->ut_type has those mask bits removed. If we + * are trying to record a dead process, and + * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, then since + * there is no matching entry, we return NULL. + */ + if (ux->ut_type == DEAD_PROCESS && + (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK)) { + errno = EINVAL; + return NULL; + } + if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1) + return NULL; + gotlock++; + if (fseeko(fp, (off_t)0, SEEK_END) == -1) + goto fail; + } + } + + if (!gotlock) { + /* + * utx->ut_type has any original mask bits, while + * ux->ut_type has those mask bits removed. If we + * are trying to record a dead process, if + * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, but the found + * entry is not a (matching) USER_PROCESS, then return NULL. + */ + if (ux->ut_type == DEAD_PROCESS && + (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK) && + x->ut_type != USER_PROCESS) { + errno = EINVAL; + return NULL; + } + /* we are not appending */ +#ifdef __LP64__ + if (fseeko(fp, -(off_t)sizeof(ut32), SEEK_CUR) == -1) +#else /* __LP64__ */ + if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1) +#endif /* __LP64__ */ + return NULL; + } + +#ifdef __LP64__ + _utmpx64_32(ux, &ut32); + if (fwrite(&ut32, sizeof (ut32), 1, fp) != 1) +#else /* __LP64__ */ + if (fwrite(ux, sizeof (*ux), 1, fp) != 1) +#endif /* __LP64__ */ + goto fail; + + if (fflush(fp) == -1) + goto fail; + + u = memcpy(&ut, ux, sizeof(ut)); + notify_post(UTMPX_CHANGE_NOTIFICATION); +fail: + if (gotlock) { + int save = errno; + if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1) + return NULL; + errno = save; + } + return u; +} + + +/* + * The following are extensions and not part of the X/Open spec. + */ +int +utmpxname(const char *fname) +{ + size_t len; + + if (fname == NULL) { + strcpy(utfile, _PATH_UTMPX); + utfile_system = 1; + endutxent(); + return 1; + } + + len = strlen(fname); + + if (len >= sizeof(utfile)) + return 0; + + /* must end in x! */ + if (fname[len - 1] != 'x') + return 0; + + (void)strlcpy(utfile, fname, sizeof(utfile)); + endutxent(); + utfile_system = 0; + return 1; +} + + +void +getutmp(const struct utmpx *ux, struct utmp *u) +{ + + bzero(u, sizeof(*u)); + (void)memcpy(u->ut_name, ux->ut_user, sizeof(u->ut_name)); + (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; +} + +void +getutmpx(const struct utmp *u, struct utmpx *ux) +{ + + bzero(ux, sizeof(*ux)); + (void)memcpy(ux->ut_user, u->ut_name, sizeof(u->ut_name)); + ux->ut_user[sizeof(u->ut_name)] = 0; + (void)memcpy(ux->ut_line, u->ut_line, sizeof(u->ut_line)); + ux->ut_line[sizeof(u->ut_line)] = 0; + (void)memcpy(ux->ut_host, u->ut_host, sizeof(u->ut_host)); + ux->ut_host[sizeof(u->ut_host)] = 0; + ux->ut_tv.tv_sec = u->ut_time; + ux->ut_tv.tv_usec = 0; + ux->ut_pid = getpid(); + ux->ut_type = USER_PROCESS; +} diff --git a/gen/utmpx.5 b/gen/utmpx.5 new file mode 100644 index 0000000..5e7d31a --- /dev/null +++ b/gen/utmpx.5 @@ -0,0 +1,97 @@ +.\" $NetBSD: utmpx.5,v 1.2 2003/04/16 13:35:24 wiz 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. +.\" 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. +.\" +.Dd Dec 26, 2005 +.Dt UTMPX 5 +.Os +.Sh NAME +.Nm utmpx +.Nd user accounting database +.Sh SYNOPSIS +.In utmpx.h +.Sh DESCRIPTION +The +.Aq Pa utmpx.h +header defines the structures and functions for logging user. +Currently logged in users are tracked in +.Pa /var/run/utmpx . +The interface to the +.Nm utmpx +file is described in +.Xr endutxent 3 . +The file is not automatically created if they do not exist; it +must be created manually. +.Pp +Traditionally, separate files would be used to store the running log of +the logins and logouts +.Pf ( Pa wtmpx ) , +and the last login of each user +.Pf ( Pa lastlogx ) . +With the availability of the Apple system log facility +.Xr asl 3 , +these separate files can be replace with log entries, which are automatically +generated when +.Nm utmpx +entries are written. +The API to access the logins and logouts is described in +.Xr endutxent_wtmp 3 +while the last login info is accessible with +.Xr getlastlogx 3 . +.Pp +For compatibility, changes to +.Nm utmpx +are reflected in +.Xr utmp 3 +(in the +.Pa utmp , +.Pa wtmp +and +.Pa lastlog +files), +but not the other way around. +.Sh FILES +.Bl -tag -width /var/log/utmpx -compact +.It Pa /var/run/utmpx +The +.Nm utmpx +file. +.El +.Sh SEE ALSO +.Xr asl 3 , +.Xr endutxent 3 , +.Xr endutxent_wtmp 3 , +.Xr getlastlogx 3 , +.Xr utmp 5 diff --git a/gen/vis-fbsd.c b/gen/vis-fbsd.c new file mode 100644 index 0000000..7eb50b7 --- /dev/null +++ b/gen/vis-fbsd.c @@ -0,0 +1,209 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include + +#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') + +/* + * vis - visually encode characters + */ +char * +vis(dst, c, flag, nextc) + char *dst; + int c, nextc; + int flag; +{ + locale_t loc = __current_locale(); + + c = (unsigned char)c; + + if (flag & VIS_HTTPSTYLE) { + /* Described in RFC 1808 */ + if (!(isalnum_l(c, loc) /* alpha-numeric */ + /* safe */ + || c == '$' || c == '-' || c == '_' || c == '.' || c == '+' + /* extra */ + || c == '!' || c == '*' || c == '\'' || c == '(' + || c == ')' || c == ',')) { + *dst++ = '%'; + snprintf_l(dst, 4, loc, (c < 16 ? "0%X" : "%X"), c); + dst += 2; + goto done; + } + } + + if ((flag & VIS_GLOB) && + (c == '*' || c == '?' || c == '[' || c == '#')) + ; + else if (isgraph_l(c, loc) || + ((flag & VIS_SP) == 0 && c == ' ') || + ((flag & VIS_TAB) == 0 && c == '\t') || + ((flag & VIS_NL) == 0 && c == '\n') || + ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) { + *dst++ = c; + if (c == '\\' && (flag & VIS_NOSLASH) == 0) + *dst++ = '\\'; + *dst = '\0'; + return (dst); + } + + if (flag & VIS_CSTYLE) { + switch(c) { + case '\n': + *dst++ = '\\'; + *dst++ = 'n'; + goto done; + case '\r': + *dst++ = '\\'; + *dst++ = 'r'; + goto done; + case '\b': + *dst++ = '\\'; + *dst++ = 'b'; + goto done; + case '\a': + *dst++ = '\\'; + *dst++ = 'a'; + goto done; + case '\v': + *dst++ = '\\'; + *dst++ = 'v'; + goto done; + case '\t': + *dst++ = '\\'; + *dst++ = 't'; + goto done; + case '\f': + *dst++ = '\\'; + *dst++ = 'f'; + goto done; + case ' ': + *dst++ = '\\'; + *dst++ = 's'; + goto done; + case '\0': + *dst++ = '\\'; + *dst++ = '0'; + if (isoctal(nextc)) { + *dst++ = '0'; + *dst++ = '0'; + } + goto done; + } + } + if (((c & 0177) == ' ') || isgraph_l(c, loc) || (flag & VIS_OCTAL)) { + *dst++ = '\\'; + *dst++ = ((u_char)c >> 6 & 07) + '0'; + *dst++ = ((u_char)c >> 3 & 07) + '0'; + *dst++ = ((u_char)c & 07) + '0'; + goto done; + } + if ((flag & VIS_NOSLASH) == 0) + *dst++ = '\\'; + if (c & 0200) { + c &= 0177; + *dst++ = 'M'; + } + if (iscntrl_l(c, loc)) { + *dst++ = '^'; + if (c == 0177) + *dst++ = '?'; + else + *dst++ = c + '@'; + } else { + *dst++ = '-'; + *dst++ = c; + } +done: + *dst = '\0'; + return (dst); +} + +/* + * strvis, strvisx - visually encode characters from src into dst + * + * Dst must be 4 times the size of src to account for possible + * expansion. The length of dst, not including the trailing NUL, + * is returned. + * + * Strvisx encodes exactly len bytes from src into dst. + * This is useful for encoding a block of data. + */ +int +strvis(dst, src, flag) + char *dst; + const char *src; + int flag; +{ + char c; + char *start; + + for (start = dst; (c = *src); ) + dst = vis(dst, c, flag, *++src); + *dst = '\0'; + return (dst - start); +} + +int +strvisx(dst, src, len, flag) + char *dst; + const char *src; + size_t len; + int flag; +{ + int c; + char *start; + + for (start = dst; len > 1; len--) { + c = *src; + dst = vis(dst, c, flag, *++src); + } + if (len) + dst = vis(dst, *src, flag, '\0'); + *dst = '\0'; + + return (dst - start); +} diff --git a/gen/vis.3 b/gen/vis.3 new file mode 120000 index 0000000..66ce53e --- /dev/null +++ b/gen/vis.3 @@ -0,0 +1 @@ +./vis.3 \ No newline at end of file diff --git a/gen/wait-fbsd.c b/gen/wait-fbsd.c new file mode 100644 index 0000000..d1c0f4d --- /dev/null +++ b/gen/wait-fbsd.c @@ -0,0 +1,64 @@ +/* + * 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" + +#ifdef VARIANT_CANCELABLE +int __wait4(pid_t, int *, int , struct rusage *); +#else /* !VARIANT_CANCELABLE */ +int __wait4_nocancel(pid_t, int *, int , struct rusage *); +#endif /* VARIANT_CANCELABLE */ + +pid_t +__wait(int *istat) +{ +#ifdef VARIANT_CANCELABLE + return (__wait4(WAIT_ANY, istat, 0, (struct rusage *)0)); +#else /* !VARIANT_CANCELABLE */ + return (__wait4_nocancel(WAIT_ANY, istat, 0, (struct rusage *)0)); +#endif /* VARIANT_CANCELABLE */ +} + +__weak_reference(__wait, wait); +__weak_reference(__wait, _wait); diff --git a/gen/wait3-fbsd.c b/gen/wait3-fbsd.c new file mode 100644 index 0000000..a4b91a7 --- /dev/null +++ b/gen/wait3-fbsd.c @@ -0,0 +1,54 @@ +/* + * 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" + +pid_t +wait3(istat, options, rup) + int *istat; + int options; + struct rusage *rup; +{ + return (_wait4(WAIT_ANY, istat, options, rup)); +} diff --git a/gen/waitpid-fbsd.c b/gen/waitpid-fbsd.c new file mode 100644 index 0000000..3679eb8 --- /dev/null +++ b/gen/waitpid-fbsd.c @@ -0,0 +1,75 @@ +/* + * 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" + +#if __DARWIN_UNIX03 +#include +#endif /* __DARWIN_UNIX03 */ +#ifdef VARIANT_CANCELABLE +int __wait4(pid_t, int *, int , struct rusage *); +#else /* !VARIANT_CANCELABLE */ +int __wait4_nocancel(pid_t, int *, int , struct rusage *); +#endif /* VARIANT_CANCELABLE */ + +pid_t +__waitpid(pid_t pid, int *istat, int options) +{ +#if __DARWIN_UNIX03 + /* POSIX: Validate waitpid() options before calling wait4() */ + if ((options & (WCONTINUED | WNOHANG | WUNTRACED)) != options) { + errno = EINVAL; + return ((pid_t)-1); + } +#endif /* __DARWIN_UNIX03 */ + +#ifdef VARIANT_CANCELABLE + return (__wait4(pid, istat, options, (struct rusage *)0)); +#else /* !VARIANT_CANCELABLE */ + return (__wait4_nocancel(pid, istat, options, (struct rusage *)0)); +#endif /* VARIANT_CANCELABLE */ +} + +__weak_reference(__waitpid, waitpid); +__weak_reference(__waitpid, _waitpid); diff --git a/gen/wordexp.3 b/gen/wordexp.3 index 642e249..e958d63 100644 --- a/gen/wordexp.3 +++ b/gen/wordexp.3 @@ -34,18 +34,24 @@ .Sh SYNOPSIS .In wordexp.h .Ft int -.Fn wordexp "const char * restrict words" "wordexp_t * restrict we" "int flags" +.Fo wordexp +.Fa "const char *restrict words" +.Fa "wordexp_t *restrict pwordexp" +.Fa "int flags" +.Fc .Ft void -.Fn wordfree "wordexp_t *we" +.Fo wordfree +.Fa "wordexp_t *pwordexp" +.Fc .Sh DESCRIPTION The .Fn wordexp function performs shell-style word expansion on -.Fa words -and places the list of words into the +.Fa words . +It places the list of words into the .Va we_wordv member of -.Fa we , +.Fa pwordexp and the number of words into .Va we_wordc . .Pp @@ -64,7 +70,7 @@ As many pointers as are specified by the .Va we_offs member of -.Fa we +.Fa pwordexp are added to the front of .Va we_wordv . .It Dv WRDE_NOCMD @@ -75,7 +81,7 @@ See the note in before using this. .It Dv WRDE_REUSE The -.Fa we +.Fa pwordexp argument was passed to a previous successful call to .Fn wordexp but has not been passed to @@ -153,10 +159,10 @@ and .Pa /etc/motd (error checking omitted): .Bd -literal -offset indent -wordexp_t we; +wordexp_t pwordexp; -wordexp("${EDITOR:-vi} *.c /etc/motd", &we, 0); -execvp(we->we_wordv[0], we->we_wordv); +wordexp("${EDITOR:-vi} *.c /etc/motd", &pwordexp, 0); +execvp(pwordexp->we_wordv[0], pwordexp->we_wordv); .Ed .Sh SEE ALSO .Xr sh 1 , diff --git a/gen/wordexp.c b/gen/wordexp.c index 3f4496a..1a10891 100644 --- a/gen/wordexp.c +++ b/gen/wordexp.c @@ -1,266 +1,325 @@ /* - * Copyright 1994, University Corporation for Atmospheric Research - * See ../COPYRIGHT file for copying and redistribution conditions. - */ -/* - * Reproduction of ../COPYRIGHT file: + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * - ********************************************************************* - -Copyright 1995-2002 University Corporation for Atmospheric Research/Unidata + * @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@ + */ -Portions of this software were developed by the Unidata Program at the -University Corporation for Atmospheric Research. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -Access and use of this software shall impose the following obligations -and understandings on the user. The user is granted the right, without -any fee or cost, to use, copy, modify, alter, enhance and distribute -this software, and any derivative works thereof, and its supporting -documentation for any purpose whatsoever, provided that this entire -notice appears in all copies of the software, derivative works and -supporting documentation. Further, UCAR requests that the user credit -UCAR/Unidata in any publications that result from the use of this -software or in any product that includes this software. The names UCAR -and/or Unidata, however, may not be used in any advertising or publicity -to endorse or promote any products or commercial entity unless specific -written permission is obtained from UCAR/Unidata. The user also -understands that UCAR/Unidata is not obligated to provide the user with -any support, consulting, training or assistance of any kind with regard -to the use, operation and performance of this software nor to provide -the user with any updates, revisions, new versions or "bug fixes." +// For _NSGetEnviron() -- which gives us a pointer to environ +#include -THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "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 UCAR/UNIDATA 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 ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. +extern size_t malloc_good_size(size_t size); +extern int errno; - ********************************************************************* - */ +pthread_once_t re_init_c = PTHREAD_ONCE_INIT; +static regex_t re_cmd, re_goodchars, re_subcmd_syntax_err_kludge; -/* $Id: wordexp.c,v 1.13 2002/12/26 16:46:46 steve Exp $ */ +/* Similar to popen, but catures stderr for you. Doesn't interoperate + with pclose. Call wait4 on your own */ +pid_t popen_oe(char *cmd, FILE **out, FILE **err) { + int out_pipe[2], err_pipe[2]; + char *argv[4]; + pid_t pid; -#if 0 -#include "ldmconfig.h" -#endif + if (pipe(out_pipe) < 0) { + return 0; + } + if (pipe(err_pipe) < 0) { + close(out_pipe[0]); + close(out_pipe[1]); + return 0; + } -/* - * Hack to provide POSIX 1003.2-1992 _interface_. - * NOT fully functional - */ + argv[0] = "sh"; + argv[1] = "-c"; + argv[2] = cmd; + argv[3] = NULL; -#include "xlocale_private.h" + switch(pid = vfork()) { + case -1: + close(out_pipe[0]); + close(out_pipe[1]); + close(err_pipe[0]); + close(err_pipe[1]); + return 0; + case 0: + if (out_pipe[1] != STDOUT_FILENO) { + dup2(out_pipe[1], STDOUT_FILENO); + close(out_pipe[1]); + } + close(out_pipe[0]); + if (err_pipe[1] != STDERR_FILENO) { + dup2(err_pipe[1], STDERR_FILENO); + close(err_pipe[1]); + } + close(err_pipe[0]); + execve(_PATH_BSHELL, argv, *_NSGetEnviron()); + _exit(127); + default: + *out = fdopen(out_pipe[0], "r"); + assert(*out); + close(out_pipe[1]); + *err = fdopen(err_pipe[0], "r"); + assert(*err); + close(err_pipe[1]); -#include -#include -#include - -#include "wordexp.h" + return pid; + } +} +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 */ + char *rx = "^([^\\\"'|&;<>(){}]" + "|\\\\." + "|'([^']|\\\\')*'" + "|\"([^\"]|\\\\\")*\"" + "|`([^`]|\\\\`)*`" + "|\\$(([^)]|\\\\))*\\)" /* can't do nesting in a regex */ + "|\\$\\{[^}]*\\}" + /* XXX: { } ? */ + ")*$"; + rc = regcomp(&re_goodchars, rx, + REG_EXTENDED|REG_NOSUB); + rc = regcomp(&re_subcmd_syntax_err_kludge, + "command substitution.*syntax error", REG_EXTENDED|REG_NOSUB); +} -/* - * Translate return value from wordexp() into a string - */ -const char * -s_wrde_err(int wrde_err) -{ - switch(wrde_err) { - case 0: return "No Error"; - case WRDE_BADCHAR: return "WRDE_BADCHAR"; - case WRDE_BADVAL: return "WRDE_BADVAL"; - case WRDE_CMDSUB: return "WRDE_CMDSUB"; - case WRDE_NOSPACE: return "WRDE_NOSPACE"; - case WRDE_SYNTAX: return "WRDE_SYNTAX"; - } - /* default */ - return "Unknown Error"; +/* Returns zero if it can't realloc */ +static int word_alloc(size_t want, wordexp_t *__restrict__ pwe, size_t *have) { + if (want < *have) { + return 1; + } + size_t bytes = malloc_good_size(sizeof(char *) * want * 2); + pwe->we_wordv = reallocf(pwe->we_wordv, bytes); + if (pwe->we_wordv) { + *have = bytes / sizeof(char *); + return 1; + } + return 0; } +/* XXX this is _not_ designed to be fast */ +/* wordexp is also rife with security "chalenges", unless you pass it + WRDE_NOCMD it *must* support subshell expansion, and even if you + don't beause it has to support so much of the standard shell (all + the odd little variable expansion options for example) it is hard + to do without a subshell). It is probbably just plan a Bad Idea + to call in anything setuid, or executing remotely. */ -/*ARGSUSED*/ -int -wordexp(const char *words, wordexp_t *pwordexp, int flags) -{ - const char *ccp; - char **argv; - const char *buf; - size_t argc; - enum states {ARGSTART, IN_QUOTE, NOT_IN_QUOTE, DONE}; - enum classes {EOS, SPACE, QUOTE, OTHER}; - int state = ARGSTART; - char *argbuf; - const char *sp; - char *dp; - int status = 0; - locale_t loc = __current_locale(); - - /* devour leading white space */ - for(ccp = words; *ccp != 0 && isspace_l(*ccp, loc); ) - ccp++; - /* skip comments */ - if(*ccp == '#') - { - pwordexp->we_wordc = 0; - pwordexp->we_wordv = NULL; - return 0; - } +int wordexp(const char *__restrict__ words, + wordexp_t *__restrict__ pwe, int flags) { + /* cbuf_l's inital value needs to be big enough for 'cmd' plus + about 20 chars */ + size_t cbuf_l = 1024; + char *cbuf = NULL; + /* Put a NUL byte between eaach word, and at the end */ + char *cmd = "/usr/bin/perl -e 'print join(chr(0), @ARGV), chr(0)' -- "; + size_t wordv_l = 0, wordv_i = 0; + int rc; + wordexp_t save; -/* If every other character was a space ... */ -#define MAXNARGS(str) ((strlen(str) +1)/2 +1) - argv = (char **)calloc(MAXNARGS(ccp), sizeof(char *)); - if(argv == NULL) - return WRDE_NOSPACE; + /* Some errors require us to leave pwe unchanged, so we save it here */ + save = *pwe; + pthread_once(&re_init_c, re_init); - buf = ccp; + if (flags & WRDE_NOCMD) { + /* Thi attmpts to match any backticks or $(...)'s, but there may be + other ways to do subshell expansion that the standard doesn't + cover, but I don't know of any -- failures here aare a potential + security risk */ + rc = regexec(&re_cmd, words, 0, NULL, 0); + if (rc != REG_NOMATCH) { + /* Technically ==0 is WRDE_CMDSUB, and != REG_NOMATCH is + "some internal error", but failing to catch those here + could allow a subshell */ + return WRDE_CMDSUB; + } + } + rc = regexec(&re_goodchars, words, 0, NULL, 0); + if (rc != 0) { + /* Technically ==REG_NOMATCH is WRDE_BADCHAR, and != is + some internal error", but again failure to notice the + internal error could allow unexpected shell commands + (allowing an unexcaped ;), or file clobbering (unescaped + >) */ + return WRDE_BADCHAR; + } - argbuf = malloc(strlen(words)+1); /* where each arg is built */ - if (argbuf == NULL) - { - free(argv); - return WRDE_NOSPACE; - } + if (flags & WRDE_APPEND) { + wordv_i = wordv_l = pwe->we_wordc; + if (flags & WRDE_DOOFFS) { + wordv_l = wordv_i += pwe->we_offs; + } + } else { + if (flags & WRDE_REUSE) { + wordfree(pwe); + } + pwe->we_wordc = 0; + pwe->we_wordv = NULL; - sp = buf; - dp = argbuf; - argc = 0; - while(state != DONE) - { - int class; + if (flags & WRDE_DOOFFS) { + size_t wend = wordv_i + pwe->we_offs; + word_alloc(wend, pwe, &wordv_l); + if (!pwe->we_wordv) { + return WRDE_NOSPACE; + } + bzero(pwe->we_wordv + wordv_i, pwe->we_offs * sizeof(char *)); + wordv_i = wend; + } + } - if (*sp == 0) - class = EOS; - else if (isspace_l(*sp, loc)) - class = SPACE; - else if (*sp == '"') - class = QUOTE; - else - class = OTHER; - switch (state) { - case ARGSTART: - switch(class) { - case EOS: - state = DONE; - break; - case SPACE: - sp++; - break; - case QUOTE: - sp++; - state = IN_QUOTE; - break; - case OTHER: - *dp++ = *sp++; - state = NOT_IN_QUOTE; - break; - } - break; - case IN_QUOTE: - switch(class) { - case EOS: /* unmatched quote */ - state = DONE; - status = WRDE_SYNTAX; - break; - case QUOTE: - sp++; - state = NOT_IN_QUOTE; - break; - case SPACE: - case OTHER: - *dp++ = *sp++; - break; - } - break; - case NOT_IN_QUOTE: - switch(class) { - case EOS: - *dp = 0; - dp = argbuf; - argv[argc++] = strdup(argbuf); - state = DONE; - break; - case SPACE: - *dp = 0; - dp = argbuf; - argv[argc++] = strdup(argbuf); - sp++; - state = ARGSTART; - break; - case QUOTE: - sp++; - state = IN_QUOTE; - break; - case OTHER: - *dp++ = *sp++; - break; - } - break; - } + size_t need = 0; + while(!cbuf || need > cbuf_l) { + if (need > cbuf_l) { + cbuf_l = malloc_good_size(need +1); + } + cbuf = reallocf(cbuf, cbuf_l); + if (cbuf == NULL) { + wordfree(pwe); + return WRDE_NOSPACE; + } + cbuf[0] = '\0'; + if (flags & WRDE_UNDEF) { + strlcat(cbuf, "set -u; ", cbuf_l); } - argv[argc] = NULL; + /* This kludge is needed because /bin/sh seems to set IFS to the + defualt even if you have set it; We also can't just ignore it + because it is hard/unplesent to code around or even a potential + security problem because the test suiete explicitly checks + to make sure setting IFS "works" */ + if (getenv("IFS")) { + setenv("_IFS", getenv("IFS"), 1); + strlcat(cbuf, "export IFS=${_IFS}; ", cbuf_l); + } + strlcat(cbuf, cmd, cbuf_l); + need = strlcat(cbuf, words, cbuf_l); + } - pwordexp->we_wordc = argc; - pwordexp->we_wordv = argv; - - free(argbuf); - - return status; -} + FILE *out, *err; + pid_t pid = popen_oe(cbuf, &out, &err); + if (pid == 0) { + wordfree(pwe); + return WRDE_NOSPACE; + } + + char *word = NULL; + int word_l = 0; + int word_i = 0; + int ch; + while(EOF != (ch = fgetc(out))) { + if (word_l <= word_i) { + word_l = malloc_good_size(word_l * 2 + 1); + word = reallocf(word, word_l); + if (!word) { + fclose(err); + fclose(out); + wordfree(pwe); + return WRDE_NOSPACE; + } + } + word[word_i++] = ch; -void -wordfree(wordexp_t *pwordexp) -{ - if(pwordexp == NULL || pwordexp->we_wordv == NULL) - return; - if(*pwordexp->we_wordv) - free(*pwordexp->we_wordv); - free(pwordexp->we_wordv); -} + if (ch == '\0') { + word_alloc(wordv_i + 1, pwe, &wordv_l); + char *tmp = strdup(word); + if (pwe->we_wordv == NULL || tmp == NULL) { + fclose(err); + fclose(out); + wordfree(pwe); + free(word); + free(tmp); + int status; + wait4(pid, &status, 0, NULL); + return WRDE_NOSPACE; + } + pwe->we_wordv[wordv_i++] = tmp; + pwe->we_wordc++; + word_i = 0; + } + } + assert(word_i == 0); + free(word); -#if TEST + char err_buf[1024]; + size_t err_sz = fread(err_buf, 1, sizeof(err_buf) -1, err); + err_buf[(err_sz >= 0) ? err_sz : 0] = '\0'; + if (flags & WRDE_SHOWERR) { + fputs(err_buf, stderr); + } -#include -#include -#include + pid_t got_pid = 0; + int status; + do { + pid = wait4(pid, &status, 0, NULL); + } while(got_pid == -1 && errno == EINTR); -int -main(int argc, char *argv[]) -{ - char strbuf[1024]; - wordexp_t wrdexp; - int status; - char **cpp; + fclose(out); + fclose(err); - while(fgets(strbuf, sizeof(strbuf), stdin) != NULL) - { - { - char *cp = strrchr(strbuf,'\n'); - if(cp) - *cp = 0; - } - fprintf(stdout, "\t%s\n", strbuf); - status = wordexp(strbuf, &wrdexp, WRDE_SHOWERR); - if(status) - { - fprintf(stderr, "wordexp: %s\n", s_wrde_err(status)); - continue; - } - /* else */ - fprintf(stdout, "\t%d:\n", wrdexp.we_wordc); - for(cpp = wrdexp.we_wordv; - cpp < &wrdexp.we_wordv[wrdexp.we_wordc]; cpp++) - { - fprintf(stdout, "\t\t%s\n", *cpp); - } - wordfree(&wrdexp); - + /* the exit status isn't set for some command syntax errors */ + if (regexec(&re_subcmd_syntax_err_kludge, err_buf, 0, NULL, 0) == 0 + || got_pid == -1 || (WIFEXITED(status) && WEXITSTATUS(status))) { + if (!(flags & (WRDE_APPEND|WRDE_REUSE))) { + /* Restore pwe if possiable, can't really do it in the append + case, and isn't easy in the reuse case */ + *pwe = save; } - exit(EXIT_SUCCESS); + if (strstr(err_buf, " unbound variable")) { + return WRDE_BADVAL; + } + return WRDE_SYNTAX; + } + + if (!word_alloc(wordv_i + 1, pwe, &wordv_l)) { + return WRDE_NOSPACE; + } + pwe->we_wordv[wordv_i] = NULL; + + return 0; } -#endif /* TEST */ +void wordfree(wordexp_t *pwe) { + if (pwe == NULL || pwe->we_wordv == NULL) { + return; + } + + int i = 0, e = pwe->we_wordc + pwe->we_offs; + for(i = 0; i < e; i++) { + free(pwe->we_wordv[i]); + } + free(pwe->we_wordv); + pwe->we_wordv = NULL; +} diff --git a/gen/zone.c b/gen/zone.c index db3e883..51824f8 100644 --- a/gen/zone.c +++ b/gen/zone.c @@ -24,44 +24,104 @@ #import #import #import +#import +#import +#import + +#define OBSOLETED + +static pthread_mutex_t _zone_mutex = PTHREAD_MUTEX_INITIALIZER; + +enum { + nXDefaultMallocZone = 0, + nXCreateZone, + nXNameZone, + nXZoneMalloc, + nXZoneRealloc, + nXZoneCalloc, + nXZoneFree, + nXDestroyZone, + nXZoneFromPtr, + nXZonePtrInfo, + nXMallocCheck, + _nXMallocDumpZones +}; +static char *once[] = { + "NXDefaultMallocZone", + "NXCreateZone", + "NXNameZone", + "NXZoneMalloc", + "NXZoneRealloc", + "NXZoneCalloc", + "NXZoneFree", + "NXDestroyZone", + "NXZoneFromPtr", + "NXZonePtrInfo", + "NXMallocCheck", + "_NXMallocDumpZones" +}; + +extern int __is_threaded; /********* NX functions ************/ +static void +_deprecated(int index) +{ + if(__is_threaded) + pthread_mutex_lock(&_zone_mutex); + if(once[index]) { + fprintf(stderr, "*** %s[%d]: %s() is deprecated and will be removed in the future\n", getprogname(), getpid(), once[index]); + once[index] = NULL; + } + if(__is_threaded) + pthread_mutex_unlock(&_zone_mutex); +} + malloc_zone_t *NXDefaultMallocZone() { + _deprecated(nXDefaultMallocZone); return malloc_default_zone(); } malloc_zone_t *NXCreateZone(size_t startsize, size_t granularity, int canfree) { + _deprecated(nXCreateZone); return malloc_create_zone(startsize, 0); } void NXNameZone(malloc_zone_t *z, const char *name) { + _deprecated(nXNameZone); malloc_set_zone_name(z, name); } void *NXZoneMalloc(malloc_zone_t *zone, size_t size) { + _deprecated(nXZoneMalloc); return malloc_zone_malloc(zone, size); } void *NXZoneRealloc(malloc_zone_t *zone, void *ptr, size_t size) { + _deprecated(nXZoneRealloc); return malloc_zone_realloc(zone, ptr, size); } void *NXZoneCalloc(malloc_zone_t *zone, size_t num_items, size_t size) { + _deprecated(nXZoneCalloc); return malloc_zone_calloc(zone, num_items, size); } void NXZoneFree(malloc_zone_t *zone, void *ptr) { + _deprecated(nXZoneFromPtr); malloc_zone_free(zone, ptr); } void NXDestroyZone(malloc_zone_t *zone) { + _deprecated(nXDestroyZone); if (zone == malloc_default_zone()) return; // we avoid destroying child zones malloc_destroy_zone(zone); } NXZone *NXZoneFromPtr(void *ptr) { NXZone *zone = malloc_zone_from_ptr(ptr); + _deprecated(nXZoneFromPtr); if (!zone) { malloc_printf("*** NXZoneFromPtr() did not find any zone for %p; returning default\n", ptr); zone = NX_NOZONE; @@ -69,6 +129,7 @@ NXZone *NXZoneFromPtr(void *ptr) { return zone; } +#ifndef OBSOLETED void NXAddRegion(void *start, size_t size, malloc_zone_t *zone) { malloc_printf("*** OBSOLETE: NXAddRegion()\n"); } @@ -76,22 +137,27 @@ void NXAddRegion(void *start, size_t size, malloc_zone_t *zone) { void NXRemoveRegion(void *start) { malloc_printf("*** OBSOLETE: NXRemoveRegion()\n"); } +#endif /* OBSOLETED */ void NXZonePtrInfo(void *ptr) { + _deprecated(nXZonePtrInfo); malloc_zone_print_ptr_info(ptr); } int NXMallocCheck(void) { + _deprecated(nXMallocCheck); malloc_zone_check(NULL); return 1; } void _NXMallocDumpZones(void) { + _deprecated(_nXMallocDumpZones); malloc_zone_print(NULL, 0); } /***************** UNIMPLEMENTED ENTRY POINTS ********************/ +#ifndef OBSOLETED void NXMergeZone(malloc_zone_t *z) { static char warned = 0; if (!warned) { @@ -118,4 +184,4 @@ malloc_zone_t *NXCreateChildZone(malloc_zone_t *parentzone, size_t startsize, si void _NXMallocDumpFrees(void) { malloc_printf("*** OBSOLETE: _NXMallocDumpFrees()\n"); } - +#endif /* OBSOLETED */ diff --git a/gmon/Makefile.inc b/gmon/Makefile.inc index 1356dc1..11ce509 100644 --- a/gmon/Makefile.inc +++ b/gmon/Makefile.inc @@ -6,11 +6,11 @@ MISRCS+= gmon.c -#.if ${LIB} == "c" -#MAN+= moncontrol.3 -# -#MLINKS+=moncontrol.3 monstartup.3 -#.endif +.if ${LIB} == "c" +MAN3 += moncontrol.3 + +MLINKS += moncontrol.3 monstartup.3 +.endif # mcount cannot be compiled with profiling gmon.po: diff --git a/gmon/gmon.c b/gmon/gmon.c index 69d7822..9770f3b 100644 --- a/gmon/gmon.c +++ b/gmon/gmon.c @@ -103,9 +103,6 @@ static char sccsid[] = "@(#)gmon.c 5.2 (Berkeley) 6/21/85"; #include #include -extern const struct section *getsectbyname( - const char *segname, - const char *sectname); #include #include #include @@ -114,6 +111,7 @@ extern const struct section *getsectbyname( #include #include #include +#include /* * These are defined in here and these declarations need to be moved to libc.h @@ -137,70 +135,74 @@ static char init = 0; /* set while moninit() is being serviced */ static unsigned long order = 0; /* call order */ -struct mon_t { +typedef struct { /* the address range and size this mon struct refers to */ char *lowpc; char *highpc; unsigned long textsize; /* the data structures to support the arc's and their counts */ unsigned short *froms; /* froms is unsigned shorts indexing into tos */ - struct tostruct *tos; + tostruct_t *tos; long tolimit; /* the pc-sample buffer, it's size and scale */ char *sbuf; - int ssiz; /* includes the gmonhdr struct */ - int scale; -}; -static struct mon_t *mon = NULL; + long ssiz; /* includes the gmonhdr_t */ + long scale; +} mon_t; +static mon_t *mon = NULL; static unsigned long nmon = 0; static void monsetup( - struct mon_t *m, + mon_t *m, char *lowpc, char *highpc); -static int getprofhz( +static long getprofhz( void); void moninit( void) { +#ifndef __LP64__ const struct section *section; +#else + const struct section_64 *section; +#endif char *lowpc, *highpc; unsigned long i; monreset(); init = 1; - section = getsectbyname ("__TEXT", "__text"); + section = getsectbyname("__TEXT", "__text"); lowpc = (char *)section->addr, highpc = (char *)(section->addr + section->size); if(mon == NULL){ - if((mon = malloc(sizeof(struct mon_t))) == NULL){ + if((mon = malloc(sizeof(mon_t))) == NULL){ write(2, MSG, sizeof(MSG) - 1); return; } nmon = 1; - memset(mon, '\0', sizeof(struct mon_t)); + memset(mon, '\0', sizeof(mon_t)); } /* * To continue to make monstartup() and the functions that existed * before adding multiple profiling areas working correctly the new * calls to get the dyld loaded code profiled are made after - * the first mon_t struct is allocated so that they will not use the - * first mon_t and the old calls will always use the first mon_t struct + * the first mon_t is allocated so that they will not use the + * first mon_t and the old calls will always use the first mon_t * in the list. */ monsetup(mon, lowpc, highpc); - profil(mon->sbuf + sizeof(struct gmonhdr), - mon->ssiz - sizeof(struct gmonhdr), - (int)mon->lowpc, mon->scale); + profil(mon->sbuf + sizeof(gmonhdr_t), + mon->ssiz - sizeof(gmonhdr_t), + (u_long)mon->lowpc, mon->scale); for(i = 1; i < nmon; i++) - add_profil(mon[i].sbuf + sizeof(struct gmonhdr), - mon[i].ssiz - sizeof(struct gmonhdr), - (int)mon[i].lowpc, mon[i].scale); + add_profil(mon[i].sbuf + sizeof(gmonhdr_t), + mon[i].ssiz - sizeof(gmonhdr_t), + (u_long)mon[i].lowpc, mon[i].scale); init = 0; profiling = 0; @@ -222,12 +224,12 @@ char *highpc) { monreset(); if(mon == NULL){ - if((mon = malloc(sizeof(struct mon_t))) == NULL){ + if((mon = malloc(sizeof(mon_t))) == NULL){ write(2, MSG, sizeof(MSG) - 1); return; } nmon = 1; - memset(mon, '\0', sizeof(struct mon_t)); + memset(mon, '\0', sizeof(mon_t)); } monsetup(mon, lowpc, highpc); } @@ -242,7 +244,7 @@ char *lowpc, char *highpc) { char save_profiling; - struct mon_t *m; + mon_t *m; if(mon == NULL){ monstartup(lowpc, highpc); @@ -250,12 +252,12 @@ char *highpc) } save_profiling = profiling; profiling = -1; - if((mon = realloc(mon, (nmon + 1) * sizeof(struct mon_t))) == NULL){ + if((mon = realloc(mon, (nmon + 1) * sizeof(mon_t))) == NULL){ write(2, MSG, sizeof(MSG) - 1); return; } m = mon + nmon; - memset(m, '\0', sizeof(struct mon_t)); + memset(m, '\0', sizeof(mon_t)); nmon++; monsetup(m, lowpc, highpc); profiling = save_profiling; @@ -264,24 +266,24 @@ char *highpc) static void monsetup( -struct mon_t *m, +mon_t *m, char *lowpc, char *highpc) { - int monsize; + long monsize; char *buffer; kern_return_t ret; - struct gmonhdr *p; - unsigned int o; + gmonhdr_t *p; + uintptr_t o; /* * round lowpc and highpc to multiples of the density we're using - * so the rest of the scaling (here and in gprof) stays in ints. + * so the rest of the scaling (here and in gprof) stays in longs. */ - lowpc = (char *)ROUNDDOWN((unsigned)lowpc, + lowpc = (char *)ROUNDDOWN((uintptr_t)lowpc, HISTFRACTION * sizeof(HISTCOUNTER)); m->lowpc = lowpc; - highpc = (char *)ROUNDUP((unsigned)highpc, + highpc = (char *)ROUNDUP((uintptr_t)highpc, HISTFRACTION * sizeof(HISTCOUNTER)); m->highpc = highpc; @@ -304,7 +306,7 @@ char *highpc) vm_deallocate(mach_task_self(), (vm_address_t)m->sbuf, (vm_size_t)m->ssiz); - monsize = (m->textsize / HISTFRACTION) + sizeof(struct gmonhdr); + monsize = (m->textsize / HISTFRACTION) + sizeof(gmonhdr_t); ret = vm_allocate(mach_task_self(), (vm_address_t *)&buffer, (vm_size_t)monsize, @@ -318,7 +320,7 @@ char *highpc) if(m->tos) vm_deallocate(mach_task_self(), (vm_address_t)m->tos, - (vm_size_t)(m->tolimit * sizeof(struct tostruct))); + (vm_size_t)(m->tolimit * sizeof(tostruct_t))); m->tolimit = m->textsize * ARCDENSITY / 100; if(m->tolimit < MINARCS){ m->tolimit = MINARCS; @@ -328,7 +330,7 @@ char *highpc) } ret = vm_allocate(mach_task_self(), (vm_address_t *)&m->tos, - (vm_size_t)(m->tolimit * sizeof(struct tostruct)), + (vm_size_t)(m->tolimit * sizeof(tostruct_t)), TRUE); if(ret != KERN_SUCCESS){ write(2, MSG, sizeof(MSG) - 1); @@ -354,28 +356,28 @@ char *highpc) /* monitor() functionality */ m->sbuf = buffer; m->ssiz = monsize; - p = (struct gmonhdr *)m->sbuf; - memset(p, '\0', sizeof(struct gmonhdr)); - p->lpc = (unsigned long)m->lowpc; - p->hpc = (unsigned long)m->highpc; + p = (gmonhdr_t *)m->sbuf; + memset(p, '\0', sizeof(gmonhdr_t)); + p->lpc = (uintptr_t)m->lowpc; + p->hpc = (uintptr_t)m->highpc; p->ncnt = m->ssiz; p->version = GMONVERSION; p->profrate = getprofhz(); o = highpc - lowpc; - if((monsize - sizeof(struct gmonhdr)) < o) -/* POSSIBLE BUG, if "(float) (monsize - sizeof(struct gmonhdr))/ o)" is zero + if((monsize - sizeof(gmonhdr_t)) < o) +/* POSSIBLE BUG, if "(float) (monsize - sizeof(gmonhdr_t))/ o)" is zero * then m->scale will be set to zero and the add_profil() call will disable * profiling */ - m->scale = ((float) (monsize - sizeof(struct gmonhdr))/ o) * + m->scale = ((float) (monsize - sizeof(gmonhdr_t))/ o) * SCALE_1_TO_1; else m->scale = SCALE_1_TO_1; /* moncontrol(mode == 1) functionality */ if(!init) - add_profil(m->sbuf + sizeof(struct gmonhdr), - m->ssiz - sizeof(struct gmonhdr), - (int)m->lowpc, m->scale); + add_profil(m->sbuf + sizeof(gmonhdr_t), + m->ssiz - sizeof(gmonhdr_t), + (long)m->lowpc, m->scale); } } @@ -384,8 +386,8 @@ monreset( void) { unsigned long i; - struct mon_t *m; - struct gmonhdr *p; + mon_t *m; + gmonhdr_t *p; moncontrol(0); if(mon == NULL) @@ -394,9 +396,9 @@ void) m = mon + i; if(m->sbuf != NULL){ memset(m->sbuf, '\0', m->ssiz); - p = (struct gmonhdr *)m->sbuf; - p->lpc = (unsigned long)m->lowpc; - p->hpc = (unsigned long)m->highpc; + p = (gmonhdr_t *)m->sbuf; + p->lpc = (uintptr_t)m->lowpc; + p->hpc = (uintptr_t)m->highpc; p->ncnt = m->ssiz; p->version = GMONVERSION; p->profrate = getprofhz(); @@ -404,7 +406,7 @@ void) if(m->froms != NULL) memset(m->froms, '\0', m->textsize / HASHFRACTION); if(m->tos != NULL) - memset(m->tos, '\0', m->tolimit * sizeof (struct tostruct)); + memset(m->tos, '\0', m->tolimit * sizeof(tostruct_t)); } order = 0; moncontrol(1); @@ -415,12 +417,14 @@ monoutput( const char *filename) { int fd; - unsigned long magic, i, fromindex, endfrom, toindex; - struct gmon_data sample_data, arc_data, dyld_data; + unsigned long i, fromindex, endfrom, toindex; + uint32_t magic; + gmon_data_t sample_data, arc_data, dyld_data; char *frompc; - struct rawarc_order rawarc_order; - struct mon_t *m; - unsigned long image_count, vmaddr_slide; + rawarc_order_t rawarc_order; + mon_t *m; + uint32_t image_count; + intptr_t image_header; char *image_name; moncontrol(0); @@ -433,8 +437,12 @@ const char *filename) return; } +#ifndef __LP64__ magic = GMON_MAGIC; - write(fd, &magic, sizeof(unsigned long)); +#else + magic = GMON_MAGIC_64; +#endif + write(fd, &magic, sizeof(uint32_t)); #if defined(__DYNAMIC__) if(_dyld_present()){ @@ -443,8 +451,8 @@ const char *filename) #ifdef DYLD_DEBUG printf("image_count = %lu\n", image_count - 1); for(i = 1; i < image_count; i++){ - vmaddr_slide = _dyld_get_image_vmaddr_slide(i); - printf("\tvmaddr_slide 0x%x\n", (unsigned int)vmaddr_slide); + image_header = _dyld_get_image_header(i); + printf("\timage_header %p\n", image_header); image_name = _dyld_get_image_name(i); printf("\timage_name %s\n", image_name); } @@ -452,9 +460,9 @@ const char *filename) /* * Calculate the dyld_data.size. */ - dyld_data.type = GMONTYPE_DYLD_STATE; - dyld_data.size = sizeof(unsigned long) + - sizeof(unsigned long) * (image_count - 1); + dyld_data.type = GMONTYPE_DYLD2_STATE; + dyld_data.size = sizeof(uint32_t) + + sizeof(intptr_t) * (image_count - 1); for(i = 1; i < image_count; i++){ image_name = _dyld_get_image_name(i); dyld_data.size += strlen(image_name) + 1; @@ -463,13 +471,13 @@ const char *filename) /* * Write the dyld_data. */ - write(fd, &dyld_data, sizeof(struct gmon_data)); + write(fd, &dyld_data, sizeof(gmon_data_t)); image_count--; - write(fd, &image_count, sizeof(unsigned long)); + write(fd, &image_count, sizeof(uint32_t)); image_count++; for(i = 1; i < image_count; i++){ - vmaddr_slide = _dyld_get_image_vmaddr_slide(i); - write(fd, &vmaddr_slide, sizeof(unsigned long)); + image_header = _dyld_get_image_header(i); + write(fd, &image_header, sizeof(intptr_t)); image_name = _dyld_get_image_name(i); write(fd, image_name, strlen(image_name) + 1); } @@ -479,15 +487,14 @@ const char *filename) for(i = 0; i < nmon; i++){ m = mon + i; #ifdef DEBUG - fprintf(stderr, "[monoutput] sbuf 0x%x ssiz %d\n", - m->sbuf, m->ssiz); + fprintf(stderr, "[monoutput] sbuf %p ssiz %d\n", m->sbuf, m->ssiz); #endif sample_data.type = GMONTYPE_SAMPLES; sample_data.size = m->ssiz; - write(fd, &sample_data, sizeof(struct gmon_data)); + write(fd, &sample_data, sizeof(gmon_data_t)); /* - * Write the gmonhdr struct and the pc-sample buffer. Note the - * gmonhdr struct is in sbuf at the beginning of sbuf already + * Write the gmonhdr_t and the pc-sample buffer. Note the + * gmonhdr_t is in sbuf at the beginning of sbuf already * filled in. */ write(fd, m->sbuf, m->ssiz); @@ -498,19 +505,26 @@ const char *filename) endfrom = m->textsize / (HASHFRACTION * sizeof(*m->froms)); arc_data.type = GMONTYPE_ARCS_ORDERS; arc_data.size = 0; +#ifdef DEBUG + fprintf(stderr, "[monoutput] raw arcs, total %lu\n", endfrom); +#endif for(fromindex = 0; fromindex < endfrom; fromindex++){ if(m->froms[fromindex] == 0){ continue; } +#ifdef DEBUG + fprintf(stderr, "[monoutput] raw arc count at index[%lu] %u\n", + fromindex, m->froms[fromindex]); +#endif frompc = m->lowpc + (fromindex * HASHFRACTION * sizeof(*m->froms)); for(toindex = m->froms[fromindex]; toindex != 0; toindex = m->tos[toindex].link){ - arc_data.size += sizeof(struct rawarc_order); + arc_data.size += sizeof(rawarc_order_t); } } - write(fd, &arc_data, sizeof(struct gmon_data)); + write(fd, &arc_data, sizeof(gmon_data_t)); for(fromindex = 0; fromindex < endfrom; fromindex++){ if(m->froms[fromindex] == 0){ @@ -522,17 +536,17 @@ const char *filename) toindex != 0; toindex = m->tos[toindex].link){ #ifdef DEBUG - fprintf(stderr, "[monoutput] frompc 0x%x selfpc 0x%x " - "count %ld order %lu\n", (unsigned int)frompc, - (unsigned int)m->tos[toindex].selfpc, + fprintf(stderr, "[monoutput] frompc %p selfpc %p " + "count %ld order %lu\n", frompc, + m->tos[toindex].selfpc, m->tos[toindex].count, m->tos[toindex].order); #endif - rawarc_order.raw_frompc = (unsigned long)frompc; - rawarc_order.raw_selfpc = (unsigned long) + rawarc_order.raw_frompc = (uintptr_t)frompc; + rawarc_order.raw_selfpc = (uintptr_t) m->tos[toindex].selfpc; rawarc_order.raw_count = m->tos[toindex].count; rawarc_order.raw_order = m->tos[toindex].order; - write(fd, &rawarc_order, sizeof(struct rawarc_order)); + write(fd, &rawarc_order, sizeof(rawarc_order_t)); } } } @@ -547,9 +561,9 @@ char *buf, int bufsiz, int nfunc) /* nfunc is not used; available for compatability only. */ { - unsigned int o; - struct gmonhdr *p; - struct mon_t *m; + intptr_t o; + gmonhdr_t *p; + mon_t *m; moncontrol(0); m = mon; @@ -562,14 +576,14 @@ int nfunc) /* nfunc is not used; available for compatability only. */ } m->sbuf = buf; m->ssiz = bufsiz; - p = (struct gmonhdr *)buf; - memset(p, '\0', sizeof(struct gmonhdr)); - p->lpc = (unsigned long)lowpc; - p->hpc = (unsigned long)highpc; + p = (gmonhdr_t *)buf; + memset(p, '\0', sizeof(gmonhdr_t)); + p->lpc = (uintptr_t)lowpc; + p->hpc = (uintptr_t)highpc; p->ncnt = m->ssiz; p->version = GMONVERSION; p->profrate = getprofhz(); - bufsiz -= sizeof(struct gmonhdr); + bufsiz -= sizeof(gmonhdr_t); if(bufsiz <= 0) return; o = highpc - lowpc; @@ -589,20 +603,20 @@ void moncontrol( int mode) { - struct mon_t *m; + mon_t *m; unsigned long i; if(mode){ /* start */ m = mon; if(m != NULL){ - profil(m->sbuf + sizeof(struct gmonhdr), - m->ssiz - sizeof(struct gmonhdr), - (int)m->lowpc, m->scale); + profil(m->sbuf + sizeof(gmonhdr_t), + m->ssiz - sizeof(gmonhdr_t), + (u_long)m->lowpc, m->scale); for(i = 1; i < nmon; i++) - add_profil(mon[i].sbuf + sizeof(struct gmonhdr), - mon[i].ssiz - sizeof(struct gmonhdr), - (int)mon[i].lowpc, mon[i].scale); + add_profil(mon[i].sbuf + sizeof(gmonhdr_t), + mon[i].ssiz - sizeof(gmonhdr_t), + (u_long)mon[i].lowpc, mon[i].scale); profiling = 0; } } @@ -619,9 +633,9 @@ char *frompc, char *selfpc) { unsigned short *frompcindex; - struct tostruct *top, *prevtop; + tostruct_t *top, *prevtop; unsigned long i, toindex; - struct mon_t *m; + mon_t *m; m = mon; if(m == NULL) @@ -637,8 +651,7 @@ char *selfpc) #ifdef DEBUG - fprintf(stderr, "[moncount] frompc 0x%x selfpc 0x%x\n", - (unsigned int)frompc, (unsigned int)selfpc); + fprintf(stderr, "[moncount] frompc %p selfpc %p\n", frompc, selfpc); #endif frompcindex = (unsigned short *)frompc; @@ -649,8 +662,8 @@ char *selfpc) */ for(i = 0; i < nmon; i++){ m = mon + i; - if((unsigned long)frompcindex >= (unsigned long)m->lowpc && - (unsigned long)frompcindex < (unsigned long)m->highpc) + if((uintptr_t)frompcindex >= (uintptr_t)m->lowpc && + (uintptr_t)frompcindex < (uintptr_t)m->highpc) break; } if(i == nmon){ @@ -658,7 +671,7 @@ char *selfpc) } else{ frompcindex = (unsigned short *) - ((unsigned long)frompcindex - (unsigned long)m->lowpc); + ((uintptr_t)frompcindex - (uintptr_t)m->lowpc); } frompcindex = &m->froms[((long)frompcindex) / (HASHFRACTION * sizeof(*m->froms))]; @@ -673,14 +686,14 @@ char *selfpc) } *frompcindex = toindex; top = &m->tos[toindex]; - top->selfpc = (unsigned long)selfpc; + top->selfpc = (uintptr_t)selfpc; top->count = 1; top->link = 0; top->order = ++order; goto done; } top = &m->tos[toindex]; - if(top->selfpc == (unsigned long)selfpc){ + if(top->selfpc == (uintptr_t)selfpc){ /* * arc at front of chain; usual case. */ @@ -698,7 +711,7 @@ char *selfpc) /* * top is end of the chain and none of the chain * had top->selfpc == selfpc. - * so we allocate a new tostruct + * so we allocate a new tostruct_t * and link it to the head of the chain. */ toindex = ++m->tos[0].link; @@ -706,7 +719,7 @@ char *selfpc) goto overflow; } top = &m->tos[toindex]; - top->selfpc = (unsigned long)selfpc; + top->selfpc = (uintptr_t)selfpc; top->count = 1; top->link = *frompcindex; top->order = ++order; @@ -718,7 +731,7 @@ char *selfpc) */ prevtop = top; top = &m->tos[top->link]; - if(top->selfpc == (unsigned long)selfpc){ + if(top->selfpc == (uintptr_t)selfpc){ /* * there it is. * increment its count @@ -746,7 +759,7 @@ overflow: * Get the profiling rate. */ static -int +long getprofhz(void) { int mib[2]; diff --git a/gmon/moncontrol.3 b/gmon/moncontrol.3 new file mode 100644 index 0000000..4b87df6 --- /dev/null +++ b/gmon/moncontrol.3 @@ -0,0 +1,101 @@ +.\" $OpenBSD: moncontrol.3,v 1.2 1996/08/19 08:28:06 tholo Exp $ +.\" +.\" Copyright (c) 1980, 1991, 1992, 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. +.\" +.Dd June 4, 1993 +.Dt MONCONTROL 3 +.Os BSD 4 +.Sh NAME +.Nm moncontrol , +.Nm monstartup +.Nd control execution profile +.Sh SYNOPSIS +.Fn moncontrol "int mode" +.Fn monstartup "u_long *lowpc" "u_long *highpc" +.Sh DESCRIPTION +An executable program compiled using the +.Fl pg +option to +.Xr cc 1 +automatically includes calls to collect statistics for the +.Xr gprof 1 +call-graph execution profiler. +In typical operation, profiling begins at program startup +and ends when the program calls exit. +When the program exits, the profiling data are written to the file +.Em gmon.out , +then +.Xr gprof 1 +can be used to examine the results. +.Pp +.Fn moncontrol +selectively controls profiling within a program. +When the program starts, profiling begins. +To stop the collection of histogram ticks and call counts use +.Fn moncontrol 0 ; +to resume the collection of histogram ticks and call counts use +.Fn moncontrol 1 . +This feature allows the cost of particular operations to be measured. +Note that an output file will be produced on program exit +regardless of the state of +.Fn moncontrol . +.Pp +Programs that are not loaded with +.Fl pg +may selectively collect profiling statistics by calling +.Fn monstartup +with the range of addresses to be profiled. +.Fa lowpc +and +.Fa highpc +specify the address range that is to be sampled; +the lowest address sampled is that of +.Fa lowpc +and the highest is just below +.Fa highpc . +Only functions in that range that have been compiled with the +.Fl pg +option to +.Xr cc 1 +will appear in the call graph part of the output; +however, all functions in that address range will +have their execution time measured. +Profiling begins on return from +.Fn monstartup . +.Sh FILES +.Bl -tag -width Pa -compact +.It Pa gmon.out execution data file +.El +.Sh SEE ALSO +.Xr cc 1 , +.Xr gprof 1 , +.Xr profil 2 diff --git a/i386/gen/Makefile.inc b/i386/gen/Makefile.inc index 4ae845f..e9bbd61 100644 --- a/i386/gen/Makefile.inc +++ b/i386/gen/Makefile.inc @@ -1,4 +1,17 @@ .PATH: ${.CURDIR}/i386/gen -MDSRCS+= icacheinval.s \ +MDSRCS+= _ctx_start.S \ + _setcontext.S \ + getcontext.S \ + getmcontext.c \ + icacheinval.s \ + makecontext.c \ mcount.s \ - setjmperr.c + setcontext.c \ + setjmperr.c \ + swapcontext.c + +.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 diff --git a/i386/gen/_ctx_start.S b/i386/gen/_ctx_start.S new file mode 100644 index 0000000..4e4a6bd --- /dev/null +++ b/i386/gen/_ctx_start.S @@ -0,0 +1,76 @@ +/* + * 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@ + */ + +/* + * Copyright (c) 2001 Daniel Eischen + * 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. Neither the name of the author 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 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. + */ + +#if defined(__i386__) + +#include + +/* + * _ctx_start((void *func)(int arg1, ..., argn), + * int arg1, ..., argn, ucontext_t *ucp) + * + * 0(%esp) - func + * 4(%esp) - arg1 + * 8(%esp) - arg2 + * ... + * (4*n)(%esp) - argn + * (4*(n + 1))(%esp) - ucp, %ebp setup to point here (base of stack) + */ +TEXT +LABEL(__ctx_start) + popl %eax /* get start function */ + call *%eax /* call start function */ + movl %esi, %esp /* + * setup stack for completion routine; + * ucp is now at top of stack + */ + CALL_EXTERN(__ctx_done) /* should never return */ + int $5 /* trap */ + +#endif /* __i386__ */ diff --git a/mach/headers/thread_act.h b/i386/gen/_setcontext.S similarity index 63% rename from mach/headers/thread_act.h rename to i386/gen/_setcontext.S index 843b9d5..b8129ba 100644 --- a/mach/headers/thread_act.h +++ b/i386/gen/_setcontext.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,14 +20,29 @@ * * @APPLE_LICENSE_HEADER_END@ */ + #if defined(__i386__) -#include -#elif defined(__x86_64__) -#include -#elif defined(__ppc__) -#include -#elif defined(__ppc64__) -#include -#else -#error unknown architecture -#endif + +#include + +TEXT +LABEL(__setcontext) + subl $28, %esp + movl 32(%esp), %eax + movl 4(%eax), %eax + movl %eax, (%esp) /* load up signal mask */ + CALL_EXTERN(_sigsetmask) /* set signal mask */ + addl $28, %esp + movl 4(%esp), %ecx + movl 28(%ecx), %ecx + movl 16(%ecx), %ebx + movl 28(%ecx), %edi + movl 32(%ecx), %esi + movl 36(%ecx), %ebp + movl 40(%ecx), %esp + pushl 48(%ecx) + popfl + movl 12(%ecx), %eax + jmp *52(%ecx) + +#endif /* __i386__ */ diff --git a/i386/gen/getcontext.S b/i386/gen/getcontext.S new file mode 100644 index 0000000..552547e --- /dev/null +++ b/i386/gen/getcontext.S @@ -0,0 +1,53 @@ +/* + * 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@ + */ + +#if defined(__i386__) + +#include + +TEXT +LABEL(_getcontext) + subl $28, %esp + movl 32(%esp), %eax + movl %eax, (%esp) + movl %esp, 4(%esp) + CALL_EXTERN(_getmcontext) + movl %eax, %ecx + addl $28, %esp + movl %ebx, 16(%ecx) + movl %edi, 28(%ecx) + movl %esi, 32(%ecx) + movl %ebp, 36(%ecx) + movl (%esp), %eax + movl %eax, 52(%ecx) + movl %esp, %eax + addl $4, %eax + movl %eax, 40(%ecx) + pushf + popl %eax + movl %eax, 48(%ecx) + xorl %eax, %eax + movl %eax, 12(%ecx) + ret + +#endif /* __i386__ */ diff --git a/i386/gen/getmcontext.c b/i386/gen/getmcontext.c new file mode 100644 index 0000000..30b0199 --- /dev/null +++ b/i386/gen/getmcontext.c @@ -0,0 +1,82 @@ +/* + * 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@ + */ + +#if defined(__i386__) + +#define _XOPEN_SOURCE 600L + +#include +#include +#include +#include +#include +#include + +extern size_t pthread_get_stacksize_np(pthread_t); +extern void *pthread_get_stackaddr_np(pthread_t); +#ifdef __DYNAMIC__ +extern int __in_sigtramp; +#endif /* __DYNAMIC_ */ + +__private_extern__ mcontext_t +getmcontext(ucontext_t *uctx, void *sp) +{ + pthread_t self = pthread_self(); + mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data; + size_t stacksize = pthread_get_stacksize_np(self); + stack_t stack; + + uctx->uc_stack.ss_sp = sp; + uctx->uc_stack.ss_flags = 0; + + if (0 == sigaltstack(NULL, &stack)) { + if (stack.ss_flags & SS_ONSTACK) { + uctx->uc_stack = stack; + stacksize = stack.ss_size; + } + } + + if (stacksize == 0) { /* main thread doesn't have pthread stack size */ + rlim_t rlim; + if (0 == getrlimit(RLIMIT_STACK, &rlim)) + stacksize = rlim; + } + + uctx->uc_stack.ss_size = stacksize; + + if (uctx->uc_mcontext != mctx) { + uctx->uc_mcontext = mctx; + +#ifdef __DYNAMIC__ + uctx->uc_link = (ucontext_t*)__in_sigtramp; /* non-zero if in signal handler */ +#else /* !__DYNAMIC__ */ + uctx->uc_link = 0; +#endif /* __DYNAMIC__ */ + + } + + sigprocmask(0, NULL, &uctx->uc_sigmask); + return mctx; +} + +#endif /* __i386__ */ diff --git a/i386/gen/icacheinval.s b/i386/gen/icacheinval.s index db86406..dbbb42d 100644 --- a/i386/gen/icacheinval.s +++ b/i386/gen/icacheinval.s @@ -1,5 +1,6 @@ /* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,10 +21,25 @@ * * @APPLE_LICENSE_HEADER_END@ */ + + + #include + + .text .align 4, 0x00 /* void sys_icache_invalidate(addr_t start, int length) */ + .globl _sys_icache_invalidate _sys_icache_invalidate: - ret + movl $(_COMM_PAGE_FLUSH_ICACHE), %eax + jmpl *%eax + + +/* void sys_dcache_flush(addr_t start, int length) */ + +.globl _sys_dcache_flush +_sys_dcache_flush: + movl $(_COMM_PAGE_FLUSH_DCACHE), %eax + jmpl *%eax diff --git a/i386/gen/makecontext.c b/i386/gen/makecontext.c new file mode 100644 index 0000000..7dcc009 --- /dev/null +++ b/i386/gen/makecontext.c @@ -0,0 +1,191 @@ +/* + * 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@ + */ + +/* + * Copyright (c) 2001 Daniel M. Eischen + * 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. Neither the name of the author 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 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. + */ + +#if defined(__i386__) + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Prototypes */ +extern void _ctx_start(ucontext_t *, int argc, ...); + +void +_ctx_done (ucontext_t *ucp) +{ + if (ucp->uc_link == NULL) + exit(0); + else { + /* + * Since this context has finished, don't allow it + * to be restarted without being reinitialized (via + * setcontext or swapcontext). + */ + ucp->uc_mcsize = 0; + + /* Set context to next one in link */ + /* XXX - what to do for error, abort? */ + setcontext((const ucontext_t *)ucp->uc_link); + abort(); /* should never get here */ + } +} + +void +makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...) +{ + va_list ap; + char *stack_top; + intptr_t *argp; + int i; + + if (ucp == NULL) + return; + else if ((ucp->uc_stack.ss_sp == NULL) || + (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { + /* + * This should really return -1 with errno set to ENOMEM + * or something, but the spec says that makecontext is + * a void function. At least make sure that the context + * isn't valid so it can't be used without an error. + */ + ucp->uc_mcsize = 0; + } + /* XXX - Do we want to sanity check argc? */ + else if ((argc < 0) || (argc > NCARGS)) { + ucp->uc_mcsize = 0; + } + /* Make sure the context is valid. */ + else { + /* + * Arrange the stack as follows: + * + * _ctx_start() - context start wrapper + * start() - user start routine + * arg1 - first argument, aligned(16) + * ... + * argn + * ucp - this context, %ebp points here + * + * When the context is started, control will return to + * the context start wrapper which will pop the user + * start routine from the top of the stack. After that, + * the top of the stack will be setup with all arguments + * necessary for calling the start routine. When the + * start routine returns, the context wrapper then sets + * the stack pointer to %ebp which was setup to point to + * the base of the stack (and where ucp is stored). It + * will then call _ctx_done() to swap in the next context + * (uc_link != 0) or exit the program (uc_link == 0). + */ + mcontext_t mc; + + stack_top = (char *)(ucp->uc_stack.ss_sp + + ucp->uc_stack.ss_size - sizeof(intptr_t)); + + /* + * Adjust top of stack to allow for 3 pointers (return + * address, _ctx_start, and ucp) and argc arguments. + * We allow the arguments to be pointers also. The first + * argument to the user function must be properly aligned. + */ + stack_top = stack_top - (sizeof(intptr_t) * (1 + argc)); + stack_top = (char *)((unsigned)stack_top & ~15); + stack_top = stack_top - (2 * sizeof(intptr_t)); + argp = (intptr_t *)stack_top; + + /* + * Setup the top of the stack with the user start routine + * followed by all of its aguments and the pointer to the + * ucontext. We need to leave a spare spot at the top of + * the stack because setcontext will move eip to the top + * of the stack before returning. + */ + *argp = (intptr_t)_ctx_start; /* overwritten with same value */ + argp++; + *argp = (intptr_t)start; + argp++; + + /* Add all the arguments: */ + va_start(ap, argc); + for (i = 0; i < argc; i++) { + *argp = va_arg(ap, intptr_t); + argp++; + } + va_end(ap); + + /* The ucontext is placed at the bottom of the stack. */ + *argp = (intptr_t)ucp; + + /* + * Set the machine context to point to the top of the + * stack and the program counter to the context start + * wrapper. Note that setcontext() pushes the return + * address onto the top of the stack, so allow for this + * by adjusting the stack downward 1 slot. Also set + * %esi to point to the base of the stack where ucp + * is stored. + */ + mc = ucp->uc_mcontext; + + mc->__ss.__esi = (int)argp; + mc->__ss.__ebp = 0; + mc->__ss.__esp = (int)stack_top + sizeof(caddr_t); + mc->__ss.__eip = (int)_ctx_start; + } +} + +#endif /* __i386__ */ diff --git a/mach/headers/task.h b/i386/gen/setcontext.c similarity index 69% rename from mach/headers/task.h rename to i386/gen/setcontext.c index 84799c2..022a74a 100644 --- a/mach/headers/task.h +++ b/i386/gen/setcontext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,14 +20,23 @@ * * @APPLE_LICENSE_HEADER_END@ */ + #if defined(__i386__) -#include -#elif defined(__x86_64__) -#include -#elif defined(__ppc__) -#include -#elif defined(__ppc64__) -#include -#else -#error unknown architecture -#endif + +#define _XOPEN_SOURCE 600L + +#include + +extern int _setcontext(const ucontext_t *); + +int +setcontext(const ucontext_t *uctx) +{ + mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data; + ucontext_t *_uctx = (ucontext_t *)uctx; + if (mctx != _uctx->uc_mcontext) + _uctx->uc_mcontext = mctx; + return _setcontext(uctx); +} + +#endif /* __i386__ */ diff --git a/i386/gen/setjmperr.c b/i386/gen/setjmperr.c index 8dc2753..bf06595 100644 --- a/i386/gen/setjmperr.c +++ b/i386/gen/setjmperr.c @@ -41,6 +41,8 @@ static char sccsid[] = "@(#)setjmperr.c 5.4 (Berkeley) 6/27/88"; #endif /* LIBC_SCCS and not lint */ +#include + /* * This routine is called from longjmp() when an error occurs. * Programs that wish to exit gracefully from this error may diff --git a/i386/gen/swapcontext.c b/i386/gen/swapcontext.c new file mode 100644 index 0000000..2c8145c --- /dev/null +++ b/i386/gen/swapcontext.c @@ -0,0 +1,81 @@ +/* + * 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@ + */ + +/* + * Copyright (c) 2001 Daniel M. Eischen + * 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. Neither the name of the author 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 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. + */ + +#if defined(__i386__) + +#include +#include +#include +#include + +#include +#include + +#define uc_flags uc_onstack +#define UCF_SWAPPED 0x80000000 + +int +swapcontext(ucontext_t *oucp, const ucontext_t *ucp) +{ + int ret; + + if ((oucp == NULL) || (ucp == NULL)) { + errno = EINVAL; + return (-1); + } + oucp->uc_flags &= ~UCF_SWAPPED; + ret = getcontext(oucp); + if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) { + oucp->uc_flags |= UCF_SWAPPED; + ret = setcontext(ucp); + } + return (ret); +} + +#endif /* __i386__ */ diff --git a/i386/mach/Makefile.inc b/i386/mach/Makefile.inc index 12bb5f4..ece2aa4 100644 --- a/i386/mach/Makefile.inc +++ b/i386/mach/Makefile.inc @@ -1,2 +1,3 @@ .PATH: ${.CURDIR}/i386/mach -MDSRCS += mach_absolute_time.c + +MDSRCS += mach_absolute_time.s diff --git a/x86_64/sys/__ioctl.s b/i386/mach/mach_absolute_time.s similarity index 86% rename from x86_64/sys/__ioctl.s rename to i386/mach/mach_absolute_time.s index 5256103..71e7462 100644 --- a/x86_64/sys/__ioctl.s +++ b/i386/mach/mach_absolute_time.s @@ -20,10 +20,13 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include -PSEUDO(__ioctl, ioctl, 3) - ret +#include + + + .text + .align 2 + .globl _mach_absolute_time +_mach_absolute_time: + movl $(_COMM_PAGE_NANOTIME), %eax + jmpl *%eax diff --git a/i386/pthreads/Makefile.inc b/i386/pthreads/Makefile.inc index f2cfb8f..b251d6b 100644 --- a/i386/pthreads/Makefile.inc +++ b/i386/pthreads/Makefile.inc @@ -4,4 +4,6 @@ MDSRCS += \ get_cpu_capabilities.s \ pthread_set_self.s \ pthread_self.s \ - pthread_getspecific.s + pthread_getspecific.s \ + start_wqthread.s \ + thread_start.s diff --git a/i386/pthreads/init_cpu_capabilities.c b/i386/pthreads/init_cpu_capabilities.c index 94e5d33..51448d7 100644 --- a/i386/pthreads/init_cpu_capabilities.c +++ b/i386/pthreads/init_cpu_capabilities.c @@ -27,8 +27,6 @@ #include #undef _APPLE_API_PRIVATE -extern int _get_cpu_capabilities(void); - int _cpu_has_altivec = 0; // DEPRECATED int _cpu_capabilities = 0; diff --git a/i386/pthreads/start_wqthread.s b/i386/pthreads/start_wqthread.s new file mode 100644 index 0000000..77be643 --- /dev/null +++ b/i386/pthreads/start_wqthread.s @@ -0,0 +1,42 @@ +/* + * 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 "pthread_machdep.h" + +.text +.align 2, 0x90 +.globl _start_wqthread +_start_wqthread: +// This routine is never called directly by user code, jumped from kernel + push %ebp + mov %esp,%ebp + sub $28,%esp // align the stack + mov %edi,16(%esp) //arg5 + mov %edx,12(%esp) //arg4 + mov %ecx,8(%esp) //arg3 + mov %ebx,4(%esp) //arg2 + mov %eax,(%esp) //arg1 + call __pthread_wqthread + leave + ret + diff --git a/i386/pthreads/thread_start.s b/i386/pthreads/thread_start.s new file mode 100644 index 0000000..8c34cb2 --- /dev/null +++ b/i386/pthreads/thread_start.s @@ -0,0 +1,43 @@ +/* + * 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 "pthread_machdep.h" + +.text +.align 2, 0x90 +.globl _thread_start +_thread_start: +// This routine is never called directly by user code, jumped from kernel + push %ebp + mov %esp,%ebp + sub $28,%esp // align the stack + mov %esi,20(%esp) //arg6 + mov %edi,16(%esp) //arg5 + mov %edx,12(%esp) //arg4 + mov %ecx,8(%esp) //arg3 + mov %ebx,4(%esp) //arg2 + mov %eax,(%esp) //arg1 + call __pthread_start + leave + ret + diff --git a/i386/stdlib/gdtoa.mk b/i386/stdlib/gdtoa.mk index 6a6a67d..a1b51f0 100644 --- a/i386/stdlib/gdtoa.mk +++ b/i386/stdlib/gdtoa.mk @@ -1,2 +1,2 @@ # Long double is 80 bits -FBSDSRCS+=gdtoa_strtopx.c machdep_ldisx.c +GDTOA_FBSDSRCS+= gdtoa_strtopx.c machdep_ldisx.c diff --git a/i386/string/Makefile.inc b/i386/string/Makefile.inc index bfccaae..9194b2f 100644 --- a/i386/string/Makefile.inc +++ b/i386/string/Makefile.inc @@ -7,8 +7,11 @@ .PATH: ${.CURDIR}/i386/string MDSRCS += bcopy.s \ bzero.s \ + ffs.s \ memcpy.s \ memmove.s \ + strlcat.s \ + strlcpy.s \ strlen.s \ strcpy.s \ strcmp.s \ diff --git a/i386/string/bcopy.s b/i386/string/bcopy.s index d5fa77a..34672bf 100644 --- a/i386/string/bcopy.s +++ b/i386/string/bcopy.s @@ -25,7 +25,6 @@ * Call the comm page routines */ -#define __APPLE_API_PRIVATE #include #include diff --git a/mach/headers/vm_task.h b/i386/string/ffs.s similarity index 74% rename from mach/headers/vm_task.h rename to i386/string/ffs.s index a8ab751..53087ec 100644 --- a/mach/headers/vm_task.h +++ b/i386/string/ffs.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,10 +20,29 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* -** This file contains compatibilty wrapper header for things that are -** generated from mach/vm_map.defs into mach/vm_map.h. -** -** This file will go away eventually - please switch. -*/ -#include + + + .text + + .align 2 + .globl _ffs +_ffs: + .globl _ffsl +_ffsl: + movl $(-1), %edx + bsfl 4(%esp), %eax + cmovel %edx, %eax + incl %eax + ret + + + .align 2 + .globl _fls +_fls: + .globl _flsl +_flsl: + movl $(-1), %edx + bsrl 4(%esp), %eax + cmovel %edx, %eax + incl %eax + ret diff --git a/i386/string/strlcat.s b/i386/string/strlcat.s new file mode 100644 index 0000000..d165cfc --- /dev/null +++ b/i386/string/strlcat.s @@ -0,0 +1,243 @@ +/* + * 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@ + */ + + +// ***************** +// * S T R L C A T * +// ***************** +// +// size_t strlcat(char *dst, const char *src, size_t size); +// +// We use SSE to do the initial strlen(), and word-parallel copies +// to do the move. This appears to be faster than either all SSE +// or all word-parallel, at least on Core2 class machines. +// +// Using 4- or 16-byte parallel loops introduce a complication: +// if we blindly did parallel load/stores until finding +// a 0, we might get a spurious page fault by touching bytes past it. +// To avoid this, we never do a load that crosses a page boundary, +// or store unnecessary bytes. +// +// The word parallel test for 0s relies on the following inobvious +// but very efficient test: +// x = dataWord + 0xFEFEFEFF +// y = ~dataWord & 0x80808080 +// if (x & y) == 0 then no zero found +// The test maps any non-zero byte to zero, and any zero byte to 0x80, +// with one exception: 0x01 bytes preceeding the first zero are also +// mapped to 0x80. +// +// On Core2 class machines, this algorithm seems to be faster than the +// naive byte-by-byte version for operands longer than about 10 bytes. + + .text + .globl _strlcat + + .align 4 +_strlcat: // size_t *strlcat(char *dst, const char *src, size_t size); + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%edi // get dest ptr + movl 20(%esp),%esi // get source ptr + movl 24(%esp),%ebx // get length of buffer + + +// Use SSE to find the 0-byte at current end of buffer. +// This is just a minor variant of strlen(). + + movl %edi,%ecx // copy buffer ptr + andl $(-16),%edi // 16-byte align buffer ptr + pxor %xmm0,%xmm0 // get some 0s + andl $15,%ecx // get #bytes in dq before start of buffer + movl $16,%edx + orl $(-1),%eax + subl %ecx,%edx // #bytes from buffer start to end of dq + subl %edx,%ebx // does buffer end before end of dq? + jb LShortBuf1 // yes, drop into byte-by-byte mode + movdqa (%edi),%xmm1 // get first aligned chunk of buffer + addl $16,%edi + pcmpeqb %xmm0,%xmm1 // check for 0s + shl %cl,%eax // create mask for the bytes of aligned dq in operand + pmovmskb %xmm1,%ecx // collect mask of 0-bytes + andl %eax,%ecx // mask out any 0s that occur before buffer start + jnz 2f // found end of buffer +1: + subl $16,%ebx // another dq in buffer? + jb LShortBuf2 // no, drop into byte-by-byte mode + movdqa (%edi),%xmm1 // get next chunk + addl $16,%edi + pcmpeqb %xmm0,%xmm1 // check for 0s + pmovmskb %xmm1,%ecx // collect mask of 0-bytes + testl %ecx,%ecx // any 0-bytes? + jz 1b // no +2: + bsf %ecx,%edx // find first 1-bit (ie, first 0-byte) + subl $16,%edi // back up ptr into buffer + addl $16,%ebx // recover length remaining as of start of dq + addl %edx,%edi // point to 0-byte + subl %edx,%ebx // compute #bytes remaining in buffer + + +// Copy byte-by-byte until source is 4-byte aligned. +// %edi = points to 1st byte available in buffer +// %esi = src ptr +// %ebx = buffer length remaining (ie, starting at %edi) +// +// NB: the rest of this code is cut-and-pasted from strlcpy(). + + movl %esi,%edx // copy source ptr + negl %edx + andl $3,%edx // how many bytes to align source ptr? + jz LAligned // already aligned + + +// Loop over bytes. +// %edi = dest ptr +// %esi = source ptr +// %ebx = length remaining in buffer +// %edx = number of bytes to copy (>0, may not fit in buffer) + +LLoopOverBytes: + movzb (%esi),%eax // get source byte before checking buffer length + testl %ebx,%ebx // buffer full? + jz L0NotFound // yes + inc %esi + dec %ebx + movb %al,(%edi) // pack into dest + inc %edi + testl %eax,%eax // 0? + jz LDone // yes, done + dec %edx // more to go? + jnz LLoopOverBytes + + +// Source is aligned. Loop over words until end of buffer. We +// align the source, rather than the dest, to avoid getting spurious page faults. +// %edi = dest ptr (unaligned) +// %esi = source ptr (word aligned) +// %ebx = length remaining in buffer + +LAligned: + movl $5,%edx // if buffer almost exhausted, prepare to copy rest byte-by-byte + cmpl $4,%ebx // enough for at least one word? + jb LLoopOverBytes + + +// Loop over words. +// %edi = dest ptr (unaligned) +// %esi = source ptr (word aligned) +// %ebx = length remaining in buffer (>=4) + +LLoopOverWords: + movl (%esi),%eax // get next 4 bytes of source + subl $4,%ebx + addl $4,%esi + movl %eax,%edx // make 2 copies of word + movl %eax,%ecx + notl %edx // use magic word-parallel test for 0s + addl $0xFEFEFEFF,%ecx + andl $0x80808080,%edx + testl %ecx,%edx + jnz L0Found // one of the bytes of %eax is a 0 + movl %eax,(%edi) // pack 4 bytes into destination + addl $4,%edi + cmpl $4,%ebx // room in buffer for another word? + jae LLoopOverWords // yes + + movl %ebx,%edx // copy leftovers in byte loop + jmp LLoopOverBytes + +// Found a 0-byte in the word of source. Store a byte at a time until the 0. +// %edi = dest ptr (unaligned) +// %eax = last word of source, known to have a 0-byte + +LNextByte: + shrl $8,%eax // next byte +L0Found: + movb %al,(%edi) // pack in next byte + incl %edi + testb %al,%al // 0? + jnz LNextByte + +// Done storing string. +// %edi = ptr to byte after 0-byte + +LDone: + subl 16(%esp),%edi // subtract original dest ptr to get length stored + decl %edi // don't count the 0-byte + movl %edi,%eax // copy to return value +LExit: + popl %ebx + popl %esi + popl %edi + ret + +// Buffer filled but 0-byte not found. We return the length of the buffer plus the length +// of the source string. This is not optimized, as it is an error condition. +// %edi = dest ptr (ie, 1 past end of buffer) +// %esi = source ptr (ptr to 1st byte that does not fit) + +L0NotFound: + movl 24(%esp),%eax // reload buffer length + testl %eax,%eax // null? + jz LScanSourceTo0 // yes, cannot store a 0 + xorl %edx,%edx // get a 0 + movb %dl,-1(%edi) // store a 0 at end of buffer to delimit string +LScanSourceTo0: + movzb (%esi),%edx // get next byte of source + incl %esi + incl %eax + testl %edx,%edx // 0? + jnz LScanSourceTo0 + decl %eax // don't count the 0-byte + jmp LExit + + +// Buffer too short to reach end of even one 16-byte aligned chunk. +// %esi = src ptr + +LShortBuf1: + movl 16(%esp),%edi // recover ptr to start of buffer + movl 24(%esp),%ebx // recover buffer length + jmp LShortBuf3 + + +// Out of aligned dq's of buffer, 0-byte still not found. +// %esi = src ptr +// %edi = 1st buffer byte not checked for 0 +// %ebx = length remaining - 16 + +LShortBuf2: + addl $16,%ebx // length remaining +LShortBuf3: + movl 24(%esp),%eax // recover original buffer length, in case 0-byte not found + movl $17,%edx // buffer almost exhausted, prepare to copy byte-by-byte +1: + testl %ebx,%ebx // no 0s in buffer at all? + jz LScanSourceTo0 // yes, cannot store a 0 + cmpb $0,(%edi) // is this the 0? + jz LLoopOverBytes // yes, append source + incl %edi + decl %ebx + jmp 1b // loop looking for 0 diff --git a/i386/string/strlcpy.s b/i386/string/strlcpy.s new file mode 100644 index 0000000..21a366c --- /dev/null +++ b/i386/string/strlcpy.s @@ -0,0 +1,167 @@ +/* + * 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@ + */ + + +// ***************** +// * S T R L C P Y * +// ***************** +// +// size_t strlcpy(char *dst, const char *src, size_t size); +// +// We optimize the move by doing it word parallel. This introduces +// a complication: if we blindly did word load/stores until finding +// a 0, we might get a spurious page fault by touching bytes past it. +// To avoid this, we never do a load that crosses a page boundary, +// or store unnecessary bytes. +// +// The test for 0s relies on the following inobvious but very efficient +// word-parallel test: +// x = dataWord + 0xFEFEFEFF +// y = ~dataWord & 0x80808080 +// if (x & y) == 0 then no zero found +// The test maps any non-zero byte to zero, and any zero byte to 0x80, +// with one exception: 0x01 bytes preceeding the first zero are also +// mapped to 0x80. +// +// On Core2 class machines, this word-parallel implementation seems to +// be slightly faster than using SSE up to about 100 bytes. +// It is faster than the naive byte-by-byte implementation for +// operands longer than about 8 bytes. + + .text + .globl _strlcpy + + .align 4 +_strlcpy: // size_t *strlcpy(char *dst, const char *src, size_t size); + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%edi // get dest ptr + movl 20(%esp),%esi // get source ptr + movl 24(%esp),%ecx // get length of buffer + movl %esi,%edx // copy source ptr + negl %edx + andl $3,%edx // how many bytes to align source ptr? + jz LAligned // already aligned + + +// Loop over bytes. +// %edi = dest ptr +// %esi = source ptr +// %ecx = length remaining in buffer +// %edx = number of bytes to copy (>0, may not fit in buffer) + +LLoopOverBytes: + movzb (%esi),%eax // get source byte before checking buffer length + testl %ecx,%ecx // buffer full? + jz L0NotFound // yes + inc %esi + dec %ecx + movb %al,(%edi) // pack into dest + inc %edi + testl %eax,%eax // 0? + jz LDone // yes, done + dec %edx // more to go? + jnz LLoopOverBytes + + +// Source is aligned. Loop over words until end of buffer. We +// align the source, rather than the dest, to avoid getting spurious page faults. +// %edi = dest ptr (unaligned) +// %esi = source ptr (word aligned) +// %ecx = length remaining in buffer + +LAligned: + movl $5,%edx // if buffer almost exhausted, prepare to copy rest byte-by-byte + cmpl $4,%ecx // enough for at least one word? + jb LLoopOverBytes + + +// Loop over words. +// %edi = dest ptr (unaligned) +// %esi = source ptr (word aligned) +// %ecx = length remaining in buffer (>=4) + +LLoopOverWords: + movl (%esi),%eax // get next 4 bytes of source + subl $4,%ecx + addl $4,%esi + movl %eax,%edx // make 2 copies of word + movl %eax,%ebx + notl %edx // use magic word-parallel test for 0s + addl $0xFEFEFEFF,%ebx + andl $0x80808080,%edx + testl %ebx,%edx + jnz L0Found // one of the bytes of %eax is a 0 + movl %eax,(%edi) // pack 4 bytes into destination + addl $4,%edi + cmpl $4,%ecx // room in buffer for another word? + jae LLoopOverWords // yes + + movl %ecx,%edx // copy leftovers in byte loop + jmp LLoopOverBytes + +// Found a 0-byte in the word of source. Store a byte at a time until the 0. +// %edi = dest ptr (unaligned) +// %eax = last word of source, known to have a 0-byte + +LNextByte: + shrl $8,%eax // next byte +L0Found: + movb %al,(%edi) // pack in next byte + incl %edi + testb %al,%al // 0? + jnz LNextByte + +// Done storing string. +// %edi = ptr to byte after 0-byte + +LDone: + subl 16(%esp),%edi // subtract original dest ptr to get length stored + decl %edi // don't count the 0-byte + movl %edi,%eax // copy to return value +LExit: + popl %ebx + popl %esi + popl %edi + ret + +// Buffer filled but 0-byte not found. We return the length of the source string. +// This is not optimized, as it is an error condition. +// %edi = dest ptr (ie, 1 past end of buffer) +// %esi = source ptr (ptr to 1st byte that does not fit) + +L0NotFound: + movl 24(%esp),%eax // reload buffer length + testl %eax,%eax // null? + jz 1f // yes, cannot store a 0 + xorl %edx,%edx // get a 0 + movb %dl,-1(%edi) // store a 0 at end of buffer to delimit string +1: + movzb (%esi),%edx // get next byte of source + incl %esi + incl %eax + testl %edx,%edx // 0? + jnz 1b + decl %eax // don't count the 0-byte + jmp LExit diff --git a/i386/sys/ATPgetreq.s b/i386/sys/ATPgetreq.s deleted file mode 100644 index 7208af1..0000000 --- a/i386/sys/ATPgetreq.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(ATPgetreq, 3) - ret diff --git a/i386/sys/ATPgetrsp.s b/i386/sys/ATPgetrsp.s deleted file mode 100644 index c16193c..0000000 --- a/i386/sys/ATPgetrsp.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(ATPgetrsp, 3) - ret diff --git a/i386/sys/ATPsndreq.s b/i386/sys/ATPsndreq.s deleted file mode 100644 index 8955faf..0000000 --- a/i386/sys/ATPsndreq.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(ATPsndreq, 3) - ret diff --git a/i386/sys/ATPsndrsp.s b/i386/sys/ATPsndrsp.s deleted file mode 100644 index eee1744..0000000 --- a/i386/sys/ATPsndrsp.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(ATPsndrsp, 3) - ret diff --git a/i386/sys/ATgetmsg.s b/i386/sys/ATgetmsg.s deleted file mode 100644 index 6d55929..0000000 --- a/i386/sys/ATgetmsg.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(ATgetmsg, 3) - ret diff --git a/i386/sys/ATputmsg.s b/i386/sys/ATputmsg.s deleted file mode 100644 index 56344c8..0000000 --- a/i386/sys/ATputmsg.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(ATputmsg, 3) - ret diff --git a/i386/sys/ATsocket.s b/i386/sys/ATsocket.s deleted file mode 100644 index bdde188..0000000 --- a/i386/sys/ATsocket.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(ATsocket, 3) - ret diff --git a/i386/sys/Makefile.inc b/i386/sys/Makefile.inc index b16c248..c3e1688 100644 --- a/i386/sys/Makefile.inc +++ b/i386/sys/Makefile.inc @@ -1,231 +1,11 @@ .PATH: ${.CURDIR}/i386/sys AINC+= -I${.CURDIR}/i386/sys -MDSRCS+= ATPgetreq.s \ - ATPgetrsp.s \ - ATPsndreq.s \ - ATPsndrsp.s \ - ATgetmsg.s \ - ATputmsg.s \ - ATsocket.s \ - _exit.s \ - _getlogin.s \ - __mmap.s \ - _pthread_kill.s \ - __pthread_canceled.s \ - __pthread_markcancel.s \ - __semwait_signal.s \ - __sysenter_trap.s \ - _setjmp.s \ - _setlogin.s \ - _sysctl.s \ - accept.s \ - access.s \ - acct.s \ - add_profil.s \ - adjtime.s \ - aio_cancel.s \ - aio_error.s \ - aio_fsync.s \ - aio_read.s \ - aio_return.s \ - aio_suspend.s \ - aio_write.s \ - audit.s \ - auditctl.s \ - auditon.s \ - bind.s \ - cerror.s \ - chdir.s \ - checkuseraccess.s \ - chflags.s \ - chmod.s \ - chown.s \ - commpage.c \ - chroot.s \ - close.s \ - connect.s \ - dup.s \ - dup2.s \ - exchangedata.s \ - execve.s \ - fchdir.s \ - fchflags.s \ - fchmod.s \ - fchown.s \ - fcntl.s \ - fgetxattr.s \ - fhopen.s \ - flistxattr.s \ - flock.s \ - fork.s \ - fpathconf.s \ - fremovexattr.s \ - fsctl.s \ - fsetxattr.s \ - fstat.s \ - fstatfs.s \ - fstatv.s \ - fsync.s \ - ftruncate.s \ - futimes.s \ - getattrlist.s \ - getaudit.s \ - getaudit_addr.s \ - getauid.s \ - getdirentries.s \ - getdirentriesattr.s \ - getdtablesize.s \ - getegid.s \ - geteuid.s \ - getfh.s \ - getfsstat.s \ - getgid.s \ - getgroups.s \ - getitimer.s \ - getpeername.s \ - getpgid.s \ - getpgrp.s \ - getpid.s \ - getppid.s \ - getpriority.s \ - getrlimit.s \ - getrusage.s \ - getsid.s \ - getsockname.s \ - getsockopt.s \ - getuid.s \ - getxattr.s \ + +MDSRCS+= OSAtomic.s \ i386_gettimeofday.s \ - i386_get_ldt.s \ - i386_set_ldt.s \ - ioctl.s \ - issetugid.s \ - kevent.s \ - kill.s \ - kqueue.s \ - kqueue_from_portset_np.s \ - kqueue_portset_np.s \ - ktrace.s \ - lchown.s \ - link.s \ - lio_listio.s \ - listen.s \ - listxattr.s \ - load_shared_file.s \ - lseek.s \ - lstat.s \ - lstatv.s \ - madvise.s \ - mincore.s \ - minherit.s \ - mkcomplex.s \ - mkdir.s \ - mkfifo.s \ - mknod.s \ - mlock.s \ - mlockall.s \ - mount.s \ - msgget.s \ - msgrcv.s \ - msgsnd.s \ - msgsys.s \ - munlock.s \ - munlockall.s \ - new_system_shared_regions.s \ - nfsclnt.s \ - nfssvc.s \ - open.s \ - OSAtomic.s \ - pathconf.s \ - pipe.s \ - poll.s \ - posix_madvise.s \ - pread.s \ - profil.s \ - pthread_sigmask.s \ - ptrace.s \ - pwrite.s \ - quota.s \ - quotactl.s \ - read.s \ - readlink.s \ - readv.s \ - reboot.s \ - recvfrom.s \ - recvmsg.s \ - removexattr.s \ - rename.s \ - reset_shared_file.s \ - revoke.s \ - rmdir.s \ - searchfs.s \ - select.s \ - sem_close.s \ - sem_destroy.s \ - sem_getvalue.s \ - sem_init.s \ - sem_post.s \ - sem_trywait.s \ - sem_wait.s \ - semget.s \ - semop.s \ - semsys.s \ - sendmsg.s \ - sendto.s \ - setattrlist.s \ - setaudit.s \ - setaudit_addr.s \ - setauid.s \ - setegid.s \ - seteuid.s \ - setgid.s \ - setgroups.s \ - setitimer.s \ + _setjmp.s \ setjmp.s \ - setpgid.s \ - setpriority.s \ - setprivexec.s \ - setquota.s \ - setrlimit.s \ - setsid.s \ - setsockopt.s \ - settimeofday.s \ - setuid.s \ - setxattr.s \ - shmat.s \ - shmdt.s \ - shmget.s \ - shmsys.s \ - shutdown.s \ - sigaltstack.s \ - sigpending.s \ - sigprocmask.s \ - sigreturn.s \ - sigwait.s \ - socket.s \ - socketpair.s \ - stat.s \ - statfs.s \ - statv.s \ - swapon.s \ - symlink.s \ - sync.s \ - syscall.s \ - systable.s \ - truncate.s \ - umask.s \ - undelete.s \ - unlink.s \ - unmount.s \ - utimes.s \ - vfork.s \ - wait4.s \ - write.s \ - writev.s - -.for _src in fhopen.s getfh.s nfsclnt.s -CFLAGS-${_src} += -DNFSCLIENT -.endfor + _sigtramp.s -CFLAGS-nfssvc.s += -DNFSSERVER +MDCOPYFILES+= ${.CURDIR}/i386/sys/libc.syscall.i386 diff --git a/i386/sys/OSAtomic.s b/i386/sys/OSAtomic.s index 23fd9f2..3524074 100644 --- a/i386/sys/OSAtomic.s +++ b/i386/sys/OSAtomic.s @@ -1,5 +1,6 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -65,15 +66,48 @@ DECLARE(_OSAtomicXor32) movl %edx, %eax 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 + 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 + 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 + 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 sete %al + movzbl %al,%eax // widen in case caller assumes we return an int ret -.align 2, 0x90 DECLARE(_OSAtomicCompareAndSwap64) pushl %ebx pushl %esi @@ -84,6 +118,7 @@ DECLARE(_OSAtomicCompareAndSwap64) movl 28(%esp), %esi call *_COMM_PAGE_COMPARE_AND_SWAP64 sete %al + movzbl %al,%eax // widen in case caller assumes we return an int popl %esi popl %ebx ret @@ -124,6 +159,7 @@ DECLARE(_OSAtomicTestAndSet) orl %ecx, %eax call *_COMM_PAGE_BTS setc %al + movzbl %al,%eax // widen in case caller assumes we return an int ret DECLARE(_OSAtomicTestAndClear) @@ -136,28 +172,99 @@ DECLARE(_OSAtomicTestAndClear) orl %ecx, %eax call *_COMM_PAGE_BTC setc %al + movzbl %al,%eax // widen in case caller assumes we return an int ret -.align 2, 0x90 -.globl _OSSpinLockTry + .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 + .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 + .align 2, 0x90 + .globl _OSSpinLockUnlock + .globl _spin_unlock + .globl __spin_unlock _OSSpinLockUnlock: +_spin_unlock: +__spin_unlock: movl 4(%esp), %eax movl $0, (%eax) ret -.align 2, 0x90 -.globl _OSMemoryBarrier + .align 2, 0x90 + .globl _OSMemoryBarrier _OSMemoryBarrier: + movl $(_COMM_PAGE_MEMORY_BARRIER), %eax + jmpl *%eax + +/* + * 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: + 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 + lock // always lock for now... + cmpxchg8b (%edi) // ...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: + 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 + lock // always lock for now... + cmpxchg8b (%edi) // ...pop off 1st element + jnz 1b +2: + popl %ebx + popl %esi + popl %edi + ret // ptr to 1st element in Q still in %eax + diff --git a/i386/sys/SYS.h b/i386/sys/SYS.h index 12de2b4..8105028 100644 --- a/i386/sys/SYS.h +++ b/i386/sys/SYS.h @@ -99,31 +99,11 @@ LEAF(_##name, 0) ;\ LEAF(_##pseudo, 0) ;\ UNIX_SYSCALL_NONAME(name, nargs) -#if !defined(SYS_getdirentriesattr) -#define SYS_getdirentriesattr 222 -#endif - -#if !defined(SYS_semsys) -#define SYS_semsys 251 -#define SYS_msgsys 252 -#define SYS_shmsys 253 -#define SYS_semctl 254 -#define SYS_semget 255 -#define SYS_semop 256 -/*#define SYS_semconfig 257*/ -#define SYS_msgctl 258 -#define SYS_msgget 259 -#define SYS_msgsnd 260 -#define SYS_msgrcv 261 -#define SYS_shmat 262 -#define SYS_shmctl 263 -#define SYS_shmdt 264 -#define SYS_shmget 265 -#endif - -#if !defined(SYS___pthread_canceled) -#define SYS___pthread_markcancel 332 -#define SYS___pthread_canceled 333 -#define SYS___semwait_signal 334 -#endif - +#define PSEUDO_ERR(pseudo, name, nargs, error_ret) \ + .globl error_ret ;\ +LEAF(_##pseudo, 0) ;\ + movl $ SYS_##name, %eax ;\ + UNIX_SYSCALL_SYSENTER ;\ + jnb 2f ;\ + BRANCH_EXTERN(error_ret) ;\ +2: diff --git a/i386/sys/__mmap.s b/i386/sys/__mmap.s deleted file mode 100644 index b22d9a3..0000000 --- a/i386/sys/__mmap.s +++ /dev/null @@ -1,26 +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 - -PSEUDO(__mmap, mmap, 6) - ret diff --git a/i386/sys/__pthread_canceled.s b/i386/sys/__pthread_canceled.s deleted file mode 100644 index 0475e96..0000000 --- a/i386/sys/__pthread_canceled.s +++ /dev/null @@ -1,29 +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) 2002 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(__pthread_canceled, 1) - ret diff --git a/i386/sys/__pthread_markcancel.s b/i386/sys/__pthread_markcancel.s deleted file mode 100644 index bed8c1e..0000000 --- a/i386/sys/__pthread_markcancel.s +++ /dev/null @@ -1,29 +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) 2002 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(__pthread_markcancel, 1) - ret diff --git a/i386/sys/__semwait_signal.s b/i386/sys/__semwait_signal.s deleted file mode 100644 index 370a578..0000000 --- a/i386/sys/__semwait_signal.s +++ /dev/null @@ -1,29 +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) 2002 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(__semwait_signal, 6) - ret diff --git a/i386/sys/_exit.s b/i386/sys/_exit.s deleted file mode 100644 index 2757478..0000000 --- a/i386/sys/_exit.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -PSEUDO(_exit, exit, 1) - ret diff --git a/i386/sys/_getlogin.s b/i386/sys/_getlogin.s deleted file mode 100644 index 47107fe..0000000 --- a/i386/sys/_getlogin.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -PSEUDO(_getlogin, getlogin, 0) - ret diff --git a/i386/sys/_pthread_kill.s b/i386/sys/_pthread_kill.s deleted file mode 100644 index 6d0f630..0000000 --- a/i386/sys/_pthread_kill.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(__pthread_kill, 2) - ret diff --git a/i386/sys/_setjmp.s b/i386/sys/_setjmp.s index 0d355c7..0390560 100644 --- a/i386/sys/_setjmp.s +++ b/i386/sys/_setjmp.s @@ -48,7 +48,7 @@ #define JB_MASK 4 #define JB_MXCSR 8 #define JB_EBX 12 -#define JB_ECX 16 +#define JB_ONSTACK 16 #define JB_EDX 20 #define JB_EDI 24 #define JB_ESI 28 diff --git a/i386/sys/_setlogin.s b/i386/sys/_setlogin.s deleted file mode 100644 index ca0d5b9..0000000 --- a/i386/sys/_setlogin.s +++ /dev/null @@ -1,30 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -PSEUDO(_setlogin, setlogin, 0) - ret - diff --git a/i386/sys/_sigtramp.s b/i386/sys/_sigtramp.s new file mode 100644 index 0000000..a8d2613 --- /dev/null +++ b/i386/sys/_sigtramp.s @@ -0,0 +1,246 @@ +/* + * 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 + +#if defined(__DYNAMIC__) + .globl ___in_sigtramp + .data + .align 2 +___in_sigtramp: + .space 4 +#endif + +#define UC_TRAD 1 +#define UC_FLAVOR 30 + +/* Structure fields for ucontext and mcontext. */ +#define UCONTEXT_UC_MCONTEXT 28 + +#define MCONTEXT_ES_EXCEPTION 0 +#define MCONTEXT_SS_EAX 12 +#define MCONTEXT_SS_EBX 16 +#define MCONTEXT_SS_ECX 20 +#define MCONTEXT_SS_EDX 24 +#define MCONTEXT_SS_EDI 28 +#define MCONTEXT_SS_ESI 32 +#define MCONTEXT_SS_EBP 36 +#define MCONTEXT_SS_ESP 40 +#define MCONTEXT_SS_EFLAGS 48 +#define MCONTEXT_SS_EIP 52 + +/* register use: + %ebp frame pointer + %ebx Address of "L00000000001$pb" + %esi uctx + +void +_sigtramp( + union __sigaction_u __sigaction_u, + int sigstyle, + int sig, + siginfo_t *sinfo, + ucontext_t *uctx +) +*/ + + .globl __sigtramp + .text + .align 4,0x90 +__sigtramp: + /* Although this routine does not need any stack frame, various parts + of the OS can't analyse the stack without them. */ + pushl %ebp + movl %esp, %ebp + subl $24, %esp + movl 8(%ebp), %ecx # get '__sigaction_u' +#if defined(__DYNAMIC__) + call 0f +"L00000000001$pb": +0: + popl %ebx + incl ___in_sigtramp-"L00000000001$pb"(%ebx) +#endif + movl 16(%ebp), %edx # get 'sig' + movl 20(%ebp), %eax # get 'sinfo' + movl 24(%ebp), %esi # get 'uctx' + /* Call the signal handler. + Some variants are not supposed to get the last two parameters, + but the test to prevent this is more expensive than just passing + them. */ + 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 + movl %esi, 4(%esp) + movl $ UC_FLAVOR, 8(%esp) + movl $ SYS_sigreturn, %eax + int $0x80 + +/* DWARF unwind table #defines. */ +#define DW_CFA_advance_loc_4 0x44 +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_def_cfa_expression 0x0F +#define DW_CFA_expression 0x10 +#define DW_CFA_val_expression 0x16 +#define DW_CFA_offset(column) 0x80+(column) + +/* DWARF expression #defines. */ +#define DW_OP_deref 0x06 +#define DW_OP_const1u 0x08 +#define DW_OP_dup 0x12 +#define DW_OP_drop 0x13 +#define DW_OP_over 0x14 +#define DW_OP_pick 0x15 +#define DW_OP_swap 0x16 +#define DW_OP_rot 0x17 +#define DW_OP_abs 0x19 +#define DW_OP_and 0x1a +#define DW_OP_div 0x1b +#define DW_OP_minus 0x1c +#define DW_OP_mod 0x1d +#define DW_OP_mul 0x1e +#define DW_OP_neg 0x1f +#define DW_OP_not 0x20 +#define DW_OP_or 0x21 +#define DW_OP_plus 0x22 +#define DW_OP_plus_uconst 0x23 +#define DW_OP_shl 0x24 +#define DW_OP_shr 0x25 +#define DW_OP_shra 0x26 +#define DW_OP_xor 0x27 +#define DW_OP_skip 0x2f +#define DW_OP_bra 0x28 +#define DW_OP_eq 0x29 +#define DW_OP_ge 0x2A +#define DW_OP_gt 0x2B +#define DW_OP_le 0x2C +#define DW_OP_lt 0x2D +#define DW_OP_ne 0x2E +#define DW_OP_lit(n) 0x30+(n) +#define DW_OP_breg(n) 0x70+(n) +#define DW_OP_deref_size 0x94 + +/* The location expression we'll use. */ + +#define loc_expr_for_reg(regno, offs) \ + .byte DW_CFA_expression, regno, 5 /* block length */, \ + DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \ + DW_OP_plus_uconst, offs + + /* Unwind tables. */ + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .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 # uleb128 0x1; CIE Code Alignment Factor + .byte 0x7c # sleb128 -4; CIE Data Alignment Factor + .byte 0x8 # CIE RA Column + .byte 0x1 # uleb128 0x1; Augmentation size + .byte 0x10 # FDE Encoding (pcrel) + .byte DW_CFA_def_cfa + .byte 0x5 # uleb128 0x5 + .byte 0x4 # uleb128 0x4 + .byte DW_CFA_offset(8) + .byte 0x1 # uleb128 0x1 + .align 2 +LECIE1: + .globl _sigtramp.eh +_sigtramp.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .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 L$set$2 # FDE address range + .byte 0x0 # uleb128 0x0; Augmentation size + + /* Now for the expressions, which all compute + uctx->uc_mcontext->register + for each register. + + Describe even the registers that are not call-saved because they + might be being used in the prologue to save other registers. + Only integer registers are described at present. */ + + loc_expr_for_reg (0, MCONTEXT_SS_EAX) + loc_expr_for_reg (1, MCONTEXT_SS_ECX) + loc_expr_for_reg (2, MCONTEXT_SS_EDX) + loc_expr_for_reg (3, MCONTEXT_SS_EBX) + loc_expr_for_reg (4, MCONTEXT_SS_EBP) # note that GCC switches + loc_expr_for_reg (5, MCONTEXT_SS_ESP) # DWARF registers 4 & 5 + loc_expr_for_reg (6, MCONTEXT_SS_ESI) + loc_expr_for_reg (7, MCONTEXT_SS_EDI) + loc_expr_for_reg (9, MCONTEXT_SS_EFLAGS) + + /* The Intel architecture classifies exceptions into three categories, + 'faults' which put the address of the faulting instruction + in EIP, 'traps' which put the following instruction in EIP, + and 'aborts' which don't typically report the instruction + causing the exception. + + The traps are #BP and #OF. */ + + .byte DW_CFA_val_expression, 8 + .set L$set$3,Lpc_end-Lpc_start + .byte L$set$3 +Lpc_start: + /* Push the mcontext address twice. */ + .byte DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref, DW_OP_dup + /* Find the value of EIP. */ + .byte DW_OP_plus_uconst, MCONTEXT_SS_EIP, DW_OP_deref, DW_OP_swap + /* Determine the exception type. */ + .byte DW_OP_plus_uconst, MCONTEXT_ES_EXCEPTION, DW_OP_deref + /* Check whether it is #BP (3) or #OF (4). */ + .byte DW_OP_dup, DW_OP_lit(3), DW_OP_ne + .byte DW_OP_swap, DW_OP_lit(4), DW_OP_ne, DW_OP_and + /* If it is, then add 1 to the instruction address, so as to point + within or past the faulting instruction. */ + .byte DW_OP_plus +Lpc_end: + + /* The CFA will have been saved as the value of ESP (it is not + ESP+4). */ + .byte DW_CFA_def_cfa_expression + .set L$set$4,Lcfa_end-Lcfa_start + .byte L$set$4 +Lcfa_start: + .byte DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref + .byte DW_OP_plus_uconst, MCONTEXT_SS_ESP, DW_OP_deref +Lcfa_end: + + .align 2 +LEFDE1: + + .subsections_via_symbols diff --git a/i386/sys/_sysctl.s b/i386/sys/_sysctl.s deleted file mode 100644 index b1157d7..0000000 --- a/i386/sys/_sysctl.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(__sysctl, 6) - ret diff --git a/i386/sys/access.s b/i386/sys/access.s deleted file mode 100644 index 1f0cbfd..0000000 --- a/i386/sys/access.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(access, 2) - ret diff --git a/i386/sys/acct.s b/i386/sys/acct.s deleted file mode 100644 index 5113338..0000000 --- a/i386/sys/acct.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(acct, 1) - ret diff --git a/i386/sys/add_profil.s b/i386/sys/add_profil.s deleted file mode 100644 index f29f838..0000000 --- a/i386/sys/add_profil.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(add_profil, 4) - ret diff --git a/i386/sys/adjtime.s b/i386/sys/adjtime.s deleted file mode 100644 index 4c4f26e..0000000 --- a/i386/sys/adjtime.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(adjtime, 2) - ret diff --git a/i386/sys/aio_cancel.s b/i386/sys/aio_cancel.s deleted file mode 100644 index 2070cb8..0000000 --- a/i386/sys/aio_cancel.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(aio_cancel, 2) - ret diff --git a/i386/sys/aio_error.s b/i386/sys/aio_error.s deleted file mode 100644 index 5a1f828..0000000 --- a/i386/sys/aio_error.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(aio_error, 1) - ret diff --git a/i386/sys/aio_fsync.s b/i386/sys/aio_fsync.s deleted file mode 100644 index a8445ba..0000000 --- a/i386/sys/aio_fsync.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(aio_fsync, 2) - ret diff --git a/i386/sys/aio_read.s b/i386/sys/aio_read.s deleted file mode 100644 index 4bafa16..0000000 --- a/i386/sys/aio_read.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(aio_read, 1) - ret diff --git a/i386/sys/aio_return.s b/i386/sys/aio_return.s deleted file mode 100644 index 6764958..0000000 --- a/i386/sys/aio_return.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(aio_return, 1) - ret diff --git a/i386/sys/aio_suspend.s b/i386/sys/aio_suspend.s deleted file mode 100644 index d7d740e..0000000 --- a/i386/sys/aio_suspend.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(aio_suspend, 3) - ret diff --git a/i386/sys/aio_write.s b/i386/sys/aio_write.s deleted file mode 100644 index 4229f0e..0000000 --- a/i386/sys/aio_write.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(aio_write, 1) - ret diff --git a/i386/sys/audit.s b/i386/sys/audit.s deleted file mode 100644 index 2b308ac..0000000 --- a/i386/sys/audit.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(audit, 2) - ret diff --git a/i386/sys/auditctl.s b/i386/sys/auditctl.s deleted file mode 100644 index 559a293..0000000 --- a/i386/sys/auditctl.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(auditctl, 1) - ret diff --git a/i386/sys/auditon.s b/i386/sys/auditon.s deleted file mode 100644 index 10d59d7..0000000 --- a/i386/sys/auditon.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(auditon, 3) - ret diff --git a/i386/sys/auditsvc.s b/i386/sys/auditsvc.s deleted file mode 100644 index 5efd544..0000000 --- a/i386/sys/auditsvc.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(auditsvc, 2) - ret diff --git a/i386/sys/chdir.s b/i386/sys/chdir.s deleted file mode 100644 index 7453e4b..0000000 --- a/i386/sys/chdir.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(chdir, 1) - ret diff --git a/i386/sys/checkuseraccess.s b/i386/sys/checkuseraccess.s deleted file mode 100644 index 09c24d6..0000000 --- a/i386/sys/checkuseraccess.s +++ /dev/null @@ -1,29 +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) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(checkuseraccess, 0) - ret diff --git a/i386/sys/chflags.s b/i386/sys/chflags.s deleted file mode 100644 index 099d9b0..0000000 --- a/i386/sys/chflags.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(chflags, 2) - ret diff --git a/i386/sys/chmod.s b/i386/sys/chmod.s deleted file mode 100644 index 02c3f0d..0000000 --- a/i386/sys/chmod.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(chmod, 2) - ret diff --git a/i386/sys/chown.s b/i386/sys/chown.s deleted file mode 100644 index 0fcafd7..0000000 --- a/i386/sys/chown.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(chown, 3) - ret diff --git a/i386/sys/chroot.s b/i386/sys/chroot.s deleted file mode 100644 index d8a30f9..0000000 --- a/i386/sys/chroot.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(chroot, 1) - ret diff --git a/i386/sys/close.s b/i386/sys/close.s deleted file mode 100644 index 2338bc4..0000000 --- a/i386/sys/close.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(close, 1) - ret diff --git a/i386/sys/connect.s b/i386/sys/connect.s deleted file mode 100644 index 51fa9d7..0000000 --- a/i386/sys/connect.s +++ /dev/null @@ -1,37 +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 (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#ifdef __LP64__ -UNIX_SYSCALL(connect, 3) - ret -#else /* !__LP64__ */ -PSEUDO(connect$UNIX2003, connect, 3) - ret - -UNIX_SYSCALL_ERR(connect, 3, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/dup.s b/i386/sys/dup.s deleted file mode 100644 index 60fcd92..0000000 --- a/i386/sys/dup.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(dup, 2) - ret diff --git a/i386/sys/dup2.s b/i386/sys/dup2.s deleted file mode 100644 index 74ea431..0000000 --- a/i386/sys/dup2.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(dup2, 2) - ret diff --git a/i386/sys/exchangedata.s b/i386/sys/exchangedata.s deleted file mode 100644 index e6a4a56..0000000 --- a/i386/sys/exchangedata.s +++ /dev/null @@ -1,29 +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) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(exchangedata, 0) - ret diff --git a/i386/sys/execve.s b/i386/sys/execve.s deleted file mode 100644 index 6a6759b..0000000 --- a/i386/sys/execve.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(execve, 3) - ret // execve(file, argv, arge) diff --git a/i386/sys/fchdir.s b/i386/sys/fchdir.s deleted file mode 100644 index fa458e2..0000000 --- a/i386/sys/fchdir.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fchdir, 1) - ret diff --git a/i386/sys/fchflags.s b/i386/sys/fchflags.s deleted file mode 100644 index f94f31f..0000000 --- a/i386/sys/fchflags.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fchflags, 2) - ret diff --git a/i386/sys/fchmod.s b/i386/sys/fchmod.s deleted file mode 100644 index 1f87d1f..0000000 --- a/i386/sys/fchmod.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fchmod, 2) - ret diff --git a/i386/sys/fchown.s b/i386/sys/fchown.s deleted file mode 100644 index 7c1eb13..0000000 --- a/i386/sys/fchown.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fchown, 3) - ret diff --git a/i386/sys/fcntl.s b/i386/sys/fcntl.s deleted file mode 100644 index 63dcabf..0000000 --- a/i386/sys/fcntl.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fcntl, 3) - ret diff --git a/i386/sys/fgetxattr.s b/i386/sys/fgetxattr.s deleted file mode 100644 index 14f1bd6..0000000 --- a/i386/sys/fgetxattr.s +++ /dev/null @@ -1,26 +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 - -UNIX_SYSCALL(fgetxattr, 5) - ret diff --git a/i386/sys/fhopen.s b/i386/sys/fhopen.s deleted file mode 100644 index a82c9af..0000000 --- a/i386/sys/fhopen.s +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 - -UNIX_SYSCALL(fhopen, 2) - ret diff --git a/i386/sys/flistxattr.s b/i386/sys/flistxattr.s deleted file mode 100644 index d953e2b..0000000 --- a/i386/sys/flistxattr.s +++ /dev/null @@ -1,26 +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 - -UNIX_SYSCALL(flistxattr, 4) - ret diff --git a/i386/sys/flock.s b/i386/sys/flock.s deleted file mode 100644 index 097fe49..0000000 --- a/i386/sys/flock.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(flock, 2) - ret diff --git a/i386/sys/fork.s b/i386/sys/fork.s deleted file mode 100644 index c78eb04..0000000 --- a/i386/sys/fork.s +++ /dev/null @@ -1,156 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -LEAF(_fork, 0) - subl $28, %esp // Align the stack, with 16 bytes of extra padding that we'll need - CALL_EXTERN(__cthread_fork_prepare) -#if defined(__DYNAMIC__) -// Just like __cthread_fork_prepare we need to prevent threads on the child's -// side from doing a mach call in the dynamic linker until __dyld_fork_child -// is run (see below). So we call __dyld_fork_prepare which takes out the dyld -// lock to prevent all other threads but this one from entering dyld. -.cstring -LC1: - .ascii "__dyld_fork_prepare\0" -.text - // Put a pointer to 8(%esp) in 4(%esp) for _dyld_func_lookup to fill in. - leal 0x8(%esp),%eax // get the address where we're going to store the pointer - movl %eax, 0x4(%esp) // copy the address of the pointer - call 1f -1: popl %eax - leal LC1-1b(%eax),%eax - movl %eax, 0x0(%esp) // copy the name of the function to look up - call __dyld_func_lookup - movl 0x8(%esp),%eax // move the value returned in address parameter - call *%eax // call __dyld_fork_prepare indirectly -#endif - - movl $ SYS_fork,%eax; // code for fork -> eax - UNIX_SYSCALL_TRAP // do the system call - jnc L1 // jump if CF==0 - -#if defined(__DYNAMIC__) -// __dyld_fork_parent() is called by the parent process after a fork syscall. -// This releases the dyld lock acquired by __dyld_fork_prepare(). In this case -// we just use it to clean up after a fork error so the parent process can -// dyld after fork() errors without deadlocking. -.cstring -LC2: - .ascii "__dyld_fork_parent\0" -.text - movl %eax, 0xc(%esp) // save the return value (errno) - leal 0x8(%esp),%eax // get the address where we're going to store the pointer - movl %eax, 0x4(%esp) // copy the address of the pointer - call 1f -1: popl %eax - leal LC2-1b(%eax),%eax - movl %eax, 0x0(%esp) // copy the name of the function to look up - call __dyld_func_lookup - movl 0x8(%esp),%eax // move the value returned in address parameter - call *%eax // call __dyld_fork_parent indirectly - movl 0xc(%esp), %eax // restore the return value (errno) -#endif - CALL_EXTERN(cerror) - CALL_EXTERN(__cthread_fork_parent) - movl $-1,%eax - addl $28, %esp // restore the stack - ret - -L1: - orl %edx,%edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child - - //child here... -#if defined(__DYNAMIC__) -// Here on the child side of the fork we need to tell the dynamic linker that -// we have forked. To do this we call __dyld_fork_child in the dyanmic -// linker. But since we can't dynamically bind anything until this is done we -// do this by using the private extern __dyld_func_lookup() function to get the -// address of __dyld_fork_child (the 'C' code equivlent): -// -// _dyld_func_lookup("__dyld_fork_child", &address); -// address(); -// -.cstring -LC0: - .ascii "__dyld_fork_child\0" - -.text - leal 0x8(%esp),%eax // get the address where we're going to store the pointer - movl %eax, 0x4(%esp) // copy the address of the pointer - call 1f -1: popl %eax - leal LC0-1b(%eax),%eax - movl %eax, 0x0(%esp) // copy the name of the function to look up - call __dyld_func_lookup - movl 0x8(%esp),%eax // move the value returned in address parameter - call *%eax // call __dyld_fork_child indirectly -#endif - xorl %eax, %eax - REG_TO_EXTERN(%eax, __current_pid) - CALL_EXTERN(__cthread_fork_child) -#if defined(__DYNAMIC__) -.cstring -LC10: - .ascii "__dyld_fork_child_final\0" - -.text - leal 0x8(%esp),%eax // get the address where we're going to store the pointer - movl %eax, 0x4(%esp) // copy the address of the pointer - call 1f -1: popl %eax - leal LC10-1b(%eax),%eax - movl %eax, 0x0(%esp) // copy the name of the function to look up - call __dyld_func_lookup - movl 0x8(%esp),%eax // move the value returned in address parameter - call *%eax // call __dyld_fork_child_final indirectly -#endif - xorl %eax,%eax // zero eax - addl $28, %esp // restore the stack - ret - - //parent here... -L2: - movl %eax, 0xc(%esp) // save pid -#if defined(__DYNAMIC__) -// __dyld_fork_parent() is called by the parent process after a fork syscall. -// This releases the dyld lock acquired by __dyld_fork_prepare(). - leal 0x8(%esp),%eax // get the address where we're going to store the pointer - movl %eax, 0x4(%esp) // copy the address of the allocated space - call 1f -1: popl %eax - leal LC2-1b(%eax),%eax - movl %eax, 0x0(%esp) // copy the name of the function to look up - call __dyld_func_lookup - movl 0x8(%esp),%eax // move the value returned in address parameter - call *%eax // call __dyld_fork_parent indirectly -#endif - CALL_EXTERN_AGAIN(__cthread_fork_parent) - movl 0xc(%esp), %eax // return pid - addl $28, %esp // restore the stack - ret - diff --git a/i386/sys/fpathconf.s b/i386/sys/fpathconf.s deleted file mode 100644 index a233793..0000000 --- a/i386/sys/fpathconf.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fpathconf, 2) - ret diff --git a/i386/sys/fremovexattr.s b/i386/sys/fremovexattr.s deleted file mode 100644 index 63831a4..0000000 --- a/i386/sys/fremovexattr.s +++ /dev/null @@ -1,26 +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 - -UNIX_SYSCALL(fremovexattr, 3) - ret diff --git a/i386/sys/fsctl.s b/i386/sys/fsctl.s deleted file mode 100644 index dae5f18..0000000 --- a/i386/sys/fsctl.s +++ /dev/null @@ -1,29 +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@ - */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fsctl, 4) - ret diff --git a/i386/sys/fsetxattr.s b/i386/sys/fsetxattr.s deleted file mode 100644 index e97b966..0000000 --- a/i386/sys/fsetxattr.s +++ /dev/null @@ -1,26 +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 - -UNIX_SYSCALL(fsetxattr, 5) - ret diff --git a/i386/sys/fstat.s b/i386/sys/fstat.s deleted file mode 100644 index 820f99a..0000000 --- a/i386/sys/fstat.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fstat, 2) - ret diff --git a/i386/sys/fstatfs.s b/i386/sys/fstatfs.s deleted file mode 100644 index 917cc77..0000000 --- a/i386/sys/fstatfs.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fstatfs, 2) - ret diff --git a/i386/sys/fstatv.s b/i386/sys/fstatv.s deleted file mode 100644 index 323c96a..0000000 --- a/i386/sys/fstatv.s +++ /dev/null @@ -1,29 +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) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fstatv, 0) - ret diff --git a/i386/sys/fsync.s b/i386/sys/fsync.s deleted file mode 100644 index 1818d21..0000000 --- a/i386/sys/fsync.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(fsync, 1) - ret diff --git a/i386/sys/ftruncate.s b/i386/sys/ftruncate.s deleted file mode 100644 index 0d5a07d..0000000 --- a/i386/sys/ftruncate.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(ftruncate, 2) - ret diff --git a/i386/sys/futimes.s b/i386/sys/futimes.s deleted file mode 100644 index b93a689..0000000 --- a/i386/sys/futimes.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(futimes, 2) - ret diff --git a/i386/sys/getaudit.s b/i386/sys/getaudit.s deleted file mode 100644 index ebf8a6f..0000000 --- a/i386/sys/getaudit.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(getaudit, 1) - ret diff --git a/i386/sys/getaudit_addr.s b/i386/sys/getaudit_addr.s deleted file mode 100644 index 4579234..0000000 --- a/i386/sys/getaudit_addr.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(getaudit_addr, 2) - ret diff --git a/i386/sys/getauid.s b/i386/sys/getauid.s deleted file mode 100644 index a6a09fd..0000000 --- a/i386/sys/getauid.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(getauid, 1) - ret diff --git a/i386/sys/getdirentries.s b/i386/sys/getdirentries.s deleted file mode 100644 index 2abc2bf..0000000 --- a/i386/sys/getdirentries.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getdirentries, 4) - ret diff --git a/i386/sys/getdirentriesattr.s b/i386/sys/getdirentriesattr.s deleted file mode 100644 index b69947e..0000000 --- a/i386/sys/getdirentriesattr.s +++ /dev/null @@ -1,29 +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) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getdirentriesattr, 0) - ret diff --git a/i386/sys/getdtablesize.s b/i386/sys/getdtablesize.s deleted file mode 100644 index 27bd6ad..0000000 --- a/i386/sys/getdtablesize.s +++ /dev/null @@ -1,27 +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 - -UNIX_SYSCALL(getdtablesize, 0) - ret // i = getdtablesize(); diff --git a/i386/sys/getegid.s b/i386/sys/getegid.s deleted file mode 100644 index 5b85e9c..0000000 --- a/i386/sys/getegid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getegid, 0) - ret diff --git a/i386/sys/geteuid.s b/i386/sys/geteuid.s deleted file mode 100644 index 40c1fe4..0000000 --- a/i386/sys/geteuid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(geteuid, 0) - ret diff --git a/i386/sys/getfh.s b/i386/sys/getfh.s deleted file mode 100644 index 8ce000a..0000000 --- a/i386/sys/getfh.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getfh, 2) - ret diff --git a/i386/sys/getgid.s b/i386/sys/getgid.s deleted file mode 100644 index 58d6d41..0000000 --- a/i386/sys/getgid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getgid, 0) - ret // gid = getgid(); diff --git a/i386/sys/getgroups.s b/i386/sys/getgroups.s deleted file mode 100644 index 61eb82c..0000000 --- a/i386/sys/getgroups.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getgroups, 2) - ret // ngroups = getgroups(gidsetsize, gidset) diff --git a/i386/sys/getitimer.s b/i386/sys/getitimer.s deleted file mode 100644 index e0d5c3b..0000000 --- a/i386/sys/getitimer.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getitimer, 2) - ret diff --git a/i386/sys/getpeername.s b/i386/sys/getpeername.s deleted file mode 100644 index d7b3a0d..0000000 --- a/i386/sys/getpeername.s +++ /dev/null @@ -1,37 +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 (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#ifdef __LP64__ -UNIX_SYSCALL(getpeername, 3) - ret -#else /* !__LP64__ */ -PSEUDO(getpeername$UNIX2003, getpeername, 3) - ret - -UNIX_SYSCALL_ERR(getpeername, 3, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/getpgid.s b/i386/sys/getpgid.s deleted file mode 100644 index a707ae8..0000000 --- a/i386/sys/getpgid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getpgid, 1) - ret diff --git a/i386/sys/getpgrp.s b/i386/sys/getpgrp.s deleted file mode 100644 index cbe43b5..0000000 --- a/i386/sys/getpgrp.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getpgrp, 1) - ret // pgrp = getpgrp(pid); diff --git a/i386/sys/getpid.s b/i386/sys/getpid.s deleted file mode 100644 index 728bf49..0000000 --- a/i386/sys/getpid.s +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 1999-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@ - */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - - .data - .private_extern __current_pid -__current_pid: - .long 0 -L__current_pid_addr = __current_pid - -#if defined(__DYNAMIC__) -#define GET_CURRENT_PID \ - call 0f ; \ -0: ; \ - popl %ecx ; \ - leal L__current_pid_addr-0b(%ecx), %ecx - -#define __current_pid (%ecx) - -#else -#define GET_CURRENT_PID -#endif - -/* - * If __current_pid is > 0, return it, else make syscall. - * If __current_pid is 0, cache result of syscall. - */ -TEXT -LEAF(_getpid, 0) - GET_CURRENT_PID - movl __current_pid, %eax - testl %eax, %eax - jle 1f - ret -1: - UNIX_SYSCALL_NONAME(getpid, 0) - movl %eax, %edx - xorl %eax, %eax - GET_CURRENT_PID - lock - cmpxchgl %edx, __current_pid - movl %edx, %eax - ret diff --git a/i386/sys/getppid.s b/i386/sys/getppid.s deleted file mode 100644 index 0c27b8b..0000000 --- a/i386/sys/getppid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getppid,0) - ret diff --git a/i386/sys/getpriority.s b/i386/sys/getpriority.s deleted file mode 100644 index 4c532ad..0000000 --- a/i386/sys/getpriority.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getpriority, 2) - ret diff --git a/i386/sys/getrlimit.s b/i386/sys/getrlimit.s deleted file mode 100644 index 89595dd..0000000 --- a/i386/sys/getrlimit.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getrlimit, 2) - ret diff --git a/i386/sys/getrusage.s b/i386/sys/getrusage.s deleted file mode 100644 index eb1bb5e..0000000 --- a/i386/sys/getrusage.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getrusage, 2) - ret diff --git a/i386/sys/getsid.s b/i386/sys/getsid.s deleted file mode 100644 index 7388e99..0000000 --- a/i386/sys/getsid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getsid, 1) - ret diff --git a/i386/sys/getsockname.s b/i386/sys/getsockname.s deleted file mode 100644 index 3cde723..0000000 --- a/i386/sys/getsockname.s +++ /dev/null @@ -1,37 +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 (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#ifdef __LP64__ -UNIX_SYSCALL(getsockname, 3) - ret -#else /* !__LP64__ */ -PSEUDO(getsockname$UNIX2003, getsockname, 3) - ret - -UNIX_SYSCALL_ERR(getsockname, 3, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/getsockopt.s b/i386/sys/getsockopt.s deleted file mode 100644 index e0fb6d4..0000000 --- a/i386/sys/getsockopt.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getsockopt, 5) - ret diff --git a/i386/sys/getuid.s b/i386/sys/getuid.s deleted file mode 100644 index 91505ba..0000000 --- a/i386/sys/getuid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(getuid, 0) - ret // uid = getuid(); diff --git a/i386/sys/getxattr.s b/i386/sys/getxattr.s deleted file mode 100644 index 370d3d3..0000000 --- a/i386/sys/getxattr.s +++ /dev/null @@ -1,26 +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 - -UNIX_SYSCALL(getxattr, 5) - ret diff --git a/i386/sys/i386_gettimeofday.s b/i386/sys/i386_gettimeofday.s index e32587c..2db860c 100644 --- a/i386/sys/i386_gettimeofday.s +++ b/i386/sys/i386_gettimeofday.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -31,14 +31,3 @@ LABEL(___commpage_gettimeofday) mov $ _COMM_PAGE_GETTIMEOFDAY,%eax jmp *%eax - -/* - * This syscall is special cased: the timeval is returned in eax/edx. - */ -LABEL(___gettimeofday) - UNIX_SYSCALL_INT_NONAME(gettimeofday,0) - mov 4(%esp),%ecx - mov %eax,(%ecx) - mov %edx,4(%ecx) - xor %eax,%eax - ret diff --git a/i386/sys/ioctl.s b/i386/sys/ioctl.s deleted file mode 100644 index 128bc3b..0000000 --- a/i386/sys/ioctl.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(ioctl, 3) - ret diff --git a/i386/sys/issetugid.s b/i386/sys/issetugid.s deleted file mode 100644 index b1e56f1..0000000 --- a/i386/sys/issetugid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(issetugid, 0) - ret diff --git a/i386/sys/kevent.s b/i386/sys/kevent.s deleted file mode 100644 index aee6db5..0000000 --- a/i386/sys/kevent.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(kevent, 6) - ret diff --git a/i386/sys/kill.s b/i386/sys/kill.s deleted file mode 100644 index 7de3ab2..0000000 --- a/i386/sys/kill.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(kill, 2) - ret diff --git a/i386/sys/kqueue.s b/i386/sys/kqueue.s deleted file mode 100644 index 6b8a0d4..0000000 --- a/i386/sys/kqueue.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(kqueue, 0) - ret diff --git a/i386/sys/kqueue_from_portset_np.s b/i386/sys/kqueue_from_portset_np.s deleted file mode 100644 index a92fb53..0000000 --- a/i386/sys/kqueue_from_portset_np.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(kqueue_from_portset_np, 1) - ret diff --git a/i386/sys/kqueue_portset_np.s b/i386/sys/kqueue_portset_np.s deleted file mode 100644 index 8e093e2..0000000 --- a/i386/sys/kqueue_portset_np.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(kqueue_portset_np, 1) - ret diff --git a/i386/sys/ktrace.s b/i386/sys/ktrace.s deleted file mode 100644 index 93a27c9..0000000 --- a/i386/sys/ktrace.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(ktrace, 4) - ret diff --git a/i386/sys/lchown.s b/i386/sys/lchown.s deleted file mode 100644 index 7d7f72b..0000000 --- a/i386/sys/lchown.s +++ /dev/null @@ -1,34 +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 - -#ifdef __LP64__ -UNIX_SYSCALL(lchown, 3) - ret -#else /* !__LP64__ */ -PSEUDO(lchown$UNIX2003, lchown, 3) - ret - -UNIX_SYSCALL_ERR(lchown, 3, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/libc.syscall.i386 b/i386/sys/libc.syscall.i386 new file mode 100644 index 0000000..e009a37 --- /dev/null +++ b/i386/sys/libc.syscall.i386 @@ -0,0 +1,82 @@ +_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 +_fsync ___fsync_nocancel +_fsync$NOCANCEL$UNIX2003 ___fsync_nocancel +_fsync$UNIX2003 ___fsync +_getattrlist$UNIX2003 ___getattrlist +_getpeername$UNIX2003 ___getpeername +_getsockname$UNIX2003 ___getsockname +_lchown$UNIX2003 ___lchown +_listen$UNIX2003 ___listen +_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 +_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 +_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/i386/sys/link.s b/i386/sys/link.s deleted file mode 100644 index e26cf59..0000000 --- a/i386/sys/link.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(link, 2) - ret diff --git a/i386/sys/lio_listio.s b/i386/sys/lio_listio.s deleted file mode 100644 index 2642027..0000000 --- a/i386/sys/lio_listio.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(lio_listio, 4) - ret diff --git a/i386/sys/listen.s b/i386/sys/listen.s deleted file mode 100644 index 3257f81..0000000 --- a/i386/sys/listen.s +++ /dev/null @@ -1,37 +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 (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#ifdef __LP64__ -UNIX_SYSCALL(listen, 2) - ret -#else /* !__LP64__ */ -PSEUDO(listen$UNIX2003, listen, 2) - ret - -UNIX_SYSCALL_ERR(listen, 2, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/listxattr.s b/i386/sys/listxattr.s deleted file mode 100644 index dce76a1..0000000 --- a/i386/sys/listxattr.s +++ /dev/null @@ -1,26 +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 - -UNIX_SYSCALL(listxattr, 4) - ret diff --git a/i386/sys/load_shared_file.s b/i386/sys/load_shared_file.s deleted file mode 100644 index e994324..0000000 --- a/i386/sys/load_shared_file.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(load_shared_file, 7) - ret diff --git a/i386/sys/lseek.s b/i386/sys/lseek.s deleted file mode 100644 index 9f58dec..0000000 --- a/i386/sys/lseek.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL_INT(lseek, 3) - ret diff --git a/i386/sys/lstat.s b/i386/sys/lstat.s deleted file mode 100644 index 80abe5b..0000000 --- a/i386/sys/lstat.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(lstat, 2) - ret diff --git a/i386/sys/lstatv.s b/i386/sys/lstatv.s deleted file mode 100644 index e06c5f5..0000000 --- a/i386/sys/lstatv.s +++ /dev/null @@ -1,29 +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) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(lstatv, 0) - ret diff --git a/i386/sys/madvise.s b/i386/sys/madvise.s deleted file mode 100644 index b6e90ed..0000000 --- a/i386/sys/madvise.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(madvise, 3) - ret diff --git a/i386/sys/mincore.s b/i386/sys/mincore.s deleted file mode 100644 index 94b1412..0000000 --- a/i386/sys/mincore.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(mincore, 3) - ret diff --git a/i386/sys/minherit.s b/i386/sys/minherit.s deleted file mode 100644 index 536c71f..0000000 --- a/i386/sys/minherit.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(minherit, 3) - ret diff --git a/i386/sys/mkcomplex.s b/i386/sys/mkcomplex.s deleted file mode 100644 index 69ee538..0000000 --- a/i386/sys/mkcomplex.s +++ /dev/null @@ -1,29 +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) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(mkcomplex, 0) - ret diff --git a/i386/sys/mkdir.s b/i386/sys/mkdir.s deleted file mode 100644 index 0dd87cf..0000000 --- a/i386/sys/mkdir.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(mkdir, 2) - ret diff --git a/i386/sys/mkfifo.s b/i386/sys/mkfifo.s deleted file mode 100644 index e21263e..0000000 --- a/i386/sys/mkfifo.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(mkfifo, 2) - ret diff --git a/i386/sys/mknod.s b/i386/sys/mknod.s deleted file mode 100644 index 27df451..0000000 --- a/i386/sys/mknod.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(mknod, 3) - ret diff --git a/i386/sys/mlock.s b/i386/sys/mlock.s deleted file mode 100644 index eccef85..0000000 --- a/i386/sys/mlock.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(mlock, 3) - ret diff --git a/i386/sys/mlockall.s b/i386/sys/mlockall.s deleted file mode 100644 index 0b077d9..0000000 --- a/i386/sys/mlockall.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(mlockall, 3) - ret diff --git a/i386/sys/mount.s b/i386/sys/mount.s deleted file mode 100644 index 5d25824..0000000 --- a/i386/sys/mount.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(mount, 4) - ret diff --git a/i386/sys/msgget.s b/i386/sys/msgget.s deleted file mode 100644 index bc5cbe2..0000000 --- a/i386/sys/msgget.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(msgget, 3) - ret diff --git a/i386/sys/msgrcv.s b/i386/sys/msgrcv.s deleted file mode 100644 index f0ba773..0000000 --- a/i386/sys/msgrcv.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(msgrcv, 3) - ret diff --git a/i386/sys/msgsnd.s b/i386/sys/msgsnd.s deleted file mode 100644 index 3877229..0000000 --- a/i386/sys/msgsnd.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(msgsnd, 3) - ret diff --git a/i386/sys/msgsys.s b/i386/sys/msgsys.s deleted file mode 100644 index 8f7d12d..0000000 --- a/i386/sys/msgsys.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(msgsys, 3) - ret diff --git a/i386/sys/munlock.s b/i386/sys/munlock.s deleted file mode 100644 index d61cfe4..0000000 --- a/i386/sys/munlock.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(munlock, 3) - ret diff --git a/i386/sys/munlockall.s b/i386/sys/munlockall.s deleted file mode 100644 index 41f4a1d..0000000 --- a/i386/sys/munlockall.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(munlockall, 3) - ret diff --git a/i386/sys/new_system_shared_regions.s b/i386/sys/new_system_shared_regions.s deleted file mode 100644 index 6c1db69..0000000 --- a/i386/sys/new_system_shared_regions.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(new_system_shared_regions, 0) - ret diff --git a/i386/sys/nfsclnt.s b/i386/sys/nfsclnt.s deleted file mode 100644 index 80dbcec..0000000 --- a/i386/sys/nfsclnt.s +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 - -UNIX_SYSCALL(nfsclnt, 2) - ret diff --git a/i386/sys/nfssvc.s b/i386/sys/nfssvc.s deleted file mode 100644 index ba92a9f..0000000 --- a/i386/sys/nfssvc.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(nfssvc, 1) - ret diff --git a/i386/sys/open.s b/i386/sys/open.s deleted file mode 100644 index 463fe2b..0000000 --- a/i386/sys/open.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(open, 3) - ret diff --git a/i386/sys/pathconf.s b/i386/sys/pathconf.s deleted file mode 100644 index 08a1e83..0000000 --- a/i386/sys/pathconf.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(pathconf, 2) - ret diff --git a/i386/sys/pipe.s b/i386/sys/pipe.s deleted file mode 100644 index c49df43..0000000 --- a/i386/sys/pipe.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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL_INT(pipe, 0) - movl 4(%esp),%ecx - movl %eax,(%ecx) - movl %edx,4(%ecx) - xorl %eax,%eax - ret diff --git a/i386/sys/poll.s b/i386/sys/poll.s deleted file mode 100644 index 8d3d8bd..0000000 --- a/i386/sys/poll.s +++ /dev/null @@ -1,26 +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 - -UNIX_SYSCALL(poll, 3) - ret diff --git a/i386/sys/posix_madvise.s b/i386/sys/posix_madvise.s deleted file mode 100644 index d08a4b6..0000000 --- a/i386/sys/posix_madvise.s +++ /dev/null @@ -1,28 +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 1998 Apple Computer, Inc. */ - -#include - -PSEUDO(posix_madvise, madvise, 3) - ret diff --git a/i386/sys/pread.s b/i386/sys/pread.s deleted file mode 100644 index ea48c9c..0000000 --- a/i386/sys/pread.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(pread, 4) - ret diff --git a/i386/sys/profil.s b/i386/sys/profil.s deleted file mode 100644 index 8610c95..0000000 --- a/i386/sys/profil.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(profil, 4) - ret diff --git a/i386/sys/pthread_sigmask.s b/i386/sys/pthread_sigmask.s deleted file mode 100644 index 510d269..0000000 --- a/i386/sys/pthread_sigmask.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(pthread_sigmask, 3) - ret diff --git a/i386/sys/ptrace.s b/i386/sys/ptrace.s deleted file mode 100644 index cccd814..0000000 --- a/i386/sys/ptrace.s +++ /dev/null @@ -1,34 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - - .globl _errno - -LEAF(_ptrace, 0) - xorl %eax,%eax - REG_TO_EXTERN(%eax,_errno) -UNIX_SYSCALL_NONAME(ptrace, 4) - ret diff --git a/i386/sys/pwrite.s b/i386/sys/pwrite.s deleted file mode 100644 index 1ea681b..0000000 --- a/i386/sys/pwrite.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(pwrite, 4) - ret diff --git a/i386/sys/quota.s b/i386/sys/quota.s deleted file mode 100644 index 402b0af..0000000 --- a/i386/sys/quota.s +++ /dev/null @@ -1,31 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#define SYS_quota 149 - -UNIX_SYSCALL(quota, 4) - ret diff --git a/i386/sys/quotactl.s b/i386/sys/quotactl.s deleted file mode 100644 index 51d7c3e..0000000 --- a/i386/sys/quotactl.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(quotactl, 3) - ret diff --git a/i386/sys/read.s b/i386/sys/read.s deleted file mode 100644 index 6035086..0000000 --- a/i386/sys/read.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(read, 3) - ret diff --git a/i386/sys/readlink.s b/i386/sys/readlink.s deleted file mode 100644 index bf690a3..0000000 --- a/i386/sys/readlink.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(readlink, 3) - ret diff --git a/i386/sys/readv.s b/i386/sys/readv.s deleted file mode 100644 index d3b3583..0000000 --- a/i386/sys/readv.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(readv, 3) - ret diff --git a/i386/sys/reboot.s b/i386/sys/reboot.s deleted file mode 100644 index 12da158..0000000 --- a/i386/sys/reboot.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(reboot, 2) - hlt diff --git a/i386/sys/recvfrom.s b/i386/sys/recvfrom.s deleted file mode 100644 index 7fb485f..0000000 --- a/i386/sys/recvfrom.s +++ /dev/null @@ -1,37 +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 (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#ifdef __LP64__ -UNIX_SYSCALL(recvfrom, 6) - ret -#else /* !__LP64__ */ -PSEUDO(recvfrom$UNIX2003, recvfrom, 6) - ret - -UNIX_SYSCALL_ERR(recvfrom, 6, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/recvmsg.s b/i386/sys/recvmsg.s deleted file mode 100644 index 347e1e0..0000000 --- a/i386/sys/recvmsg.s +++ /dev/null @@ -1,37 +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 (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#ifdef __LP64__ -UNIX_SYSCALL(recvmsg, 3) - ret -#else /* !__LP64__ */ -PSEUDO(recvmsg$UNIX2003, recvmsg, 3) - ret - -UNIX_SYSCALL_ERR(recvmsg, 3, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/removexattr.s b/i386/sys/removexattr.s deleted file mode 100644 index 77fe419..0000000 --- a/i386/sys/removexattr.s +++ /dev/null @@ -1,26 +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 - -UNIX_SYSCALL(removexattr, 3) - ret diff --git a/i386/sys/rename.s b/i386/sys/rename.s deleted file mode 100644 index 9e2278f..0000000 --- a/i386/sys/rename.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(rename, 2) - ret diff --git a/i386/sys/reset_shared_file.s b/i386/sys/reset_shared_file.s deleted file mode 100644 index 9dd0d42..0000000 --- a/i386/sys/reset_shared_file.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(reset_shared_file, 3) - ret diff --git a/i386/sys/revoke.s b/i386/sys/revoke.s deleted file mode 100644 index 8e92a8c..0000000 --- a/i386/sys/revoke.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(revoke, 1) - ret diff --git a/i386/sys/rmdir.s b/i386/sys/rmdir.s deleted file mode 100644 index 6576355..0000000 --- a/i386/sys/rmdir.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(rmdir, 1) - ret diff --git a/i386/sys/s.template b/i386/sys/s.template deleted file mode 100644 index d42f280..0000000 --- a/i386/sys/s.template +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include "SYS.h" - -UNIX_SYSCALL($FILENAMESANSEXTENSION$, 0) - ret diff --git a/i386/sys/searchfs.s b/i386/sys/searchfs.s deleted file mode 100644 index 1b343f8..0000000 --- a/i386/sys/searchfs.s +++ /dev/null @@ -1,29 +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) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(searchfs, 0) - ret diff --git a/i386/sys/select.s b/i386/sys/select.s deleted file mode 100644 index 68af42e..0000000 --- a/i386/sys/select.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(select, 5) - ret diff --git a/i386/sys/sem_close.s b/i386/sys/sem_close.s deleted file mode 100644 index 25cafa7..0000000 --- a/i386/sys/sem_close.s +++ /dev/null @@ -1,27 +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@ - */ -#include - -UNIX_SYSCALL(sem_close, 1) - ret - diff --git a/i386/sys/sem_destroy.s b/i386/sys/sem_destroy.s deleted file mode 100644 index dc0cdd1..0000000 --- a/i386/sys/sem_destroy.s +++ /dev/null @@ -1,27 +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@ - */ -#include - -UNIX_SYSCALL(sem_destroy, 1) - ret - diff --git a/i386/sys/sem_getvalue.s b/i386/sys/sem_getvalue.s deleted file mode 100644 index 5812fe7..0000000 --- a/i386/sys/sem_getvalue.s +++ /dev/null @@ -1,27 +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@ - */ -#include - -UNIX_SYSCALL(sem_getvalue, 2) - ret - diff --git a/i386/sys/sem_init.s b/i386/sys/sem_init.s deleted file mode 100644 index c7027c2..0000000 --- a/i386/sys/sem_init.s +++ /dev/null @@ -1,27 +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@ - */ -#include - -UNIX_SYSCALL(sem_init, 3) - ret - diff --git a/i386/sys/sem_post.s b/i386/sys/sem_post.s deleted file mode 100644 index 5610342..0000000 --- a/i386/sys/sem_post.s +++ /dev/null @@ -1,27 +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@ - */ -#include - -UNIX_SYSCALL(sem_post, 1) - ret - diff --git a/i386/sys/sem_trywait.s b/i386/sys/sem_trywait.s deleted file mode 100644 index f2efe65..0000000 --- a/i386/sys/sem_trywait.s +++ /dev/null @@ -1,27 +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@ - */ -#include - -UNIX_SYSCALL(sem_trywait, 1) - ret - diff --git a/i386/sys/semget.s b/i386/sys/semget.s deleted file mode 100644 index cab8501..0000000 --- a/i386/sys/semget.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(semget, 3) - ret diff --git a/i386/sys/semop.s b/i386/sys/semop.s deleted file mode 100644 index 5d0ff12..0000000 --- a/i386/sys/semop.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(semop, 3) - ret diff --git a/i386/sys/semsys.s b/i386/sys/semsys.s deleted file mode 100644 index 5813c69..0000000 --- a/i386/sys/semsys.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(semsys, 3) - ret diff --git a/i386/sys/sendmsg.s b/i386/sys/sendmsg.s deleted file mode 100644 index e30ee3b..0000000 --- a/i386/sys/sendmsg.s +++ /dev/null @@ -1,37 +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 (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#ifdef __LP64__ -UNIX_SYSCALL(sendmsg, 3) - ret -#else /* !__LP64__ */ -PSEUDO(sendmsg$UNIX2003, sendmsg, 3) - ret - -UNIX_SYSCALL_ERR(sendmsg, 3, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/sendto.s b/i386/sys/sendto.s deleted file mode 100644 index 14ba2bb..0000000 --- a/i386/sys/sendto.s +++ /dev/null @@ -1,37 +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 (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#ifdef __LP64__ -UNIX_SYSCALL(sendto, 6) - ret -#else /* !__LP64__ */ -PSEUDO(sendto$UNIX2003, sendto, 6) - ret - -UNIX_SYSCALL_ERR(sendto, 6, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/setattrlist.s b/i386/sys/setattrlist.s deleted file mode 100644 index 801bde9..0000000 --- a/i386/sys/setattrlist.s +++ /dev/null @@ -1,37 +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 (c) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include - -#ifdef __LP64__ -UNIX_SYSCALL(setattrlist, 0) - ret -#else /* !__LP64__ */ -PSEUDO(setattrlist$UNIX2003, setattrlist, 0) - ret - -UNIX_SYSCALL_ERR(setattrlist, 0, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/setaudit.s b/i386/sys/setaudit.s deleted file mode 100644 index 77b4ec4..0000000 --- a/i386/sys/setaudit.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(setaudit, 1) - ret diff --git a/i386/sys/setaudit_addr.s b/i386/sys/setaudit_addr.s deleted file mode 100644 index 5857301..0000000 --- a/i386/sys/setaudit_addr.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(setaudit_addr, 2) - ret diff --git a/i386/sys/setauid.s b/i386/sys/setauid.s deleted file mode 100644 index ac94ab2..0000000 --- a/i386/sys/setauid.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(setauid, 1) - ret diff --git a/i386/sys/setegid.s b/i386/sys/setegid.s deleted file mode 100644 index 1d05963..0000000 --- a/i386/sys/setegid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setegid, 1) - ret diff --git a/i386/sys/seteuid.s b/i386/sys/seteuid.s deleted file mode 100644 index 38744f2..0000000 --- a/i386/sys/seteuid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(seteuid, 1) - ret diff --git a/i386/sys/setgid.s b/i386/sys/setgid.s deleted file mode 100644 index 142c4b0..0000000 --- a/i386/sys/setgid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setgid, 1) - ret diff --git a/i386/sys/setgroups.s b/i386/sys/setgroups.s deleted file mode 100644 index bf8f0ed..0000000 --- a/i386/sys/setgroups.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setgroups, 2) - ret // setgroups(gidsetsize, gidset) diff --git a/i386/sys/setitimer.s b/i386/sys/setitimer.s deleted file mode 100644 index 52333d9..0000000 --- a/i386/sys/setitimer.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setitimer, 3) - ret diff --git a/i386/sys/setjmp.s b/i386/sys/setjmp.s index 0dba96f..461470a 100644 --- a/i386/sys/setjmp.s +++ b/i386/sys/setjmp.s @@ -51,7 +51,7 @@ #define JB_MASK 4 #define JB_MXCSR 8 #define JB_EBX 12 -#define JB_ECX 16 +#define JB_ONSTACK 16 #define JB_EDX 20 #define JB_EDI 24 #define JB_ESI 28 @@ -76,15 +76,26 @@ LEAF(_sigsetjmp, 0) jmp L_do__setjmp // else _setjmp(jmpbuf); LEAF(_setjmp, 0) - subl $4, %esp // make space for return from sigprocmask + subl $16, %esp // make space for return from sigprocmask + // + 12 to align stack pushl %esp // oset pushl $0 // set = NULL pushl $1 // how = SIG_BLOCK CALL_EXTERN(_sigprocmask) movl 12(%esp),%eax // save the mask - addl $16, %esp // restore original esp + addl $28, %esp // restore original esp movl 4(%esp), %ecx // jmp_buf (struct sigcontext *) movl %eax, JB_MASK(%ecx) + + subl $20, %esp // temporary struct sigaltstack + 8 to + // align stack + pushl %esp // oss + pushl $0 // ss == NULL + CALL_EXTERN(_sigaltstack) // get alternate signal stack info + movl 16(%esp), %eax // oss->ss_flags + addl $28, %esp // Restore %esp + movl %eax, JB_ONSTACK(%ecx) + L_do__setjmp: BRANCH_EXTERN(__setjmp) @@ -97,13 +108,23 @@ LEAF(_siglongjmp, 0) LEAF(_longjmp, 0) movl 4(%esp), %ecx // address of jmp_buf (saved context) movl JB_MASK(%ecx),%eax // get the mask + subl $12, %esp // Make sure the stack is 16-byte + // aligned when we call sigprocmask pushl %eax // store the mask movl %esp, %edx // save the address where we stored the mask pushl $0 // oset = NULL pushl %edx // set pushl $3 // how = SIG_SETMASK CALL_EXTERN_AGAIN(_sigprocmask) - addl $16, %esp // restore original esp + addl $28, %esp // restore original esp + + movl 4(%esp), %ecx // address of jmp_buf + movl JB_ONSTACK(%ecx), %eax // ss_flags + subl $8, %esp + pushl %eax + CALL_EXTERN(__sigunaltstack) + addl $12, %esp + L_do__longjmp: BRANCH_EXTERN(__longjmp) // else END(_longjmp) diff --git a/i386/sys/setpgid.s b/i386/sys/setpgid.s deleted file mode 100644 index f0f5160..0000000 --- a/i386/sys/setpgid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setpgid, 2) - ret diff --git a/i386/sys/setpriority.s b/i386/sys/setpriority.s deleted file mode 100644 index b391375..0000000 --- a/i386/sys/setpriority.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setpriority, 3) - ret diff --git a/i386/sys/setprivexec.s b/i386/sys/setprivexec.s deleted file mode 100644 index 4260a7f..0000000 --- a/i386/sys/setprivexec.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setprivexec, 3) - ret diff --git a/i386/sys/setquota.s b/i386/sys/setquota.s deleted file mode 100644 index fa7ad10..0000000 --- a/i386/sys/setquota.s +++ /dev/null @@ -1,31 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#define SYS_setquota 148 - -UNIX_SYSCALL(setquota, 2) - ret diff --git a/i386/sys/setrlimit.s b/i386/sys/setrlimit.s deleted file mode 100644 index adac73c..0000000 --- a/i386/sys/setrlimit.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setrlimit, 2) - ret diff --git a/i386/sys/setsid.s b/i386/sys/setsid.s deleted file mode 100644 index e074158..0000000 --- a/i386/sys/setsid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setsid, 0) - ret diff --git a/i386/sys/setsockopt.s b/i386/sys/setsockopt.s deleted file mode 100644 index 4f4afd7..0000000 --- a/i386/sys/setsockopt.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setsockopt, 5) - ret diff --git a/i386/sys/settimeofday.s b/i386/sys/settimeofday.s deleted file mode 100644 index 8191332..0000000 --- a/i386/sys/settimeofday.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(settimeofday, 2) - ret diff --git a/i386/sys/setuid.s b/i386/sys/setuid.s deleted file mode 100644 index 798dc02..0000000 --- a/i386/sys/setuid.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(setuid, 1) - ret diff --git a/i386/sys/setxattr.s b/i386/sys/setxattr.s deleted file mode 100644 index 176a795..0000000 --- a/i386/sys/setxattr.s +++ /dev/null @@ -1,26 +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 - -UNIX_SYSCALL(setxattr, 5) - ret diff --git a/i386/sys/shmat.s b/i386/sys/shmat.s deleted file mode 100644 index ae59417..0000000 --- a/i386/sys/shmat.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(shmat, 3) - ret diff --git a/i386/sys/shmdt.s b/i386/sys/shmdt.s deleted file mode 100644 index 0d72820..0000000 --- a/i386/sys/shmdt.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(shmdt, 3) - ret diff --git a/i386/sys/shmget.s b/i386/sys/shmget.s deleted file mode 100644 index 69a6e37..0000000 --- a/i386/sys/shmget.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(shmget, 3) - ret diff --git a/i386/sys/shmsys.s b/i386/sys/shmsys.s deleted file mode 100644 index 6120f95..0000000 --- a/i386/sys/shmsys.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(shmsys, 3) - ret diff --git a/i386/sys/shutdown.s b/i386/sys/shutdown.s deleted file mode 100644 index 6f7d7c3..0000000 --- a/i386/sys/shutdown.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(shutdown, 2) - ret diff --git a/i386/sys/sigaltstack.s b/i386/sys/sigaltstack.s deleted file mode 100644 index cb42ea3..0000000 --- a/i386/sys/sigaltstack.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL_INT(sigaltstack, 3) - ret diff --git a/i386/sys/sigpending.s b/i386/sys/sigpending.s deleted file mode 100644 index 08557e9..0000000 --- a/i386/sys/sigpending.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(sigpending, 1) - ret diff --git a/i386/sys/sigprocmask.s b/i386/sys/sigprocmask.s deleted file mode 100644 index 15e53c9..0000000 --- a/i386/sys/sigprocmask.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(sigprocmask, 3) - ret diff --git a/i386/sys/sigreturn.s b/i386/sys/sigreturn.s deleted file mode 100644 index 781005d..0000000 --- a/i386/sys/sigreturn.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL_INT(sigreturn, 2) - ret diff --git a/i386/sys/sigwait.s b/i386/sys/sigwait.s deleted file mode 100644 index f42d465..0000000 --- a/i386/sys/sigwait.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(sigwait, 2) - ret diff --git a/i386/sys/socket.s b/i386/sys/socket.s deleted file mode 100644 index ecb5df0..0000000 --- a/i386/sys/socket.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(socket, 3) - ret diff --git a/i386/sys/socketpair.s b/i386/sys/socketpair.s deleted file mode 100644 index feae561..0000000 --- a/i386/sys/socketpair.s +++ /dev/null @@ -1,37 +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 (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#ifdef __LP64__ -UNIX_SYSCALL(socketpair, 5) - ret -#else /* !__LP64__ */ -PSEUDO(socketpair$UNIX2003, socketpair, 5) - ret - -UNIX_SYSCALL_ERR(socketpair, 5, cerror_cvt) - ret -#endif /* !__LP64__ */ diff --git a/i386/sys/stat.s b/i386/sys/stat.s deleted file mode 100644 index 8ab986e..0000000 --- a/i386/sys/stat.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(stat, 2) - ret diff --git a/i386/sys/statfs.s b/i386/sys/statfs.s deleted file mode 100644 index 50163bc..0000000 --- a/i386/sys/statfs.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(statfs, 2); - ret diff --git a/i386/sys/statv.s b/i386/sys/statv.s deleted file mode 100644 index 7ea9660..0000000 --- a/i386/sys/statv.s +++ /dev/null @@ -1,29 +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) 1998 Apple Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(statv, 0) - ret diff --git a/i386/sys/swapon.s b/i386/sys/swapon.s deleted file mode 100644 index 7832499..0000000 --- a/i386/sys/swapon.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(swapon, 1) - ret diff --git a/i386/sys/symlink.s b/i386/sys/symlink.s deleted file mode 100644 index ddc031a..0000000 --- a/i386/sys/symlink.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(symlink, 2) - ret diff --git a/i386/sys/sync.s b/i386/sys/sync.s deleted file mode 100644 index 12863d8..0000000 --- a/i386/sys/sync.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(sync, 0) - ret diff --git a/i386/sys/syscall.s b/i386/sys/syscall.s deleted file mode 100644 index 0e91b68..0000000 --- a/i386/sys/syscall.s +++ /dev/null @@ -1,38 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -LEAF(_syscall, 0) - popl %ecx // ret addr - popl %eax // syscall number - pushl %ecx - UNIX_SYSCALL_TRAP - movl (%esp),%edx // add one element to stack so - pushl %ecx // caller "pop" will work - jnb 2f - BRANCH_EXTERN(cerror) -2: -END(_syscall) diff --git a/i386/sys/systable.s b/i386/sys/systable.s deleted file mode 100644 index 0a7a6cb..0000000 --- a/i386/sys/systable.s +++ /dev/null @@ -1,26 +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@ - */ -#include - -UNIX_SYSCALL(table, 5) - ret diff --git a/i386/sys/truncate.s b/i386/sys/truncate.s deleted file mode 100644 index 7a81e56..0000000 --- a/i386/sys/truncate.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(truncate, 2) - ret diff --git a/i386/sys/umask.s b/i386/sys/umask.s deleted file mode 100644 index bf30626..0000000 --- a/i386/sys/umask.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(umask, 1) - ret diff --git a/i386/sys/undelete.s b/i386/sys/undelete.s deleted file mode 100644 index 36776c6..0000000 --- a/i386/sys/undelete.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(undelete, 1) - ret diff --git a/i386/sys/unlink.s b/i386/sys/unlink.s deleted file mode 100644 index cd77691..0000000 --- a/i386/sys/unlink.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(unlink, 1) - ret diff --git a/i386/sys/unmount.s b/i386/sys/unmount.s deleted file mode 100644 index 1e24673..0000000 --- a/i386/sys/unmount.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(unmount, 1) - ret diff --git a/i386/sys/utimes.s b/i386/sys/utimes.s deleted file mode 100644 index 824926f..0000000 --- a/i386/sys/utimes.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(utimes, 2) - ret diff --git a/i386/sys/vfork.s b/i386/sys/vfork.s deleted file mode 100644 index b3e35ab..0000000 --- a/i386/sys/vfork.s +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 1999-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@ - */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -#if defined(__DYNAMIC__) -#define GET_CURRENT_PID PICIFY(__current_pid) - - NON_LAZY_STUB(__current_pid) -#define __current_pid (%edx) -#else -#define GET_CURRENT_PID -#endif - -/* - * If __current_pid >= 0, we want to put a -1 in there - * otherwise we just decrement it - */ - -LEAF(_vfork, 0) - GET_CURRENT_PID - movl __current_pid, %eax -0: - xorl %ecx, %ecx - testl %eax, %eax - cmovs %eax, %ecx - decl %ecx - lock - cmpxchgl %ecx, __current_pid - jne 0b - popl %ecx - movl $(SYS_vfork), %eax // code for vfork -> eax - UNIX_SYSCALL_TRAP // do the system call - jnb L1 // jump if CF==0 - GET_CURRENT_PID - lock - incl __current_pid - pushl %ecx - BRANCH_EXTERN(cerror) - -L1: - testl %edx, %edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child - xorl %eax, %eax // zero eax - jmp *%ecx - -L2: - GET_CURRENT_PID - lock - incl __current_pid - jmp *%ecx diff --git a/i386/sys/wait4.s b/i386/sys/wait4.s deleted file mode 100644 index 0d229b2..0000000 --- a/i386/sys/wait4.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(wait4, 4) - ret diff --git a/i386/sys/write.s b/i386/sys/write.s deleted file mode 100644 index a3a0959..0000000 --- a/i386/sys/write.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(write, 3) - ret diff --git a/i386/sys/writev.s b/i386/sys/writev.s deleted file mode 100644 index ff94496..0000000 --- a/i386/sys/writev.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(writev, 3) - ret diff --git a/include/Makefile.inc b/include/Makefile.inc index f6fc796..656f625 100644 --- a/include/Makefile.inc +++ b/include/Makefile.inc @@ -1,14 +1,18 @@ +.ifnmake autopatch .include "${.CURDIR}/include/arpa/Makefile.inc" .include "${.CURDIR}/include/libkern/Makefile.inc" .include "${.CURDIR}/include/protocols/Makefile.inc" .include "${.CURDIR}/include/machine/Makefile.inc" .include "${.CURDIR}/include/malloc/Makefile.inc" .include "${.CURDIR}/include/objc/Makefile.inc" +.include "${.CURDIR}/include/secure/Makefile.inc" .include "${.CURDIR}/include/sys/Makefile.inc" .include "${.CURDIR}/include/xlocale/Makefile.inc" +.endif # !autopatch INC_INSTHDRS += NSSystemDirectories.h \ _locale.h \ + _structs.h \ _types.h \ _wctype.h \ _xlocale.h \ @@ -19,7 +23,6 @@ INC_INSTHDRS += NSSystemDirectories.h \ assert.h \ asm.h \ bitstring.h \ - c.h \ cpio.h \ crt_externs.h \ ctype.h \ @@ -41,7 +44,6 @@ INC_INSTHDRS += NSSystemDirectories.h \ grp.h \ inttypes.h \ iso646.h \ - kvm.h \ langinfo.h \ libc.h \ libgen.h \ @@ -67,6 +69,7 @@ INC_INSTHDRS += NSSystemDirectories.h \ setjmp.h \ sgtty.h \ signal.h \ + spawn.h \ stab.h \ standards.h \ stdarg.h \ @@ -92,6 +95,7 @@ INC_INSTHDRS += NSSystemDirectories.h \ util.h \ utime.h \ utmp.h \ + utmpx.h \ varargs.h \ vis.h \ wchar.h \ @@ -105,9 +109,9 @@ MAN3 += sysexits.3 INC_INSTHDRS := ${INC_INSTHDRS:S/^/${.CURDIR}\/include\//} INSTHDRS += ${INC_INSTHDRS} -STRIP_HDRS += ctype.h +STRIP_HDRS += ctype.h dirent.h fnmatch.h fts.h ftw.h glob.h regex.h \ + signal.h stdio.h stdlib.h string.h time.h unistd.h wchar.h xlocale.h .include "Makefile.nbsd_begin" NBSDHDRS = utmpx.h .include "Makefile.nbsd_end" -INSTHDRS_AUTOPATCH += utmpx.h diff --git a/include/NSSystemDirectories.h b/include/NSSystemDirectories.h index 8ae5882..037a31b 100644 --- a/include/NSSystemDirectories.h +++ b/include/NSSystemDirectories.h @@ -68,6 +68,7 @@ typedef enum { 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) + NSDownloadsDirectory = 15, // location of user's Downloads directory (Downloads) NSAllApplicationsDirectory = 100, // all directories where applications can occur (Applications, Applications/Utilities, Developer/Applications, ...) NSAllLibrariesDirectory = 101 // all directories where resources can occur (Library, Developer) } NSSearchPathDirectory; diff --git a/include/NetBSD/utmpx.h.patch b/include/NetBSD/utmpx.h.patch index 86dec02..7f05196 100644 --- a/include/NetBSD/utmpx.h.patch +++ b/include/NetBSD/utmpx.h.patch @@ -1,6 +1,32 @@ ---- utmpx.h.orig 2004-08-05 14:37:28.000000000 -0700 -+++ utmpx.h 2004-08-05 15:42:48.000000000 -0700 -@@ -38,28 +38,26 @@ +--- utmpx.h.orig 2006-10-01 22:22:21.000000000 -0700 ++++ utmpx.h 2006-10-02 02:08:04.000000000 -0700 +@@ -1,3 +1,25 @@ ++/* ++ * 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@ ++ */ + /* $NetBSD: utmpx.h,v 1.11 2003/08/26 16:48:32 wiz Exp $ */ + + /*- +@@ -38,28 +60,32 @@ #ifndef _UTMPX_H_ #define _UTMPX_H_ @@ -14,17 +40,25 @@ +#define _PID_T +typedef __darwin_pid_t pid_t; +#endif ++ ++#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) ++#ifndef _UID_T ++#define _UID_T ++typedef __darwin_uid_t uid_t; ++#endif ++#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + #define _PATH_UTMPX "/var/run/utmpx" -#define _PATH_WTMPX "/var/log/wtmpx" -#define _PATH_LASTLOGX "/var/log/lastlogx" - #define _PATH_UTMP_UPDATE "/usr/libexec/utmp_update" +-#define _PATH_UTMP_UPDATE "/usr/libexec/utmp_update" -+#ifndef _POSIX_C_SOURCE +-#define _UTX_USERSIZE 32 ++#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define UTMPX_FILE _PATH_UTMPX -+#endif /* _POSIX_C_SOURCE */ ++#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + - #define _UTX_USERSIZE 32 ++#define _UTX_USERSIZE 256 /* matches MAXLOGNAME */ #define _UTX_LINESIZE 32 #define _UTX_IDSIZE 4 #define _UTX_HOSTSIZE 256 @@ -39,15 +73,23 @@ #define EMPTY 0 #define RUN_LVL 1 #define BOOT_TIME 2 -@@ -69,75 +67,35 @@ - #define LOGIN_PROCESS 6 +@@ -70,74 +96,85 @@ #define USER_PROCESS 7 #define DEAD_PROCESS 8 -- + -#if defined(_NETBSD_SOURCE) ++#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #define ACCOUNTING 9 #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 @@ -57,9 +99,11 @@ * entries using routines described in getutxent(3). */ --#define ut_user ut_name --#define ut_xtime ut_tv.tv_sec -- ++#ifdef _UTMPX_COMPAT + #define ut_user ut_name + #define ut_xtime ut_tv.tv_sec ++#endif /* _UTMPX_COMPAT */ + struct utmpx { - char ut_name[_UTX_USERSIZE]; /* login name */ - char ut_id[_UTX_IDSIZE]; /* inittab id */ @@ -78,18 +122,20 @@ + short ut_type; /* type of this entry */ struct timeval ut_tv; /* time entry was created */ - uint32_t ut_pad[10]; /* reserved for future use */ --}; -- --#if defined(_NETBSD_SOURCE) --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 */ + char ut_host[_UTX_HOSTSIZE]; /* host name */ + __uint32_t ut_pad[16]; /* reserved for future use */ }; + +-#if defined(_NETBSD_SOURCE) ++#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) + 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 */ + }; -#endif /* !_XOPEN_SOURCE */ ++#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ __BEGIN_DECLS @@ -116,14 +162,41 @@ -void getutmpx __P((const struct utmp *, struct utmpx *)); - -int utmpxname __P((const char *)); -- ++void endutxent(void); + -#endif /* _NETBSD_SOURCE */ -+void setutxent(void); -+void endutxent(void); -+struct utmpx *getutxent(void); -+struct utmpx *getutxid(const struct utmpx *); -+struct utmpx *getutxline(const struct utmpx *); -+struct utmpx *pututxline(const struct utmpx *); ++#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) ++void endutxent_wtmp(void); ++struct lastlogx * ++ getlastlogx(uid_t, struct lastlogx *); ++struct lastlogx * ++ getlastlogxbyname(const char*, struct lastlogx *); ++struct utmp; /* forward reference */ ++void getutmp(const struct utmpx *, struct utmp *); ++void getutmpx(const struct utmp *, struct utmpx *); ++#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ ++ ++struct utmpx * ++ getutxent(void); ++ ++#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) ++struct utmpx * ++ getutxent_wtmp(void); ++#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ ++ ++struct utmpx * ++ getutxid(const struct utmpx *); ++struct utmpx * ++ getutxline(const struct utmpx *); ++struct utmpx * ++ pututxline(const 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 *); ++#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ __END_DECLS diff --git a/include/_.libc_internal.h b/include/_.libc_internal.h new file mode 100644 index 0000000..dc1c9b4 --- /dev/null +++ b/include/_.libc_internal.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2006, 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@ + */ + +/*********************************************************************** + * Not to be installed in /usr/include + ***********************************************************************/ + +#ifndef __LIBC_INTERNAL_H_ +#define __LIBC_INTERNAL_H_ + +#define LIBC_STRING(str) #str + +#if defined(VARIANT_LEGACY) +# define LIBC_ALIAS(sym) /* nothing */ +# define LIBC_ALIAS_C(sym) /* nothing */ +# define LIBC_ALIAS_I(sym) /* nothing */ +# define LIBC_INODE64(sym) /* nothing */ +# define LIBC_1050(sym) /* nothing */ +#else /* !VARIANT_LEGACY */ +# if defined(__LP64__) +# define LIBC_ALIAS(sym) /* nothing */ +# if defined(VARIANT_CANCELABLE) +# define LIBC_ALIAS_C(sym) /* nothing */ +# else /* !VARIANT_CANCELABLE */ +# define LIBC_ALIAS_C(sym) _asm("_" LIBC_STRING(sym) "$NOCANCEL") +# endif /* VARIANT_CANCELABLE */ +# if defined(VARIANT_INODE32) +# define LIBC_ALIAS_I(sym) /* nothing */ +# else /* !VARIANT_INODE32 */ +# define LIBC_ALIAS_I(sym) _asm("_" LIBC_STRING(sym) "$INODE64") +# endif /* VARIANT_INODE32 */ +# else /* !__LP64__ */ +# define LIBC_ALIAS(sym) _asm("_" LIBC_STRING(sym) "$UNIX2003") +# if defined(VARIANT_CANCELABLE) +# define LIBC_ALIAS_C(sym) _asm("_" LIBC_STRING(sym) "$UNIX2003") +# else /* !VARIANT_CANCELABLE */ +# define LIBC_ALIAS_C(sym) _asm("_" LIBC_STRING(sym) "$NOCANCEL$UNIX2003") +# endif /* VARIANT_CANCELABLE */ +# if defined(VARIANT_INODE32) +# define LIBC_ALIAS_I(sym) _asm("_" LIBC_STRING(sym) "$UNIX2003") +# else /* !VARIANT_INODE32 */ +# define LIBC_ALIAS_I(sym) _asm("_" LIBC_STRING(sym) "$INODE64$UNIX2003") +# endif /* VARIANT_INODE32 */ +# endif /* __LP64__ */ +# if defined(VARIANT_INODE32) +# define LIBC_INODE64(sym) /* nothing */ +# else /* !VARIANT_INODE32 */ +# define LIBC_INODE64(sym) _asm("_" LIBC_STRING(sym) "$INODE64") +# endif /* VARIANT_INODE32 */ +# if defined(VARIANT_PRE1050) +# define LIBC_1050(sym) /* nothing */ +# else /* !VARIANT_PRE1050 */ +# define LIBC_1050(sym) _asm("_" LIBC_STRING(sym) "$1050") +# endif /* VARIANT_PRE1050 */ +#endif /* VARIANT_LEGACY */ + +#define LIBC_EXTSN(sym) _asm("_" LIBC_STRING(sym) "$DARWIN_EXTSN") +#if defined(VARIANT_CANCELABLE) +# define LIBC_EXTSN_C(sym) _asm("_" LIBC_STRING(sym) "$DARWIN_EXTSN") +#else /* !VARIANT_CANCELABLE */ +# define LIBC_EXTSN_C(sym) _asm("_" LIBC_STRING(sym) "$DARWIN_EXTSN$NOCANCEL") +#endif /* !VARIANT_CANCELABLE */ + +/* 5243343 - define PR_5243343 temporarily */ +#define PR_5243343 + +#endif /* __LIBC_INTERNAL_H_ */ diff --git a/mach/mach_vm.defs b/include/_structs.h similarity index 97% rename from mach/mach_vm.defs rename to include/_structs.h index f8b2c5d..44443b2 100644 --- a/mach/mach_vm.defs +++ b/include/_structs.h @@ -20,4 +20,6 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#include + +#include + diff --git a/include/_wctype.h b/include/_wctype.h index ff8cf63..626b531 100644 --- a/include/_wctype.h +++ b/include/_wctype.h @@ -56,6 +56,104 @@ typedef __darwin_wctype_t wctype_t; #define WEOF __DARWIN_WEOF #endif +#ifndef __DARWIN_WCTYPE_TOP_static_inline +#define __DARWIN_WCTYPE_TOP_static_inline static __inline +#endif + +#include + +/* + * Use inline functions if we are allowed to and the compiler supports them. + */ +#if !defined(_DONT_USE_CTYPE_INLINE_) && \ + (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) + +__DARWIN_WCTYPE_TOP_static_inline int +iswalnum(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_A|_CTYPE_D)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswalpha(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_A)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswcntrl(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_C)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswctype(wint_t _wc, wctype_t _charclass) +{ + return (__istype(_wc, _charclass)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswdigit(wint_t _wc) +{ + return (__isctype(_wc, _CTYPE_D)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswgraph(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_G)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswlower(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_L)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswprint(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_R)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswpunct(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_P)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswspace(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_S)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswupper(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_U)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswxdigit(wint_t _wc) +{ + return (__isctype(_wc, _CTYPE_X)); +} + +__DARWIN_WCTYPE_TOP_static_inline wint_t +towlower(wint_t _wc) +{ + return (__tolower(_wc)); +} + +__DARWIN_WCTYPE_TOP_static_inline wint_t +towupper(wint_t _wc) +{ + return (__toupper(_wc)); +} + +#else /* not using inlines */ + __BEGIN_DECLS int iswalnum(wint_t); int iswalpha(wint_t); @@ -71,26 +169,14 @@ int iswupper(wint_t); int iswxdigit(wint_t); wint_t towlower(wint_t); wint_t towupper(wint_t); -wctype_t - wctype(const char *); __END_DECLS -#include +#endif /* using inlines */ -#define iswalnum(wc) __istype((wc), _CTYPE_A|_CTYPE_D) -#define iswalpha(wc) __istype((wc), _CTYPE_A) -#define iswcntrl(wc) __istype((wc), _CTYPE_C) -#define iswctype(wc, charclass) __istype((wc), (charclass)) -#define iswdigit(wc) __istype((wc), _CTYPE_D) -#define iswgraph(wc) __istype((wc), _CTYPE_G) -#define iswlower(wc) __istype((wc), _CTYPE_L) -#define iswprint(wc) __istype((wc), _CTYPE_R) -#define iswpunct(wc) __istype((wc), _CTYPE_P) -#define iswspace(wc) __istype((wc), _CTYPE_S) -#define iswupper(wc) __istype((wc), _CTYPE_U) -#define iswxdigit(wc) __istype((wc), _CTYPE_X) -#define towlower(wc) __tolower(wc) -#define towupper(wc) __toupper(wc) +__BEGIN_DECLS +wctype_t + wctype(const char *); +__END_DECLS #ifdef _USE_EXTENDED_LOCALES_ #include diff --git a/include/ar.h b/include/ar.h index 39d7d35..e04874f 100644 --- a/include/ar.h +++ b/include/ar.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1991, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/arpa/ftp.h b/include/arpa/ftp.h index 906646b..64532b9 100644 --- a/include/arpa/ftp.h +++ b/include/arpa/ftp.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1983, 1989, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/arpa/telnet.h b/include/arpa/telnet.h index 50e8d71..10155a8 100644 --- a/include/arpa/telnet.h +++ b/include/arpa/telnet.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1983, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/arpa/tftp.h b/include/arpa/tftp.h index 2895703..9f6ac42 100644 --- a/include/arpa/tftp.h +++ b/include/arpa/tftp.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1983, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/asl.h b/include/asl.h index 688132e..c9c115c 100644 --- a/include/asl.h +++ b/include/asl.h @@ -82,14 +82,15 @@ typedef struct __aslresponse *aslresponse; * Additional attributes may be added as desired, and are * appended in the order that they are defined. */ -#define ASL_KEY_TIME "Time" /* Timestamp (see ctime(3)). Set automatically */ -#define ASL_KEY_HOST "Host" /* Sender's address (set by the server) */ -#define ASL_KEY_SENDER "Sender" /* Sender's identification string. Default is process name */ -#define ASL_KEY_PID "PID" /* Sending process ID encoded as a string. Set automatically */ -#define ASL_KEY_UID "UID" /* UID that sent the log message (set by the server) */ -#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" /* Actual message that will be logged */ +#define ASL_KEY_TIME "Time" /* Timestamp (see ctime(3)). Set automatically */ +#define ASL_KEY_HOST "Host" /* Sender's address (set by the server) */ +#define ASL_KEY_SENDER "Sender" /* Sender's identification string. Default is process name */ +#define ASL_KEY_FACILITY "Facility" /* Sender's facility. Default is "user". */ +#define ASL_KEY_PID "PID" /* Sending process ID encoded as a string. Set automatically */ +#define ASL_KEY_UID "UID" /* UID that sent the log message (set by the server) */ +#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" /* Actual message that will be logged */ /* * Message Types @@ -163,6 +164,7 @@ int asl_remove_log_file(aslclient asl, int fd); * set in the filter are not sent to the server, although they will be * sent to any file descripters added with asl_add_log_file(). * The default setting is ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE). + * Returns the previous filter value. */ int asl_set_filter(aslclient asl, int f); @@ -214,9 +216,9 @@ const char *asl_get(aslmsg msg, const char *key); * returns 0 for success, non-zero for failure */ #ifdef __DARWIN_LDBL_COMPAT2 -int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __DARWIN_LDBL_COMPAT2(asl_log); +int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __DARWIN_LDBL_COMPAT2(asl_log) __printflike(4, 5); #else -int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...); +int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __printflike(4, 5); #endif /* @@ -230,9 +232,9 @@ int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...); * returns 0 for success, non-zero for failure */ #ifdef __DARWIN_LDBL_COMPAT2 -int asl_vlog(aslclient asl, aslmsg msg, int level, const char *format, va_list ap) __DARWIN_LDBL_COMPAT2(asl_vlog); +int asl_vlog(aslclient asl, aslmsg msg, int level, const char *format, va_list ap) __DARWIN_LDBL_COMPAT2(asl_vlog) __printflike(4, 0); #else -int asl_vlog(aslclient asl, aslmsg msg, int level, const char *format, va_list ap); +int asl_vlog(aslclient asl, aslmsg msg, int level, const char *format, va_list ap) __printflike(4, 0); #endif /* diff --git a/include/assert.h b/include/assert.h index a9c9b55..1bfea51 100644 --- a/include/assert.h +++ b/include/assert.h @@ -68,7 +68,7 @@ __END_DECLS #define assert(e) \ ((void) ((e) ? 0 : __assert (#e, __FILE__, __LINE__))) #define __assert(e, file, line) \ - ((void)printf ("%s:%u: failed assertion `%s'\n", file, line, e), abort(), 0) + ((void)printf ("%s:%u: failed assertion `%s'\n", file, line, e), abort()) #else /* __GNUC__ */ @@ -78,14 +78,14 @@ void __eprintf(const char *, const char *, unsigned, const char *) __dead2; __END_DECLS #define __assert(e, file, line) \ - (__eprintf ("%s:%u: failed assertion `%s'\n", file, line, e), 0) + __eprintf ("%s:%u: failed assertion `%s'\n", file, line, e) #if __DARWIN_UNIX03 #define assert(e) \ (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0) #else /* !__DARWIN_UNIX03 */ #define assert(e) \ - ((void) (__builtin_expect(!(e), 0) ? __assert (#e, __FILE__, __LINE__) : 0)) + (__builtin_expect(!(e), 0) ? __assert (#e, __FILE__, __LINE__) : (void)0) #endif /* __DARWIN_UNIX03 */ #endif /* __GNUC__ */ diff --git a/include/bitstring.h b/include/bitstring.h index 395d727..1e08cb5 100644 --- a/include/bitstring.h +++ b/include/bitstring.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1989, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/c.h b/include/c.h deleted file mode 100644 index 96b761c..0000000 --- a/include/c.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2000 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@ - */ -/* - * Standard C macros - * - ********************************************************************** - * HISTORY - * 02-Feb-86 Glenn Marcy (gm0w) at Carnegie-Mellon University - * Added check to allow multiple or recursive inclusion of this - * file. Added bool enum from machine/types.h for regular users - * that want a real boolean type. - * - * 29-Dec-85 Glenn Marcy (gm0w) at Carnegie-Mellon University - * Also change spacing of MAX and MIN to coincide with that of - * sys/param.h. - * - * 19-Nov-85 Glenn Marcy (gm0w) at Carnegie-Mellon University - * Changed the number of tabs between TRUE, FALSE and their - * respective values to match those in sys/types.h. - * - * 17-Dec-84 Glenn Marcy (gm0w) at Carnegie-Mellon University - * Only define TRUE and FALSE if not defined. Added caseE macro - * for using enumerated types in switch statements. - * - * 23-Apr-81 Mike Accetta (mja) at Carnegie-Mellon University - * Added "sizeofS" and "sizeofA" macros which expand to the size - * of a string constant and array respectively. - * - ********************************************************************** - */ - -#ifndef _C_INCLUDE_ -#define _C_INCLUDE_ - -#ifndef ABS -#define ABS(x) ((x)>=0?(x):-(x)) -#endif /* ABS */ -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif /* MIN */ -#ifndef MAX -#define MAX(a,b) (((a)>(b))?(a):(b)) -#endif /* MAX */ - -#ifndef FALSE -#define FALSE 0 -#endif /* FALSE */ -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ - -#define CERROR (-1) - -#ifndef bool -typedef enum { false = 0, true = 1 } bool; -#endif /* bool */ - -#define sizeofS(string) (sizeof(string) - 1) -#define sizeofA(array) (sizeof(array)/sizeof(array[0])) - -#define caseE(enum_type) case (int)(enum_type) - -#endif /* _C_INCLUDE_ */ diff --git a/include/crt_externs.h b/include/crt_externs.h index f26f205..eb3729a 100644 --- a/include/crt_externs.h +++ b/include/crt_externs.h @@ -38,5 +38,10 @@ extern char ***_NSGetArgv(void); extern int *_NSGetArgc(void); extern char ***_NSGetEnviron(void); extern char **_NSGetProgname(void); -extern struct mach_header *_NSGetMachExecuteHeader(void); +#ifdef __LP64__ +extern struct mach_header_64 * +#else /* !__LP64__ */ +extern struct mach_header * +#endif /* __LP64__ */ + _NSGetMachExecuteHeader(void); __END_DECLS diff --git a/include/ctype.h b/include/ctype.h index 0340732..1e43a6b 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -116,84 +116,27 @@ #define _SW3 _CTYPE_SW3 /* 3 width character */ #endif /* _NONSTD_SOURCE */ -__BEGIN_DECLS -int isalnum(int); -int isalpha(int); -int isblank(int); -int iscntrl(int); -int isdigit(int); -int isgraph(int); -int islower(int); -int isprint(int); -int ispunct(int); -int isspace(int); -int isupper(int); -int isxdigit(int); -int tolower(int); -int toupper(int); -int isascii(int); -int toascii(int); - -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) -int _tolower(int); -int _toupper(int); -int digittoint(int); -int ishexnumber(int); -int isideogram(int); -int isnumber(int); -int isphonogram(int); -int isrune(int); -int isspecial(int); -#endif -__END_DECLS - - -#define isalnum(c) __istype((c), (_CTYPE_A|_CTYPE_D)) -#define isalpha(c) __istype((c), _CTYPE_A) -#define isblank(c) __istype((c), _CTYPE_B) -#define iscntrl(c) __istype((c), _CTYPE_C) -#define isdigit(c) __isctype((c), _CTYPE_D) /* ANSI -- locale independent */ -#define isgraph(c) __istype((c), _CTYPE_G) -#define islower(c) __istype((c), _CTYPE_L) -#define isprint(c) __istype((c), _CTYPE_R) -#define ispunct(c) __istype((c), _CTYPE_P) -#define isspace(c) __istype((c), _CTYPE_S) -#define isupper(c) __istype((c), _CTYPE_U) -#define isxdigit(c) __isctype((c), _CTYPE_X) /* ANSI -- locale independent */ -#define tolower(c) __tolower(c) -#define toupper(c) __toupper(c) - -#define _tolower(c) __tolower(c) -#define _toupper(c) __toupper(c) - -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) -#define digittoint(c) __maskrune((c), 0xFF) -#define isascii(c) (((c) & ~0x7F) == 0) -#define ishexnumber(c) __istype((c), _CTYPE_X) -#define isideogram(c) __istype((c), _CTYPE_I) -#define isnumber(c) __istype((c), _CTYPE_D) -#define isphonogram(c) __istype((c), _CTYPE_Q) -#define isrune(c) __istype((c), 0xFFFFFF00L) -#define isspecial(c) __istype((c), _CTYPE_T) -#define toascii(c) ((c) & 0x7F) -#endif - -/* See comments in about __darwin_ct_rune_t. */ -__BEGIN_DECLS -unsigned long ___runetype(__darwin_ct_rune_t); -__darwin_ct_rune_t ___tolower(__darwin_ct_rune_t); -__darwin_ct_rune_t ___toupper(__darwin_ct_rune_t); -__END_DECLS - /* * _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us - * to generate code for extern versions of all our inline functions. + * to generate code for extern versions of all intermediate inline functions. */ #ifdef _EXTERNALIZE_CTYPE_INLINES_ #define _USE_CTYPE_INLINE_ -#define static -#define __inline -#endif +#define __DARWIN_CTYPE_static_inline +#else /* !_EXTERNALIZE_CTYPE_INLINES_ */ +#define __DARWIN_CTYPE_static_inline static __inline +#endif /* !_EXTERNALIZE_CTYPE_INLINES_ */ + +/* + * _EXTERNALIZE_CTYPE_INLINES_TOP_ is defined in locale/isctype.c to tell us + * to generate code for extern versions of all top-level inline functions. + */ +#ifdef _EXTERNALIZE_CTYPE_INLINES_TOP_ +#define _USE_CTYPE_INLINE_ +#define __DARWIN_CTYPE_TOP_static_inline +#else /* !_EXTERNALIZE_CTYPE_INLINES_TOP_ */ +#define __DARWIN_CTYPE_TOP_static_inline static __inline +#endif /* _EXTERNALIZE_CTYPE_INLINES_TOP_ */ /* * Use inline functions if we are allowed to and the compiler supports them. @@ -201,15 +144,28 @@ __END_DECLS #if !defined(_DONT_USE_CTYPE_INLINE_) && \ (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) +/* See comments in about __darwin_ct_rune_t. */ +__BEGIN_DECLS +unsigned long ___runetype(__darwin_ct_rune_t); +__darwin_ct_rune_t ___tolower(__darwin_ct_rune_t); +__darwin_ct_rune_t ___toupper(__darwin_ct_rune_t); +__END_DECLS + +__DARWIN_CTYPE_TOP_static_inline int +isascii(int _c) +{ + return ((_c & ~0x7F) == 0); +} + #ifdef USE_ASCII -static __inline int +__DARWIN_CTYPE_static_inline int __maskrune(__darwin_ct_rune_t _c, unsigned long _f) { return _CurrentRuneLocale->__runetype[_c && 0xff] & _f; } //Begin-Libc #elif defined(__LIBC__) -static __inline int +__DARWIN_CTYPE_static_inline int __maskrune(__darwin_ct_rune_t _c, unsigned long _f) { return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype(_c) : @@ -222,18 +178,18 @@ int __maskrune(__darwin_ct_rune_t, unsigned long); __END_DECLS #endif /* USE_ASCII */ -static __inline int +__DARWIN_CTYPE_static_inline int __istype(__darwin_ct_rune_t _c, unsigned long _f) { #ifdef USE_ASCII return !!(__maskrune(_c, _f)); #else /* USE_ASCII */ - return !!(isascii(_c) ? (_DefaultRuneLocale.__runetype[_c] & _f) - : __maskrune(_c, _f)); + return (isascii(_c) ? !!(_DefaultRuneLocale.__runetype[_c] & _f) + : !!__maskrune(_c, _f)); #endif /* USE_ASCII */ } -static __inline __darwin_ct_rune_t +__DARWIN_CTYPE_static_inline __darwin_ct_rune_t __isctype(__darwin_ct_rune_t _c, unsigned long _f) { #ifdef USE_ASCII @@ -245,13 +201,13 @@ __isctype(__darwin_ct_rune_t _c, unsigned long _f) } #ifdef USE_ASCII -static __inline __darwin_ct_rune_t +__DARWIN_CTYPE_static_inline __darwin_ct_rune_t __toupper(__darwin_ct_rune_t _c) { return _CurrentRuneLocale->__mapupper[_c & 0xff]; } -static __inline __darwin_ct_rune_t +__DARWIN_CTYPE_static_inline __darwin_ct_rune_t __tolower(__darwin_ct_rune_t _c) { return _CurrentRuneLocale->__maplower[_c & 0xff]; @@ -264,14 +220,14 @@ __tolower(__darwin_ct_rune_t _c) * assume c >= _CACHED_RUNES. So we are stuck making __toupper() a routine * to hide the extended locale details, outside of Libc. */ -static __inline __darwin_ct_rune_t +__DARWIN_CTYPE_static_inline __darwin_ct_rune_t __toupper(__darwin_ct_rune_t _c) { return (_c < 0 || _c >= _CACHED_RUNES) ? ___toupper(_c) : __current_locale()->__lc_ctype->_CurrentRuneLocale.__mapupper[_c]; } -static __inline __darwin_ct_rune_t +__DARWIN_CTYPE_static_inline __darwin_ct_rune_t __tolower(__darwin_ct_rune_t _c) { return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_c) : @@ -285,7 +241,7 @@ __darwin_ct_rune_t __tolower(__darwin_ct_rune_t); __END_DECLS #endif /* USE_ASCII */ -static __inline int +__DARWIN_CTYPE_static_inline int __wcwidth(__darwin_ct_rune_t _c) { unsigned int _x; @@ -298,16 +254,181 @@ __wcwidth(__darwin_ct_rune_t _c) return ((_x & _CTYPE_R) != 0 ? 1 : -1); } +#ifndef _EXTERNALIZE_CTYPE_INLINES_ + +#define _tolower(c) __tolower(c) +#define _toupper(c) __toupper(c) + +__DARWIN_CTYPE_TOP_static_inline int +isalnum(int _c) +{ + return (__istype(_c, _CTYPE_A|_CTYPE_D)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isalpha(int _c) +{ + return (__istype(_c, _CTYPE_A)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isblank(int _c) +{ + return (__istype(_c, _CTYPE_B)); +} + +__DARWIN_CTYPE_TOP_static_inline int +iscntrl(int _c) +{ + return (__istype(_c, _CTYPE_C)); +} + +/* ANSI -- locale independent */ +__DARWIN_CTYPE_TOP_static_inline int +isdigit(int _c) +{ + return (__isctype(_c, _CTYPE_D)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isgraph(int _c) +{ + return (__istype(_c, _CTYPE_G)); +} + +__DARWIN_CTYPE_TOP_static_inline int +islower(int _c) +{ + return (__istype(_c, _CTYPE_L)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isprint(int _c) +{ + return (__istype(_c, _CTYPE_R)); +} + +__DARWIN_CTYPE_TOP_static_inline int +ispunct(int _c) +{ + return (__istype(_c, _CTYPE_P)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isspace(int _c) +{ + return (__istype(_c, _CTYPE_S)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isupper(int _c) +{ + return (__istype(_c, _CTYPE_U)); +} + +/* ANSI -- locale independent */ +__DARWIN_CTYPE_TOP_static_inline int +isxdigit(int _c) +{ + return (__isctype(_c, _CTYPE_X)); +} + +__DARWIN_CTYPE_TOP_static_inline int +toascii(int _c) +{ + return (_c & 0x7F); +} + +__DARWIN_CTYPE_TOP_static_inline int +tolower(int _c) +{ + return (__tolower(_c)); +} + +__DARWIN_CTYPE_TOP_static_inline int +toupper(int _c) +{ + return (__toupper(_c)); +} + +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +__DARWIN_CTYPE_TOP_static_inline int +digittoint(int _c) +{ + return (__maskrune(_c, 0x0F)); +} + +__DARWIN_CTYPE_TOP_static_inline int +ishexnumber(int _c) +{ + return (__istype(_c, _CTYPE_X)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isideogram(int _c) +{ + return (__istype(_c, _CTYPE_I)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isnumber(int _c) +{ + return (__istype(_c, _CTYPE_D)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isphonogram(int _c) +{ + return (__istype(_c, _CTYPE_Q)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isrune(int _c) +{ + return (__istype(_c, 0xFFFFFFF0L)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isspecial(int _c) +{ + return (__istype(_c, _CTYPE_T)); +} +#endif /* !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +#endif /* _EXTERNALIZE_CTYPE_INLINES_ */ + #else /* not using inlines */ __BEGIN_DECLS -int __maskrune(__darwin_ct_rune_t, unsigned long); -int __istype (__darwin_ct_rune_t, unsigned long); -int __isctype(__darwin_ct_rune_t, unsigned long); -__darwin_ct_rune_t __toupper(__darwin_ct_rune_t); -__darwin_ct_rune_t __tolower(__darwin_ct_rune_t); -int __wcwidth(__darwin_ct_rune_t); +int isalnum(int); +int isalpha(int); +int isblank(int); +int iscntrl(int); +int isdigit(int); +int isgraph(int); +int islower(int); +int isprint(int); +int ispunct(int); +int isspace(int); +int isupper(int); +int isxdigit(int); +int tolower(int); +int toupper(int); +int isascii(int); +int toascii(int); + +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +int _tolower(int); +int _toupper(int); +int digittoint(int); +int ishexnumber(int); +int isideogram(int); +int isnumber(int); +int isphonogram(int); +int isrune(int); +int isspecial(int); +#endif __END_DECLS + #endif /* using inlines */ #ifdef _USE_EXTENDED_LOCALES_ diff --git a/include/db.h b/include/db.h index fc49e1e..7af97b8 100644 --- a/include/db.h +++ b/include/db.h @@ -1,25 +1,3 @@ -/* - * 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@ - */ /*- * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. diff --git a/include/dirent.h b/include/dirent.h index dd61429..ef9bea2 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -69,23 +69,23 @@ struct _telldir; /* forward reference */ /* structure describing an open directory. */ typedef struct { - int dd_fd; /* file descriptor associated with directory */ - long dd_loc; /* offset in current buffer */ - long dd_size; /* amount of data returned by getdirentries */ - char *dd_buf; /* data buffer */ - int dd_len; /* size of data buffer */ - long dd_seek; /* magic cookie returned by getdirentries */ - long dd_rewind; /* magic cookie for rewinding */ - int dd_flags; /* flags for readdir */ - __darwin_pthread_mutex_t dd_lock; /* for thread locking */ - struct _telldir *dd_td; /* telldir position recording */ + int __dd_fd; /* file descriptor associated with directory */ + long __dd_loc; /* offset in current buffer */ + long __dd_size; /* amount of data returned by getdirentries */ + char *__dd_buf; /* data buffer */ + int __dd_len; /* size of data buffer */ + long __dd_seek; /* magic cookie returned by getdirentries */ + long __dd_rewind; /* magic cookie for rewinding */ + int __dd_flags; /* flags for readdir */ + __darwin_pthread_mutex_t __dd_lock; /* for thread locking */ + struct _telldir *__dd_td; /* telldir position recording */ } DIR; -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) /* definitions for library routines operating on directories. */ #define DIRBLKSIZ 1024 -#define dirfd(dirp) ((dirp)->dd_fd) +#define dirfd(dirp) ((dirp)->__dd_fd) /* flags for opendir2 */ #define DTF_HIDEW 0x0001 /* hide whiteout entries */ @@ -93,33 +93,81 @@ typedef struct { #define DTF_REWIND 0x0004 /* rewind after reading union stack */ #define __DTF_READALL 0x0008 /* everything has been read */ -#endif /* ! _POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #ifndef KERNEL #include __BEGIN_DECLS -#ifndef _POSIX_C_SOURCE -int alphasort(const void *, const void *); +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +int alphasort(const void *, const void *) __DARWIN_INODE64(alphasort); #endif /* not POSIX */ +//Begin-Libc +#ifndef LIBC_ALIAS_CLOSEDIR +//End-Libc int closedir(DIR *) __DARWIN_ALIAS(closedir); -#ifndef _POSIX_C_SOURCE +//Begin-Libc +#else /* LIBC_ALIAS_CLOSEDIR */ +int closedir(DIR *) LIBC_ALIAS(closedir); +#endif /* !LIBC_ALIAS_CLOSEDIR */ +//End-Libc +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) int getdirentries(int, char *, int, long *); #endif /* not POSIX */ -DIR *opendir(const char *) __DARWIN_ALIAS(opendir); -#ifndef _POSIX_C_SOURCE -DIR *__opendir2(const char *, int) __DARWIN_ALIAS(__opendir2); +//Begin-Libc +#ifndef LIBC_ALIAS_OPENDIR +//End-Libc +DIR *opendir(const char *) __DARWIN_ALIAS_I(opendir); +//Begin-Libc +#else /* LIBC_ALIAS_OPENDIR */ +DIR *opendir(const char *) LIBC_ALIAS_I(opendir); +#endif /* !LIBC_ALIAS_OPENDIR */ +//End-Libc +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +//Begin-Libc +#ifndef LIBC_ALIAS___OPENDIR2 +//End-Libc +DIR *__opendir2(const char *, int) __DARWIN_ALIAS_I(__opendir2); +//Begin-Libc +#else /* LIBC_ALIAS___OPENDIR2 */ +DIR *__opendir2(const char *, int) LIBC_ALIAS_I(__opendir2); +#endif /* !LIBC_ALIAS___OPENDIR2 */ +//End-Libc #endif /* not POSIX */ -struct dirent *readdir(DIR *); -int readdir_r(DIR *, struct dirent *, struct dirent **); -void rewinddir(DIR *) __DARWIN_ALIAS(rewinddir); -#ifndef _POSIX_C_SOURCE +struct dirent *readdir(DIR *) __DARWIN_INODE64(readdir); +int readdir_r(DIR *, struct dirent *, struct dirent **) __DARWIN_INODE64(readdir_r); +//Begin-Libc +#ifndef LIBC_ALIAS_REWINDDIR +//End-Libc +void rewinddir(DIR *) __DARWIN_ALIAS_I(rewinddir); +//Begin-Libc +#else /* LIBC_ALIAS_REWINDDIR */ +void rewinddir(DIR *) LIBC_ALIAS_I(rewinddir); +#endif /* !LIBC_ALIAS_REWINDDIR */ +//End-Libc +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) int scandir(const char *, struct dirent ***, - int (*)(struct dirent *), int (*)(const void *, const void *)); + int (*)(struct dirent *), int (*)(const void *, const void *)) __DARWIN_INODE64(scandir); #endif /* not POSIX */ -void seekdir(DIR *, long) __DARWIN_ALIAS(seekdir); -long telldir(DIR *) __DARWIN_ALIAS(telldir); +//Begin-Libc +#ifndef LIBC_ALIAS_SEEKDIR +//End-Libc +void seekdir(DIR *, long) __DARWIN_ALIAS_I(seekdir); +//Begin-Libc +#else /* LIBC_ALIAS_SEEKDIR */ +void seekdir(DIR *, long) LIBC_ALIAS_I(seekdir); +#endif /* !LIBC_ALIAS_SEEKDIR */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_TELLDIR +//End-Libc +long telldir(DIR *) __DARWIN_ALIAS_I(telldir); +//Begin-Libc +#else /* LIBC_ALIAS_TELLDIR */ +long telldir(DIR *) LIBC_ALIAS_I(telldir); +#endif /* !LIBC_ALIAS_TELLDIR */ +//End-Libc __END_DECLS #endif /* !KERNEL */ diff --git a/include/disktab.h b/include/disktab.h index 535726a..55f0f46 100644 --- a/include/disktab.h +++ b/include/disktab.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1983, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/fnmatch.h b/include/fnmatch.h index d4425f1..f2e44e5 100644 --- a/include/fnmatch.h +++ b/include/fnmatch.h @@ -68,7 +68,7 @@ #define FNM_NOSYS (-1) /* Reserved. */ -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #define FNM_LEADING_DIR 0x08 /* Ignore / after Imatch. */ #define FNM_CASEFOLD 0x10 /* Case insensitive search. */ #define FNM_IGNORECASE FNM_CASEFOLD @@ -76,7 +76,15 @@ #endif __BEGIN_DECLS -int fnmatch(const char *, const char *, int); +//Begin-Libc +#ifndef LIBC_ALIAS_FNMATCH +//End-Libc +int fnmatch(const char *, const char *, int) __DARWIN_ALIAS(fnmatch); +//Begin-Libc +#else /* LIBC_ALIAS_FNMATCH */ +int fnmatch(const char *, const char *, int) LIBC_ALIAS(fnmatch); +#endif /* !LIBC_ALIAS_FNMATCH */ +//End-Libc __END_DECLS #endif /* !_FNMATCH_H_ */ diff --git a/include/fsproperties.h b/include/fsproperties.h index e506481..bef75c4 100644 --- a/include/fsproperties.h +++ b/include/fsproperties.h @@ -38,7 +38,9 @@ #define kFSFormatArgumentsKey "FSFormatArguments" #define kFSFormatContentMaskKey "FSFormatContentMask" #define kFSFormatExecutableKey "FSFormatExecutable" +#define kFSFormatInteractiveKey "FSFormatInteractive" #define kFSFormatMinimumSizeKey "FSFormatMinimumSize" +#define kFSFormatMaximumSizeKey "FSFormatMaximumSize" #define kFSMountArgumentsKey "FSMountArguments" #define kFSMountExecutableKey "FSMountExecutable" #define kFSNameKey "FSName" @@ -46,5 +48,6 @@ #define kFSRepairExecutableKey "FSRepairExecutable" #define kFSVerificationArgumentsKey "FSVerificationArguments" #define kFSVerificationExecutableKey "FSVerificationExecutable" +#define kFSSubTypeKey "FSSubType" #endif /* _FSPROPERTIES_H_ */ diff --git a/include/fstab.h b/include/fstab.h index ec83af5..c3ae066 100644 --- a/include/fstab.h +++ b/include/fstab.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1980, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/fts.h b/include/fts.h index dc14cc2..74ba842 100644 --- a/include/fts.h +++ b/include/fts.h @@ -58,6 +58,23 @@ #ifndef _FTS_H_ #define _FTS_H_ +#include + +#ifndef _DEV_T +typedef __darwin_dev_t dev_t; /* device number */ +#define _DEV_T +#endif + +#ifndef _INO_T +typedef __darwin_ino_t ino_t; /* inode number */ +#define _INO_T +#endif + +#ifndef _NLINK_T +typedef __uint16_t nlink_t; /* link count */ +#define _NLINK_T +#endif + typedef struct { struct _ftsent *fts_cur; /* current node */ struct _ftsent *fts_child; /* linked list of children */ @@ -77,7 +94,8 @@ typedef struct { #define FTS_SEEDOT 0x020 /* return dot and dot-dot */ #define FTS_XDEV 0x040 /* don't cross devices */ #define FTS_WHITEOUT 0x080 /* return whiteout information */ -#define FTS_OPTIONMASK 0x0ff /* valid user option mask */ +#define FTS_COMFOLLOWDIR 0x400 /* (non-std) follow command line symlinks for directories only */ +#define FTS_OPTIONMASK 0x4ff /* valid user option mask */ #define FTS_NAMEONLY 0x100 /* (private) child names only */ #define FTS_STOP 0x200 /* (private) unrecoverable error */ @@ -139,12 +157,53 @@ typedef struct _ftsent { #include __BEGIN_DECLS -FTSENT *fts_children(FTS *, int); -int fts_close(FTS *); +//Begin-Libc +#ifndef LIBC_ALIAS_FTS_CHILDREN +//End-Libc +FTSENT *fts_children(FTS *, int) __DARWIN_INODE64(fts_children); +//Begin-Libc +#else /* LIBC_ALIAS_FTS_CHILDREN */ +FTSENT *fts_children(FTS *, int) LIBC_INODE64(fts_children); +#endif /* !LIBC_ALIAS_FTS_CHILDREN */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_FTS_CLOSE +//End-Libc +int fts_close(FTS *) __DARWIN_INODE64(fts_close); +//Begin-Libc +#else /* LIBC_ALIAS_FTS_CLOSE */ +int fts_close(FTS *) LIBC_INODE64(fts_close); +#endif /* !LIBC_ALIAS_FTS_CLOSE */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_FTS_OPEN +//End-Libc +FTS *fts_open(char * const *, int, + int (*)(const FTSENT **, const FTSENT **)) __DARWIN_INODE64(fts_open); +//Begin-Libc +#else /* LIBC_ALIAS_FTS_OPEN */ FTS *fts_open(char * const *, int, - int (*)(const FTSENT **, const FTSENT **)); -FTSENT *fts_read(FTS *); -int fts_set(FTS *, FTSENT *, int); + int (*)(const FTSENT **, const FTSENT **)) LIBC_INODE64(fts_open); +#endif /* !LIBC_ALIAS_FTS_OPEN */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_FTS_READ +//End-Libc +FTSENT *fts_read(FTS *) __DARWIN_INODE64(fts_read); +//Begin-Libc +#else /* LIBC_ALIAS_FTS_READ */ +FTSENT *fts_read(FTS *) LIBC_INODE64(fts_read); +#endif /* !LIBC_ALIAS_FTS_READ */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_FTS_SET +//End-Libc +int fts_set(FTS *, FTSENT *, int) __DARWIN_INODE64(fts_set); +//Begin-Libc +#else /* LIBC_ALIAS_FTS_SET */ +int fts_set(FTS *, FTSENT *, int) LIBC_INODE64(fts_set); +#endif /* !LIBC_ALIAS_FTS_SET */ +//End-Libc __END_DECLS #endif /* !_FTS_H_ */ diff --git a/include/ftw.h b/include/ftw.h index 4fda285..f1c6db8 100644 --- a/include/ftw.h +++ b/include/ftw.h @@ -51,10 +51,28 @@ struct FTW { }; __BEGIN_DECLS +//Begin-Libc +#ifndef LIBC_ALIAS_FTW +//End-Libc int ftw(const char *, int (*)(const char *, const struct stat *, int), int) - __DARWIN_ALIAS(ftw); + __DARWIN_ALIAS_I(ftw); +//Begin-Libc +#else /* LIBC_ALIAS_FTW */ +int ftw(const char *, int (*)(const char *, const struct stat *, int), int) + LIBC_ALIAS_I(ftw); +#endif /* !LIBC_ALIAS_FTW */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_NFTW +//End-Libc +int nftw(const char *, int (*)(const char *, const struct stat *, int, + struct FTW *), int, int) __DARWIN_ALIAS_I(nftw); +//Begin-Libc +#else /* LIBC_ALIAS_NFTW */ int nftw(const char *, int (*)(const char *, const struct stat *, int, - struct FTW *), int, int) __DARWIN_ALIAS(nftw); + struct FTW *), int, int) LIBC_ALIAS_I(nftw); +#endif /* !LIBC_ALIAS_NFTW */ +//End-Libc __END_DECLS #endif /* !_FTW_H */ diff --git a/include/getopt.h b/include/getopt.h index 490b92f..3247fe0 100644 --- a/include/getopt.h +++ b/include/getopt.h @@ -72,7 +72,7 @@ int getopt_long_only(int, char * const *, const char *, const struct option *, int *); #ifndef _GETOPT #define _GETOPT -int getopt(int, char * const [], const char *); +int getopt(int, char * const [], const char *) __DARWIN_ALIAS(getopt); extern char *optarg; /* getopt(3) external variables */ extern int optind, opterr, optopt; diff --git a/include/glob.h b/include/glob.h index 8b85e98..62b1756 100644 --- a/include/glob.h +++ b/include/glob.h @@ -40,7 +40,6 @@ #ifndef _GLOB_H_ #define _GLOB_H_ -#include #include <_types.h> #ifndef _SIZE_T @@ -48,10 +47,10 @@ typedef __darwin_size_t size_t; #endif -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) struct dirent; struct stat; -#endif /* _POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ typedef struct { size_t gl_pathc; /* Count of total paths so far. */ int gl_matchc; /* Count of paths matching pattern. */ @@ -61,20 +60,25 @@ typedef struct { /* Copy of errfunc parameter to glob. */ int (*gl_errfunc)(const char *, int); -#ifndef _POSIX_C_SOURCE /* * Alternate filesystem access methods for glob; replacement * versions of closedir(3), readdir(3), opendir(3), stat(2) * and lstat(2). */ void (*gl_closedir)(void *); +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) struct dirent *(*gl_readdir)(void *); +#else /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ + void *(*gl_readdir)(void *); +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ void *(*gl_opendir)(const char *); +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) int (*gl_lstat)(const char *, struct stat *); int (*gl_stat)(const char *, struct stat *); -#else /* _POSIX_C_SOURCE */ - void *_gl_reserved[5]; -#endif /* _POSIX_C_SOURCE */ +#else /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ + int (*gl_lstat)(const char *, void *); + int (*gl_stat)(const char *, void *); +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ } glob_t; /* Believed to have been introduced in 1003.2-1992 */ @@ -99,14 +103,26 @@ typedef struct { #define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ #define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ #define GLOB_LIMIT 0x1000 /* limit number of returned paths */ +//Begin-Libc +#define GLOB_INODE64 0x80000000 +//End-Libc /* source compatibility, these are the old names */ #define GLOB_MAXPATH GLOB_LIMIT #define GLOB_ABEND GLOB_ABORTED __BEGIN_DECLS +//Begin-Libc +#ifndef LIBC_ALIAS_GLOB +//End-Libc int glob(const char * __restrict, int, int (*)(const char *, int), - glob_t * __restrict); + glob_t * __restrict) __DARWIN_INODE64(glob); +//Begin-Libc +#else /* LIBC_ALIAS_GLOB */ +int glob(const char * __restrict, int, int (*)(const char *, int), + glob_t * __restrict) LIBC_INODE64(glob); +#endif /* !LIBC_ALIAS_GLOB */ +//End-Libc void globfree(glob_t *); __END_DECLS diff --git a/include/grp.h b/include/grp.h index e4ea129..10f230e 100644 --- a/include/grp.h +++ b/include/grp.h @@ -80,7 +80,7 @@ typedef __darwin_gid_t gid_t; /* [XBD] */ typedef __darwin_size_t size_t; /* [???] */ #endif -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #define _PATH_GROUP "/etc/group" #endif @@ -102,11 +102,11 @@ int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **); int getgrnam_r(const char *, struct group *, char *, size_t, struct group **); /* [XSI] */ struct group *getgrent(void); -int setgrent(void); +void setgrent(void); void endgrent(void); -#ifndef _POSIX_C_SOURCE -#ifndef _XOPEN_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#if !defined(_XOPEN_SOURCE) || defined(_DARWIN_C_SOURCE) char *group_from_gid(gid_t, int); #endif void setgrfile(const char *); diff --git a/include/inttypes.h b/include/inttypes.h index e2513f2..4f9dd8d 100644 --- a/include/inttypes.h +++ b/include/inttypes.h @@ -28,37 +28,29 @@ * and their ilk. */ -#if !defined(_INTTYPES_H_) -#define _INTTYPES_H_ - -#include /* For __BEGIN_DECLS and __END_DECLS */ -#include <_types.h> /* For __darwin_wchar_t */ -#include - -#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) - /* Translator is not ISO/IEC 9899:1999-compliant. */ -# if !defined(restrict) -# define restrict -# define __RESTRICT_KEYWORD_DEFINED__ -# endif -#endif - /* "C++ implementations should define these macros only when * __STDC_FORMAT_MACROS is defined before is included." */ -#if (! defined(__cplusplus)) || defined(__STDC_FORMAT_MACROS) +#if (!defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)) && !defined(__STDC_FORMAT_MACROS_DEFINED) +#define __STDC_FORMAT_MACROS_DEFINED # undef __PRI_8_LENGTH_MODIFIER__ # undef __PRI_64_LENGTH_MODIFIER__ # undef __SCN_64_LENGTH_MODIFIER__ +# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0 > 1020 +# define __PRI_8_LENGTH_MODIFIER__ "hh" +# define __PRI_64_LENGTH_MODIFIER__ "ll" +# define __SCN_64_LENGTH_MODIFIER__ "ll" +# else /* These could be "hh", "ll", and "ll" respectively, but that doesn't work on 10.2, and these do. Note that there's no way to use scanf to scan a decimal into a 'char' argument on 10.2, so "hh" is used unconditionally and programs that use it won't work on Jaguar. */ -# define __PRI_8_LENGTH_MODIFIER__ "" /* none */ -# define __PRI_64_LENGTH_MODIFIER__ "q" -# define __SCN_64_LENGTH_MODIFIER__ "q" +# define __PRI_8_LENGTH_MODIFIER__ "" /* none */ +# define __PRI_64_LENGTH_MODIFIER__ "q" +# define __SCN_64_LENGTH_MODIFIER__ "q" +# endif # define __PRI_MAX_LENGTH_MODIFIER__ "j" # define __SCN_MAX_LENGTH_MODIFIER__ "j" @@ -161,11 +153,19 @@ # define PRIxMAX __PRI_MAX_LENGTH_MODIFIER__ "x" # define PRIXMAX __PRI_MAX_LENGTH_MODIFIER__ "X" -# define SCNd8 "hhd" -# define SCNi8 "hhi" -# define SCNo8 "hho" -# define SCNu8 "hhu" -# define SCNx8 "hhx" +# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0 > 1020 +# define SCNd8 __PRI_8_LENGTH_MODIFIER__ "d" +# define SCNi8 __PRI_8_LENGTH_MODIFIER__ "i" +# define SCNo8 __PRI_8_LENGTH_MODIFIER__ "o" +# define SCNu8 __PRI_8_LENGTH_MODIFIER__ "u" +# define SCNx8 __PRI_8_LENGTH_MODIFIER__ "x" +# else +# define SCNd8 "hhd" +# define SCNi8 "hhi" +# define SCNo8 "hho" +# define SCNu8 "hhu" +# define SCNx8 "hhx" +# endif # define SCNd16 "hd" # define SCNi16 "hi" @@ -247,6 +247,21 @@ #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 + +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) + /* Translator is not ISO/IEC 9899:1999-compliant. */ +# if !defined(restrict) +# define restrict +# define __RESTRICT_KEYWORD_DEFINED__ +# endif +#endif + __BEGIN_DECLS /* 7.8.2.1 */ @@ -275,6 +290,11 @@ __BEGIN_DECLS extern intmax_t wcstoimax(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base); extern uintmax_t wcstoumax(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base); +/* Poison the following routines if -fshort-wchar is set */ +#if !defined(__cplusplus) && defined(__WCHAR_MAX__) && __WCHAR_MAX__ <= 0xffffU +#pragma GCC poison wcstoimax wcstoumax +#endif + __END_DECLS #ifdef _USE_EXTENDED_LOCALES_ diff --git a/include/iso646.h b/include/iso646.h index 6b4ed46..71cf9b5 100644 --- a/include/iso646.h +++ b/include/iso646.h @@ -29,7 +29,9 @@ #ifndef _ISO646_H_ #define _ISO646_H_ -#ifndef _POSIX_C_SOURCE +#include + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #ifndef __cplusplus #define and && @@ -45,6 +47,6 @@ #define xor_eq ^= #endif /* ! __cplusplus */ -#endif /* ! _POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #endif /* !_ISO646_H_ */ diff --git a/include/langinfo.h b/include/langinfo.h index a5d39c1..27ba0a5 100644 --- a/include/langinfo.h +++ b/include/langinfo.h @@ -29,7 +29,6 @@ #ifndef _LANGINFO_H_ #define _LANGINFO_H_ -#include #include <_types.h> #ifndef _NL_ITEM @@ -110,7 +109,7 @@ typedef __darwin_nl_item nl_item; #define CRNCYSTR 56 /* currency symbol */ -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #define D_MD_ORDER 57 /* month/day order (local extension) */ #endif diff --git a/include/libgen.h b/include/libgen.h index 6b6747a..06184d8 100644 --- a/include/libgen.h +++ b/include/libgen.h @@ -35,9 +35,18 @@ __BEGIN_DECLS +#if __DARWIN_UNIX03 + +char *basename(char *); +char *dirname(char *); + +#else /* !__DARWIN_UNIX03 */ + char *basename(const char *); char *dirname(const char *); +#endif /* __DARWIN_UNIX_03 */ + __END_DECLS #endif /* _LIBGEN_H_ */ diff --git a/include/libkern/Makefile.inc b/include/libkern/Makefile.inc index b2d4a78..65ac7ee 100644 --- a/include/libkern/Makefile.inc +++ b/include/libkern/Makefile.inc @@ -1,3 +1,2 @@ -LIBKERN_INSTHDRS += OSAtomic.h - +LIBKERN_INSTHDRS += OSAtomic.h OSCacheControl.h LIBKERN_INSTHDRS := ${LIBKERN_INSTHDRS:S/^/${.CURDIR}\/include\/libkern\//} diff --git a/include/libkern/OSAtomic.h b/include/libkern/OSAtomic.h index 1d42a8e..56be70d 100644 --- a/include/libkern/OSAtomic.h +++ b/include/libkern/OSAtomic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -42,14 +42,15 @@ * 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 a multiprocessor, the barrier can be quite expensive on some platforms, + * eg 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 * a shared data structure and then atomically increment a variable to indicate - * that the initialization is complete, then you MUST use OSAtomicIncrement32Barrier() + * 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(), + * Likewise, the consumer of that data structure must use 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(). @@ -62,79 +63,98 @@ __BEGIN_DECLS -/* Arithmetic functions. They return the new value. All the "or", "and", and "xor" - * operations, and the barrier forms of add, are layered on top of compare-and-swap. +/* Arithmetic functions. They return the new value. */ -int32_t OSAtomicAdd32( int32_t theAmount, int32_t *theValue ); -int32_t OSAtomicAdd32Barrier( int32_t theAmount, int32_t *theValue ); +int32_t OSAtomicAdd32( int32_t __theAmount, volatile int32_t *__theValue ); +int32_t OSAtomicAdd32Barrier( int32_t __theAmount, volatile int32_t *__theValue ); inline static -int32_t OSAtomicIncrement32( int32_t *theValue ) - { return OSAtomicAdd32( 1, theValue); } +int32_t OSAtomicIncrement32( volatile int32_t *__theValue ) + { return OSAtomicAdd32( 1, __theValue); } inline static -int32_t OSAtomicIncrement32Barrier( int32_t *theValue ) - { return OSAtomicAdd32Barrier( 1, theValue); } +int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue ) + { return OSAtomicAdd32Barrier( 1, __theValue); } inline static -int32_t OSAtomicDecrement32( int32_t *theValue ) - { return OSAtomicAdd32( -1, theValue); } +int32_t OSAtomicDecrement32( volatile int32_t *__theValue ) + { return OSAtomicAdd32( -1, __theValue); } inline static -int32_t OSAtomicDecrement32Barrier( int32_t *theValue ) - { return OSAtomicAdd32Barrier( -1, theValue); } - -int32_t OSAtomicOr32( uint32_t theMask, uint32_t *theValue ); -int32_t OSAtomicOr32Barrier( uint32_t theMask, uint32_t *theValue ); - -int32_t OSAtomicAnd32( uint32_t theMask, uint32_t *theValue ); -int32_t OSAtomicAnd32Barrier( uint32_t theMask, uint32_t *theValue ); - -int32_t OSAtomicXor32( uint32_t theMask, uint32_t *theValue ); -int32_t OSAtomicXor32Barrier( uint32_t theMask, uint32_t *theValue ); +int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue ) + { return OSAtomicAdd32Barrier( -1, __theValue); } #if defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) -int64_t OSAtomicAdd64( int64_t theAmount, int64_t *theValue ); -int64_t OSAtomicAdd64Barrier( int64_t theAmount, int64_t *theValue ); +int64_t OSAtomicAdd64( int64_t __theAmount, volatile int64_t *__theValue ); +int64_t OSAtomicAdd64Barrier( int64_t __theAmount, volatile int64_t *__theValue ); inline static -int64_t OSAtomicIncrement64( int64_t *theValue ) - { return OSAtomicAdd64( 1, theValue); } +int64_t OSAtomicIncrement64( volatile int64_t *__theValue ) + { return OSAtomicAdd64( 1, __theValue); } inline static -int64_t OSAtomicIncrement64Barrier( int64_t *theValue ) - { return OSAtomicAdd64Barrier( 1, theValue); } +int64_t OSAtomicIncrement64Barrier( volatile int64_t *__theValue ) + { return OSAtomicAdd64Barrier( 1, __theValue); } inline static -int64_t OSAtomicDecrement64( int64_t *theValue ) - { return OSAtomicAdd64( -1, theValue); } +int64_t OSAtomicDecrement64( volatile int64_t *__theValue ) + { return OSAtomicAdd64( -1, __theValue); } inline static -int64_t OSAtomicDecrement64Barrier( int64_t *theValue ) - { return OSAtomicAdd64Barrier( -1, theValue); } +int64_t OSAtomicDecrement64Barrier( volatile int64_t *__theValue ) + { return OSAtomicAdd64Barrier( -1, __theValue); } #endif /* defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) */ -/* Compare and swap. They return true if the swap occured. +/* 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 + * versions return the value after the operation. All are layered on top of + * compare-and-swap. */ -bool OSAtomicCompareAndSwap32( int32_t oldValue, int32_t newValue, int32_t *theValue ); -bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue, int32_t newValue, int32_t *theValue ); +int32_t OSAtomicOr32( uint32_t __theMask, volatile uint32_t *__theValue ); +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 ); + +int32_t OSAtomicAnd32( uint32_t __theMask, volatile uint32_t *__theValue ); +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 ); + +int32_t OSAtomicXor32( uint32_t __theMask, volatile uint32_t *__theValue ); +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 ); + + +/* 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. + */ +bool OSAtomicCompareAndSwap32( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue ); +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 ); #if defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) -bool OSAtomicCompareAndSwap64( int64_t oldValue, int64_t newValue, int64_t *theValue ); -bool OSAtomicCompareAndSwap64Barrier( int64_t oldValue, int64_t newValue, int64_t *theValue ); +bool OSAtomicCompareAndSwap64( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ); +bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ); #endif /* defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) */ /* Test and set. They return the original value of the bit, and operate on bit (0x80>>(n&7)) - * in byte ((char*)theAddress + (n>>3)). They are layered on top of the compare-and-swap - * operation. + * in byte ((char*)theAddress + (n>>3)). */ -bool OSAtomicTestAndSet( uint32_t n, void *theAddress ); -bool OSAtomicTestAndSetBarrier( uint32_t n, void *theAddress ); -bool OSAtomicTestAndClear( uint32_t n, void *theAddress ); -bool OSAtomicTestAndClearBarrier( uint32_t n, void *theAddress ); +bool OSAtomicTestAndSet( uint32_t __n, volatile void *__theAddress ); +bool OSAtomicTestAndSetBarrier( uint32_t __n, volatile void *__theAddress ); +bool OSAtomicTestAndClear( uint32_t __n, volatile void *__theAddress ); +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. @@ -143,17 +163,47 @@ bool OSAtomicTestAndClearBarrier( uint32_t n, void *theAddress ); */ #define OS_SPINLOCK_INIT 0 -typedef int32_t OSSpinLock; +typedef int32_t OSSpinLock; -bool OSSpinLockTry( OSSpinLock *lock ); -void OSSpinLockLock( OSSpinLock *lock ); -void OSSpinLockUnlock( OSSpinLock *lock ); +bool OSSpinLockTry( volatile OSSpinLock *__lock ); +void OSSpinLockLock( volatile OSSpinLock *__lock ); +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. + */ +#if defined(__x86_64__) + +typedef volatile struct { + void *opaque1; + long opaque2; +} OSQueueHead __attribute__ ((aligned (16))); + +#else + +typedef volatile struct { + void *opaque1; + long opaque2; +} OSQueueHead; + +#endif + +#define OS_ATOMIC_QUEUE_INIT { NULL, 0 } + +void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset); +void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset); /* Memory barrier. It is both a read and write barrier. */ void OSMemoryBarrier( void ); + __END_DECLS #endif /* _OSATOMIC_H_ */ diff --git a/include/libkern/OSCacheControl.h b/include/libkern/OSCacheControl.h new file mode 100644 index 0000000..771a704 --- /dev/null +++ b/include/libkern/OSCacheControl.h @@ -0,0 +1,65 @@ +/* + * 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@ + */ + +#ifndef _OS_CACHE_CONTROL_H_ +#define _OS_CACHE_CONTROL_H_ + +#include +#include +#include + +__BEGIN_DECLS + + +/* Functions performed by sys_cache_control(): */ + +/* Prepare memory for execution. This should be called + * after writing machine instructions to memory, before + * executing them. It syncs the dcache and icache. + * On IA32 processors this function is a NOP, because + * no synchronization is required. + */ +#define kCacheFunctionPrepareForExecution 1 + +/* Flush data cache(s). This ensures that cached data + * makes it all the way out to DRAM, and then removes + * copies of the data from all processor caches. + * It can be useful when dealing with cache incoherent + * devices or DMA. + */ +#define kCacheFunctionFlushDcache 2 + + +/* perform one of the above cache functions: */ +int sys_cache_control( int function, void *start, size_t len); + +/* equivalent to sys_cache_control(kCacheFunctionPrepareForExecution): */ +void sys_icache_invalidate( void *start, size_t len); + +/* equivalent to sys_cache_control(kCacheFunctionFlushDcache): */ +void sys_dcache_flush( void *start, size_t len); + + +__END_DECLS + +#endif /* _OS_CACHE_CONTROL_H_ */ diff --git a/include/limits.h b/include/limits.h index e83c92e..49d0502 100644 --- a/include/limits.h +++ b/include/limits.h @@ -60,11 +60,12 @@ #ifndef _LIMITS_H_ #define _LIMITS_H_ +#include #include #include #if !defined(_ANSI_SOURCE) -#define _POSIX_AIO_LISTIO_MAX 16 +#define _POSIX_AIO_LISTIO_MAX 2 #define _POSIX_AIO_MAX 1 #define _POSIX_DELAYTIMER_MAX 32 #define _POSIX_HOST_NAME_MAX 255 @@ -86,12 +87,11 @@ #define _POSIX_STREAM_MAX 8 #define _POSIX_TZNAME_MAX 6 +#define _POSIX_RE_DUP_MAX 255 #define _POSIX_RTSIG_MAX 8 #define _POSIX_SEM_NSEMS_MAX 256 #define _POSIX_SEM_VALUE_MAX 32767 #define _POSIX_SIGQUEUE_MAX 32 -#define _POSIX_SSIZE_MAX 32767 -#define _POSIX_STREAM_MAX 8 #define _POSIX_SS_REPL_MAX 4 #define _POSIX_SYMLINK_MAX 255 #define _POSIX_SYMLOOP_MAX 8 @@ -116,13 +116,13 @@ #define _POSIX2_LINE_MAX 2048 #define _POSIX2_RE_DUP_MAX 255 -#define PTHREAD_STACK_MIN 8192 -#define PTHREAD_DESTRUCTOR_ITERATIONS 4 -#define PTHREAD_KEYS_MAX 128 +#define PTHREAD_STACK_MIN 8192 +#define PTHREAD_DESTRUCTOR_ITERATIONS 4 +#define PTHREAD_KEYS_MAX 512 -#if !defined(_POSIX_C_SOURCE) +#if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #define PASS_MAX 128 -#endif /* _POSIX_C_SOURCE */ +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ #define NL_ARGMAX 9 #define NL_LANGMAX 14 diff --git a/include/malloc/malloc.h b/include/malloc/malloc.h index 965bbe0..5db543d 100644 --- a/include/malloc/malloc.h +++ b/include/malloc/malloc.h @@ -88,6 +88,9 @@ extern malloc_zone_t *malloc_zone_from_ptr(const void *ptr); extern size_t malloc_size(const void *ptr); /* Returns size of given 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 */ + /********* Batch methods ************/ extern unsigned malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); diff --git a/include/memory.h b/include/memory.h index abf1034..cb9c8b5 100644 --- a/include/memory.h +++ b/include/memory.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1988, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/mpool.h b/include/mpool.h index c33681a..eee1634 100644 --- a/include/mpool.h +++ b/include/mpool.h @@ -1,25 +1,3 @@ -/* - * 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@ - */ /*- * Copyright (c) 1991, 1993, 1994 * The Regents of the University of California. All rights reserved. diff --git a/include/ndbm.h b/include/ndbm.h index 71b1352..a3fb88c 100644 --- a/include/ndbm.h +++ b/include/ndbm.h @@ -61,7 +61,6 @@ #ifndef _NDBM_H_ #define _NDBM_H_ -#include #include <_types.h> #ifndef _MODE_T @@ -74,7 +73,7 @@ typedef __darwin_mode_t mode_t; typedef __darwin_size_t size_t; #endif -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) /* Map dbm interface onto db(3). */ #include #define DBM_RDONLY O_RDONLY @@ -84,7 +83,7 @@ typedef __darwin_size_t size_t; #define DBM_INSERT 0 #define DBM_REPLACE 1 -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) /* * The db(3) support for ndbm(3) always appends this suffix to the * file name to avoid overwriting the user's original database. @@ -97,8 +96,14 @@ typedef struct { size_t dsize; } datum; -typedef struct __db DBM; -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#ifndef _DBM +#define _DBM +typedef struct { + char __opaque[sizeof(int) + 8 * sizeof(void *)]; +} DBM; +#endif /* _DBM */ + +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE #endif @@ -106,13 +111,13 @@ __BEGIN_DECLS int dbm_clearerr( DBM *); void dbm_close(DBM *); int dbm_delete(DBM *, datum); -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) int dbm_dirfno(DBM *); #endif int dbm_error( DBM *); datum dbm_fetch(DBM *, datum); datum dbm_firstkey(DBM *); -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) long dbm_forder(DBM *, datum); #endif datum dbm_nextkey(DBM *); diff --git a/include/nl_types.h b/include/nl_types.h index b9c9b01..fe180d9 100644 --- a/include/nl_types.h +++ b/include/nl_types.h @@ -37,7 +37,7 @@ up-to-date. Many thanks. #include #include <_types.h> -#define NL_SETD 0 +#define NL_SETD 1 #define NL_CAT_LOCALE 1 #ifndef _NL_ITEM diff --git a/include/nlist.h b/include/nlist.h index c4c1140..f337fa9 100644 --- a/include/nlist.h +++ b/include/nlist.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1991, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/objc/zone.h b/include/objc/zone.h index efdda56..2a84ce0 100644 --- a/include/objc/zone.h +++ b/include/objc/zone.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -34,29 +34,31 @@ typedef malloc_zone_t NXZone; #include +#warning All the routines in objc/zone.h are deprecated and will be removed in the future + __BEGIN_DECLS -extern NXZone *NXDefaultMallocZone(void); +extern NXZone *NXDefaultMallocZone(void) __deprecated; // Returns the default zone used by the malloc(3) calls -extern NXZone *NXCreateZone(size_t startSize, size_t granularity, int canFree); +extern NXZone *NXCreateZone(size_t startSize, size_t granularity, int canFree) __deprecated; // Create a new zone with its own memory pool. // canfree: if 0 the allocator will never free memory and mallocing will be fast -extern void NXNameZone(NXZone *z, const char *name); +extern void NXNameZone(NXZone *z, const char *name) __deprecated; // name a zone; The string will be copied -extern void *NXZoneMalloc(malloc_zone_t *zone, size_t size); +extern void *NXZoneMalloc(malloc_zone_t *zone, size_t size) __deprecated; -extern void *NXZoneRealloc(malloc_zone_t *zone, void *ptr, size_t size); +extern void *NXZoneRealloc(malloc_zone_t *zone, void *ptr, size_t size) __deprecated; -extern void *NXZoneCalloc(NXZone *zonep, size_t numElems, size_t byteSize); +extern void *NXZoneCalloc(NXZone *zonep, size_t numElems, size_t byteSize) __deprecated; // Allocates and then clears -extern void NXZoneFree(malloc_zone_t *zone, void *ptr); +extern void NXZoneFree(malloc_zone_t *zone, void *ptr) __deprecated; -extern void NXDestroyZone(malloc_zone_t *zone); +extern void NXDestroyZone(malloc_zone_t *zone) __deprecated; -extern NXZone *NXZoneFromPtr(void *ptr); +extern NXZone *NXZoneFromPtr(void *ptr) __deprecated; // Returns the zone for a pointer, or NX_NOZONE if not in any zone. // The ptr must have been returned from a malloc or realloc call. __END_DECLS diff --git a/include/protocols/dumprestore.h b/include/protocols/dumprestore.h index a642212..fca4616 100644 --- a/include/protocols/dumprestore.h +++ b/include/protocols/dumprestore.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -89,25 +89,51 @@ 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 */ ino_t c_inumber; /* number of inode */ +#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; }; diff --git a/include/protocols/routed.h b/include/protocols/routed.h index 821e728..885375b 100644 --- a/include/protocols/routed.h +++ b/include/protocols/routed.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1983, 1989, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/protocols/rwhod.h b/include/protocols/rwhod.h index 84094eb..e9e9c32 100644 --- a/include/protocols/rwhod.h +++ b/include/protocols/rwhod.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -64,7 +64,11 @@ struct outmp { char out_line[8]; /* tty name */ char out_name[8]; /* user id */ +#ifdef __LP64__ + int out_time; /* time on */ +#else /* !__LP64__ */ long out_time; /* time on */ +#endif /* __LP64__ */ }; struct whod { diff --git a/include/protocols/talkd.h b/include/protocols/talkd.h index 2d3ef6b..bd375ab 100644 --- a/include/protocols/talkd.h +++ b/include/protocols/talkd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 2006, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -76,6 +76,15 @@ * stream connection through which the conversation takes place. */ +/* + * 4.3 compat sockaddr + */ +#include <_types.h> +struct osockaddr { + __uint16_t sa_family; /* address family */ + char sa_data[14]; /* up to 14 bytes of direct address */ +}; + /* * Client->server request message format. */ @@ -84,10 +93,18 @@ typedef struct { unsigned char type; /* request type, see below */ unsigned char answer; /* not used */ unsigned char pad; +#ifdef __LP64__ + unsigned int id_num; /* message id */ +#else /* !__LP64__ */ unsigned long id_num; /* message id */ +#endif /* __LP64__ */ struct osockaddr addr; /* old (4.3) style */ struct osockaddr ctl_addr; /* old (4.3) style */ +#ifdef __LP64__ + int pid; /* caller's process id */ +#else /* !__LP64__ */ long pid; /* caller's process id */ +#endif /* __LP64__ */ #define NAME_SIZE 12 char l_name[NAME_SIZE];/* caller's name */ char r_name[NAME_SIZE];/* callee's name */ @@ -103,7 +120,11 @@ typedef struct { unsigned char type; /* type of request message, see below */ unsigned char answer; /* respose to request message, see below */ unsigned char pad; +#ifdef __LP64__ + unsigned int id_num; /* message id */ +#else /* !__LP64__ */ unsigned long id_num; /* message id */ +#endif /* __LP64__ */ struct osockaddr addr; /* address for establishing conversation */ } CTL_RESPONSE; diff --git a/include/protocols/timed.h b/include/protocols/timed.h index c5abd01..b628fc7 100644 --- a/include/protocols/timed.h +++ b/include/protocols/timed.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -65,12 +65,21 @@ #define TSPVERSION 1 #define ANYADDR NULL +#ifdef __LP64__ +#define __need_struct_timeval32 +#include +#endif /* __LP64__ */ + struct tsp { unsigned char tsp_type; unsigned char tsp_vers; unsigned short tsp_seq; union { +#ifdef __LP64__ + struct timeval32 tspu_time; +#else /* !__LP64__ */ struct timeval tspu_time; +#endif /* __LP64__ */ char tspu_hopcnt; } tsp_u; char tsp_name[MAXHOSTNAMELEN]; diff --git a/include/pwd.h b/include/pwd.h index 83d87a7..30ce226 100644 --- a/include/pwd.h +++ b/include/pwd.h @@ -83,7 +83,7 @@ typedef __darwin_uid_t uid_t; #define _UID_T #endif -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #define _PATH_PWD "/etc" #define _PATH_PASSWD "/etc/passwd" #define _PASSWD "passwd" @@ -137,11 +137,11 @@ struct passwd *getpwnam(const char *); int getpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **); int getpwnam_r(const char *, struct passwd *, char *, size_t, struct passwd **); struct passwd *getpwent(void); -#if !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) +#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) int setpassent(int); char *user_from_uid(uid_t, int); #endif -int setpwent(void); +void setpwent(void); void endpwent(void); __END_DECLS diff --git a/include/readpassphrase.h b/include/readpassphrase.h index 8fbb8f5..c774fe5 100644 --- a/include/readpassphrase.h +++ b/include/readpassphrase.h @@ -38,7 +38,12 @@ #define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ #define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ -#include +#include <_types.h> + +#ifndef _SIZE_T +#define _SIZE_T +typedef __darwin_size_t size_t; +#endif __BEGIN_DECLS char * readpassphrase(const char *, char *, size_t, int); diff --git a/include/regex.h b/include/regex.h index 620ffd8..f348c9a 100644 --- a/include/regex.h +++ b/include/regex.h @@ -62,7 +62,6 @@ #ifndef _REGEX_H_ #define _REGEX_H_ -#include #include <_types.h> /* types */ @@ -86,18 +85,18 @@ typedef struct { } regmatch_t; /* regcomp() flags */ -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #define REG_BASIC 0000 -#endif /* !_POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #define REG_EXTENDED 0001 #define REG_ICASE 0002 #define REG_NOSUB 0004 #define REG_NEWLINE 0010 -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #define REG_NOSPEC 0020 #define REG_PEND 0040 #define REG_DUMP 0200 -#endif /* !_POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ /* regerror() flags */ #define REG_ENOSYS (-1) /* Reserved */ @@ -114,31 +113,42 @@ typedef struct { #define REG_ERANGE 11 #define REG_ESPACE 12 #define REG_BADRPT 13 -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #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 (!) */ -#endif /* !_POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ /* regexec() flags */ #define REG_NOTBOL 00001 #define REG_NOTEOL 00002 -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #define REG_STARTEND 00004 #define REG_TRACE 00400 /* tracing of execution */ #define REG_LARGE 01000 /* force large representation */ #define REG_BACKR 02000 /* force use of backref code */ -#endif /* !_POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ __BEGIN_DECLS +//Begin-Libc +#ifndef LIBC_ALIAS_REGCOMP +//End-Libc int regcomp(regex_t * __restrict, const char * __restrict, int) __DARWIN_ALIAS(regcomp); +//Begin-Libc +#else /* LIBC_ALIAS_REGCOMP */ +int regcomp(regex_t * __restrict, const char * __restrict, int) LIBC_ALIAS(regcomp); +#endif /* !LIBC_ALIAS_REGCOMP */ +//End-Libc size_t regerror(int, const regex_t * __restrict, char * __restrict, size_t); -/* For meeting c99 stds, pass regmatch_t*, rather than the array */ -int regexec(const regex_t * __restrict, - const char * __restrict, size_t, regmatch_t * __restrict, int); +/* + * gcc under c99 mode won't compile "[ __restrict]" by itself. As a workaround, + * a dummy argument name is added. + */ +int regexec(const regex_t * __restrict, const char * __restrict, size_t, + regmatch_t __pmatch[ __restrict], int); void regfree(regex_t *); __END_DECLS diff --git a/include/runetype.h b/include/runetype.h index a726c9d..fd16b82 100644 --- a/include/runetype.h +++ b/include/runetype.h @@ -39,10 +39,9 @@ #ifndef _RUNETYPE_H_ #define _RUNETYPE_H_ -#include #include <_types.h> -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #ifndef _SIZE_T #define _SIZE_T @@ -71,7 +70,7 @@ typedef __darwin_wchar_t wchar_t; typedef __darwin_wint_t wint_t; #endif -#endif /* !_POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #define _CACHED_RUNES (1 <<8 ) /* Must be a power of 2 */ #define _CRMASK (~(_CACHED_RUNES - 1)) @@ -91,6 +90,11 @@ typedef struct { _RuneEntry *__ranges; /* Pointer to the ranges */ } _RuneRange; +typedef struct { + char __name[14]; /* CHARCLASS_NAME_MAX = 14 */ + __uint32_t __mask; /* charclass mask */ +} _RuneCharClass; + typedef struct { char __magic[8]; /* Magic saying what version we are */ char __encoding[32]; /* ASCII name of this encoding */ @@ -114,9 +118,15 @@ typedef struct { void *__variable; /* Data which depends on the encoding */ int __variable_len; /* how long that data is */ + + /* + * extra fields to deal with arbitrary character classes + */ + int __ncharclasses; + _RuneCharClass *__charclasses; } _RuneLocale; -#define _RUNE_MAGIC_1 "RuneMagi" /* Indicates version 0 of RuneLocale */ +#define _RUNE_MAGIC_A "RuneMagA" /* Indicates version A of RuneLocale */ __BEGIN_DECLS extern _RuneLocale _DefaultRuneLocale; diff --git a/include/secure/Makefile.inc b/include/secure/Makefile.inc new file mode 100644 index 0000000..d355e87 --- /dev/null +++ b/include/secure/Makefile.inc @@ -0,0 +1,5 @@ +SECURE_INSTHDRS += _common.h \ + _string.h \ + _stdio.h + +SECURE_INSTHDRS := ${SECURE_INSTHDRS:S/^/${.CURDIR}\/include\/secure\//} diff --git a/mach/vm_map.defs b/include/secure/_common.h similarity index 66% rename from mach/vm_map.defs rename to include/secure/_common.h index 536ef7b..a2de0d1 100644 --- a/mach/vm_map.defs +++ b/include/secure/_common.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * 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, @@ -17,19 +17,25 @@ * 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__) -/* - * In an LP64 environment, the traditional Mach VM interface names are - * really just a second instance of the "wide" Mach VM interfaces. * - * The _MACH_VM_PUBLISH_AS_LOCAL_ flag triggers mach_vm.defs to export - * the local names instead. + * @APPLE_LICENSE_HEADER_END@ */ -#define _MACH_VM_PUBLISH_AS_LOCAL_ -#include + +#ifndef _SECURE__COMMON_H_ +#define _SECURE__COMMON_H_ + +#undef _USE_FORTIFY_LEVEL +#ifdef _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0 +#if _FORTIFY_SOURCE > 1 +#define _USE_FORTIFY_LEVEL 2 +#else +#define _USE_FORTIFY_LEVEL 1 +#endif #else -#include +#define _USE_FORTIFY_LEVEL 0 +#endif + +#define __darwin_obsz0(object) __builtin_object_size (object, 0) +#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1) + #endif diff --git a/include/secure/_stdio.h b/include/secure/_stdio.h new file mode 100644 index 0000000..b5a29b6 --- /dev/null +++ b/include/secure/_stdio.h @@ -0,0 +1,73 @@ +/* + * 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@ + */ + +#ifndef _STDIO_H_ + #error error "Never use directly; include instead." +#endif + +#ifndef _SECURE__STDIO_H_ +#define _SECURE__STDIO_H_ + +#include + +#if _USE_FORTIFY_LEVEL > 0 + +#undef sprintf +#undef vsprintf +#undef snprintf +#undef vsnprintf + +/* sprintf, vsprintf, snprintf, vsnprintf */ + +extern int __sprintf_chk (char * __restrict, int, size_t, + const char * __restrict, ...) + __DARWIN_LDBL_COMPAT (__sprintf_chk); + +#define sprintf(str, ...) \ + __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__) + +extern int __snprintf_chk (char * __restrict, size_t, int, size_t, + const char * __restrict, ...) + __DARWIN_LDBL_COMPAT (__snprintf_chk); + +#define snprintf(str, len, ...) \ + __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__) + +extern int __vsprintf_chk (char * __restrict, int, size_t, + const char * __restrict, va_list arg) + __DARWIN_LDBL_COMPAT (__vsprintf_chk); + +#define vsprintf(str, format, ap) \ + __builtin___vsprintf_chk (str, 0, __darwin_obsz(str), format, ap) + +extern int __vsnprintf_chk (char * __restrict, size_t, int, size_t, + const char * __restrict, va_list arg) + __DARWIN_LDBL_COMPAT (__vsnprintf_chk); + +#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 new file mode 100644 index 0000000..d85d91d --- /dev/null +++ b/include/secure/_string.h @@ -0,0 +1,138 @@ +/* + * 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@ + */ + +#ifndef _STRING_H_ +# error "Never use directly; include instead." +#endif + +#ifndef _SECURE__STRING_H_ +#define _SECURE__STRING_H_ + +#include + +#if _USE_FORTIFY_LEVEL > 0 + +/* memcpy, mempcpy, memmove, memset, strcpy, stpcpy, strncpy, strcat + and strncat */ + +#undef memcpy +#undef memmove +#undef memset +#undef strcpy +#undef stpcpy +#undef strncpy +#undef strcat +#undef strncat + +#define memcpy(dest, src, len) \ + ((__darwin_obsz0 (dest) != (size_t) -1) \ + ? __builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest)) \ + : __inline_memcpy_chk (dest, src, len)) + +static inline void * +__inline_memcpy_chk (void *__dest, const void *__src, size_t __len) +{ + return __builtin___memcpy_chk (__dest, __src, __len, __darwin_obsz0(__dest)); +} + +#define memmove(dest, src, len) \ + ((__darwin_obsz0 (dest) != (size_t) -1) \ + ? __builtin___memmove_chk (dest, src, len, __darwin_obsz0 (dest)) \ + : __inline_memmove_chk (dest, src, len)) + +static inline void * +__inline_memmove_chk (void *__dest, const void *__src, size_t __len) +{ + return __builtin___memmove_chk (__dest, __src, __len, __darwin_obsz0(__dest)); +} + +#define memset(dest, val, len) \ + ((__darwin_obsz0 (dest) != (size_t) -1) \ + ? __builtin___memset_chk (dest, val, len, __darwin_obsz0 (dest)) \ + : __inline_memset_chk (dest, val, len)) + +static inline void * +__inline_memset_chk (void *__dest, int __val, size_t __len) +{ + return __builtin___memset_chk (__dest, __val, __len, __darwin_obsz0(__dest)); +} + +#define strcpy(dest, src) \ + ((__darwin_obsz0 (dest) != (size_t) -1) \ + ? __builtin___strcpy_chk (dest, src, __darwin_obsz (dest)) \ + : __inline_strcpy_chk (dest, src)) + +static inline char * +__inline_strcpy_chk (char *__restrict __dest, const char *__restrict __src) +{ + return __builtin___strcpy_chk (__dest, __src, __darwin_obsz(__dest)); +} + +#define stpcpy(dest, src) \ + ((__darwin_obsz0 (dest) != (size_t) -1) \ + ? __builtin___stpcpy_chk (dest, src, __darwin_obsz (dest)) \ + : __inline_stpcpy_chk (dest, src)) + +static inline char * +__inline_stpcpy_chk (char *__dest, const char *__src) +{ + return __builtin___stpcpy_chk (__dest, __src, __darwin_obsz(__dest)); +} + +#define strncpy(dest, src, len) \ + ((__darwin_obsz0 (dest) != (size_t) -1) \ + ? __builtin___strncpy_chk (dest, src, len, __darwin_obsz (dest)) \ + : __inline_strncpy_chk (dest, src, len)) + +static inline char * +__inline_strncpy_chk (char *__restrict __dest, const char *__restrict __src, + size_t __len) +{ + return __builtin___strncpy_chk (__dest, __src, __len, __darwin_obsz(__dest)); +} + +#define strcat(dest, src) \ + ((__darwin_obsz0 (dest) != (size_t) -1) \ + ? __builtin___strcat_chk (dest, src, __darwin_obsz (dest)) \ + : __inline_strcat_chk (dest, src)) + +static inline char * +__inline_strcat_chk (char *__restrict __dest, const char *__restrict __src) +{ + return __builtin___strcat_chk (__dest, __src, __darwin_obsz(__dest)); +} + +#define strncat(dest, src, len) \ + ((__darwin_obsz0 (dest) != (size_t) -1) \ + ? __builtin___strcat_chk (dest, src, __darwin_obsz (dest)) \ + : __inline_strncat_chk (dest, src, len)) + +static inline char * +__inline_strncat_chk (char *__restrict __dest, const char *__restrict __src, + size_t __len) +{ + return __builtin___strncat_chk (__dest, __src, __len, __darwin_obsz(__dest)); +} + +#endif +#endif diff --git a/include/sgtty.h b/include/sgtty.h index ef1b9e2..5409d3e 100644 --- a/include/sgtty.h +++ b/include/sgtty.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1985, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/signal.h b/include/signal.h index 334479e..08ad77e 100644 --- a/include/signal.h +++ b/include/signal.h @@ -58,8 +58,8 @@ #ifndef _USER_SIGNAL_H #define _USER_SIGNAL_H -#include <_types.h> #include +#include <_types.h> #include #ifndef _PTHREAD_T @@ -67,7 +67,7 @@ typedef __darwin_pthread_t pthread_t; #define _PTHREAD_T #endif -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) extern __const char *__const sys_signame[NSIG]; extern __const char *__const sys_siglist[NSIG]; #endif @@ -79,14 +79,46 @@ __END_DECLS #ifndef _ANSI_SOURCE __BEGIN_DECLS void (*bsd_signal(int, void (*)(int)))(int); -int kill(pid_t, int); -int killpg(pid_t, int); +//Begin-Libc +#ifndef LIBC_ALIAS_KILL +//End-Libc +int kill(pid_t, int) __DARWIN_ALIAS(kill); +//Begin-Libc +#else /* LIBC_ALIAS_KILL */ +int kill(pid_t, int) LIBC_ALIAS(kill); +#endif /* !LIBC_ALIAS_KILL */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_KILLPG +//End-Libc +int killpg(pid_t, int) __DARWIN_ALIAS(killpg); +//Begin-Libc +#else /* LIBC_ALIAS_KILLPG */ +int killpg(pid_t, int) LIBC_ALIAS(killpg); +#endif /* !LIBC_ALIAS_KILLPG */ +//End-Libc int pthread_kill(pthread_t, int); -int pthread_sigmask(int, const sigset_t *, sigset_t *); +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_SIGMASK +//End-Libc +int pthread_sigmask(int, const sigset_t *, sigset_t *) __DARWIN_ALIAS(pthread_sigmask); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_SIGMASK */ +int pthread_sigmask(int, const sigset_t *, sigset_t *) LIBC_ALIAS(pthread_sigmask); +#endif /* !LIBC_ALIAS_PTHREAD_SIGMASK */ +//End-Libc int sigaction(int, const struct sigaction * __restrict, struct sigaction * __restrict); int sigaddset(sigset_t *, int); -int sigaltstack(const stack_t * __restrict, stack_t * __restrict); +//Begin-Libc +#ifndef LIBC_ALIAS_SIGALTSTACK +//End-Libc +int sigaltstack(const stack_t * __restrict, stack_t * __restrict) __DARWIN_ALIAS(sigaltstack); +//Begin-Libc +#else /* LIBC_ALIAS_SIGALTSTACK */ +int sigaltstack(const stack_t * __restrict, stack_t * __restrict) LIBC_ALIAS(sigaltstack); +#endif /* !LIBC_ALIAS_SIGALTSTACK */ +//End-Libc int sigdelset(sigset_t *, int); int sigemptyset(sigset_t *); int sigfillset(sigset_t *); @@ -94,28 +126,62 @@ int sighold(int); int sigignore(int); int siginterrupt(int, int); int sigismember(const sigset_t *, int); -int sigpause(int); +//Begin-Libc +#ifndef LIBC_ALIAS_SIGPAUSE +//End-Libc +int sigpause(int) __DARWIN_ALIAS_C(sigpause); +//Begin-Libc +#else /* LIBC_ALIAS_SIGPAUSE */ +int sigpause(int) LIBC_ALIAS_C(sigpause); +#endif /* !LIBC_ALIAS_SIGPAUSE */ +//End-Libc int sigpending(sigset_t *); int sigprocmask(int, const sigset_t * __restrict, sigset_t * __restrict); int sigrelse(int); void (*sigset(int, void (*)(int)))(int); -int sigsuspend(const sigset_t *); -int sigwait(const sigset_t * __restrict, int * __restrict); -#ifndef _POSIX_C_SOURCE +//Begin-Libc +#ifndef LIBC_ALIAS_SIGSUSPEND +//End-Libc +int sigsuspend(const sigset_t *) __DARWIN_ALIAS_C(sigsuspend); +//Begin-Libc +#else /* LIBC_ALIAS_SIGSUSPEND */ +int sigsuspend(const sigset_t *) LIBC_ALIAS_C(sigsuspend); +#endif /* !LIBC_ALIAS_SIGSUSPEND */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_SIGWAIT +//End-Libc +int sigwait(const sigset_t * __restrict, int * __restrict) __DARWIN_ALIAS_C(sigwait); +//Begin-Libc +#else /* LIBC_ALIAS_SIGWAIT */ +int sigwait(const sigset_t * __restrict, int * __restrict) LIBC_ALIAS_C(sigwait); +#endif /* !LIBC_ALIAS_SIGWAIT */ +//End-Libc +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) void psignal(unsigned int, const char *); int sigblock(int); -int sigreturn(struct sigcontext *); int sigsetmask(int); int sigvec(int, struct sigvec *, struct sigvec *); -#endif /* !_POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ __END_DECLS /* List definitions after function declarations, or Reiser cpp gets upset. */ -#define sigaddset(set, signo) (*(set) |= 1 << ((signo) - 1), 0) -#define sigdelset(set, signo) (*(set) &= ~(1 << ((signo) - 1)), 0) +#if defined(__i386__) || defined(__x86_64__) +/* The left shift operator on intel is modulo 32 */ +static __inline int +__sigbits(int __signo) +{ + return __signo > __DARWIN_NSIG ? 0 : (1 << (__signo - 1)); +} +#else /* !__i386__ && !__x86_64__ */ +#define __sigbits(signo) (1 << ((signo) - 1)) +#endif /* __i386__ || __x86_64__ */ + +#define sigaddset(set, signo) (*(set) |= __sigbits(signo), 0) +#define sigdelset(set, signo) (*(set) &= ~__sigbits(signo), 0) +#define sigismember(set, signo) ((*(set) & __sigbits(signo)) != 0) #define sigemptyset(set) (*(set) = 0, 0) #define sigfillset(set) (*(set) = ~(sigset_t)0, 0) -#define sigismember(set, signo) ((*(set) & (1 << ((signo) - 1))) != 0) #endif /* !_ANSI_SOURCE */ #endif /* !_USER_SIGNAL_H */ diff --git a/include/spawn.h b/include/spawn.h new file mode 100644 index 0000000..337b929 --- /dev/null +++ b/include/spawn.h @@ -0,0 +1,143 @@ +/* + * 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@ + */ + + +#ifndef _SPAWN_H_ +#define _SPAWN_H_ + +/* + * [SPN] Support for _POSIX_SPAWN + */ + +#include +#include <_types.h> +#include /* shared types */ + +/* + * [SPN] Inclusion of the header may make visible symbols defined + * in the , , and headers. + */ +#ifndef _PID_T +typedef __darwin_pid_t pid_t; +#define _PID_T +#endif + +#ifndef _SIGSET_T +#define _SIGSET_T +typedef __darwin_sigset_t sigset_t; +#endif + +#ifndef _MODE_T +typedef __darwin_mode_t mode_t; +#define _MODE_T +#endif + +/* + * Opaque types for use with posix_spawn() family functions. Internals are + * not defined, and should not be accessed directly. Types are defined as + * mandated by POSIX. + */ +typedef void *posix_spawnattr_t; +typedef void *posix_spawn_file_actions_t; + +__BEGIN_DECLS +/* + * gcc under c99 mode won't compile "[ __restrict]" by itself. As a workaround, + * a dummy argument name is added. + */ +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]); +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); +int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, + int); +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 *); +int posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict, + sigset_t * __restrict); +int posix_spawnattr_getflags(const posix_spawnattr_t * __restrict, + short * __restrict); +int posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict, + pid_t * __restrict); +int posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict, + sigset_t * __restrict); +int posix_spawnattr_init(posix_spawnattr_t *); +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); +int posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict, + const sigset_t * __restrict); + +#if 0 /* _POSIX_PRIORITY_SCHEDULING [PS] : not supported */ +int posix_spawnattr_setschedparam(posix_spawnattr_t * __restrict, + const struct sched_param * __restrict); +int posix_spawnattr_setschedpolicy(posix_spawnattr_t *, int); +int posix_spawnattr_getschedparam(const posix_spawnattr_t * __restrict, + struct sched_param * __restrict); +int posix_spawnattr_getschedpolicy(const posix_spawnattr_t * __restrict, + int * __restrict); +#endif /* 0 */ + +__END_DECLS + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +/* + * Darwin-specific extensions below + */ +#include +#include +#include + +#ifndef _SIZE_T +typedef __darwin_size_t size_t; +#define _SIZE_T +#endif + +__BEGIN_DECLS + +int posix_spawnattr_getbinpref_np(const posix_spawnattr_t * __restrict, + size_t, cpu_type_t *__restrict, size_t *__restrict); +int posix_spawnattr_setbinpref_np(posix_spawnattr_t * __restrict, + size_t, cpu_type_t *__restrict, size_t *__restrict); +int posix_spawnattr_setspecialport_np(posix_spawnattr_t *__restrict, + mach_port_t, int); +int posix_spawnattr_setexceptionports_np(posix_spawnattr_t *__restrict, + exception_mask_t, mach_port_t, + exception_behavior_t, thread_state_flavor_t); + +__END_DECLS + +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +#endif /* _SPAWN_H_ */ diff --git a/include/stab.h b/include/stab.h index 1b70544..0eae579 100644 --- a/include/stab.h +++ b/include/stab.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1991, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/standards.h b/include/standards.h index 322fd19..0c18101 100644 --- a/include/standards.h +++ b/include/standards.h @@ -27,11 +27,13 @@ #ifndef _STANDARDS_H #define _STANDARDS_H -#ifdef _POSIX_C_SOURCE +#include + +#if defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE) # ifndef __STRICT_ANSI__ # define __STRICT_ANSI__ # endif # undef __STRICT_BSD__ -#endif /* _POSIX_C_SOURCE */ +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ #endif /* _STANDARDS_H */ diff --git a/include/stddef.h b/include/stddef.h index dfbaa5f..78095de 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -93,13 +93,13 @@ typedef __darwin_wchar_t wchar_t; #endif /* __cplusplus */ #endif /* __STDDEF_H__ || __need_wchar_t */ -#if (defined(__STDDEF_H__) && !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE)) \ +#if (defined(__STDDEF_H__) && !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))) \ || defined(__need_wint_t) #ifndef _WINT_T #define _WINT_T typedef __darwin_wint_t wint_t; #endif /* _WINT_T */ -#endif /* __STDDEF_H__ && !_ANSI_SOURCE && !_POSIX_C_SOURCE || __need_wchar_t */ +#endif /* __STDDEF_H__ && !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) || __need_wchar_t */ #if defined(__STDDEF_H__) || defined(__need_NULL) #ifndef NULL diff --git a/include/stdio.h b/include/stdio.h index b1a02df..6c59a6a 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 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, @@ -17,7 +17,7 @@ * 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@ */ /*- @@ -62,7 +62,6 @@ #define _STDIO_H_ #include <_types.h> -#include #ifndef _VA_LIST #define _VA_LIST @@ -71,6 +70,11 @@ 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; @@ -80,11 +84,7 @@ typedef __darwin_size_t size_t; #define NULL __DARWIN_NULL #endif /* ! NULL */ -#if !defined(_ANSI_SOURCE) && !defined(__STRICT_ANSI__) typedef __darwin_off_t fpos_t; -#else -typedef __int64_t fpos_t; -#endif #define _FSTDIO /* Define for new stdio with functions. */ @@ -257,19 +257,44 @@ char *fgets(char * __restrict, int, FILE *); FILE *fopen(const char * __restrict, const char * __restrict); int fprintf(FILE * __restrict, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(fprintf); int fputc(int, FILE *); -int fputs(const char * __restrict, FILE * __restrict); +//Begin-Libc +#ifndef LIBC_ALIAS_FPUTS +//End-Libc +int fputs(const char * __restrict, FILE * __restrict) __DARWIN_ALIAS(fputs); +//Begin-Libc +#else /* LIBC_ALIAS_FPUTS */ +int fputs(const char * __restrict, FILE * __restrict) LIBC_ALIAS(fputs); +#endif /* !LIBC_ALIAS_FPUTS */ +//End-Libc size_t fread(void * __restrict, size_t, size_t, FILE * __restrict); +//Begin-Libc +#ifndef LIBC_ALIAS_FREOPEN +//End-Libc FILE *freopen(const char * __restrict, const char * __restrict, FILE * __restrict) __DARWIN_ALIAS(freopen); +//Begin-Libc +#else /* LIBC_ALIAS_FREOPEN */ +FILE *freopen(const char * __restrict, const char * __restrict, + FILE * __restrict) LIBC_ALIAS(freopen); +#endif /* !LIBC_ALIAS_FREOPEN */ +//End-Libc int fscanf(FILE * __restrict, const char * __restrict, ...) __DARWIN_LDBL_COMPAT(fscanf); int fseek(FILE *, long, int); int fsetpos(FILE *, const fpos_t *); long ftell(FILE *); +//Begin-Libc +#ifndef LIBC_ALIAS_FWRITE +//End-Libc size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict) __DARWIN_ALIAS(fwrite); +//Begin-Libc +#else /* LIBC_ALIAS_FWRITE */ +size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict) LIBC_ALIAS(fwrite); +#endif /* !LIBC_ALIAS_FWRITE */ +//End-Libc int getc(FILE *); int getchar(void); char *gets(char *); -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#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 @@ -292,7 +317,7 @@ 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) +#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 @@ -302,50 +327,57 @@ __END_DECLS * Functions defined in POSIX 1003.1. */ #ifndef _ANSI_SOURCE -#define L_cuserid 9 /* size for cuserid(); UT_NAMESIZE + 1 */ #define L_ctermid 1024 /* size for ctermid(); PATH_MAX */ __BEGIN_DECLS char *ctermid(char *); -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) char *ctermid_r(char *); #endif /* not POSIX */ FILE *fdopen(int, const char *); -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) char *fgetln(FILE *, size_t *); #endif /* not POSIX */ int fileno(FILE *); void flockfile(FILE *); -#ifndef _POSIX_C_SOURCE -__const char +#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 *, fpos_t, int); -fpos_t ftello(FILE *); +int fseeko(FILE *, off_t, int); +off_t ftello(FILE *); int ftrylockfile(FILE *); void funlockfile(FILE *); int getc_unlocked(FILE *); int getchar_unlocked(void); -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) int getw(FILE *); #endif /* not POSIX */ int pclose(FILE *); FILE *popen(const char *, const char *); int putc_unlocked(int, FILE *); int putchar_unlocked(int); -#ifndef _POSIX_C_SOURCE +#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); -char *tempnam(const char *, const char *); +//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); -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) FILE *zopen(const char *, const char *, int); #endif /* not POSIX */ __END_DECLS @@ -353,7 +385,7 @@ __END_DECLS /* * Stdio function-access interface. */ -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) __BEGIN_DECLS FILE *funopen(const void *, int (*)(void *, char *, int), @@ -376,7 +408,7 @@ int __swbuf(int, FILE *); __END_DECLS /* - * The __sfoo macros are here so that we can + * The __sfoo macros are here so that we can * define function versions in the C library. */ #define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) @@ -407,7 +439,7 @@ static __inline int __sputc(int _c, FILE *_p) { #define __sfileno(p) ((p)->_file) #ifndef _ANSI_SOURCE -#ifndef _POSIX_C_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) @@ -427,4 +459,9 @@ static __inline int __sputc(int _c, FILE *_p) { #include #endif /* _USE_EXTENDED_LOCALES_ */ +#if defined (__GNUC__) && _FORTIFY_SOURCE > 0 && !defined (__cplusplus) +/* Security checking functions. */ +#include +#endif + #endif /* _STDIO_H_ */ diff --git a/include/stdlib.h b/include/stdlib.h index 849fe52..602a692 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -58,13 +58,14 @@ #ifndef _STDLIB_H_ #define _STDLIB_H_ -#include +#include + #include <_types.h> #if !defined(_ANSI_SOURCE) #include -#if !defined(_POSIX_C_SOURCE) +#if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #include -#endif /* !_POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #endif /* !_ANSI_SOURCE */ #ifndef _SIZE_T @@ -74,7 +75,7 @@ typedef __darwin_size_t size_t; #endif -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #ifndef _CT_RUNE_T #define _CT_RUNE_T typedef __darwin_ct_rune_t ct_rune_t; @@ -84,7 +85,7 @@ typedef __darwin_ct_rune_t ct_rune_t; #define _RUNE_T typedef __darwin_rune_t rune_t; #endif -#endif +#endif /* !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #ifndef __cplusplus #ifndef _WCHAR_T @@ -135,7 +136,7 @@ extern int __mb_cur_max; #endif /* _USE_EXTENDED_LOCALES_ */ #endif /* MB_CUR_MAX */ -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) \ +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) \ && defined(_USE_EXTENDED_LOCALES_) && !defined(MB_CUR_MAX_L) #define MB_CUR_MAX_L(x) (___mb_cur_max_l(x)) #endif @@ -174,8 +175,8 @@ void qsort(void *, size_t, size_t, int rand(void); void *realloc(void *, size_t); void srand(unsigned); -double strtod(const char *, char **); -float strtof(const char *, char **); +double strtod(const char *, char **) __DARWIN_ALIAS(strtod); +float strtof(const char *, char **) __DARWIN_ALIAS(strtof); long strtol(const char *, char **, int); long double strtold(const char *, char **) __DARWIN_LDBL_COMPAT(strtold); @@ -189,7 +190,15 @@ unsigned long unsigned long long strtoull(const char *, char **, int); #endif /* !__DARWIN_NO_LONG_LONG */ -int system(const char *); +//Begin-Libc +#ifndef LIBC_ALIAS_SYSTEM +//End-Libc +int system(const char *) __DARWIN_ALIAS_C(system); +//Begin-Libc +#else /* LIBC_ALIAS_SYSTEM */ +int system(const char *) LIBC_ALIAS_C(system); +#endif /* !LIBC_ALIAS_SYSTEM */ +//End-Libc size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t); int wctomb(char *, wchar_t); @@ -218,14 +227,59 @@ long mrand48(void); long nrand48(unsigned short[3]); int posix_openpt(int); char *ptsname(int); +//Begin-Libc +#ifndef LIBC_ALIAS_PUTENV +//End-Libc int putenv(char *) __DARWIN_ALIAS(putenv); +//Begin-Libc +#else /* LIBC_ALIAS_PUTENV */ +int putenv(char *) LIBC_ALIAS(putenv); +#endif /* !LIBC_ALIAS_PUTENV */ +//End-Libc long random(void); -char *realpath(const char *, char *resolved_path); +int rand_r(unsigned *); +//Begin-Libc +#ifdef __LIBC__ +#ifndef LIBC_ALIAS_REALPATH +char *realpath(const char * __restrict, char * __restrict) __DARWIN_EXTSN(realpath); +#else /* LIBC_ALIAS_REALPATH */ +#ifdef VARIANT_DARWINEXTSN +char *realpath(const char * __restrict, char * __restrict) LIBC_EXTSN(realpath); +#else /* !VARIANT_DARWINEXTSN */ +char *realpath(const char * __restrict, char * __restrict) LIBC_ALIAS(realpath); +#endif /* VARIANT_DARWINEXTSN */ +#endif /* !LIBC_ALIAS_REALPATH */ +#else /* !__LIBC__ */ +//End-Libc +#if (__DARWIN_UNIX03 && !defined(_POSIX_C_SOURCE)) || defined(_DARWIN_C_SOURCE) || defined(_DARWIN_BETTER_REALPATH) +char *realpath(const char * __restrict, char * __restrict) __DARWIN_EXTSN(realpath); +#else /* (!__DARWIN_UNIX03 || _POSIX_C_SOURCE) && !_DARWIN_C_SOURCE && !_DARWIN_BETTER_REALPATH */ +char *realpath(const char * __restrict, char * __restrict) __DARWIN_ALIAS(realpath); +#endif /* (__DARWIN_UNIX03 && _POSIX_C_SOURCE) || _DARWIN_C_SOURCE || _DARWIN_BETTER_REALPATH */ +//Begin-Libc +#endif /* __LIBC__ */ +//End-Libc unsigned short *seed48(unsigned short[3]); +//Begin-Libc +#ifndef LIBC_ALIAS_SETENV +//End-Libc int setenv(const char *, const char *, int) __DARWIN_ALIAS(setenv); +//Begin-Libc +#else /* LIBC_ALIAS_SETENV */ +int setenv(const char *, const char *, int) LIBC_ALIAS(setenv); +#endif /* !LIBC_ALIAS_SETENV */ +//End-Libc #if __DARWIN_UNIX03 +//Begin-Libc +#ifndef LIBC_ALIAS_SETKEY +//End-Libc void setkey(const char *) __DARWIN_ALIAS(setkey); +//Begin-Libc +#else /* LIBC_ALIAS_SETKEY */ +void setkey(const char *) LIBC_ALIAS(setkey); +#endif /* !LIBC_ALIAS_SETKEY */ +//End-Libc #else /* !__DARWIN_UNIX03 */ int setkey(const char *); #endif /* __DARWIN_UNIX03 */ @@ -238,13 +292,21 @@ void srandom(unsigned long); #endif /* __DARWIN_UNIX03 */ int unlockpt(int); #if __DARWIN_UNIX03 +//Begin-Libc +#ifndef LIBC_ALIAS_UNSETENV +//End-Libc int unsetenv(const char *) __DARWIN_ALIAS(unsetenv); +//Begin-Libc +#else /* LIBC_ALIAS_UNSETENV */ +int unsetenv(const char *) LIBC_ALIAS(unsetenv); +#endif /* !LIBC_ALIAS_UNSETENV */ +//End-Libc #else /* !__DARWIN_UNIX03 */ void unsetenv(const char *); #endif /* __DARWIN_UNIX03 */ -#endif +#endif /* !_ANSI_SOURCE */ -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #include #ifndef _DEV_T @@ -274,7 +336,7 @@ int cgetset(const char *); int cgetstr(char *, const char *, char **); int cgetustr(char *, const char *, char **); -int daemon(int, int); +int daemon(int, int) __DARWIN_1050(daemon) __AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5; char *devname(dev_t, mode_t); char *devname_r(dev_t, mode_t, char *buf, int len); char *getbsize(int *, long *); @@ -295,7 +357,6 @@ int sradixsort(const unsigned char **, int, const unsigned char *, unsigned); void sranddev(void); void srandomdev(void); -int rand_r(unsigned *); void *reallocf(void *, size_t); #if !__DARWIN_NO_LONG_LONG long long @@ -305,6 +366,11 @@ unsigned long long #endif /* !__DARWIN_NO_LONG_LONG */ extern char *suboptarg; /* getsubopt(3) external variable */ void *valloc(size_t); +#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */ + +/* Poison the following routines if -fshort-wchar is set */ +#if !defined(__cplusplus) && defined(__WCHAR_MAX__) && __WCHAR_MAX__ <= 0xffffU +#pragma GCC poison mbstowcs mbtowc wcstombs wctomb #endif __END_DECLS diff --git a/include/string.h b/include/string.h index 98c37d1..2db632d 100644 --- a/include/string.h +++ b/include/string.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 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, @@ -17,7 +17,7 @@ * 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@ */ /*- @@ -64,12 +64,12 @@ typedef __darwin_size_t size_t; #endif -#ifndef _POSIX_C_SOURCE /* For swab */ +#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 */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #ifndef NULL #define NULL __DARWIN_NULL @@ -83,25 +83,33 @@ 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); -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) char *stpcpy(char *, const char *); char *strcasestr(const char *, const char *); -#endif /* !_POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ char *strcat(char *, const char *); char *strchr(const char *, int); int strcmp(const char *, const char *); int strcoll(const char *, const char *); char *strcpy(char *, const char *); size_t strcspn(const char *, const char *); -char *strerror(int); +//Begin-Libc +#ifndef LIBC_ALIAS_STRERROR +//End-Libc +char *strerror(int) __DARWIN_ALIAS(strerror); +//Begin-Libc +#else /* LIBC_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); -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) char *strnstr(const char *, const char *, size_t); -#endif /* !_POSIX_C_SOURCE */ +#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 *); @@ -114,12 +122,18 @@ size_t strxfrm(char *, const char *, size_t); void *memccpy(void *, const void *, int, size_t); char *strtok_r(char *, const char *, char **); char *strdup(const char *); -#ifndef _POSIX_C_SOURCE +#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 *); size_t strlcat(char *, const char *, size_t); @@ -129,7 +143,7 @@ int strncasecmp(const char *, const char *, size_t); char *strsep(char **, const char *); char *strsignal(int sig); void swab(const void * __restrict, void * __restrict, ssize_t); -#endif /* !_POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #endif /* !_ANSI_SOURCE */ __END_DECLS @@ -137,4 +151,9 @@ __END_DECLS #include #endif /* _USE_EXTENDED_LOCALES_ */ +#if defined (__GNUC__) && _FORTIFY_SOURCE > 0 && !defined (__cplusplus) +/* Security checking functions. */ +#include +#endif + #endif /* _STRING_H_ */ diff --git a/include/strings.h b/include/strings.h index 2124c8d..f8aba3d 100644 --- a/include/strings.h +++ b/include/strings.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -55,7 +55,9 @@ * @(#)strings.h 8.1 (Berkeley) 6/2/93 */ -#if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE) +#include + +#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) #include @@ -68,6 +70,7 @@ 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); @@ -76,6 +79,7 @@ char *index(const char *, int); char *rindex(const char *, int); int strcasecmp(const char *, const char *); int strncasecmp(const char *, const char *, size_t); +__END_DECLS -#endif /* _POSIX_C_SOURCE */ +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ diff --git a/include/struct.h b/include/struct.h index fcf6038..f80ecd0 100644 --- a/include/struct.h +++ b/include/struct.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1983, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/sys/acl.h b/include/sys/acl.h index 15ef22b..7224b56 100644 --- a/include/sys/acl.h +++ b/include/sys/acl.h @@ -157,7 +157,7 @@ extern acl_t acl_get_link_np(const char *path_p, acl_type_t type); extern int acl_set_fd(int fd, acl_t acl); extern int acl_set_fd_np(int fd, acl_t acl, acl_type_t acl_type); extern int acl_set_file(const char *path_p, acl_type_t type, acl_t acl); -extern int acl_set_link(const char *path_p, acl_type_t type, acl_t acl); +extern int acl_set_link_np(const char *path_p, acl_type_t type, acl_t acl); /* 23.1.6.4 ACL Format translation */ extern ssize_t acl_copy_ext(void *buf_p, acl_t acl, ssize_t size); diff --git a/include/sysexits.h b/include/sysexits.h index 55bf1a4..464cb11 100644 --- a/include/sysexits.h +++ b/include/sysexits.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1987, 1993 * The Regents of the University of California. All rights reserved. diff --git a/include/tar.h b/include/tar.h index 5d2c6c4..764ca01 100644 --- a/include/tar.h +++ b/include/tar.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1994 * The Regents of the University of California. All rights reserved. diff --git a/include/time.h b/include/time.h index aaff63b..2914d40 100644 --- a/include/time.h +++ b/include/time.h @@ -65,6 +65,9 @@ #include <_types.h> +#define __need_struct_timespec +#include <_structs.h> + #ifndef NULL #define NULL __DARWIN_NULL #endif /* ! NULL */ @@ -84,14 +87,6 @@ typedef __darwin_size_t size_t; typedef __darwin_time_t time_t; #endif -#ifndef _TIMESPEC -#define _TIMESPEC -struct timespec { - time_t tv_sec; /* seconds */ - long tv_nsec; /* and nanoseconds */ -}; -#endif - struct tm { int tm_sec; /* seconds after the minute [0-60] */ int tm_min; /* minutes after the hour [0-59] */ @@ -106,11 +101,13 @@ struct tm { char *tm_zone; /* timezone abbreviation */ }; +#if __DARWIN_UNIX03 +#define CLOCKS_PER_SEC 1000000 /* [XSI] */ +#else /* !__DARWIN_UNIX03 */ #include /* Include file containing CLK_TCK. */ #define CLOCKS_PER_SEC (__DARWIN_CLK_TCK) - -#include +#endif /* __DARWIN_UNIX03 */ #ifndef _ANSI_SOURCE extern char *tzname[]; @@ -118,32 +115,74 @@ extern char *tzname[]; extern int getdate_err; #if __DARWIN_UNIX03 +//Begin-Libc +#ifndef LIBC_ALIAS_TIMEZONE +//End-Libc extern long timezone __DARWIN_ALIAS(timezone); +//Begin-Libc +#else /* LIBC_ALIAS_TIMEZONE */ +extern long timezone LIBC_ALIAS(timezone); +#endif /* !LIBC_ALIAS_TIMEZONE */ +//End-Libc #endif /* __DARWIN_UNIX03 */ extern int daylight; __BEGIN_DECLS char *asctime(const struct tm *); -clock_t clock(void); +//Begin-Libc +#ifndef LIBC_ALIAS_CLOCK +//End-Libc +clock_t clock(void) __DARWIN_ALIAS(clock); +//Begin-Libc +#else /* LIBC_ALIAS_CLOCK */ +clock_t clock(void) LIBC_ALIAS(clock); +#endif /* !LIBC_ALIAS_CLOCK */ +//End-Libc char *ctime(const time_t *); double difftime(time_t, time_t); struct tm *getdate(const char *); struct tm *gmtime(const time_t *); struct tm *localtime(const time_t *); -time_t mktime(struct tm *); +//Begin-Libc +#ifndef LIBC_ALIAS_MKTIME +//End-Libc +time_t mktime(struct tm *) __DARWIN_ALIAS(mktime); +//Begin-Libc +#else /* LIBC_ALIAS_MKTIME */ +time_t mktime(struct tm *) LIBC_ALIAS(mktime); +#endif /* !LIBC_ALIAS_MKTIME */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_STRFTIME +//End-Libc size_t strftime(char * __restrict, size_t, const char * __restrict, const struct tm * __restrict) __DARWIN_ALIAS(strftime); -char *strptime(const char * __restrict, const char * __restrict, struct tm * __restrict); +//Begin-Libc +#else /* LIBC_ALIAS_STRFTIME */ +size_t strftime(char * __restrict, size_t, const char * __restrict, const struct tm * __restrict) LIBC_ALIAS(strftime); +#endif /* !LIBC_ALIAS_STRFTIME */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_STRPTIME +//End-Libc +char *strptime(const char * __restrict, const char * __restrict, struct tm * __restrict) __DARWIN_ALIAS(strptime); +//Begin-Libc +#else /* LIBC_ALIAS_STRPTIME */ +char *strptime(const char * __restrict, const char * __restrict, struct tm * __restrict) LIBC_ALIAS(strptime); +#endif /* !LIBC_ALIAS_STRPTIME */ +//End-Libc time_t time(time_t *); #ifndef _ANSI_SOURCE void tzset(void); #endif /* not ANSI */ -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) -char *asctime_r(const struct tm *, char *); +/* [TSF] Thread safe functions */ +char *asctime_r(const struct tm * __restrict, char * __restrict); char *ctime_r(const time_t *, char *); -struct tm *gmtime_r(const time_t *, struct tm *); -struct tm *localtime_r(const time_t *, struct tm *); +struct tm *gmtime_r(const time_t * __restrict, struct tm * __restrict); +struct tm *localtime_r(const time_t * __restrict, struct tm * __restrict); + +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) time_t posix2time(time_t); #if !__DARWIN_UNIX03 char *timezone(int, int); @@ -155,7 +194,15 @@ time_t timegm(struct tm * const); #endif /* neither ANSI nor POSIX */ #if !defined(_ANSI_SOURCE) -int nanosleep(const struct timespec *, struct timespec *) __DARWIN_ALIAS(nanosleep); +//Begin-Libc +#ifndef LIBC_ALIAS_NANOSLEEP +//End-Libc +int nanosleep(const struct timespec *, struct timespec *) __DARWIN_ALIAS_C(nanosleep); +//Begin-Libc +#else /* LIBC_ALIAS_NANOSLEEP */ +int nanosleep(const struct timespec *, struct timespec *) LIBC_ALIAS_C(nanosleep); +#endif /* !LIBC_ALIAS_NANOSLEEP */ +//End-Libc #endif __END_DECLS diff --git a/include/ttyent.h b/include/ttyent.h index 6f40d98..89855cd 100644 --- a/include/ttyent.h +++ b/include/ttyent.h @@ -1,25 +1,3 @@ -/* - * Copyright (c) 2000 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) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -66,6 +44,7 @@ #define _TTYS_WINDOW "window" #define _TTYS_ONERROR "onerror" #define _TTYS_ONOPTION "onoption" +#define _TTYS_SLOT "slot" struct ttyent { char *ty_name; /* terminal device name */ diff --git a/include/ucontext.h b/include/ucontext.h index 5d03cdf..572b379 100644 --- a/include/ucontext.h +++ b/include/ucontext.h @@ -24,6 +24,14 @@ #ifndef _UCONTEXT_H_ #define _UCONTEXT_H_ +#include #include +__BEGIN_DECLS +int getcontext(ucontext_t *); +void makecontext(ucontext_t *, void (*)(void), int, ...); +int setcontext(const ucontext_t *); +int swapcontext(ucontext_t * __restrict, const ucontext_t * __restrict); +__END_DECLS + #endif /* _UCONTEXT_H_ */ diff --git a/include/unistd.h b/include/unistd.h index 82f7855..31da492 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -69,32 +69,44 @@ #define _UNISTD_H_ #include <_types.h> - -#include #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) */ + #ifndef _GID_T -#define _GID_T +#define _GID_T typedef __darwin_gid_t gid_t; #endif #ifndef _INTPTR_T -#define _INTPTR_T +#define _INTPTR_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 +#define _OFF_T typedef __darwin_off_t off_t; #endif #ifndef _PID_T -#define _PID_T +#define _PID_T typedef __darwin_pid_t pid_t; #endif #ifndef _SIZE_T -#define _SIZE_T +#define _SIZE_T /* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: * _GCC_SIZE_T */ typedef __darwin_size_t size_t; @@ -106,34 +118,34 @@ typedef __darwin_ssize_t ssize_t; #endif #ifndef _UID_T -#define _UID_T +#define _UID_T typedef __darwin_uid_t uid_t; /* user id */ #endif #ifndef _USECONDS_T -#define _USECONDS_T +#define _USECONDS_T typedef __darwin_useconds_t useconds_t; #endif -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #ifndef _UUID_T -#define _UUID_T +#define _UUID_T typedef __darwin_uuid_t uuid_t; #endif /* _UUID_T */ -#endif /* _POSIX_C_SOURCE */ +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ #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 +#define NULL __DARWIN_NULL #endif /* ! NULL */ /* Version test macros */ /* _POSIX_VERSION and _POSIX2_VERSION from sys/unistd.h */ #define _XOPEN_VERSION 600 /* [XSI] */ -#define _XOPEN_XCU_VERSION 4 /* Older standard */ +#define _XOPEN_XCU_VERSION 4 /* Older standard */ /* Please keep this list in the same order as the applicable standard */ @@ -143,7 +155,7 @@ typedef __darwin_uuid_t uuid_t; #define _POSIX_CHOWN_RESTRICTED 200112L #define _POSIX_CLOCK_SELECTION (-1) /* [CS] */ #define _POSIX_CPUTIME (-1) /* [CPT] */ -#define _POSIX_FSYNC (-1) /* [FSC] */ +#define _POSIX_FSYNC 200112L /* [FSC] */ #define _POSIX_IPV6 200112L #define _POSIX_JOB_CONTROL 200112L #define _POSIX_MAPPED_FILES 200112L /* [MF] */ @@ -173,10 +185,10 @@ typedef __darwin_uuid_t uuid_t; #define _POSIX_THREAD_PRIO_INHERIT (-1) /* [TPI] */ #define _POSIX_THREAD_PRIO_PROTECT (-1) /* [TPP] */ #define _POSIX_THREAD_PRIORITY_SCHEDULING (-1) /* [TPS] */ -#define _POSIX_THREAD_PROCESS_SHARED (-1) /* [TSH] */ +#define _POSIX_THREAD_PROCESS_SHARED 200112L /* [TSH] */ #define _POSIX_THREAD_SAFE_FUNCTIONS 200112L /* [TSF] */ #define _POSIX_THREAD_SPORADIC_SERVER (-1) /* [TSP] */ -#define _POSIX_THREADS 200112L /* [THR] */ +#define _POSIX_THREADS 200112L /* [THR] */ #define _POSIX_TIMEOUTS (-1) /* [TMO] */ #define _POSIX_TIMERS (-1) /* [TMR] */ #define _POSIX_TRACE (-1) /* [TRC] */ @@ -205,8 +217,8 @@ typedef __darwin_uuid_t uuid_t; #define _V6_ILP32_OFF32 (-1) #define _V6_ILP32_OFFBIG (1) -#define _V6_LP64_OFF64 (1) -#define _V6_LPBIG_OFFBIG (1) +#define _V6_LP64_OFF64 (-1) +#define _V6_LPBIG_OFFBIG (-1) #define _XBS5_ILP32_OFF32 _V6_ILP32_OFF32 /* legacy */ #define _XBS5_ILP32_OFFBIG _V6_ILP32_OFFBIG /* legacy */ @@ -223,10 +235,10 @@ typedef __darwin_uuid_t uuid_t; #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 */ +#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 */ /* configurable system variables */ #define _SC_ARG_MAX 1 @@ -256,7 +268,7 @@ typedef __darwin_uuid_t uuid_t; #define _SC_2_UPE 25 #define _SC_STREAM_MAX 26 #define _SC_TZNAME_MAX 27 -#define _SC_ASYNCHRONOUS_IO 28 +#define _SC_ASYNCHRONOUS_IO 28 #define _SC_PAGESIZE 29 #define _SC_MEMLOCK 30 #define _SC_MEMLOCK_RANGE 31 @@ -281,6 +293,10 @@ 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) +#define _SC_NPROCESSORS_CONF 57 +#define _SC_NPROCESSORS_ONLN 58 +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ #define _SC_2_PBS 59 #define _SC_2_PBS_ACCOUNTING 60 #define _SC_2_PBS_CHECKPOINT 61 @@ -345,15 +361,21 @@ typedef __darwin_uuid_t uuid_t; #define _SC_XOPEN_UNIX 115 #define _SC_XOPEN_VERSION 116 #define _SC_XOPEN_XCU_VERSION 121 -#define _SC_XBS5_ILP32_OFF32 122 -#define _SC_XBS5_ILP32_OFFBIG 123 -#define _SC_XBS5_LP64_OFF64 124 -#define _SC_XBS5_LPBIG_OFFBIG 125 +#define _SC_XBS5_ILP32_OFF32 122 +#define _SC_XBS5_ILP32_OFFBIG 123 +#define _SC_XBS5_LP64_OFF64 124 +#define _SC_XBS5_LPBIG_OFFBIG 125 +#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 +#define _SC_PASS_MAX 131 #ifndef _CS_PATH /* XXX temporary #ifdef'ed for */ #define _CS_PATH 1 #endif -#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 2 +#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 2 #define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 3 #define _CS_POSIX_V6_ILP32_OFF32_LIBS 4 #define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 5 @@ -385,6 +407,10 @@ typedef __darwin_uuid_t uuid_t; #define _CS_XBS5_LPBIG_OFFBIG_LIBS 34 #define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 35 +#define _CS_DARWIN_USER_DIR 65536 +#define _CS_DARWIN_USER_TEMP_DIR 65537 +#define _CS_DARWIN_USER_CACHE_DIR 65538 + __BEGIN_DECLS void _exit(int) __dead2; @@ -393,12 +419,41 @@ unsigned int alarm(unsigned int); int chdir(const char *); int chown(const char *, uid_t, gid_t); -int close(int); -size_t confstr(int, char *, size_t); +//Begin-Libc +#ifndef LIBC_ALIAS_CLOSE +//End-Libc +int close(int) __DARWIN_ALIAS_C(close); +//Begin-Libc +#else /* LIBC_ALIAS_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 *, ...); @@ -409,6 +464,15 @@ 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); @@ -419,7 +483,15 @@ long gethostid(void); int gethostname(char *, size_t); char *getlogin(void); int getlogin_r(char *, size_t); -int getopt(int, char * const [], const char *); +//Begin-Libc +#ifndef LIBC_ALIAS_GETOPT +//End-Libc +int getopt(int, char * const [], const char *) __DARWIN_ALIAS(getopt); +//Begin-Libc +#else /* LIBC_ALIAS_GETOPT */ +int getopt(int, char * const [], const char *) LIBC_ALIAS(getopt); +#endif /* !LIBC_ALIAS_GETOPT */ +//End-Libc pid_t getpgid(pid_t); pid_t getpgrp(void); pid_t getpid(void); @@ -428,17 +500,73 @@ pid_t getsid(pid_t); uid_t getuid(void); char *getwd(char *); /* obsoleted by getcwd() */ int isatty(int); +//Begin-Libc +#ifndef LIBC_ALIAS_LCHOWN +//End-Libc int lchown(const char *, uid_t, gid_t) __DARWIN_ALIAS(lchown); +//Begin-Libc +#else /* LIBC_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 *); -int lockf(int, int, off_t); +//Begin-Libc +#ifndef LIBC_ALIAS_LOCKF +//End-Libc +int lockf(int, int, off_t) __DARWIN_ALIAS_C(lockf); +//Begin-Libc +#else /* LIBC_ALIAS_LOCKF */ +int lockf(int, int, off_t) LIBC_ALIAS_C(lockf); +#endif /* !LIBC_ALIAS_LOCKF */ +//End-Libc off_t lseek(int, off_t, int); -int nice(int); +//Begin-Libc +#ifndef LIBC_ALIAS_NICE +//End-Libc +int nice(int) __DARWIN_ALIAS(nice); +//Begin-Libc +#else /* LIBC_ALIAS_NICE */ +int nice(int) LIBC_ALIAS(nice); +#endif /* !LIBC_ALIAS_NICE */ +//End-Libc long pathconf(const char *, int); -int pause(void); +//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]); -ssize_t pread(int, void *, size_t, off_t); -ssize_t pwrite(int, const void *, size_t, off_t); -ssize_t read(int, void *, size_t); +//Begin-Libc +#ifndef LIBC_ALIAS_PREAD +//End-Libc +ssize_t pread(int, void *, size_t, off_t) __DARWIN_ALIAS_C(pread); +//Begin-Libc +#else /* LIBC_ALIAS_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 +ssize_t pwrite(int, const void *, size_t, off_t) __DARWIN_ALIAS_C(pwrite); +//Begin-Libc +#else /* LIBC_ALIAS_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); @@ -446,16 +574,49 @@ int seteuid(uid_t); int setgid(gid_t); int setpgid(pid_t, pid_t); #if __DARWIN_UNIX03 +//Begin-Libc +#ifndef LIBC_ALIAS_SETPGRP +//End-Libc pid_t setpgrp(void) __DARWIN_ALIAS(setpgrp); +//Begin-Libc +#else /* LIBC_ALIAS_SETPGRP */ +pid_t setpgrp(void) LIBC_ALIAS(setpgrp); +#endif /* !LIBC_ALIAS_SETPGRP */ +//End-Libc #else /* !__DARWIN_UNIX03 */ int setpgrp(pid_t pid, pid_t pgrp); /* obsoleted by setpgid() */ #endif /* __DARWIN_UNIX03 */ -int setregid(gid_t, gid_t); -int setreuid(uid_t, uid_t); +//Begin-Libc +#ifndef LIBC_ALIAS_SETREGID +//End-Libc +int setregid(gid_t, gid_t) __DARWIN_ALIAS(setregid); +//Begin-Libc +#else /* LIBC_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 +int setreuid(uid_t, uid_t) __DARWIN_ALIAS(setreuid); +//Begin-Libc +#else /* LIBC_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); + 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); @@ -465,39 +626,56 @@ 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 *); -int usleep(useconds_t); +//Begin-Libc +#ifndef LIBC_ALIAS_USLEEP +//End-Libc +int usleep(useconds_t) __DARWIN_ALIAS_C(usleep); +//Begin-Libc +#else /* LIBC_ALIAS_USLEEP */ +int usleep(useconds_t) LIBC_ALIAS_C(usleep); +#endif /* !LIBC_ALIAS_USLEEP */ +//End-Libc pid_t vfork(void); -ssize_t write(int, const void *, size_t); +//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 extern char *optarg; /* getopt(3) external variables */ extern int optind, opterr, optopt; -#ifndef _POSIX_C_SOURCE +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) #include 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); -int async_daemon(void); void *brk(const void *); int chroot(const char *); -#if __DARWIN_UNIX03 -void encrypt(char *, int) __DARWIN_ALIAS(encrypt); -#else /* !__DARWIN_UNIX03 */ -int encrypt(char *, int); -#endif /* __DARWIN_UNIX03 */ void endusershell(void); int execvP(const char *, const char *, char * const *); char *fflagstostr(unsigned long); -int fsync(int); int getdtablesize(void); int getdomainname(char *, int); int getgrouplist(const char *, int, int *, int *); @@ -512,6 +690,7 @@ char *getusershell(void); int getwgroups_np(int *, uuid_t); int initgroups(const char *, int); int iruserok(unsigned long, int, const char *, const char *); +int iruserok_sa(const void *, int, int, const char *, const char *); int issetugid(void); char *mkdtemp(char *); int mknod(const char *, mode_t, dev_t); @@ -523,6 +702,8 @@ int profil(char *, size_t, unsigned long, unsigned int); int pthread_setugid_np(uid_t, gid_t); int pthread_getugid_np( uid_t *, gid_t *); int rcmd(char **, int, const char *, const char *, const char *, int *); +int rcmd_af(char **, int, const char *, const char *, const char *, int *, + int); int reboot(int); int revoke(const char *); int rresvport(int *); @@ -534,7 +715,15 @@ int setgroups(int, const gid_t *); void sethostid(long); int sethostname(const char *, int); #if __DARWIN_UNIX03 +//Begin-Libc +#ifndef LIBC_ALIAS_SETKEY +//End-Libc void setkey(const char *) __DARWIN_ALIAS(setkey); +//Begin-Libc +#else /* LIBC_ALIAS_SETKEY */ +void setkey(const char *) LIBC_ALIAS(setkey); +#endif /* !LIBC_ALIAS_SETKEY */ +//End-Libc #else /* !__DARWIN_UNIX03 */ int setkey(const char *); #endif /* __DARWIN_UNIX03 */ @@ -558,19 +747,49 @@ int getsubopt(char **, char * const *, char **); /* HFS & HFS Plus semantics system calls go here */ #ifdef __LP64__ +//Begin-Libc +#ifndef LIBC_ALIAS_GETATTRLIST +//End-Libc int getattrlist(const char*,void*,void*,size_t,unsigned int) __DARWIN_ALIAS(getattrlist); +//Begin-Libc +#else /* LIBC_ALIAS_GETATTRLIST */ +int getattrlist(const char*,void*,void*,size_t,unsigned int) LIBC_ALIAS(getattrlist); +#endif /* !LIBC_ALIAS_GETATTRLIST */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_SETATTRLIST +//End-Libc int setattrlist(const char*,void*,void*,size_t,unsigned int) __DARWIN_ALIAS(setattrlist); +//Begin-Libc +#else /* LIBC_ALIAS_SETATTRLIST */ +int setattrlist(const char*,void*,void*,size_t,unsigned int) LIBC_ALIAS(setattrlist); +#endif /* !LIBC_ALIAS_SETATTRLIST */ +//End-Libc int exchangedata(const char*,const char*,unsigned int); -int checkuseraccess(const char*,uid_t,gid_t*,int,int,unsigned int); int getdirentriesattr(int,void*,void*,size_t,unsigned int*,unsigned int*,unsigned int*,unsigned int); int searchfs(const char*,void*,void*,unsigned int,unsigned int,void*); int fsctl(const char *,unsigned int,void*,unsigned int); #else /* __LP64__ */ +//Begin-Libc +#ifndef LIBC_ALIAS_GETATTRLIST +//End-Libc int getattrlist(const char*,void*,void*,size_t,unsigned long) __DARWIN_ALIAS(getattrlist); +//Begin-Libc +#else /* LIBC_ALIAS_GETATTRLIST */ +int getattrlist(const char*,void*,void*,size_t,unsigned long) LIBC_ALIAS(getattrlist); +#endif /* !LIBC_ALIAS_GETATTRLIST */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_SETATTRLIST +//End-Libc int setattrlist(const char*,void*,void*,size_t,unsigned long) __DARWIN_ALIAS(setattrlist); +//Begin-Libc +#else /* LIBC_ALIAS_SETATTRLIST */ +int setattrlist(const char*,void*,void*,size_t,unsigned long) LIBC_ALIAS(setattrlist); +#endif /* !LIBC_ALIAS_SETATTRLIST */ +//End-Libc int exchangedata(const char*,const char*,unsigned long); -int checkuseraccess(const char*,uid_t,gid_t*,int,int,unsigned long); int getdirentriesattr(int,void*,void*,size_t,unsigned long*,unsigned long*,unsigned long*,unsigned long); int searchfs(const char*,void*,void*,unsigned long,unsigned long,void*); @@ -579,7 +798,7 @@ int fsctl(const char *,unsigned long,void*,unsigned long); extern int optreset; -#endif /* !_POSIX_C_SOURCE */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ __END_DECLS #endif /* !_UNISTD_H_ */ diff --git a/include/util.h b/include/util.h index 0f0ca6a..a8078f8 100644 --- a/include/util.h +++ b/include/util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -64,7 +64,7 @@ #include #include #include -#include +#include #define PIDLOCK_NONBLOCK 1 #define PIDLOCK_USEHOSTNAME 2 @@ -85,10 +85,11 @@ #define OPENDEV_BLCK 0x04 /* Open block, not character device. */ __BEGIN_DECLS -void login(struct utmp *); +struct utmp; /* forward reference to /usr/include/utmp.h */ +void login(struct utmp *) __DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER; int login_tty(int); -int logout(const char *); -void logwtmp(const char *, const char *, const char *); +int logout(const char *) __DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER; +void logwtmp(const char *, const char *, const char *) __DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER; int opendev(char *, int, int, char **); int openpty(int *, int *, char *, struct termios *, struct winsize *); @@ -102,4 +103,7 @@ struct iovec; char *ttymsg(struct iovec *, int, const char *, int); __END_DECLS +/* Include utmp.h last to avoid deprecation warning above */ +#include + #endif /* !_UTIL_H_ */ diff --git a/include/utmp.h b/include/utmp.h index 29f0fb0..f53763c 100644 --- a/include/utmp.h +++ b/include/utmp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000, 2005, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -63,6 +63,23 @@ #ifndef _UTMP_H_ #define _UTMP_H_ +/* + * This header file is DEPRECATED and only provided for compatibility + * with previous releases of Mac OS X. Use of these structures, especially + * in 64-bit computing, may corrupt the utmp, wtmp and lastlog files. + * + * Use the utmpx APIs instead. + */ + +#include <_types.h> +#include + +#ifndef _TIME_T +#define _TIME_T +typedef __darwin_time_t time_t; +#endif + +/* These files no longer exist in 10.5 and later */ #define _PATH_UTMP "/var/run/utmp" #define _PATH_WTMP "/var/log/wtmp" #define _PATH_LASTLOG "/var/log/lastlog" @@ -75,13 +92,13 @@ struct lastlog { time_t ll_time; char ll_line[UT_LINESIZE]; char ll_host[UT_HOSTSIZE]; -}; +} __DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER; struct utmp { char ut_line[UT_LINESIZE]; char ut_name[UT_NAMESIZE]; char ut_host[UT_HOSTSIZE]; long ut_time; -}; +} __DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER; #endif /* !_UTMP_H_ */ diff --git a/include/utmpx.h b/include/utmpx.h new file mode 100644 index 0000000..ee657d2 --- /dev/null +++ b/include/utmpx.h @@ -0,0 +1,181 @@ +/* + * 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@ + */ +/* $NetBSD: utmpx.h,v 1.11 2003/08/26 16:48:32 wiz Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + */ +#ifndef _UTMPX_H_ +#define _UTMPX_H_ + +#include <_types.h> +#include + +#ifndef _PID_T +#define _PID_T +typedef __darwin_pid_t pid_t; +#endif + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#ifndef _UID_T +#define _UID_T +typedef __darwin_uid_t uid_t; +#endif +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + +#define _PATH_UTMPX "/var/run/utmpx" + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define UTMPX_FILE _PATH_UTMPX +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + +#define _UTX_USERSIZE 256 /* matches MAXLOGNAME */ +#define _UTX_LINESIZE 32 +#define _UTX_IDSIZE 4 +#define _UTX_HOSTSIZE 256 + +#define EMPTY 0 +#define RUN_LVL 1 +#define BOOT_TIME 2 +#define OLD_TIME 3 +#define NEW_TIME 4 +#define INIT_PROCESS 5 +#define LOGIN_PROCESS 6 +#define USER_PROCESS 7 +#define DEAD_PROCESS 8 + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define ACCOUNTING 9 +#define SIGNATURE 10 +#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. This is not the format the + * entries are stored in the files, and application should only access + * entries using routines described in getutxent(3). + */ + +#ifdef _UTMPX_COMPAT +#define ut_user ut_name +#define ut_xtime ut_tv.tv_sec +#endif /* _UTMPX_COMPAT */ + +struct utmpx { + char ut_user[_UTX_USERSIZE]; /* login name */ + char ut_id[_UTX_IDSIZE]; /* id */ + char ut_line[_UTX_LINESIZE]; /* tty name */ + pid_t ut_pid; /* process id creating the entry */ + short ut_type; /* type of this entry */ + struct timeval ut_tv; /* time entry was created */ + char ut_host[_UTX_HOSTSIZE]; /* host name */ + __uint32_t ut_pad[16]; /* reserved for future use */ +}; + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +struct lastlogx { + struct timeval ll_tv; /* time entry was created */ + char ll_line[_UTX_LINESIZE]; /* tty name */ + char ll_host[_UTX_HOSTSIZE]; /* host name */ +}; +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + +__BEGIN_DECLS + +void endutxent(void); + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +void endutxent_wtmp(void); +struct lastlogx * + getlastlogx(uid_t, struct lastlogx *); +struct lastlogx * + getlastlogxbyname(const char*, struct lastlogx *); +struct utmp; /* forward reference */ +void getutmp(const struct utmpx *, struct utmp *); +void getutmpx(const struct utmp *, struct utmpx *); +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + +struct utmpx * + getutxent(void); + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +struct utmpx * + getutxent_wtmp(void); +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + +struct utmpx * + getutxid(const struct utmpx *); +struct utmpx * + getutxline(const struct utmpx *); +struct utmpx * + pututxline(const 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 *); +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + +__END_DECLS + +#endif /* !_UTMPX_H_ */ diff --git a/include/wchar.h b/include/wchar.h index 8ab3661..0c5fc1e 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -67,7 +67,6 @@ #ifndef _WCHAR_H_ #define _WCHAR_H_ -#include #include <_types.h> #ifndef NULL @@ -133,13 +132,13 @@ size_t mbsrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, mbstate_t * __restrict); wint_t putwc(wchar_t, FILE *); wint_t putwchar(wchar_t); -int swprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict, +int swprintf(wchar_t * __restrict, size_t, const wchar_t * __restrict, ...) __DARWIN_LDBL_COMPAT(swprintf); int swscanf(const wchar_t * __restrict, const wchar_t * __restrict, ...) __DARWIN_LDBL_COMPAT(swscanf); wint_t ungetwc(wint_t, FILE *); int vfwprintf(FILE * __restrict, const wchar_t * __restrict, __darwin_va_list) __DARWIN_LDBL_COMPAT(vfwprintf); -int vswprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict, +int vswprintf(wchar_t * __restrict, size_t, const wchar_t * __restrict, __darwin_va_list) __DARWIN_LDBL_COMPAT(vswprintf); int vwprintf(const wchar_t * __restrict, __darwin_va_list) __DARWIN_LDBL_COMPAT(vwprintf); size_t wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); @@ -149,8 +148,17 @@ int wcscmp(const wchar_t *, const wchar_t *); int wcscoll(const wchar_t *, const wchar_t *); wchar_t *wcscpy(wchar_t * __restrict, const wchar_t * __restrict); size_t wcscspn(const wchar_t *, const wchar_t *); +//Begin-Libc +#ifndef LIBC_ALIAS_WCSFTIME +//End-Libc size_t wcsftime(wchar_t * __restrict, size_t, const wchar_t * __restrict, - const struct tm * __restrict); + const struct tm * __restrict) __DARWIN_ALIAS(wcsftime); +//Begin-Libc +#else /* LIBC_ALIAS_WCSFTIME */ +size_t wcsftime(wchar_t * __restrict, size_t, const wchar_t * __restrict, + const struct tm * __restrict) LIBC_ALIAS(wcsftime); +#endif /* !LIBC_ALIAS_WCSFTIME */ +//End-Libc size_t wcslen(const wchar_t *); wchar_t *wcsncat(wchar_t * __restrict, const wchar_t * __restrict, size_t); int wcsncmp(const wchar_t *, const wchar_t *, size_t); @@ -196,14 +204,19 @@ int wcswidth(const wchar_t *, size_t); int wcwidth(wchar_t); #endif /* !defined(_ANSI_SOURCE) */ -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) +#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); 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) */ +#endif /* !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) */ + +/* 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 +#endif __END_DECLS #ifdef _USE_EXTENDED_LOCALES_ diff --git a/include/wctype.h b/include/wctype.h index dabbaff..518f4b8 100644 --- a/include/wctype.h +++ b/include/wctype.h @@ -39,14 +39,80 @@ typedef __darwin_wctrans_t wctrans_t; #endif +/* + * _EXTERNALIZE_WCTYPE_INLINES_TOP_ is defined in locale/iswctype.c to tell us + * to generate code for extern versions of all top-level inline functions. + */ +#ifdef _EXTERNALIZE_WCTYPE_INLINES_TOP_ +#define _USE_CTYPE_INLINE_ +#define __DARWIN_WCTYPE_TOP_static_inline +#else /* !_EXTERNALIZE_WCTYPE_INLINES_TOP_ */ +#define __DARWIN_WCTYPE_TOP_static_inline static __inline +#endif /* _EXTERNALIZE_WCTYPE_INLINES_TOP_ */ + #include <_wctype.h> #include +/* + * Use inline functions if we are allowed to and the compiler supports them. + */ +#if !defined(_DONT_USE_CTYPE_INLINE_) && \ + (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) + +__DARWIN_WCTYPE_TOP_static_inline int +iswblank(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_B)); +} + +#if !defined(_ANSI_SOURCE) +__DARWIN_WCTYPE_TOP_static_inline int +iswascii(wint_t _wc) +{ + return ((_wc & ~0x7F) == 0); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswhexnumber(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_X)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswideogram(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_I)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswnumber(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_D)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswphonogram(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_Q)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswrune(wint_t _wc) +{ + return (__istype(_wc, 0xFFFFFFF0L)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswspecial(wint_t _wc) +{ + return (__istype(_wc, _CTYPE_T)); +} +#endif /* !_ANSI_SOURCE */ + +#else /* not using inlines */ + __BEGIN_DECLS int iswblank(wint_t); -wint_t towctrans(wint_t, wctrans_t); -wctrans_t - wctrans(const char *); #if !defined(_ANSI_SOURCE) wint_t iswascii(wint_t); @@ -57,23 +123,18 @@ wint_t iswphonogram(wint_t); wint_t iswrune(wint_t); wint_t iswspecial(wint_t); #endif - -#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) -wint_t nextwctype(wint_t, wctype_t); -#endif __END_DECLS -#define iswblank(wc) __istype((wc), _CTYPE_B) +#endif /* using inlines */ -#if !defined(_ANSI_SOURCE) -#define iswascii(wc) (((wc) & ~0x7F) == 0) -#define iswhexnumber(wc) __istype((wc), _CTYPE_X) -#define iswideogram(wc) __istype((wc), _CTYPE_I) -#define iswnumber(wc) __istype((wc), _CTYPE_D) -#define iswphonogram(wc) __istype((wc), _CTYPE_Q) -#define iswrune(wc) __istype((wc), 0xFFFFFF00L) -#define iswspecial(wc) __istype((wc), _CTYPE_T) +__BEGIN_DECLS +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +wint_t nextwctype(wint_t, wctype_t); #endif +wint_t towctrans(wint_t, wctrans_t); +wctrans_t + wctrans(const char *); +__END_DECLS #ifdef _USE_EXTENDED_LOCALES_ #include diff --git a/include/wordexp.h b/include/wordexp.h index 28a4999..643276c 100644 --- a/include/wordexp.h +++ b/include/wordexp.h @@ -42,7 +42,7 @@ WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. * */ -/* $Id: wordexp.h,v 1.4 2004/11/25 19:38:10 emoy Exp $ */ +/* $Id: wordexp.h,v 1.5 1994/05/12 20:46:40 davis Exp $ */ #ifndef _WORDEXP_H #define _WORDEXP_H @@ -76,13 +76,13 @@ typedef struct { #define WRDE_BADVAL 2 #define WRDE_CMDSUB 3 #define WRDE_NOSPACE 4 -#define WRDE_NOYS 5 +#define WRDE_NOSYS 5 #define WRDE_SYNTAX 6 __BEGIN_DECLS -int wordexp(const char *words, wordexp_t *pwordexp, int flags); -void wordfree(wordexp_t *pwordexp); +int wordexp(const char * __restrict, wordexp_t * __restrict, int); +void wordfree(wordexp_t *); __END_DECLS #endif /* _WORDEXP_H */ diff --git a/include/xlocale.h b/include/xlocale.h index 3c65e10..e936c2f 100644 --- a/include/xlocale.h +++ b/include/xlocale.h @@ -72,12 +72,15 @@ __const char * querylocale(int, locale_t); locale_t uselocale(locale_t); __END_DECLS -#ifdef __WCTYPE_H_ -#include -#endif /* __WCTYPE_H_ */ +//Begin-Libc +#ifndef __DARWIN_XLOCALE_PRIVATE +//End-Libc #ifdef _CTYPE_H_ #include #endif /* _CTYPE_H_ */ +#ifdef __WCTYPE_H_ +#include +#endif /* __WCTYPE_H_ */ #ifdef _INTTYPES_H_ #include #endif /* _INTTYPES_H_ */ @@ -105,5 +108,8 @@ __END_DECLS #ifdef _WCTYPE_H_ #include #endif /* _WCTYPE_H_ */ +//Begin-Libc +#endif /* __DARWIN_XLOCALE_PRIVATE */ +//End-Libc #endif /* _XLOCALE_H_ */ diff --git a/include/xlocale/Makefile.inc b/include/xlocale/Makefile.inc index be1ad26..5aac5a6 100644 --- a/include/xlocale/Makefile.inc +++ b/include/xlocale/Makefile.inc @@ -5,4 +5,4 @@ INCXLOCALE_INSTHDRS += __wctype.h _ctype.h _inttypes.h _langinfo.h \ INCXLOCALE_INSTHDRS := ${INCXLOCALE_INSTHDRS:S/^/${.CURDIR}\/include\/xlocale\//} XLOCALE_INSTHDRS += ${INCXLOCALE_INSTHDRS} -STRIP_HDRS += xlocale/_ctype.h +STRIP_HDRS += xlocale/_ctype.h xlocale/_time.h xlocale/_wchar.h diff --git a/include/xlocale/__wctype.h b/include/xlocale/__wctype.h index 68e2def..06e905b 100644 --- a/include/xlocale/__wctype.h +++ b/include/xlocale/__wctype.h @@ -24,6 +24,95 @@ #ifndef _XLOCALE___WCTYPE_H_ #define _XLOCALE___WCTYPE_H_ +#if !defined(_DONT_USE_CTYPE_INLINE_) && \ + (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) + +__DARWIN_WCTYPE_TOP_static_inline int +iswalnum_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_A|_CTYPE_D, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswalpha_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_A, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswcntrl_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_C, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswctype_l(wint_t _wc, wctype_t _charclass, locale_t _l) +{ + return (__istype_l(_wc, _charclass, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswdigit_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_D, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswgraph_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_G, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswlower_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_L, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswprint_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_R, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswpunct_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_P, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswspace_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_S, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswupper_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_U, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswxdigit_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_X, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline wint_t +towlower_l(wint_t _wc, locale_t _l) +{ + return (__tolower_l(_wc, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline wint_t +towupper_l(wint_t _wc, locale_t _l) +{ + return (__toupper_l(_wc, _l)); +} + +#else /* not using inlines */ + __BEGIN_DECLS int iswalnum_l(wint_t, locale_t); int iswalpha_l(wint_t, locale_t); @@ -39,23 +128,13 @@ int iswupper_l(wint_t, locale_t); int iswxdigit_l(wint_t, locale_t); wint_t towlower_l(wint_t, locale_t); wint_t towupper_l(wint_t, locale_t); +__END_DECLS + +#endif /* using inlines */ + +__BEGIN_DECLS wctype_t wctype_l(const char *, locale_t); __END_DECLS -#define iswalnum_l(wc, l) __istype_l((wc), _CTYPE_A|_CTYPE_D, (l)) -#define iswalpha_l(wc, l) __istype_l((wc), _CTYPE_A, (l)) -#define iswcntrl_l(wc, l) __istype_l((wc), _CTYPE_C, (l)) -#define iswctype_l(wc, charclass, l) __istype_l((wc), (charclass), (l)) -#define iswdigit_l(wc, l) __istype_l((wc), _CTYPE_D, (l)) -#define iswgraph_l(wc, l) __istype_l((wc), _CTYPE_G, (l)) -#define iswlower_l(wc, l) __istype_l((wc), _CTYPE_L, (l)) -#define iswprint_l(wc, l) __istype_l((wc), _CTYPE_R, (l)) -#define iswpunct_l(wc, l) __istype_l((wc), _CTYPE_P, (l)) -#define iswspace_l(wc, l) __istype_l((wc), _CTYPE_S, (l)) -#define iswupper_l(wc, l) __istype_l((wc), _CTYPE_U, (l)) -#define iswxdigit_l(wc, l) __istype_l((wc), _CTYPE_X, (l)) -#define towlower_l(wc, l) __tolower_l((wc), (l)) -#define towupper_l(wc, l) __toupper_l((wc), (l)) - #endif /* _XLOCALE___WCTYPE_H_ */ diff --git a/include/xlocale/_ctype.h b/include/xlocale/_ctype.h index 6cfa3f9..c4f493c 100644 --- a/include/xlocale/_ctype.h +++ b/include/xlocale/_ctype.h @@ -24,51 +24,11 @@ #ifndef _XLOCALE__CTYPE_H_ #define _XLOCALE__CTYPE_H_ -__BEGIN_DECLS -int digittoint_l(int, locale_t); -int isalnum_l(int, locale_t); -int isalpha_l(int, locale_t); -int isblank_l(int, locale_t); -int iscntrl_l(int, locale_t); -int isdigit_l(int, locale_t); -int isgraph_l(int, locale_t); -int ishexnumber_l(int, locale_t); -int isideogram_l(int, locale_t); -int islower_l(int, locale_t); -int isnumber_l(int, locale_t); -int isphonogram_l(int, locale_t); -int isprint_l(int, locale_t); -int ispunct_l(int, locale_t); -int isrune_l(int, locale_t); -int isspace_l(int, locale_t); -int isspecial_l(int, locale_t); -int isupper_l(int, locale_t); -int isxdigit_l(int, locale_t); -int tolower_l(int, locale_t); -int toupper_l(int, locale_t); -__END_DECLS - -#define digittoint_l(c, l) __maskrune_l((c), 0xFF, (l)) -#define ishexnumber_l(c, l) __istype_l((c), _CTYPE_X, (l)) -#define isideogram_l(c, l) __istype_l((c), _CTYPE_I, (l)) -#define isnumber_l(c, l) __istype_l((c), _CTYPE_D, (l)) -#define isphonogram_l(c, l) __istype_l((c), _CTYPE_Q, (l)) -#define isrune_l(c, l) __istype_l((c), 0xFFFFFF00L, (l)) -#define isspecial_l(c, l) __istype_l((c), _CTYPE_T, (l)) -#define isalnum_l(c, l) __istype_l((c), (_CTYPE_A|_CTYPE_D), (l)) -#define isalpha_l(c, l) __istype_l((c), _CTYPE_A, (l)) -#define isblank_l(c, l) __istype_l((c), _CTYPE_B, (l)) -#define iscntrl_l(c, l) __istype_l((c), _CTYPE_C, (l)) -#define isdigit_l(c, l) __istype_l((c), _CTYPE_D, (l)) -#define isgraph_l(c, l) __istype_l((c), _CTYPE_G, (l)) -#define islower_l(c, l) __istype_l((c), _CTYPE_L, (l)) -#define isprint_l(c, l) __istype_l((c), _CTYPE_R, (l)) -#define ispunct_l(c, l) __istype_l((c), _CTYPE_P, (l)) -#define isspace_l(c, l) __istype_l((c), _CTYPE_S, (l)) -#define isupper_l(c, l) __istype_l((c), _CTYPE_U, (l)) -#define isxdigit_l(c, l) __istype_l((c), _CTYPE_X, (l)) -#define tolower_l(c, l) __tolower_l(c, (l)) -#define toupper_l(c, l) __toupper_l(c, (l)) +/* + * Use inline functions if we are allowed to and the compiler supports them. + */ +#if !defined(_DONT_USE_CTYPE_INLINE_) && \ + (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) /* See comments in about __darwin_ct_rune_t. */ __BEGIN_DECLS @@ -77,15 +37,9 @@ __darwin_ct_rune_t ___tolower_l(__darwin_ct_rune_t, locale_t); __darwin_ct_rune_t ___toupper_l(__darwin_ct_rune_t, locale_t); __END_DECLS -/* - * Use inline functions if we are allowed to and the compiler supports them. - */ -#if !defined(_DONT_USE_CTYPE_INLINE_) && \ - (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) - //Begin-Libc #ifdef __LIBC__ -static __inline int +__DARWIN_CTYPE_static_inline int __maskrune_l(__darwin_ct_rune_t _c, unsigned long _f, locale_t _l) { return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype_l(_c, _l) : @@ -100,28 +54,28 @@ __END_DECLS #endif /* __LIBC__ */ //End-Libc -static __inline int +__DARWIN_CTYPE_static_inline int __istype_l(__darwin_ct_rune_t _c, unsigned long _f, locale_t _l) { return !!(isascii(_c) ? (_DefaultRuneLocale.__runetype[_c] & _f) : __maskrune_l(_c, _f, _l)); } -static __inline __darwin_ct_rune_t +__DARWIN_CTYPE_static_inline __darwin_ct_rune_t __toupper_l(__darwin_ct_rune_t _c, locale_t _l) { return isascii(_c) ? _DefaultRuneLocale.__mapupper[_c] : ___toupper_l(_c, _l); } -static __inline __darwin_ct_rune_t +__DARWIN_CTYPE_static_inline __darwin_ct_rune_t __tolower_l(__darwin_ct_rune_t _c, locale_t _l) { return isascii(_c) ? _DefaultRuneLocale.__maplower[_c] : ___tolower_l(_c, _l); } -static __inline int +__DARWIN_CTYPE_static_inline int __wcwidth_l(__darwin_ct_rune_t _c, locale_t _l) { unsigned int _x; @@ -134,14 +88,159 @@ __wcwidth_l(__darwin_ct_rune_t _c, locale_t _l) return ((_x & _CTYPE_R) != 0 ? 1 : -1); } +#ifndef _EXTERNALIZE_CTYPE_INLINES_ + +__DARWIN_CTYPE_TOP_static_inline int +digittoint_l(int c, locale_t l) +{ + return (__maskrune_l(c, 0x0F, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isalnum_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_A|_CTYPE_D, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isalpha_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_A, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isblank_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_B, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +iscntrl_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_C, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isdigit_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_D, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isgraph_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_G, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +ishexnumber_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_X, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isideogram_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_I, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +islower_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_L, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isnumber_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_D, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isphonogram_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_Q, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isprint_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_R, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +ispunct_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_P, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isrune_l(int c, locale_t l) +{ + return (__istype_l(c, 0xFFFFFFF0L, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isspace_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_S, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isspecial_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_T, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isupper_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_U, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +isxdigit_l(int c, locale_t l) +{ + return (__istype_l(c, _CTYPE_X, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +tolower_l(int c, locale_t l) +{ + return (__tolower_l(c, l)); +} + +__DARWIN_CTYPE_TOP_static_inline int +toupper_l(int c, locale_t l) +{ + return (__toupper_l(c, l)); +} +#endif /* _EXTERNALIZE_CTYPE_INLINES_ */ + #else /* not using inlines */ __BEGIN_DECLS -int __maskrune_l(__darwin_ct_rune_t, unsigned long, locale_t); -int __istype_l(__darwin_ct_rune_t, unsigned long, locale_t); -__darwin_ct_rune_t __toupper_l(__darwin_ct_rune_t, locale_t); -__darwin_ct_rune_t __tolower_l(__darwin_ct_rune_t, locale_t); -int __wcwidth_l(__darwin_ct_rune_t, locale_t); +int digittoint_l(int, locale_t); +int isalnum_l(int, locale_t); +int isalpha_l(int, locale_t); +int isblank_l(int, locale_t); +int iscntrl_l(int, locale_t); +int isdigit_l(int, locale_t); +int isgraph_l(int, locale_t); +int ishexnumber_l(int, locale_t); +int isideogram_l(int, locale_t); +int islower_l(int, locale_t); +int isnumber_l(int, locale_t); +int isphonogram_l(int, locale_t); +int isprint_l(int, locale_t); +int ispunct_l(int, locale_t); +int isrune_l(int, locale_t); +int isspace_l(int, locale_t); +int isspecial_l(int, locale_t); +int isupper_l(int, locale_t); +int isxdigit_l(int, locale_t); +int tolower_l(int, locale_t); +int toupper_l(int, locale_t); __END_DECLS #endif /* using inlines */ diff --git a/include/xlocale/_inttypes.h b/include/xlocale/_inttypes.h index 3b1a132..cb8a99e 100644 --- a/include/xlocale/_inttypes.h +++ b/include/xlocale/_inttypes.h @@ -33,6 +33,11 @@ intmax_t wcstoimax_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base, locale_t); uintmax_t wcstoumax_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base, locale_t); + +/* Poison the following routines if -fshort-wchar is set */ +#if !defined(__cplusplus) && defined(__WCHAR_MAX__) && __WCHAR_MAX__ <= 0xffffU +#pragma GCC poison wcstoimax_l wcstoumax_l +#endif __END_DECLS #endif /* _XLOCALE__INTTYPES_H_ */ diff --git a/include/xlocale/_stdlib.h b/include/xlocale/_stdlib.h index a511fdd..494a917 100644 --- a/include/xlocale/_stdlib.h +++ b/include/xlocale/_stdlib.h @@ -37,8 +37,8 @@ size_t mbstowcs_l(wchar_t * __restrict , const char * __restrict, size_t, locale_t); int mbtowc_l(wchar_t * __restrict, const char * __restrict, size_t, locale_t); -double strtod_l(const char *, char **, locale_t); -float strtof_l(const char *, char **, locale_t); +double strtod_l(const char *, char **, locale_t) __DARWIN_ALIAS(strtod_l); +float strtof_l(const char *, char **, locale_t) __DARWIN_ALIAS(strtof_l); long strtol_l(const char *, char **, int, locale_t); long double strtold_l(const char *, char **, locale_t) @@ -60,6 +60,11 @@ unsigned long long size_t wcstombs_l(char * __restrict, const wchar_t * __restrict, size_t, locale_t); int wctomb_l(char *, wchar_t, locale_t); + +/* Poison the following routines if -fshort-wchar is set */ +#if !defined(__cplusplus) && defined(__WCHAR_MAX__) && __WCHAR_MAX__ <= 0xffffU +#pragma GCC poison mbstowcs_l mbtowc_l wcstombs_l wctomb_l +#endif __END_DECLS #endif /* _XLOCALE__STDLIB_H_ */ diff --git a/include/xlocale/_time.h b/include/xlocale/_time.h index 35c908c..eaeb744 100644 --- a/include/xlocale/_time.h +++ b/include/xlocale/_time.h @@ -25,11 +25,30 @@ #define _XLOCALE__TIME_H_ __BEGIN_DECLS +//Begin-Libc +#ifndef LIBC_ALIAS_STRFTIME_L +//End-Libc size_t strftime_l(char * __restrict, size_t, const char * __restrict, const struct tm * __restrict, locale_t) __DARWIN_ALIAS(strftime_l); +//Begin-Libc +#else /* LIBC_ALIAS_STRFTIME_L */ +size_t strftime_l(char * __restrict, size_t, const char * __restrict, + const struct tm * __restrict, locale_t) + LIBC_ALIAS(strftime_l); +#endif /* !LIBC_ALIAS_STRFTIME_L */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_STRPTIME_L +//End-Libc +char *strptime_l(const char * __restrict, const char * __restrict, + struct tm * __restrict, locale_t) __DARWIN_ALIAS(strptime_l); +//Begin-Libc +#else /* LIBC_ALIAS_STRPTIME_L */ char *strptime_l(const char * __restrict, const char * __restrict, - struct tm * __restrict, locale_t); + struct tm * __restrict, locale_t) LIBC_ALIAS(strptime_l); +#endif /* !LIBC_ALIAS_STRPTIME_L */ +//End-Libc __END_DECLS #endif /* _XLOCALE__TIME_H_ */ diff --git a/include/xlocale/_wchar.h b/include/xlocale/_wchar.h index 79d80f7..5318f3b 100644 --- a/include/xlocale/_wchar.h +++ b/include/xlocale/_wchar.h @@ -71,8 +71,19 @@ int vwscanf_l(locale_t, const wchar_t * __restrict, __darwin_va_list) size_t wcrtomb_l(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); int wcscoll_l(const wchar_t *, const wchar_t *, locale_t); +//Begin-Libc +#ifndef LIBC_ALIAS_WCSFTIME_L +//End-Libc size_t wcsftime_l(wchar_t * __restrict, size_t, const wchar_t * __restrict, - const struct tm * __restrict, locale_t); + const struct tm * __restrict, locale_t) + __DARWIN_ALIAS(wcsftime_l); +//Begin-Libc +#else /* LIBC_ALIAS_WCSFTIME_L */ +size_t wcsftime_l(wchar_t * __restrict, size_t, const wchar_t * __restrict, + const struct tm * __restrict, locale_t) + 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, @@ -102,6 +113,11 @@ 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); + +/* 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 +#endif __END_DECLS #endif /* _XLOCALE__WCHAR_H_ */ diff --git a/include/xlocale/_wctype.h b/include/xlocale/_wctype.h index 9ad4891..d22654d 100644 --- a/include/xlocale/_wctype.h +++ b/include/xlocale/_wctype.h @@ -24,6 +24,53 @@ #ifndef _XLOCALE__WCTYPE_H_ #define _XLOCALE__WCTYPE_H_ +#if !defined(_DONT_USE_CTYPE_INLINE_) && \ + (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) + +__DARWIN_WCTYPE_TOP_static_inline int +iswblank_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_B, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswhexnumber_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_X, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswideogram_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_I, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswnumber_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_D, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswphonogram_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_Q, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswrune_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, 0xFFFFFFF0L, _l)); +} + +__DARWIN_WCTYPE_TOP_static_inline int +iswspecial_l(wint_t _wc, locale_t _l) +{ + return (__istype_l(_wc, _CTYPE_T, _l)); +} + +#else /* not using inlines */ + __BEGIN_DECLS int iswblank_l(wint_t, locale_t); wint_t iswhexnumber_l(wint_t, locale_t); @@ -32,19 +79,15 @@ wint_t iswnumber_l(wint_t, locale_t); wint_t iswphonogram_l(wint_t, locale_t); wint_t iswrune_l(wint_t, locale_t); wint_t iswspecial_l(wint_t, locale_t); +__END_DECLS + +#endif /* using inlines */ + +__BEGIN_DECLS wint_t nextwctype_l(wint_t, wctype_t, locale_t); wint_t towctrans_l(wint_t, wctrans_t, locale_t); wctrans_t wctrans_l(const char *, locale_t); __END_DECLS -#define iswblank_l(wc, l) __istype_l((wc), _CTYPE_B, (l)) -#define iswhexnumber_l(wc, l) __istype_l((wc), _CTYPE_X, (l)) -#define iswideogram_l(wc, l) __istype_l((wc), _CTYPE_I, (l)) -#define iswnumber_l(wc, l) __istype_l((wc), _CTYPE_D, (l)) -#define iswphonogram_l(wc, l) __istype_l((wc), _CTYPE_Q, (l)) -#define iswrune_l(wc, l) __istype_l((wc), 0xFFFFFF00L, (l)) -#define iswspecial_l(wc, l) __istype_l((wc), _CTYPE_T, (l)) - #endif /* _XLOCALE__WCTYPE_H_ */ - diff --git a/locale/FreeBSD/btowc.3.patch b/locale/FreeBSD/btowc.3.patch index ffe9df7..66f6c85 100644 --- a/locale/FreeBSD/btowc.3.patch +++ b/locale/FreeBSD/btowc.3.patch @@ -1,29 +1,45 @@ ---- btowc.3.orig Fri Mar 11 18:06:40 2005 -+++ btowc.3 Fri Mar 11 18:08:08 2005 -@@ -29,7 +29,9 @@ +--- btowc.3 2003-05-20 15:21:44.000000000 -0700 ++++ btowc.3.edit 2006-07-12 11:14:18.000000000 -0700 +@@ -29,16 +29,35 @@ .Os .Sh NAME .Nm btowc , -.Nm wctob -+.Nm wctob , +.Nm btowc_l , ++.Nm wctob , +.Nm wctob_l .Nd "convert between wide and single-byte characters" .Sh LIBRARY .Lb libc -@@ -39,6 +41,11 @@ - .Fn btowc "int c" + .Sh SYNOPSIS ++.In stdio.h + .In wchar.h + .Ft wint_t +-.Fn btowc "int c" ++.Fo btowc ++.Fa "int c" ++.Fc .Ft int - .Fn wctob "wint_t c" +-.Fn wctob "wint_t c" ++.Fo wctob ++.Fa "wint_t c" ++.Fc ++.In wchar.h +.In xlocale.h +.Ft wint_t -+.Fn btowc_l "int c" "locale_t loc" ++.Fo btowc_l ++.Fa "int c" ++.Fa "locale_t loc" ++.Fc +.Ft int -+.Fn wctob_l "wint_t c" "locale_t loc" ++.Fo wctob_l ++.Fa "wint_t c" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn btowc -@@ -59,10 +66,23 @@ +@@ -59,10 +78,29 @@ .Fn wctob returns .Dv WEOF . @@ -39,12 +55,18 @@ +functions may be passed locales directly. See +.Xr xlocale 3 +for more information. ++.Sh LEGACY SYNOPSIS ++.Pp ++The include file ++.In stdio.h ++is not necessary for these functions. .Sh SEE ALSO .Xr mbrtowc 3 , .Xr multibyte 3 , -.Xr wcrtomb 3 +.Xr wcrtomb 3 , -+.Xr xlocale 3 ++.Xr xlocale 3 , ++.Xr compat 5 .Sh STANDARDS The .Fn btowc diff --git a/locale/FreeBSD/collate.c.patch b/locale/FreeBSD/collate.c.patch index a8c49bb..d831b23 100644 --- a/locale/FreeBSD/collate.c.patch +++ b/locale/FreeBSD/collate.c.patch @@ -1,18 +1,33 @@ --- collate.c.orig 2004-11-25 11:38:16.000000000 -0800 -+++ collate.c 2005-02-17 10:35:00.000000000 -0800 -@@ -28,6 +28,11 @@ ++++ collate.c 2005-10-20 01:00:19.000000000 -0700 +@@ -28,14 +28,26 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.33 2004/09/22 16:56:48 stefanf Exp $"); +#include "xlocale_private.h" +/* assumes the locale_t variable is named loc */ -+#define __collate_substitute_table (loc->__lc_collate->__substitute_table) ++#define __collate_chain_equiv_table (loc->__lc_collate->__chain_equiv_table) ++#define __collate_chain_pri_table (loc->__lc_collate->__chain_pri_table) +#define __collate_char_pri_table (loc->__lc_collate->__char_pri_table) ++#define __collate_info (&loc->__lc_collate->__info) ++#define __collate_large_char_pri_table (loc->__lc_collate->__large_char_pri_table) ++#define __collate_substitute_table (loc->__lc_collate->__substitute_table) + #include "namespace.h" #include #include -@@ -44,36 +49,46 @@ + #include ++#include + #include ++#include + #include + #include + #include ++#include + #include "un-namespace.h" + + #include "collate.h" +@@ -44,36 +56,50 @@ #include "libc_private.h" @@ -23,6 +38,9 @@ -struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; -struct __collate_st_chain_pri *__collate_chain_pri_table; - ++#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN ++static void wntohl(wchar_t *, int); ++#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ void __collate_err(int ex, const char *f) __dead2; -int @@ -39,13 +57,16 @@ +__collate_load_tables(const char *encoding, locale_t loc) { FILE *fp; - int i, saverr, chains; - uint32_t u32; +- int i, saverr, chains; +- uint32_t u32; ++ int i, saverr, chains, z; char strbuf[STR_LEN], buf[PATH_MAX]; - void *TMP_substitute_table, *TMP_char_pri_table, *TMP_chain_pri_table; - static char collate_encoding[ENCODING_LEN + 1]; + struct __xlocale_st_collate *TMP; + static struct __xlocale_st_collate *cache = NULL; ++ struct __collate_st_info info; ++ void *vp; /* 'encoding' must be already checked. */ if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { @@ -73,7 +94,42 @@ return (_LDP_CACHE); } -@@ -121,115 +136,106 @@ +@@ -97,9 +123,7 @@ + return (_LDP_ERROR); + } + chains = -1; +- if (strcmp(strbuf, COLLATE_VERSION) == 0) +- chains = 0; +- else if (strcmp(strbuf, COLLATE_VERSION1_1) == 0) ++ if (strcmp(strbuf, COLLATE_VERSION1_1A) == 0) + chains = 1; + if (chains < 0) { + (void)fclose(fp); +@@ -107,13 +131,21 @@ + return (_LDP_ERROR); + } + if (chains) { +- if (fread(&u32, sizeof(u32), 1, fp) != 1) { ++ if (fread(&info, sizeof(info), 1, fp) != 1) { + saverr = errno; + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } +- if ((chains = (int)ntohl(u32)) < 1) { ++#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN ++ for(z = 0; z < info.directive_count; z++) { ++ info.undef_pri[z] = ntohl(info.undef_pri[z]); ++ info.subst_count[z] = ntohl(info.subst_count[z]); ++ } ++ info.chain_count = ntohl(info.chain_count); ++ info.large_pri_count = ntohl(info.large_pri_count); ++#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ ++ if ((chains = info.chain_count) < 0) { + (void)fclose(fp); + errno = EFTYPE; + return (_LDP_ERROR); +@@ -121,136 +153,446 @@ } else chains = TABLE_SIZE; @@ -86,9 +142,7 @@ - } - if ((TMP_char_pri_table = - malloc(sizeof(__collate_char_pri_table))) == NULL) { -+ if ((TMP = -+ malloc(sizeof(struct __xlocale_st_collate) + sizeof(struct __collate_st_chain_pri) * chains)) == NULL) { - saverr = errno; +- saverr = errno; - free(TMP_substitute_table); - (void)fclose(fp); - errno = saverr; @@ -96,7 +150,13 @@ - } - if ((TMP_chain_pri_table = - malloc(sizeof(*__collate_chain_pri_table) * chains)) == NULL) { -- saverr = errno; ++ 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; - free(TMP_substitute_table); - free(TMP_char_pri_table); (void)fclose(fp); @@ -105,7 +165,6 @@ } + TMP->__refcount = 2; /* one for the locale, one for the cache */ + TMP->__free_extra = NULL; -+ TMP->__chain_pri_table = (struct __collate_st_chain_pri *)(TMP + 1); #define FREAD(a, b, c, d) \ { \ @@ -125,10 +184,9 @@ - FREAD(TMP_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); - FREAD(TMP_chain_pri_table, - sizeof(*__collate_chain_pri_table), chains, fp); -+ FREAD(TMP->__substitute_table, sizeof(TMP->__substitute_table), 1, fp); -+ FREAD(TMP->__char_pri_table, sizeof(TMP->__char_pri_table), 1, fp); -+ FREAD(TMP->__chain_pri_table, -+ sizeof(struct __collate_st_chain_pri), chains, fp); ++ /* adjust size to read the remaining in one chunk */ ++ i -= offsetof(struct __xlocale_st_collate, __char_pri_table); ++ FREAD(TMP->__char_pri_table, i, 1, fp); (void)fclose(fp); - (void)strcpy(collate_encoding, encoding); @@ -141,24 +199,82 @@ - if (__collate_chain_pri_table != NULL) - free(__collate_chain_pri_table); - __collate_chain_pri_table = TMP_chain_pri_table; +- +- __collate_substitute_nontrivial = 0; +- for (i = 0; i < UCHAR_MAX + 1; i++) { +- if (__collate_substitute_table[i][0] != i || +- __collate_substitute_table[i][1] != 0) { +- __collate_substitute_nontrivial = 1; +- break; ++ vp = (void *)(TMP + 1); ++ ++ /* the COLLATE_SUBST_DUP optimization relies on COLL_WEIGHTS_MAX == 2 */ ++ if (info.subst_count[0] > 0) { ++ TMP->__substitute_table[0] = (struct __collate_st_subst *)vp; ++ vp += info.subst_count[0] * sizeof(struct __collate_st_subst); ++ } else ++ TMP->__substitute_table[0] = NULL; ++ if (info.flags & COLLATE_SUBST_DUP) ++ TMP->__substitute_table[1] = TMP->__substitute_table[0]; ++ else if (info.subst_count[1] > 0) { ++ TMP->__substitute_table[1] = (struct __collate_st_subst *)vp; ++ vp += info.subst_count[1] * sizeof(struct __collate_st_subst); ++ } else ++ TMP->__substitute_table[1] = NULL; ++ ++ if (chains > 0) { ++ TMP->__chain_pri_table = (struct __collate_st_chain_pri *)vp; ++ vp += chains * sizeof(struct __collate_st_chain_pri); ++ } else ++ TMP->__chain_pri_table = NULL; ++ if (info.large_pri_count > 0) ++ TMP->__large_char_pri_table = (struct __collate_st_large_char_pri *)vp; ++ else ++ TMP->__large_char_pri_table = NULL; ++ ++#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN ++ { ++ struct __collate_st_char_pri *p = TMP->__char_pri_table; ++ for(i = UCHAR_MAX + 1; i-- > 0; p++) { ++ for(z = 0; z < info.directive_count; z++) ++ p->pri[z] = ntohl(p->pri[z]); + } + } +- __collate_load_error = 0; ++ for(z = 0; z < info.directive_count; z++) ++ if (info.subst_count[z] > 0) { ++ struct __collate_st_subst *p = TMP->__substitute_table[z]; ++ for(i = info.subst_count[z]; i-- > 0; p++) { ++ p->val = ntohl(p->val); ++ wntohl(p->str, STR_LEN); ++ } ++ } ++ { ++ struct __collate_st_chain_pri *p = TMP->__chain_pri_table; ++ for(i = chains; i-- > 0; p++) { ++ wntohl(p->str, STR_LEN); ++ for(z = 0; z < info.directive_count; z++) ++ p->pri[z] = ntohl(p->pri[z]); ++ } ++ } ++ if (info.large_pri_count > 0) { ++ struct __collate_st_large_char_pri *p = TMP->__large_char_pri_table; ++ for(i = info.large_pri_count; i-- > 0; p++) { ++ p->val = ntohl(p->val); ++ for(z = 0; z < info.directive_count; z++) ++ p->pri.pri[z] = ntohl(p->pri.pri[z]); ++ } ++ } ++#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ + (void)strcpy(TMP->__encoding, encoding); ++ (void)memcpy(&TMP->__info, &info, sizeof(info)); + XL_RELEASE(cache); + cache = TMP; + XL_RELEASE(loc->__lc_collate); + loc->__lc_collate = cache; + /* no need to retain, since we set __refcount to 2 above */ - -- __collate_substitute_nontrivial = 0; -+ loc->__collate_substitute_nontrivial = 0; - for (i = 0; i < UCHAR_MAX + 1; i++) { - if (__collate_substitute_table[i][0] != i || - __collate_substitute_table[i][1] != 0) { -- __collate_substitute_nontrivial = 1; -+ loc->__collate_substitute_nontrivial = 1; - break; - } - } -- __collate_load_error = 0; ++ ++ loc->__collate_substitute_nontrivial = (info.subst_count[0] > 0 || info.subst_count[1] > 0); + loc->__collate_load_error = 0; + if (loc == &__global_locale) + __collate_load_error = 0; @@ -168,103 +284,729 @@ -u_char * -__collate_substitute(s) -+__private_extern__ u_char * -+__collate_substitute_l(s, loc) - const u_char *s; -+ locale_t loc; +- const u_char *s; ++static int ++__collate_wcsnlen(const wchar_t *s, int len) ++{ ++ int n = 0; ++ while (*s && n < len) { ++ s++; ++ n++; ++ } ++ return n; ++} ++ ++static struct __collate_st_subst * ++substsearch(const wchar_t key, struct __collate_st_subst *tab, int n) ++{ ++ int low = 0; ++ int high = n - 1; ++ int next, compar; ++ struct __collate_st_subst *p; ++ ++ while (low <= high) { ++ next = (low + high) / 2; ++ p = tab + next; ++ compar = key - p->val; ++ if (compar == 0) ++ return p; ++ if (compar > 0) ++ low = next + 1; ++ else ++ high = next - 1; ++ } ++ return NULL; ++} ++ ++__private_extern__ wchar_t * ++__collate_substitute(const wchar_t *s, int which, locale_t loc) { int dest_len, len, nlen; - int delta = strlen(s); -+ int delta = strlen((const char *)s); - u_char *dest_str = NULL; +- u_char *dest_str = NULL; ++ int n, delta, nsubst; ++ wchar_t *dest_str = NULL; ++ const wchar_t *fp; ++ struct __collate_st_subst *subst, *match; if (s == NULL || *s == '\0') - return (__collate_strdup("")); -+ return (__collate_strdup((u_char *)"")); - delta += delta / 8; - dest_str = malloc(dest_len = delta); +- delta += delta / 8; +- dest_str = malloc(dest_len = delta); ++ return (__collate_wcsdup(L"")); ++ dest_len = wcslen(s); ++ nsubst = __collate_info->subst_count[which]; ++ if (nsubst <= 0) ++ return __collate_wcsdup(s); ++ subst = __collate_substitute_table[which]; ++ delta = dest_len / 4; ++ if (delta < 2) ++ delta = 2; ++ dest_str = (wchar_t *)malloc((dest_len += delta) * sizeof(wchar_t)); if (dest_str == NULL) __collate_err(EX_OSERR, __func__); len = 0; while (*s) { - nlen = len + strlen(__collate_substitute_table[*s]); -+ nlen = len + strlen((const char *)__collate_substitute_table[*s]); ++ if ((match = substsearch(*s, subst, nsubst)) != NULL) { ++ fp = match->str; ++ n = __collate_wcsnlen(fp, STR_LEN); ++ } else { ++ fp = s; ++ n = 1; ++ } ++ nlen = len + n; if (dest_len <= nlen) { - dest_str = reallocf(dest_str, dest_len = nlen + delta); +- dest_str = reallocf(dest_str, dest_len = nlen + delta); ++ dest_str = reallocf(dest_str, (dest_len = nlen + delta) * sizeof(wchar_t)); if (dest_str == NULL) __collate_err(EX_OSERR, __func__); } - (void)strcpy(dest_str + len, __collate_substitute_table[*s++]); -+ (void)strcpy((char *)(dest_str + len), (const char *)__collate_substitute_table[*s++]); - len = nlen; +- len = nlen; ++ wcsncpy(dest_str + len, fp, n); ++ len += n; ++ s++; } ++ dest_str[len] = 0; return (dest_str); } -void -__collate_lookup(t, len, prim, sec) -+u_char * -+__collate_substitute(s) -+ const u_char *s; +- const u_char *t; +- int *len, *prim, *sec; ++static struct __collate_st_chain_pri * ++chainsearch(const wchar_t *key, int *len, locale_t loc) +{ -+ return __collate_substitute_l(s, __current_locale()); ++ int low = 0; ++ int high = __collate_info->chain_count - 1; ++ int next, compar, l; ++ struct __collate_st_chain_pri *p; ++ struct __collate_st_chain_pri *tab = __collate_chain_pri_table; ++ ++ while (low <= high) { ++ next = (low + high) / 2; ++ p = tab + next; ++ compar = *key - *p->str; ++ if (compar == 0) { ++ l = __collate_wcsnlen(p->str, STR_LEN); ++ compar = wcsncmp(key, p->str, l); ++ if (compar == 0) { ++ *len = l; ++ return p; ++ } ++ } ++ if (compar > 0) ++ low = next + 1; ++ else ++ high = next - 1; ++ } ++ return NULL; ++} ++ ++static struct __collate_st_large_char_pri * ++largesearch(const wchar_t key, locale_t loc) ++{ ++ int low = 0; ++ int high = __collate_info->large_pri_count - 1; ++ int next, compar; ++ struct __collate_st_large_char_pri *p; ++ struct __collate_st_large_char_pri *tab = __collate_large_char_pri_table; ++ ++ while (low <= high) { ++ next = (low + high) / 2; ++ p = tab + next; ++ compar = key - p->val; ++ if (compar == 0) ++ return p; ++ if (compar > 0) ++ low = next + 1; ++ else ++ high = next - 1; ++ } ++ return NULL; +} + +__private_extern__ void -+__collate_lookup_l(t, len, prim, sec, loc) - const u_char *t; - int *len, *prim, *sec; -+ locale_t loc; ++__collate_lookup_l(const wchar_t *t, int *len, int *prim, int *sec, locale_t loc) { struct __collate_st_chain_pri *p2; ++ int l; *len = 1; *prim = *sec = 0; - for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) { -+ for (p2 = loc->__lc_collate->__chain_pri_table; p2->str[0] != '\0'; p2++) { - if (*t == p2->str[0] && +- if (*t == p2->str[0] && - strncmp(t, p2->str, strlen(p2->str)) == 0) { - *len = strlen(p2->str); -+ strncmp((const char *)t, (const char *)p2->str, strlen((const char *)p2->str)) == 0) { -+ *len = strlen((const char *)p2->str); - *prim = p2->prim; - *sec = p2->sec; - return; -@@ -239,11 +245,19 @@ - *sec = __collate_char_pri_table[*t].sec; - } - +- *prim = p2->prim; +- *sec = p2->sec; ++ p2 = chainsearch(t, &l, loc); ++ /* use the chain if prim >= 0 */ ++ if (p2 && p2->pri[0] >= 0) { ++ *len = l; ++ *prim = p2->pri[0]; ++ *sec = p2->pri[1]; ++ return; ++ } ++ if (*t <= UCHAR_MAX) { ++ *prim = __collate_char_pri_table[*t].pri[0]; ++ *sec = __collate_char_pri_table[*t].pri[1]; ++ return; ++ } ++ if (__collate_info->large_pri_count > 0) { ++ struct __collate_st_large_char_pri *match; ++ match = largesearch(*t, loc); ++ if (match) { ++ *prim = match->pri.pri[0]; ++ *sec = match->pri.pri[1]; ++ return; ++ } ++ } ++ *prim = (l = __collate_info->undef_pri[0]) >= 0 ? l : *t - l; ++ *sec = (l = __collate_info->undef_pri[1]) >= 0 ? l : *t - l; ++} ++ ++/* ++ * This is only provided for programs (like grep) that are calling this ++ * private function. This will go away eventually. ++ */ +void -+__collate_lookup(t, len, prim, sec) -+ const u_char *t; -+ int *len, *prim, *sec; ++__collate_lookup(const unsigned char *t, int *len, int *prim, int *sec) +{ -+ return __collate_lookup_l(t, len, prim, sec, __current_locale()); ++ locale_t loc = __current_locale(); ++ wchar_t *w = __collate_mbstowcs((const char *)t, loc); ++ int sverrno; ++ ++ __collate_lookup_l(w, len, prim, sec, loc); ++ sverrno = errno; ++ free(w); ++ errno = sverrno; +} ++ ++__private_extern__ void ++__collate_lookup_which(const wchar_t *t, int *len, int *pri, int which, locale_t loc) ++{ ++ struct __collate_st_chain_pri *p2; ++ int p, l; + - u_char * - __collate_strdup(s) - u_char *s; ++ *len = 1; ++ *pri = 0; ++ p2 = chainsearch(t, &l, loc); ++ if (p2) { ++ p = p2->pri[which]; ++ /* use the chain if pri >= 0 */ ++ if (p >= 0) { ++ *len = l; ++ *pri = p; ++ return; ++ } ++ } ++ if (*t <= UCHAR_MAX) { ++ *pri = __collate_char_pri_table[*t].pri[which]; ++ return; ++ } ++ if (__collate_info->large_pri_count > 0) { ++ struct __collate_st_large_char_pri *match; ++ 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; ++ *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); -+ u_char *t = (u_char *)strdup((const char *)s); ++ static const mbstate_t initial; ++ mbstate_t st; ++ size_t len; ++ const char *ss; ++ wchar_t *wcs; ++ ++ ss = s; ++ st = initial; ++ if ((len = mbsrtowcs_l(NULL, &ss, 0, &st, loc)) == (size_t)-1) ++ return NULL; ++ if ((wcs = (wchar_t *)malloc((len + 1) * sizeof(wchar_t))) == NULL) ++ __collate_err(EX_OSERR, __func__); ++ st = initial; ++ mbsrtowcs_l(wcs, &s, len, &st, loc); ++ wcs[len] = 0; - if (t == NULL) +- if (t == NULL) ++ return (wcs); ++} ++ ++__private_extern__ wchar_t * ++__collate_wcsdup(const wchar_t *s) ++{ ++ size_t len = wcslen(s) + 1; ++ wchar_t *wcs; ++ ++ if ((wcs = (wchar_t *)malloc(len * sizeof(wchar_t))) == NULL) __collate_err(EX_OSERR, __func__); -@@ -274,6 +288,7 @@ +- return (t); ++ wcscpy(wcs, s); ++ return (wcs); + } + +-void ++__private_extern__ void ++__collate_xfrm(const wchar_t *src, wchar_t **xf, locale_t loc) ++{ ++ int pri, len; ++ size_t slen; ++ const wchar_t *t; ++ wchar_t *tt = NULL, *tr = NULL; ++ int direc, pass; ++ wchar_t *xfp; ++ struct __collate_st_info *info = __collate_info; ++ int sverrno; ++ ++ for(pass = 0; pass < COLL_WEIGHTS_MAX; pass++) ++ xf[pass] = NULL; ++ for(pass = 0; pass < info->directive_count; pass++) { ++ direc = info->directive[pass]; ++ if (pass == 0 || !(info->flags & COLLATE_SUBST_DUP)) { ++ sverrno = errno; ++ free(tt); ++ errno = sverrno; ++ tt = __collate_substitute(src, pass, loc); ++ } ++ if (direc & DIRECTIVE_BACKWARD) { ++ wchar_t *bp, *fp, c; ++ sverrno = errno; ++ free(tr); ++ errno = sverrno; ++ tr = __collate_wcsdup(tt ? tt : src); ++ bp = tr; ++ fp = tr + wcslen(tr) - 1; ++ while(bp < fp) { ++ c = *bp; ++ *bp++ = *fp; ++ *fp-- = c; ++ } ++ t = (const wchar_t *)tr; ++ } else if (tt) ++ t = (const wchar_t *)tt; ++ else ++ t = (const wchar_t *)src; ++ sverrno = errno; ++ if ((xf[pass] = (wchar_t *)malloc(sizeof(wchar_t) * (wcslen(t) + 1))) == NULL) { ++ errno = sverrno; ++ slen = 0; ++ goto end; ++ } ++ errno = sverrno; ++ xfp = xf[pass]; ++ if (direc & DIRECTIVE_POSITION) { ++ while(*t) { ++ __collate_lookup_which(t, &len, &pri, pass, loc); ++ t += len; ++ if (pri <= 0) { ++ if (pri < 0) { ++ errno = EINVAL; ++ slen = 0; ++ goto end; ++ } ++ pri = COLLATE_MAX_PRIORITY; ++ } ++ *xfp++ = pri; ++ } ++ } else { ++ while(*t) { ++ __collate_lookup_which(t, &len, &pri, pass, loc); ++ t += len; ++ if (pri <= 0) { ++ if (pri < 0) { ++ errno = EINVAL; ++ slen = 0; ++ goto end; ++ } ++ continue; ++ } ++ *xfp++ = pri; ++ } ++ } ++ *xfp = 0; ++ } ++ end: ++ sverrno = errno; ++ free(tt); ++ free(tr); ++ errno = sverrno; ++} ++ ++__private_extern__ void + __collate_err(int ex, const char *f) { - int i; - struct __collate_st_chain_pri *p2; + const char *s; +@@ -268,24 +610,345 @@ + exit(ex); + } + ++/* ++ * __collate_collating_symbol takes the multibyte string specified by ++ * src and slen, and using ps, converts that to a wide character. Then ++ * it is checked to verify it is a collating symbol, and then copies ++ * it to the wide character string specified by dst and dlen (the ++ * results are not null terminated). The length of the wide characters ++ * copied to dst is returned if successful. Zero is returned if no such ++ * collating symbol exists. (size_t)-1 is returned if there are wide-character ++ * conversion errors, if the length of the converted string is greater that ++ * STR_LEN or if dlen is too small. It is up to the calling routine to ++ * preserve the mbstate_t structure as needed. ++ */ ++__private_extern__ size_t ++__collate_collating_symbol(wchar_t *dst, size_t dlen, const char *src, size_t slen, mbstate_t *ps, locale_t loc) ++{ ++ wchar_t wname[STR_LEN]; ++ wchar_t w, *wp; ++ size_t len, l; ++ ++ /* POSIX locale */ ++ if (loc->__collate_load_error) { ++ if (dlen < 1) ++ return (size_t)-1; ++ if (slen != 1 || !isascii(*src)) ++ return 0; ++ *dst = *src; ++ return 1; ++ } ++ for(wp = wname, len = 0; slen > 0; len++) { ++ l = mbrtowc_l(&w, src, slen, ps, loc); ++ if (l == (size_t)-1 || l == (size_t)-2) ++ return (size_t)-1; ++ if (l == 0) ++ break; ++ if (len >= STR_LEN) ++ return -1; ++ *wp++ = w; ++ src += l; ++ slen = (long)slen - (long)l; ++ } ++ if (len == 0 || len > dlen) ++ return (size_t)-1; ++ if (len == 1) { ++ if (*wname <= UCHAR_MAX) { ++ if (__collate_char_pri_table[*wname].pri[0] >= 0) { ++ if (dlen > 0) ++ *dst = *wname; ++ return 1; ++ } ++ return 0; ++ } else if (__collate_info->large_pri_count > 0) { ++ struct __collate_st_large_char_pri *match; ++ match = largesearch(*wname, loc); ++ if (match && match->pri.pri[0] >= 0) { ++ if (dlen > 0) ++ *dst = *wname; ++ return 1; ++ } ++ } ++ return 0; ++ } ++ *wp = 0; ++ if (__collate_info->chain_count > 0) { ++ struct __collate_st_chain_pri *match; ++ int ll; ++ match = chainsearch(wname, &ll, loc); ++ if (match) { ++ if (ll < dlen) ++ dlen = ll; ++ wcsncpy(dst, wname, dlen); ++ return ll; ++ } ++ } ++ return 0; ++} ++ ++/* ++ * __collate_equiv_class returns the equivalence class number for the symbol ++ * specified by src and slen, using ps to convert from multi-byte to wide ++ * character. Zero is returned if the symbol is not in an equivalence ++ * class. -1 is returned if there are wide character conversion error, ++ * if there are any greater-than-8-bit characters or if a multi-byte symbol ++ * is greater or equal to STR_LEN in length. It is up to the calling ++ * routine to preserve the mbstate_t structure as needed. ++ */ ++__private_extern__ int ++__collate_equiv_class(const char *src, size_t slen, mbstate_t *ps, locale_t loc) ++{ ++ wchar_t wname[STR_LEN]; ++ wchar_t w, *wp; ++ size_t len, l; ++ int e; ++ ++ /* POSIX locale */ ++ if (loc->__collate_load_error) ++ return 0; ++ for(wp = wname, len = 0; slen > 0; len++) { ++ l = mbrtowc_l(&w, src, slen, ps, loc); ++ if (l == (size_t)-1 || l == (size_t)-2) ++ return -1; ++ if (l == 0) ++ break; ++ if (len >= STR_LEN) ++ return -1; ++ *wp++ = w; ++ src += l; ++ slen = (long)slen - (long)l; ++ } ++ if (len == 0) ++ return -1; ++ if (len == 1) { ++ e = -1; ++ if (*wname <= UCHAR_MAX) ++ e = __collate_char_pri_table[*wname].pri[0]; ++ else if (__collate_info->large_pri_count > 0) { ++ struct __collate_st_large_char_pri *match; ++ match = largesearch(*wname, loc); ++ if (match) ++ e = match->pri.pri[0]; ++ } ++ if (e == 0) ++ return IGNORE_EQUIV_CLASS; ++ return e > 0 ? e : 0; ++ } ++ *wp = 0; ++ if (__collate_info->chain_count > 0) { ++ struct __collate_st_chain_pri *match; ++ int ll; ++ match = chainsearch(wname, &ll, loc); ++ if (match) { ++ e = match->pri[0]; ++ if (e == 0) ++ return IGNORE_EQUIV_CLASS; ++ return e < 0 ? -e : e; ++ } ++ } ++ return 0; ++} ++ ++/* ++ * __collate_equiv_match tries to match any single or multi-character symbol ++ * in equivalence class equiv_class in the multi-byte string specified by src ++ * and slen. If start is non-zero, it is taken to be the first (pre-converted) ++ * wide character. Subsequence wide characters, if needed, will use ps in ++ * the conversion. On a successful match, the length of the matched string ++ * is returned (including the start character). If dst is non-NULL, the ++ * matched wide-character string is copied to dst, a wide character array of ++ * length dlen (the results are not zero-terminated). If rlen is non-NULL, ++ * the number of character in src actually used is returned. Zero is ++ * returned by __collate_equiv_match if there is no match. (size_t)-1 is ++ * returned on error: if there were conversion errors or if dlen is too small ++ * to accept the results. On no match or error, ps is restored to its incoming ++ * state. ++ */ ++size_t ++__collate_equiv_match(int equiv_class, wchar_t *dst, size_t dlen, wchar_t start, const char *src, size_t slen, mbstate_t *ps, size_t *rlen, locale_t loc) ++{ ++ wchar_t w; ++ size_t len, l, clen; ++ int i; ++ wchar_t buf[STR_LEN], *wp; ++ mbstate_t save; ++ const char *s = src; ++ size_t sl = slen; ++ struct __collate_st_chain_pri *ch = NULL; ++ ++ /* POSIX locale */ ++ if (loc->__collate_load_error) ++ return (size_t)-1; ++ if (equiv_class == IGNORE_EQUIV_CLASS) ++ equiv_class = 0; ++ if (ps) ++ save = *ps; ++ wp = buf; ++ len = clen = 0; ++ if (start) { ++ *wp++ = start; ++ len = 1; ++ } ++ /* convert up to the max chain length */ ++ while(sl > 0 && len < __collate_info->chain_max_len) { ++ l = mbrtowc_l(&w, s, sl, ps, loc); ++ if (l == (size_t)-1 || l == (size_t)-2 || l == 0) ++ break; ++ *wp++ = w; ++ s += l; ++ clen += l; ++ sl -= l; ++ len++; ++ } ++ *wp = 0; ++ if (len > 1 && (ch = chainsearch(buf, &i, loc)) != NULL) { ++ int e = ch->pri[0]; ++ if (e < 0) ++ e = -e; ++ if (e == equiv_class) ++ goto found; ++ } ++ /* try single character */ ++ i = 1; ++ if (*buf <= UCHAR_MAX) { ++ if (equiv_class == __collate_char_pri_table[*buf].pri[0]) ++ goto found; ++ } else if (__collate_info->large_pri_count > 0) { ++ struct __collate_st_large_char_pri *match; ++ match = largesearch(*buf, loc); ++ if (match && equiv_class == match->pri.pri[0]) ++ goto found; ++ } ++ /* no match */ ++ if (ps) ++ *ps = save; ++ return 0; ++found: ++ /* if we converted more than we used, restore to initial and reconvert ++ * up to what did match */ ++ if (i < len) { ++ len = i; ++ if (ps) ++ *ps = save; ++ if (start) ++ i--; ++ clen = 0; ++ while(i-- > 0) { ++ l = mbrtowc_l(&w, src, slen, ps, loc); ++ src += l; ++ clen += l; ++ slen -= l; ++ } ++ } ++ if (dst) { ++ if (dlen < len) { ++ if (ps) ++ *ps = save; ++ return (size_t)-1; ++ } ++ for(wp = buf; len > 0; len--) ++ *dst++ = *wp++; ++ } ++ if (rlen) ++ *rlen = clen; ++ return len; ++} ++ ++#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN ++static void ++wntohl(wchar_t *str, int len) ++{ ++ for(; *str && len > 0; str++, len--) ++ *str = ntohl(*str); ++} ++#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ ++ + #ifdef COLLATE_DEBUG ++static char * ++show(int c) ++{ ++ static char buf[5]; ++ ++ if (c >=32 && c <= 126) ++ sprintf(buf, "'%c' ", c); ++ else ++ sprintf(buf, "\\x{%02x}", c); ++ return buf; ++} ++ ++static char * ++showwcs(const wchar_t *t, int len) ++{ ++ static char buf[64]; ++ char *cp = buf; ++ ++ for(; *t && len > 0; len--, t++) { ++ if (*t >=32 && *t <= 126) ++ *cp++ = *t; ++ else { ++ sprintf(cp, "\\x{%02x}", *t); ++ cp += strlen(cp); ++ } ++ } ++ *cp = 0; ++ return buf; ++} ++ + void + __collate_print_tables() + { +- int i; +- struct __collate_st_chain_pri *p2; ++ int i, z; + locale_t loc = __current_locale(); - printf("Substitute table:\n"); - for (i = 0; i < UCHAR_MAX + 1; i++) -@@ -281,7 +296,7 @@ - printf("\t'%c' --> \"%s\"\n", i, - __collate_substitute_table[i]); - printf("Chain priority table:\n"); +- printf("Substitute table:\n"); +- for (i = 0; i < UCHAR_MAX + 1; i++) +- if (i != *__collate_substitute_table[i]) +- printf("\t'%c' --> \"%s\"\n", i, +- __collate_substitute_table[i]); +- printf("Chain priority table:\n"); - for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) -+ for (p2 = loc->__lc_collate->__chain_pri_table; p2->str[0] != '\0'; p2++) - printf("\t\"%s\" : %d %d\n", p2->str, p2->prim, p2->sec); +- printf("\t\"%s\" : %d %d\n", p2->str, p2->prim, p2->sec); ++ printf("Info: p=%d s=%d f=0x%02x m=%d dc=%d up=%d us=%d pc=%d sc=%d cc=%d lc=%d\n", ++ __collate_info->directive[0], __collate_info->directive[1], ++ __collate_info->flags, __collate_info->chain_max_len, ++ __collate_info->directive_count, ++ __collate_info->undef_pri[0], __collate_info->undef_pri[1], ++ __collate_info->subst_count[0], __collate_info->subst_count[1], ++ __collate_info->chain_count, __collate_info->large_pri_count); ++ for(z = 0; z < __collate_info->directive_count; z++) { ++ if (__collate_info->subst_count[z] > 0) { ++ struct __collate_st_subst *p2 = __collate_substitute_table[z]; ++ if (z == 0 && (__collate_info->flags & COLLATE_SUBST_DUP)) ++ printf("Both substitute tables:\n"); ++ else ++ printf("Substitute table %d:\n", z); ++ for (i = __collate_info->subst_count[z]; i-- > 0; p2++) ++ printf("\t%s --> \"%s\"\n", ++ show(p2->val), ++ showwcs(p2->str, STR_LEN)); ++ } ++ } ++ if (__collate_info->chain_count > 0) { ++ printf("Chain priority table:\n"); ++ struct __collate_st_chain_pri *p2 = __collate_chain_pri_table; ++ for (i = __collate_info->chain_count; i-- > 0; p2++) { ++ printf("\t\"%s\" :", showwcs(p2->str, STR_LEN)); ++ for(z = 0; z < __collate_info->directive_count; z++) ++ printf(" %d", p2->pri[z]); ++ putchar('\n'); ++ } ++ } printf("Char priority table:\n"); - for (i = 0; i < UCHAR_MAX + 1; i++) +- for (i = 0; i < UCHAR_MAX + 1; i++) +- printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, +- __collate_char_pri_table[i].sec); ++ { ++ struct __collate_st_char_pri *p2 = __collate_char_pri_table; ++ for (i = 0; i < UCHAR_MAX + 1; i++, p2++) { ++ printf("\t%s :", show(i)); ++ for(z = 0; z < __collate_info->directive_count; z++) ++ printf(" %d", p2->pri[z]); ++ putchar('\n'); ++ } ++ } ++ if (__collate_info->large_pri_count > 0) { ++ struct __collate_st_large_char_pri *p2 = __collate_large_char_pri_table; ++ printf("Large priority table:\n"); ++ for (i = __collate_info->large_pri_count; i-- > 0; p2++) { ++ printf("\t%s :", show(p2->val)); ++ for(z = 0; z < __collate_info->directive_count; z++) ++ printf(" %d", p2->pri.pri[z]); ++ putchar('\n'); ++ } ++ } + } + #endif diff --git a/locale/FreeBSD/collate.h.patch b/locale/FreeBSD/collate.h.patch index f68f99c..cbdb83f 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-02-19 14:36:36.000000000 -0800 -@@ -31,7 +31,9 @@ ++++ collate.h 2005-10-20 00:05:25.000000000 -0700 +@@ -31,36 +31,88 @@ #define _COLLATE_H_ #include @@ -10,24 +10,69 @@ #include #define STR_LEN 10 -@@ -43,24 +45,32 @@ - int prim, sec; + #define TABLE_SIZE 100 + #define COLLATE_VERSION "1.0\n" + #define COLLATE_VERSION1_1 "1.1\n" ++#define COLLATE_VERSION1_1A "1.1A\n" ++/* see discussion in string/FreeBSD/strxfrm for this value */ ++#define COLLATE_MAX_PRIORITY ((1 << 24) - 1) ++ ++#define DIRECTIVE_UNDEF 0x00 ++#define DIRECTIVE_FORWARD 0x01 ++#define DIRECTIVE_BACKWARD 0x02 ++#define DIRECTIVE_POSITION 0x04 ++ ++#define DIRECTIVE_DIRECTION_MASK (DIRECTIVE_FORWARD | DIRECTIVE_BACKWARD) ++ ++#define COLLATE_SUBST_DUP 0x0001 ++ ++#define IGNORE_EQUIV_CLASS 1 ++ ++struct __collate_st_info { ++ __uint8_t directive[COLL_WEIGHTS_MAX]; ++ __uint8_t flags; ++#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN ++ __uint8_t directive_count:4; ++ __uint8_t chain_max_len:4; ++#else ++ __uint8_t chain_max_len:4; ++ __uint8_t directive_count:4; ++#endif ++ __int32_t undef_pri[COLL_WEIGHTS_MAX]; ++ __int32_t subst_count[COLL_WEIGHTS_MAX]; ++ __int32_t chain_count; ++ __int32_t large_pri_count; ++}; + + struct __collate_st_char_pri { +- int prim, sec; ++ __int32_t pri[COLL_WEIGHTS_MAX]; }; struct __collate_st_chain_pri { - u_char str[STR_LEN]; -+ unsigned char str[STR_LEN]; - int prim, sec; +- int prim, sec; ++ __darwin_wchar_t str[STR_LEN]; ++ __int32_t pri[COLL_WEIGHTS_MAX]; ++}; ++struct __collate_st_large_char_pri { ++ __int32_t val; ++ struct __collate_st_char_pri pri; ++}; ++struct __collate_st_subst { ++ __int32_t val; ++ __darwin_wchar_t str[STR_LEN]; }; +#ifndef __LIBC__ extern int __collate_load_error; extern int __collate_substitute_nontrivial; - #define __collate_substitute_table (*__collate_substitute_table_ptr) +-#define __collate_substitute_table (*__collate_substitute_table_ptr) -extern u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; -+extern unsigned char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; #define __collate_char_pri_table (*__collate_char_pri_table_ptr) extern struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; extern struct __collate_st_chain_pri *__collate_chain_pri_table; ++extern __int32_t *__collate_chain_equiv_table; ++extern struct __collate_st_info __collate_info; +#endif /* !__LIBC__ */ __BEGIN_DECLS @@ -35,16 +80,21 @@ -u_char *__collate_substitute(const u_char *); -int __collate_load_tables(const char *); -void __collate_lookup(const u_char *, int *, int *, int *); -+unsigned char *__collate_strdup(unsigned char *); +-int __collate_range_cmp(int, int); +#ifdef __LIBC__ -+unsigned char *__collate_substitute_l(const unsigned char *, locale_t); ++__darwin_wchar_t *__collate_mbstowcs(const char *, locale_t); ++__darwin_wchar_t *__collate_wcsdup(const __darwin_wchar_t *); ++__darwin_wchar_t *__collate_substitute(const __darwin_wchar_t *, int, locale_t); +int __collate_load_tables(const char *, locale_t); -+void __collate_lookup_l(const unsigned char *, int *, int *, int *, locale_t); -+int __collate_range_cmp(int, int, locale_t); ++void __collate_lookup_l(const __darwin_wchar_t *, int *, int *, int *, locale_t); ++void __collate_lookup_which(const __darwin_wchar_t *, int *, int *, int, locale_t); ++void __collate_xfrm(const __darwin_wchar_t *, __darwin_wchar_t **, locale_t); ++int __collate_range_cmp(__darwin_wchar_t, __darwin_wchar_t, locale_t); ++size_t __collate_collating_symbol(__darwin_wchar_t *, size_t, const char *, size_t, __darwin_mbstate_t *, locale_t); ++int __collate_equiv_class(const char *, size_t, __darwin_mbstate_t *, locale_t); ++size_t __collate_equiv_match(int, __darwin_wchar_t *, size_t, __darwin_wchar_t, const char *, size_t, __darwin_mbstate_t *, size_t *, locale_t); +#else /* !__LIBC__ */ -+unsigned char *__collate_substitute(const unsigned char *); +void __collate_lookup(const unsigned char *, int *, int *, int *); - int __collate_range_cmp(int, int); +#endif /* __LIBC__ */ #ifdef COLLATE_DEBUG void __collate_print_tables(void); diff --git a/locale/FreeBSD/collcmp.c.patch b/locale/FreeBSD/collcmp.c.patch index 9ac497a..a39ad68 100644 --- a/locale/FreeBSD/collcmp.c.patch +++ b/locale/FreeBSD/collcmp.c.patch @@ -1,26 +1,30 @@ --- collcmp.c.orig 2004-11-25 11:38:16.000000000 -0800 -+++ collcmp.c 2005-02-17 10:18:01.000000000 -0800 -@@ -27,6 +27,7 @@ ++++ collcmp.c 2005-03-30 08:36:37.000000000 -0800 +@@ -27,19 +27,22 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.17 2003/08/03 19:28:23 ache Exp $"); +-#include +#include - #include ++#include #include "collate.h" -@@ -34,12 +35,13 @@ + /* * Compare two characters using collate */ -int __collate_range_cmp(c1, c2) -+int __collate_range_cmp(c1, c2, loc) - int c1, c2; +- int c1, c2; ++__private_extern__ int ++__collate_range_cmp(c1, c2, loc) ++ wchar_t c1, c2; + locale_t loc; { - static char s1[2], s2[2]; +- static char s1[2], s2[2]; ++ static wchar_t s1[2], s2[2]; s1[0] = c1; s2[0] = c2; - return (strcoll(s1, s2)); -+ return (strcoll_l(s1, s2, loc)); ++ return (wcscoll_l(s1, s2, loc)); } diff --git a/locale/FreeBSD/digittoint.3.patch b/locale/FreeBSD/digittoint.3.patch index 0339ecb..5ba211e 100644 --- a/locale/FreeBSD/digittoint.3.patch +++ b/locale/FreeBSD/digittoint.3.patch @@ -1,6 +1,6 @@ ---- digittoint.3.orig Fri Mar 11 19:44:47 2005 -+++ digittoint.3 Fri Mar 11 19:45:48 2005 -@@ -36,7 +36,8 @@ +--- 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 @@ .Dt DIGITTOINT 3 .Os .Sh NAME @@ -10,13 +10,20 @@ .Nd convert a numeric character to its integer value .Sh LIBRARY .Lb libc -@@ -44,12 +45,23 @@ + .Sh SYNOPSIS .In ctype.h .Ft int - .Fn digittoint "int c" +-.Fn digittoint "int c" ++.Fo digittoint ++.Fa "int c" ++.Fc +.In xlocale.h ++.In ctype.h +.Ft int -+.Fn digittoint_l "int c" "locale_t loc" ++.Fo digittoint_l ++.Fa "int c" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn digittoint @@ -34,7 +41,7 @@ .Sh RETURN VALUES The .Fn digittoint -@@ -60,4 +72,5 @@ +@@ -60,4 +78,5 @@ .Sh SEE ALSO .Xr ctype 3 , .Xr isdigit 3 , diff --git a/locale/FreeBSD/fix_grouping.c.patch b/locale/FreeBSD/fix_grouping.c.patch new file mode 100644 index 0000000..96e6e3e --- /dev/null +++ b/locale/FreeBSD/fix_grouping.c.patch @@ -0,0 +1,27 @@ +--- 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 @@ + #include + #include + +-static const char nogrouping[] = { CHAR_MAX, '\0' }; ++static const char nogrouping[] = { '\0' }; ++static const char __nogrouping[] = { CHAR_MAX, '\0' }; + + /* + * Internal helper used to convert grouping sequences from string +@@ -84,3 +85,14 @@ + *dst = '\0'; + return str; + } ++ ++/* ++ * internal helpers for SUSv3 compatibility. Since "nogrouping" needs to ++ * be just an empty string, we provide a routine to substitute __nogrouping ++ * so we don't have to modify code that expects CHAR_MAX. ++ */ ++__private_extern__ const char * ++__fix_nogrouping(const char *str) ++{ ++ return ((str == NULL || *str == '\0') ? __nogrouping : str); ++} diff --git a/locale/FreeBSD/isalnum.3.patch b/locale/FreeBSD/isalnum.3.patch index 6a1fda7..2a53f70 100644 --- a/locale/FreeBSD/isalnum.3.patch +++ b/locale/FreeBSD/isalnum.3.patch @@ -1,12 +1,27 @@ ---- isalnum.3.orig Fri Mar 11 19:25:22 2005 -+++ isalnum.3 Fri Mar 11 19:25:38 2005 -@@ -104,7 +104,8 @@ +--- 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 + .Dv EOF . + 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 @@ + function should be used instead. + .Sh SEE ALSO + .Xr ctype 3 , ++.Xr isalnum_l 3 , + .Xr isalpha 3 , .Xr isdigit 3 , .Xr iswalnum 3 , - .Xr multibyte 3 , --.Xr ascii 7 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn isalnum diff --git a/locale/FreeBSD/isalpha.3.patch b/locale/FreeBSD/isalpha.3.patch index 43f84ef..ccdc0d8 100644 --- a/locale/FreeBSD/isalpha.3.patch +++ b/locale/FreeBSD/isalpha.3.patch @@ -1,12 +1,27 @@ ---- isalpha.3.orig Fri Mar 11 19:25:22 2005 -+++ isalpha.3 Fri Mar 11 19:27:14 2005 -@@ -102,7 +102,8 @@ +--- 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 + .Dv EOF . + 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 @@ + function should be used instead. + .Sh SEE ALSO + .Xr ctype 3 , ++.Xr isalnum_l 3 , + .Xr islower 3 , .Xr isupper 3 , .Xr iswalpha 3 , - .Xr multibyte 3 , --.Xr ascii 7 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn isalpha diff --git a/locale/FreeBSD/isblank.3.patch b/locale/FreeBSD/isblank.3.patch index 893e3ec..7d5bc4d 100644 --- a/locale/FreeBSD/isblank.3.patch +++ b/locale/FreeBSD/isblank.3.patch @@ -1,12 +1,27 @@ ---- isblank.3.orig Fri Mar 11 19:25:22 2005 -+++ isblank.3 Fri Mar 11 19:27:12 2005 -@@ -85,7 +85,8 @@ +--- 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. + .Sh SEE ALSO .Xr ctype 3 , ++.Xr isalnum_l 3 , .Xr iswblank 3 , .Xr multibyte 3 , --.Xr ascii 7 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn isblank + .Xr ascii 7 diff --git a/locale/FreeBSD/iscntrl.3.patch b/locale/FreeBSD/iscntrl.3.patch index f61e759..06d84fd 100644 --- a/locale/FreeBSD/iscntrl.3.patch +++ b/locale/FreeBSD/iscntrl.3.patch @@ -1,12 +1,27 @@ ---- iscntrl.3.orig Fri Mar 11 19:25:22 2005 -+++ iscntrl.3 Fri Mar 11 19:27:09 2005 -@@ -92,7 +92,8 @@ +--- 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 + .Dv EOF . + 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 @@ + function should be used instead. + .Sh SEE ALSO .Xr ctype 3 , ++.Xr isalnum_l 3 , .Xr iswcntrl 3 , .Xr multibyte 3 , --.Xr ascii 7 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn iscntrl + .Xr ascii 7 diff --git a/locale/FreeBSD/isdigit.3.patch b/locale/FreeBSD/isdigit.3.patch index bf5c2b3..3545a7c 100644 --- a/locale/FreeBSD/isdigit.3.patch +++ b/locale/FreeBSD/isdigit.3.patch @@ -1,12 +1,28 @@ ---- isdigit.3.orig Fri Mar 11 19:25:22 2005 -+++ isdigit.3 Fri Mar 11 19:27:06 2005 -@@ -98,7 +98,8 @@ +--- 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 @@ + function should be used instead. + .Sh SEE ALSO .Xr ctype 3 , ++.Xr isalnum_l 3 , .Xr iswdigit 3 , .Xr multibyte 3 , --.Xr ascii 7 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn isdigit + .Xr ascii 7 diff --git a/locale/FreeBSD/isgraph.3.patch b/locale/FreeBSD/isgraph.3.patch index 70a78dc..1acc762 100644 --- a/locale/FreeBSD/isgraph.3.patch +++ b/locale/FreeBSD/isgraph.3.patch @@ -1,12 +1,32 @@ ---- isgraph.3.orig Fri Mar 11 19:25:22 2005 -+++ isgraph.3 Fri Mar 11 19:27:03 2005 -@@ -107,7 +107,8 @@ +--- 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 + .Dv EOF . + 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 @@ + function should be used instead. + .Sh SEE ALSO .Xr ctype 3 , ++.Xr isalnum_l 3 , .Xr iswgraph 3 , .Xr multibyte 3 , --.Xr ascii 7 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn isgraph + .Xr ascii 7 diff --git a/locale/FreeBSD/islower.3.patch b/locale/FreeBSD/islower.3.patch index 26b4116..4198265 100644 --- a/locale/FreeBSD/islower.3.patch +++ b/locale/FreeBSD/islower.3.patch @@ -1,12 +1,10 @@ ---- islower.3.orig Fri Mar 11 19:25:22 2005 -+++ islower.3 Fri Mar 11 19:26:51 2005 -@@ -92,7 +92,8 @@ +--- 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 @@ + 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 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn islower diff --git a/locale/FreeBSD/isprint.3.patch b/locale/FreeBSD/isprint.3.patch index 63eef0b..9a24905 100644 --- a/locale/FreeBSD/isprint.3.patch +++ b/locale/FreeBSD/isprint.3.patch @@ -1,12 +1,33 @@ ---- isprint.3.orig Fri Mar 11 19:25:22 2005 -+++ isprint.3 Fri Mar 11 19:26:43 2005 -@@ -105,7 +105,8 @@ +--- 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 + .Dv EOF . + 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 @@ + function should be used instead. + .Sh SEE ALSO .Xr ctype 3 , ++.Xr isalnum_l 3 , .Xr iswprint 3 , .Xr multibyte 3 , --.Xr ascii 7 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn isprint + .Xr ascii 7 diff --git a/locale/FreeBSD/ispunct.3.patch b/locale/FreeBSD/ispunct.3.patch index 0dc51ba..95393d0 100644 --- a/locale/FreeBSD/ispunct.3.patch +++ b/locale/FreeBSD/ispunct.3.patch @@ -1,12 +1,36 @@ ---- ispunct.3.orig Fri Mar 11 19:25:22 2005 -+++ ispunct.3 Fri Mar 11 19:26:38 2005 -@@ -97,7 +97,8 @@ +--- 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 @@ + .Sh DESCRIPTION + The + .Fn ispunct +-function tests for any printing character except for space ++function tests for any printing character, except for space + .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 + .Dv EOF . + 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 @@ + function should be used instead. + .Sh SEE ALSO .Xr ctype 3 , ++.Xr isalnum_l 3 , .Xr iswpunct 3 , .Xr multibyte 3 , --.Xr ascii 7 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn ispunct + .Xr ascii 7 diff --git a/locale/FreeBSD/isspace.3.patch b/locale/FreeBSD/isspace.3.patch index 6924029..ede5cfb 100644 --- a/locale/FreeBSD/isspace.3.patch +++ b/locale/FreeBSD/isspace.3.patch @@ -1,12 +1,27 @@ ---- isspace.3.orig Fri Mar 11 19:25:22 2005 -+++ isspace.3 Fri Mar 11 19:26:20 2005 -@@ -89,7 +89,8 @@ +--- 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 @@ + .It "\&``\et''\t``\en''\t``\ev''\t``\ef''\t``\er''\t`` ''" + .El + .Pp +-In the "C" locale ++In the "C" locale, + .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 @@ + function should be used instead. + .Sh SEE ALSO .Xr ctype 3 , ++.Xr isalnum_l 3 , .Xr iswspace 3 , .Xr multibyte 3 , --.Xr ascii 7 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn isspace + .Xr ascii 7 diff --git a/locale/FreeBSD/isupper.3.patch b/locale/FreeBSD/isupper.3.patch index d06f007..6c8b17c 100644 --- a/locale/FreeBSD/isupper.3.patch +++ b/locale/FreeBSD/isupper.3.patch @@ -1,12 +1,27 @@ ---- isupper.3.orig Fri Mar 11 19:25:22 2005 -+++ isupper.3 Fri Mar 11 19:26:13 2005 -@@ -92,7 +92,8 @@ +--- 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 + .Dv EOF . + 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 @@ + 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 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn isupper diff --git a/locale/FreeBSD/iswalnum.3.patch b/locale/FreeBSD/iswalnum.3.patch index 6279042..8740bbe 100644 --- a/locale/FreeBSD/iswalnum.3.patch +++ b/locale/FreeBSD/iswalnum.3.patch @@ -1,7 +1,11 @@ ---- iswalnum.3.orig Fri Mar 11 19:18:47 2005 -+++ iswalnum.3 Fri Mar 11 19:20:06 2005 -@@ -114,6 +114,12 @@ - functions (like +--- 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 @@ + or + .Vt wint_t ) . + See the description for the similarly-named single byte classification +-functions (like ++functions (such as .Xr isalnum 3 ) , for details. +.Pp @@ -13,13 +17,20 @@ .Sh RETURN VALUES The functions return zero if the character tests false and return non-zero if the character tests true. -@@ -137,7 +143,8 @@ +@@ -136,6 +142,7 @@ + .Xr isspace 3 , .Xr isspecial 3 , .Xr isupper 3 , ++.Xr iswalnum_l 3 , .Xr isxdigit 3 , --.Xr wctype 3 -+.Xr wctype 3 , -+.Xr iswalnum_l 3 + .Xr wctype 3 .Sh STANDARDS - These functions conform to - .St -p1003.1-2001 , +@@ -147,7 +154,7 @@ + .Fn iswideogram , + .Fn iswnumber , + .Fn iswphonogram , +-.Fn iswrune ++.Fn iswrune , + and + .Fn iswspecial , + which are diff --git a/locale/FreeBSD/isxdigit.3.patch b/locale/FreeBSD/isxdigit.3.patch index 04efa32..f1cc5cb 100644 --- a/locale/FreeBSD/isxdigit.3.patch +++ b/locale/FreeBSD/isxdigit.3.patch @@ -1,12 +1,19 @@ ---- isxdigit.3.orig Fri Mar 11 19:25:22 2005 -+++ isxdigit.3 Fri Mar 11 19:26:08 2005 -@@ -99,7 +99,8 @@ +--- 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 @@ + function should be used instead. + .Sh SEE ALSO .Xr ctype 3 , ++.Xr isalnum_l 3 , .Xr iswxdigit 3 , .Xr multibyte 3 , --.Xr ascii 7 -+.Xr ascii 7 , -+.Xr isalnum_l - .Sh STANDARDS - The - .Fn isxdigit + .Xr ascii 7 diff --git a/locale/FreeBSD/lmonetary.c.patch b/locale/FreeBSD/lmonetary.c.patch index 280741c..9f3b3b3 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:01:33.000000000 -0800 ++++ lmonetary.c 2005-03-16 23:05:30.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,6 +18,15 @@ extern const char * __fix_locale_grouping_str(const char *); #define LCMONETARY_SIZE_FULL (sizeof(struct lc_monetary_T) / sizeof(char *)) +@@ -50,7 +52,7 @@ + empty, /* currency_symbol */ + empty, /* mon_decimal_point */ + empty, /* mon_thousands_sep */ +- numempty, /* mon_grouping */ ++ empty, /* mon_grouping [C99 7.11.2.1]*/ + empty, /* positive_sign */ + empty, /* negative_sign */ + numempty, /* int_frac_digits */ @@ -69,10 +71,6 @@ numempty /* int_n_sign_posn */ }; diff --git a/locale/FreeBSD/lnumeric.c.patch b/locale/FreeBSD/lnumeric.c.patch index 0298289..70f5ccf 100644 --- a/locale/FreeBSD/lnumeric.c.patch +++ b/locale/FreeBSD/lnumeric.c.patch @@ -1,6 +1,6 @@ --- lnumeric.c.orig 2004-11-25 11:38:17.000000000 -0800 -+++ lnumeric.c 2005-03-16 23:02:09.000000000 -0800 -@@ -27,12 +27,14 @@ ++++ lnumeric.c 2005-03-16 23:06:13.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 $"); @@ -16,8 +16,14 @@ extern const char *__fix_locale_grouping_str(const char *); #define LCNUMERIC_SIZE (sizeof(struct lc_numeric_T) / sizeof(char *)) -@@ -45,49 +47,85 @@ - numempty /* grouping */ + +-static char numempty[] = { CHAR_MAX, '\0' }; +- + static const struct lc_numeric_T _C_numeric_locale = { + ".", /* decimal_point */ + "", /* thousands_sep */ +- numempty /* grouping */ ++ "" /* grouping [C99 7.11.2.1]*/ }; -static struct lc_numeric_T _numeric_locale; diff --git a/locale/FreeBSD/localeconv.3.patch b/locale/FreeBSD/localeconv.3.patch index 960a419..0e0a41b 100644 --- a/locale/FreeBSD/localeconv.3.patch +++ b/locale/FreeBSD/localeconv.3.patch @@ -1,6 +1,6 @@ ---- localeconv.3.orig Fri Mar 11 19:44:47 2005 -+++ localeconv.3 Fri Mar 11 19:57:53 2005 -@@ -40,7 +40,8 @@ +--- _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 @@ .Dt LOCALECONV 3 .Os .Sh NAME @@ -10,17 +10,22 @@ .Nd natural language formatting for C .Sh LIBRARY .Lb libc -@@ -48,6 +49,9 @@ + .Sh SYNOPSIS .In locale.h .Ft struct lconv * - .Fn localeconv "void" +-.Fn localeconv "void" ++.Fo localeconv ++.Fa "void" ++.Fc +.In xlocale.h +.Ft struct lconv * -+.Fn localeconv_l "void" "locale_t loc" ++.Fo localeconv_l ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn localeconv -@@ -201,6 +205,14 @@ +@@ -201,6 +209,14 @@ A .Dv CHAR_MAX result similarly denotes an unavailable value. @@ -35,7 +40,7 @@ .Sh RETURN VALUES The .Fn localeconv -@@ -213,7 +225,8 @@ +@@ -213,7 +229,8 @@ No errors are defined. .Sh SEE ALSO .Xr setlocale 3 , diff --git a/locale/FreeBSD/mblen.3.patch b/locale/FreeBSD/mblen.3.patch index 7e97ef4..89464dd 100644 --- a/locale/FreeBSD/mblen.3.patch +++ b/locale/FreeBSD/mblen.3.patch @@ -1,6 +1,6 @@ ---- mblen.3.orig Fri Mar 11 19:44:47 2005 -+++ mblen.3 Fri Mar 11 19:57:09 2005 -@@ -41,7 +41,8 @@ +--- _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 @@ .Dt MBLEN 3 .Os .Sh NAME @@ -10,22 +10,46 @@ .Nd get number of bytes in a character .Sh LIBRARY .Lb libc -@@ -49,6 +50,9 @@ + .Sh SYNOPSIS .In stdlib.h .Ft int - .Fn mblen "const char *mbchar" "size_t nbytes" +-.Fn mblen "const char *mbchar" "size_t nbytes" ++.Fo mblen ++.Fa "const char *s" ++.Fa "size_t n" ++.Fc ++.In stdlib.h +.In xlocale.h +.Ft int -+.Fn mblen_l "const char *mbchar" "size_t nbytes" "locale_t loc" ++.Fo mblen_l ++.Fa "const char *s" ++.Fa "size_t n" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn mblen -@@ -65,6 +69,14 @@ +-function computes the length in bytes ++function computes the length, in bytes, + of a multibyte character +-.Fa mbchar ++.Fa s , + according to the current conversion state. + Up to +-.Fa nbytes ++.Fa n + bytes are examined. + .Pp + A call with a null +-.Fa mbchar ++.Fa s pointer returns nonzero if the current locale requires shift states, - zero otherwise; - if shift states are required, the shift state is reset to the initial state. +-zero otherwise; +-if shift states are required, the shift state is reset to the initial state. ++zero otherwise. ++If shift states are required, the shift state is reset to the initial state. +.Pp -+While the ++Although the +.Fn mblen +function uses the current locale, the +.Fn mblen_l @@ -34,8 +58,30 @@ +for more information. .Sh RETURN VALUES If - .Fa mbchar -@@ -102,7 +114,8 @@ +-.Fa mbchar ++.Fa s + is + .Dv NULL , + the +@@ -76,14 +96,14 @@ + zero otherwise. + .Pp + Otherwise, if +-.Fa mbchar ++.Fa s + is not a null pointer, + .Fn mblen + either returns 0 if +-.Fa mbchar ++.Fa s + represents the null wide character, or returns + the number of bytes processed in +-.Fa mbchar , ++.Fa s , + or returns \-1 if no multibyte character + could be recognized or converted. + In this case, +@@ -102,7 +122,8 @@ .Sh SEE ALSO .Xr mbrlen 3 , .Xr mbtowc 3 , diff --git a/locale/FreeBSD/mbrlen.3.patch b/locale/FreeBSD/mbrlen.3.patch index 478e3d2..2ff046c 100644 --- a/locale/FreeBSD/mbrlen.3.patch +++ b/locale/FreeBSD/mbrlen.3.patch @@ -1,6 +1,6 @@ ---- mbrlen.3.orig Fri Mar 11 19:44:47 2005 -+++ mbrlen.3 Fri Mar 11 19:56:39 2005 -@@ -28,7 +28,8 @@ +--- _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 +@@ -28,21 +28,35 @@ .Dt MBRLEN 3 .Os .Sh NAME @@ -10,22 +10,51 @@ .Nd "get number of bytes in a character (restartable)" .Sh LIBRARY .Lb libc -@@ -36,6 +37,9 @@ + .Sh SYNOPSIS .In wchar.h .Ft size_t - .Fn mbrlen "const char * restrict s" "size_t n" "mbstate_t * restrict ps" +-.Fn mbrlen "const char * restrict s" "size_t n" "mbstate_t * restrict ps" ++.Fo mbrlen ++.Fa "const char *restrict s" ++.Fa "size_t n" ++.Fa "mbstate_t *restrict ps" ++.Fc ++.In wchar.h +.In xlocale.h +.Ft size_t -+.Fn mbrlen_l "const char * restrict s" "size_t n" "mbstate_t * restrict ps" "locale_t loc" ++.Fo mbrlen_l ++.Fa "const char *restrict s" ++.Fa "size_t n" ++.Fa "mbstate_t *restrict ps" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn mbrlen -@@ -72,6 +76,14 @@ + function inspects at most + .Fa n +-bytes pointed to by +-.Fa s ++bytes, pointed to by ++.Fa s , + to determine the number of bytes needed to complete the next + multibyte character. + .Pp +@@ -63,7 +77,7 @@ + .Pp + .Dl "mbrtowc(NULL, s, n, ps);" + .Pp +-Except that when ++Except that, when + .Fa ps + is a + .Dv NULL +@@ -72,6 +86,14 @@ uses its own static, internal .Vt mbstate_t object to keep track of the shift state. +.Pp -+While the ++Although the +.Fn mbrlen +function uses the current locale, the +.Fn mbrlen_l @@ -35,7 +64,7 @@ .Sh RETURN VALUES The .Fn mbrlen -@@ -137,7 +149,8 @@ +@@ -137,7 +159,8 @@ .Sh SEE ALSO .Xr mblen 3 , .Xr mbrtowc 3 , diff --git a/locale/FreeBSD/mbrtowc.3.patch b/locale/FreeBSD/mbrtowc.3.patch index c21e944..9c95d87 100644 --- a/locale/FreeBSD/mbrtowc.3.patch +++ b/locale/FreeBSD/mbrtowc.3.patch @@ -1,5 +1,5 @@ ---- mbrtowc.3.orig Fri Mar 11 19:44:47 2005 -+++ mbrtowc.3 Fri Mar 11 19:55:59 2005 +--- _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 @@ -28,7 +28,8 @@ .Dt MBRTOWC 3 .Os @@ -10,20 +10,59 @@ .Nd "convert a character to a wide-character code (restartable)" .Sh LIBRARY .Lb libc -@@ -39,6 +40,12 @@ - .Fa "wchar_t * restrict pwc" "const char * restrict s" "size_t n" - .Fa "mbstate_t * restrict ps" - .Fc +@@ -36,16 +37,28 @@ + .In wchar.h + .Ft size_t + .Fo mbrtowc +-.Fa "wchar_t * restrict pwc" "const char * restrict s" "size_t n" +-.Fa "mbstate_t * restrict ps" ++.Fa "wchar_t *restrict pwc" ++.Fa "const char *restrict s" ++.Fa "size_t n" ++.Fa "mbstate_t *restrict ps" ++.Fc ++.In wchar.h +.In xlocale.h +.Ft size_t +.Fo mbrtowc_l -+.Fa "wchar_t * restrict pwc" "const char * restrict s" "size_t n" -+.Fa "mbstate_t * restrict ps" "locale_t loc" -+.Fc ++.Fa "wchar_t *restrict pwc" ++.Fa "const char *restrict s" ++.Fa "size_t n" ++.Fa "mbstate_t *restrict ps" ++.Fa "locale_t loc" + .Fc .Sh DESCRIPTION The .Fn mbrtowc -@@ -86,6 +93,14 @@ + function inspects at most + .Fa n +-bytes pointed to by +-.Fa s ++bytes, pointed to by ++.Fa s , + to determine the number of bytes needed to complete the next multibyte + character. + If a character can be completed, and +@@ -65,14 +78,14 @@ + .Fn mbrtowc + behaves as if + .Fa pwc +-was ++were + .Dv NULL , + .Fa s +-was an empty string +-.Pq Qq ++were an empty string ++.Pq Qq , + and + .Fa n +-was 1. ++were 1. + .Pp + The + .Vt mbstate_t +@@ -86,6 +99,14 @@ .Vt mbstate_t object, which is initialized to the initial conversion state at program startup. @@ -38,7 +77,7 @@ .Sh RETURN VALUES The .Fn mbrtowc -@@ -131,7 +146,8 @@ +@@ -131,7 +152,8 @@ .Xr mbtowc 3 , .Xr multibyte 3 , .Xr setlocale 3 , diff --git a/locale/FreeBSD/mbsinit.3.patch b/locale/FreeBSD/mbsinit.3.patch index 6a9aac9..6ec480c 100644 --- a/locale/FreeBSD/mbsinit.3.patch +++ b/locale/FreeBSD/mbsinit.3.patch @@ -1,5 +1,5 @@ ---- mbsinit.3.orig Fri Mar 11 19:44:47 2005 -+++ mbsinit.3 Fri Mar 11 19:55:14 2005 +--- _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 @@ -28,7 +28,8 @@ .Dt MBSINIT 3 .Os @@ -10,17 +10,18 @@ .Nd "determine conversion object status" .Sh LIBRARY .Lb libc -@@ -36,6 +37,9 @@ +@@ -36,6 +37,10 @@ .In wchar.h .Ft int .Fn mbsinit "const mbstate_t *ps" ++.In wchar.h +.In xlocale.h +.Ft int +.Fn mbsinit_l "const mbstate_t *ps" "locale_t loc" .Sh DESCRIPTION The .Fn mbsinit -@@ -44,6 +48,14 @@ +@@ -44,6 +49,14 @@ object pointed to by .Fa ps describes an initial conversion state. @@ -35,7 +36,17 @@ .Sh RETURN VALUES The .Fn mbsinit -@@ -59,7 +71,8 @@ +@@ -51,15 +64,16 @@ + .Fa ps + is + .Dv NULL +-or describes an initial conversion state, +-otherwise it returns zero. ++or describes an initial conversion state; ++otherwise, it returns zero. + .Sh SEE ALSO + .Xr mbrlen 3 , + .Xr mbrtowc 3 , .Xr mbsrtowcs 3 , .Xr multibyte 3 , .Xr wcrtomb 3 , diff --git a/locale/FreeBSD/mbsrtowcs.3.patch b/locale/FreeBSD/mbsrtowcs.3.patch index 6012d72..1ad0752 100644 --- a/locale/FreeBSD/mbsrtowcs.3.patch +++ b/locale/FreeBSD/mbsrtowcs.3.patch @@ -1,35 +1,71 @@ ---- mbsrtowcs.3.orig Fri Mar 11 18:09:42 2005 -+++ mbsrtowcs.3 Fri Mar 11 18:11:17 2005 -@@ -28,7 +28,9 @@ +--- _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 +@@ -27,29 +27,55 @@ + .Dt MBSRTOWCS 3 .Os .Sh NAME ++.Nm mbsnrtowcs , ++.Nm mbsnrtowcs_l , .Nm mbsrtowcs , -.Nm mbsnrtowcs -+.Nm mbsnrtowcs , -+.Nm mbsrtowcs_l , -+.Nm mbsnrtowcs_l ++.Nm mbsrtowcs_l .Nd "convert a character string to a wide-character string (restartable)" .Sh LIBRARY .Lb libc -@@ -44,6 +46,17 @@ - .Fa "wchar_t * restrict dst" "const char ** restrict src" "size_t nms" - .Fa "size_t len" "mbstate_t * restrict ps" + .Sh SYNOPSIS + .In wchar.h + .Ft size_t ++.Fo mbsnrtowcs ++.Fa "wchar_t *restrict dst" ++.Fa "const char **restrict src" ++.Fa "size_t nms" ++.Fa "size_t len" ++.Fa "mbstate_t *restrict ps" ++.Fc ++.Ft size_t + .Fo mbsrtowcs +-.Fa "wchar_t * restrict dst" "const char ** restrict src" "size_t len" +-.Fa "mbstate_t * restrict ps" ++.Fa "wchar_t *restrict dst" ++.Fa "const char **restrict src" ++.Fa "size_t len" ++.Fa "mbstate_t *restrict ps" .Fc ++.In wchar.h +.In xlocale.h -+.Ft size_t + .Ft size_t +-.Fo mbsnrtowcs +-.Fa "wchar_t * restrict dst" "const char ** restrict src" "size_t nms" +-.Fa "size_t len" "mbstate_t * restrict ps" +.Fo mbsrtowcs_l -+.Fa "wchar_t * restrict dst" "const char ** restrict src" "size_t len" -+.Fa "mbstate_t * restrict ps" "locale_t loc" ++.Fa "wchar_t *restrict dst" ++.Fa "const char **restrict src" ++.Fa "size_t len" ++.Fa "mbstate_t *restrict ps" ++.Fa "locale_t loc" +.Fc +.Ft size_t +.Fo mbsnrtowcs_l -+.Fa "wchar_t * restrict dst" "const char ** restrict src" "size_t nms" -+.Fa "size_t len" "mbstate_t * restrict ps" "locale_t loc" -+.Fc ++.Fa "wchar_t *restrict dst" ++.Fa "const char **restrict src" ++.Fa "size_t nms" ++.Fa "size_t len" ++.Fa "mbstate_t *restrict ps" ++.Fa "locale_t loc" + .Fc .Sh DESCRIPTION The .Fn mbsrtowcs -@@ -97,6 +110,18 @@ +-function converts a sequence of multibyte characters pointed to indirectly by +-.Fa src +-into a sequence of corresponding wide characters and stores at most ++function converts a sequence of multibyte characters, pointed to indirectly by ++.Fa src , ++into a sequence of corresponding wide characters. It stores at most + .Fa len + of them in the + .Vt wchar_t +@@ -97,6 +123,18 @@ .Fa nms bytes from the buffer pointed to by .Fa src . @@ -48,7 +84,7 @@ .Sh RETURN VALUES The .Fn mbsrtowcs -@@ -123,7 +148,8 @@ +@@ -123,7 +161,8 @@ .Xr mbrtowc 3 , .Xr mbstowcs 3 , .Xr multibyte 3 , diff --git a/locale/FreeBSD/mbstowcs.3.patch b/locale/FreeBSD/mbstowcs.3.patch index a79834f..871a5a5 100644 --- a/locale/FreeBSD/mbstowcs.3.patch +++ b/locale/FreeBSD/mbstowcs.3.patch @@ -1,5 +1,5 @@ ---- mbstowcs.3.orig Fri Mar 11 19:44:47 2005 -+++ mbstowcs.3 Fri Mar 11 20:01:09 2005 +--- _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 @@ .Dt MBSTOWCS 3 .Os @@ -10,25 +10,44 @@ .Nd convert a character string to a wide-character string .Sh LIBRARY .Lb libc -@@ -52,6 +53,12 @@ - .Fa "wchar_t * restrict wcstring" "const char * restrict mbstring" - .Fa "size_t nwchars" - .Fc +@@ -49,21 +50,39 @@ + .In stdlib.h + .Ft size_t + .Fo mbstowcs +-.Fa "wchar_t * restrict wcstring" "const char * restrict mbstring" +-.Fa "size_t nwchars" ++.Fa "wchar_t *restrict pwcs" ++.Fa "const char *restrict s" ++.Fa "size_t n" ++.Fc ++.In stdlib.h +.In xlocale.h +.Ft size_t +.Fo mbstowcs_l -+.Fa "wchar_t * restrict wcstring" "const char * restrict mbstring" -+.Fa "size_t nwchars" "locale_t loc" -+.Fc ++.Fa "wchar_t *restrict pwcs" ++.Fa "const char *restrict s" ++.Fa "size_t n" ++.Fa "locale_t loc" + .Fc .Sh DESCRIPTION The .Fn mbstowcs -@@ -64,6 +71,14 @@ - .Fa nwchars + function converts a multibyte character string +-.Fa mbstring +-beginning in the initial conversion state ++.Fa s , ++beginning in the initial conversion state, + into a wide character string +-.Fa wcstring . ++.Fa pwcs . + No more than +-.Fa nwchars ++.Fa n wide characters are stored. - A terminating null wide character is appended if there is room. +-A terminating null wide character is appended if there is room. ++A terminating null wide character is appended, if there is room. +.Pp -+While the ++Although the +.Fn mbstowcs +function uses the current locale, the +.Fn mbstowcs_l @@ -38,7 +57,7 @@ .Sh RETURN VALUES The .Fn mbstowcs -@@ -83,7 +98,8 @@ +@@ -83,7 +102,8 @@ .Sh SEE ALSO .Xr mbsrtowcs 3 , .Xr mbtowc 3 , diff --git a/locale/FreeBSD/mbtowc.3.patch b/locale/FreeBSD/mbtowc.3.patch index 48538b1..6c38fdc 100644 --- a/locale/FreeBSD/mbtowc.3.patch +++ b/locale/FreeBSD/mbtowc.3.patch @@ -1,5 +1,5 @@ ---- mbtowc.3.orig Fri Mar 11 19:44:47 2005 -+++ mbtowc.3 Fri Mar 11 19:54:09 2005 +--- _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 @@ .Dt MBTOWC 3 .Os @@ -10,20 +10,45 @@ .Nd convert a character to a wide-character code .Sh LIBRARY .Lb libc -@@ -52,6 +53,12 @@ - .Fa "wchar_t * restrict wcharp" "const char * restrict mbchar" - .Fa "size_t nbytes" - .Fc +@@ -49,30 +50,48 @@ + .In stdlib.h + .Ft int + .Fo mbtowc +-.Fa "wchar_t * restrict wcharp" "const char * restrict mbchar" +-.Fa "size_t nbytes" ++.Fa "wchar_t *restrict pwc" ++.Fa "const char *restrict s" ++.Fa "size_t n" ++.Fc ++.In stdlib.h +.In xlocale.h +.Ft int +.Fo mbtowc_l -+.Fa "wchar_t * restrict wcharp" "const char * restrict mbchar" -+.Fa "size_t nbytes" "locale_t loc" -+.Fc ++.Fa "wchar_t *restrict pwc" ++.Fa "const char *restrict s" ++.Fa "size_t n" ++.Fa "locale_t loc" + .Fc .Sh DESCRIPTION The .Fn mbtowc -@@ -70,6 +77,14 @@ + function converts a multibyte character +-.Fa mbchar +-into a wide character according to the current conversion state, ++.Fa s ++into a wide character, according to the current conversion state, + and stores the result + in the object pointed to by +-.Fa wcharp . ++.Fa pwc . + Up to +-.Fa nbytes ++.Fa n + bytes are examined. + .Pp + A call with a null +-.Fa mbchar ++.Fa s pointer returns nonzero if the current encoding requires shift states, zero otherwise; if shift states are required, the shift state is reset to the initial state. @@ -37,8 +62,30 @@ +for more information. .Sh RETURN VALUES If - .Fa mbchar -@@ -110,7 +125,8 @@ +-.Fa mbchar ++.Fa s + is + .Dv NULL , + the +@@ -81,14 +100,14 @@ + zero otherwise. + .Pp + Otherwise, if +-.Fa mbchar ++.Fa s + is not a null pointer, + .Fn mbtowc + either returns 0 if +-.Fa mbchar ++.Fa s + represents the null wide character, or returns + the number of bytes processed in +-.Fa mbchar , ++.Fa s , + or returns \-1 if no multibyte character + could be recognized or converted. + In this case, +@@ -110,7 +129,8 @@ .Xr mbrtowc 3 , .Xr mbstowcs 3 , .Xr multibyte 3 , diff --git a/locale/FreeBSD/nl_langinfo.3.patch b/locale/FreeBSD/nl_langinfo.3.patch index bf7a01f..9f9e3e0 100644 --- a/locale/FreeBSD/nl_langinfo.3.patch +++ b/locale/FreeBSD/nl_langinfo.3.patch @@ -1,6 +1,6 @@ ---- nl_langinfo.3.orig Fri Mar 11 19:44:47 2005 -+++ nl_langinfo.3 Fri Mar 11 19:52:50 2005 -@@ -28,7 +28,8 @@ +--- _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 +@@ -28,14 +28,24 @@ .Dt NL_LANGINFO 3 .Os .Sh NAME @@ -10,17 +10,33 @@ .Nd language information .Sh LIBRARY .Lb libc -@@ -36,6 +37,9 @@ + .Sh SYNOPSIS .In langinfo.h .Ft char * - .Fn nl_langinfo "nl_item item" +-.Fn nl_langinfo "nl_item item" ++.Fo nl_langinfo ++.Fa "nl_item item" ++.Fc ++.In langinfo.h +.In xlocale.h +.Ft char * -+.Fn nl_langinfo_l "nl_item item" "locale_t loc" ++.Fo nl_langinfo_l ++.Fa "nl_item item" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn nl_langinfo -@@ -65,6 +69,14 @@ +@@ -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 @@ Portuguese, and .Qq Li Sun if the identified language was English. @@ -35,7 +51,7 @@ .Sh RETURN VALUES In a locale where langinfo data is not defined, .Fn nl_langinfo -@@ -77,7 +89,8 @@ +@@ -77,7 +95,8 @@ .Fa item contains an invalid setting. .Sh SEE ALSO diff --git a/locale/FreeBSD/nl_langinfo.c.patch b/locale/FreeBSD/nl_langinfo.c.patch index 2ef6c6c..20d62bd 100644 --- a/locale/FreeBSD/nl_langinfo.c.patch +++ b/locale/FreeBSD/nl_langinfo.c.patch @@ -1,5 +1,5 @@ ---- nl_langinfo.c.orig 2004-11-25 11:38:19.000000000 -0800 -+++ nl_langinfo.c 2005-02-18 22:22:41.000000000 -0800 +--- nl_langinfo.c.orig 2005-03-15 23:26:13.000000000 -0800 ++++ nl_langinfo.c 2005-03-15 23:38:20.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 $"); @@ -140,7 +140,7 @@ psn = '.'; } else psn = pos ? '-' : '+'; -@@ -166,10 +170,16 @@ +@@ -166,10 +170,19 @@ } break; case D_MD_ORDER: /* FreeBSD local extension */ @@ -148,7 +148,11 @@ + ret = (char *) __get_current_time_locale(loc)->md_order; break; default: - ret = ""; +- ret = ""; ++ return ""; /* do not consult POSIX */ ++ } ++ if (ret && !ret[0] && item != D_MD_ORDER && item != CODESET && loc != _c_locale) { ++ ret = nl_langinfo_l(item, _c_locale); } return (ret); } diff --git a/locale/FreeBSD/rune.c.patch b/locale/FreeBSD/rune.c.patch index bc7b846..7d81d4b 100644 --- a/locale/FreeBSD/rune.c.patch +++ b/locale/FreeBSD/rune.c.patch @@ -1,6 +1,6 @@ --- rune.c.orig 2004-11-25 11:38:19.000000000 -0800 -+++ rune.c 2005-02-14 19:25:48.000000000 -0800 -@@ -34,28 +34,96 @@ ++++ rune.c 2005-04-12 17:18:12.000000000 -0700 +@@ -34,28 +34,98 @@ * SUCH DAMAGE. */ @@ -26,7 +26,8 @@ #include #include "un-namespace.h" +#endif /* !RUNEOFF32 */ -+ + +-_RuneLocale * +#if defined(__LP64__) || defined(RUNEOFF32) +/* + * Because the LC_CTYPE files were created with a 32-bit program, we need @@ -41,7 +42,7 @@ +#define BYTES32BITS 4 +#define BYTES64BITS 8 +/* whether to skip over a pointer or not (one-to-one with off64) */ -+static int skip[] = { ++int skip[] = { + 1, + 1, + 0, @@ -51,10 +52,11 @@ + 0, + 1, + 1, ++ 1, + 0 +}; +#endif /* !RUNEOFF32 */ -+static int off64[] = { ++int off64[] = { + offsetof(_RuneLocale, __sgetrune), + offsetof(_RuneLocale, __sputrune), + offsetof(_RuneLocale, __runetype_ext), @@ -64,6 +66,7 @@ + offsetof(_RuneLocale, __mapupper_ext), + offsetof(_RuneLocale, __mapupper_ext) + offsetof(_RuneRange, __ranges), + offsetof(_RuneLocale, __variable), ++ offsetof(_RuneLocale, __charclasses), + sizeof(_RuneLocale) +}; +#define NOFF (sizeof(off64) / sizeof(int)) @@ -77,7 +80,7 @@ + int i; + printf("#define SIZEOF32_RUNEENTRY %d\n", sizeof(_RuneEntry)); + printf("#define SIZEOF32_RUNELOCALE %d\n", sizeof(_RuneLocale)); -+ printf("static int off32[] = {\n"); ++ printf("int off32[] = {\n"); + for(i = 0; i < NOFF; i++) + printf("\t%d,\n", off64[i]); + printf("};\n"); @@ -87,8 +90,7 @@ +#else /* !__LP64__ && !RUNEOFF32 */ +#define SIZEOF32_RUNELOCALE sizeof(_RuneLocale) +#endif /* __LP64__ || RUNEOFF32 */ - --_RuneLocale * ++ +#ifndef RUNEOFF32 +struct __xlocale_st_runelocale * _Read_RuneMagi(fp) @@ -99,7 +101,7 @@ void *lastp; _RuneLocale *rl; _RuneEntry *rr; -@@ -65,13 +133,20 @@ +@@ -65,13 +135,20 @@ if (_fstat(fileno(fp), &sb) < 0) return (NULL); @@ -122,7 +124,7 @@ errno = 0; rewind(fp); /* Someone might have read the magic number once already */ -@@ -82,17 +157,25 @@ +@@ -82,26 +159,43 @@ return (NULL); } @@ -149,9 +151,10 @@ rl->__variable = rl + 1; +#endif /* __LP64__ */ - if (memcmp(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic))) { +- if (memcmp(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic))) { ++ if (memcmp(rl->__magic, _RUNE_MAGIC_A, sizeof(rl->__magic))) { free(data); -@@ -100,6 +183,14 @@ + errno = EFTYPE; return (NULL); } @@ -165,28 +168,33 @@ +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN rl->__invalid_rune = ntohl(rl->__invalid_rune); rl->__variable_len = ntohl(rl->__variable_len); ++ rl->__ncharclasses = ntohl(rl->__ncharclasses); rl->__runetype_ext.__nranges = ntohl(rl->__runetype_ext.__nranges); -@@ -111,7 +202,43 @@ + rl->__maplower_ext.__nranges = ntohl(rl->__maplower_ext.__nranges); + rl->__mapupper_ext.__nranges = ntohl(rl->__mapupper_ext.__nranges); +@@ -111,7 +205,54 @@ rl->__maplower[x] = ntohl(rl->__maplower[x]); rl->__mapupper[x] = ntohl(rl->__mapupper[x]); } +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ -+ + +#ifdef __LP64__ + { + int count = rl->__runetype_ext.__nranges + rl->__maplower_ext.__nranges + + rl->__mapupper_ext.__nranges; -+ int extra = sb.st_size - SIZEOF32_RUNELOCALE - count * SIZEOF32_RUNEENTRY; ++ int extra = sb.st_size - SIZEOF32_RUNELOCALE - count * SIZEOF32_RUNEENTRY - rl->__ncharclasses * sizeof(_RuneCharClass); + _RuneEntry *rp; - ++ + if (extra < 0) { + saverr = errno; + free(data); + errno = saverr; + return (NULL); + } -+ if ((data = (struct __xlocale_st_runelocale *)reallocf(data, sizeof(struct __xlocale_st_runelocale) + -+ count * sizeof(_RuneEntry) + extra)) == NULL) ++ if ((data = (struct __xlocale_st_runelocale *)reallocf(data, sizeof(struct __xlocale_st_runelocale) ++ + count * sizeof(_RuneEntry) ++ + rl->__ncharclasses * sizeof(_RuneCharClass) ++ + extra)) == NULL) + return (NULL); + rl = &data->_CurrentRuneLocale; + rl->__variable = rl + 1; @@ -198,6 +206,15 @@ + errno = saverr; + return (NULL); + } ++ if (rl->__ncharclasses > 0) { ++ if (fread(rp, sizeof(_RuneCharClass), rl->__ncharclasses, fp) != rl->__ncharclasses) { ++ saverr = errno; ++ free(data); ++ errno = saverr; ++ return (NULL); ++ } ++ rp = (_RuneEntry *)((char *)rp + rl->__ncharclasses * sizeof(_RuneCharClass)); ++ } + if (extra > 0 && fread(rp, extra, 1, fp) != 1) { + saverr = errno; + free(data); @@ -210,7 +227,7 @@ rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable; rl->__variable = rl->__runetype_ext.__ranges + rl->__runetype_ext.__nranges; -@@ -142,8 +269,10 @@ +@@ -142,8 +283,10 @@ for (x = 0; x < rl->__runetype_ext.__nranges; ++x) { rr = rl->__runetype_ext.__ranges; @@ -221,7 +238,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 +282,15 @@ +@@ -153,12 +296,15 @@ errno = EFTYPE; return (NULL); } @@ -237,15 +254,30 @@ for (x = 0; x < rl->__maplower_ext.__nranges; ++x) { rr = rl->__maplower_ext.__ranges; -@@ -174,6 +306,7 @@ +@@ -174,6 +320,22 @@ rr[x].__max = ntohl(rr[x].__max); rr[x].__map = ntohl(rr[x].__map); } +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ ++ ++ if (rl->__ncharclasses > 0) { ++ rl->__charclasses = (_RuneCharClass *)rl->__variable; ++ rl->__variable = (void *)(rl->__charclasses + rl->__ncharclasses); ++ if (rl->__variable > lastp) { ++ free(data); ++ errno = EFTYPE; ++ return (NULL); ++ } ++#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN ++ for (x = 0; x < rl->__ncharclasses; ++x) ++ rl->__charclasses[x].__mask = ntohl(rl->__charclasses[x].__mask); ++#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ ++ } ++ if (((char *)rl->__variable) + rl->__variable_len > (char *)lastp) { free(data); errno = EFTYPE; -@@ -195,5 +328,7 @@ +@@ -195,5 +357,7 @@ if (!rl->__mapupper_ext.__nranges) rl->__mapupper_ext.__ranges = 0; diff --git a/locale/FreeBSD/setlocale.3.patch b/locale/FreeBSD/setlocale.3.patch new file mode 100644 index 0000000..97ed7a9 --- /dev/null +++ b/locale/FreeBSD/setlocale.3.patch @@ -0,0 +1,32 @@ +--- _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 @@ + .Sh SYNOPSIS + .In locale.h + .Ft char * +-.Fn setlocale "int category" "const char *locale" ++.Fo setlocale ++.Fa "int category" ++.Fa "const char *locale" ++.Fc + .Sh DESCRIPTION + The + .Fn setlocale +@@ -105,14 +108,14 @@ + function. + .El + .Pp +-Only three locales are defined by default, ++Only three locales are defined by default: + the empty string + .Li "\&""\|"" +-which denotes the native environment, and the ++(which denotes the native environment) and the + .Li "\&""C"" + and + .Li "\&""POSIX"" +-locales, which denote the C language environment. ++locales (which denote the C-language environment). + A + .Fa locale + argument of diff --git a/locale/FreeBSD/setlocale.c.patch b/locale/FreeBSD/setlocale.c.patch index 4d52c4a..7ac26e5 100644 --- a/locale/FreeBSD/setlocale.c.patch +++ b/locale/FreeBSD/setlocale.c.patch @@ -1,5 +1,5 @@ --- setlocale.c.orig 2004-11-25 11:38:19.000000000 -0800 -+++ setlocale.c 2005-02-17 12:42:40.000000000 -0800 ++++ setlocale.c 2005-04-27 13:37:01.000000000 -0700 @@ -41,6 +41,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.50 2004/01/31 19:15:32 ache Exp $"); @@ -18,7 +18,7 @@ /* * Category names for getenv() -@@ -99,7 +101,7 @@ +@@ -99,15 +101,16 @@ static char *currentlocale(void); static char *loadlocale(int); @@ -27,7 +27,42 @@ char * setlocale(category, locale) -@@ -237,7 +239,7 @@ + int category; + const char *locale; + { +- int i, j, len, saverr; ++ int i, j, len, saverr, save__numeric_fp_cvt; + const char *env, *r; ++ locale_t save__lc_numeric_loc; + + if (category < LC_ALL || category >= _LC_LAST) { + errno = EINVAL; +@@ -193,6 +196,9 @@ + if (category != LC_ALL) + return (loadlocale(category)); + ++ save__numeric_fp_cvt = __global_locale.__numeric_fp_cvt; ++ save__lc_numeric_loc = __global_locale.__lc_numeric_loc; ++ XL_RETAIN(save__lc_numeric_loc); + for (i = 1; i < _LC_LAST; ++i) { + (void)strcpy(saved_categories[i], current_categories[i]); + if (loadlocale(i) == NULL) { +@@ -205,10 +211,14 @@ + (void)loadlocale(j); + } + } ++ __global_locale.__numeric_fp_cvt = save__numeric_fp_cvt; ++ __global_locale.__lc_numeric_loc = save__lc_numeric_loc; ++ XL_RELEASE(save__lc_numeric_loc); + errno = saverr; + return (NULL); + } + } ++ XL_RELEASE(save__lc_numeric_loc); + return (currentlocale()); + } + +@@ -237,7 +247,7 @@ { char *new = new_categories[category]; char *old = current_categories[category]; @@ -36,16 +71,27 @@ int saved_errno; if ((new[0] == '.' && -@@ -280,7 +282,7 @@ +@@ -280,15 +290,26 @@ if (strcmp(new, old) == 0) return (old); - if (func(new) != _LDP_ERROR) { + if (func(new, &__global_locale) != _LDP_ERROR) { (void)strcpy(old, new); ++ switch (category) { ++ case LC_CTYPE: ++ if (__global_locale.__numeric_fp_cvt == LC_NUMERIC_FP_SAME_LOCALE) ++ __global_locale.__numeric_fp_cvt = LC_NUMERIC_FP_UNINITIALIZED; ++ break; ++ case LC_NUMERIC: ++ __global_locale.__numeric_fp_cvt = LC_NUMERIC_FP_UNINITIALIZED; ++ XL_RELEASE(__global_locale.__lc_numeric_loc); ++ __global_locale.__lc_numeric_loc = NULL; ++ break; ++ } return (old); } -@@ -288,7 +290,7 @@ + return (NULL); } @@ -54,7 +100,7 @@ __get_locale_env(category) int category; { -@@ -315,7 +317,7 @@ +@@ -315,7 +336,7 @@ /* * Detect locale storage location and store its value to _PathLocale variable */ diff --git a/locale/FreeBSD/setrunelocale.c.patch b/locale/FreeBSD/setrunelocale.c.patch index b4ddcdb..3638b2a 100644 --- a/locale/FreeBSD/setrunelocale.c.patch +++ b/locale/FreeBSD/setrunelocale.c.patch @@ -1,5 +1,5 @@ ---- setrunelocale.c.orig 2004-11-25 11:38:19.000000000 -0800 -+++ setrunelocale.c 2005-02-17 10:00:02.000000000 -0800 +--- setrunelocale.c.orig 2007-02-13 00:16:13.000000000 -0800 ++++ setrunelocale.c 2007-02-13 00:22:39.000000000 -0800 @@ -37,6 +37,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.44 2004/10/18 02:06:18 ache Exp $"); @@ -9,7 +9,7 @@ #include #include #include -@@ -49,50 +51,43 @@ +@@ -49,67 +51,67 @@ #include "mblocal.h" #include "setlocale.h" @@ -35,6 +35,9 @@ +extern int _UTF2_init(struct __xlocale_st_runelocale *); /* deprecated */ +extern struct __xlocale_st_runelocale *_Read_RuneMagi(FILE *); + ++extern void spin_lock(int *); ++extern void spin_unlock(int *); ++ +/* depreciated interfaces */ +rune_t sgetrune(const char *, size_t, char const **); +int sputrune(rune_t, char *, size_t, char **); @@ -64,6 +67,7 @@ - mbstate_t * __restrict); + static struct __xlocale_st_runelocale *CachedRuneLocale; + extern int __mb_cur_max; ++ static int cache_lock = 0; /* * The "C" and "POSIX" locale are always here. @@ -86,9 +90,10 @@ return (0); } -@@ -100,14 +95,14 @@ + /* * If the locale name is the same as our cache, use the cache. */ ++ spin_lock(&cache_lock); if (CachedRuneLocale != NULL && - strcmp(encoding, ctype_encoding) == 0) { - _CurrentRuneLocale = CachedRuneLocale; @@ -106,10 +111,14 @@ + _CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale; + __mb_cur_max = loc->__lc_ctype->__mb_cur_max; + } ++ spin_unlock(&cache_lock); return (0); } ++ spin_unlock(&cache_lock); -@@ -124,63 +119,72 @@ + /* + * Slurp the locale file into the cache. +@@ -124,63 +126,74 @@ if ((fp = fopen(name, "r")) == NULL) return (errno == 0 ? ENOENT : errno); @@ -189,9 +198,11 @@ - Cached__wcrtomb = __wcrtomb; - Cached__wcsnrtombs = __wcsnrtombs; - (void)strcpy(ctype_encoding, encoding); ++ spin_lock(&cache_lock); + XL_RELEASE(CachedRuneLocale); + CachedRuneLocale = xrl; + XL_RETAIN(CachedRuneLocale); ++ spin_unlock(&cache_lock); } else - free(rl); + XL_RELEASE(xrl); diff --git a/locale/FreeBSD/table.c.patch b/locale/FreeBSD/table.c.patch index b5a86bf..81a3492 100644 --- a/locale/FreeBSD/table.c.patch +++ b/locale/FreeBSD/table.c.patch @@ -1,6 +1,6 @@ --- table.c.orig 2004-11-25 11:38:19.000000000 -0800 -+++ table.c 2005-02-20 16:31:30.000000000 -0800 -@@ -40,11 +40,14 @@ ++++ table.c 2005-03-30 16:33:51.000000000 -0800 +@@ -40,13 +40,16 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/table.c,v 1.26 2004/10/17 06:51:50 tjr Exp $"); @@ -13,8 +13,11 @@ +/* _DefaultRuneLocale is depreciated; _DefaultRuneXLocale is used instead */ _RuneLocale _DefaultRuneLocale = { - _RUNE_MAGIC_1, +- _RUNE_MAGIC_1, ++ _RUNE_MAGIC_A, "NONE", + NULL, + NULL, @@ -249,15 +252,222 @@ }, }; @@ -32,7 +35,7 @@ + _none_wcsnrtombs, + sizeof(struct __xlocale_st_runelocale), + { -+ _RUNE_MAGIC_1, ++ _RUNE_MAGIC_A, + "NONE", + NULL, + NULL, diff --git a/locale/FreeBSD/tolower.3.patch b/locale/FreeBSD/tolower.3.patch index b74f7b4..1e3b08c 100644 --- a/locale/FreeBSD/tolower.3.patch +++ b/locale/FreeBSD/tolower.3.patch @@ -1,6 +1,6 @@ ---- tolower.3.orig Fri Mar 11 19:44:47 2005 -+++ tolower.3 Fri Mar 11 19:52:07 2005 -@@ -40,7 +40,8 @@ +--- _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 @@ .Dt TOLOWER 3 .Os .Sh NAME @@ -10,22 +10,36 @@ .Nd upper case to lower case letter conversion .Sh LIBRARY .Lb libc -@@ -48,6 +49,9 @@ + .Sh SYNOPSIS .In ctype.h .Ft int - .Fn tolower "int c" +-.Fn tolower "int c" ++.Fo tolower ++.Fa "int c" ++.Fc ++.In ctype.h +.In xlocale.h +.Ft int -+.Fn tolower_l "int c" "locale_t loc" ++.Fo tolower_l ++.Fa "int c" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn tolower -@@ -62,6 +66,14 @@ +@@ -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 or the value of .Dv EOF . +.Pp -+While the ++Although the +.Fn tolower +function uses the current locale, the +.Fn tolower_l @@ -35,7 +49,13 @@ .Sh RETURN VALUES If the argument is an upper-case letter, the .Fn tolower -@@ -81,7 +93,8 @@ + function returns the corresponding lower-case letter if there is +-one; otherwise the argument is returned unchanged. ++one; otherwise, the argument is returned unchanged. + .Sh COMPATIBILITY + The + .Bx 4.4 +@@ -81,7 +99,8 @@ .Xr ctype 3 , .Xr islower 3 , .Xr multibyte 3 , diff --git a/locale/FreeBSD/toupper.3.patch b/locale/FreeBSD/toupper.3.patch index 26c1d0d..d0d2531 100644 --- a/locale/FreeBSD/toupper.3.patch +++ b/locale/FreeBSD/toupper.3.patch @@ -1,6 +1,6 @@ ---- toupper.3.orig Fri Mar 11 19:44:47 2005 -+++ toupper.3 Fri Mar 11 19:51:26 2005 -@@ -40,7 +40,8 @@ +--- _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 @@ .Dt TOUPPER 3 .Os .Sh NAME @@ -10,22 +10,36 @@ .Nd lower case to upper case letter conversion .Sh LIBRARY .Lb libc -@@ -48,6 +49,9 @@ + .Sh SYNOPSIS .In ctype.h .Ft int - .Fn toupper "int c" +-.Fn toupper "int c" ++.Fo toupper ++.Fa "int c" ++.Fc ++.In ctype.h +.In xlocale.h +.Ft int -+.Fn toupper_l "int c" "locale_t loc" ++.Fo toupper_l ++.Fa "int c" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn toupper -@@ -62,6 +66,14 @@ +@@ -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 or the value of .Dv EOF . +.Pp -+While the ++Although the +.Fn toupper +function uses the current locale, the +.Fn toupper_l @@ -35,7 +49,13 @@ .Sh RETURN VALUES If the argument is a lower-case letter, the .Fn toupper -@@ -81,7 +93,8 @@ + function returns the corresponding upper-case letter if there is +-one; otherwise the argument is returned unchanged. ++one; otherwise, the argument is returned unchanged. + .Sh COMPATIBILITY + The + .Bx 4.4 +@@ -81,7 +99,8 @@ .Xr ctype 3 , .Xr isupper 3 , .Xr multibyte 3 , diff --git a/locale/FreeBSD/towlower.3.patch b/locale/FreeBSD/towlower.3.patch index 82be366..dbb16e9 100644 --- a/locale/FreeBSD/towlower.3.patch +++ b/locale/FreeBSD/towlower.3.patch @@ -1,6 +1,6 @@ ---- towlower.3.orig Fri Mar 11 19:44:47 2005 -+++ towlower.3 Fri Mar 11 19:50:47 2005 -@@ -40,7 +40,8 @@ +--- _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 @@ .Dt TOWLOWER 3 .Os .Sh NAME @@ -10,20 +10,27 @@ .Nd "upper case to lower case letter conversion (wide character version)" .Sh LIBRARY .Lb libc -@@ -48,11 +49,22 @@ + .Sh SYNOPSIS .In wctype.h .Ft wint_t - .Fn towlower "wint_t wc" +-.Fn towlower "wint_t wc" ++.Fo towlower ++.Fa "wint_t wc" ++.Fc ++.In wctype.h +.In xlocale.h +.Ft wint_t -+.Fn towlower_l "wint_t wc" "locale_t loc" ++.Fo towlower_l ++.Fa "wint_t wc" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn towlower function converts an upper-case letter to the corresponding lower-case letter. +.Pp -+While the ++Although the +.Fn towlower +function uses the current locale, the +.Fn towlower_l @@ -33,7 +40,10 @@ .Sh RETURN VALUES If the argument is an upper-case letter, the .Fn towlower -@@ -62,7 +74,8 @@ + function returns the corresponding lower-case letter if there is +-one; otherwise the argument is returned unchanged. ++one; otherwise, the argument is returned unchanged. + .Sh SEE ALSO .Xr iswlower 3 , .Xr tolower 3 , .Xr towupper 3 , diff --git a/locale/FreeBSD/towupper.3.patch b/locale/FreeBSD/towupper.3.patch index 620aae6..8882d1a 100644 --- a/locale/FreeBSD/towupper.3.patch +++ b/locale/FreeBSD/towupper.3.patch @@ -1,6 +1,6 @@ ---- towupper.3.orig Fri Mar 11 19:44:47 2005 -+++ towupper.3 Fri Mar 11 19:50:09 2005 -@@ -40,7 +40,8 @@ +--- _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 @@ .Dt TOWUPPER 3 .Os .Sh NAME @@ -10,20 +10,27 @@ .Nd "lower case to upper case letter conversion (wide character version)" .Sh LIBRARY .Lb libc -@@ -48,11 +49,22 @@ + .Sh SYNOPSIS .In wctype.h .Ft wint_t - .Fn towupper "wint_t wc" +-.Fn towupper "wint_t wc" ++.Fo towupper ++.Fa "wint_t wc" ++.Fc ++.In wctype.h +.In xlocale.h +.Ft wint_t -+.Fn towupper_l "wint_t wc" "locale_t loc" ++.Fo towupper_l ++.Fa "wint_t wc" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn towupper function converts a lower-case letter to the corresponding upper-case letter. +.Pp -+While the ++Although the +.Fn towupper +function uses the current locale, the +.Fn towupper_l @@ -33,7 +40,10 @@ .Sh RETURN VALUES If the argument is a lower-case letter, the .Fn towupper -@@ -62,7 +74,8 @@ + function returns the corresponding upper-case letter if there is +-one; otherwise the argument is returned unchanged. ++one; otherwise, the argument is returned unchanged. + .Sh SEE ALSO .Xr iswupper 3 , .Xr toupper 3 , .Xr towlower 3 , diff --git a/locale/FreeBSD/wcrtomb.3.patch b/locale/FreeBSD/wcrtomb.3.patch index 846980c..af52731 100644 --- a/locale/FreeBSD/wcrtomb.3.patch +++ b/locale/FreeBSD/wcrtomb.3.patch @@ -1,6 +1,6 @@ ---- wcrtomb.3.orig Fri Mar 11 19:44:47 2005 -+++ wcrtomb.3 Fri Mar 11 19:49:35 2005 -@@ -28,7 +28,8 @@ +--- _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 +@@ -28,14 +28,28 @@ .Dt WCRTOMB 3 .Os .Sh NAME @@ -10,17 +10,51 @@ .Nd "convert a wide-character code to a character (restartable)" .Sh LIBRARY .Lb libc -@@ -36,6 +37,9 @@ + .Sh SYNOPSIS .In wchar.h .Ft size_t - .Fn wcrtomb "char * restrict s" "wchar_t wc" "mbstate_t * restrict ps" +-.Fn wcrtomb "char * restrict s" "wchar_t wc" "mbstate_t * restrict ps" ++.Fo wcrtomb ++.Fa "char *restrict s" ++.Fa "wchar_t wc" ++.Fa "mbstate_t *restrict ps" ++.Fc ++.In wchar.h +.In xlocale.h +.Ft size_t -+.Fn wcrtomb_l "char * restrict s" "wchar_t wc" "mbstate_t * restrict ps" "locale_t loc" ++.Fo wcrtomb_l ++.Fa "char *restrict s" ++.Fa "wchar_t wc" ++.Fa "mbstate_t *restrict ps" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn wcrtomb -@@ -72,6 +76,14 @@ +@@ -44,10 +58,10 @@ + .Fa wc , + including any necessary shift sequences, to the + character array +-.Fa s , +-storing a maximum of ++.Fa s . ++A maximum of + .Dv MB_CUR_MAX +-bytes. ++bytes will be stored. + .Pp + If + .Fa s +@@ -58,7 +72,7 @@ + .Fa s + pointed to an internal buffer and + .Fa wc +-was a null wide character (L'\e0'). ++were a null wide character (L'\e0'). + .Pp + The + .Ft mbstate_t +@@ -72,6 +86,14 @@ .Vt mbstate_t object, which is initialized to the initial conversion state at program startup. @@ -35,7 +69,7 @@ .Sh RETURN VALUES The .Fn wcrtomb -@@ -97,7 +109,8 @@ +@@ -97,7 +119,8 @@ .Xr mbrtowc 3 , .Xr multibyte 3 , .Xr setlocale 3 , diff --git a/locale/FreeBSD/wcsftime.3.patch b/locale/FreeBSD/wcsftime.3.patch index 8df986c..76b959d 100644 --- a/locale/FreeBSD/wcsftime.3.patch +++ b/locale/FreeBSD/wcsftime.3.patch @@ -1,5 +1,5 @@ ---- wcsftime.3.orig Fri Mar 11 19:44:47 2005 -+++ wcsftime.3 Fri Mar 11 19:49:00 2005 +--- _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 @@ -28,7 +28,8 @@ .Dt WCSFTIME 3 .Os @@ -10,20 +10,34 @@ .Nd "convert date and time to a wide-character string" .Sh LIBRARY .Lb libc -@@ -39,6 +40,12 @@ - .Fa "wchar_t * restrict wcs" "size_t maxsize" - .Fa "const wchar_t * restrict format" "const struct tm * restrict timeptr" - .Fc +@@ -36,29 +37,50 @@ + .In wchar.h + .Ft size_t + .Fo wcsftime +-.Fa "wchar_t * restrict wcs" "size_t maxsize" +-.Fa "const wchar_t * restrict format" "const struct tm * restrict timeptr" ++.Fa "wchar_t *restrict wcs" ++.Fa "size_t maxsize" ++.Fa "const wchar_t *restrict format" ++.Fa "const struct tm *restrict timeptr" ++.Fc ++.In wchar.h +.In xlocale.h +.Ft size_t +.Fo wcsftime_l -+.Fa "wchar_t * restrict wcs" "size_t maxsize" -+.Fa "const wchar_t * restrict format" "const struct tm * restrict timeptr" "locale_t loc" -+.Fc ++.Fa "wchar_t *restrict wcs" ++.Fa "size_t maxsize" ++.Fa "const wchar_t *restrict format" ++.Fa "const struct tm *restrict timeptr" ++.Fa "locale_t loc" + .Fc .Sh DESCRIPTION The .Fn wcsftime -@@ -48,6 +55,14 @@ + function is equivalent to the + .Fn strftime +-function except for the types of its arguments. ++function, except for the types of its arguments. Refer to .Xr strftime 3 for a detailed description. @@ -38,7 +52,11 @@ .Sh COMPATIBILITY Some early implementations of .Fn wcsftime -@@ -58,7 +73,8 @@ + had a + .Fa format + argument with type +-.Vt "const char *" ++.Vt "const char *" , instead of .Vt "const wchar_t *" . .Sh SEE ALSO diff --git a/locale/FreeBSD/wcsrtombs.3.patch b/locale/FreeBSD/wcsrtombs.3.patch index 18199df..09fbb4b 100644 --- a/locale/FreeBSD/wcsrtombs.3.patch +++ b/locale/FreeBSD/wcsrtombs.3.patch @@ -1,40 +1,79 @@ ---- wcsrtombs.3.orig Fri Mar 11 18:15:27 2005 -+++ wcsrtombs.3 Fri Mar 11 18:18:11 2005 -@@ -29,7 +29,9 @@ +--- _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 +@@ -28,30 +28,57 @@ + .Dt WCSRTOMBS 3 .Os .Sh NAME ++.Nm wcsnrtombs , ++.Nm wcsnrtombs_l , .Nm wcsrtombs , -.Nm wcsnrtombs -+.Nm wcsnrtombs , -+.Nm wcsrtombs_l , -+.Nm wcsnrtombs_l ++.Nm wcsrtombs_l .Nd "convert a wide-character string to a character string (restartable)" .Sh LIBRARY .Lb libc -@@ -45,6 +47,17 @@ - .Fa "char * restrict dst" "const wchar_t ** restrict src" "size_t nwc" - .Fa "size_t len" "mbstate_t * restrict ps" - .Fc -+.In xlocale.h -+.Ft size_t -+.Fo wcsrtombs_l -+.Fa "char * restrict dst" "const wchar_t ** restrict src" -+.Fa "size_t len" "mbstate_t * restrict ps" "locale_t loc" + .Sh SYNOPSIS + .In wchar.h + .Ft size_t ++.Fo wcsnrtombs ++.Fa "char *restrict dst" ++.Fa "const wchar_t **restrict src" ++.Fa "size_t nwc" ++.Fa "size_t len" ++.Fa "mbstate_t *restrict ps" +.Fc +.Ft size_t + .Fo wcsrtombs +-.Fa "char * restrict dst" "const wchar_t ** restrict src" +-.Fa "size_t len" "mbstate_t * restrict ps" ++.Fa "char *restrict dst" ++.Fa "const wchar_t **restrict src" ++.Fa "size_t len" ++.Fa "mbstate_t *restrict ps" + .Fc ++.In wchar.h ++.In xlocale.h + .Ft size_t +-.Fo wcsnrtombs +-.Fa "char * restrict dst" "const wchar_t ** restrict src" "size_t nwc" +-.Fa "size_t len" "mbstate_t * restrict ps" +.Fo wcsnrtombs_l -+.Fa "char * restrict dst" "const wchar_t ** restrict src" "size_t nwc" -+.Fa "size_t len" "mbstate_t * restrict ps" "locale_t loc" ++.Fa "char *restrict dst" ++.Fa "const wchar_t **restrict src" ++.Fa "size_t nwc" ++.Fa "size_t len" ++.Fa "mbstate_t *restrict ps" ++.Fa "locale_t loc" +.Fc ++.Ft size_t ++.Fo wcsrtombs_l ++.Fa "char *restrict dst" ++.Fa "const wchar_t **restrict src" ++.Fa "size_t len" ++.Fa "mbstate_t *restrict ps" ++.Fa "locale_t loc" + .Fc .Sh DESCRIPTION The .Fn wcsrtombs -@@ -97,6 +110,18 @@ +-function converts a string of wide characters indirectly pointed to by +-.Fa src +-to a corresponding multibyte character string stored in the array +-pointed to by ++function converts a string of wide characters, ++indirectly pointed to by ++.Fa src , ++to a corresponding multi-byte character string, ++stored in the array pointed to by + .Fa dst . + No more than + .Fa len +@@ -97,15 +124,28 @@ .Fa nwc characters from the buffer pointed to by .Fa src . +.Pp -+While the ++Although the +.Fn wcsrtombs +and +.Fn wcsnrtombs @@ -46,9 +85,21 @@ +.Xr xlocale 3 +for more information. .Sh RETURN VALUES - The +-The ++If successful, the .Fn wcsrtombs -@@ -122,7 +147,8 @@ + and + .Fn wcsnrtombs + functions return the number of bytes stored in + the array pointed to by + .Fa dst +-(not including any terminating null), if successful, otherwise it returns ++(not including any terminating null); ++otherwise, they return + .Po Vt size_t Pc Ns \-1 . + .Sh ERRORS + The +@@ -122,7 +162,8 @@ .Sh SEE ALSO .Xr mbsrtowcs 3 , .Xr wcrtomb 3 , diff --git a/locale/FreeBSD/wcstod.3.patch b/locale/FreeBSD/wcstod.3.patch index a569d53..9be640f 100644 --- a/locale/FreeBSD/wcstod.3.patch +++ b/locale/FreeBSD/wcstod.3.patch @@ -1,6 +1,56 @@ ---- wcstod.3.orig Fri Mar 11 19:16:16 2005 -+++ wcstod.3 Fri Mar 11 19:16:55 2005 -@@ -60,9 +60,16 @@ +--- wcstod.3 2004-11-25 11:38:20.000000000 -0800 ++++ wcstod.3.edit 2006-08-09 13:29:59.000000000 -0700 +@@ -28,40 +28,57 @@ + .Dt WCSTOD 3 + .Os + .Sh NAME +-.Nm wcstof , + .Nm wcstod , ++.Nm wcstof , + .Nm wcstold + .Nd convert string to +-.Vt float , double ++.Vt float , ++.Vt double , + or + .Vt "long double" + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In wchar.h ++.Ft double ++.Fo wcstod ++.Fa "const wchar_t *restrict nptr" ++.Fa "wchar_t **restrict endptr" ++.Fc + .Ft float +-.Fn wcstof "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" ++.Fo wcstof ++.Fa "const wchar_t *restrict nptr" ++.Fa "wchar_t **restrict endptr" ++.Fc + .Ft "long double" +-.Fn wcstold "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" +-.Ft double +-.Fn wcstod "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" ++.Fo wcstold ++.Fa "const wchar_t *restrict nptr" ++.Fa "wchar_t **restrict endptr" ++.Fc + .Sh DESCRIPTION + The + .Fn wcstof , +-.Fn wcstod ++.Fn wcstod , + and + .Fn wcstold + functions are the wide-character versions of the + .Fn strtof , +-.Fn strtod ++.Fn strtod , + and + .Fn strtold + functions. Refer to .Xr strtod 3 for details. @@ -12,9 +62,7 @@ +for more information. .Sh SEE ALSO .Xr strtod 3 , --.Xr wcstol 3 -+.Xr wcstol 3 , -+.Xr wcstod_l 3 ++.Xr wcstod_l 3 , + .Xr wcstol 3 .Sh STANDARDS The - .Fn wcstof , diff --git a/locale/FreeBSD/wcstod.c.patch b/locale/FreeBSD/wcstod.c.patch index 3fdc36e..3868d1d 100644 --- a/locale/FreeBSD/wcstod.c.patch +++ b/locale/FreeBSD/wcstod.c.patch @@ -1,6 +1,6 @@ ---- wcstod.c.orig Thu Nov 25 11:38:20 2004 -+++ wcstod.c Fri Feb 18 14:45:42 2005 -@@ -27,6 +27,8 @@ +--- wcstod.c.orig 2007-03-16 01:15:20.000000000 -0700 ++++ wcstod.c 2007-03-16 03:03:41.000000000 -0700 +@@ -27,9 +27,12 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wcstod.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); @@ -9,7 +9,11 @@ #include #include #include -@@ -41,7 +43,8 @@ ++#include <_simple.h> + + /* + * Convert a string to a double-precision number. +@@ -41,42 +44,43 @@ * for at least the digits, radix character and letters. */ double @@ -19,46 +23,78 @@ { static const mbstate_t initial; mbstate_t mbs; -@@ -50,7 +53,8 @@ - const wchar_t *wcp; + double val; + char *buf, *end; +- const wchar_t *wcp; size_t len; ++ locale_t ctype; ++ _SIMPLE_STRING b; ++ char mb[MB_CUR_MAX + 1]; ++ const wchar_t *nptr0 = nptr; ++ const wchar_t *first; - while (iswspace(*nptr)) + NORMALIZE_LOCALE(loc); -+ while (iswspace_l(*nptr, loc)) ++ ctype = __numeric_ctype(loc); ++ ++ while (iswspace_l(*nptr, ctype)) nptr++; - /* -@@ -65,7 +69,7 @@ - */ - wcp = nptr; - mbs = initial; +- /* +- * Convert the supplied numeric wide char. string to multibyte. +- * +- * We could attempt to find the end of the numeric portion of the +- * wide char. string to avoid converting unneeded characters but +- * choose not to bother; optimising the uncommon case where +- * the input string contains a lot of text after the number +- * duplicates a lot of strtod()'s functionality and slows down the +- * most common cases. +- */ +- wcp = nptr; +- mbs = initial; - if ((len = wcsrtombs(NULL, &wcp, 0, &mbs)) == (size_t)-1) { -+ if ((len = wcsrtombs_l(NULL, &wcp, 0, &mbs, loc)) == (size_t)-1) { - if (endptr != NULL) - *endptr = (wchar_t *)nptr; - return (0.0); -@@ -73,10 +77,10 @@ - if ((buf = malloc(len + 1)) == NULL) +- if (endptr != NULL) +- *endptr = (wchar_t *)nptr; +- return (0.0); +- } +- if ((buf = malloc(len + 1)) == NULL) ++ if ((b = _simple_salloc()) == NULL) return (0.0); ++ ++ first = nptr; mbs = initial; - wcsrtombs(buf, &wcp, len + 1, &mbs); -+ wcsrtombs_l(buf, &wcp, len + 1, &mbs, loc); ++ while (*nptr && (len = wcrtomb_l(mb, *nptr, &mbs, ctype)) != (size_t)-1) { ++ mb[len] = 0; ++ if (_simple_sappend(b, mb) < 0) { /* no memory */ ++ _simple_sfree(b); ++ return (0.0); ++ } ++ nptr++; ++ } /* Let strtod() do most of the work for us. */ - val = strtod(buf, &end); ++ buf = _simple_string(b); + val = strtod_l(buf, &end, loc); /* * We only know where the number ended in the _multibyte_ -@@ -91,4 +95,10 @@ - free(buf); +@@ -86,9 +90,15 @@ + */ + if (endptr != NULL) + /* XXX Assume each wide char is one byte. */ +- *endptr = (wchar_t *)nptr + (end - buf); ++ *endptr = (end == buf) ? (wchar_t *)nptr0 : ((wchar_t *)first + (end - buf)); + +- free(buf); ++ _simple_sfree(b); return (val); -+} + } + +double +wcstod(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + return wcstod_l(nptr, endptr, __current_locale()); - } ++} diff --git a/locale/FreeBSD/wcstof.c.patch b/locale/FreeBSD/wcstof.c.patch index 8c316fb..2cbf6d9 100644 --- a/locale/FreeBSD/wcstof.c.patch +++ b/locale/FreeBSD/wcstof.c.patch @@ -1,6 +1,6 @@ ---- wcstof.c.orig Thu Nov 25 11:38:20 2004 -+++ wcstof.c Fri Feb 18 14:48:11 2005 -@@ -27,6 +27,8 @@ +--- wcstof.c.orig 2007-03-16 01:15:20.000000000 -0700 ++++ wcstof.c 2007-03-16 03:04:01.000000000 -0700 +@@ -27,44 +27,64 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wcstof.c,v 1.3 2004/04/07 09:47:56 tjr Exp $"); @@ -9,7 +9,9 @@ #include #include #include -@@ -35,7 +37,8 @@ ++#include <_simple.h> + + /* * See wcstod() for comments as to the logic used. */ float @@ -19,42 +21,62 @@ { static const mbstate_t initial; mbstate_t mbs; -@@ -44,12 +47,13 @@ - const wchar_t *wcp; + float val; + char *buf, *end; +- const wchar_t *wcp; size_t len; ++ locale_t ctype; ++ _SIMPLE_STRING b; ++ char mb[MB_CUR_MAX + 1]; ++ const wchar_t *nptr0 = nptr; ++ const wchar_t *first; - while (iswspace(*nptr)) + NORMALIZE_LOCALE(loc); -+ while (iswspace_l(*nptr, loc)) ++ ctype = __numeric_ctype(loc); ++ ++ while (iswspace_l(*nptr, ctype)) nptr++; - wcp = nptr; - mbs = initial; +- wcp = nptr; +- mbs = initial; - if ((len = wcsrtombs(NULL, &wcp, 0, &mbs)) == (size_t)-1) { -+ if ((len = wcsrtombs_l(NULL, &wcp, 0, &mbs, loc)) == (size_t)-1) { - if (endptr != NULL) - *endptr = (wchar_t *)nptr; - return (0.0); -@@ -57,9 +61,9 @@ - if ((buf = malloc(len + 1)) == NULL) +- if (endptr != NULL) +- *endptr = (wchar_t *)nptr; +- return (0.0); +- } +- if ((buf = malloc(len + 1)) == NULL) ++ if ((b = _simple_salloc()) == NULL) return (0.0); ++ ++ first = nptr; mbs = initial; - wcsrtombs(buf, &wcp, len + 1, &mbs); -+ wcsrtombs_l(buf, &wcp, len + 1, &mbs, loc); ++ while (*nptr && (len = wcrtomb_l(mb, *nptr, &mbs, ctype)) != (size_t)-1) { ++ mb[len] = 0; ++ if (_simple_sappend(b, mb) < 0) { /* no memory */ ++ _simple_sfree(b); ++ return (0.0); ++ } ++ nptr++; ++ } - val = strtof(buf, &end); ++ buf = _simple_string(b); + val = strtof_l(buf, &end, loc); if (endptr != NULL) - *endptr = (wchar_t *)nptr + (end - buf); -@@ -67,4 +71,10 @@ - free(buf); +- *endptr = (wchar_t *)nptr + (end - buf); ++ *endptr = (end == buf) ? (wchar_t *)nptr0 : ((wchar_t *)first + (end - buf)); + +- free(buf); ++ _simple_sfree(b); return (val); -+} + } + +float +wcstof(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + return wcstof_l(nptr, endptr, __current_locale()); - } ++} diff --git a/locale/FreeBSD/wcstol.3.patch b/locale/FreeBSD/wcstol.3.patch index 1108d62..b1607bd 100644 --- a/locale/FreeBSD/wcstol.3.patch +++ b/locale/FreeBSD/wcstol.3.patch @@ -1,6 +1,97 @@ ---- wcstol.3.orig Fri Mar 11 19:16:13 2005 -+++ wcstol.3 Fri Mar 11 19:17:53 2005 -@@ -78,9 +78,16 @@ +--- wcstol.3 2003-05-20 15:21:45.000000000 -0700 ++++ wcstol.3.edit 2006-07-12 11:29:16.000000000 -0700 +@@ -28,15 +28,18 @@ + .Dt WCSTOL 3 + .Os + .Sh NAME +-.Nm wcstol , wcstoul , +-.Nm wcstoll , wcstoull , +-.Nm wcstoimax , wcstoumax ++.Nm wcstoimax , ++.Nm wcstol , ++.Nm wcstoll , ++.Nm wcstoul , ++.Nm wcstoull , ++.Nm wcstoumax + .Nd "convert a wide character string value to a" ++.Vt intmax_t , + .Vt long , +-.Vt "unsigned long" , + .Vt "long long" , ++.Vt "unsigned long" , + .Vt "unsigned long long" , +-.Vt intmax_t + or + .Vt uintmax_t + integer +@@ -45,25 +48,50 @@ + .Sh SYNOPSIS + .In wchar.h + .Ft long +-.Fn wcstol "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +-.Ft "unsigned long" +-.Fn wcstoul "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" ++.Fo wcstol ++.Fa "const wchar_t *restrict nptr" ++.Fa "wchar_t **restrict endptr" ++.Fa "int base" ++.Fc + .Ft "long long" +-.Fn wcstoll "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" ++.Fo wcstoll ++.Fa "const wchar_t *restrict nptr" ++.Fa "wchar_t **restrict endptr" ++.Fa "int base" ++.Fc ++.Ft "unsigned long" ++.Fo wcstoul ++.Fa "const wchar_t *restrict nptr" ++.Fa "wchar_t **restrict endptr" ++.Fa "int base" ++.Fc + .Ft "unsigned long long" +-.Fn wcstoull "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" ++.Fo wcstoull ++.Fa "const wchar_t *restrict nptr" ++.Fa "wchar_t **restrict endptr" ++.Fa "int base" ++.Fc ++.In stddef.h + .In inttypes.h + .Ft intmax_t +-.Fn wcstoimax "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" ++.Fo wcstoimax ++.Fa "const wchar_t *restrict nptr" ++.Fa "wchar_t **restrict endptr" ++.Fa "int base" ++.Fc + .Ft uintmax_t +-.Fn wcstoumax "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" ++.Fo wcstoumax ++.Fa "const wchar_t *restrict nptr" ++.Fa "wchar_t **restrict endptr" ++.Fa "int base" ++.Fc + .Sh DESCRIPTION + The + .Fn wcstol , + .Fn wcstoul , + .Fn wcstoll , + .Fn wcstoull , +-.Fn wcstoimax ++.Fn wcstoimax , + and + .Fn wcstoumax + functions are wide-character versions of the +@@ -71,23 +99,42 @@ + .Fn strtoul , + .Fn strtoll , + .Fn strtoull , +-.Fn strtoimax ++.Fn strtoimax , + and + .Fn strtoumax + functions, respectively. Refer to their manual pages (for example .Xr strtol 3 ) for details. @@ -10,11 +101,31 @@ +See +.Xr xlocale 3 +for more information. ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Pp ++The include file ++.In stddef.h ++is necessary for the ++.Fn wcstoimax ++and ++.Fn wcstoumax ++functions. .Sh SEE ALSO .Xr strtol 3 , -.Xr strtoul 3 +.Xr strtoul 3 , -+.Xr wcstol_l 3 ++.Xr wcstol_l 3 , ++.Xr compat 5 .Sh STANDARDS The .Fn wcstol , + .Fn wcstoul , + .Fn wcstoll , + .Fn wcstoull , +-.Fn wcstoimax ++.Fn wcstoimax , + and + .Fn wcstoumax + functions conform to diff --git a/locale/FreeBSD/wcstold.c.patch b/locale/FreeBSD/wcstold.c.patch index 750b932..91ad556 100644 --- a/locale/FreeBSD/wcstold.c.patch +++ b/locale/FreeBSD/wcstold.c.patch @@ -1,6 +1,6 @@ ---- wcstold.c.orig Thu Nov 25 11:38:20 2004 -+++ wcstold.c Fri Feb 18 14:52:24 2005 -@@ -27,6 +27,8 @@ +--- wcstold.c.orig 2007-03-16 01:15:20.000000000 -0700 ++++ wcstold.c 2007-03-16 03:04:39.000000000 -0700 +@@ -27,44 +27,64 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wcstold.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); @@ -9,7 +9,9 @@ #include #include #include -@@ -35,7 +37,8 @@ ++#include <_simple.h> + + /* * See wcstod() for comments as to the logic used. */ long double @@ -19,42 +21,62 @@ { static const mbstate_t initial; mbstate_t mbs; -@@ -44,12 +47,13 @@ - const wchar_t *wcp; + long double val; + char *buf, *end; +- const wchar_t *wcp; size_t len; ++ locale_t ctype; ++ _SIMPLE_STRING b; ++ char mb[MB_CUR_MAX + 1]; ++ const wchar_t *nptr0 = nptr; ++ const wchar_t *first; - while (iswspace(*nptr)) + NORMALIZE_LOCALE(loc); -+ while (iswspace_l(*nptr, loc)) ++ ctype = __numeric_ctype(loc); ++ ++ while (iswspace_l(*nptr, ctype)) nptr++; - wcp = nptr; - mbs = initial; +- wcp = nptr; +- mbs = initial; - if ((len = wcsrtombs(NULL, &wcp, 0, &mbs)) == (size_t)-1) { -+ if ((len = wcsrtombs_l(NULL, &wcp, 0, &mbs, loc)) == (size_t)-1) { - if (endptr != NULL) - *endptr = (wchar_t *)nptr; - return (0.0); -@@ -57,9 +61,9 @@ - if ((buf = malloc(len + 1)) == NULL) +- if (endptr != NULL) +- *endptr = (wchar_t *)nptr; +- return (0.0); +- } +- if ((buf = malloc(len + 1)) == NULL) ++ if ((b = _simple_salloc()) == NULL) return (0.0); ++ ++ first = nptr; mbs = initial; - wcsrtombs(buf, &wcp, len + 1, &mbs); -+ wcsrtombs_l(buf, &wcp, len + 1, &mbs, loc); ++ while (*nptr && (len = wcrtomb_l(mb, *nptr, &mbs, ctype)) != (size_t)-1) { ++ mb[len] = 0; ++ if (_simple_sappend(b, mb) < 0) { /* no memory */ ++ _simple_sfree(b); ++ return (0.0); ++ } ++ nptr++; ++ } - val = strtold(buf, &end); ++ buf = _simple_string(b); + val = strtold_l(buf, &end, loc); if (endptr != NULL) - *endptr = (wchar_t *)nptr + (end - buf); -@@ -67,4 +71,10 @@ - free(buf); +- *endptr = (wchar_t *)nptr + (end - buf); ++ *endptr = (end == buf) ? (wchar_t *)nptr0 : ((wchar_t *)first + (end - buf)); + +- free(buf); ++ _simple_sfree(b); return (val); -+} + } + +long double +wcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + return wcstold_l(nptr, endptr, __current_locale()); - } ++} diff --git a/locale/FreeBSD/wcstombs.3.patch b/locale/FreeBSD/wcstombs.3.patch index 689dc68..0e57b66 100644 --- a/locale/FreeBSD/wcstombs.3.patch +++ b/locale/FreeBSD/wcstombs.3.patch @@ -1,5 +1,5 @@ ---- wcstombs.3.orig Fri Mar 11 19:44:47 2005 -+++ wcstombs.3 Fri Mar 11 19:48:16 2005 +--- _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 @@ .Dt WCSTOMBS 3 .Os @@ -10,25 +10,46 @@ .Nd convert a wide-character string to a character string .Sh LIBRARY .Lb libc -@@ -52,6 +53,12 @@ - .Fa "char * restrict mbstring" "const wchar_t * restrict wcstring" - .Fa "size_t nbytes" - .Fc +@@ -49,28 +50,47 @@ + .In stdlib.h + .Ft size_t + .Fo wcstombs +-.Fa "char * restrict mbstring" "const wchar_t * restrict wcstring" +-.Fa "size_t nbytes" ++.Fa "char *restrict s" ++.Fa "const wchar_t *restrict pwcs" ++.Fa "size_t n" ++.Fc ++.In stdlib.h +.In xlocale.h +.Ft size_t +.Fo wcstombs_l -+.Fa "char * restrict mbstring" "const wchar_t * restrict wcstring" -+.Fa "size_t nbytes" "locale_t loc" -+.Fc ++.Fa "char *restrict s" ++.Fa "const wchar_t *restrict pwcs" ++.Fa "size_t n" ++.Fa "locale_t loc" + .Fc .Sh DESCRIPTION The .Fn wcstombs -@@ -66,6 +73,14 @@ - .Fa mbstring . + function converts a wide character string +-.Fa wcstring ++.Fa pwcs + into a multibyte character string, +-.Fa mbstring , ++.Fa s , + beginning in the initial conversion state. + Up to +-.Fa nbytes ++.Fa n + bytes are stored in +-.Fa mbstring . ++.Fa s . Partial multibyte characters at the end of the string are not stored. - The multibyte character string is null terminated if there is room. +-The multibyte character string is null terminated if there is room. ++The multibyte character string is null terminated, if there is room. +.Pp -+While the ++Although the +.Fn wcstombs +function uses the current locale, the +.Fn wcstombs_l @@ -38,7 +59,14 @@ .Sh RETURN VALUES The .Fn wcstombs -@@ -86,7 +101,8 @@ + function returns the number of bytes converted +-(not including any terminating null), if successful, otherwise it returns ++(not including any terminating null), if successful; ++otherwise, it returns + .Po Vt size_t Pc Ns \-1 . + .Sh ERRORS + The +@@ -86,7 +106,8 @@ .Xr mbstowcs 3 , .Xr multibyte 3 , .Xr wcsrtombs 3 , diff --git a/locale/FreeBSD/wctomb.3.patch b/locale/FreeBSD/wctomb.3.patch index fb49db6..36d28db 100644 --- a/locale/FreeBSD/wctomb.3.patch +++ b/locale/FreeBSD/wctomb.3.patch @@ -1,6 +1,6 @@ ---- wctomb.3.orig Fri Mar 11 19:44:47 2005 -+++ wctomb.3 Fri Mar 11 19:47:38 2005 -@@ -41,7 +41,8 @@ +--- _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 @@ .Dt WCTOMB 3 .Os .Sh NAME @@ -10,22 +10,52 @@ .Nd convert a wide-character code to a character .Sh LIBRARY .Lb libc -@@ -49,6 +50,9 @@ + .Sh SYNOPSIS .In stdlib.h .Ft int - .Fn wctomb "char *mbchar" "wchar_t wchar" +-.Fn wctomb "char *mbchar" "wchar_t wchar" ++.Fo wctomb ++.Fa "char *s" ++.Fa "wchar_t wchar" ++.Fc ++.In stdlib.h +.In xlocale.h +.Ft int -+.Fn wctomb_l "char *mbchar" "wchar_t wchar" "locale_t loc" ++.Fo wctomb_l ++.Fa "char *s" ++.Fa "wchar_t wchar" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn wctomb -@@ -69,6 +73,14 @@ +-function converts a wide character +-.Fa wchar +-into a multibyte character and stores +-the result in +-.Fa mbchar . ++function converts a wide character, ++.Fa wchar , ++into a multibyte character and stores the result in ++.Fa s . + The object pointed to by +-.Fa mbchar +-must be large enough to accommodate the multibyte character, which +-may be up to ++.Fa s ++must be large enough to accommodate the multibyte character, ++which may be up to + .Dv MB_LEN_MAX + bytes. + .Pp + A call with a null +-.Fa mbchar ++.Fa s pointer returns nonzero if the current locale requires shift states, zero otherwise; if shift states are required, the shift state is reset to the initial state. +.Pp -+While the ++Although the +.Fn wctomb +function uses the current locale, the +.Fn wctomb_l @@ -34,8 +64,27 @@ +for more information. .Sh RETURN VALUES If - .Fa mbchar -@@ -104,7 +116,8 @@ +-.Fa mbchar ++.Fa s + is + .Dv NULL , + the +@@ -79,12 +98,12 @@ + function returns nonzero if shift states are supported, + zero otherwise. + If +-.Fa mbchar ++.Fa s + is valid, + .Fn wctomb + returns + the number of bytes processed in +-.Fa mbchar , ++.Fa s , + or \-1 if no multibyte character + could be recognized or converted. + In this case, +@@ -104,7 +123,8 @@ .Xr mbtowc 3 , .Xr wcrtomb 3 , .Xr wcstombs 3 , diff --git a/locale/FreeBSD/wctrans.3.patch b/locale/FreeBSD/wctrans.3.patch index af8e928..fc1e9e9 100644 --- a/locale/FreeBSD/wctrans.3.patch +++ b/locale/FreeBSD/wctrans.3.patch @@ -1,29 +1,58 @@ ---- wctrans.3.orig Fri Mar 11 18:13:15 2005 -+++ wctrans.3 Fri Mar 11 18:14:31 2005 -@@ -28,7 +28,8 @@ +--- _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 +@@ -28,21 +28,42 @@ .Dt WCTRANS 3 .Os .Sh NAME -.Nm towctrans , wctrans -+.Nm towctrans , wctrans , -+.Nm towctrans_l , wctrans_l ++.Nm towctrans , ++.Nm towctrans_l , ++.Nm wctrans , ++.Nm wctrans_l .Nd "wide character mapping functions" .Sh LIBRARY .Lb libc -@@ -38,6 +39,11 @@ - .Fn towctrans "wint_t wc" "wctrans_t desc" + .Sh SYNOPSIS + .In wctype.h + .Ft wint_t +-.Fn towctrans "wint_t wc" "wctrans_t desc" ++.Fo towctrans ++.Fa "wint_t wc" ++.Fa "wctrans_t desc" ++.Fc .Ft wctrans_t - .Fn wctrans "const char *charclass" +-.Fn wctrans "const char *charclass" ++.Fo wctrans ++.Fa "const char *charclass" ++.Fc ++.In wctype.h +.In xlocale.h +.Ft wint_t -+.Fn towctrans_l "wint_t wc" "wctrans_t desc" "locale_t loc" ++.Fo towctrans_l ++.Fa "wint_t wc" ++.Fa "wctrans_t desc" ++.Fa "locale_t loc" ++.Fc +.Ft wctrans_t -+.Fn wctrans_l "const char *charclass" "locale_t loc" ++.Fo wctrans_l ++.Fa "const char *charclass" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn wctrans -@@ -58,6 +64,18 @@ - .Fa wc + function returns a value of type +-.Vt wctrans_t ++.Vt wctrans_t , + 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 @@ + The + .Fn towctrans + function transliterates the wide character +-.Fa wc ++.Fa wc , according to the mapping described by .Fa desc . +.Pp @@ -41,7 +70,7 @@ .Sh RETURN VALUES The .Fn towctrans -@@ -105,7 +123,8 @@ +@@ -105,7 +138,8 @@ .Sh SEE ALSO .Xr tolower 3 , .Xr toupper 3 , diff --git a/locale/FreeBSD/wctype.3.patch b/locale/FreeBSD/wctype.3.patch index e7052cd..86d78c6 100644 --- a/locale/FreeBSD/wctype.3.patch +++ b/locale/FreeBSD/wctype.3.patch @@ -1,33 +1,58 @@ ---- wctype.3.orig Fri Mar 11 18:15:32 2005 -+++ wctype.3 Fri Mar 11 18:19:55 2005 -@@ -28,7 +28,8 @@ +--- _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 +@@ -28,21 +28,42 @@ .Dt WCTYPE 3 .Os .Sh NAME -.Nm iswctype , wctype -+.Nm iswctype , wctype , -+.Nm iswctype_l , wctype_l ++.Nm iswctype , ++.Nm iswctype_l , ++.Nm wctype , ++.Nm wctype_l .Nd "wide character class functions" .Sh LIBRARY .Lb libc -@@ -38,6 +39,11 @@ - .Fn iswctype "wint_t wc" "wctype_t charclass" + .Sh SYNOPSIS + .In wctype.h + .Ft int +-.Fn iswctype "wint_t wc" "wctype_t charclass" ++.Fo iswctype ++.Fa "wint_t wc" ++.Fa "wctype_t charclass" ++.Fc .Ft wctype_t - .Fn wctype "const char *property" +-.Fn wctype "const char *property" ++.Fo wctype ++.Fa "const char *property" ++.Fc ++.In wctype.h +.In xlocale.h +.Ft int -+.Fn iswctype_l "wint_t wc" "wctype_t charclass" "locale_t loc" ++.Fo iswctype_l ++.Fa "wint_t wc" ++.Fa "wctype_t charclass" ++.Fa "locale_t loc" ++.Fc +.Ft wctype_t -+.Fn wctype_l "const char *property" "locale_t loc" ++.Fo wctype_l ++.Fa "const char *property" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn wctype -@@ -60,6 +66,18 @@ + function returns a value of type +-.Vt wctype_t ++.Vt wctype_t , + which represents the requested wide character class and + may be used as the second argument for calls to + .Fn iswctype . +@@ -60,6 +81,18 @@ .Fa wc is in the character class .Fa charclass . +.Pp -+While the ++Although the +.Fn iswctype +and +.Fn wctype @@ -41,7 +66,16 @@ .Sh RETURN VALUES The .Fn iswctype -@@ -94,7 +112,8 @@ +@@ -75,7 +108,7 @@ + .Fn wctype + function returns 0 if + .Fa property +-is invalid, otherwise it returns a value of type ++is invalid; otherwise, it returns a value of type + .Vt wctype_t + that can be used in subsequent calls to + .Fn iswctype . +@@ -94,7 +127,8 @@ } .Ed .Sh SEE ALSO diff --git a/locale/FreeBSD/wctype.c.patch b/locale/FreeBSD/wctype.c.patch index 2747884..46623d0 100644 --- a/locale/FreeBSD/wctype.c.patch +++ b/locale/FreeBSD/wctype.c.patch @@ -1,6 +1,6 @@ ---- wctype.c.orig 2004-11-25 11:38:21.000000000 -0800 -+++ wctype.c 2005-02-27 02:15:11.000000000 -0800 -@@ -27,6 +27,8 @@ +--- 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 @@ #include __FBSDID("$FreeBSD: src/lib/libc/locale/wctype.c,v 1.3 2004/03/27 08:59:21 tjr Exp $"); @@ -9,22 +9,15 @@ #include #include #include -@@ -36,34 +38,57 @@ - iswctype(wint_t wc, wctype_t charclass) - { ++#include +-#undef iswctype +-int +-iswctype(wint_t wc, wctype_t charclass) +-{ +- - return (__istype(wc, charclass)); -+ return (__istype_l(wc, charclass, __current_locale())); -+} -+ -+#undef iswctype_l -+int -+iswctype_l(wint_t wc, wctype_t charclass, locale_t loc) -+{ -+ NORMALIZE_LOCALE(loc); -+ return (__istype_l(wc, charclass, loc)); - } - +-} +static struct { + const char *name; + wctype_t mask; @@ -44,14 +37,13 @@ + { "ideogram", _CTYPE_I }, /* BSD extension */ + { "special", _CTYPE_T }, /* BSD extension */ + { "phonogram", _CTYPE_Q }, /* BSD extension */ -+ { "rune", 0xFFFFFF00L }, /* BSD extension */ ++ { "rune", 0xFFFFFFF0L }, /* BSD extension */ + { NULL, 0UL }, /* Default */ +}; -+ -+/* these don't currently depend on the locale, but they could */ -+ + wctype_t - wctype(const char *property) +-wctype(const char *property) ++wctype_l(const char *property, locale_t loc) { - struct { - const char *name; @@ -75,18 +67,31 @@ - { "rune", 0xFFFFFF00L }, /* BSD extension */ - { NULL, 0UL }, /* Default */ - }; -+ int i; -+ -+ i = 0; -+ while (props[i].name != NULL && strcmp(props[i].name, property) != 0) -+ i++; + int i; ++ _RuneLocale *rl; + + i = 0; + while (props[i].name != NULL && strcmp(props[i].name, property) != 0) + i++; + +- return (props[i].mask); ++ if (props[i].mask) ++ return (props[i].mask); + -+ return (props[i].mask); ++ NORMALIZE_LOCALE(loc); ++ rl = &loc->__lc_ctype->_CurrentRuneLocale; ++ if ((i = rl->__ncharclasses) > 0) { ++ _RuneCharClass *rp; ++ for (rp = rl->__charclasses; i-- > 0; rp++) { ++ if (strncmp(rp->__name, property, CHARCLASS_NAME_MAX) == 0) ++ return (rp->__mask); ++ } ++ } ++ return 0; +} + +wctype_t -+wctype_l(const char *property, locale_t loc) ++wctype(const char *property) +{ - int i; - - i = 0; ++ return wctype_l(property, __current_locale()); + } diff --git a/locale/FreeBSD/wcwidth.3.patch b/locale/FreeBSD/wcwidth.3.patch index bb68349..7c7b829 100644 --- a/locale/FreeBSD/wcwidth.3.patch +++ b/locale/FreeBSD/wcwidth.3.patch @@ -1,6 +1,6 @@ ---- wcwidth.3.orig Fri Mar 11 19:44:47 2005 -+++ wcwidth.3 Fri Mar 11 19:46:47 2005 -@@ -28,7 +28,8 @@ +--- _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 +@@ -28,20 +28,38 @@ .Dt WCWIDTH 3 .Os .Sh NAME @@ -10,13 +10,20 @@ .Nd "number of column positions of a wide-character code" .Sh LIBRARY .Lb libc -@@ -36,12 +37,23 @@ + .Sh SYNOPSIS .In wchar.h .Ft int - .Fn wcwidth "wchar_t wc" +-.Fn wcwidth "wchar_t wc" ++.Fo wcwidth ++.Fa "wchar_t wc" ++.Fc ++.In wchar.h +.In xlocale.h +.Ft int -+.Fn wcwidth_l "wchar_t wc" "locale_t loc" ++.Fo wcwidth_l ++.Fa "wchar_t wc" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn wcwidth @@ -24,7 +31,7 @@ display the wide character .Fa wc . +.Pp -+While the ++Although the +.Fn wcwidth +function uses the current locale, the +.Fn wcwidth_l @@ -34,7 +41,18 @@ .Sh RETURN VALUES The .Fn wcwidth -@@ -79,7 +91,8 @@ +@@ -50,8 +68,8 @@ + argument is a null wide character (L'\e0'), + \-1 if + .Fa wc +-is not printable, +-otherwise it returns the number of column positions the ++is not printable; ++otherwise, it returns the number of column positions the + character occupies. + .Sh EXAMPLES + This code fragment reads text from standard input and +@@ -79,7 +97,8 @@ .Ed .Sh SEE ALSO .Xr iswprint 3 , diff --git a/locale/Makefile.inc b/locale/Makefile.inc index 82d344b..29d54d5 100644 --- a/locale/Makefile.inc +++ b/locale/Makefile.inc @@ -8,11 +8,11 @@ MISRCS += frune.c mbrune.c runedepreciated.c setinvalidrune.c # extended locale -MISRCS += isctype_l.c iswctype_l.c xlocale.c +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 \ - gb18030.c gb2312.c gbk.c isctype.c iswctype.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 \ mbstowcs.c mbtowc.c mskanji.c \ @@ -28,11 +28,14 @@ FBSDHDRS= collate.h ldpart.h lmessages.h lmonetary.h lnumeric.h \ .include "Makefile.fbsd_end" # special case: utf2-fbsd.c is derived from utf8.c with utf2.c.patch -AUTOPATCHSRCS+= ${SYMROOT}/utf2-fbsd.c -MISRCS+= utf2.c -${SYMROOT}/utf2-fbsd.c: FreeBSD/utf8.c +.ifmake autopatch +AUTOPATCHSRCS+= utf2-fbsd.c +utf2-fbsd.c: FreeBSD/utf8.c cp ${.ALLSRC} ${.TARGET} patch ${.TARGET} ${.ALLSRC:S/utf8/utf2/}.patch; +.else # !autopatch +MISRCS+= utf2.c +.endif # autopatch # also build a 64-bit long double version (ppc only) LDBLSRCS += wcstold.c @@ -44,20 +47,27 @@ CFLAGS-lconv.c += -D__APPLE_PR_3333969_HACK__ # End hack for 3333969 +LEGACYSRCS += wcsftime.c + +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +CFLAGS-wcsftime-fbsd.c += -DLIBC_ALIAS_WCSFTIME -DLIBC_ALIAS_WCSFTIME_L + # for LP64, we need to create rune32.h -.ifdef LP64 # the following is good enough for ppc, ppc64, i386 and x86_64 +.ifmake autopatch _ARCH != arch .if $(_ARCH) == x86_64 ARCH32 = i386 .else ARCH32 = $(_ARCH:C/64$//) .endif -rune.So rune.do rune.po rune.o: ${SYMROOT}/rune32.h -${SYMROOT}/rune32.h: ${SYMROOT}/rune-fbsd.c - ${CC} -arch ${ARCH32} -DRUNEOFF32 -o ${SYMROOT}/rune32 ${.ALLSRC} - ${SYMROOT}/rune32 > ${.TARGET} -.endif +rune32.h: rune-fbsd.c + ${CC} -arch ${ARCH32} -I${.CURDIR}/include -DRUNEOFF32 -o ${SRCROOT}/rune32 ${.ALLSRC} + ${SRCROOT}/rune32 > ${.TARGET} + rm -f ${SRCROOT}/rune32 +AUTOPATCHHDRS+= rune32.h +.endif # autopatch .if ${LIB} == "c" MAN3+= ctype_l.3 isalnum_l.3 iswalnum_l.3 wcstod_l.3 wcstol_l.3 @@ -83,66 +93,151 @@ FBSDMAN3= btowc.3 ctype.3 digittoint.3 \ FBSDMAN5= big5.5 euc.5 gb18030.5 gb2312.5 gbk.5 mskanji.5 utf8.5 .include "Makefile.fbsd_end" -MLINKS+=btowc.3 wctob.3 -MLINKS+=btowc.3 btowc_l.3 btowc.3 wctob_l.3 -MLINKS+=digittoint.3 digittoint_l.3 -MLINKS+=isdigit.3 isnumber.3 -MLINKS+=isalnum_l.3 isalpha_l.3 isalnum_l.3 isblank_l.3 \ - isalnum_l.3 iscntrl_l.3 isalnum_l.3 isdigit_l.3 isalnum_l.3 isgraph_l.3 \ - isalnum_l.3 ishexnumber_l.3 \ - isalnum_l.3 isideogram_l.3 isalnum_l.3 islower_l.3 isalnum_l.3 isnumber_l.3 \ - isalnum_l.3 isphonogram_l.3 isalnum_l.3 isprint_l.3 isalnum_l.3 ispunct_l.3 \ - isalnum_l.3 isrune_l.3 isalnum_l.3 isspace_l.3 isalnum_l.3 isspecial_l.3 \ - isalnum_l.3 isupper_l.3 isalnum_l.3 isxdigit_l.3 -MLINKS+=iswalnum.3 iswalpha.3 iswalnum.3 iswascii.3 iswalnum.3 iswblank.3 \ - iswalnum.3 iswcntrl.3 iswalnum.3 iswdigit.3 iswalnum.3 iswgraph.3 \ - iswalnum.3 iswhexnumber.3 \ - iswalnum.3 iswideogram.3 iswalnum.3 iswlower.3 iswalnum.3 iswnumber.3 \ - iswalnum.3 iswphonogram.3 iswalnum.3 iswprint.3 iswalnum.3 iswpunct.3 \ - iswalnum.3 iswrune.3 iswalnum.3 iswspace.3 iswalnum.3 iswspecial.3 \ - iswalnum.3 iswupper.3 iswalnum.3 iswxdigit.3 -MLINKS+=iswalnum_l.3 iswalpha_l.3 iswalnum_l.3 iswblank_l.3 \ - iswalnum_l.3 iswcntrl_l.3 iswalnum_l.3 iswdigit_l.3 iswalnum_l.3 iswgraph_l.3 \ - iswalnum_l.3 iswhexnumber_l.3 \ - iswalnum_l.3 iswideogram_l.3 iswalnum_l.3 iswlower_l.3 iswalnum_l.3 iswnumber_l.3 \ - iswalnum_l.3 iswphonogram_l.3 iswalnum_l.3 iswprint_l.3 iswalnum_l.3 iswpunct_l.3 \ - iswalnum_l.3 iswrune_l.3 iswalnum_l.3 iswspace_l.3 iswalnum_l.3 iswspecial_l.3 \ - iswalnum_l.3 iswupper_l.3 iswalnum_l.3 iswxdigit_l.3 -MLINKS+=isxdigit.3 ishexnumber.3 -MLINKS+=localeconv.3 localeconv_l.3 -MLINKS+=mblen.3 mblen_l.3 -MLINKS+=mbrlen.3 mbrlen_l.3 -MLINKS+=mbrtowc.3 mbrtowc_l.3 -MLINKS+=mbrune.3 mbmb.3 mbrune.3 mbrrune.3 -MLINKS+=mbsinit.3 mbsinit_l.3 -MLINKS+=mbsrtowcs.3 mbsnrtowcs.3 -MLINKS+=mbsrtowcs.3 mbsrtowcs_l.3 mbsrtowcs.3 mbsnrtowcs_l.3 -MLINKS+=mbstowcs.3 mbstowcs_l.3 -MLINKS+=mbtowc.3 mbtowc_l.3 -MLINKS+=nextwctype.3 nextwctype_l.3 -MLINKS+=nl_langinfo.3 nl_langinfo_l.3 -MLINKS+=rune.3 fgetrune.3 rune.3 fputrune.3 rune.3 fungetrune.3 \ - rune.3 setinvalidrune.3 rune.3 setrunelocale.3 rune.3 sgetrune.3 \ - rune.3 sputrune.3 -MLINKS+=tolower.3 tolower_l.3 -MLINKS+=toupper.3 toupper_l.3 -MLINKS+=towlower.3 towlower_l.3 -MLINKS+=towupper.3 towupper_l.3 -MLINKS+=wcrtomb.3 wcrtomb_l.3 -MLINKS+=wcsftime.3 wcsftime_l.3 -MLINKS+=wcsrtombs.3 wcsnrtombs.3 -MLINKS+=wcsrtombs.3 wcsrtombs_l.3 wcsrtombs.3 wcsnrtombs_l.3 -MLINKS+=wcstod.3 wcstof.3 wcstod.3 wcstold.3 -MLINKS+=wcstod_l.3 wcstof_l.3 wcstod_l.3 wcstold_l.3 -MLINKS+=wcstol.3 wcstoul.3 wcstol.3 wcstoll.3 wcstol.3 wcstoull.3 \ - wcstol.3 wcstoimax.3 wcstol.3 wcstoumax.3 -MLINKS+=wcstol_l.3 wcstoul_l.3 wcstol_l.3 wcstoll_l.3 wcstol_l.3 wcstoull_l.3 \ - wcstol_l.3 wcstoimax_l.3 wcstol_l.3 wcstoumax_l.3 -MLINKS+=wcstombs.3 wcstombs_l.3 -MLINKS+=wctomb.3 wctomb_l.3 -MLINKS+=wctrans.3 towctrans.3 -MLINKS+=wctrans.3 wctrans_l.3 wctrans.3 towctrans_l.3 -MLINKS+=wctype.3 iswctype.3 -MLINKS+=wctype.3 wctype_l.3 wctype.3 iswctype_l.3 -MLINKS+=wcwidth.3 wcwidth_l.3 +MLINKS+= btowc.3 wctob.3 + +MLINKS+= btowc.3 btowc_l.3 \ + btowc.3 wctob_l.3 + +MLINKS+= digittoint.3 digittoint_l.3 + +MLINKS+= isdigit.3 isnumber.3 + +MLINKS+= isalnum_l.3 isalpha_l.3 \ + isalnum_l.3 isblank_l.3 \ + isalnum_l.3 iscntrl_l.3 \ + isalnum_l.3 isdigit_l.3 \ + isalnum_l.3 isgraph_l.3 \ + isalnum_l.3 ishexnumber_l.3 \ + isalnum_l.3 isideogram_l.3 \ + isalnum_l.3 islower_l.3 \ + isalnum_l.3 isnumber_l.3 \ + isalnum_l.3 isphonogram_l.3 \ + isalnum_l.3 isprint_l.3 \ + isalnum_l.3 ispunct_l.3 \ + isalnum_l.3 isrune_l.3 \ + isalnum_l.3 isspace_l.3 \ + isalnum_l.3 isspecial_l.3 \ + isalnum_l.3 isupper_l.3 \ + isalnum_l.3 isxdigit_l.3 + +MLINKS+= iswalnum.3 iswalpha.3 \ + iswalnum.3 iswascii.3 \ + iswalnum.3 iswblank.3 \ + iswalnum.3 iswcntrl.3 \ + iswalnum.3 iswdigit.3 \ + iswalnum.3 iswgraph.3 \ + iswalnum.3 iswhexnumber.3 \ + iswalnum.3 iswideogram.3 \ + iswalnum.3 iswlower.3 \ + iswalnum.3 iswnumber.3 \ + iswalnum.3 iswphonogram.3 \ + iswalnum.3 iswprint.3 \ + iswalnum.3 iswpunct.3 \ + iswalnum.3 iswrune.3 \ + iswalnum.3 iswspace.3 \ + iswalnum.3 iswspecial.3 \ + iswalnum.3 iswupper.3 \ + iswalnum.3 iswxdigit.3 + +MLINKS+= iswalnum_l.3 iswalpha_l.3 \ + iswalnum_l.3 iswblank_l.3 \ + iswalnum_l.3 iswcntrl_l.3 \ + iswalnum_l.3 iswdigit_l.3 \ + iswalnum_l.3 iswgraph_l.3 \ + iswalnum_l.3 iswhexnumber_l.3 \ + iswalnum_l.3 iswideogram_l.3 \ + iswalnum_l.3 iswlower_l.3 \ + iswalnum_l.3 iswnumber_l.3 \ + iswalnum_l.3 iswphonogram_l.3 \ + iswalnum_l.3 iswprint_l.3 \ + iswalnum_l.3 iswpunct_l.3 \ + iswalnum_l.3 iswrune_l.3 \ + iswalnum_l.3 iswspace_l.3 \ + iswalnum_l.3 iswspecial_l.3 \ + iswalnum_l.3 iswupper_l.3 \ + iswalnum_l.3 iswxdigit_l.3 + +MLINKS+= isxdigit.3 ishexnumber.3 + +MLINKS+= localeconv.3 localeconv_l.3 + +MLINKS+= mblen.3 mblen_l.3 + +MLINKS+= mbrlen.3 mbrlen_l.3 + +MLINKS+= mbrtowc.3 mbrtowc_l.3 + +MLINKS+= mbrune.3 mbmb.3 \ + mbrune.3 mbrrune.3 + +MLINKS+= mbsinit.3 mbsinit_l.3 + +MLINKS+= mbsrtowcs.3 mbsnrtowcs.3 + +MLINKS+= mbsrtowcs.3 mbsrtowcs_l.3 \ + mbsrtowcs.3 mbsnrtowcs_l.3 + +MLINKS+= mbstowcs.3 mbstowcs_l.3 + +MLINKS+= mbtowc.3 mbtowc_l.3 + +MLINKS+= nextwctype.3 nextwctype_l.3 + +MLINKS+= nl_langinfo.3 nl_langinfo_l.3 + +MLINKS+= rune.3 fgetrune.3 \ + rune.3 fputrune.3 \ + rune.3 fungetrune.3 \ + rune.3 setinvalidrune.3 \ + rune.3 setrunelocale.3 \ + rune.3 sgetrune.3 \ + rune.3 sputrune.3 + +MLINKS+= tolower.3 tolower_l.3 + +MLINKS+= toupper.3 toupper_l.3 + +MLINKS+= towlower.3 towlower_l.3 + +MLINKS+= towupper.3 towupper_l.3 + +MLINKS+= wcrtomb.3 wcrtomb_l.3 + +MLINKS+= wcsftime.3 wcsftime_l.3 + +MLINKS+= wcsrtombs.3 wcsnrtombs.3 \ + wcsrtombs.3 wcsrtombs_l.3 \ + wcsrtombs.3 wcsnrtombs_l.3 + +MLINKS+= wcstod.3 wcstof.3 \ + wcstod.3 wcstold.3 + +MLINKS+= wcstod_l.3 wcstof_l.3 \ + wcstod_l.3 wcstold_l.3 + +MLINKS+= wcstol.3 wcstoimax.3 \ + wcstol.3 wcstoll.3 \ + wcstol.3 wcstoul.3 \ + wcstol.3 wcstoull.3 \ + wcstol.3 wcstoumax.3 + +MLINKS+= wcstol_l.3 wcstoimax_l.3 \ + wcstol_l.3 wcstoll_l.3 \ + wcstol_l.3 wcstoul_l.3 \ + wcstol_l.3 wcstoull_l.3 \ + wcstol_l.3 wcstoumax_l.3 + +MLINKS+= wctomb.3 wctomb_l.3 + +MLINKS+= wcstombs.3 wcstombs_l.3 + +MLINKS+= wctrans.3 towctrans.3 \ + wctrans.3 towctrans_l.3 \ + wctrans.3 wctrans_l.3 + +MLINKS+= wctype.3 iswctype.3 \ + wctype.3 iswctype_l.3 \ + wctype.3 wctype_l.3 + +MLINKS+= wcwidth.3 wcwidth_l.3 .endif diff --git a/locale/big5-fbsd.c b/locale/big5-fbsd.c new file mode 100644 index 0000000..d4d4142 --- /dev/null +++ b/locale/big5-fbsd.c @@ -0,0 +1,172 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 "xlocale_private.h" + +#include +#include +#include +#include +#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 int _BIG5_mbsinit(const mbstate_t *, locale_t); +static size_t _BIG5_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); + +typedef struct { + wchar_t ch; +} _BIG5State; + +__private_extern__ int +_BIG5_init(struct __xlocale_st_runelocale *xrl) +{ + + xrl->__mbrtowc = _BIG5_mbrtowc; + xrl->__wcrtomb = _BIG5_wcrtomb; + xrl->__mbsinit = _BIG5_mbsinit; + xrl->__mb_cur_max = 2; + return (0); +} + +static int +_BIG5_mbsinit(const mbstate_t *ps, locale_t loc) +{ + + return (ps == NULL || ((const _BIG5State *)ps)->ch == 0); +} + +static __inline int +_big5_check(u_int c) +{ + + c &= 0xff; + return ((c >= 0xa1 && c <= 0xfe) ? 2 : 1); +} + +static size_t +_BIG5_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t loc) +{ + _BIG5State *bs; + wchar_t wc; + size_t len; + + bs = (_BIG5State *)ps; + + if ((bs->ch & ~0xFF) != 0) { + /* Bad conversion state. */ + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + if (bs->ch != 0) { + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (bs->ch << 8) | (*s & 0xFF); + if (pwc != NULL) + *pwc = wc; + bs->ch = 0; + return (1); + } + + len = (size_t)_big5_check(*s); + wc = *s++ & 0xff; + if (len == 2) { + if (n < 2) { + /* Incomplete multibyte sequence */ + bs->ch = wc; + return ((size_t)-2); + } + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (wc << 8) | (*s++ & 0xff); + if (pwc != NULL) + *pwc = wc; + return (2); + } else { + if (pwc != NULL) + *pwc = wc; + return (wc == L'\0' ? 0 : 1); + } +} + +static size_t +_BIG5_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +{ + _BIG5State *bs; + + bs = (_BIG5State *)ps; + + if (bs->ch != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc & 0x8000) { + *s++ = (wc >> 8) & 0xff; + *s = wc & 0xff; + return (2); + } + *s = wc & 0xff; + return (1); +} diff --git a/locale/big5.5 b/locale/big5.5 new file mode 120000 index 0000000..50603f0 --- /dev/null +++ b/locale/big5.5 @@ -0,0 +1 @@ +./big5.5 \ No newline at end of file diff --git a/locale/btowc-fbsd.c b/locale/btowc-fbsd.c new file mode 100644 index 0000000..38122e7 --- /dev/null +++ b/locale/btowc-fbsd.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2002, 2003 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/locale/btowc.c,v 1.4 2004/05/12 14:26:54 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include "mblocal.h" + +wint_t +btowc_l(int c, locale_t loc) +{ + static const mbstate_t initial; + mbstate_t mbs = initial; + char cc; + wchar_t wc; + + NORMALIZE_LOCALE(loc); + if (c == EOF) + return (WEOF); + /* + * We expect mbrtowc() to return 0 or 1, hence the check for n > 1 + * which detects error return values as well as "impossible" byte + * counts. + */ + cc = (char)c; + 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/btowc.3 b/locale/btowc.3 new file mode 100644 index 0000000..39447a2 --- /dev/null +++ b/locale/btowc.3 @@ -0,0 +1,117 @@ +.\" Copyright (c) 2002 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/btowc.3,v 1.2 2002/11/10 11:14:58 tjr Exp $ +.\" +.Dd August 3, 2002 +.Dt BTOWC 3 +.Os +.Sh NAME +.Nm btowc , +.Nm btowc_l , +.Nm wctob , +.Nm wctob_l +.Nd "convert between wide and single-byte characters" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft wint_t +.Fo btowc +.Fa "int c" +.Fc +.Ft int +.Fo wctob +.Fa "wint_t c" +.Fc +.In wchar.h +.In xlocale.h +.Ft wint_t +.Fo btowc_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo wctob_l +.Fa "wint_t c" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn btowc +function converts a single-byte character into a corresponding wide character. +If the character is +.Dv EOF +or not valid in the initial shift state, +.Fn btowc +returns +.Dv WEOF . +.Pp +The +.Fn wctob +function converts a wide character into a corresponding single-byte character. +If the wide character is +.Dv WEOF +or not able to be represented as a single byte in the initial shift state, +.Fn wctob +returns +.Dv WEOF . +.Pp +While the +.Fn btowc +and +.Fn wctob +functions use the current locale, the +.Fn btowc_l +and +.Fn wctob_l +functions may be passed locales directly. See +.Xr xlocale 3 +for more information. +.Sh LEGACY SYNOPSIS +.Pp +The include file +.In stdio.h +is not necessary for these functions. +.Sh SEE ALSO +.Xr mbrtowc 3 , +.Xr multibyte 3 , +.Xr wcrtomb 3 , +.Xr xlocale 3 , +.Xr compat 5 +.Sh STANDARDS +The +.Fn btowc +and +.Fn wctob +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn btowc +and +.Fn wctob +functions first appeared in +.Fx 5.0 . diff --git a/locale/collate-fbsd.c b/locale/collate-fbsd.c new file mode 100644 index 0000000..e40350b --- /dev/null +++ b/locale/collate-fbsd.c @@ -0,0 +1,954 @@ +/*- + * Copyright (c) 1995 Alex Tatmanjants + * at Electronni Visti IA, Kiev, Ukraine. + * 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 ``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 +__FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.33 2004/09/22 16:56:48 stefanf Exp $"); + +#include "xlocale_private.h" +/* assumes the locale_t variable is named loc */ +#define __collate_chain_equiv_table (loc->__lc_collate->__chain_equiv_table) +#define __collate_chain_pri_table (loc->__lc_collate->__chain_pri_table) +#define __collate_char_pri_table (loc->__lc_collate->__char_pri_table) +#define __collate_info (&loc->__lc_collate->__info) +#define __collate_large_char_pri_table (loc->__lc_collate->__large_char_pri_table) +#define __collate_substitute_table (loc->__lc_collate->__substitute_table) + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "collate.h" +#include "setlocale.h" +#include "ldpart.h" + +#include "libc_private.h" + +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN +static void wntohl(wchar_t *, int); +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ +void __collate_err(int ex, const char *f) __dead2; + +/* + * Normally, the __collate_* routines should all be __private_extern__, + * but grep is using them (3715846). Until we can provide an alternative, + * we leave them public, and provide a read-only __collate_load_error variable + */ +#undef __collate_load_error +int __collate_load_error = 1; + +__private_extern__ int +__collate_load_tables(const char *encoding, locale_t loc) +{ + FILE *fp; + int i, saverr, chains, z; + char strbuf[STR_LEN], buf[PATH_MAX]; + struct __xlocale_st_collate *TMP; + static struct __xlocale_st_collate *cache = NULL; + struct __collate_st_info info; + void *vp; + + /* 'encoding' must be already checked. */ + if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { + loc->__collate_load_error = 1; + if (loc == &__global_locale) + __collate_load_error = 1; + XL_RELEASE(loc->__lc_collate); + loc->__lc_collate = NULL; + return (_LDP_CACHE); + } + + /* + * If the locale name is the same as our cache, use the cache. + */ + if (cache && strcmp(encoding, cache->__encoding) == 0) { + loc->__collate_load_error = 0; + if (loc == &__global_locale) + __collate_load_error = 0; + XL_RELEASE(loc->__lc_collate); + loc->__lc_collate = cache; + XL_RETAIN(loc->__lc_collate); + return (_LDP_CACHE); + } + + /* + * Slurp the locale file into the cache. + */ + + /* 'PathLocale' must be already set & checked. */ + /* Range checking not needed, encoding has fixed size */ + (void)strcpy(buf, _PathLocale); + (void)strcat(buf, "/"); + (void)strcat(buf, encoding); + (void)strcat(buf, "/LC_COLLATE"); + if ((fp = fopen(buf, "r")) == NULL) + return (_LDP_ERROR); + + if (fread(strbuf, sizeof(strbuf), 1, fp) != 1) { + saverr = errno; + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } + chains = -1; + if (strcmp(strbuf, COLLATE_VERSION1_1A) == 0) + chains = 1; + if (chains < 0) { + (void)fclose(fp); + errno = EFTYPE; + return (_LDP_ERROR); + } + if (chains) { + if (fread(&info, sizeof(info), 1, fp) != 1) { + saverr = errno; + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN + for(z = 0; z < info.directive_count; z++) { + info.undef_pri[z] = ntohl(info.undef_pri[z]); + info.subst_count[z] = ntohl(info.subst_count[z]); + } + info.chain_count = ntohl(info.chain_count); + info.large_pri_count = ntohl(info.large_pri_count); +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ + if ((chains = info.chain_count) < 0) { + (void)fclose(fp); + errno = EFTYPE; + return (_LDP_ERROR); + } + } else + chains = TABLE_SIZE; + + 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); + } + TMP->__refcount = 2; /* one for the locale, one for the cache */ + TMP->__free_extra = NULL; + +#define FREAD(a, b, c, d) \ +{ \ + if (fread(a, b, c, d) != c) { \ + saverr = errno; \ + free(TMP); \ + (void)fclose(d); \ + errno = saverr; \ + return (_LDP_ERROR); \ + } \ +} + + /* adjust size to read the remaining in one chunk */ + i -= offsetof(struct __xlocale_st_collate, __char_pri_table); + FREAD(TMP->__char_pri_table, i, 1, fp); + (void)fclose(fp); + + vp = (void *)(TMP + 1); + + /* the COLLATE_SUBST_DUP optimization relies on COLL_WEIGHTS_MAX == 2 */ + if (info.subst_count[0] > 0) { + TMP->__substitute_table[0] = (struct __collate_st_subst *)vp; + vp += info.subst_count[0] * sizeof(struct __collate_st_subst); + } else + TMP->__substitute_table[0] = NULL; + if (info.flags & COLLATE_SUBST_DUP) + TMP->__substitute_table[1] = TMP->__substitute_table[0]; + else if (info.subst_count[1] > 0) { + TMP->__substitute_table[1] = (struct __collate_st_subst *)vp; + vp += info.subst_count[1] * sizeof(struct __collate_st_subst); + } else + TMP->__substitute_table[1] = NULL; + + if (chains > 0) { + TMP->__chain_pri_table = (struct __collate_st_chain_pri *)vp; + vp += chains * sizeof(struct __collate_st_chain_pri); + } else + TMP->__chain_pri_table = NULL; + if (info.large_pri_count > 0) + TMP->__large_char_pri_table = (struct __collate_st_large_char_pri *)vp; + else + TMP->__large_char_pri_table = NULL; + +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN + { + struct __collate_st_char_pri *p = TMP->__char_pri_table; + for(i = UCHAR_MAX + 1; i-- > 0; p++) { + for(z = 0; z < info.directive_count; z++) + p->pri[z] = ntohl(p->pri[z]); + } + } + for(z = 0; z < info.directive_count; z++) + if (info.subst_count[z] > 0) { + struct __collate_st_subst *p = TMP->__substitute_table[z]; + for(i = info.subst_count[z]; i-- > 0; p++) { + p->val = ntohl(p->val); + wntohl(p->str, STR_LEN); + } + } + { + struct __collate_st_chain_pri *p = TMP->__chain_pri_table; + for(i = chains; i-- > 0; p++) { + wntohl(p->str, STR_LEN); + for(z = 0; z < info.directive_count; z++) + p->pri[z] = ntohl(p->pri[z]); + } + } + if (info.large_pri_count > 0) { + struct __collate_st_large_char_pri *p = TMP->__large_char_pri_table; + for(i = info.large_pri_count; i-- > 0; p++) { + p->val = ntohl(p->val); + for(z = 0; z < info.directive_count; z++) + p->pri.pri[z] = ntohl(p->pri.pri[z]); + } + } +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ + (void)strcpy(TMP->__encoding, encoding); + (void)memcpy(&TMP->__info, &info, sizeof(info)); + XL_RELEASE(cache); + cache = TMP; + XL_RELEASE(loc->__lc_collate); + loc->__lc_collate = cache; + /* no need to retain, since we set __refcount to 2 above */ + + loc->__collate_substitute_nontrivial = (info.subst_count[0] > 0 || info.subst_count[1] > 0); + loc->__collate_load_error = 0; + if (loc == &__global_locale) + __collate_load_error = 0; + + return (_LDP_LOADED); +} + +static int +__collate_wcsnlen(const wchar_t *s, int len) +{ + int n = 0; + while (*s && n < len) { + s++; + n++; + } + return n; +} + +static struct __collate_st_subst * +substsearch(const wchar_t key, struct __collate_st_subst *tab, int n) +{ + int low = 0; + int high = n - 1; + int next, compar; + struct __collate_st_subst *p; + + while (low <= high) { + next = (low + high) / 2; + p = tab + next; + compar = key - p->val; + if (compar == 0) + return p; + if (compar > 0) + low = next + 1; + else + high = next - 1; + } + return NULL; +} + +__private_extern__ wchar_t * +__collate_substitute(const wchar_t *s, int which, locale_t loc) +{ + int dest_len, len, nlen; + int n, delta, nsubst; + wchar_t *dest_str = NULL; + const wchar_t *fp; + struct __collate_st_subst *subst, *match; + + if (s == NULL || *s == '\0') + return (__collate_wcsdup(L"")); + dest_len = wcslen(s); + nsubst = __collate_info->subst_count[which]; + if (nsubst <= 0) + return __collate_wcsdup(s); + subst = __collate_substitute_table[which]; + delta = dest_len / 4; + if (delta < 2) + delta = 2; + dest_str = (wchar_t *)malloc((dest_len += delta) * sizeof(wchar_t)); + if (dest_str == NULL) + __collate_err(EX_OSERR, __func__); + len = 0; + while (*s) { + if ((match = substsearch(*s, subst, nsubst)) != NULL) { + fp = match->str; + n = __collate_wcsnlen(fp, STR_LEN); + } else { + fp = s; + n = 1; + } + nlen = len + n; + if (dest_len <= nlen) { + dest_str = reallocf(dest_str, (dest_len = nlen + delta) * sizeof(wchar_t)); + if (dest_str == NULL) + __collate_err(EX_OSERR, __func__); + } + wcsncpy(dest_str + len, fp, n); + len += n; + s++; + } + dest_str[len] = 0; + return (dest_str); +} + +static struct __collate_st_chain_pri * +chainsearch(const wchar_t *key, int *len, locale_t loc) +{ + int low = 0; + int high = __collate_info->chain_count - 1; + int next, compar, l; + struct __collate_st_chain_pri *p; + struct __collate_st_chain_pri *tab = __collate_chain_pri_table; + + while (low <= high) { + next = (low + high) / 2; + p = tab + next; + compar = *key - *p->str; + if (compar == 0) { + l = __collate_wcsnlen(p->str, STR_LEN); + compar = wcsncmp(key, p->str, l); + if (compar == 0) { + *len = l; + return p; + } + } + if (compar > 0) + low = next + 1; + else + high = next - 1; + } + return NULL; +} + +static struct __collate_st_large_char_pri * +largesearch(const wchar_t key, locale_t loc) +{ + int low = 0; + int high = __collate_info->large_pri_count - 1; + int next, compar; + struct __collate_st_large_char_pri *p; + struct __collate_st_large_char_pri *tab = __collate_large_char_pri_table; + + while (low <= high) { + next = (low + high) / 2; + p = tab + next; + compar = key - p->val; + if (compar == 0) + return p; + if (compar > 0) + low = next + 1; + else + high = next - 1; + } + return NULL; +} + +__private_extern__ void +__collate_lookup_l(const wchar_t *t, int *len, int *prim, int *sec, locale_t loc) +{ + struct __collate_st_chain_pri *p2; + int l; + + *len = 1; + *prim = *sec = 0; + p2 = chainsearch(t, &l, loc); + /* use the chain if prim >= 0 */ + if (p2 && p2->pri[0] >= 0) { + *len = l; + *prim = p2->pri[0]; + *sec = p2->pri[1]; + return; + } + if (*t <= UCHAR_MAX) { + *prim = __collate_char_pri_table[*t].pri[0]; + *sec = __collate_char_pri_table[*t].pri[1]; + return; + } + if (__collate_info->large_pri_count > 0) { + struct __collate_st_large_char_pri *match; + match = largesearch(*t, loc); + if (match) { + *prim = match->pri.pri[0]; + *sec = match->pri.pri[1]; + return; + } + } + *prim = (l = __collate_info->undef_pri[0]) >= 0 ? l : *t - l; + *sec = (l = __collate_info->undef_pri[1]) >= 0 ? l : *t - l; +} + +/* + * This is only provided for programs (like grep) that are calling this + * private function. This will go away eventually. + */ +void +__collate_lookup(const unsigned char *t, int *len, int *prim, int *sec) +{ + locale_t loc = __current_locale(); + wchar_t *w = __collate_mbstowcs((const char *)t, loc); + int sverrno; + + __collate_lookup_l(w, len, prim, sec, loc); + sverrno = errno; + free(w); + errno = sverrno; +} + +__private_extern__ void +__collate_lookup_which(const wchar_t *t, int *len, int *pri, int which, locale_t loc) +{ + struct __collate_st_chain_pri *p2; + int p, l; + + *len = 1; + *pri = 0; + p2 = chainsearch(t, &l, loc); + if (p2) { + p = p2->pri[which]; + /* use the chain if pri >= 0 */ + if (p >= 0) { + *len = l; + *pri = p; + return; + } + } + if (*t <= UCHAR_MAX) { + *pri = __collate_char_pri_table[*t].pri[which]; + return; + } + if (__collate_info->large_pri_count > 0) { + struct __collate_st_large_char_pri *match; + match = largesearch(*t, loc); + if (match) { + *pri = match->pri.pri[which]; + return; + } + } + *pri = (l = __collate_info->undef_pri[which]) >= 0 ? l : *t - l; +} + +__private_extern__ wchar_t * +__collate_mbstowcs(const char *s, locale_t loc) +{ + static const mbstate_t initial; + mbstate_t st; + size_t len; + const char *ss; + wchar_t *wcs; + + ss = s; + st = initial; + if ((len = mbsrtowcs_l(NULL, &ss, 0, &st, loc)) == (size_t)-1) + return NULL; + if ((wcs = (wchar_t *)malloc((len + 1) * sizeof(wchar_t))) == NULL) + __collate_err(EX_OSERR, __func__); + st = initial; + mbsrtowcs_l(wcs, &s, len, &st, loc); + wcs[len] = 0; + + return (wcs); +} + +__private_extern__ wchar_t * +__collate_wcsdup(const wchar_t *s) +{ + size_t len = wcslen(s) + 1; + wchar_t *wcs; + + if ((wcs = (wchar_t *)malloc(len * sizeof(wchar_t))) == NULL) + __collate_err(EX_OSERR, __func__); + wcscpy(wcs, s); + return (wcs); +} + +__private_extern__ void +__collate_xfrm(const wchar_t *src, wchar_t **xf, locale_t loc) +{ + int pri, len; + size_t slen; + const wchar_t *t; + wchar_t *tt = NULL, *tr = NULL; + int direc, pass; + wchar_t *xfp; + struct __collate_st_info *info = __collate_info; + int sverrno; + + for(pass = 0; pass < COLL_WEIGHTS_MAX; pass++) + xf[pass] = NULL; + for(pass = 0; pass < info->directive_count; pass++) { + direc = info->directive[pass]; + if (pass == 0 || !(info->flags & COLLATE_SUBST_DUP)) { + sverrno = errno; + free(tt); + errno = sverrno; + tt = __collate_substitute(src, pass, loc); + } + if (direc & DIRECTIVE_BACKWARD) { + wchar_t *bp, *fp, c; + sverrno = errno; + free(tr); + errno = sverrno; + tr = __collate_wcsdup(tt ? tt : src); + bp = tr; + fp = tr + wcslen(tr) - 1; + while(bp < fp) { + c = *bp; + *bp++ = *fp; + *fp-- = c; + } + t = (const wchar_t *)tr; + } else if (tt) + t = (const wchar_t *)tt; + else + t = (const wchar_t *)src; + sverrno = errno; + if ((xf[pass] = (wchar_t *)malloc(sizeof(wchar_t) * (wcslen(t) + 1))) == NULL) { + errno = sverrno; + slen = 0; + goto end; + } + errno = sverrno; + xfp = xf[pass]; + if (direc & DIRECTIVE_POSITION) { + while(*t) { + __collate_lookup_which(t, &len, &pri, pass, loc); + t += len; + if (pri <= 0) { + if (pri < 0) { + errno = EINVAL; + slen = 0; + goto end; + } + pri = COLLATE_MAX_PRIORITY; + } + *xfp++ = pri; + } + } else { + while(*t) { + __collate_lookup_which(t, &len, &pri, pass, loc); + t += len; + if (pri <= 0) { + if (pri < 0) { + errno = EINVAL; + slen = 0; + goto end; + } + continue; + } + *xfp++ = pri; + } + } + *xfp = 0; + } + end: + sverrno = errno; + free(tt); + free(tr); + errno = sverrno; +} + +__private_extern__ void +__collate_err(int ex, const char *f) +{ + const char *s; + int serrno = errno; + + s = _getprogname(); + _write(STDERR_FILENO, s, strlen(s)); + _write(STDERR_FILENO, ": ", 2); + s = f; + _write(STDERR_FILENO, s, strlen(s)); + _write(STDERR_FILENO, ": ", 2); + s = strerror(serrno); + _write(STDERR_FILENO, s, strlen(s)); + _write(STDERR_FILENO, "\n", 1); + exit(ex); +} + +/* + * __collate_collating_symbol takes the multibyte string specified by + * src and slen, and using ps, converts that to a wide character. Then + * it is checked to verify it is a collating symbol, and then copies + * it to the wide character string specified by dst and dlen (the + * results are not null terminated). The length of the wide characters + * copied to dst is returned if successful. Zero is returned if no such + * collating symbol exists. (size_t)-1 is returned if there are wide-character + * conversion errors, if the length of the converted string is greater that + * STR_LEN or if dlen is too small. It is up to the calling routine to + * preserve the mbstate_t structure as needed. + */ +__private_extern__ size_t +__collate_collating_symbol(wchar_t *dst, size_t dlen, const char *src, size_t slen, mbstate_t *ps, locale_t loc) +{ + wchar_t wname[STR_LEN]; + wchar_t w, *wp; + size_t len, l; + + /* POSIX locale */ + if (loc->__collate_load_error) { + if (dlen < 1) + return (size_t)-1; + if (slen != 1 || !isascii(*src)) + return 0; + *dst = *src; + return 1; + } + for(wp = wname, len = 0; slen > 0; len++) { + l = mbrtowc_l(&w, src, slen, ps, loc); + if (l == (size_t)-1 || l == (size_t)-2) + return (size_t)-1; + if (l == 0) + break; + if (len >= STR_LEN) + return -1; + *wp++ = w; + src += l; + slen = (long)slen - (long)l; + } + if (len == 0 || len > dlen) + return (size_t)-1; + if (len == 1) { + if (*wname <= UCHAR_MAX) { + if (__collate_char_pri_table[*wname].pri[0] >= 0) { + if (dlen > 0) + *dst = *wname; + return 1; + } + return 0; + } else if (__collate_info->large_pri_count > 0) { + struct __collate_st_large_char_pri *match; + match = largesearch(*wname, loc); + if (match && match->pri.pri[0] >= 0) { + if (dlen > 0) + *dst = *wname; + return 1; + } + } + return 0; + } + *wp = 0; + if (__collate_info->chain_count > 0) { + struct __collate_st_chain_pri *match; + int ll; + match = chainsearch(wname, &ll, loc); + if (match) { + if (ll < dlen) + dlen = ll; + wcsncpy(dst, wname, dlen); + return ll; + } + } + return 0; +} + +/* + * __collate_equiv_class returns the equivalence class number for the symbol + * specified by src and slen, using ps to convert from multi-byte to wide + * character. Zero is returned if the symbol is not in an equivalence + * class. -1 is returned if there are wide character conversion error, + * if there are any greater-than-8-bit characters or if a multi-byte symbol + * is greater or equal to STR_LEN in length. It is up to the calling + * routine to preserve the mbstate_t structure as needed. + */ +__private_extern__ int +__collate_equiv_class(const char *src, size_t slen, mbstate_t *ps, locale_t loc) +{ + wchar_t wname[STR_LEN]; + wchar_t w, *wp; + size_t len, l; + int e; + + /* POSIX locale */ + if (loc->__collate_load_error) + return 0; + for(wp = wname, len = 0; slen > 0; len++) { + l = mbrtowc_l(&w, src, slen, ps, loc); + if (l == (size_t)-1 || l == (size_t)-2) + return -1; + if (l == 0) + break; + if (len >= STR_LEN) + return -1; + *wp++ = w; + src += l; + slen = (long)slen - (long)l; + } + if (len == 0) + return -1; + if (len == 1) { + e = -1; + if (*wname <= UCHAR_MAX) + e = __collate_char_pri_table[*wname].pri[0]; + else if (__collate_info->large_pri_count > 0) { + struct __collate_st_large_char_pri *match; + match = largesearch(*wname, loc); + if (match) + e = match->pri.pri[0]; + } + if (e == 0) + return IGNORE_EQUIV_CLASS; + return e > 0 ? e : 0; + } + *wp = 0; + if (__collate_info->chain_count > 0) { + struct __collate_st_chain_pri *match; + int ll; + match = chainsearch(wname, &ll, loc); + if (match) { + e = match->pri[0]; + if (e == 0) + return IGNORE_EQUIV_CLASS; + return e < 0 ? -e : e; + } + } + return 0; +} + +/* + * __collate_equiv_match tries to match any single or multi-character symbol + * in equivalence class equiv_class in the multi-byte string specified by src + * and slen. If start is non-zero, it is taken to be the first (pre-converted) + * wide character. Subsequence wide characters, if needed, will use ps in + * the conversion. On a successful match, the length of the matched string + * is returned (including the start character). If dst is non-NULL, the + * matched wide-character string is copied to dst, a wide character array of + * length dlen (the results are not zero-terminated). If rlen is non-NULL, + * the number of character in src actually used is returned. Zero is + * returned by __collate_equiv_match if there is no match. (size_t)-1 is + * returned on error: if there were conversion errors or if dlen is too small + * to accept the results. On no match or error, ps is restored to its incoming + * state. + */ +size_t +__collate_equiv_match(int equiv_class, wchar_t *dst, size_t dlen, wchar_t start, const char *src, size_t slen, mbstate_t *ps, size_t *rlen, locale_t loc) +{ + wchar_t w; + size_t len, l, clen; + int i; + wchar_t buf[STR_LEN], *wp; + mbstate_t save; + const char *s = src; + size_t sl = slen; + struct __collate_st_chain_pri *ch = NULL; + + /* POSIX locale */ + if (loc->__collate_load_error) + return (size_t)-1; + if (equiv_class == IGNORE_EQUIV_CLASS) + equiv_class = 0; + if (ps) + save = *ps; + wp = buf; + len = clen = 0; + if (start) { + *wp++ = start; + len = 1; + } + /* convert up to the max chain length */ + while(sl > 0 && len < __collate_info->chain_max_len) { + l = mbrtowc_l(&w, s, sl, ps, loc); + if (l == (size_t)-1 || l == (size_t)-2 || l == 0) + break; + *wp++ = w; + s += l; + clen += l; + sl -= l; + len++; + } + *wp = 0; + if (len > 1 && (ch = chainsearch(buf, &i, loc)) != NULL) { + int e = ch->pri[0]; + if (e < 0) + e = -e; + if (e == equiv_class) + goto found; + } + /* try single character */ + i = 1; + if (*buf <= UCHAR_MAX) { + if (equiv_class == __collate_char_pri_table[*buf].pri[0]) + goto found; + } else if (__collate_info->large_pri_count > 0) { + struct __collate_st_large_char_pri *match; + match = largesearch(*buf, loc); + if (match && equiv_class == match->pri.pri[0]) + goto found; + } + /* no match */ + if (ps) + *ps = save; + return 0; +found: + /* if we converted more than we used, restore to initial and reconvert + * up to what did match */ + if (i < len) { + len = i; + if (ps) + *ps = save; + if (start) + i--; + clen = 0; + while(i-- > 0) { + l = mbrtowc_l(&w, src, slen, ps, loc); + src += l; + clen += l; + slen -= l; + } + } + if (dst) { + if (dlen < len) { + if (ps) + *ps = save; + return (size_t)-1; + } + for(wp = buf; len > 0; len--) + *dst++ = *wp++; + } + if (rlen) + *rlen = clen; + return len; +} + +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN +static void +wntohl(wchar_t *str, int len) +{ + for(; *str && len > 0; str++, len--) + *str = ntohl(*str); +} +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ + +#ifdef COLLATE_DEBUG +static char * +show(int c) +{ + static char buf[5]; + + if (c >=32 && c <= 126) + sprintf(buf, "'%c' ", c); + else + sprintf(buf, "\\x{%02x}", c); + return buf; +} + +static char * +showwcs(const wchar_t *t, int len) +{ + static char buf[64]; + char *cp = buf; + + for(; *t && len > 0; len--, t++) { + if (*t >=32 && *t <= 126) + *cp++ = *t; + else { + sprintf(cp, "\\x{%02x}", *t); + cp += strlen(cp); + } + } + *cp = 0; + return buf; +} + +void +__collate_print_tables() +{ + int i, z; + locale_t loc = __current_locale(); + + printf("Info: p=%d s=%d f=0x%02x m=%d dc=%d up=%d us=%d pc=%d sc=%d cc=%d lc=%d\n", + __collate_info->directive[0], __collate_info->directive[1], + __collate_info->flags, __collate_info->chain_max_len, + __collate_info->directive_count, + __collate_info->undef_pri[0], __collate_info->undef_pri[1], + __collate_info->subst_count[0], __collate_info->subst_count[1], + __collate_info->chain_count, __collate_info->large_pri_count); + for(z = 0; z < __collate_info->directive_count; z++) { + if (__collate_info->subst_count[z] > 0) { + struct __collate_st_subst *p2 = __collate_substitute_table[z]; + if (z == 0 && (__collate_info->flags & COLLATE_SUBST_DUP)) + printf("Both substitute tables:\n"); + else + printf("Substitute table %d:\n", z); + for (i = __collate_info->subst_count[z]; i-- > 0; p2++) + printf("\t%s --> \"%s\"\n", + show(p2->val), + showwcs(p2->str, STR_LEN)); + } + } + if (__collate_info->chain_count > 0) { + printf("Chain priority table:\n"); + struct __collate_st_chain_pri *p2 = __collate_chain_pri_table; + for (i = __collate_info->chain_count; i-- > 0; p2++) { + printf("\t\"%s\" :", showwcs(p2->str, STR_LEN)); + for(z = 0; z < __collate_info->directive_count; z++) + printf(" %d", p2->pri[z]); + putchar('\n'); + } + } + printf("Char priority table:\n"); + { + struct __collate_st_char_pri *p2 = __collate_char_pri_table; + for (i = 0; i < UCHAR_MAX + 1; i++, p2++) { + printf("\t%s :", show(i)); + for(z = 0; z < __collate_info->directive_count; z++) + printf(" %d", p2->pri[z]); + putchar('\n'); + } + } + if (__collate_info->large_pri_count > 0) { + struct __collate_st_large_char_pri *p2 = __collate_large_char_pri_table; + printf("Large priority table:\n"); + for (i = __collate_info->large_pri_count; i-- > 0; p2++) { + printf("\t%s :", show(p2->val)); + for(z = 0; z < __collate_info->directive_count; z++) + printf(" %d", p2->pri.pri[z]); + putchar('\n'); + } + } +} +#endif diff --git a/locale/collate.h b/locale/collate.h new file mode 100644 index 0000000..494e231 --- /dev/null +++ b/locale/collate.h @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 1995 Alex Tatmanjants + * at Electronni Visti IA, Kiev, Ukraine. + * 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 ``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. + * + * $FreeBSD: src/lib/libc/locale/collate.h,v 1.14 2002/08/30 20:26:02 ache Exp $ + */ + +#ifndef _COLLATE_H_ +#define _COLLATE_H_ + +#include +#ifndef __LIBC__ +#include +#endif /* !__LIBC__ */ +#include + +#define STR_LEN 10 +#define TABLE_SIZE 100 +#define COLLATE_VERSION "1.0\n" +#define COLLATE_VERSION1_1 "1.1\n" +#define COLLATE_VERSION1_1A "1.1A\n" +/* see discussion in string/FreeBSD/strxfrm for this value */ +#define COLLATE_MAX_PRIORITY ((1 << 24) - 1) + +#define DIRECTIVE_UNDEF 0x00 +#define DIRECTIVE_FORWARD 0x01 +#define DIRECTIVE_BACKWARD 0x02 +#define DIRECTIVE_POSITION 0x04 + +#define DIRECTIVE_DIRECTION_MASK (DIRECTIVE_FORWARD | DIRECTIVE_BACKWARD) + +#define COLLATE_SUBST_DUP 0x0001 + +#define IGNORE_EQUIV_CLASS 1 + +struct __collate_st_info { + __uint8_t directive[COLL_WEIGHTS_MAX]; + __uint8_t flags; +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN + __uint8_t directive_count:4; + __uint8_t chain_max_len:4; +#else + __uint8_t chain_max_len:4; + __uint8_t directive_count:4; +#endif + __int32_t undef_pri[COLL_WEIGHTS_MAX]; + __int32_t subst_count[COLL_WEIGHTS_MAX]; + __int32_t chain_count; + __int32_t large_pri_count; +}; + +struct __collate_st_char_pri { + __int32_t pri[COLL_WEIGHTS_MAX]; +}; +struct __collate_st_chain_pri { + __darwin_wchar_t str[STR_LEN]; + __int32_t pri[COLL_WEIGHTS_MAX]; +}; +struct __collate_st_large_char_pri { + __int32_t val; + struct __collate_st_char_pri pri; +}; +struct __collate_st_subst { + __int32_t val; + __darwin_wchar_t str[STR_LEN]; +}; + +#ifndef __LIBC__ +extern int __collate_load_error; +extern int __collate_substitute_nontrivial; +#define __collate_char_pri_table (*__collate_char_pri_table_ptr) +extern struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; +extern struct __collate_st_chain_pri *__collate_chain_pri_table; +extern __int32_t *__collate_chain_equiv_table; +extern struct __collate_st_info __collate_info; +#endif /* !__LIBC__ */ + +__BEGIN_DECLS +#ifdef __LIBC__ +__darwin_wchar_t *__collate_mbstowcs(const char *, locale_t); +__darwin_wchar_t *__collate_wcsdup(const __darwin_wchar_t *); +__darwin_wchar_t *__collate_substitute(const __darwin_wchar_t *, int, locale_t); +int __collate_load_tables(const char *, locale_t); +void __collate_lookup_l(const __darwin_wchar_t *, int *, int *, int *, locale_t); +void __collate_lookup_which(const __darwin_wchar_t *, int *, int *, int, locale_t); +void __collate_xfrm(const __darwin_wchar_t *, __darwin_wchar_t **, locale_t); +int __collate_range_cmp(__darwin_wchar_t, __darwin_wchar_t, locale_t); +size_t __collate_collating_symbol(__darwin_wchar_t *, size_t, const char *, size_t, __darwin_mbstate_t *, locale_t); +int __collate_equiv_class(const char *, size_t, __darwin_mbstate_t *, locale_t); +size_t __collate_equiv_match(int, __darwin_wchar_t *, size_t, __darwin_wchar_t, const char *, size_t, __darwin_mbstate_t *, size_t *, locale_t); +#else /* !__LIBC__ */ +void __collate_lookup(const unsigned char *, int *, int *, int *); +#endif /* __LIBC__ */ +#ifdef COLLATE_DEBUG +void __collate_print_tables(void); +#endif +__END_DECLS + +#endif /* !_COLLATE_H_ */ diff --git a/locale/collcmp-fbsd.c b/locale/collcmp-fbsd.c new file mode 100644 index 0000000..ee6a383 --- /dev/null +++ b/locale/collcmp-fbsd.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 1996 by Andrey A. Chernov, Moscow, Russia. + * 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 ``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/collcmp.c,v 1.17 2003/08/03 19:28:23 ache Exp $"); + +#include +#include +#include "collate.h" + +/* + * Compare two characters using collate + */ + +__private_extern__ int +__collate_range_cmp(c1, c2, loc) + wchar_t c1, c2; + locale_t loc; +{ + static wchar_t s1[2], s2[2]; + + s1[0] = c1; + s2[0] = c2; + return (wcscoll_l(s1, s2, loc)); +} diff --git a/locale/ctype.3 b/locale/ctype.3 new file mode 100644 index 0000000..eb1a4d7 --- /dev/null +++ b/locale/ctype.3 @@ -0,0 +1,162 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd March 30, 2004 +.Dt CTYPE 3 +.Os +.Sh NAME +.Nm digittoint , +.Nm isalnum , +.Nm isalpha , +.Nm isascii , +.Nm isblank , +.Nm iscntrl , +.Nm isdigit , +.Nm isgraph , +.Nm ishexnumber , +.Nm isideogram , +.Nm islower , +.Nm isnumber , +.Nm isphonogram , +.Nm isprint , +.Nm ispunct , +.Nm isrune , +.Nm isspace , +.Nm isspecial , +.Nm isupper , +.Nm isxdigit , +.Nm toascii , +.Nm tolower , +.Nm toupper +.Nd character classification macros +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn digittoint "int c" +.Ft int +.Fn isalnum "int c" +.Ft int +.Fn isalpha "int c" +.Ft int +.Fn isascii "int c" +.Ft int +.Fn iscntrl "int c" +.Ft int +.Fn isdigit "int c" +.Ft int +.Fn isgraph "int c" +.Ft int +.Fn ishexnumber "int c" +.Ft int +.Fn isideogram "int c" +.Ft int +.Fn islower "int c" +.Ft int +.Fn isnumber "int c" +.Ft int +.Fn isphonogram "int c" +.Ft int +.Fn isspecial "int c" +.Ft int +.Fn isprint "int c" +.Ft int +.Fn ispunct "int c" +.Ft int +.Fn isrune "int c" +.Ft int +.Fn isspace "int c" +.Ft int +.Fn isupper "int c" +.Ft int +.Fn isxdigit "int c" +.Ft int +.Fn toascii "int c" +.Ft int +.Fn tolower "int c" +.Ft int +.Fn toupper "int c" +.Sh DESCRIPTION +The above functions perform character tests and conversions on the integer +.Fa c . +They are available as macros, defined in the include file +.In ctype.h , +or as true functions in the C library. +See the specific manual pages for more information. +.Pp +Extended locale versions of these functions are documented in +.Xr ctype_l 3 . +See +.Xr xlocale 3 +for more information. +.Sh SEE ALSO +.Xr digittoint 3 , +.Xr isalnum 3 , +.Xr isalpha 3 , +.Xr isascii 3 , +.Xr isblank 3 , +.Xr iscntrl 3 , +.Xr isdigit 3 , +.Xr isgraph 3 , +.Xr isideogram 3 , +.Xr islower 3 , +.Xr isphonogram 3 , +.Xr isprint 3 , +.Xr ispunct 3 , +.Xr isrune 3 , +.Xr isspace 3 , +.Xr isspecial 3 , +.Xr isupper 3 , +.Xr isxdigit 3 , +.Xr toascii 3 , +.Xr tolower 3 , +.Xr toupper 3 , +.Xr wctype 3 , +.Xr ascii 7 , +.Xr ctype_l 3 +.Sh STANDARDS +These functions, except for +.Fn digittoint , +.Fn isascii , +.Fn ishexnumber , +.Fn isideogram , +.Fn isnumber , +.Fn isphonogram , +.Fn isrune , +.Fn isspecial +and +.Fn toascii , +conform to +.St -isoC . diff --git a/locale/ctype_l.3 b/locale/ctype_l.3 index bf5fb20..7e380b4 100644 --- a/locale/ctype_l.3 +++ b/locale/ctype_l.3 @@ -66,49 +66,115 @@ .In ctype.h .In xlocale.h .Ft int -.Fn digittoint_l "int c" "locale_t loc" -.Ft int -.Fn isalnum_l "int c" "locale_t loc" -.Ft int -.Fn isalpha_l "int c" "locale_t loc" -.Ft int -.Fn isascii_l "int c" "locale_t loc" -.Ft int -.Fn iscntrl_l "int c" "locale_t loc" -.Ft int -.Fn isdigit_l "int c" "locale_t loc" -.Ft int -.Fn isgraph_l "int c" "locale_t loc" -.Ft int -.Fn ishexnumber_l "int c" "locale_t loc" -.Ft int -.Fn isideogram_l "int c" "locale_t loc" -.Ft int -.Fn islower_l "int c" "locale_t loc" -.Ft int -.Fn isnumber_l "int c" "locale_t loc" -.Ft int -.Fn isphonogram_l "int c" "locale_t loc" -.Ft int -.Fn isspecial_l "int c" "locale_t loc" -.Ft int -.Fn isprint_l "int c" "locale_t loc" -.Ft int -.Fn ispunct_l "int c" "locale_t loc" -.Ft int -.Fn isrune_l "int c" "locale_t loc" -.Ft int -.Fn isspace_l "int c" "locale_t loc" -.Ft int -.Fn isupper_l "int c" "locale_t loc" -.Ft int -.Fn isxdigit_l "int c" "locale_t loc" -.Ft int -.Fn toascii_l "int c" "locale_t loc" -.Ft int -.Fn tolower_l "int c" "locale_t loc" -.Ft int -.Fn toupper_l "int c" "locale_t loc" +.Fo digittoint_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isalnum_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isalpha_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isascii_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo iscntrl_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isdigit_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isgraph_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo ishexnumber_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isideogram_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo islower_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isnumber_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isphonogram_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isprint_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo ispunct_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isrune_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isspace_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isspecial_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isupper_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isxdigit_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo toascii_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo tolower_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo toupper_l +.Fa "int c" +.Fa "locale_t loc" +.Fc .Sh DESCRIPTION These functions are extended locale versions of the corresponding functions in diff --git a/locale/digittoint.3 b/locale/digittoint.3 new file mode 100644 index 0000000..eecd289 --- /dev/null +++ b/locale/digittoint.3 @@ -0,0 +1,82 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd April 6, 2001 +.Dt DIGITTOINT 3 +.Os +.Sh NAME +.Nm digittoint , +.Nm digittoint_l +.Nd convert a numeric character to its integer value +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fo digittoint +.Fa "int c" +.Fc +.In xlocale.h +.In ctype.h +.Ft int +.Fo digittoint_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn digittoint +function converts a numeric character to its corresponding integer value. +The character can be any decimal digit or hexadecimal digit. +With hexadecimal characters, the case of the values does not matter. +.Pp +While the +.Fn digittoint +function uses the current locale, the +.Fn digittoint_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn digittoint +function always returns an integer from the range of 0 to 15. +If the given character was not a digit as defined by +.Xr isxdigit 3 , +the function will return 0. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isdigit 3 , +.Xr isxdigit 3 , +.Xr xlocale 3 diff --git a/locale/duplocale.3 b/locale/duplocale.3 index 9f405cd..76dd757 100644 --- a/locale/duplocale.3 +++ b/locale/duplocale.3 @@ -29,8 +29,8 @@ on error. Duplicated locales should be freed with .Xr freelocale 3 . .Sh SEE ALSO -.Xr xlocale 3 , .Xr freelocale 3 , .Xr newlocale 3 , .Xr querylocale 3 , -.Xr uselocale 3 +.Xr uselocale 3 , +.Xr xlocale 3 diff --git a/locale/euc-fbsd.c b/locale/euc-fbsd.c new file mode 100644 index 0000000..0ce9bcc --- /dev/null +++ b/locale/euc-fbsd.c @@ -0,0 +1,277 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#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 int _EUC_mbsinit(const mbstate_t *, locale_t); +static size_t _EUC_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, + locale_t); + +typedef struct { + int count[4]; + wchar_t bits[4]; + wchar_t mask; +} _EucInfo; + +typedef struct { + wchar_t ch; + int set; + int want; +} _EucState; + +/* This will be called by the XL_RELEASE() macro to free the extra storage */ +static void +_EUC_free_extra(struct __xlocale_st_runelocale *xrl) +{ + free(xrl->_CurrentRuneLocale.__variable); +} + +__private_extern__ int +_EUC_init(struct __xlocale_st_runelocale *xrl) +{ + _EucInfo *ei; + int x, new__mb_cur_max; + char *v, *e; + _RuneLocale *rl = &xrl->_CurrentRuneLocale; + + if (rl->__variable == NULL) + return (EFTYPE); + + v = (char *)rl->__variable; + + while (*v == ' ' || *v == '\t') + ++v; + + if ((ei = malloc(sizeof(_EucInfo))) == NULL) + return (errno == 0 ? ENOMEM : errno); + + new__mb_cur_max = 0; + for (x = 0; x < 4; ++x) { + ei->count[x] = (int)strtol(v, &e, 0); + if (v == e || !(v = e)) { + free(ei); + return (EFTYPE); + } + if (new__mb_cur_max < ei->count[x]) + new__mb_cur_max = ei->count[x]; + while (*v == ' ' || *v == '\t') + ++v; + ei->bits[x] = (int)strtol(v, &e, 0); + if (v == e || !(v = e)) { + free(ei); + return (EFTYPE); + } + while (*v == ' ' || *v == '\t') + ++v; + } + ei->mask = (int)strtol(v, &e, 0); + if (v == e || !(v = e)) { + free(ei); + return (EFTYPE); + } + 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; + return (0); +} + +static int +_EUC_mbsinit(const mbstate_t *ps, locale_t loc) +{ + + return (ps == NULL || ((const _EucState *)ps)->want == 0); +} + +#define _SS2 0x008e +#define _SS3 0x008f + +#define GR_BITS 0x80808080 /* XXX: to be fixed */ + +static __inline int +_euc_set(u_int c) +{ + c &= 0xff; + return ((c & 0x80) ? c == _SS3 ? 3 : c == _SS2 ? 2 : 1 : 0); +} + +static size_t +_EUC_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t loc) +{ + _EucState *es; + int i, set, want; + wchar_t wc; + const char *os; + struct __xlocale_st_runelocale *rl = loc->__lc_ctype; + _EucInfo *CEI = (_EucInfo *)rl->_CurrentRuneLocale.__variable; + + es = (_EucState *)ps; + + if (es->want < 0 || es->want > rl->__mb_cur_max || es->set < 0 || + es->set > 3) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + os = s; + + if (es->want == 0) { + want = CEI->count[set = _euc_set(*s)]; + if (set == 2 || set == 3) { + --want; + if (--n == 0) { + /* Incomplete multibyte sequence */ + es->set = set; + es->want = want; + es->ch = 0; + return ((size_t)-2); + } + ++s; + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + } + wc = (unsigned char)*s++; + } else { + set = es->set; + want = es->want; + wc = es->ch; + } + for (i = (es->want == 0) ? 1 : 0; i < MIN(want, n); i++) { + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (wc << 8) | (unsigned char)*s++; + } + if (i < want) { + /* Incomplete multibyte sequence */ + es->set = set; + es->want = want - i; + es->ch = wc; + return ((size_t)-2); + } + wc = (wc & ~CEI->mask) | CEI->bits[set]; + if (pwc != NULL) + *pwc = wc; + es->want = 0; + return (wc == L'\0' ? 0 : s - os); +} + +static size_t +_EUC_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, + locale_t loc) +{ + _EucState *es; + wchar_t m, nm; + int i, len; + _EucInfo *CEI = (_EucInfo *)loc->__lc_ctype->_CurrentRuneLocale.__variable; + + es = (_EucState *)ps; + + if (es->want != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + + m = wc & CEI->mask; + nm = wc & ~m; + + if (m == CEI->bits[1]) { +CodeSet1: + /* Codeset 1: The first byte must have 0x80 in it. */ + i = len = CEI->count[1]; + while (i-- > 0) + *s++ = (nm >> (i << 3)) | 0x80; + } else { + if (m == CEI->bits[0]) + i = len = CEI->count[0]; + else if (m == CEI->bits[2]) { + i = len = CEI->count[2]; + *s++ = _SS2; + --i; + /* SS2 designates G2 into GR */ + nm |= GR_BITS; + } else if (m == CEI->bits[3]) { + i = len = CEI->count[3]; + *s++ = _SS3; + --i; + /* SS3 designates G3 into GR */ + nm |= GR_BITS; + } else + goto CodeSet1; /* Bletch */ + while (i-- > 0) + *s++ = (nm >> (i << 3)) & 0xff; + } + return (len); +} diff --git a/locale/euc.5 b/locale/euc.5 new file mode 120000 index 0000000..9e5aafd --- /dev/null +++ b/locale/euc.5 @@ -0,0 +1 @@ +./euc.5 \ No newline at end of file diff --git a/locale/fix_grouping-fbsd.c b/locale/fix_grouping-fbsd.c new file mode 100644 index 0000000..180c800 --- /dev/null +++ b/locale/fix_grouping-fbsd.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2001 Alexey Zelkin + * 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/locale/fix_grouping.c,v 1.8 2003/06/26 10:46:16 phantom Exp $"); + +#include +#include +#include + +static const char nogrouping[] = { '\0' }; +static const char __nogrouping[] = { CHAR_MAX, '\0' }; + +/* + * Internal helper used to convert grouping sequences from string + * representation into POSIX specified form, i.e. + * + * "3;3;-1" -> "\003\003\177\000" + */ + +const char * +__fix_locale_grouping_str(const char *str) +{ + char *src, *dst; + char n; + + if (str == NULL || *str == '\0') { + return nogrouping; + } + + for (src = (char*)str, dst = (char*)str; *src != '\0'; src++) { + + /* input string examples: "3;3", "3;2;-1" */ + if (*src == ';') + continue; + + if (*src == '-' && *(src+1) == '1') { + *dst++ = CHAR_MAX; + src++; + continue; + } + + if (!isdigit((unsigned char)*src)) { + /* broken grouping string */ + return nogrouping; + } + + /* assume all numbers <= 99 */ + n = *src - '0'; + if (isdigit((unsigned char)*(src+1))) { + src++; + n *= 10; + n += *src - '0'; + } + + *dst = n; + /* NOTE: assume all input started with "0" as 'no grouping' */ + if (*dst == '\0') + return (dst == (char*)str) ? nogrouping : str; + dst++; + } + *dst = '\0'; + return str; +} + +/* + * internal helpers for SUSv3 compatibility. Since "nogrouping" needs to + * be just an empty string, we provide a routine to substitute __nogrouping + * so we don't have to modify code that expects CHAR_MAX. + */ +__private_extern__ const char * +__fix_nogrouping(const char *str) +{ + return ((str == NULL || *str == '\0') ? __nogrouping : str); +} diff --git a/locale/freelocale.3 b/locale/freelocale.3 index ad45945..3cfcc10 100644 --- a/locale/freelocale.3 +++ b/locale/freelocale.3 @@ -23,8 +23,8 @@ or is or .Dv LC_GLOBAL_LOCALE . .Sh SEE ALSO -.Xr xlocale 3 , .Xr duplocale 3 , .Xr newlocale 3 , .Xr querylocale 3 , -.Xr uselocale 3 +.Xr uselocale 3 , +.Xr xlocale 3 diff --git a/locale/gb18030-fbsd.c b/locale/gb18030-fbsd.c new file mode 100644 index 0000000..b154c4c --- /dev/null +++ b/locale/gb18030-fbsd.c @@ -0,0 +1,221 @@ +/*- + * 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. + */ +/* + * PRC National Standard GB 18030-2000 encoding of Chinese text. + * + * See gb18030(5) for details. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/gb18030.c,v 1.6 2004/05/12 14:09:04 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include "mblocal.h" + +#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 int _GB18030_mbsinit(const mbstate_t *, locale_t); +static size_t _GB18030_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); + +typedef struct { + int count; + u_char bytes[4]; +} _GB18030State; + +__private_extern__ int +_GB18030_init(struct __xlocale_st_runelocale *xrl) +{ + + xrl->__mbrtowc = _GB18030_mbrtowc; + xrl->__wcrtomb = _GB18030_wcrtomb; + xrl->__mbsinit = _GB18030_mbsinit; + xrl->__mb_cur_max = GB18030_MB_CUR_MAX; + + return (0); +} + +static int +_GB18030_mbsinit(const mbstate_t *ps, locale_t loc) +{ + + return (ps == NULL || ((const _GB18030State *)ps)->count == 0); +} + +static size_t +_GB18030_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, + size_t n, mbstate_t * __restrict ps, locale_t loc) +{ + _GB18030State *gs; + wchar_t wch; + int ch, len, ocount; + size_t ncopy; + + gs = (_GB18030State *)ps; + + if (gs->count < 0 || gs->count > sizeof(gs->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + ncopy = MIN(MIN(n, GB18030_MB_CUR_MAX), sizeof(gs->bytes) - gs->count); + memcpy(gs->bytes + gs->count, s, ncopy); + ocount = gs->count; + gs->count += ncopy; + s = (char *)gs->bytes; + n = gs->count; + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + /* + * Single byte: [00-7f] + * Two byte: [81-fe][40-7e,80-fe] + * Four byte: [81-fe][30-39][81-fe][30-39] + */ + ch = (unsigned char)*s++; + if (ch <= 0x7f) { + len = 1; + wch = ch; + } else if (ch >= 0x81 && ch <= 0xfe) { + wch = ch; + if (n < 2) + return ((size_t)-2); + ch = (unsigned char)*s++; + if ((ch >= 0x40 && ch <= 0x7e) || (ch >= 0x80 && ch <= 0xfe)) { + wch = (wch << 8) | ch; + len = 2; + } else if (ch >= 0x30 && ch <= 0x39) { + /* + * Strip high bit off the wide character we will + * eventually output so that it is positive when + * cast to wint_t on 32-bit twos-complement machines. + */ + wch = ((wch & 0x7f) << 8) | ch; + if (n < 3) + return ((size_t)-2); + ch = (unsigned char)*s++; + if (ch < 0x81 || ch > 0xfe) + goto ilseq; + wch = (wch << 8) | ch; + if (n < 4) + return ((size_t)-2); + ch = (unsigned char)*s++; + if (ch < 0x30 || ch > 0x39) + goto ilseq; + wch = (wch << 8) | ch; + len = 4; + } else + goto ilseq; + } else + goto ilseq; + + if (pwc != NULL) + *pwc = wch; + gs->count = 0; + return (wch == L'\0' ? 0 : len - ocount); +ilseq: + errno = EILSEQ; + return ((size_t)-1); +} + +static size_t +_GB18030_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +{ + _GB18030State *gs; + size_t len; + int c; + + gs = (_GB18030State *)ps; + + if (gs->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if ((wc & ~0x7fffffff) != 0) + goto ilseq; + if (wc & 0x7f000000) { + /* Replace high bit that mbrtowc() removed. */ + wc |= 0x80000000; + c = (wc >> 24) & 0xff; + if (c < 0x81 || c > 0xfe) + goto ilseq; + *s++ = c; + c = (wc >> 16) & 0xff; + if (c < 0x30 || c > 0x39) + goto ilseq; + *s++ = c; + c = (wc >> 8) & 0xff; + if (c < 0x81 || c > 0xfe) + goto ilseq; + *s++ = c; + c = wc & 0xff; + if (c < 0x30 || c > 0x39) + goto ilseq; + *s++ = c; + len = 4; + } else if (wc & 0x00ff0000) + goto ilseq; + else if (wc & 0x0000ff00) { + c = (wc >> 8) & 0xff; + if (c < 0x81 || c > 0xfe) + goto ilseq; + *s++ = c; + c = wc & 0xff; + if (c < 0x40 || c == 0x7f || c == 0xff) + goto ilseq; + *s++ = c; + len = 2; + } else if (wc <= 0x7f) { + *s++ = wc; + len = 1; + } else + goto ilseq; + + return (len); +ilseq: + errno = EILSEQ; + return ((size_t)-1); +} diff --git a/locale/gb18030.5 b/locale/gb18030.5 new file mode 120000 index 0000000..f277ba1 --- /dev/null +++ b/locale/gb18030.5 @@ -0,0 +1 @@ +./gb18030.5 \ No newline at end of file diff --git a/locale/gb2312-fbsd.c b/locale/gb2312-fbsd.c new file mode 100644 index 0000000..a632e07 --- /dev/null +++ b/locale/gb2312-fbsd.c @@ -0,0 +1,157 @@ +/*- + * Copyright (c) 2004 Tim J. Robbins. All rights reserved. + * Copyright (c) 2003 David Xu + * 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/locale/gb2312.c,v 1.8 2004/05/12 14:09:04 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include "mblocal.h" + +#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); + +typedef struct { + int count; + u_char bytes[2]; +} _GB2312State; + +__private_extern__ int +_GB2312_init(struct __xlocale_st_runelocale *xrl) +{ + + xrl->__mbrtowc = _GB2312_mbrtowc; + xrl->__wcrtomb = _GB2312_wcrtomb; + xrl->__mbsinit = _GB2312_mbsinit; + xrl->__mb_cur_max = GB2312_MB_CUR_MAX; + return (0); +} + +static int +_GB2312_mbsinit(const mbstate_t *ps, locale_t loc) +{ + + return (ps == NULL || ((const _GB2312State *)ps)->count == 0); +} + +static __inline int +_GB2312_check(const char *str, size_t n) +{ + const u_char *s = (const u_char *)str; + + if (n == 0) + /* Incomplete multibyte sequence */ + return (-2); + if (s[0] >= 0xa1 && s[0] <= 0xfe) { + if (n < 2) + /* Incomplete multibyte sequence */ + return (-2); + if (s[1] < 0xa1 || s[1] > 0xfe) + /* Invalid multibyte sequence */ + return (-1); + return (2); + } else if (s[0] & 0x80) { + /* Invalid multibyte sequence */ + return (-1); + } + return (1); +} + +static size_t +_GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t loc) +{ + _GB2312State *gs; + wchar_t wc; + int i, len, ocount; + size_t ncopy; + + gs = (_GB2312State *)ps; + + if (gs->count < 0 || gs->count > sizeof(gs->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + ncopy = MIN(MIN(n, GB2312_MB_CUR_MAX), sizeof(gs->bytes) - gs->count); + memcpy(gs->bytes + gs->count, s, ncopy); + ocount = gs->count; + gs->count += ncopy; + s = (char *)gs->bytes; + n = gs->count; + + if ((len = _GB2312_check(s, n)) < 0) + return ((size_t)len); + wc = 0; + i = len; + while (i-- > 0) + wc = (wc << 8) | (unsigned char)*s++; + if (pwc != NULL) + *pwc = wc; + gs->count = 0; + return (wc == L'\0' ? 0 : len - ocount); +} + +static size_t +_GB2312_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +{ + _GB2312State *gs; + + gs = (_GB2312State *)ps; + + if (gs->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc & 0x8000) { + *s++ = (wc >> 8) & 0xff; + *s = wc & 0xff; + return (2); + } + *s = wc & 0xff; + return (1); +} diff --git a/locale/gb2312.5 b/locale/gb2312.5 new file mode 120000 index 0000000..bfc08ae --- /dev/null +++ b/locale/gb2312.5 @@ -0,0 +1 @@ +./gb2312.5 \ No newline at end of file diff --git a/locale/gbk-fbsd.c b/locale/gbk-fbsd.c new file mode 100644 index 0000000..a919137 --- /dev/null +++ b/locale/gbk-fbsd.c @@ -0,0 +1,169 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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/gbk.c,v 1.11 2004/05/17 11:16:14 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#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 int _GBK_mbsinit(const mbstate_t *, locale_t); +static size_t _GBK_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); + +typedef struct { + wchar_t ch; +} _GBKState; + +__private_extern__ int +_GBK_init(struct __xlocale_st_runelocale *xrl) +{ + + xrl->__mbrtowc = _GBK_mbrtowc; + xrl->__wcrtomb = _GBK_wcrtomb; + xrl->__mbsinit = _GBK_mbsinit; + xrl->__mb_cur_max = 2; + return (0); +} + +static int +_GBK_mbsinit(const mbstate_t *ps, locale_t loc) +{ + + return (ps == NULL || ((const _GBKState *)ps)->ch == 0); +} + +static __inline int +_gbk_check(u_int c) +{ + + c &= 0xff; + return ((c >= 0x81 && c <= 0xfe) ? 2 : 1); +} + +static size_t +_GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t loc) +{ + _GBKState *gs; + wchar_t wc; + size_t len; + + gs = (_GBKState *)ps; + + if ((gs->ch & ~0xFF) != 0) { + /* Bad conversion state. */ + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + if (gs->ch != 0) { + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (gs->ch << 8) | (*s & 0xFF); + if (pwc != NULL) + *pwc = wc; + gs->ch = 0; + return (1); + } + + len = (size_t)_gbk_check(*s); + wc = *s++ & 0xff; + if (len == 2) { + if (n < 2) { + /* Incomplete multibyte sequence */ + gs->ch = wc; + return ((size_t)-2); + } + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (wc << 8) | (*s++ & 0xff); + if (pwc != NULL) + *pwc = wc; + return (2); + } else { + if (pwc != NULL) + *pwc = wc; + return (wc == L'\0' ? 0 : 1); + } +} + +static size_t +_GBK_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +{ + _GBKState *gs; + + gs = (_GBKState *)ps; + + if (gs->ch != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc & 0x8000) { + *s++ = (wc >> 8) & 0xff; + *s = wc & 0xff; + return (2); + } + *s = wc & 0xff; + return (1); +} diff --git a/locale/gbk.5 b/locale/gbk.5 new file mode 120000 index 0000000..8cd7f55 --- /dev/null +++ b/locale/gbk.5 @@ -0,0 +1 @@ +./gbk.5 \ No newline at end of file diff --git a/locale/isalnum.3 b/locale/isalnum.3 new file mode 100644 index 0000000..3739051 --- /dev/null +++ b/locale/isalnum.3 @@ -0,0 +1,113 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISALNUM 3 +.Os +.Sh NAME +.Nm isalnum +.Nd alphanumeric character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isalnum "int c" +.Sh DESCRIPTION +The +.Fn isalnum +function tests for any character for which +.Xr isalpha 3 +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 +or the value of +.Dv EOF . +In the ASCII character set, this includes the following characters +(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''" +.It "\&065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8'' \t071\ ``9''" +.It "\&101\ ``A'' \t102\ ``B'' \t103\ ``C'' \t104\ ``D'' \t105\ ``E''" +.It "\&106\ ``F'' \t107\ ``G'' \t110\ ``H'' \t111\ ``I'' \t112\ ``J''" +.It "\&113\ ``K'' \t114\ ``L'' \t115\ ``M'' \t116\ ``N'' \t117\ ``O''" +.It "\&120\ ``P'' \t121\ ``Q'' \t122\ ``R'' \t123\ ``S'' \t124\ ``T''" +.It "\&125\ ``U'' \t126\ ``V'' \t127\ ``W'' \t130\ ``X'' \t131\ ``Y''" +.It "\&132\ ``Z'' \t141\ ``a'' \t142\ ``b'' \t143\ ``c'' \t144\ ``d''" +.It "\&145\ ``e'' \t146\ ``f'' \t147\ ``g'' \t150\ ``h'' \t151\ ``i''" +.It "\&152\ ``j'' \t153\ ``k'' \t154\ ``l'' \t155\ ``m'' \t156\ ``n''" +.It "\&157\ ``o'' \t160\ ``p'' \t161\ ``q'' \t162\ ``r'' \t163\ ``s''" +.It "\&164\ ``t'' \t165\ ``u'' \t166\ ``v'' \t167\ ``w'' \t170\ ``x''" +.It "\&171\ ``y'' \t172\ ``z''" +.El +.Sh RETURN VALUES +The +.Fn isalnum +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswalnum +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isalnum_l 3 , +.Xr isalpha 3 , +.Xr isdigit 3 , +.Xr iswalnum 3 , +.Xr multibyte 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isalnum +function conforms to +.St -isoC . diff --git a/locale/isalnum_l.3 b/locale/isalnum_l.3 index 6233c32..0c60adc 100644 --- a/locale/isalnum_l.3 +++ b/locale/isalnum_l.3 @@ -66,42 +66,97 @@ .Sh SYNOPSIS .In wctype.h .In xlocale.h +.\" .Ft int -.Fn isalnum_l "int c" "locale_t loc" -.Ft int -.Fn isalpha_l "int c" "locale_t loc" -.Ft int -.Fn isblank_l "int c" "locale_t loc" -.Ft int -.Fn iscntrl_l "int c" "locale_t loc" -.Ft int -.Fn isdigit_l "int c" "locale_t loc" -.Ft int -.Fn isgraph_l "int c" "locale_t loc" -.Ft int -.Fn ishexnumber_l "int c" "locale_t loc" -.Ft int -.Fn isideogram_l "int c" "locale_t loc" -.Ft int -.Fn islower_l "int c" "locale_t loc" -.Ft int -.Fn isnumber_l "int c" "locale_t loc" -.Ft int -.Fn isphonogram_l "int c" "locale_t loc" -.Ft int -.Fn isprint_l "int c" "locale_t loc" -.Ft int -.Fn ispunct_l "int c" "locale_t loc" -.Ft int -.Fn isrune_l "int c" "locale_t loc" -.Ft int -.Fn isspace_l "int c" "locale_t loc" -.Ft int -.Fn isspecial_l "int c" "locale_t loc" -.Ft int -.Fn isupper_l "int c" "locale_t loc" -.Ft int -.Fn isxdigit_l "int c" "locale_t loc" +.Fo isalnum_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isalpha_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isblank_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo iscntrl_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isdigit_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isgraph_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo ishexnumber_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isideogram_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo islower_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isnumber_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isphonogram_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isprint_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo ispunct_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isrune_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isspace_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isspecial_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isupper_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo isxdigit_l +.Fa "int c" +.Fa "locale_t loc" +.Fc .Sh DESCRIPTION These functions are extended locale versions of the corresponding functions, diff --git a/locale/isalpha.3 b/locale/isalpha.3 new file mode 100644 index 0000000..eb95363 --- /dev/null +++ b/locale/isalpha.3 @@ -0,0 +1,111 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISALPHA 3 +.Os +.Sh NAME +.Nm isalpha +.Nd alphabetic character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isalpha "int c" +.Sh DESCRIPTION +The +.Fn isalpha +function tests for any character for which +.Xr isupper 3 +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 +or the value of +.Dv EOF . +In the ASCII character set, this includes the following characters +(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''" +.It "\&106\ ``F'' \t107\ ``G'' \t110\ ``H'' \t111\ ``I'' \t112\ ``J''" +.It "\&113\ ``K'' \t114\ ``L'' \t115\ ``M'' \t116\ ``N'' \t117\ ``O''" +.It "\&120\ ``P'' \t121\ ``Q'' \t122\ ``R'' \t123\ ``S'' \t124\ ``T''" +.It "\&125\ ``U'' \t126\ ``V'' \t127\ ``W'' \t130\ ``X'' \t131\ ``Y''" +.It "\&132\ ``Z'' \t141\ ``a'' \t142\ ``b'' \t143\ ``c'' \t144\ ``d''" +.It "\&145\ ``e'' \t146\ ``f'' \t147\ ``g'' \t150\ ``h'' \t151\ ``i''" +.It "\&152\ ``j'' \t153\ ``k'' \t154\ ``l'' \t155\ ``m'' \t156\ ``n''" +.It "\&157\ ``o'' \t160\ ``p'' \t161\ ``q'' \t162\ ``r'' \t163\ ``s''" +.It "\&164\ ``t'' \t165\ ``u'' \t166\ ``v'' \t167\ ``w'' \t170\ ``x''" +.It "\&171\ ``y'' \t172\ ``z''" +.El +.Sh RETURN VALUES +The +.Fn isalpha +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswalpha +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isalnum_l 3 , +.Xr islower 3 , +.Xr isupper 3 , +.Xr iswalpha 3 , +.Xr multibyte 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isalpha +function conforms to +.St -isoC . diff --git a/locale/isascii.3 b/locale/isascii.3 new file mode 120000 index 0000000..5e23aeb --- /dev/null +++ b/locale/isascii.3 @@ -0,0 +1 @@ +./isascii.3 \ No newline at end of file diff --git a/gen/getgrouplist.3 b/locale/isblank.3 similarity index 59% rename from gen/getgrouplist.3 rename to locale/isblank.3 index 28364eb..ead0706 100644 --- a/gen/getgrouplist.3 +++ b/locale/isblank.3 @@ -29,68 +29,67 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)getgrouplist.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/getgrouplist.3,v 1.7 2001/10/01 16:08:51 ru Exp $ +.\" @(#)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 $ .\" -.Dd June 9, 1993 -.Dt GETGROUPLIST 3 +.Dd August 21, 2004 +.Dt ISBLANK 3 .Os .Sh NAME -.Nm getgrouplist -.Nd calculate group access list +.Nm isblank +.Nd space or tab character test .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In unistd.h +.In ctype.h .Ft int -.Fn getgrouplist "const char *name" "int basegid" "int *groups" "int *ngroups" +.Fn isblank "int c" .Sh DESCRIPTION The -.Fn getgrouplist -function reads through the group file and calculates -the group access list for the user specified in -.Fa name . -The -.Fa basegid -is automatically included in the groups list. -Typically this value is given as -the group number from the password file. +.Fn isblank +function tests for a space or tab character. +For any locale, this includes the following standard characters: +.Pp +.Bl -column \&`\et''___ \&``\et''___ +.It "\&``\et''\t`` ''" +.El .Pp -The resulting group list is returned in the integer array pointed to by -.Fa groups . -The caller specifies the size of the -.Fa groups -array in the integer pointed to by -.Fa ngroups ; -the actual number of groups found is returned in -.Fa ngroups . +In the "C" locale, +.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 +or the value of +.Dv EOF . +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswblank +function should be used instead. .Sh RETURN VALUES The -.Fn getgrouplist -function -returns \-1 if the size of the group list is too small to -hold all the user's groups. -Here, the group array will be filled with as many groups as will fit. -.Sh FILES -.Bl -tag -width /etc/group -compact -.It Pa /etc/group -group membership list -.El +.Fn isblank +function returns zero if the character tests false and +returns non-zero if the character tests true. .Sh SEE ALSO -.Xr setgroups 2 , -.Xr initgroups 3 -.Sh HISTORY -The -.Fn getgrouplist -function first appeared in -.Bx 4.4 . -.Sh BUGS +.Xr ctype 3 , +.Xr isalnum_l 3 , +.Xr iswblank 3 , +.Xr multibyte 3 , +.Xr ascii 7 +.Sh STANDARDS The -.Fn getgrouplist +.Fn isblank function -uses the routines based on -.Xr getgrent 3 . -If the invoking program uses any of these routines, -the group structure will -be overwritten in the call to -.Fn getgrouplist . +conforms to +.St -isoC-99 . diff --git a/locale/iscntrl.3 b/locale/iscntrl.3 new file mode 100644 index 0000000..886980d --- /dev/null +++ b/locale/iscntrl.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISCNTRL 3 +.Os +.Sh NAME +.Nm iscntrl +.Nd control character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn iscntrl "int c" +.Sh DESCRIPTION +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 +or the value of +.Dv EOF . +In the ASCII character set, this includes the following characters +(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" +.It "\&005\ ENQ \t006\ ACK \t007\ BEL \t010\ BS \t011\ HT" +.It "\&012\ NL \t013\ VT \t014\ NP \t015\ CR \t016\ SO" +.It "\&017\ SI \t020\ DLE \t021\ DC1 \t022\ DC2 \t023\ DC3" +.It "\&024\ DC4 \t025\ NAK \t026\ SYN \t027\ ETB \t030\ CAN" +.It "\&031\ EM \t032\ SUB \t033\ ESC \t034\ FS \t035\ GS" +.It "\&036\ RS \t037\ US \t177\ DEL" +.El +.Sh RETURN VALUES +The +.Fn iscntrl +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswcntrl +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 +The +.Fn iscntrl +function conforms to +.St -isoC . diff --git a/sys/other_libc_init.c b/locale/isctype.c similarity index 86% rename from sys/other_libc_init.c rename to locale/isctype.c index 14e0383..08dbab4 100644 --- a/sys/other_libc_init.c +++ b/locale/isctype.c @@ -21,12 +21,10 @@ * @APPLE_LICENSE_HEADER_END@ */ -extern void __xlocale_init(void); -extern void __guard_setup(void); +/* + * Tell to generate extern versions of all the top level inline + * functions. + */ +#define _EXTERNALIZE_CTYPE_INLINES_TOP_ -__private_extern__ void -other_libc_init(void) -{ - __xlocale_init(); - __guard_setup(); -} +#include diff --git a/locale/isctype_l.c b/locale/isctype_l.c deleted file mode 100644 index e483354..0000000 --- a/locale/isctype_l.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 1989, 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. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the 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[] = "@(#)isctype.c 8.3 (Berkeley) 2/24/94"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/locale/isctype.c,v 1.9 2002/08/17 20:03:44 ache Exp $"); - -#include "xlocale_private.h" -#include - -#undef digittoint_l -int -digittoint_l(c, l) - int c; - locale_t l; -{ - return (__maskrune_l(c, 0xFF, l)); -} - -#undef isalnum_l -int -isalnum_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_A|_CTYPE_D, l)); -} - -#undef isalpha_l -int -isalpha_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_A, l)); -} - -#undef isblank_l -int -isblank_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_B, l)); -} - -#undef iscntrl_l -int -iscntrl_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_C, l)); -} - -#undef isdigit_l -int -isdigit_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_D, l)); -} - -#undef isgraph_l -int -isgraph_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_G, l)); -} - -#undef ishexnumber_l -int -ishexnumber_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_X, l)); -} - -#undef isideogram_l -int -isideogram_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_I, l)); -} - -#undef islower_l -int -islower_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_L, l)); -} - -#undef isnumber_l -int -isnumber_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_D, l)); -} - -#undef isphonogram_l -int -isphonogram_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_Q, l)); -} - -#undef isprint_l -int -isprint_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_R, l)); -} - -#undef ispunct_l -int -ispunct_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_P, l)); -} - -#undef isrune_l -int -isrune_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, 0xFFFFFF00L, l)); -} - -#undef isspace_l -int -isspace_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_S, l)); -} - -#undef isspecial_l -int -isspecial_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_T, l)); -} - -#undef isupper_l -int -isupper_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_U, l)); -} - -#undef isxdigit_l -int -isxdigit_l(c, l) - int c; - locale_t l; -{ - return (__istype_l(c, _CTYPE_X, l)); -} - -#undef tolower_l -int -tolower_l(c, l) - int c; - locale_t l; -{ - return (__tolower_l(c, l)); -} - -#undef toupper_l -int -toupper_l(c, l) - int c; - locale_t l; -{ - return (__toupper_l(c, l)); -} - diff --git a/locale/isdigit.3 b/locale/isdigit.3 new file mode 100644 index 0000000..b6e2b59 --- /dev/null +++ b/locale/isdigit.3 @@ -0,0 +1,112 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISDIGIT 3 +.Os +.Sh NAME +.Nm isdigit, isnumber +.Nd decimal-digit character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isdigit "int c" +.Ft int +.Fn isnumber "int c" +.Sh DESCRIPTION +The +.Fn isdigit +function tests for a decimal digit character. +Regardless of locale, this includes the following characters only: +.Pp +.Bl -column \&``0''______ \&``0''______ \&``0''______ \&``0''______ \&``0''______ +.It "\&``0''\t``1''\t``2''\t``3''\t``4''" +.It "\&``5''\t``6''\t``7''\t``8''\t``9''" +.El +.Pp +The +.Fn isnumber +function behaves similarly to +.Fn isdigit , +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 +or the value of +.Dv EOF . +.Sh RETURN VALUES +The +.Fn isdigit +and +.Fn isnumber +functions return zero if the character tests false and +return non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswdigit +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isalnum_l 3 , +.Xr iswdigit 3 , +.Xr multibyte 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isdigit +function conforms to +.St -isoC . +.Sh HISTORY +The +.Fn isnumber +function appeared in +.Bx 4.4 . diff --git a/locale/isgraph.3 b/locale/isgraph.3 new file mode 100644 index 0000000..de81a2b --- /dev/null +++ b/locale/isgraph.3 @@ -0,0 +1,116 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISGRAPH 3 +.Os +.Sh NAME +.Nm isgraph +.Nd printing character test (space character exclusive) +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isgraph "int c" +.Sh DESCRIPTION +The +.Fn isgraph +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 +or the value of +.Dv EOF . +In the ASCII character set, this includes the following characters +(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\ ``%''" +.It "\&046\ ``&'' \t047\ ``''' \t050\ ``('' \t051\ ``)'' \t052\ ``*''" +.It "\&053\ ``+'' \t054\ ``,'' \t055\ ``-'' \t056\ ``.'' \t057\ ``/''" +.It "\&060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3'' \t064\ ``4''" +.It "\&065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8'' \t071\ ``9''" +.It "\&072\ ``:'' \t073\ ``;'' \t074\ ``<'' \t075\ ``='' \t076\ ``>''" +.It "\&077\ ``?'' \t100\ ``@'' \t101\ ``A'' \t102\ ``B'' \t103\ ``C''" +.It "\&104\ ``D'' \t105\ ``E'' \t106\ ``F'' \t107\ ``G'' \t110\ ``H''" +.It "\&111\ ``I'' \t112\ ``J'' \t113\ ``K'' \t114\ ``L'' \t115\ ``M''" +.It "\&116\ ``N'' \t117\ ``O'' \t120\ ``P'' \t121\ ``Q'' \t122\ ``R''" +.It "\&123\ ``S'' \t124\ ``T'' \t125\ ``U'' \t126\ ``V'' \t127\ ``W''" +.It "\&130\ ``X'' \t131\ ``Y'' \t132\ ``Z'' \t133\ ``['' \t134\ ``\e\|''" +.It "\&135\ ``]'' \t136\ ``^'' \t137\ ``_'' \t140\ ```'' \t141\ ``a''" +.It "\&142\ ``b'' \t143\ ``c'' \t144\ ``d'' \t145\ ``e'' \t146\ ``f''" +.It "\&147\ ``g'' \t150\ ``h'' \t151\ ``i'' \t152\ ``j'' \t153\ ``k''" +.It "\&154\ ``l'' \t155\ ``m'' \t156\ ``n'' \t157\ ``o'' \t160\ ``p''" +.It "\&161\ ``q'' \t162\ ``r'' \t163\ ``s'' \t164\ ``t'' \t165\ ``u''" +.It "\&166\ ``v'' \t167\ ``w'' \t170\ ``x'' \t171\ ``y'' \t172\ ``z''" +.It "\&173\ ``{'' \t174\ ``|'' \t175\ ``}'' \t176\ ``~''" +.El +.Sh RETURN VALUES +The +.Fn isgraph +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswgraph +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 +The +.Fn isgraph +function conforms to +.St -isoC . diff --git a/locale/isideogram.3 b/locale/isideogram.3 new file mode 100644 index 0000000..e94bfd0 --- /dev/null +++ b/locale/isideogram.3 @@ -0,0 +1,58 @@ +.\" +.\" Copyright (c) 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/isideogram.3,v 1.2 2004/07/04 20:55:48 ru Exp $ +.\" +.Dd March 30, 2004 +.Dt ISIDEOGRAM 3 +.Os +.Sh NAME +.Nm isideogram +.Nd ideographic character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isideogram "int c" +.Sh DESCRIPTION +The +.Fn isideogram +function tests for an ideographic character. +.Sh RETURN VALUES +The +.Fn isideogram +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isphonogram 3 , +.Xr iswideogram 3 , +.Xr isalnum_l +.Sh HISTORY +The +.Fn isideogram +function appeared in +.Bx 4.4 . diff --git a/locale/islower.3 b/locale/islower.3 new file mode 100644 index 0000000..328ac0e --- /dev/null +++ b/locale/islower.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISLOWER 3 +.Os +.Sh NAME +.Nm islower +.Nd lower-case character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn islower "int c" +.Sh DESCRIPTION +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 +or the value of +.Dv EOF . +In the ASCII character set, this includes the following characters +(with their numeric values shown in octal): +.Pp +.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ +.It "\&141\ ``a'' \t142\ ``b'' \t143\ ``c'' \t144\ ``d'' \t145\ ``e''" +.It "\&146\ ``f'' \t147\ ``g'' \t150\ ``h'' \t151\ ``i'' \t152\ ``j''" +.It "\&153\ ``k'' \t154\ ``l'' \t155\ ``m'' \t156\ ``n'' \t157\ ``o''" +.It "\&160\ ``p'' \t161\ ``q'' \t162\ ``r'' \t163\ ``s'' \t164\ ``t''" +.It "\&165\ ``u'' \t166\ ``v'' \t167\ ``w'' \t170\ ``x'' \t171\ ``y''" +.It "\&172\ ``z''" +.El +.Sh RETURN VALUES +The +.Fn islower +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswlower +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 +.Sh STANDARDS +The +.Fn islower +function conforms to +.St -isoC . diff --git a/locale/isphonogram.3 b/locale/isphonogram.3 new file mode 100644 index 0000000..203925e --- /dev/null +++ b/locale/isphonogram.3 @@ -0,0 +1,58 @@ +.\" +.\" Copyright (c) 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/isphonogram.3,v 1.1 2004/03/30 07:23:54 tjr Exp $ +.\" +.Dd March 30, 2004 +.Dt ISPHONOGRAM 3 +.Os +.Sh NAME +.Nm isphonogram +.Nd phonographic character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isphonogram "int c" +.Sh DESCRIPTION +The +.Fn isphonogram +function tests for a phonographic character. +.Sh RETURN VALUES +The +.Fn isphonogram +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isideogram 3 , +.Xr iswphonogram 3 , +.Xr isalnum_l +.Sh HISTORY +The +.Fn isphonogram +function appeared in +.Bx 4.4 . diff --git a/locale/isprint.3 b/locale/isprint.3 new file mode 100644 index 0000000..642643c --- /dev/null +++ b/locale/isprint.3 @@ -0,0 +1,114 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISPRINT 3 +.Os +.Sh NAME +.Nm isprint +.Nd printing character test (space character inclusive) +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isprint "int c" +.Sh DESCRIPTION +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 +or the value of +.Dv EOF . +In the ASCII character set, this includes the following characters +(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\ ``$''" +.It "\&045\ ``%'' \t046\ ``&'' \t047\ ``''' \t050\ ``('' \t051\ ``)''" +.It "\&052\ ``*'' \t053\ ``+'' \t054\ ``,'' \t055\ ``-'' \t056\ ``.''" +.It "\&057\ ``/'' \t060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3''" +.It "\&064\ ``4'' \t065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8''" +.It "\&071\ ``9'' \t072\ ``:'' \t073\ ``;'' \t074\ ``<'' \t075\ ``=''" +.It "\&076\ ``>'' \t077\ ``?'' \t100\ ``@'' \t101\ ``A'' \t102\ ``B''" +.It "\&103\ ``C'' \t104\ ``D'' \t105\ ``E'' \t106\ ``F'' \t107\ ``G''" +.It "\&110\ ``H'' \t111\ ``I'' \t112\ ``J'' \t113\ ``K'' \t114\ ``L''" +.It "\&115\ ``M'' \t116\ ``N'' \t117\ ``O'' \t120\ ``P'' \t121\ ``Q''" +.It "\&122\ ``R'' \t123\ ``S'' \t124\ ``T'' \t125\ ``U'' \t126\ ``V''" +.It "\&127\ ``W'' \t130\ ``X'' \t131\ ``Y'' \t132\ ``Z'' \t133\ ``[''" +.It "\&134\ ``\e\|'' \t135\ ``]'' \t136\ ``^'' \t137\ ``_'' \t140\ ```''" +.It "\&141\ ``a'' \t142\ ``b'' \t143\ ``c'' \t144\ ``d'' \t145\ ``e''" +.It "\&146\ ``f'' \t147\ ``g'' \t150\ ``h'' \t151\ ``i'' \t152\ ``j''" +.It "\&153\ ``k'' \t154\ ``l'' \t155\ ``m'' \t156\ ``n'' \t157\ ``o''" +.It "\&160\ ``p'' \t161\ ``q'' \t162\ ``r'' \t163\ ``s'' \t164\ ``t''" +.It "\&165\ ``u'' \t166\ ``v'' \t167\ ``w'' \t170\ ``x'' \t171\ ``y''" +.It "\&172\ ``z'' \t173\ ``{'' \t174\ ``|'' \t175\ ``}'' \t176\ ``~''" +.El +.Sh RETURN VALUES +The +.Fn isprint +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswprint +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 +The +.Fn isprint +function conforms to +.St -isoC . diff --git a/locale/ispunct.3 b/locale/ispunct.3 new file mode 100644 index 0000000..89d780c --- /dev/null +++ b/locale/ispunct.3 @@ -0,0 +1,106 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISPUNCT 3 +.Os +.Sh NAME +.Nm ispunct +.Nd punctuation character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn ispunct "int c" +.Sh DESCRIPTION +The +.Fn ispunct +function tests for any printing character, except for space +.Pq Ql "\ " +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 +or the value of +.Dv EOF . +In the ASCII character set, this includes the following characters +(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\ ``%''" +.It "\&046\ ``&'' \t047\ ``''' \t050\ ``('' \t051\ ``)'' \t052\ ``*''" +.It "\&053\ ``+'' \t054\ ``,'' \t055\ ``-'' \t056\ ``.'' \t057\ ``/''" +.It "\&072\ ``:'' \t073\ ``;'' \t074\ ``<'' \t075\ ``='' \t076\ ``>''" +.It "\&077\ ``?'' \t100\ ``@'' \t133\ ``['' \t134\ ``\e\|'' \t135\ ``]''" +.It "\&136\ ``^'' \t137\ ``_'' \t140\ ```'' \t173\ ``{'' \t174\ ``|''" +.It "\&175\ ``}'' \t176\ ``~''" +.El +.Sh RETURN VALUES +The +.Fn ispunct +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswpunct +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 +The +.Fn ispunct +function conforms to +.St -isoC . diff --git a/locale/isrune.3 b/locale/isrune.3 new file mode 100644 index 0000000..2bda5c4 --- /dev/null +++ b/locale/isrune.3 @@ -0,0 +1,64 @@ +.\" +.\" Copyright (c) 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/isrune.3,v 1.1 2004/03/30 07:23:54 tjr Exp $ +.\" +.Dd March 30, 2004 +.Dt ISRUNE 3 +.Os +.Sh NAME +.Nm isrune +.Nd valid character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isrune "int c" +.Sh DESCRIPTION +The +.Fn isrune +function tests for any character that is valid in the current +character set. +In the +.Tn ASCII +character set, this is equivalent to +.Fn isascii . +.Sh RETURN VALUES +The +.Fn isrune +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isascii 3 , +.Xr iswrune 3 , +.Xr ascii 7 , +.Xr isalnum_l +.Sh HISTORY +The +.Fn isrune +function appeared in +.Bx 4.4 . diff --git a/locale/isspace.3 b/locale/isspace.3 new file mode 100644 index 0000000..5255105 --- /dev/null +++ b/locale/isspace.3 @@ -0,0 +1,98 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISSPACE 3 +.Os +.Sh NAME +.Nm isspace +.Nd white-space character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isspace "int c" +.Sh DESCRIPTION +The +.Fn isspace +function tests for the white-space characters. +For any locale, this includes the following standard characters: +.Pp +.Bl -column \&`\et''___ \&``\et''___ \&``\et''___ \&``\et''___ \&``\et''___ \&``\et''___ +.It "\&``\et''\t``\en''\t``\ev''\t``\ef''\t``\er''\t`` ''" +.El +.Pp +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 +or the value of +.Dv EOF . +.Sh RETURN VALUES +The +.Fn isspace +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswspace +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isalnum_l 3 , +.Xr iswspace 3 , +.Xr multibyte 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isspace +function conforms to +.St -isoC . diff --git a/locale/isspecial.3 b/locale/isspecial.3 new file mode 100644 index 0000000..579ca92 --- /dev/null +++ b/locale/isspecial.3 @@ -0,0 +1,57 @@ +.\" +.\" Copyright (c) 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/isspecial.3,v 1.1 2004/03/30 07:23:54 tjr Exp $ +.\" +.Dd March 30, 2004 +.Dt ISSPECIAL 3 +.Os +.Sh NAME +.Nm isspecial +.Nd special character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isspecial "int c" +.Sh DESCRIPTION +The +.Fn isspecial +function tests for a special character. +.Sh RETURN VALUES +The +.Fn isspecial +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswspecial 3 , +.Xr isalnum_l +.Sh HISTORY +The +.Fn isspecial +function appeared in +.Bx 4.4 . diff --git a/locale/isupper.3 b/locale/isupper.3 new file mode 100644 index 0000000..acf7c13 --- /dev/null +++ b/locale/isupper.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISUPPER 3 +.Os +.Sh NAME +.Nm isupper +.Nd upper-case character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isupper "int c" +.Sh DESCRIPTION +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 +or the value of +.Dv EOF . +In the ASCII character set, this includes the following characters +(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''" +.It "\&106\ ``F'' \t107\ ``G'' \t110\ ``H'' \t111\ ``I'' \t112\ ``J''" +.It "\&113\ ``K'' \t114\ ``L'' \t115\ ``M'' \t116\ ``N'' \t117\ ``O''" +.It "\&120\ ``P'' \t121\ ``Q'' \t122\ ``R'' \t123\ ``S'' \t124\ ``T''" +.It "\&125\ ``U'' \t126\ ``V'' \t127\ ``W'' \t130\ ``X'' \t131\ ``Y''" +.It "\&132\ ``Z''" +.El +.Sh RETURN VALUES +The +.Fn isupper +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswupper +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 +.Sh STANDARDS +The +.Fn isupper +function conforms to +.St -isoC . diff --git a/locale/iswalnum.3 b/locale/iswalnum.3 new file mode 100644 index 0000000..987804e --- /dev/null +++ b/locale/iswalnum.3 @@ -0,0 +1,169 @@ +.\" $NetBSD: iswalnum.3,v 1.5 2002/07/10 14:46:10 yamt Exp $ +.\" +.\" Copyright (c) 1991 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd October 3, 2002 +.Dt ISWALNUM 3 +.Os +.Sh NAME +.Nm iswalnum , +.Nm iswalpha , +.Nm iswascii , +.Nm iswblank , +.Nm iswcntrl , +.Nm iswdigit , +.Nm iswgraph , +.Nm iswhexnumber , +.Nm iswideogram , +.Nm iswlower , +.Nm iswnumber , +.Nm iswphonogram , +.Nm iswprint , +.Nm iswpunct , +.Nm iswrune , +.Nm iswspace , +.Nm iswspecial , +.Nm iswupper , +.Nm iswxdigit +.Nd wide character classification utilities +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft int +.Fn iswalnum "wint_t wc" +.Ft int +.Fn iswalpha "wint_t wc" +.Ft int +.Fn iswascii "wint_t wc" +.Ft int +.Fn iswblank "wint_t wc" +.Ft int +.Fn iswcntrl "wint_t wc" +.Ft int +.Fn iswdigit "wint_t wc" +.Ft int +.Fn iswgraph "wint_t wc" +.Ft int +.Fn iswhexnumber "wint_t wc" +.Ft int +.Fn iswideogram "wint_t wc" +.Ft int +.Fn iswlower "wint_t wc" +.Ft int +.Fn iswnumber "wint_t wc" +.Ft int +.Fn iswphonogram "wint_t wc" +.Ft int +.Fn iswprint "wint_t wc" +.Ft int +.Fn iswpunct "wint_t wc" +.Ft int +.Fn iswrune "wint_t wc" +.Ft int +.Fn iswspace "wint_t wc" +.Ft int +.Fn iswspecial "wint_t wc" +.Ft int +.Fn iswupper "wint_t wc" +.Ft int +.Fn iswxdigit "wint_t wc" +.Sh DESCRIPTION +The above functions are character classification utility functions, +for use with wide characters +.Vt ( wchar_t +or +.Vt wint_t ) . +See the description for the similarly-named single byte classification +functions (such as +.Xr isalnum 3 ) , +for details. +.Pp +Extended locale versions of these functions are documented in +.Xr iswalnum_l 3 . +See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The functions return zero if the character tests false and +return non-zero if the character tests true. +.Sh SEE ALSO +.Xr isalnum 3 , +.Xr isalpha 3 , +.Xr isascii 3 , +.Xr isblank 3 , +.Xr iscntrl 3 , +.Xr isdigit 3 , +.Xr isgraph 3 , +.Xr ishexnumber 3 , +.Xr isideogram 3 , +.Xr islower 3 , +.Xr isnumber 3 , +.Xr isphonogram 3 , +.Xr isprint 3 , +.Xr ispunct 3 , +.Xr isrune 3 , +.Xr isspace 3 , +.Xr isspecial 3 , +.Xr isupper 3 , +.Xr iswalnum_l 3 , +.Xr isxdigit 3 , +.Xr wctype 3 +.Sh STANDARDS +These functions conform to +.St -p1003.1-2001 , +except +.Fn iswascii , +.Fn iswhexnumber , +.Fn iswideogram , +.Fn iswnumber , +.Fn iswphonogram , +.Fn iswrune , +and +.Fn iswspecial , +which are +.Fx +extensions. +.Sh CAVEATS +The result of these functions is undefined unless +the argument is +.Dv WEOF +or a valid +.Vt wchar_t +value for the current locale. diff --git a/i386/sys/__sysenter_trap.s b/locale/iswctype.c similarity index 83% rename from i386/sys/__sysenter_trap.s rename to locale/iswctype.c index 53c854e..32b4adb 100644 --- a/i386/sys/__sysenter_trap.s +++ b/locale/iswctype.c @@ -21,10 +21,11 @@ * @APPLE_LICENSE_HEADER_END@ */ -.text -.align 2,0x90 -.private_extern __sysenter_trap -__sysenter_trap: - popl %edx - movl %esp, %ecx - sysenter +#include +/* + * Tell to generate extern versions of all the top level inline + * functions. + */ +#define _EXTERNALIZE_WCTYPE_INLINES_TOP_ + +#include diff --git a/locale/iswctype_l.c b/locale/iswctype_l.c deleted file mode 100644 index 7d64dbb..0000000 --- a/locale/iswctype_l.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 1989, 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. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the 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/iswctype.c,v 1.6 2002/08/17 20:30:34 ache Exp $"); - -#include "xlocale_private.h" -#include - -#undef iswalnum_l -int -iswalnum_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_A|_CTYPE_D, l)); -} - -#undef iswalpha_l -int -iswalpha_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_A, l)); -} - -#undef iswblank_l -int -iswblank_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_B, l)); -} - -#undef iswcntrl_l -int -iswcntrl_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_C, l)); -} - -#undef iswdigit_l -int -iswdigit_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_D, l)); -} - -#undef iswgraph_l -int -iswgraph_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_G, l)); -} - -#undef iswhexnumber_l -int -iswhexnumber_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_X, l)); -} - -#undef iswideogram_l -int -iswideogram_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_I, l)); -} - -#undef iswlower_l -int -iswlower_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_L, l)); -} - -#undef iswnumber_l -int -iswnumber_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_D, l)); -} - -#undef iswphonogram_l -int -iswphonogram_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_Q, l)); -} - -#undef iswprint_l -int -iswprint_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_R, l)); -} - -#undef iswpunct_l -int -iswpunct_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_P, l)); -} - -#undef iswrune_l -int -iswrune_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, 0xFFFFFF00L, l)); -} - -#undef iswspace_l -int -iswspace_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_S, l)); -} - -#undef iswspecial_l -int -iswspecial_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_T, l)); -} - -#undef iswupper_l -int -iswupper_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_U, l)); -} - -#undef iswxdigit_l -int -iswxdigit_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__istype_l(wc, _CTYPE_X, l)); -} - -#undef towlower_l -wint_t -towlower_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__tolower_l(wc, l)); -} - -#undef towupper_l -wint_t -towupper_l(wc, l) - wint_t wc; - locale_t l; -{ - return (__toupper_l(wc, l)); -} - diff --git a/locale/isxdigit.3 b/locale/isxdigit.3 new file mode 100644 index 0000000..0dadcba --- /dev/null +++ b/locale/isxdigit.3 @@ -0,0 +1,113 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt ISXDIGIT 3 +.Os +.Sh NAME +.Nm isxdigit, ishexnumber +.Nd hexadecimal-digit character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isxdigit "int c" +.Ft int +.Fn ishexnumber "int c" +.Sh DESCRIPTION +The +.Fn isxdigit +function tests for any hexadecimal-digit character. +Regardless of locale, this includes the following characters only: +.Pp +.Bl -column \&``0''______ \&``0''______ \&``0''______ \&``0''______ \&``0''______ +.It "\&``0''\t``1''\t``2''\t``3''\t``4''" +.It "\&``5''\t``6''\t``7''\t``8''\t``9''" +.It "\&``A''\t``B''\t``C''\t``D''\t``E''" +.It "\&``F''\t``a''\t``b''\t``c''\t``d''" +.It "\&``e''\t``f''" +.El +.Pp +The +.Fn ishexnumber +function behaves similarly to +.Fn isxdigit , +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 +or the value of +.Dv EOF . +.Sh RETURN VALUES +The +.Fn isxdigit +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswxdigit +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 +The +.Fn isxdigit +function conforms to +.St -isoC . +.Sh HISTORY +The +.Fn ishexnumber +function appeared in +.Bx 4.4 . diff --git a/locale/ldpart-fbsd.c b/locale/ldpart-fbsd.c new file mode 100644 index 0000000..8772ce1 --- /dev/null +++ b/locale/ldpart-fbsd.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * 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/locale/ldpart.c,v 1.15 2004/04/25 19:56:50 ache Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "ldpart.h" +#include "setlocale.h" + +static int split_lines(char *, const char *); + +__private_extern__ int +__part_load_locale(const char *name, + unsigned char *using_locale, + char **locale_buf, + const char *category_filename, + int locale_buf_size_max, + int locale_buf_size_min, + const char **dst_localebuf) +{ + int saverr, fd, i, num_lines; + char *lbuf, *p; + const char *plim; + char filename[PATH_MAX]; + struct stat st; + size_t namesize, bufsize; + + /* + * Slurp the locale file into the cache. + */ + namesize = strlen(name) + 1; + + /* 'PathLocale' must be already set & checked. */ + + /* Range checking not needed, 'name' size is limited */ + strcpy(filename, _PathLocale); + strcat(filename, "/"); + strcat(filename, name); + strcat(filename, "/"); + strcat(filename, category_filename); + if ((fd = _open(filename, O_RDONLY)) < 0) + return (_LDP_ERROR); + if (_fstat(fd, &st) != 0) + goto bad_locale; + if (st.st_size <= 0) { + errno = EFTYPE; + goto bad_locale; + } + bufsize = namesize + st.st_size; + if ((lbuf = malloc(bufsize)) == NULL) { + errno = ENOMEM; + goto bad_locale; + } + (void)strcpy(lbuf, name); + p = lbuf + namesize; + plim = p + st.st_size; + if (_read(fd, p, (size_t) st.st_size) != st.st_size) + goto bad_lbuf; + /* + * Parse the locale file into localebuf. + */ + if (plim[-1] != '\n') { + errno = EFTYPE; + goto bad_lbuf; + } + num_lines = split_lines(p, plim); + if (num_lines >= locale_buf_size_max) + num_lines = locale_buf_size_max; + else if (num_lines >= locale_buf_size_min) + num_lines = locale_buf_size_min; + else { + errno = EFTYPE; + goto bad_lbuf; + } + (void)_close(fd); + /* + * Record the successful parse in the cache. + */ + if (*locale_buf != NULL) + free(*locale_buf); + *locale_buf = lbuf; + for (p = *locale_buf, i = 0; i < num_lines; i++) + dst_localebuf[i] = (p += strlen(p) + 1); + for (i = num_lines; i < locale_buf_size_max; i++) + dst_localebuf[i] = NULL; + *using_locale = 1; + + return (_LDP_LOADED); + +bad_lbuf: + saverr = errno; + free(lbuf); + errno = saverr; +bad_locale: + saverr = errno; + (void)_close(fd); + errno = saverr; + + return (_LDP_ERROR); +} + +static int +split_lines(char *p, const char *plim) +{ + int i; + + i = 0; + while (p < plim) { + if (*p == '\n') { + *p = '\0'; + i++; + } + p++; + } + return (i); +} + +__private_extern__ void +__ldpart_free_extra(struct __xlocale_st_ldpart *lp) +{ + if (lp) + free(lp->_locale_buf); +} diff --git a/locale/ldpart.h b/locale/ldpart.h new file mode 100644 index 0000000..938f735 --- /dev/null +++ b/locale/ldpart.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2000, 2001 Alexey Zelkin + * 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/locale/ldpart.h,v 1.6 2003/06/13 00:14:07 jkh Exp $ + */ + +#ifndef _LDPART_H_ +#define _LDPART_H_ + +#define _LDP_LOADED 0 +#define _LDP_ERROR (-1) +#define _LDP_CACHE 1 + +int __part_load_locale(const char *, unsigned char *, char **, const char *, + int, int, const char **); + +#endif /* !_LDPART_H_ */ diff --git a/locale/lmessages-fbsd.c b/locale/lmessages-fbsd.c new file mode 100644 index 0000000..2874ca6 --- /dev/null +++ b/locale/lmessages-fbsd.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2001 Alexey Zelkin + * 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/locale/lmessages.c,v 1.14 2003/06/26 10:46:16 phantom Exp $"); + +#include "xlocale_private.h" + +#include +#include + +#include "ldpart.h" +#include "lmessages.h" + +#define LCMESSAGES_SIZE_FULL (sizeof(struct lc_messages_T) / sizeof(char *)) +#define LCMESSAGES_SIZE_MIN \ + (offsetof(struct lc_messages_T, yesstr) / sizeof(char *)) + +static char empty[] = ""; + +static const struct lc_messages_T _C_messages_locale = { + "^[yY]" , /* yesexpr */ + "^[nN]" , /* noexpr */ + "yes" , /* yesstr */ + "no" /* nostr */ +}; + +__private_extern__ int +__messages_load_locale(const char *name, locale_t loc) +{ + int ret; + struct __xlocale_st_messages *xp; + static struct __xlocale_st_messages *cache = NULL; + + /* 'name' must be already checked. */ + if (strcmp(name, "C") == 0 || strcmp(name, "POSIX") == 0) { + loc->_messages_using_locale = 0; + XL_RELEASE(loc->__lc_messages); + loc->__lc_messages = NULL; + return (_LDP_CACHE); + } + + /* + * If the locale name is the same as our cache, use the cache. + */ + if (cache && cache->_messages_locale_buf && strcmp(name, cache->_messages_locale_buf) == 0) { + loc->_messages_using_locale = 1; + XL_RELEASE(loc->__lc_messages); + loc->__lc_messages = cache; + XL_RETAIN(loc->__lc_messages); + return (_LDP_CACHE); + } + if ((xp = (struct __xlocale_st_messages *)malloc(sizeof(*xp))) == NULL) + return _LDP_ERROR; + xp->__refcount = 1; + xp->__free_extra = (__free_extra_t)__ldpart_free_extra; + xp->_messages_locale_buf = NULL; + + ret = __part_load_locale(name, &loc->_messages_using_locale, + &xp->_messages_locale_buf, "LC_MESSAGES/LC_MESSAGES", + LCMESSAGES_SIZE_FULL, LCMESSAGES_SIZE_MIN, + (const char **)&xp->_messages_locale); + if (ret == _LDP_LOADED) { + if (xp->_messages_locale.yesstr == NULL) + xp->_messages_locale.yesstr = empty; + if (xp->_messages_locale.nostr == NULL) + xp->_messages_locale.nostr = empty; + XL_RELEASE(loc->__lc_messages); + loc->__lc_messages = xp; + XL_RELEASE(cache); + cache = xp; + XL_RETAIN(cache); + } else if (ret == _LDP_ERROR) + free(xp); + return (ret); +} + +__private_extern__ struct lc_messages_T * +__get_current_messages_locale(locale_t loc) +{ + return (loc->_messages_using_locale + ? &loc->__lc_messages->_messages_locale + : (struct lc_messages_T *)&_C_messages_locale); +} + +#ifdef LOCALE_DEBUG +void +msgdebug() { +locale_t loc = __current_locale(); +printf( "yesexpr = %s\n" + "noexpr = %s\n" + "yesstr = %s\n" + "nostr = %s\n", + loc->__lc_messages->_messages_locale.yesexpr, + loc->__lc_messages->_messages_locale.noexpr, + loc->__lc_messages->_messages_locale.yesstr, + loc->__lc_messages->_messages_locale.nostr +); +} +#endif /* LOCALE_DEBUG */ diff --git a/locale/lmessages.h b/locale/lmessages.h new file mode 100644 index 0000000..47f08a9 --- /dev/null +++ b/locale/lmessages.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2000, 2001 Alexey Zelkin + * 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/locale/lmessages.h,v 1.3 2001/12/20 18:28:52 phantom Exp $ + */ + +#ifndef _LMESSAGES_H_ +#define _LMESSAGES_H_ + +#include + +struct lc_messages_T { + const char *yesexpr; + const char *noexpr; + const char *yesstr; + const char *nostr; +}; + +struct lc_messages_T *__get_current_messages_locale(locale_t); +int __messages_load_locale(const char *, locale_t); + +#endif /* !_LMESSAGES_H_ */ diff --git a/locale/lmonetary-fbsd.c b/locale/lmonetary-fbsd.c new file mode 100644 index 0000000..24091ea --- /dev/null +++ b/locale/lmonetary-fbsd.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * 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/locale/lmonetary.c,v 1.19 2003/06/26 10:46:16 phantom Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include + +#include "ldpart.h" +#include "lmonetary.h" + +extern const char * __fix_locale_grouping_str(const char *); + +#define LCMONETARY_SIZE_FULL (sizeof(struct lc_monetary_T) / sizeof(char *)) +#define LCMONETARY_SIZE_MIN \ + (offsetof(struct lc_monetary_T, int_p_cs_precedes) / \ + sizeof(char *)) + +static char empty[] = ""; +static char numempty[] = { CHAR_MAX, '\0'}; + +static const struct lc_monetary_T _C_monetary_locale = { + empty, /* int_curr_symbol */ + empty, /* currency_symbol */ + empty, /* mon_decimal_point */ + empty, /* mon_thousands_sep */ + empty, /* mon_grouping [C99 7.11.2.1]*/ + empty, /* positive_sign */ + empty, /* negative_sign */ + numempty, /* int_frac_digits */ + numempty, /* frac_digits */ + numempty, /* p_cs_precedes */ + numempty, /* p_sep_by_space */ + numempty, /* n_cs_precedes */ + numempty, /* n_sep_by_space */ + numempty, /* p_sign_posn */ + numempty, /* n_sign_posn */ + numempty, /* int_p_cs_precedes */ + numempty, /* int_n_cs_precedes */ + numempty, /* int_p_sep_by_space */ + numempty, /* int_n_sep_by_space */ + numempty, /* int_p_sign_posn */ + numempty /* int_n_sign_posn */ +}; + +static char +cnv(const char *str) +{ + int i = strtol(str, NULL, 10); + + if (i == -1) + i = CHAR_MAX; + return ((char)i); +} + +__private_extern__ int +__monetary_load_locale(const char *name, locale_t loc) +{ + int ret; + struct __xlocale_st_monetary *xp; + static struct __xlocale_st_monetary *cache = NULL; + + /* 'name' must be already checked. */ + if (strcmp(name, "C") == 0 || strcmp(name, "POSIX") == 0) { + if (!loc->_monetary_using_locale) + return (_LDP_CACHE); + loc->_monetary_using_locale = 0; + XL_RELEASE(loc->__lc_monetary); + loc->__lc_monetary = NULL; + loc->__mlocale_changed = 1; + return (_LDP_CACHE); + } + + if (loc->_monetary_using_locale && strcmp(name, loc->__lc_monetary->_monetary_locale_buf) == 0) + return (_LDP_CACHE); + /* + * If the locale name is the same as our cache, use the cache. + */ + if (cache && cache->_monetary_locale_buf && strcmp(name, cache->_monetary_locale_buf) == 0) { + loc->_monetary_using_locale = 1; + XL_RELEASE(loc->__lc_monetary); + loc->__lc_monetary = cache; + XL_RETAIN(loc->__lc_monetary); + loc->__mlocale_changed = 1; + return (_LDP_CACHE); + } + if ((xp = (struct __xlocale_st_monetary *)malloc(sizeof(*xp))) == NULL) + return _LDP_ERROR; + xp->__refcount = 1; + xp->__free_extra = (__free_extra_t)__ldpart_free_extra; + xp->_monetary_locale_buf = NULL; + + ret = __part_load_locale(name, &loc->_monetary_using_locale, + &xp->_monetary_locale_buf, "LC_MONETARY", + LCMONETARY_SIZE_FULL, LCMONETARY_SIZE_MIN, + (const char **)&xp->_monetary_locale); + if (ret != _LDP_ERROR) + loc->__mlocale_changed = 1; + else + free(xp); + if (ret == _LDP_LOADED) { + xp->_monetary_locale.mon_grouping = + __fix_locale_grouping_str(xp->_monetary_locale.mon_grouping); + +#define M_ASSIGN_CHAR(NAME) (((char *)xp->_monetary_locale.NAME)[0] = \ + cnv(xp->_monetary_locale.NAME)) + + M_ASSIGN_CHAR(int_frac_digits); + M_ASSIGN_CHAR(frac_digits); + M_ASSIGN_CHAR(p_cs_precedes); + M_ASSIGN_CHAR(p_sep_by_space); + M_ASSIGN_CHAR(n_cs_precedes); + M_ASSIGN_CHAR(n_sep_by_space); + M_ASSIGN_CHAR(p_sign_posn); + M_ASSIGN_CHAR(n_sign_posn); + + /* + * The six additional C99 international monetary formatting + * parameters default to the national parameters when + * reading FreeBSD LC_MONETARY data files. + */ +#define M_ASSIGN_ICHAR(NAME) \ + do { \ + if (xp->_monetary_locale.int_##NAME == NULL) \ + xp->_monetary_locale.int_##NAME = \ + xp->_monetary_locale.NAME; \ + else \ + M_ASSIGN_CHAR(int_##NAME); \ + } while (0) + + M_ASSIGN_ICHAR(p_cs_precedes); + M_ASSIGN_ICHAR(n_cs_precedes); + M_ASSIGN_ICHAR(p_sep_by_space); + M_ASSIGN_ICHAR(n_sep_by_space); + M_ASSIGN_ICHAR(p_sign_posn); + M_ASSIGN_ICHAR(n_sign_posn); + XL_RELEASE(loc->__lc_monetary); + loc->__lc_monetary = xp; + XL_RELEASE(cache); + cache = xp; + XL_RETAIN(cache); + } + return (ret); +} + +__private_extern__ struct lc_monetary_T * +__get_current_monetary_locale(locale_t loc) +{ + return (loc->_monetary_using_locale + ? &loc->__lc_monetary->_monetary_locale + : (struct lc_monetary_T *)&_C_monetary_locale); +} + +#ifdef LOCALE_DEBUG +void +monetdebug() { +locale_t loc = __current_locale(); +printf( "int_curr_symbol = %s\n" + "currency_symbol = %s\n" + "mon_decimal_point = %s\n" + "mon_thousands_sep = %s\n" + "mon_grouping = %s\n" + "positive_sign = %s\n" + "negative_sign = %s\n" + "int_frac_digits = %d\n" + "frac_digits = %d\n" + "p_cs_precedes = %d\n" + "p_sep_by_space = %d\n" + "n_cs_precedes = %d\n" + "n_sep_by_space = %d\n" + "p_sign_posn = %d\n" + "n_sign_posn = %d\n", + "int_p_cs_precedes = %d\n" + "int_p_sep_by_space = %d\n" + "int_n_cs_precedes = %d\n" + "int_n_sep_by_space = %d\n" + "int_p_sign_posn = %d\n" + "int_n_sign_posn = %d\n", + loc->__lc_monetary->_monetary_locale.int_curr_symbol, + loc->__lc_monetary->_monetary_locale.currency_symbol, + loc->__lc_monetary->_monetary_locale.mon_decimal_point, + loc->__lc_monetary->_monetary_locale.mon_thousands_sep, + loc->__lc_monetary->_monetary_locale.mon_grouping, + loc->__lc_monetary->_monetary_locale.positive_sign, + loc->__lc_monetary->_monetary_locale.negative_sign, + loc->__lc_monetary->_monetary_locale.int_frac_digits[0], + loc->__lc_monetary->_monetary_locale.frac_digits[0], + loc->__lc_monetary->_monetary_locale.p_cs_precedes[0], + loc->__lc_monetary->_monetary_locale.p_sep_by_space[0], + loc->__lc_monetary->_monetary_locale.n_cs_precedes[0], + loc->__lc_monetary->_monetary_locale.n_sep_by_space[0], + loc->__lc_monetary->_monetary_locale.p_sign_posn[0], + loc->__lc_monetary->_monetary_locale.n_sign_posn[0], + loc->__lc_monetary->_monetary_locale.int_p_cs_precedes[0], + loc->__lc_monetary->_monetary_locale.int_p_sep_by_space[0], + loc->__lc_monetary->_monetary_locale.int_n_cs_precedes[0], + loc->__lc_monetary->_monetary_locale.int_n_sep_by_space[0], + loc->__lc_monetary->_monetary_locale.int_p_sign_posn[0], + loc->__lc_monetary->_monetary_locale.int_n_sign_posn[0] +); +} +#endif /* LOCALE_DEBUG */ diff --git a/locale/lmonetary.h b/locale/lmonetary.h new file mode 100644 index 0000000..b7c3d0f --- /dev/null +++ b/locale/lmonetary.h @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2000, 2001 Alexey Zelkin + * 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/locale/lmonetary.h,v 1.4 2002/10/09 09:19:28 tjr Exp $ + */ + +#ifndef _LMONETARY_H_ +#define _LMONETARY_H_ + +#include + +struct lc_monetary_T { + const char *int_curr_symbol; + const char *currency_symbol; + const char *mon_decimal_point; + const char *mon_thousands_sep; + const char *mon_grouping; + const char *positive_sign; + const char *negative_sign; + const char *int_frac_digits; + const char *frac_digits; + const char *p_cs_precedes; + const char *p_sep_by_space; + const char *n_cs_precedes; + const char *n_sep_by_space; + const char *p_sign_posn; + const char *n_sign_posn; + const char *int_p_cs_precedes; + const char *int_n_cs_precedes; + const char *int_p_sep_by_space; + const char *int_n_sep_by_space; + const char *int_p_sign_posn; + const char *int_n_sign_posn; +}; + +struct lc_monetary_T *__get_current_monetary_locale(locale_t); +int __monetary_load_locale(const char *, locale_t); + +#endif /* !_LMONETARY_H_ */ diff --git a/locale/lnumeric-fbsd.c b/locale/lnumeric-fbsd.c new file mode 100644 index 0000000..adfa25b --- /dev/null +++ b/locale/lnumeric-fbsd.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * 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/locale/lnumeric.c,v 1.16 2003/06/26 10:46:16 phantom Exp $"); + +#include "xlocale_private.h" + +#include +#include + +#include "ldpart.h" +#include "lnumeric.h" + +extern const char *__fix_locale_grouping_str(const char *); + +#define LCNUMERIC_SIZE (sizeof(struct lc_numeric_T) / sizeof(char *)) + +static const struct lc_numeric_T _C_numeric_locale = { + ".", /* decimal_point */ + "", /* thousands_sep */ + "" /* grouping [C99 7.11.2.1]*/ +}; + +__private_extern__ int +__numeric_load_locale(const char *name, locale_t loc) +{ + int ret; + struct __xlocale_st_numeric *xp; + static struct __xlocale_st_numeric *cache = NULL; + + /* 'name' must be already checked. */ + if (strcmp(name, "C") == 0 || strcmp(name, "POSIX") == 0) { + if (!loc->_numeric_using_locale) + return (_LDP_CACHE); + loc->_numeric_using_locale = 0; + XL_RELEASE(loc->__lc_numeric); + loc->__lc_numeric = NULL; + loc->__nlocale_changed = 1; + return (_LDP_CACHE); + } + + if (loc->_numeric_using_locale && strcmp(name, loc->__lc_numeric->_numeric_locale_buf) == 0) + return (_LDP_CACHE); + /* + * If the locale name is the same as our cache, use the cache. + */ + if (cache && cache->_numeric_locale_buf && strcmp(name, cache->_numeric_locale_buf) == 0) { + loc->_numeric_using_locale = 1; + XL_RELEASE(loc->__lc_numeric); + loc->__lc_numeric = cache; + XL_RETAIN(loc->__lc_numeric); + loc->__nlocale_changed = 1; + return (_LDP_CACHE); + } + if ((xp = (struct __xlocale_st_numeric *)malloc(sizeof(*xp))) == NULL) + return _LDP_ERROR; + xp->__refcount = 1; + xp->__free_extra = (__free_extra_t)__ldpart_free_extra; + xp->_numeric_locale_buf = NULL; + + ret = __part_load_locale(name, &loc->_numeric_using_locale, + &xp->_numeric_locale_buf, "LC_NUMERIC", + LCNUMERIC_SIZE, LCNUMERIC_SIZE, + (const char **)&xp->_numeric_locale); + if (ret != _LDP_ERROR) + loc->__nlocale_changed = 1; + else + free(xp); + if (ret == _LDP_LOADED) { + /* Can't be empty according to C99 */ + if (*xp->_numeric_locale.decimal_point == '\0') + xp->_numeric_locale.decimal_point = + _C_numeric_locale.decimal_point; + xp->_numeric_locale.grouping = + __fix_locale_grouping_str(xp->_numeric_locale.grouping); + XL_RELEASE(loc->__lc_numeric); + loc->__lc_numeric = xp; + XL_RELEASE(cache); + cache = xp; + XL_RETAIN(cache); + } + return (ret); +} + +__private_extern__ struct lc_numeric_T * +__get_current_numeric_locale(locale_t loc) +{ + return (loc->_numeric_using_locale + ? &loc->__lc_numeric->_numeric_locale + : (struct lc_numeric_T *)&_C_numeric_locale); +} + +#ifdef LOCALE_DEBUG +void +numericdebug(void) { +locale_t loc = __current_locale(); +printf( "decimal_point = %s\n" + "thousands_sep = %s\n" + "grouping = %s\n", + loc->__lc_numeric->_numeric_locale.decimal_point, + loc->__lc_numeric->_numeric_locale.thousands_sep, + loc->__lc_numeric->_numeric_locale.grouping +); +} +#endif /* LOCALE_DEBUG */ diff --git a/locale/lnumeric.h b/locale/lnumeric.h new file mode 100644 index 0000000..e91835c --- /dev/null +++ b/locale/lnumeric.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2000, 2001 Alexey Zelkin + * 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/locale/lnumeric.h,v 1.3 2001/12/20 18:28:52 phantom Exp $ + */ + +#ifndef _LNUMERIC_H_ +#define _LNUMERIC_H_ + +#include + +struct lc_numeric_T { + const char *decimal_point; + const char *thousands_sep; + const char *grouping; +}; + +struct lc_numeric_T *__get_current_numeric_locale(locale_t); +int __numeric_load_locale(const char *, locale_t); + +#endif /* !_LNUMERIC_H_ */ diff --git a/locale/localeconv-fbsd.c b/locale/localeconv-fbsd.c new file mode 100644 index 0000000..d924e0e --- /dev/null +++ b/locale/localeconv-fbsd.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2001 Alexey Zelkin + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include + +#include "lmonetary.h" +#include "lnumeric.h" + +/*------------------------------------------------------------------------ + * PR-3417676: We need to provide a way to force "C" locale style number + * formatting independent of the locale setting. We provide private + * routines to get and set a flag that tells localeconv() to either return + * a "C" struct lconv, or the one dependent on the actual locale. + *------------------------------------------------------------------------*/ +static char empty[] = ""; +static char numempty[] = { CHAR_MAX, '\0' }; + +/* + * Default (C) locale conversion. + */ +static struct lconv _C_lconv = { + ".", /* decimal_point */ + empty, /* thousands_sep */ + numempty, /* grouping */ + empty, /* int_curr_symbol */ + empty, /* currency_symbol */ + empty, /* mon_decimal_point */ + empty, /* mon_thousands_sep */ + numempty, /* mon_grouping */ + empty, /* positive_sign */ + empty, /* negative_sign */ + CHAR_MAX, /* int_frac_digits */ + CHAR_MAX, /* frac_digits */ + CHAR_MAX, /* p_cs_precedes */ + CHAR_MAX, /* p_sep_by_space */ + CHAR_MAX, /* n_cs_precedes */ + CHAR_MAX, /* n_sep_by_space */ + CHAR_MAX, /* p_sign_posn */ + CHAR_MAX, /* n_sign_posn */ + CHAR_MAX, /* int_p_cs_precedes */ + CHAR_MAX, /* int_n_cs_precedes */ + CHAR_MAX, /* int_p_sep_by_space */ + CHAR_MAX, /* int_n_sep_by_space */ + CHAR_MAX, /* int_p_sign_posn */ + CHAR_MAX, /* int_n_sign_posn */ +}; +static int _onlyClocaleconv = 0; + +int +__getonlyClocaleconv(void) +{ + return _onlyClocaleconv; +} + +int +__setonlyClocaleconv(int val) +{ + int prev = _onlyClocaleconv; + + _onlyClocaleconv = val; + return prev; +} + +/* + * The localeconv() function constructs a struct lconv from the current + * monetary and numeric locales. + * + * Because localeconv() may be called many times (especially by library + * routines like printf() & strtod()), the approprate members of the + * lconv structure are computed only when the monetary or numeric + * locale has been changed. + */ + +/* + * Return the current locale conversion. + */ +struct lconv * +localeconv_l(locale_t loc) +{ + struct __xlocale_st_localeconv *lc; + + NORMALIZE_LOCALE(loc); + if (loc->__lc_localeconv && !loc->__mlocale_changed && !loc->__nlocale_changed) + return &loc->__lc_localeconv->__ret; + + lc = (struct __xlocale_st_localeconv *)malloc(sizeof(struct __xlocale_st_localeconv)); + lc->__refcount = 1; + lc->__free_extra = NULL; + if (loc->__lc_localeconv) + lc->__ret = loc->__lc_localeconv->__ret; + else { + loc->__mlocale_changed = 1; + loc->__nlocale_changed = 1; + } + + if (loc->__mlocale_changed) { + /* LC_MONETARY part */ + struct lc_monetary_T * mptr; + +#define M_ASSIGN_STR(NAME) (lc->__ret.NAME = (char*)mptr->NAME) +#define M_ASSIGN_CHAR(NAME) (lc->__ret.NAME = mptr->NAME[0]) + + mptr = __get_current_monetary_locale(loc); + M_ASSIGN_STR(int_curr_symbol); + M_ASSIGN_STR(currency_symbol); + M_ASSIGN_STR(mon_decimal_point); + M_ASSIGN_STR(mon_thousands_sep); + M_ASSIGN_STR(mon_grouping); + M_ASSIGN_STR(positive_sign); + M_ASSIGN_STR(negative_sign); + M_ASSIGN_CHAR(int_frac_digits); + M_ASSIGN_CHAR(frac_digits); + M_ASSIGN_CHAR(p_cs_precedes); + M_ASSIGN_CHAR(p_sep_by_space); + M_ASSIGN_CHAR(n_cs_precedes); + M_ASSIGN_CHAR(n_sep_by_space); + M_ASSIGN_CHAR(p_sign_posn); + M_ASSIGN_CHAR(n_sign_posn); + M_ASSIGN_CHAR(int_p_cs_precedes); + M_ASSIGN_CHAR(int_n_cs_precedes); + M_ASSIGN_CHAR(int_p_sep_by_space); + M_ASSIGN_CHAR(int_n_sep_by_space); + M_ASSIGN_CHAR(int_p_sign_posn); + M_ASSIGN_CHAR(int_n_sign_posn); + loc->__mlocale_changed = 0; + } + + if (loc->__nlocale_changed) { + /* LC_NUMERIC part */ + struct lc_numeric_T * nptr; + +#define N_ASSIGN_STR(NAME) (lc->__ret.NAME = (char*)nptr->NAME) + + nptr = __get_current_numeric_locale(loc); + N_ASSIGN_STR(decimal_point); + N_ASSIGN_STR(thousands_sep); + N_ASSIGN_STR(grouping); + loc->__nlocale_changed = 0; + } + + XL_RELEASE(loc->__lc_localeconv); + loc->__lc_localeconv = lc; + + return (&lc->__ret); +} + +/* + * Return the current locale conversion. + */ +struct lconv * +localeconv() +{ + /*-------------------------------------------------------------------- + * If _onlyClocaleconv is non-zero, just return __lconv, which is a "C" + * struct lconv *. Otherwise, do the normal thing. + *--------------------------------------------------------------------*/ + if (_onlyClocaleconv) + return &_C_lconv; + return localeconv_l(__current_locale()); +} diff --git a/locale/localeconv.3 b/locale/localeconv.3 new file mode 100644 index 0000000..dba0aeb --- /dev/null +++ b/locale/localeconv.3 @@ -0,0 +1,243 @@ +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley at BSDI. +.\" +.\" 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. +.\" +.\" 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 $ +.\" +.Dd November 21, 2003 +.Dt LOCALECONV 3 +.Os +.Sh NAME +.Nm localeconv , +.Nm localeconv_l +.Nd natural language formatting for C +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In locale.h +.Ft struct lconv * +.Fo localeconv +.Fa "void" +.Fc +.In xlocale.h +.Ft struct lconv * +.Fo localeconv_l +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn localeconv +function returns a pointer to a structure +which provides parameters for formatting numbers, +especially currency values: +.Bd -literal -offset indent +struct lconv { + char *decimal_point; + char *thousands_sep; + char *grouping; + char *int_curr_symbol; + char *currency_symbol; + char *mon_decimal_point; + char *mon_thousands_sep; + char *mon_grouping; + char *positive_sign; + char *negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; +.Ed +.Pp +The individual fields have the following meanings: +.Pp +.Bl -tag -width mon_decimal_point +.It Va decimal_point +The decimal point character, except for currency values, +cannot be an empty string. +.It Va thousands_sep +The separator between groups of digits +before the decimal point, except for currency values. +.It Va grouping +The sizes of the groups of digits, except for currency values. +This is a pointer to a vector of integers, each of size +.Vt char , +representing group size from low order digit groups +to high order (right to left). +The list may be terminated with 0 or +.Dv CHAR_MAX . +If the list is terminated with 0, +the last group size before the 0 is repeated to account for all the digits. +If the list is terminated with +.Dv CHAR_MAX , +no more grouping is performed. +.It Va int_curr_symbol +The standardized international currency symbol. +.It Va currency_symbol +The local currency symbol. +.It Va mon_decimal_point +The decimal point character for currency values. +.It Va mon_thousands_sep +The separator for digit groups in currency values. +.It Va mon_grouping +Like +.Va grouping +but for currency values. +.It Va positive_sign +The character used to denote nonnegative currency values, +usually the empty string. +.It Va negative_sign +The character used to denote negative currency values, +usually a minus sign. +.It Va int_frac_digits +The number of digits after the decimal point +in an international-style currency value. +.It Va frac_digits +The number of digits after the decimal point +in the local style for currency values. +.It Va p_cs_precedes +1 if the currency symbol precedes the currency value +for nonnegative values, 0 if it follows. +.It Va p_sep_by_space +1 if a space is inserted between the currency symbol +and the currency value for nonnegative values, 0 otherwise. +.It Va n_cs_precedes +Like +.Va p_cs_precedes +but for negative values. +.It Va n_sep_by_space +Like +.Va p_sep_by_space +but for negative values. +.It Va p_sign_posn +The location of the +.Va positive_sign +with respect to a nonnegative quantity and the +.Va currency_symbol , +coded as follows: +.Pp +.Bl -tag -width 3n -compact +.It Li 0 +Parentheses around the entire string. +.It Li 1 +Before the string. +.It Li 2 +After the string. +.It Li 3 +Just before +.Va currency_symbol . +.It Li 4 +Just after +.Va currency_symbol . +.El +.It Va n_sign_posn +Like +.Va p_sign_posn +but for negative currency values. +.It Va int_p_cs_precedes +Same as +.Va p_cs_precedes , +but for internationally formatted monetary quantities. +.It Va int_n_cs_precedes +Same as +.Va n_cs_precedes , +but for internationally formatted monetary quantities. +.It Va int_p_sep_by_space +Same as +.Va p_sep_by_space , +but for internationally formatted monetary quantities. +.It Va int_n_sep_by_space +Same as +.Va n_sep_by_space , +but for internationally formatted monetary quantities. +.It Va int_p_sign_posn +Same as +.Va p_sign_posn , +but for internationally formatted monetary quantities. +.It Va int_n_sign_posn +Same as +.Va n_sign_posn , +but for internationally formatted monetary quantities. +.El +.Pp +Unless mentioned above, +an empty string as a value for a field +indicates a zero length result or +a value that is not in the current locale. +A +.Dv CHAR_MAX +result similarly denotes an unavailable value. +.Pp +While the +.Fn localeconv +function uses the current locale, the +.Fn localeconv_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn localeconv +function returns a pointer to a static object +which may be altered by later calls to +.Xr setlocale 3 +or +.Fn localeconv . +.Sh ERRORS +No errors are defined. +.Sh SEE ALSO +.Xr setlocale 3 , +.Xr strfmon 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn localeconv +function conforms to +.St -isoC-99 . +.Sh HISTORY +The +.Fn localeconv +function first appeared in +.Bx 4.4 . diff --git a/locale/mblen-fbsd.c b/locale/mblen-fbsd.c new file mode 100644 index 0000000..f6bfa52 --- /dev/null +++ b/locale/mblen-fbsd.c @@ -0,0 +1,58 @@ +/*- + * 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/locale/mblen.c,v 1.9 2004/07/29 06:18:40 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include "mblocal.h" + +int +mblen_l(const char *s, size_t n, locale_t loc) +{ + static const mbstate_t initial; + size_t rval; + + NORMALIZE_LOCALE(loc); + if (s == NULL) { + /* No support for state dependent encodings. */ + loc->__mbs_mblen = initial; + return (0); + } + rval = loc->__lc_ctype->__mbrtowc(NULL, s, n, &loc->__mbs_mblen, loc); + 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/mblen.3 b/locale/mblen.3 new file mode 100644 index 0000000..d6fa0de --- /dev/null +++ b/locale/mblen.3 @@ -0,0 +1,131 @@ +.\" 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 +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" +.\" 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 $ +.\" +.Dd April 11, 2004 +.Dt MBLEN 3 +.Os +.Sh NAME +.Nm mblen , +.Nm mblen_l +.Nd get number of bytes in a character +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fo mblen +.Fa "const char *s" +.Fa "size_t n" +.Fc +.In stdlib.h +.In xlocale.h +.Ft int +.Fo mblen_l +.Fa "const char *s" +.Fa "size_t n" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn mblen +function computes the length, in bytes, +of a multibyte character +.Fa s , +according to the current conversion state. +Up to +.Fa n +bytes are examined. +.Pp +A call with a null +.Fa s +pointer returns nonzero if the current locale requires shift states, +zero otherwise. +If shift states are required, the shift state is reset to the initial state. +.Pp +Although the +.Fn mblen +function uses the current locale, the +.Fn mblen_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +If +.Fa s +is +.Dv NULL , +the +.Fn mblen +function returns nonzero if shift states are supported, +zero otherwise. +.Pp +Otherwise, if +.Fa s +is not a null pointer, +.Fn mblen +either returns 0 if +.Fa s +represents the null wide character, or returns +the number of bytes processed in +.Fa s , +or returns \-1 if no multibyte character +could be recognized or converted. +In this case, +.Fn mblen Ns 's +internal conversion state is undefined. +.Sh ERRORS +The +.Fn mblen +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The internal conversion state is not valid. +.El +.Sh SEE ALSO +.Xr mbrlen 3 , +.Xr mbtowc 3 , +.Xr multibyte 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn mblen +function conforms to +.St -isoC-99 . diff --git a/locale/mblocal.h b/locale/mblocal.h new file mode 100644 index 0000000..53d9464 --- /dev/null +++ b/locale/mblocal.h @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 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. + * + * $FreeBSD: src/lib/libc/locale/mblocal.h,v 1.4 2004/10/17 06:51:50 tjr Exp $ + */ + +#ifndef _MBLOCAL_H_ +#define _MBLOCAL_H_ + +/* + * Conversion functions for "NONE"/C/POSIX encoding. + */ +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); + +extern size_t __mbsnrtowcs_std(wchar_t * __restrict, const char ** __restrict, + size_t, size_t, mbstate_t * __restrict, locale_t); +extern size_t __wcsnrtombs_std(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict, locale_t); + +#endif /* _MBLOCAL_H_ */ diff --git a/locale/mbrlen-fbsd.c b/locale/mbrlen-fbsd.c new file mode 100644 index 0000000..2f0227a --- /dev/null +++ b/locale/mbrlen-fbsd.c @@ -0,0 +1,49 @@ +/*- + * 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/locale/mbrlen.c,v 1.4 2004/05/12 14:26:54 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include "mblocal.h" + +size_t +mbrlen_l(const char * __restrict s, size_t n, mbstate_t * __restrict ps, + locale_t loc) +{ + NORMALIZE_LOCALE(loc); + if (ps == NULL) + ps = &loc->__mbs_mbrlen; + return (loc->__lc_ctype->__mbrtowc(NULL, s, n, ps, loc)); +} + +size_t +mbrlen(const char * __restrict s, size_t n, mbstate_t * __restrict ps) +{ + return mbrlen_l(s, n, ps, __current_locale()); +} diff --git a/locale/mbrlen.3 b/locale/mbrlen.3 new file mode 100644 index 0000000..ca7be65 --- /dev/null +++ b/locale/mbrlen.3 @@ -0,0 +1,168 @@ +.\" 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/mbrlen.3,v 1.8 2004/06/30 19:32:41 ru Exp $ +.\" +.Dd April 7, 2004 +.Dt MBRLEN 3 +.Os +.Sh NAME +.Nm mbrlen , +.Nm mbrlen_l +.Nd "get number of bytes in a character (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo mbrlen +.Fa "const char *restrict s" +.Fa "size_t n" +.Fa "mbstate_t *restrict ps" +.Fc +.In wchar.h +.In xlocale.h +.Ft size_t +.Fo mbrlen_l +.Fa "const char *restrict s" +.Fa "size_t n" +.Fa "mbstate_t *restrict ps" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn mbrlen +function inspects at most +.Fa n +bytes, pointed to by +.Fa s , +to determine the number of bytes needed to complete the next +multibyte character. +.Pp +The +.Vt mbstate_t +argument, +.Fa ps , +is used to keep track of the shift state. +If it is +.Dv NULL , +.Fn mbrlen +uses an internal, static +.Vt mbstate_t +object, which is initialized to the initial conversion state +at program startup. +.Pp +It is equivalent to: +.Pp +.Dl "mbrtowc(NULL, s, n, ps);" +.Pp +Except that, when +.Fa ps +is a +.Dv NULL +pointer, +.Fn mbrlen +uses its own static, internal +.Vt mbstate_t +object to keep track of the shift state. +.Pp +Although the +.Fn mbrlen +function uses the current locale, the +.Fn mbrlen_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn mbrlen +functions returns: +.Bl -tag -width indent +.It 0 +The next +.Fa n +or fewer bytes +represent the null wide character +.Pq Li "L'\e0'" . +.It >0 +The next +.Fa n +or fewer bytes +represent a valid character, +.Fn mbrlen +returns the number of bytes used to complete the multibyte character. +.It Po Vt size_t Pc Ns \-2 +The next +.Fa n +contribute to, but do not complete, a valid multibyte character sequence, +and all +.Fa n +bytes have been processed. +.It Po Vt size_t Pc Ns \-1 +An encoding error has occurred. +The next +.Fa n +or fewer bytes do not contribute to a valid multibyte character. +.El +.Sh EXAMPLES +A function that calculates the number of characters in a multibyte +character string: +.Bd -literal -offset indent +size_t +nchars(const char *s) +{ + size_t charlen, chars; + mbstate_t mbs; + + chars = 0; + memset(&mbs, 0, sizeof(mbs)); + while ((charlen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0 && + charlen != (size_t)-1 && charlen != (size_t)-2) { + s += charlen; + chars++; + } + + return (chars); +} +.Ed +.Sh ERRORS +The +.Fn mbrlen +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mblen 3 , +.Xr mbrtowc 3 , +.Xr multibyte 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn mbrlen +function conforms to +.St -isoC-99 . diff --git a/locale/mbrtowc-fbsd.c b/locale/mbrtowc-fbsd.c new file mode 100644 index 0000000..023c8b2 --- /dev/null +++ b/locale/mbrtowc-fbsd.c @@ -0,0 +1,50 @@ +/*- + * 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/locale/mbrtowc.c,v 1.7 2004/05/12 14:09:04 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include "mblocal.h" + +size_t +mbrtowc_l(wchar_t * __restrict pwc, const char * __restrict s, + size_t n, mbstate_t * __restrict ps, locale_t loc) +{ + NORMALIZE_LOCALE(loc); + if (ps == NULL) + ps = &loc->__mbs_mbrtowc; + return (loc->__lc_ctype->__mbrtowc(pwc, s, n, ps, loc)); +} + +size_t +mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, + size_t n, mbstate_t * __restrict ps) +{ + return mbrtowc_l(pwc, s, n, ps, __current_locale()); +} diff --git a/locale/mbrtowc.3 b/locale/mbrtowc.3 new file mode 100644 index 0000000..4066184 --- /dev/null +++ b/locale/mbrtowc.3 @@ -0,0 +1,161 @@ +.\" 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/mbrtowc.3,v 1.5 2004/06/30 19:32:41 ru Exp $ +.\" +.Dd April 8, 2004 +.Dt MBRTOWC 3 +.Os +.Sh NAME +.Nm mbrtowc , +.Nm mbrtowc_l +.Nd "convert a character to a wide-character code (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo mbrtowc +.Fa "wchar_t *restrict pwc" +.Fa "const char *restrict s" +.Fa "size_t n" +.Fa "mbstate_t *restrict ps" +.Fc +.In wchar.h +.In xlocale.h +.Ft size_t +.Fo mbrtowc_l +.Fa "wchar_t *restrict pwc" +.Fa "const char *restrict s" +.Fa "size_t n" +.Fa "mbstate_t *restrict ps" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn mbrtowc +function inspects at most +.Fa n +bytes, pointed to by +.Fa s , +to determine the number of bytes needed to complete the next multibyte +character. +If a character can be completed, and +.Fa pwc +is not +.Dv NULL , +the wide character which is represented by +.Fa s +is stored in the +.Vt wchar_t +it points to. +.Pp +If +.Fa s +is +.Dv NULL , +.Fn mbrtowc +behaves as if +.Fa pwc +were +.Dv NULL , +.Fa s +were an empty string +.Pq Qq , +and +.Fa n +were 1. +.Pp +The +.Vt mbstate_t +argument, +.Fa ps , +is used to keep track of the shift state. +If it is +.Dv NULL , +.Fn mbrtowc +uses an internal, static +.Vt mbstate_t +object, which is initialized to the initial conversion state +at program startup. +.Pp +While the +.Fn mbrtowc +function uses the current locale, the +.Fn mbrtowc_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn mbrtowc +functions returns: +.Bl -tag -width indent +.It 0 +The next +.Fa n +or fewer bytes +represent the null wide character +.Pq Li "L'\e0'" . +.It >0 +The next +.Fa n +or fewer bytes +represent a valid character, +.Fn mbrtowc +returns the number of bytes used to complete the multibyte character. +.It Po Vt size_t Pc Ns \-2 +The next +.Fa n +contribute to, but do not complete, a valid multibyte character sequence, +and all +.Fa n +bytes have been processed. +.It Po Vt size_t Pc Ns \-1 +An encoding error has occurred. +The next +.Fa n +or fewer bytes do not contribute to a valid multibyte character. +.El +.Sh ERRORS +The +.Fn mbrtowc +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbtowc 3 , +.Xr multibyte 3 , +.Xr setlocale 3 , +.Xr wcrtomb 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn mbrtowc +function conforms to +.St -isoC-99 . diff --git a/locale/mbsinit-fbsd.c b/locale/mbsinit-fbsd.c new file mode 100644 index 0000000..bbc2266 --- /dev/null +++ b/locale/mbsinit-fbsd.c @@ -0,0 +1,47 @@ +/*- + * 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/locale/mbsinit.c,v 1.3 2004/05/12 14:09:04 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include "mblocal.h" + +int +mbsinit_l(const mbstate_t *ps, locale_t loc) +{ + + NORMALIZE_LOCALE(loc); + return (loc->__lc_ctype->__mbsinit(ps, loc)); +} + +int +mbsinit(const mbstate_t *ps) +{ + return mbsinit_l(ps, __current_locale()); +} diff --git a/locale/mbsinit.3 b/locale/mbsinit.3 new file mode 100644 index 0000000..8dfa1bf --- /dev/null +++ b/locale/mbsinit.3 @@ -0,0 +1,81 @@ +.\" 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/mbsinit.3,v 1.3 2004/04/08 09:59:02 tjr Exp $ +.\" +.Dd April 8, 2004 +.Dt MBSINIT 3 +.Os +.Sh NAME +.Nm mbsinit , +.Nm mbsinit_l +.Nd "determine conversion object status" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft int +.Fn mbsinit "const mbstate_t *ps" +.In wchar.h +.In xlocale.h +.Ft int +.Fn mbsinit_l "const mbstate_t *ps" "locale_t loc" +.Sh DESCRIPTION +The +.Fn mbsinit +function determines whether the +.Vt mbstate_t +object pointed to by +.Fa ps +describes an initial conversion state. +.Pp +While the +.Fn mbsinit +function uses the current locale, the +.Fn mbsinit_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn mbsinit +function returns non-zero if +.Fa ps +is +.Dv NULL +or describes an initial conversion state; +otherwise, it returns zero. +.Sh SEE ALSO +.Xr mbrlen 3 , +.Xr mbrtowc 3 , +.Xr mbsrtowcs 3 , +.Xr multibyte 3 , +.Xr wcrtomb 3 , +.Xr wcsrtombs 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn mbsinit +function conforms to +.St -isoC-99 . diff --git a/locale/mbsnrtowcs-fbsd.c b/locale/mbsnrtowcs-fbsd.c new file mode 100644 index 0000000..41cdd86 --- /dev/null +++ b/locale/mbsnrtowcs-fbsd.c @@ -0,0 +1,102 @@ +/*- + * 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/locale/mbsnrtowcs.c,v 1.1 2004/07/21 10:54:57 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include "mblocal.h" + +size_t +mbsnrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc) +{ + NORMALIZE_LOCALE(loc); + if (ps == NULL) + ps = &loc->__mbs_mbsnrtowcs; + return (loc->__lc_ctype->__mbsnrtowcs(dst, src, nms, len, ps, loc)); +} + +size_t +mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps) +{ + return mbsnrtowcs_l(dst, src, nms, len, ps, __current_locale()); +} + +__private_extern__ size_t +__mbsnrtowcs_std(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc) +{ + const char *s; + size_t nchr; + wchar_t wc; + size_t nb; + size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict, locale_t) + = loc->__lc_ctype->__mbrtowc; + + s = *src; + nchr = 0; + + if (dst == NULL) { + for (;;) { + if ((nb = __mbrtowc(&wc, s, nms, ps, loc)) == (size_t)-1) + /* Invalid sequence - mbrtowc() sets errno. */ + return ((size_t)-1); + else if (nb == 0 || nb == (size_t)-2) + return (nchr); + s += nb; + nms -= nb; + nchr++; + } + /*NOTREACHED*/ + } + + while (len-- > 0) { + if ((nb = __mbrtowc(dst, s, nms, ps, loc)) == (size_t)-1) { + *src = s; + return ((size_t)-1); + } else if (nb == (size_t)-2) { + *src = s + nms; + return (nchr); + } else if (nb == 0) { + *src = NULL; + return (nchr); + } + s += nb; + nms -= nb; + nchr++; + dst++; + } + *src = s; + return (nchr); +} diff --git a/locale/mbsrtowcs-fbsd.c b/locale/mbsrtowcs-fbsd.c new file mode 100644 index 0000000..da8b1e4 --- /dev/null +++ b/locale/mbsrtowcs-fbsd.c @@ -0,0 +1,53 @@ +/*- + * 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/locale/mbsrtowcs.c,v 1.6 2004/07/21 10:54:57 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include "mblocal.h" + +size_t +mbsrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src, size_t len, + mbstate_t * __restrict ps, locale_t loc) +{ + NORMALIZE_LOCALE(loc); + if (ps == NULL) + ps = &loc->__mbs_mbsrtowcs; + return (loc->__lc_ctype->__mbsnrtowcs(dst, src, SIZE_T_MAX, len, ps, loc)); +} + +size_t +mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len, + mbstate_t * __restrict ps) +{ + return mbsrtowcs_l(dst, src, len, ps, __current_locale()); +} diff --git a/locale/mbsrtowcs.3 b/locale/mbsrtowcs.3 new file mode 100644 index 0000000..cd22deb --- /dev/null +++ b/locale/mbsrtowcs.3 @@ -0,0 +1,174 @@ +.\" 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/mbsrtowcs.3,v 1.5 2004/07/21 10:54:57 tjr Exp $ +.Dd July 21, 2004 +.Dt MBSRTOWCS 3 +.Os +.Sh NAME +.Nm mbsnrtowcs , +.Nm mbsnrtowcs_l , +.Nm mbsrtowcs , +.Nm mbsrtowcs_l +.Nd "convert a character string to a wide-character string (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo mbsnrtowcs +.Fa "wchar_t *restrict dst" +.Fa "const char **restrict src" +.Fa "size_t nms" +.Fa "size_t len" +.Fa "mbstate_t *restrict ps" +.Fc +.Ft size_t +.Fo mbsrtowcs +.Fa "wchar_t *restrict dst" +.Fa "const char **restrict src" +.Fa "size_t len" +.Fa "mbstate_t *restrict ps" +.Fc +.In wchar.h +.In xlocale.h +.Ft size_t +.Fo mbsrtowcs_l +.Fa "wchar_t *restrict dst" +.Fa "const char **restrict src" +.Fa "size_t len" +.Fa "mbstate_t *restrict ps" +.Fa "locale_t loc" +.Fc +.Ft size_t +.Fo mbsnrtowcs_l +.Fa "wchar_t *restrict dst" +.Fa "const char **restrict src" +.Fa "size_t nms" +.Fa "size_t len" +.Fa "mbstate_t *restrict ps" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn mbsrtowcs +function converts a sequence of multibyte characters, pointed to indirectly by +.Fa src , +into a sequence of corresponding wide characters. It stores at most +.Fa len +of them in the +.Vt wchar_t +array pointed to by +.Fa dst , +until it encounters a terminating null character +.Pq Li '\e0' . +.Pp +If +.Fa dst +is +.Dv NULL , +no characters are stored. +.Pp +If +.Fa dst +is not +.Dv NULL , +the pointer pointed to by +.Fa src +is updated to point to the character after the one that conversion stopped at. +If conversion stops because a null character is encountered, +.Fa *src +is set to +.Dv NULL . +.Pp +The +.Vt mbstate_t +argument, +.Fa ps , +is used to keep track of the shift state. +If it is +.Dv NULL , +.Fn mbsrtowcs +uses an internal, static +.Vt mbstate_t +object, which is initialized to the initial conversion state +at program startup. +.Pp +The +.Fn mbsnrtowcs +function behaves identically to +.Fn mbsrtowcs , +except that conversion stops after reading at most +.Fa nms +bytes from the buffer pointed to by +.Fa src . +.Pp +While the +.Fn mbsrtowcs +and +.Fn mbsnrtowcs +functions use the current locale, the +.Fn mbsrtowcs_l +and +.Fn mbsnrtowcs_l +functions may be passed locales directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn mbsrtowcs +and +.Fn mbsnrtowcs +functions return the number of wide characters stored in +the array pointed to by +.Fa dst +if successful, otherwise it returns +.Po Vt size_t Pc Ns \-1 . +.Sh ERRORS +The +.Fn mbsrtowcs +and +.Fn mbsnrtowcs +functions will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte character sequence was encountered. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbrtowc 3 , +.Xr mbstowcs 3 , +.Xr multibyte 3 , +.Xr wcsrtombs 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn mbsrtowcs +function conforms to +.St -isoC-99 . +.Pp +The +.Fn mbsnrtowcs +function is an extension to the standard. diff --git a/locale/mbstowcs-fbsd.c b/locale/mbstowcs-fbsd.c new file mode 100644 index 0000000..73b0392 --- /dev/null +++ b/locale/mbstowcs-fbsd.c @@ -0,0 +1,53 @@ +/*- + * 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/locale/mbstowcs.c,v 1.11 2004/07/21 10:54:57 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include "mblocal.h" + +size_t +mbstowcs_l(wchar_t * __restrict pwcs, const char * __restrict s, size_t n, + locale_t loc) +{ + static const mbstate_t initial; + mbstate_t mbs; + + NORMALIZE_LOCALE(loc); + mbs = initial; + return (loc->__lc_ctype->__mbsnrtowcs(pwcs, &s, SIZE_T_MAX, n, &mbs, loc)); +} + +size_t +mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n) +{ + return mbstowcs_l(pwcs, s, n, __current_locale()); +} diff --git a/locale/mbstowcs.3 b/locale/mbstowcs.3 new file mode 100644 index 0000000..1517a9c --- /dev/null +++ b/locale/mbstowcs.3 @@ -0,0 +1,111 @@ +.\" 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 +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" +.\" 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 $ +.\" +.Dd April 8, 2004 +.Dt MBSTOWCS 3 +.Os +.Sh NAME +.Nm mbstowcs , +.Nm mbstowcs_l +.Nd convert a character string to a wide-character string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft size_t +.Fo mbstowcs +.Fa "wchar_t *restrict pwcs" +.Fa "const char *restrict s" +.Fa "size_t n" +.Fc +.In stdlib.h +.In xlocale.h +.Ft size_t +.Fo mbstowcs_l +.Fa "wchar_t *restrict pwcs" +.Fa "const char *restrict s" +.Fa "size_t n" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn mbstowcs +function converts a multibyte character string +.Fa s , +beginning in the initial conversion state, +into a wide character string +.Fa pwcs . +No more than +.Fa n +wide characters are stored. +A terminating null wide character is appended, if there is room. +.Pp +Although the +.Fn mbstowcs +function uses the current locale, the +.Fn mbstowcs_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn mbstowcs +function returns the number of wide characters converted, +not counting any terminating null wide character, or \-1 +if an invalid multibyte character was encountered. +.Sh ERRORS +The +.Fn mbstowcs +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbsrtowcs 3 , +.Xr mbtowc 3 , +.Xr multibyte 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn mbstowcs +function conforms to +.St -isoC-99 . diff --git a/locale/mbtowc-fbsd.c b/locale/mbtowc-fbsd.c new file mode 100644 index 0000000..aeb75b7 --- /dev/null +++ b/locale/mbtowc-fbsd.c @@ -0,0 +1,59 @@ +/*- + * 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/locale/mbtowc.c,v 1.11 2004/07/29 06:18:40 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include "mblocal.h" + +int +mbtowc_l(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + locale_t loc) +{ + static const mbstate_t initial; + size_t rval; + + NORMALIZE_LOCALE(loc); + if (s == NULL) { + /* No support for state dependent encodings. */ + loc->__mbs_mbtowc = initial; + return (0); + } + rval = loc->__lc_ctype->__mbrtowc(pwc, s, n, &loc->__mbs_mbtowc, loc); + 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/mbtowc.3 b/locale/mbtowc.3 new file mode 100644 index 0000000..ff6f3b3 --- /dev/null +++ b/locale/mbtowc.3 @@ -0,0 +1,138 @@ +.\" 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 +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" +.\" 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 $ +.\" +.Dd April 11, 2004 +.Dt MBTOWC 3 +.Os +.Sh NAME +.Nm mbtowc , +.Nm mbtowc_l +.Nd convert a character to a wide-character code +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fo mbtowc +.Fa "wchar_t *restrict pwc" +.Fa "const char *restrict s" +.Fa "size_t n" +.Fc +.In stdlib.h +.In xlocale.h +.Ft int +.Fo mbtowc_l +.Fa "wchar_t *restrict pwc" +.Fa "const char *restrict s" +.Fa "size_t n" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn mbtowc +function converts a multibyte character +.Fa s +into a wide character, according to the current conversion state, +and stores the result +in the object pointed to by +.Fa pwc . +Up to +.Fa n +bytes are examined. +.Pp +A call with a null +.Fa s +pointer returns nonzero if the current encoding requires shift states, +zero otherwise; +if shift states are required, the shift state is reset to the initial state. +.Pp +While the +.Fn mbtowc +function uses the current locale, the +.Fn mbtowc_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +If +.Fa s +is +.Dv NULL , +the +.Fn mbtowc +function returns nonzero if shift states are supported, +zero otherwise. +.Pp +Otherwise, if +.Fa s +is not a null pointer, +.Fn mbtowc +either returns 0 if +.Fa s +represents the null wide character, or returns +the number of bytes processed in +.Fa s , +or returns \-1 if no multibyte character +could be recognized or converted. +In this case, +.Fn mbtowc Ns 's +internal conversion state is undefined. +.Sh ERRORS +The +.Fn mbtowc +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The internal conversion state is invalid. +.El +.Sh SEE ALSO +.Xr btowc 3 , +.Xr mblen 3 , +.Xr mbrtowc 3 , +.Xr mbstowcs 3 , +.Xr multibyte 3 , +.Xr wctomb 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn mbtowc +function conforms to +.St -isoC-99 . diff --git a/locale/mskanji-fbsd.c b/locale/mskanji-fbsd.c new file mode 100644 index 0000000..1fb7232 --- /dev/null +++ b/locale/mskanji-fbsd.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. + * + * ja_JP.SJIS locale table for BSD4.4/rune + * version 1.0 + * (C) Sin'ichiro MIYATANI / Phase One, Inc + * May 12, 1995 + * + * 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 Phase One, Inc. + * 4. The name of Phase One, Inc. 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[] = "@(#)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 "xlocale_private.h" + +#include +#include +#include +#include +#include +#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 int _MSKanji_mbsinit(const mbstate_t *, locale_t); +static size_t _MSKanji_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); + +typedef struct { + wchar_t ch; +} _MSKanjiState; + +__private_extern__ int +_MSKanji_init(struct __xlocale_st_runelocale *xrl) +{ + + xrl->__mbrtowc = _MSKanji_mbrtowc; + xrl->__wcrtomb = _MSKanji_wcrtomb; + xrl->__mbsinit = _MSKanji_mbsinit; + xrl->__mb_cur_max = 2; + return (0); +} + +static int +_MSKanji_mbsinit(const mbstate_t *ps, locale_t loc) +{ + + return (ps == NULL || ((const _MSKanjiState *)ps)->ch == 0); +} + +static size_t +_MSKanji_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t loc) +{ + _MSKanjiState *ms; + wchar_t wc; + + ms = (_MSKanjiState *)ps; + + if ((ms->ch & ~0xFF) != 0) { + /* Bad conversion state. */ + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + if (ms->ch != 0) { + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (ms->ch << 8) | (*s & 0xFF); + if (pwc != NULL) + *pwc = wc; + ms->ch = 0; + return (1); + } + wc = *s++ & 0xff; + if ((wc > 0x80 && wc < 0xa0) || (wc >= 0xe0 && wc < 0xfd)) { + if (n < 2) { + /* Incomplete multibyte sequence */ + ms->ch = wc; + return ((size_t)-2); + } + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (wc << 8) | (*s++ & 0xff); + if (pwc != NULL) + *pwc = wc; + return (2); + } else { + if (pwc != NULL) + *pwc = wc; + return (wc == L'\0' ? 0 : 1); + } +} + +static size_t +_MSKanji_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +{ + _MSKanjiState *ms; + int len, i; + + ms = (_MSKanjiState *)ps; + + if (ms->ch != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + len = (wc > 0x100) ? 2 : 1; + for (i = len; i-- > 0; ) + *s++ = wc >> (i << 3); + return (len); +} diff --git a/locale/mskanji.5 b/locale/mskanji.5 new file mode 120000 index 0000000..a6df939 --- /dev/null +++ b/locale/mskanji.5 @@ -0,0 +1 @@ +./mskanji.5 \ No newline at end of file diff --git a/locale/multibyte.3 b/locale/multibyte.3 new file mode 120000 index 0000000..28c63d2 --- /dev/null +++ b/locale/multibyte.3 @@ -0,0 +1 @@ +./multibyte.3 \ No newline at end of file diff --git a/locale/newlocale.3 b/locale/newlocale.3 index 0156793..84f7cc8 100644 --- a/locale/newlocale.3 +++ b/locale/newlocale.3 @@ -81,8 +81,8 @@ in case of error. New locales should be freed with .Xr freelocale 3 . .Sh SEE ALSO -.Xr xlocale 3 , .Xr duplocale 3 , .Xr freelocale 3 , .Xr querylocale 3 , -.Xr uselocale 3 +.Xr uselocale 3 , +.Xr xlocale 3 diff --git a/locale/nextwctype-fbsd.c b/locale/nextwctype-fbsd.c new file mode 100644 index 0000000..75e5056 --- /dev/null +++ b/locale/nextwctype-fbsd.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 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/locale/nextwctype.c,v 1.1 2004/07/08 06:43:37 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include + +wint_t +nextwctype_l(wint_t wc, wctype_t wct, locale_t loc) +{ + size_t lim; + _RuneRange *rr; + _RuneEntry *base, *re; + int noinc; + _RuneLocale *rl = &loc->__lc_ctype->_CurrentRuneLocale; + + noinc = 0; + if (wc < _CACHED_RUNES) { + wc++; + while (wc < _CACHED_RUNES) { + if (rl->__runetype[wc] & wct) + return (wc); + wc++; + } + wc--; + } + rr = &rl->__runetype_ext; + if (rr->__ranges != NULL && wc < rr->__ranges[0].__min) { + wc = rr->__ranges[0].__min; + noinc = 1; + } + + /* Binary search -- see bsearch.c for explanation. */ + base = rr->__ranges; + for (lim = rr->__nranges; lim != 0; lim >>= 1) { + re = base + (lim >> 1); + if (re->__min <= wc && wc <= re->__max) + goto found; + else if (wc > re->__max) { + base = re + 1; + lim--; + } + } + return (-1); +found: + if (!noinc) + wc++; + if (re->__min <= wc && wc <= re->__max) { + if (re->__types != NULL) { + for (; wc <= re->__max; wc++) + if (re->__types[wc - re->__min] & wct) + return (wc); + } else if (re->__map & wct) + return (wc); + } + while (++re < rr->__ranges + rr->__nranges) { + wc = re->__min; + if (re->__types != NULL) { + for (; wc <= re->__max; wc++) + if (re->__types[wc - re->__min] & wct) + return (wc); + } else if (re->__map & wct) + return (wc); + } + return (-1); +} + +wint_t +nextwctype(wint_t wc, wctype_t wct) +{ + return nextwctype_l(wc, wct, __current_locale()); +} diff --git a/locale/nextwctype.3 b/locale/nextwctype.3 new file mode 100644 index 0000000..59e80fd --- /dev/null +++ b/locale/nextwctype.3 @@ -0,0 +1,73 @@ +.\" +.\" Copyright (c) 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/nextwctype.3,v 1.1 2004/07/08 06:43:37 tjr Exp $ +.\" +.Dd July 8, 2004 +.Dt NEXTWCTYPE 3 +.Os +.Sh NAME +.Nm nextwctype , +.Nm nextwctype_l +.Nd "iterate through character classes" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft wint_t +.Fo nextwctype +.Fa "wint_t ch" "wctype_t wct" +.Fc +.In xlocale.h +.Ft wint_t +.Fo nextwctype_l +.Fa "wint_t ch" "wctype_t wct" "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn nextwctype +function determines the next character after +.Fa ch +that is a member of character class +.Fa wct . +If +.Fa ch +is \-1, the search begins at the first member of +.Fa wct . +.Pp +While the +.Fn nextwctype +function uses the current locale, the +.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. +.Sh SEE ALSO +.Xr wctype 3 , +.Xr xlocale 3 diff --git a/locale/nl_langinfo-fbsd.c b/locale/nl_langinfo-fbsd.c new file mode 100644 index 0000000..ed7c29e --- /dev/null +++ b/locale/nl_langinfo-fbsd.c @@ -0,0 +1,188 @@ +/*- + * Copyright (c) 2001, 2003 Alexey Zelkin + * 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/locale/nl_langinfo.c,v 1.17 2003/06/26 10:46:16 phantom Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include + +#include "lnumeric.h" +#include "lmessages.h" +#include "lmonetary.h" +#include "timelocal.h" + +#define _REL(BASE) ((int)item-BASE) + +char * +nl_langinfo_l(nl_item item, locale_t loc) +{ + char *ret, *cs; + const char *s; + static char *csym = NULL; + + NORMALIZE_LOCALE(loc); + switch (item) { + case CODESET: + ret = ""; + if ((s = querylocale(LC_CTYPE_MASK, loc)) != NULL) { + if ((cs = strchr(s, '.')) != NULL) + ret = cs + 1; + else if (strcmp(s, "C") == 0 || + strcmp(s, "POSIX") == 0) + ret = "US-ASCII"; + } + break; + case D_T_FMT: + ret = (char *) __get_current_time_locale(loc)->c_fmt; + break; + case D_FMT: + ret = (char *) __get_current_time_locale(loc)->x_fmt; + break; + case T_FMT: + ret = (char *) __get_current_time_locale(loc)->X_fmt; + break; + case T_FMT_AMPM: + ret = (char *) __get_current_time_locale(loc)->ampm_fmt; + break; + case AM_STR: + ret = (char *) __get_current_time_locale(loc)->am; + break; + case PM_STR: + ret = (char *) __get_current_time_locale(loc)->pm; + break; + case DAY_1: case DAY_2: case DAY_3: + case DAY_4: case DAY_5: case DAY_6: case DAY_7: + ret = (char*) __get_current_time_locale(loc)->weekday[_REL(DAY_1)]; + break; + case ABDAY_1: case ABDAY_2: case ABDAY_3: + case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7: + ret = (char*) __get_current_time_locale(loc)->wday[_REL(ABDAY_1)]; + break; + case MON_1: case MON_2: case MON_3: case MON_4: + case MON_5: case MON_6: case MON_7: case MON_8: + case MON_9: case MON_10: case MON_11: case MON_12: + ret = (char*) __get_current_time_locale(loc)->month[_REL(MON_1)]; + break; + case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4: + case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8: + case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12: + ret = (char*) __get_current_time_locale(loc)->mon[_REL(ABMON_1)]; + break; + case ERA: + /* XXX: need to be implemented */ + ret = ""; + break; + case ERA_D_FMT: + /* XXX: need to be implemented */ + ret = ""; + break; + case ERA_D_T_FMT: + /* XXX: need to be implemented */ + ret = ""; + break; + case ERA_T_FMT: + /* XXX: need to be implemented */ + ret = ""; + break; + case ALT_DIGITS: + /* XXX: need to be implemented */ + ret = ""; + break; + case RADIXCHAR: + ret = (char*) __get_current_numeric_locale(loc)->decimal_point; + break; + case THOUSEP: + ret = (char*) __get_current_numeric_locale(loc)->thousands_sep; + break; + case YESEXPR: + ret = (char*) __get_current_messages_locale(loc)->yesexpr; + break; + case NOEXPR: + ret = (char*) __get_current_messages_locale(loc)->noexpr; + break; + /* + * YESSTR and NOSTR items marked with LEGACY are available, but not + * recomended by SUSv2 to be used in portable applications since + * they're subject to remove in future specification editions. + */ + case YESSTR: /* LEGACY */ + ret = (char*) __get_current_messages_locale(loc)->yesstr; + break; + case NOSTR: /* LEGACY */ + ret = (char*) __get_current_messages_locale(loc)->nostr; + break; + /* + * SUSv2 special formatted currency string + */ + case CRNCYSTR: + ret = ""; + cs = (char*) __get_current_monetary_locale(loc)->currency_symbol; + if (*cs != '\0') { + char pos = localeconv_l(loc)->p_cs_precedes; + + if (pos == localeconv_l(loc)->n_cs_precedes) { + char psn = '\0'; + + if (pos == CHAR_MAX) { + if (strcmp(cs, __get_current_monetary_locale(loc)->mon_decimal_point) == 0) + psn = '.'; + } else + psn = pos ? '-' : '+'; + if (psn != '\0') { + int clen = strlen(cs); + + if ((csym = reallocf(csym, clen + 2)) != NULL) { + *csym = psn; + strcpy(csym + 1, cs); + ret = csym; + } + } + } + } + break; + case D_MD_ORDER: /* FreeBSD local extension */ + ret = (char *) __get_current_time_locale(loc)->md_order; + break; + default: + return ""; /* do not consult POSIX */ + } + if (ret && !ret[0] && item != D_MD_ORDER && item != CODESET && loc != _c_locale) { + ret = nl_langinfo_l(item, _c_locale); + } + return (ret); +} + +char * +nl_langinfo(nl_item item) +{ + return (nl_langinfo_l(item, __current_locale())); +} diff --git a/locale/nl_langinfo.3 b/locale/nl_langinfo.3 new file mode 100644 index 0000000..13125b2 --- /dev/null +++ b/locale/nl_langinfo.3 @@ -0,0 +1,109 @@ +.\" Copyright (c) 2001 Alexey Zelkin +.\" 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 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/locale/nl_langinfo.3,v 1.5 2003/09/08 19:57:14 ru Exp $ +.\" +.Dd May 3, 2001 +.Dt NL_LANGINFO 3 +.Os +.Sh NAME +.Nm nl_langinfo , +.Nm nl_langinfo_l +.Nd language information +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In langinfo.h +.Ft char * +.Fo nl_langinfo +.Fa "nl_item item" +.Fc +.In langinfo.h +.In xlocale.h +.Ft char * +.Fo nl_langinfo_l +.Fa "nl_item item" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn nl_langinfo +function returns a pointer to a string containing information relevant to +the particular language or cultural area defined in the program's locale. +The manifest constant names and values of +.Fa item +are defined in +.In langinfo.h . +.Pp +Calls to +.Fn setlocale +with a category corresponding to the category of +.Fa item , +or to the +category +.Dv LC_ALL , +may overwrite the buffer pointed to 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. +.Pp +While the +.Fn nl_langinfo +function uses the current locale, the +.Fn nl_langinfo_l +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 +.Sh STANDARDS +The +.Fn nl_langinfo +function conforms to +.St -susv2 . +.Sh HISTORY +The +.Fn nl_langinfo +function first appeared in +.Fx 4.6 . diff --git a/locale/nomacros-fbsd.c b/locale/nomacros-fbsd.c new file mode 100644 index 0000000..eea37d0 --- /dev/null +++ b/locale/nomacros-fbsd.c @@ -0,0 +1,12 @@ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/nomacros.c,v 1.5 2002/03/22 21:52:18 obrien Exp $"); + +/* + * Tell to generate extern versions of all its inline + * functions. The extern versions get called if the system doesn't + * support inlines or the user defines _DONT_USE_CTYPE_INLINE_ + * before including . + */ +#define _EXTERNALIZE_CTYPE_INLINES_ + +#include diff --git a/locale/none-fbsd.c b/locale/none-fbsd.c new file mode 100644 index 0000000..baad0c9 --- /dev/null +++ b/locale/none-fbsd.c @@ -0,0 +1,180 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include +#include +#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); + +__private_extern__ int +_none_init(struct __xlocale_st_runelocale *xrl) +{ + + 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; + return(0); +} + +__private_extern__ int +_none_mbsinit(const mbstate_t *ps __unused, locale_t loc) +{ + + /* + * Encoding is not state dependent - we are always in the + * initial state. + */ + return (1); +} + +__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) +{ + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (0); + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + if (pwc != NULL) + *pwc = (unsigned char)*s; + return (*s == '\0' ? 0 : 1); +} + +__private_extern__ size_t +_none_wcrtomb(char * __restrict s, wchar_t wc, + mbstate_t * __restrict ps __unused, locale_t loc) +{ + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc < 0 || wc > UCHAR_MAX) { + errno = EILSEQ; + return ((size_t)-1); + } + *s = (unsigned char)wc; + return (1); +} + +__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) +{ + const char *s; + size_t nchr; + + if (dst == NULL) { + s = memchr(*src, '\0', nms); + return (s != NULL ? s - *src : nms); + } + + s = *src; + nchr = 0; + while (len-- > 0 && nms-- > 0) { + if ((*dst++ = (unsigned char)*s++) == L'\0') { + *src = NULL; + return (nchr); + } + nchr++; + } + *src = s; + return (nchr); +} + +__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) +{ + const wchar_t *s; + size_t nchr; + + if (dst == NULL) { + for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) { + if (*s < 0 || *s > UCHAR_MAX) { + errno = EILSEQ; + return ((size_t)-1); + } + } + return (s - *src); + } + + s = *src; + nchr = 0; + while (len-- > 0 && nwc-- > 0) { + if (*s < 0 || *s > UCHAR_MAX) { + errno = EILSEQ; + return ((size_t)-1); + } + if ((*dst++ = *s++) == '\0') { + *src = NULL; + return (nchr); + } + nchr++; + } + *src = s; + return (nchr); +} diff --git a/locale/querylocale.3 b/locale/querylocale.3 index f4671c9..e97ebab 100644 --- a/locale/querylocale.3 +++ b/locale/querylocale.3 @@ -24,8 +24,8 @@ The available categories are documented in and .Xr newlocale 3 . .Sh SEE ALSO -.Xr xlocale 3 , .Xr duplocale 3 , .Xr freelocale 3 , .Xr newlocale 3 , -.Xr uselocale 3 +.Xr uselocale 3 , +.Xr xlocale 3 diff --git a/locale/rune-fbsd.c b/locale/rune-fbsd.c new file mode 100644 index 0000000..34293fe --- /dev/null +++ b/locale/rune-fbsd.c @@ -0,0 +1,363 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + */ + +#ifndef RUNEOFF32 +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/rune.c,v 1.12 2004/07/29 06:16:19 tjr Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#endif /* !RUNEOFF32 */ +#include +#include +#ifndef RUNEOFF32 +#include +#include +#include +#include +#include "un-namespace.h" +#endif /* !RUNEOFF32 */ + +#if defined(__LP64__) || defined(RUNEOFF32) +/* + * Because the LC_CTYPE files were created with a 32-bit program, we need + * to adjust for the larger pointers in LP64 (the longs have already been + * replaced by 32-bit equivalents). Also, natural alignment will pad + * 64-bit types to 8-byte boundaries, and make structures containing + * 64-bit types sized to 8-byte boundaries. + */ +#include +#ifndef RUNEOFF32 +#include "rune32.h" +#define BYTES32BITS 4 +#define BYTES64BITS 8 +/* whether to skip over a pointer or not (one-to-one with off64) */ +int skip[] = { + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0 +}; +#endif /* !RUNEOFF32 */ +int off64[] = { + offsetof(_RuneLocale, __sgetrune), + offsetof(_RuneLocale, __sputrune), + offsetof(_RuneLocale, __runetype_ext), + offsetof(_RuneLocale, __runetype_ext) + offsetof(_RuneRange, __ranges), + offsetof(_RuneLocale, __maplower_ext), + offsetof(_RuneLocale, __maplower_ext) + offsetof(_RuneRange, __ranges), + offsetof(_RuneLocale, __mapupper_ext), + offsetof(_RuneLocale, __mapupper_ext) + offsetof(_RuneRange, __ranges), + offsetof(_RuneLocale, __variable), + offsetof(_RuneLocale, __charclasses), + sizeof(_RuneLocale) +}; +#define NOFF (sizeof(off64) / sizeof(int)) +#ifdef RUNEOFF32 +/* + * This program generates a header file (on stdout) that containes the 32-bit + * offsets, plus some 32-bit sizes + */ +main() +{ + int i; + printf("#define SIZEOF32_RUNEENTRY %d\n", sizeof(_RuneEntry)); + printf("#define SIZEOF32_RUNELOCALE %d\n", sizeof(_RuneLocale)); + printf("int off32[] = {\n"); + for(i = 0; i < NOFF; i++) + printf("\t%d,\n", off64[i]); + printf("};\n"); + return 0; +} +#endif /* RUNEOFF32 */ +#else /* !__LP64__ && !RUNEOFF32 */ +#define SIZEOF32_RUNELOCALE sizeof(_RuneLocale) +#endif /* __LP64__ || RUNEOFF32 */ + +#ifndef RUNEOFF32 +struct __xlocale_st_runelocale * +_Read_RuneMagi(fp) + FILE *fp; +{ + struct __xlocale_st_runelocale *data; + void *lastp; + _RuneLocale *rl; + _RuneEntry *rr; + struct stat sb; + int x, saverr; + + if (_fstat(fileno(fp), &sb) < 0) + return (NULL); + + if (sb.st_size < SIZEOF32_RUNELOCALE) { + errno = EFTYPE; + return (NULL); + } + +#ifdef __LP64__ + /* will adjust later */ + if ((data = (struct __xlocale_st_runelocale *)malloc(sizeof(struct __xlocale_st_runelocale))) == NULL) +#else /* !__LP64__ */ + if ((data = (struct __xlocale_st_runelocale *)malloc(sizeof(struct __xlocale_st_runelocale) - sizeof(_RuneLocale) + sb.st_size)) == NULL) +#endif /* __LP64__ */ + return (NULL); + data->__refcount = 1; + data->__free_extra = NULL; + + errno = 0; + rewind(fp); /* Someone might have read the magic number once already */ + if (errno) { + saverr = errno; + free(data); + errno = saverr; + return (NULL); + } + + rl = &data->_CurrentRuneLocale; + +#ifdef __LP64__ + if (fread(rl, SIZEOF32_RUNELOCALE, 1, fp) != 1) +#else /* !__LP64__ */ + if (fread(rl, sb.st_size, 1, fp) != 1) +#endif /* __LP64__ */ + { + saverr = errno; + free(data); + errno = saverr; + return (NULL); + } + +#ifndef __LP64__ + lastp = (char *)rl + sb.st_size; + + rl->__variable = rl + 1; +#endif /* __LP64__ */ + + if (memcmp(rl->__magic, _RUNE_MAGIC_A, sizeof(rl->__magic))) { + free(data); + errno = EFTYPE; + return (NULL); + } + +#ifdef __LP64__ + /* shift things into the right position */ + for (x = NOFF - 2; x >= 0; x--) + memmove((char *)rl + off64[x] + (skip[x] ? BYTES64BITS : 0), + (char *)rl + off32[x] + (skip[x] ? BYTES32BITS : 0), + off32[x + 1] - off32[x] - (skip[x] ? BYTES32BITS : 0)); +#endif /* __LP64__ */ +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN + rl->__invalid_rune = ntohl(rl->__invalid_rune); + rl->__variable_len = ntohl(rl->__variable_len); + rl->__ncharclasses = ntohl(rl->__ncharclasses); + 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); + + for (x = 0; x < _CACHED_RUNES; ++x) { + rl->__runetype[x] = ntohl(rl->__runetype[x]); + rl->__maplower[x] = ntohl(rl->__maplower[x]); + rl->__mapupper[x] = ntohl(rl->__mapupper[x]); + } +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ + +#ifdef __LP64__ + { + int count = rl->__runetype_ext.__nranges + rl->__maplower_ext.__nranges + + rl->__mapupper_ext.__nranges; + int extra = sb.st_size - SIZEOF32_RUNELOCALE - count * SIZEOF32_RUNEENTRY - rl->__ncharclasses * sizeof(_RuneCharClass); + _RuneEntry *rp; + + if (extra < 0) { + saverr = errno; + free(data); + errno = saverr; + return (NULL); + } + if ((data = (struct __xlocale_st_runelocale *)reallocf(data, sizeof(struct __xlocale_st_runelocale) + + count * sizeof(_RuneEntry) + + rl->__ncharclasses * sizeof(_RuneCharClass) + + extra)) == NULL) + return (NULL); + rl = &data->_CurrentRuneLocale; + rl->__variable = rl + 1; + rp = (_RuneEntry *)rl->__variable; + for (x = 0; x < count; x++, rp++) + if (fread(rp, SIZEOF32_RUNEENTRY, 1, fp) != 1) { + saverr = errno; + free(data); + errno = saverr; + return (NULL); + } + if (rl->__ncharclasses > 0) { + if (fread(rp, sizeof(_RuneCharClass), rl->__ncharclasses, fp) != rl->__ncharclasses) { + saverr = errno; + free(data); + errno = saverr; + return (NULL); + } + rp = (_RuneEntry *)((char *)rp + rl->__ncharclasses * sizeof(_RuneCharClass)); + } + if (extra > 0 && fread(rp, extra, 1, fp) != 1) { + saverr = errno; + free(data); + errno = saverr; + return (NULL); + } + lastp = (char *)rp + extra; + } +#endif /* __LP64__ */ + rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable; + rl->__variable = rl->__runetype_ext.__ranges + + rl->__runetype_ext.__nranges; + if (rl->__variable > lastp) { + free(data); + errno = EFTYPE; + return (NULL); + } + + rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable; + rl->__variable = rl->__maplower_ext.__ranges + + rl->__maplower_ext.__nranges; + if (rl->__variable > lastp) { + free(data); + errno = EFTYPE; + return (NULL); + } + + rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable; + rl->__variable = rl->__mapupper_ext.__ranges + + rl->__mapupper_ext.__nranges; + if (rl->__variable > lastp) { + free(data); + errno = EFTYPE; + return (NULL); + } + + for (x = 0; x < rl->__runetype_ext.__nranges; ++x) { + rr = rl->__runetype_ext.__ranges; + +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN + rr[x].__min = ntohl(rr[x].__min); + rr[x].__max = ntohl(rr[x].__max); +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ + if ((rr[x].__map = ntohl(rr[x].__map)) == 0) { + int len = rr[x].__max - rr[x].__min + 1; + rr[x].__types = rl->__variable; + rl->__variable = rr[x].__types + len; + if (rl->__variable > lastp) { + free(data); + errno = EFTYPE; + return (NULL); + } +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN + while (len-- > 0) + rr[x].__types[len] = ntohl(rr[x].__types[len]); +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ + } else + rr[x].__types = 0; + } + +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN + for (x = 0; x < rl->__maplower_ext.__nranges; ++x) { + rr = rl->__maplower_ext.__ranges; + + rr[x].__min = ntohl(rr[x].__min); + rr[x].__max = ntohl(rr[x].__max); + rr[x].__map = ntohl(rr[x].__map); + } + + for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) { + rr = rl->__mapupper_ext.__ranges; + + rr[x].__min = ntohl(rr[x].__min); + rr[x].__max = ntohl(rr[x].__max); + rr[x].__map = ntohl(rr[x].__map); + } +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ + + if (rl->__ncharclasses > 0) { + rl->__charclasses = (_RuneCharClass *)rl->__variable; + rl->__variable = (void *)(rl->__charclasses + rl->__ncharclasses); + if (rl->__variable > lastp) { + free(data); + errno = EFTYPE; + return (NULL); + } +#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN + for (x = 0; x < rl->__ncharclasses; ++x) + rl->__charclasses[x].__mask = ntohl(rl->__charclasses[x].__mask); +#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ + } + + if (((char *)rl->__variable) + rl->__variable_len > (char *)lastp) { + free(data); + errno = EFTYPE; + return (NULL); + } + + /* + * Go out and zero pointers that should be zero. + */ + if (!rl->__variable_len) + rl->__variable = 0; + + if (!rl->__runetype_ext.__nranges) + rl->__runetype_ext.__ranges = 0; + + if (!rl->__maplower_ext.__nranges) + rl->__maplower_ext.__ranges = 0; + + if (!rl->__mapupper_ext.__nranges) + rl->__mapupper_ext.__ranges = 0; + + data->__datasize = lastp - (void *)data; + return (data); +} +#endif /* !RUNEOFF32 */ diff --git a/locale/rune32.h b/locale/rune32.h new file mode 100644 index 0000000..0a0661b --- /dev/null +++ b/locale/rune32.h @@ -0,0 +1,15 @@ +#define SIZEOF32_RUNEENTRY 16 +#define SIZEOF32_RUNELOCALE 3164 +int off32[] = { + 40, + 44, + 3124, + 3128, + 3132, + 3136, + 3140, + 3144, + 3148, + 3160, + 3164, +}; diff --git a/locale/runetype-fbsd.c b/locale/runetype-fbsd.c new file mode 100644 index 0000000..1a9db15 --- /dev/null +++ b/locale/runetype-fbsd.c @@ -0,0 +1,82 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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/runetype.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include + +unsigned long +___runetype_l(c, loc) + __ct_rune_t c; + locale_t loc; +{ + size_t lim; + _RuneRange *rr; + _RuneEntry *base, *re; + + if (c < 0 || c == EOF) + return(0L); + + NORMALIZE_LOCALE(loc); + rr = &loc->__lc_ctype->_CurrentRuneLocale.__runetype_ext; + /* Binary search -- see bsearch.c for explanation. */ + base = rr->__ranges; + for (lim = rr->__nranges; lim != 0; lim >>= 1) { + re = base + (lim >> 1); + if (re->__min <= c && c <= re->__max) { + if (re->__types) + return(re->__types[c - re->__min]); + else + return(re->__map); + } else if (c > re->__max) { + base = re + 1; + lim--; + } + } + + return(0L); +} + +unsigned long +___runetype(c) + __ct_rune_t c; +{ + return ___runetype_l(c, __current_locale()); +} diff --git a/locale/setlocale-fbsd.c b/locale/setlocale-fbsd.c new file mode 100644 index 0000000..be6a7f2 --- /dev/null +++ b/locale/setlocale-fbsd.c @@ -0,0 +1,357 @@ +/* + * Copyright (c) 1996 - 2002 FreeBSD Project + * Copyright (c) 1991, 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include /* for _PATH_LOCALE */ +#include +#include +#include +#include "collate.h" +#include "lmonetary.h" /* for __monetary_load_locale() */ +#include "lnumeric.h" /* for __numeric_load_locale() */ +#include "lmessages.h" /* for __messages_load_locale() */ +#include "setlocale.h" +#include "ldpart.h" +#include "timelocal.h" /* for __time_load_locale() */ + +/* + * Category names for getenv() + */ +static char *categories[_LC_LAST] = { + "LC_ALL", + "LC_COLLATE", + "LC_CTYPE", + "LC_MONETARY", + "LC_NUMERIC", + "LC_TIME", + "LC_MESSAGES", +}; + +/* + * Current locales for each category + */ +static char current_categories[_LC_LAST][ENCODING_LEN + 1] = { + "C", + "C", + "C", + "C", + "C", + "C", + "C", +}; + +/* + * Path to locale storage directory + */ +char *_PathLocale; + +/* + * The locales we are going to try and load + */ +static char new_categories[_LC_LAST][ENCODING_LEN + 1]; +static char saved_categories[_LC_LAST][ENCODING_LEN + 1]; + +static char current_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)]; + +static char *currentlocale(void); +static char *loadlocale(int); +__private_extern__ const char *__get_locale_env(int); + +char * +setlocale(category, locale) + int category; + const char *locale; +{ + int i, j, len, saverr, save__numeric_fp_cvt; + const char *env, *r; + locale_t save__lc_numeric_loc; + + if (category < LC_ALL || category >= _LC_LAST) { + errno = EINVAL; + return (NULL); + } + + if (locale == NULL) + return (category != LC_ALL ? + current_categories[category] : currentlocale()); + + /* + * Default to the current locale for everything. + */ + for (i = 1; i < _LC_LAST; ++i) + (void)strcpy(new_categories[i], current_categories[i]); + + /* + * Now go fill up new_categories from the locale argument + */ + if (!*locale) { + if (category == LC_ALL) { + for (i = 1; i < _LC_LAST; ++i) { + env = __get_locale_env(i); + if (strlen(env) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + (void)strcpy(new_categories[i], env); + } + } else { + env = __get_locale_env(category); + if (strlen(env) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + (void)strcpy(new_categories[category], env); + } + } else if (category != LC_ALL) { + if (strlen(locale) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + (void)strcpy(new_categories[category], locale); + } else { + if ((r = strchr(locale, '/')) == NULL) { + if (strlen(locale) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + for (i = 1; i < _LC_LAST; ++i) + (void)strcpy(new_categories[i], locale); + } else { + for (i = 1; r[1] == '/'; ++r) + ; + if (!r[1]) { + errno = EINVAL; + return (NULL); /* Hmm, just slashes... */ + } + do { + if (i == _LC_LAST) + break; /* Too many slashes... */ + if ((len = r - locale) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + (void)strlcpy(new_categories[i], locale, + len + 1); + i++; + while (*r == '/') + r++; + locale = r; + while (*r && *r != '/') + r++; + } while (*locale); + while (i < _LC_LAST) { + (void)strcpy(new_categories[i], + new_categories[i-1]); + i++; + } + } + } + + if (category != LC_ALL) + return (loadlocale(category)); + + save__numeric_fp_cvt = __global_locale.__numeric_fp_cvt; + save__lc_numeric_loc = __global_locale.__lc_numeric_loc; + XL_RETAIN(save__lc_numeric_loc); + for (i = 1; i < _LC_LAST; ++i) { + (void)strcpy(saved_categories[i], current_categories[i]); + if (loadlocale(i) == NULL) { + saverr = errno; + for (j = 1; j < i; j++) { + (void)strcpy(new_categories[j], + saved_categories[j]); + if (loadlocale(j) == NULL) { + (void)strcpy(new_categories[j], "C"); + (void)loadlocale(j); + } + } + __global_locale.__numeric_fp_cvt = save__numeric_fp_cvt; + __global_locale.__lc_numeric_loc = save__lc_numeric_loc; + XL_RELEASE(save__lc_numeric_loc); + errno = saverr; + return (NULL); + } + } + XL_RELEASE(save__lc_numeric_loc); + return (currentlocale()); +} + +static char * +currentlocale() +{ + int i; + + (void)strcpy(current_locale_string, current_categories[1]); + + for (i = 2; i < _LC_LAST; ++i) + if (strcmp(current_categories[1], current_categories[i])) { + for (i = 2; i < _LC_LAST; ++i) { + (void)strcat(current_locale_string, "/"); + (void)strcat(current_locale_string, + current_categories[i]); + } + break; + } + return (current_locale_string); +} + +static char * +loadlocale(category) + int category; +{ + char *new = new_categories[category]; + char *old = current_categories[category]; + int (*func)(const char *, locale_t); + int saved_errno; + + if ((new[0] == '.' && + (new[1] == '\0' || (new[1] == '.' && new[2] == '\0'))) || + strchr(new, '/') != NULL) { + errno = EINVAL; + return (NULL); + } + + saved_errno = errno; + errno = __detect_path_locale(); + if (errno != 0) + return (NULL); + errno = saved_errno; + + switch (category) { + case LC_CTYPE: + func = __wrap_setrunelocale; + break; + case LC_COLLATE: + func = __collate_load_tables; + break; + case LC_TIME: + func = __time_load_locale; + break; + case LC_NUMERIC: + func = __numeric_load_locale; + break; + case LC_MONETARY: + func = __monetary_load_locale; + break; + case LC_MESSAGES: + func = __messages_load_locale; + break; + default: + errno = EINVAL; + return (NULL); + } + + if (strcmp(new, old) == 0) + return (old); + + if (func(new, &__global_locale) != _LDP_ERROR) { + (void)strcpy(old, new); + switch (category) { + case LC_CTYPE: + if (__global_locale.__numeric_fp_cvt == LC_NUMERIC_FP_SAME_LOCALE) + __global_locale.__numeric_fp_cvt = LC_NUMERIC_FP_UNINITIALIZED; + break; + case LC_NUMERIC: + __global_locale.__numeric_fp_cvt = LC_NUMERIC_FP_UNINITIALIZED; + XL_RELEASE(__global_locale.__lc_numeric_loc); + __global_locale.__lc_numeric_loc = NULL; + break; + } + return (old); + } + + return (NULL); +} + +__private_extern__ const char * +__get_locale_env(category) + int category; +{ + const char *env; + + /* 1. check LC_ALL. */ + env = getenv(categories[0]); + + /* 2. check LC_* */ + if (env == NULL || !*env) + env = getenv(categories[category]); + + /* 3. check LANG */ + if (env == NULL || !*env) + env = getenv("LANG"); + + /* 4. if none is set, fall to "C" */ + if (env == NULL || !*env) + env = "C"; + + return (env); +} + +/* + * Detect locale storage location and store its value to _PathLocale variable + */ +__private_extern__ int +__detect_path_locale(void) +{ + if (_PathLocale == NULL) { + char *p = getenv("PATH_LOCALE"); + + if (p != NULL && !issetugid()) { + if (strlen(p) + 1/*"/"*/ + ENCODING_LEN + + 1/*"/"*/ + CATEGORY_LEN >= PATH_MAX) + return (ENAMETOOLONG); + _PathLocale = strdup(p); + if (_PathLocale == NULL) + return (errno == 0 ? ENOMEM : errno); + } else + _PathLocale = _PATH_LOCALE; + } + return (0); +} + diff --git a/locale/setlocale.3 b/locale/setlocale.3 new file mode 100644 index 0000000..dcbd333 --- /dev/null +++ b/locale/setlocale.3 @@ -0,0 +1,181 @@ +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley at BSDI. +.\" +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd November 21, 2003 +.Dt SETLOCALE 3 +.Os +.Sh NAME +.Nm setlocale +.Nd natural language formatting for C +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In locale.h +.Ft char * +.Fo setlocale +.Fa "int category" +.Fa "const char *locale" +.Fc +.Sh DESCRIPTION +The +.Fn setlocale +function sets the C library's notion +of natural language formatting style +for particular sets of routines. +Each such style is called a +.Sq locale +and is invoked using an appropriate name passed as a C string. +.Pp +The +.Fn setlocale +function recognizes several categories of routines. +These are the categories and the sets of routines they select: +.Pp +.Bl -tag -width LC_MONETARY +.It Dv LC_ALL +Set the entire locale generically. +.It Dv LC_COLLATE +Set a locale for string collation routines. +This controls alphabetic ordering in +.Fn strcoll +and +.Fn strxfrm . +.It Dv LC_CTYPE +Set a locale for the +.Xr ctype 3 +and +.Xr multibyte 3 +functions. +This controls recognition of upper and lower case, +alphabetic or non-alphabetic characters, +and so on. +.It Dv LC_MESSAGES +Set a locale for message catalogs, see +.Xr catopen 3 +function. +.It Dv LC_MONETARY +Set a locale for formatting monetary values; +this affects the +.Fn localeconv +function. +.It Dv LC_NUMERIC +Set a locale for formatting numbers. +This controls the formatting of decimal points +in input and output of floating point numbers +in functions such as +.Fn printf +and +.Fn scanf , +as well as values returned by +.Fn localeconv . +.It Dv LC_TIME +Set a locale for formatting dates and times using the +.Fn strftime +function. +.El +.Pp +Only three locales are defined by default: +the empty string +.Li "\&""\|"" +(which denotes the native environment) and the +.Li "\&""C"" +and +.Li "\&""POSIX"" +locales (which denote the C-language environment). +A +.Fa locale +argument of +.Dv NULL +causes +.Fn setlocale +to return the current locale. +By default, C programs start in the +.Li "\&""C"" +locale. +The only function in the library that sets the locale is +.Fn setlocale ; +the locale is never changed as a side effect of some other routine. +.Sh RETURN VALUES +Upon successful completion, +.Fn setlocale +returns the string associated with the specified +.Fa category +for the requested +.Fa locale . +The +.Fn setlocale +function returns +.Dv NULL +and fails to change the locale +if the given combination of +.Fa category +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 +.It Pa /usr/share/locale/ Ns Em locale/category +locale file for the locale +.Em locale +and the category +.Em category . +.El +.Sh SEE ALSO +.Xr colldef 1 , +.Xr mklocale 1 , +.Xr catopen 3 , +.Xr ctype 3 , +.Xr localeconv 3 , +.Xr multibyte 3 , +.Xr strcoll 3 , +.Xr strxfrm 3 , +.Xr euc 5 , +.Xr utf8 5 , +.Xr environ 7 +.Sh STANDARDS +The +.Fn setlocale +function conforms to +.St -isoC-99 . +.Sh HISTORY +The +.Fn setlocale +function first appeared in +.Bx 4.4 . diff --git a/locale/setlocale.h b/locale/setlocale.h new file mode 100644 index 0000000..b21f6f7 --- /dev/null +++ b/locale/setlocale.h @@ -0,0 +1,42 @@ +/*- + * Copyright (C) 1997 by Andrey A. Chernov, Moscow, Russia. + * 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 ``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/locale/setlocale.h,v 1.6 2003/07/06 02:03:37 ache Exp $ + */ + +#ifndef _SETLOCALE_H_ +#define _SETLOCALE_H_ + +#include + +#define ENCODING_LEN 31 +#define CATEGORY_LEN 11 + +extern char *_PathLocale; + +int __detect_path_locale(void); +int __wrap_setrunelocale(const char *, locale_t); + +#endif /* !_SETLOCALE_H_ */ diff --git a/locale/setrunelocale-fbsd.c b/locale/setrunelocale-fbsd.c new file mode 100644 index 0000000..c0cda24 --- /dev/null +++ b/locale/setrunelocale-fbsd.c @@ -0,0 +1,204 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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/setrunelocale.c,v 1.44 2004/10/18 02:06:18 ache Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ldpart.h" +#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 *); + +extern void spin_lock(int *); +extern void spin_unlock(int *); + +/* depreciated interfaces */ +rune_t sgetrune(const char *, size_t, char const **); +int sputrune(rune_t, char *, size_t, char **); + +__private_extern__ int +__setrunelocale(const char *encoding, locale_t loc) +{ + FILE *fp; + char name[PATH_MAX]; + struct __xlocale_st_runelocale *xrl; + _RuneLocale *rl; + int saverr, ret; + static struct __xlocale_st_runelocale *CachedRuneLocale; + extern int __mb_cur_max; + static int cache_lock = 0; + + /* + * The "C" and "POSIX" locale are always here. + */ + if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { + 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; + } + return (0); + } + + /* + * If the locale name is the same as our cache, use the cache. + */ + spin_lock(&cache_lock); + if (CachedRuneLocale != NULL && + strcmp(encoding, CachedRuneLocale->__ctype_encoding) == 0) { + XL_RELEASE(loc->__lc_ctype); + loc->__lc_ctype = CachedRuneLocale; + XL_RETAIN(loc->__lc_ctype); + if (loc == &__global_locale) { + _CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale; + __mb_cur_max = loc->__lc_ctype->__mb_cur_max; + } + spin_unlock(&cache_lock); + return (0); + } + spin_unlock(&cache_lock); + + /* + * Slurp the locale file into the cache. + */ + + /* Range checking not needed, encoding length already checked before */ + (void) strcpy(name, _PathLocale); + (void) strcat(name, "/"); + (void) strcat(name, encoding); + (void) strcat(name, "/LC_CTYPE"); + + if ((fp = fopen(name, "r")) == NULL) + return (errno == 0 ? ENOENT : errno); + + if ((xrl = _Read_RuneMagi(fp)) == NULL) { + saverr = (errno == 0 ? EFTYPE : errno); + (void)fclose(fp); + return (saverr); + } + (void)fclose(fp); + + xrl->__mbrtowc = NULL; + xrl->__mbsinit = NULL; + xrl->__mbsnrtowcs = __mbsnrtowcs_std; + xrl->__wcrtomb = NULL; + xrl->__wcsnrtombs = __wcsnrtombs_std; + + rl = &xrl->_CurrentRuneLocale; + + /* provide backwards compatibility (depreciated interface) */ + rl->__sputrune = sputrune; + rl->__sgetrune = sgetrune; + + if (strcmp(rl->__encoding, "NONE") == 0) + ret = _none_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) + ret = _GB18030_init(xrl); + else if (strcmp(rl->__encoding, "GB2312") == 0) + ret = _GB2312_init(xrl); + else if (strcmp(rl->__encoding, "GBK") == 0) + ret = _GBK_init(xrl); + else if (strcmp(rl->__encoding, "BIG5") == 0) + ret = _BIG5_init(xrl); + else if (strcmp(rl->__encoding, "MSKanji") == 0) + ret = _MSKanji_init(xrl); + else if (strcmp(rl->__encoding, "UTF2") == 0) + ret = _UTF2_init(xrl); + else + ret = EFTYPE; + if (ret == 0) { + (void)strcpy(xrl->__ctype_encoding, encoding); + XL_RELEASE(loc->__lc_ctype); + loc->__lc_ctype = xrl; + if (loc == &__global_locale) { + _CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale; + __mb_cur_max = loc->__lc_ctype->__mb_cur_max; + } + spin_lock(&cache_lock); + XL_RELEASE(CachedRuneLocale); + CachedRuneLocale = xrl; + XL_RETAIN(CachedRuneLocale); + spin_unlock(&cache_lock); + } else + XL_RELEASE(xrl); + + return (ret); +} + +int +setrunelocale(const char *encoding) +{ + return __setrunelocale(encoding, &__global_locale); +} + +__private_extern__ int +__wrap_setrunelocale(const char *locale, locale_t loc) +{ + int ret = __setrunelocale(locale, loc); + + if (ret != 0) { + errno = ret; + return (_LDP_ERROR); + } + return (_LDP_LOADED); +} + diff --git a/locale/table-fbsd.c b/locale/table-fbsd.c new file mode 100644 index 0000000..d2c3c44 --- /dev/null +++ b/locale/table-fbsd.c @@ -0,0 +1,473 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include "mblocal.h" + +/* _DefaultRuneLocale is depreciated; _DefaultRuneXLocale is used instead */ +_RuneLocale _DefaultRuneLocale = { + _RUNE_MAGIC_A, + "NONE", + NULL, + NULL, + 0xFFFD, + + { /*00*/ _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + /*08*/ _CTYPE_C, + _CTYPE_C|_CTYPE_S|_CTYPE_B, + _CTYPE_C|_CTYPE_S, + _CTYPE_C|_CTYPE_S, + _CTYPE_C|_CTYPE_S, + _CTYPE_C|_CTYPE_S, + _CTYPE_C, + _CTYPE_C, + /*10*/ _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + /*18*/ _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + /*20*/ _CTYPE_S|_CTYPE_B|_CTYPE_R, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*28*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*30*/ _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|0, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|1, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|2, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|3, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|4, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|5, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|6, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|7, + /*38*/ _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|8, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|9, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*40*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|10, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|11, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|12, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|13, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|14, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|15, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*48*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*50*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*58*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*60*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|10, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|11, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|12, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|13, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|14, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|15, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*68*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*70*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*78*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_C, + }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + }, +}; + +__private_extern__ struct __xlocale_st_runelocale _DefaultRuneXLocale = { + 0, + XPERMANENT, + "C", + 1, + _none_mbrtowc, + _none_mbsinit, + _none_mbsnrtowcs, + _none_wcrtomb, + _none_wcsnrtombs, + sizeof(struct __xlocale_st_runelocale), + { + _RUNE_MAGIC_A, + "NONE", + NULL, + NULL, + 0xFFFD, + + { /*00*/ _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + /*08*/ _CTYPE_C, + _CTYPE_C|_CTYPE_S|_CTYPE_B, + _CTYPE_C|_CTYPE_S, + _CTYPE_C|_CTYPE_S, + _CTYPE_C|_CTYPE_S, + _CTYPE_C|_CTYPE_S, + _CTYPE_C, + _CTYPE_C, + /*10*/ _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + /*18*/ _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + /*20*/ _CTYPE_S|_CTYPE_B|_CTYPE_R, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*28*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*30*/ _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|0, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|1, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|2, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|3, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|4, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|5, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|6, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|7, + /*38*/ _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|8, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|9, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*40*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|10, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|11, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|12, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|13, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|14, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|15, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*48*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*50*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*58*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*60*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|10, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|11, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|12, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|13, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|14, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|15, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*68*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*70*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*78*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_C, + }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + }, + }, +}; + +_RuneLocale *_CurrentRuneLocale = &_DefaultRuneXLocale._CurrentRuneLocale; + +int __mb_cur_max = 1; diff --git a/locale/toascii.3 b/locale/toascii.3 new file mode 120000 index 0000000..4df4474 --- /dev/null +++ b/locale/toascii.3 @@ -0,0 +1 @@ +./toascii.3 \ No newline at end of file diff --git a/locale/tolower-fbsd.c b/locale/tolower-fbsd.c new file mode 100644 index 0000000..4785d18 --- /dev/null +++ b/locale/tolower-fbsd.c @@ -0,0 +1,86 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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/tolower.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include + +__ct_rune_t +___tolower_l(c, loc) + __ct_rune_t c; + locale_t loc; +{ + size_t lim; + _RuneRange *rr; + _RuneEntry *base, *re; + + if (c < 0 || c == EOF) + return(c); + + NORMALIZE_LOCALE(loc); + /* + * the following is not used by tolower(), but can be used by + * tolower_l(). This provides the oppurtunity to optimize tolower() + * when compatibility for Panther and lower is no longer needed + */ + if (c < _CACHED_RUNES) + return loc->__lc_ctype->_CurrentRuneLocale.__maplower[c]; + rr = &loc->__lc_ctype->_CurrentRuneLocale.__maplower_ext; + /* Binary search -- see bsearch.c for explanation. */ + base = rr->__ranges; + for (lim = rr->__nranges; lim != 0; lim >>= 1) { + re = base + (lim >> 1); + if (re->__min <= c && c <= re->__max) + return (re->__map + c - re->__min); + else if (c > re->__max) { + base = re + 1; + lim--; + } + } + + return(c); +} + +__ct_rune_t +___tolower(c) + __ct_rune_t c; +{ + return ___tolower_l(c, __current_locale()); +} diff --git a/locale/tolower.3 b/locale/tolower.3 new file mode 100644 index 0000000..1121caf --- /dev/null +++ b/locale/tolower.3 @@ -0,0 +1,108 @@ +.\" Copyright (c) 1989, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt TOLOWER 3 +.Os +.Sh NAME +.Nm tolower , +.Nm tolower_l +.Nd upper case to lower case letter conversion +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fo tolower +.Fa "int c" +.Fc +.In ctype.h +.In xlocale.h +.Ft int +.Fo tolower_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +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 +or the value of +.Dv EOF . +.Pp +Although the +.Fn tolower +function uses the current locale, the +.Fn tolower_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +If the argument is an upper-case letter, the +.Fn tolower +function returns the corresponding lower-case letter if there is +one; otherwise, the argument is returned unchanged. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn towlower +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 +The +.Fn tolower +function conforms to +.St -isoC . diff --git a/locale/toupper-fbsd.c b/locale/toupper-fbsd.c new file mode 100644 index 0000000..a19ce98 --- /dev/null +++ b/locale/toupper-fbsd.c @@ -0,0 +1,86 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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/toupper.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include + +__ct_rune_t +___toupper_l(c, loc) + __ct_rune_t c; + locale_t loc; +{ + size_t lim; + _RuneRange *rr; + _RuneEntry *base, *re; + + if (c < 0 || c == EOF) + return(c); + + NORMALIZE_LOCALE(loc); + /* + * the following is not used by toupper(), but can be used by + * toupper_l(). This provides the oppurtunity to optimize toupper() + * when compatibility for Panther and lower is no longer needed + */ + if (c < _CACHED_RUNES) + return loc->__lc_ctype->_CurrentRuneLocale.__mapupper[c]; + rr = &loc->__lc_ctype->_CurrentRuneLocale.__mapupper_ext; + /* Binary search -- see bsearch.c for explanation. */ + base = rr->__ranges; + for (lim = rr->__nranges; lim != 0; lim >>= 1) { + re = base + (lim >> 1); + if (re->__min <= c && c <= re->__max) + return (re->__map + c - re->__min); + else if (c > re->__max) { + base = re + 1; + lim--; + } + } + + return(c); +} + +__ct_rune_t +___toupper(c) + __ct_rune_t c; +{ + return ___toupper_l(c, __current_locale()); +} diff --git a/locale/toupper.3 b/locale/toupper.3 new file mode 100644 index 0000000..12b67bb --- /dev/null +++ b/locale/toupper.3 @@ -0,0 +1,108 @@ +.\" Copyright (c) 1989, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 21, 2004 +.Dt TOUPPER 3 +.Os +.Sh NAME +.Nm toupper , +.Nm toupper_l +.Nd lower case to upper case letter conversion +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fo toupper +.Fa "int c" +.Fc +.In ctype.h +.In xlocale.h +.Ft int +.Fo toupper_l +.Fa "int c" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +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 +or the value of +.Dv EOF . +.Pp +Although the +.Fn toupper +function uses the current locale, the +.Fn toupper_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +If the argument is a lower-case letter, the +.Fn toupper +function returns the corresponding upper-case letter if there is +one; otherwise, the argument is returned unchanged. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn towupper +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 +The +.Fn toupper +function conforms to +.St -isoC . diff --git a/locale/towlower.3 b/locale/towlower.3 new file mode 100644 index 0000000..b4e25e3 --- /dev/null +++ b/locale/towlower.3 @@ -0,0 +1,89 @@ +.\" Copyright (c) 1989, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd October 3, 2002 +.Dt TOWLOWER 3 +.Os +.Sh NAME +.Nm towlower , +.Nm towlower_l +.Nd "upper case to lower case letter conversion (wide character version)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft wint_t +.Fo towlower +.Fa "wint_t wc" +.Fc +.In wctype.h +.In xlocale.h +.Ft wint_t +.Fo towlower_l +.Fa "wint_t wc" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn towlower +function converts an upper-case letter to the corresponding lower-case +letter. +.Pp +Although the +.Fn towlower +function uses the current locale, the +.Fn towlower_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +If the argument is an upper-case letter, the +.Fn towlower +function returns the corresponding lower-case letter if there is +one; otherwise, the argument is returned unchanged. +.Sh SEE ALSO +.Xr iswlower 3 , +.Xr tolower 3 , +.Xr towupper 3 , +.Xr wctrans 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn towlower +function conforms to +.St -isoC-99 . diff --git a/locale/towupper.3 b/locale/towupper.3 new file mode 100644 index 0000000..87a85df --- /dev/null +++ b/locale/towupper.3 @@ -0,0 +1,89 @@ +.\" Copyright (c) 1989, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd October 3, 2002 +.Dt TOWUPPER 3 +.Os +.Sh NAME +.Nm towupper , +.Nm towupper_l +.Nd "lower case to upper case letter conversion (wide character version)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft wint_t +.Fo towupper +.Fa "wint_t wc" +.Fc +.In wctype.h +.In xlocale.h +.Ft wint_t +.Fo towupper_l +.Fa "wint_t wc" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn towupper +function converts a lower-case letter to the corresponding +upper-case letter. +.Pp +Although the +.Fn towupper +function uses the current locale, the +.Fn towupper_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +If the argument is a lower-case letter, the +.Fn towupper +function returns the corresponding upper-case letter if there is +one; otherwise, the argument is returned unchanged. +.Sh SEE ALSO +.Xr iswupper 3 , +.Xr toupper 3 , +.Xr towlower 3 , +.Xr wctrans 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn towupper +function conforms to +.St -isoC-99 . diff --git a/locale/uselocale.3 b/locale/uselocale.3 index 10de10e..df15583 100644 --- a/locale/uselocale.3 +++ b/locale/uselocale.3 @@ -24,8 +24,8 @@ Returns the previous locale, or .Dv LC_GLOBAL_LOCALE if no per-thread locale was in effect. .Sh SEE ALSO -.Xr xlocale 3 , .Xr duplocale 3 , .Xr freelocale 3 , .Xr newlocale 3 , -.Xr querylocale 3 +.Xr querylocale 3 , +.Xr xlocale 3 diff --git a/locale/utf2-fbsd.c b/locale/utf2-fbsd.c new file mode 100644 index 0000000..53fa1f5 --- /dev/null +++ b/locale/utf2-fbsd.c @@ -0,0 +1,402 @@ +/*- + * 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 +/* 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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +#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 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_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict, locale_t); + +typedef struct { + wchar_t ch; + int want; + wchar_t lbound; +} _UTF2State; + +__private_extern__ int +_UTF2_init(struct __xlocale_st_runelocale *xrl) +{ + + xrl->__mbrtowc = _UTF2_mbrtowc; + xrl->__wcrtomb = _UTF2_wcrtomb; + xrl->__mbsinit = _UTF2_mbsinit; + xrl->__mbsnrtowcs = _UTF2_mbsnrtowcs; + xrl->__wcsnrtombs = _UTF2_wcsnrtombs; + xrl->__mb_cur_max = UTF2_MB_CUR_MAX; + + return (0); +} + +static int +_UTF2_mbsinit(const mbstate_t *ps, locale_t loc) +{ + + return (ps == NULL || ((const _UTF2State *)ps)->want == 0); +} + +static size_t +_UTF2_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t loc) +{ + _UTF2State *us; + int ch, i, mask, want; + wchar_t lbound, wch; + + us = (_UTF2State *)ps; + + if (us->want < 0 || us->want > 3) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + if (us->want == 0 && ((ch = (unsigned char)*s) & ~0x7f) == 0) { + /* Fast path for plain ASCII characters. */ + if (pwc != NULL) + *pwc = ch; + return (ch != '\0' ? 1 : 0); + } + + if (us->want == 0) { + /* + * Determine the number of octets that make up this character + * from the first octet, and a mask that extracts the + * interesting bits of the first octet. We already know + * the character is at least two bytes long. + * + * We also specify a lower bound for the character code to + * detect redundant, non-"shortest form" encodings. For + * example, the sequence C0 80 is _not_ a legal representation + * of the null character. This enforces a 1-to-1 mapping + * between character codes and their multibyte representations. + */ + ch = (unsigned char)*s; + if ((ch & 0x80) == 0) { + mask = 0x7f; + want = 1; + lbound = 0; + } else if ((ch & 0xe0) == 0xc0) { + mask = 0x1f; + want = 2; + lbound = 0x80; + } else if ((ch & 0xf0) == 0xe0) { + mask = 0x0f; + want = 3; + lbound = 0x800; + } else { + /* + * Malformed input; input is not UTF2. + */ + errno = EILSEQ; + return ((size_t)-1); + } + } else { + want = us->want; + lbound = us->lbound; + } + + /* + * Decode the octet sequence representing the character in chunks + * of 6 bits, most significant first. + */ + if (us->want == 0) + wch = (unsigned char)*s++ & mask; + else + wch = us->ch; + for (i = (us->want == 0) ? 1 : 0; i < MIN(want, n); i++) { + if ((*s & 0xc0) != 0x80) { + /* + * Malformed input; bad characters in the middle + * of a character. + */ + errno = EILSEQ; + return ((size_t)-1); + } + wch <<= 6; + wch |= *s++ & 0x3f; + } + if (i < want) { + /* Incomplete multibyte sequence. */ + us->want = want - i; + us->lbound = lbound; + us->ch = wch; + return ((size_t)-2); + } + if (wch < lbound) { + /* + * Malformed input; redundant encoding. + */ + errno = EILSEQ; + return ((size_t)-1); + } + if (pwc != NULL) + *pwc = wch; + us->want = 0; + return (wch == L'\0' ? 0 : want); +} + +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) +{ + _UTF2State *us; + const char *s; + size_t nchr; + wchar_t wc; + size_t nb; + + us = (_UTF2State *)ps; + + s = *src; + nchr = 0; + + if (dst == NULL) { + /* + * The fast path in the loop below is not safe if an ASCII + * character appears as anything but the first byte of a + * multibyte sequence. Check now to avoid doing it in the loop. + */ + if (nms > 0 && us->want > 0 && (signed char)*s > 0) { + errno = EILSEQ; + return ((size_t)-1); + } + for (;;) { + if (nms > 0 && (signed char)*s > 0) + /* + * Fast path for plain ASCII characters + * excluding NUL. + */ + nb = 1; + else if ((nb = _UTF2_mbrtowc(&wc, s, nms, ps, loc)) == + (size_t)-1) + /* Invalid sequence - mbrtowc() sets errno. */ + return ((size_t)-1); + else if (nb == 0 || nb == (size_t)-2) + return (nchr); + s += nb; + nms -= nb; + nchr++; + } + /*NOTREACHED*/ + } + + /* + * The fast path in the loop below is not safe if an ASCII + * character appears as anything but the first byte of a + * multibyte sequence. Check now to avoid doing it in the loop. + */ + if (nms > 0 && len > 0 && us->want > 0 && (signed char)*s > 0) { + errno = EILSEQ; + return ((size_t)-1); + } + while (len-- > 0) { + if (nms > 0 && (signed char)*s > 0) { + /* + * Fast path for plain ASCII characters + * excluding NUL. + */ + *dst = (wchar_t)*s; + nb = 1; + } else if ((nb = _UTF2_mbrtowc(dst, s, nms, ps, loc)) == + (size_t)-1) { + *src = s; + return ((size_t)-1); + } else if (nb == (size_t)-2) { + *src = s + nms; + return (nchr); + } else if (nb == 0) { + *src = NULL; + return (nchr); + } + s += nb; + nms -= nb; + nchr++; + dst++; + } + *src = s; + return (nchr); +} + +static size_t +_UTF2_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +{ + _UTF2State *us; + unsigned char lead; + int i, len; + + us = (_UTF2State *)ps; + + if (us->want != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + + if ((wc & ~0x7f) == 0) { + /* Fast path for plain ASCII characters. */ + *s = (char)wc; + return (1); + } + + /* + * Determine the number of octets needed to represent this character. + * We always output the shortest sequence possible. Also specify the + * first few bits of the first octet, which contains the information + * about the sequence length. + */ + if ((wc & ~0x7f) == 0) { + lead = 0; + len = 1; + } else if ((wc & ~0x7ff) == 0) { + lead = 0xc0; + len = 2; + } else if ((wc & ~0xffff) == 0) { + lead = 0xe0; + len = 3; + } else { + errno = EILSEQ; + return ((size_t)-1); + } + + /* + * Output the octets representing the character in chunks + * of 6 bits, least significant last. The first octet is + * a special case because it contains the sequence length + * information. + */ + for (i = len - 1; i > 0; i--) { + s[i] = (wc & 0x3f) | 0x80; + wc >>= 6; + } + *s = (wc & 0xff) | lead; + + return (len); +} + +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) +{ + _UTF2State *us; + char buf[MB_LEN_MAX]; + const wchar_t *s; + size_t nbytes; + size_t nb; + + us = (_UTF2State *)ps; + + if (us->want != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + s = *src; + nbytes = 0; + + if (dst == NULL) { + while (nwc-- > 0) { + if (0 <= *s && *s < 0x80) + /* Fast path for plain ASCII characters. */ + nb = 1; + else if ((nb = _UTF2_wcrtomb(buf, *s, ps, loc)) == + (size_t)-1) + /* Invalid character - wcrtomb() sets errno. */ + return ((size_t)-1); + if (*s == L'\0') + return (nbytes + nb - 1); + s++; + nbytes += nb; + } + return (nbytes); + } + + while (len > 0 && nwc-- > 0) { + if (0 <= *s && *s < 0x80) { + /* Fast path for plain ASCII characters. */ + nb = 1; + *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) { + *src = s; + return ((size_t)-1); + } + } else { + /* + * May not be enough space; use temp. buffer. + */ + if ((nb = (int)_UTF2_wcrtomb(buf, *s, ps, loc)) < 0) { + *src = s; + return ((size_t)-1); + } + if (nb > (int)len) + /* MB sequence for character won't fit. */ + break; + memcpy(dst, buf, nb); + } + if (*s == L'\0') { + *src = NULL; + return (nbytes + nb - 1); + } + s++; + dst += nb; + len -= nb; + nbytes += nb; + } + *src = s; + return (nbytes); +} diff --git a/locale/utf8-fbsd.c b/locale/utf8-fbsd.c new file mode 100644 index 0000000..cd5d052 --- /dev/null +++ b/locale/utf8-fbsd.c @@ -0,0 +1,422 @@ +/*- + * 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/locale/utf8.c,v 1.11 2004/07/27 06:29:48 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +#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 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); + +typedef struct { + wchar_t ch; + int want; + wchar_t lbound; +} _UTF8State; + +__private_extern__ int +_UTF8_init(struct __xlocale_st_runelocale *xrl) +{ + + xrl->__mbrtowc = _UTF8_mbrtowc; + xrl->__wcrtomb = _UTF8_wcrtomb; + xrl->__mbsinit = _UTF8_mbsinit; + xrl->__mbsnrtowcs = _UTF8_mbsnrtowcs; + xrl->__wcsnrtombs = _UTF8_wcsnrtombs; + xrl->__mb_cur_max = UTF8_MB_CUR_MAX; + + return (0); +} + +static int +_UTF8_mbsinit(const mbstate_t *ps, locale_t loc) +{ + + return (ps == NULL || ((const _UTF8State *)ps)->want == 0); +} + +static size_t +_UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t loc) +{ + _UTF8State *us; + int ch, i, mask, want; + wchar_t lbound, wch; + + us = (_UTF8State *)ps; + + if (us->want < 0 || us->want > 6) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + if (us->want == 0 && ((ch = (unsigned char)*s) & ~0x7f) == 0) { + /* Fast path for plain ASCII characters. */ + if (pwc != NULL) + *pwc = ch; + return (ch != '\0' ? 1 : 0); + } + + if (us->want == 0) { + /* + * Determine the number of octets that make up this character + * from the first octet, and a mask that extracts the + * interesting bits of the first octet. We already know + * the character is at least two bytes long. + * + * We also specify a lower bound for the character code to + * detect redundant, non-"shortest form" encodings. For + * example, the sequence C0 80 is _not_ a legal representation + * of the null character. This enforces a 1-to-1 mapping + * between character codes and their multibyte representations. + */ + ch = (unsigned char)*s; + if ((ch & 0x80) == 0) { + mask = 0x7f; + want = 1; + lbound = 0; + } else if ((ch & 0xe0) == 0xc0) { + mask = 0x1f; + want = 2; + lbound = 0x80; + } else if ((ch & 0xf0) == 0xe0) { + mask = 0x0f; + want = 3; + lbound = 0x800; + } else if ((ch & 0xf8) == 0xf0) { + mask = 0x07; + want = 4; + lbound = 0x10000; + } else if ((ch & 0xfc) == 0xf8) { + mask = 0x03; + want = 5; + lbound = 0x200000; + } else if ((ch & 0xfc) == 0xfc) { + mask = 0x01; + want = 6; + lbound = 0x4000000; + } else { + /* + * Malformed input; input is not UTF-8. + */ + errno = EILSEQ; + return ((size_t)-1); + } + } else { + want = us->want; + lbound = us->lbound; + } + + /* + * Decode the octet sequence representing the character in chunks + * of 6 bits, most significant first. + */ + if (us->want == 0) + wch = (unsigned char)*s++ & mask; + else + wch = us->ch; + for (i = (us->want == 0) ? 1 : 0; i < MIN(want, n); i++) { + if ((*s & 0xc0) != 0x80) { + /* + * Malformed input; bad characters in the middle + * of a character. + */ + errno = EILSEQ; + return ((size_t)-1); + } + wch <<= 6; + wch |= *s++ & 0x3f; + } + if (i < want) { + /* Incomplete multibyte sequence. */ + us->want = want - i; + us->lbound = lbound; + us->ch = wch; + return ((size_t)-2); + } + if (wch < lbound) { + /* + * Malformed input; redundant encoding. + */ + errno = EILSEQ; + return ((size_t)-1); + } + if (pwc != NULL) + *pwc = wch; + us->want = 0; + return (wch == L'\0' ? 0 : want); +} + +static size_t +_UTF8_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc) +{ + _UTF8State *us; + const char *s; + size_t nchr; + wchar_t wc; + size_t nb; + + us = (_UTF8State *)ps; + + s = *src; + nchr = 0; + + if (dst == NULL) { + /* + * The fast path in the loop below is not safe if an ASCII + * character appears as anything but the first byte of a + * multibyte sequence. Check now to avoid doing it in the loop. + */ + if (nms > 0 && us->want > 0 && (signed char)*s > 0) { + errno = EILSEQ; + return ((size_t)-1); + } + for (;;) { + if (nms > 0 && (signed char)*s > 0) + /* + * Fast path for plain ASCII characters + * excluding NUL. + */ + nb = 1; + else if ((nb = _UTF8_mbrtowc(&wc, s, nms, ps, loc)) == + (size_t)-1) + /* Invalid sequence - mbrtowc() sets errno. */ + return ((size_t)-1); + else if (nb == 0 || nb == (size_t)-2) + return (nchr); + s += nb; + nms -= nb; + nchr++; + } + /*NOTREACHED*/ + } + + /* + * The fast path in the loop below is not safe if an ASCII + * character appears as anything but the first byte of a + * multibyte sequence. Check now to avoid doing it in the loop. + */ + if (nms > 0 && len > 0 && us->want > 0 && (signed char)*s > 0) { + errno = EILSEQ; + return ((size_t)-1); + } + while (len-- > 0) { + if (nms > 0 && (signed char)*s > 0) { + /* + * Fast path for plain ASCII characters + * excluding NUL. + */ + *dst = (wchar_t)*s; + nb = 1; + } else if ((nb = _UTF8_mbrtowc(dst, s, nms, ps, loc)) == + (size_t)-1) { + *src = s; + return ((size_t)-1); + } else if (nb == (size_t)-2) { + *src = s + nms; + return (nchr); + } else if (nb == 0) { + *src = NULL; + return (nchr); + } + s += nb; + nms -= nb; + nchr++; + dst++; + } + *src = s; + return (nchr); +} + +static size_t +_UTF8_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t loc) +{ + _UTF8State *us; + unsigned char lead; + int i, len; + + us = (_UTF8State *)ps; + + if (us->want != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + + if ((wc & ~0x7f) == 0) { + /* Fast path for plain ASCII characters. */ + *s = (char)wc; + return (1); + } + + /* + * Determine the number of octets needed to represent this character. + * We always output the shortest sequence possible. Also specify the + * first few bits of the first octet, which contains the information + * about the sequence length. + */ + if ((wc & ~0x7f) == 0) { + lead = 0; + len = 1; + } else if ((wc & ~0x7ff) == 0) { + lead = 0xc0; + len = 2; + } else if ((wc & ~0xffff) == 0) { + lead = 0xe0; + len = 3; + } else if ((wc & ~0x1fffff) == 0) { + lead = 0xf0; + len = 4; + } else if ((wc & ~0x3ffffff) == 0) { + lead = 0xf8; + len = 5; + } else if ((wc & ~0x7fffffff) == 0) { + lead = 0xfc; + len = 6; + } else { + errno = EILSEQ; + return ((size_t)-1); + } + + /* + * Output the octets representing the character in chunks + * of 6 bits, least significant last. The first octet is + * a special case because it contains the sequence length + * information. + */ + for (i = len - 1; i > 0; i--) { + s[i] = (wc & 0x3f) | 0x80; + wc >>= 6; + } + *s = (wc & 0xff) | lead; + + return (len); +} + +static size_t +_UTF8_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, + size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc) +{ + _UTF8State *us; + char buf[MB_LEN_MAX]; + const wchar_t *s; + size_t nbytes; + size_t nb; + + us = (_UTF8State *)ps; + + if (us->want != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + s = *src; + nbytes = 0; + + if (dst == NULL) { + while (nwc-- > 0) { + if (0 <= *s && *s < 0x80) + /* Fast path for plain ASCII characters. */ + nb = 1; + else if ((nb = _UTF8_wcrtomb(buf, *s, ps, loc)) == + (size_t)-1) + /* Invalid character - wcrtomb() sets errno. */ + return ((size_t)-1); + if (*s == L'\0') + return (nbytes + nb - 1); + s++; + nbytes += nb; + } + return (nbytes); + } + + while (len > 0 && nwc-- > 0) { + if (0 <= *s && *s < 0x80) { + /* Fast path for plain ASCII characters. */ + nb = 1; + *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) { + *src = s; + return ((size_t)-1); + } + } else { + /* + * May not be enough space; use temp. buffer. + */ + if ((nb = (int)_UTF8_wcrtomb(buf, *s, ps, loc)) < 0) { + *src = s; + return ((size_t)-1); + } + if (nb > (int)len) + /* MB sequence for character won't fit. */ + break; + memcpy(dst, buf, nb); + } + if (*s == L'\0') { + *src = NULL; + return (nbytes + nb - 1); + } + s++; + dst += nb; + len -= nb; + nbytes += nb; + } + *src = s; + return (nbytes); +} diff --git a/locale/utf8.5 b/locale/utf8.5 new file mode 120000 index 0000000..6992565 --- /dev/null +++ b/locale/utf8.5 @@ -0,0 +1 @@ +./utf8.5 \ No newline at end of file diff --git a/locale/wcrtomb-fbsd.c b/locale/wcrtomb-fbsd.c new file mode 100644 index 0000000..81b99d4 --- /dev/null +++ b/locale/wcrtomb-fbsd.c @@ -0,0 +1,49 @@ +/*- + * 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/locale/wcrtomb.c,v 1.8 2004/05/12 14:09:04 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include "mblocal.h" + +size_t +wcrtomb_l(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, + locale_t loc) +{ + NORMALIZE_LOCALE(loc); + if (ps == NULL) + ps = &loc->__mbs_wcrtomb; + return (loc->__lc_ctype->__wcrtomb(s, wc, ps, loc)); +} + +size_t +wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) +{ + return wcrtomb_l(s, wc, ps, __current_locale()); +} diff --git a/locale/wcrtomb.3 b/locale/wcrtomb.3 new file mode 100644 index 0000000..2b320a2 --- /dev/null +++ b/locale/wcrtomb.3 @@ -0,0 +1,128 @@ +.\" 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/wcrtomb.3,v 1.4 2004/04/08 09:59:02 tjr Exp $ +.\" +.Dd April 8, 2004 +.Dt WCRTOMB 3 +.Os +.Sh NAME +.Nm wcrtomb , +.Nm wcrtomb_l +.Nd "convert a wide-character code to a character (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo wcrtomb +.Fa "char *restrict s" +.Fa "wchar_t wc" +.Fa "mbstate_t *restrict ps" +.Fc +.In wchar.h +.In xlocale.h +.Ft size_t +.Fo wcrtomb_l +.Fa "char *restrict s" +.Fa "wchar_t wc" +.Fa "mbstate_t *restrict ps" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wcrtomb +function stores a multibyte sequence representing the +wide character +.Fa wc , +including any necessary shift sequences, to the +character array +.Fa s . +A maximum of +.Dv MB_CUR_MAX +bytes will be stored. +.Pp +If +.Fa s +is +.Dv NULL , +.Fn wcrtomb +behaves as if +.Fa s +pointed to an internal buffer and +.Fa wc +were a null wide character (L'\e0'). +.Pp +The +.Ft mbstate_t +argument, +.Fa ps , +is used to keep track of the shift state. +If it is +.Dv NULL , +.Fn wcrtomb +uses an internal, static +.Vt mbstate_t +object, which is initialized to the initial conversion state +at program startup. +.Pp +While the +.Fn wcrtomb +function uses the current locale, the +.Fn wcrtomb_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn wcrtomb +functions returns the length (in bytes) of the multibyte sequence +needed to represent +.Fa wc , +or +.Po Vt size_t Pc Ns \-1 +if +.Fa wc +is not a valid wide character code. +.Sh ERRORS +The +.Fn wcrtomb +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid wide character code was specified. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbrtowc 3 , +.Xr multibyte 3 , +.Xr setlocale 3 , +.Xr wctomb 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn wcrtomb +function conforms to +.St -isoC-99 . diff --git a/locale/wcsftime-fbsd.c b/locale/wcsftime-fbsd.c new file mode 100644 index 0000000..bf413e1 --- /dev/null +++ b/locale/wcsftime-fbsd.c @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 2002 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/locale/wcsftime.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include + +/* + * Convert date and time to a wide-character string. + * + * This is the wide-character counterpart of strftime(). So that we do not + * have to duplicate the code of strftime(), we convert the format string to + * multibyte, call strftime(), then convert the result back into wide + * characters. + * + * This technique loses in the presence of stateful multibyte encoding if any + * of the conversions in the format string change conversion state. When + * stateful encoding is implemented, we will need to reset the state between + * format specifications in the format string. + */ +size_t +wcsftime_l(wchar_t * __restrict wcs, size_t maxsize, + const wchar_t * __restrict format, const struct tm * __restrict timeptr, + locale_t loc) +{ + static const mbstate_t initial; + mbstate_t mbs; + char *dst, *dstp, *sformat; + size_t n, sflen; + int sverrno; + + NORMALIZE_LOCALE(loc); + sformat = dst = NULL; + + /* + * Convert the supplied format string to a multibyte representation + * for strftime(), which only handles single-byte characters. + */ + mbs = initial; + sflen = wcsrtombs_l(NULL, &format, 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); + + /* + * Allocate memory for longest multibyte sequence that will fit + * into the caller's buffer and call strftime() to fill it. + * Then, copy and convert the result back into wide characters in + * the caller's buffer. + */ + if (SIZE_T_MAX / MB_CUR_MAX_L(loc) <= maxsize) { + /* maxsize is prepostorously large - avoid int. overflow. */ + errno = EINVAL; + goto error; + } + if ((dst = malloc(maxsize * MB_CUR_MAX_L(loc))) == NULL) + goto error; + if (strftime_l(dst, maxsize, sformat, timeptr, loc) == 0) + goto error; + dstp = dst; + mbs = initial; + n = mbsrtowcs_l(wcs, (const char **)&dstp, maxsize, &mbs, loc); + if (n == (size_t)-2 || n == (size_t)-1 || dstp != NULL) + goto error; + + free(sformat); + free(dst); + return (n); + +error: + sverrno = errno; + free(sformat); + free(dst); + errno = sverrno; + return (0); +} + +size_t +wcsftime(wchar_t * __restrict wcs, size_t maxsize, + const wchar_t * __restrict format, const struct tm * __restrict timeptr) +{ + return wcsftime_l(wcs, maxsize, format, timeptr, __current_locale()); +} diff --git a/locale/wcsftime.3 b/locale/wcsftime.3 new file mode 100644 index 0000000..b11967a --- /dev/null +++ b/locale/wcsftime.3 @@ -0,0 +1,88 @@ +.\" Copyright (c) 2002 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/wcsftime.3,v 1.2 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd September 8, 2002 +.Dt WCSFTIME 3 +.Os +.Sh NAME +.Nm wcsftime , +.Nm wcsftime_l +.Nd "convert date and time to a wide-character string" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo wcsftime +.Fa "wchar_t *restrict wcs" +.Fa "size_t maxsize" +.Fa "const wchar_t *restrict format" +.Fa "const struct tm *restrict timeptr" +.Fc +.In wchar.h +.In xlocale.h +.Ft size_t +.Fo wcsftime_l +.Fa "wchar_t *restrict wcs" +.Fa "size_t maxsize" +.Fa "const wchar_t *restrict format" +.Fa "const struct tm *restrict timeptr" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wcsftime +function is equivalent to the +.Fn strftime +function, except for the types of its arguments. +Refer to +.Xr strftime 3 +for a detailed description. +.Pp +While the +.Fn wcsftime +function uses the current locale, the +.Fn wcsftime_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh COMPATIBILITY +Some early implementations of +.Fn wcsftime +had a +.Fa format +argument with type +.Vt "const char *" , +instead of +.Vt "const wchar_t *" . +.Sh SEE ALSO +.Xr strftime 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn wcsftime +function conforms to +.St -isoC-99 . diff --git a/locale/wcsnrtombs-fbsd.c b/locale/wcsnrtombs-fbsd.c new file mode 100644 index 0000000..7c58c2f --- /dev/null +++ b/locale/wcsnrtombs-fbsd.c @@ -0,0 +1,122 @@ +/*- + * 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/locale/wcsnrtombs.c,v 1.2 2004/07/22 02:57:29 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include "mblocal.h" + +size_t +wcsnrtombs_l(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, + size_t len, mbstate_t * __restrict ps, locale_t loc) +{ + NORMALIZE_LOCALE(loc); + if (ps == NULL) + ps = &loc->__mbs_wcsnrtombs; + return (loc->__lc_ctype->__wcsnrtombs(dst, src, nwc, len, ps, loc)); +} + +size_t +wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, + size_t len, mbstate_t * __restrict ps) +{ + return wcsnrtombs_l(dst, src, nwc, len, ps, __current_locale()); +} + +__private_extern__ size_t +__wcsnrtombs_std(char * __restrict dst, const wchar_t ** __restrict src, + size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc) +{ + mbstate_t mbsbak; + char buf[MB_LEN_MAX]; + const wchar_t *s; + size_t nbytes; + size_t nb; + struct __xlocale_st_runelocale *runeLocale = loc->__lc_ctype; + size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t) = runeLocale->__wcrtomb; + int mb_cur_max = runeLocale->__mb_cur_max; + + s = *src; + nbytes = 0; + + if (dst == NULL) { + while (nwc-- > 0) { + if ((nb = __wcrtomb(buf, *s, ps, loc)) == (size_t)-1) + /* Invalid character - wcrtomb() sets errno. */ + return ((size_t)-1); + else if (*s == L'\0') + return (nbytes + nb - 1); + s++; + nbytes += nb; + } + return (nbytes); + } + + 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) { + *src = s; + return ((size_t)-1); + } + } else { + /* + * May not be enough space; use temp. buffer. + * + * We need to save a copy of the conversion state + * here so we can restore it if the multibyte + * character is too long for the buffer. + */ + mbsbak = *ps; + if ((nb = (int)__wcrtomb(buf, *s, ps, loc)) < 0) { + *src = s; + return ((size_t)-1); + } + if (nb > (int)len) { + /* MB sequence for character won't fit. */ + *ps = mbsbak; + break; + } + memcpy(dst, buf, nb); + } + if (*s == L'\0') { + *src = NULL; + return (nbytes + nb - 1); + } + s++; + dst += nb; + len -= nb; + nbytes += nb; + } + *src = s; + return (nbytes); +} diff --git a/locale/wcsrtombs-fbsd.c b/locale/wcsrtombs-fbsd.c new file mode 100644 index 0000000..483b862 --- /dev/null +++ b/locale/wcsrtombs-fbsd.c @@ -0,0 +1,53 @@ +/*- + * 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/locale/wcsrtombs.c,v 1.6 2004/07/21 10:54:57 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include "mblocal.h" + +size_t +wcsrtombs_l(char * __restrict dst, const wchar_t ** __restrict src, size_t len, + mbstate_t * __restrict ps, locale_t loc) +{ + NORMALIZE_LOCALE(loc); + if (ps == NULL) + ps = &loc->__mbs_wcsrtombs; + return (loc->__lc_ctype->__wcsnrtombs(dst, src, SIZE_T_MAX, len, ps, loc)); +} + +size_t +wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len, + mbstate_t * __restrict ps) +{ + return wcsrtombs_l(dst, src, len, ps, __current_locale()); +} diff --git a/locale/wcsrtombs.3 b/locale/wcsrtombs.3 new file mode 100644 index 0000000..0848655 --- /dev/null +++ b/locale/wcsrtombs.3 @@ -0,0 +1,175 @@ +.\" 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/wcsrtombs.3,v 1.5 2004/07/21 10:54:57 tjr Exp $ +.\" +.Dd July 21, 2004 +.Dt WCSRTOMBS 3 +.Os +.Sh NAME +.Nm wcsnrtombs , +.Nm wcsnrtombs_l , +.Nm wcsrtombs , +.Nm wcsrtombs_l +.Nd "convert a wide-character string to a character string (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo wcsnrtombs +.Fa "char *restrict dst" +.Fa "const wchar_t **restrict src" +.Fa "size_t nwc" +.Fa "size_t len" +.Fa "mbstate_t *restrict ps" +.Fc +.Ft size_t +.Fo wcsrtombs +.Fa "char *restrict dst" +.Fa "const wchar_t **restrict src" +.Fa "size_t len" +.Fa "mbstate_t *restrict ps" +.Fc +.In wchar.h +.In xlocale.h +.Ft size_t +.Fo wcsnrtombs_l +.Fa "char *restrict dst" +.Fa "const wchar_t **restrict src" +.Fa "size_t nwc" +.Fa "size_t len" +.Fa "mbstate_t *restrict ps" +.Fa "locale_t loc" +.Fc +.Ft size_t +.Fo wcsrtombs_l +.Fa "char *restrict dst" +.Fa "const wchar_t **restrict src" +.Fa "size_t len" +.Fa "mbstate_t *restrict ps" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wcsrtombs +function converts a string of wide characters, +indirectly pointed to by +.Fa src , +to a corresponding multi-byte character string, +stored in the array pointed to by +.Fa dst . +No more than +.Fa len +bytes are written to +.Fa dst . +.Pp +If +.Fa dst +is +.Dv NULL , +no characters are stored. +.Pp +If +.Fa dst +is not +.Dv NULL , +the pointer pointed to by +.Fa src +is updated to point to the character after the one that conversion stopped at. +If conversion stops because a null character is encountered, +.Fa *src +is set to +.Dv NULL . +.Pp +The +.Vt mbstate_t +argument, +.Fa ps , +is used to keep track of the shift state. +If it is +.Dv NULL , +.Fn wcsrtombs +uses an internal, static +.Vt mbstate_t +object, which is initialized to the initial conversion state +at program startup. +.Pp +The +.Fn wcsnrtombs +function behaves identically to +.Fn wcsrtombs , +except that conversion stops after reading at most +.Fa nwc +characters from the buffer pointed to by +.Fa src . +.Pp +Although the +.Fn wcsrtombs +and +.Fn wcsnrtombs +functions use the current locale, the +.Fn wcsrtombs_l +and +.Fn wcsnrtombs_l +functions may be passed locales directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +If successful, the +.Fn wcsrtombs +and +.Fn wcsnrtombs +functions return the number of bytes stored in +the array pointed to by +.Fa dst +(not including any terminating null); +otherwise, they return +.Po Vt size_t Pc Ns \-1 . +.Sh ERRORS +The +.Fn wcsrtombs +and +.Fn wcsnrtombs +functions will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid wide character was encountered. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbsrtowcs 3 , +.Xr wcrtomb 3 , +.Xr wcstombs 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn wcsrtombs +function conforms to +.St -isoC-99 . +.Pp +The +.Fn wcsnrtombs +function is an extension to the standard. diff --git a/locale/wcstod-fbsd.c b/locale/wcstod-fbsd.c new file mode 100644 index 0000000..e2470d6 --- /dev/null +++ b/locale/wcstod-fbsd.c @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 2002 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/locale/wcstod.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include <_simple.h> + +/* + * Convert a string to a double-precision number. + * + * This is the wide-character counterpart of strtod(). So that we do not + * have to duplicate the code of strtod() here, we convert the supplied + * wide character string to multibyte and call strtod() on the result. + * This assumes that the multibyte encoding is compatible with ASCII + * for at least the digits, radix character and letters. + */ +double +wcstod_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + locale_t loc) +{ + static const mbstate_t initial; + mbstate_t mbs; + double val; + char *buf, *end; + size_t len; + locale_t ctype; + _SIMPLE_STRING b; + char mb[MB_CUR_MAX + 1]; + const wchar_t *nptr0 = nptr; + const wchar_t *first; + + NORMALIZE_LOCALE(loc); + ctype = __numeric_ctype(loc); + + while (iswspace_l(*nptr, ctype)) + nptr++; + + if ((b = _simple_salloc()) == NULL) + return (0.0); + + first = nptr; + mbs = initial; + while (*nptr && (len = wcrtomb_l(mb, *nptr, &mbs, ctype)) != (size_t)-1) { + mb[len] = 0; + if (_simple_sappend(b, mb) < 0) { /* no memory */ + _simple_sfree(b); + return (0.0); + } + nptr++; + } + + /* Let strtod() do most of the work for us. */ + buf = _simple_string(b); + val = strtod_l(buf, &end, loc); + + /* + * We only know where the number ended in the _multibyte_ + * representation of the string. If the caller wants to know + * where it ended, count multibyte characters to find the + * corresponding position in the wide char string. + */ + if (endptr != NULL) + /* XXX Assume each wide char is one byte. */ + *endptr = (end == buf) ? (wchar_t *)nptr0 : ((wchar_t *)first + (end - buf)); + + _simple_sfree(b); + + return (val); +} + +double +wcstod(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + return wcstod_l(nptr, endptr, __current_locale()); +} diff --git a/locale/wcstod.3 b/locale/wcstod.3 new file mode 100644 index 0000000..9595d07 --- /dev/null +++ b/locale/wcstod.3 @@ -0,0 +1,90 @@ +.\" Copyright (c) 2002, 2003 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/wcstod.3,v 1.4 2003/05/22 13:02:27 ru Exp $ +.\" +.Dd February 22, 2003 +.Dt WCSTOD 3 +.Os +.Sh NAME +.Nm wcstod , +.Nm wcstof , +.Nm wcstold +.Nd convert string to +.Vt float , +.Vt double , +or +.Vt "long double" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft double +.Fo wcstod +.Fa "const wchar_t *restrict nptr" +.Fa "wchar_t **restrict endptr" +.Fc +.Ft float +.Fo wcstof +.Fa "const wchar_t *restrict nptr" +.Fa "wchar_t **restrict endptr" +.Fc +.Ft "long double" +.Fo wcstold +.Fa "const wchar_t *restrict nptr" +.Fa "wchar_t **restrict endptr" +.Fc +.Sh DESCRIPTION +The +.Fn wcstof , +.Fn wcstod , +and +.Fn wcstold +functions are the wide-character versions of the +.Fn strtof , +.Fn strtod , +and +.Fn strtold +functions. +Refer to +.Xr strtod 3 +for details. +.Pp +Extended locale versions of these functions are documented in +.Xr wcstod_l 3 . +See +.Xr xlocale 3 +for more information. +.Sh SEE ALSO +.Xr strtod 3 , +.Xr wcstod_l 3 , +.Xr wcstol 3 +.Sh STANDARDS +The +.Fn wcstof , +.Fn wcstod +and +.Fn wcstold +functions conform to +.St -isoC-99 . diff --git a/locale/wcstof-fbsd.c b/locale/wcstof-fbsd.c new file mode 100644 index 0000000..df38723 --- /dev/null +++ b/locale/wcstof-fbsd.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2002, 2003 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/locale/wcstof.c,v 1.3 2004/04/07 09:47:56 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include <_simple.h> + +/* + * See wcstod() for comments as to the logic used. + */ +float +wcstof_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + locale_t loc) +{ + static const mbstate_t initial; + mbstate_t mbs; + float val; + char *buf, *end; + size_t len; + locale_t ctype; + _SIMPLE_STRING b; + char mb[MB_CUR_MAX + 1]; + const wchar_t *nptr0 = nptr; + const wchar_t *first; + + NORMALIZE_LOCALE(loc); + ctype = __numeric_ctype(loc); + + while (iswspace_l(*nptr, ctype)) + nptr++; + + if ((b = _simple_salloc()) == NULL) + return (0.0); + + first = nptr; + mbs = initial; + while (*nptr && (len = wcrtomb_l(mb, *nptr, &mbs, ctype)) != (size_t)-1) { + mb[len] = 0; + if (_simple_sappend(b, mb) < 0) { /* no memory */ + _simple_sfree(b); + return (0.0); + } + nptr++; + } + + buf = _simple_string(b); + val = strtof_l(buf, &end, loc); + + if (endptr != NULL) + *endptr = (end == buf) ? (wchar_t *)nptr0 : ((wchar_t *)first + (end - buf)); + + _simple_sfree(b); + + return (val); +} + +float +wcstof(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + return wcstof_l(nptr, endptr, __current_locale()); +} diff --git a/locale/wcstoimax-fbsd.c b/locale/wcstoimax-fbsd.c new file mode 100644 index 0000000..b46c8d3 --- /dev/null +++ b/locale/wcstoimax-fbsd.c @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 1992, 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. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include + +/* + * Convert a wide character string to an intmax_t integer. + */ +intmax_t +wcstoimax_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base, locale_t loc) +{ + const wchar_t *s; + uintmax_t acc; + wchar_t c; + uintmax_t cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * See strtoimax for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace_l(c, loc)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = neg ? (uintmax_t)-(INTMAX_MIN + INTMAX_MAX) + INTMAX_MAX + : INTMAX_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit_l(c, loc)) + c = digittoint_l(c, loc); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? INTMAX_MIN : INTMAX_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (wchar_t *)(any ? s - 1 : nptr); + return (acc); +} + +intmax_t +wcstoimax(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base) +{ + return wcstoimax_l(nptr, endptr, base, __current_locale()); +} diff --git a/locale/wcstol-fbsd.c b/locale/wcstol-fbsd.c new file mode 100644 index 0000000..2aadd10 --- /dev/null +++ b/locale/wcstol-fbsd.c @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 1990, 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. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstol.c,v 1.1 2002/09/08 13:27:26 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include + +/* + * Convert a string to a long integer. + */ +long +wcstol_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base, locale_t loc) +{ + const wchar_t *s; + unsigned long acc; + wchar_t c; + unsigned long cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace_l(c, loc)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX + : LONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit_l(c, loc)) + c = digittoint_l(c, loc); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LONG_MIN : LONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *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/wcstol.3 b/locale/wcstol.3 new file mode 100644 index 0000000..89936c9 --- /dev/null +++ b/locale/wcstol.3 @@ -0,0 +1,141 @@ +.\" Copyright (c) 2002 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/wcstol.3,v 1.4 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd September 7, 2002 +.Dt WCSTOL 3 +.Os +.Sh NAME +.Nm wcstoimax , +.Nm wcstol , +.Nm wcstoll , +.Nm wcstoul , +.Nm wcstoull , +.Nm wcstoumax +.Nd "convert a wide character string value to a" +.Vt intmax_t , +.Vt long , +.Vt "long long" , +.Vt "unsigned long" , +.Vt "unsigned long long" , +or +.Vt uintmax_t +integer +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft long +.Fo wcstol +.Fa "const wchar_t *restrict nptr" +.Fa "wchar_t **restrict endptr" +.Fa "int base" +.Fc +.Ft "long long" +.Fo wcstoll +.Fa "const wchar_t *restrict nptr" +.Fa "wchar_t **restrict endptr" +.Fa "int base" +.Fc +.Ft "unsigned long" +.Fo wcstoul +.Fa "const wchar_t *restrict nptr" +.Fa "wchar_t **restrict endptr" +.Fa "int base" +.Fc +.Ft "unsigned long long" +.Fo wcstoull +.Fa "const wchar_t *restrict nptr" +.Fa "wchar_t **restrict endptr" +.Fa "int base" +.Fc +.In stddef.h +.In inttypes.h +.Ft intmax_t +.Fo wcstoimax +.Fa "const wchar_t *restrict nptr" +.Fa "wchar_t **restrict endptr" +.Fa "int base" +.Fc +.Ft uintmax_t +.Fo wcstoumax +.Fa "const wchar_t *restrict nptr" +.Fa "wchar_t **restrict endptr" +.Fa "int base" +.Fc +.Sh DESCRIPTION +The +.Fn wcstol , +.Fn wcstoul , +.Fn wcstoll , +.Fn wcstoull , +.Fn wcstoimax , +and +.Fn wcstoumax +functions are wide-character versions of the +.Fn strtol , +.Fn strtoul , +.Fn strtoll , +.Fn strtoull , +.Fn strtoimax , +and +.Fn strtoumax +functions, respectively. +Refer to their manual pages (for example +.Xr strtol 3 ) +for details. +.Pp +Extended locale versions of these functions are documented in +.Xr wcstol_l 3 . +See +.Xr xlocale 3 +for more information. +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +The include file +.In stddef.h +is necessary for the +.Fn wcstoimax +and +.Fn wcstoumax +functions. +.Sh SEE ALSO +.Xr strtol 3 , +.Xr strtoul 3 , +.Xr wcstol_l 3 , +.Xr compat 5 +.Sh STANDARDS +The +.Fn wcstol , +.Fn wcstoul , +.Fn wcstoll , +.Fn wcstoull , +.Fn wcstoimax , +and +.Fn wcstoumax +functions conform to +.St -isoC-99 . diff --git a/locale/wcstol_l.3 b/locale/wcstol_l.3 index 97bbd85..942c8c0 100644 --- a/locale/wcstol_l.3 +++ b/locale/wcstol_l.3 @@ -28,9 +28,12 @@ .Dt WCSTOL_L 3 .Os .Sh NAME -.Nm wcstol_l , wcstoul_l , -.Nm wcstoll_l , wcstoull_l , -.Nm wcstoimax_l , wcstoumax_l +.Nm wcstoimax_l , +.Nm wcstol_l , +.Nm wcstoll_l , +.Nm wcstoul_l , +.Nm wcstoull_l , +.Nm wcstoumax_l .Nd "convert a wide character string value to a" .Vt long , .Vt "unsigned long" , @@ -46,18 +49,43 @@ integer .In wchar.h .In xlocale.h .Ft long -.Fn wcstol_l "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" "locale_t loc" -.Ft "unsigned long" -.Fn wcstoul_l "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" "locale_t loc" +.Fo wcstol_l +.Fa "const wchar_t * restrict nptr" +.Fa "wchar_t ** restrict endptr" +.Fa "int base" "locale_t loc" +.Fc .Ft "long long" -.Fn wcstoll_l "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" "locale_t loc" +.Fo wcstoll_l +.Fa "const wchar_t * restrict nptr" +.Fa "wchar_t ** restrict endptr" +.Fa "int base" "locale_t loc" +.Fc +.Ft "unsigned long" +.Fo wcstoul_l +.Fa "const wchar_t * restrict nptr" +.Fa "wchar_t ** restrict endptr" +.Fa "int base" "locale_t loc" +.Fc .Ft "unsigned long long" -.Fn wcstoull_l "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" "locale_t loc" +.Fo wcstoull_l +.Fa "const wchar_t * restrict nptr" +.Fa "wchar_t ** restrict endptr" +.Fa "int base" "locale_t loc" +.Fc .In inttypes.h +.In xlocale.h .Ft intmax_t -.Fn wcstoimax_l "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" "locale_t loc" +.Fo wcstoimax_l +.Fa "const wchar_t * restrict nptr" +.Fa "wchar_t ** restrict endptr" +.Fa "int base" "locale_t loc" +.Fc .Ft uintmax_t -.Fn wcstoumax_l "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" "locale_t loc" +.Fo wcstoumax_l +.Fa "const wchar_t * restrict nptr" +.Fa "wchar_t ** restrict endptr" +.Fa "int base" "locale_t loc" +.Fc .Sh DESCRIPTION The .Fn wcstol_l , diff --git a/locale/wcstold-fbsd.c b/locale/wcstold-fbsd.c new file mode 100644 index 0000000..cf73555 --- /dev/null +++ b/locale/wcstold-fbsd.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2002, 2003 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/locale/wcstold.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include <_simple.h> + +/* + * See wcstod() for comments as to the logic used. + */ +long double +wcstold_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + locale_t loc) +{ + static const mbstate_t initial; + mbstate_t mbs; + long double val; + char *buf, *end; + size_t len; + locale_t ctype; + _SIMPLE_STRING b; + char mb[MB_CUR_MAX + 1]; + const wchar_t *nptr0 = nptr; + const wchar_t *first; + + NORMALIZE_LOCALE(loc); + ctype = __numeric_ctype(loc); + + while (iswspace_l(*nptr, ctype)) + nptr++; + + if ((b = _simple_salloc()) == NULL) + return (0.0); + + first = nptr; + mbs = initial; + while (*nptr && (len = wcrtomb_l(mb, *nptr, &mbs, ctype)) != (size_t)-1) { + mb[len] = 0; + if (_simple_sappend(b, mb) < 0) { /* no memory */ + _simple_sfree(b); + return (0.0); + } + nptr++; + } + + buf = _simple_string(b); + val = strtold_l(buf, &end, loc); + + if (endptr != NULL) + *endptr = (end == buf) ? (wchar_t *)nptr0 : ((wchar_t *)first + (end - buf)); + + _simple_sfree(b); + + return (val); +} + +long double +wcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + return wcstold_l(nptr, endptr, __current_locale()); +} diff --git a/locale/wcstoll-fbsd.c b/locale/wcstoll-fbsd.c new file mode 100644 index 0000000..f2b9f00 --- /dev/null +++ b/locale/wcstoll-fbsd.c @@ -0,0 +1,137 @@ +/*- + * Copyright (c) 1992, 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. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include + +/* + * Convert a wide character string to a long long integer. + */ +long long +wcstoll_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base, locale_t loc) +{ + const wchar_t *s; + unsigned long long acc; + wchar_t c; + unsigned long long cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * See strtoll for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace_l(c, loc)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX + : LLONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit_l(c, loc)) + c = digittoint_l(c, loc); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LLONG_MIN : LLONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *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/wcstombs-fbsd.c b/locale/wcstombs-fbsd.c new file mode 100644 index 0000000..034b64f --- /dev/null +++ b/locale/wcstombs-fbsd.c @@ -0,0 +1,53 @@ +/*- + * 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/locale/wcstombs.c,v 1.10 2004/07/21 10:54:57 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include "mblocal.h" + +size_t +wcstombs_l(char * __restrict s, const wchar_t * __restrict pwcs, size_t n, + locale_t loc) +{ + static const mbstate_t initial; + mbstate_t mbs; + + NORMALIZE_LOCALE(loc); + mbs = initial; + return (loc->__lc_ctype->__wcsnrtombs(s, &pwcs, SIZE_T_MAX, n, &mbs, loc)); +} + +size_t +wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n) +{ + return wcstombs_l(s, pwcs, n, __current_locale()); +} diff --git a/locale/wcstombs.3 b/locale/wcstombs.3 new file mode 100644 index 0000000..b197803 --- /dev/null +++ b/locale/wcstombs.3 @@ -0,0 +1,115 @@ +.\" 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 +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" +.\" 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 $ +.\" +.Dd April 8, 2004 +.Dt WCSTOMBS 3 +.Os +.Sh NAME +.Nm wcstombs , +.Nm wcstombs_l +.Nd convert a wide-character string to a character string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft size_t +.Fo wcstombs +.Fa "char *restrict s" +.Fa "const wchar_t *restrict pwcs" +.Fa "size_t n" +.Fc +.In stdlib.h +.In xlocale.h +.Ft size_t +.Fo wcstombs_l +.Fa "char *restrict s" +.Fa "const wchar_t *restrict pwcs" +.Fa "size_t n" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wcstombs +function converts a wide character string +.Fa pwcs +into a multibyte character string, +.Fa s , +beginning in the initial conversion state. +Up to +.Fa n +bytes are stored in +.Fa s . +Partial multibyte characters at the end of the string are not stored. +The multibyte character string is null terminated, if there is room. +.Pp +Although the +.Fn wcstombs +function uses the current locale, the +.Fn wcstombs_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn wcstombs +function returns the number of bytes converted +(not including any terminating null), if successful; +otherwise, it returns +.Po Vt size_t Pc Ns \-1 . +.Sh ERRORS +The +.Fn wcstombs +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid wide character was encountered. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbstowcs 3 , +.Xr multibyte 3 , +.Xr wcsrtombs 3 , +.Xr wctomb 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn wcstombs +function conforms to +.St -isoC-99 . diff --git a/locale/wcstoul-fbsd.c b/locale/wcstoul-fbsd.c new file mode 100644 index 0000000..270ad7c --- /dev/null +++ b/locale/wcstoul-fbsd.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 1990, 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. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoul.c,v 1.1 2002/09/08 13:27:26 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include + +/* + * Convert a wide character string to an unsigned long integer. + */ +unsigned long +wcstoul_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base, locale_t loc) +{ + const wchar_t *s; + unsigned long acc; + wchar_t c; + unsigned long cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace_l(c, loc)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = ULONG_MAX / base; + cutlim = ULONG_MAX % base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit_l(c, loc)) + c = digittoint_l(c, loc); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *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/wcstoull-fbsd.c b/locale/wcstoull-fbsd.c new file mode 100644 index 0000000..c20ffac --- /dev/null +++ b/locale/wcstoull-fbsd.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 1992, 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. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include + +/* + * Convert a wide character string to an unsigned long long integer. + */ +unsigned long long +wcstoull_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base, locale_t loc) +{ + const wchar_t *s; + unsigned long long acc; + wchar_t c; + unsigned long long cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * See strtoull for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace_l(c, loc)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = ULLONG_MAX / base; + cutlim = ULLONG_MAX % base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit_l(c, loc)) + c = digittoint_l(c, loc); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULLONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *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/wcstoumax-fbsd.c b/locale/wcstoumax-fbsd.c new file mode 100644 index 0000000..d8c75a4 --- /dev/null +++ b/locale/wcstoumax-fbsd.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 1992, 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. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include + +/* + * Convert a wide character string to a uintmax_t integer. + */ +uintmax_t +wcstoumax_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base, locale_t loc) +{ + const wchar_t *s; + uintmax_t acc; + wchar_t c; + uintmax_t cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * See strtoimax for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace_l(c, loc)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = UINTMAX_MAX / base; + cutlim = UINTMAX_MAX % base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit_l(c, loc)) + c = digittoint_l(c, loc); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = UINTMAX_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (wchar_t *)(any ? s - 1 : nptr); + return (acc); +} + +uintmax_t +wcstoumax(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base) +{ + return wcstoumax_l(nptr, endptr, base, __current_locale()); +} diff --git a/locale/wctob-fbsd.c b/locale/wctob-fbsd.c new file mode 100644 index 0000000..130d00d --- /dev/null +++ b/locale/wctob-fbsd.c @@ -0,0 +1,54 @@ +/*- + * 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/locale/wctob.c,v 1.4 2004/05/12 14:26:54 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include "mblocal.h" + +int +wctob_l(wint_t c, locale_t loc) +{ + static const mbstate_t initial; + mbstate_t mbs = initial; + char buf[MB_LEN_MAX]; + + NORMALIZE_LOCALE(loc); + if (c == WEOF || loc->__lc_ctype->__wcrtomb(buf, c, &mbs, loc) != 1) + return (EOF); + return ((unsigned char)*buf); +} + +int +wctob(wint_t c) +{ + return wctob_l(c, __current_locale()); +} diff --git a/locale/wctomb-fbsd.c b/locale/wctomb-fbsd.c new file mode 100644 index 0000000..0df7799 --- /dev/null +++ b/locale/wctomb-fbsd.c @@ -0,0 +1,57 @@ +/*- + * 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/locale/wctomb.c,v 1.8 2004/07/29 06:18:40 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include "mblocal.h" + +int +wctomb_l(char *s, wchar_t wchar, locale_t loc) +{ + static const mbstate_t initial; + size_t rval; + + NORMALIZE_LOCALE(loc); + if (s == NULL) { + /* No support for state dependent encodings. */ + loc->__mbs_wctomb = initial; + return (0); + } + if ((rval = loc->__lc_ctype->__wcrtomb(s, wchar, &loc->__mbs_wctomb, loc)) == (size_t)-1) + return (-1); + return ((int)rval); +} + +int +wctomb(char *s, wchar_t wchar) +{ + return wctomb_l(s, wchar, __current_locale()); +} diff --git a/locale/wctomb.3 b/locale/wctomb.3 new file mode 100644 index 0000000..0efbc55 --- /dev/null +++ b/locale/wctomb.3 @@ -0,0 +1,132 @@ +.\" 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 +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" +.\" 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 $ +.\" +.Dd April 8, 2004 +.Dt WCTOMB 3 +.Os +.Sh NAME +.Nm wctomb , +.Nm wctomb_l +.Nd convert a wide-character code to a character +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fo wctomb +.Fa "char *s" +.Fa "wchar_t wchar" +.Fc +.In stdlib.h +.In xlocale.h +.Ft int +.Fo wctomb_l +.Fa "char *s" +.Fa "wchar_t wchar" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wctomb +function converts a wide character, +.Fa wchar , +into a multibyte character and stores the result in +.Fa s . +The object pointed to by +.Fa s +must be large enough to accommodate the multibyte character, +which may be up to +.Dv MB_LEN_MAX +bytes. +.Pp +A call with a null +.Fa s +pointer returns nonzero if the current locale requires shift states, +zero otherwise; +if shift states are required, the shift state is reset to the initial state. +.Pp +Although the +.Fn wctomb +function uses the current locale, the +.Fn wctomb_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +If +.Fa s +is +.Dv NULL , +the +.Fn wctomb +function returns nonzero if shift states are supported, +zero otherwise. +If +.Fa s +is valid, +.Fn wctomb +returns +the number of bytes processed in +.Fa s , +or \-1 if no multibyte character +could be recognized or converted. +In this case, +.Fn wctomb Ns 's +internal conversion state is undefined. +.Sh ERRORS +The +.Fn wctomb +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The internal conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbtowc 3 , +.Xr wcrtomb 3 , +.Xr wcstombs 3 , +.Xr wctob 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn wctomb +function conforms to +.St -isoC-99 . diff --git a/locale/wctrans-fbsd.c b/locale/wctrans-fbsd.c new file mode 100644 index 0000000..30ca5b9 --- /dev/null +++ b/locale/wctrans-fbsd.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2002 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/locale/wctrans.c,v 1.3 2003/11/01 08:20:58 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include + +enum { + _WCT_ERROR = 0, + _WCT_TOLOWER = 1, + _WCT_TOUPPER = 2 +}; + +wint_t +towctrans_l(wint_t wc, wctrans_t desc, locale_t loc) +{ + + NORMALIZE_LOCALE(loc); + switch (desc) { + case _WCT_TOLOWER: + wc = towlower_l(wc, loc); + break; + case _WCT_TOUPPER: + wc = towupper_l(wc, loc); + break; + case _WCT_ERROR: + default: + errno = EINVAL; + break; + } + + return (wc); +} + +wint_t +towctrans(wint_t wc, wctrans_t desc) +{ + return towctrans_l(wc, desc, __current_locale()); +} + +wctrans_t +wctrans(const char *charclass) +{ + struct { + const char *name; + wctrans_t trans; + } ccls[] = { + { "tolower", _WCT_TOLOWER }, + { "toupper", _WCT_TOUPPER }, + { NULL, _WCT_ERROR }, /* Default */ + }; + int i; + + i = 0; + while (ccls[i].name != NULL && strcmp(ccls[i].name, charclass) != 0) + i++; + + if (ccls[i].trans == _WCT_ERROR) + errno = EINVAL; + return (ccls[i].trans); +} + +/* + * The extended locale version just calls the regular version. If there + * is ever support for arbitrary per-locale translations, this need to + * be modified. + */ +wctrans_t +wctrans_l(const char *charclass, locale_t loc) +{ + return wctrans(charclass); +} diff --git a/locale/wctrans.3 b/locale/wctrans.3 new file mode 100644 index 0000000..7cb0da6 --- /dev/null +++ b/locale/wctrans.3 @@ -0,0 +1,156 @@ +.\" Copyright (c) 2002 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/wctrans.3,v 1.3 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd October 3, 2002 +.Dt WCTRANS 3 +.Os +.Sh NAME +.Nm towctrans , +.Nm towctrans_l , +.Nm wctrans , +.Nm wctrans_l +.Nd "wide character mapping functions" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft wint_t +.Fo towctrans +.Fa "wint_t wc" +.Fa "wctrans_t desc" +.Fc +.Ft wctrans_t +.Fo wctrans +.Fa "const char *charclass" +.Fc +.In wctype.h +.In xlocale.h +.Ft wint_t +.Fo towctrans_l +.Fa "wint_t wc" +.Fa "wctrans_t desc" +.Fa "locale_t loc" +.Fc +.Ft wctrans_t +.Fo wctrans_l +.Fa "const char *charclass" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wctrans +function returns a value of type +.Vt wctrans_t , +which represents the requested wide character mapping operation and +may be used as the second argument for calls to +.Fn towctrans . +.Pp +The following character mapping names are recognised: +.Bl -column -offset indent ".Li tolower" ".Li toupper" +.It Li "tolower toupper" +.El +.Pp +The +.Fn towctrans +function transliterates the wide character +.Fa wc , +according to the mapping described by +.Fa desc . +.Pp +While the +.Fn towctrans +and +.Fn wctrans +functions use the current locale, the +.Fn towctrans_l +and +.Fn wctrans_l +functions may be passed locales directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn towctrans +function returns the transliterated character if successful, otherwise +it returns the character unchanged and sets +.Va errno . +.Pp +The +.Fn wctrans +function returns non-zero if successful, otherwise it returns zero +and sets +.Va errno . +.Sh EXAMPLES +Reimplement +.Fn towupper +in terms of +.Fn towctrans +and +.Fn wctrans : +.Bd -literal -offset indent +wint_t +mytowupper(wint_t wc) +{ + return (towctrans(wc, wctrans("toupper"))); +} +.Ed +.Sh ERRORS +The +.Fn towctrans +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The supplied +.Fa desc +argument is invalid. +.El +.Pp +The +.Fn wctrans +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The requested mapping name is invalid. +.El +.Sh SEE ALSO +.Xr tolower 3 , +.Xr toupper 3 , +.Xr wctype 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn towctrans +and +.Fn wctrans +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn towctrans +and +.Fn wctrans +functions first appeared in +.Fx 5.0 . diff --git a/locale/wctype-fbsd.c b/locale/wctype-fbsd.c new file mode 100644 index 0000000..0ed47b8 --- /dev/null +++ b/locale/wctype-fbsd.c @@ -0,0 +1,89 @@ +/*- + * Copyright (c) 2002 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/locale/wctype.c,v 1.3 2004/03/27 08:59:21 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#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; + + i = 0; + while (props[i].name != NULL && strcmp(props[i].name, property) != 0) + i++; + + if (props[i].mask) + return (props[i].mask); + + NORMALIZE_LOCALE(loc); + rl = &loc->__lc_ctype->_CurrentRuneLocale; + if ((i = rl->__ncharclasses) > 0) { + _RuneCharClass *rp; + for (rp = rl->__charclasses; i-- > 0; rp++) { + if (strncmp(rp->__name, property, CHARCLASS_NAME_MAX) == 0) + return (rp->__mask); + } + } + return 0; +} + +wctype_t +wctype(const char *property) +{ + return wctype_l(property, __current_locale()); +} diff --git a/locale/wctype.3 b/locale/wctype.3 new file mode 100644 index 0000000..6608fe2 --- /dev/null +++ b/locale/wctype.3 @@ -0,0 +1,152 @@ +.\" Copyright (c) 2002 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/wctype.3,v 1.5 2004/03/27 08:59:21 tjr Exp $ +.\" +.Dd March 27, 2004 +.Dt WCTYPE 3 +.Os +.Sh NAME +.Nm iswctype , +.Nm iswctype_l , +.Nm wctype , +.Nm wctype_l +.Nd "wide character class functions" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft int +.Fo iswctype +.Fa "wint_t wc" +.Fa "wctype_t charclass" +.Fc +.Ft wctype_t +.Fo wctype +.Fa "const char *property" +.Fc +.In wctype.h +.In xlocale.h +.Ft int +.Fo iswctype_l +.Fa "wint_t wc" +.Fa "wctype_t charclass" +.Fa "locale_t loc" +.Fc +.Ft wctype_t +.Fo wctype_l +.Fa "const char *property" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wctype +function returns a value of type +.Vt wctype_t , +which represents the requested wide character class and +may be used as the second argument for calls to +.Fn iswctype . +.Pp +The following character class names are recognised: +.Bl -column -offset indent ".Li alnum" ".Li cntrl" ".Li ideogram" ".Li print" ".Li space" +.It Li "alnum cntrl ideogram print space xdigit" +.It Li "alpha digit lower punct special" +.It Li "blank graph phonogram rune upper" +.El +.Pp +The +.Fn iswctype +function checks whether the wide character +.Fa wc +is in the character class +.Fa charclass . +.Pp +Although the +.Fn iswctype +and +.Fn wctype +functions use the current locale, the +.Fn iswctype_l +and +.Fn wctype_l +functions may be passed locales directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn iswctype +function returns non-zero if and only if +.Fa wc +has the property described by +.Fa charclass , +or +.Fa charclass +is zero. +.Pp +The +.Fn wctype +function returns 0 if +.Fa property +is invalid; otherwise, it returns a value of type +.Vt wctype_t +that can be used in subsequent calls to +.Fn iswctype . +.Sh EXAMPLES +Reimplement +.Xr iswalpha 3 +in terms of +.Fn iswctype +and +.Fn wctype : +.Bd -literal -offset indent +int +myiswalpha(wint_t wc) +{ + return (iswctype(wc, wctype("alpha"))); +} +.Ed +.Sh SEE ALSO +.Xr ctype 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn iswctype +and +.Fn wctype +functions conform to +.St -p1003.1-2001 . +The +.Dq Li ideogram , +.Dq Li phonogram +.Dq Li special , +and +.Dq Li rune +character classes are extensions. +.Sh HISTORY +The +.Fn iswctype +and +.Fn wctype +functions first appeared in +.Fx 5.0 . diff --git a/locale/FreeBSD/iswctype.c b/locale/wcwidth-fbsd.c similarity index 54% rename from locale/FreeBSD/iswctype.c rename to locale/wcwidth-fbsd.c index 37e2656..ad9fe56 100644 --- a/locale/FreeBSD/iswctype.c +++ b/locale/wcwidth-fbsd.c @@ -40,175 +40,25 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/iswctype.c,v 1.6 2002/08/17 20:30:34 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/wcwidth.c,v 1.7 2004/08/12 12:19:11 tjr Exp $"); -#include +#include "xlocale_private.h" -#undef iswalnum -int -iswalnum(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_A|_CTYPE_D)); -} - -#undef iswalpha -int -iswalpha(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_A)); -} - -#undef iswascii -int -iswascii(wc) - wint_t wc; -{ - return ((wc & ~0x7F) == 0); -} - -#undef iswblank -int -iswblank(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_B)); -} - -#undef iswcntrl -int -iswcntrl(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_C)); -} - -#undef iswdigit -int -iswdigit(wc) - wint_t wc; -{ - return (__isctype(wc, _CTYPE_D)); -} - -#undef iswgraph -int -iswgraph(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_G)); -} +#include -#undef iswhexnumber -int -iswhexnumber(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_X)); -} +#undef wcwidth -#undef iswideogram int -iswideogram(wc) - wint_t wc; +wcwidth(wchar_t wc) { - return (__istype(wc, _CTYPE_I)); -} -#undef iswlower -int -iswlower(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_L)); + return (__wcwidth_l(wc, __current_locale())); } -#undef iswnumber int -iswnumber(wc) - wint_t wc; +wcwidth_l(wchar_t wc, locale_t loc) { - return (__istype(wc, _CTYPE_D)); -} -#undef iswphonogram -int -iswphonogram(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_Q)); + NORMALIZE_LOCALE(loc); + return (__wcwidth_l(wc, loc)); } - -#undef iswprint -int -iswprint(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_R)); -} - -#undef iswpunct -int -iswpunct(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_P)); -} - -#undef iswrune -int -iswrune(wc) - wint_t wc; -{ - return (__istype(wc, 0xFFFFFF00L)); -} - -#undef iswspace -int -iswspace(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_S)); -} - -#undef iswspecial -int -iswspecial(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_T)); -} - -#undef iswupper -int -iswupper(wc) - wint_t wc; -{ - return (__istype(wc, _CTYPE_U)); -} - -#undef iswxdigit -int -iswxdigit(wc) - wint_t wc; -{ - return (__isctype(wc, _CTYPE_X)); -} - -#undef towlower -wint_t -towlower(wc) - wint_t wc; -{ - return (__tolower(wc)); -} - -#undef towupper -wint_t -towupper(wc) - wint_t wc; -{ - return (__toupper(wc)); -} - diff --git a/locale/wcwidth.3 b/locale/wcwidth.3 new file mode 100644 index 0000000..4c014ce --- /dev/null +++ b/locale/wcwidth.3 @@ -0,0 +1,106 @@ +.\" Copyright (c) 2002 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. +.\" +.\" $FreeBSD: src/lib/libc/locale/wcwidth.3,v 1.6 2004/08/17 04:56:03 trhodes Exp $ +.\" +.Dd August 17, 2004 +.Dt WCWIDTH 3 +.Os +.Sh NAME +.Nm wcwidth , +.Nm wcwidth_l +.Nd "number of column positions of a wide-character code" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft int +.Fo wcwidth +.Fa "wchar_t wc" +.Fc +.In wchar.h +.In xlocale.h +.Ft int +.Fo wcwidth_l +.Fa "wchar_t wc" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wcwidth +function determines the number of column positions required to +display the wide character +.Fa wc . +.Pp +Although the +.Fn wcwidth +function uses the current locale, the +.Fn wcwidth_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn wcwidth +function returns 0 if the +.Fa wc +argument is a null wide character (L'\e0'), +\-1 if +.Fa wc +is not printable; +otherwise, it returns the number of column positions the +character occupies. +.Sh EXAMPLES +This code fragment reads text from standard input and +breaks lines that are more than 20 column positions wide, +similar to the +.Xr fold 1 +utility: +.Bd -literal -offset indent +wint_t ch; +int column, w; + +column = 0; +while ((ch = getwchar()) != WEOF) { + w = wcwidth(ch); + if (w > 0 && column + w >= 20) { + putwchar(L'\en'); + column = 0; + } + putwchar(ch); + if (ch == L'\en') + column = 0; + else if (w > 0) + column += w; +} +.Ed +.Sh SEE ALSO +.Xr iswprint 3 , +.Xr wcswidth 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn wcwidth +function conforms to +.St -p1003.1-2001 . diff --git a/locale/xlocale.3 b/locale/xlocale.3 index 4b83cf6..101402b 100644 --- a/locale/xlocale.3 +++ b/locale/xlocale.3 @@ -13,7 +13,8 @@ for extended locale support. It can be used alone or with the POSIX locale API in .Aq locale.h . .Pp -The extended locale, or "xlocale" API consists of five basic routines, which are documented separately: +The extended locale, or "xlocale" API consists of five basic routines, +which are documented separately: .Xr duplocale 3 , .Xr freelocale 3 , .Xr newlocale 3 , @@ -34,22 +35,25 @@ LC_GLOBAL_LOCALE - A special .Vt locale_t value that corresponds to the global, process-wide locale. .It -MB_CUR_MAX - This macro is traditionally defined as an integer containing the value of the -longest multi-byte string that a single-wide character in the global locale +MB_CUR_MAX - This macro is traditionally defined as an integer +containing the value of the longest multi-byte string +that a single-wide character in the global locale can translate into. +With extended locales, this macro is replaced with a function +that returns the value of the longest multi-byte string +that a single-wide character in the current locale (per-thread or global) can translate into. -With extended locales, this macro is replaced with a function that returns the -value of the longest multi-byte string that a single-wide character in the current -locale (per-thread or global) can translate into. .It -MB_CUR_MAX_L(loc) - This macro is equivalent to MB_CUR_MAX, except that it may be passed -a specific locale directly. +MB_CUR_MAX_L(loc) - This macro is equivalent to MB_CUR_MAX, +except that it may be passed a specific locale directly. .El .Sh CAVEATS The POSIX .Xr setlocale 3 -function only affects the global locale, so using it when a per-thread locale -is in effect will not change locale behavior for that thread. However, it will -change behavior for threads with no per-thread locale in effect. +function only affects the global locale, +so using it when a per-thread locale is in effect +will not change locale behavior for that thread. +However, it will change behavior for threads +with no per-thread locale in effect. .Pp The routines defined in .Aq rune.h @@ -64,23 +68,28 @@ and sub-structures may be shared by multiple locales, has been modified to make a copy of the sub-structure. This prevents it from affecting other locales. .Sh SEE ALSO -.Xr localeconv 3 , .Xr duplocale 3 , .Xr freelocale 3 , +.Xr localeconv 3 , .Xr newlocale 3 , .Xr querylocale 3 , .Xr uselocale 3 .Sh CONVENIENCE FUNCTIONS -The xlocale API also includes "convenience functions"; functions that can be -executed using a given locale, rather than the current locale. These functions all take one extra +The xlocale API also includes "convenience functions": +functions that can be executed using a given locale, +rather than the current locale. +These functions all take one extra .Vt locale_t -argument at the end of the traditional argument list, except in the case of variable-argument functions, in which case the extra argument comes before the format string. +argument at the end of the traditional argument list, +except in the case of variable-argument functions, +in which case the extra argument comes before the format string. If a NULL .Vt locale_t is passed, the C locale will be used. .Pp For completeness, -the convenience functions are listed here (organized by the header file that contains the original function). +the convenience functions are listed here +(organized by the header file that contains the original function). .Pp .Bl -tag -width monetary.h .It Aq _wctype.h diff --git a/locale/xlocale.c b/locale/xlocale.c index 12de5b4..494a63a 100644 --- a/locale/xlocale.c +++ b/locale/xlocale.c @@ -29,10 +29,11 @@ #define NMBSTATET 10 #define C_LOCALE_INITIALIZER { \ + 0, NULL, \ {}, {}, {}, {}, {}, \ {}, {}, {}, {}, {}, \ XMAGIC, \ - 1, 0, 0, 0, 0, 0, 1, 1, \ + 1, 0, 0, 0, 0, 0, 1, 1, 0, \ NULL, \ &_DefaultRuneXLocale, \ } @@ -52,6 +53,8 @@ extern int __numeric_load_locale(const char *, locale_t); extern int __setrunelocale(const char *, locale_t); extern int __time_load_locale(const char *, locale_t); +static void _releaselocale(locale_t loc); + /* * check that the encoding is the right size, isn't . or .. and doesn't * contain any slashes @@ -99,6 +102,8 @@ _duplocale(locale_t loc) if ((new = (locale_t)malloc(sizeof(struct _xlocale))) == NULL) return NULL; + new->__refcount = 1; + new->__free_extra = (__free_extra_t)_releaselocale; if (loc == NULL) loc = __current_locale(); else if (loc == LC_GLOBAL_LOCALE) @@ -109,7 +114,8 @@ _duplocale(locale_t loc) } _copylocale(new, loc); /* __mbs_mblen is the first of NMBSTATET mbstate_t buffers */ - bzero(&new->__mbs_mblen, NMBSTATET * sizeof(new->__mbs_mblen)); + bzero(&new->__mbs_mblen, offsetof(struct _xlocale, __magic) + - offsetof(struct _xlocale, __mbs_mblen)); /* collate */ XL_RETAIN(new->__lc_collate); /* ctype */ @@ -120,6 +126,7 @@ _duplocale(locale_t loc) XL_RETAIN(new->__lc_monetary); /* numeric */ XL_RETAIN(new->__lc_numeric); + XL_RETAIN(new->__lc_numeric_loc); /* time */ XL_RETAIN(new->__lc_time); /* newale_t */ @@ -175,9 +182,13 @@ _modifylocale(locale_t loc, int mask, __const char *locale) return -1; } } - if (strcmp(enc, loc->__lc_ctype->__ctype_encoding) != 0 && (ret = __setrunelocale(enc, loc)) != 0) { - errno = ret; - return -1; + if (strcmp(enc, loc->__lc_ctype->__ctype_encoding) != 0) { + if ((ret = __setrunelocale(enc, loc)) != 0) { + errno = ret; + return -1; + } + if (loc->__numeric_fp_cvt == LC_NUMERIC_FP_SAME_LOCALE) + loc->__numeric_fp_cvt = LC_NUMERIC_FP_UNINITIALIZED; } break; case LC_MESSAGES_MASK: @@ -213,8 +224,13 @@ _modifylocale(locale_t loc, int mask, __const char *locale) } } oenc = (loc->_numeric_using_locale ? loc->__lc_numeric->_numeric_locale_buf : C); - if (strcmp(enc, oenc) != 0 && __numeric_load_locale(enc, loc) == _LDP_ERROR) - return -1; + if (strcmp(enc, oenc) != 0) { + if (__numeric_load_locale(enc, loc) == _LDP_ERROR) + return -1; + loc->__numeric_fp_cvt = LC_NUMERIC_FP_UNINITIALIZED; + XL_RELEASE(loc->__lc_numeric_loc); + loc->__lc_numeric_loc = NULL; + } break; case LC_TIME_MASK: if (!*locale) { @@ -251,6 +267,7 @@ _releaselocale(locale_t loc) XL_RELEASE(loc->__lc_monetary); /* numeric */ XL_RELEASE(loc->__lc_numeric); + XL_RELEASE(loc->__lc_numeric_loc); /* time */ XL_RELEASE(loc->__lc_time); /* locale_t */ @@ -280,12 +297,11 @@ int freelocale(locale_t loc) { if (!loc || _checklocale(loc) < 0 || loc == &__global_locale - || loc == LC_GLOBAL_LOCALE) { + || loc == LC_GLOBAL_LOCALE || loc == &__c_locale) { errno = EINVAL; return -1; } - _releaselocale(loc); - free(loc); + XL_RELEASE(loc); return 0; } @@ -323,6 +339,40 @@ newlocale(int mask, __const char *locale, locale_t base) return new; } +/* + * PRIVATE EXTERNAL: Returns the locale that can be used by wcstod and + * family, to convert the wide character string to a multi-byte string + * (the LC_NUMERIC and LC_CTYPE locales may be different). + */ +__private_extern__ locale_t +__numeric_ctype(locale_t loc) +{ + switch(loc->__numeric_fp_cvt) { + case LC_NUMERIC_FP_UNINITIALIZED: { + const char *ctype = loc->__lc_ctype->__ctype_encoding; + const char *numeric = (loc->_numeric_using_locale ? loc->__lc_numeric->_numeric_locale_buf : C); + if (strcmp(ctype, numeric) == 0) { + loc->__numeric_fp_cvt = LC_NUMERIC_FP_SAME_LOCALE; + return loc; + } else { + loc->__lc_numeric_loc = newlocale(LC_CTYPE_MASK, numeric, &__c_locale); + if (loc->__lc_numeric_loc) { + loc->__numeric_fp_cvt = LC_NUMERIC_FP_USE_LOCALE; + return loc->__lc_numeric_loc; + } else { /* shouldn't happen, but just use the same locale */ + loc->__numeric_fp_cvt = LC_NUMERIC_FP_SAME_LOCALE; + return loc; + } + } + } + case LC_NUMERIC_FP_SAME_LOCALE: + return loc; + case LC_NUMERIC_FP_USE_LOCALE: + return loc->__lc_numeric_loc; + } + return loc; /* shouldn't happen */ +} + /* * EXTERNAL: Returns the locale string for the part specified in mask. The * least significant bit is used. If loc is NULL, the current per-thread @@ -414,9 +464,17 @@ ___mb_cur_max_l(locale_t loc) /* * Called from the Libc initializer to setup the thread-specific key. */ +/* + * Partition _pthread_keys in a lower part that dyld can use, and an upper + * part for libSystem. The libSystem part starts at __pthread_tsd_first = 10. + * dyld will set this value to 1. + */ +extern int __pthread_tsd_first; + __private_extern__ void __xlocale_init(void) { if (__locale_key == (pthread_key_t)-1) - pthread_key_create(&__locale_key, NULL); + __locale_key = __pthread_tsd_first; } + diff --git a/locale/xlocale_private.h b/locale/xlocale_private.h index 7088d55..9b6b127 100644 --- a/locale/xlocale_private.h +++ b/locale/xlocale_private.h @@ -25,11 +25,14 @@ #define _XLOCALE_PRIVATE_H_ #include +#define __DARWIN_XLOCALE_PRIVATE #include +#undef __DARWIN_XLOCALE_PRIVATE #include #include #include #include +#include #include "setlocale.h" #include "collate.h" #include "runetype.h" @@ -57,9 +60,11 @@ typedef void (*__free_extra_t)(void *); struct __xlocale_st_collate { __STRUCT_COMMON char __encoding[ENCODING_LEN + 1]; - unsigned char __substitute_table[UCHAR_MAX + 1][STR_LEN]; - struct __collate_st_char_pri __char_pri_table[UCHAR_MAX + 1]; + struct __collate_st_info __info; + struct __collate_st_subst *__substitute_table[COLL_WEIGHTS_MAX]; struct __collate_st_chain_pri *__chain_pri_table; + struct __collate_st_large_char_pri *__large_char_pri_table; + struct __collate_st_char_pri __char_pri_table[UCHAR_MAX + 1]; }; struct __xlocale_st_runelocale { __STRUCT_COMMON @@ -112,8 +117,14 @@ struct __xlocale_st_localeconv { }; /* the extended locale structure */ + /* values for __numeric_fp_cvt */ +#define LC_NUMERIC_FP_UNINITIALIZED 0 +#define LC_NUMERIC_FP_SAME_LOCALE 1 +#define LC_NUMERIC_FP_USE_LOCALE 2 + struct _xlocale { /* The item(s) before __magic are not copied when duplicating locale_t's */ + __STRUCT_COMMON /* only used for locale_t's in __lc_numeric_loc */ /* 10 independent mbstate_t buffers! */ __darwin_mbstate_t __mbs_mblen; __darwin_mbstate_t __mbs_mbrlen; @@ -136,6 +147,7 @@ struct _xlocale { unsigned char _time_using_locale; unsigned char __mlocale_changed; unsigned char __nlocale_changed; + unsigned char __numeric_fp_cvt; /* collate */ struct __xlocale_st_collate *__lc_collate; /* ctype */ @@ -146,6 +158,7 @@ struct _xlocale { struct __xlocale_st_monetary *__lc_monetary; /* numeric */ struct __xlocale_st_numeric *__lc_numeric; + struct _xlocale *__lc_numeric_loc; /* time */ struct __xlocale_st_time *__lc_time; /* localeconv */ @@ -172,6 +185,7 @@ __private_extern__ pthread_key_t __locale_key; __BEGIN_DECLS void __ldpart_free_extra(struct __xlocale_st_ldpart *); +locale_t __numeric_ctype(locale_t); void __xlocale_init(void); static inline __attribute__((always_inline)) locale_t diff --git a/mach/Makefile.inc b/mach/Makefile.inc deleted file mode 100644 index 643758c..0000000 --- a/mach/Makefile.inc +++ /dev/null @@ -1,75 +0,0 @@ -# machine-dependent mach sources -.if exists(${.CURDIR}/${MACHINE_ARCH}/mach/Makefile.inc) -.include "${.CURDIR}/${MACHINE_ARCH}/mach/Makefile.inc" -.endif - -.PATH: ${.CURDIR}/mach - -.include "${.CURDIR}/mach/headers/Makefile.inc" -.include "${.CURDIR}/mach/servers/Makefile.inc" - -MD_MIGDEFS += task.defs \ - thread_act.defs - -MD_MIGHDRS += ${MD_MIGDEFS:.defs=.h} - -MIGDEFS += \ - clock.defs \ - clock_priv.defs \ - host_priv.defs \ - host_security.defs \ - ledger.defs \ - lock_set.defs \ - mach_port.defs \ - mach_host.defs \ - mach_vm.defs \ - processor.defs \ - processor_set.defs \ - vm_map.defs - -MIGHDRS = ${MIGDEFS:.defs=.h} -MIGHDRS += clock_reply.h -MACH_INSTHDRS += ${MIGHDRS} - -# These files are generated from the .defs files -MIGSRCS = ${MIGDEFS:.defs=User.c} ${MD_MIGDEFS:.defs=User.c} - -MISRCS += ${MIGSRCS} \ - bootstrap_ports.c \ - clock_sleep.c \ - error_codes.c \ - excServer.c \ - excUser.c \ - exc_catcher.c \ - exc_catcher_state.c \ - exc_catcher_state_identity.c \ - fprintf_stderr.c \ - mig_allocate.c \ - mig_deallocate.c \ - mig_reply_setup.c \ - mig_strncpy.c \ - mach_error.c \ - mach_error_string.c \ - mach_init.c \ - mach_init_ports.c \ - mach_msg.c \ - mach_traps.s \ - ms_thread_switch.c \ - notifyUser.c \ - panic.c \ - port_obj.c \ - sbrk.c \ - semaphore.c \ - slot_name.c - -CLEANFILES += ${MIGHDRS} ${MIGSRCS} ${MD_MIGDEFS:.defs=Server.c} \ - ${MIGDEFS:.defs=Server.c} exc.h excUser.c excServer.c \ - notify.h notifyUser.c notifyServer.c - -.if ${LIB} == "c" - -MAN2 += brk.2 - -MLINKS += brk.2 sbrk.2 - -.endif diff --git a/mach/bootstrap_ports.c b/mach/bootstrap_ports.c deleted file mode 100644 index 1a278c2..0000000 --- a/mach/bootstrap_ports.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#include - -/* - * Stub out the old bootstrap_ports() API, as some applications need - * it to exist. We do not publish a prototype for this, and the stub - * WILL disappear in a future release. - */ -kern_return_t -bootstrap_ports( - mach_port_t bootstrap, - mach_port_t *priv_host, - mach_port_t *device_master, - mach_port_t *wired_ledger, - mach_port_t *paged_ledger, - mach_port_t *host_security) -{ - return KERN_FAILURE; -} - diff --git a/mach/brk.2 b/mach/brk.2 deleted file mode 100644 index 9ea4f61..0000000 --- a/mach/brk.2 +++ /dev/null @@ -1,150 +0,0 @@ -.\" $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/mach/clock.defs b/mach/clock.defs deleted file mode 100644 index 4334cee..0000000 --- a/mach/clock.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/clock_priv.defs b/mach/clock_priv.defs deleted file mode 100644 index d796ab1..0000000 --- a/mach/clock_priv.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/clock_reply.defs b/mach/clock_reply.defs deleted file mode 100644 index 19b5fe8..0000000 --- a/mach/clock_reply.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/clock_sleep.c b/mach/clock_sleep.c deleted file mode 100644 index e6d1dcf..0000000 --- a/mach/clock_sleep.c +++ /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@ - */ -#include -#include -#include - -kern_return_t clock_sleep(mach_port_t clock_name, - sleep_type_t clock_type, - mach_timespec_t sleep_time, - mach_timespec_t *wake_time) { - - return clock_sleep_trap(clock_name, clock_type, sleep_time.tv_sec, sleep_time.tv_nsec, wake_time); -} diff --git a/mach/err_ipc.sub b/mach/err_ipc.sub deleted file mode 100644 index 9c763cc..0000000 --- a/mach/err_ipc.sub +++ /dev/null @@ -1,99 +0,0 @@ -/* - * @OSF_COPYRIGHT@ - */ - -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -/* - * File: err_ipc.sub - * Author: Douglas Orr, Carnegie Mellon University - * Date: Mar, 1988 - * - * Definitions of error strings for original IPC - */ - -static const char * err_codes_send[] = { - "(ipc/send) unknown error", /* -100 */ - "(ipc/send) invalid memory", /* -101 */ - "(ipc/send) invalid port", /* -102 */ - "(ipc/send) timed out", /* -103 */ - "(ipc/send) unused error", /* -104 */ - "(ipc/send) will notify", /* -105 */ - "(ipc/send) notify in progress", /* -106 */ - "(ipc/send) kernel refused message", /* -107 */ - "(ipc/send) send interrupted", /* -108 */ - "(ipc/send) send message too large", /* -109 */ - "(ipc/send) send message too small", /* -110 */ - "(ipc/send) message size changed while being copied", /* -111 */ -}; - -static const char * err_codes_rcv[] = { - "(ipc/rcv) unknown error", /* -200 */ - "(ipc/rcv) invalid memory", /* -201 */ - "(ipc/rcv) invalid port", /* -202 */ - "(ipc/rcv) receive timed out", /* -203 */ - "(ipc/rcv) message too large", /* -204 */ - "(ipc/rcv) no space for message data", /* -205 */ - "(ipc/rcv) only sender remaining", /* -206 */ - "(ipc/rcv) receive interrupted", /* -207 */ - "(ipc/rcv) port receiver changed or port became enabled", /* -208 */ -}; - -static const char * err_codes_mig[] = { - "(ipc/mig) type check failure in message interface", /* 0 (-300) */ - "(ipc/mig) wrong return message ID", /* 1 */ - "(ipc/mig) server detected error", /* 2 */ - "(ipc/mig) bad message ID", /* 3 */ - "(ipc/mig) server found wrong arguments", /* 4 */ - "(ipc/mig) no reply should be sent", /* 5 */ - "(ipc/mig) server raised exception", /* 6 */ - "(ipc/mig) user specified array not large enough for return info", /* 7 */ -}; - -/* err_ipc subsystems */ -static struct error_subsystem err_ipc_sub[] = { - /* ipc/0; */ - { - (char *)"(ipc/send)", - errlib_count(err_codes_send), - (char **)err_codes_send, - }, - /* ipc/1; */ - { - (char *)"(ipc/rcv)", - errlib_count(err_codes_rcv), - (char **)err_codes_rcv, - - }, - /* ipc/2 */ - { - (char *)"(ipc/mig)", - errlib_count(err_codes_mig), - (char **)err_codes_mig, - }, - -}; diff --git a/mach/err_kern.sub b/mach/err_kern.sub deleted file mode 100644 index 5103603..0000000 --- a/mach/err_kern.sub +++ /dev/null @@ -1,182 +0,0 @@ -/* - * @OSF_COPYRIGHT@ - */ - -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -/* - * File: err_kern.sub - * Author: Douglas Orr, Carnegie Mellon University - * Date: Mar, 1988 - * - * error codes for Mach and Unix kernels - */ - -static const char * err_codes_kern[] = { - "(os/kern) successful", /* 0 */ - "(os/kern) invalid address", - "(os/kern) protection failure", - "(os/kern) no space available", - "(os/kern) invalid argument", - "(os/kern) failure", /* 5 */ - "(os/kern) resource shortage", - "(os/kern) not receiver", - "(os/kern) no access", - "(os/kern) memory failure", - "(os/kern) memory error", /* 10 */ - "(os/kern) already in set", - "(os/kern) not in set", - "(os/kern) name exists", - "(os/kern) aborted", - "(os/kern) invalid name", /* 15 */ - "(os/kern) invalid task", - "(os/kern) invalid right", - "(os/kern) invalid value", - "(os/kern) urefs overflow", - "(os/kern) invalid capability", /* 20 */ - "(os/kern) right exists", - "(os/kern) invalid host", - "(os/kern) memory present", - "(os/kern) memory data moved", - "(os/kern) memory restart copy", /* 25 */ - "(os/kern) invalid processor set", - "(os/kern) policy limit", - "(os/kern) invalid policy", - "(os/kern) invalid object", - "(os/kern) already waiting", /* 30 */ - "(os/kern) default set", - "(os/kern) exception protected", - "(os/kern) invalid ledger", - "(os/kern) invalid memory control", - "(os/kern) invalid security", /* 35 */ - "(os/kern) not depressed", - "(os/kern) object terminated", - "(os/kern) lock set destroyed", - "(os/kern) lock unstable", - "(os/kern) lock owned by another", /* 40 */ - "(os/kern) lock owned by self", - "(os/kern) semaphore destroyed", - "(os/kern) RPC terminated", - "(os/kern) terminate orphan", - "(os/kern) let orphan continue", /* 45 */ - "(os/kern) service not supported", - "(os/kern) remote node down", -}; - -static const char * err_codes_unix[] = { - NO_SUCH_ERROR, - "(os/unix) no rights to object", - "(os/unix) file or directory does not exist", - "(os/unix) no such process", - "(os/unix) interrupted system call", - "(os/unix) i/o error", - "(os/unix) device does not exist", - "(os/unix) argument list is too long", - "(os/unix) invalid executable object format", - "(os/unix) bad file descriptor number", - "(os/unix) no child processes are present", - "(os/unix) no more processes are available", - "(os/unix) insufficient memory", - "(os/unix) access denied", - "(os/unix) memory access fault", - "(os/unix) block device required for operation", - "(os/unix) mount device busy", - "(os/unix) file already exists", - "(os/unix) cross device link", - "(os/unix) device does not exist", - "(os/unix) object is not a directory", - "(os/unix) object is a directory", - "(os/unix) invalid argument", - "(os/unix) internal file table overflow", - "(os/unix) maximum number of open files reached", - "(os/unix) object is not a tty-like device", - "(os/unix) executable object is in use", - "(os/unix) file is too large", - "(os/unix) no space is left on device", - "(os/unix) illegal seek attempt", - "(os/unix) read-only file system", - "(os/unix) too many links", - "(os/unix) broken pipe", - "(os/unix) argument is too large", - "(os/unix) result is out of range", - "(os/unix) operation on device would block", - "(os/unix) operation is now in progress", - "(os/unix) operation is already in progress", - "(os/unix) socket operation attempted on non-socket object", - "(os/unix) destination address is required", - "(os/unix) message is too long", - "(os/unix) protocol type is incorrect for socket", - "(os/unix) protocol type is not availaible", - "(os/unix) protocol type is not supported", - "(os/unix) socket type is not supported", - "(os/unix) operation is not supported on sockets", - "(os/unix) protocol family is not supported", - "(os/unix) address family is not supported by protocol family", - "(os/unix) address is already in use", - "(os/unix) can't assign requested address", - "(os/unix) network is down", - "(os/unix) network is unreachable", - "(os/unix) network dropped connection on reset", - "(os/unix) software aborted connection", - "(os/unix) connection reset by peer", - "(os/unix) no buffer space is available", - "(os/unix) socket is already connected", - "(os/unix) socket is not connected", - "(os/unix) can't send after socket shutdown", - "(os/unix) too many references; can't splice", - "(os/unix) connection timed out", - "(os/unix) connection was refused", - "(os/unix) too many levels of symbolic links", - "(os/unix) file name exceeds system maximum limit", - "(os/unix) host is down", - "(os/unix) there is no route to host", - "(os/unix) directory is not empty", - "(os/unix) quota on number of processes exceeded", - "(os/unix) quota on number of users exceeded", - "(os/unix) quota on available disk space exceeded", -}; - -static struct error_subsystem err_os_sub[] = { - { - (char *)"(os/kern)", - errlib_count(err_codes_kern), - (char **)err_codes_kern, - }, - { - (char *)"(os/?)", - 0, - }, - { - (char *)"(os/?)", - 0, - }, - { - (char *)"(os/unix)", - errlib_count(err_codes_unix), - (char **)err_codes_unix, - }, -}; diff --git a/mach/err_mach_ipc.sub b/mach/err_mach_ipc.sub deleted file mode 100644 index 6db64fb..0000000 --- a/mach/err_mach_ipc.sub +++ /dev/null @@ -1,119 +0,0 @@ -/* - * @OSF_COPYRIGHT@ - */ - -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -/* - * File: err_mach_ipc.sub - * Author: Richard Draves, Carnegie Mellon University - * Date: Jan, 1990 - * - * Error string definitions for the new Mach IPC - */ - -static const char * err_codes_mach_send[] = { - /* 0 */ "(ipc/send) no error", - /* 1 */ "(ipc/send) send in progress", - /* 2 */ "(ipc/send) invalid data", - /* 3 */ "(ipc/send) invalid destination port", - /* 4 */ "(ipc/send) timed out", - /* 5 */ "(ipc/send) will notify", - /* 6 */ "(ipc/send) notify in progress", - /* 7 */ "(ipc/send) interrupted", - /* 8 */ "(ipc/send) msg too small", - /* 9 */ "(ipc/send) invalid reply port", - /* 10 */ "(ipc/send) invalid port right", - /* 11 */ "(ipc/send) invalid notify port", - /* 12 */ "(ipc/send) invalid memory", - /* 13 */ "(ipc/send) no msg buffer", - /* 14 */ "(ipc/send) no notify possible", - /* 15 */ "(ipc/send) invalid msg-type", - /* 16 */ "(ipc/send) invalid msg-header", - /* 17 */ "(ipc/send) invalid msg-trailer", - /* 18 */ "(ipc/send) DIPC transport failure", - /* 19 */ "(ipc/send) DIPC port migrated", - /* 20 */ "(ipc/send) DIPC resend failed", - /* 21 */ "(ipc/send) out-of-line buffer too large", -}; - -static const char * err_codes_mach_rcv[] = { - /* 0 */ "(ipc/rcv) no error", - /* 1 */ "(ipc/rcv) receive in progress", - /* 2 */ "(ipc/rcv) invalid name", - /* 3 */ "(ipc/rcv) timed out", - /* 4 */ "(ipc/rcv) msg too large", - /* 5 */ "(ipc/rcv) interrupted", - /* 6 */ "(ipc/rcv) port changed", - /* 7 */ "(ipc/rcv) invalid notify port", - /* 8 */ "(ipc/rcv) invalid data", - /* 9 */ "(ipc/rcv) port died", - /* 10 */ "(ipc/rcv) port in set", - /* 11 */ "(ipc/rcv) header error", - /* 12 */ "(ipc/rcv) body error", - /* 13 */ "(ipc/rcv) invalid scatter list entry", - /* 14 */ "(ipc/rcv) overwrite region too small", - /* 15 */ "(ipc/rcv) invalid msg-trailer", - /* 16 */ "(ipc/rcv) DIPC transport error", -}; - -static const char * err_codes_mach_mig[] = { - /* 0 */ "(ipc/mig) client type check failure", - /* 1 */ "(ipc/mig) wrong reply message ID", - /* 2 */ "(ipc/mig) server detected error", - /* 3 */ "(ipc/mig) bad request message ID", - /* 4 */ "(ipc/mig) server type check failure", - /* 5 */ "(ipc/mig) no reply should be sent", - /* 6 */ "(ipc/mig) server raised exception", - /* 7 */ "(ipc/mig) array not large enough", - /* 8 */ "(ipc/mig) server died", - /* 9 */ "(ipc/mig) unknown trailer format", -}; - -/* err_mach_ipc subsystems */ -static struct error_subsystem err_mach_ipc_sub[] = { - /* ipc/0; */ - { - (char *)"(ipc/send)", - errlib_count(err_codes_mach_send), - (char **)err_codes_mach_send, - }, - /* ipc/1; */ - { - (char *)"(ipc/rcv)", - errlib_count(err_codes_mach_rcv), - (char **)err_codes_mach_rcv, - - }, - /* ipc/2 */ - { - (char *)"(ipc/mig)", - errlib_count(err_codes_mach_mig), - (char **)err_codes_mach_mig, - }, - -}; diff --git a/mach/err_server.sub b/mach/err_server.sub deleted file mode 100644 index fcbe91b..0000000 --- a/mach/err_server.sub +++ /dev/null @@ -1,357 +0,0 @@ -/* - * @OSF_COPYRIGHT@ - */ - -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -/* - * File: err_server.sub - * Author: Douglas Orr, Carnegie Mellon University - * Date: Mar, 1988 - * - * Definitions of Servers error strings - */ - -static const char * err_codes_netname[] = { /* 0 */ - "(server/netname) name is not yours", - "(server/netname) name not checked in", - "(server/netname) no such host", - "(server/netname) host not found", -}; -static const char * err_codes_env_mgr[] = { /* 1 */ - NO_SUCH_ERROR, - "(server/env_mgr) variable not found", - "(server/env_mgr) wrong type of variable", - "(server/env_mgr) unknown port", - "(server/env_mgr) read only environment", - "(server/env_mgr) no more connections available", - "(server/env_mgr) port table full", - "(server/env_mgr) attempting to enter a null port ", -}; -static const char * err_codes_execd[] = { /* 2 */ - NO_SUCH_ERROR, - "(server/execd) could not find file to run", - "(server/execd) userid or password incorrect", - "(server/execd) fork failed", -}; -static const char * err_codes_netmemory[] = { /* 3 */ - "(server/netmemory) successful", - "(server/netmemory) invalid argument", - "(server/netmemory) resource shortage", -}; -static const char * err_codes_ufs[] = { /* 4 */ - NO_SUCH_ERROR, -/* XXX "(server/ufs) invalid port", */ -}; - -static const char * err_codes_task_master[] = { /* 5 */ - "(server/task_master) GENERIC ERROR", - "(server/task_master) invalid tm_task port", - "(server/task_master) invalid task id", - "(server/task_master) invalid kernel port", - "(server/task_master) invalid job group", - "(server/task_master) invalid action", -}; - -static const char * err_codes_ns[] = { /* 6 */ - "(server/ns) GENERIC ERROR", - "(server/ns) invalid handle", - "(server/ns) name not found", - "(server/ns) name already exists", - "(server/ns) name too long", - "(server/ns) path too long", - "(server/ns) invalid name", - "(server/ns) not a directory", - "(server/ns) is a directory", - "(server/ns) directory not empty", - "(server/ns) infinite retry loop in resolver", - "(server/ns) infinite forwarding loop in resolver", - "(server/ns) invalid prefix", - "(server/ns) prefix table overflow", - "(server/ns) bad format for directory", - "(server/ns) unknown entry type", - "(server/ns) invalid generation", - "(server/ns) entry not reserved", -}; - -static const char * err_codes_io[] = { /* 7 */ - "(server/io) GENERIC ERROR", - "(server/io) invalid offset", - "(server/io) invalid size", - "(server/io) invalid mode", - "(server/io) invalid strategy", - "(server/io) operation rejected under current I/O strategy", -}; - -static const char * err_codes_auth[] = { /* 8 */ - "(server/auth) GENERIC ERROR", - "(server/auth) bad private port", - "(server/auth) bad name", - "(server/auth) not primary", - "(server/auth) bad pauthsword", - "(server/auth) bad group", - "(server/auth) duplicate id", - "(server/auth) duplicate name", - "(server/auth) not secondary", -}; - -static const char * err_codes_us[] = { /* 9 */ - "(server/us) GENERIC ERROR", - "(server/us) unknown error", - "(server/us) object not found", - "(server/us) object exists", - "(server/us) object busy", - "(server/us) object not started", - "(server/us) object dead", - "(server/us) invalid args", - "(server/us) invalid access", - "(server/us) invalid format", - "(server/us) invalid buffer size", - "(server/us) access denied", - "(server/us) resource exhausted", - "(server/us) quota exceeded", - "(server/us) limit exceeded", - "(server/us) not implemented", - "(server/us) not supported", - "(server/us) hardware error", - "(server/us) retry required", - "(server/us) not authenticated", - "(server/us) exclusive access", - "(server/us) timeout", - "(server/us) bad reference count", - "(server/us) internal error", -}; - -static const char * err_codes_sunrpc[] = { /* 10 */ - "(server/sunrpc) GENERIC ERROR", - "(server/sunrpc) cannot encode arguments", - "(server/sunrpc) cannot decode results", - "(server/sunrpc) failure in sending call", - "(server/sunrpc) failure in receiving result", - "(server/sunrpc) call timed out", - "(server/sunrpc) rpc versions not compatible", - "(server/sunrpc) authentication error", - "(server/sunrpc) program not available", - "(server/sunrpc) program version mismatched", - "(server/sunrpc) procedure unavailable", - "(server/sunrpc) decode arguments error", - "(server/sunrpc) generic other problem", - "(server/sunrpc) unknown host name", - "(server/sunrpc) portmapper failed", - "(server/sunrpc) remote program not registered", - "(server/sunrpc) unspecified error", - "(server/sunrpc) unknown protocol", -}; - -static const char * err_codes_machobj[] = { /* 11 */ - "(server/object system) GENERIC ERROR", - "(server/object system) object not found", - "(server/object system) no such operation", - "(server/object system) undefined ipc method arguments", - "(server/object system) too many arguments to method", - "(server/object system) bad ipc message format", -}; - -static const char * err_codes_loader[] = { /* 12 */ - "(server/loader) GENERIC ERROR", - "(server/loader) object file not relocated", - "(server/loader) unknown file type", - "(server/loader) symbol not found", - "(server/loader) symbol multiply defined", - "(server/loader) memory region overlap", -}; - - -static const char * err_codes_exception[] = { /* 13 */ - "(server/exception) GENERIC ERROR", - "(server/exception) invalid access", - "(server/exception) invalid instruction", - "(server/exception) arithmetic exception", - "(server/exception) emulation exception", - "(server/exception) software exception", - "(server/exception) breakpoint exception", -}; - -static const char * err_codes_ux_signal[] = { /* 14 */ - "(server/unix-signal) GENERIC ERROR", - "(server/unix-signal) hangup", - "(server/unix-signal) interrupt", - "(server/unix-signal) quit", - "(server/unix-signal) undefined", - "(server/unix-signal) undefined", - "(server/unix-signal) undefined", - "(server/unix-signal) undefined", - "(server/unix-signal) kill", - "(server/unix-signal) undefined", - "(server/unix-signal) undefined", - "(server/unix-signal) system error", - "(server/unix-signal) pipe signal", - "(server/unix-signal) alarm", - "(server/unix-signal) terminate", - "(server/unix-signal) urgent i/o", - "(server/unix-signal) stop", - "(server/unix-signal) terminal stop", - "(server/unix-signal) continue", - "(server/unix-signal) child death", - "(server/unix-signal) tty input", - "(server/unix-signal) tty output", - "(server/unix-signal) i/o signal", - "(server/unix-signal) cpu time limit exceeded", - "(server/unix-signal) file size exceeded", - "(server/unix-signal) virtual alarm", - "(server/unix-signal) profile signal", - "(server/unix-signal) window size change", - "(server/unix-signal) user-defined signal 1", - "(server/unix-signal) user-defined signal 2", -}; - -static const char * err_codes_xkernel[] = { /* 15 */ - "(server/xkernel) GENERIC ERROR", - "(server/xkernel) map full", - "(server/xkernel) inconsistent bind", - "(server/xkernel) cannot resolve", - "(server/xkernel) cannot unbind", - "(server/xkernel) invalid type", - "(server/xkernel) invalid opcode", - "(server/xkernel) buffer too small", - "(server/xkernel) invalid ev code", - "(server/xkernel) event not registered", - "(server/xkernel) invalid open", - "(server/xkernel) already open", - "(server/xkernel) bad addr", -}; - - -/* err_server subsystems */ -static struct error_subsystem err_server_sub[] = { - /* server/0; */ - { - (char *)"(server/netname)", - errlib_count(err_codes_netname), - (char **)err_codes_netname, - }, - /* server/1; */ - { - (char *)"(server/env_mgr)", - errlib_count(err_codes_env_mgr), - (char **)err_codes_env_mgr, - }, - /* server/2; */ - { - (char *)"(server/execd)", - errlib_count(err_codes_execd), - (char **)err_codes_execd, - }, - /* server/3; */ - { - (char *)"(server/netmemory)", - errlib_count(err_codes_netmemory), - (char **)err_codes_netmemory, - }, - /* server/4; */ - { - (char *)"(server/ufs)", - errlib_count(err_codes_ufs), - (char **)err_codes_ufs, - }, - /* server/5; */ - { - (char *)"(server/task_master)", - errlib_count(err_codes_task_master), - (char **)err_codes_task_master, - }, - /* server/6; */ - { - (char *)"(server/ns)", - errlib_count(err_codes_ns), - (char **)err_codes_ns, - }, - - /* server/7; i/o subsystem */ - { - (char *)"(server/io)", - errlib_count(err_codes_io), - (char **)err_codes_io, - }, - - /* server/8; authentication server */ - { - (char *)"(server/auth)", - errlib_count(err_codes_auth), - (char **)err_codes_auth, - }, - - /* server/9; generic US system */ - { - (char *)"(server/us)", - errlib_count(err_codes_us), - (char **)err_codes_us, - }, - - /* server/10; SUN RPC package */ - { - (char *)"(server/sunrpc)", - errlib_count(err_codes_sunrpc), - (char **)err_codes_sunrpc, - }, - - /* server/11; MachObject system */ - { - (char *)"(server/object system)", - errlib_count(err_codes_machobj), - (char **)err_codes_machobj, - }, - - /* server/12; loader */ - { - (char *)"(server/loader)", - errlib_count(err_codes_loader), - (char **)err_codes_loader, - }, - - /* server/13; mach exception */ - { - (char *)"(server/exception)", - errlib_count(err_codes_exception), - (char **)err_codes_exception, - }, - - /* server/14; unix signal */ - { - (char *)"(server/unix-signal)", - errlib_count(err_codes_ux_signal), - (char **)err_codes_ux_signal, - }, - - /* server/15; xkernel */ - { - (char *)"(server/xkernel)", - errlib_count(err_codes_xkernel), - (char **)err_codes_xkernel, - }, - -}; diff --git a/mach/err_us.sub b/mach/err_us.sub deleted file mode 100644 index 8db68f6..0000000 --- a/mach/err_us.sub +++ /dev/null @@ -1,45 +0,0 @@ -/* - * @OSF_COPYRIGHT@ - */ - -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -/* - * File: err_us.sub - * Author: Douglas Orr, Carnegie Mellon University - * Date: Mar, 1988 - * - * A place to define User errors - */ - - -/* err_us subsystems */ -static struct error_subsystem err_us_sub[] = { - { - (char *)0, - }, -}; diff --git a/mach/error_codes.c b/mach/error_codes.c deleted file mode 100644 index 4b2461b..0000000 --- a/mach/error_codes.c +++ /dev/null @@ -1,101 +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@ - */ -/* - * @OSF_COPYRIGHT@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -/* - * File: error_codes.c - * Author: Douglas Orr, Carnegie Mellon University - * Date: Mar, 1988 - * - * Generic error code interface - */ - -#include -#include "errorlib.h" -#include "err_kern.sub" -#include "err_us.sub" -#include "err_server.sub" -#include "err_ipc.sub" -#include "err_mach_ipc.sub" - -__private_extern__ struct error_system _mach_errors[err_max_system+1] = { - /* 0; err_kern */ - { - errlib_count(err_os_sub), - (char *)"(operating system/?) unknown subsystem error", - err_os_sub, - }, - /* 1; err_us */ - { - errlib_count(err_us_sub), - (char *)"(user space/?) unknown subsystem error", - err_us_sub, - }, - /* 2; err_server */ - { - errlib_count(err_server_sub), - (char *)"(server/?) unknown subsystem error", - err_server_sub, - }, - /* 3 (& 3f); err_ipc */ - { - errlib_count(err_ipc_sub), - (char *)"(ipc/?) unknown subsystem error", - err_ipc_sub, - }, - /* 4; err_mach_ipc */ - { - errlib_count(err_mach_ipc_sub), - (char *)"(ipc/?) unknown subsystem error", - err_mach_ipc_sub, - }, -}; - -int error_system_count = errlib_count(_mach_errors); diff --git a/mach/errorlib.h b/mach/errorlib.h deleted file mode 100644 index 2049010..0000000 --- a/mach/errorlib.h +++ /dev/null @@ -1,95 +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@ - */ -/* - * @OSF_COPYRIGHT@ - */ - -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -/* - * File: errorlib.h - * Author: Douglas Orr, Carnegie Mellon University - * Date: Mar. 1988 - * - * Error bases for subsytems errors. - */ - -#include -#include - -#define MACH_IPC_SEND_MOD (err_mach_ipc|err_sub(0)) -#define MACH_IPC_RCV_MOD (err_mach_ipc|err_sub(1)) -#define MACH_IPC_MIG_MOD (err_mach_ipc|err_sub(2)) - -#define IPC_SEND_MOD (err_ipc|err_sub(0)) -#define IPC_RCV_MOD (err_ipc|err_sub(1)) -#define IPC_MIG_MOD (err_ipc|err_sub(2)) - -#define SERV_NETNAME_MOD (err_server|err_sub(0)) -#define SERV_ENV_MOD (err_server|err_sub(1)) -#define SERV_EXECD_MOD (err_server|err_sub(2)) - - -#define NO_SUCH_ERROR "unknown error code" - -struct error_subsystem { - char * subsys_name; - int max_code; - char * * codes; -}; - -struct error_system { - int max_sub; - char * bad_sub; - struct error_subsystem * subsystem; -}; - -__private_extern__ struct error_system _mach_errors[err_max_system+1]; - -__private_extern__ char *mach_error_string_int(mach_error_t, boolean_t *); - -#define errlib_count(s) (sizeof(s)/sizeof(s[0])) diff --git a/mach/exc.defs b/mach/exc.defs deleted file mode 100644 index 399e6a2..0000000 --- a/mach/exc.defs +++ /dev/null @@ -1,24 +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@ - */ -#define catch_ internal_catch_ -#include diff --git a/mach/exc_catcher.c b/mach/exc_catcher.c deleted file mode 100644 index 2606e4f..0000000 --- a/mach/exc_catcher.c +++ /dev/null @@ -1,62 +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@ - */ -/* - * catch_exception_raise will be implemented by user programs - * This implementation is provided to resolve the reference in - * exc_server(). - */ - -#include -#include -#include -#include -#include -#include - -__private_extern__ kern_return_t internal_catch_exception_raise ( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t codeCnt) -{ -#if defined(__DYNAMIC__) - static int checkForFunction = 0; - /* This will be non-zero if the user has defined this function */ - static kern_return_t (*func)(mach_port_t, mach_port_t, mach_port_t, exception_type_t, exception_data_t, mach_msg_type_number_t); - if (checkForFunction == 0) { - checkForFunction = 1; - _dyld_lookup_and_bind("_catch_exception_raise", (unsigned long *)&func, (void **)0); - } - if (func == 0) { - /* The user hasn't defined catch_exception_raise in their binary */ - abort(); - } - return (*func)(exception_port, thread, task, exception, code, codeCnt); -#else - extern kern_return_t catch_exception_raise(mach_port_t, mach_port_t, mach_port_t, exception_type_t, exception_data_t, mach_msg_type_number_t); - return catch_exception_raise(exception_port, thread, task, exception, code, codeCnt); -#endif -} - diff --git a/mach/exc_catcher_state.c b/mach/exc_catcher_state.c deleted file mode 100644 index 0070cc8..0000000 --- a/mach/exc_catcher_state.c +++ /dev/null @@ -1,64 +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@ - */ -/* - * catch_exception_raise_state will be implemented by user programs - * This implementation is provided to resolve the reference in - * exc_server(). - */ - -#include -#include -#include -#include -#include -#include - -__private_extern__ kern_return_t internal_catch_exception_raise_state ( - mach_port_t exception_port, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt) -{ -#if defined(__DYNAMIC__) - static int checkForFunction = 0; - /* This will be non-zero if the user has defined this function */ - static kern_return_t (*func)(mach_port_t, exception_type_t, exception_data_t, mach_msg_type_number_t, int *, thread_state_t, mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t *); - if (checkForFunction == 0) { - checkForFunction = 1; - _dyld_lookup_and_bind("_catch_exception_raise_state", (unsigned long *)&func, (void **)0); - } - if (func == 0) { - /* The user hasn't defined catch_exception_raise in their binary */ - abort(); - } - return (*func)(exception_port, exception, code, codeCnt, flavor, old_state, old_stateCnt, new_state, new_stateCnt); -#else - extern kern_return_t catch_exception_raise_state(mach_port_t, exception_type_t, exception_data_t, mach_msg_type_number_t, int *, thread_state_t, mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t *); - return catch_exception_raise_state(exception_port, exception, code, codeCnt, flavor, old_state, old_stateCnt, new_state, new_stateCnt); -#endif -} diff --git a/mach/exc_catcher_state_identity.c b/mach/exc_catcher_state_identity.c deleted file mode 100644 index ace77a3..0000000 --- a/mach/exc_catcher_state_identity.c +++ /dev/null @@ -1,66 +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@ - */ -/* - * catch_exception_raise_state_identity will be implemented by user programs - * This implementation is provided to resolve the reference in - * exc_server(). - */ - -#include -#include -#include -#include -#include -#include - -__private_extern__ kern_return_t internal_catch_exception_raise_state_identity ( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt) -{ -#if defined(__DYNAMIC__) - static int checkForFunction = 0; - /* This will be non-zero if the user has defined this function */ - static kern_return_t (*func)(mach_port_t, mach_port_t, mach_port_t, exception_type_t, exception_data_t, mach_msg_type_number_t, int *, thread_state_t, mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t *); - if (checkForFunction == 0) { - checkForFunction = 1; - _dyld_lookup_and_bind("_catch_exception_raise_state_identity", (unsigned long *)&func, (void **)0); - } - if (func == 0) { - /* The user hasn't defined catch_exception_raise in their binary */ - abort(); - } - return (*func)(exception_port, thread, task, exception, code, codeCnt, flavor, old_state, old_stateCnt, new_state, new_stateCnt); -#else - extern kern_return_t catch_exception_raise_state_identity(mach_port_t, mach_port_t, mach_port_t, exception_type_t, exception_data_t, mach_msg_type_number_t, int *, thread_state_t, mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t *); - return catch_exception_raise_state_identity(exception_port, thread, task, exception, code, codeCnt, flavor, old_state, old_stateCnt, new_state, new_stateCnt); -#endif -} diff --git a/mach/fprintf_stderr.c b/mach/fprintf_stderr.c deleted file mode 100644 index 5e4c883..0000000 --- a/mach/fprintf_stderr.c +++ /dev/null @@ -1,57 +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@ - */ -/* - * @OSF_FREE_COPYRIGHT@ - * - */ - -#include -#include -#include -#include - -int (*vprintf_stderr_func)(const char *format, va_list ap); - - -/* This function allows the writing of a mach error message to an - * application-controllable output method, the default being to - * use printf if no other method is specified by the application. - * - * To override, set the global (static) function pointer vprintf_stderr to - * a function which takes the same parameters as vprintf. - */ - -int fprintf_stderr(const char *format, ...) -{ - va_list args; - int retval; - - va_start(args, format); - if (vprintf_stderr_func == NULL) - retval = vprintf(format, args); - else - retval = (*vprintf_stderr_func)(format, args); - va_end(args); - - return retval; -} diff --git a/mach/headers/Makefile.inc b/mach/headers/Makefile.inc deleted file mode 100644 index f747c3d..0000000 --- a/mach/headers/Makefile.inc +++ /dev/null @@ -1,10 +0,0 @@ -MACH_INSTHDRS += mach.h \ - mach_error.h \ - mach_init.h \ - mach_interface.h \ - port_obj.h \ - sync.h \ - task.h \ - thread_act.h \ - vm_task.h -MACH_INSTHDRS := ${MACH_INSTHDRS:S/^/${.CURDIR}\/mach\/headers\//} diff --git a/mach/headers/errorlib.h b/mach/headers/errorlib.h deleted file mode 100644 index d987c0c..0000000 --- a/mach/headers/errorlib.h +++ /dev/null @@ -1,96 +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@ - */ -/* - * @OSF_COPYRIGHT@ - */ - -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -/* - * File: errorlib.h - * Author: Douglas Orr, Carnegie Mellon University - * Date: Mar. 1988 - * - * Error bases for subsytems errors. - */ - -#include - -#define MACH_IPC_SEND_MOD (err_mach_ipc|err_sub(0)) -#define MACH_IPC_RCV_MOD (err_mach_ipc|err_sub(1)) -#define MACH_IPC_MIG_MOD (err_mach_ipc|err_sub(2)) - -#define IPC_SEND_MOD (err_ipc|err_sub(0)) -#define IPC_RCV_MOD (err_ipc|err_sub(1)) -#define IPC_MIG_MOD (err_ipc|err_sub(2)) - -#define SERV_NETNAME_MOD (err_server|err_sub(0)) -#define SERV_ENV_MOD (err_server|err_sub(1)) -#define SERV_EXECD_MOD (err_server|err_sub(2)) - - -#define NO_SUCH_ERROR "unknown error code" - -struct error_subsystem { - char * subsys_name; - int max_code; - char * * codes; -}; - -struct error_system { - int max_sub; - char * bad_sub; - struct error_subsystem * subsystem; -}; - -#include - -__BEGIN_DECLS -extern struct error_system errors[err_max_system+1]; -__END_DECLS - -#define errlib_count(s) (sizeof(s)/sizeof(s[0])) diff --git a/mach/headers/mach.h b/mach/headers/mach.h deleted file mode 100644 index d79c880..0000000 --- a/mach/headers/mach.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 1999-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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -/* - * Includes all the types that a normal user - * of Mach programs should need - */ - -#ifndef _MACH_H_ -#define _MACH_H_ - -#define __MACH30__ -#define MACH_IPC_FLAVOR UNTYPED - -#include -#include -#include -#include -#include -#include -#include - -#include /* for compatibility only */ -#include - -#include -#include - -#include - -__BEGIN_DECLS -/* - * Standard prototypes - */ -extern void panic_init(mach_port_t); -extern void panic(const char *, ...); - -extern void safe_gets(char *, - char *, - int); - -extern void slot_name(cpu_type_t, - cpu_subtype_t, - char **, - char **); - -extern void mig_reply_setup(mach_msg_header_t *, - mach_msg_header_t *); - -extern void mach_msg_destroy(mach_msg_header_t *); - -extern mach_msg_return_t mach_msg_receive(mach_msg_header_t *); - -extern mach_msg_return_t mach_msg_send(mach_msg_header_t *); - -extern mach_msg_return_t mach_msg_server_once(boolean_t (*) - (mach_msg_header_t *, - mach_msg_header_t *), - mach_msg_size_t, - mach_port_t, - mach_msg_options_t); -extern mach_msg_return_t mach_msg_server(boolean_t (*) - (mach_msg_header_t *, - mach_msg_header_t *), - mach_msg_size_t, - mach_port_t, - mach_msg_options_t); - -/* - * Prototypes for compatibility - */ -extern kern_return_t clock_get_res(mach_port_t, - clock_res_t *); -extern kern_return_t clock_set_res(mach_port_t, - clock_res_t); - -extern kern_return_t clock_sleep(mach_port_t, - int, - mach_timespec_t, - mach_timespec_t *); -__END_DECLS - -#endif /* _MACH_H_ */ diff --git a/mach/headers/mach_error.h b/mach/headers/mach_error.h deleted file mode 100644 index 9443e7f..0000000 --- a/mach/headers/mach_error.h +++ /dev/null @@ -1,88 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -/* - * File: mach_error.h - * Author: Douglas Orr, Carnegie Mellon University - * Date: Mar. 1988 - * - * Definitions of routines in mach_error.c - */ - -#ifndef _MACH_ERROR_ -#define _MACH_ERROR_ 1 - -#include - -#include - -__BEGIN_DECLS -char *mach_error_string( -/* - * Returns a string appropriate to the error argument given - */ - mach_error_t error_value - ); - -void mach_error( -/* - * Prints an appropriate message on the standard error stream - */ - char *str, - mach_error_t error_value - ); - -char *mach_error_type( -/* - * Returns a string with the error system, subsystem and code - */ - mach_error_t error_value - ); -__END_DECLS - -#endif /* _MACH_ERROR_ */ diff --git a/mach/headers/mach_init.h b/mach/headers/mach_init.h deleted file mode 100644 index 58cc74d..0000000 --- a/mach/headers/mach_init.h +++ /dev/null @@ -1,118 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987,1986 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -/* - * Items provided by the Mach environment initialization. - */ - -#ifndef _MACH_INIT_ -#define _MACH_INIT_ 1 - -#include -#include - -#include - -/* - * Kernel-related ports; how a task/thread controls itself - */ - -__BEGIN_DECLS -extern mach_port_t mach_task_self(void); -extern mach_port_t mach_host_self(void); -extern mach_port_t mach_thread_self(void); -__END_DECLS - -extern mach_port_t mach_task_self_; -#define mach_task_self() mach_task_self_ -#define current_task() mach_task_self() - -#include - -/* - * Other important ports in the Mach user environment - */ - -extern mach_port_t bootstrap_port; -extern mach_port_t name_server_port; -extern mach_port_t environment_port; -extern mach_port_t service_port; - -/* - * Where these ports occur in the "mach_ports_register" - * collection... only servers or the runtime library need know. - */ - -#define NAME_SERVER_SLOT 0 -#define ENVIRONMENT_SLOT 1 -#define SERVICE_SLOT 2 - -#define MACH_PORTS_SLOTS_USED 3 - -/* - * Globally interesting numbers. - * These macros assume vm_page_size is a power-of-2. - */ - -extern vm_size_t vm_page_size; -extern vm_size_t vm_page_mask; -extern int vm_page_shift; - -#define trunc_page(x) ((x) & (~(vm_page_size - 1))) -#define round_page(x) trunc_page((x) + (vm_page_size - 1)) - -/* - * fprintf_stderr uses vprintf_stderr_func to produce - * error messages, this can be overridden by a user - * application to point to a user-specified output function - */ -__BEGIN_DECLS -extern int (*vprintf_stderr_func)(const char *format, va_list ap); -__END_DECLS - -#endif /* _MACH_INIT_ */ diff --git a/mach/headers/mach_interface.h b/mach/headers/mach_interface.h deleted file mode 100644 index 0afa489..0000000 --- a/mach/headers/mach_interface.h +++ /dev/null @@ -1,49 +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@ - */ -/* - * Copyright (C) Apple Computer 1998 - * ALL Rights Reserved - */ -/* - * This file represents the interfaces that used to come - * from creating the user headers from the mach.defs file. - * Because mach.defs was decomposed, this file now just - * wraps up all the new interface headers generated from - * each of the new .defs resulting from that decomposition. - */ -#ifndef _MACH_INTERFACE_H_ -#define _MACH_INTERFACE_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif /* _MACH_INTERFACE_H_ */ diff --git a/mach/headers/port_obj.h b/mach/headers/port_obj.h deleted file mode 100644 index 808abf3..0000000 --- a/mach/headers/port_obj.h +++ /dev/null @@ -1,98 +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@ - */ -/* - * @OSF_COPYRIGHT@ - */ - -/* - * Define a service to map from a kernel-generated port name - * to server-defined "type" and "value" data to be associated - * with the port. - */ - -#ifndef PORT_OBJ_H -#define PORT_OBJ_H - -#include - -struct port_obj_tentry { - void *pos_value; - int pos_type; -}; - -#include - -__BEGIN_DECLS -extern void port_obj_init(int); -__END_DECLS - -extern struct port_obj_tentry *port_obj_table; -extern int port_obj_table_size; - -#ifndef PORT_OBJ_ASSERT - -#define port_set_obj_value_type(pname, value, type) \ -do { \ - int ndx; \ - \ - if (!port_obj_table) \ - port_obj_init(port_obj_table_size); \ - ndx = MACH_PORT_INDEX(pname); \ - port_obj_table[ndx].pos_value = (value); \ - port_obj_table[ndx].pos_type = (type); \ -} while (0) - -#define port_get_obj_value(pname) \ - (port_obj_table[MACH_PORT_INDEX(pname)].pos_value) - -#define port_get_obj_type(pname) \ - (port_obj_table[MACH_PORT_INDEX(pname)].pos_type) - -#else /* PORT_OBJ_ASSERT */ - -#define port_set_obj_value_type(pname, value, type) \ -do { \ - int ndx; \ - \ - if (!port_obj_table) \ - port_obj_init(port_obj_table_size); \ - ndx = MACH_PORT_INDEX(pname); \ - assert(ndx > 0); \ - assert(ndx < port_obj_table_size); \ - port_obj_table[ndx].pos_value = (value); \ - port_obj_table[ndx].pos_type = (type); \ -} while (0) - -#define port_get_obj_value(pname) \ - ((MACH_PORT_INDEX(pname) < (unsigned)port_obj_table_size) ? \ - port_obj_table[MACH_PORT_INDEX(pname)].pos_value : \ - (panic("port_get_obj_value: index too big"), (void *)-1)) - -#define port_get_obj_type(pname) \ - ((MACH_PORT_INDEX(pname) < (unsigned)port_obj_table_size) ? \ - port_obj_table[MACH_PORT_INDEX(pname)].pos_type : \ - (panic("port_get_obj_type: index too big"), -1)) - -#endif /* PORT_OBJ_ASSERT */ - -#endif /* PORT_OBJ_H */ diff --git a/mach/headers/sync.h b/mach/headers/sync.h deleted file mode 100644 index d948763..0000000 --- a/mach/headers/sync.h +++ /dev/null @@ -1,30 +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@ - */ -/* -** This file contains compatibilty wrapper header for things that used -** to be generated from mach/sync.defs. Now that code is split into two -** different interface generator files, so include the two resulting -** headers here. -*/ -#include -#include diff --git a/mach/host_priv.defs b/mach/host_priv.defs deleted file mode 100644 index e24592a..0000000 --- a/mach/host_priv.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/host_security.defs b/mach/host_security.defs deleted file mode 100644 index 5c43238..0000000 --- a/mach/host_security.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/ledger.defs b/mach/ledger.defs deleted file mode 100644 index 841ef8c..0000000 --- a/mach/ledger.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/lock_set.defs b/mach/lock_set.defs deleted file mode 100644 index 9c6693d..0000000 --- a/mach/lock_set.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/mach_error.c b/mach/mach_error.c deleted file mode 100644 index bfd034d..0000000 --- a/mach/mach_error.c +++ /dev/null @@ -1,82 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -/* - * File: mach_error.c - * Author: Douglas Orr, Carnegie Mellon University - * Date: Mar 1988 - * - * interprets structured mach error codes and prints - * or returns a descriptive string. - */ - -#include -#include -#include -#include "errorlib.h" - -int fprintf_stderr(const char *format, ...); - -void -mach_error( str, err ) - char *str; - mach_error_t err; -{ - char * err_str; - char buf[1024]; - boolean_t diag; - - err_str=mach_error_string_int(err, &diag); - - if ( diag ) { - sprintf( buf, "%s %s (%x)", mach_error_type(err), err_str, err ); - err_str = buf; - } - - fprintf_stderr("%s %s\n", str, err_str); -} diff --git a/mach/mach_error_string.c b/mach/mach_error_string.c deleted file mode 100644 index 0975343..0000000 --- a/mach/mach_error_string.c +++ /dev/null @@ -1,135 +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@ - */ -/* - * @OSF_COPYRIGHT@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#include -#include -#include - -#include "errorlib.h" -#include "externs.h" - -static void do_compat(mach_error_t *); - -static void -do_compat(mach_error_t *org_err) -{ - mach_error_t err = *org_err; - - /* - * map old error numbers to - * to new error sys & subsystem - */ - - if ((-200 < err) && (err <= -100)) - err = -(err + 100) | IPC_SEND_MOD; - else if ((-300 < err) && (err <= -200)) - err = -(err + 200) | IPC_RCV_MOD; - else if ((-400 < err) && (err <= -300)) - err = -(err + 300) | MACH_IPC_MIG_MOD; - else if ((1000 <= err) && (err < 1100)) - err = (err - 1000) | SERV_NETNAME_MOD; - else if ((1600 <= err) && (err < 1700)) - err = (err - 1600) | SERV_ENV_MOD; - else if ((27600 <= err) && (err < 27700)) - err = (err - 27600) | SERV_EXECD_MOD; - - *org_err = err; -} - -char * -mach_error_type(mach_error_t err) -{ - int sub, system; - - do_compat( &err ); - - sub = err_get_sub(err); - system = err_get_system(err); - - if (system > err_max_system || sub >= _mach_errors[system].max_sub) - return((char *)"(?/?)"); - return(_mach_errors[system].subsystem[sub].subsys_name); -} - -boolean_t mach_error_full_diag = FALSE; - -__private_extern__ char * -mach_error_string_int(mach_error_t err, boolean_t *diag) -{ - int sub, system, code; - - do_compat( &err ); - - sub = err_get_sub(err); - system = err_get_system(err); - code = err_get_code(err); - - *diag = TRUE; - - if (system > err_max_system) - return((char *)"(?/?) unknown error system"); - if (sub >= _mach_errors[system].max_sub) - return(_mach_errors[system].bad_sub); - if (code >= _mach_errors[system].subsystem[sub].max_code) - return ((char *)NO_SUCH_ERROR); - - *diag = mach_error_full_diag; - return( _mach_errors[system].subsystem[sub].codes[code] ); -} - -char * -mach_error_string(mach_error_t err) -{ - boolean_t diag; - - return mach_error_string_int( err, &diag ); - -} diff --git a/mach/mach_host.defs b/mach/mach_host.defs deleted file mode 100644 index 496ca14..0000000 --- a/mach/mach_host.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/mach_init.c b/mach/mach_init.c deleted file mode 100644 index 8ac6241..0000000 --- a/mach/mach_init.c +++ /dev/null @@ -1,265 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#include -#include -#include -#include -#include -#include -#include "externs.h" - -mach_port_t mach_task_self_ = MACH_PORT_NULL; -mach_port_t mach_host_self_ = MACH_PORT_NULL; - -__private_extern__ kern_return_t _host_mach_msg_trap_return_; - -vm_size_t vm_page_size; -vm_size_t vm_page_mask; -int vm_page_shift; - -/* - * Forward internal declarations for automatic mach_init during - * fork() implementation. - */ -/* fork() calls through atfork_child_routine */ -void (*_atfork_child_routine)(void); - -static void mach_atfork_child_routine(void); -static boolean_t first = TRUE; -static void (*previous_atfork_child_routine)(void); -static boolean_t mach_init_inited = FALSE; -extern int mach_init(void); -extern void _pthread_set_self(void *); -extern void cthread_set_self(void *); -extern void other_libc_init(void); - - -static void mach_atfork_child_routine(void) -{ - /* - * If an (*_atfork_child_routine)() was registered when - * mach_init was first called, then call that routine - * prior to performing our re-initialization. This ensures - * that the post-fork handlers are called in exactly the - * same order as the crt0 (exec) handlers. Any library - * that makes use of the _atfork_child_routine must follow - * the same technique. - */ - if (previous_atfork_child_routine) { - (*previous_atfork_child_routine)(); - } - mach_init_inited = FALSE; - mach_init(); -} - -mach_port_t -mach_host_self() -{ - return(host_self_trap()); -} - -int mach_init_doit(int forkchild) -{ - host_t host; - - /* - * Get the important ports into the cached values, - * as required by "mach_init.h". - */ - - mach_task_self_ = task_self_trap(); - host = host_self_trap(); - - - if (!forkchild) { - /* - * Set up the post-fork child handler in the libc stub - * to invoke this routine if this process forks. Save the - * previous value in order that we can call that handler - * prior to performing our postfork work. - */ - - first = FALSE; - previous_atfork_child_routine = _atfork_child_routine; - _atfork_child_routine = mach_atfork_child_routine; - _pthread_set_self(0); - cthread_set_self(0); - } - - /* - * Initialize the single mig reply port - */ - - mig_init(0); - - /* - * Cache some other valuable system constants - */ - -#if defined(__ppc64__) /* NGK hack for now */ - vm_page_size = 4096; -#else - (void)host_page_size(host, &vm_page_size); -#endif - vm_page_mask = vm_page_size - 1; - if (vm_page_size == 0) { - /* guard against unlikely craziness */ - vm_page_shift = 0; - } else { - /* - * Unfortunately there's no kernel interface to get the - * vm_page_shift, but it's easy enough to calculate. - */ - for (vm_page_shift = 0; - (vm_page_size & (1 << vm_page_shift)) == 0; - vm_page_shift++) - continue; - } - - mach_port_deallocate(mach_task_self_, host); - - mach_init_ports(); - -#if WE_REALLY_NEED_THIS_GDB_HACK - /* - * Check to see if GDB wants us to stop - */ - { - task_user_data_data_t user_data; - mach_msg_type_number_t user_data_count = TASK_USER_DATA_COUNT; - - user_data.user_data = 0; - (void)task_info(mach_task_self_, TASK_USER_DATA, - (task_info_t)&user_data, &user_data_count); -#define MACH_GDB_RUN_MAGIC_NUMBER 1 -#ifdef MACH_GDB_RUN_MAGIC_NUMBER - /* This magic number is set in mach-aware gdb - * for RUN command to allow us to suspend user's - * executable (linked with this libmach!) - * with the code below. - * This hack should disappear when gdb improves. - */ - if ((int)user_data.user_data == MACH_GDB_RUN_MAGIC_NUMBER) { - kern_return_t ret; - user_data.user_data = 0; - - ret = task_suspend (mach_task_self_); - if (ret != KERN_SUCCESS) { - while(1) (void)task_terminate(mach_task_self_); - } - } -#undef MACH_GDB_RUN_MAGIC_NUMBER -#endif /* MACH_GDB_RUN_MAGIC_NUMBER */ - } -#endif /* WE_REALLY_NEED_THIS_GDB_HACK */ - - /* - * Reserve page 0 so that the program doesn't get it as - * the result of a vm_allocate() or whatever. - */ - { - vm_offset_t zero_page_start; - - zero_page_start = 0; - (void)vm_map(mach_task_self_, &zero_page_start, vm_page_size, - 0, FALSE, MEMORY_OBJECT_NULL, 0, TRUE, - VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY); - /* ignore result, we don't care if it failed */ - } - - return(0); -} - -#ifdef __DYNAMIC__ -/* libc_initializer is the dyld initializer for libc (3760827) */ -static void libc_initializer() __attribute__((constructor)); -static void -libc_initializer() -{ - mach_init(); -} -#endif /* __DYNAMIC__ */ - -/* mach_init may get called from the initializer and from crt.c, but only - * call mach_init_doit() once */ -int mach_init(void) -{ - int ret; - - if (mach_init_inited) - return(0); - mach_init_inited = TRUE; - ret = mach_init_doit(0); - - /* Do other Libc initialization */ - other_libc_init(); - - return ret; -} - -int (*mach_init_routine)(void) = mach_init; -int fork_mach_init() -{ - /* called only from child */ - return(mach_init_doit(1)); -} - -#undef mach_task_self - -mach_port_t -mach_task_self() -{ - return(task_self_trap()); -} - -mach_port_t -mach_thread_self() -{ - return(thread_self_trap()); -} diff --git a/mach/mach_init_ports.c b/mach/mach_init_ports.c deleted file mode 100644 index 71e52cb..0000000 --- a/mach/mach_init_ports.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2003-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@ - */ -/* - * @OSF_COPYRIGHT@ - */ - -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#include -#include -#include "externs.h" - -mach_port_t bootstrap_port = MACH_PORT_NULL; -mach_port_t name_server_port = MACH_PORT_NULL; -mach_port_t environment_port = MACH_PORT_NULL; -mach_port_t service_port = MACH_PORT_NULL; -semaphore_t clock_sem = MACH_PORT_NULL; -mach_port_t clock_port = MACH_PORT_NULL; -mach_port_t thread_recycle_port = MACH_PORT_NULL; - -void -mach_init_ports(void) -{ - mach_port_array_t ports; - mach_msg_type_number_t ports_count; - kern_return_t kr; - host_t host; - - /* - * Find those ports important to every task. - */ - kr = task_get_special_port(mach_task_self(), - TASK_BOOTSTRAP_PORT, - &bootstrap_port); - if (kr != KERN_SUCCESS) - return; - - /* Get the clock service port for nanosleep */ - host = mach_host_self(); - 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); - kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &thread_recycle_port); - if (kr != KERN_SUCCESS) { - abort(); - } - - /* - * Find the options service ports. - * XXX - Don't need these on Darwin, should go away. - */ - kr = mach_ports_lookup(mach_task_self(), &ports, - &ports_count); - if (kr == KERN_SUCCESS) { - if (ports_count >= MACH_PORTS_SLOTS_USED) { - name_server_port = ports[NAME_SERVER_SLOT]; - environment_port = ports[ENVIRONMENT_SLOT]; - service_port = ports[SERVICE_SLOT]; - } - - /* get rid of out-of-line data */ - (void) vm_deallocate(mach_task_self(), - (vm_offset_t) ports, - (vm_size_t) (ports_count * sizeof *ports)); - } -} - -#ifdef notdef -/* will have problems with dylib build --> not needed anyway */ -#ifndef lint -/* - * Routines which our library must suck in, to avoid - * a later library from referencing them and getting - * the wrong version. - */ -extern void _replacements(void); - -void -_replacements(void) -{ - (void)sbrk(0); /* Pull in our sbrk/brk */ - (void)malloc(0); /* Pull in our malloc package */ -} -#endif /* lint */ -#endif /* notdef */ diff --git a/mach/mach_msg.c b/mach/mach_msg.c deleted file mode 100644 index 8d5251a..0000000 --- a/mach/mach_msg.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright (c) 1999-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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define MACH_MSG_TRAP(msg, opt, ssize, rsize, rname, to, not) \ - mach_msg_trap((msg), (opt), (ssize), (rsize), (rname), (to), (not)) - -#define LIBMACH_OPTIONS (MACH_SEND_INTERRUPT|MACH_RCV_INTERRUPT) - -/* - * Routine: mach_msg - * Purpose: - * Send and/or receive a message. If the message operation - * is interrupted, and the user did not request an indication - * of that fact, then restart the appropriate parts of the - * operation. - */ -mach_msg_return_t -mach_msg(msg, option, send_size, rcv_size, rcv_name, timeout, notify) - mach_msg_header_t *msg; - mach_msg_option_t option; - mach_msg_size_t send_size; - mach_msg_size_t rcv_size; - mach_port_t rcv_name; - mach_msg_timeout_t timeout; - mach_port_t notify; -{ - mach_msg_return_t mr; - - /* - * Consider the following cases: - * 1) Errors in pseudo-receive (eg, MACH_SEND_INTERRUPTED - * plus special bits). - * 2) Use of MACH_SEND_INTERRUPT/MACH_RCV_INTERRUPT options. - * 3) RPC calls with interruptions in one/both halves. - * - * We refrain from passing the option bits that we implement - * to the kernel. This prevents their presence from inhibiting - * the kernel's fast paths (when it checks the option value). - */ - - mr = MACH_MSG_TRAP(msg, option &~ LIBMACH_OPTIONS, - send_size, rcv_size, rcv_name, - timeout, notify); - if (mr == MACH_MSG_SUCCESS) - return MACH_MSG_SUCCESS; - - if ((option & MACH_SEND_INTERRUPT) == 0) - while (mr == MACH_SEND_INTERRUPTED) - mr = MACH_MSG_TRAP(msg, - option &~ LIBMACH_OPTIONS, - send_size, rcv_size, rcv_name, - timeout, notify); - - if ((option & MACH_RCV_INTERRUPT) == 0) - while (mr == MACH_RCV_INTERRUPTED) - mr = MACH_MSG_TRAP(msg, - option &~ (LIBMACH_OPTIONS|MACH_SEND_MSG), - 0, rcv_size, rcv_name, - timeout, notify); - - return mr; -} - -/* - * Routine: mach_msg_overwrite - * Purpose: - * Send and/or receive a message. If the message operation - * is interrupted, and the user did not request an indication - * of that fact, then restart the appropriate parts of the - * operation. - * - * Distinct send and receive buffers may be specified. If - * no separate receive buffer is specified, the msg parameter - * will be used for both send and receive operations. - * - * In addition to a distinct receive buffer, that buffer may - * already contain scatter control information to direct the - * receiving of the message. - */ -mach_msg_return_t -mach_msg_overwrite(msg, option, send_size, rcv_limit, rcv_name, timeout, - notify, rcv_msg, rcv_scatter_size) - mach_msg_header_t *msg; - mach_msg_option_t option; - mach_msg_size_t send_size; - mach_msg_size_t rcv_limit; - mach_port_t rcv_name; - mach_msg_timeout_t timeout; - mach_port_t notify; - mach_msg_header_t *rcv_msg; - mach_msg_size_t rcv_scatter_size; -{ - mach_msg_return_t mr; - - /* - * Consider the following cases: - * 1) Errors in pseudo-receive (eg, MACH_SEND_INTERRUPTED - * plus special bits). - * 2) Use of MACH_SEND_INTERRUPT/MACH_RCV_INTERRUPT options. - * 3) RPC calls with interruptions in one/both halves. - * - * We refrain from passing the option bits that we implement - * to the kernel. This prevents their presence from inhibiting - * the kernel's fast paths (when it checks the option value). - */ - - mr = mach_msg_overwrite_trap(msg, option &~ LIBMACH_OPTIONS, - send_size, rcv_limit, rcv_name, - timeout, notify, rcv_msg, rcv_scatter_size); - if (mr == MACH_MSG_SUCCESS) - return MACH_MSG_SUCCESS; - - if ((option & MACH_SEND_INTERRUPT) == 0) - while (mr == MACH_SEND_INTERRUPTED) - mr = mach_msg_overwrite_trap(msg, - option &~ LIBMACH_OPTIONS, - send_size, rcv_limit, rcv_name, - timeout, notify, rcv_msg, rcv_scatter_size); - - if ((option & MACH_RCV_INTERRUPT) == 0) - while (mr == MACH_RCV_INTERRUPTED) - mr = mach_msg_overwrite_trap(msg, - option &~ (LIBMACH_OPTIONS|MACH_SEND_MSG), - 0, rcv_limit, rcv_name, - timeout, notify, rcv_msg, rcv_scatter_size); - - return mr; -} - - -mach_msg_return_t -mach_msg_send(mach_msg_header_t *msg) -{ - return mach_msg(msg, MACH_SEND_MSG, - msg->msgh_size, 0, MACH_PORT_NULL, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); -} - -mach_msg_return_t -mach_msg_receive(mach_msg_header_t *msg) -{ - return mach_msg(msg, MACH_RCV_MSG, - 0, msg->msgh_size, msg->msgh_local_port, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); -} - - -static void -mach_msg_destroy_port(mach_port_t port, mach_msg_type_name_t type) -{ - if (MACH_PORT_VALID(port)) switch (type) { - case MACH_MSG_TYPE_MOVE_SEND: - case MACH_MSG_TYPE_MOVE_SEND_ONCE: - /* destroy the send/send-once right */ - (void) mach_port_deallocate(mach_task_self(), port); - break; - - case MACH_MSG_TYPE_MOVE_RECEIVE: - /* destroy the receive right */ - (void) mach_port_mod_refs(mach_task_self(), port, - MACH_PORT_RIGHT_RECEIVE, -1); - break; - - case MACH_MSG_TYPE_MAKE_SEND: - /* create a send right and then destroy it */ - (void) mach_port_insert_right(mach_task_self(), port, - port, MACH_MSG_TYPE_MAKE_SEND); - (void) mach_port_deallocate(mach_task_self(), port); - break; - - case MACH_MSG_TYPE_MAKE_SEND_ONCE: - /* create a send-once right and then destroy it */ - (void) mach_port_extract_right(mach_task_self(), port, - MACH_MSG_TYPE_MAKE_SEND_ONCE, - &port, &type); - (void) mach_port_deallocate(mach_task_self(), port); - break; - } -} - -static void -mach_msg_destroy_memory(vm_offset_t addr, vm_size_t size) -{ - if (size != 0) - (void) vm_deallocate(mach_task_self(), addr, size); -} - - -/* - * Routine: mach_msg_destroy - * Purpose: - * mach_msg_destroy is useful in two contexts. - * - * First, it can deallocate all port rights and - * out-of-line memory in a received message. - * When a server receives a request it doesn't want, - * it needs this functionality. - * - * Second, it can mimic the side-effects of a msg-send - * operation. The effect is as if the message were sent - * and then destroyed inside the kernel. When a server - * can't send a reply (because the client died), - * it needs this functionality. - */ -void -mach_msg_destroy(mach_msg_header_t *msg) -{ - mach_msg_bits_t mbits = msg->msgh_bits; - - /* - * The msgh_local_port field doesn't hold a port right. - * The receive operation consumes the destination port right. - */ - - mach_msg_destroy_port(msg->msgh_remote_port, MACH_MSGH_BITS_REMOTE(mbits)); - - if (mbits & MACH_MSGH_BITS_COMPLEX) { - mach_msg_body_t *body; - mach_msg_descriptor_t *saddr, *eaddr; - - body = (mach_msg_body_t *) (msg + 1); - saddr = (mach_msg_descriptor_t *) - ((mach_msg_base_t *) msg + 1); - eaddr = saddr + body->msgh_descriptor_count; - - for ( ; saddr < eaddr; saddr++) { - switch (saddr->type.type) { - - case MACH_MSG_PORT_DESCRIPTOR: { - mach_msg_port_descriptor_t *dsc; - - /* - * Destroy port rights carried in the message - */ - dsc = &saddr->port; - mach_msg_destroy_port(dsc->name, dsc->disposition); - break; - } - - case MACH_MSG_OOL_DESCRIPTOR : { - mach_msg_ool_descriptor_t *dsc; - - /* - * Destroy memory carried in the message - */ - dsc = &saddr->out_of_line; - if (dsc->deallocate) { - mach_msg_destroy_memory((vm_offset_t)dsc->address, - dsc->size); - } - break; - } - - case MACH_MSG_OOL_PORTS_DESCRIPTOR : { - mach_port_t *ports; - mach_msg_ool_ports_descriptor_t *dsc; - mach_msg_type_number_t j; - - /* - * Destroy port rights carried in the message - */ - dsc = &saddr->ool_ports; - ports = (mach_port_t *) dsc->address; - for (j = 0; j < dsc->count; j++, ports++) { - mach_msg_destroy_port(*ports, dsc->disposition); - } - - /* - * Destroy memory carried in the message - */ - if (dsc->deallocate) { - mach_msg_destroy_memory((vm_offset_t)dsc->address, - dsc->count * sizeof(mach_port_t)); - } - break; - } - } - } - } -} - -/* - * Routine: mach_msg_server_once - * Purpose: - * A simple generic server function. It allows more flexibility - * than mach_msg_server by processing only one message request - * and then returning to the user. Note that more in the way - * of error codes are returned to the user; specifically, any - * failing error from mach_msg calls will be returned - * (though errors from the demux routine or the routine it - * calls will not be). - */ -mach_msg_return_t -mach_msg_server_once( - boolean_t (*demux)(mach_msg_header_t *, mach_msg_header_t *), - mach_msg_size_t max_size, - mach_port_t rcv_name, - mach_msg_options_t options) -{ - mig_reply_error_t *bufRequest, *bufReply; - mach_msg_size_t request_size; - mach_msg_size_t request_alloc; - mach_msg_size_t trailer_alloc; - mach_msg_size_t reply_alloc; - mach_msg_return_t mr; - kern_return_t kr; - mach_port_t self = mach_task_self(); - - options &= ~(MACH_SEND_MSG|MACH_RCV_MSG); - - trailer_alloc = REQUESTED_TRAILER_SIZE(options); - request_alloc = round_page(max_size + trailer_alloc); - - request_size = (options & MACH_RCV_LARGE) ? - request_alloc : max_size + trailer_alloc; - - reply_alloc = round_page((options & MACH_SEND_TRAILER) ? - (max_size + MAX_TRAILER_SIZE) : - max_size); - - kr = vm_allocate(self, - (vm_address_t *)&bufReply, - reply_alloc, - VM_MAKE_TAG(VM_MEMORY_MACH_MSG)|TRUE); - if (kr != KERN_SUCCESS) - return kr; - - for (;;) { - mach_msg_size_t new_request_alloc; - - kr = vm_allocate(self, - (vm_address_t *)&bufRequest, - request_alloc, - VM_MAKE_TAG(VM_MEMORY_MACH_MSG)|TRUE); - if (kr != KERN_SUCCESS) { - vm_deallocate(self, - (vm_address_t)bufReply, - reply_alloc); - return kr; - } - - mr = mach_msg(&bufRequest->Head, MACH_RCV_MSG|options, - 0, request_size, rcv_name, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - if (!((mr == MACH_RCV_TOO_LARGE) && (options & MACH_RCV_LARGE))) - break; - - new_request_alloc = round_page(bufRequest->Head.msgh_size + - trailer_alloc); - vm_deallocate(self, - (vm_address_t) bufRequest, - request_alloc); - request_size = request_alloc = new_request_alloc; - } - - if (mr == MACH_MSG_SUCCESS) { - /* we have a request message */ - - (void) (*demux)(&bufRequest->Head, &bufReply->Head); - - if (!(bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) { - if (bufReply->RetCode == MIG_NO_REPLY) - bufReply->Head.msgh_remote_port = MACH_PORT_NULL; - else if ((bufReply->RetCode != KERN_SUCCESS) && - (bufRequest->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) { - /* destroy the request - but not the reply port */ - bufRequest->Head.msgh_remote_port = MACH_PORT_NULL; - mach_msg_destroy(&bufRequest->Head); - } - } - - /* - * We don't want to block indefinitely because the client - * isn't receiving messages from the reply port. - * If we have a send-once right for the reply port, then - * this isn't a concern because the send won't block. - * If we have a send right, we need to use MACH_SEND_TIMEOUT. - * To avoid falling off the kernel's fast RPC path unnecessarily, - * we only supply MACH_SEND_TIMEOUT when absolutely necessary. - */ - if (bufReply->Head.msgh_remote_port != MACH_PORT_NULL) { - - mr = mach_msg(&bufReply->Head, - (MACH_MSGH_BITS_REMOTE(bufReply->Head.msgh_bits) == - MACH_MSG_TYPE_MOVE_SEND_ONCE) ? - MACH_SEND_MSG|options : - MACH_SEND_MSG|MACH_SEND_TIMEOUT|options, - bufReply->Head.msgh_size, 0, MACH_PORT_NULL, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - if ((mr != MACH_SEND_INVALID_DEST) && - (mr != MACH_SEND_TIMED_OUT)) - goto done_once; - mr = MACH_MSG_SUCCESS; - } - if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) - mach_msg_destroy(&bufReply->Head); - } - - done_once: - (void)vm_deallocate(self, - (vm_address_t) bufRequest, - request_alloc); - (void)vm_deallocate(self, - (vm_address_t) bufReply, - reply_alloc); - return mr; -} - -/* - * Routine: mach_msg_server - * Purpose: - * A simple generic server function. Note that changes here - * should be considered for duplication above. - */ -mach_msg_return_t -mach_msg_server( - boolean_t (*demux)(mach_msg_header_t *, mach_msg_header_t *), - mach_msg_size_t max_size, - mach_port_t rcv_name, - mach_msg_options_t options) -{ - mig_reply_error_t *bufRequest, *bufReply; - mach_msg_size_t request_size; - mach_msg_size_t new_request_alloc; - mach_msg_size_t request_alloc; - mach_msg_size_t trailer_alloc; - mach_msg_size_t reply_alloc; - mach_msg_return_t mr; - kern_return_t kr; - mach_port_t self = mach_task_self(); - - options &= ~(MACH_SEND_MSG|MACH_RCV_MSG|MACH_RCV_OVERWRITE); - - reply_alloc = round_page((options & MACH_SEND_TRAILER) ? - (max_size + MAX_TRAILER_SIZE) : max_size); - - kr = vm_allocate(self, - (vm_address_t *)&bufReply, - reply_alloc, - VM_MAKE_TAG(VM_MEMORY_MACH_MSG)|TRUE); - if (kr != KERN_SUCCESS) - return kr; - - request_alloc = 0; - trailer_alloc = REQUESTED_TRAILER_SIZE(options); - new_request_alloc = round_page(max_size + trailer_alloc); - - request_size = (options & MACH_RCV_LARGE) ? - new_request_alloc : max_size + trailer_alloc; - - for (;;) { - if (request_alloc < new_request_alloc) { - request_alloc = new_request_alloc; - kr = vm_allocate(self, - (vm_address_t *)&bufRequest, - request_alloc, - VM_MAKE_TAG(VM_MEMORY_MACH_MSG)|TRUE); - if (kr != KERN_SUCCESS) { - vm_deallocate(self, - (vm_address_t)bufReply, - reply_alloc); - return kr; - } - } - - mr = mach_msg(&bufRequest->Head, MACH_RCV_MSG|options, - 0, request_size, rcv_name, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - while (mr == MACH_MSG_SUCCESS) { - /* we have another request message */ - - (void) (*demux)(&bufRequest->Head, &bufReply->Head); - - if (!(bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) { - if (bufReply->RetCode == MIG_NO_REPLY) - bufReply->Head.msgh_remote_port = MACH_PORT_NULL; - else if ((bufReply->RetCode != KERN_SUCCESS) && - (bufRequest->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) { - /* destroy the request - but not the reply port */ - bufRequest->Head.msgh_remote_port = MACH_PORT_NULL; - mach_msg_destroy(&bufRequest->Head); - } - } - - /* - * We don't want to block indefinitely because the client - * isn't receiving messages from the reply port. - * If we have a send-once right for the reply port, then - * this isn't a concern because the send won't block. - * If we have a send right, we need to use MACH_SEND_TIMEOUT. - * To avoid falling off the kernel's fast RPC path, - * we only supply MACH_SEND_TIMEOUT when absolutely necessary. - */ - if (bufReply->Head.msgh_remote_port != MACH_PORT_NULL) { - if (request_alloc == reply_alloc) { - mig_reply_error_t *bufTemp; - - mr = mach_msg( - &bufReply->Head, - (MACH_MSGH_BITS_REMOTE(bufReply->Head.msgh_bits) == - MACH_MSG_TYPE_MOVE_SEND_ONCE) ? - MACH_SEND_MSG|MACH_RCV_MSG|options : - MACH_SEND_MSG|MACH_RCV_MSG|MACH_SEND_TIMEOUT|options, - bufReply->Head.msgh_size, request_size, rcv_name, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - /* swap request and reply */ - bufTemp = bufRequest; - bufRequest = bufReply; - bufReply = bufTemp; - - } else { - mr = mach_msg_overwrite( - &bufReply->Head, - (MACH_MSGH_BITS_REMOTE(bufReply->Head.msgh_bits) == - MACH_MSG_TYPE_MOVE_SEND_ONCE) ? - MACH_SEND_MSG|MACH_RCV_MSG|options : - MACH_SEND_MSG|MACH_RCV_MSG|MACH_SEND_TIMEOUT|options, - bufReply->Head.msgh_size, request_size, rcv_name, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, - &bufRequest->Head, 0); - } - - if ((mr != MACH_SEND_INVALID_DEST) && - (mr != MACH_SEND_TIMED_OUT)) - continue; - } - if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) - mach_msg_destroy(&bufReply->Head); - - mr = mach_msg(&bufRequest->Head, MACH_RCV_MSG|options, - 0, request_size, rcv_name, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - } /* while (mr == MACH_MSG_SUCCESS) */ - - if ((mr == MACH_RCV_TOO_LARGE) && (options & MACH_RCV_LARGE)) { - new_request_alloc = round_page(bufRequest->Head.msgh_size + - trailer_alloc); - request_size = new_request_alloc; - vm_deallocate(self, - (vm_address_t) bufRequest, - request_alloc); - continue; - } - - break; - - } /* for(;;) */ - - (void)vm_deallocate(self, - (vm_address_t) bufRequest, - request_alloc); - (void)vm_deallocate(self, - (vm_address_t) bufReply, - reply_alloc); - return mr; -} diff --git a/mach/mach_port.defs b/mach/mach_port.defs deleted file mode 100644 index 11b50b8..0000000 --- a/mach/mach_port.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/mach_traps.s b/mach/mach_traps.s deleted file mode 100644 index 9071976..0000000 --- a/mach/mach_traps.s +++ /dev/null @@ -1,49 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987,1986 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#include diff --git a/mach/mig_allocate.c b/mach/mig_allocate.c deleted file mode 100644 index 6bda3b3..0000000 --- a/mach/mig_allocate.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 1999-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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -/* - * Memory allocation routine for MiG interfaces. - */ -#include - -void -mig_allocate(vm_address_t *addr_p, vm_size_t size) -{ - if (vm_allocate(mach_task_self(), - addr_p, - size, - VM_MAKE_TAG(VM_MEMORY_MACH_MSG)|TRUE) - != KERN_SUCCESS) - *addr_p = 0; -} diff --git a/mach/mig_deallocate.c b/mach/mig_deallocate.c deleted file mode 100644 index 124cebe..0000000 --- a/mach/mig_deallocate.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1999-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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -/* - * Memory deallocation routine for MiG interfaces. - */ -#include - -void -mig_deallocate(vm_address_t addr, vm_size_t size) -{ - (void) vm_deallocate(mach_task_self(), - addr, - size); -} diff --git a/mach/mig_reply_setup.c b/mach/mig_reply_setup.c deleted file mode 100644 index fd961a8..0000000 --- a/mach/mig_reply_setup.c +++ /dev/null @@ -1,76 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -/* - * Routine to set up a MiG reply message from a request message. - * - * Knows about the MiG reply message ID convention: - * reply_id = request_id + 100 - * - * For typed IPC sets up the RetCode type field. Does NOT set a - * return code value. - */ - -#include -#include -#include - -void -mig_reply_setup(mach_msg_header_t *request, mach_msg_header_t *reply) -{ -#define InP (request) -#define OutP ((mig_reply_error_t *) reply) - - OutP->Head.msgh_bits = - MACH_MSGH_BITS(MACH_MSGH_BITS_LOCAL(InP->msgh_bits), 0); - OutP->Head.msgh_size = sizeof(mig_reply_error_t); - OutP->Head.msgh_remote_port = InP->msgh_local_port; - OutP->Head.msgh_local_port = MACH_PORT_NULL; - OutP->Head.msgh_id = InP->msgh_id + 100; - OutP->NDR = NDR_record; -} diff --git a/mach/mig_strncpy.c b/mach/mig_strncpy.c deleted file mode 100644 index 44e0536..0000000 --- a/mach/mig_strncpy.c +++ /dev/null @@ -1,86 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * mig_strncpy.c - by Joshua Block - * - * mig_strncpy -- Bounded string copy. Does what the library routine strncpy - * OUGHT to do: Copies the (null terminated) string in src into dest, a - * buffer of length len. Assures that the copy is still null terminated - * and doesn't overflow the buffer, truncating the copy if necessary. - * - * Parameters: - * - * dest - Pointer to destination buffer. - * - * src - Pointer to source string. - * - * len - Length of destination buffer. - * - * Result: - * length of string copied, INCLUDING the trailing 0. - */ -#include - -int -mig_strncpy( - register char *dest, - register const char *src, - register int len) -{ - register int i; - - if (len <= 0) - return 0; - - for (i=1; i -#include -#include -#include -#include - -extern kern_return_t syscall_thread_switch(mach_port_name_t, int, mach_msg_timeout_t); // From pthread_internals.h - -kern_return_t -thread_switch( - mach_port_t thread, - int option, - mach_msg_timeout_t option_time) -{ - kern_return_t result; - - result = syscall_thread_switch(thread, option, option_time); - return (result); -} diff --git a/mach/notify.defs b/mach/notify.defs deleted file mode 100644 index 8821011..0000000 --- a/mach/notify.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/panic.c b/mach/panic.c deleted file mode 100644 index 363739f..0000000 --- a/mach/panic.c +++ /dev/null @@ -1,83 +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@ - */ -/* - * @OSF_COPYRIGHT@ - */ - -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#include -#include -#include -#include - -static mach_port_t master_host_port; - -void -panic_init(mach_port_t port) -{ - master_host_port = port; -} - -/*VARARGS1*/ -void -panic(const char *s, ...) -{ - va_list listp; - - printf("panic: "); - va_start(listp, s); - vprintf(s, listp); - va_end(listp); - printf("\n"); - -#define RB_DEBUGGER 0x1000 /* enter debugger NOW */ - (void) host_reboot(master_host_port, RB_DEBUGGER); - - /* 4279008 - don't return */ - abort(); -} diff --git a/mach/processor.defs b/mach/processor.defs deleted file mode 100644 index c3a96ed..0000000 --- a/mach/processor.defs +++ /dev/null @@ -1,23 +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@ - */ -#include diff --git a/mach/processor_set.defs b/mach/processor_set.defs deleted file mode 100644 index 2b9c480..0000000 --- a/mach/processor_set.defs +++ /dev/null @@ -1,23 +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@ - */ -#include \ No newline at end of file diff --git a/mach/sbrk.c b/mach/sbrk.c deleted file mode 100644 index e1d554d..0000000 --- a/mach/sbrk.c +++ /dev/null @@ -1,73 +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@ - */ -/* - * File: sbrk.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 - -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(size) - 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) - return((void *)-1); - } - - if (size <= 0) - return((void *)sbrk_curbrk); - else if (size > sbrk_region_size) - return((void *)-1); - sbrk_curbrk += size; - sbrk_region_size -= size; - return((void *)(sbrk_curbrk - size)); -} - -void *brk(x) - void *x; -{ - return((void *)-1); -} - diff --git a/mach/semaphore.c b/mach/semaphore.c deleted file mode 100644 index 988c618..0000000 --- a/mach/semaphore.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2000 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 -#include -#include - -kern_return_t semaphore_signal( - mach_port_t signal_semaphore) -{ - return semaphore_signal_trap(signal_semaphore); -} - -kern_return_t semaphore_signal_all( - mach_port_t signal_semaphore) -{ - return semaphore_signal_all_trap(signal_semaphore); -} - -kern_return_t semaphore_signal_thread( - mach_port_t signal_semaphore, - mach_port_t thread_act) -{ - return semaphore_signal_thread_trap(signal_semaphore, thread_act); -} - -kern_return_t semaphore_wait ( - mach_port_t wait_semaphore) -{ - return semaphore_wait_trap(wait_semaphore); -} - -kern_return_t semaphore_timedwait ( - mach_port_t wait_semaphore, - mach_timespec_t wait_time) -{ - return semaphore_timedwait_trap(wait_semaphore, - wait_time.tv_sec, - wait_time.tv_nsec); -} - -kern_return_t semaphore_wait_signal ( - mach_port_t wait_semaphore, - mach_port_t signal_semaphore) -{ - return semaphore_wait_signal_trap(wait_semaphore, signal_semaphore); -} - -kern_return_t semaphore_timedwait_signal ( - mach_port_t wait_semaphore, - mach_port_t signal_semaphore, - mach_timespec_t wait_time) -{ - return semaphore_timedwait_signal_trap(wait_semaphore, - signal_semaphore, - wait_time.tv_sec, - wait_time.tv_nsec); -} diff --git a/mach/servers/Makefile.inc b/mach/servers/Makefile.inc deleted file mode 100644 index a48455f..0000000 --- a/mach/servers/Makefile.inc +++ /dev/null @@ -1,16 +0,0 @@ -.PATH: ${.CURDIR}/${MACHINE_ARCH}/mach/servers ${.CURDIR}/mach/servers - -SRVMIGDEFS += srvbootstrap.defs netname.defs - -SRVMIGHDRS = ${SRVMIGDEFS:S/.defs$/.h/} -#SRVMIGHDRS = ${SRVMIGDEFS:S/.defs$/.h/:S/^/${.CURDIR}\/mach\/servers\//} -SRVMIGSRCS = ${SRVMIGDEFS:S/.defs$/User.c/} - -SRVHDRS = bootstrap_defs.h netname_defs.h key_defs.h nm_defs.h ls_defs.h -SRVHDRS := ${SRVHDRS:S/^/${.CURDIR}\/mach\/servers\//} -SRVHDRS += ${SRVMIGHDRS} - -MISRCS+= ${SRVMIGDEFS:S/.defs$/User.defs/} - -CLEANFILES += ${SRVMIGHDRS} ${SRVMIGHDRS:S/.h$/User.c/} \ - ${SRVMIGHDRS:S/.h$/Server.c/} diff --git a/mach/servers/bootstrap_defs.h b/mach/servers/bootstrap_defs.h deleted file mode 100644 index 3d7ffe4..0000000 --- a/mach/servers/bootstrap_defs.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1999-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@ - */ -/* - * bootstrap -- fundamental service initiator and port server - * Mike DeMoney, NeXT, Inc. - * Copyright, 1990. All rights reserved. - * - * bootstrap_defs.h -- bootstrap service data types and constants - * See bootstrap.defs for description of bootstrap services. - */ - -#ifndef _BOOTSTRAP_DEFS_ -#define _BOOTSTRAP_DEFS_ -#import - -#define BOOTSTRAP_MAX_NAME_LEN 128 -#define BOOTSTRAP_MAX_CMD_LEN 512 - -typedef char name_t[BOOTSTRAP_MAX_NAME_LEN]; -typedef char cmd_t[BOOTSTRAP_MAX_CMD_LEN]; -typedef name_t *name_array_t; -typedef int bootstrap_status_t; -typedef bootstrap_status_t *bootstrap_status_array_t; - -typedef boolean_t *bool_array_t; - -#define BOOTSTRAP_MAX_LOOKUP_COUNT 20 - -#define BOOTSTRAP_SUCCESS 0 -#define BOOTSTRAP_NOT_PRIVILEGED 1100 -#define BOOTSTRAP_NAME_IN_USE 1101 -#define BOOTSTRAP_UNKNOWN_SERVICE 1102 -#define BOOTSTRAP_SERVICE_ACTIVE 1103 -#define BOOTSTRAP_BAD_COUNT 1104 -#define BOOTSTRAP_NO_MEMORY 1105 - -#define BOOTSTRAP_STATUS_INACTIVE 0 -#define BOOTSTRAP_STATUS_ACTIVE 1 -#define BOOTSTRAP_STATUS_ON_DEMAND 2 - -#endif /* _BOOTSTRAP_DEFS_ */ diff --git a/mach/servers/key_defs.h b/mach/servers/key_defs.h deleted file mode 100644 index 074d4ee..0000000 --- a/mach/servers/key_defs.h +++ /dev/null @@ -1,103 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1987 Carnegie-Mellon University - * All rights reserved. The CMU software License Agreement specifies - * the terms and conditions for use and redistribution. - */ - -/* - * Definitions of encryption keys etc.. - */ - -/* - * HISTORY: - * 5-Jun-87 Robert Sansom (rds) at Carnegie Mellon University - * Added macros to convert keys between network and host order. - * - * 12-Apr-87 Robert Sansom (rds) at Carnegie Mellon University - * Added KEY_IS_NULL. - * - * 2-Feb-87 Robert Sansom (rds) at Carnegie Mellon University - * Added KEY_EQUAL. - * - * 5-Nov-86 Robert Sansom (rds) at Carnegie-Mellon University - * Started. - * - */ - -#ifndef _KEY_DEFS_ -#define _KEY_DEFS_ - -/* - * An encrytion key. - */ -typedef union { - unsigned char key_bytes[16]; - unsigned long key_longs[4]; -} key_t, *key_ptr_t; - -#define KEY_EQUAL(key1, key2) \ - ((key1.key_longs[0] == key2.key_longs[0]) \ - && (key1.key_longs[1] == key2.key_longs[1]) \ - && (key1.key_longs[2] == key2.key_longs[2]) \ - && (key1.key_longs[3] == key2.key_longs[3])) - -#define KEY_IS_NULL(key) \ - (((key).key_longs[0] == 0) && ((key).key_longs[1] == 0) \ - && ((key).key_longs[2] == 0) && ((key).key_longs[3] == 0)) - - -/* - * Macros to convert keys between network and host byte order. - */ -#define NTOH_KEY(key) { \ - (key).key_longs[0] = ntohl((key).key_longs[0]); \ - (key).key_longs[1] = ntohl((key).key_longs[1]); \ - (key).key_longs[2] = ntohl((key).key_longs[2]); \ - (key).key_longs[3] = ntohl((key).key_longs[3]); \ -} - -#define HTON_KEY(key) { \ - (key).key_longs[0] = htonl((key).key_longs[0]); \ - (key).key_longs[1] = htonl((key).key_longs[1]); \ - (key).key_longs[2] = htonl((key).key_longs[2]); \ - (key).key_longs[3] = htonl((key).key_longs[3]); \ -} - -/* - * Structure used to transmit or store a token or a key. - */ -typedef union { - key_t si_key; - key_t si_token; -} secure_info_t, *secure_info_ptr_t; - -/* - * Security Level of ports and messages. - */ -#define PORT_NOT_SECURE 0 -#define MESSAGE_NOT_SECURE 0 - -#endif /* _KEY_DEFS_ */ diff --git a/mach/servers/ls_defs.h b/mach/servers/ls_defs.h deleted file mode 100644 index 64dc4f6..0000000 --- a/mach/servers/ls_defs.h +++ /dev/null @@ -1,233 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1989 Carnegie-Mellon University - * Copyright (c) 1988 Carnegie-Mellon University - * Copyright (c) 1987 Carnegie-Mellon University - * All rights reserved. The CMU software License Agreement specifies - * the terms and conditions for use and redistribution. - */ - -/* - * Definitions for the logstat module. - */ - - -#ifndef _LS_DEFS_ -#define _LS_DEFS_ - -#include - -/* - * Definition for a log record. - */ -typedef struct { - long code; - long thread; - long a1; - long a2; - long a3; - long a4; - long a5; - long a6; -} log_rec_t; - -typedef log_rec_t *log_ptr_t; - -/* - * Statistics record. - */ -typedef struct { - int datagram_pkts_sent; - int datagram_pkts_rcvd; - int srr_requests_sent; - int srr_bcasts_sent; - int srr_requests_rcvd; - int srr_bcasts_rcvd; - int srr_replies_sent; - int srr_replies_rcvd; - int srr_retries_sent; - int srr_retries_rcvd; - int srr_cfailures_sent; - int srr_cfailures_rcvd; - int deltat_dpkts_sent; - int deltat_acks_rcvd; - int deltat_dpkts_rcvd; - int deltat_acks_sent; - int deltat_oldpkts_rcvd; - int deltat_oospkts_rcvd; - int deltat_retries_sent; - int deltat_retries_rcvd; - int deltat_cfailures_sent; - int deltat_cfailures_rcvd; - int deltat_aborts_sent; - int deltat_aborts_rcvd; - int vmtp_requests_sent; - int vmtp_requests_rcvd; - int vmtp_replies_sent; - int vmtp_replies_rcvd; - int ipc_in_messages; - int ipc_out_messages; - int ipc_unblocks_sent; - int ipc_unblocks_rcvd; - int pc_requests_sent; - int pc_requests_rcvd; - int pc_replies_rcvd; - int pc_startups_rcvd; - int nn_requests_sent; - int nn_requests_rcvd; - int nn_replies_rcvd; - int po_ro_hints_sent; - int po_ro_hints_rcvd; - int po_token_requests_sent; - int po_token_requests_rcvd; - int po_token_replies_rcvd; - int po_xfer_requests_sent; - int po_xfer_requests_rcvd; - int po_xfer_replies_rcvd; - int po_deaths_sent; - int po_deaths_rcvd; - int ps_requests_sent; - int ps_requests_rcvd; - int ps_replies_rcvd; - int ps_auth_requests_sent; - int ps_auth_requests_rcvd; - int ps_auth_replies_rcvd; - int mallocs_or_vm_allocates; - int mem_allocs; - int mem_deallocs; - int mem_allocobjs; - int mem_deallocobjs; - int pkts_encrypted; - int pkts_decrypted; - int vmtp_segs_encrypted; - int vmtp_segs_decrypted; - int tcp_requests_sent; - int tcp_replies_sent; - int tcp_requests_rcvd; - int tcp_replies_rcvd; - int tcp_send; - int tcp_recv; - int tcp_connect; - int tcp_accept; - int tcp_close; -} stat_t; - -typedef stat_t *stat_ptr_t; - - -/* - * Debugging flags record. - */ -typedef struct { - int print_level; - int ipc_in; - int ipc_out; - int tracing; - int vmtp; - int netname; - int deltat; - int tcp; - int mem; -} debug_t; - -typedef debug_t *debug_ptr_t; - - -/* - * Parameters record. - */ -typedef struct { - int srr_max_tries; - int srr_retry_sec; - int srr_retry_usec; - int deltat_max_tries; - int deltat_retry_sec; - int deltat_retry_usec; - int deltat_msg_life; - int pc_checkup_interval; - int crypt_algorithm; - int transport_default; - int conf_network; - int conf_netport; - int timer_quantum; - int tcp_conn_steady; - int tcp_conn_opening; - int tcp_conn_max; - int compat; - int syslog; - int old_nmmonitor; -} param_t; - -typedef param_t *param_ptr_t; - - -/* - * Port statistics record. - */ -typedef struct { - u_int port_id; - u_int alive; - u_int nport_id_high; - u_int nport_id_low; - u_int nport_receiver; - u_int nport_owner; - u_int messages_sent; - u_int messages_rcvd; - u_int send_rights_sent; - u_int send_rights_rcvd_sender; - u_int send_rights_rcvd_recown; - u_int rcv_rights_xferd; - u_int own_rights_xferd; - u_int all_rights_xferd; - u_int tokens_sent; - u_int tokens_requested; - u_int xfer_hints_sent; - u_int xfer_hints_rcvd; -} port_stat_t, *port_stat_ptr_t; - -extern port_stat_ptr_t port_stat_cur; -extern port_stat_ptr_t port_stat_end; -extern struct mutex port_stat_lock; - - -/* - * Types for the mem_list operation. - * - * XXX These must be faked, because we cannot include mem.h here - * (mutual includes). - */ -typedef char *mem_class_ptr_t; -typedef char *mem_nam_ptr_t; -typedef int *mem_bucket_ptr_t; - - -/* - * Definitions for print_level. - */ -#define LS_PRINT_NEVER 5 -#define LS_PRINT_LOG 3 -#define LS_PRINT_ALWAYS 0 - -#endif /* _LS_DEFS_ */ diff --git a/mach/servers/netname.defs b/mach/servers/netname.defs deleted file mode 100644 index 7a25618..0000000 --- a/mach/servers/netname.defs +++ /dev/null @@ -1,71 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1987 Carnegie-Mellon University - * All rights reserved. The CMU software License Agreement specifies - * the terms and conditions for use and redistribution. - */ - -/* - * Mig definitions for Network Name Service. - */ - -/* - * HISTORY: - * 30-May-87 Robert Sansom (rds) at Carnegie Mellon University - * Changes for the new mig. - * - * 20-Oct-86 Robert Sansom (rds) at Carnegie Mellon University - * New network name service interface. - * Added a serverprefix. - */ - -#include - -import ; - -subsystem netname 1040; - -serverprefix _; - - -type netname_name_t = c_string[*:80]; - -routine netname_check_in(server_port : mach_port_t; - port_name : netname_name_t; - signature : mach_port_t; - port_id : mach_port_t); - -routine netname_look_up(server_port : mach_port_t; - host_name : netname_name_t; - port_name : netname_name_t; - out port_id : mach_port_t); - -routine netname_check_out(server_port : mach_port_t; - port_name : netname_name_t; - signature : mach_port_t); - -routine netname_version(server_port : mach_port_t; - out version : netname_name_t); - diff --git a/mach/servers/netname_defs.h b/mach/servers/netname_defs.h deleted file mode 100644 index 3180b71..0000000 --- a/mach/servers/netname_defs.h +++ /dev/null @@ -1,66 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1987 Carnegie-Mellon University - * All rights reserved. The CMU software License Agreement specifies - * the terms and conditions for use and redistribution. - */ - -/* - * Definitions for the mig interface to the network name service. - */ - -/* - * HISTORY: - * 28-Jul-88 Mary R. Thompson (mrt) at Carnegie Mellon - * Copied definitions of NAME_NOT_YOURS and NAME_NOT_CHECKED_IN - * from the old netname_defs.h so that old code would not break - * - * 8-Mar-88 Daniel Julin (dpj) at Carnegie-Mellon University - * Added NETNAME_INVALID_PORT. - * - * 28-Feb-88 Daniel Julin (dpj) at Carnegie-Mellon University - * Added NETNAME_PENDING. - * - * 23-Dec-86 Robert Sansom (rds) at Carnegie Mellon University - * Copied from the previous version of the network server. - * - */ - -#ifndef _NETNAME_DEFS_ -#define _NETNAME_DEFS_ - -#define NETNAME_SUCCESS (0) -#define NETNAME_PENDING (-1) -#define NETNAME_NOT_YOURS (1000) -#define NAME_NOT_YOURS (1000) -#define NETNAME_NOT_CHECKED_IN (1001) -#define NAME_NOT_CHECKED_IN (1001) -#define NETNAME_NO_SUCH_HOST (1002) -#define NETNAME_HOST_NOT_FOUND (1003) -#define NETNAME_INVALID_PORT (1004) - -typedef char netname_name_t[80]; - -#endif /* NETNAME_DEFS_ */ diff --git a/mach/servers/nm_defs.h b/mach/servers/nm_defs.h deleted file mode 100644 index 96a513c..0000000 --- a/mach/servers/nm_defs.h +++ /dev/null @@ -1,79 +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@ - */ -/* - * Mach Operating System - * Copyright (c) 1987 Carnegie-Mellon University - * All rights reserved. The CMU software License Agreement specifies - * the terms and conditions for use and redistribution. - */ - -/* - * Random definitions for the network service that everyone needs! - */ - -/* - * HISTORY: - * 27-Mar-90 Gregg Kellogg (gk) at NeXT - * include rather than - * - * 24-Aug-88 Daniel Julin (dpj) at Carnegie-Mellon University - * Replace sys/mach_ipc_netport.h with kern/ipc_netport.h. Sigh. - * - * 24-May-88 Daniel Julin (dpj) at Carnegie-Mellon University - * Replace mach_ipc_vmtp.h with mach_ipc_netport.h. - * - * 4-Sep-87 Daniel Julin (dpj) at Carnegie-Mellon University - * Fixed for new kernel include files which declare a lot - * of network server stuff internally, because of the NETPORT - * option. - * - * 5-Nov-86 Robert Sansom (rds) at Carnegie-Mellon University - * Started. - * - */ - -#ifndef _NM_DEFS_ -#define _NM_DEFS_ - -/* - * netaddr_t is declared with the kernel files, - * in . - */ -#include - -#ifdef notdef -typedef unsigned long netaddr_t; -#endif /* notdef */ - -typedef union { - struct { - unsigned char ia_net_owner; - unsigned char ia_net_node_type; - unsigned char ia_host_high; - unsigned char ia_host_low; - } ia_bytes; - netaddr_t ia_netaddr; -} ip_addr_t; - -#endif /* _NM_DEFS_ */ - diff --git a/mach/servers/srvbootstrap.defs b/mach/servers/srvbootstrap.defs deleted file mode 100644 index d564916..0000000 --- a/mach/servers/srvbootstrap.defs +++ /dev/null @@ -1,359 +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@ - */ -/* - * bootstrap -- fundamental service initiator and port server - * Mike DeMoney, NeXT, Inc. - * Copyright, 1990. All rights reserved. - * - * bootstrap.defs -- Mig interface definition - */ - -subsystem bootstrap 400; - -/* - * Interface: Bootstrap server - * - * The bootstrap server is the first user-mode task initiated by the Mach - * kernel at system boot time. The bootstrap server provides two services, - * it initiates other system tasks, and manages a table of name-port bindings - * for fundamental system services (e.g. lookupd, Window Manager, etc...). - * - * Name-port bindings can be established with the bootstrap server by either - * of two mechanisms: - * - * 1. The binding can be indicated, in advance of the service that backs it - * being available, via a "service create" request. In this case, bootstrap - * will immediately create a port and bind the indicated name with that port. - * At a later time, a service may "checkin" for the name-port - * binding and will be returned receive rights for the bound port. Lookup's - * on bindings created by this mechanism will return send rights to the port, - * even if no service has "checked-in". In this case, requests sent to the - * bound port will be queued until a server has checked-in and can satisfy the - * request. - * - * 2. Bindings can be established dynamically via a "register" request. In - * this case, the register request provides bootstrap with a name and send - * rights for a port. Bootstrap will provide send rights for the bound port - * to any requestor via the lookup request. - * - * Bootstrap provides its service port to descendant tasks via the Mach - * "bootstrap" special task port. All direct descendants of bootstrap receive - * a "privileged" bootstrap service port. System services that initiate - * untrusted tasks should replace the Mach bootstrap task special port with - * a subset bootstrap port to prevent them from infecting the namespace. - * - * The bootstrap server creates a "backup" port for each service that it - * creates. This is used to detect when a checked out service is no longer - * being served. The bootstrap server regains all rights to the port and - * it is marked available for check-out again. This allows crashed servers to - * resume service to previous clients. Lookup's on this named port will - * continue to be serviced by bootstrap while holding receive rights for the - * bound port. A client may detect that the service is inactive via the - * bootstrap status request. If an inactive service re-registers rather - * than "checking-in" the original bound port is destroyed. - * - * The status of a named service may be obtained via the "status" request. - * A service is "active" if a name-port binding exists and receive rights - * to the bound port are held by a task other than bootstrap. - * - * The bootstrap server may also (re)start server processes associated with - * with a set of services. The definition of the server process is done - * through the "create server" request. The server will be launched in the - * same bootstrap context in which it was registered. - */ - -#include -#include -import ; - -type cmd_t = c_string[512]; -type name_t = c_string[128]; -type cmd_array_t = ^array [] of cmd_t; -type name_array_t = ^array [] of name_t; -type bootstrap_status_t = integer_t; -type bootstrap_status_array_t = ^array [] of bootstrap_status_t; - -serverprefix x_; - -/* - * kern_return_t - * bootstrap_create_server(mach_port_t bootstrap_port, - * cmd_t server_command, - * integer_t server_uid, - * boolean_t on_demand, - * mach_port_t *server_port) - * - * Declares a server that mach_init will re-spawn within the specified - * bootstrap context. The server is considered already "active" - * (i.e. will not be re-spawned) until the returned server_port is - * deallocated. - * - * In the meantime, services can be declared against the server, - * by using the server_port as the privileged bootstrap target of - * subsequent bootstrap_create_service() calls. - * - * When mach_init re-spawns the server, its task bootstrap port - * is set to the privileged sever_port. Through this special - * bootstrap port, it can access all of parent bootstrap's context - * (and all services are created in the parent's namespace). But - * all additional service declarations (and declaration removals) - * will be associated with this particular server. - * - * Only a holder of the server_port privilege bootstrap port can - * check in or register over those services. - * - * When all services associated with a server are deleted, and the server - * exits, it will automatically be deleted itself. - * - * If the server is declared "on_demand," then a non-running server - * will be re-launched on first use of one of the service ports - * registered against it. Otherwise, it will be re-launched - * immediately upon exiting (whether any client is actively using - * any of the service ports or not). - * - * Errors: Returns appropriate kernel errors on rpc failure. - * Returns BOOTSTRAP_NOT_PRIVILEGED, bootstrap or uid invalid. - */ -routine bootstrap_create_server( - bootstrap_port : mach_port_t; - server_cmd : cmd_t; - server_uid : integer_t; - on_demand : boolean_t; - ServerSecToken token : security_token_t; - out server_port : mach_port_make_send_t); - -/* - * kern_return_t - * bootstrap_unprivileged(mach_port_t bootstrap_port, - * mach_port_t *unpriv_port) - * - * Given a bootstrap port, return its unprivileged equivalent. If - * the port is already unprivileged, another reference to the same - * port is returned. - * - * This is most often used by servers, which are launched with their - * bootstrap port set to the privileged port for the server, to get - * an unprivileged version of the same port for use by its unprivileged - * children (or any offspring that it does not want to count as part - * of the "server" for mach_init registration and re-launch purposes). - */ -routine bootstrap_unprivileged( - bootstrap_port : mach_port_t; - out unpriv_port : mach_port_t); - -/* - * kern_return_t - * bootstrap_check_in(mach_port_t bootstrap_port, - * name_t service_name, - * mach_port_t *service_port) - * - * Returns the receive right for the service named by service_name. The - * service must have previously been declared in this bootstrap context via - * a call to bootstrap_create_service(). Attempts to check_in a service - * which is already active are not allowed. - * - * If the service was declared as being associated with a server, the - * check_in must come from the server's privileged port (server_port). - * - * Errors: Returns appropriate kernel errors on rpc failure. - * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist. - * Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to - * bootstrap port without privilege. - * Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been - * registered or checked-in. - */ -routine bootstrap_check_in( - bootstrap_port : mach_port_t; - service_name : name_t; - out service_port : mach_port_move_receive_t); - -/* - * kern_return_t - * bootstrap_register(mach_port_t bootstrap_port, - * name_t service_name, - * mach_port_t service_port) - * - * Registers a send right for service_port with the service identified by - * service_name. Attempts to register a service where an active binding - * already exists are rejected. - * - * If the service was previously declared with bootstrap_create_service(), - * but is not currently active, this call can be used to undeclare the - * service. The bootstrap port used must have sufficient privilege to - * do so. (Registering MACH_PORT_NULL is especially useful for shutting - * down declared services). - * - * Errors: Returns appropriate kernel errors on rpc failure. - * Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to - * bootstrap port without privilege. - * Returns BOOTSTRAP_NAME_IN_USE, if service has already been - * register or checked-in. - */ -routine bootstrap_register( - bootstrap_port : mach_port_t; - service_name : name_t; - service_port : mach_port_t); - -/* - * kern_return_t - * bootstrap_look_up(mach_port_t bootstrap_port, - * name_t service_name, - * mach_port_t *service_port) - * - * Returns a send right for the service port declared/registered under the - * name service_name. The service is not guaranteed to be active. Use the - * bootstrap_status call to determine the status of the service. - * - * Errors: Returns appropriate kernel errors on rpc failure. - * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist. - */ -routine bootstrap_look_up( - bootstrap_port : mach_port_t; - service_name : name_t; - out service_port : mach_port_t); - -/* - * kern_return_t - * bootstrap_look_up_array(mach_port_t bootstrap_port, - * name_array_t service_names, - * int service_names_cnt, - * port_array_t *service_port, - * int *service_ports_cnt, - * boolean_t *all_services_known) - * - * Returns port send rights in corresponding entries of the array service_ports - * for all services named in the array service_names. Service_ports_cnt is - * returned and will always equal service_names_cnt (assuming service_names_cnt - * is greater than or equal to zero). - * - * Errors: Returns appropriate kernel errors on rpc failure. - * Returns BOOTSTRAP_NO_MEMORY, if server couldn't obtain memory - * for response. - * Unknown service names have the corresponding service port set - * to PORT_NULL. - * If all services are known, all_services_known is true on - * return, if any service is unknown, it's false. - */ -routine bootstrap_look_up_array( - bootstrap_port : mach_port_t; - service_names : name_array_t; - out service_ports : mach_port_array_t; - out all_services_known: boolean_t); - -/* - * kern_return_t - * bootstrap_parent(mach_port_t bootstrap_port, - * mach_port_t *parent_port); - * - * Given a bootstrap subset port, return the parent bootstrap port. - * If the specified bootstrap port is already the root subset, - * MACH_PORT_NULL will be returned. - * - * Errors: - * Returns BOOTSTRAP_NOT_PRIVILEGED if the caller is not running - * with an effective user id of root (as determined by the security - * token in the message trailer). - */ -routine bootstrap_parent( - bootstrap_port : mach_port_t; - ServerSecToken token : security_token_t; - out parent_port : mach_port_t); - -/* - * kern_return_t - * bootstrap_status(mach_port_t bootstrap_port, - * name_t service_name, - * bootstrap_status_t *service_active); - * - * Returns: service_active indicates if service is active, inactive, or - * associated with a launch-on-demand server. - * - * Errors: Returns appropriate kernel errors on rpc failure. - * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist. - */ -routine bootstrap_status( - bootstrap_port : mach_port_t; - service_name : name_t; - out service_active : bootstrap_status_t); - -/* - * kern_return_t - * bootstrap_info(port_t bootstrap_port, - * name_array_t *service_names, - * int *service_names_cnt, - * name_array_t *server_names, - * int *server_names_cnt, - * bool_array_t *service_active, - * int *service_active_cnt); - * - * Errors: Returns appropriate kernel errors on rpc failure. - */ -routine bootstrap_info( - bootstrap_port : mach_port_t; - out service_names : name_array_t, dealloc; - out server_names : name_array_t, dealloc; - out service_active : bootstrap_status_array_t, dealloc); - -/* - * kern_return_t - * bootstrap_subset(mach_port_t bootstrap_port, - * mach_port_t requestor_port, - * mach_port_t *subset_port); - * - * Returns a new port to use as a bootstrap port. This port behaves - * exactly like the previous bootstrap_port, except that ports dynamically - * registered via bootstrap_register() are available only to users of this - * specific subset_port. Lookups on the subset_port will return ports - * registered with this port specifically, and ports registered with - * ancestors of this subset_port. Duplications of services already - * registered with an ancestor port may be registered with the subset port - * are allowed. Services already advertised may then be effectively removed - * by registering PORT_NULL for the service. - * When it is detected that the requestor_port is destroyed the subset - * port and all services advertized by it are destroied as well. - * - * Errors: Returns appropriate kernel errors on rpc failure. - */ -routine bootstrap_subset( - bootstrap_port : mach_port_t; - requestor_port : mach_port_t; - out subset_port : mach_port_t); - -/* - * kern_return_t - * bootstrap_create_service(mach_port_t bootstrap_port, - * name_t service_name, - * mach_port_t *service_port) - * - * Creates a service named "service_name" and returns send rights to that - * port in "service_port." The port may later be checked in as if this - * port were configured in the bootstrap configuration file. - * - * Errors: Returns appropriate kernel errors on rpc failure. - * Returns BOOTSTRAP_SERVICE_ACTIVE, if service already exists. - */ -routine bootstrap_create_service( - bootstrap_port : mach_port_t; - service_name : name_t; - out service_port : mach_port_t); - diff --git a/mach/slot_name.c b/mach/slot_name.c deleted file mode 100644 index 4d72ec0..0000000 --- a/mach/slot_name.c +++ /dev/null @@ -1,83 +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@ - */ -/* - * 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 -#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; -} - -kern_return_t msg_rpc(void) { - return KERN_FAILURE; -} - -kern_return_t msg_send(void) { - return KERN_FAILURE; -} - -kern_return_t msg_receive(void) { - return KERN_FAILURE; -} - -mach_port_t task_self_(void) { - return mach_task_self(); -} - -mach_port_t host_self(void) { - return mach_host_self(); -} - diff --git a/mach/task.defs b/mach/task.defs deleted file mode 100644 index 0086d67..0000000 --- a/mach/task.defs +++ /dev/null @@ -1,23 +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@ - */ -#include \ No newline at end of file diff --git a/mach/thread_act.defs b/mach/thread_act.defs deleted file mode 100644 index 6e1717d..0000000 --- a/mach/thread_act.defs +++ /dev/null @@ -1,23 +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@ - */ -#include \ No newline at end of file diff --git a/makeCombos b/makeCombos index a9957fe..70570d2 100755 --- a/makeCombos +++ b/makeCombos @@ -39,10 +39,10 @@ push(@args, $prev) if $prev; # now make all unique combinations my %combos; -foreach my $variant (@args) { +foreach my $variant (sort(@args)) { my($v, $defines) = split('/', $variant, 2); my %new; - @new{$v, map("$_-$v", keys %combos)} = ($defines, map("$_\@$defines", values %combos)); + @new{$v, map("$_-$v", sort(keys %combos))} = ($defines, map("$_\@$defines", sort(values %combos))); %combos = (%combos, %new); } for(sort keys(%combos)) { diff --git a/make_libldbl128 b/make_libldbl128 deleted file mode 100755 index bd233a4..0000000 --- a/make_libldbl128 +++ /dev/null @@ -1,30 +0,0 @@ -#! /bin/sh -x - -libc_ldbl128=$1 -suffix=$2 -destdir=$3 -usr_local_lib_system=$4 - -libldbl128=libldbl128$suffix.a -objdir=`dirname $libc_ldbl128` -tmpdir=$objdir/tmp -libm=libm$suffix.a -libgcc=libgcc -libgccppc=$libgcc-ppc.a -libm128='ArcHyperbolicDD.o ArcSinCosDD.o ArcTanDD.o AuxiliaryDD.o ErfDD.o ExpDD.o ExpTableLD.o GammaDD.o HyperbolicDD.o LogDD.o LogTableLD.o PowerDD.o SinCosTanDD.o SqrtDD.o complex.o complexld64.o d3ops.o floating.o fpmacros.o ld64.o' - -mkdir -p $tmpdir -cd $tmpdir -rm -f * -lipo -thin ppc -output $libm $usr_local_lib_system/$libm -ar x $libm $libm128 -rm -f $libm -ar x $libc_ldbl128 -rm -f __.* -mkdir -p $destdir -ar cq $destdir/$libldbl128 `lorder * | tsort -q` -ranlib $destdir/$libldbl128 -if [ -z "$suffix" ]; then - lib=`gcc-3.5 -arch ppc -print-file-name=$libgcc.a` - cp $lib $destdir/$libgccppc -fi diff --git a/man/Makefile.inc b/man/Makefile.inc new file mode 100644 index 0000000..413ad34 --- /dev/null +++ b/man/Makefile.inc @@ -0,0 +1,20 @@ +# miscellaneous man pages + +.PATH: ${.CURDIR}/man + +.if ${LIB} == "c" + +MAN3 += assert.3 bitstring.3 stdarg.3 +MAN7 += environ.7 + +MLINKS += bitstring.3 bit_alloc.3 +MLINKS += bitstring.3 bit_clear.3 +MLINKS += bitstring.3 bit_decl.3 +MLINKS += bitstring.3 bit_ffs.3 +MLINKS += bitstring.3 bit_nclear.3 +MLINKS += bitstring.3 bit_nset.3 +MLINKS += bitstring.3 bit_set.3 +MLINKS += bitstring.3 bit_test.3 +MLINKS += bitstring.3 bitstr_size.3 + +.endif diff --git a/man/assert.3 b/man/assert.3 new file mode 100644 index 0000000..af51048 --- /dev/null +++ b/man/assert.3 @@ -0,0 +1,96 @@ +.\" $NetBSD: assert.3,v 1.5 1994/11/30 15:24:30 jtc Exp $ +.\" +.\" 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. +.\" +.\" @(#)assert.3 8.1 (Berkeley) 6/9/93 +.\" +.Dd June 9, 1993 +.Dt ASSERT 3 +.Os +.Sh NAME +.Nm assert +.Nd expression verification macro +.Sh SYNOPSIS +.Fd #include +.Fn assert expression +.Sh DESCRIPTION +The +.Fn assert +macro tests the given +.Ar expression +and if it is false, +the calling process is terminated. +A +diagnostic message is written to +.Em stderr +and the +.Xr abort 3 +function is called, effectively terminating the program. +.Pp +If +.Ar expression +is true, +the +.Fn assert +macro does nothing. +.Pp +The +.Fn assert +macro +may be removed at compile time with +the +.Xr cc 1 +option +.Fl DNDEBUG . +.Sh DIAGNOSTICS +The following diagnostic message is written to +.Em stderr +if +.Ar expression +is false: +.Bd -literal -offset indent +"assertion \e"%s\e" failed: file \e"%s\e", line %d\en", \e + "expression", __FILE__, __LINE__); +.Ed +.Sh SEE ALSO +.Xr cc 1 , +.Xr abort 3 +.Sh STANDARDS +The +.Fn assert +macro conforms to +.St -ansiC . +.Sh HISTORY +A +.Nm assert +macro appeared in +.At v6 . diff --git a/man/bitstring.3 b/man/bitstring.3 new file mode 100644 index 0000000..4257c54 --- /dev/null +++ b/man/bitstring.3 @@ -0,0 +1,181 @@ +.\" $NetBSD: bitstring.3,v 1.4 1994/11/30 15:24:31 jtc Exp $ +.\" +.\" Copyright (c) 1989, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Paul Vixie. +.\" 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. +.\" +.\" @(#)bitstring.3 8.1 (Berkeley) 7/19/93 +.\" +.Dd July 19, 1993 +.Dt BITSTRING 3 +.Os BSD 4 +.Sh NAME +.Nm bit_alloc , +.Nm bit_clear , +.Nm bit_decl , +.Nm bit_ffs , +.Nm bit_nclear , +.Nm bit_nset, +.Nm bit_set , +.Nm bitstr_size , +.Nm bit_test +.Nd bit-string manipulation macros +.Sh SYNOPSIS +.Fd #include +.Ft bitstr_t * +.Fn bit_alloc "int nbits" +.Fn bit_decl "bit_str name" "int nbits" +.Fn bit_clear "bit_str name" "int bit" +.Fn bit_ffc "bit_str name" "int nbits" "int *value" +.Fn bit_ffs "bit_str name" "int nbits" "int *value" +.Fn bit_nclear "bit_str name" "int start" "int stop" +.Fn bit_nset "bit_str name" "int start" "int stop" +.Fn bit_set "bit_str name" "int bit" +.Fn bitstr_size "int nbits" +.Fn bit_test "bit_str name" "int bit" +.Sh DESCRIPTION +These macros operate on strings of bits. +.Pp +The macro +.Fn bit_alloc +returns a pointer of type +.Dq Fa "bitstr_t *" +to sufficient space to store +.Fa nbits +bits, or +.Dv NULL +if no space is available. +.Pp +The macro +.Fn bit_decl +allocates sufficient space to store +.Fa nbits +bits on the stack. +.Pp +The macro +.Fn bitstr_size +returns the number of elements of type +.Fa bitstr_t +necessary to store +.Fa nbits +bits. +This is useful for copying bit strings. +.Pp +The macros +.Fn bit_clear +and +.Fn bit_set +clear or set the zero-based numbered bit +.Fa bit , +in the bit string +.Ar name . +.Pp +The +.Fn bit_nset +and +.Fn bit_nclear +macros +set or clear the zero-based numbered bits from +.Fa start +to +.Fa stop +in the bit string +.Ar name . +.Pp +The +.Fn bit_test +macro +evaluates to non-zero if the zero-based numbered bit +.Fa bit +of bit string +.Fa name +is set, and zero otherwise. +.Pp +The +.Fn bit_ffs +macro +stores in the location referenced by +.Fa value +the zero-based number of the first bit set in the array of +.Fa nbits +bits referenced by +.Fa name . +If no bits are set, the location referenced by +.Fa value +is set to \-1. +.Pp +The macro +.Fn bit_ffc +stores in the location referenced by +.Fa value +the zero-based number of the first bit not set in the array of +.Fa nbits +bits referenced by +.Fa name . +If all bits are set, the location referenced by +.Fa value +is set to \-1. +.Pp +The arguments to these macros are evaluated only once and may safely +have side effects. +.Sh EXAMPLE +.Bd -literal -offset indent +#include +#include + +... +#define LPR_BUSY_BIT 0 +#define LPR_FORMAT_BIT 1 +#define LPR_DOWNLOAD_BIT 2 +... +#define LPR_AVAILABLE_BIT 9 +#define LPR_MAX_BITS 10 + +make_lpr_available() +{ + bitstr_t bit_decl(bitlist, LPR_MAX_BITS); + ... + bit_nclear(bitlist, 0, LPR_MAX_BITS - 1); + ... + if (!bit_test(bitlist, LPR_BUSY_BIT)) { + bit_clear(bitlist, LPR_FORMAT_BIT); + bit_clear(bitlist, LPR_DOWNLOAD_BIT); + bit_set(bitlist, LPR_AVAILABLE_BIT); + } +} +.Ed +.Sh SEE ALSO +.Xr malloc 3 +.Sh HISTORY +The +.Nm bitstring +functions first appeared in 4.4BSD. diff --git a/man/environ.7 b/man/environ.7 new file mode 100644 index 0000000..cd510e4 --- /dev/null +++ b/man/environ.7 @@ -0,0 +1,215 @@ +.\" $NetBSD: environ.7,v 1.4 1995/07/03 19:45:07 jtc Exp $ +.\" +.\" Copyright (c) 1983, 1990, 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. +.\" +.\" @(#)environ.7 8.3 (Berkeley) 4/19/94 +.\" +.Dd April 19, 1994 +.Dt ENVIRON 7 +.Os BSD 4.2 +.Sh NAME +.Nm environ +.Nd user environment +.Sh SYNOPSIS +.Ar extern char **environ ; +.Sh DESCRIPTION +An array of strings called the +.Ar environment +is made available by +.Xr execve 2 +when a process begins. By convention these strings have the form +.Dq Ar name=value . +The following names are used by various commands: +.Bl -tag -width BLOCKSIZE +.It Ev BLOCKSIZE +The size of the block units used by several commands, most notably +.Xr df 1 , +.Xr du 1 +and +.Xr ls 1 . +BLOCKSIZE may be specified in units of a byte by specifying a number, +in units of a kilobyte by specifying a number followed by ``K'' or +``k'', in units of a megabyte by specifying a number followed by ``M'' +or ``m'' and in units of a gigabyte by specifying a number followed +by ``G'' or ``g''. +Sizes less than 512 bytes or greater than a gigabyte are ignored. +.It Ev EXINIT +A startup list of commands read by +.Xr ex 1 , +.Xr edit 1 , +and +.Xr vi 1 . +.It Ev HOME +A user's login directory, set by +.Xr login 1 +from the password file +.Xr passwd 5 . +.It Ev PATH +The sequence of directories, separated by colons, searched by +.Xr csh 1 , +.Xr sh 1 , +.Xr system 3 , +.Xr execvp 3 , +etc, when looking for an executable file. +PATH is set to ``/usr/bin:/bin'' initially by +.Xr login 1 . +.It Ev PRINTER +The name of the default printer to be used by +.Xr lpr 1 , +.Xr lpq 1 , +and +.Xr lprm 1 . +.It Ev SHELL +The full pathname of the user's login shell. +.It Ev TERM +The kind of terminal for which output is to be prepared. +This information is used by commands, such as +.Xr nroff 1 +or +.Xr plot 1 +which may exploit special terminal capabilities. See +.Pa /usr/share/misc/termcap +.Pq Xr termcap 5 +for a list of terminal types. +.It Ev TERMCAP +The string describing the terminal in TERM, or, if +it begins with a '/', the name of the termcap file. +See +.Ev TERMPATH +below, +.Xr termcap 5 , +and +.Xr termcap . +.It Ev TERMPATH +A sequence of pathnames of termcap files, separated by colons or spaces, +which are searched for terminal descriptions in the order listed. Having +no +.Ev TERMPATH +is equivalent to a +.Ev TERMPATH +of +.Dq Pa $HOME/.termcap:/etc/termcap . +.Ev TERMPATH +is ignored if +.Ev TERMCAP +contains a full pathname. +.It Ev TMPDIR +The directory in which to store temporary files. +Most applications use either +.Dq /tmp +or +.Dq /var/tmp . +Setting this variable will make them use another directory. +.It Ev TZ +The timezone to use when displaying dates. +The normal format is a pathname relative to +.Dq /usr/share/zoneinfo . +For example, the command +.Dq env TZ=US/Pacific date +displays the current time in California. +See +.Xr tzset 3 +for more information. +.It Ev LOGNAME +The login name of the user. +.It Ev USER +Deprecated synonym of +.Ev LOGNAME +(for backwards compatibility). +.El +.Pp +Further names may be placed in the environment by the +.Xr export +command and +.Ar name=value +arguments in +.Xr sh 1 , +or by the +.Xr setenv +command if you use +.Xr csh 1 . +It is unwise to change certain +.Xr sh 1 +variables that are frequently exported by +.Pa .profile +files, such as +.Ev MAIL , +.Ev PS1 , +.Ev PS2 , +and +.Ev IFS , +unless you know what you are doing. +.Sh PROGRAMMING +Programs can query and modify the environment, using the environment routines +.Xr getenv 3 , +.Xr putenv 3 , +.Xr setenv 3 +and +.Xr unsetenv 3 . +Direct access can be made through the global variable +.Va environ , +though it is recommended that changes to the enviroment still be made through +the environment routines. +.Pp +Shared libraries and bundles don't have direct access to +.Va environ , +which is only available to the loader +.Xr ld 1 +when a complete program is being linked. +The environment routines can still be used, but if direct access to +.Va environ +is needed, the +.Fn _NSGetEnviron +routine, defined in +.In crt_externs.h , +can be used to retrieve the address of +.Va environ +at runtime. +.Sh SEE ALSO +.Xr csh 1 , +.Xr ex 1 , +.Xr login 1 , +.Xr sh 1 , +.Xr getenv 3 , +.Xr putenv 3 , +.Xr setenv 3 , +.Xr unsetenv 3 , +.Xr execve 2 , +.Xr execle 3 , +.Xr system 3 , +.Xr termcap 3 , +.Xr termcap 5 +.Sh HISTORY +The +.Nm environ +manual page appeared in +.Bx 4.2 . diff --git a/man/stdarg.3 b/man/stdarg.3 new file mode 100644 index 0000000..a058265 --- /dev/null +++ b/man/stdarg.3 @@ -0,0 +1,207 @@ +.\" $NetBSD: stdarg.3,v 1.3 1994/11/30 15:24:37 jtc Exp $ +.\" +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)stdarg.3 8.1 (Berkeley) 6/5/93 +.\" +.Dd June 5, 1993 +.Dt STDARG 3 +.Os +.Sh NAME +.Nm stdarg +.Nd variable argument lists +.Sh SYNOPSIS +.Fd #include +.Ft void +.Fn va_start "va_list ap" last +.Ft type +.Fn va_arg "va_list ap" type +.Ft void +.Fn va_end "va_list ap" +.Sh DESCRIPTION +A function may be called with a varying number of arguments of varying +types. +The include file +.Aq Pa stdarg.h +declares a type +.Pq Em va_list +and defines three macros for stepping +through a list of arguments whose number and types are not known to +the called function. +.Pp +The called function must declare an object of type +.Em va_list +which is used by the macros +.Fn va_start , +.Fn va_arg , +and +.Fn va_end . +.Pp +The +.Fn va_start +macro initializes +.Fa ap +for subsequent use by +.Fn va_arg +and +.Fn va_end , +and must be called first. +.Pp +The parameter +.Fa last +is the name of the last parameter before the variable argument list, +i.e. the last parameter of which the calling function knows the type. +.Pp +Because the address of this parameter is used in the +.Fn va_start +macro, it should not be declared as a register variable, or as a +function or an array type. +.Pp +The +.Fn va_start +macro returns no value. +.Pp +The +.Fn va_arg +macro expands to an expression that has the type and value of the next +argument in the call. +The parameter +.Fa ap +is the +.Em va_list Fa ap +initialized by +.Fn va_start . +Each call to +.Fn va_arg +modifies +.Fa ap +so that the next call returns the next argument. +The parameter +.Fa type +is a type name specified so that the type of a pointer to an +object that has the specified type can be obtained simply by +adding a * +to +.Fa type . +.Pp +If there is no next argument, or if +.Fa type +is not compatible with the type of the actual next argument +(as promoted according to the default argument promotions), +random errors will occur. +.Pp +The first use of the +.Fn va_arg +macro after that of the +.Fn va_start +macro returns the argument after +.Fa last . +Successive invocations return the values of the remaining +arguments. +.Pp +The +.Fn va_end +macro handles a normal return from the function whose variable argument +list was initialized by +.Fn va_start . +.Pp +The +.Fn va_end +macro returns no value. +.Sh EXAMPLES +The function +.Em foo +takes a string of format characters and prints out the argument +associated with each format character based on the type. +.Bd -literal -offset indent +void foo(char *fmt, ...) +{ + va_list ap; + int d; + char c, *p, *s; + + va_start(ap, fmt); + while (*fmt) + switch(*fmt++) { + case 's': /* string */ + s = va_arg(ap, char *); + printf("string %s\en", s); + break; + case 'd': /* int */ + d = va_arg(ap, int); + printf("int %d\en", d); + break; + case 'c': /* char */ + c = va_arg(ap, char); + printf("char %c\en", c); + break; + } + va_end(ap); +} +.Ed +.Sh STANDARDS +The +.Fn va_start , +.Fn va_arg , +and +.Fn va_end +macros conform to +.St -ansiC . +.Sh COMPATIBILITY +These macros are +.Em not +compatible with the historic macros they replace. +A backward compatible version can be found in the include +file +.Aq Pa varargs.h . +.Sh BUGS +Unlike the +.Em varargs +macros, the +.Nm stdarg +macros do not permit programmers to +code a function with no fixed arguments. +This problem generates work mainly when converting +.Em varargs +code to +.Nm stdarg +code, +but it also creates difficulties for variadic functions that +wish to pass all of their arguments on to a function +that takes a +.Em va_list +argument, such as +.Xr vfprintf 3 . diff --git a/net/FreeBSD/inet.3.patch b/net/FreeBSD/inet.3.patch new file mode 100644 index 0000000..34a2d7f --- /dev/null +++ b/net/FreeBSD/inet.3.patch @@ -0,0 +1,127 @@ +--- 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 @@ + .Dt INET 3 + .Os + .Sh NAME +-.Nm inet_aton , + .Nm inet_addr , ++.Nm inet_aton , ++.Nm inet_lnaof , ++.Nm inet_makeaddr , ++.Nm inet_netof , + .Nm inet_network , + .Nm inet_ntoa , + .Nm inet_ntop , +-.Nm inet_pton , +-.Nm inet_makeaddr , +-.Nm inet_lnaof , +-.Nm inet_netof ++.Nm inet_pton + .Nd Internet address manipulation routines + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS +-.In sys/types.h +-.In sys/socket.h +-.In netinet/in.h + .In arpa/inet.h ++.Ft in_addr_t ++.Fo inet_addr ++.Fa "const char *cp" ++.Fc + .Ft int +-.Fn inet_aton "const char *cp" "struct in_addr *pin" ++.Fo inet_aton ++.Fa "const char *cp" ++.Fa "struct in_addr *pin" ++.Fc + .Ft in_addr_t +-.Fn inet_addr "const char *cp" ++.Fo inet_lnaof ++.Fa "struct in_addr in" ++.Fc ++.Ft struct in_addr ++.Fo inet_makeaddr ++.Fa "in_addr_t net" ++.Fa "in_addr_t lna" ++.Fc + .Ft in_addr_t +-.Fn inet_network "const char *cp" ++.Fo inet_netof ++.Fa "struct in_addr in" ++.Fc ++.Ft in_addr_t ++.Fo inet_network ++.Fa "const char *cp" ++.Fc + .Ft char * +-.Fn inet_ntoa "struct in_addr in" ++.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" + .Fa "socklen_t size" + .Fc + .Ft int +-.Fn inet_pton "int af" "const char * restrict src" "void * restrict dst" +-.Ft struct in_addr +-.Fn inet_makeaddr "in_addr_t net" "in_addr_t lna" +-.Ft in_addr_t +-.Fn inet_lnaof "struct in_addr in" +-.Ft in_addr_t +-.Fn inet_netof "struct in_addr in" ++.Fo inet_pton ++.Fa "int af" ++.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 @@ + .Fn inet_ntop + call fails if: + .Bl -tag -width Er +-.It Bq Er ENOSPC +-.Fa size +-was not large enough to store the presentation form of the address. + .It Bq Er EAFNOSUPPORT + .Fa *src + was not an +@@ -252,13 +266,24 @@ + or + .Dv AF_INET6 + family address. ++.It Bq Er ENOSPC ++.Fa size ++was not large enough to store the presentation form of the address. + .El ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Fd #include ++.Fd #include ++.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 diff --git a/net/FreeBSD/recv.c.patch b/net/FreeBSD/recv.c.patch new file mode 100644 index 0000000..d375e3e --- /dev/null +++ b/net/FreeBSD/recv.c.patch @@ -0,0 +1,25 @@ +--- recv.c.orig 2006-09-16 19:12:41.000000000 -0700 ++++ recv.c 2006-09-17 00:11:11.000000000 -0700 +@@ -44,11 +44,21 @@ + #include + #include "un-namespace.h" + ++#ifdef VARIANT_CANCELABLE ++ssize_t __recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict); ++#else /* !VARIANT_CANCELABLE */ ++ssize_t __recvfrom_nocancel(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict); ++#endif /* VARIANT_CANCELABLE */ ++ + ssize_t + recv(s, buf, len, flags) + int s, flags; + size_t len; + void *buf; + { +- return (_recvfrom(s, buf, len, flags, NULL, 0)); ++#ifdef VARIANT_CANCELABLE ++ return (__recvfrom(s, buf, len, flags, NULL, 0)); ++#else /* !VARIANT_CANCELABLE */ ++ return (__recvfrom_nocancel(s, buf, len, flags, NULL, 0)); ++#endif /* VARIANT_CANCELABLE */ + } diff --git a/net/FreeBSD/send.c.patch b/net/FreeBSD/send.c.patch new file mode 100644 index 0000000..3758f9d --- /dev/null +++ b/net/FreeBSD/send.c.patch @@ -0,0 +1,25 @@ +--- send.c.orig 2006-09-16 19:12:41.000000000 -0700 ++++ send.c 2006-09-17 00:07:27.000000000 -0700 +@@ -44,11 +44,21 @@ + #include + #include "un-namespace.h" + ++#ifdef VARIANT_CANCELABLE ++ssize_t __sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); ++#else /* !VARIANT_CANCELABLE */ ++ssize_t __sendto_nocancel(int, const void *, size_t, int, const struct sockaddr *, socklen_t); ++#endif /* VARIANT_CANCELABLE */ ++ + ssize_t + send(s, msg, len, flags) + int s, flags; + size_t len; + const void *msg; + { +- return (_sendto(s, msg, len, flags, NULL, 0)); ++#ifdef VARIANT_CANCELABLE ++ return (__sendto(s, msg, len, flags, NULL, 0)); ++#else /* !VARIANT_CANCELABLE */ ++ return (__sendto_nocancel(s, msg, len, flags, NULL, 0)); ++#endif /* VARIANT_CANCELABLE */ + } diff --git a/net/FreeBSD/sockatmark.3 b/net/FreeBSD/sockatmark.3 new file mode 100644 index 0000000..0bb8745 --- /dev/null +++ b/net/FreeBSD/sockatmark.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2002 William C. Fenner. 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 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/net/sockatmark.3,v 1.4 2002/12/19 09:40:22 ru Exp $ +.\" +.Dd October 13, 2002 +.Dt SOCKATMARK 3 +.Os +.Sh NAME +.Nm sockatmark +.Nd determine whether the read pointer is at the OOB mark +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/socket.h +.Ft int +.Fn sockatmark "int s" +.Sh DESCRIPTION +To find out if the read pointer is currently pointing at +the mark in the data stream, the +.Fn sockatmark +function is provided. +If +.Fn sockatmark +returns 1, the next read will return data +after the mark. +Otherwise (assuming out of band data has arrived), +the next read will provide data sent by the client prior +to transmission of the out of band signal. +The routine used +in the remote login process to flush output on receipt of an +interrupt or quit signal is shown below. +It reads the normal data up to the mark (to discard it), +then reads the out-of-band byte. +.Bd -literal -offset indent +#include +\&... +oob() +{ + int out = FWRITE, mark; + char waste[BUFSIZ]; + + /* flush local terminal output */ + ioctl(1, TIOCFLUSH, (char *)&out); + for (;;) { + if ((mark = sockatmark(rem)) < 0) { + perror("sockatmark"); + break; + } + if (mark) + break; + (void) read(rem, waste, sizeof (waste)); + } + if (recv(rem, &mark, 1, MSG_OOB) < 0) { + perror("recv"); + ... + } + ... +} +.Ed +.Sh RETURN VALUES +Upon successful completion, the +.Fn sockatmark +function returns the value 1 if the read pointer is pointing at +the OOB mark, 0 if it is not. +Otherwise the value \-1 is returned +and the global variable +.Va errno +is set to +indicate the error. +.Sh ERRORS +The +.Fn sockatmark +call fails if: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa s +argument +is not a valid descriptor. +.It Bq Er ENOTTY +The +.Fa s +argument +is a descriptor for a file, not a socket. +.El +.Sh SEE ALSO +.Xr recv 2 , +.Xr send 2 +.Sh HISTORY +The +.Fn sockatmark +function was introduced by +.St -p1003.1-2001 , +to standardize the historical +.Dv SIOCATMARK +.Xr ioctl 2 . +The +.Er ENOTTY +error instead of the usual +.Er ENOTSOCK +is to match the historical behavior of +.Dv SIOCATMARK . diff --git a/net/FreeBSD/sockatmark.3.patch b/net/FreeBSD/sockatmark.3.patch new file mode 100644 index 0000000..30d36cf --- /dev/null +++ b/net/FreeBSD/sockatmark.3.patch @@ -0,0 +1,11 @@ +--- _SB/Libc/net/FreeBSD/sockatmark.3 2005-12-16 00:23:58.000000000 -0800 ++++ _SB/Libc/net/FreeBSD/sockatmark.3.edit 2006-06-28 16:55:51.000000000 -0700 +@@ -83,7 +83,7 @@ + .Fn sockatmark + function returns the value 1 if the read pointer is pointing at + the OOB mark, 0 if it is not. +-Otherwise the value \-1 is returned ++Otherwise, the value \-1 is returned + and the global variable + .Va errno + is set to diff --git a/net/FreeBSD/sockatmark.c b/net/FreeBSD/sockatmark.c new file mode 100644 index 0000000..497ce7f --- /dev/null +++ b/net/FreeBSD/sockatmark.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2002 William C. Fenner. 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 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/net/sockatmark.c,v 1.1 2002/12/13 22:22:55 fenner Exp $ + */ +#include + +int sockatmark(int s) +{ + int atmark; + + if (ioctl(s, SIOCATMARK, &atmark) == -1) + return -1; + return atmark; +} diff --git a/net/Makefile.inc b/net/Makefile.inc index 0528491..1a07714 100644 --- a/net/Makefile.inc +++ b/net/Makefile.inc @@ -1,6 +1,13 @@ # from @(#)Makefile.inc 8.2 (Berkeley) 9/5/93 # $FreeBSD: src/lib/libc/net/Makefile.inc,v 1.43 2001/10/23 06:22:14 imp Exp $ +.ifnmake autopatch +# machine-dependent net sources +.if exists(${.CURDIR}/${MACHINE_ARCH}/net/Makefile.inc) +.include "${.CURDIR}/${MACHINE_ARCH}/net/Makefile.inc" +.endif +.endif # !autopatch + # machine-independent net sources .PATH: ${.CURDIR}/${MACHINE_ARCH}/net ${.CURDIR}/net @@ -8,40 +15,52 @@ 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 + recv.c send.c sockatmark.c .include "Makefile.fbsd_end" -UNIX03SRCS+= recv.c send.c +LEGACYSRCS+= recv.c send.c +CANCELABLESRCS+= recv.c send.c -CFLAGS+= -I${.OBJDIR} - -# machine-dependent net sources -.if exists(${.CURDIR}/${MACHINE_ARCH}/net/Makefile.inc) -.include "${.CURDIR}/${MACHINE_ARCH}/net/Makefile.inc" -.endif +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +CFLAGS-recv-fbsd.c += -DLIBC_ALIAS_RECV +CFLAGS-send-fbsd.c += -DLIBC_ALIAS_SEND .if ${LIB} == "c" -MAN3+= byteorder.3 ethers.3 hesiod.3 \ - rcmdsh.3 resolver.3 +MAN3+= byteorder.3 ethers.3 rcmdsh.3 .include "Makefile.fbsd_begin" -FBSDMAN3= addr2ascii.3 inet.3 inet_net.3 linkaddr.3 +FBSDMAN3= addr2ascii.3 inet.3 inet_net.3 linkaddr.3 sockatmark.3 .include "Makefile.fbsd_end" -MLINKS+=addr2ascii.3 ascii2addr.3 -MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ - byteorder.3 ntohs.3 -MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \ - ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 -MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \ - inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \ - inet.3 inet_network.3 inet.3 inet_ntoa.3 \ - inet.3 inet_ntop.3 inet.3 inet_pton.3 \ - inet.3 network.3 inet.3 ntoa.3 -MLINKS+=inet_net.3 inet_net_ntop.3 inet_net.3 inet_net_pton.3 -MLINKS+=linkaddr.3 link_addr.3 linkaddr.3 link_ntoa.3 -MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ - resolver.3 res_mkquery.3 resolver.3 res_query.3 \ - resolver.3 res_search.3 resolver.3 res_send.3 resolver.3 dn_skipname.3 \ - resolver.3 ns_get16.3 resolver.3 ns_get32.3 \ - resolver.3 ns_put16.3 resolver.3 ns_put32.3 +MLINKS+= addr2ascii.3 ascii2addr.3 + +MLINKS+= byteorder.3 htonl.3 \ + byteorder.3 htons.3 \ + byteorder.3 ntohl.3 \ + byteorder.3 ntohs.3 + +MLINKS+= ethers.3 ether_aton.3 \ + ethers.3 ether_hostton.3 \ + ethers.3 ether_line.3 \ + ethers.3 ether_ntoa.3 \ + ethers.3 ether_ntohost.3 + +MLINKS+= inet.3 addr.3 \ + inet.3 inet_addr.3 \ + inet.3 inet_aton.3 \ + inet.3 inet_lnaof.3 \ + inet.3 inet_makeaddr.3 \ + inet.3 inet_netof.3 \ + inet.3 inet_network.3 \ + inet.3 inet_ntoa.3 \ + inet.3 inet_ntop.3 \ + inet.3 inet_pton.3 \ + inet.3 network.3 \ + inet.3 ntoa.3 + +MLINKS+= inet_net.3 inet_net_ntop.3 \ + inet_net.3 inet_net_pton.3 + +MLINKS+= linkaddr.3 link_addr.3 \ + linkaddr.3 link_ntoa.3 .endif diff --git a/net/addr2ascii-fbsd.c b/net/addr2ascii-fbsd.c new file mode 100644 index 0000000..708b0f5 --- /dev/null +++ b/net/addr2ascii-fbsd.c @@ -0,0 +1,95 @@ +/* + * Copyright 1996 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. 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. + * + * $ANA: addr2ascii.c,v 1.1 1996/06/13 18:41:46 wollman Exp $ + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/net/addr2ascii.c,v 1.2 2002/03/22 21:52:28 obrien Exp $"); + +#include +#include + +#include +#include + +#include +#include +#include + +/*- + * Convert a network address from binary to printable numeric format. + * This API is copied from INRIA's IPv6 implementation, but it is a + * bit bogus in two ways: + * + * 1) There is no value in passing both an address family and + * an address length; either one should imply the other, + * or we should be passing sockaddrs instead. + * 2) There should by contrast be /added/ a length for the buffer + * that we pass in, so that programmers are spared the need to + * manually calculate (read: ``guess'') the maximum length. + * + * Flash: the API is also the same in the NRL implementation, and seems to + * be some sort of standard, so we appear to be stuck with both the bad + * naming and the poor choice of arguments. + */ +char * +addr2ascii(af, addrp, len, buf) + int af; + const void *addrp; + int len; /* should be size_t XXX */ + char *buf; /* XXX should pass length of buffer */ +{ + static char staticbuf[64]; /* 64 for AF_LINK > 16 for AF_INET */ + + if (!buf) + buf = staticbuf; + + switch(af) { + case AF_INET: + if (len != sizeof(struct in_addr)) { + errno = ENAMETOOLONG; + return 0; + } + strcpy(buf, inet_ntoa(*(const struct in_addr *)addrp)); + break; + + case AF_LINK: + if (len != sizeof(struct sockaddr_dl)) { + errno = ENAMETOOLONG; + return 0; + } + strcpy(buf, link_ntoa((const struct sockaddr_dl *)addrp)); + break; + + default: + errno = EPROTONOSUPPORT; + return 0; + } + return buf; +} diff --git a/net/addr2ascii.3 b/net/addr2ascii.3 new file mode 120000 index 0000000..1a9716a --- /dev/null +++ b/net/addr2ascii.3 @@ -0,0 +1 @@ +./addr2ascii.3 \ No newline at end of file diff --git a/net/ascii2addr-fbsd.c b/net/ascii2addr-fbsd.c new file mode 100644 index 0000000..bf2263b --- /dev/null +++ b/net/ascii2addr-fbsd.c @@ -0,0 +1,75 @@ +/* + * Copyright 1996 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. 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. + * + * $ANA: ascii2addr.c,v 1.2 1996/06/13 18:46:02 wollman Exp $ + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/net/ascii2addr.c,v 1.4 2002/03/22 21:52:28 obrien Exp $"); + +#include +#include + +#include +#include + +#include +#include +#include + +int +ascii2addr(af, ascii, result) + int af; + const char *ascii; + void *result; +{ + struct in_addr *ina; + char strbuf[4*sizeof("123")]; /* long enough for V4 only */ + + switch(af) { + case AF_INET: + ina = result; + strbuf[0] = '\0'; + strncat(strbuf, ascii, (sizeof strbuf)-1); + if (inet_aton(strbuf, ina)) + return sizeof(struct in_addr); + errno = EINVAL; + break; + + case AF_LINK: + link_addr(ascii, result); + /* oops... no way to detect failure */ + return sizeof(struct sockaddr_dl); + + default: + errno = EPROTONOSUPPORT; + break; + } + + return -1; +} diff --git a/net/byteorder.3 b/net/byteorder.3 index 527bae4..ce4eef2 100644 --- a/net/byteorder.3 +++ b/net/byteorder.3 @@ -56,6 +56,7 @@ .Sh DESCRIPTION These routines convert 16 and 32 bit quantities between network byte order and host byte order. +(Network byte order is big endian, or most significant byte first.) On machines which have a byte order which is the same as the network order, routines are defined as null macros. .Pp diff --git a/net/hesiod.3 b/net/hesiod.3 deleted file mode 100644 index 8de1f92..0000000 --- a/net/hesiod.3 +++ /dev/null @@ -1,159 +0,0 @@ -.\" $NetBSD: hesiod.3,v 1.1 1999/01/25 03:43:04 lukem Exp $ -.\" $FreeBSD: src/lib/libc/net/hesiod.3,v 1.3 2001/10/01 16:08:55 ru Exp $ -.\" -.\" from: #Id: hesiod.3,v 1.9.2.1 1997/01/03 21:02:23 ghudson Exp # -.\" -.\" Copyright 1988, 1996 by the Massachusetts Institute of Technology. -.\" -.\" 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 the name of M.I.T. not be used in -.\" advertising or publicity pertaining to distribution of the -.\" software without specific, written prior permission. -.\" M.I.T. makes no representations about the suitability of -.\" this software for any purpose. It is provided "as is" -.\" without express or implied warranty. -.\" -.Dd November 30, 1996 -.Dt HESIOD 3 -.Os -.Sh NAME -.Nm hesiod , -.Nm hesiod_init , -.Nm hesiod_resolve , -.Nm hesiod_free_list , -.Nm hesiod_to_bind , -.Nm hesiod_end -.Nd Hesiod name server interface library -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In hesiod.h -.Ft int -.Fn hesiod_init "void **context" -.Ft char ** -.Fn hesiod_resolve "void *context" "const char *name" "const char *type" -.Ft void -.Fn hesiod_free_list "void *context" "char **list" -.Ft char * -.Fn hesiod_to_bind "void *context" "const char *name" "const char *type" -.Ft void -.Fn hesiod_end "void *context" -.Sh DESCRIPTION -This family of functions allows you to perform lookups of Hesiod -information, which is stored as text records in the Domain Name -Service. -To perform lookups, you must first initialize a -.Fa context , -an opaque object which stores information used internally by the -library between calls. -.Fn hesiod_init -initializes a context, storing a pointer to the context in the -location pointed to by the -.Fa context -argument. -.Fn hesiod_end -frees the resources used by a context. -.Pp -.Fn hesiod_resolve -is the primary interface to the library. -If successful, it returns a -list of one or more strings giving the records matching -.Fa name -and -.Fa type . -The last element of the list is followed by a -.Dv NULL -pointer. -It is the -caller's responsibility to call -.Fn hesiod_free_list -to free the resources used by the returned list. -.Pp -.Fn hesiod_to_bind -converts -.Fa name -and -.Fa type -into the DNS name used by -.Fn hesiod_resolve . -It is the caller's responsibility to free the returned string using -.Fn free . -.Sh RETURN VALUES -.Rv -std hesiod_init -On failure, -.Fn hesiod_resolve -and -.Fn hesiod_to_bind -return -.Dv NULL -and set the global variable -.Va errno -to indicate the error. -.Sh ENVIRONMENT -.Bl -tag -width HESIOD_CONFIG -.It Ev HES_DOMAIN -If the environment variable -.Ev HES_DOMAIN -is set, it will override the domain in the Hesiod configuration file. -.It Ev HESIOD_CONFIG -If the environment variable -.Ev HESIOD_CONFIG -is set, it specifies the location of the Hesiod configuration file. -.El -.Sh SEE ALSO -.Xr hesiod.conf 5 , -.Xr named 8 -.Rs -.%T "Hesiod - Project Athena Technical Plan -- Name Service" -.Re -.Sh ERRORS -Hesiod calls may fail because of: -.Bl -tag -width Er -.It Bq Er ENOMEM -Insufficient memory was available to carry out the requested -operation. -.It Bq Er ENOEXEC -.Fn hesiod_init -failed because the Hesiod configuration file was invalid. -.It Bq Er ECONNREFUSED -.Fn hesiod_resolve -failed because no name server could be contacted to answer the query. -.It Bq Er EMSGSIZE -.Fn hesiod_resolve -or -.Fn hesiod_to_bind -failed because the query or response was too big to fit into the -packet buffers. -.It Bq Er ENOENT -.Fn hesiod_resolve -failed because the name server had no text records matching -.Fa name -and -.Fa type , -or -.Fn hesiod_to_bind -failed because the -.Fa name -argument had a domain extension which could not be resolved with type -.Dq rhs\-extension -in the local Hesiod domain. -.El -.Sh AUTHORS -.An Steve Dyer , -IBM/Project Athena -.An Greg Hudson , -MIT Team Athena -.Pp -Copyright 1987, 1988, 1995, 1996 by the Massachusetts Institute of Technology. -.Sh BUGS -The strings corresponding to the -.Va errno -values set by the Hesiod functions are not particularly indicative of -what went wrong, especially for -.Er ENOEXEC -and -.Er ENOENT . diff --git a/net/inet.3 b/net/inet.3 new file mode 100644 index 0000000..576b161 --- /dev/null +++ b/net/inet.3 @@ -0,0 +1,328 @@ +.\" Copyright (c) 1983, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" 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 $ +.\" +.Dd June 14, 2004 +.Dt INET 3 +.Os +.Sh NAME +.Nm inet_addr , +.Nm inet_aton , +.Nm inet_lnaof , +.Nm inet_makeaddr , +.Nm inet_netof , +.Nm inet_network , +.Nm inet_ntoa , +.Nm inet_ntop , +.Nm inet_pton +.Nd Internet address manipulation routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In arpa/inet.h +.Ft in_addr_t +.Fo inet_addr +.Fa "const char *cp" +.Fc +.Ft int +.Fo inet_aton +.Fa "const char *cp" +.Fa "struct in_addr *pin" +.Fc +.Ft in_addr_t +.Fo inet_lnaof +.Fa "struct in_addr in" +.Fc +.Ft struct in_addr +.Fo inet_makeaddr +.Fa "in_addr_t net" +.Fa "in_addr_t lna" +.Fc +.Ft in_addr_t +.Fo inet_netof +.Fa "struct in_addr in" +.Fc +.Ft in_addr_t +.Fo inet_network +.Fa "const char *cp" +.Fc +.Ft char * +.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 "socklen_t size" +.Fc +.Ft int +.Fo inet_pton +.Fa "int af" +.Fa "const char *restrict src" +.Fa "void *restrict dst" +.Fc +.Sh DESCRIPTION +The routines +.Fn inet_aton , +.Fn inet_addr , +and +.Fn inet_network +interpret character strings representing +numbers expressed in the Internet standard +.Ql .\& +notation. +.Pp +The +.Fn inet_pton +function converts a presentation format address (that is, printable form +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 +if some system error occurred (in which case +.Va errno +will have been set). +This function is presently valid for +.Dv AF_INET +and +.Dv AF_INET6 . +.Pp +The +.Fn inet_aton +routine interprets the specified character string as an Internet address, +placing the address into the structure provided. +It returns 1 if the string was successfully interpreted, +or 0 if the string is invalid. +The +.Fn inet_addr +and +.Fn inet_network +functions return numbers suitable for use +as Internet addresses and Internet network +numbers, respectively. +.Pp +The function +.Fn inet_ntop +converts an address +.Fa *src +from network format +(usually a +.Ft struct in_addr +or some other binary form, in network byte order) to presentation format +(suitable for external display purposes). +The +.Fa size +argument specifies the size, in bytes, of the buffer +.Fa *dst . +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. +This function is presently valid for +.Dv AF_INET +and +.Dv AF_INET6 . +.Pp +The routine +.Fn inet_ntoa +takes an Internet address and returns an +.Tn ASCII +string representing the address in +.Ql .\& +notation. +The routine +.Fn inet_makeaddr +takes an Internet network number and a local +network address and constructs an Internet address +from it. +The routines +.Fn inet_netof +and +.Fn inet_lnaof +break apart Internet host addresses, returning +the network number and local network address part, +respectively. +.Pp +All Internet addresses are returned in network +order (bytes ordered from left to right). +All network numbers and local address parts are +returned as machine byte order integer values. +.Sh INTERNET ADDRESSES +Values specified using the +.Ql .\& +notation take one +of the following forms: +.Bd -literal -offset indent +a.b.c.d +a.b.c +a.b +a +.Ed +.Pp +When four parts are specified, each is interpreted +as a byte of data and assigned, from left to right, +to the four bytes of an Internet address. +Note +that when an Internet address is viewed as a 32-bit +integer quantity on the +.Tn VAX +the bytes referred to +above appear as +.Dq Li d.c.b.a . +That is, +.Tn VAX +bytes are +ordered from right to left. +.Pp +When a three part address is specified, the last +part is interpreted as a 16-bit quantity and placed +in the right-most two bytes of the network address. +This makes the three part address format convenient +for specifying Class B network addresses as +.Dq Li 128.net.host . +.Pp +When a two part address is supplied, the last part +is interpreted as a 24-bit quantity and placed in +the right most three bytes of the network address. +This makes the two part address format convenient +for specifying Class A network addresses as +.Dq Li net.host . +.Pp +When only one part is given, the value is stored +directly in the network address without any byte +rearrangement. +.Pp +All numbers supplied as +.Dq parts +in a +.Ql .\& +notation +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 +is returned by +.Fn inet_addr +and +.Fn inet_network +for malformed requests. +.Sh ERRORS +The +.Fn inet_ntop +call fails if: +.Bl -tag -width Er +.It Bq Er EAFNOSUPPORT +.Fa *src +was not an +.Dv AF_INET +or +.Dv AF_INET6 +family address. +.It Bq Er ENOSPC +.Fa size +was not large enough to store the presentation form of the address. +.El +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Fd #include +.Fd #include +.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 +.%R RFC +.%N 2373 +.%D July 1998 +.%T "IP Version 6 Addressing Architecture" +.Re +.Sh STANDARDS +The +.Fn inet_ntop +and +.Fn inet_pton +functions conform to +.St -xns5.2 . +Note that +.Fn inet_pton +does not accept 1-, 2-, or 3-part dotted addresses; all four parts +must be specified and are interpreted only as decimal values. +This is a narrower input set than that accepted by +.Fn inet_aton . +.Sh HISTORY +These +functions appeared in +.Bx 4.2 . +.Sh BUGS +The value +.Dv INADDR_NONE +(0xffffffff) is a valid broadcast address, but +.Fn inet_addr +cannot return that value without indicating failure. +The newer +.Fn inet_aton +function does not share this problem. +The problem of host byte ordering versus network byte ordering is +confusing. +The string returned by +.Fn inet_ntoa +resides in a static memory area. +.Pp +Inet_addr should return a +.Fa struct in_addr . diff --git a/net/inet_addr-fbsd.c b/net/inet_addr-fbsd.c new file mode 100644 index 0000000..d5c673f --- /dev/null +++ b/net/inet_addr-fbsd.c @@ -0,0 +1,203 @@ +/* $KAME: inet_addr.c,v 1.5 2001/08/20 02:32:40 itojun Exp $ */ + +/* + * ++Copyright++ 1983, 1990, 1993 + * - + * Copyright (c) 1983, 1990, 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. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * 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, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION 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. + * - + * --Copyright-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/net/inet_addr.c,v 1.16 2002/04/19 04:46:20 suz Exp $"); + +#include "xlocale_private.h" + +#include + +#include +#include + +#include +#include +#include +#include + +/* + * ASCII internet address interpretation routine. + * The value returned is in network order. + */ +in_addr_t /* XXX should be struct in_addr :( */ +inet_addr(cp) + const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); +} + +/* + * Check whether "cp" is a valid ASCII representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(cp, addr) + const char *cp; + struct in_addr *addr; +{ + u_long parts[4]; + in_addr_t val; + char *c; + char *endptr; + int gotend, n; + locale_t loc = __current_locale(); + + c = (char *)cp; + n = 0; + /* + * Run through the string, grabbing numbers until + * the end of the string, or some error + */ + gotend = 0; + while (!gotend) { + errno = 0; + val = strtoul_l(c, &endptr, 0, loc); + + if (errno == ERANGE) /* Fail completely if it overflowed. */ + return (0); + + /* + * If the whole string is invalid, endptr will equal + * c.. this way we can make sure someone hasn't + * gone '.12' or something which would get past + * the next check. + */ + if (endptr == c) + return (0); + parts[n] = val; + c = endptr; + + /* Check the next character past the previous number's end */ + switch (*c) { + case '.' : + /* Make sure we only do 3 dots .. */ + if (n == 3) /* Whoops. Quit. */ + return (0); + n++; + c++; + break; + + case '\0': + gotend = 1; + break; + + default: + if (isspace_l((unsigned char)*c, loc)) { + gotend = 1; + break; + } else + return (0); /* Invalid character, so fail */ + } + + } + + /* + * Concoct the address according to + * the number of parts specified. + */ + + switch (n) { + case 0: /* a -- 32 bits */ + /* + * Nothing is necessary here. Overflow checking was + * already done in strtoul(). + */ + break; + case 1: /* a.b -- 8.24 bits */ + if (val > 0xffffff || parts[0] > 0xff) + return (0); + val |= parts[0] << 24; + break; + + case 2: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 3: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff || + parts[2] > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + + if (addr != NULL) + addr->s_addr = htonl(val); + return (1); +} + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include . + */ +#undef inet_addr +__weak_reference(__inet_addr, inet_addr); +#undef inet_aton +__weak_reference(__inet_aton, inet_aton); diff --git a/net/inet_lnaof-fbsd.c b/net/inet_lnaof-fbsd.c new file mode 100644 index 0000000..d107b27 --- /dev/null +++ b/net/inet_lnaof-fbsd.c @@ -0,0 +1,68 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/net/inet_lnaof.c,v 1.5 2002/03/22 21:52:29 obrien Exp $"); + +#include +#include +#include + +/* + * Return the local network address portion of an + * internet address; handles class a/b/c network + * number formats. + */ +in_addr_t +inet_lnaof(in) + struct in_addr in; +{ + in_addr_t i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return ((i)&IN_CLASSA_HOST); + else if (IN_CLASSB(i)) + return ((i)&IN_CLASSB_HOST); + else + return ((i)&IN_CLASSC_HOST); +} + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include . + */ +#undef inet_lnaof +__weak_reference(__inet_lnaof, inet_lnaof); diff --git a/net/inet_makeaddr-fbsd.c b/net/inet_makeaddr-fbsd.c new file mode 100644 index 0000000..27544e7 --- /dev/null +++ b/net/inet_makeaddr-fbsd.c @@ -0,0 +1,71 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/net/inet_makeaddr.c,v 1.4 2002/03/22 21:52:29 obrien Exp $"); + +#include +#include +#include + +/* + * Formulate an Internet address from network + host. Used in + * building addresses stored in the ifnet structure. + */ +struct in_addr +inet_makeaddr(net, host) + in_addr_t net, host; +{ + in_addr_t addr; + + if (net < 128) + addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST); + else if (net < 65536) + addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST); + else if (net < 16777216L) + addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST); + else + addr = net | host; + addr = htonl(addr); + return (*(struct in_addr *)&addr); +} + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include . + */ +#undef inet_makeaddr +__weak_reference(__inet_makeaddr, inet_makeaddr); diff --git a/net/inet_net.3 b/net/inet_net.3 new file mode 120000 index 0000000..18824dc --- /dev/null +++ b/net/inet_net.3 @@ -0,0 +1 @@ +./inet_net.3 \ No newline at end of file diff --git a/net/inet_net_ntop-fbsd.c b/net/inet_net_ntop-fbsd.c new file mode 100644 index 0000000..b97428a --- /dev/null +++ b/net/inet_net_ntop-fbsd.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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 const char orig_rcsid[] = "From Id: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp"; +#endif +#include +__FBSDID("$FreeBSD: src/lib/libc/net/inet_net_ntop.c,v 1.7 2002/03/22 21:52:29 obrien Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +static char * inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, + size_t size); + +/* + * char * + * inet_net_ntop(af, src, bits, dst, size) + * convert network number from network to presentation format. + * generates CIDR style result always. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * author: + * Paul Vixie (ISC), July 1996 + */ +char * +inet_net_ntop(af, src, bits, dst, size) + int af; + const void *src; + int bits; + char *dst; + size_t size; +{ + switch (af) { + case AF_INET: + return (inet_net_ntop_ipv4(src, bits, dst, size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } +} + +/* + * static char * + * inet_net_ntop_ipv4(src, bits, dst, size) + * convert IPv4 network number from network to presentation format. + * generates CIDR style result always. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * network byte order assumed. this means 192.5.5.240/28 has + * 0x11110000 in its fourth octet. + * author: + * Paul Vixie (ISC), July 1996 + */ +static char * +inet_net_ntop_ipv4(src, bits, dst, size) + const u_char *src; + int bits; + char *dst; + size_t size; +{ + char *odst = dst; + char *t; + u_int m; + int b; + + if (bits < 0 || bits > 32) { + errno = EINVAL; + return (NULL); + } + if (bits == 0) { + if (size < sizeof "0") + goto emsgsize; + *dst++ = '0'; + *dst = '\0'; + } + + /* Format whole octets. */ + for (b = bits / 8; b > 0; b--) { + if (size < sizeof "255.") + goto emsgsize; + t = dst; + dst += SPRINTF((dst, "%u", *src++)); + if (b > 1) { + *dst++ = '.'; + *dst = '\0'; + } + size -= (size_t)(dst - t); + } + + /* Format partial octet. */ + b = bits % 8; + if (b > 0) { + if (size < sizeof ".255") + goto emsgsize; + t = dst; + if (dst != odst) + *dst++ = '.'; + m = ((1 << b) - 1) << (8 - b); + dst += SPRINTF((dst, "%u", *src & m)); + size -= (size_t)(dst - t); + } + + /* Format CIDR /width. */ + if (size < sizeof "/32") + goto emsgsize; + dst += SPRINTF((dst, "/%u", bits)); + return (odst); + + emsgsize: + errno = EMSGSIZE; + return (NULL); +} + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include . + */ +#undef inet_net_ntop +__weak_reference(__inet_net_ntop, inet_net_ntop); diff --git a/net/inet_net_pton-fbsd.c b/net/inet_net_pton-fbsd.c new file mode 100644 index 0000000..fc122b8 --- /dev/null +++ b/net/inet_net_pton-fbsd.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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 const char orig_rcsid[] = "From Id: inet_net_pton.c,v 1.8 1996/11/21 10:28:12 vixie Exp $"; +#endif +#include +__FBSDID("$FreeBSD: src/lib/libc/net/inet_net_pton.c,v 1.9 2003/09/15 23:38:06 fenner Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +static int inet_net_pton_ipv4(const char *src, u_char *dst, size_t size); + +/* + * static int + * inet_net_pton(af, src, dst, size) + * convert network number from presentation to network format. + * accepts hex octets, hex strings, decimal octets, and /CIDR. + * "size" is in bytes and describes "dst". + * return: + * number of bits, either imputed classfully or specified with /CIDR, + * or -1 if some failure occurred (check errno). ENOENT means it was + * not a valid network specification. + * author: + * Paul Vixie (ISC), June 1996 + */ +int +inet_net_pton(af, src, dst, size) + int af; + const char *src; + void *dst; + size_t size; +{ + switch (af) { + case AF_INET: + return (inet_net_pton_ipv4(src, dst, size)); + default: + errno = EAFNOSUPPORT; + return (-1); + } +} + +/* + * static int + * inet_net_pton_ipv4(src, dst, size) + * convert IPv4 network number from presentation to network format. + * accepts hex octets, hex strings, decimal octets, and /CIDR. + * "size" is in bytes and describes "dst". + * return: + * number of bits, either imputed classfully or specified with /CIDR, + * or -1 if some failure occurred (check errno). ENOENT means it was + * not an IPv4 network specification. + * note: + * network byte order assumed. this means 192.5.5.240/28 has + * 0x11110000 in its fourth octet. + * author: + * Paul Vixie (ISC), June 1996 + */ +static int +inet_net_pton_ipv4(src, dst, size) + const char *src; + u_char *dst; + size_t size; +{ + static const char + xdigits[] = "0123456789abcdef", + digits[] = "0123456789"; + int n, ch, tmp, dirty, bits; + const u_char *odst = dst; + locale_t loc = __current_locale(); + + ch = *src++; + if (ch == '0' && (src[0] == 'x' || src[0] == 'X') + && isascii(src[1]) && isxdigit_l(src[1], loc)) { + /* Hexadecimal: Eat nybble string. */ + if (size <= 0) + goto emsgsize; + *dst = 0, dirty = 0; + src++; /* skip x or X. */ + while ((ch = *src++) != '\0' && + isascii(ch) && isxdigit_l(ch, loc)) { + if (isupper_l(ch, loc)) + ch = tolower_l(ch, loc); + n = strchr(xdigits, ch) - xdigits; + assert(n >= 0 && n <= 15); + *dst |= n; + if (!dirty++) + *dst <<= 4; + else if (size-- > 0) + *++dst = 0, dirty = 0; + else + goto emsgsize; + } + if (dirty) + size--; + } else if (isascii(ch) && isdigit_l(ch, loc)) { + /* Decimal: eat dotted digit string. */ + for (;;) { + tmp = 0; + do { + n = strchr(digits, ch) - digits; + assert(n >= 0 && n <= 9); + tmp *= 10; + tmp += n; + if (tmp > 255) + goto enoent; + } while ((ch = *src++) != '\0' && + isascii(ch) && isdigit_l(ch, loc)); + if (size-- <= 0) + goto emsgsize; + *dst++ = (u_char) tmp; + if (ch == '\0' || ch == '/') + break; + if (ch != '.') + goto enoent; + ch = *src++; + if (!isascii(ch) || !isdigit_l(ch, loc)) + goto enoent; + } + } else + goto enoent; + + bits = -1; + if (ch == '/' && isascii(src[0]) && isdigit_l(src[0], loc) && dst > odst) { + /* CIDR width specifier. Nothing can follow it. */ + ch = *src++; /* Skip over the /. */ + bits = 0; + do { + n = strchr(digits, ch) - digits; + assert(n >= 0 && n <= 9); + bits *= 10; + bits += n; + } while ((ch = *src++) != '\0' && isascii(ch) && isdigit_l(ch, loc)); + if (ch != '\0') + goto enoent; + if (bits > 32) + goto emsgsize; + } + + /* Firey death and destruction unless we prefetched EOS. */ + if (ch != '\0') + goto enoent; + + /* If nothing was written to the destination, we found no address. */ + if (dst == odst) + goto enoent; + /* If no CIDR spec was given, infer width from net class. */ + if (bits == -1) { + if (*odst >= 240) /* Class E */ + bits = 32; + else if (*odst >= 224) /* Class D */ + bits = 4; + else if (*odst >= 192) /* Class C */ + bits = 24; + else if (*odst >= 128) /* Class B */ + bits = 16; + else /* Class A */ + bits = 8; + /* If imputed mask is narrower than specified octets, widen. */ + if (bits < ((dst - odst) * 8)) + bits = (dst - odst) * 8; + } + /* Extend network to cover the actual mask. */ + while (bits > ((dst - odst) * 8)) { + if (size-- <= 0) + goto emsgsize; + *dst++ = '\0'; + } + return (bits); + + enoent: + errno = ENOENT; + return (-1); + + emsgsize: + errno = EMSGSIZE; + return (-1); +} + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include . + */ +#undef inet_net_pton +__weak_reference(__inet_net_pton, inet_net_pton); diff --git a/net/inet_neta-fbsd.c b/net/inet_neta-fbsd.c new file mode 100644 index 0000000..43b4af1 --- /dev/null +++ b/net/inet_neta-fbsd.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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 const char orig_rcsid[] = "From Id: inet_neta.c,v 8.2 1996/08/08 06:54:44 vixie Exp"; +#endif +#include +__FBSDID("$FreeBSD: src/lib/libc/net/inet_neta.c,v 1.9 2003/01/01 18:48:43 schweikh Exp $"); + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +/* + * char * + * inet_neta(src, dst, size) + * format an in_addr_t network number into presentation format. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * format of ``src'' is as for inet_network(). + * author: + * Paul Vixie (ISC), July 1996 + */ +char * +inet_neta(src, dst, size) + in_addr_t src; + char *dst; + size_t size; +{ + char *odst = dst; + char *tp; + + while (src & 0xffffffff) { + u_char b = (src & 0xff000000) >> 24; + + src <<= 8; + if (b) { + if (size < sizeof "255.") + goto emsgsize; + tp = dst; + dst += SPRINTF((dst, "%u", b)); + if (src != 0L) { + *dst++ = '.'; + *dst = '\0'; + } + size -= (size_t)(dst - tp); + } + } + if (dst == odst) { + if (size < sizeof "0.0.0.0") + goto emsgsize; + strcpy(dst, "0.0.0.0"); + } + return (odst); + + emsgsize: + errno = EMSGSIZE; + return (NULL); +} + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include . + */ +#undef inet_neta +__weak_reference(__inet_neta, inet_neta); diff --git a/net/inet_netof-fbsd.c b/net/inet_netof-fbsd.c new file mode 100644 index 0000000..1f829a4 --- /dev/null +++ b/net/inet_netof-fbsd.c @@ -0,0 +1,67 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/net/inet_netof.c,v 1.5 2002/03/22 21:52:29 obrien Exp $"); + +#include +#include +#include + +/* + * Return the network number from an internet + * address; handles class a/b/c network #'s. + */ +in_addr_t +inet_netof(in) + struct in_addr in; +{ + in_addr_t i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); + else if (IN_CLASSB(i)) + return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT); + else + return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); +} + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include . + */ +#undef inet_netof +__weak_reference(__inet_netof, inet_netof); diff --git a/net/inet_network-fbsd.c b/net/inet_network-fbsd.c new file mode 100644 index 0000000..0fabb33 --- /dev/null +++ b/net/inet_network-fbsd.c @@ -0,0 +1,103 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/net/inet_network.c,v 1.9 2002/03/22 21:52:29 obrien Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include + +/* + * Internet network address interpretation routine. + * The library routines call this routine to interpret + * network numbers. + */ +in_addr_t +inet_network(cp) + const char *cp; +{ + in_addr_t val, base, n; + char c; + in_addr_t parts[4], *pp = parts; + int i; + locale_t loc = __current_locale(); + +again: + val = 0; base = 10; + if (*cp == '0') + base = 8, cp++; + if (*cp == 'x' || *cp == 'X') + base = 16, cp++; + while ((c = *cp) != 0) { + if (isdigit_l((unsigned char)c, loc)) { + val = (val * base) + (c - '0'); + cp++; + continue; + } + if (base == 16 && isxdigit_l((unsigned char)c, loc)) { + val = (val << 4) + (c + 10 - (islower_l((unsigned char)c, loc) ? 'a' : 'A')); + cp++; + continue; + } + break; + } + if (*cp == '.') { + if (pp >= parts + 3) + return (INADDR_NONE); + *pp++ = val, cp++; + goto again; + } + if (*cp && !isspace_l((unsigned char)*cp, loc)) + return (INADDR_NONE); + *pp++ = val; + n = pp - parts; + for (val = 0, i = 0; i < n; i++) { + val <<= 8; + val |= parts[i] & 0xff; + } + return (val); +} + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include . + */ +#undef inet_network +__weak_reference(__inet_network, inet_network); diff --git a/net/inet_ntoa-fbsd.c b/net/inet_ntoa-fbsd.c new file mode 100644 index 0000000..326a76a --- /dev/null +++ b/net/inet_ntoa-fbsd.c @@ -0,0 +1,67 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/net/inet_ntoa.c,v 1.6 2002/03/22 21:52:29 obrien Exp $"); + +#include +#include +#include +#include +#include +#include + +/* + * Convert network-format internet address + * to base 256 d.d.d.d representation. + */ +char * +inet_ntoa(in) + struct in_addr in; +{ + static char ret[18]; + + strcpy(ret, "[inet_ntoa error]"); + (void) inet_ntop(AF_INET, &in, ret, sizeof ret); + return (ret); +} + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include . + */ +#undef inet_ntoa +__weak_reference(__inet_ntoa, inet_ntoa); diff --git a/net/linkaddr-fbsd.c b/net/linkaddr-fbsd.c new file mode 100644 index 0000000..0161558 --- /dev/null +++ b/net/linkaddr-fbsd.c @@ -0,0 +1,160 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/net/linkaddr.c,v 1.3 2002/03/21 18:49:23 obrien Exp $"); + +#include +#include +#include +#include + +/* States*/ +#define NAMING 0 +#define GOTONE 1 +#define GOTTWO 2 +#define RESET 3 +/* Inputs */ +#define DIGIT (4*0) +#define END (4*1) +#define DELIM (4*2) +#define LETTER (4*3) + +void +link_addr(addr, sdl) + const char *addr; + struct sockaddr_dl *sdl; +{ + char *cp = sdl->sdl_data; + char *cplim = sdl->sdl_len + (char *)sdl; + int byte = 0, state = NAMING, new; + + bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1); + sdl->sdl_family = AF_LINK; + do { + state &= ~LETTER; + if ((*addr >= '0') && (*addr <= '9')) { + new = *addr - '0'; + } else if ((*addr >= 'a') && (*addr <= 'f')) { + new = *addr - 'a' + 10; + } else if ((*addr >= 'A') && (*addr <= 'F')) { + new = *addr - 'A' + 10; + } else if (*addr == 0) { + state |= END; + } else if (state == NAMING && + (((*addr >= 'A') && (*addr <= 'Z')) || + ((*addr >= 'a') && (*addr <= 'z')))) + state |= LETTER; + else + state |= DELIM; + addr++; + switch (state /* | INPUT */) { + case NAMING | DIGIT: + case NAMING | LETTER: + *cp++ = addr[-1]; + continue; + case NAMING | DELIM: + state = RESET; + sdl->sdl_nlen = cp - sdl->sdl_data; + continue; + case GOTTWO | DIGIT: + *cp++ = byte; + /* FALLTHROUGH */ + case RESET | DIGIT: + state = GOTONE; + byte = new; + continue; + case GOTONE | DIGIT: + state = GOTTWO; + byte = new + (byte << 4); + continue; + default: /* | DELIM */ + state = RESET; + *cp++ = byte; + byte = 0; + continue; + case GOTONE | END: + case GOTTWO | END: + *cp++ = byte; + /* FALLTHROUGH */ + case RESET | END: + break; + } + break; + } while (cp < cplim); + sdl->sdl_alen = cp - LLADDR(sdl); + new = cp - (char *)sdl; + if (new > sizeof(*sdl)) + sdl->sdl_len = new; + return; +} + +static char hexlist[] = "0123456789abcdef"; + +char * +link_ntoa(sdl) + const struct sockaddr_dl *sdl; +{ + static char obuf[64]; + char *out = obuf; + int i; + u_char *in = (u_char *)LLADDR(sdl); + u_char *inlim = in + sdl->sdl_alen; + int firsttime = 1; + + if (sdl->sdl_nlen) { + bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen); + out += sdl->sdl_nlen; + if (sdl->sdl_alen) + *out++ = ':'; + } + while (in < inlim) { + if (firsttime) + firsttime = 0; + else + *out++ = '.'; + i = *in++; + if (i > 0xf) { + out[1] = hexlist[i & 0xf]; + i >>= 4; + out[0] = hexlist[i]; + out += 2; + } else + *out++ = hexlist[i]; + } + *out = 0; + return (obuf); +} diff --git a/net/linkaddr.3 b/net/linkaddr.3 new file mode 120000 index 0000000..f4e564f --- /dev/null +++ b/net/linkaddr.3 @@ -0,0 +1 @@ +./linkaddr.3 \ No newline at end of file diff --git a/net/nsap_addr-fbsd.c b/net/nsap_addr-fbsd.c new file mode 100644 index 0000000..e2fc0e8 --- /dev/null +++ b/net/nsap_addr-fbsd.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 1996, 1998 by Internet Software Consortium. + * + * 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/net/nsap_addr.c,v 1.9 2002/03/22 21:52:29 obrien Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char +xtob(c) + int c; +{ + return (c - (((c >= '0') && (c <= '9')) ? '0' : '7')); +} + +u_int +inet_nsap_addr(ascii, binary, maxlen) + const char *ascii; + u_char *binary; + int maxlen; +{ + u_char c, nib; + u_int len = 0; + locale_t loc = __current_locale(); + + while ((c = *ascii++) != '\0' && len < (u_int)maxlen) { + if (c == '.' || c == '+' || c == '/') + continue; + if (!isascii(c)) + return (0); + if (islower_l(c, loc)) + c = toupper_l(c, loc); + if (isxdigit_l(c, loc)) { + nib = xtob(c); + c = *ascii++; + if (c != '\0') { + c = toupper_l(c, loc); + if (isxdigit_l(c, loc)) { + *binary++ = (nib << 4) | xtob(c); + len++; + } else + return (0); + } + else + return (0); + } + else + return (0); + } + return (len); +} + +char * +inet_nsap_ntoa(binlen, binary, ascii) + int binlen; + const u_char *binary; + char *ascii; +{ + int nib; + int i; + static char *tmpbuf = NULL; + char *start; + + if (tmpbuf == NULL) { + tmpbuf = malloc(255*3); + if (tmpbuf == NULL) + return NULL; + } + if (ascii) + start = ascii; + else { + ascii = tmpbuf; + start = tmpbuf; + } + + if (binlen > 255) + binlen = 255; + + for (i = 0; i < binlen; i++) { + nib = *binary >> 4; + *ascii++ = nib + (nib < 10 ? '0' : '7'); + nib = *binary++ & 0x0f; + *ascii++ = nib + (nib < 10 ? '0' : '7'); + if (((i % 2) == 0 && (i + 1) < binlen)) + *ascii++ = '.'; + } + *ascii = '\0'; + return (start); +} + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include . + */ +#undef inet_nsap_addr +__weak_reference(__inet_nsap_addr, inet_nsap_addr); +#undef inet_nsap_ntoa +__weak_reference(__inet_nsap_ntoa, inet_nsap_ntoa); diff --git a/net/recv-fbsd.c b/net/recv-fbsd.c new file mode 100644 index 0000000..f53be59 --- /dev/null +++ b/net/recv-fbsd.c @@ -0,0 +1,64 @@ +/* + * 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[] = "@(#)recv.c 8.2 (Berkeley) 2/21/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/net/recv.c,v 1.3 2002/03/22 21:52:29 obrien Exp $"); + +#include "namespace.h" +#include +#include + +#include +#include "un-namespace.h" + +#ifdef VARIANT_CANCELABLE +ssize_t __recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict); +#else /* !VARIANT_CANCELABLE */ +ssize_t __recvfrom_nocancel(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict); +#endif /* VARIANT_CANCELABLE */ + +ssize_t +recv(s, buf, len, flags) + int s, flags; + size_t len; + void *buf; +{ +#ifdef VARIANT_CANCELABLE + return (__recvfrom(s, buf, len, flags, NULL, 0)); +#else /* !VARIANT_CANCELABLE */ + return (__recvfrom_nocancel(s, buf, len, flags, NULL, 0)); +#endif /* VARIANT_CANCELABLE */ +} diff --git a/net/resolver.3 b/net/resolver.3 deleted file mode 100644 index 1417598..0000000 --- a/net/resolver.3 +++ /dev/null @@ -1,422 +0,0 @@ -.\" Copyright (c) 1985, 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. -.\" -.\" @(#)resolver.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/net/resolver.3,v 1.21 2001/10/01 16:08:56 ru Exp $ -.\" -.Dd June 4, 1993 -.Dt RESOLVER 3 -.Os -.Sh NAME -.Nm res_query , -.Nm res_search , -.Nm res_mkquery , -.Nm res_send , -.Nm res_init , -.Nm dn_comp , -.Nm dn_expand , -.Nm dn_skipname , -.Nm ns_get16 , -.Nm ns_get32 , -.Nm ns_put16 , -.Nm ns_put32 -.Nd resolver routines -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In netinet/in.h -.In arpa/nameser.h -.In resolv.h -.Ft int -.Fo res_query -.Fa "const char *dname" -.Fa "int class" -.Fa "int type" -.Fa "u_char *answer" -.Fa "int anslen" -.Fc -.Ft int -.Fo res_search -.Fa "const char *dname" -.Fa "int class" -.Fa "int type" -.Fa "u_char *answer" -.Fa "int anslen" -.Fc -.Ft int -.Fo res_mkquery -.Fa "int op" -.Fa "const char *dname" -.Fa "int class" -.Fa "int type" -.Fa "const u_char *data" -.Fa "int datalen" -.Fa "const u_char *newrr_in" -.Fa "u_char *buf" -.Fa "int buflen" -.Fc -.Ft int -.Fo res_send -.Fa "const u_char *msg" -.Fa "int msglen" -.Fa "u_char *answer" -.Fa "int anslen" -.Fc -.Ft int -.Fn res_init -.Ft int -.Fo dn_comp -.Fa "const char *exp_dn" -.Fa "u_char *comp_dn" -.Fa "int length" -.Fa "u_char **dnptrs" -.Fa "u_char **lastdnptr" -.Fc -.Ft int -.Fo dn_expand -.Fa "const u_char *msg" -.Fa "const u_char *eomorig" -.Fa "const u_char *comp_dn" -.Fa "char *exp_dn" -.Fa "int length" -.Fc -.Ft int -.Fn dn_skipname "const u_char *comp_dn" "const u_char *eom" -.Ft u_int -.Fn ns_get16 "const u_char *src" -.Ft u_long -.Fn ns_get32 "const u_char *src" -.Ft void -.Fn ns_put16 "u_int src" "u_char *dst" -.Ft void -.Fn ns_put32 "u_long src" "u_char *dst" -.Sh DESCRIPTION -These routines are used for making, sending and interpreting -query and reply messages with Internet domain name servers. -.Pp -Global configuration and state information that is used by the -resolver routines is kept in the structure -.Em _res . -Most of the values have reasonable defaults and can be ignored. -Options -stored in -.Em _res.options -are defined in -.Pa resolv.h -and are as follows. -Options are stored as a simple bit mask containing the bitwise ``or'' -of the options enabled. -.Bl -tag -width RES_USE_INET6 -.It Dv RES_INIT -True if the initial name server address and default domain name are -initialized (i.e., -.Fn res_init -has been called). -.It Dv RES_DEBUG -Print debugging messages. -.It Dv RES_AAONLY -Accept authoritative answers only. -With this option, -.Fn res_send -should continue until it finds an authoritative answer or finds an error. -Currently this is not implemented. -.It Dv RES_USEVC -Use -.Tn TCP -connections for queries instead of -.Tn UDP -datagrams. -.It Dv RES_STAYOPEN -Used with -.Dv RES_USEVC -to keep the -.Tn TCP -connection open between -queries. -This is useful only in programs that regularly do many queries. -.Tn UDP -should be the normal mode used. -.It Dv RES_IGNTC -Unused currently (ignore truncation errors, i.e., don't retry with -.Tn TCP ) . -.It Dv RES_RECURSE -Set the recursion-desired bit in queries. -This is the default. -.Pf ( Fn res_send -does not do iterative queries and expects the name server -to handle recursion.) -.It Dv RES_DEFNAMES -If set, -.Fn res_search -will append the default domain name to single-component names -(those that do not contain a dot). -This option is enabled by default. -.It Dv RES_DNSRCH -If this option is set, -.Fn res_search -will search for host names in the current domain and in parent domains; see -.Xr hostname 7 . -This is used by the standard host lookup routine -.Xr gethostbyname 3 . -This option is enabled by default. -.It Dv RES_NOALIASES -This option turns off the user level aliasing feature controlled by the -.Dq Ev HOSTALIASES -environment variable. Network daemons should set this option. -.It Dv RES_USE_INET6 -Enables support for IPv6-only applications. -This causes IPv4 addresses to be returned as an IPv4 mapped address. -For example, -.Li 10.1.1.1 -will be returned as -.Li ::ffff:10.1.1.1 . -The option is meaningful with certain kernel configuration only. -.It Dv RES_USE_EDNS0 -Enables support for OPT pseudo-RR for EDNS0 extension. -With the option, resolver code will attach OPT pseudo-RR into DNS queries, -to inform of our receive buffer size. -The option will allow DNS servers to take advantage of non-default receive -buffer size, and to send larger replies. -DNS query packets with EDNS0 extension is not compatible with -non-EDNS0 DNS servers. -.El -.Pp -The -.Fn res_init -routine -reads the configuration file (if any; see -.Xr resolver 5 ) -to get the default domain name, -search list and -the Internet address of the local name server(s). -If no server is configured, the host running -the resolver is tried. -The current domain name is defined by the hostname -if not specified in the configuration file; -it can be overridden by the environment variable -.Ev LOCALDOMAIN . -This environment variable may contain several blank-separated -tokens if you wish to override the -.Em "search list" -on a per-process basis. This is similar to the -.Em search -command in the configuration file. -Another environment variable -.Dq Ev RES_OPTIONS -can be set to -override certain internal resolver options which are otherwise -set by changing fields in the -.Em _res -structure or are inherited from the configuration file's -.Em options -command. The syntax of the -.Dq Ev RES_OPTIONS -environment variable is explained in -.Xr resolver 5 . -Initialization normally occurs on the first call -to one of the following routines. -.Pp -The -.Fn res_query -function provides an interface to the server query mechanism. -It constructs a query, sends it to the local server, -awaits a response, and makes preliminary checks on the reply. -The query requests information of the specified -.Fa type -and -.Fa class -for the specified fully-qualified domain name -.Fa dname . -The reply message is left in the -.Fa answer -buffer with length -.Fa anslen -supplied by the caller. -.Pp -The -.Fn res_search -routine makes a query and awaits a response like -.Fn res_query , -but in addition, it implements the default and search rules -controlled by the -.Dv RES_DEFNAMES -and -.Dv RES_DNSRCH -options. -It returns the first successful reply. -.Pp -The remaining routines are lower-level routines used by -.Fn res_query . -The -.Fn res_mkquery -function -constructs a standard query message and places it in -.Fa buf . -It returns the size of the query, or \-1 if the query is -larger than -.Fa buflen . -The query type -.Fa op -is usually -.Dv QUERY , -but can be any of the query types defined in -.Aq Pa arpa/nameser.h . -The domain name for the query is given by -.Fa dname . -.Fa Newrr -is currently unused but is intended for making update messages. -.Pp -The -.Fn res_send -routine -sends a pre-formatted query and returns an answer. -It will call -.Fn res_init -if -.Dv RES_INIT -is not set, send the query to the local name server, and -handle timeouts and retries. -The length of the reply message is returned, or -\-1 if there were errors. -.Pp -The -.Fn dn_comp -function -compresses the domain name -.Fa exp_dn -and stores it in -.Fa comp_dn . -The size of the compressed name is returned or \-1 if there were errors. -The size of the array pointed to by -.Fa comp_dn -is given by -.Fa length . -The compression uses -an array of pointers -.Fa dnptrs -to previously-compressed names in the current message. -The first pointer points to -the beginning of the message and the list ends with -.Dv NULL . -The limit to the array is specified by -.Fa lastdnptr . -A side effect of -.Fn dn_comp -is to update the list of pointers for -labels inserted into the message -as the name is compressed. -If -.Em dnptr -is -.Dv NULL , -names are not compressed. -If -.Fa lastdnptr -is -.Dv NULL , -the list of labels is not updated. -.Pp -The -.Fn dn_expand -entry -expands the compressed domain name -.Fa comp_dn -to a full domain name -The compressed name is contained in a query or reply message; -.Fa msg -is a pointer to the beginning of the message. -The uncompressed name is placed in the buffer indicated by -.Fa exp_dn -which is of size -.Fa length . -The size of compressed name is returned or \-1 if there was an error. -.Pp -The -.Fn dn_skipname -function skips over a compressed domain name, which starts at a location -pointed to by -.Fa comp_dn . -The compressed name is contained in a query or reply message; -.Fa eom -is a pointer to the end of the message. -The size of compressed name is returned or \-1 if there was -an error. -.Pp -The -.Fn ns_get16 -function gets a 16-bit quantity from a buffer pointed to by -.Fa src . -.Pp -The -.Fn ns_get32 -function gets a 32-bit quantity from a buffer pointed to by -.Fa src . -.Pp -The -.Fn ns_put16 -function puts a 16-bit quantity -.Fa src -to a buffer pointed to by -.Fa dst . -.Pp -The -.Fn ns_put32 -function puts a 32-bit quantity -.Fa src -to a buffer pointed to by -.Fa dst . -.Sh FILES -.Bl -tag -width /etc/resolv.conf -.It Pa /etc/resolv.conf -The configuration file, -see -.Xr resolver 5 . -.El -.Sh SEE ALSO -.Xr gethostbyname 3 , -.Xr resolver 5 , -.Xr hostname 7 , -.Xr named 8 -.Pp -.%T RFC1032 , -.%T RFC1033 , -.%T RFC1034 , -.%T RFC1035 , -.%T RFC974 -.Rs -.%T "Name Server Operations Guide for BIND" -.Re -.Sh HISTORY -The -.Nm -function appeared in -.Bx 4.3 . diff --git a/net/send-fbsd.c b/net/send-fbsd.c new file mode 100644 index 0000000..904fdac --- /dev/null +++ b/net/send-fbsd.c @@ -0,0 +1,64 @@ +/* + * 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[] = "@(#)send.c 8.2 (Berkeley) 2/21/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/net/send.c,v 1.3 2002/03/22 21:52:30 obrien Exp $"); + +#include "namespace.h" +#include +#include + +#include +#include "un-namespace.h" + +#ifdef VARIANT_CANCELABLE +ssize_t __sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); +#else /* !VARIANT_CANCELABLE */ +ssize_t __sendto_nocancel(int, const void *, size_t, int, const struct sockaddr *, socklen_t); +#endif /* VARIANT_CANCELABLE */ + +ssize_t +send(s, msg, len, flags) + int s, flags; + size_t len; + const void *msg; +{ +#ifdef VARIANT_CANCELABLE + return (__sendto(s, msg, len, flags, NULL, 0)); +#else /* !VARIANT_CANCELABLE */ + return (__sendto_nocancel(s, msg, len, flags, NULL, 0)); +#endif /* VARIANT_CANCELABLE */ +} diff --git a/net/sockatmark-fbsd.c b/net/sockatmark-fbsd.c new file mode 100644 index 0000000..497ce7f --- /dev/null +++ b/net/sockatmark-fbsd.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2002 William C. Fenner. 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 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/net/sockatmark.c,v 1.1 2002/12/13 22:22:55 fenner Exp $ + */ +#include + +int sockatmark(int s) +{ + int atmark; + + if (ioctl(s, SIOCATMARK, &atmark) == -1) + return -1; + return atmark; +} diff --git a/net/sockatmark.3 b/net/sockatmark.3 new file mode 100644 index 0000000..0c09189 --- /dev/null +++ b/net/sockatmark.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2002 William C. Fenner. 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 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/net/sockatmark.3,v 1.4 2002/12/19 09:40:22 ru Exp $ +.\" +.Dd October 13, 2002 +.Dt SOCKATMARK 3 +.Os +.Sh NAME +.Nm sockatmark +.Nd determine whether the read pointer is at the OOB mark +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/socket.h +.Ft int +.Fn sockatmark "int s" +.Sh DESCRIPTION +To find out if the read pointer is currently pointing at +the mark in the data stream, the +.Fn sockatmark +function is provided. +If +.Fn sockatmark +returns 1, the next read will return data +after the mark. +Otherwise (assuming out of band data has arrived), +the next read will provide data sent by the client prior +to transmission of the out of band signal. +The routine used +in the remote login process to flush output on receipt of an +interrupt or quit signal is shown below. +It reads the normal data up to the mark (to discard it), +then reads the out-of-band byte. +.Bd -literal -offset indent +#include +\&... +oob() +{ + int out = FWRITE, mark; + char waste[BUFSIZ]; + + /* flush local terminal output */ + ioctl(1, TIOCFLUSH, (char *)&out); + for (;;) { + if ((mark = sockatmark(rem)) < 0) { + perror("sockatmark"); + break; + } + if (mark) + break; + (void) read(rem, waste, sizeof (waste)); + } + if (recv(rem, &mark, 1, MSG_OOB) < 0) { + perror("recv"); + ... + } + ... +} +.Ed +.Sh RETURN VALUES +Upon successful completion, the +.Fn sockatmark +function returns the value 1 if the read pointer is pointing at +the OOB mark, 0 if it is not. +Otherwise, the value \-1 is returned +and the global variable +.Va errno +is set to +indicate the error. +.Sh ERRORS +The +.Fn sockatmark +call fails if: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa s +argument +is not a valid descriptor. +.It Bq Er ENOTTY +The +.Fa s +argument +is a descriptor for a file, not a socket. +.El +.Sh SEE ALSO +.Xr recv 2 , +.Xr send 2 +.Sh HISTORY +The +.Fn sockatmark +function was introduced by +.St -p1003.1-2001 , +to standardize the historical +.Dv SIOCATMARK +.Xr ioctl 2 . +The +.Er ENOTTY +error instead of the usual +.Er ENOTSOCK +is to match the historical behavior of +.Dv SIOCATMARK . diff --git a/nls/FreeBSD/msgcat.c.patch b/nls/FreeBSD/msgcat.c.patch index 6a531ba..e267fae 100644 --- a/nls/FreeBSD/msgcat.c.patch +++ b/nls/FreeBSD/msgcat.c.patch @@ -1,6 +1,6 @@ ---- /Network/Servers/hills/Volumes/capanna/josborne/work-area/PR-4416984/Libc/nls/FreeBSD/msgcat.c 2004-11-25 11:38:30.000000000 -0800 -+++ msgcat.c 2006-02-21 12:46:25.000000000 -0800 -@@ -45,16 +45,23 @@ +--- 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 @@ #include #include #include @@ -19,14 +19,13 @@ -#include "../locale/setlocale.h" /* for ENCODING_LEN */ +#include "setlocale.h" /* for ENCODING_LEN */ + -+#ifndef htonll -+#define htonll(x) OSSwapHostToBigInt64(x) ++#ifndef ntohll +#define ntohll(x) OSSwapBigToHostInt64(x) +#endif #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 +94,7 @@ +@@ -87,7 +93,7 @@ return (loadCat(name)); if (type == NL_CAT_LOCALE) @@ -35,7 +34,7 @@ else lang = getenv("LANG"); -@@ -210,21 +217,21 @@ +@@ -210,21 +216,21 @@ #define LOOKUP(PARENT, CHILD, ID, NUM, SET) { \ lo = 0; \ @@ -51,19 +50,19 @@ while (TRUE) { \ CHILD = PARENT->SET + cur; \ - if (CHILD->ID == ID) \ -+ if (htonl(CHILD->ID) == ID) \ ++ if (ntohl(CHILD->ID) == ID) \ break; \ - if (CHILD->ID < ID) { \ -+ if (htonl(CHILD->ID) < ID) { \ ++ if (ntohl(CHILD->ID) < ID) { \ lo = cur + 1; \ - if (hi > cur + (ID - CHILD->ID) + 1) \ - hi = cur + (ID - CHILD->ID) + 1; \ -+ if (hi > cur + (ID - htonl(CHILD->ID)) + 1) \ -+ hi = cur + (ID - htonl(CHILD->ID)) + 1; \ ++ if (hi > cur + (ID - ntohl(CHILD->ID)) + 1) \ ++ hi = cur + (ID - ntohl(CHILD->ID)) + 1; \ dir = 1; \ } else { \ hi = cur; \ -@@ -240,32 +247,28 @@ +@@ -240,32 +246,28 @@ } static MCSetT * @@ -73,7 +72,8 @@ +MCGetSet(MCCatT *cat, int setId) { MCSetT *set; - long lo, hi, cur, dir; +- long lo, hi, cur, dir; ++ int32_t lo, hi, cur, dir; if (cat == NULL || setId <= 0) return (NULL); @@ -91,118 +91,129 @@ +MCGetMsg(MCSetT *set, int msgId) { MCMsgT *msg; - long lo, hi, cur, dir; +- long lo, hi, cur, dir; ++ int32_t lo, hi, cur, dir; if (set == NULL || set->invalid || msgId <= 0) return (NULL); - LOOKUP(set, msg, msgId, numMsgs, u.msgs); -+ LOOKUP(set, msg, msgId, htonl(set->numMsgs), u.msgs); ++ LOOKUP(set, msg, msgId, ntohl(set->numMsgs), u.msgs); return (msg); } -@@ -377,27 +380,30 @@ +@@ -357,7 +359,7 @@ + MCHeaderT header; + MCCatT *cat; + MCSetT *set; +- long i; ++ int32_t i; + off_t nextSet; + int saverr; + +@@ -377,27 +379,30 @@ strncmp(header.magic, MCMagic, MCMagicLen) != 0) CORRUPT(); - if (header.majorVer != MCMajorVer) { -+ if (htonl(header.majorVer) != MCMajorVer) { ++ if (ntohl(header.majorVer) != MCMajorVer) { (void)fclose(cat->fp); free(cat); - (void)fprintf(stderr, "%s: %s is version %ld, we need %ld.\n", - _errowner, catpath, header.majorVer, MCMajorVer); -+ if (OSSwapInt32(htonl(header.majorVer)) == MCMajorVer) { ++ if (OSSwapInt32(ntohl(header.majorVer)) == MCMajorVer) { + (void)fprintf(stderr, "%s: %s is the wrong byte ordering.\n", _errowner, catpath); + } else { -+ (void)fprintf(stderr, "%s: %s is version %ld, we need %ld.\n", _errowner, catpath, htonl(header.majorVer), MCMajorVer); ++ (void)fprintf(stderr, "%s: %s is version %d, we need %d.\n", _errowner, catpath, (int)ntohl(header.majorVer), MCMajorVer); + } NLRETERR(EFTYPE); } - if (header.numSets <= 0) { -+ if (htonl(header.numSets) <= 0) { ++ if (ntohl(header.numSets) <= 0) { (void)fclose(cat->fp); free(cat); - (void)fprintf(stderr, "%s: %s has %ld sets!\n", +- (void)fprintf(stderr, "%s: %s has %ld sets!\n", - _errowner, catpath, header.numSets); -+ _errowner, catpath, htonl(header.numSets)); ++ (void)fprintf(stderr, "%s: %s has %d sets!\n", ++ _errowner, catpath, (int)ntohl(header.numSets)); NLRETERR(EFTYPE); } - cat->numSets = header.numSets; - if ((cat->sets = (MCSetT *)malloc(sizeof(MCSetT) * header.numSets)) == -+ cat->numSets = htonl(header.numSets); ++ cat->numSets = ntohl(header.numSets); + if ((cat->sets = (MCSetT *)malloc(sizeof(MCSetT) * cat->numSets)) == NULL) NOSPACE(); - nextSet = header.firstSet; -+ nextSet = htonll(header.firstSet); ++ nextSet = ntohll(header.firstSet); for (i = 0; i < cat->numSets; ++i) { if (fseeko(cat->fp, nextSet, SEEK_SET) == -1) { __nls_free_resources(cat, i); -@@ -414,7 +420,7 @@ +@@ -414,7 +419,7 @@ /* if it's invalid, skip over it (and backup 'i') */ if (set->invalid) { --i; - nextSet = set->nextSet; -+ nextSet = htonll(set->nextSet); ++ nextSet = ntohll(set->nextSet); continue; } #if 0 -@@ -432,7 +438,7 @@ +@@ -432,7 +437,7 @@ } else #endif set->invalid = TRUE; - nextSet = set->nextSet; -+ nextSet = htonll(set->nextSet); ++ nextSet = ntohll(set->nextSet); } #if 0 if (cat->loadType == MCLoadAll) { -@@ -453,11 +459,11 @@ +@@ -453,11 +458,11 @@ int saverr; /* Get the data */ - if (fseeko(cat->fp, set->data.off, SEEK_SET) == -1) -+ if (fseeko(cat->fp, htonll(set->data.off), SEEK_SET) == -1) ++ if (fseeko(cat->fp, ntohll(set->data.off), SEEK_SET) == -1) return (0); - if ((set->data.str = malloc(set->dataLen)) == NULL) -+ if ((set->data.str = malloc(htonl(set->dataLen))) == NULL) ++ if ((set->data.str = malloc(ntohl(set->dataLen))) == NULL) return (-1); - if (fread(set->data.str, set->dataLen, 1, cat->fp) != 1) { -+ if (fread(set->data.str, htonl(set->dataLen), 1, cat->fp) != 1) { ++ if (fread(set->data.str, ntohl(set->dataLen), 1, cat->fp) != 1) { saverr = errno; free(set->data.str); errno = saverr; -@@ -465,13 +471,13 @@ +@@ -465,13 +470,13 @@ } /* Get the messages */ - if (fseeko(cat->fp, set->u.firstMsg, SEEK_SET) == -1) { -+ if (fseeko(cat->fp, htonll(set->u.firstMsg), SEEK_SET) == -1) { ++ if (fseeko(cat->fp, ntohll(set->u.firstMsg), SEEK_SET) == -1) { saverr = errno; free(set->data.str); errno = saverr; return (0); } - if ((set->u.msgs = (MCMsgT *)malloc(sizeof(MCMsgT) * set->numMsgs)) == -+ if ((set->u.msgs = (MCMsgT *)malloc(sizeof(MCMsgT) * htonl(set->numMsgs))) == ++ if ((set->u.msgs = (MCMsgT *)malloc(sizeof(MCMsgT) * ntohl(set->numMsgs))) == NULL) { saverr = errno; free(set->data.str); -@@ -479,7 +485,7 @@ +@@ -479,7 +484,7 @@ return (-1); } - for (i = 0; i < set->numMsgs; ++i) { -+ for (i = 0; i < htonl(set->numMsgs); ++i) { ++ for (i = 0; i < ntohl(set->numMsgs); ++i) { msg = set->u.msgs + i; if (fread(msg, sizeof(*msg), 1, cat->fp) != 1) { saverr = errno; -@@ -492,7 +498,7 @@ +@@ -492,7 +497,7 @@ --i; continue; } - msg->msg.str = (char *)(set->data.str + msg->msg.off); -+ msg->msg.str = (char *)(set->data.str + htonll(msg->msg.off)); ++ msg->msg.str = (char *)(set->data.str + ntohll(msg->msg.off)); } set->invalid = FALSE; return (1); diff --git a/nls/FreeBSD/msgcat.h.patch b/nls/FreeBSD/msgcat.h.patch new file mode 100644 index 0000000..8b40fef --- /dev/null +++ b/nls/FreeBSD/msgcat.h.patch @@ -0,0 +1,88 @@ +--- 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 @@ + */ + + /* 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 @@ + struct _MCSetT *set; + } MCOffsetT; + ++#ifdef __LP64__ ++#pragma pack(4) ++#endif /* __LP64__ */ + /* + * MCMsgT - Message structure (disk and runtime) + */ + typedef struct _MCMsgT { +- long msgId; /* Id of this message */ ++ int32_t msgId; /* Id of this message */ + MCOffsetT msg; /* Relative offset on disk or pointer in memory */ +- long invalid; /* Valid on disk, loaded in memory */ ++ int32_t invalid; /* Valid on disk, loaded in memory */ + } MCMsgT; + + /* + * MCSetT - Set structure (disk and runtime) + */ + typedef struct _MCSetT { +- long setId; /* Id of this set */ ++ int32_t setId; /* Id of this set */ + off_t nextSet; /* Offset of next set on disk */ + union { + off_t firstMsg; /* Offset to first Msg (while on disk) */ + MCMsgT *msgs; /* Pointer to array of msgs (in mem, loaded) */ + } u; + MCOffsetT data; /* Offset to data, or pointer to data */ +- long dataLen; /* Length of data area on disk */ +- long numMsgs; /* Number of messages */ +- long invalid; /* Valid on disk, loaded in memory */ ++ int32_t dataLen; /* Length of data area on disk */ ++ int32_t numMsgs; /* Number of messages */ ++ int32_t invalid; /* Valid on disk, loaded in memory */ + } MCSetT; ++#ifdef __LP64__ ++#pragma pack() ++#endif /* __LP64__ */ + + /* + * 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 @@ + */ + typedef struct { + char magic[MCMagicLen]; /* Magic cookie "*nazgul*" */ +- long majorVer; /* ++ on incompatible changes */ +- long minorVer; /* ++ on compatible changes */ +- long flags; /* Informational flags */ +- long numSets; /* Number of valid Sets */ ++ int32_t majorVer; /* ++ on incompatible changes */ ++ int32_t minorVer; /* ++ on compatible changes */ ++ int32_t flags; /* Informational flags */ ++ int32_t numSets; /* Number of valid Sets */ + off_t firstSet; /* Offset of first set on disk */ + } MCHeaderT; + diff --git a/nls/Makefile.inc b/nls/Makefile.inc index 9c4ee6a..e25b6c6 100644 --- a/nls/Makefile.inc +++ b/nls/Makefile.inc @@ -9,7 +9,7 @@ FBSDHDRS= msgcat.h .include "Makefile.fbsd_end" # Install msgcat.h for usage by gencat (in adv_cmds) -LOCALHDRS+= ${SYMROOT}/msgcat.h +LOCALHDRS+= ${.CURDIR}/nls/msgcat.h .if ${LIB} == "c" .include "Makefile.fbsd_begin" diff --git a/nls/catclose.3 b/nls/catclose.3 new file mode 120000 index 0000000..5f1c02f --- /dev/null +++ b/nls/catclose.3 @@ -0,0 +1 @@ +./catclose.3 \ No newline at end of file diff --git a/nls/catgets.3 b/nls/catgets.3 new file mode 120000 index 0000000..06d6838 --- /dev/null +++ b/nls/catgets.3 @@ -0,0 +1 @@ +./catgets.3 \ No newline at end of file diff --git a/nls/catopen.3 b/nls/catopen.3 new file mode 120000 index 0000000..9c44bf2 --- /dev/null +++ b/nls/catopen.3 @@ -0,0 +1 @@ +./catopen.3 \ No newline at end of file diff --git a/nls/msgcat-fbsd.c b/nls/msgcat-fbsd.c new file mode 100644 index 0000000..c647da6 --- /dev/null +++ b/nls/msgcat-fbsd.c @@ -0,0 +1,504 @@ +/*********************************************************** +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 + +******************************************************************/ + +#include +__FBSDID("$FreeBSD: src/lib/libc/nls/msgcat.c,v 1.48 2003/10/29 10:45:01 tjr Exp $"); + +/* + * We need a better way of handling errors than printing text. I need + * to add an error handling routine. + */ + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "msgcat.h" +#include "setlocale.h" /* for ENCODING_LEN */ + +#ifndef ntohll +#define ntohll(x) OSSwapBigToHostInt64(x) +#endif + +#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" + +#define TRUE 1 +#define FALSE 0 + +#define NLERR ((nl_catd) -1) +#define NLRETERR(errc) { errno = errc; return (NLERR); } + +static nl_catd loadCat(); +static int loadSet(); +static void __nls_free_resources(); + +nl_catd +catopen(name, type) + __const char *name; + int type; +{ + int spcleft, saverr; + char path[PATH_MAX]; + char *nlspath, *lang, *base, *cptr, *pathP, *tmpptr; + char *cptr1, *plang, *pter, *pcode; + struct stat sbuf; + + if (name == NULL || *name == '\0') + NLRETERR(EINVAL); + + /* is it absolute path ? if yes, load immediately */ + if (strchr(name, '/') != NULL) + return (loadCat(name)); + + if (type == NL_CAT_LOCALE) + lang = (char *)querylocale(LC_MESSAGES_MASK, NULL); + else + lang = getenv("LANG"); + + if (lang == NULL || *lang == '\0' || strlen(lang) > ENCODING_LEN || + (lang[0] == '.' && + (lang[1] == '\0' || (lang[1] == '.' && lang[2] == '\0'))) || + strchr(lang, '/') != NULL) + lang = "C"; + + if ((plang = cptr1 = strdup(lang)) == NULL) + return (NLERR); + if ((cptr = strchr(cptr1, '@')) != NULL) + *cptr = '\0'; + pter = pcode = ""; + if ((cptr = strchr(cptr1, '_')) != NULL) { + *cptr++ = '\0'; + pter = cptr1 = cptr; + } + if ((cptr = strchr(cptr1, '.')) != NULL) { + *cptr++ = '\0'; + pcode = cptr; + } + + if ((nlspath = getenv("NLSPATH")) == NULL || issetugid()) + nlspath = _DEFAULT_NLS_PATH; + + if ((base = cptr = strdup(nlspath)) == NULL) { + saverr = errno; + free(plang); + errno = saverr; + return (NLERR); + } + + while ((nlspath = strsep(&cptr, ":")) != NULL) { + pathP = path; + if (*nlspath) { + for (; *nlspath; ++nlspath) { + if (*nlspath == '%') { + switch (*(nlspath + 1)) { + case 'l': + tmpptr = plang; + break; + case 't': + tmpptr = pter; + break; + case 'c': + tmpptr = pcode; + break; + case 'L': + tmpptr = lang; + break; + case 'N': + tmpptr = (char *)name; + break; + case '%': + ++nlspath; + /* fallthrough */ + default: + if (pathP - path >= + sizeof(path) - 1) + goto too_long; + *(pathP++) = *nlspath; + continue; + } + ++nlspath; + put_tmpptr: + spcleft = sizeof(path) - + (pathP - path) - 1; + if (strlcpy(pathP, tmpptr, spcleft) >= + spcleft) { + too_long: + free(plang); + free(base); + NLRETERR(ENAMETOOLONG); + } + pathP += strlen(tmpptr); + } else { + if (pathP - path >= sizeof(path) - 1) + goto too_long; + *(pathP++) = *nlspath; + } + } + *pathP = '\0'; + if (stat(path, &sbuf) == 0) { + free(plang); + free(base); + return (loadCat(path)); + } + } else { + tmpptr = (char *)name; + --nlspath; + goto put_tmpptr; + } + } + free(plang); + free(base); + NLRETERR(ENOENT); +} + +/* + * We've got an odd situation here. The odds are real good that the + * number we are looking for is almost the same as the index. We could + * use the index, check the difference and do something intelligent, but + * I haven't quite figured out what's intelligent. + * + * Here's a start. + * Take an id N. If there are > N items in the list, then N cannot + * be more than N items from the start, since otherwise there would + * have to be duplicate items. So we can safely set the top to N+1 + * (after taking into account that ids start at 1, and arrays at 0) + * + * Let's say we are at position P, and we are looking for N, but have + * V. If N > V, then the furthest away that N could be is + * P + (N-V). So we can safely set hi to P+(N-V)+1. For example: + * We are looking for 10, but have 8 + * 8 ? ? ? ? + * >=9 >=10 >=11 + * + */ + +#define LOOKUP(PARENT, CHILD, ID, NUM, SET) { \ + lo = 0; \ + if (ID - 1 < NUM) { \ + cur = ID - 1; \ + hi = ID; \ + } else { \ + hi = NUM; \ + cur = (hi - lo) / 2; \ + } \ + while (TRUE) { \ + CHILD = PARENT->SET + cur; \ + if (ntohl(CHILD->ID) == ID) \ + break; \ + if (ntohl(CHILD->ID) < ID) { \ + lo = cur + 1; \ + if (hi > cur + (ID - ntohl(CHILD->ID)) + 1) \ + hi = cur + (ID - ntohl(CHILD->ID)) + 1; \ + dir = 1; \ + } else { \ + hi = cur; \ + dir = -1; \ + } \ + if (lo >= hi) \ + return (NULL); \ + if (hi - lo == 1) \ + cur += dir; \ + else \ + cur += ((hi - lo) / 2) * dir; \ + } \ +} + +static MCSetT * +MCGetSet(MCCatT *cat, int setId) +{ + MCSetT *set; + int32_t lo, hi, cur, dir; + + if (cat == NULL || setId <= 0) + return (NULL); + LOOKUP(cat, set, setId, cat->numSets, sets); + if (set->invalid && loadSet(cat, set) <= 0) + return (NULL); + return (set); +} + +static MCMsgT * +MCGetMsg(MCSetT *set, int msgId) +{ + MCMsgT *msg; + int32_t lo, hi, cur, dir; + + if (set == NULL || set->invalid || msgId <= 0) + return (NULL); + LOOKUP(set, msg, msgId, ntohl(set->numMsgs), u.msgs); + return (msg); +} + +char * +catgets(catd, setId, msgId, dflt) + nl_catd catd; + int setId; + int msgId; + __const char *dflt; +{ + MCMsgT *msg; + MCCatT *cat = (MCCatT *)catd; + __const char *cptr; + + if (catd == NULL || catd == NLERR) + return ((char *)dflt); + msg = MCGetMsg(MCGetSet(cat, setId), msgId); + if (msg != NULL) + cptr = msg->msg.str; + else + cptr = dflt; + return ((char *)cptr); +} + +int +catclose(catd) + nl_catd catd; +{ + MCCatT *cat = (MCCatT *)catd; + + if (catd == NULL || catd == NLERR) { + errno = EBADF; + return (-1); + } +#if 0 + if (cat->loadType != MCLoadAll) +#endif + (void)fclose(cat->fp); + __nls_free_resources(cat, cat->numSets); + free(cat); + return (0); +} + +/* + * Internal routines + */ + +/* Note that only malloc failures are allowed to return an error */ +static char *_errowner = "Message Catalog System"; + +#define CORRUPT() { \ + (void)fclose(cat->fp); \ + (void)fprintf(stderr, "%s: corrupt file.", _errowner); \ + free(cat); \ + NLRETERR(EFTYPE); \ +} + +#define NOSPACE() { \ + saverr = errno; \ + (void)fclose(cat->fp); \ + (void)fprintf(stderr, "%s: no more memory.", _errowner); \ + free(cat); \ + errno = saverr; \ + return (NLERR); \ +} + +static void +__nls_free_resources(cat, i) + MCCatT *cat; + int i; +{ + MCSetT *set; + int j; + + for (j = 0; j < i; j++) { + set = cat->sets + j; + if (!set->invalid) { + free(set->data.str); + free(set->u.msgs); + } + } + free(cat->sets); +} + +static nl_catd +loadCat(catpath) + __const char *catpath; +{ + MCHeaderT header; + MCCatT *cat; + MCSetT *set; + int32_t i; + off_t nextSet; + int saverr; + + if ((cat = (MCCatT *)malloc(sizeof(MCCatT))) == NULL) + return (NLERR); + cat->loadType = MCLoadBySet; + + if ((cat->fp = fopen(catpath, "r")) == NULL) { + saverr = errno; + free(cat); + errno = saverr; + return (NLERR); + } + (void)_fcntl(fileno(cat->fp), F_SETFD, FD_CLOEXEC); + + if (fread(&header, sizeof(header), 1, cat->fp) != 1 || + strncmp(header.magic, MCMagic, MCMagicLen) != 0) + CORRUPT(); + + if (ntohl(header.majorVer) != MCMajorVer) { + (void)fclose(cat->fp); + free(cat); + if (OSSwapInt32(ntohl(header.majorVer)) == MCMajorVer) { + (void)fprintf(stderr, "%s: %s is the wrong byte ordering.\n", _errowner, catpath); + } else { + (void)fprintf(stderr, "%s: %s is version %d, we need %d.\n", _errowner, catpath, (int)ntohl(header.majorVer), MCMajorVer); + } + NLRETERR(EFTYPE); + } + if (ntohl(header.numSets) <= 0) { + (void)fclose(cat->fp); + free(cat); + (void)fprintf(stderr, "%s: %s has %d sets!\n", + _errowner, catpath, (int)ntohl(header.numSets)); + NLRETERR(EFTYPE); + } + + cat->numSets = ntohl(header.numSets); + if ((cat->sets = (MCSetT *)malloc(sizeof(MCSetT) * cat->numSets)) == + NULL) + NOSPACE(); + + nextSet = ntohll(header.firstSet); + for (i = 0; i < cat->numSets; ++i) { + if (fseeko(cat->fp, nextSet, SEEK_SET) == -1) { + __nls_free_resources(cat, i); + CORRUPT(); + } + + /* read in the set header */ + set = cat->sets + i; + if (fread(set, sizeof(*set), 1, cat->fp) != 1) { + __nls_free_resources(cat, i); + CORRUPT(); + } + + /* if it's invalid, skip over it (and backup 'i') */ + if (set->invalid) { + --i; + 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; + 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; +{ + MCMsgT *msg; + int i; + int saverr; + + /* Get the data */ + if (fseeko(cat->fp, ntohll(set->data.off), SEEK_SET) == -1) + return (0); + if ((set->data.str = malloc(ntohl(set->dataLen))) == NULL) + return (-1); + if (fread(set->data.str, ntohl(set->dataLen), 1, cat->fp) != 1) { + saverr = errno; + free(set->data.str); + errno = saverr; + return (0); + } + + /* Get the messages */ + if (fseeko(cat->fp, ntohll(set->u.firstMsg), SEEK_SET) == -1) { + saverr = errno; + free(set->data.str); + errno = saverr; + return (0); + } + if ((set->u.msgs = (MCMsgT *)malloc(sizeof(MCMsgT) * ntohl(set->numMsgs))) == + NULL) { + saverr = errno; + free(set->data.str); + errno = saverr; + return (-1); + } + + for (i = 0; i < ntohl(set->numMsgs); ++i) { + msg = set->u.msgs + i; + if (fread(msg, sizeof(*msg), 1, cat->fp) != 1) { + saverr = errno; + free(set->u.msgs); + free(set->data.str); + errno = saverr; + return (0); + } + if (msg->invalid) { + --i; + continue; + } + msg->msg.str = (char *)(set->data.str + ntohll(msg->msg.off)); + } + set->invalid = FALSE; + return (1); +} diff --git a/nls/msgcat.h b/nls/msgcat.h new file mode 100644 index 0000000..51b009a --- /dev/null +++ b/nls/msgcat.h @@ -0,0 +1,161 @@ +/* $FreeBSD: src/lib/libc/nls/msgcat.h,v 1.8 2000/09/03 21:05:10 ache Exp $ */ + +#ifndef _MSGCAT_H_ +#define _MSGCAT_H_ + + +/*********************************************************** +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 + +******************************************************************/ + + +#include + +/* + * On disk data structures + */ + +/* 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 + +/* + * Critical note here. Sets and Messages *MUST* be stored in ascending + * order. There are stored that way (by specification) in the original + * data file, however in the process of merging in new stuff you might + * mix that up. Don't! The catget stuff does a binary search and will + * totally lose it if these aren't in order (not contiguous mind you, just + * in order. If this turns out to be a major problem this could be enhanced + * by adding a 'sorted' flag to the db, and sorting msgs and sets at load + * time if things aren't sorted, but I'd like not to have to do that. + */ + +/* + * I have tried here to define data structures which can be used + * while the catalog is on disk, and at runtime. + * This is rather dangerous of course, but I think it can be done without + * overly increasing the memory usage, and it makes loading and storing + * somewhat simpler and less prone to accidents. I have also tried to + * define on disk data structures which can be updated in place, so that + * with a very large catalog (e.g. all system errors) you don't have to + * load everything in memory in order to add or update one set. With + * this in mind there are "invalid" flags which allow items to be + * invalidated and thus not loaded at runtime. Note however that although + * I pay attention to these when I load the DB, I do not currently use + * them in gencat (it just reads everything into memory), so there is + * 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 + */ +typedef union { + off_t off; + char *str; + void *ptr; + struct _MCMsgT *msg; + struct _MCSetT *set; +} MCOffsetT; + +#ifdef __LP64__ +#pragma pack(4) +#endif /* __LP64__ */ +/* + * MCMsgT - Message structure (disk and runtime) + */ +typedef struct _MCMsgT { + int32_t msgId; /* Id of this message */ + MCOffsetT msg; /* Relative offset on disk or pointer in memory */ + int32_t invalid; /* Valid on disk, loaded in memory */ +} MCMsgT; + +/* + * MCSetT - Set structure (disk and runtime) + */ +typedef struct _MCSetT { + int32_t setId; /* Id of this set */ + off_t nextSet; /* Offset of next set on disk */ + union { + off_t firstMsg; /* Offset to first Msg (while on disk) */ + MCMsgT *msgs; /* Pointer to array of msgs (in mem, loaded) */ + } u; + MCOffsetT data; /* Offset to data, or pointer to data */ + int32_t dataLen; /* Length of data area on disk */ + int32_t numMsgs; /* Number of messages */ + int32_t invalid; /* Valid on disk, loaded in memory */ +} MCSetT; +#ifdef __LP64__ +#pragma pack() +#endif /* __LP64__ */ + +/* + * 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 */ + off_t firstSet; /* Offset of first set on disk */ +} MCCatT; + +/* + * MCHeaderT - Disk file header + */ +typedef struct { + char magic[MCMagicLen]; /* Magic cookie "*nazgul*" */ + int32_t majorVer; /* ++ on incompatible changes */ + int32_t minorVer; /* ++ on compatible changes */ + int32_t flags; /* Informational flags */ + int32_t numSets; /* Number of valid Sets */ + off_t firstSet; /* Offset of first set on disk */ +} MCHeaderT; + +/* Some flags */ +#define MC68KByteOrder 0x01 +#define MCn86ByteOrder 0x02 + +#endif /* !_MSGCAT_H_ */ diff --git a/patchHeaders b/patchHeaders new file mode 100755 index 0000000..603693d --- /dev/null +++ b/patchHeaders @@ -0,0 +1,112 @@ +#!/usr/bin/perl +# +# Copyright (c) 2006, 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@ +# +# patchheaders srcdir destdir +# +# The last path component of srcdir is replicated in destdir, with the +# __DARWIN_ALIAS* and __DARWIN_EXTSN macro wrapped so that Libc can set +# the symbol decoration independently: +# +# #ifndef LIBC_ALIAS_FOO +# int foo(int) __DARWIN_ALIAS(foo); +# #else /* LIBC_ALIAS_FOO */ +# int foo(int) LIBC_ALIAS(foo); +# #endif /* !LIBC_ALIAS_FOO */ + +use strict; +use IO::File; +use File::Basename (); +use File::Find (); +use File::Path (); +use File::Spec; + +my $MyName = File::Basename::basename($0); +my $dest; + +sub process { + my($path, $file) = @_; + local $_; + my $p = IO::File->new($path, 'r'); + die "$MyName: Can't open $path: $!\n" unless defined($p); + my $f = IO::File->new($file, 'w'); + die "$MyName: Can't open $file: $!\n" unless defined($f); + my @save; + while(<$p>) { + if(/^\S/ or /^\s*$/) { + my $n = scalar(@save); + my $sym; + if($n > 0) { + my($sym) = ($save[$n - 1] =~ /__DARWIN_(?:10\d+|ALIAS|EXTSN|INODE64)[^(]*\(([^)]*)\)/); + if(defined($sym)) { + if(defined($path)) { + print " $path\n"; + undef($path); + } + $sym =~ s/^\s+//; + $sym =~ s/\s+$//; + $sym =~ tr/a-z/A-Z/; + $f->print("#ifndef LIBC_ALIAS_$sym\n"); + } + $f->print(@save); + if(defined($sym)) { + $save[$n - 1] =~ s/__DARWIN_(10\d+|ALIAS|EXTSN|INODE64)/LIBC_$1/; + $f->print("#else /* LIBC_ALIAS_$sym */\n"); + $f->print(@save); + $f->print("#endif /* !LIBC_ALIAS_$sym */\n"); + } + } + if(/^#/) { + $f->print($_); + @save = (); + } else { + @save = ($_); + } + } else { + push(@save, $_); + } + } + $f->print(@save); +} + +sub usage { + die "Usage: $MyName srcdir dstdir\n"; +} + +sub wanted { + if(-d $File::Find::name) { + #print "DIR: $File::Find::name\n"; + my $dir = File::Spec->join($dest, $File::Find::name); + File::Path::mkpath($dir, 0, 0755); + } else { + #print "FIL: $File::Find::name\n"; + my $file = File::Spec->join($dest, $File::Find::name); + process($File::Find::name, $file); + } +} + +usage() unless scalar(@ARGV) == 2; +my $start = File::Basename::dirname($ARGV[0]); +chdir($start) || die "$MyName: chdir($start): $!\n"; +$dest = $ARGV[1]; +File::Path::mkpath($dest, 0, 0755); +File::Find::find({wanted => \&wanted, no_chdir => 1}, File::Basename::basename($ARGV[0])); diff --git a/posix1e/Makefile.inc b/posix1e/Makefile.inc index 7203296..60f217e 100644 --- a/posix1e/Makefile.inc +++ b/posix1e/Makefile.inc @@ -16,7 +16,6 @@ MAN3 += acl.3 \ acl_clear_perms.3 \ acl_copy_entry.3 \ acl_create_entry.3 \ - acl_delete.3 \ acl_delete_entry.3 \ acl_delete_flag_np.3 \ acl_delete_perm.3 \ @@ -39,16 +38,25 @@ MAN3 += acl.3 \ acl_to_text.3 \ acl_valid.3 -MLINKS+=acl_create_entry.3 acl_create_entry_np.3 \ - acl_delete.3 acl_delete_file_np.3 \ - acl_delete.3 acl_delete_fd_np.3 \ - acl_get.3 acl_get_file.3 \ - acl_get.3 acl_get_fd.3 \ - acl_get.3 acl_get_fd_np.3 \ - acl_set.3 acl_set_file.3 \ - acl_set.3 acl_set_fd.3 \ - acl_set.3 acl_set_fd_np.3 \ - acl_valid.3 acl_valid_file_np.3 \ - acl_valid.3 acl_valid_fd_np.3 +MLINKS+= acl_create_entry.3 acl_create_entry_np.3 + +#MLINKS+= acl_delete.3 acl_delete_fd_np.3 \ +# acl_delete.3 acl_delete_file_np.3 \ +# acl_delete.3 acl_delete_link_np.3 + +MLINKS+= acl_get.3 acl_get_fd.3 \ + acl_get.3 acl_get_fd_np.3 \ + acl_get.3 acl_get_file.3 \ + acl_get.3 acl_get_link_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 \ + acl_set.3 acl_set_link.3 + + +MLINKS+= acl_valid.3 acl_valid_fd_np.3 \ + acl_valid.3 acl_valid_file_np.3 \ + acl_valid.3 acl_valid_link_np.3 .endif diff --git a/posix1e/acl.3 b/posix1e/acl.3 index 4c79db5..54446b2 100644 --- a/posix1e/acl.3 +++ b/posix1e/acl.3 @@ -178,8 +178,10 @@ routines may change over time, and as such are not documented. They are not intended to be called directly without going through the library. .Sh SEE ALSO -.Xr getfacl 1 , -.Xr setfacl 1 , +.\".Xr getfacl 1 , +.\".Xr setfacl 1 , +.Xr ls 1 , +.Xr chmod 1 , .Xr acl_add_perm 3 , .Xr acl_clear_perms 3 , .Xr acl_copy_entry 3 , diff --git a/posix1e/acl_clear_flags_np.3 b/posix1e/acl_clear_flags_np.3 index a4e4853..04bbb1b 100644 --- a/posix1e/acl_clear_flags_np.3 +++ b/posix1e/acl_clear_flags_np.3 @@ -61,7 +61,7 @@ is not a valid descriptor for a flag set. .Xr acl_add_flag_np 3 , .Xr acl_delete_flag_np 3 , .Xr acl_get_flagset_np 3 , -.Xr acl_set_flagset_np 3 , +.Xr acl_set_flagset_np 3 .Sh AUTHORS .An Michael Smith .An Chris D Fulhaber diff --git a/posix1e/acl_delete_flag_np.3 b/posix1e/acl_delete_flag_np.3 index 157733d..ee5f0c5 100644 --- a/posix1e/acl_delete_flag_np.3 +++ b/posix1e/acl_delete_flag_np.3 @@ -69,7 +69,7 @@ flagset. .Xr acl_add_flag_np 3 , .Xr acl_clear_flags_np 3 , .Xr acl_get_flagset_np 3 , -.Xr acl_set_flagset_np 3 , +.Xr acl_set_flagset_np 3 .Sh AUTHORS .An Michael Smith .An Chris D. Faulhaber diff --git a/posix1e/acl_file.c b/posix1e/acl_file.c index ec899b0..7948bc1 100644 --- a/posix1e/acl_file.c +++ b/posix1e/acl_file.c @@ -73,6 +73,10 @@ acl_get_fd_np(int fd, acl_type_t type) acl_t acl; struct stat sb; + if (type != ACL_TYPE_EXTENDED) { + errno = EINVAL; + return(NULL); + } if ((fsec = filesec_init()) == NULL) return(NULL); @@ -90,6 +94,10 @@ acl_get_file1(const char *path, acl_type_t acl_type, int follow) acl_t acl; struct stat sb; + if (acl_type != ACL_TYPE_EXTENDED) { + errno = EINVAL; + return(NULL); + } if ((fsec = filesec_init()) == NULL) return(NULL); diff --git a/posix1e/acl_get_entry.3 b/posix1e/acl_get_entry.3 index 037ff26..0171fb3 100644 --- a/posix1e/acl_get_entry.3 +++ b/posix1e/acl_get_entry.3 @@ -88,21 +88,8 @@ will return the entry following the previously nominated entry and so forth. .Sh RETURN VALUES If the .Fn acl_get_entry -function successfully obtains an ACL entry, a value of 1 is returned. -If the ACL has no ACL entries, the -.Fn acl_get_entry -returns a value of 0. If the value of -.Fa entry_id -is -.Dv ACL_NEXT_ENTRY -and the last ACL entry in the ACL has already been returned by a -previous call to -.Fn acl_get_entry , -a value of 0 will be returned until a successful call with -.Fa entry_id -of -.Dv ACL_FIRST_ENTRY -is made. Otherwise, a value of -1 will be returned and +function successfully obtains an ACL entry, a value of 0 is returned. +Otherwise, a value of -1 will be returned and the global variable .Va errno will be set to indicate the error. @@ -120,6 +107,14 @@ is neither .Dv ACL_FIRST_ENTRY , .Dv ACL_NEXT_ENTRY or a valid entry index. +.It Bq Er EINVAL +The value of +.Fa entry_id +is +.Dv ACL_NEXT_ENTRY +and the last ACL entry in the ACL has already been returned by a +previous call to +.Fn acl_get_entry . .El .Sh SEE ALSO .Xr acl 3 , diff --git a/posix1e/acl_get_flagset_np.3 b/posix1e/acl_get_flagset_np.3 index 8bb7e3c..0ceb80b 100644 --- a/posix1e/acl_get_flagset_np.3 +++ b/posix1e/acl_get_flagset_np.3 @@ -62,10 +62,10 @@ is not a valid descriptor for an ACL or ACL entry. .El .Sh SEE ALSO .Xr acl 3 , -.Xr acl_add_flag 3 , -.Xr acl_clear_flagss 3 , -.Xr acl_delete_flag 3 , -.Xr acl_set_flagset 3 , +.Xr acl_add_flag_np 3 , +.Xr acl_clear_flags_np 3 , +.Xr acl_delete_flag_np 3 , +.Xr acl_set_flagset_np 3 .Sh AUTHORS .An Michael Smith .An Chris D. Faulhaber diff --git a/posix1e/acl_set_flagset_np.3 b/posix1e/acl_set_flagset_np.3 index 73a7078..8666f07 100644 --- a/posix1e/acl_set_flagset_np.3 +++ b/posix1e/acl_set_flagset_np.3 @@ -26,10 +26,10 @@ .\" $FreeBSD: src/lib/libc/posix1e/acl_set_permset.3,v 1.6 2002/12/18 12:45:09 ru Exp $ .\" .Dd March 10, 2001 -.Dt ACL_SET_FLAGSET 3 +.Dt ACL_SET_FLAGSET_NP 3 .Os .Sh NAME -.Nm acl_set_flagset +.Nm acl_set_flagset_np .Nd set the flags of an ACL or ACL entry .Sh LIBRARY .Lb libc @@ -37,20 +37,20 @@ .In sys/types.h .In sys/acl.h .Ft int -.Fn acl_set_flagset "void *obj" "acl_flagset_t flagset_d" +.Fn acl_set_flagset_np "void *obj" "acl_flagset_t flagset_d" .Sh DESCRIPTION The -.Fn acl_set_flagset +.Fn acl_set_flagset_np function is a nonstandard extension that sets the permissions of the ACL or ACL entry .Fa obj with the flags contained in .Fa flagset_d . .Sh RETURN VALUES -.Rv -std acl_set_flagset +.Rv -std acl_set_flagset_np .Sh ERRORS The -.Fn acl_set_flagset +.Fn acl_set_flagset_np function fails if: .Bl -tag -width Er .It Bq Er EINVAL @@ -63,10 +63,10 @@ is not a valid flagset for .El .Sh SEE ALSO .Xr acl 3 , -.Xr acl_add_flag 3 , -.Xr acl_clear_flags 3 , -.Xr acl_delete_flag 3 , -.Xr acl_get_flagset 3 , +.Xr acl_add_flag_np 3 , +.Xr acl_clear_flags_np 3 , +.Xr acl_delete_flag_np 3 , +.Xr acl_get_flagset_np 3 .Sh AUTHORS .An Michael Smith .An Chris D. Faulhaber diff --git a/posix1e/acl_translate.c b/posix1e/acl_translate.c index 960a6d1..e429d8a 100644 --- a/posix1e/acl_translate.c +++ b/posix1e/acl_translate.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -280,16 +281,15 @@ uuid_to_name(uuid_t *uu, uid_t *id, int *isgid) errout: ; //warn("Unable to translate qualifier on ACL\n"); } } - return strdup(""); + return NULL; } acl_t acl_from_text(const char *buf_p) { - int i, error = 0, need_tag = 1, ug_tag = -1; - char *buf; - char *entry, *field, *sub, - *last_field, *last_entry, *last_sub; + int i, error = 0, need_tag, ug_tag; + char *buf, *orig_buf; + char *entry, *field, *sub; uuid_t *uu; struct passwd *tpass = NULL; struct group *tgrp = NULL; @@ -299,41 +299,51 @@ acl_from_text(const char *buf_p) acl_tag_t tag; acl_t acl_ret; - if ((acl_ret = acl_init(1)) == NULL) - return NULL; - if (buf_p == NULL) + { + errno = EINVAL; return NULL; + } if ((buf = strdup(buf_p)) == NULL) return NULL; - /* acl flags */ - if ((entry = strtok_r(buf, "\n", &last_entry)) != NULL) + if ((acl_ret = acl_init(1)) == NULL) + return NULL; + + orig_buf = buf; + + /* global acl flags + * format: !#acl [] + */ + if ((entry = strsep(&buf, "\n")) != NULL && *entry) { - /* stamp */ - field = strtok_r(entry, " ", &last_field); - if (field && strncmp(field, "!#acl", strlen("!#acl"))) + /* field 1: !#acl */ + field = strsep(&entry, " "); + if (*field && strncmp(field, "!#acl", strlen("!#acl"))) { error = EINVAL; goto exit; } - /* version */ - field = strtok_r(NULL, " ", &last_field); + /* field 2: + * currently only accepts 1 + */ + field = strsep(&entry, " "); errno = 0; - if (field == NULL || strtol(field, NULL, 0) != 1) + if (!*field || strtol(field, NULL, 0) != 1) { error = EINVAL; goto exit; } - /* optional flags */ - if((field = strtok_r(NULL, " ", &last_field)) != NULL) + /* field 3: + * optional + */ + if((field = strsep(&entry, " ")) != NULL && *field) { acl_get_flagset_np(acl_ret, &flags); - for (sub = strtok_r(field, ",", &last_sub); sub; - sub = strtok_r(NULL, ",", &last_sub)) + while ((sub = strsep(&field, ",")) && *sub) { for (i = 0; acl_flags[i].name != NULL; ++i) { @@ -352,45 +362,73 @@ acl_from_text(const char *buf_p) } } } + } else { + error = EINVAL; + goto exit; } - for (entry = strtok_r(NULL, "\n", &last_entry); entry; - entry = strtok_r(NULL, "\n", &last_entry)) + /* parse each acl line + * format: : + * []: + * []: + * []: + * [,] + * [:[,]] + * + * only one of the user/group identifies is required + * the first one found is used + */ + while ((entry = strsep(&buf, "\n")) && *entry) { - field = strtok_r(entry, ":", &last_field); + need_tag = 1; + ug_tag = -1; + + /* field 1: */ + field = strsep(&entry, ":"); if((uu = calloc(1, sizeof(uuid_t))) == NULL) + { + error = errno; goto exit; + } if(acl_create_entry(&acl_ret, &acl_entry)) + { + error = errno; goto exit; + } - acl_get_flagset_np(acl_entry, &flags); - acl_get_permset(acl_entry, &perms); + if (-1 == acl_get_flagset_np(acl_entry, &flags) + || -1 == acl_get_permset(acl_entry, &perms)) + { + error = errno; + goto exit; + } switch(*field) { case 'u': - if(!strncmp(buf, "user", strlen(field))) + if(!strcmp(field, "user")) ug_tag = ID_TYPE_UID; break; case 'g': - if(!strncmp(buf, "group", strlen(field))) + if(!strcmp(field, "group")) ug_tag = ID_TYPE_GID; break; - + default: + error = EINVAL; + goto exit; } - /* uuid */ - if ((field = strtok_r(NULL, ":", &last_field)) != NULL) + /* field 2: */ + if ((field = strsep(&entry, ":")) != NULL && *field) { mbr_string_to_uuid(field, *uu); need_tag = 0; } - /* name */ - if (*last_field == ':') // empty username field - last_field++; - else if ((field = strtok_r(NULL, ":", &last_field)) != NULL && need_tag) + + /* field 3: */ + if ((field = strsep(&entry, ":")) != NULL && *field && need_tag) { switch(ug_tag) { @@ -410,13 +448,15 @@ acl_from_text(const char *buf_p) goto exit; } break; + default: + error = EINVAL; + goto exit; } need_tag = 0; } - /* uid */ - if (*last_field == ':') // empty uid field - last_field++; - else if ((field = strtok_r(NULL, ":", &last_field)) != NULL && need_tag) + + /* field 4: */ + if ((field = strsep(&entry, ":")) != NULL && *field && need_tag) { uid_t id; error = 0; @@ -449,30 +489,35 @@ acl_from_text(const char *buf_p) need_tag = 0; } - /* nothing do set as qualifier */ + /* sanity check: nothing set as qualifier */ if (need_tag) { error = EINVAL; goto exit; } - /* flags */ - if((field = strtok_r(NULL, ":", &last_field)) == NULL) + /* field 5: */ + if((field = strsep(&entry, ":")) == NULL || !*field) { error = EINVAL; goto exit; } - for (tag = 0, sub = strtok_r(field, ",", &last_sub); sub; - sub = strtok_r(NULL, ",", &last_sub)) + for (tag = 0; (sub = strsep(&field, ",")) && *sub;) { - if (!tag && !strcmp(sub, "allow")) { + if (!tag) + { + if (!strcmp(sub, "allow")) tag = ACL_EXTENDED_ALLOW; - continue; - } else if (!tag && !strcmp(sub, "deny")) { + else if (!strcmp(sub, "deny")) tag = ACL_EXTENDED_DENY; - continue; + else { + error = EINVAL; + goto exit; + } + continue; } + for (i = 0; acl_flags[i].name != NULL; ++i) { if (acl_flags[i].type & (ACL_TYPE_FILE | ACL_TYPE_DIR) @@ -490,9 +535,10 @@ acl_from_text(const char *buf_p) } } - if((field = strtok_r(NULL, ":", &last_field)) != NULL) { - for (sub = strtok_r(field, ",", &last_sub); sub; - sub = strtok_r(NULL, ",", &last_sub)) + /* field 6: (can be empty) */ + if((field = strsep(&entry, ":")) != NULL && *field) + { + while ((sub = strsep(&field, ",")) && *sub) { for (i = 0; acl_perms[i].name != NULL; i++) { @@ -515,7 +561,7 @@ acl_from_text(const char *buf_p) acl_set_qualifier(acl_entry, *uu); } exit: - free(buf); + free(orig_buf); if (error) { acl_free(acl_ret); @@ -528,31 +574,32 @@ exit: char * acl_to_text(acl_t acl, ssize_t *len_p) { - uuid_t *uu; acl_tag_t tag; acl_entry_t entry = NULL; acl_flagset_t flags; acl_permset_t perms; uid_t id; - char *str, uu_str[256]; int i, first; int isgid; size_t bufsize = 1024; - char *buf; + char *buf = NULL; if (!_ACL_VALID_ACL(acl)) { errno = EINVAL; return NULL; } - buf = malloc(bufsize); if (len_p == NULL) - len_p = alloca(sizeof(ssize_t)); + if ((len_p = alloca(sizeof(ssize_t))) == NULL) + goto err_nomem; *len_p = 0; + if ((buf = malloc(bufsize)) == NULL) + goto err_nomem; + if (!raosnprintf(&buf, &bufsize, len_p, "!#acl %d", 1)) - return NULL; + goto err_nomem; if (acl_get_flagset_np(acl, &flags) == 0) { @@ -563,31 +610,40 @@ acl_to_text(acl_t acl, ssize_t *len_p) { if(!raosnprintf(&buf, &bufsize, len_p, "%s%s", first++ ? "," : " ", acl_flags[i].name)) - return NULL; + goto err_nomem; } } } for (;acl_get_entry(acl, entry == NULL ? ACL_FIRST_ENTRY : ACL_NEXT_ENTRY, &entry) == 0;) { + int valid; + uuid_t *uu; + char *str, uu_str[37]; + 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)) + || (acl_get_permset(entry, &perms) != 0) + || ((str = uuid_to_name(uu, &id, &isgid)) == NULL)) { + if (uu != NULL) acl_free(uu); continue; + } - str = uuid_to_name(uu, &id, &isgid); - mbr_uuid_to_string(uu, uu_str); // XXX how big should uu_str be? // XXX error? + uuid_unparse_upper(*uu, uu_str); - if(!raosnprintf(&buf, &bufsize, len_p, "\n%s:%s:%s:%d:%s", + 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")) - return NULL; + (tag == ACL_EXTENDED_ALLOW) ? "allow" : "deny"); free(str); + acl_free(uu); + + if (!valid) + goto err_nomem; for (i = 0; acl_flags[i].name != NULL; ++i) { @@ -597,7 +653,7 @@ acl_to_text(acl_t acl, ssize_t *len_p) { if(!raosnprintf(&buf, &bufsize, len_p, ",%s", acl_flags[i].name)) - return NULL; + goto err_nomem; } } } @@ -609,9 +665,8 @@ acl_to_text(acl_t acl, ssize_t *len_p) if(acl_get_perm_np(perms, acl_perms[i].perm) != 0) { if(!raosnprintf(&buf, &bufsize, len_p, "%s%s", - first++ ? "," : ":", - acl_perms[i].name)) - return NULL; + first++ ? "," : ":", acl_perms[i].name)) + goto err_nomem; } } } @@ -619,6 +674,13 @@ acl_to_text(acl_t acl, ssize_t *len_p) buf[(*len_p)++] = '\n'; buf[(*len_p)] = 0; return buf; + +err_nomem: + if (buf != NULL) + free(buf); + + errno = ENOMEM; + return NULL; } ssize_t diff --git a/ppc/gen/Makefile.inc b/ppc/gen/Makefile.inc index 5ef1c9b..4c17c1c 100644 --- a/ppc/gen/Makefile.inc +++ b/ppc/gen/Makefile.inc @@ -2,10 +2,21 @@ MDSRCS += \ abs.s \ - ffs.s \ fp.h \ icacheinval.s \ mcount.s \ - setjmperr.c + setjmperr.c \ + _ctx_start.S \ + getcontext.S \ + getmcontext.c \ + makecontext.c \ + _setcontext.S \ + setcontext.c \ + swapcontext.c SUPPRESSSRCS += memcpy.c memmove.c memset.c + +# makecontext.c can only compile with __DARWIN_UNIX03=0 because the structure +# field names are renamed with __ prefix when __DARWIN_UNIX03=1. If +# makecontext.c ever needs to build variant, this will have to be fix properly +CFLAGS-makecontext.c = -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0 diff --git a/ppc/gen/_ctx_start.S b/ppc/gen/_ctx_start.S new file mode 100644 index 0000000..76e6a0a --- /dev/null +++ b/ppc/gen/_ctx_start.S @@ -0,0 +1,62 @@ +/* + * 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@ + */ + +/* + * Copyright (c) 2004 Suleiman Souhlal + * 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. + */ + +#if defined(__ppc__) + +#include + +TEXT +LABEL(__ctx_start) + mtlr r14 + blrl /* branch to start function */ + mr r3, r15 /* pass pointer to ucontext as argument */ + BRANCH_EXTERN(__ctx_done) /* branch to ctxt completion func */ + trap /* should never get here */ + +#endif /* __ppc__ */ diff --git a/ppc/gen/_setcontext.S b/ppc/gen/_setcontext.S new file mode 100644 index 0000000..ca06fb5 --- /dev/null +++ b/ppc/gen/_setcontext.S @@ -0,0 +1,76 @@ +/* + * 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@ + */ + +#if defined(__ppc__) + +#include + +TEXT +LABEL(__setcontext) + mr r31, r3 /* save ucontext across call */ + lwz r3, 4(r3) /* load up signal mask */ + CALL_EXTERN(_sigsetmask) /* set signal mask */ + mr r3, r31 /* restore ucontext */ + lwz r3, 28(r3) /* load up mcontext */ + lwz r1, 44(r3) /* start restoring regs */ + lwz r2, 48(r3) + lwz r4, 56(r3) + lwz r5, 60(r3) + lwz r6, 64(r3) + lwz r7, 68(r3) + lwz r8, 72(r3) + lwz r9, 76(r3) + lwz r10, 80(r3) + lwz r11, 84(r3) + lwz r12, 88(r3) + lwz r13, 92(r3) + lwz r14, 96(r3) + lwz r15, 100(r3) + lwz r16, 104(r3) + lwz r17, 108(r3) + lwz r18, 112(r3) + lwz r19, 116(r3) + lwz r20, 120(r3) + lwz r21, 124(r3) + lwz r22, 128(r3) + lwz r23, 132(r3) + lwz r24, 136(r3) + lwz r25, 140(r3) + lwz r26, 144(r3) + lwz r27, 148(r3) + lwz r28, 152(r3) + lwz r29, 156(r3) + lwz r30, 160(r3) + lwz r31, 164(r3) + lwz r0, 168(r3) /* only restore non-vol CR's */ + mtcrf 0x20, r0 + mtcrf 0x10, r0 + mtcrf 0x08, r0 + lwz r0, 176(r3) + mtlr r0 + lwz r0, 32(r3) + mtctr r0 + lwz r3, 52(r3) /* restore r3 last */ + bctrl + +#endif /* __ppc__ */ diff --git a/ppc/sys/getdtablesize.s b/ppc/gen/getcontext.S similarity index 60% rename from ppc/sys/getdtablesize.s rename to ppc/gen/getcontext.S index 856c82a..81a76a9 100644 --- a/ppc/sys/getdtablesize.s +++ b/ppc/gen/getcontext.S @@ -21,7 +21,42 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include "SYS.h" +#if defined(__ppc__) -SYSCALL(getdtablesize, 0) +#include +TEXT +LABEL(_getcontext) + mr r4, r1 + CALL_EXTERN(_getmcontext) + stw r1, 44(r3) + stw r2, 48(r3) + stw r13, 92(r3) + stw r14, 96(r3) + stw r15, 100(r3) + stw r16, 104(r3) + stw r17, 108(r3) + stw r18, 112(r3) + stw r19, 116(r3) + stw r21, 124(r3) + stw r22, 128(r3) + stw r23, 132(r3) + stw r24, 136(r3) + stw r25, 140(r3) + stw r26, 144(r3) + stw r27, 148(r3) + stw r28, 152(r3) + stw r29, 156(r3) + stw r30, 160(r3) + stw r31, 164(r3) + mfcr r0 + stw r0, 168(r3) + mflr r4 + stw r4, 176(r3) + stw r4, 32(r3) + li r5, 0 + stw r5, 52(r3) + li r3, 0 + blr + +#endif /* __ppc__ */ diff --git a/ppc/gen/getmcontext.c b/ppc/gen/getmcontext.c new file mode 100644 index 0000000..ff327f7 --- /dev/null +++ b/ppc/gen/getmcontext.c @@ -0,0 +1,82 @@ +/* + * 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@ + */ + +#if defined(__ppc__) + +#define _XOPEN_SOURCE 600L + +#include +#include +#include +#include +#include +#include + +extern size_t pthread_get_stacksize_np(pthread_t); +extern void *pthread_get_stackaddr_np(pthread_t); +#ifdef __DYNAMIC__ +extern int __in_sigtramp; +#endif /* __DYNAMIC_ */ + +__private_extern__ mcontext_t +getmcontext(ucontext_t *uctx, void *sp) +{ + pthread_t self = pthread_self(); + mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data; + size_t stacksize = pthread_get_stacksize_np(self); + stack_t stack; + + uctx->uc_stack.ss_sp = sp; + uctx->uc_stack.ss_flags = 0; + + if (0 == sigaltstack(NULL, &stack)) { + if (stack.ss_flags & SS_ONSTACK) { + uctx->uc_stack = stack; + stacksize = stack.ss_size; + } + } + + if (stacksize == 0) { /* main thread doesn't have pthread stack size */ + rlim_t rlim; + if (0 == getrlimit(RLIMIT_STACK, &rlim)) + stacksize = rlim; + } + + uctx->uc_stack.ss_size = stacksize; + + if (uctx->uc_mcontext != mctx) { + uctx->uc_mcontext = mctx; + +#ifdef __DYNAMIC__ + uctx->uc_link = (ucontext_t*)__in_sigtramp; /* non-zero if in signal handler */ +#else /* !__DYNAMIC__ */ + uctx->uc_link = 0; +#endif /* __DYNAMIC__ */ + + } + + sigprocmask(0, NULL, &uctx->uc_sigmask); + return mctx; +} + +#endif /* __ppc__ */ diff --git a/ppc/gen/icacheinval.s b/ppc/gen/icacheinval.s index 82c5845..d584a85 100644 --- a/ppc/gen/icacheinval.s +++ b/ppc/gen/icacheinval.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,15 +21,22 @@ * @APPLE_LICENSE_HEADER_END@ */ -#define __APPLE_API_PRIVATE #include -#undef __APPLE_API_PRIVATE -/* sys_icache_invalidate(char *start, long len) */ -/* this routine has moved to the comm page */ +/* void sys_icache_invalidate(char *start, long len) */ .text .globl _sys_icache_invalidate .align 2 _sys_icache_invalidate: ba _COMM_PAGE_FLUSH_ICACHE + + + +/* void sys_dcache_flush(char *start, long len) */ + + .text + .globl _sys_dcache_flush + .align 2 +_sys_dcache_flush: + ba _COMM_PAGE_FLUSH_DCACHE diff --git a/ppc/gen/makecontext.c b/ppc/gen/makecontext.c new file mode 100644 index 0000000..fcab68e --- /dev/null +++ b/ppc/gen/makecontext.c @@ -0,0 +1,160 @@ +/* + * 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@ + */ + +/* + * Copyright (c) 2004 Suleiman Souhlal + * 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. + */ + +#if defined(__ppc__) + +#include +#include + +#include +#include +#include +#include +#include +#include + +void _ctx_done(ucontext_t *ucp); +void _ctx_start(void); + +void +_ctx_done(ucontext_t *ucp) +{ + if (ucp->uc_link == NULL) + exit(0); + else { + /* invalidate context */ + ucp->uc_mcsize = 0; + + setcontext((const ucontext_t *)ucp->uc_link); + + abort(); /* should never return from above call */ + } +} + +void +makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...) +{ + mcontext_t mc; + char *sp; + va_list ap; + int i, regargs, stackargs; + uint32_t args[8]; + + /* Sanity checks */ + if ((ucp == NULL) || (argc < 0) || (argc > NCARGS) + || (ucp->uc_stack.ss_sp == NULL) + || (ucp->uc_stack.ss_size < 8192)) { + /* invalidate context */ + ucp->uc_mcsize = 0; + return; + } + + /* + * The stack must have space for the frame pointer, saved + * link register, overflow arguments, and be 16-byte + * aligned. + */ + stackargs = (argc > 8) ? argc - 8 : 0; + sp = (char *) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size + - sizeof(uint32_t)*(stackargs + 2); + sp = (char *)((uint32_t)sp & ~0x1f); + + mc = ucp->uc_mcontext; + + /* + * Up to 8 register args. Assumes all args are 32-bit and + * integer only. Not sure how to cater for floating point, + * although 64-bit args will work if aligned correctly + * in the arg list. + */ + regargs = (argc > 8) ? 8 : argc; + va_start(ap, argc); + for (i = 0; i < regargs; i++) + args[i] = va_arg(ap, uint32_t); + + switch (regargs) { + /* + * Hi Tom! + */ + case 8 : mc->ss.r10 = args[7]; + case 7 : mc->ss.r9 = args[6]; + case 6 : mc->ss.r8 = args[5]; + case 5 : mc->ss.r7 = args[4]; + case 4 : mc->ss.r6 = args[3]; + case 3 : mc->ss.r5 = args[2]; + case 2 : mc->ss.r4 = args[1]; + case 1 : mc->ss.r3 = args[0]; + default: break; + } + + /* + * Overflow args go onto the stack + */ + if (argc > 8) { + uint32_t *argp; + + /* Skip past frame pointer and saved LR */ + argp = (uint32_t *)sp + 2; + + for (i = 0; i < stackargs; i++) + *argp++ = va_arg(ap, uint32_t); + } + va_end(ap); + + /* + * Use caller-saved regs 14/15 to hold params that _ctx_start + * will use to invoke the user-supplied func + */ + mc->ss.srr0 = (uint32_t) _ctx_start; + mc->ss.r1 = (uint32_t) sp; /* new stack pointer */ + mc->ss.r14 = (uint32_t) start; /* r14 <- start */ + mc->ss.r15 = (uint32_t) ucp; /* r15 <- ucp */ +} + +#endif /* __ppc__ */ diff --git a/sys/accessx_np.c b/ppc/gen/setcontext.c similarity index 73% rename from sys/accessx_np.c rename to ppc/gen/setcontext.c index cc21c83..6b9db08 100644 --- a/sys/accessx_np.c +++ b/ppc/gen/setcontext.c @@ -20,11 +20,23 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#include -#include + +#if defined(__ppc__) + +#define _XOPEN_SOURCE 600L + +#include + +extern int _setcontext(const ucontext_t *); int -accessx_np(const struct accessx_descriptor *entries, size_t desc_size, int *results, uid_t uid) +setcontext(const ucontext_t *uctx) { - return syscall(SYS_access_extended, entries, desc_size, results, uid); + mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data; + ucontext_t *_uctx = (ucontext_t *)uctx; + if (mctx != _uctx->uc_mcontext) + _uctx->uc_mcontext = mctx; + return _setcontext(uctx); } + +#endif /* __ppc__ */ diff --git a/ppc/gen/swapcontext.c b/ppc/gen/swapcontext.c new file mode 100644 index 0000000..047bef1 --- /dev/null +++ b/ppc/gen/swapcontext.c @@ -0,0 +1,81 @@ +/* + * 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@ + */ + +/* + * Copyright (c) 2001 Daniel M. Eischen + * 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. Neither the name of the author 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 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. + */ + +#if defined(__ppc__) + +#include +#include +#include +#include + +#include +#include + +#define uc_flags uc_onstack +#define UCF_SWAPPED 0x80000000 + +int +swapcontext(ucontext_t *oucp, const ucontext_t *ucp) +{ + int ret; + + if ((oucp == NULL) || (ucp == NULL)) { + errno = EINVAL; + return (-1); + } + oucp->uc_flags &= ~UCF_SWAPPED; + ret = getcontext(oucp); + if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) { + oucp->uc_flags |= UCF_SWAPPED; + ret = setcontext(ucp); + } + return (ret); +} + +#endif /* __ppc__ */ diff --git a/ppc/pthreads/init_cpu_capabilities.c b/ppc/pthreads/init_cpu_capabilities.c index 67b73bd..bbbd51a 100644 --- a/ppc/pthreads/init_cpu_capabilities.c +++ b/ppc/pthreads/init_cpu_capabilities.c @@ -27,8 +27,6 @@ #include #undef __APPLE_API_PRIVATE -extern int _get_cpu_capabilities(void); - int _cpu_capabilities = 0; int _cpu_has_altivec = 0; // DEPRECATED: use _cpu_capabilities instead diff --git a/ppc/stdlib/gdtoa.mk b/ppc/stdlib/gdtoa.mk index 31312cd..076c4cc 100644 --- a/ppc/stdlib/gdtoa.mk +++ b/ppc/stdlib/gdtoa.mk @@ -1,5 +1,8 @@ # Long double is head-tail pair of doubles -FBSDSRCS+= gdtoa-strtopdd.c machdep_ldisdd.c _ldbl_util.c +GDTOA_FBSDSRCS+= gdtoa-strtopdd.c machdep_ldisdd.c +MISRCS+= _ldbl_util.c + +CFLAGS-_ldbl_util.c += -I${.CURDIR}/fbsdcompat # also build a 64-bit long double version (ppc only) LDBLSRCS += machdep_ldisdd.c diff --git a/ppc/string/Makefile.inc b/ppc/string/Makefile.inc index ecb45fc..3b336bf 100644 --- a/ppc/string/Makefile.inc +++ b/ppc/string/Makefile.inc @@ -7,6 +7,10 @@ MDSRCS += \ bcopy.s \ bzero.s \ + ffs.s \ + ffsl.s \ + fls.s \ + flsl.s \ memset.s \ memcmp.s \ strcat.s \ diff --git a/ppc/gen/ffs.s b/ppc/string/ffs.s similarity index 100% rename from ppc/gen/ffs.s rename to ppc/string/ffs.s diff --git a/ppc/sys/connect.s b/ppc/string/ffsl.s similarity index 57% rename from ppc/sys/connect.s rename to ppc/string/ffsl.s index 033693b..7a6eae4 100644 --- a/ppc/sys/connect.s +++ b/ppc/string/ffsl.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,14 +20,40 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#include "SYS.h" +/* Copyright (c) 1992, 1997 NeXT Software, Inc. All rights reserved. + * + * File: libc/gen/ppc/ffs.s + * + * Find the first bit set (starting with the least significant bit). + * + * HISTORY + * + * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) + * Ported to PPC. + * + * 19-Jan-1998 Matt Watson (mwatson@apple.com) + * Simplified + * + * 10-Mar-1998 Matt Watson (mwatson@apple.com) + * Correctified + * + * 14-Nov-2005 Edward Moy + * Convert ffs to ffsl + * + */ +#include + +.text +.align 2 +.globl _ffsl +_ffsl: + neg r0,r3 + and r3,r0,r3 + cntlzg r3,r3 #ifdef __LP64__ -SYSCALL(connect, 3) + subfic r3,r3,64 #else /* !__LP64__ */ -PSEUDO(connect$UNIX2003, connect, 3) - blr - -SYSCALL_ERR(connect, 3, cerror_cvt) + subfic r3,r3,32 #endif /* __LP64__ */ - + blr diff --git a/i386/sys/commpage.c b/ppc/string/fls.s similarity index 93% rename from i386/sys/commpage.c rename to ppc/string/fls.s index fa1d6fe..e37c085 100644 --- a/i386/sys/commpage.c +++ b/ppc/string/fls.s @@ -21,3 +21,10 @@ * @APPLE_LICENSE_HEADER_END@ */ +.text +.align 2 +.globl _fls +_fls: + cntlzw r3,r3 + subfic r3,r3,32 + blr diff --git a/ppc/sys/bind.s b/ppc/string/flsl.s similarity index 83% rename from ppc/sys/bind.s rename to ppc/string/flsl.s index 9e7eb67..709a868 100644 --- a/ppc/sys/bind.s +++ b/ppc/string/flsl.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,13 +20,17 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#include "SYS.h" +#include + +.text +.align 2 +.globl _flsl +_flsl: + cntlzg r3,r3 #ifdef __LP64__ -SYSCALL(bind, 3) + subfic r3,r3,64 #else /* !__LP64__ */ -PSEUDO(bind$UNIX2003, bind, 3) - blr - -SYSCALL_ERR(bind, 3, cerror_cvt) + subfic r3,r3,32 #endif /* __LP64__ */ + blr diff --git a/ppc/string/memset.s b/ppc/string/memset.s index 25e4613..706167c 100644 --- a/ppc/string/memset.s +++ b/ppc/string/memset.s @@ -49,23 +49,14 @@ .align 5 _memset: // void * memset(void *b, int c, size_t len); andi. r7,r4,0xFF // copy value to working register, test for 0 - mr r4,r5 // move length to working register + mr r4,r5 // move length to working register cmplgi cr1,r5,kShort // long enough to bother with _COMM_PAGE_MEMSET_PATTERN? beqa++ _COMM_PAGE_BZERO // if (c==0), map to bzero() rlwimi r7,r7,8,16,23 // replicate nonzero value to low 2 bytes - neg r5,r3 // start to compute #bytes to align - mr r8,r3 // make working copy of operand ptr + neg r5,r3 // start to compute #bytes to align + mr r8,r3 // make working copy of operand ptr rlwimi r7,r7,16,0,15 // value now in all 4 bytes - blt cr1,Lmemset3 // too short to use commpage - - // TEMPORARY HACK - // Operand is long enough to use _COMM_PAGE_MEMSET_PATTERN. During Tiger - // development, B&I uses Panther kernels on their builders but runs Tiger - // apps on it. So _COMM_PAGE_MEMSET_PATTERN may not be on this machine. - // Rather than patch build fleet kernels, we just test to see if it is there - // and use the short-operand case if not. We can remove the hack when Tiger ships. - - lhz r10,_COMM_PAGE_VERSION(0) // REMOVE THIS LINE WHEN TIGER SHIPS + blt cr1,Lmemset3 // too short to use commpage andi. r0,r5,0xF // r0 <- #bytes to align on quadword // Align ptr and store enough so that we have an aligned 16-byte pattern. @@ -74,7 +65,6 @@ _memset: // void * memset(void *b, int c, size_t len); stw r7,4(r8) stw r7,8(r8) stw r7,12(r8) - cmpwi cr1,r10,1 // REMOVE THIS LINE WHEN TIGER SHIPS beq Lmemset1 // skip if (r0==0), ie if r8 is 16-byte aligned add r8,r8,r0 // 16-byte align ptr sub r4,r4,r0 // adjust length @@ -96,7 +86,7 @@ Lmemset1: mr r9,r8 // point to 16-byte-aligned 16-byte pattern addi r8,r8,16 // point to first unstored byte subi r4,r4,16 // account for the aligned bytes we have stored - bnela++ cr1,_COMM_PAGE_MEMSET_PATTERN // CHANGE THIS LINE WHEN TIGER SHIPS + bla _COMM_PAGE_MEMSET_PATTERN mtlr r12 // Here for short nonzero memset. @@ -139,20 +129,20 @@ Lmemset5: blr -/* ************************************* - * * _ M E M S E T _ P A T T E R N 1 6 * - * ************************************* +/* *********************************** + * * M E M S E T _ P A T T E R N 1 6 * + * *********************************** * * Used to store a 16-byte pattern in memory: * - * void _memset_pattern16(void *b, const void *c16, size_t len); + * void memset_pattern16(void *b, const void *c16, size_t len); * * Where c16 points to the 16-byte pattern. None of the parameters need be aligned. */ - .globl __memset_pattern16 + .globl _memset_pattern16 .align 5 -__memset_pattern16: +_memset_pattern16: cmplgi cr1,r5,kShort // check length lwz r7,0(r4) // load pattern into (these remain lwz in 64-bit mode) lwz r9,4(r4) @@ -162,20 +152,20 @@ __memset_pattern16: b __memset_pattern_common -/* *********************************** - * * _ M E M S E T _ P A T T E R N 8 * - * *********************************** +/* ********************************* + * * M E M S E T _ P A T T E R N 8 * + * ********************************* * * Used to store an 8-byte pattern in memory: * - * void _memset_pattern8(void *b, const void *c8, size_t len); + * void memset_pattern8(void *b, const void *c8, size_t len); * * Where c8 points to the 8-byte pattern. None of the parameters need be aligned. */ - .globl __memset_pattern8 + .globl _memset_pattern8 .align 5 -__memset_pattern8: +_memset_pattern8: lwz r7,0(r4) // load pattern (these remain lwz in 64-bit mode) lwz r9,4(r4) cmplgi cr1,r5,kShort // check length @@ -185,20 +175,20 @@ __memset_pattern8: b __memset_pattern_common -/* *********************************** - * * _ M E M S E T _ P A T T E R N 4 * - * *********************************** +/* ********************************* + * * M E M S E T _ P A T T E R N 4 * + * ********************************* * * Used to store a 4-byte pattern in memory: * - * void _memset_pattern4(void *b, const void *c4, size_t len); + * void memset_pattern4(void *b, const void *c4, size_t len); * * Where c4 points to the 4-byte pattern. None of the parameters need be aligned. */ - .globl __memset_pattern4 + .globl _memset_pattern4 .align 5 -__memset_pattern4: +_memset_pattern4: lwz r7,0(r4) // load pattern cmplgi cr1,r5,kShort // check length neg r6,r3 // start to compute ptr alignment @@ -212,7 +202,7 @@ __memset_pattern4: * * _ M E M S E T _ P A T T E R N _ C O M M O N * * *********************************************** * - * This is the common code used by _memset_patter16, 8, and 4. They all get here via + * This is the common code used by _memset_pattern16, 8, and 4. They all get here via * long branch (ie, "b") in case the routines are re-ordered, with: * r3 = ptr to memory to store pattern into (unaligned) * r5 = length in bytes @@ -222,6 +212,7 @@ __memset_pattern4: */ .globl __memset_pattern_common + .private_extern __memset_pattern_common // avoid dyld stub, which trashes r11 .align 5 __memset_pattern_common: andi. r0,r6,0xF // get #bytes to 16-byte align ptr diff --git a/ppc/sys/ATPgetreq.s b/ppc/sys/ATPgetreq.s deleted file mode 100644 index b7c1af2..0000000 --- a/ppc/sys/ATPgetreq.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(ATPgetreq, 3) - diff --git a/ppc/sys/ATPgetrsp.s b/ppc/sys/ATPgetrsp.s deleted file mode 100644 index 5d23b06..0000000 --- a/ppc/sys/ATPgetrsp.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(ATPgetrsp, 3) - diff --git a/ppc/sys/ATPsndreq.s b/ppc/sys/ATPsndreq.s deleted file mode 100644 index 9c30a75..0000000 --- a/ppc/sys/ATPsndreq.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(ATPsndreq, 3) - diff --git a/ppc/sys/ATPsndrsp.s b/ppc/sys/ATPsndrsp.s deleted file mode 100644 index 0cead0e..0000000 --- a/ppc/sys/ATPsndrsp.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(ATPsndrsp, 3) - diff --git a/ppc/sys/ATgetmsg.s b/ppc/sys/ATgetmsg.s deleted file mode 100644 index 043942d..0000000 --- a/ppc/sys/ATgetmsg.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(ATgetmsg, 3) - diff --git a/ppc/sys/ATputmsg.s b/ppc/sys/ATputmsg.s deleted file mode 100644 index bf42d1c..0000000 --- a/ppc/sys/ATputmsg.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(ATputmsg, 3) - diff --git a/ppc/sys/ATsocket.s b/ppc/sys/ATsocket.s deleted file mode 100644 index 4aa08a7..0000000 --- a/ppc/sys/ATsocket.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(ATsocket, 3) - diff --git a/ppc/sys/Makefile.inc b/ppc/sys/Makefile.inc index 36b80fb..64a9e46 100644 --- a/ppc/sys/Makefile.inc +++ b/ppc/sys/Makefile.inc @@ -1,228 +1,12 @@ .PATH: ${.CURDIR}/ppc/sys -MDSRCS+= ATPgetreq.s \ - ATPgetrsp.s \ - ATPsndreq.s \ - ATPsndrsp.s \ - ATgetmsg.s \ - ATputmsg.s \ - ATsocket.s \ - OSAtomic.s \ - _exit.s \ - _getlogin.s \ + +MDSRCS+= OSAtomic.s \ + ldbl64.s \ _longjmp.s \ - __mmap.s \ - _pthread_kill.s \ - __pthread_canceled.s \ - __pthread_markcancel.s \ - __semwait_signal.s \ - _setjmp.s \ - _setlogin.s \ - _sysctl.s \ - accept.s \ - access.s \ - acct.s \ - add_profil.s \ - adjtime.s \ - aio_cancel.s \ - aio_error.s \ - aio_fsync.s \ - aio_read.s \ - aio_return.s \ - aio_suspend.s \ - aio_write.s \ - audit.s \ - auditctl.s \ - auditon.s \ - bind.s \ - cerror.s \ - chdir.s \ - checkuseraccess.s \ - chflags.s \ - chmod.s \ - chown.s \ - chroot.s \ - close.s \ - connect.s \ - dup.s \ - dup2.s \ - exchangedata.s \ - execve.s \ - fchdir.s \ - fchflags.s \ - fchmod.s \ - fchown.s \ - fcntl.s \ - fgetxattr.s \ - fhopen.s \ - flistxattr.s \ - flock.s \ - fork.s \ - fpathconf.s \ - fremovexattr.s \ - fsctl.s \ - fsetxattr.s \ - fstat.s \ - fstatfs.s \ - fstatv.s \ - fsync.s \ - ftruncate.s \ - futimes.s \ - getattrlist.s \ - getaudit.s \ - getaudit_addr.s \ - getauid.s \ - getdirentries.s \ - getdirentriesattr.s \ - getdtablesize.s \ - getegid.s \ - geteuid.s \ - getfh.s \ - getfsstat.s \ - getgid.s \ - getgroups.s \ - getitimer.s \ - getpeername.s \ - getpgid.s \ - getpgrp.s \ - getpid.s \ - getppid.s \ - getpriority.s \ - getrlimit.s \ - getrusage.s \ - getsid.s \ - getsockname.s \ - getsockopt.s \ - getuid.s \ - getxattr.s \ - ioctl.s \ - issetugid.s \ - kevent.s \ - kill.s \ - kqueue.s \ - kqueue_from_portset_np.s \ - kqueue_portset_np.s \ - ktrace.s \ - lchown.s \ - link.s \ - lio_listio.s \ - listen.s \ - listxattr.s \ - load_shared_file.s \ longjmp.s \ - lseek.s \ - lstat.s \ - lstatv.s \ - madvise.s \ - mincore.s \ - minherit.s \ - mkcomplex.s \ - mkdir.s \ - mkfifo.s \ - mknod.s \ - mlock.s \ - mlockall.s \ - mount.s \ - msgget.s \ - msgrcv.s \ - msgsnd.s \ - msgsys.s \ - munlock.s \ - munlockall.s \ - new_system_shared_regions.s \ - nfsclnt.s \ - nfssvc.s \ - open.s \ - pathconf.s \ - pipe.s \ - poll.s \ - posix_madvise.s \ ppc_gettimeofday.s \ - pread.s \ - processor_facilities.s \ - profil.s \ - pthread_sigmask.s \ - ptrace.s \ - pwrite.s \ - quota.s \ - quotactl.s \ - read.s \ - readlink.s \ - readv.s \ - reboot.s \ - recvfrom.s \ - recvmsg.s \ - removexattr.s \ - rename.s \ - reset_shared_file.s \ - revoke.s \ - rmdir.s \ - searchfs.s \ - select.s \ - sem_close.s \ - sem_destroy.s \ - sem_getvalue.s \ - sem_init.s \ - sem_post.s \ - sem_trywait.s \ - sem_wait.s \ - semget.s \ - semop.s \ - semsys.s \ - sendmsg.s \ - sendto.s \ - setattrlist.s \ - setaudit.s \ - setaudit_addr.s \ - setauid.s \ - setegid.s \ - seteuid.s \ - setgid.s \ - setgroups.s \ - setitimer.s \ + _setjmp.s \ setjmp.s \ - setpgid.s \ - setpriority.s \ - setprivexec.s \ - setquota.s \ - setrlimit.s \ - setsid.s \ - setsockopt.s \ - settimeofday.s \ - setuid.s \ - setxattr.s \ - shmat.s \ - shmdt.s \ - shmget.s \ - shmsys.s \ - shutdown.s \ - sigaltstack.s \ - sigpending.s \ - sigprocmask.s \ - sigreturn.s \ - sigwait.s \ - socket.s \ - socketpair.s \ - stat.s \ - statfs.s \ - statv.s \ - swapon.s \ - symlink.s \ - sync.s \ - syscall.s \ - systable.s \ - truncate.s \ - umask.s \ - undelete.s \ - unlink.s \ - unmount.s \ - utimes.s \ - vfork.s \ - wait4.s \ - write.s \ - writev.s - -.for _src in fhopen.s getfh.s nfsclnt.s -CFLAGS-${_src} += -DNFSCLIENT -.endfor + _sigtramp.s -CFLAGS-nfssvc.s += -DNFSSERVER +MDCOPYFILES+= ${.CURDIR}/ppc/sys/libc.syscall.ppc diff --git a/ppc/sys/OSAtomic.s b/ppc/sys/OSAtomic.s index 105a732..24858e9 100644 --- a/ppc/sys/OSAtomic.s +++ b/ppc/sys/OSAtomic.s @@ -1,5 +1,6 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -90,6 +91,60 @@ MI_ENTRY_POINT(_OSAtomicXor32) blr +/* int32_t OSAtomicOr32Orig( int32_t theMask, int32_t *theValue ); */ + +MI_ENTRY_POINT(_OSAtomicOr32Orig) + mflr r12 // save return address + mr r5,r4 // move ptr to where compare-and-swap wants it + mr r11,r3 // copy mask +1: + lwz r3,0(r5) // get old value + mr r10,r3 // save old value + or r4,r3,r11 // make new value + bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12 + cmpwi r3,0 // did swap occur? + beq-- 1b // compare-and-swap failed, try again + mtlr r12 // restore return adddress + mr r3,r10 // return old value + blr + + +/* int32_t OSAtomicAnd32Orig( int32_t theMask, int32_t *theValue ); */ + +MI_ENTRY_POINT(_OSAtomicAnd32Orig) + mflr r12 // save return address + mr r5,r4 // move ptr to where compare-and-swap wants it + mr r11,r3 // copy mask +1: + lwz r3,0(r5) // get old value + mr r10,r3 // save old value + and r4,r3,r11 // make new value + bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12 + cmpwi r3,0 // did swap occur? + beq-- 1b // compare-and-swap failed, try again + mtlr r12 // restore return adddress + mr r3,r10 // return old value + blr + + +/* int32_t OSAtomicXor32Orig( int32_t theMask, int32_t *theValue ); */ + +MI_ENTRY_POINT(_OSAtomicXor32Orig) + mflr r12 // save return address + mr r5,r4 // move ptr to where compare-and-swap wants it + mr r11,r3 // copy mask +1: + lwz r3,0(r5) // get old value + mr r10,r3 // save old value + xor r4,r3,r11 // make new value + bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12 + cmpwi r3,0 // did swap occur? + beq-- 1b // compare-and-swap failed, try again + mtlr r12 // restore return adddress + mr r3,r10 // return old value + blr + + /* int64_t OSAtomicAdd64( int64_t theAmount, int64_t *theValue ); */ #if defined(__ppc64__) @@ -99,16 +154,28 @@ MI_ENTRY_POINT(_OSAtomicAdd64) /* bool OSAtomicCompareAndSwap32( int32_t oldValue, int32_t newValue, int32_t *theValue ); */ +/* bool OSAtomicCompareAndSwap64( int64_t oldValue, int64_t newValue, int64_t *theValue ); */ +/* bool OSAtomicCompareAndSwapPtr( void* oldValue, void* newValue, void* *theValue ); */ +/* bool OSAtomicCompareAndSwapInt( int oldValue, int newValue, int *theValue ); */ +/* bool OSAtomicCompareAndSwapLong( long oldValue, long newValue, long *theValue ); */ MI_ENTRY_POINT(_OSAtomicCompareAndSwap32) ba _COMM_PAGE_COMPARE_AND_SWAP32 - - -/* bool OSAtomicCompareAndSwap64( int364_t oldValue, int64_t newValue, int64_t *theValue ); */ +MI_ENTRY_POINT(_OSAtomicCompareAndSwapInt) + ba _COMM_PAGE_COMPARE_AND_SWAP32 #if defined(__ppc64__) MI_ENTRY_POINT(_OSAtomicCompareAndSwap64) ba _COMM_PAGE_COMPARE_AND_SWAP64 +MI_ENTRY_POINT(_OSAtomicCompareAndSwapPtr) + ba _COMM_PAGE_COMPARE_AND_SWAP64 +MI_ENTRY_POINT(_OSAtomicCompareAndSwapLong) + ba _COMM_PAGE_COMPARE_AND_SWAP64 +#else /* !defined(__ppc64__) */ +MI_ENTRY_POINT(_OSAtomicCompareAndSwapPtr) + ba _COMM_PAGE_COMPARE_AND_SWAP32 +MI_ENTRY_POINT(_OSAtomicCompareAndSwapLong) + ba _COMM_PAGE_COMPARE_AND_SWAP32 #endif /* defined(__ppc64__) */ @@ -228,6 +295,60 @@ MI_ENTRY_POINT(_OSAtomicXor32Barrier) blr +/* int32_t OSAtomicOr32OrigBarrier( int32_t theMask, int32_t *theValue ); */ + +MI_ENTRY_POINT(_OSAtomicOr32OrigBarrier) + mflr r12 // save return address + mr r5,r4 // move ptr to where compare-and-swap wants it + mr r11,r3 // copy mask +1: + lwz r3,0(r5) // get old value + mr r10,r3 // save old value + or r4,r3,r11 // make new value + bla _COMM_PAGE_COMPARE_AND_SWAP32B // preserves r4,r5,r9-r12 + cmpwi r3,0 // did swap occur? + beq-- 1b // compare-and-swap failed, try again + mtlr r12 // restore return adddress + mr r3,r10 // return old value + blr + + +/* int32_t OSAtomicAnd32OrigBarrier( int32_t theMask, int32_t *theValue ); */ + +MI_ENTRY_POINT(_OSAtomicAnd32OrigBarrier) + mflr r12 // save return address + mr r5,r4 // move ptr to where compare-and-swap wants it + mr r11,r3 // copy mask +1: + lwz r3,0(r5) // get old value + mr r10,r3 // save old value + and r4,r3,r11 // make new value + bla _COMM_PAGE_COMPARE_AND_SWAP32B // preserves r4,r5,r9-r12 + cmpwi r3,0 // did swap occur? + beq-- 1b // compare-and-swap failed, try again + mtlr r12 // restore return adddress + mr r3,r10 // return old value + blr + + +/* int32_t OSAtomicXor32OrigBarrier( int32_t theMask, int32_t *theValue ); */ + +MI_ENTRY_POINT(_OSAtomicXor32OrigBarrier) + mflr r12 // save return address + mr r5,r4 // move ptr to where compare-and-swap wants it + mr r11,r3 // copy mask +1: + lwz r3,0(r5) // get old value + mr r10,r3 // save old value + xor r4,r3,r11 // make new value + bla _COMM_PAGE_COMPARE_AND_SWAP32B // preserves r4,r5,r9-r12 + cmpwi r3,0 // did swap occur? + beq-- 1b // compare-and-swap failed, try again + mtlr r12 // restore return adddress + mr r3,r10 // return old value + blr + + /* int64_t OSAtomicAdd64Barrier( int64_t theAmount, int64_t *theValue ); */ #if defined(__ppc64__) @@ -248,16 +369,28 @@ MI_ENTRY_POINT(_OSAtomicAdd64Barrier) /* bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue, int32_t newValue, int32_t *theValue ); */ +/* bool OSAtomicCompareAndSwap64Barrier( int64_t oldValue, int64_t newValue, int64_t *theValue ); */ +/* bool OSAtomicCompareAndSwapPtrBarrier( void* oldValue, void* newValue, void* *theValue ); */ +/* bool OSAtomicCompareAndSwapIntBarrier( int oldValue, int newValue, int *theValue ); */ +/* bool OSAtomicCompareAndSwapLongBarrier( long oldValue, long newValue, long *theValue ); */ MI_ENTRY_POINT(_OSAtomicCompareAndSwap32Barrier) ba _COMM_PAGE_COMPARE_AND_SWAP32B - - -/* bool OSAtomicCompareAndSwap64Barrier( int364_t oldValue, int64_t newValue, int64_t *theValue ); */ +MI_ENTRY_POINT(_OSAtomicCompareAndSwapIntBarrier) + ba _COMM_PAGE_COMPARE_AND_SWAP32B #if defined(__ppc64__) MI_ENTRY_POINT(_OSAtomicCompareAndSwap64Barrier) ba _COMM_PAGE_COMPARE_AND_SWAP64B +MI_ENTRY_POINT(_OSAtomicCompareAndSwapPtrBarrier) + ba _COMM_PAGE_COMPARE_AND_SWAP64B +MI_ENTRY_POINT(_OSAtomicCompareAndSwapLongBarrier) + ba _COMM_PAGE_COMPARE_AND_SWAP64B +#else /* !defined(__ppc64__) */ +MI_ENTRY_POINT(_OSAtomicCompareAndSwapPtrBarrier) + ba _COMM_PAGE_COMPARE_AND_SWAP32B +MI_ENTRY_POINT(_OSAtomicCompareAndSwapLongBarrier) + ba _COMM_PAGE_COMPARE_AND_SWAP32B #endif /* defined(__ppc64__) */ @@ -311,18 +444,28 @@ MI_ENTRY_POINT(_OSAtomicTestAndClearBarrier) /* bool OSSpinLockTry( OSSpinLock *lock ); */ MI_ENTRY_POINT(_OSSpinLockTry) + .globl __spin_lock_try +__spin_lock_try: ba _COMM_PAGE_SPINLOCK_TRY /* void OSSpinLockLock( OSSpinLock *lock ); */ MI_ENTRY_POINT(_OSSpinLockLock) + .globl _spin_lock + .globl __spin_lock +_spin_lock: +__spin_lock: ba _COMM_PAGE_SPINLOCK_LOCK /* void OSSpinLockUnlock( OSSpinLock *lock ); */ MI_ENTRY_POINT(_OSSpinLockUnlock) + .globl _spin_unlock + .globl __spin_unlock +_spin_unlock: +__spin_unlock: ba _COMM_PAGE_SPINLOCK_UNLOCK @@ -331,3 +474,14 @@ MI_ENTRY_POINT(_OSSpinLockUnlock) MI_ENTRY_POINT(_OSMemoryBarrier) ba _COMM_PAGE_MEMORY_BARRIER + +/* void OSAtomicEnqueue( OSQueueHead *list, void *new, size_t offset); */ + +MI_ENTRY_POINT(_OSAtomicEnqueue) + ba _COMM_PAGE_ENQUEUE + + +/* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */ + +MI_ENTRY_POINT(_OSAtomicDequeue) + ba _COMM_PAGE_DEQUEUE diff --git a/ppc/sys/SYS.h b/ppc/sys/SYS.h index 0ce8a58..5a94d38 100644 --- a/ppc/sys/SYS.h +++ b/ppc/sys/SYS.h @@ -148,12 +148,19 @@ _##trap_name: @\ _##pseudo: @\ SYSCALL_NONAME(name, nargs) +#define PSEUDO_ERR(pseudo, name, nargs, error_ret) \ + .globl _##pseudo @\ + .globl error_ret @\ + .text @\ + .align 2 @\ +_##pseudo: @\ + kernel_trap_args_##nargs @\ + li r0,SYS_##name @\ + sc @\ + b 1f @\ + blr @\ +1: MI_BRANCH_EXTERNAL(error_ret) + #undef END #import - -#if !defined(SYS___pthread_canceled) -#define SYS___pthread_markcancel 332 -#define SYS___pthread_canceled 333 -#define SYS___semwait_signal 334 -#endif diff --git a/ppc/sys/__mmap.s b/ppc/sys/__mmap.s deleted file mode 100644 index 91926b7..0000000 --- a/ppc/sys/__mmap.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -PSEUDO(__mmap, mmap, 6) - blr diff --git a/ppc/sys/__pthread_canceled.s b/ppc/sys/__pthread_canceled.s deleted file mode 100644 index 906eefd..0000000 --- a/ppc/sys/__pthread_canceled.s +++ /dev/null @@ -1,27 +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@ - */ -#include "SYS.h" - -SYSCALL(__pthread_canceled, 1) - - diff --git a/ppc/sys/__semwait_signal.s b/ppc/sys/__semwait_signal.s deleted file mode 100644 index 339b31d..0000000 --- a/ppc/sys/__semwait_signal.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(__semwait_signal, 6) - diff --git a/ppc/sys/_exit.s b/ppc/sys/_exit.s deleted file mode 100644 index ce75ddb..0000000 --- a/ppc/sys/_exit.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -PSEUDO(_exit, exit, 1) - blr diff --git a/ppc/sys/_getlogin.s b/ppc/sys/_getlogin.s deleted file mode 100644 index b37dee5..0000000 --- a/ppc/sys/_getlogin.s +++ /dev/null @@ -1,27 +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@ - */ -#include "SYS.h" - -PSEUDO(_getlogin, getlogin, 0) - blr - diff --git a/ppc/sys/_pthread_kill.s b/ppc/sys/_pthread_kill.s deleted file mode 100644 index bb863c0..0000000 --- a/ppc/sys/_pthread_kill.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(__pthread_kill, 2) - diff --git a/ppc/sys/_setjmp.h b/ppc/sys/_setjmp.h index 65456c7..68fb686 100644 --- a/ppc/sys/_setjmp.h +++ b/ppc/sys/_setjmp.h @@ -81,7 +81,8 @@ /* save room for 12 VRs (v20-v31), or 0xC0 bytes */ #define JMP_fp_base_addr 0x144 /* save room for 18 FPRs (f14-f31), or 0x90 bytes */ -#define JMP_buf_end 0x1d4 +#define JMP_ss_flags 0x1d4 +#define JMP_buf_end 0x1d8 /* 64-bit-mode layout */ @@ -121,7 +122,8 @@ /* save room for 12 VRs (v20-v31), or 0xC0 bytes */ #define JMP_fp_base_addr 0x1ac /* save room for 18 FPRs (f14-f31), or 0x90 bytes */ -#define JMP_buf_end 0x23c +#define JMP_ss_flags 0x23c +#define JMP_buf_end 0x240 #else #error architecture not supported diff --git a/ppc/sys/_setlogin.s b/ppc/sys/_setlogin.s deleted file mode 100644 index cc99282..0000000 --- a/ppc/sys/_setlogin.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -PSEUDO(_setlogin, setlogin, 0) - blr diff --git a/ppc/sys/_sigtramp.s b/ppc/sys/_sigtramp.s new file mode 100644 index 0000000..cd2dfc6 --- /dev/null +++ b/ppc/sys/_sigtramp.s @@ -0,0 +1,529 @@ +/* + * 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 +#include + +#define UC_TRAD 1 +#define UC_TRAD64 20 +#define UC_TRAD64_VEC 25 +#define UC_FLAVOR 30 +#define UC_FLAVOR_VEC 35 +#define UC_FLAVOR64 40 +#define UC_FLAVOR64_VEC 45 +#define UC_DUAL 50 +#define UC_DUAL_VEC 55 + +/* Structure fields and sizes for ucontext and mcontext. */ +#define UCONTEXT_UC_MCSIZE MODE_CHOICE (24, 40) +#define UCONTEXT_UC_MCONTEXT MODE_CHOICE (28, 48) +#define MCONTEXT_SIZE 1032 +#define MCONTEXT64_SIZE 1176 +#define UC_FLAVOR64_SIZE 600 +#define UC_FLAVOR64_VEC_SIZE MCONTEXT64_SIZE + +#define MCONTEXT_ES_EXCEPTION 8 +#define MCONTEXT_SS_SRR0 32 +#define MCONTEXT_SS_SRR1 36 +#define MCONTEXT_SS_R0 40 +#define MCONTEXT_SS_CR 168 +#define MCONTEXT_SS_XER 172 +#define MCONTEXT_SS_LR 176 +#define MCONTEXT_SS_CTR 180 +#define MCONTEXT_SS_MQ 184 +#define MCONTEXT_SS_VRSAVE 188 +#define MCONTEXT_FS_FPREGS 192 +#define MCONTEXT_FS_FPSCR 448 +#define MCONTEXT_VS_SAVE_VR 456 +#define MCONTEXT_VS_VSCR 968 + +#define MCONTEXT64_ES_EXCEPTION 12 +#define MCONTEXT64_SS_SRR0 32 +#define MCONTEXT64_SS_SRR1 40 +#define MCONTEXT64_SS_R0 48 +#define MCONTEXT64_SS_CR 304 +#define MCONTEXT64_SS_XER 308 +#define MCONTEXT64_SS_LR 316 +#define MCONTEXT64_SS_CTR 324 +#define MCONTEXT64_SS_VRSAVE 332 +#define MCONTEXT64_FS_FPREGS 336 +#define MCONTEXT64_FS_FPSCR 592 +#define MCONTEXT64_VS_SAVE_VR 600 +#define MCONTEXT64_VS_VSCR 1112 + +/* Exception types. I believe the MCONTEXT_ES_EXCEPTION field is set from + the address called to handle the exception, for example a + Program Exception jumps to address 0x00700 and so the field has + value 7. */ +#define EXCEPTION_DSI 3 +#define EXCEPTION_ISI 4 +#define EXCEPTION_INTERRUPT 5 +#define EXCEPTION_ALIGN 6 +#define EXCEPTION_PROGRAM 7 +#define EXCEPTION_FPUNAVAIL 8 +#define EXCEPTION_DEC 9 +#define EXCEPTION_SC 0xC +#define EXCEPTION_TRACE 0xD +#define EXCEPTION_FPASSIST 0xE + +/* register allocation: + r0 : scratch, also used by MI_* macros + r3 : parameter union __sigaction_u __sigaction_u + r4 : parameter int sigstyle + r5 : parameter int sig + r6 : parameter siginfo_t *sinfo + r7 : parameter ucontext_t *uctx + r8 : value of __in_sigtramp + r9 : &__in_sigtramp + r12: scratch used by MI_* macros + + r29 : sigstyle + r28 : uctx + r27 : uctx->uc_mcontext + +*/ + +MI_ENTRY_POINT(__sigtramp) + /* Save away sigstyle and uctx. This code doesn't need to + restore the callee-saved registers, since sigreturn + will do it. */ + mr r28,r7 + mr r29,r4 +#if defined(__DYNAMIC__) + /* ++__in_sigtramp; */ + MI_GET_ADDRESS (r9, ___in_sigtramp) + lwz r8,0(r9) + addi r8,r8,1 + stw r8,0(r9) +#endif + /* Having this here shortens the unwind tables significantly. */ + lg r27,UCONTEXT_UC_MCONTEXT(r7) + + /* Call the signal handler. + Some variants are not supposed to get the last two parameters, + but the test to prevent this is more expensive than just passing + them. */ + mtctr r3 + mr r3,r5 + mr r4,r6 + mr r5,r7 +Lcall_start: + bctrl +Lcall_end: + + /* Call __finish_sigtramp in sigtramp.c to complete processing + for ppc, or just return to the kernel using sigtramp for ppc64. */ + mr r3,r28 + mr r4,r29 + b MODE_CHOICE (___finish_sigtramp, ___sigreturn) + /* Does not return. */ + +/* DWARF unwind table #defines. */ +#define DW_CFA_advance_loc_4 0x44 +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_def_cfa_expression 0x0F +#define DW_CFA_expression 0x10 +#define DW_CFA_val_expression 0x16 +#define DW_CFA_offset(column) 0x80+(column) + +/* DWARF expression #defines. */ +#define DW_OP_deref 0x06 +#define DW_OP_const1u 0x08 +#define DW_OP_dup 0x12 +#define DW_OP_drop 0x13 +#define DW_OP_over 0x14 +#define DW_OP_pick 0x15 +#define DW_OP_swap 0x16 +#define DW_OP_rot 0x17 +#define DW_OP_abs 0x19 +#define DW_OP_and 0x1a +#define DW_OP_div 0x1b +#define DW_OP_minus 0x1c +#define DW_OP_mod 0x1d +#define DW_OP_mul 0x1e +#define DW_OP_neg 0x1f +#define DW_OP_not 0x20 +#define DW_OP_or 0x21 +#define DW_OP_plus 0x22 +#define DW_OP_plus_uconst 0x23 +#define DW_OP_shl 0x24 +#define DW_OP_shr 0x25 +#define DW_OP_shra 0x26 +#define DW_OP_xor 0x27 +#define DW_OP_skip 0x2f +#define DW_OP_bra 0x28 +#define DW_OP_eq 0x29 +#define DW_OP_ge 0x2A +#define DW_OP_gt 0x2B +#define DW_OP_le 0x2C +#define DW_OP_lt 0x2D +#define DW_OP_ne 0x2E +#define DW_OP_lit(n) 0x30+(n) +#define DW_OP_breg(n) 0x70+(n) +#define DW_OP_deref_size 0x94 + +/* The location expressions we'll use. */ + +#ifdef __ppc__ +/* The ppc versions test register 29 for UC_TRAD64, UC_TRAD64_VEC, + UC_FLAVOR64, UC_FLAVOR64_VEC, and then use the appropriate offset + off r27 (either the offset for a mcontext or a mcontext64). + + The expression computed has been somewhat optimised to reduce the size + of the unwind entries, and is of the form + + (r27 + offs + + ((r29/10)==UC_TRAD64/10 || (r29/10)==UC_FLAVOR64/10)*(offs64-offs)) +*/ + +/* For when REGNO < 128 and OFFS < 64. */ +#define loc_expr_for_reg_sml(regno, offs, offs64) \ + .byte DW_CFA_expression, regno, 17 /* block length */, \ + DW_OP_breg(27), offs, \ + DW_OP_breg(29), 0, DW_OP_lit(10), DW_OP_div, \ + DW_OP_dup, DW_OP_lit(UC_TRAD64/10), DW_OP_eq, \ + DW_OP_swap, DW_OP_lit(UC_FLAVOR64/10), DW_OP_eq, DW_OP_or, \ + DW_OP_const1u, offs64-(offs), DW_OP_mul, DW_OP_plus + +/* For when REGNO < 128 and OFFS >= 64. */ +#define loc_expr_for_reg(regno, offs, offs64) \ + .byte DW_CFA_expression, regno, 18 /* block length */, \ + DW_OP_breg(27), (offs & 0x7F) | 0x80, (offs >> 7), \ + DW_OP_breg(29), 0, DW_OP_lit(10), DW_OP_div, \ + DW_OP_dup, DW_OP_lit(UC_TRAD64/10), DW_OP_eq, \ + DW_OP_swap, DW_OP_lit(UC_FLAVOR64/10), DW_OP_eq, DW_OP_or, \ + DW_OP_const1u, offs64-(offs), DW_OP_mul, DW_OP_plus + +#else + +/* The kernel always gives a ppc64 process a mcontext64, so just use + that offset. */ +#define loc_expr_for_reg(regno, offs, offs64) \ + .byte DW_CFA_expression, regno, 3 /* block length */, \ + DW_OP_breg(27), (offs64 & 0x7F) | 0x80, (offs64 >> 7) + +#define loc_expr_for_reg_sml(regno, offs, offs64) \ + loc_expr_for_reg(regno, offs, offs64) + +#endif /* __ppc__ */ + +#define loc_expr_varying(regno, offs, offs64) \ + loc_expr_for_reg (regno, offs, (offs64+MODE_CHOICE(4,0))) + +/* For REGNO < 22 */ +#define loc_expr_gpr_sml(regno) \ + loc_expr_for_reg_sml (regno, MCONTEXT_SS_R0+(4*regno), \ + MCONTEXT64_SS_R0+(8*regno)+MODE_CHOICE (4,0)) + +/* For REGNO >= 22 */ +#define loc_expr_gpr(regno) \ + loc_expr_varying (regno, MCONTEXT_SS_R0+(4*regno), \ + MCONTEXT64_SS_R0+(8*regno)) + +#define loc_expr_fpr(regno) \ + loc_expr_for_reg (regno+32, MCONTEXT_FS_FPREGS+(8*regno), \ + MCONTEXT64_FS_FPREGS+(8*regno)) +#define loc_expr_vr(regno) \ + loc_expr_for_reg (regno+77, MCONTEXT_VS_SAVE_VR+(16*regno), \ + MCONTEXT64_VS_SAVE_VR+(16*regno)) + + /* Unwind tables. */ + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 ; Length of Common Information Entry +LSCIE1: + .long 0 ; CIE Identifier Tag + .byte 0x3 ; CIE Version + .ascii "zR\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 + /* The choice of column for the return address is somewhat tricky. + Fortunately, the actual choice is private to this file, and + the space it's reserved from is the GCC register space, not the + DWARF2 numbering. So any free element of the right size is an OK + choice. Thus: */ + .byte 67 ; CIE RA Column + .byte 0x1 ; uleb128 0x1; Augmentation size + .byte 0x10 ; FDE Encoding (pcrel) + .byte 0xc ; DW_CFA_def_cfa + .byte 0x1 ; uleb128 0x1 + .byte 0x0 ; uleb128 0x0 + .align LOG2_GPR_BYTES +LECIE1: + .globl _sigtramp.eh +_sigtramp.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 ; FDE Length +LASFDE1: + .long LASFDE1-EH_frame1 ; FDE CIE offset + .g_long Lcall_start-. ; FDE initial location + .set L$set$2,Lcall_end-Lcall_start + .g_long L$set$2 ; FDE address range + .byte 0x0 ; uleb128 0x0; Augmentation size + + /* Now for the expressions, which all compute + uctx->uc_mcontext->register + for each register. + uctx->uc_mcontext is already in r27, so + the tricky part is that this might be a 64-bit context, + in which case the offset would be different. + + In the case of a dual context, only the low half of a + GPR is restored. + + Restore even the registers that are not call-saved because they + might be being used in the prologue to save other registers, + for instance GPR0 is sometimes used to save LR. */ + + loc_expr_gpr_sml (0) + loc_expr_gpr_sml (1) + loc_expr_gpr_sml (2) + loc_expr_gpr_sml (3) + loc_expr_gpr_sml (4) + loc_expr_gpr_sml (5) + loc_expr_gpr (6) + loc_expr_gpr (7) + loc_expr_gpr (8) + loc_expr_gpr (9) + loc_expr_gpr (10) + loc_expr_gpr (11) + loc_expr_gpr (12) + loc_expr_gpr (13) + loc_expr_gpr (14) + loc_expr_gpr (15) + loc_expr_gpr (16) + loc_expr_gpr (17) + loc_expr_gpr (18) + loc_expr_gpr (19) + loc_expr_gpr (20) + loc_expr_gpr (21) + loc_expr_gpr (22) + loc_expr_gpr (23) + loc_expr_gpr (24) + loc_expr_gpr (25) + loc_expr_gpr (26) + loc_expr_gpr (27) + loc_expr_gpr (28) + loc_expr_gpr (29) + loc_expr_gpr (30) + loc_expr_gpr (31) + + loc_expr_for_reg (64, MCONTEXT_SS_CR, MCONTEXT64_SS_CR) + loc_expr_varying (76, MCONTEXT_SS_XER, MCONTEXT64_SS_XER) + loc_expr_varying (65, MCONTEXT_SS_LR, MCONTEXT64_SS_LR) + loc_expr_varying (66, MCONTEXT_SS_CTR, MCONTEXT64_SS_CTR) + loc_expr_for_reg (109, MCONTEXT_SS_VRSAVE, MCONTEXT64_SS_VRSAVE) + + loc_expr_fpr (0) + loc_expr_fpr (1) + loc_expr_fpr (2) + loc_expr_fpr (3) + loc_expr_fpr (4) + loc_expr_fpr (5) + loc_expr_fpr (6) + loc_expr_fpr (7) + loc_expr_fpr (8) + loc_expr_fpr (9) + loc_expr_fpr (10) + loc_expr_fpr (11) + loc_expr_fpr (12) + loc_expr_fpr (13) + loc_expr_fpr (14) + loc_expr_fpr (15) + loc_expr_fpr (16) + loc_expr_fpr (17) + loc_expr_fpr (18) + loc_expr_fpr (19) + loc_expr_fpr (20) + loc_expr_fpr (21) + loc_expr_fpr (22) + loc_expr_fpr (23) + loc_expr_fpr (24) + loc_expr_fpr (25) + loc_expr_fpr (26) + loc_expr_fpr (27) + loc_expr_fpr (28) + loc_expr_fpr (29) + loc_expr_fpr (30) + loc_expr_fpr (31) + + loc_expr_for_reg (112, MCONTEXT_FS_FPSCR, MCONTEXT64_FS_FPSCR) + + loc_expr_vr (0) + loc_expr_vr (1) + loc_expr_vr (2) + loc_expr_vr (3) + loc_expr_vr (4) + loc_expr_vr (5) + loc_expr_vr (6) + loc_expr_vr (7) + loc_expr_vr (8) + loc_expr_vr (9) + loc_expr_vr (10) + loc_expr_vr (11) + loc_expr_vr (12) + loc_expr_vr (13) + loc_expr_vr (14) + loc_expr_vr (15) + loc_expr_vr (16) + loc_expr_vr (17) + loc_expr_vr (18) + loc_expr_vr (19) + loc_expr_vr (20) + loc_expr_vr (21) + loc_expr_vr (22) + loc_expr_vr (23) + loc_expr_vr (24) + loc_expr_vr (25) + loc_expr_vr (26) + loc_expr_vr (27) + loc_expr_vr (28) + loc_expr_vr (29) + loc_expr_vr (30) + loc_expr_vr (31) + + loc_expr_for_reg (110, MCONTEXT_VS_VSCR, MCONTEXT64_VS_VSCR) + + /* The return address is even more complicated, because it needs + to be the actual address to which to return, and so + depends on the signal thrown, because some signals have SRR0 + as the address of the faulting instruction, and others + have it as the next address to execute. + + Although MCONTEXT_SS_SRR0 is the same as MCONTEXT64_SS_SRR0, + that doesn't really simplify things much, since if + the context is a 64-bit context for a 32-bit process, + we'll need to add 4 to get to the low word. */ + + /* The exception types that point to the faulting instruction are: + EXCEPTION_DSI, EXCEPTION_ALIGN, EXCEPTION_FPUNAVAIL, + and + EXCEPTION_PROGRAM when SRR1[47] is clear. + The others point to the next instruction to execute. + + EXCEPTION_ISI is a special case. There are these possibilies: + - program calls a subroutine which is NULL, in which case + SRR0 holds NULL and LR-4 is the faulting instruction. + - program executes a computed goto to NULL, in which case + there is no way to know the faulting instruction. + - program runs off end of its text, in which case + SRR0-4 is the faulting instruction + - program executes a wild branch. + I think this code most needs to handle the first case, as + the other cases are rare or can't be handled. */ + + .byte DW_CFA_val_expression, 67 + .set L$set$3,Lpc_end-Lpc_start + .byte L$set$3 +Lpc_start: +#ifdef __ppc__ + /* On ppc, compute whether or not a 64-bit exception frame is in + use. */ + .byte DW_OP_breg(29), 0, DW_OP_lit(10), DW_OP_div + .byte DW_OP_dup, DW_OP_lit(UC_TRAD64/10), DW_OP_eq + .byte DW_OP_swap, DW_OP_lit(UC_FLAVOR64/10), DW_OP_eq, DW_OP_or + + /* Find the value of SRR0. */ + .byte DW_OP_dup + .byte DW_OP_lit(MCONTEXT64_SS_SRR0+4-MCONTEXT_SS_SRR0), DW_OP_mul + .byte DW_OP_breg(27), MCONTEXT_SS_SRR0 + .byte DW_OP_plus, DW_OP_deref + /* Determine the exception type. */ + .byte DW_OP_swap, DW_OP_dup + .byte DW_OP_lit(MCONTEXT64_ES_EXCEPTION-MCONTEXT_ES_EXCEPTION) + .byte DW_OP_mul + .byte DW_OP_breg(27), MCONTEXT_ES_EXCEPTION + .byte DW_OP_plus, DW_OP_deref + /* Find the value of SRR1. */ + .byte DW_OP_swap, DW_OP_dup + .byte DW_OP_lit(MCONTEXT64_SS_SRR1+4-MCONTEXT_SS_SRR1), DW_OP_mul + .byte DW_OP_breg(27), MCONTEXT_SS_SRR1 + .byte DW_OP_plus, DW_OP_deref + /* Find the value of LR. */ + .byte DW_OP_swap + .byte DW_OP_const1u, MCONTEXT64_SS_LR+4-MCONTEXT_SS_LR, DW_OP_mul + .byte DW_OP_breg(27), MCONTEXT_SS_LR, MCONTEXT_SS_LR >> 7 + .byte DW_OP_plus, DW_OP_deref +#else + /* Find the value of SRR0. */ + .byte DW_OP_breg(27), MCONTEXT64_SS_SRR0, DW_OP_deref + /* Determine the exception type. */ + .byte DW_OP_breg(27), MCONTEXT64_ES_EXCEPTION, DW_OP_deref_size, 4 + /* Find the value of SRR1. */ + .byte DW_OP_breg(27), MCONTEXT64_SS_SRR1, DW_OP_deref + /* Find the value of LR. */ + .byte DW_OP_breg(27), MCONTEXT64_SS_LR & 0x7f | 0x80 + .byte MCONTEXT64_SS_LR >> 7 + .byte DW_OP_deref +#endif + /* At this point, the stack contains LR, SRR1, the exception type, + SRR0, and the base CFA address (which this doesn't use). */ + + /* If the exception type is EXCEPTION_ISI, the result is LR. */ + .byte DW_OP_pick, 2 + .byte DW_OP_lit(EXCEPTION_ISI), DW_OP_eq + .byte DW_OP_bra ; 'bra' is a conditional branch. + .set L$set$5,Lpc_end-0f + .short L$set$5 +0: + .byte DW_OP_drop + + /* Otherwise, start by determining if SRR1[47] is clear... */ + .byte DW_OP_not, DW_OP_lit(16), DW_OP_shr, DW_OP_lit(1), DW_OP_and + /* ...and the exception type is EXCEPTION_PROGRAM. */ + .byte DW_OP_over, DW_OP_lit(EXCEPTION_PROGRAM), DW_OP_eq, DW_OP_and + /* Check if any of the other exception cases are present. */ + .byte DW_OP_over, DW_OP_lit(EXCEPTION_DSI), DW_OP_eq, DW_OP_or + .byte DW_OP_over, DW_OP_lit(EXCEPTION_ALIGN), DW_OP_eq, DW_OP_or + .byte DW_OP_swap, DW_OP_lit(EXCEPTION_FPUNAVAIL) + .byte DW_OP_eq, DW_OP_or + /* If the exception points to the faulting instruction, add + 4 to point past the faulting instruction. */ + .byte DW_OP_lit(4), DW_OP_mul, DW_OP_plus +Lpc_end: + + /* The CFA will have been saved as the value of R1. */ + .byte DW_CFA_def_cfa_expression + .set L$set$4,Lcfa_end-Lcfa_start + .byte L$set$4 +Lcfa_start: +#ifdef __ppc__ + .byte DW_OP_breg(27), MCONTEXT_SS_R0+4 + .byte DW_OP_breg(29), 0, DW_OP_lit(10), DW_OP_div + .byte DW_OP_dup, DW_OP_lit(UC_TRAD64/10), DW_OP_eq + .byte DW_OP_swap, DW_OP_lit(UC_FLAVOR64/10), DW_OP_eq, DW_OP_or + .byte DW_OP_lit(MCONTEXT64_SS_R0+12-MCONTEXT_SS_R0-4) + .byte DW_OP_mul, DW_OP_plus + .byte DW_OP_deref +#else + .byte DW_OP_breg(27), MCONTEXT64_SS_R0+8, DW_OP_deref +#endif +Lcfa_end: + + .align LOG2_GPR_BYTES +LEFDE1: + + .subsections_via_symbols diff --git a/ppc/sys/_sysctl.s b/ppc/sys/_sysctl.s deleted file mode 100644 index 1322e52..0000000 --- a/ppc/sys/_sysctl.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(__sysctl, 6) - diff --git a/ppc/sys/accept.s b/ppc/sys/accept.s deleted file mode 100644 index dcd2eda..0000000 --- a/ppc/sys/accept.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@ - */ -#include "SYS.h" - -#ifdef __LP64__ -SYSCALL(accept, 3) -#else /* !__LP64__ */ -PSEUDO(accept$UNIX2003, accept, 3) - blr - -SYSCALL_ERR(accept, 3, cerror_cvt) -#endif /* __LP64__ */ - diff --git a/ppc/sys/access.s b/ppc/sys/access.s deleted file mode 100644 index 49d0b3b..0000000 --- a/ppc/sys/access.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(access, 2) - diff --git a/ppc/sys/acct.s b/ppc/sys/acct.s deleted file mode 100644 index 1c0581d..0000000 --- a/ppc/sys/acct.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(acct, 1) - diff --git a/ppc/sys/add_profil.s b/ppc/sys/add_profil.s deleted file mode 100644 index 8baa49a..0000000 --- a/ppc/sys/add_profil.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(add_profil, 4) diff --git a/ppc/sys/adjtime.s b/ppc/sys/adjtime.s deleted file mode 100644 index 2b50258..0000000 --- a/ppc/sys/adjtime.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(adjtime, 2) - diff --git a/ppc/sys/aio_cancel.s b/ppc/sys/aio_cancel.s deleted file mode 100644 index 918e1bf..0000000 --- a/ppc/sys/aio_cancel.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(aio_cancel, 2) - diff --git a/ppc/sys/aio_error.s b/ppc/sys/aio_error.s deleted file mode 100644 index 6a559e4..0000000 --- a/ppc/sys/aio_error.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(aio_error, 1) - diff --git a/ppc/sys/aio_fsync.s b/ppc/sys/aio_fsync.s deleted file mode 100644 index becaad5..0000000 --- a/ppc/sys/aio_fsync.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(aio_fsync, 2) - diff --git a/ppc/sys/aio_read.s b/ppc/sys/aio_read.s deleted file mode 100644 index 87f99a2..0000000 --- a/ppc/sys/aio_read.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(aio_read, 1) - diff --git a/ppc/sys/aio_return.s b/ppc/sys/aio_return.s deleted file mode 100644 index a58039f..0000000 --- a/ppc/sys/aio_return.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(aio_return, 1) - diff --git a/ppc/sys/aio_suspend.s b/ppc/sys/aio_suspend.s deleted file mode 100644 index 9250c5f..0000000 --- a/ppc/sys/aio_suspend.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(aio_suspend, 3) - diff --git a/ppc/sys/aio_write.s b/ppc/sys/aio_write.s deleted file mode 100644 index 348e2ac..0000000 --- a/ppc/sys/aio_write.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(aio_write, 1) - diff --git a/ppc/sys/assym.h b/ppc/sys/assym.h deleted file mode 100644 index c025721..0000000 --- a/ppc/sys/assym.h +++ /dev/null @@ -1,156 +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@ - */ -#ifndef _ASSYM_H_ -#define _ASSYM_H_ -#define PCB_FLOAT_STATE 208 -#define PCB_FS_F0 208 -#define PCB_FS_F1 216 -#define PCB_FS_F2 224 -#define PCB_FS_F3 232 -#define PCB_FS_F4 240 -#define PCB_FS_F5 248 -#define PCB_FS_F6 256 -#define PCB_FS_F7 264 -#define PCB_FS_F8 272 -#define PCB_FS_F9 280 -#define PCB_FS_F10 288 -#define PCB_FS_F11 296 -#define PCB_FS_F12 304 -#define PCB_FS_F13 312 -#define PCB_FS_F14 320 -#define PCB_FS_F15 328 -#define PCB_FS_F16 336 -#define PCB_FS_F17 344 -#define PCB_FS_F18 352 -#define PCB_FS_F19 360 -#define PCB_FS_F20 368 -#define PCB_FS_F21 376 -#define PCB_FS_F22 384 -#define PCB_FS_F23 392 -#define PCB_FS_F24 400 -#define PCB_FS_F25 408 -#define PCB_FS_F26 416 -#define PCB_FS_F27 424 -#define PCB_FS_F28 432 -#define PCB_FS_F29 440 -#define PCB_FS_F30 448 -#define PCB_FS_F31 456 -#define PCB_FS_FPSCR 464 -#define PCB_SAVED_STATE 0 -#define PCB_KSP 472 -#define PCB_SR0 476 -#define PCB_SIZE 480 -#define SS_R0 8 -#define SS_R1 12 -#define SS_R2 16 -#define SS_R3 20 -#define SS_R4 24 -#define SS_R5 28 -#define SS_R6 32 -#define SS_R7 36 -#define SS_R8 40 -#define SS_R9 44 -#define SS_R10 48 -#define SS_R11 52 -#define SS_R12 56 -#define SS_R13 60 -#define SS_R14 64 -#define SS_R15 68 -#define SS_R16 72 -#define SS_R17 76 -#define SS_R18 80 -#define SS_R19 84 -#define SS_R20 88 -#define SS_R21 92 -#define SS_R22 96 -#define SS_R23 100 -#define SS_R24 104 -#define SS_R25 108 -#define SS_R26 112 -#define SS_R27 116 -#define SS_R28 120 -#define SS_R29 124 -#define SS_R30 128 -#define SS_R31 132 -#define SS_CR 136 -#define SS_XER 140 -#define SS_LR 144 -#define SS_CTR 148 -#define SS_SRR0 0 -#define SS_SRR1 4 -#define SS_MQ 152 -#define SS_SR_COPYIN 160 -#define SS_SIZE 176 -#define PP_SAVE_CR 0 -#define PP_SAVE_SRR0 4 -#define PP_SAVE_SRR1 8 -#define PP_SAVE_DAR 12 -#define PP_SAVE_DSISR 16 -#define PP_SAVE_SPRG0 20 -#define PP_SAVE_SPRG1 24 -#define PP_SAVE_SPRG2 28 -#define PP_SAVE_SPRG3 32 -#define PP_SAVE_EXCEPTION_TYPE 36 -#define PP_CPU_DATA 52 -#define PP_PHYS_EXCEPTION_HANDLERS 40 -#define PP_VIRT_PER_PROC 44 -#define PP_ACTIVE_STACKS 56 -#define PP_NEED_AST 60 -#define PP_FPU_PCB 64 -#define KS_PCB 16276 -#define KS_R1 16280 -#define KS_R2 16284 -#define KS_R13 16288 -#define KS_LR 16364 -#define KS_CR 16368 -#define KS_SIZE 96 -#define KSTK_SIZE 16372 -#define THREAD_PCB 36 -#define THREAD_KERNEL_STACK 40 -#define THREAD_SWAPFUNC 48 -#define THREAD_RECOVER 116 -#define THREAD_TASK 12 -#define TASK_VMMAP 8 -#define TASK_MACH_EXC_PORT 96 -#define VMMAP_PMAP 32 -#define PMAP_SPACE 4 -#define MACH_TRAP_OFFSET_POW2 4 -#define MACH_TRAP_ARGC 0 -#define MACH_TRAP_FUNCTION 4 -#define HOST_SELF 0 -#define CPU_ACTIVE_THREAD 0 -#define FM_SIZE 56 -#define ARG_SIZE 16 -#define LA_SIZE 24 -#define FM_BACKPTR 0 -#define FM_LR_SAVE 8 -#define FM_TOC_SAVE 20 -#define RPA_SIZE 32 -#define SPA_SIZE 16 -#define FM_ARG0 56 -#define FM_REDZONE 0 - -#define SIZEOF_SIGCATCH 4 -#define SIGCATCH_HANDLER 0x00000000 - -#endif /* _ASSYM_H_ */ diff --git a/ppc/sys/assymdefs.c b/ppc/sys/assymdefs.c deleted file mode 100644 index 407e9ea..0000000 --- a/ppc/sys/assymdefs.c +++ /dev/null @@ -1,129 +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@ - */ -/* - * assymdefs.c -- list of symbols to #define in assym.h - */ - -#import -#import - -#define __TARGET_ARCHITECTURE__ "ppc" -#import -#import "sigcatch.h" - -#import "genassym.h" - -void -assymdefs(void) -{ - comment(MAJOR, "Structure Offsets"); - - comment(MINOR, "struct sigcontext offsets and sizes"); - PRINT_SIZEOF(struct sigcontext); - PRINT_OFFSET(struct sigcontext *, sc_regs_saved); - PRINT_OFFSET(struct sigcontext *, sc_sp); - PRINT_OFFSET(struct sigcontext *, sc_cia); - PRINT_OFFSET(struct sigcontext *, sc_a0); - PRINT_OFFSET(struct sigcontext *, sc_a1); - PRINT_OFFSET(struct sigcontext *, sc_a2); - PRINT_OFFSET(struct sigcontext *, sc_ep); - PRINT_OFFSET(struct sigcontext *, sc_mq); - PRINT_OFFSET(struct sigcontext *, sc_lr); - PRINT_OFFSET(struct sigcontext *, sc_cr); - PRINT_OFFSET(struct sigcontext *, sc_ctr); - PRINT_OFFSET(struct sigcontext *, sc_xer); - PRINT_OFFSET(struct sigcontext *, sc_fpscr); - PRINT_OFFSET(struct sigcontext *, sc_zt); - PRINT_OFFSET(struct sigcontext *, sc_a3); - PRINT_OFFSET(struct sigcontext *, sc_a4); - PRINT_OFFSET(struct sigcontext *, sc_a5); - PRINT_OFFSET(struct sigcontext *, sc_a6); - PRINT_OFFSET(struct sigcontext *, sc_a7); - PRINT_OFFSET(struct sigcontext *, sc_at); - PRINT_OFFSET(struct sigcontext *, sc_ft0); - PRINT_OFFSET(struct sigcontext *, sc_fa0); - PRINT_OFFSET(struct sigcontext *, sc_fa1); - PRINT_OFFSET(struct sigcontext *, sc_fa2); - PRINT_OFFSET(struct sigcontext *, sc_fa3); - PRINT_OFFSET(struct sigcontext *, sc_fa4); - PRINT_OFFSET(struct sigcontext *, sc_fa5); - PRINT_OFFSET(struct sigcontext *, sc_fa6); - PRINT_OFFSET(struct sigcontext *, sc_fa7); - PRINT_OFFSET(struct sigcontext *, sc_fa8); - PRINT_OFFSET(struct sigcontext *, sc_fa9); - PRINT_OFFSET(struct sigcontext *, sc_fa10); - PRINT_OFFSET(struct sigcontext *, sc_fa11); - PRINT_OFFSET(struct sigcontext *, sc_fa12); - PRINT_OFFSET(struct sigcontext *, sc_s17); - PRINT_OFFSET(struct sigcontext *, sc_s16); - PRINT_OFFSET(struct sigcontext *, sc_s15); - PRINT_OFFSET(struct sigcontext *, sc_s14); - PRINT_OFFSET(struct sigcontext *, sc_s13); - PRINT_OFFSET(struct sigcontext *, sc_s12); - PRINT_OFFSET(struct sigcontext *, sc_s11); - PRINT_OFFSET(struct sigcontext *, sc_s10); - PRINT_OFFSET(struct sigcontext *, sc_s9); - PRINT_OFFSET(struct sigcontext *, sc_s8); - PRINT_OFFSET(struct sigcontext *, sc_s7); - PRINT_OFFSET(struct sigcontext *, sc_s6); - PRINT_OFFSET(struct sigcontext *, sc_s5); - PRINT_OFFSET(struct sigcontext *, sc_s4); - PRINT_OFFSET(struct sigcontext *, sc_s3); - PRINT_OFFSET(struct sigcontext *, sc_s2); - PRINT_OFFSET(struct sigcontext *, sc_s1); - PRINT_OFFSET(struct sigcontext *, sc_s0); - PRINT_OFFSET(struct sigcontext *, sc_toc); - PRINT_OFFSET(struct sigcontext *, sc_fp); - PRINT_OFFSET(struct sigcontext *, sc_fs17); - PRINT_OFFSET(struct sigcontext *, sc_fs16); - PRINT_OFFSET(struct sigcontext *, sc_fs15); - PRINT_OFFSET(struct sigcontext *, sc_fs14); - PRINT_OFFSET(struct sigcontext *, sc_fs13); - PRINT_OFFSET(struct sigcontext *, sc_fs12); - PRINT_OFFSET(struct sigcontext *, sc_fs11); - PRINT_OFFSET(struct sigcontext *, sc_fs10); - PRINT_OFFSET(struct sigcontext *, sc_fs9); - PRINT_OFFSET(struct sigcontext *, sc_fs8); - PRINT_OFFSET(struct sigcontext *, sc_fs7); - PRINT_OFFSET(struct sigcontext *, sc_fs6); - PRINT_OFFSET(struct sigcontext *, sc_fs5); - PRINT_OFFSET(struct sigcontext *, sc_fs4); - PRINT_OFFSET(struct sigcontext *, sc_fs3); - PRINT_OFFSET(struct sigcontext *, sc_fs2); - PRINT_OFFSET(struct sigcontext *, sc_fs1); - PRINT_OFFSET(struct sigcontext *, sc_fs0); - PRINT_ENUM(REGS_SAVED_NONE); - PRINT_ENUM(REGS_SAVED_CALLER); - PRINT_ENUM(REGS_SAVED_ALL); - - comment(MINOR, "struct sigstack offsets and sizes"); - PRINT_SIZEOF(struct sigstack); - PRINT_OFFSET(struct sigstack *, ss_sp); - PRINT_OFFSET(struct sigstack *, ss_onstack); - - comment(MINOR, "sigcatch_t offsets"); - PRINT_SIZEOF(sigcatch_t); - PRINT_OFFSET(sigcatch_t *, handler); -// PRINT_OFFSET(sigcatch_t *, flags); - PRINT_CONSTANT(SV_SAVE_REGS); -} diff --git a/ppc/sys/audit.s b/ppc/sys/audit.s deleted file mode 100644 index ec20e21..0000000 --- a/ppc/sys/audit.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(audit, 2) - diff --git a/ppc/sys/auditctl.s b/ppc/sys/auditctl.s deleted file mode 100644 index 9f6a4e0..0000000 --- a/ppc/sys/auditctl.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(auditctl, 1) - diff --git a/ppc/sys/auditon.s b/ppc/sys/auditon.s deleted file mode 100644 index a35ddc4..0000000 --- a/ppc/sys/auditon.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(auditon, 3) - diff --git a/ppc/sys/auditsvc.s b/ppc/sys/auditsvc.s deleted file mode 100644 index e631b6b..0000000 --- a/ppc/sys/auditsvc.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(auditsvc, 2) - diff --git a/ppc/sys/cerror.s b/ppc/sys/cerror.s deleted file mode 100644 index 2d3982d..0000000 --- a/ppc/sys/cerror.s +++ /dev/null @@ -1,62 +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. - */ - -/* We use mode-independent "g" opcodes such as "srgi", and/or - * mode-independent macros such as MI_GET_ADDRESS. These expand - * into word operations when targeting __ppc__, and into doubleword - * operations when targeting __ppc64__. - */ -#include - - .globl _errno - -#if 0 -MI_ENTRY_POINT(cerror_cvt) - MI_PUSH_STACK_FRAME - MI_GET_ADDRESS(r12,_errno) - cmplwi r3,102 /* EOPNOTSUPP? */ - bne 1f - li r3,45 /* Yes; make ENOTSUP for compatibility */ -1: - stw r3,0(r12) /* save syscall return code in global */ - MI_CALL_EXTERNAL(_cthread_set_errno_self) - li r3,-1 /* then bug return value */ - li r4,-1 /* in case we're returning a long-long in 32-bit mode, etc */ - MI_POP_STACK_FRAME_AND_RETURN -#endif - -MI_ENTRY_POINT(cerror_cvt) - cmplwi r3,102 /* EOPNOTSUPP? */ - bne 1f - li r3,45 /* Yes; make ENOTSUP for compatibility */ -1: -MI_ENTRY_POINT(cerror) - MI_PUSH_STACK_FRAME - MI_GET_ADDRESS(r12,_errno) - stw r3,0(r12) /* save syscall return code in global */ - MI_CALL_EXTERNAL(_cthread_set_errno_self) - li r3,-1 /* then bug return value */ - li r4,-1 /* in case we're returning a long-long in 32-bit mode, etc */ - MI_POP_STACK_FRAME_AND_RETURN diff --git a/ppc/sys/chdir.s b/ppc/sys/chdir.s deleted file mode 100644 index b2e0d57..0000000 --- a/ppc/sys/chdir.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(chdir, 1) - diff --git a/ppc/sys/checkuseraccess.s b/ppc/sys/checkuseraccess.s deleted file mode 100644 index c1ebd0f..0000000 --- a/ppc/sys/checkuseraccess.s +++ /dev/null @@ -1,27 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL(checkuseraccess, 0) diff --git a/ppc/sys/chflags.s b/ppc/sys/chflags.s deleted file mode 100644 index 930eb4e..0000000 --- a/ppc/sys/chflags.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(chflags, 2) diff --git a/ppc/sys/chmod.s b/ppc/sys/chmod.s deleted file mode 100644 index 2a46c09..0000000 --- a/ppc/sys/chmod.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(chmod, 2) - diff --git a/ppc/sys/chown.s b/ppc/sys/chown.s deleted file mode 100644 index 7008e88..0000000 --- a/ppc/sys/chown.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(chown, 3) - diff --git a/ppc/sys/chroot.s b/ppc/sys/chroot.s deleted file mode 100644 index f3fd6c9..0000000 --- a/ppc/sys/chroot.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(chroot, 1) - diff --git a/ppc/sys/close.s b/ppc/sys/close.s deleted file mode 100644 index dc41a36..0000000 --- a/ppc/sys/close.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(close, 1) - diff --git a/ppc/sys/dup.s b/ppc/sys/dup.s deleted file mode 100644 index c68af1d..0000000 --- a/ppc/sys/dup.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(dup, 2) - diff --git a/ppc/sys/dup2.s b/ppc/sys/dup2.s deleted file mode 100644 index bcb5a38..0000000 --- a/ppc/sys/dup2.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(dup2, 2) - diff --git a/ppc/sys/exchangedata.s b/ppc/sys/exchangedata.s deleted file mode 100644 index 96b73f8..0000000 --- a/ppc/sys/exchangedata.s +++ /dev/null @@ -1,27 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL(exchangedata, 0) diff --git a/ppc/sys/execve.s b/ppc/sys/execve.s deleted file mode 100644 index 667b09f..0000000 --- a/ppc/sys/execve.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(execve, 3) - diff --git a/ppc/sys/fchdir.s b/ppc/sys/fchdir.s deleted file mode 100644 index 131d989..0000000 --- a/ppc/sys/fchdir.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(fchdir, 1) - diff --git a/ppc/sys/fchflags.s b/ppc/sys/fchflags.s deleted file mode 100644 index 3538f84..0000000 --- a/ppc/sys/fchflags.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(fchflags, 2) diff --git a/ppc/sys/fchmod.s b/ppc/sys/fchmod.s deleted file mode 100644 index dc8e29f..0000000 --- a/ppc/sys/fchmod.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(fchmod, 2) - diff --git a/ppc/sys/fchown.s b/ppc/sys/fchown.s deleted file mode 100644 index 919ccd4..0000000 --- a/ppc/sys/fchown.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(fchown, 3) - diff --git a/ppc/sys/fcntl.s b/ppc/sys/fcntl.s deleted file mode 100644 index 25f6bca..0000000 --- a/ppc/sys/fcntl.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(fcntl, 3) - diff --git a/ppc/sys/fgetxattr.s b/ppc/sys/fgetxattr.s deleted file mode 100644 index 9198ba5..0000000 --- a/ppc/sys/fgetxattr.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -SYSCALL(fgetxattr, 6) - diff --git a/ppc/sys/fhopen.s b/ppc/sys/fhopen.s deleted file mode 100644 index 3875be8..0000000 --- a/ppc/sys/fhopen.s +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 "SYS.h" - -SYSCALL(fhopen, 2) - diff --git a/ppc/sys/flistxattr.s b/ppc/sys/flistxattr.s deleted file mode 100644 index e2fa172..0000000 --- a/ppc/sys/flistxattr.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -SYSCALL(flistxattr, 4) - diff --git a/ppc/sys/flock.s b/ppc/sys/flock.s deleted file mode 100644 index 67eafdf..0000000 --- a/ppc/sys/flock.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(flock, 2) - diff --git a/ppc/sys/fork.s b/ppc/sys/fork.s deleted file mode 100644 index 838c717..0000000 --- a/ppc/sys/fork.s +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 1999-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@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: libc/ppc/sys/fork.s - * - * HISTORY - * 18-Nov-92 Ben Fathi (benf@next.com) - * Created from M88K sources - * - * 11-Jan-92 Peter King (king@next.com) - * Created from M68K sources - */ - -/* We use mode-independent "g" opcodes such as "srgi". These expand - * into word operations when targeting __ppc__, and into doubleword - * operations when targeting __ppc64__. - */ -#include - -#include "SYS.h" - - -MI_ENTRY_POINT(_fork) - MI_PUSH_STACK_FRAME - - MI_CALL_EXTERNAL(__cthread_fork_prepare) - -#if defined(__DYNAMIC__) - .cstring -LC1: - .ascii "__dyld_fork_prepare\0" - .text - .align 2 - mflr r0 - bcl 20,31,1f -1: mflr r3 - mtlr r0 - addis r3,r3,ha16(LC1-1b) - addi r3,r3,lo16(LC1-1b) - addi r4,r1,SF_LOCAL1 - bl __dyld_func_lookup - lg r3,SF_LOCAL1(r1) - mtspr ctr,r3 - bctrl -#endif - - li r0,SYS_fork - sc // do the fork - b Lbotch // error return - - cmpwi r4,0 // parent (r4==0) or child (r4==1) ? - beq Lparent // parent, since r4==0 - - -/* Here if we are the child. */ - -#if defined(__DYNAMIC__) - .cstring -LC3: - .ascii "__dyld_fork_child\0" - .text - .align 2 - mflr r0 - bcl 20,31,1f -1: mflr r3 - mtlr r0 - addis r3,r3,ha16(LC3-1b) - addi r3,r3,lo16(LC3-1b) - addi r4,r1,SF_LOCAL1 - bl __dyld_func_lookup - lg r3,SF_LOCAL1(r1) - mtspr ctr,r3 - bctrl -#endif - - li r9,0 - MI_GET_ADDRESS(r8,__current_pid) - stw r9,0(r8) // clear cached pid in child - - MI_CALL_EXTERNAL(__cthread_fork_child) - -#if defined(__DYNAMIC__) - .cstring -LC4: - .ascii "__dyld_fork_child_final\0" - .text - .align 2 - mflr r0 - bcl 20,31,1f -1: mflr r3 - mtlr r0 - addis r3,r3,ha16(LC4-1b) - addi r3,r3,lo16(LC4-1b) - addi r4,r1,SF_LOCAL1 - bl __dyld_func_lookup - lg r3,SF_LOCAL1(r1) - mtspr ctr,r3 - bctrl -#endif - - li r3,0 // flag for "we are the child" - b Lreturn - - -/* Here if we are the parent, with: - * r3 = child's pid - */ -Lparent: - stg r3,SF_LOCAL2(r1) // save child pid in stack - -#if defined(__DYNAMIC__) - mflr r0 - bcl 20,31,1f -1: mflr r3 - mtlr r0 - addis r3,r3,ha16(LC2-1b) - addi r3,r3,lo16(LC2-1b) - addi r4,r1,SF_LOCAL1 - bl __dyld_func_lookup - lg r3,SF_LOCAL1(r1) - mtspr ctr,r3 - bctrl -#endif - - b Lparent_return // clean up and return child's pid - - -/* Here if the fork() syscall failed. We're still the parent. */ - -Lbotch: - -#if defined(__DYNAMIC__) - .cstring -LC2: - .ascii "__dyld_fork_parent\0" - .text - .align 2 - stg r3,SF_LOCAL2(r1) // save error return in stack - mflr r0 - bcl 20,31,1f -1: mflr r3 - mtlr r0 - addis r3,r3,ha16(LC2-1b) - addi r3,r3,lo16(LC2-1b) - addi r4,r1,SF_LOCAL1 - bl __dyld_func_lookup - lg r3,SF_LOCAL1(r1) - mtspr ctr,r3 - bctrl - lg r3,SF_LOCAL2(r1) // restore error code -#endif - - MI_CALL_EXTERNAL(cerror) - li r3,-1 // get an error return code - stg r3,SF_LOCAL2(r1) // save return code in stack - - /* - * We use cthread_fork_parent() to clean up after a fork error - * (unlock cthreads and mailloc packages) so the parent - * process can Malloc() after fork() errors without - * deadlocking. - */ - -Lparent_return: - MI_CALL_EXTERNAL(__cthread_fork_parent) - lg r3,SF_LOCAL2(r1) // return -1 on error, child's pid on success - -Lreturn: - MI_POP_STACK_FRAME_AND_RETURN - diff --git a/ppc/sys/fpathconf.s b/ppc/sys/fpathconf.s deleted file mode 100644 index 8ac0e15..0000000 --- a/ppc/sys/fpathconf.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(fpathconf, 2) - diff --git a/ppc/sys/fremovexattr.s b/ppc/sys/fremovexattr.s deleted file mode 100644 index 43c099c..0000000 --- a/ppc/sys/fremovexattr.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -SYSCALL(fremovexattr, 3) - diff --git a/ppc/sys/fsctl.s b/ppc/sys/fsctl.s deleted file mode 100644 index 2788c94..0000000 --- a/ppc/sys/fsctl.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(fsctl, 4) - diff --git a/ppc/sys/fsetxattr.s b/ppc/sys/fsetxattr.s deleted file mode 100644 index d677208..0000000 --- a/ppc/sys/fsetxattr.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -SYSCALL(fsetxattr, 6) - diff --git a/ppc/sys/fstat.s b/ppc/sys/fstat.s deleted file mode 100644 index 6992c31..0000000 --- a/ppc/sys/fstat.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(fstat, 2) - diff --git a/ppc/sys/fstatfs.s b/ppc/sys/fstatfs.s deleted file mode 100644 index 8c1b15a..0000000 --- a/ppc/sys/fstatfs.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(fstatfs, 2) - diff --git a/ppc/sys/fstatv.s b/ppc/sys/fstatv.s deleted file mode 100644 index 07dc617..0000000 --- a/ppc/sys/fstatv.s +++ /dev/null @@ -1,27 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL(fstatv, 0) diff --git a/ppc/sys/fsync.s b/ppc/sys/fsync.s deleted file mode 100644 index acfa327..0000000 --- a/ppc/sys/fsync.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(fsync, 1) - diff --git a/ppc/sys/ftruncate.s b/ppc/sys/ftruncate.s deleted file mode 100644 index 86c3ded..0000000 --- a/ppc/sys/ftruncate.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(ftruncate, 2) - diff --git a/ppc/sys/futimes.s b/ppc/sys/futimes.s deleted file mode 100644 index 84f001f..0000000 --- a/ppc/sys/futimes.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(futimes, 2) - diff --git a/ppc/sys/genassym.c b/ppc/sys/genassym.c deleted file mode 100644 index ac6afca..0000000 --- a/ppc/sys/genassym.c +++ /dev/null @@ -1,206 +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@ - */ -#import -#import -#import -#import - -#import "genassym.h" - -#define NAME_LEN 30 - -char *progname; - -unsigned bit_num(char *reg_type, char *field, unsigned bits) -{ - unsigned bit; - unsigned mask; - - for (bit = 0, mask = 0x1; - (mask & bits) == 0 && mask; - mask <<= 1, bit += 1) - continue; - if (mask) - return bit; - fprintf(stderr, "%s: Bad BIT_POS for %s.%s\n", progname, - reg_type, field); - exit(1); -} - -unsigned field_width(char *reg_type, char *field, unsigned bits) -{ - unsigned width; - - while (bits && (bits & 0x1) == 0) - bits >>= 1; - for (width = 0; (bits & 0x1) == 1; bits >>= 1, width += 1) - continue; - if (bits == 0 && width) - return width; - fprintf(stderr, "%s: Bad BIT_FIELD for %s.%s\n", progname, - reg_type, field); - exit(1); -} - -unsigned log2(unsigned val, char *type) -{ - unsigned l2 = 0; - - if (val == 0) { - fprintf(stderr, "log2: sizeof(%s) is zero!\n", type); - exit(1); - } - while ((val & 0x1) == 0) { - l2 += 1; - val >>= 1; - } - if (val != 0x1) { - fprintf(stderr, "log2: sizeof(%s) is not power of two!\n", - type); - exit(1); - } - return l2; -} - -const char *skip_white(const char *cp) -{ - while (*cp && isspace(*cp)) - cp += 1; - return cp; -} - -const char *strip_prefix(const char *cp, const char *prefix) -{ - int len; - - cp = skip_white(cp); - len = strlen(prefix); - if (strncmp(cp, prefix, len) == 0 && isspace(*(cp+len))) - cp += len; - return cp; -} - -void -print_define(const char *prefix, const char *type_name, const char *field) -{ - const char *cp; - int col = 0; - - printf("#define\t"); - if (prefix != NULL && *prefix != '\0') { - printf("%s", prefix); - col += strlen(prefix); - } - if (type_name != NULL && *type_name != '\0') { - cp = strip_prefix(type_name, "struct"); - cp = strip_prefix(cp, "enum"); - cp = skip_white(cp); - if (*cp != '\0' && col != 0) { - putchar('_'); - col += 1; - } - for (; *cp != '\0'; cp++) { - if (isspace(*cp)) - break; - if (*cp == '*') - break; - if (strncmp(cp, "_t", 2) == 0 && !isalnum(cp[2])) - break; - putchar(isalpha(*cp) ? toupper(*cp) : *cp); - col += 1; - - } - } - if (field != NULL && *field != '\0') { - if (col != 0) { - putchar('_'); - col++; - } - for (cp = field; *cp != 0; cp++) { - if (*cp == '.') - putchar('_'); - else if (*cp == '[') - putchar('_'); - else if (*cp == ']') - continue; - else if (!isspace(*cp)) - putchar(isalpha(*cp) ? toupper(*cp) : *cp); - col++; - } - } - if (col == 0) { - fprintf(stderr, "%s: Bad call to print_define\n", progname); - exit(1); - } - do { - putchar(' '); - col += 1; - } while (col < NAME_LEN); -} - -void print_dec(int val) -{ - printf("%d\n", val); -} - -void print_hex(unsigned val) -{ - printf("%#010x\n", val); -} - -void print_str(const char *str) -{ - printf("%s\n", str); -} - -void comment(cmt_level_t level, const char *cmt) -{ - switch (level) { - case MAJOR: - printf("\n\n"); - printf("/*\n"); - printf(" * %s\n", cmt); - printf(" */\n"); - break; - case MINOR: - printf("\n"); - printf("/* %s */\n", cmt); - printf("\n"); - break; - default: - fprintf(stderr, "%s: Bad comment level\n", progname); - exit(1); - } -} - -void main(int argc, char **argv) -{ - progname = argv[0]; - - printf("/* assym.h -- generated by genassym */\n"); - printf("/* DON'T EDIT THIS -- change assymdefs.c */\n"); - - assymdefs(); - - exit(0); -} diff --git a/ppc/sys/genassym.h b/ppc/sys/genassym.h deleted file mode 100644 index 4097703..0000000 --- a/ppc/sys/genassym.h +++ /dev/null @@ -1,127 +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@ - */ -/* - * genassym.h -- macros of use with genassym.c and assymdefs.c - */ - -#import -#import - -#define PRINT_OFFSET(ptr_type, field) \ -MACRO_BEGIN \ - print_define("", #ptr_type, #field); \ - print_hex((unsigned) &(((ptr_type)0)->field)); \ -MACRO_END - -#define PRINT_BIT_FIELD(reg_type, field) \ -MACRO_BEGIN \ - reg_type __reg; \ - CONTENTS(__reg) = 0; \ - __reg.field = (typeof (__reg.field)) -1; \ - print_define("", #reg_type, #field); \ - print_hex(CONTENTS(__reg)); \ -MACRO_END - -#define PRINT_ENUM(item) \ -MACRO_BEGIN \ - print_define("", "", #item); \ - print_hex((unsigned)item); \ -MACRO_END - -#define PRINT_DEFINE(macro) \ -MACRO_BEGIN \ - print_define("", "", #macro); \ - print_str(STRINGIFY(macro)); \ -MACRO_END - -#define PRINT_CONSTANT(macro) \ -MACRO_BEGIN \ - print_define("", "", #macro); \ - print_hex((unsigned)macro); \ -MACRO_END - -#define PRINT_REGADDR(macro) \ -MACRO_BEGIN \ - print_define("", "", #macro); \ - print_hex((unsigned) ¯o); \ -MACRO_END - -#define PRINT_REG_PAIR(struct_ptr, name0, name1) \ -MACRO_BEGIN \ - print_define("", #struct_ptr, #name0 "_" #name1); \ - print_hex((unsigned) &(((struct_ptr)0)->U_##name0##_##name1)); \ -MACRO_END - -#define PRINT_BIT_POS(reg_type, field) \ -MACRO_BEGIN \ - reg_type __reg; \ - CONTENTS(__reg) = 0; \ - __reg.field = 1; \ - print_define("", #reg_type, #field "_BIT"); \ - print_dec((int) bit_num(#reg_type, #field, CONTENTS(__reg))); \ -MACRO_END - -#define PRINT_FIELD_INFO(reg_type, field) \ -MACRO_BEGIN \ - reg_type __reg; \ - CONTENTS(__reg) = 0; \ - __reg.field = -1; \ - print_define("", #reg_type, #field "_OFF"); \ - print_dec((int) bit_num(#reg_type, #field, CONTENTS(__reg))); \ - print_define("", #reg_type, #field "_WIDTH"); \ - print_dec((int) field_width(#reg_type, #field, CONTENTS(__reg)));\ -MACRO_END - -#define PRINT_L2_SIZE(type) \ -MACRO_BEGIN \ - print_define("L2_SIZEOF", #type, ""); \ - print_dec((int) log2(sizeof(type), #type)); \ -MACRO_END - -#define PRINT_SIZEOF(type) \ -MACRO_BEGIN \ - print_define("SIZEOF", #type, ""); \ - print_dec((int) sizeof(type)); \ -MACRO_END - -#define PRINT_L2_CONSTANT(macro) \ -MACRO_BEGIN \ - print_define("L2", "", #macro); \ - print_dec((int) log2(macro, #macro)); \ -MACRO_END - -typedef enum { - MAJOR, MINOR -} cmt_level_t; - -extern void comment(cmt_level_t level, const char *cmt); -extern void print_define(const char *prefix, const char *type_name, - const char *field); -extern void print_dec(int val); -extern void print_hex(unsigned val); -extern void print_str(const char *str); -extern unsigned bit_num(char *reg_type, char *field, unsigned bits); -extern unsigned field_width(char *reg_type, char *field, unsigned bits); -extern unsigned log2(unsigned val, char *type); -extern void assymdefs(void); - diff --git a/ppc/sys/getaudit.s b/ppc/sys/getaudit.s deleted file mode 100644 index 87cd358..0000000 --- a/ppc/sys/getaudit.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getaudit, 1) - diff --git a/ppc/sys/getaudit_addr.s b/ppc/sys/getaudit_addr.s deleted file mode 100644 index 091af6d..0000000 --- a/ppc/sys/getaudit_addr.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getaudit_addr, 2) - diff --git a/ppc/sys/getauid.s b/ppc/sys/getauid.s deleted file mode 100644 index 1f3cd17..0000000 --- a/ppc/sys/getauid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getauid, 1) - diff --git a/ppc/sys/getdirentries.s b/ppc/sys/getdirentries.s deleted file mode 100644 index 4fc362f..0000000 --- a/ppc/sys/getdirentries.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getdirentries, 4) - diff --git a/ppc/sys/getdirentriesattr.s b/ppc/sys/getdirentriesattr.s deleted file mode 100644 index 4f5e0bb..0000000 --- a/ppc/sys/getdirentriesattr.s +++ /dev/null @@ -1,27 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL(getdirentriesattr, 0) diff --git a/ppc/sys/geteuid.s b/ppc/sys/geteuid.s deleted file mode 100644 index ec7bc70..0000000 --- a/ppc/sys/geteuid.s +++ /dev/null @@ -1,29 +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. */ - -#import - -#import "SYS.h" - -SYSCALL(geteuid,0) diff --git a/ppc/sys/getfh.s b/ppc/sys/getfh.s deleted file mode 100644 index 25312a8..0000000 --- a/ppc/sys/getfh.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getfh, 2) - diff --git a/ppc/sys/getfsstat.s b/ppc/sys/getfsstat.s deleted file mode 100644 index 58dc985..0000000 --- a/ppc/sys/getfsstat.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getfsstat, 3) - diff --git a/ppc/sys/getgid.s b/ppc/sys/getgid.s deleted file mode 100644 index e9d1ca4..0000000 --- a/ppc/sys/getgid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getgid, 0) - diff --git a/ppc/sys/getgroups.s b/ppc/sys/getgroups.s deleted file mode 100644 index aeade81..0000000 --- a/ppc/sys/getgroups.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getgroups, 2) - diff --git a/ppc/sys/getitimer.s b/ppc/sys/getitimer.s deleted file mode 100644 index a1b2c7c..0000000 --- a/ppc/sys/getitimer.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getitimer, 2) - diff --git a/ppc/sys/getpeername.s b/ppc/sys/getpeername.s deleted file mode 100644 index ccdaeae..0000000 --- a/ppc/sys/getpeername.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@ - */ -#include "SYS.h" - -#ifdef __LP64__ -SYSCALL(getpeername, 3) -#else /* !__LP64__ */ -PSEUDO(getpeername$UNIX2003, getpeername, 3) - blr - -SYSCALL_ERR(getpeername, 3, cerror_cvt) -#endif /* __LP64__ */ - diff --git a/ppc/sys/getpgid.s b/ppc/sys/getpgid.s deleted file mode 100644 index 96b2861..0000000 --- a/ppc/sys/getpgid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getpgid, 1) - diff --git a/ppc/sys/getpgrp.s b/ppc/sys/getpgrp.s deleted file mode 100644 index 11fc616..0000000 --- a/ppc/sys/getpgrp.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getpgrp, 1) - diff --git a/ppc/sys/getpid.s b/ppc/sys/getpid.s deleted file mode 100644 index af84984..0000000 --- a/ppc/sys/getpid.s +++ /dev/null @@ -1,59 +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@ - */ -#include "SYS.h" - - .data - .globl __current_pid - .align 2 -__current_pid: - .long 0 - -MI_ENTRY_POINT(_getpid) -#if defined(__DYNAMIC__) - mflr r0 // note we cannot use MI_GET_ADDRESS... - bcl 20,31,1f // ...because we define __current_pid -1: - mflr r5 - mtlr r0 - addis r5, r5, ha16(__current_pid - 1b) - addi r5, r5, lo16(__current_pid - 1b) -#else - lis r5,hi16(__current_pid) - ori r5,r5,lo16(__current_pid) -#endif - lwz r3,0(r5) // get the cached pid - cmpwi r3,0 // if positive, - bgtlr++ // return it - - SYSCALL_NONAME(getpid, 0) - - lwarx r4,0,r5 // see if we can cache it - cmpwi r4,0 // we can't if there are any... - blt-- 1f // ...vforks in progress - - stwcx. r3,0,r5 // ignore cache conflicts - blr -1: - li r6,-4 // on 970, cancel the reservation using red zone... - stwcx. r3,r6,r1 // ...to avoid an errata - blr diff --git a/ppc/sys/getpriority.s b/ppc/sys/getpriority.s deleted file mode 100644 index 53783b3..0000000 --- a/ppc/sys/getpriority.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getpriority, 2) - diff --git a/ppc/sys/getrlimit.s b/ppc/sys/getrlimit.s deleted file mode 100644 index 7b4ea0a..0000000 --- a/ppc/sys/getrlimit.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getrlimit, 2) - diff --git a/ppc/sys/getrusage.s b/ppc/sys/getrusage.s deleted file mode 100644 index 7b66a4b..0000000 --- a/ppc/sys/getrusage.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getrusage, 2) - diff --git a/ppc/sys/getsid.s b/ppc/sys/getsid.s deleted file mode 100644 index f9cfe99..0000000 --- a/ppc/sys/getsid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getsid, 1) - diff --git a/ppc/sys/getsockname.s b/ppc/sys/getsockname.s deleted file mode 100644 index d0ea5c6..0000000 --- a/ppc/sys/getsockname.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@ - */ -#include "SYS.h" - -#ifdef __LP64__ -SYSCALL(getsockname, 3) -#else /* !__LP64__ */ -PSEUDO(getsockname$UNIX2003, getsockname, 3) - blr - -SYSCALL_ERR(getsockname, 3, cerror_cvt) -#endif /* __LP64__ */ - diff --git a/ppc/sys/getsockopt.s b/ppc/sys/getsockopt.s deleted file mode 100644 index cd46a42..0000000 --- a/ppc/sys/getsockopt.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getsockopt, 5) - diff --git a/ppc/sys/getuid.s b/ppc/sys/getuid.s deleted file mode 100644 index f1f41fb..0000000 --- a/ppc/sys/getuid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(getuid, 0) - diff --git a/ppc/sys/getxattr.s b/ppc/sys/getxattr.s deleted file mode 100644 index baad09e..0000000 --- a/ppc/sys/getxattr.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -SYSCALL(getxattr, 6) - diff --git a/ppc/sys/ioctl.s b/ppc/sys/ioctl.s deleted file mode 100644 index 5d19770..0000000 --- a/ppc/sys/ioctl.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(ioctl, 3) - diff --git a/ppc/sys/issetugid.s b/ppc/sys/issetugid.s deleted file mode 100644 index 65435f9..0000000 --- a/ppc/sys/issetugid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(issetugid, 0) - diff --git a/ppc/sys/kevent.s b/ppc/sys/kevent.s deleted file mode 100644 index a0471af..0000000 --- a/ppc/sys/kevent.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(kevent, 6) - diff --git a/ppc/sys/kill.s b/ppc/sys/kill.s deleted file mode 100644 index 01628d1..0000000 --- a/ppc/sys/kill.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(kill, 2) - diff --git a/ppc/sys/kqueue.s b/ppc/sys/kqueue.s deleted file mode 100644 index dfde475..0000000 --- a/ppc/sys/kqueue.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(kqueue, 0) - diff --git a/ppc/sys/kqueue_from_portset_np.s b/ppc/sys/kqueue_from_portset_np.s deleted file mode 100644 index 8e88cb2..0000000 --- a/ppc/sys/kqueue_from_portset_np.s +++ /dev/null @@ -1,27 +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@ - */ -#include "SYS.h" - -SYSCALL(kqueue_from_portset_np, 1) - - diff --git a/ppc/sys/kqueue_portset_np.s b/ppc/sys/kqueue_portset_np.s deleted file mode 100644 index 4ab1c78..0000000 --- a/ppc/sys/kqueue_portset_np.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(kqueue_portset_np, 1) - diff --git a/ppc/sys/ktrace.s b/ppc/sys/ktrace.s deleted file mode 100644 index c759ae6..0000000 --- a/ppc/sys/ktrace.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(ktrace, 4) diff --git a/ppc/sys/lchown.s b/ppc/sys/lchown.s deleted file mode 100644 index 8470f7a..0000000 --- a/ppc/sys/lchown.s +++ /dev/null @@ -1,32 +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 "SYS.h" - -#ifdef __LP64__ -SYSCALL(lchown, 3) -#else /* !__LP64__ */ -PSEUDO(lchown$UNIX2003, lchown, 3) - blr - -SYSCALL_ERR(lchown, 3, cerror_cvt) -#endif /* __LP64__ */ diff --git a/ppc/sys/libc.syscall.ppc b/ppc/sys/libc.syscall.ppc new file mode 100644 index 0000000..e009a37 --- /dev/null +++ b/ppc/sys/libc.syscall.ppc @@ -0,0 +1,82 @@ +_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 +_fsync ___fsync_nocancel +_fsync$NOCANCEL$UNIX2003 ___fsync_nocancel +_fsync$UNIX2003 ___fsync +_getattrlist$UNIX2003 ___getattrlist +_getpeername$UNIX2003 ___getpeername +_getsockname$UNIX2003 ___getsockname +_lchown$UNIX2003 ___lchown +_listen$UNIX2003 ___listen +_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 +_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 +_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/ppc/sys/link.s b/ppc/sys/link.s deleted file mode 100644 index f37dabf..0000000 --- a/ppc/sys/link.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(link, 2) - diff --git a/ppc/sys/lio_listio.s b/ppc/sys/lio_listio.s deleted file mode 100644 index 819613e..0000000 --- a/ppc/sys/lio_listio.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(lio_listio, 4) - diff --git a/ppc/sys/listen.s b/ppc/sys/listen.s deleted file mode 100644 index de039e8..0000000 --- a/ppc/sys/listen.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@ - */ -#include "SYS.h" - -#ifdef __LP64__ -SYSCALL(listen, 2) -#else /* !__LP64__ */ -PSEUDO(listen$UNIX2003, listen, 2) - blr - -SYSCALL_ERR(listen, 2, cerror_cvt) -#endif /* __LP64__ */ - diff --git a/ppc/sys/listxattr.s b/ppc/sys/listxattr.s deleted file mode 100644 index 20eba19..0000000 --- a/ppc/sys/listxattr.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -SYSCALL(listxattr, 4) - diff --git a/ppc/sys/load_shared_file.s b/ppc/sys/load_shared_file.s deleted file mode 100644 index 7f32fb1..0000000 --- a/ppc/sys/load_shared_file.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(load_shared_file, 7) - diff --git a/ppc/sys/longjmp.s b/ppc/sys/longjmp.s index b530d5d..6c3c287 100644 --- a/ppc/sys/longjmp.s +++ b/ppc/sys/longjmp.s @@ -53,6 +53,8 @@ MI_ENTRY_POINT(_siglongjmp) lg r0, JMP_SIGFLAG(r3) ; load sigflag saved by siglongjmp() cmpgi cr1,r0,0 ; this changes cr1 which is volatile + mr r30, r3 ; preserve args across _sigsetmask + mr r31, r4 beq-- cr1, L__exit ; if r0 == 0 do _longjmp() ; else *** fall through *** to longjmp() @@ -60,14 +62,23 @@ MI_ENTRY_POINT(_siglongjmp) MI_ENTRY_POINT(_longjmp) mr r30, r3 ; preserve args across _sigsetmask - mr r31, r4 - + mr r31, r4 + /* NB: this code assumes the signal mask is an int. Change the "lwz" below * if not. The JMP_sig field is already 8 bytes in the jmpbuf. */ lwz r3, JMP_sig(r3) ; restore the signal mask MI_CALL_EXTERNAL(_sigsetmask) // make a (deprecated!) syscall to set the mask - mr r4, r31 +L__exit: + lwz r3,JMP_ss_flags(r30) + MI_CALL_EXTERNAL(__sigunaltstack) +L__exit2: mr r3, r30 -L__exit: + mr r4, r31 MI_BRANCH_EXTERNAL(__longjmp) + + + + + + diff --git a/ppc/sys/lseek.s b/ppc/sys/lseek.s deleted file mode 100644 index ee09f5c..0000000 --- a/ppc/sys/lseek.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(lseek, 3) - diff --git a/ppc/sys/lstat.s b/ppc/sys/lstat.s deleted file mode 100644 index e02665e..0000000 --- a/ppc/sys/lstat.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(lstat, 2) - diff --git a/ppc/sys/lstatv.s b/ppc/sys/lstatv.s deleted file mode 100644 index d9d2ea9..0000000 --- a/ppc/sys/lstatv.s +++ /dev/null @@ -1,27 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL(lstatv, 0) diff --git a/ppc/sys/madvise.s b/ppc/sys/madvise.s deleted file mode 100644 index ef7a6b9..0000000 --- a/ppc/sys/madvise.s +++ /dev/null @@ -1,28 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL(madvise, 3) - diff --git a/ppc/sys/mincore.s b/ppc/sys/mincore.s deleted file mode 100644 index a2be47d..0000000 --- a/ppc/sys/mincore.s +++ /dev/null @@ -1,27 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL(mincore, 3) diff --git a/ppc/sys/minherit.s b/ppc/sys/minherit.s deleted file mode 100644 index b733f5a..0000000 --- a/ppc/sys/minherit.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(minherit, 3) - diff --git a/ppc/sys/mkcomplex.s b/ppc/sys/mkcomplex.s deleted file mode 100644 index 3da9fa7..0000000 --- a/ppc/sys/mkcomplex.s +++ /dev/null @@ -1,27 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL(mkcomplex, 0) diff --git a/ppc/sys/mkdir.s b/ppc/sys/mkdir.s deleted file mode 100644 index 7e0e868..0000000 --- a/ppc/sys/mkdir.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(mkdir, 2) - diff --git a/ppc/sys/mkfifo.s b/ppc/sys/mkfifo.s deleted file mode 100644 index 0211ff6..0000000 --- a/ppc/sys/mkfifo.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(mkfifo, 2) diff --git a/ppc/sys/mknod.s b/ppc/sys/mknod.s deleted file mode 100644 index 52dabe5..0000000 --- a/ppc/sys/mknod.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(mknod, 3) - diff --git a/ppc/sys/mlock.s b/ppc/sys/mlock.s deleted file mode 100644 index 664ae6c..0000000 --- a/ppc/sys/mlock.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(mlock, 3) - diff --git a/ppc/sys/mlockall.s b/ppc/sys/mlockall.s deleted file mode 100644 index aa2f01c..0000000 --- a/ppc/sys/mlockall.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(mlockall, 3) - diff --git a/ppc/sys/mount.s b/ppc/sys/mount.s deleted file mode 100644 index 3c7b32e..0000000 --- a/ppc/sys/mount.s +++ /dev/null @@ -1,27 +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. */ - -#import "SYS.h" - -SYSCALL(mount, 4) diff --git a/ppc/sys/msgget.s b/ppc/sys/msgget.s deleted file mode 100644 index 1e5e544..0000000 --- a/ppc/sys/msgget.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(msgget, 3) - diff --git a/ppc/sys/msgrcv.s b/ppc/sys/msgrcv.s deleted file mode 100644 index db69ab6..0000000 --- a/ppc/sys/msgrcv.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(msgrcv, 3) - diff --git a/ppc/sys/msgsnd.s b/ppc/sys/msgsnd.s deleted file mode 100644 index bf4c21a..0000000 --- a/ppc/sys/msgsnd.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(msgsnd, 3) - diff --git a/ppc/sys/msgsys.s b/ppc/sys/msgsys.s deleted file mode 100644 index da09564..0000000 --- a/ppc/sys/msgsys.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(msgsys, 3) - diff --git a/ppc/sys/munlock.s b/ppc/sys/munlock.s deleted file mode 100644 index fd8c52d..0000000 --- a/ppc/sys/munlock.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(munlock, 3) - diff --git a/ppc/sys/munlockall.s b/ppc/sys/munlockall.s deleted file mode 100644 index fe5f9cf..0000000 --- a/ppc/sys/munlockall.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(munlockall, 3) - diff --git a/ppc/sys/new_system_shared_regions.s b/ppc/sys/new_system_shared_regions.s deleted file mode 100644 index 765ae1a..0000000 --- a/ppc/sys/new_system_shared_regions.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(new_system_shared_regions, 0) - diff --git a/ppc/sys/nfsclnt.s b/ppc/sys/nfsclnt.s deleted file mode 100644 index f2a8297..0000000 --- a/ppc/sys/nfsclnt.s +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 "SYS.h" - -SYSCALL(nfsclnt, 2) - diff --git a/ppc/sys/nfssvc.s b/ppc/sys/nfssvc.s deleted file mode 100644 index a03969d..0000000 --- a/ppc/sys/nfssvc.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(nfssvc, 1) - diff --git a/ppc/sys/oldldbl64.s b/ppc/sys/oldldbl64.s deleted file mode 100644 index 30dfbe1..0000000 --- a/ppc/sys/oldldbl64.s +++ /dev/null @@ -1,74 +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 - -#define BRANCH(X, Y) \ -TEXT @ \ -LABEL(X) @ \ -BRANCH_EXTERN(Y) - -BRANCH(_asprintf$LDBL64, _asprintf) -BRANCH(_err$LDBL64, _err) -BRANCH(_errc$LDBL64, _errc) -BRANCH(_errx$LDBL64, _errx) -BRANCH(_fprintf$LDBL64, _fprintf) -BRANCH(_fscanf$LDBL64, _fscanf) -BRANCH(_fwprintf$LDBL64, _fwprintf) -BRANCH(_fwscanf$LDBL64, _fwscanf) -BRANCH(_printf$LDBL64, _printf) -BRANCH(_scanf$LDBL64, _scanf) -BRANCH(_snprintf$LDBL64, _snprintf) -BRANCH(_sprintf$LDBL64, _sprintf) -BRANCH(_sscanf$LDBL64, _sscanf) -BRANCH(_strtold$LDBL64, _strtold) -BRANCH(_swprintf$LDBL64, _swprintf) -BRANCH(_swscanf$LDBL64, _swscanf) -BRANCH(_syslog$LDBL64, _syslog) -BRANCH(_vasprintf$LDBL64, _vasprintf) -BRANCH(_verr$LDBL64, _verr) -BRANCH(_verrc$LDBL64, _verrc) -BRANCH(_verrx$LDBL64, _verrx) -BRANCH(_vfprintf$LDBL64, _vfprintf) -BRANCH(_vfscanf$LDBL64, _vfscanf) -BRANCH(_vfwprintf$LDBL64, _vfwprintf) -BRANCH(_vfwscanf$LDBL64, _vfwscanf) -BRANCH(_vprintf$LDBL64, _vprintf) -BRANCH(_vscanf$LDBL64, _vscanf) -BRANCH(_vsnprintf$LDBL64, _vsnprintf) -BRANCH(_vsprintf$LDBL64, _vsprintf) -BRANCH(_vsscanf$LDBL64, _vsscanf) -BRANCH(_vswprintf$LDBL64, _vswprintf) -BRANCH(_vswscanf$LDBL64, _vswscanf) -BRANCH(_vsyslog$LDBL64, _vsyslog) -BRANCH(_vwarn$LDBL64, _vwarn) -BRANCH(_vwarnc$LDBL64, _vwarnc) -BRANCH(_vwarnx$LDBL64, _vwarnx) -BRANCH(_vwprintf$LDBL64, _vwprintf) -BRANCH(_vwscanf$LDBL64, _vwscanf) -BRANCH(_warn$LDBL64, _warn) -BRANCH(_warnc$LDBL64, _warnc) -BRANCH(_warnx$LDBL64, _warnx) -BRANCH(_wcstold$LDBL64, _wcstold) -BRANCH(_wprintf$LDBL64, _wprintf) -BRANCH(_wscanf$LDBL64, _wscanf) diff --git a/ppc/sys/open.s b/ppc/sys/open.s deleted file mode 100644 index 1af88bf..0000000 --- a/ppc/sys/open.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(open, 3) - diff --git a/ppc/sys/pathconf.s b/ppc/sys/pathconf.s deleted file mode 100644 index 9150e0a..0000000 --- a/ppc/sys/pathconf.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(pathconf, 2) diff --git a/ppc/sys/pipe.s b/ppc/sys/pipe.s deleted file mode 100644 index 1861d32..0000000 --- a/ppc/sys/pipe.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. */ - -#import "SYS.h" - -MI_ENTRY_POINT(_pipe) - mr r12,r3 // save fildes across syscall - SYSCALL_NONAME(pipe, 0) - stw r3,0(r12) - stw r4,4(r12) - li r3,0 - blr diff --git a/ppc/sys/poll.s b/ppc/sys/poll.s deleted file mode 100644 index 50e3af6..0000000 --- a/ppc/sys/poll.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -SYSCALL(poll, 3) - diff --git a/ppc/sys/posix_madvise.s b/ppc/sys/posix_madvise.s deleted file mode 100644 index 098f7f5..0000000 --- a/ppc/sys/posix_madvise.s +++ /dev/null @@ -1,28 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -PSEUDO(posix_madvise, madvise, 3) - blr diff --git a/ppc/sys/ppc_gettimeofday.s b/ppc/sys/ppc_gettimeofday.s index 9d84417..3cfd2b3 100644 --- a/ppc/sys/ppc_gettimeofday.s +++ b/ppc/sys/ppc_gettimeofday.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -30,17 +30,3 @@ MI_ENTRY_POINT(___commpage_gettimeofday) ba _COMM_PAGE_GETTIMEOFDAY - - -/* This syscall is special cased: the timeval is returned in r3/r4. - * Note also that the "seconds" field of the timeval is a long, so - * it's size is mode dependent. - */ -MI_ENTRY_POINT(___gettimeofday) - mr r12,r3 // save ptr to timeval - SYSCALL_NONAME(gettimeofday,0) - stg r3,0(r12) // "stw" in 32-bit mode, "std" in 64-bit mode - stw r4,GPR_BYTES(r12) - li r3,0 - blr - diff --git a/ppc/sys/pread.s b/ppc/sys/pread.s deleted file mode 100644 index 723f6d7..0000000 --- a/ppc/sys/pread.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(pread, 4) - diff --git a/ppc/sys/processor_facilities.h b/ppc/sys/processor_facilities.h deleted file mode 100644 index 2fa6707..0000000 --- a/ppc/sys/processor_facilities.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2000 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@ - */ - -/* Does the current CPU have Altivec support? */ -extern int _cpu_has_altivec; - -/* What processor facilities is the current thread using? */ -#define floatUsed 0x40000000 -#define vectorUsed 0x20000000 - -extern int processor_facilities_used(void); diff --git a/ppc/sys/processor_facilities.s b/ppc/sys/processor_facilities.s deleted file mode 100644 index 9001dbd..0000000 --- a/ppc/sys/processor_facilities.s +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2000 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@ - */ -.globl _processor_facilities_used -_processor_facilities_used: - li r0,0x7FF3 - sc - blr diff --git a/ppc/sys/profil.s b/ppc/sys/profil.s deleted file mode 100644 index 705995d..0000000 --- a/ppc/sys/profil.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(profil, 4) - diff --git a/ppc/sys/pthread_sigmask.s b/ppc/sys/pthread_sigmask.s deleted file mode 100644 index 9defe25..0000000 --- a/ppc/sys/pthread_sigmask.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(pthread_sigmask, 3) - diff --git a/ppc/sys/ptrace.s b/ppc/sys/ptrace.s deleted file mode 100644 index ac37d3e..0000000 --- a/ppc/sys/ptrace.s +++ /dev/null @@ -1,32 +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. */ - -#import "SYS.h" - -MI_ENTRY_POINT(_ptrace) - li r7,0 - MI_GET_ADDRESS(r8,_errno) - stw r7,0(r8) - SYSCALL_NONAME(ptrace, 4) - blr diff --git a/ppc/sys/pwrite.s b/ppc/sys/pwrite.s deleted file mode 100644 index 79fb8d0..0000000 --- a/ppc/sys/pwrite.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(pwrite, 4) - diff --git a/ppc/sys/quota.s b/ppc/sys/quota.s deleted file mode 100644 index 78ffe62..0000000 --- a/ppc/sys/quota.s +++ /dev/null @@ -1,28 +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@ - */ -#include "SYS.h" - -#define SYS_quota 149 - -SYSCALL(quota, 4) - diff --git a/ppc/sys/quotactl.s b/ppc/sys/quotactl.s deleted file mode 100644 index dfa5ee2..0000000 --- a/ppc/sys/quotactl.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(quotactl, 3) - diff --git a/ppc/sys/read.s b/ppc/sys/read.s deleted file mode 100644 index a880698..0000000 --- a/ppc/sys/read.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(read, 3) - diff --git a/ppc/sys/readlink.s b/ppc/sys/readlink.s deleted file mode 100644 index 0c97e93..0000000 --- a/ppc/sys/readlink.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(readlink, 3) - diff --git a/ppc/sys/readv.s b/ppc/sys/readv.s deleted file mode 100644 index f2be2d4..0000000 --- a/ppc/sys/readv.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(readv, 3) - diff --git a/ppc/sys/reboot.s b/ppc/sys/reboot.s deleted file mode 100644 index cfa58d8..0000000 --- a/ppc/sys/reboot.s +++ /dev/null @@ -1,28 +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 */ - -#import "SYS.h" - -SYSCALL(reboot, 2) - MI_BRANCH_EXTERNAL(_abort) diff --git a/ppc/sys/recvfrom.s b/ppc/sys/recvfrom.s deleted file mode 100644 index ebe1bb0..0000000 --- a/ppc/sys/recvfrom.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@ - */ -#include "SYS.h" - -#ifdef __LP64__ -SYSCALL(recvfrom, 6) -#else /* !__LP64__ */ -PSEUDO(recvfrom$UNIX2003, recvfrom, 6) - blr - -SYSCALL_ERR(recvfrom, 6, cerror_cvt) -#endif /* __LP64__ */ - diff --git a/ppc/sys/recvmsg.s b/ppc/sys/recvmsg.s deleted file mode 100644 index f44002d..0000000 --- a/ppc/sys/recvmsg.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@ - */ -#include "SYS.h" - -#ifdef __LP64__ -SYSCALL(recvmsg, 3) -#else /* !__LP64__ */ -PSEUDO(recvmsg$UNIX2003, recvmsg, 3) - blr - -SYSCALL_ERR(recvmsg, 3, cerror_cvt) -#endif /* __LP64__ */ - diff --git a/ppc/sys/removexattr.s b/ppc/sys/removexattr.s deleted file mode 100644 index c002762..0000000 --- a/ppc/sys/removexattr.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -SYSCALL(removexattr, 3) - diff --git a/ppc/sys/rename.s b/ppc/sys/rename.s deleted file mode 100644 index a4d7a8b..0000000 --- a/ppc/sys/rename.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(rename, 2) - diff --git a/ppc/sys/reset_shared_file.s b/ppc/sys/reset_shared_file.s deleted file mode 100644 index 2d6517a..0000000 --- a/ppc/sys/reset_shared_file.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(reset_shared_file, 3) - diff --git a/ppc/sys/revoke.s b/ppc/sys/revoke.s deleted file mode 100644 index 6e4248b..0000000 --- a/ppc/sys/revoke.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(revoke, 1) - diff --git a/ppc/sys/rmdir.s b/ppc/sys/rmdir.s deleted file mode 100644 index d06e70c..0000000 --- a/ppc/sys/rmdir.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(rmdir, 1) - diff --git a/ppc/sys/s.template b/ppc/sys/s.template deleted file mode 100644 index 171d0ed..0000000 --- a/ppc/sys/s.template +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL($FILENAMESANSEXTENSION$, 0) - blr diff --git a/ppc/sys/searchfs.s b/ppc/sys/searchfs.s deleted file mode 100644 index 523b832..0000000 --- a/ppc/sys/searchfs.s +++ /dev/null @@ -1,27 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL(searchfs, 0) diff --git a/ppc/sys/select.s b/ppc/sys/select.s deleted file mode 100644 index 171ee24..0000000 --- a/ppc/sys/select.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(select, 5) - diff --git a/ppc/sys/sem_close.s b/ppc/sys/sem_close.s deleted file mode 100644 index bafa743..0000000 --- a/ppc/sys/sem_close.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(sem_close, 1) - diff --git a/ppc/sys/sem_destroy.s b/ppc/sys/sem_destroy.s deleted file mode 100644 index 89809ce..0000000 --- a/ppc/sys/sem_destroy.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(sem_destroy, 1) - diff --git a/ppc/sys/sem_getvalue.s b/ppc/sys/sem_getvalue.s deleted file mode 100644 index fb42420..0000000 --- a/ppc/sys/sem_getvalue.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(sem_getvalue, 2) - diff --git a/ppc/sys/sem_init.s b/ppc/sys/sem_init.s deleted file mode 100644 index 1f243d5..0000000 --- a/ppc/sys/sem_init.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(sem_init, 3) - diff --git a/ppc/sys/sem_post.s b/ppc/sys/sem_post.s deleted file mode 100644 index 4f2829c..0000000 --- a/ppc/sys/sem_post.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(sem_post, 1) - diff --git a/ppc/sys/sem_trywait.s b/ppc/sys/sem_trywait.s deleted file mode 100644 index a1db0f0..0000000 --- a/ppc/sys/sem_trywait.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(sem_trywait, 1) - diff --git a/ppc/sys/sem_wait.s b/ppc/sys/sem_wait.s deleted file mode 100644 index 9e309e5..0000000 --- a/ppc/sys/sem_wait.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(sem_wait, 1) - diff --git a/ppc/sys/semget.s b/ppc/sys/semget.s deleted file mode 100644 index 66181f3..0000000 --- a/ppc/sys/semget.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(semget, 3) - diff --git a/ppc/sys/semop.s b/ppc/sys/semop.s deleted file mode 100644 index 0d55e79..0000000 --- a/ppc/sys/semop.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(semop, 3) - diff --git a/ppc/sys/semsys.s b/ppc/sys/semsys.s deleted file mode 100644 index 98caf93..0000000 --- a/ppc/sys/semsys.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(semsys, 3) - diff --git a/ppc/sys/sendmsg.s b/ppc/sys/sendmsg.s deleted file mode 100644 index e081b2c..0000000 --- a/ppc/sys/sendmsg.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@ - */ -#include "SYS.h" - -#ifdef __LP64__ -SYSCALL(sendmsg, 3) -#else /* !__LP64__ */ -PSEUDO(sendmsg$UNIX2003, sendmsg, 3) - blr - -SYSCALL_ERR(sendmsg, 3, cerror_cvt) -#endif /* __LP64__ */ - diff --git a/ppc/sys/sendto.s b/ppc/sys/sendto.s deleted file mode 100644 index 3a3a5d3..0000000 --- a/ppc/sys/sendto.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@ - */ -#include "SYS.h" - -#ifdef __LP64__ -SYSCALL(sendto, 6) -#else /* !__LP64__ */ -PSEUDO(sendto$UNIX2003, sendto, 6) - blr - -SYSCALL_ERR(sendto, 6, cerror_cvt) -#endif /* __LP64__ */ - diff --git a/ppc/sys/setattrlist.s b/ppc/sys/setattrlist.s deleted file mode 100644 index 8004f2d..0000000 --- a/ppc/sys/setattrlist.s +++ /dev/null @@ -1,34 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -#ifdef __LP64__ -SYSCALL(setattrlist, 0) -#else /* !__LP64__ */ -PSEUDO(setattrlist$UNIX2003, setattrlist, 0) - blr - -SYSCALL_ERR(setattrlist, 0, cerror_cvt) -#endif /* __LP64__ */ diff --git a/ppc/sys/setaudit.s b/ppc/sys/setaudit.s deleted file mode 100644 index 7d49366..0000000 --- a/ppc/sys/setaudit.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setaudit, 1) - diff --git a/ppc/sys/setaudit_addr.s b/ppc/sys/setaudit_addr.s deleted file mode 100644 index dd56b59..0000000 --- a/ppc/sys/setaudit_addr.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setaudit_addr, 2) - diff --git a/ppc/sys/setauid.s b/ppc/sys/setauid.s deleted file mode 100644 index 9c48fb3..0000000 --- a/ppc/sys/setauid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setauid, 1) - diff --git a/ppc/sys/setegid.s b/ppc/sys/setegid.s deleted file mode 100644 index ba3fe64..0000000 --- a/ppc/sys/setegid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setegid, 1) - diff --git a/ppc/sys/seteuid.s b/ppc/sys/seteuid.s deleted file mode 100644 index 00e0a3a..0000000 --- a/ppc/sys/seteuid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(seteuid, 1) - diff --git a/ppc/sys/setgid.s b/ppc/sys/setgid.s deleted file mode 100644 index 2bafccb..0000000 --- a/ppc/sys/setgid.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(setgid, 1) diff --git a/ppc/sys/setgroups.s b/ppc/sys/setgroups.s deleted file mode 100644 index b86d5f3..0000000 --- a/ppc/sys/setgroups.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setgroups, 2) - diff --git a/ppc/sys/setitimer.s b/ppc/sys/setitimer.s deleted file mode 100644 index 5c94832..0000000 --- a/ppc/sys/setitimer.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setitimer, 3) - diff --git a/ppc/sys/setjmp.s b/ppc/sys/setjmp.s index 4c2b2e3..c9839f7 100644 --- a/ppc/sys/setjmp.s +++ b/ppc/sys/setjmp.s @@ -51,7 +51,7 @@ /* int sigsetjmp(sigjmp_buf env, int savemask); */ MI_ENTRY_POINT(_sigsetjmp) - cmpgi cr1,r4,0 ; this changes cr1 which is volatile + cmpgi cr1,r4,0 ; this changes cr1 which is volatile stg r4, JMP_SIGFLAG(r3) ; save the sigflag for use by siglongjmp() beq-- cr1, L__exit ; if r4 == 0 do _setjmp() ; else *** fall through *** to setjmp() @@ -62,12 +62,25 @@ MI_ENTRY_POINT(_setjmp) mflr r0 stg r31, JMP_r31(r3) stg r0, JMP_lr(r3) - mr r31, r3 ; save ptr to jmpbuf across call - li r3, 1 ; get the previous signal mask + mr r31, r3 ; save ptr to jmpbuf across calls + + /* call sigprocmask() to get signal mask */ + + li r3, 1 ; get the previous signal mask li r4, 0 la r5, JMP_sig(r31) ; get address where previous mask needs to be - MI_CALL_EXTERNAL(_sigprocmask) // make a syscall to get mask - mr r3, r31 ; restore jmp_buf ptr + MI_CALL_EXTERNAL(_sigprocmask) ; make a syscall to get mask + + /* call sigaltstack() to get SS_ONSTACK flag */ + + li r3,0 ; ss is NULL + la r4,JMP_vr_base_addr(r31); oss is a temp buffer in jmp_buf + MI_CALL_EXTERNAL(_sigaltstack) ; make a syscall to get current stack state + la r4,JMP_vr_base_addr(r31); recreate temp buffer ptr + lwz r5,2*GPR_BYTES(r4) ; get ss_flags (an int) from stack_t + stw r5,JMP_ss_flags(r31) ; save ss_flags in jmp_buf + + mr r3, r31 ; restore jmp_buf ptr lg r0, JMP_lr(r31) lg r31, JMP_r31(r31) mtlr r0 diff --git a/ppc/sys/setpgid.s b/ppc/sys/setpgid.s deleted file mode 100644 index 3d58d06..0000000 --- a/ppc/sys/setpgid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setpgid, 2) - diff --git a/ppc/sys/setpriority.s b/ppc/sys/setpriority.s deleted file mode 100644 index 87203b2..0000000 --- a/ppc/sys/setpriority.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setpriority, 3) - diff --git a/ppc/sys/setprivexec.s b/ppc/sys/setprivexec.s deleted file mode 100644 index 92053ed..0000000 --- a/ppc/sys/setprivexec.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setprivexec, 3) - diff --git a/ppc/sys/setquota.s b/ppc/sys/setquota.s deleted file mode 100644 index 25560c8..0000000 --- a/ppc/sys/setquota.s +++ /dev/null @@ -1,27 +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@ - */ -#include "SYS.h" - -#define SYS_setquota 148 - -SYSCALL(setquota, 2) diff --git a/ppc/sys/setrlimit.s b/ppc/sys/setrlimit.s deleted file mode 100644 index fd51209..0000000 --- a/ppc/sys/setrlimit.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setrlimit, 2) - diff --git a/ppc/sys/setsid.s b/ppc/sys/setsid.s deleted file mode 100644 index aa4e8bc..0000000 --- a/ppc/sys/setsid.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setsid, 0) - diff --git a/ppc/sys/setsockopt.s b/ppc/sys/setsockopt.s deleted file mode 100644 index 0dcfcd1..0000000 --- a/ppc/sys/setsockopt.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(setsockopt, 5) - diff --git a/ppc/sys/settimeofday.s b/ppc/sys/settimeofday.s deleted file mode 100644 index 0d70390..0000000 --- a/ppc/sys/settimeofday.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(settimeofday, 2) - diff --git a/ppc/sys/setuid.s b/ppc/sys/setuid.s deleted file mode 100644 index 225d68a..0000000 --- a/ppc/sys/setuid.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(setuid, 1) diff --git a/ppc/sys/setxattr.s b/ppc/sys/setxattr.s deleted file mode 100644 index 171cf1b..0000000 --- a/ppc/sys/setxattr.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -SYSCALL(setxattr, 6) - diff --git a/ppc/sys/shmat.s b/ppc/sys/shmat.s deleted file mode 100644 index ff6e1f1..0000000 --- a/ppc/sys/shmat.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(shmat, 3) - diff --git a/ppc/sys/shmdt.s b/ppc/sys/shmdt.s deleted file mode 100644 index 53df096..0000000 --- a/ppc/sys/shmdt.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(shmdt, 3) - diff --git a/ppc/sys/shmget.s b/ppc/sys/shmget.s deleted file mode 100644 index 9be7cd8..0000000 --- a/ppc/sys/shmget.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(shmget, 3) - diff --git a/ppc/sys/shmsys.s b/ppc/sys/shmsys.s deleted file mode 100644 index 376f234..0000000 --- a/ppc/sys/shmsys.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(shmsys, 3) - diff --git a/ppc/sys/shutdown.s b/ppc/sys/shutdown.s deleted file mode 100644 index 737ee0c..0000000 --- a/ppc/sys/shutdown.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(shutdown, 2) - diff --git a/ppc/sys/sigaltstack.s b/ppc/sys/sigaltstack.s deleted file mode 100644 index 2cf3baf..0000000 --- a/ppc/sys/sigaltstack.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(sigaltstack, 3) diff --git a/ppc/sys/sigpending.s b/ppc/sys/sigpending.s deleted file mode 100644 index 336b836..0000000 --- a/ppc/sys/sigpending.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(sigpending, 1) diff --git a/ppc/sys/sigprocmask.s b/ppc/sys/sigprocmask.s deleted file mode 100644 index 90285aa..0000000 --- a/ppc/sys/sigprocmask.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(sigprocmask, 3) - diff --git a/ppc/sys/sigreturn.s b/ppc/sys/sigreturn.s deleted file mode 100644 index 0ecaf66..0000000 --- a/ppc/sys/sigreturn.s +++ /dev/null @@ -1,53 +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/m98k/sys/sigreturn.s - * - * The sigreturn() system call. - * - * The M98K sigcontext structure is more robust than older cousins. - * This routine is responsible for restoring register state - * based on the setting of sc_regs_saved before trapping into the - * kernel. See - * - * HISTORY - * 18-Nov-92 Ben Fathi (benf@next.com) - * Ported to m98k. - * - * 13-Jan-92 Peter King (king@next.com) - * Created. - */ - -#import "SYS.h" - -/* - * r3 = sigcontext pointer - */ - -MI_ENTRY_POINT(_sigreturn) - - /* Now call the kernel routine to restore the rest */ - - SYSCALL_NONAME(sigreturn, 1) - blr diff --git a/ppc/sys/sigwait.s b/ppc/sys/sigwait.s deleted file mode 100644 index 8c4c2d8..0000000 --- a/ppc/sys/sigwait.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(sigwait, 2) - diff --git a/ppc/sys/socket.s b/ppc/sys/socket.s deleted file mode 100644 index 5daadd1..0000000 --- a/ppc/sys/socket.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(socket, 3) - diff --git a/ppc/sys/socketpair.s b/ppc/sys/socketpair.s deleted file mode 100644 index d6304c2..0000000 --- a/ppc/sys/socketpair.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@ - */ -#include "SYS.h" - -#ifdef __LP64__ -SYSCALL(socketpair, 5) -#else /* !__LP64__ */ -PSEUDO(socketpair$UNIX2003, socketpair, 5) - blr - -SYSCALL_ERR(socketpair, 5, cerror_cvt) -#endif /* __LP64__ */ - diff --git a/ppc/sys/stat.s b/ppc/sys/stat.s deleted file mode 100644 index d9cab4c..0000000 --- a/ppc/sys/stat.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(stat, 2) - diff --git a/ppc/sys/statfs.s b/ppc/sys/statfs.s deleted file mode 100644 index 5a5694a..0000000 --- a/ppc/sys/statfs.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(statfs, 2) - diff --git a/ppc/sys/statv.s b/ppc/sys/statv.s deleted file mode 100644 index 330bc73..0000000 --- a/ppc/sys/statv.s +++ /dev/null @@ -1,27 +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 1998 Apple Computer, Inc. */ - -#include "SYS.h" - -SYSCALL(statv, 0) diff --git a/ppc/sys/swapon.s b/ppc/sys/swapon.s deleted file mode 100644 index c0197d2..0000000 --- a/ppc/sys/swapon.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(swapon, 1) - diff --git a/ppc/sys/symlink.s b/ppc/sys/symlink.s deleted file mode 100644 index 4304685..0000000 --- a/ppc/sys/symlink.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(symlink, 2) - diff --git a/ppc/sys/sync.s b/ppc/sys/sync.s deleted file mode 100644 index efe002d..0000000 --- a/ppc/sys/sync.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(sync, 0) - diff --git a/ppc/sys/syscall.s b/ppc/sys/syscall.s deleted file mode 100644 index 8af52f5..0000000 --- a/ppc/sys/syscall.s +++ /dev/null @@ -1,28 +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. */ - -#include "SYS.h" - -PSEUDO(syscall, syscall, 7) - blr diff --git a/ppc/sys/systable.s b/ppc/sys/systable.s deleted file mode 100644 index d3a6426..0000000 --- a/ppc/sys/systable.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(table, 5) diff --git a/ppc/sys/truncate.s b/ppc/sys/truncate.s deleted file mode 100644 index c54d976..0000000 --- a/ppc/sys/truncate.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(truncate, 2) - diff --git a/ppc/sys/umask.s b/ppc/sys/umask.s deleted file mode 100644 index 30e9bf4..0000000 --- a/ppc/sys/umask.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(umask, 1) - diff --git a/ppc/sys/undelete.s b/ppc/sys/undelete.s deleted file mode 100644 index 1e7cdbb..0000000 --- a/ppc/sys/undelete.s +++ /dev/null @@ -1,25 +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@ - */ -#include "SYS.h" - -SYSCALL(undelete, 1) diff --git a/ppc/sys/unlink.s b/ppc/sys/unlink.s deleted file mode 100644 index 8a21f70..0000000 --- a/ppc/sys/unlink.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(unlink, 1) - diff --git a/ppc/sys/unmount.s b/ppc/sys/unmount.s deleted file mode 100644 index acbd04c..0000000 --- a/ppc/sys/unmount.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(unmount, 1) - diff --git a/ppc/sys/utimes.s b/ppc/sys/utimes.s deleted file mode 100644 index 8595d64..0000000 --- a/ppc/sys/utimes.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(utimes, 2) - diff --git a/ppc/sys/vfork.s b/ppc/sys/vfork.s deleted file mode 100644 index d345e45..0000000 --- a/ppc/sys/vfork.s +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 1999-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@ - */ -/* Copyright (c) 1998 Apple Computer, Inc. All rights reserved. - * - * File: libc/ppc/sys/vfork.s - * - * HISTORY - * 23-Jun-1998 Umesh Vaishampayan (umeshv@apple.com) - * Created from fork.s - * - */ - -/* We use mode-independent "g" opcodes such as "srgi", and/or - * mode-independent macros such as MI_GET_ADDRESS. These expand - * into word operations when targeting __ppc__, and into doubleword - * operations when targeting __ppc64__. - */ -#include - -/* In vfork(), the child runs in parent's address space. */ - -#include "SYS.h" - -MI_ENTRY_POINT(_vfork) - MI_GET_ADDRESS(r5,__current_pid) // get address of __current_pid in r5 -2: - lwarx r6,0,r5 // don't cache pid across vfork - cmpwi r6,0 - ble-- 3f // is another vfork in progress - li r6,0 // if not, erase the stored pid -3: - addi r6,r6,-1 // count the parallel vforks in - stwcx. r6,0,r5 // negative cached pid values - bne-- 2b - - li r0,SYS_vfork - sc - b Lbotch // error return - - cmpwi r4,0 - beq Lparent // parent, since a1 == 0 in parent, - - li r3,0 // child - blr - -Lparent: // r3 == child's pid - lwarx r6,0,r5 // we're back, decrement vfork count - addi r6,r6,1 - stwcx. r6,0,r5 - bne-- Lparent - blr // return pid - -Lbotch: - lwarx r6,0,r5 // never went, decrement vfork count - addi r6,r6,1 - stwcx. r6,0,r5 - bne-- Lbotch - - MI_BRANCH_EXTERNAL(cerror) - diff --git a/ppc/sys/wait4.s b/ppc/sys/wait4.s deleted file mode 100644 index 84c1be5..0000000 --- a/ppc/sys/wait4.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(wait4, 4) - diff --git a/ppc/sys/write.s b/ppc/sys/write.s deleted file mode 100644 index 3c74493..0000000 --- a/ppc/sys/write.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(write, 3) - diff --git a/ppc/sys/writev.s b/ppc/sys/writev.s deleted file mode 100644 index 64f059e..0000000 --- a/ppc/sys/writev.s +++ /dev/null @@ -1,26 +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@ - */ -#include "SYS.h" - -SYSCALL(writev, 3) - diff --git a/ppc64/gen/Makefile.inc b/ppc64/gen/Makefile.inc index 0889bd6..e2d2966 100644 --- a/ppc64/gen/Makefile.inc +++ b/ppc64/gen/Makefile.inc @@ -3,7 +3,6 @@ MDSRCS += \ abs.s \ - ffs.s \ fp.h \ icacheinval.s \ mcount.s \ diff --git a/ppc64/stdlib/gdtoa.mk b/ppc64/stdlib/gdtoa.mk index 303aa14..242a70f 100644 --- a/ppc64/stdlib/gdtoa.mk +++ b/ppc64/stdlib/gdtoa.mk @@ -1,2 +1,5 @@ # Long double is head-tail pair of doubles -FBSDSRCS+= gdtoa-strtopdd.c machdep_ldisdd.c _ldbl_util.c +GDTOA_FBSDSRCS+= gdtoa-strtopdd.c machdep_ldisdd.c +MISRCS+= _ldbl_util.c + +CFLAGS-_ldbl_util.c += -I${.CURDIR}/fbsdcompat diff --git a/ppc64/string/Makefile.inc b/ppc64/string/Makefile.inc index 8c955d4..8b8fa87 100644 --- a/ppc64/string/Makefile.inc +++ b/ppc64/string/Makefile.inc @@ -5,6 +5,10 @@ MDSRCS += \ bcopy.s \ bzero.s \ + ffs.s \ + ffsl.s \ + fls.s \ + flsl.s \ memset.s \ memcmp.s \ strcat.s \ diff --git a/ppc64/sys/Makefile.inc b/ppc64/sys/Makefile.inc index edd7fe7..b8cff02 100644 --- a/ppc64/sys/Makefile.inc +++ b/ppc64/sys/Makefile.inc @@ -1,240 +1,12 @@ # searching ppc directory as a fallback to avoid unnecessary code duplication .PATH: ${.CURDIR}/ppc/sys ${.CURDIR}/ppc64/sys -MDSRCS+= ATPgetreq.s \ - ATPgetrsp.s \ - ATPsndreq.s \ - ATPsndrsp.s \ - ATgetmsg.s \ - ATputmsg.s \ - ATsocket.s \ - OSAtomic.s \ - _exit.s \ - __fcntl.s \ - _getlogin.s \ - __ioctl.s \ +MDSRCS+= OSAtomic.s \ _longjmp.s \ - __mmap.s \ - _pthread_kill.s \ - __pthread_canceled.s \ - __pthread_markcancel.s \ - __semwait_signal.s \ - _setjmp.s \ - _setlogin.s \ - _sysctl.s \ - accept.s \ - access.s \ - acct.s \ - add_profil.s \ - adjtime.s \ - aio_cancel.s \ - aio_error.s \ - aio_fsync.s \ - aio_read.s \ - aio_return.s \ - aio_suspend.s \ - aio_write.s \ - audit.s \ - auditctl.s \ - auditon.s \ - bind.s \ - cerror.s \ - chdir.s \ - checkuseraccess.s \ - chflags.s \ - chmod.s \ - chown.s \ - chroot.s \ - close.s \ - connect.s \ - dup.s \ - dup2.s \ - exchangedata.s \ - execve.s \ - fchdir.s \ - fchflags.s \ - fchmod.s \ - fchown.s \ - fgetxattr.s \ - fhopen.s \ - flistxattr.s \ - flock.s \ - fork.s \ - fpathconf.s \ - fremovexattr.s \ - fsctl.s \ - fsetxattr.s \ - fstat.s \ - fstatfs.s \ - fstatv.s \ - fsync.s \ - ftruncate.s \ - futimes.s \ - getattrlist.s \ - getaudit.s \ - getaudit_addr.s \ - getauid.s \ - getdirentries.s \ - getdirentriesattr.s \ - getdtablesize.s \ - getegid.s \ - geteuid.s \ - getfh.s \ - getfsstat.s \ - getgid.s \ - getgroups.s \ - getitimer.s \ - getpeername.s \ - getpgid.s \ - getpgrp.s \ - getpid.s \ - getppid.s \ - getpriority.s \ - getrlimit.s \ - getrusage.s \ - getsid.s \ - getsockname.s \ - getsockopt.s \ - getuid.s \ - getxattr.s \ - issetugid.s \ - kevent.s \ - kill.s \ - kqueue.s \ - kqueue_from_portset_np.s \ - kqueue_portset_np.s \ - ktrace.s \ - lchown.s \ - link.s \ - lio_listio.s \ - listen.s \ - listxattr.s \ - load_shared_file.s \ longjmp.s \ - lseek.s \ - lstat.s \ - lstatv.s \ - madvise.s \ - mincore.s \ - minherit.s \ - mkcomplex.s \ - mkdir.s \ - mkfifo.s \ - mknod.s \ - mlock.s \ - mlockall.s \ - mount.s \ - msgctl.s \ - msgget.s \ - msgrcv.s \ - msgsnd.s \ - msgsys.s \ - munlock.s \ - munlockall.s \ - new_system_shared_regions.s \ - nfsclnt.s \ - nfssvc.s \ - open.s \ - pathconf.s \ - pipe.s \ - poll.s \ - posix_madvise.s \ ppc_gettimeofday.s \ - pread.s \ - processor_facilities.s \ - profil.s \ - pthread_sigmask.s \ - ptrace.s \ - pwrite.s \ - quota.s \ - quotactl.s \ - read.s \ - readlink.s \ - readv.s \ - reboot.s \ - recvfrom.s \ - recvmsg.s \ - removexattr.s \ - rename.s \ - reset_shared_file.s \ - revoke.s \ - rmdir.s \ - searchfs.s \ - select.s \ - sem_close.s \ - sem_destroy.s \ - sem_getvalue.s \ - sem_init.s \ - sem_post.s \ - sem_trywait.s \ - sem_wait.s \ - semctl.s \ - semget.s \ - semop.s \ - semsys.s \ - sendmsg.s \ - sendto.s \ - setattrlist.s \ - setaudit.s \ - setaudit_addr.s \ - setauid.s \ - setegid.s \ - seteuid.s \ - setgid.s \ - setgroups.s \ - setitimer.s \ + _setjmp.s \ setjmp.s \ - setpgid.s \ - setpriority.s \ - setprivexec.s \ - setquota.s \ - setrlimit.s \ - setsid.s \ - setsockopt.s \ - settimeofday.s \ - setuid.s \ - setxattr.s \ - shmat.s \ - shmctl.s \ - shmdt.s \ - shmget.s \ - shmsys.s \ - shutdown.s \ - sigaltstack.s \ - sigpending.s \ - sigprocmask.s \ - sigreturn.s \ - sigwait.s \ - socket.s \ - socketpair.s \ - stat.s \ - statfs.s \ - statv.s \ - swapon.s \ - symlink.s \ - sync.s \ - syscall.s \ - systable.s \ - truncate.s \ - umask.s \ - undelete.s \ - unlink.s \ - unmount.s \ - utimes.s \ - vfork.s \ - wait4.s \ - write.s \ - writev.s - -MISRCS+= fcntl64.c ioctl64.c - -.for _src in fhopen.s getfh.s nfsclnt.s -CFLAGS-${_src} += -DNFSCLIENT -.endfor - -CFLAGS-nfssvc.s += -DNFSSERVER + _sigtramp.s -# for ppc64-specific assembly code, use the SYS.h in ppc/sys -.for _src in __fcntl.s __ioctl.s -CFLAGS-${_src} += -I${.CURDIR}/ppc/sys -.endfor +MDCOPYFILES+= ${.CURDIR}/ppc64/sys/libc.syscall.ppc64 diff --git a/ppc64/sys/__fcntl.s b/ppc64/sys/__fcntl.s deleted file mode 100644 index 57dffe2..0000000 --- a/ppc64/sys/__fcntl.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -PSEUDO(__fcntl, fcntl, 3) - blr diff --git a/ppc64/sys/__ioctl.s b/ppc64/sys/__ioctl.s deleted file mode 100644 index d80137c..0000000 --- a/ppc64/sys/__ioctl.s +++ /dev/null @@ -1,26 +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 "SYS.h" - -PSEUDO(__ioctl, ioctl, 3) - blr diff --git a/ppc64/sys/libc.syscall.ppc64 b/ppc64/sys/libc.syscall.ppc64 new file mode 100644 index 0000000..0c660de --- /dev/null +++ b/ppc64/sys/libc.syscall.ppc64 @@ -0,0 +1,25 @@ +_accept$NOCANCEL ___accept_nocancel +_aio_suspend$NOCANCEL ___aio_suspend_nocancel +_close$NOCANCEL ___close_nocancel +_connect$NOCANCEL ___connect_nocancel +_fsync$NOCANCEL ___fsync_nocancel +_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 +_waitid$NOCANCEL ___waitid_nocancel +_write$NOCANCEL ___write_nocancel +_writev$NOCANCEL ___writev_nocancel diff --git a/pthreads/Makefile.inc b/pthreads/Makefile.inc index 2c38fa9..447cf68 100644 --- a/pthreads/Makefile.inc +++ b/pthreads/Makefile.inc @@ -1,18 +1,49 @@ +.ifnmake autopatch .if exists(${.CURDIR}/${MACHINE_ARCH}/pthreads/Makefile.inc) .include "${.CURDIR}/${MACHINE_ARCH}/pthreads/Makefile.inc" .endif +.endif # !autopatch .PATH: ${.CURDIR}/pthreads -MISRCS += pthread_cond.c pthread_tsd.c pthread.c \ - pthread_mutex.c thread_setup.c stack.s pthread_rwlock.c \ - lock.s +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 + +${SYMROOT}/plockstat.h: ${.CURDIR}/pthreads/plockstat.d + dtrace -o ${.TARGET} -C -h -s ${.ALLSRC} + +.for _src in pthread_cond.c pthread_mutex.c pthread_rwlock.c +CFLAGS-${_src} += -I${SYMROOT} +${_src:R}.So ${_src:R}.po ${_src:R}.do ${_src:R}.o: ${SYMROOT}/plockstat.h +.endfor PTHREADS_INSTHDRS += pthread.h pthread_impl.h sched.h PTHREADS_INSTHDRS := ${PTHREADS_INSTHDRS:S/^/${.CURDIR}\/pthreads\//} INSTHDRS += ${PTHREADS_INSTHDRS} -UNIX03SRCS += pthread.c pthread_cond.c +PRIV_INSTHDRS += ${.CURDIR}/pthreads/pthread_machdep.h +LOCALHDRS += ${.CURDIR}/pthreads/pthread_workqueue.h + +LEGACYSRCS += pthread.c pthread_cancelable.c pthread_cond.c pthread_mutex.c pthread_rwlock.c +CANCELABLESRCS += pthread_cancelable.c + +# thread_setup.c can only compile with __DARWIN_UNIX03=0 (for ppc64) because +# the structure field names are renamed with __ prefix when __DARWIN_UNIX03=1. +# If thread_setup.c ever needs to build variant, this will have to be fix +# properly +CFLAGS-thread_setup.c = -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0 + +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +CFLAGS-pthread.c += -DLIBC_ALIAS_PTHREAD_CANCEL -DLIBC_ALIAS_PTHREAD_SETCANCELSTATE -DLIBC_ALIAS_PTHREAD_SETCANCELTYPE -DLIBC_ALIAS_PTHREAD_SIGMASK -DLIBC_ALIAS_PTHREAD_TESTCANCEL +CFLAGS-pthread_cancelable.c += -DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT +CFLAGS-pthread_cond.c += -DLIBC_ALIAS_PTHREAD_COND_INIT +CFLAGS-pthread_mutex.c += -DLIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY +CFLAGS-pthread_rwlock.c += -DLIBC_ALIAS_PTHREAD_RWLOCK_DESTROY -DLIBC_ALIAS_PTHREAD_RWLOCK_INIT -DLIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK + +STRIP_HDRS += pthread.h .if ${LIB} == "c" MAN3+= pthread.3 pthread_atfork.3 pthread_attr.3 pthread_cancel.3 \ @@ -36,43 +67,43 @@ MAN3+= pthread.3 pthread_atfork.3 pthread_attr.3 pthread_cancel.3 \ pthread_rwlockattr_getpshared.3 pthread_rwlockattr_init.3 \ pthread_rwlockattr_setpshared.3 -MLINKS+=pthread_attr.3 pthread_attr_destroy.3 \ - pthread_attr.3 pthread_attr_getdetachstate.3 \ - pthread_attr.3 pthread_attr_getinheritsched.3 \ - pthread_attr.3 pthread_attr_getschedparam.3 \ - pthread_attr.3 pthread_attr_getschedpolicy.3 \ - pthread_attr.3 pthread_attr_getscope.3 \ - pthread_attr.3 pthread_attr_getstackaddr.3 \ - pthread_attr.3 pthread_attr_getstacksize.3 \ - pthread_attr.3 pthread_attr_init.3 \ - pthread_attr.3 pthread_attr_setdetachstate.3 \ - pthread_attr.3 pthread_attr_setinheritsched.3 \ - pthread_attr.3 pthread_attr_setschedparam.3 \ - pthread_attr.3 pthread_attr_setschedpolicy.3 \ - pthread_attr.3 pthread_attr_setscope.3 \ - pthread_attr.3 pthread_attr_setstackaddr.3 \ - pthread_attr.3 pthread_attr_setstacksize.3 - -MLINKS+=pthread_getschedparam.3 pthread_setschedparam.3 - -MLINKS+=pthread_mutexattr.3 pthread_mutexattr_destroy.3 \ - pthread_mutexattr.3 pthread_mutexattr_getprioceiling.3 \ - pthread_mutexattr.3 pthread_mutexattr_getprotocol.3 \ - pthread_mutexattr.3 pthread_mutexattr_gettype.3 \ - pthread_mutexattr.3 pthread_mutexattr_init.3 \ - pthread_mutexattr.3 pthread_mutexattr_setprioceiling.3 \ - pthread_mutexattr.3 pthread_mutexattr_setprotocol.3 \ - pthread_mutexattr.3 pthread_mutexattr_settype.3 - -MLINKS+=pthread_setcancelstate.3 pthread_setcanceltype.3 \ - pthread_setcancelstate.3 pthread_testcancel.3 - -MLINKS+=pthread_condattr.3 pthread_condattr_init.3 \ - pthread_condattr.3 pthread_condattr_destroy.3 - -MLINKS+=pthread_rwlock_rdlock.3 pthread_rwlock_tryrdlock.3 - -MLINKS+=pthread_rwlock_wrlock.3 pthread_rwlock_trywrlock.3 +MLINKS+= pthread_attr.3 pthread_attr_destroy.3 \ + pthread_attr.3 pthread_attr_getdetachstate.3 \ + pthread_attr.3 pthread_attr_getinheritsched.3 \ + pthread_attr.3 pthread_attr_getschedparam.3 \ + pthread_attr.3 pthread_attr_getschedpolicy.3 \ + pthread_attr.3 pthread_attr_getscope.3 \ + pthread_attr.3 pthread_attr_getstackaddr.3 \ + pthread_attr.3 pthread_attr_getstacksize.3 \ + pthread_attr.3 pthread_attr_init.3 \ + pthread_attr.3 pthread_attr_setdetachstate.3 \ + pthread_attr.3 pthread_attr_setinheritsched.3 \ + pthread_attr.3 pthread_attr_setschedparam.3 \ + pthread_attr.3 pthread_attr_setschedpolicy.3 \ + pthread_attr.3 pthread_attr_setscope.3 \ + pthread_attr.3 pthread_attr_setstackaddr.3 \ + pthread_attr.3 pthread_attr_setstacksize.3 + +MLINKS+= pthread_getschedparam.3 pthread_setschedparam.3 + +MLINKS+= pthread_mutexattr.3 pthread_mutexattr_destroy.3 \ + pthread_mutexattr.3 pthread_mutexattr_getprioceiling.3 \ + pthread_mutexattr.3 pthread_mutexattr_getprotocol.3 \ + pthread_mutexattr.3 pthread_mutexattr_gettype.3 \ + pthread_mutexattr.3 pthread_mutexattr_init.3 \ + pthread_mutexattr.3 pthread_mutexattr_setprioceiling.3 \ + pthread_mutexattr.3 pthread_mutexattr_setprotocol.3 \ + pthread_mutexattr.3 pthread_mutexattr_settype.3 + +MLINKS+= pthread_setcancelstate.3 pthread_setcanceltype.3 \ + pthread_setcancelstate.3 pthread_testcancel.3 + +MLINKS+= pthread_condattr.3 pthread_condattr_destroy.3 \ + pthread_condattr.3 pthread_condattr_init.3 + +MLINKS+= pthread_rwlock_rdlock.3 pthread_rwlock_tryrdlock.3 + +MLINKS+= pthread_rwlock_wrlock.3 pthread_rwlock_trywrlock.3 .endif diff --git a/pthreads/lock.s b/pthreads/lock.s deleted file mode 100644 index 18c05b1..0000000 --- a/pthreads/lock.s +++ /dev/null @@ -1,169 +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@ - */ -/* - * 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. - * - */ - -#define __APPLE_API_PRIVATE -#include -#undef __APPLE_API_PRIVATE - -#if defined(__ppc__) || defined(__ppc64__) - -#import -#import - -/* void spin_lock(int *p); - * - * Lock the lock pointed to by `p'. Spin (possibly forever) until - * the lock is available. Test and test and set logic used. - * These routines have moved to the comm page. - */ - -.text -.align 2 -LEAF(__spin_lock_try) - ba _COMM_PAGE_SPINLOCK_TRY -END(__spin_lock_try) - -.globl _spin_lock -LEAF(__spin_lock) -_spin_lock: - ba _COMM_PAGE_SPINLOCK_LOCK -END(__spin_lock) - -/* void spin_unlock(int *p); - * - * Unlock the lock pointed to by p. - */ -.globl _spin_unlock -LEAF(__spin_unlock) -_spin_unlock: - ba _COMM_PAGE_SPINLOCK_UNLOCK -END(__spin_unlock) - -#elif defined(__i386__) - -#include - -/* - * void - * _spin_lock(p) - * int *p; - * - * Lock the lock pointed to by p. Spin (possibly forever) until the next - * lock is available. - */ - TEXT - ALIGN - -LEAF(__spin_lock_try, 0) - movl $(_COMM_PAGE_SPINLOCK_TRY), %eax - jmpl *%eax - - ALIGN - -.globl _spin_lock -LEAF(__spin_lock, 0) -_spin_lock: - movl $(_COMM_PAGE_SPINLOCK_LOCK), %eax - jmpl *%eax - -/* - * void - * _spin_unlock(p) - * int *p; - * - * Unlock the lock pointed to by p. - */ - ALIGN - -.globl _spin_unlock -LEAF(__spin_unlock, 0) -_spin_unlock: - movl $(_COMM_PAGE_SPINLOCK_UNLOCK), %eax - jmpl *%eax - -#elif defined(__x86_64__) - -#include - -/* - * void - * _spin_lock(p) - * int *p; - * - * Lock the lock pointed to by p. Spin (possibly forever) until the next - * lock is available. - */ - TEXT - ALIGN - -LEAF(__spin_lock_try, 0) - movq $(_COMM_PAGE_SPINLOCK_TRY), %rax - jmp *%rax - - ALIGN - -.globl _spin_lock -LEAF(__spin_lock, 0) -_spin_lock: - movq $(_COMM_PAGE_SPINLOCK_LOCK), %rax - jmp *%rax - -/* - * void - * _spin_unlock(p) - * int *p; - * - * Unlock the lock pointed to by p. - */ - ALIGN - -.globl _spin_unlock -LEAF(__spin_unlock, 0) -_spin_unlock: - movl $0, (%rdi) - ret - -#else -#error spin_locks not defined for this architecture -#endif diff --git a/pthreads/plockstat.d b/pthreads/plockstat.d new file mode 100644 index 0000000..a0fdc84 --- /dev/null +++ b/pthreads/plockstat.d @@ -0,0 +1,23 @@ +#include + +provider plockstat { + probe mutex__acquire(pthread_mutex_t *mutex, int recursive, int spin_count); + probe mutex__release(pthread_mutex_t *mutex, int recursive); + probe mutex__error(pthread_mutex_t *mutex, int errno); + probe mutex__block(pthread_mutex_t *mutex); + probe mutex__blocked(pthread_mutex_t *mutex, int successful); + probe mutex__spin(pthread_mutex_t *mutex); + probe mutex__spun(pthread_mutex_t *mutex, int successful, int spin_count); + + probe rw__acquire(pthread_rwlock_t *rwlock, int write_lock); + probe rw__block(pthread_rwlock_t *rwlock, int write_lock); + probe rw__blocked(pthread_rwlock_t *rwlock, int write_lock, int successful); + probe rw__release(pthread_rwlock_t *rwlock, int write_lock); + probe rw__error(pthread_rwlock_t *rwlock, int write_lock, int error); +}; + +#pragma D attributes Evolving/Evolving/ISA provider plockstat provider +#pragma D attributes Private/Private/Unknown provider plockstat module +#pragma D attributes Private/Private/Unknown provider plockstat function +#pragma D attributes Evolving/Evolving/ISA provider plockstat name +#pragma D attributes Evolving/Evolving/ISA provider plockstat args diff --git a/pthreads/pthread.3 b/pthreads/pthread.3 index 24639fd..fee3f7f 100644 --- a/pthreads/pthread.3 +++ b/pthreads/pthread.3 @@ -382,8 +382,9 @@ cancellation stack. .El .Sh INSTALLATION The default system libraries include -.Nm -funcitons. No additional libraries or CFLAGS are necessary to use this API. +.Nm pthread +functions. +No additional libraries or CFLAGS are necessary to use this API. .Sh SEE ALSO .Xr pthread_cleanup_pop 3 , .Xr pthread_cleanup_push 3 , @@ -406,15 +407,15 @@ funcitons. No additional libraries or CFLAGS are necessary to use this API. .Xr pthread_mutex_trylock 3 , .Xr pthread_mutex_unlock 3 , .Xr pthread_once 3 , -.Xr pthread_rwlockattr_destroy 3 , -.Xr pthread_rwlockattr_getpshared 3 , -.Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 , .Xr pthread_rwlock_destroy 3 , .Xr pthread_rwlock_init 3 , .Xr pthread_rwlock_rdlock 3 , .Xr pthread_rwlock_unlock 3 , .Xr pthread_rwlock_wrlock 3 , +.Xr pthread_rwlockattr_destroy 3 , +.Xr pthread_rwlockattr_getpshared 3 , +.Xr pthread_rwlockattr_init 3 , +.Xr pthread_rwlockattr_setpshared 3 , .Xr pthread_self 3 , .Xr pthread_setspecific 3 .Sh STANDARDS diff --git a/pthreads/pthread.c b/pthreads/pthread.c index cc79c42..59632e6 100644 --- a/pthreads/pthread.c +++ b/pthreads/pthread.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -50,29 +50,45 @@ */ #include "pthread_internals.h" +#include "pthread_workqueue.h" #include #include /* For printf(). */ #include #include /* For __mach_errno_addr() prototype. */ +#include #include #include #include #include -#include #include #include #define __APPLE_API_PRIVATE #include +#include +#if defined(__ppc__) +#include +#endif #ifndef BUILDING_VARIANT /* [ */ -__private_extern__ struct __pthread_list __pthread_head = LIST_HEAD_INITIALIZER(&__pthread_head); +__private_extern__ struct __pthread_list __pthread_head = TAILQ_HEAD_INITIALIZER(__pthread_head); + + /* Per-thread kernel support */ extern void _pthread_set_self(pthread_t); 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); +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 *), + void *arg, + int create_susp); /* Get CPU capabilities from the kernel */ __private_extern__ void _init_cpu_capabilities(void); @@ -82,6 +98,7 @@ extern void set_malloc_singlethreaded(int); /* Used when we need to call into the kernel with no reply port */ extern pthread_lock_t reply_port_lock; +int _pthread_find_thread(pthread_t thread); /* Mach message used to notify that a thread needs to be reaped */ @@ -102,7 +119,10 @@ int __is_threaded = 0; /* _pthread_count is protected by _pthread_list_lock */ static int _pthread_count = 1; int __unix_conforming = 0; +__private_extern__ size_t pthreadsize = 0; +/* under rosetta we will use old style creation of threads */ +static int __oldstyle = 0; __private_extern__ pthread_lock_t _pthread_list_lock = LOCK_INITIALIZER; @@ -135,24 +155,70 @@ static int max_priority; static int min_priority; static int pthread_concurrency; +static OSSpinLock __workqueue_list_lock = OS_SPINLOCK_INIT; + static void _pthread_exit(pthread_t self, void *value_ptr); +int _pthread_setcancelstate_internal(int state, int *oldstate, int conforming); +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 handle_removeitem(pthread_workqueue_t workq, pthread_workitem_t item); +static int kernel_workq_setup = 0; +static volatile int32_t kernel_workq_count = 0; +static volatile unsigned int user_workq_count = 0; +#define KERNEL_WORKQ_ELEM_MAX 64 /* Max number of elements in the kerrel */ +static int wqreadyprio = 0; /* current highest prio queue ready with items */ + +__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); + +struct _pthread_workqueue_head __pthread_workq0_head; +struct _pthread_workqueue_head __pthread_workq1_head; +struct _pthread_workqueue_head __pthread_workq2_head; +struct _pthread_workqueue_head __pthread_workq3_head; +struct _pthread_workqueue_head __pthread_workq4_head; +pthread_workqueue_head_t __pthread_wq_head_tbl[WQ_NUM_PRIO_QS] = {&__pthread_workq0_head, &__pthread_workq1_head, &__pthread_workq2_head, &__pthread_workq3_head, &__pthread_workq4_head}; + +static void workqueue_list_lock(void); +static void workqueue_list_unlock(void); +static int valid_workq(pthread_workqueue_t); +static void pick_nextworkqueue_droplock(void); +static int post_nextworkitem(pthread_workqueue_t workq); +static void _pthread_workq_return(pthread_t self); +static pthread_workqueue_attr_t _pthread_wq_attr_default = {0}; +void _pthread_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthread_workitem_t item, int reuse); +extern void start_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthread_workitem_t item, int reuse); +extern void thread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, int flags); +static pthread_workitem_t alloc_workitem(void); +static void free_workitem(pthread_workitem_t); +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); + +/* workq_ops commands */ +#define WQOPS_QUEUE_ADD 1 +#define WQOPS_QUEUE_REMOVE 2 +#define WQOPS_THREAD_RETURN 4 /* - * [Internal] stack support - */ -size_t _pthread_stack_size = 0; -#define STACK_LOWEST(sp) ((sp) & ~__pthread_stack_mask) -#define STACK_RESERVED (sizeof (struct _pthread)) - + * Flags filed passed to bsdthread_create and back in pthread_start +31 <---------------------------------> 0 +_________________________________________ +| flags(8) | policy(8) | importance(16) | +----------------------------------------- +*/ +void _pthread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int flags); -/* The stack grows towards lower addresses: - |<----------------user stack|struct _pthread| - ^STACK_LOWEST ^STACK_START ^STACK_BASE - ^STACK_SELF */ +#define PTHREAD_START_CUSTOM 0x01000000 +#define PTHREAD_START_SETSCHED 0x02000000 +#define PTHREAD_START_DETACHED 0x04000000 +#define PTHREAD_START_POLICY_BITSHIFT 16 +#define PTHREAD_START_POLICY_MASK 0xff +#define PTHREAD_START_IMPORTANCE_MASK 0xffff -#define STACK_BASE(sp) (((sp) | __pthread_stack_mask) + 1) -#define STACK_START(stack_low) (STACK_BASE(stack_low) - STACK_RESERVED) -#define STACK_SELF(sp) STACK_START(sp) +extern pthread_t __bsdthread_create(void (*func)(void *), void * func_arg, void * stack, pthread_t thread, unsigned int flags); +extern int __bsdthread_terminate(void * freeaddr, size_t freesize, mach_port_t kport, mach_port_t joinsem); #if defined(__ppc__) || defined(__ppc64__) static const vm_address_t PTHREAD_STACK_HINT = 0xF0000000; @@ -174,7 +240,7 @@ _pthread_allocate_stack(pthread_attr_t *attrs, void **stack) kern_return_t kr; vm_address_t stackaddr; size_t guardsize; -#if 1 + assert(attrs->stacksize >= PTHREAD_STACK_MIN); if (attrs->stackaddr != NULL) { /* No guard pages setup in this case */ @@ -203,86 +269,164 @@ _pthread_allocate_stack(pthread_attr_t *attrs, void **stack) if (guardsize) kr = vm_protect(mach_task_self(), stackaddr, guardsize, FALSE, VM_PROT_NONE); *stack = (void *)(stackaddr + attrs->stacksize + guardsize); + return 0; +} -#else - vm_address_t cur_stack = (vm_address_t)0; - if (free_stacks == 0) - { - /* Allocating guard pages is done by doubling - * the actual stack size, since STACK_BASE() needs - * to have stacks aligned on stack_size. Allocating just - * one page takes as much memory as allocating more pages - * since it will remain one entry in the vm map. - * Besides, allocating more than one page allows tracking the - * overflow pattern when the overflow is bigger than one page. - */ -#ifndef NO_GUARD_PAGES -# define GUARD_SIZE(a) (2*(a)) -# define GUARD_MASK(a) (((a)<<1) | 1) -#else -# define GUARD_SIZE(a) (a) -# define GUARD_MASK(a) (a) +static int +_pthread_create_pthread_onstack(pthread_attr_t *attrs, void **stack, pthread_t *thread) +{ + kern_return_t kr; + pthread_t t; + vm_address_t stackaddr; + size_t guardsize, allocsize; + + assert(attrs->stacksize >= PTHREAD_STACK_MIN); + + if (attrs->stackaddr != NULL) { + /* No guard pages setup in this case */ + assert(((uintptr_t)attrs->stackaddr % vm_page_size) == 0); + *stack = attrs->stackaddr; + t = (pthread_t)malloc(pthreadsize); + _pthread_struct_init(t, attrs, attrs->stackaddr, 0, 0, 0); + t->freeStackOnExit = 0; + t->freeaddr = 0; + t->freesize = 0; + *thread = t; + return 0; + } + + guardsize = attrs->guardsize; + allocsize = attrs->stacksize + guardsize + pthreadsize; + stackaddr = PTHREAD_STACK_HINT; + kr = vm_map(mach_task_self(), &stackaddr, + allocsize, + vm_page_size-1, + VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE , MEMORY_OBJECT_NULL, + 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL, + VM_INHERIT_DEFAULT); + if (kr != KERN_SUCCESS) + kr = vm_allocate(mach_task_self(), + &stackaddr, allocsize, + VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE); + if (kr != KERN_SUCCESS) { + return EAGAIN; + } + /* The guard page is at the lowest address */ + /* The stack base is the highest address */ + if (guardsize) + kr = vm_protect(mach_task_self(), stackaddr, guardsize, FALSE, VM_PROT_NONE); + + + *stack = (void *)(stackaddr + attrs->stacksize + guardsize); + + t = (pthread_t)(stackaddr + attrs->stacksize + guardsize); + _pthread_struct_init(t, attrs, *stack, 0, 0, 1); + t->kernalloc = 0; + t->freesize = allocsize; + t->freeaddr = (void *)stackaddr; + t->freeStackOnExit = 1; + *thread = t; + + return 0; +} + +static kern_return_t +_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; + +#if WQ_TRACE + __kdebug_trace(0x900001c, freestruct, termthread, 0, 0, 0); #endif - while (lowest_stack > GUARD_SIZE(__pthread_stack_size)) - { - lowest_stack -= GUARD_SIZE(__pthread_stack_size); - /* Ensure stack is there */ - kr = vm_allocate(mach_task_self(), - &lowest_stack, - GUARD_SIZE(__pthread_stack_size), - FALSE); -#ifndef NO_GUARD_PAGES - if (kr == KERN_SUCCESS) { - kr = vm_protect(mach_task_self(), - lowest_stack, - __pthread_stack_size, - FALSE, VM_PROT_NONE); - lowest_stack += __pthread_stack_size; - if (kr == KERN_SUCCESS) - break; + kport = t->kernel_thread; + joinsem = t->joiner_notify; + + if (t->freeStackOnExit) { + freeaddr = (vm_address_t)t->freeaddr; + if (freestruct) + freesize = t->stacksize + t->guardsize + pthreadsize; + else + freesize = t->stacksize + t->guardsize; + if (termthread) { + mig_dealloc_reply_port(MACH_PORT_NULL); + LOCK(_pthread_list_lock); + if (freestruct != 0) { + TAILQ_REMOVE(&__pthread_head, t, plist); + /* if parent has not returned from create yet keep pthread_t */ +#if WQ_TRACE + __kdebug_trace(0x9000010, t, 0, 0, 1, 0); +#endif + if (t->parentcheck == 0) + freesize -= pthreadsize; } -#else - if (kr == KERN_SUCCESS) - break; + t->childexit = 1; + thread_count = --_pthread_count; + UNLOCK(_pthread_list_lock); + +#if WQ_TRACE + __kdebug_trace(0x9000020, freeaddr, freesize, kport, 1, 0); #endif + if (thread_count <=0) + exit(0); + else + __bsdthread_terminate(freeaddr, freesize, kport, joinsem); + abort(); + } else { +#if WQ_TRACE + __kdebug_trace(0x9000024, freeaddr, freesize, 0, 1, 0); +#endif + res = vm_deallocate(mach_task_self(), freeaddr, freesize); } - if (lowest_stack > 0) - free_stacks = (vm_address_t *)lowest_stack; - else - { - /* Too bad. We'll just have to take what comes. - Use vm_map instead of vm_allocate so we can - specify alignment. */ - kr = vm_map(mach_task_self(), &lowest_stack, - GUARD_SIZE(__pthread_stack_size), - GUARD_MASK(__pthread_stack_mask), - TRUE /* anywhere */, MEMORY_OBJECT_NULL, - 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL, - VM_INHERIT_DEFAULT); - /* This really shouldn't fail and if it does I don't - know what to do. */ -#ifndef NO_GUARD_PAGES - if (kr == KERN_SUCCESS) { - kr = vm_protect(mach_task_self(), - lowest_stack, - __pthread_stack_size, - FALSE, VM_PROT_NONE); - lowest_stack += __pthread_stack_size; + } else { + if (termthread) { + mig_dealloc_reply_port(MACH_PORT_NULL); + LOCK(_pthread_list_lock); + if (freestruct != 0) { + TAILQ_REMOVE(&__pthread_head, t, plist); +#if WQ_TRACE + __kdebug_trace(0x9000010, t, 0, 0, 2, 0); +#endif + } + thread_count = --_pthread_count; + t->childexit = 1; + UNLOCK(_pthread_list_lock); + + if (freestruct) { +#if WQ_TRACE + __kdebug_trace(0x9000008, t, 0, 0, 2, 0); +#endif + free(t); } + + freeaddr = 0; + freesize = 0; +#if WQ_TRACE + __kdebug_trace(0x9000020, 0, 0, kport, 2, 0); +#endif + + if (thread_count <=0) + exit(0); + else + __bsdthread_terminate(NULL, 0, kport, joinsem); + abort(); + } else if (freestruct) { + t->sig = _PTHREAD_NO_SIG; +#if WQ_TRACE + __kdebug_trace(0x9000024, t, 0, 0, 2, 0); #endif - free_stacks = (vm_address_t *)lowest_stack; - lowest_stack = 0; + free(t); } - *free_stacks = 0; /* No other free stacks */ } - cur_stack = STACK_START((vm_address_t) free_stacks); - free_stacks = (vm_address_t *)*free_stacks; - cur_stack = _adjust_sp(cur_stack); /* Machine dependent stack fudging */ -#endif - return 0; -} + return(res); +} + -static pthread_attr_t _pthread_attr_default = {0}; /* * Destroy a thread attribute structure @@ -292,7 +436,8 @@ pthread_attr_destroy(pthread_attr_t *attr) { if (attr->sig == _PTHREAD_ATTR_SIG) { - return (ESUCCESS); + attr->sig = 0; + return (0); } else { return (EINVAL); /* Not an attribute structure! */ @@ -310,7 +455,7 @@ pthread_attr_getdetachstate(const pthread_attr_t *attr, if (attr->sig == _PTHREAD_ATTR_SIG) { *detachstate = attr->detached; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an attribute structure! */ @@ -328,7 +473,7 @@ pthread_attr_getinheritsched(const pthread_attr_t *attr, if (attr->sig == _PTHREAD_ATTR_SIG) { *inheritsched = attr->inherit; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an attribute structure! */ @@ -346,7 +491,7 @@ pthread_attr_getschedparam(const pthread_attr_t *attr, if (attr->sig == _PTHREAD_ATTR_SIG) { *param = attr->param; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an attribute structure! */ @@ -364,7 +509,7 @@ pthread_attr_getschedpolicy(const pthread_attr_t *attr, if (attr->sig == _PTHREAD_ATTR_SIG) { *policy = attr->policy; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an attribute structure! */ @@ -379,17 +524,19 @@ static const size_t DEFAULT_STACK_SIZE = (512*1024); int pthread_attr_init(pthread_attr_t *attr) { - attr->stacksize = DEFAULT_STACK_SIZE; - attr->stackaddr = NULL; + attr->stacksize = DEFAULT_STACK_SIZE; + attr->stackaddr = NULL; attr->sig = _PTHREAD_ATTR_SIG; attr->param.sched_priority = default_priority; attr->param.quantum = 10; /* quantum isn't public yet */ attr->detached = PTHREAD_CREATE_JOINABLE; attr->inherit = _PTHREAD_DEFAULT_INHERITSCHED; attr->policy = _PTHREAD_DEFAULT_POLICY; - attr->freeStackOnExit = TRUE; + attr->freeStackOnExit = 1; + attr->fastpath = 1; + attr->schedset = 0; attr->guardsize = vm_page_size; - return (ESUCCESS); + return (0); } /* @@ -406,7 +553,7 @@ pthread_attr_setdetachstate(pthread_attr_t *attr, (detachstate == PTHREAD_CREATE_DETACHED)) { attr->detached = detachstate; - return (ESUCCESS); + return (0); } else { return (EINVAL); @@ -431,7 +578,7 @@ pthread_attr_setinheritsched(pthread_attr_t *attr, (inheritsched == PTHREAD_EXPLICIT_SCHED)) { attr->inherit = inheritsched; - return (ESUCCESS); + return (0); } else { return (EINVAL); @@ -454,7 +601,8 @@ pthread_attr_setschedparam(pthread_attr_t *attr, { /* TODO: Validate sched_param fields */ attr->param = *param; - return (ESUCCESS); + attr->schedset = 1; + return (0); } else { return (EINVAL); /* Not an attribute structure! */ @@ -476,7 +624,8 @@ pthread_attr_setschedpolicy(pthread_attr_t *attr, (policy == SCHED_FIFO)) { attr->policy = policy; - return (ESUCCESS); + attr->schedset = 1; + return (0); } else { return (EINVAL); @@ -498,7 +647,7 @@ pthread_attr_setscope(pthread_attr_t *attr, if (attr->sig == _PTHREAD_ATTR_SIG) { if (scope == PTHREAD_SCOPE_SYSTEM) { /* No attribute yet for the scope */ - return (ESUCCESS); + return (0); } else if (scope == PTHREAD_SCOPE_PROCESS) { return (ENOTSUP); } @@ -511,12 +660,12 @@ pthread_attr_setscope(pthread_attr_t *attr, * We currently only provide PTHREAD_SCOPE_SYSTEM */ int -pthread_attr_getscope(pthread_attr_t *attr, +pthread_attr_getscope(const pthread_attr_t *attr, int *scope) { if (attr->sig == _PTHREAD_ATTR_SIG) { *scope = PTHREAD_SCOPE_SYSTEM; - return (ESUCCESS); + return (0); } return (EINVAL); /* Not an attribute structure! */ } @@ -527,7 +676,7 @@ pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) { if (attr->sig == _PTHREAD_ATTR_SIG) { *stackaddr = attr->stackaddr; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an attribute structure! */ } @@ -538,8 +687,9 @@ pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) { if ((attr->sig == _PTHREAD_ATTR_SIG) && (((uintptr_t)stackaddr % vm_page_size) == 0)) { attr->stackaddr = stackaddr; - attr->freeStackOnExit = FALSE; - return (ESUCCESS); + attr->freeStackOnExit = 0; + attr->fastpath = 0; + return (0); } else { return (EINVAL); /* Not an attribute structure! */ } @@ -550,7 +700,7 @@ pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) { if (attr->sig == _PTHREAD_ATTR_SIG) { *stacksize = attr->stacksize; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an attribute structure! */ } @@ -561,7 +711,7 @@ pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) { if ((attr->sig == _PTHREAD_ATTR_SIG) && ((stacksize % vm_page_size) == 0) && (stacksize >= PTHREAD_STACK_MIN)) { attr->stacksize = stacksize; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an attribute structure! */ } @@ -573,7 +723,7 @@ pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t * sta if (attr->sig == _PTHREAD_ATTR_SIG) { *stackaddr = (void *)((uintptr_t)attr->stackaddr - attr->stacksize); *stacksize = attr->stacksize; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an attribute structure! */ } @@ -590,8 +740,9 @@ pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize) ((stacksize % vm_page_size) == 0) && (stacksize >= PTHREAD_STACK_MIN)) { attr->stackaddr = (void *)((uintptr_t)stackaddr + stacksize); attr->stacksize = stacksize; - attr->freeStackOnExit = FALSE; - return (ESUCCESS); + attr->freeStackOnExit = 0; + attr->fastpath = 0; + return (0); } else { return (EINVAL); /* Not an attribute structure! */ } @@ -609,7 +760,8 @@ pthread_attr_setguardsize(pthread_attr_t *attr, /* Guardsize of 0 is valid, ot means no guard */ if ((guardsize % vm_page_size) == 0) { attr->guardsize = guardsize; - return (ESUCCESS); + attr->fastpath = 0; + return (0); } else return(EINVAL); } @@ -625,7 +777,7 @@ pthread_attr_getguardsize(const pthread_attr_t *attr, { if (attr->sig == _PTHREAD_ATTR_SIG) { *guardsize = attr->guardsize; - return (ESUCCESS); + return (0); } return (EINVAL); /* Not an attribute structure! */ } @@ -642,6 +794,61 @@ _pthread_body(pthread_t self) _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 + pthread_attr_t *attrs = &_pthread_attr_default; + char * stackaddr; + + if ((pflags & PTHREAD_START_CUSTOM) == 0) { + stackaddr = self; + _pthread_struct_init(self, attrs, stackaddr, stacksize, 1, 1); + LOCK(_pthread_list_lock); + if (pflags & PTHREAD_START_SETSCHED) { + self->policy = ((pflags >> PTHREAD_START_POLICY_BITSHIFT) & PTHREAD_START_POLICY_MASK); + self->param.sched_priority = (pflags & PTHREAD_START_IMPORTANCE_MASK); + } + /* These are not joinable threads */ + if ((pflags & PTHREAD_START_DETACHED) == PTHREAD_START_DETACHED) { + self->detached &= ~PTHREAD_CREATE_JOINABLE; + self->detached |= PTHREAD_CREATE_DETACHED; + } + } else + LOCK(_pthread_list_lock); + self->kernel_thread = kport; + self->fun = fun; + self->arg = funarg; + + /* Add to the pthread list */ + if (self->parentcheck == 0) { + TAILQ_INSERT_TAIL(&__pthread_head, self, plist); +#if WQ_TRACE + __kdebug_trace(0x900000c, self, 0, 0, 3, 0); +#endif + _pthread_count++; + } + self->childrun = 1; + UNLOCK(_pthread_list_lock); +#if defined(__i386__) || defined(__x86_64__) + _pthread_set_self(self); +#endif + +#if WQ_DEBUG + pself = pthread_self(); + if (self != pself) + abort(); +#endif +#if WQ_TRACE + __kdebug_trace(0x9000030, self, pflags, 0, 0, 0); +#endif + + _pthread_exit(self, (self->fun)(self->arg)); +} + int _pthread_create(pthread_t t, const pthread_attr_t *attrs, @@ -649,12 +856,19 @@ _pthread_create(pthread_t t, const mach_port_t kernel_thread) { int res; - res = ESUCCESS; + res = 0; do { memset(t, 0, sizeof(*t)); + t->newstyle = 0; + t->schedset = 0; + t->kernalloc = 0; t->tsd[0] = t; + t->max_tsd_key = 0; + t->wqthread = 0; + t->cur_workq = 0; + t->cur_workitem = 0; t->stacksize = attrs->stacksize; t->stackaddr = (void *)stack; t->guardsize = attrs->guardsize; @@ -663,14 +877,14 @@ _pthread_create(pthread_t t, t->inherit = attrs->inherit; t->policy = attrs->policy; t->param = attrs->param; - t->freeStackOnExit = attrs->freeStackOnExit; + t->freeStackOnExit = attrs->freeStackOnExit; t->mutexes = (struct _pthread_mutex *)NULL; t->sig = _PTHREAD_SIG; t->reply_port = MACH_PORT_NULL; t->cthread_self = NULL; LOCK_INIT(t->lock); - t->plist.le_next = (struct _pthread *)0; - t->plist.le_prev = (struct _pthread **)0; + t->plist.tqe_next = (struct _pthread *)0; + t->plist.tqe_prev = (struct _pthread **)0; t->cancel_state = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED; t->__cleanup_stack = (struct __darwin_pthread_handler_rec *)NULL; t->death = SEMAPHORE_NULL; @@ -681,6 +895,59 @@ _pthread_create(pthread_t t, return (res); } +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)stack; + + if (nozero == 0) { + memset(t, 0, sizeof(*t)); + t->plist.tqe_next = (struct _pthread *)0; + t->plist.tqe_prev = (struct _pthread **)0; + } + t->schedset = attrs->schedset; + t->tsd[0] = t; + if (kernalloc != 0) { + stackaddr = (mach_vm_offset_t)t; + + /* if allocated from kernel set values appropriately */ + t->stacksize = stacksize; + t->stackaddr = stackaddr; + t->freeStackOnExit = 1; + t->freeaddr = stackaddr - stacksize - vm_page_size; + t->freesize = pthreadsize + stacksize + vm_page_size; + } else { + t->stacksize = attrs->stacksize; + t->stackaddr = (void *)stack; + } + t->guardsize = attrs->guardsize; + t->detached = attrs->detached; + t->inherit = attrs->inherit; + t->policy = attrs->policy; + t->param = attrs->param; + t->mutexes = (struct _pthread_mutex *)NULL; + t->sig = _PTHREAD_SIG; + t->reply_port = MACH_PORT_NULL; + t->cthread_self = NULL; + LOCK_INIT(t->lock); + t->cancel_state = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED; + t->__cleanup_stack = (struct __darwin_pthread_handler_rec *)NULL; + t->death = SEMAPHORE_NULL; + t->newstyle = 1; + t->kernalloc = kernalloc; + t->wqthread = 0; + t->cur_workq = 0; + t->cur_workitem = 0; + 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) @@ -702,25 +969,67 @@ pthread_is_threaded_np(void) mach_port_t pthread_mach_thread_np(pthread_t t) { - thread_t kernel_thread; + mach_port_t kport = MACH_PORT_NULL; + + if (_pthread_lookup_thread(t, &kport, 0) != 0) + return(NULL); + + return(kport); +} - /* Wait for the creator to initialize it */ - while ((kernel_thread = t->kernel_thread) == MACH_PORT_NULL) - sched_yield(); +pthread_t pthread_from_mach_thread_np(mach_port_t kernel_thread) +{ + struct _pthread * p = NULL; - return kernel_thread; + /* No need to wait as mach port is already known */ + LOCK(_pthread_list_lock); + TAILQ_FOREACH(p, &__pthread_head, plist) { + if (p->kernel_thread == kernel_thread) + break; + } + UNLOCK(_pthread_list_lock); + return p; } size_t pthread_get_stacksize_np(pthread_t t) { - return t->stacksize; + int ret; + size_t size = 0; + + if (t == NULL) + return(ESRCH); + + LOCK(_pthread_list_lock); + + if ((ret = _pthread_find_thread(t)) != 0) { + UNLOCK(_pthread_list_lock); + return(ret); + } + size = t->stacksize; + UNLOCK(_pthread_list_lock); + return(size); } void * pthread_get_stackaddr_np(pthread_t t) { - return t->stackaddr; + int ret; + void * addr = NULL; + + if (t == NULL) + return(ESRCH); + + LOCK(_pthread_list_lock); + + if ((ret = _pthread_find_thread(t)) != 0) { + UNLOCK(_pthread_list_lock); + return(ret); + } + addr = t->stackaddr; + UNLOCK(_pthread_list_lock); + + return(addr); } mach_port_t @@ -739,6 +1048,184 @@ pthread_main_np(void) return ((self->detached & _PTHREAD_CREATE_PARENT) == _PTHREAD_CREATE_PARENT); } +static int +_new_pthread_create_suspended(pthread_t *thread, + const pthread_attr_t *attr, + void *(*start_routine)(void *), + void *arg, + int create_susp) +{ + pthread_attr_t *attrs; + void *stack; + int error; + unsigned int flags; + pthread_t t; + kern_return_t kern_res; + mach_port_t kernel_thread = MACH_PORT_NULL; + int needresume; + task_t self = mach_task_self(); + int kernalloc = 0; + int susp = create_susp; + + if ((attrs = (pthread_attr_t *)attr) == (pthread_attr_t *)NULL) + { /* Set up default paramters */ + attrs = &_pthread_attr_default; + } else if (attrs->sig != _PTHREAD_ATTR_SIG) { + return EINVAL; + } + error = 0; + + if (((attrs->policy != _PTHREAD_DEFAULT_POLICY) || + (attrs->param.sched_priority != default_priority)) && (create_susp == 0)) { + needresume = 1; + susp = 1; + } else + needresume = 0; + + /* In default policy (ie SCHED_OTHER) only sched_priority is used. Check for + * any change in priority or policy is needed here. + */ + if ((__oldstyle == 1) || (create_susp != 0)) { + /* Rosetta or pthread_create_suspended() */ + /* running under rosetta */ + /* Allocate a stack for the thread */ +#if WQ_TRACE + __kdebug_trace(0x9000000, create_susp, 0, 0, 0, 0); +#endif + if ((error = _pthread_allocate_stack(attrs, &stack)) != 0) { + return(error); + } + t = (pthread_t)malloc(sizeof(struct _pthread)); + *thread = t; + if (susp) { + /* Create the Mach thread for this thread */ + PTHREAD_MACH_CALL(thread_create(self, &kernel_thread), kern_res); + if (kern_res != KERN_SUCCESS) + { + printf("Can't create thread: %d\n", kern_res); + return(EINVAL); + } + } + if ((error = _pthread_create(t, attrs, stack, kernel_thread)) != 0) + { + return(error); + } + set_malloc_singlethreaded(0); + __is_threaded = 1; + + /* Send it on it's way */ + t->arg = arg; + t->fun = start_routine; + t->newstyle = 0; + /* Now set it up to execute */ + LOCK(_pthread_list_lock); + TAILQ_INSERT_TAIL(&__pthread_head, t, plist); +#if WQ_TRACE + __kdebug_trace(0x900000c, t, 0, 0, 4, 0); +#endif + _pthread_count++; + UNLOCK(_pthread_list_lock); + _pthread_setup(t, _pthread_body, stack, susp, needresume); + return(0); + } else { + + flags = 0; + if (attrs->fastpath == 1) + kernalloc = 1; + + if (attrs->detached == PTHREAD_CREATE_DETACHED) + flags |= PTHREAD_START_DETACHED; + if (attrs->schedset != 0) { + flags |= PTHREAD_START_SETSCHED; + flags |= ((attrs->policy & PTHREAD_START_POLICY_MASK) << PTHREAD_START_POLICY_BITSHIFT); + flags |= (attrs->param.sched_priority & PTHREAD_START_IMPORTANCE_MASK); + } + + set_malloc_singlethreaded(0); + __is_threaded = 1; + + if (kernalloc == 0) { + /* Allocate a stack for the thread */ + flags |= PTHREAD_START_CUSTOM; + if ((error = _pthread_create_pthread_onstack(attrs, &stack, &t)) != 0) { + return(error); + } + /* Send it on it's way */ + t->arg = arg; + t->fun = start_routine; + t->newstyle = 1; + +#if WQ_TRACE + __kdebug_trace(0x9000004, t, flags, 0, 0, 0); +#endif + + if ((t = __bsdthread_create(start_routine, arg, stack, t, flags)) == -1) { + _pthread_free_pthread_onstack(t, 1, 0); + return (EAGAIN); + } + LOCK(_pthread_list_lock); + t->parentcheck = 1; + if ((t->childexit != 0) && ((t->detached & PTHREAD_CREATE_DETACHED) == PTHREAD_CREATE_DETACHED)) { + /* detached child exited, mop up */ + UNLOCK(_pthread_list_lock); +#if WQ_TRACE + __kdebug_trace(0x9000008, t, 0, 0, 1, 0); +#endif + free(t); + } else if (t->childrun == 0) { + TAILQ_INSERT_TAIL(&__pthread_head, t, plist); + _pthread_count++; +#if WQ_TRACE + __kdebug_trace(0x900000c, t, 0, 0, 1, 0); +#endif + UNLOCK(_pthread_list_lock); + } else + UNLOCK(_pthread_list_lock); + + *thread = t; + +#if WQ_TRACE + __kdebug_trace(0x9000014, t, 0, 0, 1, 0); +#endif + return (0); + + } else { + /* kernel allocation */ +#if WQ_TRACE + __kdebug_trace(0x9000018, flags, 0, 0, 0, 0); +#endif + if ((t = __bsdthread_create(start_routine, arg, attrs->stacksize, NULL, flags)) == -1) + return (EAGAIN); + /* Now set it up to execute */ + LOCK(_pthread_list_lock); + t->parentcheck = 1; + if ((t->childexit != 0) && ((t->detached & PTHREAD_CREATE_DETACHED) == PTHREAD_CREATE_DETACHED)) { + /* detached child exited, mop up */ + UNLOCK(_pthread_list_lock); +#if WQ_TRACE + __kdebug_trace(0x9000008, t, pthreadsize, 0, 2, 0); +#endif + vm_deallocate(self, t, pthreadsize); + } else if (t->childrun == 0) { + TAILQ_INSERT_TAIL(&__pthread_head, t, plist); + _pthread_count++; +#if WQ_TRACE + __kdebug_trace(0x900000c, t, 0, 0, 2, 0); +#endif + UNLOCK(_pthread_list_lock); + } else + UNLOCK(_pthread_list_lock); + + *thread = t; + +#if WQ_TRACE + __kdebug_trace(0x9000014, t, 0, 0, 2, 0); +#endif + return(0); + } + } +} + static int _pthread_create_suspended(pthread_t *thread, const pthread_attr_t *attr, @@ -760,7 +1247,7 @@ _pthread_create_suspended(pthread_t *thread, } else if (attrs->sig != _PTHREAD_ATTR_SIG) { return EINVAL; } - res = ESUCCESS; + res = 0; /* In default policy (ie SCHED_OTHER) only sched_priority is used. Check for * any change in priority or policy is needed here. @@ -802,7 +1289,10 @@ _pthread_create_suspended(pthread_t *thread, t->fun = start_routine; /* Now set it up to execute */ LOCK(_pthread_list_lock); - LIST_INSERT_HEAD(&__pthread_head, t, plist); + TAILQ_INSERT_TAIL(&__pthread_head, t, plist); +#if WQ_TRACE + __kdebug_trace(0x900000c, t, 0, 0, 5, 0); +#endif _pthread_count++; UNLOCK(_pthread_list_lock); _pthread_setup(t, _pthread_body, stack, suspended, needresume); @@ -816,7 +1306,7 @@ pthread_create(pthread_t *thread, void *(*start_routine)(void *), void *arg) { - return _pthread_create_suspended(thread, attr, start_routine, arg, 0); + return _new_pthread_create_suspended(thread, attr, start_routine, arg, 0); } int @@ -834,16 +1324,22 @@ pthread_create_suspended_np(pthread_t *thread, int pthread_detach(pthread_t thread) { - if (thread->sig == _PTHREAD_SIG) + int newstyle = 0; + int ret; + + if ((ret = _pthread_lookup_thread(thread, NULL, 1)) != 0) + return (ret); /* Not a valid thread */ + + LOCK(thread->lock); + newstyle = thread->newstyle; + if (thread->detached & PTHREAD_CREATE_JOINABLE) { - LOCK(thread->lock); - if (thread->detached & PTHREAD_CREATE_JOINABLE) - { - if (thread->detached & _PTHREAD_EXITED) { - UNLOCK(thread->lock); - pthread_join(thread, NULL); - return ESUCCESS; - } else { + if (thread->detached & _PTHREAD_EXITED) { + UNLOCK(thread->lock); + pthread_join(thread, NULL); + return 0; + } else { + if (newstyle == 0) { semaphore_t death = thread->death; thread->detached &= ~PTHREAD_CREATE_JOINABLE; @@ -851,14 +1347,22 @@ pthread_detach(pthread_t thread) UNLOCK(thread->lock); if (death) (void) semaphore_signal(death); - return (ESUCCESS); + } else { + mach_port_t joinport = thread->joiner_notify; + + thread->detached &= ~PTHREAD_CREATE_JOINABLE; + thread->detached |= PTHREAD_CREATE_DETACHED; + + UNLOCK(thread->lock); + if (joinport) { + semaphore_signal(joinport); + } } - } else { - UNLOCK(thread->lock); - return (EINVAL); + return(0); } } else { - return (ESRCH); /* Not a valid thread */ + UNLOCK(thread->lock); + return (EINVAL); } } @@ -875,18 +1379,19 @@ pthread_kill ( int sig) { int error = 0; + mach_port_t kport = MACH_PORT_NULL; if ((sig < 0) || (sig > NSIG)) return(EINVAL); - if (th && (th->sig == _PTHREAD_SIG)) { - error = __pthread_kill(pthread_mach_thread_np(th), sig); - if (error == -1) - error = errno; - return(error); - } - else - return(ESRCH); + if (_pthread_lookup_thread(th, &kport, 0) != 0) + return (ESRCH); /* Not a valid thread */ + + error = __pthread_kill(kport, sig); + + if (error == -1) + error = errno; + return(error); } /* Announce that there are pthread resources ready to be reclaimed in a */ @@ -910,7 +1415,7 @@ void _pthread_become_available(pthread_t thread, mach_port_t kernel_thread) { /* Reap the resources for available threads */ __private_extern__ -int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr) { +int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr, int conforming) { mach_port_type_t ptype; kern_return_t ret; task_t self; @@ -955,13 +1460,21 @@ int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_p } } - if (value_ptr) + + if (value_ptr) *value_ptr = th->exit_value; + if (conforming) { + if ((th->cancel_state & (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) == + (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) + *value_ptr = PTHREAD_CANCELED; + th->sig = _PTHREAD_NO_SIG; + } + if (th != &_thread) free(th); - return ESUCCESS; + return 0; } static @@ -977,7 +1490,7 @@ void _pthread_reap_threads(void) mach_port_t kernel_thread = msg.header.msgh_remote_port; pthread_t thread = msg.thread; - if (_pthread_reap_thread(thread, kernel_thread, (void **)0) == EAGAIN) + if (_pthread_reap_thread(thread, kernel_thread, (void **)0, 0) == EAGAIN) { /* not dead yet, put it back for someone else to reap, stop here */ _pthread_become_available(thread, kernel_thread); @@ -999,15 +1512,25 @@ _pthread_self() { /* * Terminate a thread. */ +int __disable_threadsignal(int); + static void _pthread_exit(pthread_t self, void *value_ptr) { struct __darwin_pthread_handler_rec *handler; kern_return_t kern_res; int thread_count; + int newstyle = self->newstyle; /* Make this thread not to receive any signals */ - syscall(331,1); + __disable_threadsignal(1); + +#if WQ_TRACE + __kdebug_trace(0x900001c, self, newstyle, 0, 0, 0); +#endif + + /* set cancel state to disable and type to deferred */ + _pthread_setcancelstate_exit(self, value_ptr, __unix_conforming); while ((handler = self->__cleanup_stack) != 0) { @@ -1016,50 +1539,84 @@ _pthread_exit(pthread_t self, void *value_ptr) } _pthread_tsd_cleanup(self); - _pthread_reap_threads(); + if (newstyle == 0) { + _pthread_reap_threads(); + + LOCK(self->lock); + self->detached |= _PTHREAD_EXITED; + + if (self->detached & PTHREAD_CREATE_JOINABLE) { + mach_port_t death = self->death; + self->exit_value = value_ptr; + UNLOCK(self->lock); + /* the joiner will need a kernel thread reference, leave ours for it */ + if (death) { + PTHREAD_MACH_CALL(semaphore_signal(death), kern_res); + if (kern_res != KERN_SUCCESS) + fprintf(stderr, + "semaphore_signal(death) failed: %s\n", + mach_error_string(kern_res)); + } + LOCK(_pthread_list_lock); + thread_count = --_pthread_count; + UNLOCK(_pthread_list_lock); + } else { + UNLOCK(self->lock); + LOCK(_pthread_list_lock); + TAILQ_REMOVE(&__pthread_head, self, plist); +#if WQ_TRACE + __kdebug_trace(0x9000010, self, 0, 0, 5, 0); +#endif + thread_count = --_pthread_count; + UNLOCK(_pthread_list_lock); + /* with no joiner, we let become available consume our cached ref */ + _pthread_become_available(self, self->kernel_thread); + } - LOCK(self->lock); - self->detached |= _PTHREAD_EXITED; + if (thread_count <= 0) + exit(0); - if (self->detached & PTHREAD_CREATE_JOINABLE) { - mach_port_t death = self->death; - self->exit_value = value_ptr; - UNLOCK(self->lock); - /* the joiner will need a kernel thread reference, leave ours for it */ - if (death) { - PTHREAD_MACH_CALL(semaphore_signal(death), kern_res); - if (kern_res != KERN_SUCCESS) - fprintf(stderr, - "semaphore_signal(death) failed: %s\n", - mach_error_string(kern_res)); - } - LOCK(_pthread_list_lock); - thread_count = --_pthread_count; - UNLOCK(_pthread_list_lock); + /* Use a new reference to terminate ourselves. Should never return. */ + PTHREAD_MACH_CALL(thread_terminate(mach_thread_self()), kern_res); + fprintf(stderr, "thread_terminate(mach_thread_self()) failed: %s\n", + mach_error_string(kern_res)); } else { - UNLOCK(self->lock); - LOCK(_pthread_list_lock); - LIST_REMOVE(self, plist); - thread_count = --_pthread_count; - UNLOCK(_pthread_list_lock); - /* with no joiner, we let become available consume our cached ref */ - _pthread_become_available(self, pthread_mach_thread_np(self)); - } + semaphore_t joinsem = SEMAPHORE_NULL; - if (thread_count <= 0) - exit(0); + if ((self->joiner_notify == NULL) && (self->detached & PTHREAD_CREATE_JOINABLE)) + joinsem = new_sem_from_pool(); + LOCK(self->lock); + self->detached |= _PTHREAD_EXITED; - /* Use a new reference to terminate ourselves. Should never return. */ - PTHREAD_MACH_CALL(thread_terminate(mach_thread_self()), kern_res); - fprintf(stderr, "thread_terminate(mach_thread_self()) failed: %s\n", - mach_error_string(kern_res)); + self->exit_value = value_ptr; + if (self->detached & PTHREAD_CREATE_JOINABLE) { + if (self->joiner_notify == NULL) { + self->joiner_notify = joinsem; + joinsem = SEMAPHORE_NULL; + } + UNLOCK(self->lock); + if (joinsem != SEMAPHORE_NULL) + restore_sem_to_pool(joinsem); + _pthread_free_pthread_onstack(self, 0, 1); + } else { + UNLOCK(self->lock); + /* with no joiner, we let become available consume our cached ref */ + if (joinsem != SEMAPHORE_NULL) + restore_sem_to_pool(joinsem); + _pthread_free_pthread_onstack(self, 1, 1); + } + } abort(); } void pthread_exit(void *value_ptr) { - _pthread_exit(pthread_self(), value_ptr); + pthread_t self = pthread_self(); + if (self->wqthread != 0) + workqueue_exit(self, self->cur_workq, self->cur_workitem); + else + _pthread_exit(self, value_ptr); } /* @@ -1070,15 +1627,24 @@ pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param) { - if (thread->sig == _PTHREAD_SIG) - { - *policy = thread->policy; - *param = thread->param; - return (ESUCCESS); - } else - { - return (ESRCH); /* Not a valid thread structure */ + int ret; + + if (thread == NULL) + return(ESRCH); + + LOCK(_pthread_list_lock); + + if ((ret = _pthread_find_thread(thread)) != 0) { + UNLOCK(_pthread_list_lock); + return(ret); } + if (policy != 0) + *policy = thread->policy; + if (param != 0) + *param = thread->param; + UNLOCK(_pthread_list_lock); + + return(0); } /* @@ -1094,10 +1660,8 @@ pthread_setschedparam(pthread_t thread, mach_msg_type_number_t count; kern_return_t ret; - if (thread->sig == _PTHREAD_SIG) + switch (policy) { - switch (policy) - { case SCHED_OTHER: bases.ts.base_priority = param->sched_priority; base = (policy_base_t)&bases.ts; @@ -1117,19 +1681,13 @@ pthread_setschedparam(pthread_t thread, break; default: return (EINVAL); - } - ret = thread_policy(pthread_mach_thread_np(thread), policy, base, count, TRUE); - if (ret != KERN_SUCCESS) - { - return (EINVAL); - } - thread->policy = policy; - thread->param = *param; - return (ESUCCESS); - } else - { - return (ESRCH); /* Not a valid thread structure */ } + ret = thread_policy(pthread_mach_thread_np(thread), policy, base, count, TRUE); + if (ret != KERN_SUCCESS) + return (EINVAL); + thread->policy = policy; + thread->param = *param; + return (0); } /* @@ -1192,6 +1750,17 @@ ur_cthread_self(void) { return self->cthread_self; } +/* + * cancellation handler for pthread once as the init routine can have a + * cancellation point. In that case we need to restore the spin unlock + */ +void +__pthread_once_cancel_handler(pthread_once_t *once_control) +{ + _spin_unlock(&once_control->lock); +} + + /* * Execute a function exactly one time in a thread-safe fashion. */ @@ -1202,11 +1771,13 @@ pthread_once(pthread_once_t *once_control, _spin_lock(&once_control->lock); if (once_control->sig == _PTHREAD_ONCE_SIG_init) { + pthread_cleanup_push(__pthread_once_cancel_handler, once_control); (*init_routine)(); + pthread_cleanup_pop(0); once_control->sig = _PTHREAD_ONCE_SIG; } _spin_unlock(&once_control->lock); - return (ESUCCESS); /* Spec defines no possible errors! */ + return (0); /* Spec defines no possible errors! */ } /* @@ -1239,21 +1810,22 @@ pthread_getconcurrency(void) int pthread_setconcurrency(int new_level) { + if (new_level < 0) + return EINVAL; pthread_concurrency = new_level; - return(ESUCCESS); + return(0); } /* * Perform package initialization - called automatically when application starts */ -static int +__private_extern__ int pthread_init(void) { pthread_attr_t *attrs; pthread_t thread; kern_return_t kr; - host_basic_info_data_t basic_info; host_priority_info_data_t priority_info; host_info_t info; host_flavor_t flavor; @@ -1261,10 +1833,10 @@ pthread_init(void) mach_msg_type_number_t count; int mib[2]; size_t len; - int numcpus; void *stackaddr; - count = HOST_PRIORITY_INFO_COUNT; + pthreadsize = round_page(sizeof (struct _pthread)); + count = HOST_PRIORITY_INFO_COUNT; info = (host_info_t)&priority_info; flavor = HOST_PRIORITY_INFO; host = mach_host_self(); @@ -1279,44 +1851,37 @@ pthread_init(void) attrs = &_pthread_attr_default; pthread_attr_init(attrs); - LIST_INIT(&__pthread_head); + TAILQ_INIT(&__pthread_head); LOCK_INIT(_pthread_list_lock); thread = &_thread; - LIST_INSERT_HEAD(&__pthread_head, thread, plist); + TAILQ_INSERT_HEAD(&__pthread_head, thread, plist); _pthread_set_self(thread); - mib[0] = CTL_KERN; - mib[1] = KERN_USRSTACK; - len = sizeof (stackaddr); - if (sysctl (mib, 2, &stackaddr, &len, NULL, 0) != 0) - stackaddr = (void *)USRSTACK; + /* In case of dyld reset the tsd keys from 1 - 10 */ + _pthread_keys_init(); + + mib[0] = CTL_KERN; + mib[1] = KERN_USRSTACK; + len = sizeof (stackaddr); + if (sysctl (mib, 2, &stackaddr, &len, NULL, 0) != 0) + stackaddr = (void *)USRSTACK; _pthread_create(thread, attrs, stackaddr, mach_thread_self()); thread->detached = PTHREAD_CREATE_JOINABLE|_PTHREAD_CREATE_PARENT; - /* See if we're on a multiprocessor and set _spin_tries if so. */ - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - len = sizeof(numcpus); - if (sysctl(mib, 2, &numcpus, &len, NULL, 0) == 0) { - if (numcpus > 1) { - _spin_tries = MP_SPIN_TRIES; - } - } else { - count = HOST_BASIC_INFO_COUNT; - info = (host_info_t)&basic_info; - flavor = HOST_BASIC_INFO; - kr = host_info(host, flavor, info, &count); - if (kr != KERN_SUCCESS) - printf("host_info failed (%d)\n", kr); - else { - if (basic_info.avail_cpus > 1) - _spin_tries = MP_SPIN_TRIES; - } - } + _init_cpu_capabilities(); + if (_NumCPUs() > 1) + _spin_tries = MP_SPIN_TRIES; mach_port_deallocate(mach_task_self(), host); - _init_cpu_capabilities(); +#if defined(__ppc__) + IF_ROSETTA() { + __oldstyle = 1; + } +#endif +#if defined(__arm__) + __oldstyle = 1; +#endif #if defined(_OBJC_PAGE_BASE_ADDRESS) { @@ -1333,6 +1898,13 @@ pthread_init(void) #endif mig_init(1); /* enable multi-threaded mig interfaces */ + if (__oldstyle == 0) { +#if defined(__i386__) || defined(__x86_64__) + __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread))); +#else + __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread))); +#endif + } return 0; } @@ -1342,8 +1914,9 @@ int sched_yield(void) return 0; } -/* This is the "magic" that gets the initialization routine called when the application starts */ -int (*_cthread_init_routine)(void) = pthread_init; +/* 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; /* Get a semaphore from the pool, growing it if necessary */ @@ -1387,220 +1960,1368 @@ __private_extern__ void _pthread_fork_child(pthread_t p) { /* No need to hold the pthread_list_lock as no one other than this * thread is present at this time */ - LIST_INIT(&__pthread_head); + TAILQ_INIT(&__pthread_head); LOCK_INIT(_pthread_list_lock); - LIST_INSERT_HEAD(&__pthread_head, p, plist); + TAILQ_INSERT_HEAD(&__pthread_head, p, plist); _pthread_count = 1; } -#else /* !BUILDING_VARIANT ] [ */ -extern int __unix_conforming; -extern pthread_lock_t _pthread_list_lock; -extern void _pthread_testcancel(pthread_t thread, int isconforming); -extern int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr); - -#endif /* !BUILDING_VARIANT ] */ - -#if __DARWIN_UNIX03 - -static void __posix_join_cleanup(void *arg) +/* + * Query/update the cancelability 'state' of a thread + */ +int +_pthread_setcancelstate_internal(int state, int *oldstate, int conforming) { - pthread_t thread = (pthread_t)arg; - int already_exited, res; - void * dummy; - semaphore_t death; - - LOCK(thread->lock); - death = thread->death; - already_exited = (thread->detached & _PTHREAD_EXITED); + pthread_t self = pthread_self(); - if (!already_exited){ - thread->joiner = (struct _pthread *)NULL; - UNLOCK(thread->lock); - restore_sem_to_pool(death); - } else { - UNLOCK(thread->lock); - while ((res = _pthread_reap_thread(thread, - thread->kernel_thread, - &dummy)) == EAGAIN) - { - sched_yield(); - } - restore_sem_to_pool(death); + switch (state) { + case PTHREAD_CANCEL_ENABLE: + if (conforming) + __pthread_canceled(1); + break; + case PTHREAD_CANCEL_DISABLE: + if (conforming) + __pthread_canceled(2); + break; + default: + return EINVAL; } -} - -#endif /* __DARWIN_UNIX03 */ + self = pthread_self(); + LOCK(self->lock); + if (oldstate) + *oldstate = self->cancel_state & _PTHREAD_CANCEL_STATE_MASK; + self->cancel_state &= ~_PTHREAD_CANCEL_STATE_MASK; + self->cancel_state |= state; + UNLOCK(self->lock); + if (!conforming) + _pthread_testcancel(self, 0); /* See if we need to 'die' now... */ + return (0); +} -/* - * Wait for a thread to terminate and obtain its exit value. - */ -int -pthread_join(pthread_t thread, - void **value_ptr) +/* When a thread exits set the cancellation state to DISABLE and DEFERRED */ +static void +_pthread_setcancelstate_exit(pthread_t self, void * value_ptr, int conforming) { - kern_return_t kern_res; - int res = ESUCCESS; - -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; -#endif /* __DARWIN_UNIX03 */ - - if (thread->sig == _PTHREAD_SIG) - { - semaphore_t death = new_sem_from_pool(); /* in case we need it */ + LOCK(self->lock); + self->cancel_state &= ~(_PTHREAD_CANCEL_STATE_MASK | _PTHREAD_CANCEL_TYPE_MASK); + self->cancel_state |= (PTHREAD_CANCEL_DISABLE | PTHREAD_CANCEL_DEFERRED); + if ((value_ptr == PTHREAD_CANCELED)) { +// 4597450: begin + self->detached |= _PTHREAD_WASCANCEL; +// 4597450: end + } + UNLOCK(self->lock); +} - LOCK(thread->lock); - if ((thread->detached & PTHREAD_CREATE_JOINABLE) && - thread->death == SEMAPHORE_NULL) - { - pthread_t self = pthread_self(); +int +_pthread_join_cleanup(pthread_t thread, void ** value_ptr, int conforming) +{ + kern_return_t res; + int detached = 0, ret; - assert(thread->joiner == NULL); - if (thread != self && (self == NULL || self->joiner != thread)) - { - int already_exited = (thread->detached & _PTHREAD_EXITED); +#if WQ_TRACE + __kdebug_trace(0x9000028, thread, 0, 0, 1, 0); +#endif + /* The scenario where the joiner was waiting for the thread and + * the pthread detach happened on that thread. Then the semaphore + * will trigger but by the time joiner runs, the target thread could be + * freed. So we need to make sure that the thread is still in the list + * and is joinable before we continue with the join. + */ + LOCK(_pthread_list_lock); + if ((ret = _pthread_find_thread(thread)) != 0) { + UNLOCK(_pthread_list_lock); + /* returns ESRCH */ + return(ret); + } + if ((thread->detached & PTHREAD_CREATE_JOINABLE) == 0) { + /* the thread might be a detached thread */ + UNLOCK(_pthread_list_lock); + return(ESRCH); - thread->death = death; - thread->joiner = self; - UNLOCK(thread->lock); + } + /* It is still a joinable thread and needs to be reaped */ + TAILQ_REMOVE(&__pthread_head, thread, plist); +#if WQ_TRACE + __kdebug_trace(0x9000010, thread, 0, 0, 3, 0); +#endif + UNLOCK(_pthread_list_lock); - if (!already_exited) - { -#if __DARWIN_UNIX03 - /* Wait for it to signal... */ - pthread_cleanup_push(__posix_join_cleanup, (void *)thread); - do { - res = __semwait_signal(death, 0, 0, 0, 0, 0); - } while ((res < 0) && (errno == EINTR)); - pthread_cleanup_pop(0); + if (value_ptr) + *value_ptr = thread->exit_value; + if (conforming) { + if ((thread->cancel_state & (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) == + (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) { + *value_ptr = PTHREAD_CANCELED; + } + } + if (thread->reply_port != MACH_PORT_NULL) { + res = mach_port_mod_refs(mach_task_self(), thread->reply_port, MACH_PORT_RIGHT_RECEIVE, -1); + if (res != KERN_SUCCESS) + fprintf(stderr,"mach_port_mod_refs(reply_port) failed: %s\n",mach_error_string(res)); + thread->reply_port = MACH_PORT_NULL; + } + if (thread->freeStackOnExit) { + thread->sig = _PTHREAD_NO_SIG; +#if WQ_TRACE + __kdebug_trace(0x9000028, thread, 0, 0, 2, 0); +#endif + vm_deallocate(mach_task_self(), thread, pthreadsize); + } else { + thread->sig = _PTHREAD_NO_SIG; +#if WQ_TRACE + __kdebug_trace(0x9000028, thread, 0, 0, 3, 0); +#endif + free(thread); + } + return(0); +} -#else /* __DARWIN_UNIX03 */ - /* Wait for it to signal... */ - do { - PTHREAD_MACH_CALL(semaphore_wait(death), kern_res); - } while (kern_res != KERN_SUCCESS); -#endif /* __DARWIN_UNIX03 */ - } -#if __DARWIN_UNIX03 - else { - if ((thread->cancel_state & (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) == (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) - res = PTHREAD_CANCELED; - } -#endif /* __DARWIN_UNIX03 */ +/* ALWAYS called with list lock and return with list lock */ +int +_pthread_find_thread(pthread_t thread) +{ + pthread_t p; - LOCK(_pthread_list_lock); - LIST_REMOVE(thread, plist); +loop: + TAILQ_FOREACH(p, &__pthread_head, plist) { + if (p == thread) { + if (thread->kernel_thread == MACH_PORT_NULL) { UNLOCK(_pthread_list_lock); - /* ... and wait for it to really be dead */ - while ((res = _pthread_reap_thread(thread, - thread->kernel_thread, - value_ptr)) == EAGAIN) - { - sched_yield(); - } - } else { - UNLOCK(thread->lock); - res = EDEADLK; - } - } else { - UNLOCK(thread->lock); - res = EINVAL; + sched_yield(); + LOCK(_pthread_list_lock); + goto loop; + } + return(0); } - restore_sem_to_pool(death); - return res; } - return ESRCH; + return(ESRCH); } -/* - * Cancel a thread - */ int -pthread_cancel(pthread_t thread) +_pthread_lookup_thread(pthread_t thread, mach_port_t * portp, int only_joinable) { -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; -#endif /* __DARWIN_UNIX03 */ + mach_port_t kport; + int ret = 0; + + if (thread == NULL) + return(ESRCH); + + LOCK(_pthread_list_lock); + + if ((ret = _pthread_find_thread(thread)) != 0) { + UNLOCK(_pthread_list_lock); + return(ret); + } + if ((only_joinable != 0) && ((thread->detached & PTHREAD_CREATE_DETACHED) != 0)) { + UNLOCK(_pthread_list_lock); + return(EINVAL); + } + kport = thread->kernel_thread; + UNLOCK(_pthread_list_lock); + if (portp != NULL) + *portp = kport; + return(0); +} - if (thread->sig == _PTHREAD_SIG) +/* XXXXXXXXXXXXX Pthread Workqueue Attributes XXXXXXXXXXXXXXXXXX */ +int +pthread_workqueue_attr_init_np(pthread_workqueue_attr_t * attrp) +{ + attrp->stacksize = DEFAULT_STACK_SIZE; + attrp->istimeshare = 1; + attrp->importance = 0; + attrp->affinity = 0; + attrp->queueprio = WORK_QUEUE_NORMALIZER; + attrp->sig = PTHEAD_WRKQUEUE_ATTR_SIG; + return(0); +} + +int +pthread_workqueue_attr_destroy_np(pthread_workqueue_attr_t * attr) +{ + if (attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG) { -#if __DARWIN_UNIX03 - int state; - LOCK(thread->lock); - state = thread->cancel_state |= _PTHREAD_CANCEL_PENDING; - UNLOCK(thread->lock); - if (state & PTHREAD_CANCEL_ENABLE) - __pthread_markcancel(thread->kernel_thread); -#else /* __DARWIN_UNIX03 */ - thread->cancel_state |= _PTHREAD_CANCEL_PENDING; -#endif /* __DARWIN_UNIX03 */ - return (ESUCCESS); + return (0); } else { - return (ESRCH); + return (EINVAL); /* Not an attribute structure! */ } } -void -pthread_testcancel(void) +#ifdef NOTYET /* [ */ +int +pthread_workqueue_attr_getstacksize_np(const pthread_workqueue_attr_t * attr, size_t * stacksizep) { - pthread_t self = pthread_self(); + if (attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG) { + *stacksizep = attr->stacksize; + return (0); + } else { + return (EINVAL); /* Not an attribute structure! */ + } +} + +int +pthread_workqueue_attr_setstacksize_np(pthread_workqueue_attr_t * attr, size_t stacksize) +{ + if ((attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG) && ((stacksize % vm_page_size) == 0) && (stacksize >= PTHREAD_STACK_MIN)) { + attr->stacksize = stacksize; + return (0); + } else { + return (EINVAL); /* Not an attribute structure! */ + } +} -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; - _pthread_testcancel(self, 1); -#else /* __DARWIN_UNIX03 */ - _pthread_testcancel(self, 0); -#endif /* __DARWIN_UNIX03 */ +int +pthread_workqueue_attr_getthreadtimeshare_np(const pthread_workqueue_attr_t * attr, int * istimesahrep) +{ + if (attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG) { + *istimesahrep = attr->istimeshare; + return (0); + } else { + return (EINVAL); /* Not an attribute structure! */ + } } -/* - * Query/update the cancelability 'state' of a thread - */ -int -pthread_setcancelstate(int state, int *oldstate) + +int +pthread_workqueue_attr_settthreadtimeshare_np(pthread_workqueue_attr_t * attr, int istimeshare) { - pthread_t self = pthread_self(); + if (attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG) { + if (istimeshare != 0) + attr->istimeshare = istimeshare; + else + attr->istimeshare = 0; + return (0); + } else { + return (EINVAL); /* Not an attribute structure! */ + } +} -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; -#endif /* __DARWIN_UNIX03 */ +int +pthread_workqueue_attr_getthreadimportance_np(const pthread_workqueue_attr_t * attr, int * importancep) +{ + if (attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG) { + *importancep = attr->importance; + return (0); + } else { + return (EINVAL); /* Not an attribute structure! */ + } +} - switch (state) { - case PTHREAD_CANCEL_ENABLE: -#if __DARWIN_UNIX03 - __pthread_canceled(1); -#endif /* __DARWIN_UNIX03 */ +int +pthread_workqueue_attr_settthreadimportance_np(pthread_workqueue_attr_t * attr, int importance) +{ + if (attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG){ + attr->importance = importance; + return (0); + } else { + return (EINVAL); /* Not an attribute structure! */ + } +} + +int +pthread_workqueue_attr_getthreadaffinity_np(const pthread_workqueue_attr_t * attr, int * affinityp) +{ + if (attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG) { + *affinityp = attr->affinity; + return (0); + } else { + return (EINVAL); /* Not an attribute structure! */ + } +} + +int +pthread_workqueue_attr_settthreadaffinity_np(pthread_workqueue_attr_t * attr, int affinity) +{ + if (attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG){ + attr->affinity = affinity; + return (0); + } else { + return (EINVAL); /* Not an attribute structure! */ + } +} + +#endif /* NOTYET ] */ + +int +pthread_workqueue_attr_getqueuepriority_np(const pthread_workqueue_attr_t * attr, int * qpriop) +{ + if (attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG) { + *qpriop = (attr->queueprio - WORK_QUEUE_NORMALIZER); + return (0); + } else { + return (EINVAL); /* Not an attribute structure! */ + } +} + +int +pthread_workqueue_attr_setqueuepriority_np(pthread_workqueue_attr_t * attr, int qprio) +{ + /* only -2 to +2 is valid */ + if ((attr->sig == PTHEAD_WRKQUEUE_ATTR_SIG) && (qprio <= 2) && (qprio >= -2)) { + attr->queueprio = (qprio + WORK_QUEUE_NORMALIZER); + return (0); + } else { + return (EINVAL); /* Not an attribute structure! */ + } +} + +/* XXXXXXXXXXXXX Pthread Workqueue support routines XXXXXXXXXXXXXXXXXX */ + +static void +workqueue_list_lock() +{ + OSSpinLockLock(&__workqueue_list_lock); +} + +static void +workqueue_list_unlock() +{ + OSSpinLockUnlock(&__workqueue_list_lock); +} + +int +pthread_workqueue_init_np() +{ + int ret; + + workqueue_list_lock(); + ret =_pthread_work_internal_init(); + workqueue_list_unlock(); + + return(ret); +} + +static int +_pthread_work_internal_init(void) +{ + int i, error; + pthread_workqueue_head_t headp; + pthread_workitem_t witemp; + pthread_workqueue_t wq; + + if (kernel_workq_setup == 0) { +#if defined(__i386__) || defined(__x86_64__) + __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread))); +#else + __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread))); +#endif + + _pthread_wq_attr_default.stacksize = DEFAULT_STACK_SIZE; + _pthread_wq_attr_default.istimeshare = 1; + _pthread_wq_attr_default.importance = 0; + _pthread_wq_attr_default.affinity = 0; + _pthread_wq_attr_default.queueprio = WORK_QUEUE_NORMALIZER; + _pthread_wq_attr_default.sig = PTHEAD_WRKQUEUE_ATTR_SIG; + + for( i = 0; i< WQ_NUM_PRIO_QS; 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); + } + 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++) { + TAILQ_INSERT_TAIL(&__pthread_workqueue_pool_head, &wq[i], wq_list); + } + + if (error = __workq_open()) { + TAILQ_INIT(&__pthread_workitem_pool_head); + TAILQ_INIT(&__pthread_workqueue_pool_head); + free(witemp); + free(wq); + return(ENOMEM); + } + kernel_workq_setup = 1; + } + return(0); +} + + +/* This routine is called with list lock held */ +static pthread_workitem_t +alloc_workitem(void) +{ + pthread_workitem_t witem; + + if (TAILQ_EMPTY(&__pthread_workitem_pool_head)) { + workqueue_list_unlock(); + witem = malloc(sizeof(struct _pthread_workitem)); + workqueue_list_lock(); + } else { + witem = TAILQ_FIRST(&__pthread_workitem_pool_head); + TAILQ_REMOVE(&__pthread_workitem_pool_head, witem, item_entry); + } + return(witem); +} + +/* This routine is called with list lock held */ +static void +free_workitem(pthread_workitem_t witem) +{ + TAILQ_INSERT_TAIL(&__pthread_workitem_pool_head, witem, item_entry); +} + +/* This routine is called with list lock held */ +static pthread_workqueue_t +alloc_workqueue(void) +{ + pthread_workqueue_t wq; + + if (TAILQ_EMPTY(&__pthread_workqueue_pool_head)) { + workqueue_list_unlock(); + wq = malloc(sizeof(struct _pthread_workqueue)); + workqueue_list_lock(); + } else { + wq = TAILQ_FIRST(&__pthread_workqueue_pool_head); + TAILQ_REMOVE(&__pthread_workqueue_pool_head, wq, wq_list); + } + user_workq_count++; + return(wq); +} + +/* This routine is called with list lock held */ +static void +free_workqueue(pthread_workqueue_t wq) +{ + user_workq_count--; + TAILQ_INSERT_TAIL(&__pthread_workqueue_pool_head, wq, wq_list); +} + +static void +_pthread_workq_init(pthread_workqueue_t wq, const pthread_workqueue_attr_t * attr) +{ + bzero(wq, sizeof(struct _pthread_workqueue)); + if (attr != NULL) { + wq->stacksize = attr->stacksize; + wq->istimeshare = attr->istimeshare; + wq->importance = attr->importance; + wq->affinity = attr->affinity; + wq->queueprio = attr->queueprio; + } else { + wq->stacksize = DEFAULT_STACK_SIZE; + wq->istimeshare = 1; + wq->importance = 0; + wq->affinity = 0; + wq->queueprio = WORK_QUEUE_NORMALIZER; + } + LOCK_INIT(wq->lock); + wq->flags = 0; + TAILQ_INIT(&wq->item_listhead); + TAILQ_INIT(&wq->item_kernhead); + wq->wq_list.tqe_next = 0; + wq->wq_list.tqe_prev = 0; + wq->sig = PTHEAD_WRKQUEUE_SIG; + wq->headp = __pthread_wq_head_tbl[wq->queueprio]; +} + +int +valid_workq(pthread_workqueue_t workq) +{ + if (workq->sig == PTHEAD_WRKQUEUE_SIG) + return(1); + else + return(0); +} + + +/* called with list lock */ +static void +pick_nextworkqueue_droplock() +{ + int i, curwqprio, val, found; + pthread_workqueue_head_t headp; + pthread_workqueue_t workq; + pthread_workqueue_t nworkq = NULL; + +loop: + while (kernel_workq_count < KERNEL_WORKQ_ELEM_MAX) { + found = 0; + for (i = 0; i < WQ_NUM_PRIO_QS; i++) { + wqreadyprio = i; /* because there is nothing else higher to run */ + headp = __pthread_wq_head_tbl[i]; + + if (TAILQ_EMPTY(&headp->wqhead)) + continue; + workq = headp->next_workq; + if (workq == NULL) + workq = TAILQ_FIRST(&headp->wqhead); + curwqprio = workq->queueprio; + nworkq = workq; /* starting pt */ + while (kernel_workq_count < KERNEL_WORKQ_ELEM_MAX) { + headp->next_workq = TAILQ_NEXT(workq, wq_list); + if (headp->next_workq == NULL) + headp->next_workq = TAILQ_FIRST(&headp->wqhead); + val = post_nextworkitem(workq); + + if (val != 0) { + /* things could have changed so reasses */ + /* If kernel queue is full , skip */ + if (kernel_workq_count >= KERNEL_WORKQ_ELEM_MAX) + break; + /* If anything with higher prio arrived, then reevaluate */ + if (wqreadyprio < curwqprio) + goto loop; /* we need re evaluate again */ + /* we can post some more work items */ + found = 1; + } + + /* cannot use workq here as it could be freed */ + if (TAILQ_EMPTY(&headp->wqhead)) + break; + /* if we found nothing to run and only one workqueue in the list, skip */ + if ((val == 0) && (workq == headp->next_workq)) + break; + workq = headp->next_workq; + if (workq == NULL) + workq = TAILQ_FIRST(&headp->wqhead); + if (val != 0) + nworkq = workq; + /* if we found nothing to run and back to workq where we started */ + if ((val == 0) && (workq == nworkq)) + break; + } + if (kernel_workq_count >= KERNEL_WORKQ_ELEM_MAX) + break; + } + /* nothing found to run? */ + if (found == 0) break; - case PTHREAD_CANCEL_DISABLE: + } + workqueue_list_unlock(); +} + +static int +post_nextworkitem(pthread_workqueue_t workq) +{ + int error; + pthread_workitem_t witem; + pthread_workqueue_head_t headp; + void (*func)(pthread_workqueue_t, void *); + + if ((workq->flags & PTHREAD_WORKQ_SUSPEND) == PTHREAD_WORKQ_SUSPEND) { + return(0); + } + if (TAILQ_EMPTY(&workq->item_listhead)) { + return(0); + } + witem = TAILQ_FIRST(&workq->item_listhead); + headp = workq->headp; + if ((witem->flags & PTH_WQITEM_BARRIER) == PTH_WQITEM_BARRIER) { + + if ((witem->flags & PTH_WQITEM_APPLIED) != 0) { + return(0); + } + /* Also barrier when nothing is there needs to be handled */ + /* Nothing to wait for */ + if (workq->kq_count != 0) { + witem->flags |= PTH_WQITEM_APPLIED; + workq->flags |= PTHREAD_WORKQ_BARRIER_ON; + workq->barrier_count = workq->kq_count; +#if WQ_TRACE + __kdebug_trace(0x9000064, 1, workq->barrier_count, 0, 0, 0); +#endif + return(1); + } else { +#if WQ_TRACE + __kdebug_trace(0x9000064, 2, workq->barrier_count, 0, 0, 0); +#endif + if (witem->func != NULL) { + workqueue_list_unlock(); + func = witem->func; + (*func)(workq, witem->func_arg); + workqueue_list_lock(); + } + TAILQ_REMOVE(&workq->item_listhead, witem, item_entry); + witem->flags = 0; + free_workitem(witem); + return(1); + } + } else if ((witem->flags & PTH_WQITEM_DESTROY) == PTH_WQITEM_DESTROY) { +#if WQ_TRACE + __kdebug_trace(0x9000068, 1, workq->kq_count, 0, 0, 0); +#endif + if ((witem->flags & PTH_WQITEM_APPLIED) != 0) { + return(0); + } + witem->flags |= PTH_WQITEM_APPLIED; + workq->flags |= (PTHREAD_WORKQ_BARRIER_ON | PTHREAD_WORKQ_TERM_ON); + workq->barrier_count = workq->kq_count; + workq->term_callback = witem->func; + workq->term_callarg = witem->func_arg; + TAILQ_REMOVE(&workq->item_listhead, witem, item_entry); + if ((TAILQ_EMPTY(&workq->item_listhead)) && (workq->kq_count == 0)) { + if (!(TAILQ_EMPTY(&workq->item_kernhead))) { +#if WQ_TRACE + __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 + __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 1, 0); +#endif + headp = __pthread_wq_head_tbl[workq->queueprio]; + if (headp->next_workq == workq) { + headp->next_workq = TAILQ_NEXT(workq, wq_list); + if (headp->next_workq == NULL) { + headp->next_workq = TAILQ_FIRST(&headp->wqhead); + if (headp->next_workq == workq) + headp->next_workq = NULL; + } + } + workq->sig = 0; + TAILQ_REMOVE(&headp->wqhead, workq, wq_list); + if (workq->term_callback != NULL) { + workqueue_list_unlock(); + (*workq->term_callback)(workq, workq->term_callarg); + workqueue_list_lock(); + } + free_workqueue(workq); + return(1); + } else + TAILQ_INSERT_HEAD(&workq->item_listhead, witem, item_entry); +#if WQ_TRACE + __kdebug_trace(0x9000068, 2, workq->barrier_count, 0, 0, 0); +#endif + return(1); + } else { +#if WQ_TRACE + __kdebug_trace(0x9000060, witem, workq, witem->func_arg, 0xfff, 0); +#endif + TAILQ_REMOVE(&workq->item_listhead, witem, item_entry); + TAILQ_INSERT_TAIL(&workq->item_kernhead, witem, item_entry); + if ((witem->flags & PTH_WQITEM_KERN_COUNT) == 0) { + workq->kq_count++; + witem->flags |= PTH_WQITEM_KERN_COUNT; + } + OSAtomicIncrement32(&kernel_workq_count); + workqueue_list_unlock(); + if (( error =__workq_ops(WQOPS_QUEUE_ADD, witem, 0)) == -1) { + OSAtomicDecrement32(&kernel_workq_count); + workqueue_list_lock(); +#if WQ_TRACE + __kdebug_trace(0x900007c, witem, workq, witem->func_arg, workq->kq_count, 0); +#endif + TAILQ_REMOVE(&workq->item_kernhead, witem, item_entry); + TAILQ_INSERT_HEAD(&workq->item_listhead, witem, item_entry); + if ((workq->flags & (PTHREAD_WORKQ_BARRIER_ON | PTHREAD_WORKQ_TERM_ON)) != 0) + workq->flags |= PTHREAD_WORKQ_REQUEUED; + } else + workqueue_list_lock(); +#if WQ_TRACE + __kdebug_trace(0x9000060, witem, workq, witem->func_arg, workq->kq_count, 0); +#endif + return(1); + } + /* noone should come here */ +#if 1 + printf("error in logic for next workitem\n"); + abort(); +#endif + return(0); +} + +void +_pthread_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthread_workitem_t item, int reuse) +{ + int ret; + pthread_attr_t *attrs = &_pthread_attr_default; + pthread_workqueue_t workq; + pthread_t pself; + + + workq = item->workq; + if (reuse == 0) { + /* reuse is set to 0, when a thread is newly created to run a workitem */ + _pthread_struct_init(self, attrs, stackaddr, DEFAULT_STACK_SIZE, 1, 1); + self->wqthread = 1; + self->parentcheck = 1; + + /* These are not joinable threads */ + self->detached &= ~PTHREAD_CREATE_JOINABLE; + self->detached |= PTHREAD_CREATE_DETACHED; +#if defined(__i386__) || defined(__x86_64__) + _pthread_set_self(self); +#endif +#if WQ_TRACE + __kdebug_trace(0x9000050, self, item, item->func_arg, 0, 0); +#endif + self->kernel_thread = kport; + self->fun = item->func; + self->arg = item->func_arg; + /* Add to the pthread list */ + LOCK(_pthread_list_lock); + TAILQ_INSERT_TAIL(&__pthread_head, self, plist); +#if WQ_TRACE + __kdebug_trace(0x900000c, self, 0, 0, 10, 0); +#endif + _pthread_count++; + UNLOCK(_pthread_list_lock); + } else { + /* reuse is set to 1, when a thread is resued to run another work item */ +#if WQ_TRACE + __kdebug_trace(0x9000054, self, item, item->func_arg, 0, 0); +#endif + /* reset all tsd from 1 to KEYS_MAX */ + _pthread_tsd_reinit(self); + + self->fun = item->func; + self->arg = item->func_arg; + } + +#if WQ_DEBUG + if (reuse == 0) { + pself = pthread_self(); + if (self != pself) { +#if WQ_TRACE + __kdebug_trace(0x9000078, self, pself, item->func_arg, 0, 0); +#endif + printf("pthread_self not set: pself %p, passed in %p\n", pself, self); + _pthread_set_self(self); + pself = pthread_self(); + if (self != pself) + printf("(2)pthread_self not set: pself %p, passed in %p\n", pself, self); + pself = self; + } + } else { + pself = pthread_self(); + if (self != pself) { + printf("(3)pthread_self not set in reuse: pself %p, passed in %p\n", pself, self); + abort(); + } + } +#endif /* WQ_DEBUG */ + + self->cur_workq = workq; + self->cur_workitem = item; + OSAtomicDecrement32(&kernel_workq_count); + + ret = (*self->fun)(self->arg); + + workqueue_exit(self, workq, item); + +} + +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 *); + + workqueue_list_lock(); + + TAILQ_REMOVE(&workq->item_kernhead, item, item_entry); + workq->kq_count--; +#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) { + workq->barrier_count--; +#if WQ_TRACE + __kdebug_trace(0x9000084, self, workq->barrier_count, workq->kq_count, 1, 0); +#endif + if (workq->barrier_count <= 0 ) { + /* Need to remove barrier item from the list */ + baritem = TAILQ_FIRST(&workq->item_listhead); +#if WQ_DEBUG + if ((baritem->flags & (PTH_WQITEM_BARRIER | PTH_WQITEM_DESTROY| PTH_WQITEM_APPLIED)) == 0) + printf("Incorect bar item being removed in barrier processing\n"); +#endif /* WQ_DEBUG */ + /* if the front item is a barrier and call back is registered, run that */ + if (((baritem->flags & PTH_WQITEM_BARRIER) == PTH_WQITEM_BARRIER) && (baritem->func != NULL)) { + workqueue_list_unlock(); + func = baritem->func; + (*func)(workq, baritem->func_arg); + workqueue_list_lock(); + } + TAILQ_REMOVE(&workq->item_listhead, baritem, item_entry); + baritem->flags = 0; + free_workitem(baritem); + workq->flags &= ~PTHREAD_WORKQ_BARRIER_ON; +#if WQ_TRACE + __kdebug_trace(0x9000058, self, item, item->func_arg, 0, 0); +#endif + if ((workq->flags & PTHREAD_WORKQ_TERM_ON) != 0) { + headp = __pthread_wq_head_tbl[workq->queueprio]; + workq->flags |= PTHREAD_WORKQ_DESTROYED; +#if WQ_TRACE + __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 2, 0); +#endif + if (headp->next_workq == workq) { + headp->next_workq = TAILQ_NEXT(workq, wq_list); + if (headp->next_workq == NULL) { + headp->next_workq = TAILQ_FIRST(&headp->wqhead); + if (headp->next_workq == workq) + headp->next_workq = NULL; + } + } + TAILQ_REMOVE(&headp->wqhead, workq, wq_list); + workq->sig = 0; + if (workq->term_callback != NULL) { + workqueue_list_unlock(); + (*workq->term_callback)(workq, workq->term_callarg); + workqueue_list_lock(); + } + free_workqueue(workq); + } else { + /* if there are higher prio schedulabel item reset to wqreadyprio */ + if ((workq->queueprio < wqreadyprio) && (!(TAILQ_EMPTY(&workq->item_listhead)))) + wqreadyprio = workq->queueprio; + } + } + } +#if WQ_TRACE + else { + __kdebug_trace(0x9000070, self, 2, item->func_arg, workq->barrier_count, 0); + } + + __kdebug_trace(0x900005c, self, item, 0, 0, 0); +#endif + pick_nextworkqueue_droplock(); + _pthread_workq_return(self); +} + +static void +_pthread_workq_return(pthread_t self) +{ + struct __darwin_pthread_handler_rec *handler; + int value = 0; + int * value_ptr=&value; + + /* set cancel state to disable and type to deferred */ + _pthread_setcancelstate_exit(self, value_ptr, __unix_conforming); + + /* Make this thread not to receive any signals */ + __disable_threadsignal(1); + + while ((handler = self->__cleanup_stack) != 0) + { + (handler->__routine)(handler->__arg); + self->__cleanup_stack = handler->__next; + } + _pthread_tsd_cleanup(self); + + __workq_ops(WQOPS_THREAD_RETURN, NULL, 0); + + /* This is the way to terminate the thread */ + _pthread_exit(self, NULL); +} + + +/* returns 0 if it handles it, otherwise 1 */ +static int +handle_removeitem(pthread_workqueue_t workq, pthread_workitem_t item) +{ + pthread_workitem_t baritem; + pthread_workqueue_head_t headp; + void (*func)(pthread_workqueue_t, void *); + + if ((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == PTHREAD_WORKQ_BARRIER_ON) { + workq->barrier_count--; + if (workq->barrier_count <= 0 ) { + /* Need to remove barrier item from the list */ + baritem = TAILQ_FIRST(&workq->item_listhead); +#if WQ_DEBUG + if ((baritem->flags & (PTH_WQITEM_BARRIER | PTH_WQITEM_DESTROY| PTH_WQITEM_APPLIED)) == 0) + printf("Incorect bar item being removed in barrier processing\n"); +#endif /* WQ_DEBUG */ + /* if the front item is a barrier and call back is registered, run that */ + if (((baritem->flags & PTH_WQITEM_BARRIER) == PTH_WQITEM_BARRIER) + && (baritem->func != NULL)) { + workqueue_list_unlock(); + func = baritem->func; + (*func)(workq, baritem->func_arg); + workqueue_list_lock(); + } + TAILQ_REMOVE(&workq->item_listhead, baritem, item_entry); + baritem->flags = 0; + free_workitem(baritem); + item->flags = 0; + free_workitem(item); + workq->flags &= ~PTHREAD_WORKQ_BARRIER_ON; +#if WQ_TRACE + __kdebug_trace(0x9000058, pthread_self(), item, item->func_arg, 0, 0); +#endif + if ((workq->flags & PTHREAD_WORKQ_TERM_ON) != 0) { + headp = __pthread_wq_head_tbl[workq->queueprio]; + workq->flags |= PTHREAD_WORKQ_DESTROYED; +#if WQ_TRACE + __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 2, 0); +#endif + if (headp->next_workq == workq) { + headp->next_workq = TAILQ_NEXT(workq, wq_list); + if (headp->next_workq == NULL) { + headp->next_workq = TAILQ_FIRST(&headp->wqhead); + if (headp->next_workq == workq) + headp->next_workq = NULL; + } + } + TAILQ_REMOVE(&headp->wqhead, workq, wq_list); + workq->sig = 0; + if (workq->term_callback != NULL) { + workqueue_list_unlock(); + (*workq->term_callback)(workq, workq->term_callarg); + workqueue_list_lock(); + } + free_workqueue(workq); + pick_nextworkqueue_droplock(); + return(0); + } else { + /* if there are higher prio schedulabel item reset to wqreadyprio */ + if ((workq->queueprio < wqreadyprio) && (!(TAILQ_EMPTY(&workq->item_listhead)))) + wqreadyprio = workq->queueprio; + free_workitem(item); + pick_nextworkqueue_droplock(); + return(0); + } + } + } + return(1); +} +/* XXXXXXXXXXXXX Pthread Workqueue functions XXXXXXXXXXXXXXXXXX */ + +int +pthread_workqueue_create_np(pthread_workqueue_t * workqp, const pthread_workqueue_attr_t * attr) +{ + pthread_workqueue_t wq; + pthread_workqueue_head_t headp; + + if ((attr != NULL) && (attr->sig != PTHEAD_WRKQUEUE_ATTR_SIG)) { + return(EINVAL); + } + + if (__is_threaded == 0) + __is_threaded = 1; + + workqueue_list_lock(); + if (kernel_workq_setup == 0) { + int ret = _pthread_work_internal_init(); + if (ret != 0) { + workqueue_list_unlock(); + return(ret); + } + } + + wq = alloc_workqueue(); + + _pthread_workq_init(wq, attr); + + headp = __pthread_wq_head_tbl[wq->queueprio]; + TAILQ_INSERT_TAIL(&headp->wqhead, wq, wq_list); + if (headp->next_workq == NULL) { + headp->next_workq = TAILQ_FIRST(&headp->wqhead); + } + + workqueue_list_unlock(); + + *workqp = wq; + + return(0); +} + +int +pthread_workqueue_destroy_np(pthread_workqueue_t workq, void (* callback_func)(pthread_workqueue_t, void *), void * callback_arg) +{ + pthread_workitem_t witem; + pthread_workqueue_head_t headp; + + if (valid_workq(workq) == 0) { + return(EINVAL); + } + + workqueue_list_lock(); + + /* + * Allocate the workitem here as it can drop the lock. + * Also we can evaluate the workqueue state only once. + */ + witem = alloc_workitem(); + witem->item_entry.tqe_next = 0; + witem->item_entry.tqe_prev = 0; + witem->func = callback_func; + witem->func_arg = callback_arg; + witem->flags = PTH_WQITEM_DESTROY; + + if ((workq->flags & (PTHREAD_WORKQ_IN_TERMINATE | PTHREAD_WORKQ_TERM_ON | PTHREAD_WORKQ_DESTROYED)) == 0) { + workq->flags |= PTHREAD_WORKQ_IN_TERMINATE; + /* If nothing queued or running, destroy now */ + if ((TAILQ_EMPTY(&workq->item_listhead)) && (TAILQ_EMPTY(&workq->item_kernhead))) { + workq->flags |= (PTHREAD_WORKQ_TERM_ON | PTHREAD_WORKQ_DESTROYED); + headp = __pthread_wq_head_tbl[workq->queueprio]; + workq->term_callback = callback_func; + workq->term_callarg = callback_arg; + if (headp->next_workq == workq) { + headp->next_workq = TAILQ_NEXT(workq, wq_list); + if (headp->next_workq == NULL) { + headp->next_workq = TAILQ_FIRST(&headp->wqhead); + if (headp->next_workq == workq) + headp->next_workq = NULL; + } + } + TAILQ_REMOVE(&headp->wqhead, workq, wq_list); + workq->sig = 0; + free_workitem(witem); + if (workq->term_callback != NULL) { + workqueue_list_unlock(); + (*workq->term_callback)(workq, workq->term_callarg); + workqueue_list_lock(); + } +#if WQ_TRACE + __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 3, 0); +#endif + free_workqueue(workq); + workqueue_list_unlock(); + return(0); + } + TAILQ_INSERT_TAIL(&workq->item_listhead, witem, item_entry); + } else { + free_workitem(witem); + workqueue_list_unlock(); + return(EINPROGRESS); + } + workqueue_list_unlock(); + return(0); +} + + +int +pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep) +{ + pthread_workitem_t witem; + + if (valid_workq(workq) == 0) { + return(EINVAL); + } + + workqueue_list_lock(); + + /* + * Allocate the workitem here as it can drop the lock. + * Also we can evaluate the workqueue state only once. + */ + 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) { + free_workitem(witem); + workqueue_list_unlock(); + *itemhandlep = 0; + return(ESRCH); + } + + if (itemhandlep != NULL) + *itemhandlep = (pthread_workitem_handle_t *)witem; + TAILQ_INSERT_TAIL(&workq->item_listhead, witem, item_entry); + if (((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == 0) && (workq->queueprio < wqreadyprio)) + wqreadyprio = workq->queueprio; + + pick_nextworkqueue_droplock(); + + return(0); +} + +int +pthread_workqueue_removeitem_np(pthread_workqueue_t workq, pthread_workitem_handle_t itemhandle) +{ + pthread_workitem_t item, baritem; + pthread_workqueue_head_t headp; + int error; + + if (valid_workq(workq) == 0) { + return(EINVAL); + } + + workqueue_list_lock(); + if ((workq->flags & (PTHREAD_WORKQ_IN_TERMINATE | PTHREAD_WORKQ_DESTROYED)) != 0) { + workqueue_list_unlock(); + return(ESRCH); + } + + TAILQ_FOREACH(item, &workq->item_listhead, item_entry) { + if (item == (pthread_workitem_t)itemhandle) { + TAILQ_REMOVE(&workq->item_listhead, item, item_entry); + if ((item->flags & (PTH_WQITEM_BARRIER | PTH_WQITEM_APPLIED)) == (PTH_WQITEM_BARRIER | PTH_WQITEM_APPLIED)) { + workq->flags &= ~PTHREAD_WORKQ_BARRIER_ON; + workq->barrier_count = 0; + if ((workq->queueprio < wqreadyprio) && (!(TAILQ_EMPTY(&workq->item_listhead)))) { + wqreadyprio = workq->queueprio; + } + } else if ((item->flags & PTH_WQITEM_KERN_COUNT) == PTH_WQITEM_KERN_COUNT) { + workq->kq_count--; + item->flags |= PTH_WQITEM_REMOVED; + if (handle_removeitem(workq, item) == 0) + return(0); + } + item->flags |= PTH_WQITEM_NOTINLIST; + free_workitem(item); + workqueue_list_unlock(); + return(0); + } + } + + TAILQ_FOREACH(item, &workq->item_kernhead, item_entry) { + if (item == (pthread_workitem_t)itemhandle) { + workqueue_list_unlock(); + if ((error = __workq_ops(WQOPS_QUEUE_REMOVE, item, 0)) == 0) { + workqueue_list_lock(); + TAILQ_REMOVE(&workq->item_kernhead, item, item_entry); + OSAtomicDecrement32(&kernel_workq_count); + workq->kq_count--; + item->flags |= PTH_WQITEM_REMOVED; + if (handle_removeitem(workq, item) != 0) { + free_workitem(item); + pick_nextworkqueue_droplock(); + } + return(0); + } else { + workqueue_list_unlock(); + return(EBUSY); + } + } + } + workqueue_list_unlock(); + return(EINVAL); +} + + +int +pthread_workqueue_addbarrier_np(pthread_workqueue_t workq, void (* callback_func)(pthread_workqueue_t, void *), void * callback_arg, __unused int waitforcallback, pthread_workitem_handle_t *itemhandlep) +{ + pthread_workitem_t witem; + + if (valid_workq(workq) == 0) { + return(EINVAL); + } + + workqueue_list_lock(); + + /* + * Allocate the workitem here as it can drop the lock. + * Also we can evaluate the workqueue state only once. + */ + witem = alloc_workitem(); + witem->item_entry.tqe_next = 0; + witem->item_entry.tqe_prev = 0; + witem->func = callback_func; + witem->func_arg = callback_arg; + witem->flags = PTH_WQITEM_BARRIER; + + /* alloc workitem can drop the lock, check the state */ + if ((workq->flags & (PTHREAD_WORKQ_IN_TERMINATE | PTHREAD_WORKQ_DESTROYED)) != 0) { + free_workitem(witem); + workqueue_list_unlock(); + return(ESRCH); + } + + if (itemhandlep != NULL) + *itemhandlep = (pthread_workitem_handle_t *)witem; + + TAILQ_INSERT_TAIL(&workq->item_listhead, witem, item_entry); + if (((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == 0) && (workq->queueprio < wqreadyprio)) + wqreadyprio = workq->queueprio; + + pick_nextworkqueue_droplock(); + + return(0); +} + +int +pthread_workqueue_suspend_np(pthread_workqueue_t workq) +{ + if (valid_workq(workq) == 0) { + return(EINVAL); + } + workqueue_list_lock(); + if ((workq->flags & (PTHREAD_WORKQ_IN_TERMINATE | PTHREAD_WORKQ_DESTROYED)) != 0) { + workqueue_list_unlock(); + return(ESRCH); + } + + workq->flags |= PTHREAD_WORKQ_SUSPEND; + workq->suspend_count++; + workqueue_list_unlock(); + return(0); +} + +int +pthread_workqueue_resume_np(pthread_workqueue_t workq) +{ + if (valid_workq(workq) == 0) { + return(EINVAL); + } + workqueue_list_lock(); + if ((workq->flags & (PTHREAD_WORKQ_IN_TERMINATE | PTHREAD_WORKQ_DESTROYED)) != 0) { + workqueue_list_unlock(); + return(ESRCH); + } + + workq->suspend_count--; + if (workq->suspend_count <= 0) { + workq->flags &= ~PTHREAD_WORKQ_SUSPEND; + if (((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == 0) && (workq->queueprio < wqreadyprio)) + wqreadyprio = workq->queueprio; + + pick_nextworkqueue_droplock(); + } else + workqueue_list_unlock(); + + + return(0); +} + +#else /* !BUILDING_VARIANT ] [ */ +extern int __unix_conforming; +extern int _pthread_count; +extern pthread_lock_t _pthread_list_lock; +extern void _pthread_testcancel(pthread_t thread, int isconforming); +extern int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr, int conforming); + +#endif /* !BUILDING_VARIANT ] */ + #if __DARWIN_UNIX03 - __pthread_canceled(2); -#endif /* __DARWIN_UNIX03 */ - break; - default: - return EINVAL; + +__private_extern__ void +__posix_join_cleanup(void *arg) +{ + pthread_t thread = (pthread_t)arg; + int already_exited, res; + void * dummy; + semaphore_t death; + mach_port_t joinport; + int newstyle = 0; + + LOCK(thread->lock); + already_exited = (thread->detached & _PTHREAD_EXITED); + + newstyle = thread->newstyle; + +#if WQ_TRACE + __kdebug_trace(0x900002c, thread, newstyle, 0, 0, 0); +#endif + if (newstyle = 0) { + death = thread->death; + if (!already_exited){ + thread->joiner = (struct _pthread *)NULL; + UNLOCK(thread->lock); + restore_sem_to_pool(death); + } else { + UNLOCK(thread->lock); + while ((res = _pthread_reap_thread(thread, + thread->kernel_thread, + &dummy, 1)) == EAGAIN) + { + sched_yield(); + } + restore_sem_to_pool(death); + + } + + } else { + /* leave another thread to join */ + thread->joiner = (struct _pthread *)NULL; + UNLOCK(thread->lock); } +} - self = pthread_self(); - LOCK(self->lock); - if (oldstate) - *oldstate = self->cancel_state & _PTHREAD_CANCEL_STATE_MASK; - self->cancel_state &= ~_PTHREAD_CANCEL_STATE_MASK; - self->cancel_state |= state; - UNLOCK(self->lock); -#if !__DARWIN_UNIX03 - _pthread_testcancel(self, 0); /* See if we need to 'die' now... */ +#endif /* __DARWIN_UNIX03 */ + + +/* + * Wait for a thread to terminate and obtain its exit value. + */ +/* +int +pthread_join(pthread_t thread, + void **value_ptr) + +moved to pthread_cancelable.c */ + +/* + * Cancel a thread + */ +int +pthread_cancel(pthread_t thread) +{ +#if __DARWIN_UNIX03 + if (__unix_conforming == 0) + __unix_conforming = 1; +#endif /* __DARWIN_UNIX03 */ + + if (_pthread_lookup_thread(thread, NULL, 0) != 0) + return(ESRCH); + +#if __DARWIN_UNIX03 + int state; + + LOCK(thread->lock); + state = thread->cancel_state |= _PTHREAD_CANCEL_PENDING; + UNLOCK(thread->lock); + if (state & PTHREAD_CANCEL_ENABLE) + __pthread_markcancel(thread->kernel_thread); +#else /* __DARWIN_UNIX03 */ + thread->cancel_state |= _PTHREAD_CANCEL_PENDING; #endif /* __DARWIN_UNIX03 */ return (0); } +void +pthread_testcancel(void) +{ + pthread_t self = pthread_self(); + +#if __DARWIN_UNIX03 + if (__unix_conforming == 0) + __unix_conforming = 1; + _pthread_testcancel(self, 1); +#else /* __DARWIN_UNIX03 */ + _pthread_testcancel(self, 0); +#endif /* __DARWIN_UNIX03 */ + +} + + +/* + * Query/update the cancelability 'state' of a thread + */ +int +pthread_setcancelstate(int state, int *oldstate) +{ +#if __DARWIN_UNIX03 + if (__unix_conforming == 0) { + __unix_conforming = 1; + } + return (_pthread_setcancelstate_internal(state, oldstate, 1)); +#else /* __DARWIN_UNIX03 */ + return (_pthread_setcancelstate_internal(state, oldstate, 0)); +#endif /* __DARWIN_UNIX03 */ + +} + + + /* * Query/update the cancelability 'type' of a thread */ @@ -1630,3 +3351,23 @@ pthread_setcanceltype(int type, int *oldtype) return (0); } +int +pthread_sigmask(int how, const sigset_t * set, sigset_t * oset) +{ +#if __DARWIN_UNIX03 + int err = 0; + + if (__pthread_sigmask(how, set, oset) == -1) { + err = errno; + } + return(err); +#else /* __DARWIN_UNIX03 */ + return(__pthread_sigmask(how, set, oset)); +#endif /* __DARWIN_UNIX03 */ +} + +/* +int +sigwait(const sigset_t * set, int * sig) + +moved to pthread_cancelable.c */ diff --git a/pthreads/pthread.h b/pthreads/pthread.h index db58287..dbd2fb5 100644 --- a/pthreads/pthread.h +++ b/pthreads/pthread.h @@ -2,14 +2,14 @@ * Copyright (c) 2000-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, @@ -17,29 +17,29 @@ * 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. - * + * 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 @@ -49,8 +49,8 @@ * POSIX Threads - IEEE 1003.1c */ -#ifndef _POSIX_PTHREAD_H -#define _POSIX_PTHREAD_H +#ifndef _PTHREAD_H +#define _PTHREAD_H #include <_types.h> #ifndef __POSIX_LIB__ @@ -109,7 +109,7 @@ typedef __darwin_pthread_rwlockattr_t pthread_rwlockattr_t; typedef __darwin_pthread_t pthread_t; #endif -#if !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) +#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) #ifndef _MACH_PORT_T #define _MACH_PORT_T @@ -121,13 +121,13 @@ typedef __darwin_mach_port_t mach_port_t; typedef __darwin_sigset_t sigset_t; #endif -#endif /* ! _POSIX_C_SOURCE && ! _XOPEN_SOURCE */ +#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ /* * These symbols indicate which [optional] features are available * They can be tested at compile time via '#ifdef XXX' * The way to check for pthreads is like so: - + * #include * #ifdef _POSIX_THREADS * #include @@ -208,9 +208,14 @@ __BEGIN_DECLS * Mutex type attributes */ #define PTHREAD_MUTEX_NORMAL 0 -#define PTHREAD_MUTEX_ERRORCHECK 1 +#define PTHREAD_MUTEX_ERRORCHECK 1 #define PTHREAD_MUTEX_RECURSIVE 2 #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL +/* + * RWLock variables + */ + +#define PTHREAD_RWLOCK_INITIALIZER {_PTHREAD_RWLOCK_SIG_init, {0}} /* * Mutex variables */ @@ -236,136 +241,234 @@ __BEGIN_DECLS /* * Prototypes for all PTHREAD interfaces */ -int pthread_atfork(void (*prepare)(void), void (*parent)(void), - void (*child)(void)); -int pthread_attr_destroy(pthread_attr_t *attr); -int pthread_attr_getdetachstate(const pthread_attr_t *attr, - int *detachstate); -int pthread_attr_getguardsize(const pthread_attr_t *attr, - size_t *guardsize); -int pthread_attr_getinheritsched(const pthread_attr_t *attr, - int *inheritsched); -int pthread_attr_getschedparam(const pthread_attr_t *attr, - struct sched_param *param); -int pthread_attr_getschedpolicy(const pthread_attr_t *attr, - int *policy); -int pthread_attr_getscope(pthread_attr_t *, int *); -int pthread_attr_getstack(const pthread_attr_t *attr, - void **stackaddr, size_t *stacksize); -int pthread_attr_getstackaddr(const pthread_attr_t *attr, - void **stackaddr); -int pthread_attr_getstacksize(const pthread_attr_t *attr, - size_t *stacksize); -int pthread_attr_init(pthread_attr_t *attr); -int pthread_attr_setdetachstate(pthread_attr_t *attr, - int detachstate); -int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); -int pthread_attr_setinheritsched(pthread_attr_t *attr, - int inheritsched); -int pthread_attr_setschedparam(pthread_attr_t *attr, - const struct sched_param *param); -int pthread_attr_setschedpolicy(pthread_attr_t *attr, - int policy); +int pthread_atfork(void (*)(void), void (*)(void), + void (*)(void)); +int pthread_attr_destroy(pthread_attr_t *); +int pthread_attr_getdetachstate(const pthread_attr_t *, + int *); +int pthread_attr_getguardsize(const pthread_attr_t * __restrict, + size_t * __restrict); +int pthread_attr_getinheritsched(const pthread_attr_t * __restrict, + int * __restrict); +int pthread_attr_getschedparam(const pthread_attr_t * __restrict, + struct sched_param * __restrict); +int pthread_attr_getschedpolicy(const pthread_attr_t * __restrict, + int * __restrict); +int pthread_attr_getscope(const pthread_attr_t * __restrict, int * __restrict); +int pthread_attr_getstack(const pthread_attr_t * __restrict, + void ** __restrict, size_t * __restrict); +int pthread_attr_getstackaddr(const pthread_attr_t * __restrict, + void ** __restrict); +int pthread_attr_getstacksize(const pthread_attr_t * __restrict, + size_t * __restrict); +int pthread_attr_init(pthread_attr_t *); +int pthread_attr_setdetachstate(pthread_attr_t *, + int ); +int pthread_attr_setguardsize(pthread_attr_t *, size_t ); +int pthread_attr_setinheritsched(pthread_attr_t *, + int ); +int pthread_attr_setschedparam(pthread_attr_t * __restrict, + const struct sched_param * __restrict); +int pthread_attr_setschedpolicy(pthread_attr_t *, + int ); int pthread_attr_setscope(pthread_attr_t *, int); -int pthread_attr_setstack(pthread_attr_t *attr, - void *stackaddr, size_t stacksize); -int pthread_attr_setstackaddr(pthread_attr_t *attr, - void *stackaddr); -int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); -int pthread_cancel(pthread_t thread) __DARWIN_ALIAS(pthread_cancel); - -int pthread_cond_broadcast(pthread_cond_t *cond); -int pthread_cond_destroy(pthread_cond_t *cond); -int pthread_cond_init(pthread_cond_t *cond, - const pthread_condattr_t *attr); -int pthread_cond_signal(pthread_cond_t *cond); -int pthread_cond_timedwait(pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *abstime) __DARWIN_ALIAS(pthread_cond_timedwait); -int pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex) __DARWIN_ALIAS(pthread_cond_wait); -int pthread_condattr_destroy(pthread_condattr_t *attr); -int pthread_condattr_getpshared(const pthread_condattr_t *attr, - int *pshared); -int pthread_condattr_init(pthread_condattr_t *attr); -int pthread_condattr_setpshared(pthread_condattr_t *attr, - int pshared); -int pthread_create(pthread_t *thread, - const pthread_attr_t *attr, - void *(*start_routine)(void *), - void *arg); -int pthread_detach(pthread_t thread); -int pthread_equal(pthread_t t1, - pthread_t t2); -void pthread_exit(void *value_ptr) __dead2; +int pthread_attr_setstack(pthread_attr_t *, + void *, size_t ); +int pthread_attr_setstackaddr(pthread_attr_t *, + void *); +int pthread_attr_setstacksize(pthread_attr_t *, size_t ); +int pthread_cancel(pthread_t ) __DARWIN_ALIAS(pthread_cancel); + +int pthread_cond_broadcast(pthread_cond_t *); +int pthread_cond_destroy(pthread_cond_t *); +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_COND_INIT +//End-Libc +int pthread_cond_init(pthread_cond_t * __restrict, + const pthread_condattr_t * __restrict) __DARWIN_ALIAS(pthread_cond_init); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_COND_INIT */ +int pthread_cond_init(pthread_cond_t * __restrict, + const pthread_condattr_t * __restrict) LIBC_ALIAS(pthread_cond_init); +#endif /* !LIBC_ALIAS_PTHREAD_COND_INIT */ +//End-Libc +int pthread_cond_signal(pthread_cond_t *); +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_COND_TIMEDWAIT +//End-Libc +int pthread_cond_timedwait(pthread_cond_t * __restrict, + pthread_mutex_t * __restrict, + const struct timespec * __restrict) __DARWIN_ALIAS_C(pthread_cond_timedwait); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_COND_TIMEDWAIT */ +int pthread_cond_timedwait(pthread_cond_t * __restrict, + pthread_mutex_t * __restrict, + const struct timespec * __restrict) LIBC_ALIAS_C(pthread_cond_timedwait); +#endif /* !LIBC_ALIAS_PTHREAD_COND_TIMEDWAIT */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_COND_WAIT +//End-Libc +int pthread_cond_wait(pthread_cond_t * __restrict, + pthread_mutex_t * __restrict) __DARWIN_ALIAS_C(pthread_cond_wait); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_COND_WAIT */ +int pthread_cond_wait(pthread_cond_t * __restrict, + pthread_mutex_t * __restrict) LIBC_ALIAS_C(pthread_cond_wait); +#endif /* !LIBC_ALIAS_PTHREAD_COND_WAIT */ +//End-Libc +int pthread_condattr_destroy(pthread_condattr_t *); +int pthread_condattr_init(pthread_condattr_t *); +int pthread_condattr_getpshared(const pthread_condattr_t * __restrict, + int * __restrict); +int pthread_condattr_setpshared(pthread_condattr_t *, + int ); +int pthread_create(pthread_t * __restrict, + const pthread_attr_t * __restrict, + void *(*)(void *), + void * __restrict); +int pthread_detach(pthread_t ); +int pthread_equal(pthread_t , + pthread_t ); +void pthread_exit(void *) __dead2; int pthread_getconcurrency(void); -int pthread_getschedparam(pthread_t thread, - int *policy, - struct sched_param *param); -void *pthread_getspecific(pthread_key_t key); -int pthread_join(pthread_t thread, - void **value_ptr) __DARWIN_ALIAS(pthread_join); -int pthread_key_create(pthread_key_t *key, - void (*destructor)(void *)); -int pthread_key_delete(pthread_key_t key); -int pthread_mutex_destroy(pthread_mutex_t *mutex); -int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, - int *prioceiling); -int pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *attr); -int pthread_mutex_lock(pthread_mutex_t *mutex); -int pthread_mutex_setprioceiling(pthread_mutex_t *mutex, - int prioceiling, - int *old_prioceiling); -int pthread_mutex_trylock(pthread_mutex_t *mutex); -int pthread_mutex_unlock(pthread_mutex_t *mutex); -int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); -int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, - int *prioceiling); -int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, - int *protocol); -int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, - int *pshared); -int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, - int *type); -int pthread_mutexattr_init(pthread_mutexattr_t *attr); -int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, - int prioceiling); -int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, - int protocol); -int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, - int pshared); -int pthread_mutexattr_settype(pthread_mutexattr_t *attr, - int type); -int pthread_once(pthread_once_t *once_control, - void (*init_routine)(void)); -int pthread_rwlock_destroy(pthread_rwlock_t * rwlock); -int pthread_rwlock_init(pthread_rwlock_t * rwlock, - const pthread_rwlockattr_t *attr); -int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); -int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); -int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); -int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); -int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); -int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); -int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, - int *pshared); -int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); -int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, - int pshared); +int pthread_getschedparam(pthread_t , int * __restrict, struct sched_param * __restrict); +void *pthread_getspecific(pthread_key_t ); +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_JOIN +//End-Libc +int pthread_join(pthread_t , void **) __DARWIN_ALIAS_C(pthread_join); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_JOIN */ +int pthread_join(pthread_t , void **) LIBC_ALIAS_C(pthread_join); +#endif /* !LIBC_ALIAS_PTHREAD_JOIN */ +//End-Libc +int pthread_key_create(pthread_key_t *, void (*)(void *)); +int pthread_key_delete(pthread_key_t ); +int pthread_mutex_destroy(pthread_mutex_t *); +int pthread_mutex_getprioceiling(const pthread_mutex_t * __restrict, int * __restrict); +int pthread_mutex_init(pthread_mutex_t * __restrict, const pthread_mutexattr_t * __restrict); +int pthread_mutex_lock(pthread_mutex_t *); +int pthread_mutex_setprioceiling(pthread_mutex_t * __restrict, int, int * __restrict); +int pthread_mutex_trylock(pthread_mutex_t *); +int pthread_mutex_unlock(pthread_mutex_t *); +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY +//End-Libc +int pthread_mutexattr_destroy(pthread_mutexattr_t *) __DARWIN_ALIAS(pthread_mutexattr_destroy); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY */ +int pthread_mutexattr_destroy(pthread_mutexattr_t *) LIBC_ALIAS(pthread_mutexattr_destroy); +#endif /* !LIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY */ +//End-Libc +int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t * __restrict, int * __restrict); +int pthread_mutexattr_getprotocol(const pthread_mutexattr_t * __restrict, int * __restrict); +int pthread_mutexattr_getpshared(const pthread_mutexattr_t * __restrict, int * __restrict); +int pthread_mutexattr_gettype(const pthread_mutexattr_t * __restrict, int * __restrict); +int pthread_mutexattr_init(pthread_mutexattr_t *); +int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int); +int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int); +int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int ); +int pthread_mutexattr_settype(pthread_mutexattr_t *, int); +int pthread_once(pthread_once_t *, void (*)(void)); +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_DESTROY +//End-Libc +int pthread_rwlock_destroy(pthread_rwlock_t * ) __DARWIN_ALIAS(pthread_rwlock_destroy); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_RWLOCK_DESTROY */ +int pthread_rwlock_destroy(pthread_rwlock_t * ) LIBC_ALIAS(pthread_rwlock_destroy); +#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_DESTROY */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_INIT +//End-Libc +int pthread_rwlock_init(pthread_rwlock_t * __restrict, const pthread_rwlockattr_t * __restrict) __DARWIN_ALIAS(pthread_rwlock_init); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_RWLOCK_INIT */ +int pthread_rwlock_init(pthread_rwlock_t * __restrict, const pthread_rwlockattr_t * __restrict) LIBC_ALIAS(pthread_rwlock_init); +#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_INIT */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK +//End-Libc +int pthread_rwlock_rdlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_rdlock); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK */ +int pthread_rwlock_rdlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_rdlock); +#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK +//End-Libc +int pthread_rwlock_tryrdlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_tryrdlock); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK */ +int pthread_rwlock_tryrdlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_tryrdlock); +#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK +//End-Libc +int pthread_rwlock_trywrlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_trywrlock); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK */ +int pthread_rwlock_trywrlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_trywrlock); +#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK +//End-Libc +int pthread_rwlock_wrlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_wrlock); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK */ +int pthread_rwlock_wrlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_wrlock); +#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK +//End-Libc +int pthread_rwlock_unlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_unlock); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK */ +int pthread_rwlock_unlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_unlock); +#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK */ +//End-Libc +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t * __restrict, + int * __restrict); +int pthread_rwlockattr_init(pthread_rwlockattr_t *); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, + int ); pthread_t pthread_self(void); -int pthread_setcancelstate(int state, int *oldstate) __DARWIN_ALIAS(pthread_setcancelstate); -int pthread_setcanceltype(int type, int *oldtype) __DARWIN_ALIAS(pthread_setcanceltype); +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_SETCANCELSTATE +//End-Libc +int pthread_setcancelstate(int , int *) __DARWIN_ALIAS(pthread_setcancelstate); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_SETCANCELSTATE */ +int pthread_setcancelstate(int , int *) LIBC_ALIAS(pthread_setcancelstate); +#endif /* !LIBC_ALIAS_PTHREAD_SETCANCELSTATE */ +//End-Libc +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_SETCANCELTYPE +//End-Libc +int pthread_setcanceltype(int , int *) __DARWIN_ALIAS(pthread_setcanceltype); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_SETCANCELTYPE */ +int pthread_setcanceltype(int , int *) LIBC_ALIAS(pthread_setcanceltype); +#endif /* !LIBC_ALIAS_PTHREAD_SETCANCELTYPE */ +//End-Libc int pthread_setconcurrency(int); -int pthread_setschedparam(pthread_t thread, - int policy, - const struct sched_param *param); -int pthread_setspecific(pthread_key_t key, - const void *value); +int pthread_setschedparam(pthread_t , + int , + const struct sched_param *); +int pthread_setspecific(pthread_key_t , + const void *); void pthread_testcancel(void) __DARWIN_ALIAS(pthread_testcancel); -#if !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) +#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) /* returns non-zero if pthread_create or cthread_fork have been called */ int pthread_is_threaded_np(void); @@ -381,18 +484,29 @@ void * pthread_get_stackaddr_np(pthread_t); int pthread_cond_signal_thread_np(pthread_cond_t *, pthread_t); /* Like pthread_cond_timedwait, but use a relative timeout */ -int pthread_cond_timedwait_relative_np(pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *reltime); +int pthread_cond_timedwait_relative_np(pthread_cond_t *, + pthread_mutex_t *, + const struct timespec *); /* Like pthread_create(), but leaves the thread suspended */ -int pthread_create_suspended_np(pthread_t *thread, - const pthread_attr_t *attr, - void *(*start_routine)(void *), - void *arg); +int pthread_create_suspended_np(pthread_t *, + const pthread_attr_t *, + void *(*)(void *), + void *); int pthread_kill(pthread_t, int); -int pthread_sigmask(int, const sigset_t *, sigset_t *); + +pthread_t pthread_from_mach_thread_np(mach_port_t); + +//Begin-Libc +#ifndef LIBC_ALIAS_PTHREAD_SIGMASK +//End-Libc +int pthread_sigmask(int, const sigset_t *, sigset_t *) __DARWIN_ALIAS(pthread_sigmask); +//Begin-Libc +#else /* LIBC_ALIAS_PTHREAD_SIGMASK */ +int pthread_sigmask(int, const sigset_t *, sigset_t *) LIBC_ALIAS(pthread_sigmask); +#endif /* !LIBC_ALIAS_PTHREAD_SIGMASK */ +//End-Libc void pthread_yield_np(void); -#endif /* ! _POSIX_C_SOURCE && ! _XOPEN_SOURCE */ +#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ __END_DECLS -#endif /* _POSIX_PTHREAD_H */ +#endif /* _PTHREAD_H */ diff --git a/pthreads/pthread_atfork.3 b/pthreads/pthread_atfork.3 index 3f3581c..bde2035 100644 --- a/pthreads/pthread_atfork.3 +++ b/pthreads/pthread_atfork.3 @@ -19,8 +19,8 @@ function is used to register functions to be called before and after The .Fa prepare handler is called before -.Fn fork -, while the +.Fn fork , +while the .Fa parent and .Fa child diff --git a/pthreads/pthread_attr.3 b/pthreads/pthread_attr.3 index 4926715..1019425 100644 --- a/pthreads/pthread_attr.3 +++ b/pthreads/pthread_attr.3 @@ -30,57 +30,103 @@ .Dt PTHREAD_ATTR 3 .Os .Sh NAME -.Nm pthread_attr_init , .Nm pthread_attr_destroy , -.Nm pthread_attr_setstacksize , -.Nm pthread_attr_getstacksize , -.Nm pthread_attr_setstackaddr , +.Nm pthread_attr_getdetachstate , +.Nm pthread_attr_getinheritsched , +.Nm pthread_attr_getschedparam , +.Nm pthread_attr_getschedpolicy , +.Nm pthread_attr_getscope , .Nm pthread_attr_getstackaddr , +.Nm pthread_attr_getstacksize , +.Nm pthread_attr_init , .Nm pthread_attr_setdetachstate , -.Nm pthread_attr_getdetachstate , .Nm pthread_attr_setinheritsched , -.Nm pthread_attr_getinheritsched , .Nm pthread_attr_setschedparam , -.Nm pthread_attr_getschedparam , .Nm pthread_attr_setschedpolicy , -.Nm pthread_attr_getschedpolicy , .Nm pthread_attr_setscope , -.Nm pthread_attr_getscope +.Nm pthread_attr_setstackaddr , +.Nm pthread_attr_setstacksize .Nd thread attribute operations .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_attr_init "pthread_attr_t *attr" +.Fo pthread_attr_destroy +.Fa "pthread_attr_t *attr" +.Fc .Ft int -.Fn pthread_attr_destroy "pthread_attr_t *attr" +.Fo pthread_attr_getdetachstate +.Fa "const pthread_attr_t *attr" +.Fa "int *detachstate" +.Fc .Ft int -.Fn pthread_attr_setstacksize "pthread_attr_t *attr" "size_t stacksize" +.Fo pthread_attr_getinheritsched +.Fa "const pthread_attr_t *restrict attr" +.Fa "int *restrict inheritsched" +.Fc .Ft int -.Fn pthread_attr_getstacksize "const pthread_attr_t *attr" "size_t *stacksize" +.Fo pthread_attr_getschedparam +.Fa "const pthread_attr_t *restrict attr" +.Fa "struct sched_param *restrict param" +.Fc .Ft int -.Fn pthread_attr_setstackaddr "pthread_attr_t *attr" "void *stackaddr" +.Fo pthread_attr_getschedpolicy +.Fa "const pthread_attr_t *restrict attr" +.Fa "int *restrict policy" +.Fc .Ft int -.Fn pthread_attr_getstackaddr "const pthread_attr_t *attr" "void **stackaddr" +.Fo pthread_attr_getscope +.Fa "const pthread_attr_t *restrict attr" +.Fa "int *restrict contentionscope" +.Fc .Ft int -.Fn pthread_attr_setdetachstate "pthread_attr_t *attr" "int detachstate" +.Fo pthread_attr_getstackaddr +.Fa "const pthread_attr_t *restrict attr" +.Fa "void **restrict stackaddr" +.Fc .Ft int -.Fn pthread_attr_getdetachstate "const pthread_attr_t *attr" "int *detachstate" +.Fo pthread_attr_getstacksize +.Fa "const pthread_attr_t *restrict attr" +.Fa "size_t *restrict stacksize" +.Fc .Ft int -.Fn pthread_attr_setinheritsched "pthread_attr_t *attr" "int inheritsched" +.Fo pthread_attr_init +.Fa "pthread_attr_t *attr" +.Fc .Ft int -.Fn pthread_attr_getinheritsched "const pthread_attr_t *attr" "int *inheritsched" +.Fo pthread_attr_setdetachstate +.Fa "pthread_attr_t *attr" +.Fa "int detachstate" +.Fc .Ft int -.Fn pthread_attr_setschedparam "pthread_attr_t *attr" "const struct sched_param *param" +.Fo pthread_attr_setinheritsched +.Fa "pthread_attr_t *attr" +.Fa "int inheritsched" +.Fc .Ft int -.Fn pthread_attr_getschedparam "const pthread_attr_t *attr" "struct sched_param *param" +.Fo pthread_attr_setschedparam +.Fa "pthread_attr_t *restrict attr" +.Fa "const struct sched_param *restrict param" +.Fc .Ft int -.Fn pthread_attr_setschedpolicy "pthread_attr_t *attr" "int policy" +.Fo pthread_attr_setschedpolicy +.Fa "pthread_attr_t *attr" +.Fa "int policy" +.Fc .Ft int -.Fn pthread_attr_getschedpolicy "const pthread_attr_t *attr" "int *policy" +.Fo pthread_attr_setscope +.Fa "pthread_attr_t *attr" +.Fa "int contentionscope" +.Fc .Ft int -.Fn pthread_attr_setscope "pthread_attr_t *attr" "int contentionscope" +.Fo pthread_attr_setstackaddr +.Fa "pthread_attr_t *attr" +.Fa "void *stackaddr" +.Fc .Ft int -.Fn pthread_attr_getscope "const pthread_attr_t *attr" "int *contentionscope" +.Fo pthread_attr_setstacksize +.Fa "pthread_attr_t *attr" +.Fa "size_t stacksize" +.Fc .Sh DESCRIPTION Thread attributes are used to specify parameters to .Fn pthread_create . @@ -114,6 +160,7 @@ Otherwise, an error number is returned to indicate the error. .Fn pthread_attr_init will fail if: .Bl -tag -width Er +.\" ======== .It Bq Er ENOMEM Out of memory. .El @@ -121,6 +168,7 @@ Out of memory. .Fn pthread_attr_destroy will fail if: .Bl -tag -width Er +.\" ======== .It Bq Er EINVAL Invalid value for .Fa attr . @@ -129,23 +177,36 @@ Invalid value for .Fn pthread_attr_setstacksize will fail if: .Bl -tag -width Er +.\" ======== +.It Bq Er EINVAL +Invalid value for +.Fa attr . +.\" ======== .It Bq Er EINVAL .Fa stacksize is less than .Dv PTHREAD_STACK_MIN . +.\" ======== +.It Bq Er EINVAL +.Fa stacksize +is not a multiple of the system page size. .El .Pp .Fn pthread_attr_setdetachstate will fail if: .Bl -tag -width Er +.\" ======== .It Bq Er EINVAL Invalid value for +.Fa attr +or .Fa detachstate . .El .Pp .Fn pthread_attr_setinheritsched will fail if: .Bl -tag -width Er +.\" ======== .It Bq Er EINVAL Invalid value for .Fa attr . @@ -154,9 +215,11 @@ Invalid value for .Fn pthread_attr_setschedparam will fail if: .Bl -tag -width Er +.\" ======== .It Bq Er EINVAL Invalid value for .Fa attr . +.\" ======== .It Bq Er ENOTSUP Invalid value for .Fa param . @@ -165,6 +228,7 @@ Invalid value for .Fn pthread_attr_setschedpolicy will fail if: .Bl -tag -width Er +.\" ======== .It Bq Er EINVAL Invalid value for .Fa attr . @@ -176,9 +240,11 @@ Invalid or unsupported value for .Fn pthread_attr_setscope will fail if: .Bl -tag -width Er +.\" ======== .It Bq Er EINVAL Invalid value for .Fa attr . +.\" ======== .It Bq Er ENOTSUP Invalid or unsupported value for .Fa contentionscope . diff --git a/pthreads/pthread_cancelable.c b/pthreads/pthread_cancelable.c new file mode 100644 index 0000000..3b0f207 --- /dev/null +++ b/pthreads/pthread_cancelable.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2000-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@ + */ +/* + * 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 + */ + +/* + * POSIX Pthread Library + */ + +#include "pthread_internals.h" + +#include +#include /* For printf(). */ +#include +#include /* For __mach_errno_addr() prototype. */ +#include +#include +#include +#include +#include +#include +#include + +extern int __unix_conforming; +extern void __posix_join_cleanup(void *arg); +extern pthread_lock_t _pthread_list_lock; +extern void _pthread_testcancel(pthread_t thread, int isconforming); +extern int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr, int conforming); +extern int _pthread_cond_wait(pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime, + int isRelative, + int isconforming); +extern int __sigwait(const sigset_t *set, int *sig); + +/* + * Wait for a thread to terminate and obtain its exit value. + */ +int +pthread_join(pthread_t thread, + void **value_ptr) +{ + kern_return_t kern_res; + int res = 0; + pthread_t self = pthread_self(); + mach_port_t ignore; + mach_port_t kthport; + int conforming = 0; + task_t tself = mach_task_self(); + +#if __DARWIN_UNIX03 + if (__unix_conforming == 0) + __unix_conforming = 1; + +#ifdef VARIANT_CANCELABLE + _pthread_testcancel(self, 1); +#endif /* VARIANT_CANCELABLE */ +#endif /* __DARWIN_UNIX03 */ + + if ((res = _pthread_lookup_thread(thread, &kthport, 1)) != 0) + return(res); + + if (thread->sig == _PTHREAD_SIG) + { + if (thread->newstyle == 0) { + semaphore_t death = new_sem_from_pool(); /* in case we need it */ + + LOCK(thread->lock); + if ((thread->detached & PTHREAD_CREATE_JOINABLE) && + thread->death == SEMAPHORE_NULL) + { + + assert(thread->joiner == NULL); + if (thread != self && (self == NULL || self->joiner != thread)) + { + int already_exited = (thread->detached & _PTHREAD_EXITED); + + thread->death = death; + thread->joiner = self; + UNLOCK(thread->lock); + + if (!already_exited) + { +#if __DARWIN_UNIX03 + /* Wait for it to signal... */ + pthread_cleanup_push(__posix_join_cleanup, (void *)thread); + do { + res = __semwait_signal(death, 0, 0, 0, 0, 0); + } while ((res < 0) && (errno == EINTR)); + pthread_cleanup_pop(0); + +#else /* __DARWIN_UNIX03 */ + /* Wait for it to signal... */ + do { + PTHREAD_MACH_CALL(semaphore_wait(death), kern_res); + } while (kern_res != KERN_SUCCESS); +#endif /* __DARWIN_UNIX03 */ + } + + LOCK(_pthread_list_lock); + TAILQ_REMOVE(&__pthread_head, thread, plist); +#if WQ_TRACE + __kdebug_trace(0x9000010, thread, 0, 0, 16, 0); +#endif + UNLOCK(_pthread_list_lock); + /* ... and wait for it to really be dead */ + while ((res = _pthread_reap_thread(thread, + thread->kernel_thread, + value_ptr, __unix_conforming)) == EAGAIN) + { + sched_yield(); + } + + } else { + UNLOCK(thread->lock); + res = EDEADLK; + } + } else { + UNLOCK(thread->lock); + res = EINVAL; + } + restore_sem_to_pool(death); + return res; + } else { + /* new style */ + + semaphore_t death = SEMAPHORE_NULL; /* in case we need it */ + semaphore_t joinsem = SEMAPHORE_NULL; + + if (thread->joiner_notify == NULL) + death = new_sem_from_pool(); + + LOCK(thread->lock); + if ((thread->detached & PTHREAD_CREATE_JOINABLE) && + (thread->joiner == NULL)) + { + assert(thread->kernel_thread == kthport); + if (thread != self && (self == NULL || self->joiner != thread)) + { + int already_exited; + + if (thread->joiner_notify == NULL) { + if (death == SEMAPHORE_NULL) + abort(); + thread->joiner_notify = death; + death = SEMAPHORE_NULL; + } + joinsem = thread->joiner_notify; + thread->joiner = self; + UNLOCK(thread->lock); + + if (death != SEMAPHORE_NULL) { + restore_sem_to_pool(death); + death = SEMAPHORE_NULL; + } +#if __DARWIN_UNIX03 + /* Wait for it to signal... */ + pthread_cleanup_push(__posix_join_cleanup, (void *)thread); + do { + res = __semwait_signal(joinsem, 0, 0, 0, 0, 0); + } while ((res < 0) && (errno == EINTR)); + pthread_cleanup_pop(0); +#else /* __DARWIN_UNIX03 */ + /* Wait for it to signal... */ + do { + PTHREAD_MACH_CALL(semaphore_wait(joinsem), kern_res); + } while (kern_res != KERN_SUCCESS); +#endif /* __DARWIN_UNIX03 */ + + restore_sem_to_pool(joinsem); + res = _pthread_join_cleanup(thread, value_ptr, conforming); + } else { + UNLOCK(thread->lock); + res = EDEADLK; + } + } else { + UNLOCK(thread->lock); + res = EINVAL; + } + if (death != SEMAPHORE_NULL) + restore_sem_to_pool(death); + return res; + }/* end of new style */ + } + return ESRCH; +} + +int +pthread_cond_wait(pthread_cond_t *cond, + pthread_mutex_t *mutex) +{ + int conforming; +#if __DARWIN_UNIX03 + + if (__unix_conforming == 0) + __unix_conforming = 1; + +#ifdef VARIANT_CANCELABLE + conforming = 1; +#else /* !VARIANT_CANCELABLE */ + conforming = -1; +#endif /* VARIANT_CANCELABLE */ +#else /* __DARWIN_UNIX03 */ + conforming = 0; +#endif /* __DARWIN_UNIX03 */ + return (_pthread_cond_wait(cond, mutex, (struct timespec *)NULL, 0, conforming)); +} + +int +pthread_cond_timedwait(pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + int conforming; +#if __DARWIN_UNIX03 + if (__unix_conforming == 0) + __unix_conforming = 1; + +#ifdef VARIANT_CANCELABLE + conforming = 1; +#else /* !VARIANT_CANCELABLE */ + conforming = -1; +#endif /* VARIANT_CANCELABLE */ +#else /* __DARWIN_UNIX03 */ + conforming = 0; +#endif /* __DARWIN_UNIX03 */ + + return (_pthread_cond_wait(cond, mutex, abstime, 0, conforming)); +} + +int +sigwait(const sigset_t * set, int * sig) +{ +#if __DARWIN_UNIX03 + int err = 0; + + if (__unix_conforming == 0) + __unix_conforming = 1; + +#ifdef VARIANT_CANCELABLE + _pthread_testcancel(pthread_self(), 1); +#endif /* VARIANT_CANCELABLE */ + + if (__sigwait(set, sig) == -1) { + err = errno; + } + return(err); +#else /* __DARWIN_UNIX03 */ + return(__sigwait(set, sig)); + +#endif /* __DARWIN_UNIX03 */ +} diff --git a/pthreads/pthread_cleanup_pop.3 b/pthreads/pthread_cleanup_pop.3 index a965922..7bbae54 100644 --- a/pthreads/pthread_cleanup_pop.3 +++ b/pthreads/pthread_cleanup_pop.3 @@ -40,12 +40,11 @@ .Sh DESCRIPTION The .Fn pthread_cleanup_pop -function pops the top cleanup routine off of the current threads cleanup -routine stack, and, if +function pops the top cleanup routine off +of the current thread's cleanup routine stack and, if .Fa execute is non-zero, it will execute the function. -If there is no cleanup routine -then +If there is no cleanup routine, .Fn pthread_cleanup_pop does nothing. .Sh RETURN VALUES diff --git a/pthreads/pthread_cleanup_push.3 b/pthreads/pthread_cleanup_push.3 index 5a8aa9d..d307756 100644 --- a/pthreads/pthread_cleanup_push.3 +++ b/pthreads/pthread_cleanup_push.3 @@ -36,17 +36,20 @@ .Sh SYNOPSIS .Fd #include .Ft void -.Fn pthread_cleanup_push "void \*[lp]*cleanup_routine\*[rp]\*[lp]void *\*[rp]" "void *arg" +.Fo pthread_cleanup_push +.Fa "void \*[lp]*routine\*[rp]\*[lp]void *\*[rp]" +.Fa "void *arg" +.Fc .Sh DESCRIPTION The .Fn pthread_cleanup_push function adds -.Fa cleanup_routine +.Fa routine to the top of the stack of cleanup handlers that get called when the current thread exits. .Pp When -.Fa cleanup_routine +.Fa routine is called, it is passed .Fa arg as its only argument. diff --git a/pthreads/pthread_cond.c b/pthreads/pthread_cond.c index 56889d2..ff2bed1 100644 --- a/pthreads/pthread_cond.c +++ b/pthreads/pthread_cond.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -51,7 +51,9 @@ #include "pthread_internals.h" #include /* For struct timespec and getclock(). */ #include - + +#include "plockstat.h" + extern void _pthread_mutex_remove(pthread_mutex_t *, pthread_t); extern int __unix_conforming; @@ -67,7 +69,7 @@ pthread_cond_destroy(pthread_cond_t *cond) int sig = cond->sig; /* to provide backwards compat for apps using united condtn vars */ - if((sig != _PTHREAD_COND_SIG) && (sig !=_PTHREAD_COND_SIG_init)) + if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init) && (sig != _PTHREAD_KERN_COND_SIG)) return(EINVAL); LOCK(cond->lock); @@ -76,44 +78,22 @@ pthread_cond_destroy(pthread_cond_t *cond) if (cond->busy == (pthread_mutex_t *)NULL) { cond->sig = _PTHREAD_NO_SIG; - ret = ESUCCESS; + ret = 0; } else ret = EBUSY; + } else if (cond->sig == _PTHREAD_KERN_COND_SIG) { + int condid = cond->_pthread_cond_kernid; + UNLOCK(cond->lock); + if (__pthread_cond_destroy(condid) == -1) + return(errno); + cond->sig = _PTHREAD_NO_SIG; + return(0); } else ret = EINVAL; /* Not an initialized condition variable structure */ UNLOCK(cond->lock); return (ret); } -/* - * Initialize a condition variable. Note: 'attr' is ignored. - */ -static int -_pthread_cond_init(pthread_cond_t *cond, - const pthread_condattr_t *attr) -{ - cond->next = (pthread_cond_t *)NULL; - cond->prev = (pthread_cond_t *)NULL; - cond->busy = (pthread_mutex_t *)NULL; - cond->waiters = 0; - cond->sigspending = 0; - cond->sem = SEMAPHORE_NULL; - cond->sig = _PTHREAD_COND_SIG; - return (ESUCCESS); -} - -/* - * Initialize a condition variable. This is the public interface. - * We can't trust the lock, so initialize it first before taking - * it. - */ -int -pthread_cond_init(pthread_cond_t *cond, - const pthread_condattr_t *attr) -{ - LOCK_INIT(cond->lock); - return (_pthread_cond_init(cond, attr)); -} /* * Signal a condition variable, waking up all threads waiting for it. @@ -126,7 +106,7 @@ pthread_cond_broadcast(pthread_cond_t *cond) int sig = cond->sig; /* to provide backwards compat for apps using united condtn vars */ - if((sig != _PTHREAD_COND_SIG) && (sig !=_PTHREAD_COND_SIG_init)) + if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init) && (sig != _PTHREAD_KERN_COND_SIG)) return(EINVAL); LOCK(cond->lock); @@ -136,8 +116,14 @@ pthread_cond_broadcast(pthread_cond_t *cond) if (cond->sig == _PTHREAD_COND_SIG_init) { - _pthread_cond_init(cond, NULL); - res = ESUCCESS; + _pthread_cond_init(cond, NULL, 0); + res = 0; + } else if (cond->sig == _PTHREAD_KERN_COND_SIG) { + int condid = cond->_pthread_cond_kernid; + UNLOCK(cond->lock); + if (__pthread_cond_broadcast(condid) == -1) + return(errno); + return(0); } else res = EINVAL; /* Not a condition variable */ UNLOCK(cond->lock); @@ -147,7 +133,7 @@ pthread_cond_broadcast(pthread_cond_t *cond) { /* Avoid kernel call since there are no waiters... */ UNLOCK(cond->lock); - return (ESUCCESS); + return (0); } cond->sigspending++; UNLOCK(cond->lock); @@ -164,7 +150,7 @@ pthread_cond_broadcast(pthread_cond_t *cond) UNLOCK(cond->lock); if (kern_res != KERN_SUCCESS) return (EINVAL); - return (ESUCCESS); + return (0); } /* @@ -178,9 +164,9 @@ pthread_cond_signal_thread_np(pthread_cond_t *cond, pthread_t thread) 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); + if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init) && (sig != _PTHREAD_KERN_COND_SIG)) + return(EINVAL); LOCK(cond->lock); if (cond->sig != _PTHREAD_COND_SIG) { @@ -188,10 +174,15 @@ pthread_cond_signal_thread_np(pthread_cond_t *cond, pthread_t thread) if (cond->sig == _PTHREAD_COND_SIG_init) { - _pthread_cond_init(cond, NULL); - ret = ESUCCESS; - } - else + _pthread_cond_init(cond, NULL, 0); + ret = 0; + } else if (cond->sig == _PTHREAD_KERN_COND_SIG) { + int condid = cond->_pthread_cond_kernid; + UNLOCK(cond->lock); + if (__pthread_cond_signal(condid) == -1) + return(errno); + return(0); + } else ret = EINVAL; /* Not a condition variable */ UNLOCK(cond->lock); return (ret); @@ -200,7 +191,7 @@ pthread_cond_signal_thread_np(pthread_cond_t *cond, pthread_t thread) { /* Avoid kernel call since there are not enough waiters... */ UNLOCK(cond->lock); - return (ESUCCESS); + return (0); } cond->sigspending++; UNLOCK(cond->lock); @@ -229,7 +220,7 @@ pthread_cond_signal_thread_np(pthread_cond_t *cond, pthread_t thread) UNLOCK(cond->lock); if (kern_res != KERN_SUCCESS) return (EINVAL); - return (ESUCCESS); + return (0); } /* @@ -292,6 +283,18 @@ 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--; @@ -300,6 +303,7 @@ static void cond_cleanup(void *arg) cond->busy = (pthread_mutex_t *)NULL; } UNLOCK(cond->lock); + /* ** Can't do anything if this fails -- we're on the way out */ @@ -310,6 +314,8 @@ static void cond_cleanup(void *arg) * 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, @@ -318,26 +324,80 @@ _pthread_cond_wait(pthread_cond_t *cond, int isRelative, int isconforming) { - int res; + int res, saved_error; kern_return_t kern_res; int wait_res; pthread_mutex_t *busy; mach_timespec_t then; 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)) + if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init) && (sig != _PTHREAD_KERN_COND_SIG)) return(EINVAL); + + if (isconforming) { + if((msig != _PTHREAD_MUTEX_SIG) && (msig != _PTHREAD_MUTEX_SIG_init) && (msig != _PTHREAD_KERN_MUTEX_SIG)) + 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 */ + if ((cond->sig == _PTHREAD_KERN_COND_SIG) && (mutex->sig == _PTHREAD_KERN_MUTEX_SIG)) { + int condid = cond->_pthread_cond_kernid; + int mutexid = mutex->_pthread_mutex_kernid; + UNLOCK(cond->lock); + + if (abstime) { + 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 ((res = pthread_mutex_unlock(mutex)) != 0) + return (res); + + if ((__pthread_cond_timedwait(condid, mutexid, &then)) == -1) + saved_error = errno; + else + saved_error = 0; + } else { + if ((res = pthread_mutex_unlock(mutex)) != 0) + return (res); + if(( __pthread_cond_wait(condid, mutexid)) == -1) + saved_error = errno; + else + saved_error = 0; + } + if ((res = pthread_mutex_lock(mutex)) != 0) + return (res); + return(saved_error); + } else { + UNLOCK(cond->lock); + return (EINVAL); /* Not a condition variable */ + } } - _pthread_cond_init(cond, NULL); + _pthread_cond_init(cond, NULL, 0); } if (abstime) { @@ -372,6 +432,36 @@ _pthread_cond_wait(pthread_cond_t *cond, 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)) { @@ -405,6 +495,8 @@ _pthread_cond_wait(pthread_cond_t *cond, LOCK(mutex->lock); if (--mutex->lock_count == 0) { + PLOCKSTAT_MUTEX_RELEASE(mutex, (mutex->type == PTHREAD_MUTEX_RECURSIVE)? 1:0); + if (mutex->sem == SEMAPHORE_NULL) mutex->sem = new_sem_from_pool(); mutex->owner = _PTHREAD_MUTEX_OWNER_SWITCHING; @@ -423,6 +515,7 @@ _pthread_cond_wait(pthread_cond_t *cond, pthread_cleanup_pop(0); } } else { + PLOCKSTAT_MUTEX_RELEASE(mutex, (mutex->type == PTHREAD_MUTEX_RECURSIVE)? 1:0); UNLOCK(mutex->lock); if (!isconforming) { if (abstime) { @@ -447,13 +540,13 @@ _pthread_cond_wait(pthread_cond_t *cond, cond->busy = (pthread_mutex_t *)NULL; } UNLOCK(cond->lock); - if ((res = pthread_mutex_lock(mutex)) != ESUCCESS) + 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 (ESUCCESS); + return (0); else if (kern_res == KERN_OPERATION_TIMED_OUT) return (ETIMEDOUT); return (EINVAL); @@ -486,14 +579,15 @@ int pthread_condattr_init(pthread_condattr_t *attr) { attr->sig = _PTHREAD_COND_ATTR_SIG; - return (ESUCCESS); + attr->pshared = _PTHREAD_DEFAULT_PSHARED; + return (0); } int pthread_condattr_destroy(pthread_condattr_t *attr) { attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */ - return (ESUCCESS); + return (0); } int @@ -502,24 +596,70 @@ pthread_condattr_getpshared(const pthread_condattr_t *attr, { if (attr->sig == _PTHREAD_COND_ATTR_SIG) { - *pshared = (int)PTHREAD_PROCESS_PRIVATE; - return (ESUCCESS); + *pshared = (int)attr->pshared; + return (0); } else { return (EINVAL); /* Not an initialized 'attribute' structure */ } } +#ifdef PR_5243343 +/* 5243343 - temporary hack to detect if we are running the conformance test */ +extern int PR_5243343_flag; +#endif /* PR_5243343 */ +__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; + if (cond->pshared == PTHREAD_PROCESS_SHARED) { + cond->sem = SEMAPHORE_NULL; + cond->sig = 0; + if( __pthread_cond_init(cond, attr) == -1) + return(errno); + cond->sig = _PTHREAD_KERN_COND_SIG; + return(0); + } + } + 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 */ int 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 */ - return (ESUCCESS); + attr->pshared = pshared; + return (0); } else { return (EINVAL); /* Invalid parameter */ @@ -531,6 +671,7 @@ pthread_condattr_setpshared(pthread_condattr_t * attr, int pshared) } + #else /* !BUILDING_VARIANT */ extern int _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, @@ -538,40 +679,46 @@ extern int _pthread_cond_wait(pthread_cond_t *cond, int isRelative, int isconforming); +extern int +_pthread_cond_init(pthread_cond_t *cond, + const pthread_condattr_t *attr, + int conforming); + #endif /* !BUILDING_VARIANT ] */ +/* + * Initialize a condition variable. Note: 'attr' is ignored. + */ +/* + * Initialize a condition variable. This is the public interface. + * We can't trust the lock, so initialize it first before taking + * it. + */ int -pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex) +pthread_cond_init(pthread_cond_t *cond, + const pthread_condattr_t *attr) { int conforming; -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; - - conforming = 1; +#if __DARWIN_UNIX03 + conforming = 1; #else /* __DARWIN_UNIX03 */ - conforming = 0; + conforming = 0; #endif /* __DARWIN_UNIX03 */ - return (_pthread_cond_wait(cond, mutex, (struct timespec *)NULL, 0, conforming)); + + + LOCK_INIT(cond->lock); + return (_pthread_cond_init(cond, attr, conforming)); } +/* +int +pthread_cond_wait(pthread_cond_t *cond, + pthread_mutex_t *mutex) + int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) -{ - int conforming; -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; - - conforming = 1; -#else /* __DARWIN_UNIX03 */ - conforming = 0; -#endif /* __DARWIN_UNIX03 */ - - return (_pthread_cond_wait(cond, mutex, abstime, 0, conforming)); -} +moved to pthread_cancelable.c */ diff --git a/pthreads/pthread_cond_broadcast.3 b/pthreads/pthread_cond_broadcast.3 index 27600a6..279636d 100644 --- a/pthreads/pthread_cond_broadcast.3 +++ b/pthreads/pthread_cond_broadcast.3 @@ -40,12 +40,13 @@ .Sh DESCRIPTION The .Fn pthread_cond_broadcast -function unblocks all threads waiting for the condition variable +function unblocks all threads that are waiting for the condition variable .Fa cond . .Sh RETURN VALUES If successful, the .Fn pthread_cond_broadcast -function will return zero, otherwise an error number will be returned +function will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_cond_broadcast diff --git a/pthreads/pthread_cond_destroy.3 b/pthreads/pthread_cond_destroy.3 index 6b0ecc2..523bf8a 100644 --- a/pthreads/pthread_cond_destroy.3 +++ b/pthreads/pthread_cond_destroy.3 @@ -45,20 +45,21 @@ function frees the resources allocated by the condition variable .Sh RETURN VALUES If successful, the .Fn pthread_cond_destroy -function will return zero, otherwise an error number will be returned +function will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_cond_destroy will fail if: .Bl -tag -width Er -.It Bq Er EINVAL -The value specified by -.Fa cond -is invalid. .It Bq Er EBUSY The variable .Fa cond is locked by another thread. +.It Bq Er EINVAL +The value specified by +.Fa cond +is invalid. .El .Sh SEE ALSO .Xr pthread_cond_broadcast 3 , diff --git a/pthreads/pthread_cond_init.3 b/pthreads/pthread_cond_init.3 index ec30f86..a69fbac 100644 --- a/pthreads/pthread_cond_init.3 +++ b/pthreads/pthread_cond_init.3 @@ -36,7 +36,10 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_cond_init "pthread_cond_t *cond" "const pthread_condattr_t *attr" +.Fo pthread_cond_init +.Fa "pthread_cond_t *restrict cond" +.Fa "const pthread_condattr_t *restrict attr" +.Fc .Sh DESCRIPTION The .Fn pthread_cond_init @@ -44,17 +47,20 @@ function creates a new condition variable, with attributes specified with .Fa attr . If .Fa attr -is NULL the default attributes are used. +is NULL, the default attributes are used. .Sh RETURN VALUES If successful, the .Fn pthread_cond_init function will return zero and put the new condition variable id into -.Fa cond , -otherwise an error number will be returned to indicate the error. +.Fa cond . +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_cond_init will fail if: .Bl -tag -width Er +.It Bq Er EAGAIN +The system temporarily lacks the resources to create another condition +variable. .It Bq Er EINVAL The value specified by .Fa attr @@ -62,9 +68,6 @@ is invalid. .It Bq Er ENOMEM The process cannot allocate enough memory to create another condition variable. -.It Bq Er EAGAIN -The system temporarily lacks the resources to create another condition -variable. .El .Sh SEE ALSO .Xr pthread_cond_broadcast 3 , diff --git a/pthreads/pthread_cond_signal.3 b/pthreads/pthread_cond_signal.3 index 06078a9..669b6fc 100644 --- a/pthreads/pthread_cond_signal.3 +++ b/pthreads/pthread_cond_signal.3 @@ -45,8 +45,8 @@ function unblocks one thread waiting for the condition variable .Sh RETURN VALUES If successful, the .Fn pthread_cond_signal -function will return zero, otherwise an error number will be returned -to indicate the error. +function will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_cond_signal will fail if: diff --git a/pthreads/pthread_cond_timedwait.3 b/pthreads/pthread_cond_timedwait.3 index 3ff427d..052599b 100644 --- a/pthreads/pthread_cond_timedwait.3 +++ b/pthreads/pthread_cond_timedwait.3 @@ -36,13 +36,17 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_cond_timedwait "pthread_cond_t *cond" "pthread_mutex_t *mutex" "const struct timespec *abstime" +.Fo pthread_cond_timedwait +.Fa "pthread_cond_t *restrict cond" +.Fa "pthread_mutex_t *restrict mutex" +.Fa "const struct timespec *restrict abstime" +.Fc .Sh DESCRIPTION The .Fn pthread_cond_timedwait function atomically blocks the current thread waiting on the condition variable specified by -.Fa cond , +.Fa cond and unblocks the mutex specified by .Fa mutex . The waiting thread unblocks only after another thread calls @@ -58,7 +62,7 @@ and the current thread reacquires the lock on If successful, the .Fn pthread_cond_timedwait function will return zero. -Otherwise an error number will be returned to +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_cond_timedwait diff --git a/pthreads/pthread_cond_wait.3 b/pthreads/pthread_cond_wait.3 index d64c49e..6aebfc1 100644 --- a/pthreads/pthread_cond_wait.3 +++ b/pthreads/pthread_cond_wait.3 @@ -37,7 +37,10 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_cond_wait "pthread_cond_t *cond" "pthread_mutex_t *mutex" +.Fo pthread_cond_wait +.Fa "pthread_cond_t *restrict cond" +.Fa "pthread_mutex_t *restrict mutex" +.Fc .Sh DESCRIPTION The .Fn pthread_cond_wait @@ -50,8 +53,7 @@ argument. If successful, the .Fn pthread_cond_wait function will return zero. -Otherwise an error number will be returned to -indicate the error. +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_cond_wait will fail if: diff --git a/pthreads/pthread_condattr.3 b/pthreads/pthread_condattr.3 index e63da0d..4db5027 100644 --- a/pthreads/pthread_condattr.3 +++ b/pthreads/pthread_condattr.3 @@ -30,15 +30,19 @@ .Dt PTHREAD_CONDATTR 3 .Os .Sh NAME -.Nm pthread_condattr_init , -.Nm pthread_condattr_destroy +.Nm pthread_condattr_destroy , +.Nm pthread_condattr_init .Nd condition attribute operations .Sh SYNOPSIS .In pthread.h .Ft int -.Fn pthread_condattr_init "pthread_condattr_t *attr" +.Fo pthread_condattr_destroy +.Fa "pthread_condattr_t *attr" +.Fc .Ft int -.Fn pthread_condattr_destroy "pthread_condattr_t *attr" +.Fo pthread_condattr_init +.Fa "pthread_condattr_t *attr" +.Fc .Sh DESCRIPTION Condition attribute objects are used to specify parameters to .Fn pthread_cond_init . @@ -59,13 +63,6 @@ function destroys a condition attribute object. If successful, these functions return 0. Otherwise, an error number is returned to indicate the error. .Sh ERRORS -.Fn pthread_condattr_init -will fail if: -.Bl -tag -width Er -.It Bq Er ENOMEM -Out of memory. -.El -.Pp .Fn pthread_condattr_destroy will fail if: .Bl -tag -width Er @@ -73,6 +70,13 @@ will fail if: Invalid value for .Fa attr . .El +.Pp +.Fn pthread_condattr_init +will fail if: +.Bl -tag -width Er +.It Bq Er ENOMEM +Out of memory. +.El .Sh SEE ALSO .Xr pthread_cond_init 3 .Sh STANDARDS diff --git a/pthreads/pthread_create.3 b/pthreads/pthread_create.3 index c495109..c6a670c 100644 --- a/pthreads/pthread_create.3 +++ b/pthreads/pthread_create.3 @@ -39,7 +39,12 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_create "pthread_t *thread" "const pthread_attr_t *attr" "void *(*start_routine)(void *)" "void *arg" +.Fo pthread_create +.Fa "pthread_t *restrict thread" +.Fa "const pthread_attr_t *restrict attr" +.Fa "void *(*start_routine)(void *)" +.Fa "void *restrict arg" +.Fc .Sh DESCRIPTION The .Fn pthread_create @@ -52,21 +57,20 @@ is NULL, the default attributes are used. If the attributes specified by .Fa attr are modified later, the thread's attributes are not affected. -Upon -successful completion +Upon successful completion, .Fn pthread_create will store the ID of the created thread in the location specified by .Fa thread . .Pp -The thread is created executing -.Fa start_routine +Upon its creation, the thread executes +.Fa start_routine , with .Fa arg as its sole argument. -If the +If .Fa start_routine returns, the effect is as if there was an implicit call to -.Fn pthread_exit +.Fn pthread_exit , using the return value of .Fa start_routine as the exit status. @@ -76,7 +80,7 @@ was originally invoked differs from this. When it returns from .Fn main , the effect is as if there was an implicit call to -.Fn exit +.Fn exit , using the return value of .Fn main as the exit status. @@ -92,7 +96,7 @@ The set of signals pending for the new thread is empty. If successful, the .Fn pthread_create function will return zero. -Otherwise an error number will be returned to +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_create diff --git a/pthreads/pthread_detach.3 b/pthreads/pthread_detach.3 index 3608bc3..f354951 100644 --- a/pthreads/pthread_detach.3 +++ b/pthreads/pthread_detach.3 @@ -39,7 +39,9 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_detach "pthread_t thread" +.Fo pthread_detach +.Fa "pthread_t thread" +.Fc .Sh DESCRIPTION The .Fn pthread_detach @@ -59,10 +61,10 @@ calls on the same target thread is unspecified. If successful, the .Fn pthread_detach function will return zero. -Otherwise an error number will be returned to +Otherwise, an error number will be returned to indicate the error. Note that the function does not change the value -of errno as it did for some drafts of the standard. +of errno, as it did for some drafts of the standard. These early drafts also passed a pointer to pthread_t as the argument. Beware! diff --git a/pthreads/pthread_equal.3 b/pthreads/pthread_equal.3 index 37b2c01..c865329 100644 --- a/pthreads/pthread_equal.3 +++ b/pthreads/pthread_equal.3 @@ -39,7 +39,10 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_equal "pthread_t t1" "pthread_t t2" +.Fo pthread_equal +.Fa "pthread_t t1" +.Fa "pthread_t t2" +.Fc .Sh DESCRIPTION The .Fn pthread_equal @@ -54,7 +57,7 @@ function will return non-zero if the thread IDs .Fa t1 and .Fa t2 -correspond to the same thread, otherwise it will return zero. +correspond to the same thread. Otherwise, it will return zero. .Sh ERRORS None. .Sh SEE ALSO diff --git a/pthreads/pthread_exit.3 b/pthreads/pthread_exit.3 index 3bb690a..52b8403 100644 --- a/pthreads/pthread_exit.3 +++ b/pthreads/pthread_exit.3 @@ -39,7 +39,9 @@ .Sh SYNOPSIS .Fd #include .Ft void -.Fn pthread_exit "void *value_ptr" +.Fo pthread_exit +.Fa "void *value_ptr" +.Fc .Sh DESCRIPTION The .Fn pthread_exit diff --git a/pthreads/pthread_getschedparam.3 b/pthreads/pthread_getschedparam.3 index e00454b..854596c 100644 --- a/pthreads/pthread_getschedparam.3 +++ b/pthreads/pthread_getschedparam.3 @@ -30,21 +30,29 @@ .Dt PTHREAD_SCHEDPARAM 3 .Os .Sh NAME -.Nm pthread_setschedparam , -.Nm pthread_getschedparam +.Nm pthread_getschedparam , +.Nm pthread_setschedparam .Nd thread scheduling parameter manipulation .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_setschedparam "pthread_t thread" "int policy" "const struct sched_param *param" +.Fo pthread_getschedparam +.Fa "pthread_t thread" +.Fa "int *restrict policy" +.Fa "struct sched_param *restrict param" +.Fc .Ft int -.Fn pthread_getschedparam "pthread_t thread" "int *policy" "struct sched_param *param" +.Fo pthread_setschedparam +.Fa "pthread_t thread" +.Fa "int policy" +.Fa "const struct sched_param *param" +.Fc .Sh DESCRIPTION The -.Fn pthread_setschedparam -and .Fn pthread_getschedparam -functions set and get the scheduling parameters of individual threads. +and +.Fn pthread_setschedparam +functions get and set the scheduling parameters of individual threads. The scheduling policy for a thread can either be .Dv SCHED_FIFO (first in, first out) or @@ -60,22 +68,22 @@ and no more than If successful, these functions return 0. Otherwise, an error number is returned to indicate the error. .Sh ERRORS -.Fn pthread_setschedparam +.Fn pthread_getschedparam will fail if: .Bl -tag -width Er -.It Bq Er EINVAL -Invalid value for -.Va policy . -.It Bq Er ENOTSUP -Invalid value for scheduling parameters. .It Bq Er ESRCH Non-existent thread .Va thread . .El .Pp -.Fn pthread_getschedparam +.Fn pthread_setschedparam will fail if: .Bl -tag -width Er +.It Bq Er EINVAL +Invalid value for +.Va policy . +.It Bq Er ENOTSUP +Invalid value for scheduling parameters. .It Bq Er ESRCH Non-existent thread .Va thread . diff --git a/pthreads/pthread_getspecific.3 b/pthreads/pthread_getspecific.3 index d53ba46..642aed8 100644 --- a/pthreads/pthread_getspecific.3 +++ b/pthreads/pthread_getspecific.3 @@ -39,24 +39,26 @@ .Sh SYNOPSIS .Fd #include .Ft void * -.Fn pthread_getspecific "pthread_key_t key" +.Fo pthread_getspecific +.Fa "pthread_key_t key" +.Fc .Sh DESCRIPTION The .Fn pthread_getspecific -function returns the value currently bound to the specified -.Fa key +function returns the value that is currently bound to the specified +.Fa key , on behalf of the calling thread. .Pp The effect of calling .Fn pthread_getspecific with a .Fa key -value not obtained from -.Fn pthread_key_create -or after +value that was not obtained from +.Fn pthread_key_create , +or after a .Fa key has been deleted with -.Fn pthread_key_delete +.Fn pthread_key_delete , is undefined. .Pp .Fn pthread_getspecific @@ -68,7 +70,7 @@ function will return the thread-specific data value associated with the given .Fa key . If no thread-specific data value is associated with .Fa key , -then the value NULL is returned. +the value NULL is returned. .Sh ERRORS None. .Sh SEE ALSO diff --git a/pthreads/pthread_impl.h b/pthreads/pthread_impl.h index d778092..72969ae 100644 --- a/pthreads/pthread_impl.h +++ b/pthreads/pthread_impl.h @@ -37,6 +37,7 @@ #define _PTHREAD_MUTEX_SIG_init 0x32AAABA7 #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 795f38e..cce2e48 100644 --- a/pthreads/pthread_internals.h +++ b/pthreads/pthread_internals.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -76,14 +76,16 @@ typedef struct _pthread_attr_t pthread_attr_t; #include "pthread_machdep.h" /* Machine-dependent definitions. */ #include "pthread_spinlock.h" /* spinlock definitions. */ -LIST_HEAD(__pthread_list, _pthread); +TAILQ_HEAD(__pthread_list, _pthread); extern struct __pthread_list __pthread_head; /* head of list of open files */ extern pthread_lock_t _pthread_list_lock; +extern size_t pthreadsize; /* * Compiled-in limits */ -#undef _POSIX_THREAD_KEYS_MAX -#define _POSIX_THREAD_KEYS_MAX 128 +#define _EXTERNAL_POSIX_THREAD_KEYS_MAX 512 +#define _INTERNAL_POSIX_THREAD_KEYS_MAX 256 +#define _INTERNAL_POSIX_THREAD_KEYS_END 768 /* * Threads @@ -97,7 +99,12 @@ typedef struct _pthread u_int32_t detached:8, inherit:8, policy:8, - pad:8; + freeStackOnExit:1, + newstyle:1, + kernalloc:1, + schedset:1, + wqthread:1, + pad:3; size_t guardsize; /* size in bytes to guard stack overflow */ #if !defined(__LP64__) int pad0; /* for backwards compatibility */ @@ -115,7 +122,7 @@ typedef struct _pthread void *arg; /* Argment for thread start routine */ int cancel_state; /* Whether thread can be cancelled */ int err_no; /* thread-local errno */ - void *tsd[_POSIX_THREAD_KEYS_MAX]; /* Thread specific data */ + void *tsd[_EXTERNAL_POSIX_THREAD_KEYS_MAX + _INTERNAL_POSIX_THREAD_KEYS_MAX]; /* Thread specific data */ void *stackaddr; /* Base of the stack (is aligned on vm_page_size boundary */ size_t stacksize; /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */ mach_port_t reply_port; /* Cached MiG reply port */ @@ -123,11 +130,22 @@ typedef struct _pthread int pad2; /* for natural alignment */ #endif void *cthread_self; /* cthread_self() if somebody calls cthread_set_self() */ - boolean_t freeStackOnExit; /* Should we free the stack when we're done? */ + /* protected by list lock */ + u_int32_t childrun:1, + parentcheck:1, + childexit:1, + pad3:29; #if defined(__LP64__) - int pad3; /* for natural alignment */ + int pad4; /* for natural alignment */ #endif - LIST_ENTRY(_pthread) plist; + TAILQ_ENTRY(_pthread) plist; + void * freeaddr; + size_t freesize; + mach_port_t joiner_notify; + char pthread_name[64]; /* including nulll the name */ + int max_tsd_key; + void * cur_workq; + void * cur_workitem; } *pthread_t; /* @@ -142,17 +160,20 @@ typedef char _need_to_change_PTHREAD_TSD_OFFSET[(_PTHREAD_TSD_OFFSET == offsetof struct _pthread_attr_t { long sig; /* Unique signature for this structure */ - pthread_lock_t lock; /* Used for internal mutex on structure */ + pthread_lock_t lock; u_int32_t detached:8, inherit:8, policy:8, - reserved1:8; + freeStackOnExit:1, + fastpath:1, + schedset:1, + reserved1:5; size_t guardsize; /* size in bytes to guard stack overflow */ - int reserved2; + int reserved2; /* Should we free the stack when we exit? */ struct sched_param param; void *stackaddr; /* Base of the stack (is aligned on vm_page_size boundary */ size_t stacksize; /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */ - boolean_t freeStackOnExit;/* Should we free the stack when we exit? */ + boolean_t reserved3; }; /* @@ -165,7 +186,8 @@ typedef struct int prioceiling; u_int32_t protocol:2, /* protocol attribute */ type:2, /* mutex type */ - rfu:28; + pshared:2, + rfu:26; } pthread_mutexattr_t; /* @@ -177,11 +199,13 @@ typedef struct _pthread_mutex long sig; /* Unique signature for this structure */ pthread_lock_t lock; /* Used for internal mutex on structure */ u_int32_t waiters; /* Count of threads waiting for this mutex */ +#define _pthread_mutex_kernid waiters pthread_t owner; /* Which thread has this mutex locked */ semaphore_t sem; /* Semaphore used for waiting */ u_int32_t protocol:2, /* protocol */ type:2, /* mutex type */ - rfu:12, + pshared:2, /* mutex type */ + rfu:10, lock_count:16; struct _pthread_mutex *next, *prev; /* List of other mutexes he owns */ struct _pthread_cond *busy; /* List of condition variables using this mutex */ @@ -190,6 +214,8 @@ typedef struct _pthread_mutex semaphore_t order; } pthread_mutex_t; + + /* * Condition variable attributes */ @@ -197,7 +223,8 @@ typedef struct _pthread_mutex typedef struct { long sig; /* Unique signature for this structure */ - int unsupported; + u_int32_t pshared:2, /* pshared */ + unsupported:30; } pthread_condattr_t; /* @@ -209,10 +236,12 @@ typedef struct _pthread_cond long sig; /* Unique signature for this structure */ pthread_lock_t lock; /* Used for internal mutex on structure */ semaphore_t sem; /* Kernel semaphore */ +#define _pthread_cond_kernid sem struct _pthread_cond *next, *prev; /* List of condition variables using mutex */ struct _pthread_mutex *busy; /* mutex associated with variable */ - u_int32_t waiters:16, /* Number of threads waiting */ - sigspending:16; /* Number of outstanding signals */ + u_int32_t waiters:15, /* Number of threads waiting */ + sigspending:15, /* Number of outstanding signals */ + pshared:2; } pthread_cond_t; /* @@ -235,15 +264,107 @@ typedef struct { #define _PTHREAD_RWLOCK_T typedef struct { long sig; - pthread_mutex_t lock; /* monitor lock */ + pthread_mutex_t lock; /* monitor lock */ int state; +#define _pthread_rwlock_kernid state pthread_cond_t read_signal; pthread_cond_t write_signal; int blocked_writers; int pshared; - int rfu[3]; + pthread_t owner; + int rfu[2]; } pthread_rwlock_t; +/* keep the size to 64bytes for both 64 and 32 */ +#define _PTHREAD_WORKQUEUE_ATTR_T +typedef struct { + u_int32_t sig; +#if defined(__ppc64__) || defined(__x86_64__) + u_int32_t resv1; +#endif + size_t stacksize; + int istimeshare; + int importance; + int affinity; + int queueprio; +#if defined(__ppc64__) || defined(__x86_64__) + unsigned int resv2[8]; +#else + unsigned int resv2[10]; +#endif +} pthread_workqueue_attr_t; + +#define _PTHREAD_WORKITEM_T +typedef struct _pthread_workitem { + TAILQ_ENTRY(_pthread_workitem) item_entry; /* pthread_workitem list in prio */ + void (*func)(void *); + void * func_arg; + struct _pthread_workqueue * workq; + unsigned int flags; +} * pthread_workitem_t; + +#define PTH_WQITEM_INKERNEL_QUEUE 1 +#define PTH_WQITEM_RUNNING 2 +#define PTH_WQITEM_COMPLETED 4 +#define PTH_WQITEM_REMOVED 8 +#define PTH_WQITEM_BARRIER 0x10 +#define PTH_WQITEM_DESTROY 0x20 +#define PTH_WQITEM_NOTINLIST 0x40 +#define PTH_WQITEM_APPLIED 0x80 +#define PTH_WQITEM_KERN_COUNT 0x100 + +#define WORKITEM_POOL_SIZE 1000 +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 5 /* -2 to +2 */ +#define WORK_QUEUE_NORMALIZER 2 /* so all internal usages are from 0 to 4 */ + +#define _PTHREAD_WORKQUEUE_HEAD_T +typedef struct _pthread_workqueue_head { + TAILQ_HEAD(, _pthread_workqueue) wqhead; + struct _pthread_workqueue * next_workq; +} * pthread_workqueue_head_t; + + +#define _PTHREAD_WORKQUEUE_T +typedef struct _pthread_workqueue { + unsigned int sig; /* Unique signature for this structure */ + pthread_lock_t lock; /* Used for internal mutex on structure */ + TAILQ_ENTRY(_pthread_workqueue) wq_list; /* workqueue list in prio */ + TAILQ_HEAD(, _pthread_workitem) item_listhead; /* pthread_workitem list in prio */ + TAILQ_HEAD(, _pthread_workitem) item_kernhead; /* pthread_workitem list in prio */ + unsigned int flags; + size_t stacksize; + int istimeshare; + int importance; + int affinity; + int queueprio; + int barrier_count; + int kq_count; + void (*term_callback)(struct _pthread_workqueue *,void *); + void * term_callarg; + pthread_workqueue_head_t headp; + int suspend_count; +#if defined(__ppc64__) || defined(__x86_64__) + unsigned int rev2[2]; +#else + unsigned int rev2[12]; +#endif +} * pthread_workqueue_t; + +#define PTHREAD_WORKQ_IN_CREATION 1 +#define PTHREAD_WORKQ_IN_TERMINATE 2 +#define PTHREAD_WORKQ_BARRIER_ON 4 +#define PTHREAD_WORKQ_TERM_ON 8 +#define PTHREAD_WORKQ_DESTROYED 0x10 +#define PTHREAD_WORKQ_REQUEUED 0x20 +#define PTHREAD_WORKQ_SUSPEND 0x40 + +#define WORKQUEUE_POOL_SIZE 100 +TAILQ_HEAD(__pthread_workqueue_pool, _pthread_workqueue); +extern struct __pthread_workqueue_pool __pthread_workqueue_pool_head; /* head list of workqueue pool */ + #include "pthread.h" #if defined(__i386__) || defined(__ppc64__) || defined(__x86_64__) @@ -271,6 +392,7 @@ _pthread_self_direct(void) #define _PTHREAD_DEFAULT_PRIOCEILING 0 #define _PTHREAD_DEFAULT_POLICY SCHED_OTHER #define _PTHREAD_DEFAULT_STACKSIZE 0x80000 /* 512K */ +#define _PTHREAD_DEFAULT_PSHARED PTHREAD_PROCESS_PRIVATE #define _PTHREAD_NO_SIG 0x00000000 #define _PTHREAD_MUTEX_ATTR_SIG 0x4D545841 /* 'MTXA' */ @@ -287,8 +409,16 @@ _pthread_self_direct(void) #define _PTHREAD_RWLOCK_SIG 0x52574C4B /* 'RWLK' */ #define _PTHREAD_RWLOCK_SIG_init 0x2DA8B3B4 /* [almost] ~'RWLK' */ -#define _PTHREAD_CREATE_PARENT 4 -#define _PTHREAD_EXITED 8 + +#define _PTHREAD_KERN_COND_SIG 0x12345678 /* */ +#define _PTHREAD_KERN_MUTEX_SIG 0x34567812 /* */ +#define _PTHREAD_KERN_RWLOCK_SIG 0x56781234 /* */ + +#define _PTHREAD_CREATE_PARENT 4 +#define _PTHREAD_EXITED 8 +// 4597450: begin +#define _PTHREAD_WASCANCEL 0x10 +// 4597450: end #if defined(DEBUG) #define _PTHREAD_MUTEX_OWNER_SELF pthread_self() @@ -303,10 +433,6 @@ _pthread_self_direct(void) extern boolean_t swtch_pri(int); -#ifndef ESUCCESS -#define ESUCCESS 0 -#endif - #ifndef PTHREAD_MACH_CALL #define PTHREAD_MACH_CALL(expr, ret) (ret) = (expr) #endif @@ -323,4 +449,6 @@ extern void _pthread_tsd_cleanup(pthread_t self); __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); #endif /* _POSIX_PTHREAD_INTERNALS_H */ diff --git a/pthreads/pthread_join.3 b/pthreads/pthread_join.3 index ef9ddf8..6402393 100644 --- a/pthreads/pthread_join.3 +++ b/pthreads/pthread_join.3 @@ -39,13 +39,16 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_join "pthread_t thread" "void **value_ptr" +.Fo pthread_join +.Fa "pthread_t thread" +.Fa "void **value_ptr" +.Fc .Sh DESCRIPTION The .Fn pthread_join function suspends execution of the calling thread until the target .Fa thread -terminates unless the target +terminates, unless the target .Fa thread has already terminated. .Pp @@ -62,22 +65,26 @@ When a returns successfully, the target thread has been terminated. The results of multiple simultaneous calls to -.Fn pthread_join -specifying the same target thread are undefined. +.Fn pthread_join , +specifying the same target thread, are undefined. If the thread calling .Fn pthread_join -is cancelled, then the target thread is not detached. +is cancelled, the target thread is not detached. .Pp .Sh RETURN VALUES If successful, the .Fn pthread_join function will return zero. -Otherwise an error number will be returned to +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_join will fail if: .Bl -tag -width Er +.It Bq Er EDEADLK +A deadlock was detected or the value of +.Fa thread +specifies the calling thread. .It Bq Er EINVAL The implementation has detected that the value specified by .Fa thread @@ -86,10 +93,6 @@ does not refer to a joinable thread. No thread could be found corresponding to that specified by the given thread ID, .Fa thread . -.It Bq Er EDEADLK -A deadlock was detected or the value of -.Fa thread -specifies the calling thread. .El .Sh SEE ALSO .Xr wait 2 , diff --git a/pthreads/pthread_key_create.3 b/pthreads/pthread_key_create.3 index 82a8a1c..77fae74 100644 --- a/pthreads/pthread_key_create.3 +++ b/pthreads/pthread_key_create.3 @@ -39,15 +39,18 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_key_create "pthread_key_t *key" "void (*destructor)(void *)" +.Fo pthread_key_create +.Fa "pthread_key_t *key" +.Fa "void (*destructor)(void *)" +.Fc .Sh DESCRIPTION The .Fn pthread_key_create -function creates a thread-specific data key visible to all threads in the -process. +function creates a thread-specific data key +that is visible to all threads in the process. Key values provided by .Fn pthread_key_create -are opaque objects used to locate thread-specific data. +are opaque objects, used to locate thread-specific data. Although the same key value may be used by different threads, the values bound to the key by @@ -82,7 +85,7 @@ If successful, the function will store the newly created key value at the location specified by .Fa key and returns zero. -Otherwise an error number will be returned to indicate +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_key_create diff --git a/pthreads/pthread_key_delete.3 b/pthreads/pthread_key_delete.3 index 9e4a1ae..013ecd4 100644 --- a/pthreads/pthread_key_delete.3 +++ b/pthreads/pthread_key_delete.3 @@ -39,11 +39,13 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_key_delete "pthread_key_t key" +.Fo pthread_key_delete +.Fa "pthread_key_t key" +.Fc .Sh DESCRIPTION The .Fn pthread_key_delete -function deletes a thread-specific data key previously returned by +function deletes a thread-specific data key, previously returned by .Fn pthread_key_create . The thread-specific data values associated with .Fa key @@ -75,7 +77,7 @@ will no longer be called upon thread exit. If successful, the .Fn pthread_key_delete function will return zero. -Otherwise an error number will be returned to +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_key_delete diff --git a/pthreads/pthread_machdep.h b/pthreads/pthread_machdep.h index 4ac0f27..9dc0be2 100644 --- a/pthreads/pthread_machdep.h +++ b/pthreads/pthread_machdep.h @@ -56,10 +56,96 @@ #endif /* __LP64__ */ #ifndef __ASSEMBLER__ -typedef int32_t pthread_lock_t; + +#include + +/* +** Define macros for inline pthread_getspecific() usage. +** We reserve a number of slots for Apple internal use. +** This number can grow dynamically, no need to fix it. +*/ + +/* This header contains pre defined thread specific keys */ +/* 0 is used for pthread_self */ +#define _PTHREAD_TSD_SLOT_PTHREAD_SELF 0 +/* Keys 1- 9 for use by dyld, directly or indirectly */ +#define _PTHREAD_TSD_SLOT_DYLD_1 1 +#define _PTHREAD_TSD_SLOT_DYLD_2 2 +#define _PTHREAD_TSD_SLOT_DYLD_3 3 +#define _PTHREAD_TSD_RESERVED_SLOT_COUNT 4 + +/* Keys 10 - 29 are for Libc/Libsystem internal ussage */ +/* used as __pthread_tsd_first + Num */ +#define __PTK_LIBC_LOCALE_KEY 10 +#define __PTK_LIBC_TTYNAME_KEY 11 +#define __PTK_LIBC_LOCALTIME_KEY 12 +#define __PTK_LIBC_GMTIME_KEY 13 + + +/* Keys 30-255 for Non Libsystem usage */ +#define _PTHREAD_TSD_SLOT_OPENGL 30 /* backwards compat sake */ +#define __PTK_FRAMEWORK_OPENGL_KEY 30 + +/* +** Define macros for inline pthread_getspecific() usage. +** We reserve a number of slots for Apple internal use. +** This number can grow dynamically, no need to fix it. +*/ + + +#if defined(__cplusplus) +extern "C" { +#endif + +extern void *pthread_getspecific(unsigned long); +int pthread_key_init_np(int, void (*)(void *)); + +#if defined(__cplusplus) +} +#endif + +typedef int pthread_lock_t; + +inline static int +_pthread_has_direct_tsd(void) +{ +#if defined(__ppc__) + int *caps = (int *)_COMM_PAGE_CPU_CAPABILITIES; + if (*caps & kFastThreadLocalStorage) { + return 1; + } else { + return 0; + } +#else + return 1; +#endif +} + +inline static void * +_pthread_getspecific_direct(unsigned long slot) +{ + void *ret; +#if defined(__OPTIMIZE__) +#if defined(__i386__) || defined(__x86_64__) + asm volatile("mov %%gs:%P1, %0" : "=r" (ret) : "i" (slot * sizeof(void *) + _PTHREAD_TSD_OFFSET)); +#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 *))]; +#else +#error no pthread_getspecific_direct implementation for this arch +#endif +#else /* ! __OPTIMIZATION__ */ + ret = pthread_getspecific(slot); #endif + return ret; +} #define LOCK_INIT(l) ((l) = 0) #define LOCK_INITIALIZER 0 +#endif /* ! __ASSEMBLER__ */ #endif /* _POSIX_PTHREAD_MACHDEP_H */ diff --git a/pthreads/pthread_mutex.c b/pthreads/pthread_mutex.c index 1c85670..dbe5cf6 100644 --- a/pthreads/pthread_mutex.c +++ b/pthreads/pthread_mutex.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -52,6 +52,24 @@ #include "pthread_internals.h" +#include "plockstat.h" + +extern int __unix_conforming; + +#ifndef BUILDING_VARIANT /* [ */ + +#define BLOCK_FAIL_PLOCKSTAT 0 +#define BLOCK_SUCCESS_PLOCKSTAT 1 + +/* This function is never called and exists to provide never-fired dtrace + * probes so that user d scripts don't get errors. + */ +__private_extern__ void _plockstat_never_fired(void) +{ + PLOCKSTAT_MUTEX_SPIN(NULL); + PLOCKSTAT_MUTEX_SPUN(NULL, 0, 0); +} + /* * Destroy a mutex variable. */ @@ -67,17 +85,27 @@ pthread_mutex_destroy(pthread_mutex_t *mutex) mutex->busy == (pthread_cond_t *)NULL) { mutex->sig = _PTHREAD_NO_SIG; - res = ESUCCESS; + res = 0; } else res = EBUSY; - } - else + } else if (mutex->sig == _PTHREAD_KERN_MUTEX_SIG) { + int mutexid = mutex->_pthread_mutex_kernid; + UNLOCK(mutex->lock); + if( __pthread_mutex_destroy(mutexid) == -1) + return(errno); + mutex->sig = _PTHREAD_NO_SIG; + return(0); + } else res = EINVAL; UNLOCK(mutex->lock); return (res); } +#ifdef PR_5243343 +/* 5243343 - temporary hack to detect if we are running the conformance test */ +extern int PR_5243343_flag; +#endif /* PR_5243343 */ /* * Initialize a mutex variable, possibly with additional attributes. */ @@ -91,10 +119,27 @@ _pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) mutex->prioceiling = attr->prioceiling; mutex->protocol = attr->protocol; mutex->type = attr->type; + mutex->pshared = attr->pshared; + if (attr->pshared == PTHREAD_PROCESS_SHARED) { + mutex->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->sig = 0; + if( __pthread_mutex_init(mutex, attr) == -1) + return(errno); + mutex->sig = _PTHREAD_KERN_MUTEX_SIG; + return(0); + } } else { mutex->prioceiling = _PTHREAD_DEFAULT_PRIOCEILING; mutex->protocol = _PTHREAD_DEFAULT_PROTOCOL; mutex->type = PTHREAD_MUTEX_DEFAULT; + mutex->pshared = _PTHREAD_DEFAULT_PSHARED; } mutex->lock_count = 0; mutex->owner = (pthread_t)NULL; @@ -105,7 +150,7 @@ _pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) mutex->sem = SEMAPHORE_NULL; mutex->order = SEMAPHORE_NULL; mutex->sig = _PTHREAD_MUTEX_SIG; - return (ESUCCESS); + return (0); } /* @@ -115,6 +160,12 @@ _pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { +#if 0 + /* conformance tests depend on not having this behavior */ + /* The test for this behavior is optional */ + if (mutex->sig == _PTHREAD_MUTEX_SIG) + return EBUSY; +#endif LOCK_INIT(mutex->lock); return (_pthread_mutex_init(mutex, attr)); } @@ -171,15 +222,34 @@ pthread_mutex_lock(pthread_mutex_t *mutex) int sig = mutex->sig; /* 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) && (sig != _PTHREAD_KERN_MUTEX_SIG)) { + 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); - return (EINVAL); + if (mutex->sig == _PTHREAD_KERN_MUTEX_SIG) { + int mutexid = mutex->_pthread_mutex_kernid; + UNLOCK(mutex->lock); + + PLOCKSTAT_MUTEX_BLOCK(mutex); + if( __pthread_mutex_lock(mutexid) == -1) { + PLOCKSTAT_MUTEX_BLOCKED(mutex, BLOCK_FAIL_PLOCKSTAT); + PLOCKSTAT_MUTEX_ERROR(mutex, errno); + return(errno); + } + + PLOCKSTAT_MUTEX_BLOCKED(mutex, BLOCK_SUCCESS_PLOCKSTAT); + PLOCKSTAT_MUTEX_ACQUIRE(mutex, 0, 0); + return(0); + } else { + UNLOCK(mutex->lock); + PLOCKSTAT_MUTEX_ERROR(mutex, EINVAL); + return (EINVAL); + } } _pthread_mutex_init(mutex, NULL); self = _PTHREAD_MUTEX_OWNER_SELF; @@ -196,11 +266,16 @@ pthread_mutex_lock(pthread_mutex_t *mutex) if (mutex->lock_count < USHRT_MAX) { mutex->lock_count++; - res = ESUCCESS; - } else + PLOCKSTAT_MUTEX_ACQUIRE(mutex, 1, 0); + res = 0; + } else { res = EAGAIN; - } else /* PTHREAD_MUTEX_ERRORCHECK */ + PLOCKSTAT_MUTEX_ERROR(mutex, res); + } + } else { /* PTHREAD_MUTEX_ERRORCHECK */ res = EDEADLK; + PLOCKSTAT_MUTEX_ERROR(mutex, res); + } UNLOCK(mutex->lock); return (res); } @@ -227,12 +302,15 @@ pthread_mutex_lock(pthread_mutex_t *mutex) } 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) { @@ -259,7 +337,8 @@ pthread_mutex_lock(pthread_mutex_t *mutex) _pthread_mutex_add(mutex, self); #endif UNLOCK(mutex->lock); - return (ESUCCESS); + PLOCKSTAT_MUTEX_ACQUIRE(mutex, 0, 0); + return (0); } /* @@ -276,8 +355,21 @@ pthread_mutex_trylock(pthread_mutex_t *mutex) { if (mutex->sig != _PTHREAD_MUTEX_SIG_init) { - UNLOCK(mutex->lock); - return (EINVAL); + + if (mutex->sig == _PTHREAD_KERN_MUTEX_SIG) { + int mutexid = mutex->_pthread_mutex_kernid; + UNLOCK(mutex->lock); + if( __pthread_mutex_trylock(mutexid) == -1) { + PLOCKSTAT_MUTEX_ERROR(mutex, errno); + return(errno); + } + PLOCKSTAT_MUTEX_ACQUIRE(mutex, 0, 0); + return(0); + } else { + PLOCKSTAT_MUTEX_ERROR(mutex, EINVAL); + UNLOCK(mutex->lock); + return (EINVAL); + } } _pthread_mutex_init(mutex, NULL); self = _PTHREAD_MUTEX_OWNER_SELF; @@ -294,9 +386,12 @@ pthread_mutex_trylock(pthread_mutex_t *mutex) if (mutex->lock_count < USHRT_MAX) { mutex->lock_count++; - res = ESUCCESS; - } else + PLOCKSTAT_MUTEX_ACQUIRE(mutex, 1, 0); + res = 0; + } else { res = EAGAIN; + PLOCKSTAT_MUTEX_ERROR(mutex, res); + } UNLOCK(mutex->lock); return (res); } @@ -308,6 +403,7 @@ pthread_mutex_trylock(pthread_mutex_t *mutex) { if (mutex->waiters || mutex->owner != _PTHREAD_MUTEX_OWNER_SWITCHING) { + PLOCKSTAT_MUTEX_ERROR(mutex, EBUSY); UNLOCK(mutex->lock); return (EBUSY); } @@ -329,7 +425,8 @@ pthread_mutex_trylock(pthread_mutex_t *mutex) _pthread_mutex_add(mutex, self); #endif UNLOCK(mutex->lock); - return (ESUCCESS); + PLOCKSTAT_MUTEX_ACQUIRE(mutex, 0, 0); + return (0); } /* @@ -345,15 +442,29 @@ pthread_mutex_unlock(pthread_mutex_t *mutex) /* 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) && (sig != _PTHREAD_KERN_MUTEX_SIG)) { + 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); - return (EINVAL); /* Not a mutex variable */ + if (mutex->sig == _PTHREAD_KERN_MUTEX_SIG) { + int mutexid = mutex->_pthread_mutex_kernid; + UNLOCK(mutex->lock); + if( __pthread_mutex_unlock(mutexid) == -1) { + PLOCKSTAT_MUTEX_ERROR(mutex, errno); + return(errno); + } + PLOCKSTAT_MUTEX_RELEASE(mutex, 0); + return(0); + } else { + PLOCKSTAT_MUTEX_ERROR(mutex, EINVAL); + UNLOCK(mutex->lock); + return (EINVAL); + } } _pthread_mutex_init(mutex, NULL); } else @@ -368,13 +479,15 @@ pthread_mutex_unlock(pthread_mutex_t *mutex) #if defined(DEBUG) abort(); #endif + PLOCKSTAT_MUTEX_ERROR(mutex, EPERM); UNLOCK(mutex->lock); return EPERM; } else if (mutex->type == PTHREAD_MUTEX_RECURSIVE && --mutex->lock_count) { + PLOCKSTAT_MUTEX_RELEASE(mutex, 1); UNLOCK(mutex->lock); - return ESUCCESS; + return(0); } } @@ -387,15 +500,17 @@ pthread_mutex_unlock(pthread_mutex_t *mutex) 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 (ESUCCESS); + return (0); } /* @@ -412,7 +527,7 @@ pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, if (mutex->sig == _PTHREAD_MUTEX_SIG) { *prioceiling = mutex->prioceiling; - res = ESUCCESS; + res = 0; } else res = EINVAL; /* Not an initialized 'attribute' structure */ UNLOCK(mutex->lock); @@ -438,7 +553,7 @@ pthread_mutex_setprioceiling(pthread_mutex_t *mutex, { *old_prioceiling = mutex->prioceiling; mutex->prioceiling = prioceiling; - res = ESUCCESS; + res = 0; } else res = EINVAL; /* Invalid parameter */ } else @@ -447,16 +562,6 @@ pthread_mutex_setprioceiling(pthread_mutex_t *mutex, return (res); } -/* - * Destroy a mutex attribute structure. - */ -int -pthread_mutexattr_destroy(pthread_mutexattr_t *attr) -{ - attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */ - return (ESUCCESS); -} - /* * Get the priority ceiling value from a mutex attribute structure. * Note: written as a 'helper' function to hide implementation details. @@ -468,7 +573,7 @@ pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) { *prioceiling = attr->prioceiling; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an initialized 'attribute' structure */ @@ -486,7 +591,7 @@ pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) { *protocol = attr->protocol; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an initialized 'attribute' structure */ @@ -503,7 +608,7 @@ pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) { *type = attr->type; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Not an initialized 'attribute' structure */ @@ -518,8 +623,8 @@ pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared) { if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) { - *pshared = (int)PTHREAD_PROCESS_PRIVATE; - return (ESUCCESS); + *pshared = (int)attr->pshared; + return (0); } else { return (EINVAL); /* Not an initialized 'attribute' structure */ @@ -536,7 +641,8 @@ pthread_mutexattr_init(pthread_mutexattr_t *attr) attr->protocol = _PTHREAD_DEFAULT_PROTOCOL; attr->type = PTHREAD_MUTEX_DEFAULT; attr->sig = _PTHREAD_MUTEX_ATTR_SIG; - return (ESUCCESS); + attr->pshared = _PTHREAD_DEFAULT_PSHARED; + return (0); } /* @@ -553,7 +659,7 @@ pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, (prioceiling <= 999)) { attr->prioceiling = prioceiling; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Invalid parameter */ @@ -579,7 +685,7 @@ pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, (protocol == PTHREAD_PRIO_PROTECT)) { attr->protocol = protocol; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Invalid parameter */ @@ -605,7 +711,7 @@ pthread_mutexattr_settype(pthread_mutexattr_t *attr, (type == PTHREAD_MUTEX_DEFAULT)) { attr->type = type; - return (ESUCCESS); + return (0); } else { return (EINVAL); /* Invalid parameter */ @@ -616,27 +722,6 @@ pthread_mutexattr_settype(pthread_mutexattr_t *attr, } } -/* - * - */ -int -pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) -{ - if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) - { - if (pshared == PTHREAD_PROCESS_PRIVATE) - { - /* attr->pshared = protocol; */ - return (ESUCCESS); - } else - { - return (EINVAL); /* Invalid parameter */ - } - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} int mutex_try_lock(int *x) { return _spin_lock_try((pthread_lock_t *)x); @@ -663,3 +748,60 @@ pthread_yield_np (void) sched_yield(); } + +/* + * Temp: till pshared is fixed correctly + */ +int +pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) +{ +#if __DARWIN_UNIX03 + if (__unix_conforming == 0) + __unix_conforming = 1; +#endif /* __DARWIN_UNIX03 */ + + 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 + { + return (EINVAL); /* Invalid parameter */ + } + } else + { + return (EINVAL); /* Not an initialized 'attribute' structure */ + } +} + + +#endif /* !BUILDING_VARIANT ] */ + +/* + * Destroy a mutex attribute structure. + */ +int +pthread_mutexattr_destroy(pthread_mutexattr_t *attr) +{ +#if __DARWIN_UNIX03 + if (__unix_conforming == 0) + __unix_conforming = 1; + if (attr->sig != _PTHREAD_MUTEX_ATTR_SIG) + return (EINVAL); +#endif /* __DARWIN_UNIX03 */ + + attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */ + return (0); +} + + diff --git a/pthreads/pthread_mutex_destroy.3 b/pthreads/pthread_mutex_destroy.3 index d00d976..f8375dd 100644 --- a/pthreads/pthread_mutex_destroy.3 +++ b/pthreads/pthread_mutex_destroy.3 @@ -36,7 +36,9 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_mutex_destroy "pthread_mutex_t *mutex" +.Fo pthread_mutex_destroy +.Fa "pthread_mutex_t *mutex" +.Fc .Sh DESCRIPTION The .Fn pthread_mutex_destroy @@ -45,19 +47,19 @@ function frees the resources allocated for .Sh RETURN VALUES If successful, .Fn pthread_mutex_destroy -will return zero, otherwise an error number will be returned to -indicate the error. +will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_mutex_destroy will fail if: .Bl -tag -width Er +.It Bq Er EBUSY +.Fa Mutex +is locked by another thread. .It Bq Er EINVAL The value specified by .Fa mutex is invalid. -.It Bq Er EBUSY -.Fa Mutex -is locked by another thread. .El .Sh SEE ALSO .Xr pthread_mutex_init 3 , diff --git a/pthreads/pthread_mutex_init.3 b/pthreads/pthread_mutex_init.3 index bd6e2f5..bebe8a2 100644 --- a/pthreads/pthread_mutex_init.3 +++ b/pthreads/pthread_mutex_init.3 @@ -36,7 +36,10 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_mutex_init "pthread_mutex_t *mutex" "const pthread_mutexattr_t *attr" +.Fo pthread_mutex_init +.Fa "pthread_mutex_t *restrict mutex" +.Fa "const pthread_mutexattr_t *restrict attr" +.Fc .Sh DESCRIPTION The .Fn pthread_mutex_init @@ -44,25 +47,25 @@ function creates a new mutex, with attributes specified with .Fa attr . If .Fa attr -is NULL the default attributes are used. +is NULL, the default attributes are used. .Sh RETURN VALUES If successful, .Fn pthread_mutex_init will return zero and put the new mutex id into -.Fa mutex , -otherwise an error number will be returned to indicate the error. +.Fa mutex . +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_mutex_init will fail if: .Bl -tag -width Er +.It Bq Er EAGAIN +The system temporarily lacks the resources to create another mutex. .It Bq Er EINVAL The value specified by .Fa attr is invalid. .It Bq Er ENOMEM The process cannot allocate enough memory to create another mutex. -.It Bq Er EAGAIN -The temporarily lacks the resources to create another mutex. .El .Sh SEE ALSO .Xr pthread_mutex_destroy 3 , diff --git a/pthreads/pthread_mutex_lock.3 b/pthreads/pthread_mutex_lock.3 index 468bd0c..e0a4fad 100644 --- a/pthreads/pthread_mutex_lock.3 +++ b/pthreads/pthread_mutex_lock.3 @@ -36,7 +36,9 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_mutex_lock "pthread_mutex_t *mutex" +.Fo pthread_mutex_lock +.Fa "pthread_mutex_t *mutex" +.Fc .Sh DESCRIPTION The .Fn pthread_mutex_lock @@ -47,19 +49,19 @@ mutex becomes available. .Sh RETURN VALUES If successful, .Fn pthread_mutex_lock -will return zero, otherwise an error number will be returned to -indicate the error. +will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_mutex_lock will fail if: .Bl -tag -width Er +.It Bq Er EDEADLK +A deadlock would occur if the thread blocked waiting for +.Fa mutex . .It Bq Er EINVAL The value specified by .Fa mutex is invalid. -.It Bq Er EDEADLK -A deadlock would occur if the thread blocked waiting for -.Fa mutex . .El .Sh SEE ALSO .Xr pthread_mutex_destroy 3 , diff --git a/pthreads/pthread_mutex_trylock.3 b/pthreads/pthread_mutex_trylock.3 index 87fac64..345a014 100644 --- a/pthreads/pthread_mutex_trylock.3 +++ b/pthreads/pthread_mutex_trylock.3 @@ -36,7 +36,9 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_mutex_trylock "pthread_mutex_t *mutex" +.Fo pthread_mutex_trylock +.Fa "pthread_mutex_t *mutex" +.Fc .Sh DESCRIPTION The .Fn pthread_mutex_trylock @@ -48,19 +50,19 @@ will not block waiting for the mutex, but will return an error condition. .Sh RETURN VALUES If successful, .Fn pthread_mutex_trylock -will return zero, otherwise an error number will be returned to -indicate the error. +will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_mutex_trylock will fail if: .Bl -tag -width Er +.It Bq Er EBUSY +.Fa Mutex +is already locked. .It Bq Er EINVAL The value specified by .Fa mutex is invalid. -.It Bq Er EBUSY -.Fa Mutex -is already locked. .El .Sh SEE ALSO .Xr pthread_mutex_destroy 3 , diff --git a/pthreads/pthread_mutex_unlock.3 b/pthreads/pthread_mutex_unlock.3 index 38c509f..08ef98e 100644 --- a/pthreads/pthread_mutex_unlock.3 +++ b/pthreads/pthread_mutex_unlock.3 @@ -36,7 +36,9 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_mutex_unlock "pthread_mutex_t *mutex" +.Fo pthread_mutex_unlock +.Fa "pthread_mutex_t *mutex" +.Fc .Sh DESCRIPTION If the current thread holds the lock on .Fa mutex , @@ -47,10 +49,10 @@ function unlocks .Sh RETURN VALUES If successful, .Fn pthread_mutex_unlock -will return zero, otherwise an error number will be returned to -indicate the error. +will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS -.Fn pthread_mutex_trylock +.Fn pthread_mutex_unlock will fail if: .Bl -tag -width Er .It Bq Er EINVAL diff --git a/pthreads/pthread_mutexattr.3 b/pthreads/pthread_mutexattr.3 index e8aeba9..229c37f 100644 --- a/pthreads/pthread_mutexattr.3 +++ b/pthreads/pthread_mutexattr.3 @@ -57,33 +57,73 @@ .Dt PTHREAD_MUTEXATTR 3 .Os .Sh NAME -.Nm pthread_mutexattr_init , .Nm pthread_mutexattr_destroy , -.Nm pthread_mutexattr_setprioceiling , .Nm pthread_mutexattr_getprioceiling , -.Nm pthread_mutexattr_setprotocol , .Nm pthread_mutexattr_getprotocol , -.Nm pthread_mutexattr_settype , -.Nm pthread_mutexattr_gettype +.Nm pthread_mutexattr_gettype , +.Nm pthread_mutexattr_init , +.Nm pthread_mutexattr_setprioceiling , +.Nm pthread_mutexattr_setprotocol , +.Nm pthread_mutexattr_settype .Nd mutex attribute operations .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_mutexattr_init "pthread_mutexattr_t *attr" +.Fo pthread_mutexattr_destroy +.Fa "pthread_mutexattr_t *attr" +.Fc .Ft int -.Fn pthread_mutexattr_destroy "pthread_mutexattr_t *attr" +.Fo pthread_mutexattr_getprioceiling +.Fa "const pthread_mutexattr_t *attr" +.Fa "int *prioceiling" +.Fc +.\" To match the SUS, this should be: +.\" .Ft int +.\" .Fo pthread_mutexattr_getprioceiling +.\" .Fa "pthread_mutexattr_t *restrict attr" +.\" .Fa "int *restrict prioceiling" +.\" .Fc .Ft int -.Fn pthread_mutexattr_setprioceiling "pthread_mutexattr_t *attr" "int prioceiling" +.Fo pthread_mutexattr_getprotocol +.Fa "const pthread_mutexattr_t *attr" +.Fa "int *protocol" +.Fc +.\" To match the SUS, this should be: +.\" .Ft int +.\" .Fo pthread_mutexattr_getprotocol +.\" .Fa "pthread_mutexattr_t *restrict attr" +.\" .Fa "int *restrict protocol" +.\" .Fc .Ft int -.Fn pthread_mutexattr_getprioceiling "pthread_mutexattr_t *attr" "int *prioceiling" +.Fo pthread_mutexattr_gettype +.Fa "const pthread_mutexattr_t *attr" +.Fa "int *type" +.Fc +.\" To match the SUS, this should be: +.\" .Ft int +.\" .Fo pthread_mutexattr_gettype +.\" .Fa "pthread_mutexattr_t *restrict attr" +.\" .Fa "int *restrict type" +.\" .Fc .Ft int -.Fn pthread_mutexattr_setprotocol "pthread_mutexattr_t *attr" "int protocol" +.Fo pthread_mutexattr_init +.Fa "pthread_mutexattr_t *attr" +.Fc .Ft int -.Fn pthread_mutexattr_getprotocol "pthread_mutexattr_t *attr" "int *protocol" +.Fo pthread_mutexattr_setprioceiling +.Fa "pthread_mutexattr_t *attr" +.Fa "int prioceiling" +.Fc .Ft int -.Fn pthread_mutexattr_settype "pthread_mutexattr_t *attr" "int type" +.Fo pthread_mutexattr_setprotocol +.Fa "pthread_mutexattr_t *attr" +.Fa "int protocol" +.Fc .Ft int -.Fn pthread_mutexattr_gettype "pthread_mutexattr_t *attr" "int *type" +.Fo pthread_mutexattr_settype +.Fa "pthread_mutexattr_t *attr" +.Fa "int type" +.Fc .Sh DESCRIPTION Mutex attributes are used to specify parameters to .Fn pthread_mutex_init . @@ -95,7 +135,7 @@ The .Fn pthread_mutexattr_init function initializes .Fa attr -with all the default mutex attributes. +with all of the default mutex attributes. .Pp The .Fn pthread_mutexattr_destroy @@ -104,7 +144,7 @@ function destroys .Pp The .Fn pthread_mutexattr_settype -functions set the mutex type value of the attribute. Valid mutex types are: +function sets the mutex type value of the attribute. Valid mutex types are: .Dv PTHREAD_MUTEX_NORMAL , .Dv PTHREAD_MUTEX_ERRORCHECK , .Dv PTHREAD_MUTEX_RECURSIVE , @@ -115,7 +155,7 @@ The default mutex type for is .Dv PTHREAD_MUTEX_DEFAULT . .Pp -.Dv PTHREAD_MUXEX_NORMAL +.Dv PTHREAD_MUTEX_NORMAL mutexes do not check for usage errors. .Dv PTHREAD_MUTEX_NORMAL mutexes will deadlock if reentered, and result in undefined behavior if a @@ -128,14 +168,13 @@ mutex will result in undefined behavior. mutexes do check for usage errors. If an attempt is made to relock a .Dv PTHREAD_MUTEX_ERRORCHECK -mutex without first dropping the lock an error will be returned. If a thread -attempts to unlock a +mutex without first dropping the lock, an error will be returned. +If a thread attempts to unlock a .Dv PTHREAD_MUTEX_ERRORCHECK mutex that is locked by another thread, an error will be returned. If a -thread attemps to unlock a +thread attempts to unlock a .Dv PTHREAD_MUTEX_ERRORCHECK -thread that is unlocked, an error will be -returned. +thread that is unlocked, an error will be returned. .Pp .Dv PTHREAD_MUTEX_RECURSIVE mutexes allow recursive locking. diff --git a/pthreads/pthread_once.3 b/pthreads/pthread_once.3 index d9d5685..1a84320 100644 --- a/pthreads/pthread_once.3 +++ b/pthreads/pthread_once.3 @@ -90,11 +90,10 @@ is undefined if has automatic storage duration or is not initialized by .Fa PTHREAD_ONCE_INIT . .Sh RETURN VALUES -If successful, the +If successful, the .Fn pthread_once function will return zero. -Otherwise an error number will be returned to -indicate the error. +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS None. .Sh STANDARDS diff --git a/pthreads/pthread_rwlock.c b/pthreads/pthread_rwlock.c index e78cc3c..92dd740 100644 --- a/pthreads/pthread_rwlock.c +++ b/pthreads/pthread_rwlock.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -56,22 +56,113 @@ */ #include "pthread_internals.h" +extern int __unix_conforming; + +#include "plockstat.h" +#define READ_LOCK_PLOCKSTAT 0 +#define WRITE_LOCK_PLOCKSTAT 1 + +#define BLOCK_FAIL_PLOCKSTAT 0 +#define BLOCK_SUCCESS_PLOCKSTAT 1 /* maximum number of times a read lock may be obtained */ -#define MAX_READ_LOCKS (INT_MAX - 1) +#define MAX_READ_LOCKS (INT_MAX - 1) + + +#ifndef BUILDING_VARIANT /* [ */ + + +int +pthread_rwlockattr_init(pthread_rwlockattr_t *attr) +{ + attr->sig = _PTHREAD_RWLOCK_ATTR_SIG; + attr->pshared = _PTHREAD_DEFAULT_PSHARED; + return (0); +} + +int +pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr) +{ + attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */ + attr->pshared = 0; + return (0); +} + +int +pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, + int *pshared) +{ + if (attr->sig == _PTHREAD_RWLOCK_ATTR_SIG) + { + *pshared = (int)attr->pshared; + return (0); + } else + { + return (EINVAL); /* Not an initialized 'attribute' structure */ + } +} + +/* Temp: untill pshared is fixed right */ +#ifdef PR_5243343 +/* 5243343 - temporary hack to detect if we are running the conformance test */ +extern int PR_5243343_flag; +#endif /* PR_5243343 */ + +int +pthread_rwlockattr_setpshared(pthread_rwlockattr_t * attr, int pshared) +{ + if (attr->sig == _PTHREAD_RWLOCK_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 + { + return (EINVAL); /* Invalid parameter */ + } + } else + { + return (EINVAL); /* Not an initialized 'attribute' structure */ + } + +} + +#endif /* !BUILDING_VARIANT ] */ int pthread_rwlock_destroy(pthread_rwlock_t *rwlock) { + int ret; if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { return(EINVAL); } 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(ESUCCESS); + return(0); } } @@ -79,6 +170,15 @@ int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) { int ret; +#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) && (rwlock->state !=0 )) { + return(EBUSY); + } +#endif /* __DARWIN_UNIX03 */ /* initialize the lock */ if ((ret = pthread_mutex_init(&rwlock->lock, NULL)) != 0) @@ -101,9 +201,15 @@ pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) } 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(ESUCCESS); + return(0); } } } @@ -113,35 +219,66 @@ int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) { int ret; +#if __DARWIN_UNIX03 + pthread_t self = pthread_self(); +#endif 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) + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, EINVAL); return(EINVAL); + } /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) + 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 */ - while (rwlock->blocked_writers || rwlock->state < 0) { + 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); } + + PLOCKSTAT_RW_BLOCKED(rwlock, READ_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); } /* check lock count */ - if (rwlock->state == MAX_READ_LOCKS) + if (rwlock->state == MAX_READ_LOCKS) { ret = EAGAIN; - else + PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); + } + else { ++rwlock->state; /* indicate we are locked for reading */ + PLOCKSTAT_RW_ACQUIRE(rwlock, READ_LOCK_PLOCKSTAT); + } /* * Something is really wrong if this call fails. Returning @@ -158,27 +295,41 @@ int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) { int ret; +#if __DARWIN_UNIX03 + pthread_t self = pthread_self(); +#endif /* 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 (rwlock->sig != _PTHREAD_RWLOCK_SIG) + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, EINVAL); return(EINVAL); + } /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) + if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) { + PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); return(ret); + } /* give writers priority over readers */ - if (rwlock->blocked_writers || rwlock->state < 0) + if (rwlock->blocked_writers || rwlock->state < 0) { ret = EBUSY; - else if (rwlock->state == MAX_READ_LOCKS) + PLOCKSTAT_RW_ERROR(rwlock, READ_LOCK_PLOCKSTAT, ret); + } + else if (rwlock->state == MAX_READ_LOCKS) { ret = EAGAIN; /* too many read locks acquired */ - else + 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); @@ -190,25 +341,41 @@ int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) { int ret; +#if __DARWIN_UNIX03 + pthread_t self = pthread_self(); +#endif /* __DARWIN_UNIX03 */ /* 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 (rwlock->sig != _PTHREAD_RWLOCK_SIG) + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); return(EINVAL); + } /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) + if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) { + PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, ret); return(ret); + } + - if (rwlock->state != 0) + if (rwlock->state != 0) { ret = EBUSY; - else + PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, ret); + } + else { /* 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); @@ -220,18 +387,29 @@ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) { int ret; + int writer = (rwlock < 0) ? 1:0; +#if __DARWIN_UNIX03 + pthread_t self = pthread_self(); +#endif /* __DARWIN_UNIX03 */ - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + PLOCKSTAT_RW_ERROR(rwlock, writer, EINVAL); return(EINVAL); + } /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) + if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) { + PLOCKSTAT_RW_ERROR(rwlock, writer, ret); return(ret); + } 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 __DARWIN_UNIX03 + rwlock->owner = (pthread_t)0; +#endif /* __DARWIN_UNIX03 */ if (rwlock->blocked_writers) ret = pthread_cond_signal(&rwlock->write_signal); @@ -240,6 +418,12 @@ pthread_rwlock_unlock(pthread_rwlock_t *rwlock) } else ret = EINVAL; + if (ret == 0) { + PLOCKSTAT_RW_RELEASE(rwlock, writer); + } else { + PLOCKSTAT_RW_ERROR(rwlock, writer, ret); + } + /* see the comment on this in pthread_rwlock_rdlock */ pthread_mutex_unlock(&rwlock->lock); @@ -250,36 +434,60 @@ int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) { int ret; +#if __DARWIN_UNIX03 + pthread_t self = pthread_self(); +#endif /* __DARWIN_UNIX03 */ /* 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 (rwlock->sig != _PTHREAD_RWLOCK_SIG) + if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { + PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); return(EINVAL); + } /* grab the monitor lock */ - if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) + if ((ret = pthread_mutex_lock(&rwlock->lock)) != 0) { + PLOCKSTAT_RW_ERROR(rwlock, WRITE_LOCK_PLOCKSTAT, ret); return(ret); + } +#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); } + PLOCKSTAT_RW_BLOCKED(rwlock, WRITE_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); + --rwlock->blocked_writers; } /* 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); @@ -287,55 +495,4 @@ pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) return(ret); } -int -pthread_rwlockattr_init(pthread_rwlockattr_t *attr) -{ - attr->sig = _PTHREAD_RWLOCK_ATTR_SIG; - attr->pshared = PTHREAD_PROCESS_PRIVATE; - return (ESUCCESS); -} - -int -pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr) -{ - attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */ - attr->pshared = 0; - return (ESUCCESS); -} - -int -pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, - int *pshared) -{ - if (attr->sig == _PTHREAD_RWLOCK_ATTR_SIG) - { - /* *pshared = (int)attr->pshared; */ - *pshared = (int)PTHREAD_PROCESS_PRIVATE; - return (ESUCCESS); - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - - -int -pthread_rwlockattr_setpshared(pthread_rwlockattr_t * attr, int pshared) -{ - if (attr->sig == _PTHREAD_RWLOCK_ATTR_SIG) - { - if ( pshared == PTHREAD_PROCESS_PRIVATE) - { - attr->pshared = pshared ; - return (ESUCCESS); - } else - { - return (EINVAL); /* Invalid parameter */ - } - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } - -} diff --git a/pthreads/pthread_rwlock_destroy.3 b/pthreads/pthread_rwlock_destroy.3 index 2e77f37..47beb62 100644 --- a/pthreads/pthread_rwlock_destroy.3 +++ b/pthreads/pthread_rwlock_destroy.3 @@ -33,7 +33,9 @@ .Sh SYNOPSIS .In pthread.h .Ft int -.Fn pthread_rwlock_destroy "pthread_rwlock_t *lock" +.Fo pthread_rwlock_destroy +.Fa "pthread_rwlock_t *rwlock" +.Fc .Sh DESCRIPTION The .Fn pthread_rwlock_destroy @@ -42,8 +44,8 @@ function is used to destroy a read/write lock previously created with .Sh RETURN VALUES If successful, the .Fn pthread_rwlock_destroy -function will return zero. Otherwise an error number will be returned -to indicate the error. +function will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh SEE ALSO .Xr pthread_rwlock_init 3 .Sh STANDARDS @@ -66,11 +68,11 @@ function may fail if: .Bl -tag -width Er .It Bq Er EBUSY The system has detected an attempt to destroy the object referenced by -.Fa lock +.Fa rwlock while it is locked. .It Bq Er EINVAL The value specified by -.Fa lock +.Fa rwlock is invalid. .El .Sh HISTORY diff --git a/pthreads/pthread_rwlock_init.3 b/pthreads/pthread_rwlock_init.3 index 6a47d38..507317a 100644 --- a/pthreads/pthread_rwlock_init.3 +++ b/pthreads/pthread_rwlock_init.3 @@ -33,7 +33,10 @@ .Sh SYNOPSIS .In pthread.h .Ft int -.Fn pthread_rwlock_init "pthread_rwlock_t *lock" "const pthread_rwlockattr_t *attr" +.Fo pthread_rwlock_init +.Fa "pthread_rwlock_t *restrict rwlock" +.Fa "const pthread_rwlockattr_t *restrict attr" +.Fc .Sh DESCRIPTION The .Fn pthread_rwlock_init @@ -50,12 +53,12 @@ with an already initialized lock are undefined. .Sh RETURN VALUES If successful, the .Fn pthread_rwlock_init -function will return zero. Otherwise an error number will be returned -to indicate the error. +function will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh SEE ALSO +.Xr pthread_rwlock_destroy 3 , .Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 , -.Xr pthread_rwlock_destroy 3 +.Xr pthread_rwlockattr_setpshared 3 .Sh STANDARDS The .Fn pthread_rwlock_init @@ -83,7 +86,7 @@ function may fail if: .It Bq Er EBUSY The system has detected an attempt to re-initialize the object referenced by -.Fa lock , +.Fa rwlock , a previously initialized but not yet destroyed read/write lock. .It Bq Er EINVAL The value specified by diff --git a/pthreads/pthread_rwlock_rdlock.3 b/pthreads/pthread_rwlock_rdlock.3 index b703359..815da8c 100644 --- a/pthreads/pthread_rwlock_rdlock.3 +++ b/pthreads/pthread_rwlock_rdlock.3 @@ -34,16 +34,20 @@ .Sh SYNOPSIS .In pthread.h .Ft int -.Fn pthread_rwlock_rdlock "pthread_rwlock_t *lock" +.Fo pthread_rwlock_rdlock +.Fa "pthread_rwlock_t *rwlock" +.Fc .Ft int -.Fn pthread_rwlock_tryrdlock "pthread_rwlock_t *lock" +.Fo pthread_rwlock_tryrdlock +.Fa "pthread_rwlock_t *rwlock" +.Fc .Sh DESCRIPTION The .Fn pthread_rwlock_rdlock function acquires a read lock on -.Fa lock +.Fa rwlock , provided that -.Fa lock +.Fa rwlock is not presently held for writing and no writer threads are presently blocked on the lock. If the read lock cannot be immediately acquired, the calling thread blocks until it can @@ -52,7 +56,7 @@ acquire the lock. The .Fn pthread_rwlock_tryrdlock function performs the same action, but does not block if the lock -cannot be immediately obtained (i.e. the lock is held for writing +cannot be immediately obtained (i.e., the lock is held for writing or there are waiting writers). .Pp A thread may hold multiple concurrent read locks. If so, @@ -68,8 +72,8 @@ If successful, the .Fn pthread_rwlock_rdlock and .Fn pthread_rwlock_tryrdlock -functions will return zero. Otherwise an error number will be returned -to indicate the error. +functions will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh SEE ALSO .Xr pthread_rwlock_init 3 , .Xr pthread_rwlock_trywrlock 3 , @@ -88,7 +92,7 @@ The function will fail if: .Bl -tag -width Er .It Bq Er EBUSY -The lock could not be acquired because a writer holds the lock or +The lock could not be acquired, because a writer holds the lock or was blocked on it. .El .Pp @@ -99,17 +103,17 @@ and functions may fail if: .Bl -tag -width Er .It Bq Er EAGAIN -The lock could not be acquired because the maximum number of read locks +The lock could not be acquired, because the maximum number of read locks against .Fa lock has been exceeded. .It Bq Er EDEADLK The current thread already owns -.Fa lock +.Fa rwlock for writing. .It Bq Er EINVAL The value specified by -.Fa lock +.Fa rwlock is invalid. .It Bq Er ENOMEM Insufficient memory exists to initialize the lock (applies to diff --git a/pthreads/pthread_rwlock_unlock.3 b/pthreads/pthread_rwlock_unlock.3 index 4384cec..def7aaf 100644 --- a/pthreads/pthread_rwlock_unlock.3 +++ b/pthreads/pthread_rwlock_unlock.3 @@ -33,7 +33,9 @@ .Sh SYNOPSIS .In pthread.h .Ft int -.Fn pthread_rwlock_unlock "pthread_rwlock_t *lock" +.Fo pthread_rwlock_unlock +.Fa "pthread_rwlock_t *rwlock" +.Fc .Sh DESCRIPTION The .Fn pthread_rwlock_unlock @@ -46,11 +48,11 @@ or .Sh RETURN VALUES If successful, the .Fn pthread_rwlock_unlock -function will return zero. Otherwise an error number will be returned -to indicate the error. +function will return zero. +Otherwise, an error number will be returned to indicate the error. .Pp The results are undefined if -.Fa lock +.Fa rwlock is not held by the calling thread. .Sh SEE ALSO .Xr pthread_rwlock_rdlock 3 , @@ -67,7 +69,7 @@ function may fail if: .Bl -tag -width Er .It Bq Er EINVAL The value specified by -.Fa lock +.Fa rwlock is invalid. .It Bq Er EPERM The current thread does not own the read/write lock. diff --git a/pthreads/pthread_rwlock_wrlock.3 b/pthreads/pthread_rwlock_wrlock.3 index f30df5a..5906e4b 100644 --- a/pthreads/pthread_rwlock_wrlock.3 +++ b/pthreads/pthread_rwlock_wrlock.3 @@ -28,20 +28,24 @@ .Dt PTHREAD_RWLOCK_WRLOCK 3 .Os .Sh NAME -.Nm pthread_rwlock_wrlock , -.Nm pthread_rwlock_trywrlock +.Nm pthread_rwlock_trywrlock , +.Nm pthread_rwlock_wrlock .Nd acquire a read/write lock for writing .Sh SYNOPSIS .In pthread.h .Ft int -.Fn pthread_rwlock_wrlock "pthread_rwlock_t *lock" +.Fo pthread_rwlock_trywrlock +.Fa "pthread_rwlock_t *rwlock" +.Fc .Ft int -.Fn pthread_rwlock_trywrlock "pthread_rwlock_t *lock" +.Fo pthread_rwlock_wrlock +.Fa "pthread_rwlock_t *rwlock" +.Fc .Sh DESCRIPTION The .Fn pthread_rwlock_wrlock function blocks until a write lock can be acquired against -.Fa lock . +.Fa rwlock . The .Fn pthread_rwlock_trywrlock function performs the same action, but does not block if the lock @@ -56,8 +60,8 @@ If successful, the .Fn pthread_rwlock_wrlock and .Fn pthread_rwlock_trywrlock -functions will return zero. Otherwise an error number will be returned -to indicate the error. +functions will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh SEE ALSO .Xr pthread_rwlock_trywrlock 3 , .Xr pthread_rwlock_unlock 3 , @@ -89,7 +93,7 @@ The calling thread already owns the read/write lock (for reading or writing). .It Bq Er EINVAL The value specified by -.Fa lock +.Fa rwlock is invalid. .It Bq Er ENOMEM Insufficient memory exists to initialize the lock (applies to diff --git a/pthreads/pthread_rwlockattr_destroy.3 b/pthreads/pthread_rwlockattr_destroy.3 index 5a7a143..3d45228 100644 --- a/pthreads/pthread_rwlockattr_destroy.3 +++ b/pthreads/pthread_rwlockattr_destroy.3 @@ -33,18 +33,20 @@ .Sh SYNOPSIS .In pthread.h .Ft int -.Fn pthread_rwlockattr_destroy "pthread_rwlockattr_t *attr" +.Fo pthread_rwlockattr_destroy +.Fa "pthread_rwlockattr_t *attr" +.Fc .Sh DESCRIPTION The .Fn pthread_rwlockattr_destroy -function is used to destroy a read/write lock attribute object +function is used to destroy a read/write lock attribute object, previously created with .Fn pthread_rwlockattr_init . .Sh RETURN VALUES If successful, the .Fn pthread_rwlockattr_destroy -function will return zero. Otherwise an error number will be returned -to indicate the error. +function will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh SEE ALSO .Xr pthread_rwlockattr_init 3 .Sh STANDARDS diff --git a/pthreads/pthread_rwlockattr_getpshared.3 b/pthreads/pthread_rwlockattr_getpshared.3 index a07c37b..61dcc73 100644 --- a/pthreads/pthread_rwlockattr_getpshared.3 +++ b/pthreads/pthread_rwlockattr_getpshared.3 @@ -33,11 +33,14 @@ .Sh SYNOPSIS .In pthread.h .Ft int -.Fn pthread_rwlockattr_getpshared "const pthread_rwlockattr_t *attr" "int *pshared" +.Fo pthread_rwlockattr_getpshared +.Fa "const pthread_rwlockattr_t *restrict attr" +.Fa "int *restrict pshared" +.Fc .Sh DESCRIPTION The .Fn pthread_rwlockattr_getpshared -function is used to get the process shared setting of a read/write +function is used to get the process-shared setting of a read/write lock attribute object. The setting is returned via .Fa pshared , and may be one of two values: @@ -53,12 +56,12 @@ the default value. .Sh RETURN VALUES If successful, the .Fn pthread_rwlockattr_getpshared -function will return zero. Otherwise an error number will be returned -to indicate the error. +function will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh SEE ALSO +.Xr pthread_rwlock_init 3 , .Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 , -.Xr pthread_rwlock_init 3 +.Xr pthread_rwlockattr_setpshared 3 .Sh STANDARDS The .Fn pthread_rwlockattr_getpshared diff --git a/pthreads/pthread_rwlockattr_init.3 b/pthreads/pthread_rwlockattr_init.3 index 6d125e6..1d75a3c 100644 --- a/pthreads/pthread_rwlockattr_init.3 +++ b/pthreads/pthread_rwlockattr_init.3 @@ -33,21 +33,23 @@ .Sh SYNOPSIS .In pthread.h .Ft int -.Fn pthread_rwlockattr_init "pthread_rwlockattr_t *attr" +.Fo pthread_rwlockattr_init +.Fa "pthread_rwlockattr_t *attr" +.Fc .Sh DESCRIPTION The .Fn pthread_rwlockattr_init -function is used to initialize a read/write lock attributes object. +function is used to initialize a read/write lock attribute object. .Sh RETURN VALUES If successful, the .Fn pthread_rwlockattr_init -function will return zero. Otherwise an error number will be returned -to indicate the error. +function will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh SEE ALSO +.Xr pthread_rwlock_init 3 , .Xr pthread_rwlockattr_destroy 3 , .Xr pthread_rwlockattr_getpshared 3 , -.Xr pthread_rwlockattr_setpshared 3 , -.Xr pthread_rwlock_init 3 +.Xr pthread_rwlockattr_setpshared 3 .Sh STANDARDS The .Fn pthread_rwlockattr_init diff --git a/pthreads/pthread_rwlockattr_setpshared.3 b/pthreads/pthread_rwlockattr_setpshared.3 index 9824c63..d8702b9 100644 --- a/pthreads/pthread_rwlockattr_setpshared.3 +++ b/pthreads/pthread_rwlockattr_setpshared.3 @@ -33,11 +33,14 @@ .Sh SYNOPSIS .In pthread.h .Ft int -.Fn pthread_rwlockattr_setpshared "pthread_rwlockattr_t *attr" "int pshared" +.Fo pthread_rwlockattr_setpshared +.Fa "pthread_rwlockattr_t *attr" +.Fa "int pshared" +.Fc .Sh DESCRIPTION The .Fn pthread_rwlockattr_setpshared -function sets the process shared attribute of +function sets the process-shared attribute of .Fa attr to the value referenced by .Fa pshared . @@ -55,12 +58,12 @@ the default value. .Sh RETURN VALUES If successful, the .Fn pthread_rwlockattr_setpshared -function will return zero. Otherwise an error number will be returned -to indicate the error. +function will return zero. +Otherwise, an error number will be returned to indicate the error. .Sh SEE ALSO +.Xr pthread_rwlock_init 3 , .Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 , -.Xr pthread_rwlock_init 3 +.Xr pthread_rwlockattr_setpshared 3 .Sh STANDARDS The .Fn pthread_rwlockattr_setpshared diff --git a/pthreads/pthread_setcancelstate.3 b/pthreads/pthread_setcancelstate.3 index c68970c..f8f5ba0 100644 --- a/pthreads/pthread_setcancelstate.3 +++ b/pthreads/pthread_setcancelstate.3 @@ -10,11 +10,19 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_setcancelstate "int state" "int *oldstate" +.Fo pthread_setcancelstate +.Fa "int state" +.Fa "int *oldstate" +.Fc .Ft int -.Fn pthread_setcanceltype "int type" "int *oldtype" +.Fo pthread_setcanceltype +.Fa "int type" +.Fa "int *oldtype" +.Fc .Ft void -.Fn pthread_testcancel "void" +.Fo pthread_testcancel +.Fa "void" +.Fc .Sh DESCRIPTION The .Fn pthread_setcancelstate @@ -156,7 +164,7 @@ Second, the cancelability type may be explicitly set to either or .Em asynchronous upon entry to an object. -But as with the cancelability state, on exit from +But, as with the cancelability state, on exit from an object that cancelability type should always be restored to its value on entry to the object. .Pp diff --git a/pthreads/pthread_setspecific.3 b/pthreads/pthread_setspecific.3 index f820eb8..96104b4 100644 --- a/pthreads/pthread_setspecific.3 +++ b/pthreads/pthread_setspecific.3 @@ -39,7 +39,10 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn pthread_setspecific "pthread_key_t key" "const void *value" +.Fo pthread_setspecific +.Fa "pthread_key_t key" +.Fa "const void *value" +.Fc .Sh DESCRIPTION The .Fn pthread_setspecific @@ -47,7 +50,7 @@ function associates a thread-specific value with a .Fa key obtained via a previous call to .Fn pthread_key_create . -Different threads man bind different values to the same key. +Different threads may bind different values to the same key. These values are typically pointers to blocks of dynamically allocated memory that have been reserved for use by the calling thread. @@ -55,33 +58,32 @@ reserved for use by the calling thread. The effect of calling .Fn pthread_setspecific with a key value not obtained from -.Fn pthread_key_create +.Fn pthread_key_create , or after .Fa key has been deleted with -.Fn pthread_key_delete +.Fn pthread_key_delete , is undefined. .Pp .Fn pthread_setspecific -may be called from a thread-specific data destructor function, however this -may result in lost storage or infinite loops. +may be called from a thread-specific data destructor function; +however, this may result in lost storage or infinite loops. .Sh RETURN VALUES If successful, the .Fn pthread_setspecific function will return zero. -Otherwise an error number will be returned to -indicate the error. +Otherwise, an error number will be returned to indicate the error. .Sh ERRORS .Fn pthread_setspecific will fail if: .Bl -tag -width Er -.It Bq Er ENOMEM -Insufficient memory exists to associate the value with the -.Fa key . .It Bq Er EINVAL The .Fa key value is invalid. +.It Bq Er ENOMEM +Insufficient memory exists to associate the value with the +.Fa key . .El .Sh SEE ALSO .Xr pthread_getspecific 3 , diff --git a/pthreads/pthread_tsd.c b/pthreads/pthread_tsd.c index 91cdf3c..29e0efc 100644 --- a/pthreads/pthread_tsd.c +++ b/pthreads/pthread_tsd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -57,15 +57,27 @@ static struct { int created; /* Set TRUE if 'create_key' used this slot */ void (*destructor)(void *); -} _pthread_keys[_POSIX_THREAD_KEYS_MAX]; +} _pthread_keys[_INTERNAL_POSIX_THREAD_KEYS_END]; static pthread_lock_t tds_lock = LOCK_INITIALIZER; + /* * Partition _pthread_keys in a lower part that dyld can use, and an upper * part for libSystem. The libSystem part starts at __pthread_tsd_first = 4. * dyld will set this value to 1. + * LEFT OVER TILL DYLD changes to using static (1-3) numbers */ -__private_extern__ int __pthread_tsd_first = 4; +#ifdef DYLD_STATIC_LIBC_BUILD +__private_extern__ int __pthread_tsd_first = 1; +__private_extern__ int __pthread_tsd_start = 5; +__private_extern__ int __pthread_tsd_end = 10; +__private_extern__ int __pthread_tsd_max = 10; +#else +__private_extern__ int __pthread_tsd_first = 10; +__private_extern__ int __pthread_tsd_start = _INTERNAL_POSIX_THREAD_KEYS_MAX; +__private_extern__ int __pthread_tsd_end = _INTERNAL_POSIX_THREAD_KEYS_END; +__private_extern__ int __pthread_tsd_max = 10; +#endif /* * Create a new key for thread specific data */ @@ -75,16 +87,16 @@ pthread_key_create(pthread_key_t *key, { int res, i; LOCK(tds_lock); - res = ENOMEM; /* No 'free' keys */ + res = EAGAIN; /* No 'free' keys, return EAGAIN (as per standard) */ /* The first slot is reserved for pthread_self() */ - for (i = __pthread_tsd_first; i < _POSIX_THREAD_KEYS_MAX; i++) + for (i = __pthread_tsd_start; i < __pthread_tsd_end; i++) { if (_pthread_keys[i].created == FALSE) { _pthread_keys[i].created = TRUE; _pthread_keys[i].destructor = destructor; *key = i; - res = ESUCCESS; + res = 0; break; } } @@ -101,7 +113,7 @@ pthread_key_delete(pthread_key_t key) int res; LOCK(tds_lock); /* The first slot is reserved for pthread_self() */ - if ((key >= __pthread_tsd_first) && (key < _POSIX_THREAD_KEYS_MAX)) + if ((key >= __pthread_tsd_start) && (key < __pthread_tsd_end)) { if (_pthread_keys[key].created) { @@ -109,12 +121,12 @@ pthread_key_delete(pthread_key_t key) _pthread_keys[key].created = FALSE; LOCK(_pthread_list_lock); - LIST_FOREACH(p, &__pthread_head, plist) { + TAILQ_FOREACH(p, &__pthread_head, plist) { /* It is an 32bit value no lock needed */ p->tsd[key] = 0; } UNLOCK(_pthread_list_lock); - res = ESUCCESS; + res = 0; } else { res = EINVAL; @@ -143,13 +155,18 @@ pthread_setspecific(pthread_key_t key, int res; pthread_t self; /* The first slot is reserved for pthread_self() */ - if ((key >= __pthread_tsd_first) && (key < _POSIX_THREAD_KEYS_MAX)) + if ((key >= __pthread_tsd_first) && (key < __pthread_tsd_end)) { - if (_pthread_keys[key].created) + if ((key < __pthread_tsd_start) || _pthread_keys[key].created) { self = pthread_self(); self->tsd[key] = (void *) value; - res = ESUCCESS; + res = 0; + if ((key < __pthread_tsd_start) && (_pthread_keys[key].created == FALSE)) + _pthread_keys[key].created = TRUE; + + if (key > self->max_tsd_key) + self->max_tsd_key = key; } else { res = EINVAL; @@ -169,10 +186,23 @@ _pthread_tsd_cleanup(pthread_t self) { int i, j; void *param; + for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++) { /* The first slot is reserved for pthread_self() */ - for (i = __pthread_tsd_first; i < _POSIX_THREAD_KEYS_MAX; i++) + + for (i = __pthread_tsd_first; i <= __pthread_tsd_max; i++) + { + if (_pthread_keys[i].created && (param = self->tsd[i])) + { + self->tsd[i] = (void *)NULL; + if (_pthread_keys[i].destructor) + { + (_pthread_keys[i].destructor)(param); + } + } + } + for (i = __pthread_tsd_start; i <= self->max_tsd_key; i++) { if (_pthread_keys[i].created && (param = self->tsd[i])) { @@ -184,4 +214,34 @@ _pthread_tsd_cleanup(pthread_t self) } } } + self->max_tsd_key = 0; } + +int +pthread_key_init_np(int key, void (*destructor)(void *)) +{ + if ((key >= __pthread_tsd_first) && (key < __pthread_tsd_start)) { + LOCK(tds_lock); + _pthread_keys[key].created = TRUE; + _pthread_keys[key].destructor = destructor; + + if (key > __pthread_tsd_max) + __pthread_tsd_max = key; + UNLOCK(tds_lock); + return (0); + } else + return(EINVAL); +} + +/* we need this till the switchover happens for the dyld. It get 1- 10 slot */ +void +_pthread_keys_init() +{ + if (__pthread_tsd_first == 1) { + __pthread_tsd_start = 5; + __pthread_tsd_end = 10; + __pthread_tsd_max = 10; + } + +} + diff --git a/pthreads/pthread_workqueue.h b/pthreads/pthread_workqueue.h new file mode 100644 index 0000000..c367822 --- /dev/null +++ b/pthreads/pthread_workqueue.h @@ -0,0 +1,74 @@ +/* + * 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@ + */ +/* pthread workqueue defns */ + +#ifndef _POSIX_PTHREAD_WORKQUEUE_H +#define _POSIX_PTHREAD_WORKQUEUE_H + +#include +#include + + +#define __PTHREAD_WORKQ_SIZE__ 128 +#define __PTHREAD_WORKQ_ATTR_SIZE__ 60 + +#define PTHEAD_WRKQUEUE_SIG 0xBEBEBEBE +#define PTHEAD_WRKQUEUE_ATTR_SIG 0xBEBEBEBE + +#ifndef __POSIX_LIB__ +typedef struct { unsigned int sig; char opaque[__PTHREAD_WORKQ_SIZE__];} *pthread_workqueue_t; +typedef struct { unsigned int sig; char opaque[__PTHREAD_WORKQ_ATTR_SIZE__]; } pthread_workqueue_attr_t; +#endif +typedef void * pthread_workitem_handle_t; + +__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_attr_setqueuepriority_np(pthread_workqueue_attr_t * attr, int qprio); + +#ifdef NOTYET +/* Following attributes not supported yet */ +int pthread_workqueue_attr_getstacksize_np(const pthread_workqueue_attr_t * attr, size_t * stacksizep); +int pthread_workqueue_attr_setstacksize_np(pthread_workqueue_attr_t * attr, size_t stacksize); +int pthread_workqueue_attr_getthreadtimeshare_np(const pthread_workqueue_attr_t * attr, int * istimesahrep); +int pthread_workqueue_attr_settthreadtimeshare_np(pthread_workqueue_attr_t * attr, int istimeshare); +int pthread_workqueue_attr_getthreadimportance_np(const pthread_workqueue_attr_t * attr, int * importancep); +int pthread_workqueue_attr_settthreadimportance_np(pthread_workqueue_attr_t * attr, int importance); +int pthread_workqueue_attr_getthreadaffinity_np(const pthread_workqueue_attr_t * attr, int * affinityp); +int pthread_workqueue_attr_settthreadaffinity_np(pthread_workqueue_attr_t * attr, int affinity); +#endif + +int pthread_workqueue_create_np(pthread_workqueue_t * workqp, const pthread_workqueue_attr_t * attr); +int pthread_workqueue_destroy_np(pthread_workqueue_t workq, void (* callback_func)(pthread_workqueue_t, void *), void * callback_arg); +int pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep); +int pthread_workqueue_removeitem_np(pthread_workqueue_t workq, pthread_workitem_handle_t itemhandle); +int pthread_workqueue_addbarrier_np(pthread_workqueue_t workq, void (* callback_func)(pthread_workqueue_t, void *), void * callback_arg, int waitforcallback, pthread_workitem_handle_t *itemhandlep); +int pthread_workqueue_suspend_np(pthread_workqueue_t workq); +int pthread_workqueue_resume_np(pthread_workqueue_t workq); + +__END_DECLS + +#endif /* _POSIX_PTHREAD_WORKQUEUE_H */ + diff --git a/pthreads/sched.h b/pthreads/sched.h index 5c5693d..df1fc51 100644 --- a/pthreads/sched.h +++ b/pthreads/sched.h @@ -32,7 +32,7 @@ __BEGIN_DECLS * Scheduling paramters */ #ifndef __POSIX_LIB__ -struct sched_param { int sched_priority; char opaque[__SCHED_PARAM_SIZE__]; }; +struct sched_param { int sched_priority; char __opaque[__SCHED_PARAM_SIZE__]; }; #endif extern int sched_yield(void); diff --git a/quad/Makefile.inc b/quad/Makefile.inc deleted file mode 100644 index a1335b9..0000000 --- a/quad/Makefile.inc +++ /dev/null @@ -1,19 +0,0 @@ -# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 -# $FreeBSD: src/lib/libc/quad/Makefile.inc,v 1.8 1999/08/28 00:00:27 peter Exp $ - -# Quad support, if needed -.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/quad ${.CURDIR}/../libc/quad - -.if ${MACHINE_ARCH} == "i386" - -MISRCS+= cmpdi2.c divdi3.c moddi3.c qdivrem.c ucmpdi2.c udivdi3.c umoddi3.c - -.else - -MISRCS+= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c fixdfdi.c \ - fixsfdi.c fixunsdfdi.c fixunssfdi.c floatdidf.c floatdisf.c \ - floatunsdidf.c iordi3.c lshldi3.c lshrdi3.c moddi3.c muldi3.c \ - negdi2.c notdi2.c qdivrem.c subdi3.c ucmpdi2.c udivdi3.c umoddi3.c \ - xordi3.c - -.endif diff --git a/regex/FreeBSD/engine.c.patch b/regex/FreeBSD/engine.c.patch index 1202eb5..b40e6d0 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-02-24 14:25:22.000000000 -0800 -@@ -270,7 +270,7 @@ ++++ engine.c 2005-04-18 16:52:09.000000000 -0700 +@@ -270,7 +270,7 @@ int eflags; break; assert(m->coldp < m->endp); m->coldp += XMBRTOWC(NULL, m->coldp, @@ -9,7 +9,7 @@ } if (nmatch == 1 && !g->backrefs) break; /* no further info needed */ -@@ -331,7 +331,7 @@ +@@ -331,7 +331,7 @@ int eflags; NOTE("false alarm"); /* recycle starting later */ start = m->coldp + XMBRTOWC(NULL, m->coldp, @@ -18,7 +18,7 @@ assert(start <= stop); } -@@ -409,7 +409,7 @@ +@@ -409,7 +409,7 @@ sopno stopst; assert(nope); break; case OCHAR: @@ -27,7 +27,7 @@ break; case OBOL: case OEOL: -@@ -418,7 +418,7 @@ +@@ -418,7 +418,7 @@ sopno stopst; break; case OANY: case OANYOF: @@ -36,7 +36,33 @@ break; case OBACK_: case O_BACK: -@@ -585,14 +585,14 @@ +@@ -479,6 +479,10 @@ sopno stopst; + sep = ssp; + ssp = oldssp; + } ++ else if (tail==rest) { ++ /* Fix for test expr 105 */ ++ ssp = oldssp; ++ } + 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; + i = OPND(m->g->strip[ss]); + assert(0 < i && i <= m->g->nsub); + m->pmatch[i].rm_so = sp - m->offp; ++ /* fix for T.regcomp 43: don't remember previous ++ subexpression matches beyond the current one (i) */ ++ i++; ++ while (i<= m->g->nsub) { ++ m->pmatch[i].rm_so = -1; ++ m->pmatch[i].rm_eo = -1; ++ i++; ++ } + break; + case ORPAREN: + i = OPND(m->g->strip[ss]); +@@ -585,14 +597,14 @@ sopno lev; /* PLUS nesting level */ case OCHAR: if (sp == stop) return(NULL); @@ -53,7 +79,7 @@ if (wc == BADCHAR) return (NULL); break; -@@ -600,8 +600,8 @@ +@@ -600,8 +612,8 @@ sopno lev; /* PLUS nesting level */ if (sp == stop) return (NULL); cs = &m->g->sets[OPND(s)]; @@ -64,7 +90,7 @@ return(NULL); break; case OBOL: -@@ -625,8 +625,8 @@ +@@ -625,8 +637,8 @@ sopno lev; /* PLUS nesting level */ (sp < m->endp && *(sp-1) == '\n' && (m->g->cflags®_NEWLINE)) || (sp > m->beginp && @@ -75,7 +101,7 @@ { /* yes */ } else return(NULL); -@@ -635,8 +635,8 @@ +@@ -635,8 +647,8 @@ sopno lev; /* PLUS nesting level */ if (( (sp == m->endp && !(m->eflags®_NOTEOL)) || (sp < m->endp && *sp == '\n' && (m->g->cflags®_NEWLINE)) || @@ -86,7 +112,7 @@ { /* yes */ } else return(NULL); -@@ -807,7 +807,7 @@ +@@ -807,7 +819,7 @@ sopno stopst; if (p == m->endp) c = OUT; else @@ -95,7 +121,7 @@ if (EQ(st, fresh)) coldp = p; -@@ -831,12 +831,12 @@ +@@ -831,12 +843,12 @@ sopno stopst; } /* how about a word boundary? */ @@ -112,7 +138,7 @@ flagch = EOW; } if (flagch == BOW || flagch == EOW) { -@@ -861,7 +861,7 @@ +@@ -861,7 +873,7 @@ sopno stopst; assert(coldp != NULL); m->coldp = coldp; if (ISSET(st, stopst)) @@ -121,7 +147,7 @@ else return(NULL); } -@@ -913,7 +913,7 @@ +@@ -913,7 +925,7 @@ sopno stopst; c = OUT; clen = 0; } else @@ -130,7 +156,7 @@ /* is there an EOL and/or BOL between lastc and c? */ flagch = '\0'; -@@ -935,12 +935,12 @@ +@@ -935,12 +947,12 @@ sopno stopst; } /* how about a word boundary? */ @@ -147,7 +173,7 @@ flagch = EOW; } if (flagch == BOW || flagch == EOW) { -@@ -1031,7 +1031,7 @@ +@@ -1031,7 +1043,7 @@ states aft; /* states already known re break; case OANYOF: cs = &g->sets[OPND(s)]; diff --git a/regex/FreeBSD/regcomp.c.patch b/regex/FreeBSD/regcomp.c.patch index 65aec8b..a52baac 100644 --- a/regex/FreeBSD/regcomp.c.patch +++ b/regex/FreeBSD/regcomp.c.patch @@ -1,5 +1,5 @@ --- regcomp.c.orig 2004-11-25 11:38:32.000000000 -0800 -+++ regcomp.c 2005-02-24 13:46:56.000000000 -0800 ++++ regcomp.c 2005-04-05 14:46:18.000000000 -0700 @@ -43,6 +43,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/regex/regcomp.c,v 1.34 2004/10/03 15:42:59 stefanf Exp $"); @@ -129,8 +129,34 @@ } /* -@@ -639,7 +661,7 @@ +@@ -609,12 +631,22 @@ + i = (c&~BACKSL) - '0'; + assert(i < NPAREN); + if (p->pend[i] != 0) { ++#if __DARWIN_UNIX03 ++ int skip = 1; ++#endif /* __DARWIN_UNIX03 */ + assert(i <= p->g->nsub); + EMIT(OBACK_, i); + assert(p->pbegin[i] != 0); + assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); + assert(OP(p->strip[p->pend[i]]) == ORPAREN); ++#if __DARWIN_UNIX03 ++ if (OP(p->strip[p->pbegin[i]+skip]) == OBOL) { ++ skip++; /* don't dup anchor in subexp */ ++ } ++ (void) dupl(p, p->pbegin[i]+skip, p->pend[i]); ++#else /* !__DARWIN_UNIX03 */ + (void) dupl(p, p->pbegin[i]+1, p->pend[i]); ++#endif /* __DARWIN_UNIX03 */ + EMIT(O_BACK, i); + } else + SETERROR(REG_ESUBREG); +@@ -637,9 +669,10 @@ + INSERT(OQUEST_, pos); + ASTERN(O_QUEST, pos); } else if (EATTWO('\\', '{')) { ++ (void)REQUIRE(MORE(), REG_EBRACE); count = p_count(p); if (EAT(',')) { - if (MORE() && isdigit((uch)PEEK())) { @@ -138,7 +164,7 @@ count2 = p_count(p); (void)REQUIRE(count <= count2, REG_BADBR); } else /* single number with comma */ -@@ -670,7 +692,7 @@ +@@ -670,7 +703,7 @@ int count = 0; int ndigits = 0; @@ -147,29 +173,30 @@ count = count*10 + (GETNEXT() - '0'); ndigits++; } -@@ -709,10 +731,21 @@ +@@ -709,10 +742,22 @@ cs->icase = 1; if (EAT('^')) cs->invert = 1; +#if __DARWIN_UNIX03 -+ if (PEEK2() != '-') { /* Don't eat '-' or ']' if they're part of ranges */ -+ if (EAT(']')) -+ CHadd(p, cs, ']'); -+ else if (EAT('-')) -+ CHadd(p, cs, '-'); -+ } -+ if (MORE() && !SEETWO('-',']')) /* Parse RE []-'] */ -+ p_b_term(p, cs); -+#else /* !__DARWIN_UNIX03 */ ++ if (PEEK2() != '-' && PEEK2() != ']') { /* Don't eat '-' or ']' if they're part of ranges ++ * but do process [^-] */ if (EAT(']')) CHadd(p, cs, ']'); else if (EAT('-')) CHadd(p, cs, '-'); ++ } ++ if (MORE() && !SEETWO('-',']')) /* Parse RE []-'] */ ++ p_b_term(p, cs); ++#else /* !__DARWIN_UNIX03 */ ++ if (EAT(']')) ++ CHadd(p, cs, ']'); ++ else if (EAT('-')) ++ CHadd(p, cs, '-'); +#endif /* __DARWIN_UNIX03 */ while (MORE() && PEEK() != ']' && !SEETWO('-', ']')) p_b_term(p, cs); if (EAT('-')) -@@ -725,7 +758,7 @@ +@@ -725,7 +770,7 @@ if (cs->invert && p->g->cflags®_NEWLINE) cs->bmp['\n' >> 3] |= 1 << ('\n' & 7); @@ -178,14 +205,14 @@ ordinary(p, ch); freeset(p, cs); } else -@@ -751,8 +784,16 @@ +@@ -751,8 +796,16 @@ c = (MORE2()) ? PEEK2() : '\0'; break; case '-': +#if __DARWIN_UNIX03 + if (PEEK2() != '-') { /* Allow [---] */ -+ SETERROR(REG_ERANGE); -+ return; /* NOTE RETURN */ ++ SETERROR(REG_ERANGE); ++ return; /* NOTE RETURN */ + } else + c = '-'; +#else /* !__DARWIN_UNIX03 */ @@ -195,7 +222,7 @@ break; default: c = '\0'; -@@ -773,7 +814,11 @@ +@@ -773,7 +826,11 @@ NEXT2(); (void)REQUIRE(MORE(), REG_EBRACK); c = PEEK(); @@ -207,7 +234,7 @@ p_b_eclass(p, cs); (void)REQUIRE(MORE(), REG_EBRACK); (void)REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); -@@ -792,14 +837,14 @@ +@@ -792,14 +849,14 @@ if (start == finish) CHadd(p, cs, start); else { @@ -226,7 +253,7 @@ ) CHadd(p, cs, i); } -@@ -823,7 +868,7 @@ +@@ -823,7 +880,7 @@ wctype_t wct; char clname[16]; @@ -235,7 +262,7 @@ NEXT(); len = p->next - sp; if (len >= sizeof(clname) - 1) { -@@ -832,7 +877,7 @@ +@@ -832,7 +889,7 @@ } memcpy(clname, sp, len); clname[len] = '\0'; @@ -244,16 +271,75 @@ SETERROR(REG_ECTYPE); return; } -@@ -903,7 +948,7 @@ +@@ -842,16 +899,40 @@ + /* + - p_b_eclass - parse an equivalence-class name and deal with it + == static void p_b_eclass(struct parse *p, cset *cs); +- * +- * This implementation is incomplete. xxx + */ + static void + p_b_eclass(p, cs) + struct parse *p; + cset *cs; + { +- wint_t c; +- ++ char *sp = p->next; ++ int len, ec; ++ mbstate_t mbs; ++ int *newequiv_classes; ++ wint_t c; ++ ++ while (MORE() && !SEETWO('=', ']')) ++ NEXT(); ++ if (!MORE()) { ++ SETERROR(REG_EBRACK); ++ return; ++ } ++ len = p->next - sp; ++ memset(&mbs, 0, sizeof(mbs)); ++ ec = __collate_equiv_class(sp, len, &mbs, p->g->loc); ++ if (ec > 0) { ++ newequiv_classes = realloc(cs->equiv_classes, ++ (cs->nequiv_classes + 1) * sizeof(*cs->equiv_classes)); ++ if (newequiv_classes == NULL) { ++ SETERROR(REG_ESPACE); ++ return; ++ } ++ cs->equiv_classes = newequiv_classes; ++ cs->equiv_classes[cs->nequiv_classes++] = ec; ++ return; ++ } ++ /* not an equivalence class, so fallback to a collating element */ ++ p->next = sp; + c = p_b_coll_elem(p, '='); + CHadd(p, cs, c); + } +@@ -889,7 +970,7 @@ + struct cname *cp; + int len; + mbstate_t mbs; +- wchar_t wc; ++ wchar_t wbuf[16]; + size_t clen; + + while (MORE() && !SEETWO(endc, ']')) +@@ -903,9 +984,10 @@ if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') return(cp->code); /* known name */ memset(&mbs, 0, sizeof(mbs)); - if ((clen = mbrtowc(&wc, sp, len, &mbs)) == len) -+ if ((clen = mbrtowc_l(&wc, sp, len, &mbs, p->g->loc)) == len) - return (wc); /* single character */ - else if (clen == (size_t)-1 || clen == (size_t)-2) +- return (wc); /* single character */ +- else if (clen == (size_t)-1 || clen == (size_t)-2) ++ clen = __collate_collating_symbol(wbuf, 16, sp, len, &mbs, p->g->loc); ++ if (clen == 1) ++ return (*wbuf); /* single character */ ++ else if (clen == (size_t)-1) SETERROR(REG_ILLSEQ); -@@ -914,17 +959,18 @@ + else + SETERROR(REG_ECOLLATE); /* neither */ +@@ -914,17 +996,18 @@ /* - othercase - return the case counterpart of an alphabetic @@ -279,7 +365,7 @@ else /* peculiar, but could happen */ return(ch); } -@@ -946,10 +992,10 @@ +@@ -946,10 +1029,10 @@ size_t n; mbstate_t mbs; @@ -292,7 +378,7 @@ assert(n != (size_t)-1); bracket[n] = ']'; bracket[n + 1] = '\0'; -@@ -971,7 +1017,7 @@ +@@ -971,7 +1054,7 @@ { cset *cs; @@ -301,7 +387,7 @@ bothcases(p, ch); else if ((ch & OPDMASK) == ch) EMIT(OCHAR, ch); -@@ -1039,6 +1085,9 @@ +@@ -1039,10 +1122,22 @@ switch (REP(MAP(from), MAP(to))) { case REP(0, 0): /* must be user doing this */ DROP(finish-start); /* drop the operand */ @@ -309,9 +395,42 @@ + p->zerorepeats++; +#endif /* __DARWIN_UNIX03 */ break; ++ case REP(0, INF): /* as x{1,}? */ ++#if __DARWIN_UNIX03 ++ /* this case does not require the (y|) trick, noKLUDGE */ ++ /* Just like * =+? */ ++ INSERT(OPLUS_, start); ++ ASTERN(O_PLUS, start); ++ INSERT(OQUEST_, start); ++ ASTERN(O_QUEST, start); ++ break; ++#endif /* __DARWIN_UNIX03 */ case REP(0, 1): /* as x{1,1}? */ case REP(0, N): /* as x{1,n}? */ -@@ -1099,7 +1148,7 @@ +- case REP(0, INF): /* as x{1,}? */ + /* 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 @@ + /* done */ + break; + case REP(1, N): /* as x?x{1,n-1} */ ++#if __DARWIN_UNIX03 ++ INSERT(OQUEST_, start); ++ ASTERN(O_QUEST, start); ++#else /* !__DARWIN_UNIX03 */ + /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ + INSERT(OCH_, start); + ASTERN(OOR1, start); +@@ -1063,6 +1162,7 @@ + EMIT(OOR2, 0); /* offset very wrong... */ + AHEAD(THERE()); /* ...so fix it */ + ASTERN(O_CH, THERETHERE()); ++#endif /* __DARWIN_UNIX03 */ + copy = dupl(p, start+1, finish+1); + assert(copy == finish+4); + repeat(p, copy, 1, to-1); +@@ -1099,7 +1199,7 @@ size_t n; memset(&mbs, 0, sizeof(mbs)); @@ -320,7 +439,7 @@ if (n == (size_t)-1 || n == (size_t)-2) { SETERROR(REG_ILLSEQ); return (0); -@@ -1172,13 +1221,14 @@ +@@ -1172,13 +1272,14 @@ - returning it if so, otherwise returning OUT. */ static wint_t @@ -337,7 +456,7 @@ n++; s = i; } -@@ -1215,9 +1265,9 @@ +@@ -1215,9 +1316,9 @@ cs->wides[cs->nwides++] = ch; } if (cs->icase) { @@ -349,7 +468,7 @@ cs->bmp[nch >> 3] |= 1 << (nch & 7); } } -@@ -1262,7 +1312,7 @@ +@@ -1262,7 +1363,7 @@ wctype_t *newtypes; for (i = 0; i < NC; i++) @@ -358,7 +477,7 @@ CHadd(p, cs, i); newtypes = realloc(cs->types, (cs->ntypes + 1) * sizeof(*cs->types)); -@@ -1451,6 +1501,7 @@ +@@ -1451,6 +1552,7 @@ char buf[MB_LEN_MAX]; size_t clen; mbstate_t mbs; @@ -366,7 +485,7 @@ /* avoid making error situations worse */ if (p->error != 0) -@@ -1461,8 +1512,8 @@ +@@ -1461,8 +1563,8 @@ * multibyte character strings, but it's safe for at least * UTF-8 (see RFC 3629). */ @@ -377,7 +496,7 @@ return; /* find the longest OCHAR sequence in strip */ -@@ -1478,7 +1529,7 @@ +@@ -1478,7 +1580,7 @@ memset(&mbs, 0, sizeof(mbs)); newstart = scan - 1; } @@ -386,7 +505,7 @@ if (clen == (size_t)-1) goto toohard; newlen += clen; -@@ -1597,7 +1648,7 @@ +@@ -1597,7 +1699,7 @@ while (cp < g->must + g->mlen) { while (OP(s = *scan++) != OCHAR) continue; diff --git a/regex/FreeBSD/regex.3.patch b/regex/FreeBSD/regex.3.patch new file mode 100644 index 0000000..bc740ce --- /dev/null +++ b/regex/FreeBSD/regex.3.patch @@ -0,0 +1,67 @@ +--- 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 @@ + .Os + .Sh NAME + .Nm regcomp , +-.Nm regexec , + .Nm regerror , ++.Nm regexec , + .Nm regfree + .Nd regular-expression library + .Sh LIBRARY +@@ -51,20 +51,29 @@ + .In regex.h + .Ft int + .Fo regcomp +-.Fa "regex_t * restrict preg" "const char * restrict pattern" "int cflags" +-.Fc +-.Ft int +-.Fo regexec +-.Fa "const regex_t * restrict preg" "const char * restrict string" +-.Fa "size_t nmatch" "regmatch_t pmatch[restrict]" "int eflags" ++.Fa "regex_t *restrict preg" ++.Fa "const char *restrict pattern" ++.Fa "int cflags" + .Fc + .Ft size_t + .Fo regerror +-.Fa "int errcode" "const regex_t * restrict preg" +-.Fa "char * restrict errbuf" "size_t errbuf_size" ++.Fa "int errcode" ++.Fa "const regex_t *restrict preg" ++.Fa "char *restrict errbuf" ++.Fa "size_t errbuf_size" ++.Fc ++.Ft int ++.Fo regexec ++.Fa "const regex_t *restrict preg" ++.Fa "const char *restrict string" ++.Fa "size_t nmatch" ++.Fa "regmatch_t pmatch[restrict]" ++.Fa "int eflags" + .Fc + .Ft void +-.Fn regfree "regex_t *preg" ++.Fo regfree ++.Fa "regex_t *preg" ++.Fc + .Sh DESCRIPTION + These routines implement + .St -p1003.2 +@@ -75,12 +84,11 @@ + The + .Fn regcomp + function +-compiles an RE written as a string into an internal form, ++compiles an RE, written as a string, into an internal form. + .Fn regexec +-matches that internal form against a string and reports results, ++matches that internal form against a string and reports results. + .Fn regerror +-transforms error codes from either into human-readable messages, +-and ++transforms error codes from either into human-readable messages. + .Fn regfree + frees any dynamically-allocated storage used by the internal form + of an RE. diff --git a/regex/FreeBSD/regex2.h.patch b/regex/FreeBSD/regex2.h.patch index fd35a89..1b07d49 100644 --- a/regex/FreeBSD/regex2.h.patch +++ b/regex/FreeBSD/regex2.h.patch @@ -1,8 +1,15 @@ ---- regex2.h.orig 2004-11-25 11:38:32.000000000 -0800 -+++ regex2.h 2005-02-24 14:26:21.000000000 -0800 -@@ -127,9 +127,10 @@ +--- 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 @@ + int nranges; + int invert; + int icase; ++ int *equiv_classes; ++ int nequiv_classes; } cset; ++#include "collate.h" ++ static int -CHIN1(cs, ch) +CHIN1(cs, ch, loc) @@ -12,7 +19,16 @@ { int i; -@@ -144,15 +145,16 @@ + assert(ch >= 0); ++ for (i = 0; i < cs->nequiv_classes; i++) ++ /* sadly, we can only deal with single characters from an ++ * equivalence class */ ++ if (__collate_equiv_match(cs->equiv_classes[i], NULL, 0, ch, NULL, 0, NULL, NULL, loc) > 0) ++ return (!cs->invert); + if (ch < NC) + return (((cs->bmp[ch >> 3] & (1 << (ch & 7))) != 0) ^ + cs->invert); +@@ -144,26 +154,27 @@ if (cs->ranges[i].min <= ch && ch <= cs->ranges[i].max) return (!cs->invert); for (i = 0; i < cs->ntypes; i++) @@ -31,7 +47,8 @@ { assert(ch >= 0); -@@ -160,10 +162,10 @@ +- if (ch < NC) ++ if (ch < NC && cs->nequiv_classes == 0) return (((cs->bmp[ch >> 3] & (1 << (ch & 7))) != 0) ^ cs->invert); else if (cs->icase) @@ -45,7 +62,7 @@ } /* -@@ -193,8 +195,9 @@ +@@ -193,8 +204,9 @@ size_t nsub; /* copy of re_nsub */ int backrefs; /* does it use back references? */ sopno nplus; /* how deep does it nest +s? */ @@ -53,6 +70,7 @@ }; /* misc utilities */ - #define OUT (-2) /* a non-character value */ +-#define OUT (-2) /* a non-character value */ -#define ISWORD(c) (iswalnum((uch)(c)) || (c) == '_') ++#define OUT (-130) /* a non-character value */ +#define ISWORD(c,l) (iswalnum_l((uch)(c), l) || (c) == '_') diff --git a/regex/FreeBSD/regfree.c.patch b/regex/FreeBSD/regfree.c.patch new file mode 100644 index 0000000..eadc425 --- /dev/null +++ b/regex/FreeBSD/regfree.c.patch @@ -0,0 +1,10 @@ +--- 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 @@ + free(g->sets[i].ranges); + free(g->sets[i].wides); + free(g->sets[i].types); ++ free(g->sets[i].equiv_classes); + } + free((char *)g->sets); + } diff --git a/regex/Makefile.inc b/regex/Makefile.inc index f47cee8..c04a212 100644 --- a/regex/Makefile.inc +++ b/regex/Makefile.inc @@ -10,7 +10,11 @@ CFLAGS-regcomp-fbsd.c+= -DPOSIX_MISTAKE FBSDHDRS= cclass.h cname.h engine.c regex2.h utils.h .include "Makefile.fbsd_end" -UNIX03SRCS += regcomp.c +LEGACYSRCS += regcomp.c + +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +CFLAGS-regcomp-fbsd.c += -DLIBC_ALIAS_REGCOMP .if ${LIB} == "c" .include "Makefile.fbsd_begin" @@ -18,6 +22,9 @@ FBSDMAN3= regex.3 FBSDMAN7= re_format.7 .include "Makefile.fbsd_end" -MLINKS+=regex.3 regcomp.3 regex.3 regexec.3 regex.3 regerror.3 -MLINKS+=regexec.3 regfree.3 +MLINKS+= regex.3 regcomp.3 \ + regex.3 regexec.3 \ + regex.3 regerror.3 + +MLINKS+= regexec.3 regfree.3 .endif diff --git a/regex/cclass.h b/regex/cclass.h new file mode 100644 index 0000000..956a655 --- /dev/null +++ b/regex/cclass.h @@ -0,0 +1,63 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + * + * @(#)cclass.h 8.3 (Berkeley) 3/20/94 + * $FreeBSD: src/lib/libc/regex/cclass.h,v 1.4 2002/03/22 23:41:56 obrien Exp $ + */ + + +typedef enum {CALNUM, CALPHA, CBLANK, CCNTRL, CDIGIT, CGRAPH, + CLOWER, CPRINT, CPUNCT, CSPACE, CUPPER, CXDIGIT} citype; + +/* character-class table */ +static struct cclass { + char *name; + citype fidx; +} cclasses[] = { + {"alnum", CALNUM}, + {"alpha", CALPHA}, + {"blank", CBLANK}, + {"cntrl", CCNTRL}, + {"digit", CDIGIT}, + {"graph", CGRAPH}, + {"lower", CLOWER}, + {"print", CPRINT}, + {"punct", CPUNCT}, + {"space", CSPACE}, + {"upper", CUPPER}, + {"xdigit", CXDIGIT}, + {NULL, } +}; diff --git a/regex/cname.h b/regex/cname.h new file mode 100644 index 0000000..4f0d583 --- /dev/null +++ b/regex/cname.h @@ -0,0 +1,142 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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.3 2002/03/22 23:41:56 obrien 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 new file mode 100644 index 0000000..5d2543f --- /dev/null +++ b/regex/engine.c @@ -0,0 +1,1204 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + * + * @(#)engine.c 8.5 (Berkeley) 3/20/94 + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/regex/engine.c,v 1.14 2004/07/12 07:35:59 tjr Exp $"); + +/* + * The matching engine and friends. This file is #included by regexec.c + * after suitable #defines of a variety of macros used herein, so that + * different state representations can be used without duplicating masses + * of code. + */ + +#ifdef SNAMES +#define matcher smatcher +#define fast sfast +#define slow sslow +#define dissect sdissect +#define backref sbackref +#define step sstep +#define print sprint +#define at sat +#define match smat +#endif +#ifdef LNAMES +#define matcher lmatcher +#define fast lfast +#define slow lslow +#define dissect ldissect +#define backref lbackref +#define step lstep +#define print lprint +#define at lat +#define match lmat +#endif +#ifdef MNAMES +#define matcher mmatcher +#define fast mfast +#define slow mslow +#define dissect mdissect +#define backref mbackref +#define step mstep +#define print mprint +#define at mat +#define match mmat +#endif + +/* another structure passed up and down to avoid zillions of parameters */ +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] */ + STATEVARS; + states st; /* current states */ + states fresh; /* states for a fresh start */ + states tmp; /* temporary */ + states empty; /* empty set of states */ + mbstate_t mbs; /* multibyte conversion state */ +}; + +/* ========= begin header generated by ./mkh ========= */ +#ifdef __cplusplus +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 states step(struct re_guts *g, sopno start, sopno stop, states bef, wint_t ch, states aft); +#define BOL (OUT-1) +#define EOL (BOL-1) +#define BOLEOL (BOL-2) +#define NOTHING (BOL-3) +#define BOW (BOL-4) +#define EOW (BOL-5) +#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); +#endif +#ifdef REDEBUG +static void at(struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst); +#endif +#ifdef REDEBUG +static char *pchar(int ch); +#endif + +#ifdef __cplusplus +} +#endif +/* ========= end header generated by ./mkh ========= */ + +#ifdef REDEBUG +#define SP(t, s, c) print(m, t, s, c, stdout) +#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) +#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } +#else +#define SP(t, s, c) /* nothing */ +#define AT(t, p1, p2, s1, s2) /* nothing */ +#define NOTE(s) /* nothing */ +#endif + +/* + - matcher - the actual matching engine + == static int matcher(struct re_guts *g, 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; +{ + char *endp; + int i; + struct match mv; + struct match *m = &mv; + char *dp; + const sopno gf = g->firststate+1; /* +1 for OEND */ + const sopno gl = g->laststate; + char *start; + char *stop; + /* Boyer-Moore algorithms variables */ + char *pp; + int cj, mj; + char *mustfirst; + char *mustlast; + int *matchjump; + int *charjump; + + /* simplify the situation where possible */ + if (g->cflags®_NOSUB) + nmatch = 0; + if (eflags®_STARTEND) { + start = string + pmatch[0].rm_so; + stop = string + pmatch[0].rm_eo; + } else { + start = string; + stop = start + strlen(start); + } + if (stop < start) + return(REG_INVARG); + + /* prescreening; this does wonders for this rather slow code */ + if (g->must != NULL) { + if (g->charjump != NULL && g->matchjump != NULL) { + mustfirst = g->must; + mustlast = g->must + g->mlen - 1; + charjump = g->charjump; + matchjump = g->matchjump; + pp = mustlast; + for (dp = start+g->mlen-1; dp < stop;) { + /* Fast skip non-matches */ + while (dp < stop && charjump[(int)*dp]) + dp += charjump[(int)*dp]; + + if (dp >= stop) + break; + + /* Greedy matcher */ + /* We depend on not being used for + * for strings of length 1 + */ + while (*--dp == *--pp && pp != mustfirst); + + if (*dp == *pp) + break; + + /* Jump to next possible match */ + mj = matchjump[pp - mustfirst]; + cj = charjump[(int)*dp]; + dp += (cj < mj ? mj : cj); + pp = mustlast; + } + if (pp != mustfirst) + return(REG_NOMATCH); + } else { + for (dp = start; dp < stop; dp++) + if (*dp == g->must[0] && + stop - dp >= g->mlen && + memcmp(dp, g->must, (size_t)g->mlen) == 0) + break; + if (dp == stop) /* we didn't find g->must */ + return(REG_NOMATCH); + } + } + + /* match struct setup */ + m->g = g; + m->eflags = eflags; + m->pmatch = NULL; + m->lastpos = NULL; + m->offp = string; + m->beginp = start; + m->endp = stop; + STATESETUP(m, 4); + SETUP(m->st); + SETUP(m->fresh); + SETUP(m->tmp); + SETUP(m->empty); + CLEAR(m->empty); + ZAPSTATE(&m->mbs); + + /* Adjust start according to moffset, to speed things up */ + if (g->moffset > -1) + start = ((dp - g->moffset) < start) ? start : dp - g->moffset; + + /* this loop does only one repetition except for backrefs */ + for (;;) { + endp = fast(m, start, stop, gf, gl); + if (endp == NULL) { /* a miss */ + STATETEARDOWN(m); + return(REG_NOMATCH); + } + if (nmatch == 0 && !g->backrefs) + break; /* no further info needed */ + + /* where? */ + assert(m->coldp != NULL); + for (;;) { + NOTE("finding start"); + endp = slow(m, m->coldp, stop, gf, gl); + if (endp != NULL) + break; + assert(m->coldp < m->endp); + m->coldp += XMBRTOWC(NULL, m->coldp, + m->endp - m->coldp, &m->mbs, 0, g->loc); + } + if (nmatch == 1 && !g->backrefs) + break; /* no further info needed */ + + /* oh my, he wants the subexpressions... */ + if (m->pmatch == NULL) + m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * + sizeof(regmatch_t)); + if (m->pmatch == NULL) { + STATETEARDOWN(m); + return(REG_ESPACE); + } + for (i = 1; i <= m->g->nsub; i++) + m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1; + if (!g->backrefs && !(m->eflags®_BACKR)) { + NOTE("dissecting"); + 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 *)); + 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); + } + if (dp != NULL) + break; + + /* uh-oh... we couldn't find a subexpression-level match */ + assert(g->backrefs); /* must be back references doing it */ + assert(g->nplus == 0 || m->lastpos != NULL); + for (;;) { + if (dp != NULL || endp <= m->coldp) + break; /* defeat */ + NOTE("backoff"); + endp = slow(m, m->coldp, endp-1, gf, gl); + if (endp == NULL) + break; /* defeat */ + /* try it on a shorter possibility */ +#ifndef NDEBUG + for (i = 1; i <= m->g->nsub; i++) { + assert(m->pmatch[i].rm_so == -1); + assert(m->pmatch[i].rm_eo == -1); + } +#endif + NOTE("backoff dissect"); + dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); + } + assert(dp == NULL || dp == endp); + if (dp != NULL) /* found a shorter one */ + break; + + /* despite initial appearances, there is no match here */ + NOTE("false alarm"); + /* recycle starting later */ + start = m->coldp + XMBRTOWC(NULL, m->coldp, + m->endp - m->coldp, &m->mbs, 0, g->loc); + assert(start <= stop); + } + + /* fill in the details if requested */ + if (nmatch > 0) { + pmatch[0].rm_so = m->coldp - m->offp; + pmatch[0].rm_eo = endp - m->offp; + } + if (nmatch > 1) { + assert(m->pmatch != NULL); + for (i = 1; i < nmatch; i++) + if (i <= m->g->nsub) + pmatch[i] = m->pmatch[i]; + else { + pmatch[i].rm_so = -1; + pmatch[i].rm_eo = -1; + } + } + + if (m->pmatch != NULL) + free((char *)m->pmatch); + if (m->lastpos != NULL) + free((char *)m->lastpos); + STATETEARDOWN(m); + return(0); +} + +/* + - dissect - figure out what matched what, no back references + == static char *dissect(struct match *m, char *start, \ + == 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; +{ + 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 */ + 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; + + AT("diss", start, stop, startst, stopst); + sp = start; + for (ss = startst; ss < stopst; ss = es) { + /* identify end of subRE */ + es = ss; + switch (OP(m->g->strip[es])) { + case OPLUS_: + case OQUEST_: + es += OPND(m->g->strip[es]); + break; + case OCH_: + while (OP(m->g->strip[es]) != O_CH) + es += OPND(m->g->strip[es]); + break; + } + es++; + + /* figure out what it matched */ + switch (OP(m->g->strip[ss])) { + case OEND: + assert(nope); + break; + case OCHAR: + sp += XMBRTOWC(NULL, sp, stop - start, &m->mbs, 0, m->g->loc); + break; + case OBOL: + case OEOL: + case OBOW: + case OEOW: + break; + case OANY: + case OANYOF: + sp += XMBRTOWC(NULL, sp, stop - start, &m->mbs, 0, m->g->loc); + break; + case OBACK_: + case O_BACK: + assert(nope); + break; + /* cases where length of match is hard to find */ + case OQUEST_: + stp = stop; + for (;;) { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = es - 1; + /* did innards match? */ + if (slow(m, sp, rest, ssub, esub) != NULL) { + dp = dissect(m, sp, rest, ssub, esub); + assert(dp == rest); + } else /* no */ + assert(sp == rest); + sp = rest; + break; + case OPLUS_: + stp = stop; + for (;;) { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = es - 1; + ssp = sp; + oldssp = ssp; + for (;;) { /* find last match of innards */ + sep = slow(m, ssp, rest, ssub, esub); + if (sep == NULL || sep == ssp) + break; /* failed or matched null */ + oldssp = ssp; /* on to next try */ + ssp = sep; + } + if (sep == NULL) { + /* last successful match */ + sep = ssp; + ssp = oldssp; + } + else if (tail==rest) { + /* Fix for test expr 105 */ + ssp = oldssp; + } + assert(sep == rest); /* must exhaust substring */ + assert(slow(m, ssp, sep, ssub, esub) == rest); + dp = dissect(m, ssp, sep, ssub, esub); + assert(dp == sep); + sp = rest; + break; + case OCH_: + stp = stop; + for (;;) { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = ss + OPND(m->g->strip[ss]) - 1; + assert(OP(m->g->strip[esub]) == OOR1); + for (;;) { /* find first matching branch */ + if (slow(m, sp, rest, ssub, esub) == rest) + break; /* it matched all of it */ + /* that one missed, try next one */ + assert(OP(m->g->strip[esub]) == OOR1); + esub++; + assert(OP(m->g->strip[esub]) == OOR2); + ssub = esub + 1; + esub += OPND(m->g->strip[esub]); + if (OP(m->g->strip[esub]) == OOR2) + esub--; + else + assert(OP(m->g->strip[esub]) == O_CH); + } + dp = dissect(m, sp, rest, ssub, esub); + assert(dp == rest); + sp = rest; + break; + case O_PLUS: + case O_QUEST: + case OOR1: + case OOR2: + case O_CH: + assert(nope); + break; + case OLPAREN: + i = OPND(m->g->strip[ss]); + assert(0 < i && i <= m->g->nsub); + m->pmatch[i].rm_so = sp - m->offp; + /* fix for T.regcomp 43: don't remember previous + subexpression matches beyond the current one (i) */ + i++; + while (i<= m->g->nsub) { + m->pmatch[i].rm_so = -1; + m->pmatch[i].rm_eo = -1; + i++; + } + break; + case ORPAREN: + i = OPND(m->g->strip[ss]); + assert(0 < i && i <= m->g->nsub); + m->pmatch[i].rm_eo = sp - m->offp; + break; + default: /* uh oh */ + assert(nope); + break; + } + } + + assert(sp == stop); + return(sp); +} + +/* + - 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 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 */ +{ + int i; + sopno ss; /* start sop of current subRE */ + 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; + size_t len; + int hard; + sop s; + regoff_t offsave; + cset *cs; + wint_t wc; + + AT("back", start, stop, startst, stopst); + sp = start; + + /* get as far as we can with easy stuff */ + hard = 0; + for (ss = startst; !hard && ss < stopst; ss++) + switch (OP(s = m->g->strip[ss])) { + case OCHAR: + if (sp == stop) + return(NULL); + sp += XMBRTOWC(&wc, sp, stop - sp, &m->mbs, BADCHAR, m->g->loc); + if (wc != OPND(s)) + return(NULL); + break; + case OANY: + if (sp == stop) + return(NULL); + sp += XMBRTOWC(&wc, sp, stop - sp, &m->mbs, BADCHAR, m->g->loc); + if (wc == BADCHAR) + return (NULL); + break; + case OANYOF: + if (sp == stop) + return (NULL); + cs = &m->g->sets[OPND(s)]; + sp += XMBRTOWC(&wc, sp, stop - sp, &m->mbs, BADCHAR, m->g->loc); + if (wc == BADCHAR || !CHIN(cs, wc, m->g->loc)) + return(NULL); + break; + case OBOL: + if ( (sp == m->beginp && !(m->eflags®_NOTBOL)) || + (sp < m->endp && *(sp-1) == '\n' && + (m->g->cflags®_NEWLINE)) ) + { /* yes */ } + else + return(NULL); + break; + case OEOL: + if ( (sp == m->endp && !(m->eflags®_NOTEOL)) || + (sp < m->endp && *sp == '\n' && + (m->g->cflags®_NEWLINE)) ) + { /* yes */ } + else + return(NULL); + break; + case OBOW: + if (( (sp == m->beginp && !(m->eflags®_NOTBOL)) || + (sp < m->endp && *(sp-1) == '\n' && + (m->g->cflags®_NEWLINE)) || + (sp > m->beginp && + !ISWORD(*(sp-1), m->g->loc)) ) && + (sp < m->endp && ISWORD(*sp, m->g->loc)) ) + { /* yes */ } + else + return(NULL); + break; + case OEOW: + if (( (sp == m->endp && !(m->eflags®_NOTEOL)) || + (sp < m->endp && *sp == '\n' && + (m->g->cflags®_NEWLINE)) || + (sp < m->endp && !ISWORD(*sp, m->g->loc)) ) && + (sp > m->beginp && ISWORD(*(sp-1), m->g->loc)) ) + { /* yes */ } + else + return(NULL); + break; + case O_QUEST: + break; + case OOR1: /* matches null but needs to skip */ + ss++; + s = m->g->strip[ss]; + do { + assert(OP(s) == OOR2); + ss += OPND(s); + } while (OP(s = m->g->strip[ss]) != O_CH); + /* note that the ss++ gets us past the O_CH */ + break; + default: /* have to make a choice */ + hard = 1; + break; + } + if (!hard) { /* that was it! */ + if (sp != stop) + return(NULL); + return(sp); + } + ss--; /* adjust for the for's final increment */ + + /* the hard stuff */ + AT("hard", sp, stop, ss, stopst); + s = m->g->strip[ss]; + switch (OP(s)) { + case OBACK_: /* the vilest depths */ + i = OPND(s); + assert(0 < i && i <= m->g->nsub); + if (m->pmatch[i].rm_eo == -1) + return(NULL); + assert(m->pmatch[i].rm_so != -1); + len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so; + assert(stop - m->beginp >= len); + if (sp > stop - len) + return(NULL); /* not enough left to match */ + ssp = m->offp + m->pmatch[i].rm_so; + if (memcmp(sp, ssp, len) != 0) + return(NULL); + while (m->g->strip[ss] != SOP(O_BACK, i)) + ss++; + return(backref(m, sp+len, stop, ss+1, stopst, lev)); + break; + case OQUEST_: /* to null or not */ + dp = backref(m, sp, stop, ss+1, stopst, lev); + if (dp != NULL) + return(dp); /* not */ + return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev)); + 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)); + break; + case O_PLUS: + if (sp == m->lastpos[lev]) /* last pass matched null */ + return(backref(m, sp, stop, ss+1, stopst, lev-1)); + /* try another pass */ + m->lastpos[lev] = sp; + dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev); + if (dp == NULL) + return(backref(m, sp, stop, ss+1, stopst, lev-1)); + else + return(dp); + break; + case OCH_: /* find the right one, if any */ + ssub = ss + 1; + 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); + if (dp != NULL) + return(dp); + /* that one missed, try next one */ + if (OP(m->g->strip[esub]) == O_CH) + return(NULL); /* there is none */ + esub++; + assert(OP(m->g->strip[esub]) == OOR2); + ssub = esub + 1; + esub += OPND(m->g->strip[esub]); + if (OP(m->g->strip[esub]) == OOR2) + esub--; + else + assert(OP(m->g->strip[esub]) == O_CH); + } + break; + case OLPAREN: /* must undo assignment if rest fails */ + i = OPND(s); + 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); + if (dp != NULL) + return(dp); + m->pmatch[i].rm_so = offsave; + return(NULL); + break; + case ORPAREN: /* must undo assignment if rest fails */ + i = OPND(s); + 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); + if (dp != NULL) + return(dp); + m->pmatch[i].rm_eo = offsave; + return(NULL); + break; + default: /* uh oh */ + assert(nope); + break; + } + + /* "can't happen" */ + assert(nope); + /* NOTREACHED */ + return "shut up gcc"; +} + +/* + - fast - step through the string at top speed + == static char *fast(struct match *m, char *start, \ + == 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; +{ + states st = m->st; + states fresh = m->fresh; + states tmp = m->tmp; + 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 */ + size_t clen; + + CLEAR(st); + SET1(st, startst); + st = step(m->g, startst, stopst, st, NOTHING, st); + ASSIGN(fresh, st); + SP("start", st, *p); + coldp = NULL; + if (start == m->beginp) + c = OUT; + else { + /* + * XXX Wrong if the previous character was multi-byte. + * Newline never is (in encodings supported by FreeBSD), + * so this only breaks the ISWORD tests below. + */ + c = (uch)*(start - 1); + } + for (;;) { + /* next character */ + lastc = c; + if (p == m->endp) + c = OUT; + else + clen = XMBRTOWC(&c, p, m->endp - p, &m->mbs, BADCHAR, m->g->loc); + if (EQ(st, fresh)) + coldp = p; + + /* is there an EOL and/or BOL between lastc and c? */ + flagch = '\0'; + i = 0; + if ( (lastc == '\n' && m->g->cflags®_NEWLINE) || + (lastc == OUT && !(m->eflags®_NOTBOL)) ) { + flagch = BOL; + i = m->g->nbol; + } + if ( (c == '\n' && m->g->cflags®_NEWLINE) || + (c == OUT && !(m->eflags®_NOTEOL)) ) { + flagch = (flagch == BOL) ? BOLEOL : EOL; + i += m->g->neol; + } + if (i != 0) { + for (; i > 0; i--) + st = step(m->g, startst, stopst, st, flagch, st); + SP("boleol", st, c); + } + + /* how about a word boundary? */ + if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc, m->g->loc))) && + (c != OUT && ISWORD(c, m->g->loc)) ) { + flagch = BOW; + } + if ( (lastc != OUT && ISWORD(lastc, m->g->loc)) && + (flagch == EOL || (c != OUT && !ISWORD(c, m->g->loc))) ) { + flagch = EOW; + } + if (flagch == BOW || flagch == EOW) { + st = step(m->g, startst, stopst, st, flagch, st); + SP("boweow", st, c); + } + + /* are we done? */ + if (ISSET(st, stopst) || p == stop) + break; /* NOTE BREAK OUT */ + + /* no, we must deal with this character */ + ASSIGN(tmp, st); + ASSIGN(st, fresh); + assert(c != OUT); + st = step(m->g, startst, stopst, tmp, c, st); + SP("aft", st, c); + assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); + p += clen; + } + + assert(coldp != NULL); + m->coldp = coldp; + if (ISSET(st, stopst)) + return(p+XMBRTOWC(NULL, p, m->endp - 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 char * /* where it ended */ +slow(m, start, stop, startst, stopst) +struct match *m; +char *start; +char *stop; +sopno startst; +sopno stopst; +{ + states st = m->st; + states empty = m->empty; + states tmp = m->tmp; + 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 */ + size_t clen; + + AT("slow", start, stop, startst, stopst); + CLEAR(st); + SET1(st, startst); + SP("sstart", st, *p); + st = step(m->g, startst, stopst, st, NOTHING, st); + matchp = NULL; + if (start == m->beginp) + c = OUT; + else { + /* + * XXX Wrong if the previous character was multi-byte. + * Newline never is (in encodings supported by FreeBSD), + * so this only breaks the ISWORD tests below. + */ + c = (uch)*(start - 1); + } + for (;;) { + /* next character */ + lastc = c; + if (p == m->endp) { + c = OUT; + clen = 0; + } else + clen = XMBRTOWC(&c, p, m->endp - p, &m->mbs, BADCHAR, m->g->loc); + + /* is there an EOL and/or BOL between lastc and c? */ + flagch = '\0'; + i = 0; + if ( (lastc == '\n' && m->g->cflags®_NEWLINE) || + (lastc == OUT && !(m->eflags®_NOTBOL)) ) { + flagch = BOL; + i = m->g->nbol; + } + if ( (c == '\n' && m->g->cflags®_NEWLINE) || + (c == OUT && !(m->eflags®_NOTEOL)) ) { + flagch = (flagch == BOL) ? BOLEOL : EOL; + i += m->g->neol; + } + if (i != 0) { + for (; i > 0; i--) + st = step(m->g, startst, stopst, st, flagch, st); + SP("sboleol", st, c); + } + + /* how about a word boundary? */ + if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc, m->g->loc))) && + (c != OUT && ISWORD(c, m->g->loc)) ) { + flagch = BOW; + } + if ( (lastc != OUT && ISWORD(lastc, m->g->loc)) && + (flagch == EOL || (c != OUT && !ISWORD(c, m->g->loc))) ) { + flagch = EOW; + } + if (flagch == BOW || flagch == EOW) { + st = step(m->g, startst, stopst, st, flagch, st); + SP("sboweow", st, c); + } + + /* are we done? */ + if (ISSET(st, stopst)) + matchp = p; + if (EQ(st, empty) || p == stop) + break; /* NOTE BREAK OUT */ + + /* no, we must deal with this character */ + ASSIGN(tmp, st); + ASSIGN(st, empty); + assert(c != OUT); + st = step(m->g, startst, stopst, tmp, c, st); + SP("saft", st, c); + assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); + p += clen; + } + + return(matchp); +} + + +/* + - step - map set of states reachable before char to set reachable after + == static states step(struct re_guts *g, sopno start, sopno stop, \ + == states bef, int ch, states aft); + == #define BOL (OUT-1) + == #define EOL (BOL-1) + == #define BOLEOL (BOL-2) + == #define NOTHING (BOL-3) + == #define BOW (BOL-4) + == #define EOW (BOL-5) + == #define BADCHAR (BOL-6) + == #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 */ +{ + cset *cs; + sop s; + sopno pc; + onestate here; /* note, macros know this name */ + sopno look; + int i; + + for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { + s = g->strip[pc]; + switch (OP(s)) { + case OEND: + assert(pc == stop-1); + break; + case OCHAR: + /* only characters can match */ + assert(!NONCHAR(ch) || ch != OPND(s)); + if (ch == OPND(s)) + FWD(aft, bef, 1); + break; + case OBOL: + if (ch == BOL || ch == BOLEOL) + FWD(aft, bef, 1); + break; + case OEOL: + if (ch == EOL || ch == BOLEOL) + FWD(aft, bef, 1); + break; + case OBOW: + if (ch == BOW) + FWD(aft, bef, 1); + break; + case OEOW: + if (ch == EOW) + FWD(aft, bef, 1); + break; + case OANY: + if (!NONCHAR(ch)) + FWD(aft, bef, 1); + break; + case OANYOF: + cs = &g->sets[OPND(s)]; + if (!NONCHAR(ch) && CHIN(cs, ch, g->loc)) + FWD(aft, bef, 1); + break; + case OBACK_: /* ignored here */ + case O_BACK: + FWD(aft, aft, 1); + break; + case OPLUS_: /* forward, this is just an empty */ + FWD(aft, aft, 1); + break; + case O_PLUS: /* both forward and back */ + FWD(aft, aft, 1); + i = ISSETBACK(aft, OPND(s)); + BACK(aft, aft, OPND(s)); + if (!i && ISSETBACK(aft, OPND(s))) { + /* oho, must reconsider loop body */ + pc -= OPND(s) + 1; + INIT(here, pc); + } + break; + case OQUEST_: /* two branches, both forward */ + FWD(aft, aft, 1); + FWD(aft, aft, OPND(s)); + break; + case O_QUEST: /* just an empty */ + FWD(aft, aft, 1); + break; + case OLPAREN: /* not significant here */ + case ORPAREN: + FWD(aft, aft, 1); + break; + case OCH_: /* mark the first two branches */ + FWD(aft, aft, 1); + assert(OP(g->strip[pc+OPND(s)]) == OOR2); + FWD(aft, aft, OPND(s)); + break; + case OOR1: /* done a branch, find the O_CH */ + if (ISSTATEIN(aft, here)) { + for (look = 1; + OP(s = g->strip[pc+look]) != O_CH; + look += OPND(s)) + assert(OP(s) == OOR2); + FWD(aft, aft, look); + } + break; + case OOR2: /* propagate OCH_'s marking */ + FWD(aft, aft, 1); + if (OP(g->strip[pc+OPND(s)]) != O_CH) { + assert(OP(g->strip[pc+OPND(s)]) == OOR2); + FWD(aft, aft, OPND(s)); + } + break; + case O_CH: /* just empty */ + FWD(aft, aft, 1); + break; + default: /* ooooops... */ + assert(nope); + break; + } + } + + return(aft); +} + +#ifdef REDEBUG +/* + - print - print a set of states + == #ifdef REDEBUG + == static void print(struct match *m, 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; +{ + struct re_guts *g = m->g; + int i; + int first = 1; + + if (!(m->eflags®_TRACE)) + return; + + fprintf(d, "%s", caption); + if (ch != '\0') + fprintf(d, " %s", pchar(ch)); + for (i = 0; i < g->nstates; i++) + if (ISSET(st, i)) { + fprintf(d, "%s%d", (first) ? "\t" : ", ", i); + first = 0; + } + fprintf(d, "\n"); +} + +/* + - at - print current situation + == #ifdef REDEBUG + == static void at(struct match *m, char *title, char *start, 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; +{ + if (!(m->eflags®_TRACE)) + return; + + printf("%s %s-", title, pchar(*start)); + printf("%s ", pchar(*stop)); + printf("%ld-%ld\n", (long)startst, (long)stopst); +} + +#ifndef PCHARDONE +#define PCHARDONE /* never again */ +/* + - pchar - make a character printable + == #ifdef REDEBUG + == static char *pchar(int ch); + == #endif + * + * Is this identical to regchar() over in debug.c? Well, yes. But a + * duplicate here avoids having a debugging-capable regexec.o tied to + * 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 char pbuf[10]; + + if (isprint((uch)ch) || ch == ' ') + sprintf(pbuf, "%c", ch); + else + sprintf(pbuf, "\\%o", ch); + return(pbuf); +} +#endif +#endif + +#undef matcher +#undef fast +#undef slow +#undef dissect +#undef backref +#undef step +#undef print +#undef at +#undef match diff --git a/regex/re_format.7 b/regex/re_format.7 new file mode 120000 index 0000000..9946732 --- /dev/null +++ b/regex/re_format.7 @@ -0,0 +1 @@ +./re_format.7 \ No newline at end of file diff --git a/regex/regcomp-fbsd.c b/regex/regcomp-fbsd.c new file mode 100644 index 0000000..0f06201 --- /dev/null +++ b/regex/regcomp-fbsd.c @@ -0,0 +1,1946 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + * + * @(#)regcomp.c 8.5 (Berkeley) 3/20/94 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "collate.h" + +#include "utils.h" +#include "regex2.h" + +#include "cname.h" + +/* + * parse structure, passed up and down to avoid global variables and + * other clumsinesses + */ +struct parse { + char *next; /* next character in RE */ + char *end; /* end of string (-> NUL normally) */ + int error; /* has an error been seen? */ + sop *strip; /* malloced strip */ + sopno ssize; /* malloced strip size (allocated) */ + sopno slen; /* malloced strip length (used) */ + int ncsalloc; /* number of csets allocated */ +#if __DARWIN_UNIX03 + int zerorepeats; +#endif /* __DARWIN_UNIX03 */ + struct re_guts *g; +# define NPAREN 10 /* we need to remember () 1-9 for back refs */ + sopno pbegin[NPAREN]; /* -> ( ([0] unused) */ + sopno pend[NPAREN]; /* -> ) ([0] unused) */ +}; + +/* ========= begin header generated by ./mkh ========= */ +#ifdef __cplusplus +extern "C" { +#endif + +/* === regcomp.c === */ +static void p_ere(struct parse *p, wint_t stop); +static void p_ere_exp(struct parse *p); +static void p_str(struct parse *p); +static void p_bre(struct parse *p, wint_t end1, wint_t end2); +static int p_simp_re(struct parse *p, int starordinary); +static int p_count(struct parse *p); +static void p_bracket(struct parse *p); +static void p_b_term(struct parse *p, cset *cs); +static void p_b_cclass(struct parse *p, cset *cs); +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); +static wint_t othercase(wint_t ch, locale_t loc); +static void bothcases(struct parse *p, wint_t ch); +static void ordinary(struct parse *p, wint_t ch); +static void nonnewline(struct parse *p); +static void repeat(struct parse *p, sopno start, int from, int to); +static int seterr(struct parse *p, int e); +static cset *allocset(struct parse *p); +static void freeset(struct parse *p, cset *cs); +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); +static wint_t singleton(cset *cs, locale_t loc); +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); +static void dofwd(struct parse *p, sopno pos, sop value); +static void enlarge(struct parse *p, sopno size); +static void stripsnug(struct parse *p, struct re_guts *g); +static void findmust(struct parse *p, struct re_guts *g); +static int altoffset(sop *scan, int offset); +static void computejumps(struct parse *p, struct re_guts *g); +static void computematchjumps(struct parse *p, struct re_guts *g); +static sopno pluscount(struct parse *p, struct re_guts *g); +static wint_t wgetnext(struct parse *p); + +#ifdef __cplusplus +} +#endif +/* ========= end header generated by ./mkh ========= */ + +static char nuls[10]; /* place to point scanner in event of error */ + +/* + * macros for use with parse structure + * BEWARE: these know that the parse structure is named `p' !!! + */ +#define PEEK() (*p->next) +#define PEEK2() (*(p->next+1)) +#define MORE() (p->next < p->end) +#define MORE2() (p->next+1 < p->end) +#define SEE(c) (MORE() && PEEK() == (c)) +#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b)) +#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0) +#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0) +#define NEXT() (p->next++) +#define NEXT2() (p->next += 2) +#define NEXTn(n) (p->next += (n)) +#define GETNEXT() (*p->next++) +#define WGETNEXT() wgetnext(p) +#define SETERROR(e) seterr(p, (e)) +#define REQUIRE(co, e) ((co) || SETERROR(e)) +#define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e)) +#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e)) +#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e)) +#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd)) +#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos) +#define AHEAD(pos) dofwd(p, pos, HERE()-(pos)) +#define ASTERN(sop, pos) EMIT(sop, HERE()-pos) +#define HERE() (p->slen) +#define THERE() (p->slen - 1) +#define THERETHERE() (p->slen - 2) +#define DROP(n) (p->slen -= (n)) + +#ifndef NDEBUG +static int never = 0; /* for use in asserts; shuts lint up */ +#else +#define never 0 /* some s have bugs too */ +#endif + +/* Macro used by computejump()/computematchjump() */ +#define MIN(a,b) ((a)<(b)?(a):(b)) + +/* + - regcomp - interface for parser and compilation + = extern int regcomp(regex_t *, const char *, int); + = #define REG_BASIC 0000 + = #define REG_EXTENDED 0001 + = #define REG_ICASE 0002 + = #define REG_NOSUB 0004 + = #define REG_NEWLINE 0010 + = #define REG_NOSPEC 0020 + = #define REG_PEND 0040 + = #define REG_DUMP 0200 + */ +int /* 0 success, otherwise REG_something */ +regcomp(preg, pattern, cflags) +regex_t * __restrict preg; +const char * __restrict pattern; +int cflags; +{ + struct parse pa; + struct re_guts *g; + struct parse *p = &pa; + int i; + size_t len; +#ifdef REDEBUG +# define GOODFLAGS(f) (f) +#else +# define GOODFLAGS(f) ((f)&~REG_DUMP) +#endif + + cflags = GOODFLAGS(cflags); + if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) + return(REG_INVARG); + + if (cflags®_PEND) { + if (preg->re_endp < pattern) + return(REG_INVARG); + len = preg->re_endp - pattern; + } else + len = strlen((char *)pattern); + + /* do the mallocs early so failure handling is easy */ + g = (struct re_guts *)malloc(sizeof(struct re_guts)); + if (g == NULL) + return(REG_ESPACE); + p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */ + p->strip = (sop *)malloc(p->ssize * sizeof(sop)); + p->slen = 0; + if (p->strip == NULL) { + free((char *)g); + return(REG_ESPACE); + } + + /* set things up */ + p->g = g; + p->next = (char *)pattern; /* convenience; we do not modify it */ + p->end = p->next + len; + p->error = 0; + p->ncsalloc = 0; +#if __DARWIN_UNIX03 + p->zerorepeats = 0; +#endif /* __DARWIN_UNIX03 */ + for (i = 0; i < NPAREN; i++) { + p->pbegin[i] = 0; + p->pend[i] = 0; + } + g->loc = __current_locale(); + g->sets = NULL; + g->ncsets = 0; + g->cflags = cflags; + g->iflags = 0; + g->nbol = 0; + g->neol = 0; + g->must = NULL; + g->moffset = -1; + g->charjump = NULL; + g->matchjump = NULL; + g->mlen = 0; + g->nsub = 0; + g->backrefs = 0; + + /* do it */ + EMIT(OEND, 0); + g->firststate = THERE(); + if (cflags®_EXTENDED) + p_ere(p, OUT); + else if (cflags®_NOSPEC) + p_str(p); + else + p_bre(p, OUT, OUT); + EMIT(OEND, 0); + g->laststate = THERE(); + + /* tidy up loose ends and fill things in */ + stripsnug(p, g); + findmust(p, g); + /* only use Boyer-Moore algorithm if the pattern is bigger + * than three characters + */ + if(g->mlen > 3) { + computejumps(p, g); + computematchjumps(p, g); + if(g->matchjump == NULL && g->charjump != NULL) { + free(g->charjump); + g->charjump = NULL; + } + } + g->nplus = pluscount(p, g); + g->magic = MAGIC2; + preg->re_nsub = g->nsub; + preg->re_g = g; + preg->re_magic = MAGIC1; +#ifndef REDEBUG + /* not debugging, so can't rely on the assert() in regexec() */ + if (g->iflags&BAD) + SETERROR(REG_ASSERT); +#endif + + /* win or lose, we're done */ + if (p->error != 0) /* lose */ + regfree(preg); + return(p->error); +} + +/* + - p_ere - ERE parser top level, concatenation and alternation + == 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 */ +{ + char c; + sopno prevback; + sopno prevfwd; + sopno conc; + int first = 1; /* is this the first alternative? */ + + for (;;) { + /* do a bunch of concatenated expressions */ + conc = HERE(); + while (MORE() && (c = PEEK()) != '|' && c != stop) + p_ere_exp(p); +#if __DARWIN_UNIX03 + if (!p->zerorepeats) REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ + else p->zerorepeats--; +#else + (void)REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ +#endif + if (!EAT('|')) + break; /* NOTE BREAK OUT */ + + if (first) { + INSERT(OCH_, conc); /* offset is wrong */ + prevfwd = conc; + prevback = conc; + first = 0; + } + ASTERN(OOR1, prevback); + prevback = THERE(); + AHEAD(prevfwd); /* fix previous offset */ + prevfwd = HERE(); + EMIT(OOR2, 0); /* offset is very wrong */ + } + + if (!first) { /* tail-end fixups */ + AHEAD(prevfwd); + ASTERN(O_CH, prevback); + } + + assert(!MORE() || SEE(stop)); +} + +/* + - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op + == static void p_ere_exp(struct parse *p); + */ +static void +p_ere_exp(p) +struct parse *p; +{ + char c; + wint_t wc; + sopno pos; + int count; + int count2; + sopno subno; + int wascaret = 0; + + assert(MORE()); /* caller should have ensured this */ + c = GETNEXT(); + + pos = HERE(); + switch (c) { + case '(': + (void)REQUIRE(MORE(), REG_EPAREN); + p->g->nsub++; + subno = p->g->nsub; + if (subno < NPAREN) + p->pbegin[subno] = HERE(); + EMIT(OLPAREN, subno); + if (!SEE(')')) + p_ere(p, ')'); + if (subno < NPAREN) { + p->pend[subno] = HERE(); + assert(p->pend[subno] != 0); + } + EMIT(ORPAREN, subno); + (void)MUSTEAT(')', REG_EPAREN); + break; +#ifndef POSIX_MISTAKE + case ')': /* happens only if no current unmatched ( */ + /* + * You may ask, why the ifndef? Because I didn't notice + * this until slightly too late for 1003.2, and none of the + * other 1003.2 regular-expression reviewers noticed it at + * all. So an unmatched ) is legal POSIX, at least until + * we can get it fixed. + */ + SETERROR(REG_EPAREN); + break; +#endif + case '^': + EMIT(OBOL, 0); + p->g->iflags |= USEBOL; + p->g->nbol++; + wascaret = 1; + break; + case '$': + EMIT(OEOL, 0); + p->g->iflags |= USEEOL; + p->g->neol++; + break; + case '|': + SETERROR(REG_EMPTY); + break; + case '*': + case '+': + case '?': + SETERROR(REG_BADRPT); + break; + case '.': + if (p->g->cflags®_NEWLINE) + nonnewline(p); + else + EMIT(OANY, 0); + break; + case '[': + p_bracket(p); + break; + case '\\': + (void)REQUIRE(MORE(), REG_EESCAPE); + wc = WGETNEXT(); + ordinary(p, wc); + break; + case '{': /* okay as ordinary except if digit follows */ + (void)REQUIRE(!MORE() || !isdigit_l((uch)PEEK(), p->g->loc), REG_BADRPT); + /* FALLTHROUGH */ + default: + p->next--; + wc = WGETNEXT(); + ordinary(p, wc); + break; + } + + if (!MORE()) + return; + c = PEEK(); + /* we call { a repetition if followed by a digit */ + if (!( c == '*' || c == '+' || c == '?' || + (c == '{' && MORE2() && isdigit_l((uch)PEEK2(), p->g->loc)) )) + return; /* no repetition, we're done */ + NEXT(); + + (void)REQUIRE(!wascaret, REG_BADRPT); + switch (c) { + case '*': /* implemented as +? */ + /* this case does not require the (y|) trick, noKLUDGE */ + INSERT(OPLUS_, pos); + ASTERN(O_PLUS, pos); + INSERT(OQUEST_, pos); + ASTERN(O_QUEST, pos); + break; + case '+': + INSERT(OPLUS_, pos); + ASTERN(O_PLUS, pos); + break; + case '?': + /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ + INSERT(OCH_, pos); /* offset slightly wrong */ + ASTERN(OOR1, pos); /* this one's right */ + AHEAD(pos); /* fix the OCH_ */ + EMIT(OOR2, 0); /* offset very wrong... */ + AHEAD(THERE()); /* ...so fix it */ + ASTERN(O_CH, THERETHERE()); + break; + case '{': + count = p_count(p); + if (EAT(',')) { + if (isdigit_l((uch)PEEK(), p->g->loc)) { + count2 = p_count(p); + (void)REQUIRE(count <= count2, REG_BADBR); + } else /* single number with comma */ + count2 = INFINITY; + } else /* just a single number */ + count2 = count; + repeat(p, pos, count, count2); + if (!EAT('}')) { /* error heuristics */ + while (MORE() && PEEK() != '}') + NEXT(); + (void)REQUIRE(MORE(), REG_EBRACE); + SETERROR(REG_BADBR); + } + break; + } + + if (!MORE()) + return; + c = PEEK(); + if (!( c == '*' || c == '+' || c == '?' || + (c == '{' && MORE2() && isdigit_l((uch)PEEK2(), p->g->loc)) ) ) + return; + SETERROR(REG_BADRPT); +} + +/* + - p_str - string (no metacharacters) "parser" + == static void p_str(struct parse *p); + */ +static void +p_str(p) +struct parse *p; +{ +#if __DARWIN_UNIX03 + if (!p->zerorepeats) REQUIRE(MORE(), REG_EMPTY); + else p->zerorepeats--; +#else /* !__DARWIN_UNIX03 */ + (void)REQUIRE(MORE(), REG_EMPTY); +#endif /* __DARWIN_UNIX03 */ + while (MORE()) + ordinary(p, WGETNEXT()); +} + +/* + - p_bre - BRE parser top level, anchoring and concatenation + == static void p_bre(struct parse *p, int end1, \ + == int end2); + * Giving end1 as OUT essentially eliminates the end1/end2 check. + * + * This implementation is a bit of a kludge, in that a trailing $ is first + * taken as an ordinary character and then revised to be an anchor. + * 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 */ +{ + sopno start = HERE(); + int first = 1; /* first subexpression? */ + int wasdollar = 0; + + if (EAT('^')) { + EMIT(OBOL, 0); + p->g->iflags |= USEBOL; + p->g->nbol++; + } + while (MORE() && !SEETWO(end1, end2)) { + wasdollar = p_simp_re(p, first); + first = 0; + } + if (wasdollar) { /* oops, that was a trailing anchor */ + DROP(1); + EMIT(OEOL, 0); + p->g->iflags |= USEEOL; + p->g->neol++; + } +#if __DARWIN_UNIX03 + if (!p->zerorepeats) REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ + else p->zerorepeats--; +#else /* !__DARWIN_UNIX03 */ + (void)REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ +#endif /* __DARWIN_UNIX03 */ +} + +/* + - p_simp_re - parse a simple RE, an atom possibly followed by a repetition + == 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? */ +{ + int c; + int count; + int count2; + sopno pos; + int i; + wint_t wc; + sopno subno; +# define BACKSL (1<g->cflags®_NEWLINE) + nonnewline(p); + else + EMIT(OANY, 0); + break; + case '[': + p_bracket(p); + break; + case BACKSL|'{': + SETERROR(REG_BADRPT); + break; + case BACKSL|'(': + p->g->nsub++; + subno = p->g->nsub; + if (subno < NPAREN) + p->pbegin[subno] = HERE(); + EMIT(OLPAREN, subno); + /* the MORE here is an error heuristic */ + if (MORE() && !SEETWO('\\', ')')) + p_bre(p, '\\', ')'); + if (subno < NPAREN) { + p->pend[subno] = HERE(); + assert(p->pend[subno] != 0); + } + EMIT(ORPAREN, subno); + (void)REQUIRE(EATTWO('\\', ')'), REG_EPAREN); + break; + case BACKSL|')': /* should not get here -- must be user */ + case BACKSL|'}': + SETERROR(REG_EPAREN); + break; + case BACKSL|'1': + case BACKSL|'2': + case BACKSL|'3': + case BACKSL|'4': + case BACKSL|'5': + case BACKSL|'6': + case BACKSL|'7': + case BACKSL|'8': + case BACKSL|'9': + i = (c&~BACKSL) - '0'; + assert(i < NPAREN); + if (p->pend[i] != 0) { +#if __DARWIN_UNIX03 + int skip = 1; +#endif /* __DARWIN_UNIX03 */ + assert(i <= p->g->nsub); + EMIT(OBACK_, i); + assert(p->pbegin[i] != 0); + assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); + assert(OP(p->strip[p->pend[i]]) == ORPAREN); +#if __DARWIN_UNIX03 + if (OP(p->strip[p->pbegin[i]+skip]) == OBOL) { + skip++; /* don't dup anchor in subexp */ + } + (void) dupl(p, p->pbegin[i]+skip, p->pend[i]); +#else /* !__DARWIN_UNIX03 */ + (void) dupl(p, p->pbegin[i]+1, p->pend[i]); +#endif /* __DARWIN_UNIX03 */ + EMIT(O_BACK, i); + } else + SETERROR(REG_ESUBREG); + p->g->backrefs = 1; + break; + case '*': + (void)REQUIRE(starordinary, REG_BADRPT); + /* FALLTHROUGH */ + default: + p->next--; + wc = WGETNEXT(); + ordinary(p, wc); + break; + } + + if (EAT('*')) { /* implemented as +? */ + /* this case does not require the (y|) trick, noKLUDGE */ + INSERT(OPLUS_, pos); + ASTERN(O_PLUS, pos); + INSERT(OQUEST_, pos); + ASTERN(O_QUEST, pos); + } else if (EATTWO('\\', '{')) { + (void)REQUIRE(MORE(), REG_EBRACE); + count = p_count(p); + if (EAT(',')) { + if (MORE() && isdigit_l((uch)PEEK(), p->g->loc)) { + count2 = p_count(p); + (void)REQUIRE(count <= count2, REG_BADBR); + } else /* single number with comma */ + count2 = INFINITY; + } else /* just a single number */ + count2 = count; + repeat(p, pos, count, count2); + if (!EATTWO('\\', '}')) { /* error heuristics */ + while (MORE() && !SEETWO('\\', '}')) + NEXT(); + (void)REQUIRE(MORE(), REG_EBRACE); + SETERROR(REG_BADBR); + } + } else if (c == '$') /* $ (but not \$) ends it */ + return(1); + + return(0); +} + +/* + - p_count - parse a repetition count + == static int p_count(struct parse *p); + */ +static int /* the value */ +p_count(p) +struct parse *p; +{ + int count = 0; + int ndigits = 0; + + while (MORE() && isdigit_l((uch)PEEK(), p->g->loc) && count <= DUPMAX) { + count = count*10 + (GETNEXT() - '0'); + ndigits++; + } + + (void)REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); + return(count); +} + +/* + - p_bracket - parse a bracketed character list + == static void p_bracket(struct parse *p); + */ +static void +p_bracket(p) +struct parse *p; +{ + cset *cs; + wint_t ch; + + /* Dept of Truly Sickening Special-Case Kludges */ + if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) { + EMIT(OBOW, 0); + NEXTn(6); + return; + } + if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) { + EMIT(OEOW, 0); + NEXTn(6); + return; + } + + if ((cs = allocset(p)) == NULL) + return; + + if (p->g->cflags®_ICASE) + cs->icase = 1; + if (EAT('^')) + cs->invert = 1; +#if __DARWIN_UNIX03 + if (PEEK2() != '-' && PEEK2() != ']') { /* Don't eat '-' or ']' if they're part of ranges + * but do process [^-] */ + if (EAT(']')) + CHadd(p, cs, ']'); + else if (EAT('-')) + CHadd(p, cs, '-'); + } + if (MORE() && !SEETWO('-',']')) /* Parse RE []-'] */ + p_b_term(p, cs); +#else /* !__DARWIN_UNIX03 */ + if (EAT(']')) + CHadd(p, cs, ']'); + else if (EAT('-')) + CHadd(p, cs, '-'); +#endif /* __DARWIN_UNIX03 */ + while (MORE() && PEEK() != ']' && !SEETWO('-', ']')) + p_b_term(p, cs); + if (EAT('-')) + CHadd(p, cs, '-'); + (void)MUSTEAT(']', REG_EBRACK); + + if (p->error != 0) /* don't mess things up further */ + return; + + if (cs->invert && p->g->cflags®_NEWLINE) + cs->bmp['\n' >> 3] |= 1 << ('\n' & 7); + + if ((ch = singleton(cs, p->g->loc)) != OUT) { /* optimize singleton sets */ + ordinary(p, ch); + freeset(p, cs); + } else + EMIT(OANYOF, (int)(cs - p->g->sets)); +} + +/* + - p_b_term - parse one term of a bracketed character list + == static void p_b_term(struct parse *p, cset *cs); + */ +static void +p_b_term(p, cs) +struct parse *p; +cset *cs; +{ + char c; + wint_t start, finish; + wint_t i; + + /* classify what we've got */ + switch ((MORE()) ? PEEK() : '\0') { + case '[': + c = (MORE2()) ? PEEK2() : '\0'; + break; + case '-': +#if __DARWIN_UNIX03 + if (PEEK2() != '-') { /* Allow [---] */ + SETERROR(REG_ERANGE); + return; /* NOTE RETURN */ + } else + c = '-'; +#else /* !__DARWIN_UNIX03 */ + SETERROR(REG_ERANGE); + return; /* NOTE RETURN */ +#endif /* __DARWIN_UNIX03 */ + break; + default: + c = '\0'; + break; + } + + switch (c) { + case ':': /* character class */ + NEXT2(); + (void)REQUIRE(MORE(), REG_EBRACK); + c = PEEK(); + (void)REQUIRE(c != '-' && c != ']', REG_ECTYPE); + p_b_cclass(p, cs); + (void)REQUIRE(MORE(), REG_EBRACK); + (void)REQUIRE(EATTWO(':', ']'), REG_ECTYPE); + break; + case '=': /* equivalence class */ + NEXT2(); + (void)REQUIRE(MORE(), REG_EBRACK); + c = PEEK(); +#if __DARWIN_UNIX03 + REQUIRE(c != '-', REG_ECOLLATE); /* allow [=]=] */ +#else /* !__DARWIN_UNIX03 */ + (void)REQUIRE(c != '-' && c != ']', REG_ECOLLATE); +#endif /* __DARWIN_UNIX03 */ + p_b_eclass(p, cs); + (void)REQUIRE(MORE(), REG_EBRACK); + (void)REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); + break; + default: /* symbol, ordinary character, or range */ + start = p_b_symbol(p); + if (SEE('-') && MORE2() && PEEK2() != ']') { + /* range */ + NEXT(); + if (EAT('-')) + finish = '-'; + else + finish = p_b_symbol(p); + } else + finish = start; + if (start == finish) + CHadd(p, cs, start); + else { + if (p->g->loc->__collate_load_error) { + (void)REQUIRE((uch)start <= (uch)finish, REG_ERANGE); + CHaddrange(p, cs, start, finish); + } else { + (void)REQUIRE(__collate_range_cmp(start, finish, p->g->loc) <= 0, REG_ERANGE); + for (i = 0; i <= UCHAR_MAX; i++) { + if ( __collate_range_cmp(start, i, p->g->loc) <= 0 + && __collate_range_cmp(i, finish, p->g->loc) <= 0 + ) + CHadd(p, cs, i); + } + } + } + break; + } +} + +/* + - p_b_cclass - parse a character-class name and deal with it + == static void p_b_cclass(struct parse *p, cset *cs); + */ +static void +p_b_cclass(p, cs) +struct parse *p; +cset *cs; +{ + char *sp = p->next; + size_t len; + wctype_t wct; + char clname[16]; + + while (MORE() && isalpha_l((uch)PEEK(), p->g->loc)) + NEXT(); + len = p->next - sp; + if (len >= sizeof(clname) - 1) { + SETERROR(REG_ECTYPE); + return; + } + memcpy(clname, sp, len); + clname[len] = '\0'; + if ((wct = wctype_l(clname, p->g->loc)) == 0) { + SETERROR(REG_ECTYPE); + return; + } + CHaddtype(p, cs, wct); +} + +/* + - p_b_eclass - parse an equivalence-class name and deal with it + == static void p_b_eclass(struct parse *p, cset *cs); + */ +static void +p_b_eclass(p, cs) +struct parse *p; +cset *cs; +{ + char *sp = p->next; + int len, ec; + mbstate_t mbs; + int *newequiv_classes; + wint_t c; + + while (MORE() && !SEETWO('=', ']')) + NEXT(); + if (!MORE()) { + SETERROR(REG_EBRACK); + return; + } + len = p->next - sp; + memset(&mbs, 0, sizeof(mbs)); + ec = __collate_equiv_class(sp, len, &mbs, p->g->loc); + if (ec > 0) { + newequiv_classes = realloc(cs->equiv_classes, + (cs->nequiv_classes + 1) * sizeof(*cs->equiv_classes)); + if (newequiv_classes == NULL) { + SETERROR(REG_ESPACE); + return; + } + cs->equiv_classes = newequiv_classes; + cs->equiv_classes[cs->nequiv_classes++] = ec; + return; + } + /* not an equivalence class, so fallback to a collating element */ + p->next = sp; + c = p_b_coll_elem(p, '='); + CHadd(p, cs, c); +} + +/* + - p_b_symbol - parse a character or [..]ed multicharacter collating symbol + == static char p_b_symbol(struct parse *p); + */ +static wint_t /* value of symbol */ +p_b_symbol(p) +struct parse *p; +{ + wint_t value; + + (void)REQUIRE(MORE(), REG_EBRACK); + if (!EATTWO('[', '.')) + return(WGETNEXT()); + + /* collating symbol */ + value = p_b_coll_elem(p, '.'); + (void)REQUIRE(EATTWO('.', ']'), REG_ECOLLATE); + return(value); +} + +/* + - p_b_coll_elem - parse a collating-element name and look it up + == 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,']' */ +{ + char *sp = p->next; + struct cname *cp; + int len; + mbstate_t mbs; + wchar_t wbuf[16]; + size_t clen; + + while (MORE() && !SEETWO(endc, ']')) + NEXT(); + if (!MORE()) { + SETERROR(REG_EBRACK); + return(0); + } + len = p->next - sp; + for (cp = cnames; cp->name != NULL; cp++) + if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') + return(cp->code); /* known name */ + memset(&mbs, 0, sizeof(mbs)); + clen = __collate_collating_symbol(wbuf, 16, sp, len, &mbs, p->g->loc); + if (clen == 1) + return (*wbuf); /* single character */ + else if (clen == (size_t)-1) + SETERROR(REG_ILLSEQ); + else + SETERROR(REG_ECOLLATE); /* neither */ + return(0); +} + +/* + - othercase - return the case counterpart of an alphabetic + == static char othercase(int ch, locale_t loc); + */ +static wint_t /* if no counterpart, return ch */ +othercase(ch, loc) +wint_t ch; +locale_t loc; +{ + assert(iswalpha_l(ch, loc)); + if (iswupper_l(ch, loc)) + return(towlower_l(ch, loc)); + else if (iswlower_l(ch, loc)) + return(towupper_l(ch, loc)); + else /* peculiar, but could happen */ + return(ch); +} + +/* + - bothcases - emit a dualcase version of a two-case character + == static void bothcases(struct parse *p, int ch); + * + * Boy, is this implementation ever a kludge... + */ +static void +bothcases(p, ch) +struct parse *p; +wint_t ch; +{ + char *oldnext = p->next; + char *oldend = p->end; + char bracket[3 + MB_LEN_MAX]; + size_t n; + mbstate_t mbs; + + assert(othercase(ch, p->g->loc) != ch); /* p_bracket() would recurse */ + p->next = bracket; + memset(&mbs, 0, sizeof(mbs)); + n = wcrtomb_l(bracket, ch, &mbs, p->g->loc); + assert(n != (size_t)-1); + bracket[n] = ']'; + bracket[n + 1] = '\0'; + p->end = bracket+n+1; + p_bracket(p); + assert(p->next == p->end); + p->next = oldnext; + p->end = oldend; +} + +/* + - ordinary - emit an ordinary character + == static void ordinary(struct parse *p, int ch); + */ +static void +ordinary(p, ch) +struct parse *p; +wint_t ch; +{ + cset *cs; + + if ((p->g->cflags®_ICASE) && iswalpha_l(ch, p->g->loc) && othercase(ch, p->g->loc) != ch) + bothcases(p, ch); + else if ((ch & OPDMASK) == ch) + EMIT(OCHAR, ch); + else { + /* + * Kludge: character is too big to fit into an OCHAR operand. + * Emit a singleton set. + */ + if ((cs = allocset(p)) == NULL) + return; + CHadd(p, cs, ch); + EMIT(OANYOF, (int)(cs - p->g->sets)); + } +} + +/* + - nonnewline - emit REG_NEWLINE version of OANY + == static void nonnewline(struct parse *p); + * + * Boy, is this implementation ever a kludge... + */ +static void +nonnewline(p) +struct parse *p; +{ + char *oldnext = p->next; + char *oldend = p->end; + char bracket[4]; + + p->next = bracket; + p->end = bracket+3; + bracket[0] = '^'; + bracket[1] = '\n'; + bracket[2] = ']'; + bracket[3] = '\0'; + p_bracket(p); + assert(p->next == bracket+3); + p->next = oldnext; + p->end = oldend; +} + +/* + - repeat - generate code for a bounded repetition, recursively if needed + == 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) */ +{ + sopno finish = HERE(); +# define N 2 +# define INF 3 +# define REP(f, t) ((f)*8 + (t)) +# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) + sopno copy; + + if (p->error != 0) /* head off possible runaway recursion */ + return; + + assert(from <= to); + + switch (REP(MAP(from), MAP(to))) { + case REP(0, 0): /* must be user doing this */ + DROP(finish-start); /* drop the operand */ +#if __DARWIN_UNIX03 + p->zerorepeats++; +#endif /* __DARWIN_UNIX03 */ + break; + case REP(0, INF): /* as x{1,}? */ +#if __DARWIN_UNIX03 + /* this case does not require the (y|) trick, noKLUDGE */ + /* Just like * =+? */ + INSERT(OPLUS_, start); + ASTERN(O_PLUS, start); + INSERT(OQUEST_, start); + ASTERN(O_QUEST, start); + break; +#endif /* __DARWIN_UNIX03 */ + case REP(0, 1): /* as x{1,1}? */ + case REP(0, N): /* as x{1,n}? */ + /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ + INSERT(OCH_, start); /* offset is wrong... */ + repeat(p, start+1, 1, to); + ASTERN(OOR1, start); + AHEAD(start); /* ... fix it */ + EMIT(OOR2, 0); + AHEAD(THERE()); + ASTERN(O_CH, THERETHERE()); + break; + case REP(1, 1): /* trivial case */ + /* done */ + break; + case REP(1, N): /* as x?x{1,n-1} */ +#if __DARWIN_UNIX03 + INSERT(OQUEST_, start); + ASTERN(O_QUEST, start); +#else /* !__DARWIN_UNIX03 */ + /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ + INSERT(OCH_, start); + ASTERN(OOR1, start); + AHEAD(start); + EMIT(OOR2, 0); /* offset very wrong... */ + AHEAD(THERE()); /* ...so fix it */ + ASTERN(O_CH, THERETHERE()); +#endif /* __DARWIN_UNIX03 */ + copy = dupl(p, start+1, finish+1); + assert(copy == finish+4); + repeat(p, copy, 1, to-1); + break; + case REP(1, INF): /* as x+ */ + INSERT(OPLUS_, start); + ASTERN(O_PLUS, start); + break; + case REP(N, N): /* as xx{m-1,n-1} */ + copy = dupl(p, start, finish); + repeat(p, copy, from-1, to-1); + break; + case REP(N, INF): /* as xx{n-1,INF} */ + copy = dupl(p, start, finish); + repeat(p, copy, from-1, to); + break; + default: /* "can't happen" */ + SETERROR(REG_ASSERT); /* just in case */ + break; + } +} + +/* + - wgetnext - helper function for WGETNEXT() macro. Gets the next wide + - character from the parse struct, signals a REG_ILLSEQ error if the + - character can't be converted. Returns the number of bytes consumed. + */ +static wint_t +wgetnext(p) +struct parse *p; +{ + mbstate_t mbs; + wchar_t wc; + size_t n; + + memset(&mbs, 0, sizeof(mbs)); + n = mbrtowc_l(&wc, p->next, p->end - p->next, &mbs, p->g->loc); + if (n == (size_t)-1 || n == (size_t)-2) { + SETERROR(REG_ILLSEQ); + return (0); + } + if (n == 0) + n = 1; + p->next += n; + return (wc); +} + +/* + - seterr - set an error condition + == static int seterr(struct parse *p, int e); + */ +static int /* useless but makes type checking happy */ +seterr(p, e) +struct parse *p; +int e; +{ + if (p->error == 0) /* keep earliest error condition */ + p->error = e; + p->next = nuls; /* try to bring things to a halt */ + p->end = nuls; + return(0); /* make the return value well-defined */ +} + +/* + - allocset - allocate a set of characters for [] + == static cset *allocset(struct parse *p); + */ +static cset * +allocset(p) +struct parse *p; +{ + cset *cs, *ncs; + + ncs = realloc(p->g->sets, (p->g->ncsets + 1) * sizeof(*ncs)); + if (ncs == NULL) { + SETERROR(REG_ESPACE); + return (NULL); + } + p->g->sets = ncs; + cs = &p->g->sets[p->g->ncsets++]; + memset(cs, 0, sizeof(*cs)); + + return(cs); +} + +/* + - freeset - free a now-unused set + == static void freeset(struct parse *p, cset *cs); + */ +static void +freeset(p, cs) +struct parse *p; +cset *cs; +{ + cset *top = &p->g->sets[p->g->ncsets]; + + free(cs->wides); + free(cs->ranges); + free(cs->types); + memset(cs, 0, sizeof(*cs)); + if (cs == top-1) /* recover only the easy case */ + p->g->ncsets--; +} + +/* + - singleton - Determine whether a set contains only one character, + - returning it if so, otherwise returning OUT. + */ +static wint_t +singleton(cs, loc) +cset *cs; +locale_t loc; +{ + wint_t i, s, n; + + for (i = n = 0; i < NC; i++) + if (CHIN(cs, i, loc)) { + n++; + s = i; + } + if (n == 1) + return (s); + if (cs->nwides == 1 && cs->nranges == 0 && cs->ntypes == 0 && + cs->icase == 0) + return (cs->wides[0]); + /* Don't bother handling the other cases. */ + return (OUT); +} + +/* + - CHadd - add character to character set. + */ +static void +CHadd(p, cs, ch) +struct parse *p; +cset *cs; +wint_t ch; +{ + wint_t nch, *newwides; + assert(ch >= 0); + if (ch < NC) + cs->bmp[ch >> 3] |= 1 << (ch & 7); + else { + newwides = realloc(cs->wides, (cs->nwides + 1) * + sizeof(*cs->wides)); + if (newwides == NULL) { + SETERROR(REG_ESPACE); + return; + } + cs->wides = newwides; + cs->wides[cs->nwides++] = ch; + } + if (cs->icase) { + if ((nch = towlower_l(ch, p->g->loc)) < NC) + cs->bmp[nch >> 3] |= 1 << (nch & 7); + if ((nch = towupper_l(ch, p->g->loc)) < NC) + cs->bmp[nch >> 3] |= 1 << (nch & 7); + } +} + +/* + - 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; +{ + crange *newranges; + + for (; min < NC && min <= max; min++) + CHadd(p, cs, min); + if (min >= max) + return; + newranges = realloc(cs->ranges, (cs->nranges + 1) * + sizeof(*cs->ranges)); + if (newranges == NULL) { + SETERROR(REG_ESPACE); + return; + } + cs->ranges = newranges; + cs->ranges[cs->nranges].min = min; + cs->ranges[cs->nranges].min = max; + cs->nranges++; +} + +/* + - 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; +{ + wint_t i; + wctype_t *newtypes; + + for (i = 0; i < NC; i++) + if (iswctype_l(i, wct, p->g->loc)) + CHadd(p, cs, i); + newtypes = realloc(cs->types, (cs->ntypes + 1) * + sizeof(*cs->types)); + if (newtypes == NULL) { + SETERROR(REG_ESPACE); + return; + } + cs->types = newtypes; + cs->types[cs->ntypes++] = wct; +} + +/* + - dupl - emit a duplicate of a bunch of sops + == 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 */ +{ + sopno ret = HERE(); + sopno len = finish - start; + + assert(finish >= start); + if (len == 0) + return(ret); + enlarge(p, p->ssize + len); /* this many unexpected additions */ + assert(p->ssize >= p->slen + len); + (void) memcpy((char *)(p->strip + p->slen), + (char *)(p->strip + start), (size_t)len*sizeof(sop)); + p->slen += len; + return(ret); +} + +/* + - doemit - emit a strip operator + == static void doemit(struct parse *p, sop op, size_t opnd); + * + * It might seem better to implement this as a macro with a function as + * hard-case backup, but it's just too big and messy unless there are + * some changes to the data structures. Maybe later. + */ +static void +doemit(p, op, opnd) +struct parse *p; +sop op; +size_t opnd; +{ + /* avoid making error situations worse */ + if (p->error != 0) + return; + + /* deal with oversize operands ("can't happen", more or less) */ + assert(opnd < 1<slen >= p->ssize) + enlarge(p, (p->ssize+1) / 2 * 3); /* +50% */ + assert(p->slen < p->ssize); + + /* finally, it's all reduced to the easy case */ + p->strip[p->slen++] = SOP(op, opnd); +} + +/* + - doinsert - insert a sop into the strip + == 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; +{ + sopno sn; + sop s; + int i; + + /* avoid making error situations worse */ + if (p->error != 0) + return; + + sn = HERE(); + EMIT(op, opnd); /* do checks, ensure space */ + assert(HERE() == sn+1); + s = p->strip[sn]; + + /* adjust paren pointers */ + assert(pos > 0); + for (i = 1; i < NPAREN; i++) { + if (p->pbegin[i] >= pos) { + p->pbegin[i]++; + } + if (p->pend[i] >= pos) { + p->pend[i]++; + } + } + + memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], + (HERE()-pos-1)*sizeof(sop)); + p->strip[pos] = s; +} + +/* + - dofwd - complete a forward reference + == static void dofwd(struct parse *p, sopno pos, sop value); + */ +static void +dofwd(p, pos, value) +struct parse *p; +sopno pos; +sop value; +{ + /* avoid making error situations worse */ + if (p->error != 0) + return; + + assert(value < 1<strip[pos] = OP(p->strip[pos]) | value; +} + +/* + - enlarge - enlarge the strip + == static void enlarge(struct parse *p, sopno size); + */ +static void +enlarge(p, size) +struct parse *p; +sopno size; +{ + sop *sp; + + if (p->ssize >= size) + return; + + sp = (sop *)realloc(p->strip, size*sizeof(sop)); + if (sp == NULL) { + SETERROR(REG_ESPACE); + return; + } + p->strip = sp; + p->ssize = size; +} + +/* + - stripsnug - compact the strip + == static void stripsnug(struct parse *p, struct re_guts *g); + */ +static void +stripsnug(p, g) +struct parse *p; +struct re_guts *g; +{ + g->nstates = p->slen; + g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop)); + if (g->strip == NULL) { + SETERROR(REG_ESPACE); + g->strip = p->strip; + } +} + +/* + - findmust - fill in must and mlen with longest mandatory literal string + == static void findmust(struct parse *p, struct re_guts *g); + * + * This algorithm could do fancy things like analyzing the operands of | + * for common subsequences. Someday. This code is simple and finds most + * of the interesting cases. + * + * Note that must and mlen got initialized during setup. + */ +static void +findmust(p, g) +struct parse *p; +struct re_guts *g; +{ + sop *scan; + sop *start; + sop *newstart; + sopno newlen; + sop s; + char *cp; + int offset; + char buf[MB_LEN_MAX]; + size_t clen; + mbstate_t mbs; + struct __xlocale_st_runelocale *rl = p->g->loc->__lc_ctype; + + /* avoid making error situations worse */ + if (p->error != 0) + return; + + /* + * It's not generally safe to do a ``char'' substring search on + * multibyte character strings, but it's safe for at least + * UTF-8 (see RFC 3629). + */ + if (rl->__mb_cur_max > 1 && + strcmp(rl->_CurrentRuneLocale.__encoding, "UTF-8") != 0) + return; + + /* find the longest OCHAR sequence in strip */ + newlen = 0; + offset = 0; + g->moffset = 0; + scan = g->strip + 1; + do { + s = *scan++; + switch (OP(s)) { + case OCHAR: /* sequence member */ + if (newlen == 0) { /* new sequence */ + memset(&mbs, 0, sizeof(mbs)); + newstart = scan - 1; + } + clen = wcrtomb_l(buf, OPND(s), &mbs, p->g->loc); + if (clen == (size_t)-1) + goto toohard; + newlen += clen; + break; + case OPLUS_: /* things that don't break one */ + case OLPAREN: + case ORPAREN: + break; + case OQUEST_: /* things that must be skipped */ + case OCH_: + offset = altoffset(scan, offset); + scan--; + do { + scan += OPND(s); + s = *scan; + /* assert() interferes w debug printouts */ + if (OP(s) != O_QUEST && OP(s) != O_CH && + OP(s) != OOR2) { + g->iflags |= BAD; + return; + } + } while (OP(s) != O_QUEST && OP(s) != O_CH); + /* FALLTHROUGH */ + case OBOW: /* things that break a sequence */ + case OEOW: + case OBOL: + case OEOL: + case O_QUEST: + case O_CH: + case OEND: + if (newlen > g->mlen) { /* ends one */ + start = newstart; + g->mlen = newlen; + if (offset > -1) { + g->moffset += offset; + offset = newlen; + } else + g->moffset = offset; + } else { + if (offset > -1) + offset += newlen; + } + newlen = 0; + break; + case OANY: + if (newlen > g->mlen) { /* ends one */ + start = newstart; + g->mlen = newlen; + if (offset > -1) { + g->moffset += offset; + offset = newlen; + } else + g->moffset = offset; + } else { + if (offset > -1) + offset += newlen; + } + if (offset > -1) + offset++; + newlen = 0; + break; + case OANYOF: /* may or may not invalidate offset */ + /* First, everything as OANY */ + if (newlen > g->mlen) { /* ends one */ + start = newstart; + g->mlen = newlen; + if (offset > -1) { + g->moffset += offset; + offset = newlen; + } else + g->moffset = offset; + } else { + if (offset > -1) + offset += newlen; + } + if (offset > -1) + offset++; + newlen = 0; + break; + toohard: + default: + /* Anything here makes it impossible or too hard + * to calculate the offset -- so we give up; + * save the last known good offset, in case the + * must sequence doesn't occur later. + */ + if (newlen > g->mlen) { /* ends one */ + start = newstart; + g->mlen = newlen; + if (offset > -1) + g->moffset += offset; + else + g->moffset = offset; + } + offset = -1; + newlen = 0; + break; + } + } while (OP(s) != OEND); + + if (g->mlen == 0) { /* there isn't one */ + g->moffset = -1; + return; + } + + /* turn it into a character string */ + g->must = malloc((size_t)g->mlen + 1); + if (g->must == NULL) { /* argh; just forget it */ + g->mlen = 0; + g->moffset = -1; + return; + } + cp = g->must; + scan = start; + memset(&mbs, 0, sizeof(mbs)); + while (cp < g->must + g->mlen) { + while (OP(s = *scan++) != OCHAR) + continue; + clen = wcrtomb_l(cp, OPND(s), &mbs, p->g->loc); + assert(clen != (size_t)-1); + cp += clen; + } + assert(cp == g->must + g->mlen); + *cp++ = '\0'; /* just on general principles */ +} + +/* + - altoffset - choose biggest offset among multiple choices + == static int altoffset(sop *scan, int offset); + * + * Compute, recursively if necessary, the largest offset among multiple + * re paths. + */ +static int +altoffset(scan, offset) +sop *scan; +int offset; +{ + int largest; + int try; + sop s; + + /* If we gave up already on offsets, return */ + if (offset == -1) + return -1; + + largest = 0; + try = 0; + s = *scan++; + while (OP(s) != O_QUEST && OP(s) != O_CH) { + switch (OP(s)) { + case OOR1: + if (try > largest) + largest = try; + try = 0; + break; + case OQUEST_: + case OCH_: + try = altoffset(scan, try); + if (try == -1) + return -1; + scan--; + do { + scan += OPND(s); + s = *scan; + if (OP(s) != O_QUEST && OP(s) != O_CH && + OP(s) != OOR2) + return -1; + } while (OP(s) != O_QUEST && OP(s) != O_CH); + /* We must skip to the next position, or we'll + * leave altoffset() too early. + */ + scan++; + break; + case OANYOF: + case OCHAR: + case OANY: + try++; + case OBOW: + case OEOW: + case OLPAREN: + case ORPAREN: + case OOR2: + break; + default: + try = -1; + break; + } + if (try == -1) + return -1; + s = *scan++; + } + + if (try > largest) + largest = try; + + return largest+offset; +} + +/* + - computejumps - compute char jumps for BM scan + == static void computejumps(struct parse *p, struct re_guts *g); + * + * This algorithm assumes g->must exists and is has size greater than + * zero. It's based on the algorithm found on Computer Algorithms by + * Sara Baase. + * + * A char jump is the number of characters one needs to jump based on + * the value of the character from the text that was mismatched. + */ +static void +computejumps(p, g) +struct parse *p; +struct re_guts *g; +{ + int ch; + int mindex; + + /* Avoid making errors worse */ + if (p->error != 0) + return; + + g->charjump = (int*) malloc((NC + 1) * sizeof(int)); + if (g->charjump == NULL) /* Not a fatal error */ + return; + /* Adjust for signed chars, if necessary */ + g->charjump = &g->charjump[-(CHAR_MIN)]; + + /* If the character does not exist in the pattern, the jump + * is equal to the number of characters in the pattern. + */ + for (ch = CHAR_MIN; ch < (CHAR_MAX + 1); ch++) + g->charjump[ch] = g->mlen; + + /* If the character does exist, compute the jump that would + * take us to the last character in the pattern equal to it + * (notice that we match right to left, so that last character + * is the first one that would be matched). + */ + for (mindex = 0; mindex < g->mlen; mindex++) + g->charjump[(int)g->must[mindex]] = g->mlen - mindex - 1; +} + +/* + - computematchjumps - compute match jumps for BM scan + == static void computematchjumps(struct parse *p, struct re_guts *g); + * + * This algorithm assumes g->must exists and is has size greater than + * zero. It's based on the algorithm found on Computer Algorithms by + * Sara Baase. + * + * A match jump is the number of characters one needs to advance based + * on the already-matched suffix. + * Notice that all values here are minus (g->mlen-1), because of the way + * the search algorithm works. + */ +static void +computematchjumps(p, g) +struct parse *p; +struct re_guts *g; +{ + int mindex; /* General "must" iterator */ + int suffix; /* Keeps track of matching suffix */ + int ssuffix; /* Keeps track of suffixes' suffix */ + int* pmatches; /* pmatches[k] points to the next i + * such that i+1...mlen is a substring + * of k+1...k+mlen-i-1 + */ + + /* Avoid making errors worse */ + if (p->error != 0) + return; + + pmatches = (int*) malloc(g->mlen * sizeof(unsigned int)); + if (pmatches == NULL) { + g->matchjump = NULL; + return; + } + + g->matchjump = (int*) malloc(g->mlen * sizeof(unsigned int)); + if (g->matchjump == NULL) /* Not a fatal error */ + return; + + /* Set maximum possible jump for each character in the pattern */ + for (mindex = 0; mindex < g->mlen; mindex++) + g->matchjump[mindex] = 2*g->mlen - mindex - 1; + + /* Compute pmatches[] */ + for (mindex = g->mlen - 1, suffix = g->mlen; mindex >= 0; + mindex--, suffix--) { + pmatches[mindex] = suffix; + + /* If a mismatch is found, interrupting the substring, + * compute the matchjump for that position. If no + * mismatch is found, then a text substring mismatched + * against the suffix will also mismatch against the + * substring. + */ + while (suffix < g->mlen + && g->must[mindex] != g->must[suffix]) { + g->matchjump[suffix] = MIN(g->matchjump[suffix], + g->mlen - mindex - 1); + suffix = pmatches[suffix]; + } + } + + /* Compute the matchjump up to the last substring found to jump + * to the beginning of the largest must pattern prefix matching + * it's own suffix. + */ + for (mindex = 0; mindex <= suffix; mindex++) + g->matchjump[mindex] = MIN(g->matchjump[mindex], + g->mlen + suffix - mindex); + + ssuffix = pmatches[suffix]; + while (suffix < g->mlen) { + while (suffix <= ssuffix && suffix < g->mlen) { + g->matchjump[suffix] = MIN(g->matchjump[suffix], + g->mlen + ssuffix - suffix); + suffix++; + } + if (suffix < g->mlen) + ssuffix = pmatches[ssuffix]; + } + + free(pmatches); +} + +/* + - pluscount - count + nesting + == static sopno pluscount(struct parse *p, struct re_guts *g); + */ +static sopno /* nesting depth */ +pluscount(p, g) +struct parse *p; +struct re_guts *g; +{ + sop *scan; + sop s; + sopno plusnest = 0; + sopno maxnest = 0; + + if (p->error != 0) + return(0); /* there may not be an OEND */ + + scan = g->strip + 1; + do { + s = *scan++; + switch (OP(s)) { + case OPLUS_: + plusnest++; + break; + case O_PLUS: + if (plusnest > maxnest) + maxnest = plusnest; + plusnest--; + break; + } + } while (OP(s) != OEND); + if (plusnest != 0) + g->iflags |= BAD; + return(maxnest); +} diff --git a/regex/regerror-fbsd.c b/regex/regerror-fbsd.c new file mode 100644 index 0000000..4e43f3d --- /dev/null +++ b/regex/regerror-fbsd.c @@ -0,0 +1,181 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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.9 2004/07/12 06:07:26 tjr 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(errcode, preg, errbuf, errbuf_size) +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(preg, localbuf) +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 new file mode 100644 index 0000000..9f6b115 --- /dev/null +++ b/regex/regex.3 @@ -0,0 +1,737 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd July 12, 2004 +.Dt REGEX 3 +.Os +.Sh NAME +.Nm regcomp , +.Nm regerror , +.Nm regexec , +.Nm regfree +.Nd regular-expression library +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In regex.h +.Ft int +.Fo regcomp +.Fa "regex_t *restrict preg" +.Fa "const char *restrict pattern" +.Fa "int cflags" +.Fc +.Ft size_t +.Fo regerror +.Fa "int errcode" +.Fa "const regex_t *restrict preg" +.Fa "char *restrict errbuf" +.Fa "size_t errbuf_size" +.Fc +.Ft int +.Fo regexec +.Fa "const regex_t *restrict preg" +.Fa "const char *restrict string" +.Fa "size_t nmatch" +.Fa "regmatch_t pmatch[restrict]" +.Fa "int eflags" +.Fc +.Ft void +.Fo regfree +.Fa "regex_t *preg" +.Fc +.Sh DESCRIPTION +These routines implement +.St -p1003.2 +regular expressions +.Pq Do RE Dc Ns s ; +see +.Xr re_format 7 . +The +.Fn regcomp +function +compiles an RE, written as a string, into an internal form. +.Fn regexec +matches that internal form against a string and reports results. +.Fn regerror +transforms error codes from either into human-readable messages. +.Fn regfree +frees any dynamically-allocated storage used by the internal form +of an RE. +.Pp +The header +.In regex.h +declares two structure types, +.Ft regex_t +and +.Ft regmatch_t , +the former for compiled internal forms and the latter for match reporting. +It also declares the four functions, +a type +.Ft regoff_t , +and a number of constants with names starting with +.Dq Dv REG_ . +.Pp +The +.Fn regcomp +function +compiles the regular expression contained in the +.Fa pattern +string, +subject to the flags in +.Fa cflags , +and places the results in the +.Ft regex_t +structure pointed to by +.Fa preg . +The +.Fa cflags +argument +is the bitwise OR of zero or more of the following flags: +.Bl -tag -width REG_EXTENDED +.It Dv REG_EXTENDED +Compile modern +.Pq Dq extended +REs, +rather than the obsolete +.Pq Dq basic +REs that +are the default. +.It Dv REG_BASIC +This is a synonym for 0, +provided as a counterpart to +.Dv REG_EXTENDED +to improve readability. +.It Dv REG_NOSPEC +Compile with recognition of all special characters turned off. +All characters are thus considered ordinary, +so the +.Dq RE +is a literal string. +This is an extension, +compatible with but not specified by +.St -p1003.2 , +and should be used with +caution in software intended to be portable to other systems. +.Dv REG_EXTENDED +and +.Dv REG_NOSPEC +may not be used +in the same call to +.Fn regcomp . +.It Dv REG_ICASE +Compile for matching that ignores upper/lower case distinctions. +See +.Xr re_format 7 . +.It Dv REG_NOSUB +Compile for matching that need only report success or failure, +not what was matched. +.It Dv REG_NEWLINE +Compile for newline-sensitive matching. +By default, newline is a completely ordinary character with no special +meaning in either REs or strings. +With this flag, +.Ql [^ +bracket expressions and +.Ql .\& +never match newline, +a +.Ql ^\& +anchor matches the null string after any newline in the string +in addition to its normal function, +and the +.Ql $\& +anchor matches the null string before any newline in the +string in addition to its normal function. +.It Dv REG_PEND +The regular expression ends, +not at the first NUL, +but just before the character pointed to by the +.Va re_endp +member of the structure pointed to by +.Fa preg . +The +.Va re_endp +member is of type +.Ft "const char *" . +This flag permits inclusion of NULs in the RE; +they are considered ordinary characters. +This is an extension, +compatible with but not specified by +.St -p1003.2 , +and should be used with +caution in software intended to be portable to other systems. +.El +.Pp +When successful, +.Fn regcomp +returns 0 and fills in the structure pointed to by +.Fa preg . +One member of that structure +(other than +.Va re_endp ) +is publicized: +.Va re_nsub , +of type +.Ft size_t , +contains the number of parenthesized subexpressions within the RE +(except that the value of this member is undefined if the +.Dv REG_NOSUB +flag was used). +If +.Fn regcomp +fails, it returns a non-zero error code; +see +.Sx DIAGNOSTICS . +.Pp +The +.Fn regexec +function +matches the compiled RE pointed to by +.Fa preg +against the +.Fa string , +subject to the flags in +.Fa eflags , +and reports results using +.Fa nmatch , +.Fa pmatch , +and the returned value. +The RE must have been compiled by a previous invocation of +.Fn regcomp . +The compiled form is not altered during execution of +.Fn regexec , +so a single compiled RE can be used simultaneously by multiple threads. +.Pp +By default, +the NUL-terminated string pointed to by +.Fa string +is considered to be the text of an entire line, minus any terminating +newline. +The +.Fa eflags +argument is the bitwise OR of zero or more of the following flags: +.Bl -tag -width REG_STARTEND +.It Dv REG_NOTBOL +The first character of +the string +is not the beginning of a line, so the +.Ql ^\& +anchor should not match before it. +This does not affect the behavior of newlines under +.Dv REG_NEWLINE . +.It Dv REG_NOTEOL +The NUL terminating +the string +does not end a line, so the +.Ql $\& +anchor should not match before it. +This does not affect the behavior of newlines under +.Dv REG_NEWLINE . +.It Dv REG_STARTEND +The string is considered to start at +.Fa string ++ +.Fa pmatch Ns [0]. Ns Va rm_so +and to have a terminating NUL located at +.Fa string ++ +.Fa pmatch Ns [0]. Ns Va rm_eo +(there need not actually be a NUL at that location), +regardless of the value of +.Fa nmatch . +See below for the definition of +.Fa pmatch +and +.Fa nmatch . +This is an extension, +compatible with but not specified by +.St -p1003.2 , +and should be used with +caution in software intended to be portable to other systems. +Note that a non-zero +.Va rm_so +does not imply +.Dv REG_NOTBOL ; +.Dv REG_STARTEND +affects only the location of the string, +not how it is matched. +.El +.Pp +See +.Xr re_format 7 +for a discussion of what is matched in situations where an RE or a +portion thereof could match any of several substrings of +.Fa string . +.Pp +Normally, +.Fn regexec +returns 0 for success and the non-zero code +.Dv REG_NOMATCH +for failure. +Other non-zero error codes may be returned in exceptional situations; +see +.Sx DIAGNOSTICS . +.Pp +If +.Dv REG_NOSUB +was specified in the compilation of the RE, +or if +.Fa nmatch +is 0, +.Fn regexec +ignores the +.Fa pmatch +argument (but see below for the case where +.Dv REG_STARTEND +is specified). +Otherwise, +.Fa pmatch +points to an array of +.Fa nmatch +structures of type +.Ft regmatch_t . +Such a structure has at least the members +.Va rm_so +and +.Va rm_eo , +both of type +.Ft regoff_t +(a signed arithmetic type at least as large as an +.Ft off_t +and a +.Ft ssize_t ) , +containing respectively the offset of the first character of a substring +and the offset of the first character after the end of the substring. +Offsets are measured from the beginning of the +.Fa string +argument given to +.Fn regexec . +An empty substring is denoted by equal offsets, +both indicating the character following the empty substring. +.Pp +The 0th member of the +.Fa pmatch +array is filled in to indicate what substring of +.Fa string +was matched by the entire RE. +Remaining members report what substring was matched by parenthesized +subexpressions within the RE; +member +.Va i +reports subexpression +.Va i , +with subexpressions counted (starting at 1) by the order of their opening +parentheses in the RE, left to right. +Unused entries in the array (corresponding either to subexpressions that +did not participate in the match at all, or to subexpressions that do not +exist in the RE (that is, +.Va i +> +.Fa preg Ns -> Ns Va re_nsub ) ) +have both +.Va rm_so +and +.Va rm_eo +set to -1. +If a subexpression participated in the match several times, +the reported substring is the last one it matched. +(Note, as an example in particular, that when the RE +.Ql "(b*)+" +matches +.Ql bbb , +the parenthesized subexpression matches each of the three +.So Li b Sc Ns s +and then +an infinite number of empty strings following the last +.Ql b , +so the reported substring is one of the empties.) +.Pp +If +.Dv REG_STARTEND +is specified, +.Fa pmatch +must point to at least one +.Ft regmatch_t +(even if +.Fa nmatch +is 0 or +.Dv REG_NOSUB +was specified), +to hold the input offsets for +.Dv REG_STARTEND . +Use for output is still entirely controlled by +.Fa nmatch ; +if +.Fa nmatch +is 0 or +.Dv REG_NOSUB +was specified, +the value of +.Fa pmatch Ns [0] +will not be changed by a successful +.Fn regexec . +.Pp +The +.Fn regerror +function +maps a non-zero +.Fa errcode +from either +.Fn regcomp +or +.Fn regexec +to a human-readable, printable message. +If +.Fa preg +is +.No non\- Ns Dv NULL , +the error code should have arisen from use of +the +.Ft regex_t +pointed to by +.Fa preg , +and if the error code came from +.Fn regcomp , +it should have been the result from the most recent +.Fn regcomp +using that +.Ft regex_t . +The +.Fn ( regerror +may be able to supply a more detailed message using information +from the +.Ft regex_t . ) +The +.Fn regerror +function +places the NUL-terminated message into the buffer pointed to by +.Fa errbuf , +limiting the length (including the NUL) to at most +.Fa errbuf_size +bytes. +If the whole message won't 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 +message (including terminating NUL). +If +.Fa errbuf_size +is 0, +.Fa errbuf +is ignored but the return value is still correct. +.Pp +If the +.Fa errcode +given to +.Fn regerror +is first ORed with +.Dv REG_ITOA , +the +.Dq message +that results is the printable name of the error code, +e.g.\& +.Dq Dv REG_NOMATCH , +rather than an explanation thereof. +If +.Fa errcode +is +.Dv REG_ATOI , +then +.Fa preg +shall be +.No non\- Ns Dv NULL +and the +.Va re_endp +member of the structure it points to +must point to the printable name of an error code; +in this case, the result in +.Fa errbuf +is the decimal digits of +the numeric value of the error code +(0 if the name is not recognized). +.Dv REG_ITOA +and +.Dv REG_ATOI +are intended primarily as debugging facilities; +they are extensions, +compatible with but not specified by +.St -p1003.2 , +and should be used with +caution in software intended to be portable to other systems. +Be warned also that they are considered experimental and changes are possible. +.Pp +The +.Fn regfree +function +frees any dynamically-allocated storage associated with the compiled RE +pointed to by +.Fa preg . +The remaining +.Ft regex_t +is no longer a valid compiled RE +and the effect of supplying it to +.Fn regexec +or +.Fn regerror +is undefined. +.Pp +None of these functions references global variables except for tables +of constants; +all are safe for use from multiple threads if the arguments are safe. +.Sh IMPLEMENTATION CHOICES +There are a number of decisions that +.St -p1003.2 +leaves up to the implementor, +either by explicitly saying +.Dq undefined +or by virtue of them being +forbidden by the RE grammar. +This implementation treats them as follows. +.Pp +See +.Xr re_format 7 +for a discussion of the definition of case-independent matching. +.Pp +There is no particular limit on the length of REs, +except insofar as memory is limited. +Memory usage is approximately linear in RE size, and largely insensitive +to RE complexity, except for bounded repetitions. +See +.Sx BUGS +for one short RE using them +that will run almost any system out of memory. +.Pp +A backslashed character other than one specifically given a magic meaning +by +.St -p1003.2 +(such magic meanings occur only in obsolete +.Bq Dq basic +REs) +is taken as an ordinary character. +.Pp +Any unmatched +.Ql [\& +is a +.Dv REG_EBRACK +error. +.Pp +Equivalence classes cannot begin or end bracket-expression ranges. +The endpoint of one range cannot begin another. +.Pp +.Dv RE_DUP_MAX , +the limit on repetition counts in bounded repetitions, is 255. +.Pp +A repetition operator +.Ql ( ?\& , +.Ql *\& , +.Ql +\& , +or bounds) +cannot follow another +repetition operator. +A repetition operator cannot begin an expression or subexpression +or follow +.Ql ^\& +or +.Ql |\& . +.Pp +.Ql |\& +cannot appear first or last in a (sub)expression or after another +.Ql |\& , +i.e., an operand of +.Ql |\& +cannot be an empty subexpression. +An empty parenthesized subexpression, +.Ql "()" , +is legal and matches an +empty (sub)string. +An empty string is not a legal RE. +.Pp +A +.Ql {\& +followed by a digit is considered the beginning of bounds for a +bounded repetition, which must then follow the syntax for bounds. +A +.Ql {\& +.Em not +followed by a digit is considered an ordinary character. +.Pp +.Ql ^\& +and +.Ql $\& +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 +and +.Fn regexec +include the following: +.Pp +.Bl -tag -width REG_ECOLLATE -compact +.It Dv REG_NOMATCH +The +.Fn regexec +function +failed to match +.It Dv REG_BADPAT +invalid regular expression +.It Dv REG_ECOLLATE +invalid collating element +.It Dv REG_ECTYPE +invalid character class +.It Dv REG_EESCAPE +.Ql \e +applied to unescapable character +.It Dv REG_ESUBREG +invalid backreference number +.It Dv REG_EBRACK +brackets +.Ql "[ ]" +not balanced +.It Dv REG_EPAREN +parentheses +.Ql "( )" +not balanced +.It Dv REG_EBRACE +braces +.Ql "{ }" +not balanced +.It Dv REG_BADBR +invalid repetition count(s) in +.Ql "{ }" +.It Dv REG_ERANGE +invalid character range in +.Ql "[ ]" +.It Dv REG_ESPACE +ran out of memory +.It Dv REG_BADRPT +.Ql ?\& , +.Ql *\& , +or +.Ql +\& +operand invalid +.It Dv REG_EMPTY +empty (sub)expression +.It Dv REG_ASSERT +can't 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 HISTORY +Originally written by +.An Henry Spencer . +Altered for inclusion in the +.Bx 4.4 +distribution. +.Sh BUGS +This is an alpha release with known defects. +Please report problems. +.Pp +The back-reference code is subtle and doubts linger about its correctness +in complex cases. +.Pp +The +.Fn regexec +function +performance is poor. +This will improve with later releases. +The +.Fa nmatch +argument +exceeding 0 is expensive; +.Fa nmatch +exceeding 1 is worse. +The +.Fn regexec +function +is largely insensitive to RE complexity +.Em except +that back +references are massively expensive. +RE length does matter; in particular, there is a strong speed bonus +for keeping RE length under about 30 characters, +with most special characters counting roughly double. +.Pp +The +.Fn regcomp +function +implements bounded repetitions by macro expansion, +which is costly in time and space if counts are large +or bounded repetitions are nested. +An RE like, say, +.Ql "((((a{1,100}){1,100}){1,100}){1,100}){1,100}" +will (eventually) run almost any existing machine out of swap space. +.Pp +There are suspected problems with response to obscure error conditions. +Notably, +certain kinds of internal overflow, +produced only by truly enormous REs or by multiply nested bounded repetitions, +are probably not handled well. +.Pp +Due to a mistake in +.St -p1003.2 , +things like +.Ql "a)b" +are legal REs because +.Ql )\& +is +a special character only in the presence of a previous unmatched +.Ql (\& . +This can't be fixed until the spec is fixed. +.Pp +The standard's definition of back references is vague. +For example, does +.Ql "a\e(\e(b\e)*\e2\e)*d" +match +.Ql "abbbd" ? +Until the standard is clarified, +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. diff --git a/regex/regex2.h b/regex/regex2.h new file mode 100644 index 0000000..15a6bcf --- /dev/null +++ b/regex/regex2.h @@ -0,0 +1,212 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + * + * @(#)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 $ + */ + +/* + * First, the stuff that ends up in the outside-world include file + = typedef off_t regoff_t; + = typedef struct { + = int re_magic; + = size_t re_nsub; // number of parenthesized subexpressions + = const char *re_endp; // end pointer for REG_PEND + = struct re_guts *re_g; // none of your business :-) + = } regex_t; + = typedef struct { + = regoff_t rm_so; // start of match + = regoff_t rm_eo; // end of match + = } regmatch_t; + */ +/* + * internals of regex_t + */ +#define MAGIC1 ((('r'^0200)<<8) | 'e') + +/* + * The internal representation is a *strip*, a sequence of + * operators ending with an endmarker. (Some terminology etc. is a + * historical relic of earlier versions which used multiple strips.) + * Certain oddities in the representation are there to permit running + * the machinery backwards; in particular, any deviation from sequential + * flow must be marked at both its source and its destination. Some + * fine points: + * + * - OPLUS_ and O_PLUS are *inside* the loop they create. + * - OQUEST_ and O_QUEST are *outside* the bypass they create. + * - OCH_ and O_CH are *outside* the multi-way branch they create, while + * OOR1 and OOR2 are respectively the end and the beginning of one of + * the branches. Note that there is an implicit OOR2 following OCH_ + * and an implicit OOR1 preceding O_CH. + * + * In state representations, an operator's bit is on to signify a state + * immediately *preceding* "execution" of that operator. + */ +typedef unsigned long sop; /* strip operator */ +typedef long sopno; +#define OPRMASK 0xf8000000L +#define OPDMASK 0x07ffffffL +#define OPSHIFT ((unsigned)27) +#define OP(n) ((n)&OPRMASK) +#define OPND(n) ((n)&OPDMASK) +#define SOP(op, opnd) ((op)|(opnd)) +/* operators meaning operand */ +/* (back, fwd are offsets) */ +#define OEND (1L<= 0); + for (i = 0; i < cs->nequiv_classes; i++) + /* sadly, we can only deal with single characters from an + * equivalence class */ + if (__collate_equiv_match(cs->equiv_classes[i], NULL, 0, ch, NULL, 0, NULL, NULL, loc) > 0) + return (!cs->invert); + if (ch < NC) + return (((cs->bmp[ch >> 3] & (1 << (ch & 7))) != 0) ^ + cs->invert); + for (i = 0; i < cs->nwides; i++) + if (ch == cs->wides[i]) + return (!cs->invert); + for (i = 0; i < cs->nranges; i++) + if (cs->ranges[i].min <= ch && ch <= cs->ranges[i].max) + return (!cs->invert); + for (i = 0; i < cs->ntypes; i++) + if (iswctype_l(ch, cs->types[i], loc)) + return (!cs->invert); + return (cs->invert); +} + +static __inline int +CHIN(cs, ch, loc) +cset *cs; +wint_t ch; +locale_t loc; +{ + + assert(ch >= 0); + if (ch < NC && cs->nequiv_classes == 0) + return (((cs->bmp[ch >> 3] & (1 << (ch & 7))) != 0) ^ + cs->invert); + else if (cs->icase) + return (CHIN1(cs, ch, loc) || CHIN1(cs, towlower_l(ch, loc), loc) || + CHIN1(cs, towupper_l(ch, loc), loc)); + else + return (CHIN1(cs, ch, loc)); +} + +/* + * main compiled-expression structure + */ +struct re_guts { + int magic; +# define MAGIC2 ((('R'^0200)<<8)|'E') + sop *strip; /* malloced area for strip */ + int ncsets; /* number of csets in use */ + cset *sets; /* -> cset [ncsets] */ + int cflags; /* copy of regcomp() cflags argument */ + sopno nstates; /* = number of sops */ + sopno firststate; /* the initial OEND (normally 0) */ + sopno laststate; /* the final OEND */ + int iflags; /* internal flags */ +# define USEBOL 01 /* used ^ */ +# define USEEOL 02 /* used $ */ +# define BAD 04 /* something wrong */ + int nbol; /* number of ^ used */ + int neol; /* number of $ used */ + char *must; /* match must contain this string */ + int moffset; /* latest point at which must may be located */ + int *charjump; /* Boyer-Moore char jump table */ + int *matchjump; /* Boyer-Moore match jump table */ + int mlen; /* length of must */ + size_t nsub; /* copy of re_nsub */ + int backrefs; /* does it use back references? */ + sopno nplus; /* how deep does it nest +s? */ + locale_t loc; /* current locale */ +}; + +/* misc utilities */ +#define OUT (-130) /* 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 new file mode 100644 index 0000000..55eecfb --- /dev/null +++ b/regex/regexec-fbsd.c @@ -0,0 +1,251 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + * + * @(#)regexec.c 8.3 (Berkeley) 3/20/94 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +/* + * the outer shell of regexec() + * + * This file includes engine.c three times, after muchos fiddling with the + * macros that code uses. This lets the same code operate on two different + * representations for state sets and characters. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "regex2.h" + +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; +{ + size_t nr; + wchar_t wc; + + nr = mbrtowc_l(&wc, s, n, mbs, loc); + if (wi != NULL) + *wi = wc; + if (nr == 0) + return (1); + else if (nr == (size_t)-1 || nr == (size_t)-2) { + memset(mbs, 0, sizeof(*mbs)); + if (wi != NULL) + *wi = dummy; + return (1); + } else + return (nr); +} + +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; +{ + + if (wi != NULL) + *wi = (unsigned char)*s; + return (1); +} + +/* macros for manipulating states, small version */ +#define states long +#define states1 states /* for later use in regexec() decision */ +#define CLEAR(v) ((v) = 0) +#define SET0(v, n) ((v) &= ~((unsigned long)1 << (n))) +#define SET1(v, n) ((v) |= (unsigned long)1 << (n)) +#define ISSET(v, n) (((v) & ((unsigned long)1 << (n))) != 0) +#define ASSIGN(d, s) ((d) = (s)) +#define EQ(a, b) ((a) == (b)) +#define STATEVARS long dummy /* dummy version */ +#define STATESETUP(m, n) /* nothing */ +#define STATETEARDOWN(m) /* nothing */ +#define SETUP(v) ((v) = 0) +#define onestate long +#define INIT(o, n) ((o) = (unsigned long)1 << (n)) +#define INC(o) ((o) <<= 1) +#define ISSTATEIN(v, o) (((v) & (o)) != 0) +/* some abbreviations; note that some of these know variable names! */ +/* do "if I'm here, I can also be there" etc without branches */ +#define FWD(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) << (n)) +#define BACK(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) >> (n)) +#define ISSETBACK(v, n) (((v) & ((unsigned long)here >> (n))) != 0) +/* no multibyte support */ +#define XMBRTOWC xmbrtowc_dummy +#define ZAPSTATE(mbs) ((void)(mbs)) +/* function names */ +#define SNAMES /* engine.c looks after details */ + +#include "engine.c" + +/* now undo things */ +#undef states +#undef CLEAR +#undef SET0 +#undef SET1 +#undef ISSET +#undef ASSIGN +#undef EQ +#undef STATEVARS +#undef STATESETUP +#undef STATETEARDOWN +#undef SETUP +#undef onestate +#undef INIT +#undef INC +#undef ISSTATEIN +#undef FWD +#undef BACK +#undef ISSETBACK +#undef SNAMES +#undef XMBRTOWC +#undef ZAPSTATE + +/* macros for manipulating states, large version */ +#define states char * +#define CLEAR(v) memset(v, 0, m->g->nstates) +#define SET0(v, n) ((v)[n] = 0) +#define SET1(v, n) ((v)[n] = 1) +#define ISSET(v, n) ((v)[n]) +#define ASSIGN(d, s) memcpy(d, s, m->g->nstates) +#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0) +#define STATEVARS long vn; char *space +#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \ + if ((m)->space == NULL) return(REG_ESPACE); \ + (m)->vn = 0; } +#define STATETEARDOWN(m) { free((m)->space); } +#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates]) +#define onestate long +#define INIT(o, n) ((o) = (n)) +#define INC(o) ((o)++) +#define ISSTATEIN(v, o) ((v)[o]) +/* some abbreviations; note that some of these know variable names! */ +/* do "if I'm here, I can also be there" etc without branches */ +#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here]) +#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here]) +#define ISSETBACK(v, n) ((v)[here - (n)]) +/* no multibyte support */ +#define XMBRTOWC xmbrtowc_dummy +#define ZAPSTATE(mbs) ((void)(mbs)) +/* function names */ +#define LNAMES /* flag */ + +#undef __FBSDID +#define __FBSDID(x) +#include "engine.c" + +/* multibyte character & large states version */ +#undef LNAMES +#undef XMBRTOWC +#undef ZAPSTATE +#define XMBRTOWC xmbrtowc +#define ZAPSTATE(mbs) memset((mbs), 0, sizeof(*(mbs))) +#define MNAMES + +#include "engine.c" + +/* + - regexec - interface for matching + = extern int regexec(const regex_t *, const char *, size_t, \ + = regmatch_t [], int); + = #define REG_NOTBOL 00001 + = #define REG_NOTEOL 00002 + = #define REG_STARTEND 00004 + = #define REG_TRACE 00400 // tracing of execution + = #define REG_LARGE 01000 // force large representation + = #define REG_BACKR 02000 // force use of backref code + * + * We put this here so we can exploit knowledge of the state representation + * when choosing which matcher to call. Also, by this point the matchers + * 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; +{ + struct re_guts *g = preg->re_g; +#ifdef REDEBUG +# define GOODFLAGS(f) (f) +#else +# define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND)) +#endif + + if (preg->re_magic != MAGIC1 || g->magic != MAGIC2) + return(REG_BADPAT); + assert(!(g->iflags&BAD)); + if (g->iflags&BAD) /* backstop for no-debug case */ + return(REG_BADPAT); + eflags = GOODFLAGS(eflags); + + g->loc = __current_locale(); + if (MB_CUR_MAX_L(g->loc) > 1) + return(mmatcher(g, (char *)string, nmatch, pmatch, eflags)); + else if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags®_LARGE)) + return(smatcher(g, (char *)string, nmatch, pmatch, eflags)); + else + return(lmatcher(g, (char *)string, nmatch, pmatch, eflags)); +} diff --git a/regex/regfree-fbsd.c b/regex/regfree-fbsd.c new file mode 100644 index 0000000..d11060c --- /dev/null +++ b/regex/regfree-fbsd.c @@ -0,0 +1,95 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + * + * @(#)regfree.c 8.3 (Berkeley) 3/20/94 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "regex2.h" + +/* + - regfree - free everything + = extern void regfree(regex_t *); + */ +void +regfree(preg) +regex_t *preg; +{ + struct re_guts *g; + int i; + + if (preg->re_magic != MAGIC1) /* oops */ + return; /* nice to complain, but hard */ + + g = preg->re_g; + if (g == NULL || g->magic != MAGIC2) /* oops again */ + return; + preg->re_magic = 0; /* mark it invalid */ + g->magic = 0; /* mark it invalid */ + + if (g->strip != NULL) + free((char *)g->strip); + if (g->sets != NULL) { + for (i = 0; i < g->ncsets; i++) { + free(g->sets[i].ranges); + free(g->sets[i].wides); + free(g->sets[i].types); + free(g->sets[i].equiv_classes); + } + free((char *)g->sets); + } + if (g->must != NULL) + free(g->must); + if (g->charjump != NULL) + free(&g->charjump[CHAR_MIN]); + if (g->matchjump != NULL) + free(g->matchjump); + free((char *)g); +} diff --git a/regex/utils.h b/regex/utils.h new file mode 100644 index 0000000..5439b6c --- /dev/null +++ b/regex/utils.h @@ -0,0 +1,58 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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. + * + * @(#)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 $ + */ + +/* utility definitions */ +#define DUPMAX _POSIX2_RE_DUP_MAX /* xxx is this right? */ +#define INFINITY (DUPMAX + 1) +#define NC (CHAR_MAX - CHAR_MIN + 1) +typedef unsigned char uch; + +/* switch off assertions (if not already off) if no REDEBUG */ +#ifndef REDEBUG +#ifndef NDEBUG +#define NDEBUG /* no assertions please */ +#endif +#endif +#include + +/* for old systems with bcopy() but no memmove() */ +#ifdef USEBCOPY +#define memmove(d, s, c) bcopy(s, d, c) +#endif diff --git a/rpc/Makefile.inc b/rpc/Makefile.inc index 65e2712..d65e093 100644 --- a/rpc/Makefile.inc +++ b/rpc/Makefile.inc @@ -8,7 +8,8 @@ MISRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \ getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \ pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \ rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \ - rpcb_st_xdr.c svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_generic.c \ + rpcb_st_xdr.c \ + svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_generic.c \ svc_raw.c svc_run.c svc_simple.c svc_vc.c # XDR @@ -48,110 +49,123 @@ MAN+= bindresvport.3 des_crypt.3 getnetconfig.3 getnetpath.3 getrpcent.3 \ rpc_svc_reg.3 rpc_xdr.3 rpcbind.3 xdr.3 publickey.3 rpc_secure.3 \ rtime.3 MAN+= publickey.5 rpc.5 netconfig.5 -MLINKS+= bindresvport.3 bindresvport_sa.3 \ - getnetconfig.3 setnetconfig.3 \ - getnetconfig.3 getnetconfigent.3 \ - getnetconfig.3 endnetconfig.3 \ - getnetconfig.3 nc_perror.3 \ - getnetconfig.3 nc_sperror.3 \ - getnetpath.3 setnetpath.3 \ - getnetpath.3 endnetpath.3 \ - getrpcent.3 getrpcbyname.3 \ - getrpcent.3 getrpcbynumber.3 \ - getrpcent.3 endrpcent.3 \ - getrpcent.3 setrpcent.3 \ - rpc_clnt_auth.3 auth_destroy.3 \ - rpc_clnt_auth.3 authnone_create.3 \ - rpc_clnt_auth.3 authsys_create.3 \ - rpc_clnt_auth.3 authsys_create_default.3 \ - rpc_clnt_calls.3 clnt_call.3 \ - rpc_clnt_calls.3 clnt_perrno.3 \ - rpc_clnt_calls.3 clnt_perror.3 \ - rpc_clnt_calls.3 clnt_sperrno.3 \ - rpc_clnt_calls.3 clnt_sperror.3 \ - rpc_clnt_calls.3 rpc_call.3 \ - rpc_clnt_calls.3 rpc_broadcast.3 \ - rpc_clnt_calls.3 rpc_broadcast_exp.3 \ - rpc_clnt_calls.3 clnt_freeres.3 \ - rpc_clnt_calls.3 clnt_geterr.3 \ - rpc_clnt_create.3 clnt_control.3 \ - rpc_clnt_create.3 clnt_create.3 \ - rpc_clnt_create.3 clnt_create_vers.3 \ - rpc_clnt_create.3 clnt_destroy.3 \ - rpc_clnt_create.3 clnt_pcreateerror.3 \ - rpc_clnt_create.3 clnt_spcreateerror.3 \ - rpc_clnt_create.3 clnt_dg_create.3 \ - rpc_clnt_create.3 clnt_raw_create.3 \ - rpc_clnt_create.3 clnt_tli_create.3 \ - rpc_clnt_create.3 clnt_tp_create.3 \ - rpc_clnt_create.3 clnt_vc_create.3 \ - rpc_svc_calls.3 svc_dg_enablecache.3 \ - rpc_svc_calls.3 svc_exit.3 \ - rpc_svc_calls.3 svc_freeargs.3 \ - rpc_svc_calls.3 svc_getargs.3 \ - rpc_svc_calls.3 svc_getreq_common.3 \ - rpc_svc_calls.3 svc_getreq_poll.3 \ - rpc_svc_calls.3 svc_getreqset.3 \ - rpc_svc_calls.3 svc_getrpccaller.3 \ - rpc_svc_calls.3 __svc_getcallercreds.3 \ - rpc_svc_calls.3 svc_pollset.3 \ - rpc_svc_calls.3 svc_run.3 \ - rpc_svc_calls.3 svc_sendreply.3 \ - rpc_svc_create.3 svc_control.3 \ - rpc_svc_create.3 svc_create.3 \ - rpc_svc_create.3 svc_dg_create.3 \ - rpc_svc_create.3 svc_destroy.3 \ - rpc_svc_create.3 svc_fd_create.3 \ - rpc_svc_create.3 svc_raw_create.3 \ - rpc_svc_create.3 svc_tli_create.3 \ - rpc_svc_create.3 svc_tp_create.3 \ - rpc_svc_create.3 svc_vc_create.3 \ - rpc_svc_err.3 svcerr_auth.3 \ - rpc_svc_err.3 svcerr_decode.3 \ - rpc_svc_err.3 svcerr_noproc.3 \ - rpc_svc_err.3 svcerr_noprog.3 \ - rpc_svc_err.3 svcerr_progvers.3 \ - rpc_svc_err.3 svcerr_systemerr.3 \ - rpc_svc_err.3 svcerr_weakauth.3 \ - rpc_svc_reg.3 rpc_reg.3 \ - rpc_svc_reg.3 svc_reg.3 \ - rpc_svc_reg.3 svc_unreg.3 \ - rpc_svc_reg.3 svc_auth_reg.3 \ - rpc_svc_reg.3 xprt_register.3 \ - rpc_svc_reg.3 xprt_unregister.3 \ - rpcbind.3 rpcb_getmaps.3 \ - rpcbind.3 rpcb_getaddr.3 \ - rpcbind.3 rpcb_gettime.3 \ - rpcbind.3 rpcb_rmtcall.3 \ - rpcbind.3 rpcb_set.3 \ - rpcbind.3 rpcb_unset.3 \ - rpc_soc.3 authunix_create.3 \ - rpc_soc.3 authunix_create_default.3 \ - rpc_soc.3 callrpc.3 \ - rpc_soc.3 clnt_broadcast.3 \ - rpc_soc.3 clntraw_create.3 \ - rpc_soc.3 clnttcp_create.3 \ - rpc_soc.3 clntunix_create.3 \ - rpc_soc.3 clntudp_bufcreate.3 \ - rpc_soc.3 clntudp_create.3 \ - rpc_soc.3 get_myaddress.3 \ - rpc_soc.3 pmap_getmaps.3 \ - rpc_soc.3 pmap_getport.3 \ - rpc_soc.3 pmap_rmtcall.3 \ - rpc_soc.3 pmap_set.3 \ - rpc_soc.3 pmap_unset.3 \ - rpc_soc.3 registerrpc.3 \ - rpc_soc.3 rpc_createerr.3 \ - rpc_soc.3 svc_fds.3 \ - rpc_soc.3 svc_fdset.3 \ - rpc_soc.3 svc_getcaller.3 \ - rpc_soc.3 svc_register.3 \ - rpc_soc.3 svc_unregister.3 \ - rpc_soc.3 svcfd_create.3 \ - rpc_soc.3 svcunixfd_create.3 \ - rpc_soc.3 svcraw_create.3 \ - rpc_soc.3 svctcp_create.3 \ - rpc_soc.3 svcudp_bufcreate.3 \ - rpc_soc.3 svcunix_create.3 \ - rpc_soc.3 xdr_pmap.3 \ - rpc_soc.3 xdr_pmaplist.3 + +MLINKS+= bindresvport.3 bindresvport_sa.3 + +MLINKS+= getnetconfig.3 endnetconfig.3 \ + getnetconfig.3 getnetconfigent.3 \ + getnetconfig.3 nc_perror.3 \ + getnetconfig.3 nc_sperror.3 \ + getnetconfig.3 setnetconfig.3 + +MLINKS+= getnetpath.3 setnetpath.3 \ + getnetpath.3 endnetpath.3 + +MLINKS+= getrpcent.3 endrpcent.3 \ + getrpcent.3 getrpcbyname.3 \ + getrpcent.3 getrpcbynumber.3 \ + getrpcent.3 setrpcent.3 + +MLINKS+= rpc_clnt_auth.3 auth_destroy.3 \ + rpc_clnt_auth.3 authnone_create.3 \ + rpc_clnt_auth.3 authsys_create.3 \ + rpc_clnt_auth.3 authsys_create_default.3 + +MLINKS+= rpc_clnt_calls.3 clnt_call.3 \ + rpc_clnt_calls.3 clnt_freeres.3 \ + rpc_clnt_calls.3 clnt_geterr.3 \ + rpc_clnt_calls.3 clnt_perrno.3 \ + rpc_clnt_calls.3 clnt_perror.3 \ + rpc_clnt_calls.3 clnt_sperrno.3 \ + rpc_clnt_calls.3 clnt_sperror.3 \ + rpc_clnt_calls.3 rpc_broadcast.3 \ + rpc_clnt_calls.3 rpc_broadcast_exp.3 \ + rpc_clnt_calls.3 rpc_call.3 + +MLINKS+= rpc_clnt_create.3 clnt_control.3 \ + rpc_clnt_create.3 clnt_create.3 \ + rpc_clnt_create.3 clnt_create_vers.3 \ + rpc_clnt_create.3 clnt_destroy.3 \ + rpc_clnt_create.3 clnt_dg_create.3 \ + rpc_clnt_create.3 clnt_pcreateerror.3 \ + rpc_clnt_create.3 clnt_raw_create.3 \ + rpc_clnt_create.3 clnt_spcreateerror.3 \ + rpc_clnt_create.3 clnt_tli_create.3 \ + rpc_clnt_create.3 clnt_tp_create.3 \ + rpc_clnt_create.3 clnt_vc_create.3 + +MLINKS+= rpc_svc_calls.3 __svc_getcallercreds.3 \ + rpc_svc_calls.3 svc_dg_enablecache.3 \ + rpc_svc_calls.3 svc_exit.3 \ + rpc_svc_calls.3 svc_freeargs.3 \ + rpc_svc_calls.3 svc_getargs.3 \ + rpc_svc_calls.3 svc_getreq_common.3 \ + rpc_svc_calls.3 svc_getreq_poll.3 \ + rpc_svc_calls.3 svc_getreqset.3 \ + rpc_svc_calls.3 svc_getrpccaller.3 \ + rpc_svc_calls.3 svc_pollset.3 \ + rpc_svc_calls.3 svc_run.3 \ + rpc_svc_calls.3 svc_sendreply.3 + +MLINKS+= rpc_svc_create.3 svc_control.3 \ + rpc_svc_create.3 svc_create.3 \ + rpc_svc_create.3 svc_destroy.3 \ + rpc_svc_create.3 svc_dg_create.3 \ + rpc_svc_create.3 svc_fd_create.3 \ + rpc_svc_create.3 svc_raw_create.3 \ + rpc_svc_create.3 svc_tli_create.3 \ + rpc_svc_create.3 svc_tp_create.3 \ + rpc_svc_create.3 svc_vc_create.3 + +MLINKS+= rpc_svc_err.3 svcerr_auth.3 \ + rpc_svc_err.3 svcerr_decode.3 \ + rpc_svc_err.3 svcerr_noproc.3 \ + rpc_svc_err.3 svcerr_noprog.3 \ + rpc_svc_err.3 svcerr_progvers.3 \ + rpc_svc_err.3 svcerr_systemerr.3 \ + rpc_svc_err.3 svcerr_weakauth.3 + +MLINKS+= rpc_svc_reg.3 rpc_reg.3 \ + rpc_svc_reg.3 svc_auth_reg.3 \ + rpc_svc_reg.3 svc_reg.3 \ + rpc_svc_reg.3 svc_unreg.3 \ + rpc_svc_reg.3 xprt_register.3 \ + rpc_svc_reg.3 xprt_unregister.3 + +MLINKS+= rpcbind.3 rpcb_getaddr.3 \ + rpcbind.3 rpcb_getmaps.3 \ + rpcbind.3 rpcb_gettime.3 \ + rpcbind.3 rpcb_rmtcall.3 \ + rpcbind.3 rpcb_set.3 \ + rpcbind.3 rpcb_unset.3 + +MLINKS+= rpc_soc.3 authunix_create.3 \ + rpc_soc.3 authunix_create_default.3 \ + rpc_soc.3 callrpc.3 \ + rpc_soc.3 clnt_broadcast.3 \ + rpc_soc.3 clntraw_create.3 \ + rpc_soc.3 clnttcp_create.3 \ + rpc_soc.3 clntudp_bufcreate.3 \ + rpc_soc.3 clntudp_create.3 \ + rpc_soc.3 clntunix_create.3 \ + rpc_soc.3 get_myaddress.3 \ + rpc_soc.3 pmap_getmaps.3 \ + rpc_soc.3 pmap_getport.3 \ + rpc_soc.3 pmap_rmtcall.3 \ + rpc_soc.3 pmap_set.3 \ + rpc_soc.3 pmap_unset.3 \ + rpc_soc.3 registerrpc.3 \ + rpc_soc.3 rpc_createerr.3 \ + rpc_soc.3 svc_fds.3 \ + rpc_soc.3 svc_fdset.3 \ + rpc_soc.3 svc_getcaller.3 \ + rpc_soc.3 svc_register.3 \ + rpc_soc.3 svc_unregister.3 \ + rpc_soc.3 svcfd_create.3 \ + rpc_soc.3 svcraw_create.3 \ + rpc_soc.3 svctcp_create.3 \ + rpc_soc.3 svcudp_bufcreate.3 \ + rpc_soc.3 svcunix_create.3 \ + rpc_soc.3 svcunixfd_create.3 \ + rpc_soc.3 xdr_pmap.3 \ + rpc_soc.3 xdr_pmaplist.3 diff --git a/secure/Makefile.inc b/secure/Makefile.inc new file mode 100644 index 0000000..7e904d1 --- /dev/null +++ b/secure/Makefile.inc @@ -0,0 +1,20 @@ +.PATH: ${.CURDIR}/secure + +MISRCS += chk_fail.c \ + memcpy_chk.c \ + memmove_chk.c \ + memset_chk.c \ + strcpy_chk.c \ + stpcpy_chk.c \ + strncpy_chk.c \ + strcat_chk.c \ + strncat_chk.c \ + sprintf_chk.c \ + snprintf_chk.c \ + vsprintf_chk.c \ + vsnprintf_chk.c + +LDBLSRCS += sprintf_chk.c \ + snprintf_chk.c \ + vsprintf_chk.c \ + vsnprintf_chk.c diff --git a/sys/getwgroups_np.c b/secure/chk_fail.c similarity index 73% rename from sys/getwgroups_np.c rename to secure/chk_fail.c index a138c13..95b536d 100644 --- a/sys/getwgroups_np.c +++ b/secure/chk_fail.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * 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, @@ -17,14 +17,23 @@ * 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 -getwgroups_np(int *uuidsetlen, uuid_t uuidset) +#include +#include +#include + +extern void __abort(void) __dead2; + +void +__attribute__ ((noreturn)) +__chk_fail (void) { - return syscall(SYS_getwgroups, uuidsetlen, uuidset); + const char message[] = "[%d] detected buffer overflow"; + + syslog(LOG_CRIT, message, getpid()); + + __abort(); } diff --git a/secure/memcpy_chk.c b/secure/memcpy_chk.c new file mode 100644 index 0000000..6f2e06b --- /dev/null +++ b/secure/memcpy_chk.c @@ -0,0 +1,36 @@ +/* + * 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 +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); + +void * +__memcpy_chk (void *dest, const void *src, size_t len, size_t dstlen) +{ + if (__builtin_expect (dstlen < len, 0)) + __chk_fail (); + + return memcpy (dest, src, len); +} diff --git a/secure/memmove_chk.c b/secure/memmove_chk.c new file mode 100644 index 0000000..60ede5a --- /dev/null +++ b/secure/memmove_chk.c @@ -0,0 +1,36 @@ +/* + * 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 +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); + +void * +__memmove_chk (void *dest, const void *src, size_t len, size_t dstlen) +{ + if (__builtin_expect (dstlen < len, 0)) + __chk_fail (); + + return memmove (dest, src, len); +} diff --git a/sys/getsgroups_np.c b/secure/memset_chk.c similarity index 73% rename from sys/getsgroups_np.c rename to secure/memset_chk.c index cbc6a92..ed4b2ed 100644 --- a/sys/getsgroups_np.c +++ b/secure/memset_chk.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * 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, @@ -17,14 +17,20 @@ * 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 -getsgroups_np(int *uuidsetlen, uuid_t uuidset) +#include +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); + +void * +__memset_chk (void *dest, int val, size_t len, size_t dstlen) { - return syscall(SYS_getsgroups, uuidsetlen, uuidset); + if (__builtin_expect (dstlen < len, 0)) + __chk_fail (); + + return memset (dest, val, len); } diff --git a/secure/snprintf_chk.c b/secure/snprintf_chk.c new file mode 100644 index 0000000..4fb2fbd --- /dev/null +++ b/secure/snprintf_chk.c @@ -0,0 +1,51 @@ +/* + * 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 +#include +#include +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); +extern int __snprintf_chk (char * __restrict, size_t, int, size_t, + const char * __restrict, ...) + __DARWIN_LDBL_COMPAT (__snprintf_chk); + +int +__snprintf_chk (char *s, size_t maxlen, int flags, size_t len, + const char *format, ...) +{ + va_list arg; + int done; + + if (__builtin_expect (maxlen > len, 0)) + __chk_fail (); + + va_start (arg, format); + + done = vsnprintf (s, maxlen, format, arg); + + va_end (arg); + + return done; +} diff --git a/secure/sprintf_chk.c b/secure/sprintf_chk.c new file mode 100644 index 0000000..62a2a60 --- /dev/null +++ b/secure/sprintf_chk.c @@ -0,0 +1,54 @@ +/* + * 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 +#include +#include +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); +extern int __sprintf_chk (char * __restrict, int, size_t, + const char * __restrict, ...) + __DARWIN_LDBL_COMPAT (__sprintf_chk); + +int +__sprintf_chk (char *s, int flags, size_t len, const char *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + + if (len > (size_t) INT_MAX) + done = vsprintf (s, format, arg); + else + { + done = vsnprintf (s, len, format, arg); + if (done >= 0 && (size_t) done >= len) + __chk_fail (); + } + + va_end (arg); + + return done; +} diff --git a/secure/stpcpy_chk.c b/secure/stpcpy_chk.c new file mode 100644 index 0000000..d33c7af --- /dev/null +++ b/secure/stpcpy_chk.c @@ -0,0 +1,38 @@ +/* + * 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 +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); + +void * +__stpcpy_chk (char *dest, const char *src, size_t dstlen) +{ + size_t len = strlen (src); + + if (__builtin_expect (dstlen < len, 0)) + __chk_fail (); + + return memcpy (dest, src, len + 1) + len; +} diff --git a/i386/sys/cerror.s b/secure/strcat_chk.c similarity index 60% rename from i386/sys/cerror.s rename to secure/strcat_chk.c index 1e4428b..e0ace2b 100644 --- a/i386/sys/cerror.s +++ b/secure/strcat_chk.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * 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, @@ -17,29 +17,35 @@ * 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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - - .globl _errno - -LABEL(cerror_cvt) - cmpl $102, %eax /* EOPNOTSUPP? */ - jnz cerror - movl $45, %eax /* Yes; make ENOTSUP for compatibility */ -LABEL(cerror) - REG_TO_EXTERN(%eax, _errno) - mov %esp,%edx - andl $0xfffffff0,%esp - subl $16,%esp - movl %edx,4(%esp) - movl %eax,(%esp) - CALL_EXTERN(_cthread_set_errno_self) - movl 4(%esp),%esp - movl $-1,%eax - movl $-1,%edx /* in case a 64-bit value is returned */ - ret + +#include +#include +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); + +char * +__strcat_chk (char *__restrict s, const char *__restrict append, + size_t slen) +{ + char *save = s; + + /* Advance to the end. */ + for (; *s; ++s) + if (__builtin_expect (slen-- == 0, 0)) + __chk_fail (); + + do + { + /* Append the string. Make sure we check before writing. */ + if (__builtin_expect (slen-- == 0, 0)) + __chk_fail (); + + } while (*s++ = *append++); + + return save; + +} diff --git a/secure/strcpy_chk.c b/secure/strcpy_chk.c new file mode 100644 index 0000000..dd3df20 --- /dev/null +++ b/secure/strcpy_chk.c @@ -0,0 +1,38 @@ +/* + * 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 +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); + +void * +__strcpy_chk (char *restrict dest, char *restrict src, size_t dstlen) +{ + size_t len = strlen (src); + + if (__builtin_expect (dstlen < len, 0)) + __chk_fail (); + + return memcpy (dest, src, len + 1); +} diff --git a/secure/strncat_chk.c b/secure/strncat_chk.c new file mode 100644 index 0000000..6c09eb2 --- /dev/null +++ b/secure/strncat_chk.c @@ -0,0 +1,59 @@ +/* + * 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 +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); + +char * +__strncat_chk (char *restrict dest, const char *restrict src, + size_t len, size_t dstlen) +{ + char *s1 = dest; + const char *s2 = src; + + /* Advance to the end. */ + while (*s1 != 0) + { + if (__builtin_expect (dstlen-- == 0, 0)) + __chk_fail (); + s1++; + } + + dstlen++; + + /* Append the string. */ + while (len > 0) + { + if (__builtin_expect (dstlen-- == 0, 0)) + __chk_fail (); + if ((*s1 = *s2++) == 0) + break; + s1++; + len--; + } + + return dest; + +} diff --git a/secure/strncpy_chk.c b/secure/strncpy_chk.c new file mode 100644 index 0000000..df4420d --- /dev/null +++ b/secure/strncpy_chk.c @@ -0,0 +1,37 @@ +/* + * 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 +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); + +void * +__strncpy_chk (char *restrict dest, char *restrict src, + size_t len, size_t dstlen) +{ + if (__builtin_expect (dstlen < len, 0)) + __chk_fail (); + + return strncpy (dest, src, len); +} diff --git a/i386/sys/getfsstat.s b/secure/vsnprintf_chk.c similarity index 61% rename from i386/sys/getfsstat.s rename to secure/vsnprintf_chk.c index 2622be2..5c7e2cc 100644 --- a/i386/sys/getfsstat.s +++ b/secure/vsnprintf_chk.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * 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, @@ -17,13 +17,30 @@ * 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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include -UNIX_SYSCALL(getfsstat, 3) - ret +#include +#include +#include +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); +extern int __vsnprintf_chk (char * __restrict, size_t, int, size_t, + const char * __restrict, va_list arg) + __DARWIN_LDBL_COMPAT (__vsnprintf_chk); + +int +__vsnprintf_chk (char *s, size_t maxlen, int flags, size_t len, + const char *format, va_list arg) +{ + int done; + + if (maxlen > len) + __chk_fail (); + + done = vsnprintf (s, maxlen, format, arg); + + return done; +} diff --git a/secure/vsprintf_chk.c b/secure/vsprintf_chk.c new file mode 100644 index 0000000..72a4004 --- /dev/null +++ b/secure/vsprintf_chk.c @@ -0,0 +1,50 @@ +/* + * 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 +#include +#include +#include + +extern void __chk_fail (void) __attribute__((__noreturn__)); +extern int __vsprintf_chk (char * __restrict, int, size_t, + const char * __restrict, va_list arg) + __DARWIN_LDBL_COMPAT (__vsprintf_chk); + +int +__vsprintf_chk (char *s, int flags, size_t len, const char *format, + va_list arg) +{ + int done; + + if (len > (size_t) INT_MAX) + done = vsprintf (s, format, arg); + else + { + done = vsnprintf (s, len, format, arg); + if (done >= 0 && (size_t) done >= len) + __chk_fail (); + } + + return done; +} diff --git a/stdio/FreeBSD/fclose.c.patch b/stdio/FreeBSD/fclose.c.patch new file mode 100644 index 0000000..1f6be87 --- /dev/null +++ b/stdio/FreeBSD/fclose.c.patch @@ -0,0 +1,18 @@ +Index: fclose.c +=================================================================== +RCS file: /cvs/root/Libc/stdio/FreeBSD/fclose.c,v +retrieving revision 1.2 +diff -u -d -b -w -p -r1.2 fclose.c +--- fclose.c 2003/05/20 22:22:40 1.2 ++++ fclose.c 2005/02/14 21:57:28 +@@ -53,6 +53,10 @@ fclose(FILE *fp) + { + int r; + ++ if (fp == NULL) { ++ errno = EFAULT; ++ return (EOF); ++ } + if (fp->_flags == 0) { /* not open! */ + errno = EBADF; + return (EOF); diff --git a/stdio/FreeBSD/fflush.c.patch b/stdio/FreeBSD/fflush.c.patch new file mode 100644 index 0000000..29fb1fb --- /dev/null +++ b/stdio/FreeBSD/fflush.c.patch @@ -0,0 +1,25 @@ +--- 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 @@ + #include "namespace.h" + #include + #include ++#include + #include "un-namespace.h" + #include "libc_private.h" + #include "local.h" +@@ -126,6 +127,14 @@ + for (; n > 0; n -= t, p += t) { + t = _swrite(fp, (char *)p, n); + if (t <= 0) { ++ /* 5340694: reset _p and _w on EAGAIN */ ++ if (t < 0 && errno == EAGAIN) { ++ if (p > fp->_p) /* some was written */ ++ memmove(fp->_p, p, n); ++ fp->_p += n; ++ if (!(fp->_flags & (__SLBF|__SNBF))) ++ fp->_w -= n; ++ } + fp->_flags |= __SERR; + return (EOF); + } diff --git a/stdio/FreeBSD/fgets.3.patch b/stdio/FreeBSD/fgets.3.patch index da1eeff..045ec30 100644 --- a/stdio/FreeBSD/fgets.3.patch +++ b/stdio/FreeBSD/fgets.3.patch @@ -1,5 +1,47 @@ ---- fgets.3.orig Fri May 28 14:34:54 2004 -+++ fgets.3 Fri May 28 14:35:03 2004 +--- _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 , diff --git a/stdio/FreeBSD/fgetws.3.patch b/stdio/FreeBSD/fgetws.3.patch index f670eca..c589e6f 100644 --- a/stdio/FreeBSD/fgetws.3.patch +++ b/stdio/FreeBSD/fgetws.3.patch @@ -1,5 +1,5 @@ ---- fgetws.3.orig Fri Mar 11 11:51:15 2005 -+++ fgetws.3 Fri Mar 11 11:52:41 2005 +--- 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 @@ .Dt FGETWS 3 .Os @@ -10,17 +10,39 @@ .Nd get a line of wide characters from a stream .Sh LIBRARY .Lb libc -@@ -50,6 +51,9 @@ +@@ -49,7 +50,21 @@ + .In stdio.h .In wchar.h .Ft "wchar_t *" - .Fn fgetws "wchar_t * restrict ws" "int n" "FILE * restrict fp" +-.Fn fgetws "wchar_t * restrict ws" "int n" "FILE * restrict fp" ++.Fo fgetws ++.Fa "wchar_t *restrict ws" ++.Fa "int n" ++.Fa "FILE *restrict stream" ++.Fc ++.In stdio.h ++.In wchar.h +.In xlocale.h +.Ft "wchar_t *" -+.Fn fgetws_l "wchar_t * restrict ws" "int n" "FILE * restrict fp" "locale_t loc" ++.Fo fgetws_l ++.Fa "wchar_t *restrict ws" ++.Fa "int n" ++.Fa "FILE *restrict stream" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn fgetws -@@ -66,6 +70,14 @@ +@@ -57,7 +72,7 @@ + reads at most one less than the number of characters specified by + .Fa n + from the given +-.Fa fp ++.Fa stream + and stores them in the wide character string + .Fa ws . + Reading stops when a newline character is found, +@@ -66,6 +81,14 @@ If any characters are read and there is no error, a .Ql \e0 character is appended to end the string. @@ -35,7 +57,26 @@ .Sh RETURN VALUES Upon successful completion, .Fn fgetws -@@ -116,7 +128,8 @@ +@@ -84,7 +107,8 @@ + The + .Fn fgetws + function +-does not distinguish between end-of-file and error, and callers must use ++does not distinguish between end-of-file and error; ++callers must use + .Xr feof 3 + and + .Xr ferror 3 +@@ -96,7 +120,7 @@ + .Bl -tag -width Er + .It Bq Er EBADF + The given +-.Fa fp ++.Fa stream + 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 @@ .Sh SEE ALSO .Xr feof 3 , .Xr ferror 3 , diff --git a/stdio/FreeBSD/flags.c.patch b/stdio/FreeBSD/flags.c.patch new file mode 100644 index 0000000..31c0dab --- /dev/null +++ b/stdio/FreeBSD/flags.c.patch @@ -0,0 +1,21 @@ +--- 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 @@ + } + + /* [rwa]\+ or [rwa]b\+ means read and write */ +- if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) { ++ if (*mode == 'b') ++ mode++; ++ if (*mode == '+') { + ret = __SRW; + m = O_RDWR; ++ mode++; ++ if (*mode == 'b') ++ mode++; + } ++ if (*mode == 'x') ++ o |= O_EXCL; + *optr = m | o; + return (ret); + } diff --git a/stdio/FreeBSD/flockfile.3.patch b/stdio/FreeBSD/flockfile.3.patch new file mode 100644 index 0000000..7cbffa9 --- /dev/null +++ b/stdio/FreeBSD/flockfile.3.patch @@ -0,0 +1,74 @@ +--- _SB/Libc/stdio/FreeBSD/flockfile.3 2003-05-20 15:22:41.000000000 -0700 ++++ _SB/Libc/stdio/FreeBSD/flockfile.3.edit 2006-06-28 16:55:52.000000000 -0700 +@@ -37,21 +37,22 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft void +-.Fn flockfile "FILE *stream" ++.Fn flockfile "FILE *file" + .Ft int +-.Fn ftrylockfile "FILE *stream" ++.Fn ftrylockfile "FILE *file" + .Ft void +-.Fn funlockfile "FILE *stream" ++.Fn funlockfile "FILE *file" + .Sh DESCRIPTION +-These functions provide explicit application-level locking of stdio streams. ++These functions provide explicit application-level locking ++of stdio FILE objects. + They can be used to avoid output from multiple threads being interspersed, + input being dispersed among multiple readers, and to avoid the overhead +-of locking the stream for each operation. ++of locking the object for each operation. + .Pp + The + .Fn flockfile +-function acquires an exclusive lock on the specified stream. +-If another thread has already locked the stream, ++function acquires an exclusive lock on the specified object. ++If another thread has already locked the object, + .Fn flockfile + will block until the lock is released. + .Pp +@@ -65,19 +66,19 @@ + .Pp + The + .Fn funlockfile +-function releases the lock on a stream acquired by an earlier call to ++function releases the lock on an object acquired by an earlier call to + .Fn flockfile + or + .Fn ftrylockfile . + .Pp + These functions behave as if there is a lock count associated +-with each stream. ++with each object. + Each time + .Fn flockfile +-is called on the stream, the count is incremented, ++is called on the object, the count is incremented, + and each time + .Fn funlockfile +-is called on the stream, the count is decremented. ++is called on the object, the count is decremented. + The lock is only actually released when the count reaches zero. + .Sh RETURN VALUES + The +@@ -89,7 +90,7 @@ + The + .Fn ftrylockfile + function +-returns zero if the stream was successfully locked, ++returns zero if the object was successfully locked, + non-zero otherwise. + .Sh SEE ALSO + .Xr getc_unlocked 3 , +@@ -97,7 +98,7 @@ + .Sh STANDARDS + The + .Fn flockfile , +-.Fn ftrylockfile ++.Fn ftrylockfile , + and + .Fn funlockfile + functions conform to diff --git a/stdio/FreeBSD/fopen.3.patch b/stdio/FreeBSD/fopen.3.patch new file mode 100644 index 0000000..8675abe --- /dev/null +++ b/stdio/FreeBSD/fopen.3.patch @@ -0,0 +1,89 @@ +--- 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 @@ + .Dt FOPEN 3 + .Os + .Sh NAME +-.Nm fopen , + .Nm fdopen , ++.Nm fopen , + .Nm freopen + .Nd stream open functions + .Sh LIBRARY +@@ -49,17 +49,27 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft FILE * +-.Fn fopen "const char * restrict path" "const char * restrict mode" ++.Fo fdopen ++.Fa "int fildes" ++.Fa "const char *mode" ++.Fc + .Ft FILE * +-.Fn fdopen "int fildes" "const char *mode" ++.Fo fopen ++.Fa "const char *restrict filename" ++.Fa "const char *restrict mode" ++.Fc + .Ft FILE * +-.Fn freopen "const char *path" "const char *mode" "FILE *stream" ++.Fo freopen ++.Fa "const char *restrict filename" ++.Fa "const char *restrict mode" ++.Fa "FILE *restrict stream" ++.Fc + .Sh DESCRIPTION + The + .Fn fopen + function + opens the file whose name is the string pointed to by +-.Fa path ++.Fa filename + and associates a stream with it. + .Pp + The argument +@@ -107,6 +117,17 @@ + .St -isoC + and has no effect; the ``b'' is ignored. + .Pp ++Finally, as an extension to the standards (and thus may not be portable), ++.Fa mode ++string may end with the letter ``x'', which insists on creating a new file ++when used with ``w'' or ``a''. ++If ++.Fa path ++exists, then an error is returned (this is the equivalent of specifying ++.Dv O_EXCL ++with ++.Xr open 2 ) . ++.Pp + Any created files will have mode + .Pf \\*q Dv S_IRUSR + \&| +@@ -148,7 +169,7 @@ + .Fn freopen + function + opens the file whose name is the string pointed to by +-.Fa path ++.Fa filename + and associates the stream pointed to by + .Fa stream + with it. +@@ -160,7 +181,7 @@ + function. + .Pp + If the +-.Fa path ++.Fa filename + argument is + .Dv NULL , + .Fn freopen +@@ -204,7 +225,7 @@ + .Sh RETURN VALUES + Upon successful completion + .Fn fopen , +-.Fn fdopen ++.Fn fdopen , + and + .Fn freopen + return a diff --git a/stdio/FreeBSD/fputs.3.patch b/stdio/FreeBSD/fputs.3.patch index 174daab..2d786ce 100644 --- a/stdio/FreeBSD/fputs.3.patch +++ b/stdio/FreeBSD/fputs.3.patch @@ -1,6 +1,53 @@ ---- fputs.3.orig Tue May 20 15:22:42 2003 -+++ fputs.3 Thu Jul 31 17:34:11 2003 -@@ -109,3 +109,13 @@ +--- 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 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft int +-.Fn fputs "const char *str" "FILE *stream" ++.Fo fputs ++.Fa "const char *restrict s" ++.Fa "FILE *restrict stream" ++.Fc + .Ft int +-.Fn puts "const char *str" ++.Fo puts ++.Fa "const char *s" ++.Fc + .Sh DESCRIPTION + The function + .Fn fputs + writes the string pointed to by +-.Fa str ++.Fa s + to the stream pointed to by + .Fa stream . + .\" The terminating +@@ -65,7 +70,7 @@ + The function + .Fn puts + writes the string +-.Fa str , ++.Fa s , + and a terminating newline character, + to the stream + .Dv stdout . +@@ -97,6 +102,14 @@ + .Va errno + for any of the errors specified for the routines + .Xr write 2 . ++.Sh COMPATIBILITY ++.Fn fputs ++now returns a non-negative number (as opposed to 0) ++on successful completion. ++As a result, many tests (e.g., "fputs() == 0", "fputs() != 0") ++do not give the desired result. ++Use "fputs() != EOF" or "fputs() == EOF" ++to determine success or failure. + .Sh SEE ALSO + .Xr ferror 3 , + .Xr fputws 3 , +@@ -109,3 +122,13 @@ .Fn puts conform to .St -isoC . diff --git a/stdio/FreeBSD/fputs.c.patch b/stdio/FreeBSD/fputs.c.patch index 19dee98..1f55656 100644 --- a/stdio/FreeBSD/fputs.c.patch +++ b/stdio/FreeBSD/fputs.c.patch @@ -1,6 +1,11 @@ ---- fputs.c.orig Tue May 20 15:22:42 2003 -+++ fputs.c Thu Jul 31 13:19:02 2003 -@@ -48,6 +48,9 @@ +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 #include "libc_private.h" #include "local.h" @@ -10,7 +15,7 @@ /* * Write the given string to the given file. */ -@@ -60,6 +63,9 @@ +@@ -60,6 +63,9 @@ fputs(s, fp) struct __suio uio; struct __siov iov; @@ -20,3 +25,13 @@ iov.iov_base = (void *)s; iov.iov_len = uio.uio_resid = strlen(s); uio.uio_iov = &iov; +@@ -68,5 +74,9 @@ fputs(s, fp) + ORIENT(fp, -1); + retval = __sfvwrite(fp, &uio); + FUNLOCKFILE(fp); ++#if __DARWIN_UNIX03 ++ if (retval == 0) ++ return iov.iov_len; ++#endif /* __DARWIN_UNIX03 */ + return (retval); + } diff --git a/stdio/FreeBSD/fputws.3.patch b/stdio/FreeBSD/fputws.3.patch index f7dd3b1..e9e9cb8 100644 --- a/stdio/FreeBSD/fputws.3.patch +++ b/stdio/FreeBSD/fputws.3.patch @@ -1,5 +1,5 @@ ---- fputws.3.orig Fri Mar 11 11:53:01 2005 -+++ fputws.3 Fri Mar 11 11:53:53 2005 +--- _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 @@ .Dt FPUTWS 3 .Os @@ -10,22 +10,34 @@ .Nd output a line of wide characters to a stream .Sh LIBRARY .Lb libc -@@ -50,6 +51,9 @@ +@@ -49,14 +50,34 @@ + .In stdio.h .In wchar.h .Ft int - .Fn fputws "const wchar_t * restrict ws" "FILE * restrict fp" +-.Fn fputws "const wchar_t * restrict ws" "FILE * restrict fp" ++.Fo fputws ++.Fa "const wchar_t *restrict ws" ++.Fa "FILE *restrict stream" ++.Fc ++.In stdio.h ++.In wchar.h +.In xlocale.h +.Ft int -+.Fn fputws_l "const wchar_t * restrict ws" "FILE * restrict fp" "locale_t loc" ++.Fo fputws_l ++.Fa "const wchar_t *restrict ws" ++.Fa "FILE *restrict stream" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn fputws -@@ -57,6 +61,14 @@ + function writes the wide character string pointed to by .Fa ws to the stream pointed to by - .Fa fp . +-.Fa fp . ++.Fa stream . +.Pp -+While the ++Although the +.Fn fputws +function uses the current locale, the +.Fn fputws_l @@ -35,7 +47,16 @@ .Sh RETURN VALUES The .Fn fputws -@@ -84,7 +96,8 @@ +@@ -69,7 +90,7 @@ + .Bl -tag -width Er + .It Bq Er EBADF + The +-.Fa fp ++.Fa stream + argument supplied + is not a writable stream. + .El +@@ -84,7 +105,8 @@ .Xr ferror 3 , .Xr fputs 3 , .Xr putwc 3 , diff --git a/stdio/FreeBSD/fread.3.patch b/stdio/FreeBSD/fread.3.patch new file mode 100644 index 0000000..697cc0a --- /dev/null +++ b/stdio/FreeBSD/fread.3.patch @@ -0,0 +1,49 @@ +--- _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 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft size_t +-.Fn fread "void * restrict ptr" "size_t size" "size_t nmemb" "FILE * restrict stream" ++.Fn fread "void *restrict ptr" "size_t size" "size_t nitems" \ ++ "FILE *restrict stream" + .Ft size_t +-.Fn fwrite "const void * restrict ptr" "size_t size" "size_t nmemb" "FILE * restrict stream" ++.Fn fwrite "const void *restrict ptr" "size_t size" "size_t nitems" \ ++ "FILE *restrict stream" + .Sh DESCRIPTION + The function + .Fn fread + reads +-.Fa nmemb ++.Fa nitems + objects, each + .Fa size + bytes long, from the stream pointed to by +@@ -66,7 +68,7 @@ + The function + .Fn fwrite + writes +-.Fa nmemb ++.Fa nitems + objects, each + .Fa size + bytes long, to the stream pointed to by +@@ -86,7 +88,7 @@ + .Pp + The function + .Fn fread +-does not distinguish between end-of-file and error, and callers ++does not distinguish between end-of-file and error; callers + must use + .Xr feof 3 + and +@@ -95,7 +97,7 @@ + The function + .Fn fwrite + returns a value less than +-.Fa nmemb ++.Fa nitems + only if a write error has occurred. + .Sh SEE ALSO + .Xr read 2 , diff --git a/stdio/FreeBSD/freopen.c.patch b/stdio/FreeBSD/freopen.c.patch index c9c6e76..899579c 100644 --- a/stdio/FreeBSD/freopen.c.patch +++ b/stdio/FreeBSD/freopen.c.patch @@ -1,6 +1,20 @@ ---- freopen.c.orig 2004-10-28 23:51:35.000000000 -0700 -+++ freopen.c 2004-10-28 23:53:14.000000000 -0700 -@@ -136,6 +136,8 @@ +Index: freopen.c +=================================================================== +RCS file: /cvs/root/Libc/stdio/FreeBSD/freopen.c,v +retrieving revision 1.3 +diff -u -d -b -w -p -r1.3 freopen.c +--- freopen.c 2004/11/25 19:38:34 1.3 ++++ freopen.c 2005/01/25 18:01:26 +@@ -99,7 +99,7 @@ freopen(file, mode, fp) + (oflags & O_ACCMODE)) { + fclose(fp); + FUNLOCKFILE(fp); +- errno = EINVAL; ++ errno = EBADF; + return (NULL); + } + if ((oflags ^ dflags) & O_APPEND) { +@@ -136,6 +136,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. @@ -9,7 +23,7 @@ */ if (fp->_flags == 0) { fp->_flags = __SEOF; /* hold on to it */ -@@ -146,11 +148,18 @@ +@@ -146,11 +148,18 @@ freopen(file, mode, fp) if (fp->_flags & __SWR) (void) __sflush(fp); /* if close is NULL, closing is a no-op, hence pointless */ diff --git a/stdio/FreeBSD/fseek.3.patch b/stdio/FreeBSD/fseek.3.patch new file mode 100644 index 0000000..9ac9e00 --- /dev/null +++ b/stdio/FreeBSD/fseek.3.patch @@ -0,0 +1,83 @@ +--- 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 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft int +-.Fn fseek "FILE *stream" "long offset" "int whence" +-.Ft long +-.Fn ftell "FILE *stream" +-.Ft void +-.Fn rewind "FILE *stream" ++.Fo fgetpos ++.Fa "FILE *restrict stream" ++.Fa "fpos_t *restrict pos" ++.Fc + .Ft int +-.Fn fgetpos "FILE * restrict stream" "fpos_t * restrict pos" ++.Fo fseek ++.Fa "FILE *stream" ++.Fa "long offset" ++.Fa "int whence" ++.Fc + .Ft int +-.Fn fsetpos "FILE *stream" "const fpos_t *pos" +-.In sys/types.h ++.Fo fseeko ++.Fa "FILE *stream" ++.Fa "off_t offset" ++.Fa "int whence" ++.Fc + .Ft int +-.Fn fseeko "FILE *stream" "off_t offset" "int whence" ++.Fo fsetpos ++.Fa "FILE *stream" ++.Fa "const fpos_t *pos" ++.Fc ++.Ft long ++.Fo ftell ++.Fa "FILE *stream" ++.Fc + .Ft off_t +-.Fn ftello "FILE *stream" ++.Fo ftello ++.Fa "FILE *stream" ++.Fc ++.Ft void ++.Fo rewind ++.Fa "FILE *stream" ++.Fc + .Sh DESCRIPTION + The + .Fn fseek +@@ -246,12 +265,29 @@ + .Xr lseek 2 , + and + .Xr malloc 3 . ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Pp ++.Ft int ++.br ++.Fo fseeko ++.Fa "FILE *stream" ++.Fa "off_t offset" ++.Fa "int whence" ++.Fc ; ++.Pp ++The include file ++.In sys/types.h ++supplies the definition for ++.Vt off_t . + .Sh SEE ALSO + .Xr lseek 2 , + .Xr clearerr 3 , + .Xr fwide 3 , + .Xr ungetc 3 , +-.Xr ungetwc 3 ++.Xr ungetwc 3 , ++.Xr compat 5 + .Sh STANDARDS + The + .Fn fgetpos , diff --git a/stdio/FreeBSD/ftell.c.patch b/stdio/FreeBSD/ftell.c.patch index 9b82036..68109d1 100644 --- a/stdio/FreeBSD/ftell.c.patch +++ b/stdio/FreeBSD/ftell.c.patch @@ -1,10 +1,16 @@ ---- ftell.c.orig Tue May 20 15:22:42 2003 -+++ ftell.c Tue May 25 13:14:32 2004 -@@ -105,6 +105,7 @@ +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) * Find offset of underlying I/O object, then * adjust for buffered bytes. */ -+ __sflush(fp); /* may adjust seek offset on append stream */ ++ if (__sflush(fp)) /* may adjust seek offset on append stream */ ++ return (1); if (fp->_flags & __SOFF) pos = fp->_offset; else { diff --git a/stdio/FreeBSD/fwide.3.patch b/stdio/FreeBSD/fwide.3.patch new file mode 100644 index 0000000..c3c54ba --- /dev/null +++ b/stdio/FreeBSD/fwide.3.patch @@ -0,0 +1,18 @@ +--- _SB/Libc/stdio/FreeBSD/fwide.3 2003-05-20 15:22:42.000000000 -0700 ++++ _SB/Libc/stdio/FreeBSD/fwide.3.edit 2006-06-28 16:55:52.000000000 -0700 +@@ -63,10 +63,12 @@ + .Fa mode + is less than zero, + .Fa stream +-is set to byte-oriented. +-If it is greater than zero, ++is set to be byte-oriented. ++If ++.Fa mode ++is greater than zero, + .Fa stream +-is set to wide-oriented. ++is set to be wide-oriented. + Otherwise, + .Fa mode + is zero, and diff --git a/stdio/FreeBSD/getc.3.patch b/stdio/FreeBSD/getc.3.patch new file mode 100644 index 0000000..045b4ab --- /dev/null +++ b/stdio/FreeBSD/getc.3.patch @@ -0,0 +1,20 @@ +--- _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 @@ + .Ft int + .Fn getc_unlocked "FILE *stream" + .Ft int +-.Fn getchar ++.Fn getchar "void" + .Ft int + .Fn getchar_unlocked "void" + .Ft int +@@ -145,7 +145,7 @@ + .Sh STANDARDS + The + .Fn fgetc , +-.Fn getc ++.Fn getc , + and + .Fn getchar + functions diff --git a/stdio/FreeBSD/getwc.3.patch b/stdio/FreeBSD/getwc.3.patch index 836f098..7728d51 100644 --- a/stdio/FreeBSD/getwc.3.patch +++ b/stdio/FreeBSD/getwc.3.patch @@ -1,5 +1,14 @@ ---- getwc.3.orig Fri Mar 11 17:08:31 2005 -+++ getwc.3 Fri Mar 11 16:20:25 2005 +--- 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 @@ + .Ft wint_t + .Fn getwc "FILE *stream" + .Ft wint_t +-.Fn getwchar ++.Fn getwchar void + .Sh DESCRIPTION + The + .Fn fgetwc @@ -79,6 +79,12 @@ .Fn getwc with the argument @@ -13,13 +22,19 @@ .Sh RETURN VALUES If successful, these routines return the next wide character from the -@@ -106,7 +112,8 @@ +@@ -104,13 +110,14 @@ + .Xr fopen 3 , + .Xr fread 3 , .Xr getc 3 , ++.Xr getwc_l 3 , .Xr putwc 3 , .Xr stdio 3 , --.Xr ungetwc 3 -+.Xr ungetwc 3 , -+.Xr getwc_l 3 + .Xr ungetwc 3 .Sh STANDARDS The .Fn fgetwc , +-.Fn getwc ++.Fn getwc , + and + .Fn getwchar + functions diff --git a/stdio/FreeBSD/makebuf.c.patch b/stdio/FreeBSD/makebuf.c.patch new file mode 100644 index 0000000..49aeb43 --- /dev/null +++ b/stdio/FreeBSD/makebuf.c.patch @@ -0,0 +1,33 @@ +--- makebuf.c.orig 2006-10-11 20:54:06.000000000 -0700 ++++ makebuf.c 2006-10-12 10:09:09.000000000 -0700 +@@ -49,6 +49,8 @@ + #include "local.h" + #include "un-namespace.h" + ++#define TTYBUFSIZE 4096 ++ + /* + * Allocate a file buffer, or switch to unbuffered I/O. + * Per the ANSI C standard, ALL tty devices default to line buffered. +@@ -71,6 +73,12 @@ + return; + } + flags = __swhatbuf(fp, &size, &couldbetty); ++ if (couldbetty && isatty(fp->_file)) { ++ flags |= __SLBF; ++ /* st_blksize for ttys is 128K, so make it more reasonable */ ++ if (size > TTYBUFSIZE) ++ fp->_blksize = size = TTYBUFSIZE; ++ } + if ((p = malloc(size)) == NULL) { + fp->_flags |= __SNBF; + fp->_bf._base = fp->_p = fp->_nbuf; +@@ -81,8 +89,6 @@ + flags |= __SMBF; + fp->_bf._base = fp->_p = p; + fp->_bf._size = size; +- if (couldbetty && isatty(fp->_file)) +- flags |= __SLBF; + fp->_flags |= flags; + } + diff --git a/stdio/FreeBSD/mktemp.3.patch b/stdio/FreeBSD/mktemp.3.patch new file mode 100644 index 0000000..1edf538 --- /dev/null +++ b/stdio/FreeBSD/mktemp.3.patch @@ -0,0 +1,80 @@ +--- mktemp.3 2004-11-25 11:38:35.000000000 -0800 ++++ mktemp.3.edit 2006-07-12 11:24:49.000000000 -0700 +@@ -36,20 +36,33 @@ + .Dt MKTEMP 3 + .Os + .Sh NAME +-.Nm mktemp ++.Nm mkdtemp , ++.Nm mkstemp , ++.Nm mktemp , ++.Nm mktemps + .Nd make temporary file name (unique) + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In unistd.h + .Ft char * +-.Fn mktemp "char *template" ++.Fo mkdtemp ++.Fa "char *template" ++.Fc + .Ft int +-.Fn mkstemp "char *template" ++.Fo mkstemps ++.Fa "char *template" ++.Fa "int suffixlen" ++.Fc ++.In stdlib.h + .Ft int +-.Fn mkstemps "char *template" "int suffixlen" ++.Fo mkstemp ++.Fa "char *template" ++.Fc + .Ft char * +-.Fn mkdtemp "char *template" ++.Fo mktemp ++.Fa "char *template" ++.Fc + .Sh DESCRIPTION + The + .Fn mktemp +@@ -137,7 +150,7 @@ + .Pp + The + .Fn mkstemp , +-.Fn mkstemps ++.Fn mkstemps , + and + .Fn mkdtemp + functions +@@ -171,7 +184,7 @@ + passes in a read-only string to + .Fn mktemp , + .Fn mkstemp , +-.Fn mkstemps ++.Fn mkstemps , + or + .Fn mkdtemp . + This is common with programs that were developed before +@@ -226,12 +239,19 @@ + You must provide your own locking around this and other consumers of the + .Xr arc4random 3 + API. ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Pp ++The include file ++.In unistd.h ++is necessary and sufficient for all functions. + .Sh SEE ALSO + .Xr chmod 2 , + .Xr getpid 2 , + .Xr mkdir 2 , + .Xr open 2 , +-.Xr stat 2 ++.Xr stat 2 , ++.Xr compat 5 + .Sh HISTORY + A + .Fn mktemp diff --git a/stdio/FreeBSD/perror.c.patch b/stdio/FreeBSD/perror.c.patch new file mode 100644 index 0000000..e816373 --- /dev/null +++ b/stdio/FreeBSD/perror.c.patch @@ -0,0 +1,10 @@ +--- 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.3.patch b/stdio/FreeBSD/printf.3.patch index ca5226e..5cab6cb 100644 --- a/stdio/FreeBSD/printf.3.patch +++ b/stdio/FreeBSD/printf.3.patch @@ -1,6 +1,112 @@ ---- printf.3.orig 2004-11-25 11:38:35.000000000 -0800 -+++ printf.3 2005-08-09 22:37:08.000000000 -0700 -@@ -101,6 +101,12 @@ +--- printf.3 2004-11-25 11:38:35.000000000 -0800 ++++ printf.3.edit 2006-09-06 16:56:37.000000000 -0700 +@@ -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 + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .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 @@ + and + .Fn vsnprintf + write to the character string +-.Fa str ; ++.Fa s ; + and + .Fn asprintf + and +@@ -101,6 +145,12 @@ dynamically allocate a new string with .Xr malloc 3 . .Pp @@ -13,7 +119,43 @@ These functions write the output under the control of a .Fa format string that specifies how subsequent arguments -@@ -287,6 +293,20 @@ +@@ -117,7 +167,7 @@ + and + .Fn vsnprintf , + which return the number of characters that would have been printed if the +-.Fa size ++.Fa n + were unlimited + (again, not including the final + .Ql \e0 ) . +@@ -149,14 +199,14 @@ + .Fn vsnprintf + functions + will write at most +-.Fa size Ns \-1 ++.Fa n Ns \-1 + of the characters printed into the output string + (the +-.Fa size Ns 'th ++.Fa n Ns \'th + character then gets the terminating + .Ql \e0 ) ; + if the return value is greater than or equal to the +-.Fa size ++.Fa n + argument, the string was too short + and some of the printed characters were discarded. + The output is always null-terminated. +@@ -167,7 +217,7 @@ + .Fn vsprintf + functions + effectively assume an infinite +-.Fa size . ++.Fa n . + .Pp + The format string is composed of zero or more directives: + ordinary +@@ -287,6 +337,20 @@ .Xr localeconv 3 . .El .It @@ -34,7 +176,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 +399,34 @@ +@@ -379,6 +443,34 @@ .It Sy Modifier Ta Cm c Ta Cm s .It Cm l No (ell) Ta Vt wint_t Ta Vt "wchar_t *" .El @@ -69,18 +211,20 @@ .It A character that specifies the type of conversion to be applied. .El -@@ -792,12 +840,8 @@ +@@ -790,14 +882,11 @@ + .Sh SEE ALSO + .Xr printf 1 , .Xr fmtcheck 3 , ++.Xr printf_l 3 , .Xr scanf 3 , .Xr setlocale 3 , --.Xr wprintf 3 ++.Xr stdarg 3 , + .Xr wprintf 3 -.Rs -.%T "The FreeBSD Security Architecture" -.Re -(See -.Pa "/usr/share/doc/{to be determined}" . ) -+.Xr wprintf 3 , -+.Xr printf_l 3 .Sh STANDARDS Subject to the caveats noted in the .Sx BUGS diff --git a/stdio/FreeBSD/putc.3.patch b/stdio/FreeBSD/putc.3.patch new file mode 100644 index 0000000..744545a --- /dev/null +++ b/stdio/FreeBSD/putc.3.patch @@ -0,0 +1,56 @@ +--- _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 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft int +-.Fn fputc "int c" "FILE *stream" +-.Ft int +-.Fn putc "int c" "FILE *stream" +-.Ft int +-.Fn putc_unlocked "int c" "FILE *stream" +-.Ft int +-.Fn putchar "int c" +-.Ft int +-.Fn putchar_unlocked "int c" +-.Ft int +-.Fn putw "int w" "FILE *stream" ++.Fo fputc ++.Fa "int c" ++.Fa "FILE *stream" ++.Fc ++.Ft int ++.Fo putc ++.Fa "int c" ++.Fa "FILE *stream" ++.Fc ++.Ft int ++.Fo putc_unlocked ++.Fa "int c" ++.Fa "FILE *stream" ++.Fc ++.Ft int ++.Fo putchar ++.Fa "int c" ++.Fc ++.Ft int ++.Fo putchar_unlocked ++.Fa "int c" ++.Fc ++.Ft int ++.Fo putw ++.Fa "int w" ++.Fa "FILE *stream" ++.Fc + .Sh DESCRIPTION + The + .Fn fputc +@@ -121,7 +137,7 @@ + .Fn fputc , + .Fn putc , + .Fn putchar , +-.Fn putc_unlocked ++.Fn putc_unlocked , + and + .Fn putchar_unlocked + return the character written. diff --git a/stdio/FreeBSD/putwc.3.patch b/stdio/FreeBSD/putwc.3.patch index d45d8d5..5589478 100644 --- a/stdio/FreeBSD/putwc.3.patch +++ b/stdio/FreeBSD/putwc.3.patch @@ -1,6 +1,29 @@ ---- putwc.3.orig Fri Mar 11 17:08:50 2005 -+++ putwc.3 Fri Mar 11 16:21:00 2005 -@@ -79,6 +79,12 @@ +--- 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 @@ + .In stdio.h + .In wchar.h + .Ft wint_t +-.Fn fputwc "wchar_t wc" "FILE *stream" ++.Fo fputwc ++.Fa "wchar_t wc" ++.Fa "FILE *stream" ++.Fc + .Ft wint_t +-.Fn putwc "wchar_t wc" "FILE *stream" ++.Fo putwc ++.Fa "wchar_t wc" ++.Fa "FILE *stream" ++.Fc + .Ft wint_t +-.Fn putwchar "wchar_t wc" ++.Fo putwchar ++.Fa "wchar_t wc" ++.Fc + .Sh DESCRIPTION + The + .Fn fputwc +@@ -79,6 +87,12 @@ .Fn putwc with an output stream of .Dv stdout . @@ -13,13 +36,11 @@ .Sh RETURN VALUES The .Fn fputwc , -@@ -95,7 +101,8 @@ +@@ -95,6 +109,7 @@ .Xr fopen 3 , .Xr getwc 3 , .Xr putc 3 , --.Xr stdio 3 -+.Xr stdio 3 , -+.Xr putwc_l 3 ++.Xr putwc_l 3 , + .Xr stdio 3 .Sh STANDARDS The - .Fn fputwc , diff --git a/stdio/FreeBSD/remove.3.patch b/stdio/FreeBSD/remove.3.patch new file mode 100644 index 0000000..9d94403 --- /dev/null +++ b/stdio/FreeBSD/remove.3.patch @@ -0,0 +1,11 @@ +--- _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 @@ + .Va errno + for any of the errors specified for the routines + .Xr lstat 2 , +-.Xr rmdir 2 ++.Xr rmdir 2 , + or + .Xr unlink 2 . + .Sh SEE ALSO diff --git a/stdio/FreeBSD/scanf.3.patch b/stdio/FreeBSD/scanf.3.patch index e6cdd56..df24ce5 100644 --- a/stdio/FreeBSD/scanf.3.patch +++ b/stdio/FreeBSD/scanf.3.patch @@ -1,27 +1,92 @@ ---- scanf.3.orig Fri Mar 11 17:08:59 2005 -+++ scanf.3 Fri Mar 11 17:03:13 2005 -@@ -115,10 +115,18 @@ - each successive conversion specifier - (but see the - .Cm * --conversion below). -+and -+.Cm %n$ -+conversions below). - All conversions are introduced by the - .Cm % --(percent sign) character. -+(percent sign) character or -+.Cm %n$ -+sequence. In the latter case the next -+.Em pointer -+will be the -+.Cm n -+th argument after the format string. +--- scanf.3.orig 2007-04-08 18:49:37.000000000 -0700 ++++ scanf.3 2007-04-08 20:14:03.000000000 -0700 +@@ -40,35 +40,55 @@ + .Dt SCANF 3 + .Os + .Sh NAME +-.Nm scanf , + .Nm fscanf , ++.Nm scanf , + .Nm sscanf , ++.Nm vfscanf , + .Nm vscanf , +-.Nm vsscanf , +-.Nm vfscanf ++.Nm vsscanf + .Nd input format conversion + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In stdio.h + .Ft int +-.Fn scanf "const char * restrict format" ... ++.Fo fscanf ++.Fa "FILE *restrict stream" ++.Fa "const char *restrict format" ... ++.Fc + .Ft int +-.Fn fscanf "FILE * restrict stream" "const char * restrict format" ... ++.Fo scanf ++.Fa "const char *restrict format" ... ++.Fc + .Ft int +-.Fn sscanf "const char * restrict str" "const char * restrict format" ... ++.Fo sscanf ++.Fa "const char *restrict s" ++.Fa "const char *restrict format" ... ++.Fc + .In stdarg.h ++.In stdio.h + .Ft int +-.Fn vscanf "const char * restrict format" "va_list ap" ++.Fo vfscanf ++.Fa "FILE *restrict stream" ++.Fa "const char *restrict format" ++.Fa "va_list arg" ++.Fc + .Ft int +-.Fn vsscanf "const char * restrict str" "const char * restrict format" "va_list ap" ++.Fo vscanf ++.Fa "const char *restrict format" ++.Fa "va_list arg" ++.Fc + .Ft int +-.Fn vfscanf "FILE * restrict stream" "const char * restrict format" "va_list ap" ++.Fo vsscanf ++.Fa "const char *restrict s" ++.Fa "const char *restrict format" ++.Fa "va_list arg" ++.Fc + .Sh DESCRIPTION + The + .Fn scanf + family of functions scans input according to a +-.Fa format ++.Fa format , + as described below. + This format may contain + .Em conversion specifiers ; +@@ -87,7 +107,8 @@ + and + .Fn sscanf + reads its input from the character string pointed to by +-.Fa str . ++.Fa s . ++.Pp The - .Fa format - string -@@ -132,10 +140,18 @@ + .Fn vfscanf + function +@@ -108,7 +129,8 @@ + .Fn vprintf + and + .Fn vsprintf +-functions respectively. ++functions, respectively. ++.Pp + Each successive + .Em pointer + argument must correspond properly with +@@ -132,10 +154,16 @@ when an input character does not match such a format character. Scanning also stops when an input conversion cannot be made (see below). @@ -35,30 +100,42 @@ Following the .Cm % -character introducing a conversion -+character or -+.Cm %n$ -+sequence introducing a conversion ++character introducing a conversion, there may be a number of .Em flag characters, as follows: -@@ -466,7 +482,8 @@ +@@ -440,13 +468,10 @@ + causes an immediate return of + .Dv EOF . + .Sh RETURN VALUES +-These +-functions +-return +-the number of input items assigned, which can be fewer than provided +-for, or even zero, in the event of a matching failure. +-Zero +-indicates that, while there was input available, ++These functions return the number of input items assigned. ++This can be fewer than provided for, or even zero, ++in the event of a matching failure. ++Zero indicates that, although there was input available, + no conversions were assigned; + typically this is due to an invalid input character, + such as an alphabetic character for a +@@ -463,6 +488,7 @@ + .Xr getc 3 , + .Xr mbrtowc 3 , + .Xr printf 3 , ++.Xr scanf_l 3 , .Xr strtod 3 , .Xr strtol 3 , .Xr strtoul 3 , --.Xr wscanf 3 -+.Xr wscanf 3 , -+.Xr scanf_l 3 - .Sh STANDARDS - The functions - .Fn fscanf , -@@ -505,10 +522,6 @@ - .Cm %512f +@@ -473,7 +499,7 @@ + .Fn scanf , + .Fn sscanf , + .Fn vfscanf , +-.Fn vscanf ++.Fn vscanf , and - .Cm %512d . --.Pp --The --.Cm %n$ --modifiers for positional arguments are not implemented. - .Pp - The - .Nm + .Fn vsscanf + conform to diff --git a/stdio/FreeBSD/setbuf.3.patch b/stdio/FreeBSD/setbuf.3.patch new file mode 100644 index 0000000..64744e1 --- /dev/null +++ b/stdio/FreeBSD/setbuf.3.patch @@ -0,0 +1,79 @@ +--- _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 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft void +-.Fn setbuf "FILE * restrict stream" "char * restrict buf" ++.Fo setbuf ++.Fa "FILE *restrict stream" ++.Fa "char *restrict buf" ++.Fc + .Ft void +-.Fn setbuffer "FILE *stream" "char *buf" "int size" ++.Fo setbuffer ++.Fa "FILE *stream" ++.Fa "char *buf" ++.Fa "int size" ++.Fc + .Ft int +-.Fn setlinebuf "FILE *stream" ++.Fo setlinebuf ++.Fa "FILE *stream" ++.Fc + .Ft int +-.Fn setvbuf "FILE * restrict stream" "char * restrict buf" "int mode" "size_t size" ++.Fo setvbuf ++.Fa "FILE *restrict stream" ++.Fa "char *restrict buf" ++.Fa "int type" ++.Fa "size_t size" ++.Fc + .Sh DESCRIPTION +-The three types of buffering available are unbuffered, block buffered, +-and line buffered. ++Three types of buffering are available: ++unbuffered, block buffered, and line buffered. + When an output stream is unbuffered, information appears on the + destination file or terminal as soon as written; +-when it is block buffered many characters are saved up and written as a block; +-when it is line buffered characters are saved up until a newline is +-output or input is read from any stream attached to a terminal device ++when it is block buffered, ++many characters are saved up and written as a block; ++when it is line buffered, ++characters are saved up until a newline is output ++or input is read from any stream attached to a terminal device + (typically + .Dv stdin ) . + The function +@@ -73,17 +89,16 @@ + (See + .Xr fclose 3 . ) + .Pp +-Normally all files are block buffered. ++Normally, all files are block buffered. + When the first + .Tn I/O + operation occurs on a file, + .Xr malloc 3 +-is called, +-and an optimally-sized buffer is obtained. ++is called and an optimally-sized buffer is obtained. + If a stream refers to a terminal + (as + .Dv stdout +-normally does) it is line buffered. ++normally does), it is line buffered. + The standard error stream + .Dv stderr + is always unbuffered. +@@ -93,7 +108,7 @@ + function + may be used to alter the buffering behavior of a stream. + The +-.Fa mode ++.Fa type + argument must be one of the following three macros: + .Bl -tag -width _IOFBF -offset indent + .It Dv _IONBF diff --git a/stdio/FreeBSD/stdio.3.patch b/stdio/FreeBSD/stdio.3.patch new file mode 100644 index 0000000..7ed9c8e --- /dev/null +++ b/stdio/FreeBSD/stdio.3.patch @@ -0,0 +1,108 @@ +--- 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 @@ + .Vt FILE *stdin ; + .Vt FILE *stdout ; + .Vt FILE *stderr ; ++.Pp ++Note: ++The current implementation does not allow these variables ++to be evaluated at C compile/link time. ++That is, a runtime calculation must be performed, such as: ++.Bd -literal -offset indent ++#include ++ ++static FILE *var; ++ ++int main() { ++ var = stdout; ++} ++.Ed + .Sh DESCRIPTION + The standard + .Tn I/O +@@ -232,11 +246,21 @@ + .Dv putchar_unlocked + exist and will be used if the macro + definitions are explicitly removed. ++.Sh LEGACY SYNOPSIS ++The -D_NONSTD_SOURCE flag can be used ++to allow stdin, stdout, and/or stderr ++to be evaluated at compile/link time, as: ++.Bd -literal -offset indent ++#include ++ ++static FILE *var = stdout; ++.Ed + .Sh SEE ALSO + .Xr close 2 , + .Xr open 2 , + .Xr read 2 , +-.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 @@ + .Bl -column "Description" + .It Sy "Function Description" + .It "asprintf formatted output conversion" ++.It "" + .It "clearerr check and reset stream status" ++.It "" + .It "fclose close a stream" + .It "fdopen stream open functions" + .It "feof check and reset stream status" +@@ -282,15 +308,18 @@ + .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 "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" ++.It "" + .It "mkdtemp create unique temporary directory" + .It "mkstemp create unique temporary file" + .It "mktemp create unique temporary file" ++.It "" + .It "perror system error messages" + .It "printf formatted output conversion" + .It "putc output a character or word to a stream" +@@ -299,8 +328,10 @@ + .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" ++.It "" + .It "remove remove directory entry" + .It "rewind reposition a stream" ++.It "" + .It "scanf input format conversion" + .It "setbuf stream buffering operations" + .It "setbuffer stream buffering operations" +@@ -313,11 +344,14 @@ + .It "swprintf formatted wide character output conversion" + .It "sys_errlist system error messages" + .It "sys_nerr system error messages" ++.It "" + .It "tempnam temporary file routines" + .It "tmpfile temporary file routines" + .It "tmpnam temporary file routines" ++.It "" + .It "ungetc un-get character from input stream" + .It "ungetwc un-get wide character from input stream" ++.It "" + .It "vasprintf formatted output conversion" + .It "vfprintf formatted output conversion" + .It "vfscanf input format conversion" +@@ -329,5 +363,6 @@ + .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 diff --git a/stdio/FreeBSD/tempnam.c.patch b/stdio/FreeBSD/tempnam.c.patch new file mode 100644 index 0000000..6ae185d --- /dev/null +++ b/stdio/FreeBSD/tempnam.c.patch @@ -0,0 +1,78 @@ +--- tempnam.c.orig 2006-09-15 00:33:51.000000000 -0700 ++++ tempnam.c 2006-09-15 01:19:22.000000000 -0700 +@@ -38,6 +38,7 @@ + __FBSDID("$FreeBSD: src/lib/libc/stdio/tempnam.c,v 1.10 2002/03/22 21:53:04 obrien Exp $"); + + #include ++#include + #include + #include + #include +@@ -57,35 +58,61 @@ + int sverrno; + char *f, *name; + +- if (!(name = malloc(MAXPATHLEN))) ++#if __DARWIN_UNIX03 ++ struct stat sb; ++#endif /* __DARWIN_UNIX03 */ ++ if (!(name = malloc(MAXPATHLEN))) { + return(NULL); ++ } + + if (!pfx) + pfx = "tmp."; + ++#if !__DARWIN_UNIX03 + if (issetugid() == 0 && (f = getenv("TMPDIR"))) { + (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, + *(f + strlen(f) - 1) == '/'? "": "/", pfx); +- if ((f = _mktemp(name))) ++ if ((f = _mktemp(name))) { + return(f); ++ } + } +- ++#endif /* !__DARWIN_UNIX03 */ + if ((f = (char *)dir)) { ++#if __DARWIN_UNIX03 ++ if (!access(dir, W_OK)) { ++#endif /* __DARWIN_UNIX03 */ + (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, + *(f + strlen(f) - 1) == '/'? "": "/", pfx); +- if ((f = _mktemp(name))) ++ if ((f = _mktemp(name))) { + return(f); ++ } ++#if __DARWIN_UNIX03 ++ } ++#endif /* __DARWIN_UNIX03 */ + } + + f = P_tmpdir; ++#if __DARWIN_UNIX03 ++ if (stat(f, &sb) == 0) { /* directory accessible? */ ++#endif /* __DARWIN_UNIX03 */ + (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); +- if ((f = _mktemp(name))) ++ if ((f = _mktemp(name))) { + return(f); ++ } + ++#if __DARWIN_UNIX03 ++ } ++#endif /* __DARWIN_UNIX03 */ + f = _PATH_TMP; ++#if __DARWIN_UNIX03 ++ if (stat(f, &sb) < 0) { ++ f = "./"; /* directory inaccessible */ ++ } ++#endif /* __DARWIN_UNIX03 */ + (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); +- if ((f = _mktemp(name))) ++ if ((f = _mktemp(name))) { + return(f); ++ } + + sverrno = errno; + free(name); diff --git a/stdio/FreeBSD/tmpnam.3.patch b/stdio/FreeBSD/tmpnam.3.patch index 98d7ca7..682b0ee 100644 --- a/stdio/FreeBSD/tmpnam.3.patch +++ b/stdio/FreeBSD/tmpnam.3.patch @@ -1,6 +1,82 @@ ---- /Volumes/XDisk/tmp/Libc/stdio/FreeBSD/tmpnam.3.orig 2004-06-21 12:38:25.000000000 -0700 -+++ /Volumes/XDisk/tmp/Libc/stdio/FreeBSD/tmpnam.3 2004-10-24 17:08:31.000000000 -0700 -@@ -229,11 +229,6 @@ +--- _SB/Libc/stdio/FreeBSD/tmpnam.3 2004-11-25 11:38:35.000000000 -0800 ++++ _SB/Libc/stdio/FreeBSD/tmpnam.3.edit 2006-06-28 16:55:52.000000000 -0700 +@@ -49,11 +49,18 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft FILE * +-.Fn tmpfile void ++.Fo tmpfile ++.Fa void ++.Fc + .Ft char * +-.Fn tmpnam "char *str" ++.Fo tmpnam ++.Fa "char *s" ++.Fc + .Ft char * +-.Fn tempnam "const char *tmpdir" "const char *prefix" ++.Fo tempnam ++.Fa "const char *dir" ++.Fa "const char *pfx" ++.Fc + .Sh DESCRIPTION + The + .Fn tmpfile +@@ -67,12 +74,13 @@ + reference to it is closed. + The file is opened with the access value + .Ql w+ . +-The file is created in the directory determined by the environment variable ++If the environment variable + .Ev TMPDIR +-if set. +-The default location if ++is defined, ++the file is created in the specified directory. ++The default location, if + .Ev TMPDIR +-is not set is ++is not set, is + .Pa /tmp . + .Pp + The +@@ -87,7 +95,7 @@ + is defined in the include file + .In stdio.h . + If the argument +-.Fa str ++.Fa s + is + .Pf non- Dv NULL , + the file name is copied to the buffer it references. +@@ -97,7 +105,7 @@ + returns a pointer to the file name. + .Pp + The buffer referenced by +-.Fa str ++.Fa s + is expected to be at least + .Dv L_tmpnam + bytes in length. +@@ -116,7 +124,7 @@ + The environment variable + .Ev TMPDIR + (if set), the argument +-.Fa tmpdir ++.Fa dir + (if + .Pf non- Dv NULL ) , + the directory +@@ -127,7 +135,7 @@ + temporary file. + .Pp + The argument +-.Fa prefix , ++.Fa pfx , + if + .Pf non- Dv NULL , + is used to specify a file name prefix, which will be the +@@ -229,11 +237,6 @@ .Sh SEE ALSO .Xr mkstemp 3 , .Xr mktemp 3 diff --git a/stdio/FreeBSD/ungetc.3.patch b/stdio/FreeBSD/ungetc.3.patch new file mode 100644 index 0000000..cb470b3 --- /dev/null +++ b/stdio/FreeBSD/ungetc.3.patch @@ -0,0 +1,43 @@ +--- _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 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft int +-.Fn ungetc "int c" "FILE *stream" ++.Fo ungetc ++.Fa "int c" ++.Fa "FILE *stream" ++.Fc + .Sh DESCRIPTION + The + .Fn ungetc +@@ -56,20 +59,20 @@ + (converted to an unsigned char) + back onto the input stream pointed to by + .Fa stream . +-The pushed-back characters will be returned by subsequent reads on the +-stream (in reverse order). +-A successful intervening call, +-using the same stream, ++The pushed-back characters will be returned (in reverse order) ++by subsequent reads on the stream. ++A successful intervening call + to one of the file positioning functions + .Xr ( fseek 3 , + .Xr fsetpos 3 , + or +-.Xr rewind 3 ) +-will discard the pushed back characters. ++.Xr rewind 3 ) , ++using the same stream, ++will discard the pushed-back characters. + .Pp +-One character of push-back is guaranteed, ++Only one character of push-back is guaranteed, + but as long as there is sufficient memory, +-an effectively infinite amount of pushback is allowed. ++an effectively infinite amount of push-back is allowed. + .Pp + If a character is successfully pushed-back, + the end-of-file indicator for the stream is cleared. diff --git a/stdio/FreeBSD/ungetwc.3.patch b/stdio/FreeBSD/ungetwc.3.patch index 44307b3..0cc1a09 100644 --- a/stdio/FreeBSD/ungetwc.3.patch +++ b/stdio/FreeBSD/ungetwc.3.patch @@ -1,5 +1,5 @@ ---- ungetwc.3.orig Fri Mar 11 11:54:47 2005 -+++ ungetwc.3 Fri Mar 11 11:55:38 2005 +--- _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 @@ .Dt UNGETWC 3 .Os @@ -10,22 +10,58 @@ .Nd un-get wide character from input stream .Sh LIBRARY .Lb libc -@@ -51,6 +52,9 @@ +@@ -50,7 +51,19 @@ + .In stdio.h .In wchar.h .Ft wint_t - .Fn ungetwc "wint_t wc" "FILE *stream" +-.Fn ungetwc "wint_t wc" "FILE *stream" ++.Fo ungetwc ++.Fa "wint_t wc" ++.Fa "FILE *stream" ++.Fc ++.In stdio.h ++.In wchar.h +.In xlocale.h +.Ft wint_t -+.Fn ungetwc_l "wint_t wc" "FILE *stream" "locale_t loc" ++.Fo ungetwc_l ++.Fa "wint_t wc" ++.Fa "FILE *stream" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn ungetwc -@@ -76,6 +80,14 @@ +@@ -60,22 +73,31 @@ + .Vt wchar_t ) + back onto the input stream pointed to by + .Fa stream . +-The pushed-backed wide characters will be returned by subsequent reads on the +-stream (in reverse order). +-A successful intervening call, using the same stream, to one of the file ++The pushed-backed wide characters will be returned (in reverse order) ++by subsequent reads on the stream. ++A successful intervening call to one of the file + positioning functions + .Xr fseek 3 , + .Xr fsetpos 3 , + or +-.Xr rewind 3 +-will discard the pushed back wide characters. ++.Xr rewind 3 , ++using the same stream, ++will discard the pushed-back wide characters. + .Pp +-One wide character of push-back is guaranteed, +-but as long as there is +-sufficient memory, an effectively infinite amount of pushback is allowed. ++Only one wide character of push-back is guaranteed, ++but as long as there is sufficient memory, ++an effectively infinite amount of push-back is allowed. .Pp If a character is successfully pushed-back, the end-of-file indicator for the stream is cleared. +.Pp -+While the ++Although the +.Fn ungetwc +function uses the current locale, the +.Fn ungetwc_l @@ -35,7 +71,7 @@ .Sh RETURN VALUES The .Fn ungetwc -@@ -91,7 +103,8 @@ +@@ -91,7 +113,8 @@ the operation will fail and the stream will remain unchanged. .Sh SEE ALSO .Xr fseek 3 , diff --git a/stdio/FreeBSD/vfprintf.c.patch b/stdio/FreeBSD/vfprintf.c.patch index 88df771..ab4a546 100644 --- a/stdio/FreeBSD/vfprintf.c.patch +++ b/stdio/FreeBSD/vfprintf.c.patch @@ -1,5 +1,5 @@ ---- vfprintf.c.orig 2004-11-25 11:38:35.000000000 -0800 -+++ vfprintf.c 2005-11-08 22:43:11.000000000 -0800 +--- vfprintf.c.orig 2006-10-01 00:03:16.000000000 -0700 ++++ vfprintf.c 2006-10-01 00:21:05.000000000 -0700 @@ -40,6 +40,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des Exp $"); @@ -94,7 +94,7 @@ if (ret >= 0 && __fflush(&fake)) ret = EOF; if (fake._flags & __SERR) -@@ -336,7 +365,7 @@ +@@ -336,14 +365,14 @@ * that the wide char. string ends in a null character. */ static char * @@ -103,6 +103,14 @@ { 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 @@ p = wcsarg; mbs = initial; @@ -130,7 +138,16 @@ if (clen == 0 || clen == (size_t)-1) break; mbp += clen; -@@ -402,7 +431,21 @@ +@@ -395,6 +424,8 @@ + /* + * MT-safe version + */ ++__private_extern__ const char *__fix_nogrouping(const char *); ++ + int + vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) + +@@ -402,7 +433,21 @@ int ret; FLOCKFILE(fp); @@ -153,7 +170,7 @@ FUNLOCKFILE(fp); return (ret); } -@@ -451,12 +494,15 @@ +@@ -451,12 +496,15 @@ #define PTRDIFFT 0x800 /* ptrdiff_t */ #define INTMAXT 0x1000 /* intmax_t */ #define CHARINT 0x2000 /* print char using int format */ @@ -171,7 +188,7 @@ { char *fmt; /* format string */ int ch; /* character from fmt */ -@@ -502,6 +548,11 @@ +@@ -502,6 +550,11 @@ int nseps; /* number of group separators with ' */ int nrepeats; /* number of repeats of the last group */ #endif @@ -183,7 +200,16 @@ u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ -@@ -633,22 +684,23 @@ +@@ -599,7 +652,7 @@ + #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() \ +@@ -633,22 +686,24 @@ val = GETARG (int); \ } @@ -202,6 +228,7 @@ + errno = EBADF; return (EOF); + } ++ ORIENT(fp, -1); /* optimise fprintf(stderr) (and other unbuffered Unix files) */ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && @@ -211,7 +238,7 @@ fmt = (char *)fmt0; argtable = NULL; -@@ -675,6 +727,9 @@ +@@ -675,6 +730,9 @@ } if (ch == '\0') goto done; @@ -221,7 +248,7 @@ fmt++; /* skip over '%' */ flags = 0; -@@ -683,6 +738,9 @@ +@@ -683,6 +741,9 @@ prec = -1; sign = '\0'; ox[1] = '\0'; @@ -231,7 +258,7 @@ rflag: ch = *fmt++; reswitch: switch (ch) { -@@ -698,6 +756,11 @@ +@@ -698,6 +759,11 @@ case '#': flags |= ALT; goto rflag; @@ -243,18 +270,18 @@ case '*': /*- * ``A negative field width argument is taken as a -@@ -718,8 +781,8 @@ +@@ -718,8 +784,8 @@ goto rflag; case '\'': flags |= GROUPING; - thousands_sep = *(localeconv()->thousands_sep); - grouping = localeconv()->grouping; + thousands_sep = *(localeconv_l(loc)->thousands_sep); -+ grouping = localeconv_l(loc)->grouping; ++ grouping = __fix_nogrouping(localeconv_l(loc)->grouping); goto rflag; case '.': if ((ch = *fmt++) == '*') { -@@ -793,14 +856,18 @@ +@@ -793,14 +859,18 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'c': @@ -275,7 +302,7 @@ if (mbseqlen == (size_t)-1) { fp->_flags |= __SERR; goto error; -@@ -817,6 +884,10 @@ +@@ -817,6 +887,10 @@ /*FALLTHROUGH*/ case 'd': case 'i': @@ -286,7 +313,7 @@ if (flags & INTMAX_SIZE) { ujval = SJARG(); if ((intmax_t)ujval < 0) { -@@ -835,6 +906,12 @@ +@@ -835,6 +909,12 @@ #ifndef NO_FLOATING_POINT case 'a': case 'A': @@ -299,7 +326,7 @@ if (ch == 'a') { ox[1] = 'x'; xdigs = xdigs_lower; -@@ -848,6 +925,12 @@ +@@ -848,6 +928,12 @@ prec++; if (dtoaresult != NULL) freedtoa(dtoaresult); @@ -312,7 +339,7 @@ if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = cp = -@@ -859,6 +942,7 @@ +@@ -859,6 +945,7 @@ __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend); } @@ -320,7 +347,7 @@ if (prec < 0) prec = dtoaend - cp; if (expt == INT_MAX) -@@ -866,6 +950,12 @@ +@@ -866,6 +953,12 @@ goto fp_common; case 'e': case 'E': @@ -333,7 +360,7 @@ expchar = ch; if (prec < 0) /* account for digit before decpt */ prec = DEFPREC + 1; -@@ -874,10 +964,22 @@ +@@ -874,10 +967,22 @@ goto fp_begin; case 'f': case 'F': @@ -356,7 +383,7 @@ expchar = ch - ('g' - 'e'); if (prec == 0) prec = 1; -@@ -886,6 +988,14 @@ +@@ -886,6 +991,14 @@ prec = DEFPREC; if (dtoaresult != NULL) freedtoa(dtoaresult); @@ -371,7 +398,7 @@ if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = cp = -@@ -899,6 +1009,7 @@ +@@ -899,6 +1012,7 @@ if (expt == 9999) expt = INT_MAX; } @@ -379,7 +406,7 @@ fp_common: if (signflag) sign = '-'; -@@ -993,6 +1104,10 @@ +@@ -993,6 +1107,10 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'o': @@ -390,7 +417,7 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1007,6 +1122,10 @@ +@@ -1007,6 +1125,10 @@ * defined manner.'' * -- ANSI X3J11 */ @@ -401,7 +428,7 @@ ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; xdigs = xdigs_lower; -@@ -1025,7 +1144,7 @@ +@@ -1025,7 +1147,7 @@ if ((wcp = GETARG(wchar_t *)) == NULL) cp = "(null)"; else { @@ -410,7 +437,7 @@ if (convbuf == NULL) { fp->_flags |= __SERR; goto error; -@@ -1056,6 +1175,10 @@ +@@ -1056,6 +1178,10 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'u': @@ -421,7 +448,7 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1068,6 +1191,10 @@ +@@ -1068,6 +1194,10 @@ case 'x': xdigs = xdigs_lower; hex: @@ -432,7 +459,24 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1112,6 +1239,11 @@ +@@ -1093,6 +1223,7 @@ + * ``The result of converting a zero value with an + * explicit precision of zero is no characters.'' + * -- ANSI X3J11 ++ * except for %#.0o and zero value + */ + cp = buf + BUF; + if (flags & INTMAX_SIZE) { +@@ -1102,7 +1233,7 @@ + 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, +@@ -1112,6 +1243,11 @@ if (size > BUF) /* should never happen */ abort(); break; @@ -444,7 +488,7 @@ default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; -@@ -1123,6 +1255,290 @@ +@@ -1123,6 +1259,290 @@ break; } @@ -735,7 +779,34 @@ /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be -@@ -1406,6 +1822,11 @@ +@@ -1178,7 +1598,7 @@ + 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 @@ + 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 @@ if (flags & LONGINT) ADDTYPE(T_WINT); else @@ -747,7 +818,7 @@ ADDTYPE(T_INT); break; case 'D': -@@ -1413,6 +1834,11 @@ +@@ -1413,6 +1838,11 @@ /*FALLTHROUGH*/ case 'd': case 'i': @@ -759,8 +830,11 @@ ADDSARG(); break; #ifndef NO_FLOATING_POINT -@@ -1423,6 +1849,11 @@ +@@ -1421,8 +1851,14 @@ + case 'e': + case 'E': case 'f': ++ case 'F': case 'g': case 'G': +#ifdef VECTORS @@ -771,7 +845,7 @@ if (flags & LONGDBL) ADDTYPE(T_LONG_DOUBLE); else -@@ -1451,9 +1882,19 @@ +@@ -1451,9 +1887,19 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'o': @@ -791,7 +865,7 @@ ADDTYPE(TP_VOID); break; case 'S': -@@ -1471,6 +1912,11 @@ +@@ -1471,6 +1917,11 @@ case 'u': case 'X': case 'x': @@ -803,7 +877,7 @@ ADDUARG(); break; default: /* "%?" prints ?, unless ? is NUL */ -@@ -1537,7 +1983,7 @@ +@@ -1537,7 +1988,7 @@ (*argtable) [n].sizearg = va_arg (ap, size_t); break; case TP_SIZET: @@ -812,7 +886,7 @@ break; case T_INTMAXT: (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); -@@ -1556,6 +2002,11 @@ +@@ -1556,6 +2007,11 @@ (*argtable) [n].longdoublearg = va_arg (ap, long double); break; #endif diff --git a/stdio/FreeBSD/vfscanf.c.patch b/stdio/FreeBSD/vfscanf.c.patch index aa47ead..54d9799 100644 --- a/stdio/FreeBSD/vfscanf.c.patch +++ b/stdio/FreeBSD/vfscanf.c.patch @@ -1,5 +1,5 @@ --- vfscanf.c.orig 2004-11-25 11:38:35.000000000 -0800 -+++ vfscanf.c 2005-02-23 19:24:50.000000000 -0800 ++++ vfscanf.c 2005-05-20 00:46:37.000000000 -0700 @@ -40,6 +40,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.37 2004/05/02 10:55:05 das Exp $"); @@ -226,7 +226,7 @@ n = 0; - while (!isspace(*fp->_p) && width != 0) { - if (n == MB_CUR_MAX) { -+ while (!isspace_l(*fp->_p, loc) && width != 0) { ++ while (width != 0) { + if (n == mb_cur_max) { fp->_flags |= __SERR; goto input_failure; @@ -287,7 +287,7 @@ if (flags & POINTER) *va_arg(ap, void **) = (void *)(uintptr_t)res; -@@ -763,43 +800,52 @@ +@@ -763,43 +800,48 @@ nassigned++; } nread += p - buf; @@ -302,11 +302,8 @@ - if (width == 0 || width > sizeof(buf) - 1) - width = sizeof(buf) - 1; - if ((width = parsefloat(fp, buf, buf + width)) == 0) -+ if ((width = parsefloat(fp, &pbuf, width, loc)) == 0) { -+ if (pbuf) -+ free(pbuf); ++ if ((width = parsefloat(fp, &pbuf, width, loc)) == 0) goto match_failure; -+ } if ((flags & SUPPRESS) == 0) { if (flags & LONGDBL) { - long double res = strtold(buf, &p); @@ -328,7 +325,6 @@ } nread += width; - nconversions++; -+ free(pbuf); break; + } #endif /* !NO_FLOATING_POINT */ @@ -350,7 +346,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 +853,10 @@ +@@ -807,9 +849,10 @@ * considered part of the scanset. */ static const u_char * @@ -362,7 +358,7 @@ { int c, n, v, i; -@@ -845,6 +892,7 @@ +@@ -845,6 +888,7 @@ return (fmt - 1); case '-': @@ -370,7 +366,7 @@ /* * A scanset of the form * [01+-] -@@ -865,8 +913,8 @@ +@@ -865,8 +909,8 @@ */ n = *fmt; if (n == ']' @@ -381,7 +377,7 @@ ) ) { c = '-'; -@@ -874,14 +922,14 @@ +@@ -874,14 +918,14 @@ } fmt++; /* fill in the range */ @@ -399,7 +395,7 @@ ) tab[i] = v; } -@@ -901,7 +949,7 @@ +@@ -901,7 +945,7 @@ return (fmt); #endif break; @@ -408,7 +404,7 @@ case ']': /* end of scanset */ return (fmt); -@@ -915,7 +963,7 @@ +@@ -915,18 +959,42 @@ #ifndef NO_FLOATING_POINT static int @@ -417,27 +413,45 @@ { char *commit, *p; int infnanpos = 0; -@@ -924,9 +972,18 @@ - S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS + 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 } state = S_START; unsigned char c; - char decpt = *localeconv()->decimal_point; -+ char decpt = *localeconv_l(loc)->decimal_point; ++ unsigned char *decpt = (unsigned char *)localeconv_l(loc)->decimal_point; ++ char *decpt_start; _Bool gotmantdig = 0, ishex = 0; -+ char *b, *e; +- ++ static char *b = NULL; ++ static size_t bsiz = 0; ++ char *e; + size_t s; - -+ s = (width == 0 ? BUF : width + 1); -+ b = (char *)malloc(s); -+ if (b == NULL) { -+ *buf = NULL; -+ return 0; ++ ++ if (bsiz = 0) { ++ b = (char *)malloc(BUF); ++ if (b == NULL) { ++ *buf = NULL; ++ return 0; ++ } ++ bsiz = BUF; ++ } ++ s = (width == 0 ? BUF : (width + 1)); ++ if (s > bsiz) { ++ b = (char *)reallocf(b, s); ++ if (b == NULL) { ++ bsiz = 0; ++ *buf = NULL; ++ return 0; ++ } ++ bsiz = s; + } + e = b + (s - 1); /* * We set commit = p whenever the string we have read so far * constitutes a valid representation of a floating point -@@ -936,8 +993,8 @@ +@@ -936,8 +1004,8 @@ * always necessary to read at least one character that doesn't * match; thus, we can't short-circuit "infinity" or "nan(...)". */ @@ -448,7 +462,7 @@ c = *fp->_p; reswitch: switch (state) { -@@ -997,7 +1054,7 @@ +@@ -997,7 +1065,7 @@ if (c == ')') { commit = p; infnanpos = -2; @@ -457,7 +471,7 @@ goto parsedone; break; } -@@ -1013,7 +1070,7 @@ +@@ -1013,16 +1081,33 @@ goto reswitch; } case S_DIGITS: @@ -465,8 +479,37 @@ + if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc)) gotmantdig = 1; else { - state = S_FRAC; -@@ -1030,7 +1087,7 @@ +- 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 +1115,7 @@ goto parsedone; else state = S_EXP; @@ -475,7 +518,7 @@ commit = p; gotmantdig = 1; } else -@@ -1043,7 +1100,7 @@ +@@ -1043,7 +1128,7 @@ else goto reswitch; case S_EXPDIGITS: @@ -484,25 +527,29 @@ commit = p; else goto parsedone; -@@ -1051,6 +1108,17 @@ +@@ -1051,6 +1136,21 @@ default: abort(); } + if (p >= e) { -+ size_t diff = (p - b); ++ ssize_t diff = (p - b); ++ ssize_t com = (commit - b); + s += BUF; + b = (char *)reallocf(b, s); + if (b == NULL) { ++ bsiz = 0; + *buf = NULL; + return 0; + } ++ bsiz = s; + e = b + (s - 1); + p = b + diff; ++ commit = b + com; + } *p++ = c; if (--fp->_r > 0) fp->_p++; -@@ -1062,6 +1130,7 @@ +@@ -1062,6 +1162,7 @@ while (commit < --p) __ungetc(*(u_char *)p, fp); *++commit = '\0'; diff --git a/stdio/FreeBSD/vfwprintf.c.patch b/stdio/FreeBSD/vfwprintf.c.patch index a645ab8..cbfa375 100644 --- a/stdio/FreeBSD/vfwprintf.c.patch +++ b/stdio/FreeBSD/vfwprintf.c.patch @@ -1,5 +1,5 @@ ---- vfwprintf.c.orig 2004-11-25 11:38:36.000000000 -0800 -+++ vfwprintf.c 2005-11-08 22:46:07.000000000 -0800 +--- vfwprintf.c.orig 2006-10-01 00:03:16.000000000 -0700 ++++ vfwprintf.c 2006-10-01 00:21:40.000000000 -0700 @@ -42,6 +42,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.23 2004/08/26 06:25:28 des Exp $"); @@ -127,7 +127,8 @@ mbstate_t mbs; wchar_t *convbuf, *wcp; const char *p; - size_t insize, nchars, nconv; +- size_t insize, nchars, nconv; ++ size_t insize, nchars, nconv = 0; + int mb_cur_max = MB_CUR_MAX_L(loc); if (mbsarg == NULL) @@ -150,7 +151,16 @@ if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) break; wcp++; -@@ -425,7 +455,21 @@ +@@ -418,6 +448,8 @@ + /* + * 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 @@ int ret; FLOCKFILE(fp); @@ -173,7 +183,7 @@ FUNLOCKFILE(fp); return (ret); } -@@ -474,12 +518,15 @@ +@@ -474,12 +520,15 @@ #define PTRDIFFT 0x800 /* ptrdiff_t */ #define INTMAXT 0x1000 /* intmax_t */ #define CHARINT 0x2000 /* print char using int format */ @@ -191,7 +201,17 @@ { wchar_t *fmt; /* format string */ wchar_t ch; /* character from fmt */ -@@ -524,6 +571,11 @@ +@@ -507,7 +556,8 @@ + * 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 @@ int nseps; /* number of group separators with ' */ int nrepeats; /* number of repeats of the last group */ #endif @@ -203,7 +223,7 @@ u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ -@@ -560,7 +612,7 @@ +@@ -560,7 +615,7 @@ */ #define PRINT(ptr, len) do { \ for (n3 = 0; n3 < (len); n3++) \ @@ -212,7 +232,16 @@ } while (0) #define PAD(howmany, with) do { \ if ((n = (howmany)) > 0) { \ -@@ -640,21 +692,22 @@ +@@ -606,7 +661,7 @@ + #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() \ +@@ -640,21 +695,24 @@ val = GETARG (int); \ } @@ -221,7 +250,8 @@ grouping = NULL; #ifndef NO_FLOATING_POINT - decimal_point = localeconv()->decimal_point; -+ decimal_point = localeconv_l(loc)->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 */ @@ -230,6 +260,7 @@ + errno = EBADF; return (EOF); + } ++ ORIENT(fp, 1); /* optimise fprintf(stderr) (and other unbuffered Unix files) */ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && @@ -239,7 +270,7 @@ fmt = (wchar_t *)fmt0; argtable = NULL; -@@ -678,6 +731,9 @@ +@@ -678,6 +736,9 @@ } if (ch == '\0') goto done; @@ -249,7 +280,7 @@ fmt++; /* skip over '%' */ flags = 0; -@@ -686,6 +742,9 @@ +@@ -686,6 +747,9 @@ prec = -1; sign = '\0'; ox[1] = '\0'; @@ -259,7 +290,7 @@ rflag: ch = *fmt++; reswitch: switch (ch) { -@@ -701,6 +760,11 @@ +@@ -701,6 +765,11 @@ case '#': flags |= ALT; goto rflag; @@ -271,18 +302,18 @@ case '*': /*- * ``A negative field width argument is taken as a -@@ -721,8 +785,8 @@ +@@ -721,8 +790,8 @@ goto rflag; case '\'': flags |= GROUPING; - thousands_sep = *(localeconv()->thousands_sep); - grouping = localeconv()->grouping; + thousands_sep = *(localeconv_l(loc)->thousands_sep); -+ grouping = localeconv_l(loc)->grouping; ++ grouping = __fix_nogrouping(localeconv_l(loc)->grouping); goto rflag; case '.': if ((ch = *fmt++) == '*') { -@@ -796,10 +860,14 @@ +@@ -796,10 +865,14 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'c': @@ -298,7 +329,7 @@ size = 1; sign = '\0'; break; -@@ -808,6 +876,10 @@ +@@ -808,6 +881,10 @@ /*FALLTHROUGH*/ case 'd': case 'i': @@ -309,7 +340,7 @@ if (flags & INTMAX_SIZE) { ujval = SJARG(); if ((intmax_t)ujval < 0) { -@@ -826,6 +898,12 @@ +@@ -826,6 +903,12 @@ #ifndef NO_FLOATING_POINT case 'a': case 'A': @@ -322,7 +353,7 @@ if (ch == 'a') { ox[1] = 'x'; xdigs = xdigs_lower; -@@ -837,6 +915,12 @@ +@@ -837,6 +920,12 @@ } if (prec >= 0) prec++; @@ -335,7 +366,7 @@ if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = -@@ -848,6 +932,7 @@ +@@ -848,6 +937,7 @@ __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend); } @@ -343,7 +374,7 @@ if (prec < 0) prec = dtoaend - dtoaresult; if (expt == INT_MAX) -@@ -855,11 +940,17 @@ +@@ -855,11 +945,17 @@ if (convbuf != NULL) free(convbuf); ndig = dtoaend - dtoaresult; @@ -362,7 +393,7 @@ expchar = ch; if (prec < 0) /* account for digit before decpt */ prec = DEFPREC + 1; -@@ -868,10 +959,22 @@ +@@ -868,10 +964,22 @@ goto fp_begin; case 'f': case 'F': @@ -385,7 +416,7 @@ expchar = ch - ('g' - 'e'); if (prec == 0) prec = 1; -@@ -880,6 +983,14 @@ +@@ -880,6 +988,14 @@ prec = DEFPREC; if (convbuf != NULL) free(convbuf); @@ -400,7 +431,7 @@ if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = -@@ -893,8 +1004,9 @@ +@@ -893,8 +1009,9 @@ if (expt == 9999) expt = INT_MAX; } @@ -411,7 +442,7 @@ freedtoa(dtoaresult); fp_common: if (signflag) -@@ -989,6 +1101,10 @@ +@@ -989,6 +1106,10 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'o': @@ -422,7 +453,7 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1003,6 +1119,10 @@ +@@ -1003,6 +1124,10 @@ * defined manner.'' * -- ANSI X3J11 */ @@ -433,7 +464,7 @@ ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; xdigs = xdigs_lower; -@@ -1024,7 +1144,7 @@ +@@ -1024,7 +1149,7 @@ if ((mbp = GETARG(char *)) == NULL) cp = L"(null)"; else { @@ -442,7 +473,7 @@ if (convbuf == NULL) { fp->_flags |= __SERR; goto error; -@@ -1055,6 +1175,10 @@ +@@ -1055,6 +1180,10 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'u': @@ -453,7 +484,7 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1067,6 +1191,10 @@ +@@ -1067,6 +1196,10 @@ case 'x': xdigs = xdigs_lower; hex: @@ -464,7 +495,24 @@ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1111,6 +1239,11 @@ +@@ -1092,6 +1225,7 @@ + * ``The result of converting a zero value with an + * explicit precision of zero is no characters.'' + * -- ANSI X3J11 ++ * except for %#.0o and zero value + */ + cp = buf + BUF; + if (flags & INTMAX_SIZE) { +@@ -1101,7 +1235,7 @@ + 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, +@@ -1111,6 +1245,11 @@ if (size > BUF) /* should never happen */ abort(); break; @@ -476,7 +524,7 @@ default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; -@@ -1122,6 +1255,288 @@ +@@ -1122,6 +1261,288 @@ break; } @@ -765,7 +813,34 @@ /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be -@@ -1401,6 +1816,11 @@ +@@ -1177,7 +1598,7 @@ + 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 @@ + 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 @@ if (flags & LONGINT) ADDTYPE(T_WINT); else @@ -777,7 +852,7 @@ ADDTYPE(T_INT); break; case 'D': -@@ -1408,6 +1828,11 @@ +@@ -1408,6 +1833,11 @@ /*FALLTHROUGH*/ case 'd': case 'i': @@ -789,8 +864,11 @@ ADDSARG(); break; #ifndef NO_FLOATING_POINT -@@ -1418,6 +1843,11 @@ +@@ -1416,8 +1846,14 @@ + case 'e': + case 'E': case 'f': ++ case 'F': case 'g': case 'G': +#ifdef VECTORS @@ -801,7 +879,7 @@ if (flags & LONGDBL) ADDTYPE(T_LONG_DOUBLE); else -@@ -1446,9 +1876,19 @@ +@@ -1446,9 +1882,19 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'o': @@ -821,7 +899,7 @@ ADDTYPE(TP_VOID); break; case 'S': -@@ -1466,6 +1906,11 @@ +@@ -1466,6 +1912,11 @@ case 'u': case 'X': case 'x': @@ -833,7 +911,7 @@ ADDUARG(); break; default: /* "%?" prints ?, unless ? is NUL */ -@@ -1532,7 +1977,7 @@ +@@ -1532,7 +1983,7 @@ (*argtable) [n].sizearg = va_arg (ap, size_t); break; case TP_SIZET: @@ -842,7 +920,7 @@ break; case T_INTMAXT: (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); -@@ -1551,6 +1996,11 @@ +@@ -1551,6 +2002,11 @@ (*argtable) [n].longdoublearg = va_arg (ap, long double); break; #endif diff --git a/stdio/FreeBSD/vfwscanf.c.patch b/stdio/FreeBSD/vfwscanf.c.patch index 95dd467..d369649 100644 --- a/stdio/FreeBSD/vfwscanf.c.patch +++ b/stdio/FreeBSD/vfwscanf.c.patch @@ -1,5 +1,5 @@ --- vfwscanf.c.orig 2004-11-25 11:38:36.000000000 -0800 -+++ vfwscanf.c 2005-02-23 16:25:00.000000000 -0800 ++++ vfwscanf.c 2005-05-20 00:24:42.000000000 -0700 @@ -42,6 +42,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.12 2004/05/02 20:13:29 obrien Exp $"); @@ -108,8 +108,9 @@ goto input_failure; if (wi != c) { - __ungetwc(wi, fp); +- goto input_failure; + __ungetwc(wi, fp, loc); - goto input_failure; ++ goto match_failure; } nread++; continue; @@ -371,7 +372,7 @@ if (flags & POINTER) *va_arg(ap, void **) = (void *)(uintptr_t)res; -@@ -684,47 +715,49 @@ +@@ -684,47 +715,45 @@ nassigned++; } nread += p - buf; @@ -387,11 +388,8 @@ - sizeof(*buf) - 1) - width = sizeof(buf) / sizeof(*buf) - 1; - if ((width = parsefloat(fp, buf, buf + width)) == 0) -+ if ((width = parsefloat(fp, &pbuf, width, loc)) == 0) { -+ if (pbuf) -+ free(pbuf); ++ if ((width = parsefloat(fp, &pbuf, width, loc)) == 0) goto match_failure; -+ } if ((flags & SUPPRESS) == 0) { if (flags & LONGDBL) { - long double res = wcstold(buf, &p); @@ -413,7 +411,6 @@ } nread += width; - nconversions++; -+ free(pbuf); break; + } #endif /* !NO_FLOATING_POINT */ @@ -433,27 +430,43 @@ { wchar_t *commit, *p; int infnanpos = 0; -@@ -733,9 +766,18 @@ +@@ -733,9 +762,33 @@ 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 = (wchar_t)(unsigned char)*localeconv_l(loc)->decimal_point; ++ char *decimal_point; ++ wchar_t decpt; _Bool gotmantdig = 0, ishex = 0; -+ wchar_t *b, *e; +- ++ static wchar_t *b = NULL; ++ static size_t bsiz = 0; ++ wchar_t *e; + size_t s; - -+ s = (width == 0 ? BUF : width + 1); -+ b = (wchar_t *)malloc(s * sizeof(wchar_t)); -+ if (b == NULL) { -+ *buf = NULL; -+ return 0; ++ ++ if (bsiz == 0) { ++ b = (wchar_t *)malloc(BUF * sizeof(wchar_t)); ++ if (b == NULL) { ++ *buf = NULL; ++ return 0; ++ } ++ bsiz = BUF; ++ } ++ s = (width == 0 ? bsiz : (width + 1)); ++ if (s > bsiz) { ++ b = (wchar_t *)reallocf(b, s * sizeof(wchar_t)); ++ if (b == NULL) { ++ bsiz = 0; ++ *buf = NULL; ++ return 0; ++ } ++ bsiz = s; + } + e = b + (s - 1); /* * We set commit = p whenever the string we have read so far * constitutes a valid representation of a floating point -@@ -745,10 +787,10 @@ +@@ -745,10 +798,12 @@ * always necessary to read at least one character that doesn't * match; thus, we can't short-circuit "infinity" or "nan(...)". */ @@ -462,12 +475,14 @@ 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 +850,7 @@ +@@ -808,7 +863,7 @@ if (c == ')') { commit = p; infnanpos = -2; @@ -476,7 +491,7 @@ goto parsedone; break; } -@@ -824,7 +866,7 @@ +@@ -824,7 +879,7 @@ goto reswitch; } case S_DIGITS: @@ -485,7 +500,7 @@ gotmantdig = 1; else { state = S_FRAC; -@@ -841,7 +883,7 @@ +@@ -841,7 +896,7 @@ goto parsedone; else state = S_EXP; @@ -494,7 +509,7 @@ commit = p; gotmantdig = 1; } else -@@ -854,7 +896,7 @@ +@@ -854,7 +909,7 @@ else goto reswitch; case S_EXPDIGITS: @@ -503,20 +518,24 @@ commit = p; else goto parsedone; -@@ -862,16 +904,28 @@ +@@ -862,16 +917,32 @@ default: abort(); } + if (p >= e) { -+ size_t diff = (p - b); ++ ssize_t diff = (p - b); ++ ssize_t com = (commit - b); + s += BUF; + b = (wchar_t *)reallocf(b, s * sizeof(wchar_t)); + if (b == NULL) { ++ bsiz = 0; + *buf = NULL; + return 0; + } ++ bsiz = s; + e = b + (s - 1); + p = b + diff; ++ commit = b + com; + } *p++ = c; c = WEOF; diff --git a/stdio/FreeBSD/wprintf.3.patch b/stdio/FreeBSD/wprintf.3.patch index 66f41af..fa7ca8b 100644 --- a/stdio/FreeBSD/wprintf.3.patch +++ b/stdio/FreeBSD/wprintf.3.patch @@ -1,6 +1,78 @@ ---- wprintf.3.orig Fri Mar 11 17:09:07 2005 -+++ wprintf.3 Fri Mar 11 17:03:23 2005 -@@ -87,6 +87,12 @@ +--- 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 @@ + .Dt WPRINTF 3 + .Os + .Sh NAME +-.Nm wprintf , fwprintf , swprintf , +-.Nm vwprintf , vfwprintf , vswprintf ++.Nm fwprintf , ++.Nm swprintf , ++.Nm vfwprintf , ++.Nm vswprintf , ++.Nm vwprintf , ++.Nm wprintf + .Nd formatted wide character output conversion + .Sh LIBRARY + .Lb libc +@@ -50,23 +54,49 @@ + .In stdio.h + .In wchar.h + .Ft int +-.Fn fwprintf "FILE * restrict stream" "const wchar_t * restrict format" ... ++.Fo fwprintf ++.Fa "FILE *restrict stream" ++.Fa "const wchar_t *restrict format" ++.Fa ... ++.Fc + .Ft int +-.Fn swprintf "wchar_t * restrict ws" "size_t n" "const wchar_t * restrict format" ... ++.Fo swprintf ++.Fa "wchar_t *restrict ws" ++.Fa "size_t n" ++.Fa "const wchar_t *restrict format" ++.Fa ... ++.Fc + .Ft int +-.Fn wprintf "const wchar_t * restrict format" ... ++.Fo wprintf ++.Fa "const wchar_t *restrict format" ++.Fa ... ++.Fc + .In stdarg.h ++.In stdio.h ++.In wchar.h + .Ft int +-.Fn vfwprintf "FILE * restrict stream" "const wchar_t * restrict" "va_list ap" ++.Fo vfwprintf ++.Fa "FILE *restrict stream" ++.Fa "const wchar_t *restrict format" ++.Fa "va_list arg" ++.Fc + .Ft int +-.Fn vswprintf "wchar_t * restrict ws" "size_t n" "const wchar_t *restrict format" "va_list ap" ++.Fo vswprintf ++.Fa "wchar_t *restrict ws" ++.Fa "size_t n" ++.Fa "const wchar_t *restrict format" ++.Fa "va_list arg" ++.Fc + .Ft int +-.Fn vwprintf "const wchar_t * restrict format" "va_list ap" ++.Fo vwprintf ++.Fa "const wchar_t *restrict format" ++.Fa "va_list arg" ++.Fc + .Sh DESCRIPTION + The + .Fn wprintf + family of functions produces output according to a +-.Fa format ++.Fa format , + as described below. + The + .Fn wprintf +@@ -87,6 +117,12 @@ write to the wide character string .Fa ws . .Pp @@ -13,63 +85,29 @@ These functions write the output under the control of a .Fa format string that specifies how subsequent arguments -@@ -224,6 +230,20 @@ - .Xr localeconv 3 . - .El - .It -+An optional separator character ( -+.Cm \ , | \; | \ : | _ -+) used for separating multiple values when printing an AltiVec vector, -+or other multi-value unit. -+.Pp -+NOTE: This is an AltiVec only extension onto the -+.Fn printf -+specification. -+Behaviour of these values for -+.Fn printf -+is only defined for operating systems conforming to the -+AltiVec Technology Programming Interface Manual. -+(At time of writing this includes only Mac OS X 10.2 and later.) -+.It - 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 -@@ -314,6 +334,28 @@ - .It Sy Modifier Ta Cm c Ta Cm s - .It Cm l No (ell) Ta Vt wint_t Ta Vt "wchar_t *" - .El -+.Pp -+The AltiVec Technology Programming Interface Manual also defines five additional length modifiers -+which can be used (in place of the conventional length modifiers) for the printing of AltiVec vectors: -+.Bl -tag -compact -+.It Cm v -+Treat the argument as a vector value, unit length will be determined by the conversion -+specifier (default = 16 8-bit units for all integer conversions, -+4 32-bit units for floating point conversions). -+.It Cm vh, hv -+Treat the argument as a vector of 8 16-bit units. -+.It Cm vl, lv -+Treat the argument as a vector of 4 32-bit units. -+.El -+.Pp -+NOTE: The vector length specifiers are AltiVec only extensions onto the -+.Fn printf -+specification. -+Behaviour of these values for -+.Fn printf -+is only defined for operating systems conforming to the -+AltiVec Technology Programming Interface Manual. -+(At time of writing this includes only Mac OS X 10.2 and later.) - .It - A character that specifies the type of conversion to be applied. - .El -@@ -602,7 +644,8 @@ +@@ -96,7 +132,7 @@ + .Pp + These functions return the number of characters printed + (not including the trailing +-.Ql \e0 ++.Ql \e0 , + used to end output to strings). + .Pp + The +@@ -602,6 +638,7 @@ .Xr putwc 3 , .Xr setlocale 3 , .Xr wcsrtombs 3 , --.Xr wscanf 3 -+.Xr wscanf 3 , -+.Xr wprintf_l 3 ++.Xr wprintf_l 3 , + .Xr wscanf 3 .Sh STANDARDS Subject to the caveats noted in the - .Sx BUGS +@@ -614,7 +651,7 @@ + .Fn fwprintf , + .Fn swprintf , + .Fn vwprintf , +-.Fn vfwprintf ++.Fn vfwprintf , + and + .Fn vswprintf + functions diff --git a/stdio/FreeBSD/wscanf.3.patch b/stdio/FreeBSD/wscanf.3.patch index a7f7caf..1fd5edc 100644 --- a/stdio/FreeBSD/wscanf.3.patch +++ b/stdio/FreeBSD/wscanf.3.patch @@ -1,6 +1,94 @@ ---- wscanf.3.orig Fri Mar 11 17:09:15 2005 -+++ wscanf.3 Fri Mar 11 16:43:04 2005 -@@ -134,6 +134,12 @@ +--- 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 @@ + .Dt WSCANF 3 + .Os + .Sh NAME +-.Nm wscanf , + .Nm fwscanf , + .Nm swscanf , +-.Nm vwscanf , ++.Nm vfwscanf , + .Nm vswscanf , +-.Nm vfwscanf ++.Nm vwscanf , ++.Nm wscanf + .Nd wide character input format conversion + .Sh LIBRARY + .Lb libc +@@ -54,22 +54,46 @@ + .In stdio.h + .In wchar.h + .Ft int +-.Fn wscanf "const wchar_t * restrict format" ... ++.Fo fwscanf ++.Fa "FILE *restrict stream" ++.Fa "const wchar_t *restrict format" ++.Fa ... ++.Fc + .Ft int +-.Fn fwscanf "FILE * restrict stream" "const wchar_t * restrict format" ... ++.Fo swscanf ++.Fa "const wchar_t *restrict ws" ++.Fa "const wchar_t *restrict format" ++.Fa ... ++.Fc + .Ft int +-.Fn swscanf "const wchar_t * restrict str" "const wchar_t * restrict format" ... ++.Fo wscanf ++.Fa "const wchar_t *restrict format" ++.Fa ... ++.Fc + .In stdarg.h ++.In stdio.h ++.In wchar.h + .Ft int +-.Fn vwscanf "const wchar_t * restrict format" "va_list ap" ++.Fo vfwscanf ++.Fa "FILE *restrict stream" ++.Fa "const wchar_t *restrict format" ++.Fa "va_list arg" ++.Fc + .Ft int +-.Fn vswscanf "const wchar_t * restrict str" "const wchar_t * restrict format" "va_list ap" ++.Fo vswscanf ++.Fa "const wchar_t *restrict ws" ++.Fa "const wchar_t *restrict format" ++.Fa "va_list arg" ++.Fc + .Ft int +-.Fn vfwscanf "FILE * restrict stream" "const wchar_t * restrict format" "va_list ap" ++.Fo vwscanf ++.Fa "const wchar_t *restrict format" ++.Fa "va_list arg" ++.Fc + .Sh DESCRIPTION + The + .Fn wscanf +-family of functions scans input according to a ++family of functions scans input, according to a + .Fa format + as described below. + This format may contain +@@ -89,7 +113,8 @@ + and + .Fn swscanf + reads its input from the wide character string pointed to by +-.Fa str . ++.Fa ws . ++.Pp + The + .Fn vfwscanf + function +@@ -121,6 +146,7 @@ + All conversions are introduced by the + .Cm % + (percent sign) character. ++.Pp + The + .Fa format + string +@@ -134,10 +160,16 @@ when an input character does not match such a format character. Scanning also stops when an input conversion cannot be made (see below). @@ -13,7 +101,33 @@ .Sh CONVERSIONS Following the .Cm % -@@ -459,7 +465,8 @@ +-character introducing a conversion ++character introducing a conversion, + there may be a number of + .Em flag + characters, as follows: +@@ -433,15 +465,12 @@ + causes an immediate return of + .Dv EOF . + .Sh RETURN VALUES +-These +-functions +-return +-the number of input items assigned, which can be fewer than provided +-for, or even zero, in the event of a matching failure. +-Zero +-indicates that, while there was input available, ++These functions return the number of input items assigned, ++which can be fewer than provided for, or even zero, ++in the event of a matching failure. ++Zero indicates that, while there was input available, + no conversions were assigned; +-typically this is due to an invalid input character, ++typically, this is due to an invalid input character, + such as an alphabetic character for a + .Ql %d + conversion. +@@ -459,14 +488,15 @@ .Xr wcstod 3 , .Xr wcstol 3 , .Xr wcstoul 3 , @@ -23,3 +137,11 @@ .Sh STANDARDS The .Fn fwscanf , + .Fn wscanf , + .Fn swscanf , + .Fn vfwscanf , +-.Fn vwscanf ++.Fn vwscanf , + and + .Fn vswscanf + functions diff --git a/stdio/Makefile.inc b/stdio/Makefile.inc index 0e6892a..c09ffd2 100644 --- a/stdio/Makefile.inc +++ b/stdio/Makefile.inc @@ -32,7 +32,14 @@ LDBLSRCS += asprintf.c fprintf.c fscanf.c fwprintf.c fwscanf.c printf.c \ CFLAGS-${_src} += -fshort-enums -DVECTORS .endfor -UNIX03SRCS+= freopen.c fwrite.c +LEGACYSRCS+= fputs.c freopen.c fwrite.c tempnam.c + +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +CFLAGS-fputs-fbsd.c += -DLIBC_ALIAS_FPUTS +CFLAGS-freopen-fbsd.c += -DLIBC_ALIAS_FREOPEN +CFLAGS-fwrite-fbsd.c += -DLIBC_ALIAS_FWRITE +CFLAGS-tempnam-fbsd.c += -DLIBC_ALIAS_TEMPNAM .if ${LIB} == "c" MAN3+= getwc_l.3 putwc_l.3 printf_l.3 scanf_l.3 wprintf_l.3 wscanf_l.3 @@ -44,54 +51,132 @@ FBSDMAN3= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetws.3 flockfile.3 \ stdio.3 tmpnam.3 ungetc.3 ungetwc.3 wprintf.3 wscanf.3 .include "Makefile.fbsd_end" -MLINKS+=ferror.3 ferror_unlocked.3 \ - ferror.3 clearerr.3 ferror.3 clearerr_unlocked.3 \ - ferror.3 feof.3 ferror.3 feof_unlocked.3 \ - ferror.3 fileno.3 ferror.3 fileno_unlocked.3 -MLINKS+=fflush.3 fpurge.3 -MLINKS+=fgets.3 gets.3 -MLINKS+=fgetws.3 fgetws_l.3 -MLINKS+=flockfile.3 ftrylockfile.3 flockfile.3 funlockfile.3 -MLINKS+=fopen.3 fdopen.3 fopen.3 freopen.3 -MLINKS+=fputs.3 puts.3 -MLINKS+=fputws.3 fputws_l.3 -MLINKS+=fread.3 fwrite.3 -MLINKS+=fseek.3 fgetpos.3 fseek.3 fseeko.3 fseek.3 fsetpos.3 fseek.3 ftell.3 \ - fseek.3 ftello.3 fseek.3 rewind.3 -MLINKS+=funopen.3 fropen.3 funopen.3 fwopen.3 -MLINKS+=getc.3 fgetc.3 getc.3 getc_unlocked.3 getc.3 getchar.3 \ - getc.3 getchar_unlocked.3 getc.3 getw.3 -MLINKS+=getwc.3 fgetwc.3 getwc.3 getwchar.3 -MLINKS+=getwc_l.3 fgetwc_l.3 getwc_l.3 getwchar_l.3 -MLINKS+=mktemp.3 mkdtemp.3 mktemp.3 mkstemp.3 mktemp.3 mkstemps.3 -MLINKS+=printf.3 asprintf.3 printf.3 fprintf.3 \ - printf.3 snprintf.3 printf.3 sprintf.3 \ - printf.3 vasprintf.3 \ - printf.3 vfprintf.3 printf.3 vprintf.3 printf.3 vsnprintf.3 \ - printf.3 vsprintf.3 -MLINKS+=printf_l.3 asprintf_l.3 printf_l.3 fprintf_l.3 \ - printf_l.3 snprintf_l.3 printf_l.3 sprintf_l.3 \ - printf_l.3 vasprintf_l.3 \ - printf_l.3 vfprintf_l.3 printf_l.3 vprintf_l.3 printf_l.3 vsnprintf_l.3 \ - printf_l.3 vsprintf_l.3 -MLINKS+=putc.3 fputc.3 putc.3 putc_unlocked.3 putc.3 putchar.3 \ - putc.3 putchar_unlocked.3 putc.3 putw.3 -MLINKS+=putwc.3 fputwc.3 putwc.3 putwchar.3 -MLINKS+=putwc_l.3 fputwc_l.3 putwc_l.3 putwchar_l.3 -MLINKS+=scanf.3 fscanf.3 scanf.3 sscanf.3 scanf.3 vfscanf.3 scanf.3 vscanf.3 \ - scanf.3 vsscanf.3 -MLINKS+=scanf_l.3 fscanf_l.3 scanf_l.3 sscanf_l.3 scanf_l.3 vfscanf_l.3 \ - scanf_l.3 vscanf_l.3 scanf_l.3 vsscanf_l.3 -MLINKS+=setbuf.3 setbuffer.3 setbuf.3 setlinebuf.3 setbuf.3 setvbuf.3 -MLINKS+=tmpnam.3 tempnam.3 tmpnam.3 tmpfile.3 -MLINKS+=ungetwc.3 ungetwc_l.3 -MLINKS+=wprintf.3 fwprintf.3 wprintf.3 swprintf.3 \ - wprintf.3 vwprintf.3 wprintf.3 vfwprintf.3 wprintf.3 vswprintf.3 -MLINKS+=wprintf_l.3 fwprintf_l.3 wprintf_l.3 swprintf_l.3 \ - wprintf_l.3 vwprintf_l.3 wprintf_l.3 vfwprintf_l.3 \ - wprintf_l.3 vswprintf_l.3 -MLINKS+=wscanf.3 fwscanf.3 wscanf.3 swscanf.3 wscanf.3 vwscanf.3 \ - wscanf.3 vswscanf.3 wscanf.3 vfwscanf.3 -MLINKS+=wscanf_l.3 fwscanf_l.3 wscanf_l.3 swscanf_l.3 wscanf_l.3 vwscanf_l.3 \ - wscanf_l.3 vswscanf_l.3 wscanf_l.3 vfwscanf_l.3 +MLINKS+= ferror.3 clearerr.3 \ + ferror.3 clearerr_unlocked.3 \ + ferror.3 feof.3 \ + ferror.3 feof_unlocked.3 \ + ferror.3 ferror_unlocked.3 \ + ferror.3 fileno.3 \ + ferror.3 fileno_unlocked.3 + +MLINKS+= fflush.3 fpurge.3 + +MLINKS+= fgets.3 gets.3 + +MLINKS+= fgetws.3 fgetws_l.3 + +MLINKS+= flockfile.3 ftrylockfile.3 \ + flockfile.3 funlockfile.3 + +MLINKS+= fopen.3 fdopen.3 \ + fopen.3 freopen.3 + +MLINKS+= fputs.3 puts.3 + +MLINKS+= fputws.3 fputws_l.3 + +MLINKS+= fread.3 fwrite.3 + +MLINKS+= fseek.3 fgetpos.3 \ + fseek.3 fseeko.3 \ + fseek.3 fsetpos.3 \ + fseek.3 ftell.3 \ + fseek.3 ftello.3 \ + fseek.3 rewind.3 + +MLINKS+= funopen.3 fropen.3 \ + funopen.3 fwopen.3 + +MLINKS+= getc.3 fgetc.3 \ + getc.3 getc_unlocked.3 \ + getc.3 getchar.3 \ + getc.3 getchar_unlocked.3 \ + getc.3 getw.3 + +MLINKS+= getwc.3 fgetwc.3 \ + getwc.3 getwchar.3 + +MLINKS+= getwc_l.3 fgetwc_l.3 \ + getwc_l.3 getwchar_l.3 + +MLINKS+= mktemp.3 mkdtemp.3 \ + mktemp.3 mkstemp.3 \ + mktemp.3 mkstemps.3 + +MLINKS+= printf.3 asprintf.3 \ + printf.3 fprintf.3 \ + printf.3 snprintf.3 \ + printf.3 sprintf.3 \ + printf.3 vasprintf.3 \ + printf.3 vfprintf.3 \ + printf.3 vprintf.3 \ + printf.3 vsnprintf.3 \ + printf.3 vsprintf.3 + +MLINKS+= printf_l.3 asprintf_l.3 \ + printf_l.3 fprintf_l.3 \ + printf_l.3 snprintf_l.3 \ + printf_l.3 sprintf_l.3 \ + printf_l.3 vasprintf_l.3 \ + printf_l.3 vfprintf_l.3 \ + printf_l.3 vprintf_l.3 \ + printf_l.3 vsnprintf_l.3 \ + printf_l.3 vsprintf_l.3 + +MLINKS+= putc.3 fputc.3 \ + putc.3 putc_unlocked.3 \ + putc.3 putchar.3 \ + putc.3 putchar_unlocked.3 \ + putc.3 putw.3 + +MLINKS+= putwc.3 fputwc.3 \ + putwc.3 putwchar.3 + +MLINKS+= putwc_l.3 fputwc_l.3 \ + putwc_l.3 putwchar_l.3 + +MLINKS+= scanf.3 fscanf.3 \ + scanf.3 sscanf.3 \ + scanf.3 vfscanf.3 \ + scanf.3 vscanf.3 \ + scanf.3 vsscanf.3 + +MLINKS+= scanf_l.3 fscanf_l.3 \ + scanf_l.3 sscanf_l.3 \ + scanf_l.3 vfscanf_l.3 \ + scanf_l.3 vscanf_l.3 \ + scanf_l.3 vsscanf_l.3 + +MLINKS+= setbuf.3 setbuffer.3 \ + setbuf.3 setlinebuf.3 \ + setbuf.3 setvbuf.3 + +MLINKS+= tmpnam.3 tempnam.3 \ + tmpnam.3 tmpfile.3 + +MLINKS+= ungetwc.3 ungetwc_l.3 + +MLINKS+= wprintf.3 fwprintf.3 \ + wprintf.3 swprintf.3 \ + wprintf.3 vwprintf.3 \ + wprintf.3 vfwprintf.3 \ + wprintf.3 vswprintf.3 + +MLINKS+= wprintf_l.3 fwprintf_l.3 \ + wprintf_l.3 swprintf_l.3 \ + wprintf_l.3 vwprintf_l.3 \ + wprintf_l.3 vfwprintf_l.3 \ + wprintf_l.3 vswprintf_l.3 + +MLINKS+= wscanf.3 fwscanf.3 \ + wscanf.3 swscanf.3 \ + wscanf.3 vfwscanf.3 \ + wscanf.3 vswscanf.3 \ + wscanf.3 vwscanf.3 + +MLINKS+= wscanf_l.3 fwscanf_l.3 \ + wscanf_l.3 swscanf_l.3 \ + wscanf_l.3 vfwscanf_l.3 \ + wscanf_l.3 vswscanf_l.3 \ + wscanf_l.3 vwscanf_l.3 .endif diff --git a/stdio/_flock_stub-fbsd.c b/stdio/_flock_stub-fbsd.c new file mode 100644 index 0000000..3a73ee1 --- /dev/null +++ b/stdio/_flock_stub-fbsd.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 1998 John Birrell . + * 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 John Birrell. + * 4. 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. + * + * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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. + */ + +/* + * POSIX stdio FILE locking functions. These assume that the locking + * is only required at FILE structure level, not at file descriptor + * level too. + * + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/stdio/_flock_stub.c,v 1.14 2004/03/09 04:51:58 jb Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" + +#include "local.h" + + +/* + * Weak symbols for externally visible functions in this file: + */ +__weak_reference(_flockfile, flockfile); +__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++; + 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; + } +} + +/* + * This can be overriden by the threads library if it is linked in. + */ +void +_flockfile_debug_stub(FILE *fp, char *fname, int lineno) +{ + _flockfile(fp); +} + +int +_ftrylockfile(FILE *fp) +{ + pthread_t curthread = _pthread_self(); + int ret = 0; + + if (fp->_lock->fl_owner == curthread) + fp->_lock->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 + ret = -1; + return (ret); +} + +void +_funlockfile(FILE *fp) +{ + pthread_t curthread = _pthread_self(); + + /* + * Check if this file is owned by the current thread: + */ + if (fp->_lock->fl_owner == curthread) { + /* + * Check if this thread has locked the FILE + * more than once: + */ + if (fp->_lock->fl_count > 1) + /* + * Decrement the count of the number of + * times the running thread has locked this + * file: + */ + fp->_lock->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); + } + } +} diff --git a/stdio/asprintf-fbsd.c b/stdio/asprintf-fbsd.c new file mode 100644 index 0000000..539d2ce --- /dev/null +++ b/stdio/asprintf-fbsd.c @@ -0,0 +1,107 @@ +/* $OpenBSD: asprintf.c,v 1.8 2002/02/19 19:39:36 millert 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. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.13 2002/09/26 13:09:48 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include + +#include "local.h" + +int +asprintf(char **str, char const *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 */ + 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, ...) +{ + 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 */ + 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/clrerr-fbsd.c b/stdio/clrerr-fbsd.c new file mode 100644 index 0000000..bfac2c1 --- /dev/null +++ b/stdio/clrerr-fbsd.c @@ -0,0 +1,56 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" +#undef clearerr + +void +clearerr(fp) + FILE *fp; +{ + FLOCKFILE(fp); + __sclearerr(fp); + FUNLOCKFILE(fp); +} diff --git a/stdio/fclose-fbsd.c b/stdio/fclose-fbsd.c new file mode 100644 index 0000000..bb54156 --- /dev/null +++ b/stdio/fclose-fbsd.c @@ -0,0 +1,79 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +int +fclose(FILE *fp) +{ + int r; + + if (fp == NULL) { + errno = EFAULT; + return (EOF); + } + if (fp->_flags == 0) { /* not open! */ + errno = EBADF; + return (EOF); + } + FLOCKFILE(fp); + r = fp->_flags & __SWR ? __sflush(fp) : 0; + if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) + r = EOF; + if (fp->_flags & __SMBF) + free((char *)fp->_bf._base); + if (HASUB(fp)) + FREEUB(fp); + if (HASLB(fp)) + FREELB(fp); + fp->_file = -1; + fp->_r = fp->_w = 0; /* Mess up if reaccessed. */ + fp->_flags = 0; /* Release this FILE for reuse. */ + FUNLOCKFILE(fp); + return (r); +} diff --git a/stdio/fclose.3 b/stdio/fclose.3 new file mode 120000 index 0000000..dd8386c --- /dev/null +++ b/stdio/fclose.3 @@ -0,0 +1 @@ +./fclose.3 \ No newline at end of file diff --git a/stdio/fdopen-fbsd.c b/stdio/fdopen-fbsd.c new file mode 100644 index 0000000..15e7e8f --- /dev/null +++ b/stdio/fdopen-fbsd.c @@ -0,0 +1,93 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "local.h" + +FILE * +fdopen(fd, mode) + int fd; + const char *mode; +{ + FILE *fp; + static int nofile; + int flags, oflags, fdflags, tmp; + + if (nofile == 0) + nofile = getdtablesize(); + + if ((flags = __sflags(mode, &oflags)) == 0) + return (NULL); + + /* Make sure the mode the user wants is a subset of the actual mode. */ + if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0) + return (NULL); + tmp = fdflags & O_ACCMODE; + if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { + errno = EINVAL; + return (NULL); + } + + if ((fp = __sfp()) == NULL) + return (NULL); + fp->_flags = flags; + /* + * If opened for appending, but underlying descriptor does not have + * O_APPEND bit set, assert __SAPP so that __swrite() caller + * will _sseek() to the end before write. + */ + if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) + fp->_flags |= __SAPP; + fp->_file = fd; + fp->_cookie = fp; + fp->_read = __sread; + fp->_write = __swrite; + fp->_seek = __sseek; + fp->_close = __sclose; + return (fp); +} diff --git a/stdio/feof-fbsd.c b/stdio/feof-fbsd.c new file mode 100644 index 0000000..7c09187 --- /dev/null +++ b/stdio/feof-fbsd.c @@ -0,0 +1,59 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" + +#undef feof + +int +feof(FILE *fp) +{ + int ret; + + FLOCKFILE(fp); + ret= __sfeof(fp); + FUNLOCKFILE(fp); + return (ret); +} diff --git a/stdio/ferror-fbsd.c b/stdio/ferror-fbsd.c new file mode 100644 index 0000000..0f960f7 --- /dev/null +++ b/stdio/ferror-fbsd.c @@ -0,0 +1,59 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" + +#undef ferror + +int +ferror(FILE *fp) +{ + int ret; + + FLOCKFILE(fp); + ret = __sferror(fp); + FUNLOCKFILE(fp); + return (ret); +} diff --git a/stdio/ferror.3 b/stdio/ferror.3 new file mode 120000 index 0000000..4890b6d --- /dev/null +++ b/stdio/ferror.3 @@ -0,0 +1 @@ +./ferror.3 \ No newline at end of file diff --git a/stdio/fflush-fbsd.c b/stdio/fflush-fbsd.c new file mode 100644 index 0000000..34040cd --- /dev/null +++ b/stdio/fflush-fbsd.c @@ -0,0 +1,154 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +static int sflush_locked(FILE *); + +/* + * Flush a single file, or (if fp is NULL) all files. + * MT-safe version + */ +int +fflush(FILE *fp) +{ + int retval; + + if (fp == NULL) + return (_fwalk(sflush_locked)); + FLOCKFILE(fp); + + /* + * There is disagreement about the correct behaviour of fflush() + * when passed a file which is not open for reading. According to + * the ISO C standard, the behaviour is undefined. + * Under linux, such an fflush returns success and has no effect; + * under Windows, such an fflush is documented as behaving instead + * as fpurge(). + * Given that applications may be written with the expectation of + * either of these two behaviours, the only safe (non-astonishing) + * option is to return EBADF and ask that applications be fixed. + */ + if ((fp->_flags & (__SWR | __SRW)) == 0) { + errno = EBADF; + retval = EOF; + } else + retval = __sflush(fp); + FUNLOCKFILE(fp); + return (retval); +} + +/* + * Flush a single file, or (if fp is NULL) all files. + * Non-MT-safe version + */ +int +__fflush(FILE *fp) +{ + int retval; + + if (fp == NULL) + return (_fwalk(sflush_locked)); + if ((fp->_flags & (__SWR | __SRW)) == 0) { + errno = EBADF; + retval = EOF; + } else + retval = __sflush(fp); + return (retval); +} + +int +__sflush(FILE *fp) +{ + unsigned char *p; + int n, t; + + t = fp->_flags; + if ((t & __SWR) == 0) + return (0); + + if ((p = fp->_bf._base) == NULL) + return (0); + + n = fp->_p - p; /* write this much */ + + /* + * Set these immediately to avoid problems with longjmp and to allow + * exchange buffering (via setvbuf) in user write function. + */ + fp->_p = p; + fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size; + + for (; n > 0; n -= t, p += t) { + t = _swrite(fp, (char *)p, n); + if (t <= 0) { + /* 5340694: reset _p and _w on EAGAIN */ + if (t < 0 && errno == EAGAIN) { + if (p > fp->_p) /* some was written */ + memmove(fp->_p, p, n); + fp->_p += n; + if (!(fp->_flags & (__SLBF|__SNBF))) + fp->_w -= n; + } + fp->_flags |= __SERR; + return (EOF); + } + } + return (0); +} + +static int +sflush_locked(FILE *fp) +{ + int ret; + + FLOCKFILE(fp); + ret = __sflush(fp); + FUNLOCKFILE(fp); + return (ret); +} diff --git a/stdio/fflush.3 b/stdio/fflush.3 new file mode 120000 index 0000000..e6c2eaf --- /dev/null +++ b/stdio/fflush.3 @@ -0,0 +1 @@ +./fflush.3 \ No newline at end of file diff --git a/stdio/fgetc-fbsd.c b/stdio/fgetc-fbsd.c new file mode 100644 index 0000000..5cd8c7e --- /dev/null +++ b/stdio/fgetc-fbsd.c @@ -0,0 +1,60 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +int +fgetc(fp) + FILE *fp; +{ + int retval; + FLOCKFILE(fp); + /* Orientation set by __sgetc() when buffer is empty. */ + /* ORIENT(fp, -1); */ + retval = __sgetc(fp); + FUNLOCKFILE(fp); + return (retval); +} diff --git a/stdio/fgetln-fbsd.c b/stdio/fgetln-fbsd.c new file mode 100644 index 0000000..a1b303e --- /dev/null +++ b/stdio/fgetln-fbsd.c @@ -0,0 +1,168 @@ +/*- + * 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. + */ + +#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.10 2004/07/16 05:52:51 tjr Exp $"); + +#include "namespace.h" +#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 ((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; /* ??? */ + FUNLOCKFILE(fp); + return (NULL); /* ??? */ +} diff --git a/stdio/fgetln.3 b/stdio/fgetln.3 new file mode 120000 index 0000000..3f9ad0c --- /dev/null +++ b/stdio/fgetln.3 @@ -0,0 +1 @@ +./fgetln.3 \ No newline at end of file diff --git a/stdio/fgetpos-fbsd.c b/stdio/fgetpos-fbsd.c new file mode 100644 index 0000000..581c5c8 --- /dev/null +++ b/stdio/fgetpos-fbsd.c @@ -0,0 +1,55 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +int +fgetpos(FILE * __restrict fp, fpos_t * __restrict pos) +{ + /* + * ftello is thread-safe; no need to lock fp. + */ + if ((*pos = ftello(fp)) == (fpos_t)-1) + return (-1); + else + return (0); +} diff --git a/stdio/fgets-fbsd.c b/stdio/fgets-fbsd.c new file mode 100644 index 0000000..36ae4fd --- /dev/null +++ b/stdio/fgets-fbsd.c @@ -0,0 +1,116 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +/* + * Read at most n-1 characters from the given file. + * Stop when a newline has been read, or the count runs out. + * Return first argument, or NULL if no characters were read. + */ +char * +fgets(buf, n, fp) + char *buf; + int n; + FILE *fp; +{ + size_t len; + char *s; + unsigned char *p, *t; + + if (n <= 0) /* sanity check */ + return (NULL); + + FLOCKFILE(fp); + ORIENT(fp, -1); + s = buf; + n--; /* leave space for NUL */ + while (n != 0) { + /* + * If the buffer is empty, refill it. + */ + if ((len = fp->_r) <= 0) { + if (__srefill(fp)) { + /* EOF/error: stop with partial or no line */ + if (s == buf) { + FUNLOCKFILE(fp); + return (NULL); + } + break; + } + len = fp->_r; + } + p = fp->_p; + + /* + * Scan through at most n bytes of the current buffer, + * looking for '\n'. If found, copy up to and including + * newline, and stop. Otherwise, copy entire chunk + * and loop. + */ + if (len > n) + len = n; + t = memchr((void *)p, '\n', len); + if (t != NULL) { + len = ++t - p; + fp->_r -= len; + fp->_p = t; + (void)memcpy((void *)s, (void *)p, len); + s[len] = 0; + FUNLOCKFILE(fp); + return (buf); + } + fp->_r -= len; + fp->_p += len; + (void)memcpy((void *)s, (void *)p, len); + s += len; + n -= len; + } + *s = 0; + FUNLOCKFILE(fp); + return (buf); +} diff --git a/stdio/fgets.3 b/stdio/fgets.3 new file mode 100644 index 0000000..6c6eaeb --- /dev/null +++ b/stdio/fgets.3 @@ -0,0 +1,161 @@ +.\" 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/fgetwc-fbsd.c b/stdio/fgetwc-fbsd.c new file mode 100644 index 0000000..af3dd5f --- /dev/null +++ b/stdio/fgetwc-fbsd.c @@ -0,0 +1,114 @@ +/*- + * 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/fgetwc.c,v 1.12 2004/07/20 08:27:27 tjr Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" +#include "mblocal.h" + +/* + * MT-safe version. + */ +wint_t +fgetwc(FILE *fp) +{ + wint_t r; + + FLOCKFILE(fp); + ORIENT(fp, 1); + r = __fgetwc(fp, __current_locale()); + FUNLOCKFILE(fp); + + return (r); +} + +wint_t +fgetwc_l(FILE *fp, locale_t loc) +{ + wint_t r; + + NORMALIZE_LOCALE(loc); + FLOCKFILE(fp); + ORIENT(fp, 1); + r = __fgetwc(fp, loc); + FUNLOCKFILE(fp); + + return (r); +} + +/* + * Non-MT-safe version. + */ +wint_t +__fgetwc(FILE *fp, locale_t loc) +{ + wchar_t wc; + size_t nconv; + struct __xlocale_st_runelocale *xrl = loc->__lc_ctype; + size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict, locale_t) = xrl->__mbrtowc; + + if (fp->_r <= 0 && __srefill(fp)) + return (WEOF); + if (xrl->__mb_cur_max == 1) { + /* Fast path for single-byte encodings. */ + wc = *fp->_p++; + fp->_r--; + return (wc); + } + do { + nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_extra->mbstate, loc); + if (nconv == (size_t)-1) + break; + else if (nconv == (size_t)-2) + continue; + else if (nconv == 0) { + /* + * Assume that the only valid representation of + * the null wide character is a single null byte. + */ + fp->_p++; + fp->_r--; + return (L'\0'); + } else { + fp->_p += nconv; + fp->_r -= nconv; + return (wc); + } + } while (__srefill(fp) == 0); + fp->_flags |= __SERR; + errno = EILSEQ; + return (WEOF); +} diff --git a/stdio/fgetws-fbsd.c b/stdio/fgetws-fbsd.c new file mode 100644 index 0000000..bd64c2b --- /dev/null +++ b/stdio/fgetws-fbsd.c @@ -0,0 +1,113 @@ +/*- + * 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/fgetws.c,v 1.6 2004/10/03 15:48:32 stefanf Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" +#include "mblocal.h" + +wchar_t * +fgetws_l(wchar_t * __restrict ws, int n, FILE * __restrict fp, locale_t loc) +{ + wchar_t *wsp; + size_t nconv; + const char *src; + unsigned char *nl; + struct __xlocale_st_runelocale *rl; + size_t (*__mbsnrtowcs)(wchar_t * __restrict, const char ** __restrict, size_t, size_t, __darwin_mbstate_t * __restrict, locale_t); + + NORMALIZE_LOCALE(loc); + rl = loc->__lc_ctype; + __mbsnrtowcs = rl->__mbsnrtowcs; + FLOCKFILE(fp); + ORIENT(fp, 1); + + if (n <= 0) { + errno = EINVAL; + goto error; + } + + if (fp->_r <= 0 && __srefill(fp)) + /* EOF */ + goto error; + wsp = ws; + do { + src = (const char *)fp->_p; + 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); + if (nconv == (size_t)-1) + /* Conversion error */ + goto error; + if (src == NULL) { + /* + * We hit a null byte. Increment the character count, + * since mbsnrtowcs()'s return value doesn't include + * the terminating null, then resume conversion + * after the null. + */ + nconv++; + src = memchr(fp->_p, '\0', fp->_r); + src++; + } + fp->_r -= (unsigned char *)src - fp->_p; + fp->_p = (unsigned char *)src; + n -= nconv; + wsp += nconv; + } while (wsp[-1] != L'\n' && n > 1 && (fp->_r > 0 || + __srefill(fp) == 0)); + if (wsp == ws) + /* EOF */ + goto error; + if (!rl->__mbsinit(&fp->_extra->mbstate, loc)) + /* Incomplete character */ + goto error; + *wsp++ = L'\0'; + FUNLOCKFILE(fp); + + return (ws); + +error: + FUNLOCKFILE(fp); + return (NULL); +} + +wchar_t * +fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) +{ + return fgetws_l(ws, n, fp, __current_locale()); +} diff --git a/stdio/fgetws.3 b/stdio/fgetws.3 new file mode 100644 index 0000000..e29130c --- /dev/null +++ b/stdio/fgetws.3 @@ -0,0 +1,150 @@ +.\" 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.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 $ +.\" +.Dd August 6, 2002 +.Dt FGETWS 3 +.Os +.Sh NAME +.Nm fgetws , +.Nm fgetws_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 *" +.Fo fgetws +.Fa "wchar_t *restrict ws" +.Fa "int n" +.Fa "FILE *restrict stream" +.Fc +.In stdio.h +.In wchar.h +.In xlocale.h +.Ft "wchar_t *" +.Fo fgetws_l +.Fa "wchar_t *restrict ws" +.Fa "int n" +.Fa "FILE *restrict stream" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn fgetws +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 wide character string +.Fa ws . +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 +While the +.Fn fgetws +function uses the current locale, the +.Fn fgetws_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +Upon successful completion, +.Fn fgetws +returns +.Fa ws . +If end-of-file occurs before any characters are read, +.Fn fgetws +returns +.Dv NULL +and the buffer contents remain unchanged. +If an error occurs, +.Fn fgetws +returns +.Dv NULL +and the buffer contents are indeterminate. +The +.Fn fgetws +function +does not distinguish between end-of-file and error; +callers must use +.Xr feof 3 +and +.Xr ferror 3 +to determine which occurred. +.Sh ERRORS +The +.Fn fgetws +function will fail if: +.Bl -tag -width Er +.It Bq Er EBADF +The given +.Fa stream +argument is not a readable stream. +.It Bq Er EILSEQ +The data obtained from the input stream does not form a valid +multibyte character. +.El +.Pp +The function +.Fn fgetws +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 . +.Sh SEE ALSO +.Xr feof 3 , +.Xr ferror 3 , +.Xr fgets 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn fgetws +function +conforms to +.St -p1003.1-2001 . diff --git a/stdio/fileno-fbsd.c b/stdio/fileno-fbsd.c new file mode 100644 index 0000000..60bac45 --- /dev/null +++ b/stdio/fileno-fbsd.c @@ -0,0 +1,60 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" + +#undef fileno + +int +fileno(FILE *fp) +{ + int fd; + + FLOCKFILE(fp); + fd = __sfileno(fp); + FUNLOCKFILE(fp); + + return (fd); +} diff --git a/stdio/findfp-fbsd.c b/stdio/findfp-fbsd.c new file mode 100644 index 0000000..1c91a8e --- /dev/null +++ b/stdio/findfp-fbsd.c @@ -0,0 +1,252 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "libc_private.h" +#include "local.h" +#include "glue.h" + +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 __sFXInit {0, PTHREAD_MUTEX_INITIALIZER} + /* 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] = {__sFXInit, __sFXInit, __sFXInit}; + +/* + * 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] = { + 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]; + +struct glue __sglue = { &uglue, 3, __sF }; +static struct glue *lastglue = &uglue; + +static struct glue * moreglue(int); + +static spinlock_t thread_lock = _SPINLOCK_INITIALIZER; +#define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock) +#define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock) + +#if NOT_YET +#define SET_GLUE_PTR(ptr, val) atomic_set_rel_ptr(&(ptr), (uintptr_t)(val)) +#else +#define SET_GLUE_PTR(ptr, val) ptr = val +#endif + +static struct glue * +moreglue(n) + int n; +{ + struct glue *g; + static FILE empty; + static struct __sFILEX emptyx = __sFXInit; + FILE *p; + struct __sFILEX *fx; + + 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; + p->_extra = fx; + *p->_extra = emptyx; + p++, fx++; + } + return (g); +} + +/* + * Find a free FILE for fopen et al. + */ +FILE * +__sfp() +{ + FILE *fp; + int n; + struct glue *g; + + if (!__sdidinit) + __sinit(); + /* + * The list must be locked because a FILE may be updated. + */ + THREAD_LOCK(); + for (g = &__sglue; g != NULL; g = g->next) { + for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) + if (fp->_flags == 0) + goto found; + } + THREAD_UNLOCK(); /* don't hold lock while malloc()ing. */ + if ((g = moreglue(NDYNAMIC)) == NULL) + return (NULL); + THREAD_LOCK(); /* reacquire the lock */ + SET_GLUE_PTR(lastglue->next, g); /* atomically append glue to list */ + lastglue = g; /* not atomic; only accessed when locked */ + fp = g->iobs; +found: + fp->_flags = 1; /* reserve this slot; caller sets real flags */ + THREAD_UNLOCK(); + fp->_p = NULL; /* no current pointer */ + fp->_w = 0; /* nothing to read or write */ + fp->_r = 0; + fp->_bf._base = NULL; /* no buffer */ + fp->_bf._size = 0; + fp->_lbfsize = 0; /* not line buffered */ + fp->_file = -1; /* no file */ +/* fp->_cookie = ; */ /* caller sets cookie, _read/_write etc */ + fp->_ub._base = NULL; /* no ungetc buffer */ + fp->_ub._size = 0; + 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; + memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t)); + return (fp); +} + +/* + * XXX. Force immediate allocation of internal memory. Not used by stdio, + * but documented historically for certain applications. Bad applications. + */ +__warn_references(f_prealloc, + "warning: this program uses f_prealloc(), which is not recommended."); + +void +f_prealloc() +{ + struct glue *g; + int n; + + n = getdtablesize() - FOPEN_MAX + 20; /* 20 for slop. */ + /* + * It should be safe to walk the list without locking it; + * new nodes are only added to the end and none are ever + * removed. + */ + for (g = &__sglue; (n -= g->niobs) > 0 && g->next; g = g->next) + /* void */; + if ((n > 0) && ((g = moreglue(n)) != NULL)) { + THREAD_LOCK(); + SET_GLUE_PTR(lastglue->next, g); + lastglue = g; + THREAD_UNLOCK(); + } +} + +/* + * exit() calls _cleanup() through *__cleanup, set whenever we + * open or buffer a file. This chicanery is done so that programs + * that do not use stdio need not link it all in. + * + * The name `_cleanup' is, alas, fairly well known outside stdio. + */ +void +_cleanup() +{ + /* (void) _fwalk(fclose); */ + (void) _fwalk(__sflush); /* `cheating' */ +} + +/* + * __sinit() is called whenever stdio's internal variables must be set up. + */ +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(); +} diff --git a/stdio/flags-fbsd.c b/stdio/flags-fbsd.c new file mode 100644 index 0000000..85687f6 --- /dev/null +++ b/stdio/flags-fbsd.c @@ -0,0 +1,101 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include +#include +#include + +#include "local.h" + +/* + * Return the (stdio) flags for a given mode. Store the flags + * to be passed to an _open() syscall through *optr. + * Return 0 on error. + */ +int +__sflags(mode, optr) + const char *mode; + int *optr; +{ + int ret, m, o; + + switch (*mode++) { + + case 'r': /* open for reading */ + ret = __SRD; + m = O_RDONLY; + o = 0; + break; + + case 'w': /* open for writing */ + ret = __SWR; + m = O_WRONLY; + o = O_CREAT | O_TRUNC; + break; + + case 'a': /* open for appending */ + ret = __SWR; + m = O_WRONLY; + o = O_CREAT | O_APPEND; + break; + + default: /* illegal mode */ + errno = EINVAL; + return (0); + } + + /* [rwa]\+ or [rwa]b\+ means read and write */ + if (*mode == 'b') + mode++; + if (*mode == '+') { + ret = __SRW; + m = O_RDWR; + mode++; + if (*mode == 'b') + mode++; + } + if (*mode == 'x') + o |= O_EXCL; + *optr = m | o; + return (ret); +} diff --git a/stdio/floatio.h b/stdio/floatio.h new file mode 100644 index 0000000..83beec7 --- /dev/null +++ b/stdio/floatio.h @@ -0,0 +1,58 @@ +/*- + * 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. + * + * @(#)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 $ + */ + +/* + * Floating point scanf/printf (input/output) definitions. + */ + +/* + * MAXEXPDIG is the maximum number of decimal digits needed to store a + * floating point exponent in the largest supported format. It should + * be ceil(log10(LDBL_MAX_10_EXP)) or, if hexadecimal floating point + * conversions are supported, ceil(log10(LDBL_MAX_EXP)). But since it + * is presently never greater than 5 in practice, we fudge it. + */ +#define MAXEXPDIG 6 +#if LDBL_MAX_EXP > 999999 +#error "floating point buffers too small" +#endif + +char *__hdtoa(double, const char *, int, int *, int *, char **); +char *__hldtoa(long double, const char *, int, int *, int *, char **); +char *__ldtoa(long double *, int, int, int *, int *, char **); diff --git a/stdio/flockfile.3 b/stdio/flockfile.3 new file mode 100644 index 0000000..924b9e5 --- /dev/null +++ b/stdio/flockfile.3 @@ -0,0 +1,105 @@ +.\" Copyright (c) 2003 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. +.\" +.\" $FreeBSD: src/lib/libc/stdio/flockfile.3,v 1.3 2003/01/13 01:29:14 tjr Exp $ +.\" +.Dd January 10, 2003 +.Dt FLOCKFILE 3 +.Os +.Sh NAME +.Nm flockfile , +.Nm ftrylockfile , +.Nm funlockfile +.Nd "stdio locking functions" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft void +.Fn flockfile "FILE *file" +.Ft int +.Fn ftrylockfile "FILE *file" +.Ft void +.Fn funlockfile "FILE *file" +.Sh DESCRIPTION +These functions provide explicit application-level locking +of stdio FILE objects. +They can be used to avoid output from multiple threads being interspersed, +input being dispersed among multiple readers, and to avoid the overhead +of locking the object for each operation. +.Pp +The +.Fn flockfile +function acquires an exclusive lock on the specified object. +If another thread has already locked the object, +.Fn flockfile +will block until the lock is released. +.Pp +The +.Fn ftrylockfile +function is a non-blocking version of +.Fn flockfile ; +if the lock cannot be acquired immediately, +.Fn ftrylockfile +returns non-zero instead of blocking. +.Pp +The +.Fn funlockfile +function releases the lock on an object acquired by an earlier call to +.Fn flockfile +or +.Fn ftrylockfile . +.Pp +These functions behave as if there is a lock count associated +with each object. +Each time +.Fn flockfile +is called on the object, the count is incremented, +and each time +.Fn funlockfile +is called on the object, the count is decremented. +The lock is only actually released when the count reaches zero. +.Sh RETURN VALUES +The +.Fn flockfile +and +.Fn funlockfile +functions return no value. +.Pp +The +.Fn ftrylockfile +function +returns zero if the object was successfully locked, +non-zero otherwise. +.Sh SEE ALSO +.Xr getc_unlocked 3 , +.Xr putc_unlocked 3 +.Sh STANDARDS +The +.Fn flockfile , +.Fn ftrylockfile , +and +.Fn funlockfile +functions conform to +.St -p1003.1-2001 . diff --git a/stdio/fopen-fbsd.c b/stdio/fopen-fbsd.c new file mode 100644 index 0000000..5a043ca --- /dev/null +++ b/stdio/fopen-fbsd.c @@ -0,0 +1,88 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "local.h" + +FILE * +fopen(file, mode) + const char * __restrict file; + const char * __restrict mode; +{ + FILE *fp; + int f; + int flags, oflags; + + if ((flags = __sflags(mode, &oflags)) == 0) + return (NULL); + if ((fp = __sfp()) == NULL) + return (NULL); + if ((f = _open(file, oflags, DEFFILEMODE)) < 0) { + fp->_flags = 0; /* release */ + return (NULL); + } + fp->_file = f; + fp->_flags = flags; + fp->_cookie = fp; + fp->_read = __sread; + 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); + return (fp); +} diff --git a/stdio/fopen.3 b/stdio/fopen.3 new file mode 100644 index 0000000..0416170 --- /dev/null +++ b/stdio/fopen.3 @@ -0,0 +1,308 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd January 26, 2003 +.Dt FOPEN 3 +.Os +.Sh NAME +.Nm fdopen , +.Nm fopen , +.Nm freopen +.Nd stream open functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft FILE * +.Fo fdopen +.Fa "int fildes" +.Fa "const char *mode" +.Fc +.Ft FILE * +.Fo fopen +.Fa "const char *restrict filename" +.Fa "const char *restrict mode" +.Fc +.Ft FILE * +.Fo freopen +.Fa "const char *restrict filename" +.Fa "const char *restrict mode" +.Fa "FILE *restrict stream" +.Fc +.Sh DESCRIPTION +The +.Fn fopen +function +opens the file whose name is the string pointed to by +.Fa filename +and associates a stream with it. +.Pp +The argument +.Fa mode +points to a string beginning with one of the following +sequences (Additional characters may follow these sequences.): +.Bl -tag -width indent +.It Dq Li r +Open text file for reading. +The stream is positioned at the beginning of the file. +.It Dq Li r+ +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. +The stream is positioned at the beginning of the file. +.It Dq Li w+ +Open for reading and writing. +The file is created if it does not exist, otherwise it is truncated. +The stream is positioned at the beginning of the file. +.It Dq Li a +Open for writing. +The file is created if it does not exist. +The stream is positioned at the end of the file. +Subsequent writes to the file will always end up at the then current +end of file, irrespective of any intervening +.Xr fseek 3 +or similar. +.It Dq Li a+ +Open for reading and writing. +The file is created if it does not exist. +The stream is positioned at the end of the file. +Subsequent writes to the file will always end up at the then current +end of file, irrespective of any intervening +.Xr fseek 3 +or similar. +.El +.Pp +The +.Fa mode +string can also include the letter ``b'' either as a third character or +as a character between the characters in any of the two-character strings +described above. +This is strictly for compatibility with +.St -isoC +and has no effect; the ``b'' is ignored. +.Pp +Finally, as an extension to the standards (and thus may not be portable), +.Fa mode +string may end with the letter ``x'', which insists on creating a new file +when used with ``w'' or ``a''. +If +.Fa path +exists, then an error is returned (this is the equivalent of specifying +.Dv O_EXCL +with +.Xr open 2 ) . +.Pp +Any created files will have mode +.Pf \\*q Dv S_IRUSR +\&| +.Dv S_IWUSR +\&| +.Dv S_IRGRP +\&| +.Dv S_IWGRP +\&| +.Dv S_IROTH +\&| +.Dv S_IWOTH Ns \\*q +.Pq Li 0666 , +as modified by the process' +umask value (see +.Xr umask 2 ) . +.Pp +Reads and writes may be intermixed on read/write streams in any order, +and do not require an intermediate seek as in previous versions of +.Em stdio . +This is not portable to other systems, however; +.Tn ANSI C +requires that +a file positioning function intervene between output and input, unless +an input operation encounters end-of-file. +.Pp +The +.Fn fdopen +function associates a stream with the existing file descriptor, +.Fa fildes . +The mode +of the stream must be compatible with the mode of the file descriptor. +When the stream is closed via +.Xr fclose 3 , +.Fa fildes +is closed also. +.Pp +The +.Fn freopen +function +opens the file whose name is the string pointed to by +.Fa filename +and associates the stream pointed to by +.Fa stream +with it. +The original stream (if it exists) is closed. +The +.Fa mode +argument is used just as in the +.Fn fopen +function. +.Pp +If the +.Fa filename +argument is +.Dv NULL , +.Fn freopen +attempts to re-open the file associated with +.Fa stream +with a new mode. +The new mode must be compatible with the mode that the stream was originally +opened with: +.Bl -bullet -offset indent +.It +Streams originally opened with mode +.Dq Li r +can only be reopened with that same mode. +.It +Streams originally opened with mode +.Dq Li a +can be reopened with the same mode, or mode +.Dq Li w . +.It +Streams originally opened with mode +.Dq Li w +can be reopened with the same mode, or mode +.Dq Li a . +.It +Streams originally opened with mode +.Dq Li r+ , +.Dq Li w+ , +or +.Dq Li a+ +can be reopened with any mode. +.El +.Pp +The primary use of the +.Fn freopen +function +is to change the file associated with a +standard text stream +.Dv ( stderr , stdin , +or +.Dv stdout ) . +.Sh RETURN VALUES +Upon successful completion +.Fn fopen , +.Fn fdopen , +and +.Fn freopen +return a +.Tn FILE +pointer. +Otherwise, +.Dv NULL +is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa mode +argument +to +.Fn fopen , +.Fn fdopen , +or +.Fn freopen +was invalid. +.El +.Pp +The +.Fn fopen , +.Fn fdopen +and +.Fn freopen +functions +may also fail and set +.Va errno +for any of the errors specified for the routine +.Xr malloc 3 . +.Pp +The +.Fn fopen +function +may also fail and set +.Va errno +for any of the errors specified for the routine +.Xr open 2 . +.Pp +The +.Fn fdopen +function +may also fail and set +.Va errno +for any of the errors specified for the routine +.Xr fcntl 2 . +.Pp +The +.Fn freopen +function +may also fail and set +.Va errno +for any of the errors specified for the routines +.Xr open 2 , +.Xr fclose 3 +and +.Xr fflush 3 . +.Sh SEE ALSO +.Xr open 2 , +.Xr fclose 3 , +.Xr fileno 3 , +.Xr fseek 3 , +.Xr funopen 3 +.Sh STANDARDS +The +.Fn fopen +and +.Fn freopen +functions +conform to +.St -isoC . +The +.Fn fdopen +function +conforms to +.St -p1003.1-88 . diff --git a/stdio/fprintf-fbsd.c b/stdio/fprintf-fbsd.c new file mode 100644 index 0000000..9b9cdd4 --- /dev/null +++ b/stdio/fprintf-fbsd.c @@ -0,0 +1,71 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include + +int +fprintf(FILE * __restrict fp, const char * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf_l(fp, __current_locale(), fmt, ap); + va_end(ap); + return (ret); +} + +int +fprintf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt, ...) +{ + int ret; + va_list ap; + + /* no need to call NORMALIZE_LOCALE(loc), because vfprintf_l will */ + va_start(ap, fmt); + ret = vfprintf_l(fp, loc, fmt, ap); + va_end(ap); + return (ret); +} diff --git a/stdio/fpurge-fbsd.c b/stdio/fpurge-fbsd.c new file mode 100644 index 0000000..f191843 --- /dev/null +++ b/stdio/fpurge-fbsd.c @@ -0,0 +1,74 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +/* + * fpurge: like fflush, but without writing anything: leave the + * given FILE's buffer empty. + */ +int +fpurge(fp) + FILE *fp; +{ + int retval; + FLOCKFILE(fp); + if (!fp->_flags) { + errno = EBADF; + retval = EOF; + } else { + if (HASUB(fp)) + FREEUB(fp); + fp->_p = fp->_bf._base; + fp->_r = 0; + fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size; + retval = 0; + } + FUNLOCKFILE(fp); + return (retval); +} diff --git a/stdio/fputc-fbsd.c b/stdio/fputc-fbsd.c new file mode 100644 index 0000000..a10af2b --- /dev/null +++ b/stdio/fputc-fbsd.c @@ -0,0 +1,61 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +int +fputc(c, fp) + int c; + FILE *fp; +{ + int retval; + FLOCKFILE(fp); + /* Orientation set by __sputc() when buffer is full. */ + /* ORIENT(fp, -1); */ + retval = __sputc(c, fp); + FUNLOCKFILE(fp); + return (retval); +} diff --git a/stdio/fputs-fbsd.c b/stdio/fputs-fbsd.c new file mode 100644 index 0000000..5e99ef4 --- /dev/null +++ b/stdio/fputs-fbsd.c @@ -0,0 +1,82 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "fvwrite.h" +#include "libc_private.h" +#include "local.h" + +// 3340719: __puts_null__ is used if string is NULL. Defined in puts.c +__private_extern__ char const __puts_null__[]; + +/* + * Write the given string to the given file. + */ +int +fputs(s, fp) + const char * __restrict s; + FILE * __restrict fp; +{ + int retval; + struct __suio uio; + struct __siov iov; + + // 3340719: __puts_null__ is used if s is NULL + if(s == NULL) + s = __puts_null__; + iov.iov_base = (void *)s; + iov.iov_len = uio.uio_resid = strlen(s); + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + FLOCKFILE(fp); + ORIENT(fp, -1); + retval = __sfvwrite(fp, &uio); + FUNLOCKFILE(fp); +#if __DARWIN_UNIX03 + if (retval == 0) + return iov.iov_len; +#endif /* __DARWIN_UNIX03 */ + return (retval); +} diff --git a/stdio/fputs.3 b/stdio/fputs.3 new file mode 100644 index 0000000..1c1eb7f --- /dev/null +++ b/stdio/fputs.3 @@ -0,0 +1,134 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt FPUTS 3 +.Os +.Sh NAME +.Nm fputs , +.Nm puts +.Nd output a line to a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft int +.Fo fputs +.Fa "const char *restrict s" +.Fa "FILE *restrict stream" +.Fc +.Ft int +.Fo puts +.Fa "const char *s" +.Fc +.Sh DESCRIPTION +The function +.Fn fputs +writes the string pointed to by +.Fa s +to the stream pointed to by +.Fa stream . +.\" The terminating +.\" .Dv NUL +.\" character is not written. +.Pp +The function +.Fn puts +writes the string +.Fa s , +and a terminating newline character, +to the stream +.Dv stdout . +.Sh RETURN VALUES +The +.Fn fputs +function +returns 0 on success and +.Dv EOF +on error; +.Fn puts +returns a nonnegative integer on success and +.Dv EOF +on error. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa stream +argument +is not a writable stream. +.El +.Pp +The functions +.Fn fputs +and +.Fn puts +may also fail and set +.Va errno +for any of the errors specified for the routines +.Xr write 2 . +.Sh COMPATIBILITY +.Fn fputs +now returns a non-negative number (as opposed to 0) +on successful completion. +As a result, many tests (e.g., "fputs() == 0", "fputs() != 0") +do not give the desired result. +Use "fputs() != EOF" or "fputs() == EOF" +to determine success or failure. +.Sh SEE ALSO +.Xr ferror 3 , +.Xr fputws 3 , +.Xr putc 3 , +.Xr stdio 3 +.Sh STANDARDS +The functions +.Fn fputs +and +.Fn puts +conform to +.St -isoC . +While not mentioned in the standard, both +.Fn fputs +and +.Fn puts +print +.Ql (null) +if +.Fa str +is +.Dv NULL . diff --git a/stdio/fputwc-fbsd.c b/stdio/fputwc-fbsd.c new file mode 100644 index 0000000..df646f8 --- /dev/null +++ b/stdio/fputwc-fbsd.c @@ -0,0 +1,104 @@ +/*- + * 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/fputwc.c,v 1.10 2004/07/20 08:27:27 tjr Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" +#include "mblocal.h" + +/* + * Non-MT-safe version. + */ +__private_extern__ wint_t +__fputwc(wchar_t wc, FILE *fp, locale_t loc) +{ + char buf[MB_LEN_MAX]; + size_t i, len; + struct __xlocale_st_runelocale *xrl = loc->__lc_ctype; + + if (xrl->__mb_cur_max == 1 && wc > 0 && wc <= UCHAR_MAX) { + /* + * Assume single-byte locale with no special encoding. + * A more careful test would be to check + * _CurrentRuneLocale->encoding. + */ + *buf = (unsigned char)wc; + len = 1; + } else { + if ((len = xrl->__wcrtomb(buf, wc, &fp->_extra->mbstate, loc)) == + (size_t)-1) { + fp->_flags |= __SERR; + return (WEOF); + } + } + + for (i = 0; i < len; i++) + if (__sputc((unsigned char)buf[i], fp) == EOF) + return (WEOF); + + return ((wint_t)wc); +} + +/* + * MT-safe version. + */ +wint_t +fputwc(wchar_t wc, FILE *fp) +{ + wint_t r; + + FLOCKFILE(fp); + ORIENT(fp, 1); + r = __fputwc(wc, fp, __current_locale()); + FUNLOCKFILE(fp); + + return (r); +} + +wint_t +fputwc_l(wchar_t wc, FILE *fp, locale_t loc) +{ + wint_t r; + + NORMALIZE_LOCALE(loc); + FLOCKFILE(fp); + ORIENT(fp, 1); + r = __fputwc(wc, fp, loc); + FUNLOCKFILE(fp); + + return (r); +} diff --git a/stdio/fputws-fbsd.c b/stdio/fputws-fbsd.c new file mode 100644 index 0000000..e299065 --- /dev/null +++ b/stdio/fputws-fbsd.c @@ -0,0 +1,83 @@ +/*- + * 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/fputws.c,v 1.6 2004/07/21 10:54:57 tjr Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "fvwrite.h" +#include "libc_private.h" +#include "local.h" +#include "mblocal.h" + +int +fputws_l(const wchar_t * __restrict ws, FILE * __restrict fp, locale_t loc) +{ + size_t nbytes; + char buf[BUFSIZ]; + struct __suio uio; + struct __siov iov; + size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict, locale_t); + + NORMALIZE_LOCALE(loc); + __wcsnrtombs = loc->__lc_ctype->__wcsnrtombs; + FLOCKFILE(fp); + ORIENT(fp, 1); + if (prepwrite(fp) != 0) + goto error; + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + iov.iov_base = buf; + do { + nbytes = __wcsnrtombs(buf, &ws, SIZE_T_MAX, sizeof(buf), + &fp->_extra->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); + FUNLOCKFILE(fp); + return (0); + +error: + FUNLOCKFILE(fp); + return (-1); +} + +int +fputws(const wchar_t * __restrict ws, FILE * __restrict fp) +{ + return fputws_l(ws, fp, __current_locale()); +} diff --git a/stdio/fputws.3 b/stdio/fputws.3 new file mode 100644 index 0000000..3882b1b --- /dev/null +++ b/stdio/fputws.3 @@ -0,0 +1,114 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 6, 2002 +.Dt FPUTWS 3 +.Os +.Sh NAME +.Nm fputws , +.Nm fputws_l +.Nd output a line of wide characters to a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft int +.Fo fputws +.Fa "const wchar_t *restrict ws" +.Fa "FILE *restrict stream" +.Fc +.In stdio.h +.In wchar.h +.In xlocale.h +.Ft int +.Fo fputws_l +.Fa "const wchar_t *restrict ws" +.Fa "FILE *restrict stream" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn fputws +function writes the wide character string pointed to by +.Fa ws +to the stream pointed to by +.Fa stream . +.Pp +Although the +.Fn fputws +function uses the current locale, the +.Fn fputws_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn fputws +function +returns 0 on success and \-1 on error. +.Sh ERRORS +The +.Fn fputws +function will fail if: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa stream +argument supplied +is not a writable stream. +.El +.Pp +The +.Fn fputws +function may also fail and set +.Va errno +for any of the errors specified for the routine +.Xr write 2 . +.Sh SEE ALSO +.Xr ferror 3 , +.Xr fputs 3 , +.Xr putwc 3 , +.Xr stdio 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn fputws +function conforms to +.St -p1003.1-2001 . diff --git a/stdio/fread-fbsd.c b/stdio/fread-fbsd.c new file mode 100644 index 0000000..ad5d81b --- /dev/null +++ b/stdio/fread-fbsd.c @@ -0,0 +1,91 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +size_t +fread(buf, size, count, fp) + void * __restrict buf; + size_t size, count; + FILE * __restrict fp; +{ + size_t resid; + char *p; + int r; + 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. + */ + if ((resid = count * size) == 0) + return (0); + FLOCKFILE(fp); + ORIENT(fp, -1); + if (fp->_r < 0) + fp->_r = 0; + total = resid; + p = buf; + while (resid > (r = fp->_r)) { + (void)memcpy((void *)p, (void *)fp->_p, (size_t)r); + fp->_p += r; + /* fp->_r = 0 ... done in __srefill */ + p += r; + 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/fread.3 b/stdio/fread.3 new file mode 100644 index 0000000..ffebed6 --- /dev/null +++ b/stdio/fread.3 @@ -0,0 +1,111 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd March 8, 1994 +.Dt FREAD 3 +.Os +.Sh NAME +.Nm fread , +.Nm fwrite +.Nd binary stream input/output +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft size_t +.Fn fread "void *restrict ptr" "size_t size" "size_t nitems" \ + "FILE *restrict stream" +.Ft size_t +.Fn fwrite "const void *restrict ptr" "size_t size" "size_t nitems" \ + "FILE *restrict stream" +.Sh DESCRIPTION +The function +.Fn fread +reads +.Fa nitems +objects, each +.Fa size +bytes long, from the stream pointed to by +.Fa stream , +storing them at the location given by +.Fa ptr . +.Pp +The function +.Fn fwrite +writes +.Fa nitems +objects, each +.Fa size +bytes long, to the stream pointed to by +.Fa stream , +obtaining them from the location given by +.Fa ptr . +.Sh RETURN VALUES +The functions +.Fn fread +and +.Fn fwrite +advance the file position indicator for the stream +by the number of bytes read or written. +They return the number of objects read or written. +If an error occurs, or the end-of-file is reached, +the return value is a short object count (or zero). +.Pp +The function +.Fn fread +does not distinguish between end-of-file and error; callers +must use +.Xr feof 3 +and +.Xr ferror 3 +to determine which occurred. +The function +.Fn fwrite +returns a value less than +.Fa nitems +only if a write error has occurred. +.Sh SEE ALSO +.Xr read 2 , +.Xr write 2 +.Sh STANDARDS +The functions +.Fn fread +and +.Fn fwrite +conform to +.St -isoC . diff --git a/stdio/freopen-fbsd.c b/stdio/freopen-fbsd.c new file mode 100644 index 0000000..74dbc35 --- /dev/null +++ b/stdio/freopen-fbsd.c @@ -0,0 +1,230 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * Re-direct an existing, open (probably) file to some other file. + * ANSI is written such that the original file gets closed if at + * all possible, no matter what. + */ +FILE * +freopen(file, mode, fp) + const char * __restrict file; + const char * __restrict mode; + FILE *fp; +{ + int f; + int dflags, flags, isopen, oflags, sverrno, wantfd; + + if ((flags = __sflags(mode, &oflags)) == 0) { + (void) fclose(fp); + return (NULL); + } + + FLOCKFILE(fp); + + if (!__sdidinit) + __sinit(); + + /* + * If the filename is a NULL pointer, the caller is asking us to + * re-open the same file with a different mode. We allow this only + * if the modes are compatible. + */ + if (file == NULL) { + /* See comment below regarding freopen() of closed files. */ + if (fp->_flags == 0) { + FUNLOCKFILE(fp); + errno = EINVAL; + return (NULL); + } + if ((dflags = _fcntl(fp->_file, F_GETFL)) < 0) { + sverrno = errno; + fclose(fp); + FUNLOCKFILE(fp); + errno = sverrno; + return (NULL); + } + if ((dflags & O_ACCMODE) != O_RDWR && (dflags & O_ACCMODE) != + (oflags & O_ACCMODE)) { + fclose(fp); + FUNLOCKFILE(fp); + errno = EBADF; + return (NULL); + } + if ((oflags ^ dflags) & O_APPEND) { + dflags &= ~O_APPEND; + dflags |= oflags & O_APPEND; + if (_fcntl(fp->_file, F_SETFL, dflags) < 0) { + sverrno = errno; + fclose(fp); + FUNLOCKFILE(fp); + errno = sverrno; + return (NULL); + } + } + 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); + } + f = fp->_file; + isopen = 0; + wantfd = -1; + goto finish; + } + + /* + * There are actually programs that depend on being able to "freopen" + * descriptors that weren't originally open. Keep this from breaking. + * Remember whether the stream was open to begin with, and which file + * 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. + * + * For UNIX03, we always close if it was open. + */ + if (fp->_flags == 0) { + fp->_flags = __SEOF; /* hold on to it */ + isopen = 0; + wantfd = -1; + } else { + /* flush the stream; ANSI doesn't require this. */ + if (fp->_flags & __SWR) + (void) __sflush(fp); + /* if close is NULL, closing is a no-op, hence pointless */ +#if __DARWIN_UNIX03 + if (fp->_close) + (void) (*fp->_close)(fp->_cookie); + isopen = 0; + wantfd = -1; +#else /* !__DARWIN_UNIX03 */ + isopen = fp->_close != NULL; + if ((wantfd = fp->_file) < 0 && isopen) { + (void) (*fp->_close)(fp->_cookie); + isopen = 0; + } +#endif /* __DARWIN_UNIX03 */ + } + + /* Get a new descriptor to refer to the new file. */ + f = _open(file, oflags, DEFFILEMODE); + if (f < 0 && isopen) { + /* If out of fd's close the old one and try again. */ + if (errno == ENFILE || errno == EMFILE) { + (void) (*fp->_close)(fp->_cookie); + isopen = 0; + f = _open(file, oflags, DEFFILEMODE); + } + } + sverrno = errno; + +finish: + /* + * Finish closing fp. Even if the open succeeded above, we cannot + * keep fp->_base: it may be the wrong size. This loses the effect + * of any setbuffer calls, but stdio has always done this before. + */ + if (isopen) + (void) (*fp->_close)(fp->_cookie); + if (fp->_flags & __SMBF) + free((char *)fp->_bf._base); + fp->_w = 0; + fp->_r = 0; + fp->_p = NULL; + fp->_bf._base = NULL; + fp->_bf._size = 0; + fp->_lbfsize = 0; + if (HASUB(fp)) + FREEUB(fp); + fp->_ub._size = 0; + if (HASLB(fp)) + FREELB(fp); + fp->_lb._size = 0; + fp->_extra->orientation = 0; + memset(&fp->_extra->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); + return (NULL); + } + + /* + * If reopening something that was open before on a real file, try + * to maintain the descriptor. Various C library routines (perror) + * assume stderr is always fd STDERR_FILENO, even if being freopen'd. + */ + if (wantfd >= 0 && f != wantfd) { + if (_dup2(f, wantfd) >= 0) { + (void)_close(f); + f = wantfd; + } + } + + fp->_flags = flags; + fp->_file = f; + fp->_cookie = fp; + fp->_read = __sread; + fp->_write = __swrite; + fp->_seek = __sseek; + fp->_close = __sclose; + FUNLOCKFILE(fp); + return (fp); +} diff --git a/stdio/fscanf-fbsd.c b/stdio/fscanf-fbsd.c new file mode 100644 index 0000000..3bf8252 --- /dev/null +++ b/stdio/fscanf-fbsd.c @@ -0,0 +1,79 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +int +fscanf(FILE * __restrict fp, char const * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + FLOCKFILE(fp); + ret = __svfscanf_l(fp, __current_locale(), fmt, ap); + va_end(ap); + FUNLOCKFILE(fp); + return (ret); +} + +int +fscanf_l(FILE * __restrict fp, locale_t loc, char const * __restrict fmt, ...) +{ + int ret; + va_list ap; + + NORMALIZE_LOCALE(loc); + va_start(ap, fmt); + FLOCKFILE(fp); + ret = __svfscanf_l(fp, loc, fmt, ap); + va_end(ap); + FUNLOCKFILE(fp); + return (ret); +} diff --git a/stdio/fseek-fbsd.c b/stdio/fseek-fbsd.c new file mode 100644 index 0000000..e6a5bd6 --- /dev/null +++ b/stdio/fseek-fbsd.c @@ -0,0 +1,314 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +#define POS_ERR (-(fpos_t)1) + +int +fseek(fp, offset, whence) + FILE *fp; + long offset; + int whence; +{ + int ret; + int serrno = errno; + + /* make sure stdio is set up */ + if (!__sdidinit) + __sinit(); + + FLOCKFILE(fp); + ret = _fseeko(fp, (off_t)offset, whence, 1); + FUNLOCKFILE(fp); + if (ret == 0) + errno = serrno; + return (ret); +} + +int +fseeko(fp, offset, whence) + FILE *fp; + off_t offset; + int whence; +{ + int ret; + int serrno = errno; + + /* make sure stdio is set up */ + if (!__sdidinit) + __sinit(); + + FLOCKFILE(fp); + ret = _fseeko(fp, offset, whence, 0); + FUNLOCKFILE(fp); + if (ret == 0) + errno = serrno; + return (ret); +} + +/* + * Seek the given file to the given offset. + * `Whence' must be one of the three SEEK_* macros. + */ +int +_fseeko(fp, offset, whence, ltest) + FILE *fp; + off_t offset; + int whence; + int ltest; +{ + fpos_t (*seekfn)(void *, fpos_t, int); + fpos_t target, curoff, ret; + size_t n; + struct stat st; + int havepos; + + /* + * Have to be able to seek. + */ + if ((seekfn = fp->_seek) == NULL) { + errno = ESPIPE; /* historic practice */ + return (-1); + } + + /* + * Change any SEEK_CUR to SEEK_SET, and check `whence' argument. + * After this, whence is either SEEK_SET or SEEK_END. + */ + switch (whence) { + + case SEEK_CUR: + /* + * In order to seek relative to the current stream offset, + * we have to first find the current stream offset via + * ftell (see ftell for details). + */ + if (_ftello(fp, &curoff)) + return (-1); + if (curoff < 0) { + /* Unspecified position because of ungetc() at 0 */ + errno = ESPIPE; + return (-1); + } + if (offset > 0 && curoff > OFF_MAX - offset) { + errno = EOVERFLOW; + return (-1); + } + offset += curoff; + if (offset < 0) { + errno = EINVAL; + return (-1); + } + if (ltest && offset > LONG_MAX) { + errno = EOVERFLOW; + return (-1); + } + whence = SEEK_SET; + havepos = 1; + break; + + case SEEK_SET: + if (offset < 0) { + errno = EINVAL; + return (-1); + } + case SEEK_END: + curoff = 0; /* XXX just to keep gcc quiet */ + havepos = 0; + break; + + default: + errno = EINVAL; + return (-1); + } + + /* + * Can only optimise if: + * reading (and not reading-and-writing); + * not unbuffered; and + * this is a `regular' Unix file (and hence seekfn==__sseek). + * We must check __NBF first, because it is possible to have __NBF + * and __SOPT both set. + */ + if (fp->_bf._base == NULL) + __smakebuf(fp); + if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT)) + goto dumb; + if ((fp->_flags & __SOPT) == 0) { + if (seekfn != __sseek || + fp->_file < 0 || _fstat(fp->_file, &st) || + (st.st_mode & S_IFMT) != S_IFREG) { + fp->_flags |= __SNPT; + goto dumb; + } + fp->_blksize = st.st_blksize; + fp->_flags |= __SOPT; + } + + /* + * We are reading; we can try to optimise. + * Figure out where we are going and where we are now. + */ + if (whence == SEEK_SET) + target = offset; + else { + if (_fstat(fp->_file, &st)) + goto dumb; + if (offset > 0 && st.st_size > OFF_MAX - offset) { + errno = EOVERFLOW; + return (-1); + } + target = st.st_size + offset; + if ((off_t)target < 0) { + errno = EINVAL; + return (-1); + } + if (ltest && (off_t)target > LONG_MAX) { + errno = EOVERFLOW; + return (-1); + } + } + + if (!havepos && _ftello(fp, &curoff)) + goto dumb; + + /* + * (If the buffer was modified, we have to + * skip this; see fgetln.c.) + */ + if (fp->_flags & __SMOD) + goto abspos; + + /* + * Compute the number of bytes in the input buffer (pretending + * that any ungetc() input has been discarded). Adjust current + * offset backwards by this count so that it represents the + * file offset for the first byte in the current input buffer. + */ + if (HASUB(fp)) { + curoff += fp->_r; /* kill off ungetc */ + n = fp->_extra->_up - fp->_bf._base; + curoff -= n; + n += fp->_ur; + } else { + n = fp->_p - fp->_bf._base; + curoff -= n; + n += fp->_r; + } + + /* + * If the target offset is within the current buffer, + * simply adjust the pointers, clear EOF, undo ungetc(), + * and return. + */ + if (target >= curoff && target < curoff + n) { + size_t o = target - curoff; + + fp->_p = fp->_bf._base + o; + fp->_r = n - o; + if (HASUB(fp)) + FREEUB(fp); + fp->_flags &= ~__SEOF; + memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t)); + return (0); + } + +abspos: + /* + * The place we want to get to is not within the current buffer, + * but we can still be kind to the kernel copyout mechanism. + * By aligning the file offset to a block boundary, we can let + * the kernel use the VM hardware to map pages instead of + * copying bytes laboriously. Using a block boundary also + * ensures that we only read one block, rather than two. + */ + curoff = target & ~(fp->_blksize - 1); + if (_sseek(fp, curoff, SEEK_SET) == POS_ERR) + goto dumb; + fp->_r = 0; + fp->_p = fp->_bf._base; + if (HASUB(fp)) + FREEUB(fp); + n = target - curoff; + if (n) { + if (__srefill(fp) || fp->_r < n) + goto dumb; + fp->_p += n; + fp->_r -= n; + } + fp->_flags &= ~__SEOF; + return (0); + + /* + * We get here if we cannot optimise the seek ... just + * do it. Allow the seek function to change fp->_bf._base. + */ +dumb: + if (__sflush(fp) || + (ret = _sseek(fp, (fpos_t)offset, whence)) == POS_ERR) + return (-1); + /* success: clear EOF indicator and discard ungetc() data */ + if (HASUB(fp)) + FREEUB(fp); + fp->_p = fp->_bf._base; + 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); + } + return (0); +} diff --git a/stdio/fseek.3 b/stdio/fseek.3 new file mode 100644 index 0000000..5c46469 --- /dev/null +++ b/stdio/fseek.3 @@ -0,0 +1,308 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd March 19, 2004 +.Dt FSEEK 3 +.Os +.Sh NAME +.Nm fgetpos , +.Nm fseek , +.Nm fseeko , +.Nm fsetpos , +.Nm ftell , +.Nm ftello , +.Nm rewind +.Nd reposition a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft int +.Fo fgetpos +.Fa "FILE *restrict stream" +.Fa "fpos_t *restrict pos" +.Fc +.Ft int +.Fo fseek +.Fa "FILE *stream" +.Fa "long offset" +.Fa "int whence" +.Fc +.Ft int +.Fo fseeko +.Fa "FILE *stream" +.Fa "off_t offset" +.Fa "int whence" +.Fc +.Ft int +.Fo fsetpos +.Fa "FILE *stream" +.Fa "const fpos_t *pos" +.Fc +.Ft long +.Fo ftell +.Fa "FILE *stream" +.Fc +.Ft off_t +.Fo ftello +.Fa "FILE *stream" +.Fc +.Ft void +.Fo rewind +.Fa "FILE *stream" +.Fc +.Sh DESCRIPTION +The +.Fn fseek +function sets the file position indicator for the stream pointed +to by +.Fa stream . +The new position, measured in bytes, is obtained by adding +.Fa offset +bytes to the position specified by +.Fa whence . +If +.Fa whence +is set to +.Dv SEEK_SET , +.Dv SEEK_CUR , +or +.Dv SEEK_END , +the offset is relative to the +start of the file, the current position indicator, or end-of-file, +respectively. +A successful call to the +.Fn fseek +function clears the end-of-file indicator for the stream and undoes +any effects of the +.Xr ungetc 3 +and +.Xr ungetwc 3 +functions on the same stream. +.Pp +The +.Fn ftell +function +obtains the current value of the file position indicator for the +stream pointed to by +.Fa stream . +.Pp +The +.Fn rewind +function sets the file position indicator for the stream pointed +to by +.Fa stream +to the beginning of the file. +It is equivalent to: +.Pp +.Dl (void)fseek(stream, 0L, SEEK_SET) +.Pp +except that the error indicator for the stream is also cleared +(see +.Xr clearerr 3 ) . +.Pp +Since +.Fn rewind +does not return a value, +an application wishing to detect errors should clear +.Va errno , +then call +.Fn rewind , +and if +.Va errno +is non-zero, assume an error has occurred. +.Pp +The +.Fn fseeko +function is identical to +.Fn fseek , +except it takes an +.Fa off_t +argument +instead of a +.Fa long . +Likewise, the +.Fn ftello +function is identical to +.Fn ftell , +except it returns an +.Fa off_t . +.Pp +The +.Fn fgetpos +and +.Fn fsetpos +functions +are alternate interfaces for retrieving and setting the current position in +the file, similar to +.Fn ftell +and +.Fn fseek , +except that the current position is stored in an opaque object of +type +.Vt fpos_t +pointed to by +.Fa pos . +These functions provide a portable way to seek to offsets larger than +those that can be represented by a +.Vt long int . +They may also store additional state information in the +.Vt fpos_t +object to facilitate seeking within files containing multibyte +characters with state-dependent encodings. +Although +.Vt fpos_t +has traditionally been an integral type, +applications cannot assume that it is; +in particular, they must not perform arithmetic on objects +of this type. +.Pp +If the stream is a wide character stream (see +.Xr fwide 3 ) , +the position specified by the combination of +.Fa offset +and +.Fa whence +must contain the first byte of a multibyte sequence. +.Sh RETURN VALUES +The +.Fn rewind +function +returns no value. +.Pp +.Rv -std fgetpos fseek fseeko fsetpos +.Pp +Upon successful completion, +.Fn ftell +and +.Fn ftello +return the current offset. +Otherwise, \-1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa stream +argument +is not a seekable stream. +.It Bq Er EINVAL +The +.Fa whence +argument is invalid or +the resulting file-position +indicator would be set to a negative value. +.It Bq Er EOVERFLOW +The resulting file offset would be a value which +cannot be represented correctly in an object of type +.Fa off_t +for +.Fn fseeko +and +.Fn ftello +or +.Fa long +for +.Fn fseek +and +.Fn ftell . +.It Bq Er ESPIPE +The file descriptor underlying stream is associated with a pipe or FIFO +or file-position indicator value is unspecified +(see +.Xr ungetc 3 ) . +.El +.Pp +The functions +.Fn fgetpos , +.Fn fseek , +.Fn fseeko , +.Fn fsetpos , +.Fn ftell , +and +.Fn ftello +may also fail and set +.Va errno +for any of the errors specified for the routines +.Xr fflush 3 , +.Xr fstat 2 , +.Xr lseek 2 , +and +.Xr malloc 3 . +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +.Ft int +.br +.Fo fseeko +.Fa "FILE *stream" +.Fa "off_t offset" +.Fa "int whence" +.Fc ; +.Pp +The include file +.In sys/types.h +supplies the definition for +.Vt off_t . +.Sh SEE ALSO +.Xr lseek 2 , +.Xr clearerr 3 , +.Xr fwide 3 , +.Xr ungetc 3 , +.Xr ungetwc 3 , +.Xr compat 5 +.Sh STANDARDS +The +.Fn fgetpos , +.Fn fsetpos , +.Fn fseek , +.Fn ftell , +and +.Fn rewind +functions +conform to +.St -isoC . +.Pp +The +.Fn fseeko +and +.Fn ftello +functions conform to +.St -p1003.1-2001 . diff --git a/stdio/fsetpos-fbsd.c b/stdio/fsetpos-fbsd.c new file mode 100644 index 0000000..6d75acd --- /dev/null +++ b/stdio/fsetpos-fbsd.c @@ -0,0 +1,55 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include + +/* + * fsetpos: like fseek. + */ +int +fsetpos(iop, pos) + FILE *iop; + const fpos_t *pos; +{ + return (fseeko(iop, (off_t)*pos, SEEK_SET)); +} diff --git a/stdio/ftell-fbsd.c b/stdio/ftell-fbsd.c new file mode 100644 index 0000000..4c80885 --- /dev/null +++ b/stdio/ftell-fbsd.c @@ -0,0 +1,145 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +/* + * standard ftell function. + */ +long +ftell(fp) + FILE *fp; +{ + off_t rv; + + rv = ftello(fp); + if (rv > LONG_MAX) { + errno = EOVERFLOW; + return (-1); + } + return (rv); +} + +/* + * ftello: return current offset. + */ +off_t +ftello(fp) + FILE *fp; +{ + fpos_t rv; + int ret; + + FLOCKFILE(fp); + ret = _ftello(fp, &rv); + FUNLOCKFILE(fp); + if (ret) + return (-1); + if (rv < 0) { /* Unspecified value because of ungetc() at 0 */ + errno = ESPIPE; + return (-1); + } + return (rv); +} + +int +_ftello(fp, offset) + FILE *fp; + fpos_t *offset; +{ + fpos_t pos; + size_t n; + + if (fp->_seek == NULL) { + errno = ESPIPE; /* historic practice */ + return (1); + } + + /* + * Find offset of underlying I/O object, then + * adjust for buffered bytes. + */ + if (__sflush(fp)) /* may adjust seek offset on append stream */ + return (1); + if (fp->_flags & __SOFF) + pos = fp->_offset; + else { + pos = _sseek(fp, (fpos_t)0, SEEK_CUR); + if (pos == -1) + return (1); + } + if (fp->_flags & __SRD) { + /* + * Reading. Any unread characters (including + * those from ungetc) cause the position to be + * smaller than that in the underlying object. + */ + if ((pos -= (HASUB(fp) ? fp->_ur : fp->_r)) < 0) { + fp->_flags |= __SERR; + errno = EIO; + return (1); + } + if (HASUB(fp)) + pos -= fp->_r; /* Can be negative at this point. */ + } else if ((fp->_flags & __SWR) && fp->_p != NULL) { + /* + * Writing. Any buffered characters cause the + * position to be greater than that in the + * underlying object. + */ + n = fp->_p - fp->_bf._base; + if (pos > OFF_MAX - n) { + errno = EOVERFLOW; + return (1); + } + pos += n; + } + *offset = pos; + return (0); +} diff --git a/stdio/funopen-fbsd.c b/stdio/funopen-fbsd.c new file mode 100644 index 0000000..040c806 --- /dev/null +++ b/stdio/funopen-fbsd.c @@ -0,0 +1,80 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include + +#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)(); +{ + FILE *fp; + int flags; + + if (readfn == NULL) { + if (writefn == NULL) { /* illegal */ + errno = EINVAL; + return (NULL); + } else + flags = __SWR; /* write only */ + } else { + if (writefn == NULL) + flags = __SRD; /* read only */ + else + flags = __SRW; /* read-write */ + } + if ((fp = __sfp()) == NULL) + return (NULL); + fp->_flags = flags; + fp->_file = -1; + fp->_cookie = (void *)cookie; + fp->_read = readfn; + fp->_write = writefn; + fp->_seek = seekfn; + fp->_close = closefn; + return (fp); +} diff --git a/stdio/funopen.3 b/stdio/funopen.3 new file mode 120000 index 0000000..0d1067a --- /dev/null +++ b/stdio/funopen.3 @@ -0,0 +1 @@ +./funopen.3 \ No newline at end of file diff --git a/stdio/fvwrite-fbsd.c b/stdio/fvwrite-fbsd.c new file mode 100644 index 0000000..fd12da1 --- /dev/null +++ b/stdio/fvwrite-fbsd.c @@ -0,0 +1,211 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include +#include +#include "local.h" +#include "fvwrite.h" + +/* + * Write some memory regions. Return zero on success, EOF on error. + * + * This routine is large and unsightly, but most of the ugliness due + * to the three different kinds of output buffering is handled here. + */ +int +__sfvwrite(fp, uio) + FILE *fp; + struct __suio *uio; +{ + size_t len; + char *p; + struct __siov *iov; + int w, s; + char *nl; + int nlknown, nldist; + + if ((len = uio->uio_resid) == 0) + return (0); + /* make sure we can write */ + if (prepwrite(fp) != 0) + return (EOF); + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n)) + + iov = uio->uio_iov; + p = iov->iov_base; + len = iov->iov_len; + iov++; +#define GETIOV(extra_work) \ + while (len == 0) { \ + extra_work; \ + p = iov->iov_base; \ + len = iov->iov_len; \ + iov++; \ + } + if (fp->_flags & __SNBF) { + /* + * Unbuffered: write up to BUFSIZ bytes at a time. + */ + do { + GETIOV(;); + w = _swrite(fp, p, MIN(len, BUFSIZ)); + if (w <= 0) + goto err; + p += w; + len -= w; + } while ((uio->uio_resid -= w) != 0); + } else if ((fp->_flags & __SLBF) == 0) { + /* + * Fully buffered: fill partially full buffer, if any, + * and then flush. If there is no partial buffer, write + * one _bf._size byte chunk directly (without copying). + * + * String output is a special case: write as many bytes + * as fit, but pretend we wrote everything. This makes + * snprintf() return the number of bytes needed, rather + * than the number used, and avoids its write function + * (so that the write function can be invalid). + */ + do { + GETIOV(;); + if ((fp->_flags & (__SALC | __SSTR)) == + (__SALC | __SSTR) && fp->_w < len) { + size_t blen = fp->_p - fp->_bf._base; + + /* + * Alloc an extra 128 bytes (+ 1 for NULL) + * so we don't call realloc(3) so often. + */ + fp->_w = len + 128; + fp->_bf._size = blen + len + 128; + fp->_bf._base = + reallocf(fp->_bf._base, fp->_bf._size + 1); + if (fp->_bf._base == NULL) + goto err; + fp->_p = fp->_bf._base + blen; + } + w = fp->_w; + if (fp->_flags & __SSTR) { + if (len < w) + w = len; + if (w > 0) { + COPY(w); /* copy MIN(fp->_w,len), */ + fp->_w -= w; + fp->_p += w; + } + w = len; /* but pretend copied all */ + } else if (fp->_p > fp->_bf._base && len > w) { + /* fill and flush */ + COPY(w); + /* fp->_w -= w; */ /* unneeded */ + fp->_p += w; + if (__fflush(fp)) + goto err; + } else if (len >= (w = fp->_bf._size)) { + /* write directly */ + w = _swrite(fp, p, w); + if (w <= 0) + goto err; + } else { + /* fill and done */ + w = len; + COPY(w); + fp->_w -= w; + fp->_p += w; + } + p += w; + len -= w; + } while ((uio->uio_resid -= w) != 0); + } else { + /* + * Line buffered: like fully buffered, but we + * must check for newlines. Compute the distance + * to the first newline (including the newline), + * or `infinity' if there is none, then pretend + * that the amount to write is MIN(len,nldist). + */ + nlknown = 0; + nldist = 0; /* XXX just to keep gcc happy */ + do { + GETIOV(nlknown = 0); + if (!nlknown) { + nl = memchr((void *)p, '\n', len); + nldist = nl ? nl + 1 - p : len + 1; + nlknown = 1; + } + s = MIN(len, nldist); + w = fp->_w + fp->_bf._size; + if (fp->_p > fp->_bf._base && s > w) { + COPY(w); + /* fp->_w -= w; */ + fp->_p += w; + if (__fflush(fp)) + goto err; + } else if (s >= (w = fp->_bf._size)) { + w = _swrite(fp, p, w); + if (w <= 0) + goto err; + } else { + w = s; + COPY(w); + fp->_w -= w; + fp->_p += w; + } + if ((nldist -= w) == 0) { + /* copied the newline: flush and forget */ + if (__fflush(fp)) + goto err; + nlknown = 0; + } + p += w; + len -= w; + } while ((uio->uio_resid -= w) != 0); + } + return (0); + +err: + fp->_flags |= __SERR; + return (EOF); +} diff --git a/stdio/fvwrite.h b/stdio/fvwrite.h new file mode 100644 index 0000000..5414ec8 --- /dev/null +++ b/stdio/fvwrite.h @@ -0,0 +1,53 @@ +/*- + * 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. + * + * @(#)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 $ + */ + +/* + * I/O descriptors for __sfvwrite(). + */ +struct __siov { + void *iov_base; + size_t iov_len; +}; +struct __suio { + struct __siov *uio_iov; + int uio_iovcnt; + int uio_resid; +}; + +extern int __sfvwrite(FILE *, struct __suio *); diff --git a/stdio/fwalk-fbsd.c b/stdio/fwalk-fbsd.c new file mode 100644 index 0000000..a8a49fc --- /dev/null +++ b/stdio/fwalk-fbsd.c @@ -0,0 +1,71 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include +#include +#include "local.h" +#include "glue.h" + +int +_fwalk(function) + int (*function)(FILE *); +{ + FILE *fp; + int n, ret; + struct glue *g; + + ret = 0; + /* + * It should be safe to walk the list without locking it; + * new nodes are only added to the end and none are ever + * removed. + * + * Avoid locking this list while walking it or else you will + * introduce a potential deadlock in [at least] refill.c. + */ + for (g = &__sglue; g != NULL; g = g->next) + for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) + if ((fp->_flags != 0) && ((fp->_flags & __SIGN) == 0)) + ret |= (*function)(fp); + return (ret); +} diff --git a/stdio/fwide-fbsd.c b/stdio/fwide-fbsd.c new file mode 100644 index 0000000..1386c48 --- /dev/null +++ b/stdio/fwide-fbsd.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2002 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/fwide.c,v 1.1 2002/08/13 09:30:41 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +int +fwide(FILE *fp, int mode) +{ + int m; + + 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; + FUNLOCKFILE(fp); + + return (m); +} diff --git a/stdio/fwide.3 b/stdio/fwide.3 new file mode 100644 index 0000000..93163f3 --- /dev/null +++ b/stdio/fwide.3 @@ -0,0 +1,99 @@ +.\" $NetBSD: fwide.3,v 1.3 2002/02/07 07:00:25 ross Exp $ +.\" +.\" Copyright (c)2001 Citrus Project, +.\" 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. +.\" +.\" $Citrus: xpg4dl/FreeBSD/lib/libc/stdio/fwide.3,v 1.2 2001/12/07 04:47:08 yamt Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fwide.3,v 1.3 2002/12/18 12:45:10 ru Exp $ +.\" +.Dd October 24, 2001 +.Dt FWIDE 3 +.Os +.Sh NAME +.Nm fwide +.Nd get/set orientation of a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft int +.Fn fwide "FILE *stream" "int mode" +.Sh DESCRIPTION +The +.Fn fwide +function +determines the orientation of the stream pointed at by +.Fa stream . +.Pp +If the orientation of +.Fa stream +has already been determined, +.Fn fwide +leaves it unchanged. +Otherwise, +.Fn fwide +sets the orientation of +.Fa stream +according to +.Fa mode . +.Pp +If +.Fa mode +is less than zero, +.Fa stream +is set to be byte-oriented. +If +.Fa mode +is greater than zero, +.Fa stream +is set to be wide-oriented. +Otherwise, +.Fa mode +is zero, and +.Fa stream +is unchanged. +.Sh RETURN VALUES +The +.Fn fwide +function +returns a value according to orientation after the call of +.Fn fwide ; +a value less than zero if byte-oriented, a value greater than zero +if wide-oriented, and zero if the stream has no orientation. +.Sh SEE ALSO +.Xr ferror 3 , +.Xr fgetc 3 , +.Xr fgetwc 3 , +.Xr fopen 3 , +.Xr fputc 3 , +.Xr fputwc 3 , +.Xr freopen 3 , +.Xr stdio 3 +.Sh STANDARDS +The +.Fn fwide +function +conforms to +.St -isoC-99 . diff --git a/stdio/fwprintf-fbsd.c b/stdio/fwprintf-fbsd.c new file mode 100644 index 0000000..5fefd4a --- /dev/null +++ b/stdio/fwprintf-fbsd.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2002 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/fwprintf.c,v 1.1 2002/09/21 13:00:30 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include + +int +fwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfwprintf_l(fp, __current_locale(), fmt, ap); + va_end(ap); + + return (ret); +} + +int +fwprintf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt, ...) +{ + int ret; + va_list ap; + + /* no need to call NORMALIZE_LOCALE(loc) because vfwprintf_l will */ + va_start(ap, fmt); + ret = vfwprintf_l(fp, loc, fmt, ap); + va_end(ap); + + return (ret); +} diff --git a/stdio/fwrite-fbsd.c b/stdio/fwrite-fbsd.c new file mode 100644 index 0000000..6f51be3 --- /dev/null +++ b/stdio/fwrite-fbsd.c @@ -0,0 +1,85 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "local.h" +#include "fvwrite.h" +#include "libc_private.h" + +/* + * Write `count' objects (each size `size') from memory to the given file. + * Return the number of whole objects written. + */ +size_t +fwrite(buf, size, count, fp) + const void * __restrict buf; + size_t size, count; + FILE * __restrict fp; +{ + size_t n; + struct __suio uio; + struct __siov iov; + + iov.iov_base = (void *)buf; + uio.uio_resid = iov.iov_len = n = count * size; + +#if __DARWIN_UNIX03 + if (n == 0) /* POSIX */ + return 0; +#endif /* __DARWIN_UNIX03 */ + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + + FLOCKFILE(fp); + ORIENT(fp, -1); + /* + * The usual case is success (__sfvwrite returns 0); + * skip the divide if this happens, since divides are + * generally slow and since this occurs whenever size==0. + */ + if (__sfvwrite(fp, &uio) != 0) + count = (n - uio.uio_resid) / size; + FUNLOCKFILE(fp); + return (count); +} diff --git a/stdio/fwscanf-fbsd.c b/stdio/fwscanf-fbsd.c new file mode 100644 index 0000000..4fefaea --- /dev/null +++ b/stdio/fwscanf-fbsd.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2002 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/fwscanf.c,v 1.1 2002/09/23 12:40:06 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include + +int +fwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...) +{ + va_list ap; + int r; + + va_start(ap, fmt); + r = vfwscanf_l(fp, __current_locale(), fmt, ap); + va_end(ap); + + return (r); +} + +int +fwscanf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt, ...) +{ + va_list ap; + int r; + + /* no need to call NORMALIZE_LOCALE(loc) because vfwscanf_l will */ + va_start(ap, fmt); + r = vfwscanf_l(fp, loc, fmt, ap); + va_end(ap); + + return (r); +} diff --git a/stdio/getc-fbsd.c b/stdio/getc-fbsd.c new file mode 100644 index 0000000..0aa9dca --- /dev/null +++ b/stdio/getc-fbsd.c @@ -0,0 +1,61 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +#undef getc + +int +getc(FILE *fp) +{ + int retval; + FLOCKFILE(fp); + /* Orientation set by __sgetc() when buffer is empty. */ + /* ORIENT(fp, -1); */ + retval = __sgetc(fp); + FUNLOCKFILE(fp); + return (retval); +} diff --git a/stdio/getc.3 b/stdio/getc.3 new file mode 100644 index 0000000..2d9ea4e --- /dev/null +++ b/stdio/getc.3 @@ -0,0 +1,174 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd January 10, 2003 +.Dt GETC 3 +.Os +.Sh NAME +.Nm fgetc , +.Nm getc , +.Nm getc_unlocked , +.Nm getchar , +.Nm getchar_unlocked , +.Nm getw +.Nd get next character or word from input stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft int +.Fn fgetc "FILE *stream" +.Ft int +.Fn getc "FILE *stream" +.Ft int +.Fn getc_unlocked "FILE *stream" +.Ft int +.Fn getchar "void" +.Ft int +.Fn getchar_unlocked "void" +.Ft int +.Fn getw "FILE *stream" +.Sh DESCRIPTION +The +.Fn fgetc +function +obtains the next input character (if present) from the stream pointed at by +.Fa stream , +or the next character pushed back on the stream via +.Xr ungetc 3 . +.Pp +The +.Fn getc +function +acts essentially identically to +.Fn fgetc , +but is a macro that expands in-line. +.Pp +The +.Fn getchar +function +is equivalent to +.Fn getc stdin . +.Pp +The +.Fn getw +function +obtains the next +.Vt int +(if present) +from the stream pointed at by +.Fa stream . +.Pp +The +.Fn getc_unlocked +and +.Fn getchar_unlocked +functions are equivalent to +.Fn getc +and +.Fn getchar +respectively, +except that the caller is responsible for locking the stream +with +.Xr flockfile 3 +before calling them. +These functions may be used to avoid the overhead of locking the stream +for each character, and to avoid input being dispersed among multiple +threads reading from the same stream. +.Sh RETURN VALUES +If successful, these routines return the next requested object +from the +.Fa stream . +Character values are returned as an +.Vt "unsigned char" +converted to an +.Vt int . +If the stream is at end-of-file or a read error occurs, +the routines return +.Dv EOF . +The routines +.Xr feof 3 +and +.Xr ferror 3 +must be used to distinguish between end-of-file and error. +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 EOF +until the condition is cleared with +.Xr clearerr 3 . +.Sh SEE ALSO +.Xr ferror 3 , +.Xr flockfile 3 , +.Xr fopen 3 , +.Xr fread 3 , +.Xr getwc 3 , +.Xr putc 3 , +.Xr ungetc 3 +.Sh STANDARDS +The +.Fn fgetc , +.Fn getc , +and +.Fn getchar +functions +conform to +.St -isoC . +The +.Fn getc_unlocked +and +.Fn getchar_unlocked +functions conform to +.St -p1003.1-2001 . +.Sh BUGS +Since +.Dv EOF +is a valid integer value, +.Xr feof 3 +and +.Xr ferror 3 +must be used to check for failure after calling +.Fn getw . +The size and byte order of an +.Vt int +varies from one machine to another, and +.Fn getw +is not recommended for portable applications. +.Pp diff --git a/stdio/getchar-fbsd.c b/stdio/getchar-fbsd.c new file mode 100644 index 0000000..2ea530f --- /dev/null +++ b/stdio/getchar-fbsd.c @@ -0,0 +1,64 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +/* + * A subroutine version of the macro getchar. + */ +#include "namespace.h" +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +#undef getchar + +int +getchar() +{ + int retval; + FLOCKFILE(stdin); + /* Orientation set by __sgetc() when buffer is empty. */ + /* ORIENT(stdin, -1); */ + retval = __sgetc(stdin); + FUNLOCKFILE(stdin); + return (retval); +} diff --git a/stdio/gets-fbsd.c b/stdio/gets-fbsd.c new file mode 100644 index 0000000..5ef23ab --- /dev/null +++ b/stdio/gets-fbsd.c @@ -0,0 +1,81 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +__warn_references(gets, "warning: this program uses gets(), which is unsafe."); + +char * +gets(buf) + char *buf; +{ + int c; + char *s; + static int warned; + static char w[] = + "warning: this program uses gets(), which is unsafe.\n"; + + FLOCKFILE(stdin); + ORIENT(stdin, -1); + if (!warned) { + (void) _write(STDERR_FILENO, w, sizeof(w) - 1); + warned = 1; + } + for (s = buf; (c = __sgetc(stdin)) != '\n';) + if (c == EOF) + if (s == buf) { + FUNLOCKFILE(stdin); + return (NULL); + } else + break; + else + *s++ = c; + *s = 0; + FUNLOCKFILE(stdin); + return (buf); +} diff --git a/stdio/getw-fbsd.c b/stdio/getw-fbsd.c new file mode 100644 index 0000000..c7ba04f --- /dev/null +++ b/stdio/getw-fbsd.c @@ -0,0 +1,52 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +int +getw(fp) + FILE *fp; +{ + int x; + + return (fread((void *)&x, sizeof(x), 1, fp) == 1 ? x : EOF); +} diff --git a/stdio/getwc-fbsd.c b/stdio/getwc-fbsd.c new file mode 100644 index 0000000..0128a77 --- /dev/null +++ b/stdio/getwc-fbsd.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2002 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/getwc.c,v 1.3 2004/05/25 10:42:52 tjr Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +#undef getwc + +/* + * Synonym for fgetwc(). The only difference is that getwc(), if it is a + * macro, may evaluate `fp' more than once. + */ +wint_t +getwc(FILE *fp) +{ + + return (fgetwc_l(fp, __current_locale())); +} + +wint_t +getwc_l(FILE *fp, locale_t loc) +{ + + /* no need to call NORMALIZE_LOCALE(loc) because fgetwc_l will */ + return (fgetwc_l(fp, loc)); +} diff --git a/stdio/getwc.3 b/stdio/getwc.3 new file mode 100644 index 0000000..b1e0bef --- /dev/null +++ b/stdio/getwc.3 @@ -0,0 +1,125 @@ +.\" $NetBSD: getwc.3,v 1.3 2002/02/07 07:00:26 ross Exp $ +.\" +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd March 3, 2004 +.Dt GETWC 3 +.Os +.Sh NAME +.Nm fgetwc , +.Nm getwc , +.Nm getwchar +.Nd get next wide character from input stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft wint_t +.Fn fgetwc "FILE *stream" +.Ft wint_t +.Fn getwc "FILE *stream" +.Ft wint_t +.Fn getwchar void +.Sh DESCRIPTION +The +.Fn fgetwc +function +obtains the next input wide character (if present) from the stream pointed at by +.Fa stream , +or the next character pushed back on the stream via +.Xr ungetwc 3 . +.Pp +The +.Fn getwc +function +acts essentially identically to +.Fn fgetwc . +.Pp +The +.Fn getwchar +function +is equivalent to +.Fn getwc +with the argument +.Dv stdin . +.Pp +Extended locale versions of these functions are documented in +.Xr getwc_l 3 . +See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +If successful, these routines return the next wide character +from the +.Fa stream . +If the stream is at end-of-file or a read error occurs, +the routines return +.Dv WEOF . +The routines +.Xr feof 3 +and +.Xr ferror 3 +must be used to distinguish between end-of-file and error. +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 WEOF +until the condition is cleared with +.Xr clearerr 3 . +.Sh SEE ALSO +.Xr ferror 3 , +.Xr fopen 3 , +.Xr fread 3 , +.Xr getc 3 , +.Xr getwc_l 3 , +.Xr putwc 3 , +.Xr stdio 3 , +.Xr ungetwc 3 +.Sh STANDARDS +The +.Fn fgetwc , +.Fn getwc , +and +.Fn getwchar +functions +conform to +.St -isoC-99 . diff --git a/stdio/getwchar-fbsd.c b/stdio/getwchar-fbsd.c new file mode 100644 index 0000000..f5c2dd6 --- /dev/null +++ b/stdio/getwchar-fbsd.c @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2002 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/getwchar.c,v 1.3 2004/05/25 10:42:52 tjr Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +#undef getwchar + +/* + * Synonym for fgetwc(stdin). + */ +wint_t +getwchar(void) +{ + + return (fgetwc_l(stdin, __current_locale())); +} + +wint_t +getwchar_l(locale_t loc) +{ + + /* no need to call NORMALIZE_LOCALE(loc) because fgetwc_l will */ + return (fgetwc_l(stdin, loc)); +} diff --git a/stdio/glue.h b/stdio/glue.h new file mode 100644 index 0000000..ef74293 --- /dev/null +++ b/stdio/glue.h @@ -0,0 +1,49 @@ +/*- + * 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/local.h b/stdio/local.h new file mode 100644 index 0000000..a8235f6 --- /dev/null +++ b/stdio/local.h @@ -0,0 +1,144 @@ +/*- + * 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. + * + * @(#)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 $ + */ + +#include +#include "xlocale_private.h" +#include /* for off_t */ +#include +#include +#include +#include + +/* + * Information local to this implementation of stdio, + * in particular, macros and private variables. + */ + +extern int _sread(FILE *, char *, int); +extern int _swrite(FILE *, char const *, int); +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 wint_t __fgetwc(FILE *, locale_t); +extern wint_t __fputwc(wchar_t, FILE *, locale_t); +extern int __sflush(FILE *); +extern FILE *__sfp(void); +extern int __slbexpand(FILE *, size_t); +extern int __srefill(FILE *); +extern int __sread(void *, char *, int); +extern int __swrite(void *, char const *, int); +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 *)); +extern int __svfscanf_l(FILE *, locale_t, const char *, __va_list) __DARWIN_LDBL_COMPAT(__svfscanf_l); +extern int __swsetup(FILE *); +extern int __sflags(const char *, int *); +extern int __ungetc(int, FILE *); +extern wint_t __ungetwc(wint_t, FILE *, locale_t); +extern int __vfprintf(FILE *, locale_t, const char *, __va_list) __DARWIN_LDBL_COMPAT(__vfprintf); +extern int __vfscanf(FILE *, const char *, __va_list) __DARWIN_LDBL_COMPAT(__vfscanf); +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 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. + */ +#define prepwrite(fp) \ + ((((fp)->_flags & __SWR) == 0 || \ + ((fp)->_bf._base == NULL && ((fp)->_flags & __SSTR) == 0)) && \ + __swsetup(fp)) + +/* + * Test whether the given stdio file has an active ungetc buffer; + * release such a buffer, without restoring ordinary unread data. + */ +#define HASUB(fp) ((fp)->_ub._base != NULL) +#define FREEUB(fp) { \ + if ((fp)->_ub._base != (fp)->_ubuf) \ + free((char *)(fp)->_ub._base); \ + (fp)->_ub._base = NULL; \ +} + +/* + * test for an fgetln() buffer. + */ +#define HASLB(fp) ((fp)->_lb._base != NULL) +#define FREELB(fp) { \ + free((char *)(fp)->_lb._base); \ + (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); \ +} while (0) diff --git a/stdio/makebuf-fbsd.c b/stdio/makebuf-fbsd.c new file mode 100644 index 0000000..b52251b --- /dev/null +++ b/stdio/makebuf-fbsd.c @@ -0,0 +1,128 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "local.h" +#include "un-namespace.h" + +#define TTYBUFSIZE 4096 + +/* + * Allocate a file buffer, or switch to unbuffered I/O. + * Per the ANSI C standard, ALL tty devices default to line buffered. + * + * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek + * optimisation) right after the _fstat() that finds the buffer size. + */ +void +__smakebuf(fp) + FILE *fp; +{ + void *p; + int flags; + size_t size; + int couldbetty; + + if (fp->_flags & __SNBF) { + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; + return; + } + flags = __swhatbuf(fp, &size, &couldbetty); + if (couldbetty && isatty(fp->_file)) { + flags |= __SLBF; + /* st_blksize for ttys is 128K, so make it more reasonable */ + if (size > TTYBUFSIZE) + fp->_blksize = size = TTYBUFSIZE; + } + if ((p = malloc(size)) == NULL) { + fp->_flags |= __SNBF; + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; + return; + } + __cleanup = _cleanup; + flags |= __SMBF; + fp->_bf._base = fp->_p = p; + fp->_bf._size = size; + fp->_flags |= flags; +} + +/* + * Internal routine to determine `proper' buffering for a file. + */ +int +__swhatbuf(fp, bufsize, couldbetty) + FILE *fp; + size_t *bufsize; + int *couldbetty; +{ + struct stat st; + + if (fp->_file < 0 || _fstat(fp->_file, &st) < 0) { + *couldbetty = 0; + *bufsize = BUFSIZ; + return (__SNPT); + } + + /* could be a tty iff it is a character device */ + *couldbetty = (st.st_mode & S_IFMT) == S_IFCHR; + if (st.st_blksize <= 0) { + *bufsize = BUFSIZ; + return (__SNPT); + } + + /* + * Optimise fseek() only if it is a regular file. (The test for + * __sseek is mainly paranoia.) It is safe to set _blksize + * unconditionally; it will only be used if __SOPT is also set. + */ + *bufsize = st.st_blksize; + fp->_blksize = st.st_blksize; + return ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek ? + __SOPT : __SNPT); +} diff --git a/stdio/mktemp-fbsd.c b/stdio/mktemp-fbsd.c new file mode 100644 index 0000000..244cc00 --- /dev/null +++ b/stdio/mktemp-fbsd.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 1987, 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +char *_mktemp(char *); + +static int _gettemp(char *, int *, int, int); + +static const unsigned char padchar[] = +"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +int +mkstemps(path, slen) + char *path; + int slen; +{ + int fd; + + return (_gettemp(path, &fd, 0, slen) ? fd : -1); +} + +int +mkstemp(path) + char *path; +{ + int fd; + + return (_gettemp(path, &fd, 0, 0) ? fd : -1); +} + +char * +mkdtemp(path) + char *path; +{ + return (_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); +} + +char * +_mktemp(path) + char *path; +{ + return (_gettemp(path, (int *)NULL, 0, 0) ? path : (char *)NULL); +} + +__warn_references(mktemp, + "warning: mktemp() possibly used unsafely; consider using mkstemp()"); + +char * +mktemp(path) + char *path; +{ + return (_mktemp(path)); +} + +static int +_gettemp(path, doopen, domkdir, slen) + char *path; + int *doopen; + int domkdir; + int slen; +{ + char *start, *trv, *suffp, *carryp; + char *pad; + struct stat sbuf; + int rval; + uint32_t rand; + char carrybuf[NAME_MAX]; + + if ((doopen != NULL && domkdir) || slen < 0) { + errno = EINVAL; + return (0); + } + + for (trv = path; *trv != '\0'; ++trv) + ; + trv -= slen; + suffp = trv; + --trv; + 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); + *trv-- = padchar[rand]; + } + start = trv + 1; + + /* save first combination of random characters */ + memcpy(carrybuf, start, suffp - start); + + /* + * check the target directory. + */ + if (doopen != NULL || domkdir) { + for (; trv > path; --trv) { + if (*trv == '/') { + *trv = '\0'; + rval = stat(path, &sbuf); + *trv = '/'; + if (rval != 0) + return (0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return (0); + } + break; + } + } + } + + for (;;) { + if (doopen) { + if ((*doopen = + _open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + return (1); + if (errno != EEXIST) + return (0); + } else if (domkdir) { + if (mkdir(path, 0700) == 0) + return (1); + if (errno != EEXIST) + return (0); + } else if (lstat(path, &sbuf)) + return (errno == ENOENT); + + /* If we have a collision, cycle through the space of filenames */ + 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) { + /* 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; + } + } + } + /*NOTREACHED*/ +} diff --git a/stdio/mktemp.3 b/stdio/mktemp.3 new file mode 100644 index 0000000..ffec3a5 --- /dev/null +++ b/stdio/mktemp.3 @@ -0,0 +1,275 @@ +.\" Copyright (c) 1989, 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. +.\" +.\" @(#)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 $ +.\" +.Dd February 11, 1998 +.Dt MKTEMP 3 +.Os +.Sh NAME +.Nm mkdtemp , +.Nm mkstemp , +.Nm mktemp , +.Nm mktemps +.Nd make temporary file name (unique) +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft char * +.Fo mkdtemp +.Fa "char *template" +.Fc +.Ft int +.Fo mkstemps +.Fa "char *template" +.Fa "int suffixlen" +.Fc +.In stdlib.h +.Ft int +.Fo mkstemp +.Fa "char *template" +.Fc +.Ft char * +.Fo mktemp +.Fa "char *template" +.Fc +.Sh DESCRIPTION +The +.Fn mktemp +function +takes the given file name template and overwrites a portion of it +to create a file name. +This file name is guaranteed not to exist at the time of function invocation +and is suitable for use +by the application. +The template may be any file name with some number of +.Ql X Ns s +appended +to it, for example +.Pa /tmp/temp.XXXXXX . +The trailing +.Ql X Ns s +are replaced with a +unique alphanumeric combination. +The number of unique file names +.Fn mktemp +can return depends on the number of +.Ql X Ns s +provided; six +.Ql X Ns s +will +result in +.Fn mktemp +selecting one of 56800235584 (62 ** 6) possible temporary file names. +.Pp +The +.Fn mkstemp +function +makes the same replacement to the template and creates the template file, +mode 0600, returning a file descriptor opened for reading and writing. +This avoids the race between testing for a file's existence and opening it +for use. +.Pp +The +.Fn mkstemps +function acts the same as +.Fn mkstemp , +except it permits a suffix to exist in the template. +The template should be of the form +.Pa /tmp/tmpXXXXXXsuffix . +The +.Fn mkstemps +function +is told the length of the suffix string. +.Pp +The +.Fn mkdtemp +function makes the same replacement to the template as in +.Fn mktemp +and creates the template directory, mode 0700. +.Sh RETURN VALUES +The +.Fn mktemp +and +.Fn mkdtemp +functions return a pointer to the template on success and +.Dv NULL +on failure. +The +.Fn mkstemp +and +.Fn mkstemps +functions +return \-1 if no suitable file could be created. +If either call fails an error code is placed in the global variable +.Va errno . +.Sh ERRORS +The +.Fn mkstemp , +.Fn mkstemps +and +.Fn mkdtemp +functions +may set +.Va errno +to one of the following values: +.Bl -tag -width Er +.It Bq Er ENOTDIR +The pathname portion of the template is not an existing directory. +.El +.Pp +The +.Fn mkstemp , +.Fn mkstemps , +and +.Fn mkdtemp +functions +may also set +.Va errno +to any value specified by the +.Xr stat 2 +function. +.Pp +The +.Fn mkstemp +and +.Fn mkstemps +functions +may also set +.Va errno +to any value specified by the +.Xr open 2 +function. +.Pp +The +.Fn mkdtemp +function +may also set +.Va errno +to any value specified by the +.Xr mkdir 2 +function. +.Sh NOTES +A common problem that results in a core dump is that the programmer +passes in a read-only string to +.Fn mktemp , +.Fn mkstemp , +.Fn mkstemps , +or +.Fn mkdtemp . +This is common with programs that were developed before +.St -isoC +compilers were common. +For example, calling +.Fn mkstemp +with an argument of +.Qq /tmp/tempfile.XXXXXX +will result in a core dump due to +.Fn mkstemp +attempting to modify the string constant that was given. +If the program in question makes heavy use of that type +of function call, you do have the option of compiling the program +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. +.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. +.Sh LEGACY SYNOPSIS +.Fd #include +.Pp +The include file +.In unistd.h +is necessary and sufficient for all functions. +.Sh SEE ALSO +.Xr chmod 2 , +.Xr getpid 2 , +.Xr mkdir 2 , +.Xr open 2 , +.Xr stat 2 , +.Xr compat 5 +.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/perror-fbsd.c b/stdio/perror-fbsd.c new file mode 100644 index 0000000..8b5934b --- /dev/null +++ b/stdio/perror-fbsd.c @@ -0,0 +1,81 @@ +/* + * 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/printf-fbsd.c b/stdio/printf-fbsd.c new file mode 100644 index 0000000..ab89d95 --- /dev/null +++ b/stdio/printf-fbsd.c @@ -0,0 +1,71 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include + +int +printf(char const * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf_l(stdout, __current_locale(), fmt, ap); + va_end(ap); + return (ret); +} + +int +printf_l(locale_t loc, char const * __restrict fmt, ...) +{ + int ret; + va_list ap; + + /* no need to call NORMALIZE_LOCALE(loc) because vfprintf_l will */ + va_start(ap, fmt); + ret = vfprintf_l(stdout, loc, fmt, ap); + va_end(ap); + return (ret); +} diff --git a/stdio/printf.3 b/stdio/printf.3 new file mode 100644 index 0000000..337dcec --- /dev/null +++ b/stdio/printf.3 @@ -0,0 +1,957 @@ +.\" 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. +.\" +.\" @(#)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 October 16, 2004 +.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 +.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 +.Ft int +.Fo fprintf +.Fa "FILE *restrict stream" +.Fa "const char *restrict format" ... +.Fc +.Ft int +.Fo printf +.Fa "const char *restrict format" ... +.Fc +.Ft int +.Fo snprintf +.Fa "char *restrict s" +.Fa "size_t n" +.Fa "const char *restrict format" ... +.Fc +.Ft int +.Fo sprintf +.Fa "char *restrict s" +.Fa "const char *restrict format" ... +.Fc +.In stdarg.h +.In stdio.h +.Ft int +.Fo vasprintf +.Fa "char **ret" +.Fa "const char *format" +.Fa "va_list ap" +.Fc +.Ft int +.Fo vfprintf +.Fa "FILE *restrict stream" +.Fa "const char *restrict format" +.Fa "va_list ap" +.Fc +.Ft int +.Fo vprintf +.Fa "const char *restrict format" +.Fa "va_list ap" +.Fc +.Ft int +.Fo vsnprintf +.Fa "char *restrict s" +.Fa "size_t n" +.Fa "const char *restrict format" +.Fa "va_list ap" +.Fc +.Ft int +.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 , +as described below. +The +.Fn printf +and +.Fn vprintf +functions +write output to +.Dv stdout , +the standard output stream; +.Fn fprintf +and +.Fn vfprintf +write output to the given output +.Fa stream ; +.Fn sprintf , +.Fn snprintf , +.Fn vsprintf , +and +.Fn vsnprintf +write to the character string +.Fa s ; +and +.Fn asprintf +and +.Fn vasprintf +dynamically allocate a new string with +.Xr malloc 3 . +.Pp +Extended locale versions of these functions are documented in +.Xr printf_l 3 . +See +.Xr xlocale 3 +for more information. +.Pp +These functions write the output under the control of a +.Fa format +string that specifies how subsequent arguments +(or arguments accessed via the variable-length argument facilities of +.Xr stdarg 3 ) +are converted for output. +.Pp +These functions return the number of characters printed +(not including the trailing +.Ql \e0 +used to end output to strings) or a negative value if an output error occurs, +except for +.Fn snprintf +and +.Fn vsnprintf , +which return the number of characters that would have been printed if the +.Fa n +were unlimited +(again, not including the final +.Ql \e0 ) . +.Pp +The +.Fn asprintf +and +.Fn vasprintf +functions +set +.Fa *ret +to be a pointer to a buffer sufficiently large to hold the formatted string. +This pointer should be passed to +.Xr free 3 +to release the allocated storage when it is no longer needed. +If sufficient space cannot be allocated, +.Fn asprintf +and +.Fn vasprintf +will return \-1 and set +.Fa ret +to be a +.Dv NULL +pointer. +.Pp +The +.Fn snprintf +and +.Fn vsnprintf +functions +will write at most +.Fa n Ns \-1 +of the characters printed into the output string +(the +.Fa n Ns \'th +character then gets the terminating +.Ql \e0 ) ; +if the return value is greater than or equal to the +.Fa n +argument, the string was too short +and some of the printed characters were discarded. +The output is always null-terminated. +.Pp +The +.Fn sprintf +and +.Fn vsprintf +functions +effectively assume an infinite +.Fa n . +.Pp +The format string is composed of zero or more directives: +ordinary +.\" multibyte +characters (not +.Cm % ) , +which are copied unchanged to the output stream; +and conversion specifications, each of which results +in fetching zero or more subsequent arguments. +Each conversion specification is introduced by +the +.Cm % +character. +The arguments must correspond properly (after type promotion) +with the conversion specifier. +After the +.Cm % , +the following appear in sequence: +.Bl -bullet +.It +An optional field, consisting of a decimal digit string followed by a +.Cm $ , +specifying the next argument to access. +If this field is not provided, the argument following the last +argument accessed will be used. +Arguments are numbered starting at +.Cm 1 . +If unaccessed arguments in the format string are interspersed with ones that +are accessed the results will be indeterminate. +.It +Zero or more of the following flags: +.Bl -tag -width ".So \ Sc (space)" +.It Sq Cm # +The value should be converted to an +.Dq alternate form . +For +.Cm c , d , i , n , p , s , +and +.Cm u +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). +For +.Cm x +and +.Cm X +conversions, a non-zero result has the string +.Ql 0x +(or +.Ql 0X +for +.Cm X +conversions) prepended to it. +For +.Cm a , A , e , E , f , F , g , +and +.Cm G +conversions, the result will always contain a decimal point, even if no +digits follow it (normally, a decimal point appears in the results of +those conversions only if a digit follows). +For +.Cm g +and +.Cm G +conversions, trailing zeros are not removed from the result as they +would otherwise be. +.It So Cm 0 Sc (zero) +Zero padding. +For all conversions except +.Cm n , +the converted value is padded on the left with zeros rather than blanks. +If a precision is given with a numeric conversion +.Cm ( d , i , o , u , i , x , +and +.Cm X ) , +the +.Cm 0 +flag is ignored. +.It Sq Cm \- +A negative field width flag; +the converted value is to be left adjusted on the field boundary. +Except for +.Cm n +conversions, the converted value is padded on the right with blanks, +rather than on the left with blanks or zeros. +A +.Cm \- +overrides a +.Cm 0 +if both are given. +.It So "\ " Sc (space) +A blank should be left before a positive number +produced by a signed conversion +.Cm ( a , A , d , e , E , f , F , g , G , +or +.Cm i ) . +.It Sq Cm + +A sign must always be placed before a +number produced by a signed conversion. +A +.Cm + +overrides a space if both are used. +.It Sq Cm ' +Decimal conversions +.Cm ( d , u , +or +.Cm i ) +or the integral portion of a floating point conversion +.Cm ( f +or +.Cm F ) +should be grouped and separated by thousands using +the non-monetary separator returned by +.Xr localeconv 3 . +.El +.It +An optional separator character ( +.Cm \ , | \; | \ : | _ +) used for separating multiple values when printing an AltiVec or SSE vector, +or other multi-value unit. +.Pp +NOTE: This is an extension to the +.Fn printf +specification. +Behaviour of these values for +.Fn printf +is only defined for operating systems conforming to the +AltiVec Technology Programming Interface Manual. +(At time of writing this includes only Mac OS X 10.2 and later.) +.It +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 +flag has been given) to fill out +the field width. +.It +An optional precision, in the form of a period +.Cm \&. +followed by an +optional digit string. +If the digit string is omitted, the precision is taken as zero. +This gives the minimum number of digits to appear for +.Cm d , i , o , u , x , +and +.Cm X +conversions, the number of digits to appear after the decimal-point for +.Cm a , A , e , E , f , +and +.Cm F +conversions, the maximum number of significant digits for +.Cm g +and +.Cm G +conversions, or the maximum number of characters to be printed from a +string for +.Cm s +conversions. +.It +An optional length modifier, that specifies the size of the argument. +The following length modifiers are valid for the +.Cm d , i , n , o , u , x , +or +.Cm X +conversion: +.Bl -column ".Cm q Em (deprecated)" ".Vt signed char" ".Vt unsigned long long" ".Vt long long *" +.It Sy Modifier Ta Cm d , i Ta Cm o , u , x , X Ta Cm n +.It Cm hh Ta Vt "signed char" Ta Vt "unsigned char" Ta Vt "signed char *" +.It Cm h Ta Vt short Ta Vt "unsigned short" Ta Vt "short *" +.It Cm l No (ell) Ta Vt long Ta Vt "unsigned long" Ta Vt "long *" +.It Cm ll No (ell ell) Ta Vt "long long" Ta Vt "unsigned long long" Ta Vt "long long *" +.It Cm j Ta Vt intmax_t Ta Vt uintmax_t Ta Vt "intmax_t *" +.It Cm t Ta Vt ptrdiff_t Ta (see note) Ta Vt "ptrdiff_t *" +.It Cm z Ta (see note) Ta Vt size_t Ta (see note) +.It Cm q Em (deprecated) Ta Vt quad_t Ta Vt u_quad_t Ta Vt "quad_t *" +.El +.Pp +Note: +the +.Cm t +modifier, when applied to a +.Cm o , u , x , +or +.Cm X +conversion, indicates that the argument is of an unsigned type +equivalent in size to a +.Vt ptrdiff_t . +The +.Cm z +modifier, when applied to a +.Cm d +or +.Cm i +conversion, indicates that the argument is of a signed type equivalent in +size to a +.Vt size_t . +Similarly, when applied to an +.Cm n +conversion, it indicates that the argument is a pointer to a signed type +equivalent in size to a +.Vt size_t . +.Pp +The following length modifier is valid for the +.Cm a , A , e , E , f , F , g , +or +.Cm G +conversion: +.Bl -column ".Sy Modifier" ".Cm a , A , e , E , f , F , g , G" +.It Sy Modifier Ta Cm a , A , e , E , f , F , g , G +.It Cm l No (ell) Ta Vt double +(ignored, same behavior as without it) +.It Cm L Ta Vt "long double" +.El +.Pp +The following length modifier is valid for the +.Cm c +or +.Cm s +conversion: +.Bl -column ".Sy Modifier" ".Vt wint_t" ".Vt wchar_t *" +.It Sy Modifier Ta Cm c Ta Cm s +.It Cm l No (ell) Ta Vt wint_t Ta Vt "wchar_t *" +.El +.Pp +The AltiVec Technology Programming Interface Manual also defines five additional length modifiers +which can be used (in place of the conventional length modifiers) for the printing of AltiVec or SSE vectors: +.Bl -tag -compact +.It Cm v +Treat the argument as a vector value, unit length will be determined by the conversion +specifier (default = 16 8-bit units for all integer conversions, +4 32-bit units for floating point conversions). +.It Cm vh, hv +Treat the argument as a vector of 8 16-bit units. +.It Cm vl, lv +Treat the argument as a vector of 4 32-bit units. +.El +.Pp +NOTE: The vector length specifiers are extensions to the +.Fn printf +specification. +Behaviour of these values for +.Fn printf +is only defined for operating systems conforming to the +AltiVec Technology Programming Interface Manual. +(At time of writing this includes only Mac OS X 10.2 and later.) +.Pp +As a further extension, for SSE2 64-bit units: +.Bl -tag -compact +.It Cm vll, llv +Treat the argument as a vector of 2 64-bit units. +.El +.It +A character that specifies the type of conversion to be applied. +.El +.Pp +A field width or precision, or both, may be indicated by +an asterisk +.Ql * +or an asterisk followed by one or more decimal digits and a +.Ql $ +instead of a +digit string. +In this case, an +.Vt int +argument supplies the field width or precision. +A negative field width is treated as a left adjustment flag followed by a +positive field width; a negative precision is treated as though it were +missing. +If a single format directive mixes positional +.Pq Li nn$ +and non-positional arguments, the results are undefined. +.Pp +The conversion specifiers and their meanings are: +.Bl -tag -width ".Cm diouxX" +.It Cm diouxX +The +.Vt int +(or appropriate variant) argument is converted to signed decimal +.Cm ( d +and +.Cm i ) , +unsigned octal +.Pq Cm o , +unsigned decimal +.Pq Cm u , +or unsigned hexadecimal +.Cm ( x +and +.Cm X ) +notation. +The letters +.Dq Li abcdef +are used for +.Cm x +conversions; the letters +.Dq Li ABCDEF +are used for +.Cm X +conversions. +The precision, if any, gives the minimum number of digits that must +appear; if the converted value requires fewer digits, it is padded on +the left with zeros. +.It Cm DOU +The +.Vt "long int" +argument is converted to signed decimal, unsigned octal, or unsigned +decimal, as if the format had been +.Cm ld , lo , +or +.Cm lu +respectively. +These conversion characters are deprecated, and will eventually disappear. +.It Cm eE +The +.Vt double +argument is rounded and converted in the style +.Sm off +.Oo \- Oc Ar d Li \&. Ar ddd Li e \\*[Pm] Ar dd +.Sm on +where there is one digit before the +decimal-point character +and the number of digits after it is equal to the precision; +if the precision is missing, +it is taken as 6; if the precision is +zero, no decimal-point character appears. +An +.Cm E +conversion uses the letter +.Ql E +(rather than +.Ql e ) +to introduce the exponent. +The exponent always contains at least two digits; if the value is zero, +the exponent is 00. +.Pp +For +.Cm a , A , e , E , f , F , g , +and +.Cm G +conversions, positive and negative infinity are represented as +.Li inf +and +.Li -inf +respectively when using the lowercase conversion character, and +.Li INF +and +.Li -INF +respectively when using the uppercase conversion character. +Similarly, NaN is represented as +.Li nan +when using the lowercase conversion, and +.Li NAN +when using the uppercase conversion. +.It Cm fF +The +.Vt double +argument is rounded and converted to decimal notation in the style +.Sm off +.Oo \- Oc Ar ddd Li \&. Ar ddd , +.Sm on +where the number of digits after the decimal-point character +is equal to the precision specification. +If the precision is missing, it is taken as 6; if the precision is +explicitly zero, no decimal-point character appears. +If a decimal point appears, at least one digit appears before it. +.It Cm gG +The +.Vt double +argument is converted in style +.Cm f +or +.Cm e +(or +.Cm F +or +.Cm E +for +.Cm G +conversions). +The precision specifies the number of significant digits. +If the precision is missing, 6 digits are given; if the precision is zero, +it is treated as 1. +Style +.Cm e +is used if the exponent from its conversion is less than \-4 or greater than +or equal to the precision. +Trailing zeros are removed from the fractional part of the result; a +decimal point appears only if it is followed by at least one digit. +.It Cm aA +The +.Vt double +argument is rounded and converted to hexadecimal notation in the style +.Sm off +.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \\*[Pm] Oc Ar d , +.Sm on +where the number of digits after the hexadecimal-point character +is equal to the precision specification. +If the precision is missing, it is taken as enough to represent +the floating-point number exactly, and no rounding occurs. +If the precision is zero, no hexadecimal-point character appears. +The +.Cm p +is a literal character +.Ql p , +and the exponent consists of a positive or negative sign +followed by a decimal number representing an exponent of 2. +The +.Cm A +conversion uses the prefix +.Dq Li 0X +(rather than +.Dq Li 0x ) , +the letters +.Dq Li ABCDEF +(rather than +.Dq Li abcdef ) +to represent the hex digits, and the letter +.Ql P +(rather than +.Ql p ) +to separate the mantissa and exponent. +.Pp +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 +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. +Zeroes are always represented with a mantissa of 0 (preceded by a +.Ql - +if appropriate) and an exponent of +.Li +0 . +.It Cm C +Treated as +.Cm c +with the +.Cm l +(ell) modifier. +.It Cm c +The +.Vt int +argument is converted to an +.Vt "unsigned char" , +and the resulting character is written. +.Pp +If the +.Cm l +(ell) modifier is used, the +.Vt wint_t +argument shall be converted to a +.Vt wchar_t , +and the (potentially multi-byte) sequence representing the +single wide character is written, including any shift sequences. +If a shift sequence is used, the shift state is also restored +to the original state after the character. +.It Cm S +Treated as +.Cm s +with the +.Cm l +(ell) modifier. +.It Cm s +The +.Vt "char *" +argument is expected to be a pointer to an array of character type (pointer +to a string). +Characters from the array are written up to (but not including) +a terminating +.Dv NUL +character; +if a precision is specified, no more than the number specified are +written. +If a precision is given, no null character +need be present; if the precision is not specified, or is greater than +the size of the array, the array must contain a terminating +.Dv NUL +character. +.Pp +If the +.Cm l +(ell) modifier is used, the +.Vt "wchar_t *" +argument is expected to be a pointer to an array of wide characters +(pointer to a wide string). +For each wide character in the string, the (potentially multi-byte) +sequence representing the +wide character is written, including any shift sequences. +If any shift sequence is used, the shift state is also restored +to the original state after the string. +Wide characters from the array are written up to (but not including) +a terminating wide +.Dv NUL +character; +if a precision is specified, no more than the number of bytes specified are +written (including shift sequences). +Partial characters are never written. +If a precision is given, no null character +need be present; if the precision is not specified, or is greater than +the number of bytes required to render the multibyte representation of +the string, the array must contain a terminating wide +.Dv NUL +character. +.It Cm p +The +.Vt "void *" +pointer argument is printed in hexadecimal (as if by +.Ql %#x +or +.Ql %#lx ) . +.It Cm n +The number of characters written so far is stored into the +integer indicated by the +.Vt "int *" +(or variant) pointer argument. +No argument is converted. +.It Cm % +A +.Ql % +is written. +No argument is converted. +The complete conversion specification +is +.Ql %% . +.El +.Pp +The decimal point +character is defined in the program's locale (category +.Dv LC_NUMERIC ) . +.Pp +In no case does a non-existent or small field width cause truncation of +a numeric field; if the result of a conversion is wider than the field +width, the +field is expanded to contain the conversion result. +.Sh EXAMPLES +To print a date and time in the form +.Dq Li "Sunday, July 3, 10:02" , +where +.Fa weekday +and +.Fa month +are pointers to strings: +.Bd -literal -offset indent +#include +fprintf(stdout, "%s, %s %d, %.2d:%.2d\en", + weekday, month, day, hour, min); +.Ed +.Pp +To print \*(Pi +to five decimal places: +.Bd -literal -offset indent +#include +#include +fprintf(stdout, "pi = %.5f\en", 4 * atan(1.0)); +.Ed +.Pp +To allocate a 128 byte string and print into it: +.Bd -literal -offset indent +#include +#include +#include +char *newfmt(const char *fmt, ...) +{ + char *p; + va_list ap; + if ((p = malloc(128)) == NULL) + return (NULL); + va_start(ap, fmt); + (void) vsnprintf(p, 128, fmt, ap); + va_end(ap); + return (p); +} +.Ed +.Sh SECURITY CONSIDERATIONS +The +.Fn sprintf +and +.Fn vsprintf +functions are easily misused in a manner which enables malicious users +to arbitrarily change a running program's functionality through +a buffer overflow attack. +Because +.Fn sprintf +and +.Fn vsprintf +assume an infinitely long string, +callers must be careful not to overflow the actual space; +this is often hard to assure. +For safety, programmers should use the +.Fn snprintf +interface instead. +For example: +.Bd -literal +void +foo(const char *arbitrary_string, const char *and_another) +{ + char onstack[8]; + +#ifdef BAD + /* + * This first sprintf is bad behavior. Do not use sprintf! + */ + sprintf(onstack, "%s, %s", arbitrary_string, and_another); +#else + /* + * The following two lines demonstrate better use of + * snprintf(). + */ + snprintf(onstack, sizeof(onstack), "%s, %s", arbitrary_string, + and_another); +#endif +} +.Ed +.Pp +The +.Fn printf +and +.Fn sprintf +family of functions are also easily misused in a manner +allowing malicious users to arbitrarily change a running program's +functionality by either causing the program +to print potentially sensitive data +.Dq "left on the stack" , +or causing it to generate a memory fault or bus error +by dereferencing an invalid pointer. +.Pp +.Cm %n +can be used to write arbitrary data to potentially carefully-selected +addresses. +Programmers are therefore strongly advised to never pass untrusted strings +as the +.Fa format +argument, as an attacker can put format specifiers in the string +to mangle your stack, +leading to a possible security hole. +This holds true even if the string was built using a function like +.Fn snprintf , +as the resulting string may still contain user-supplied conversion specifiers +for later interpolation by +.Fn printf . +.Pp +Always use the proper secure idiom: +.Pp +.Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);" +.Sh ERRORS +In addition to the errors documented for the +.Xr write 2 +system call, the +.Fn printf +family of functions may fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid wide character code was encountered. +.It Bq Er ENOMEM +Insufficient storage space is available. +.El +.Sh SEE ALSO +.Xr printf 1 , +.Xr fmtcheck 3 , +.Xr printf_l 3 , +.Xr scanf 3 , +.Xr setlocale 3 , +.Xr stdarg 3 , +.Xr wprintf 3 +.Sh STANDARDS +Subject to the caveats noted in the +.Sx BUGS +section below, the +.Fn fprintf , +.Fn printf , +.Fn sprintf , +.Fn vprintf , +.Fn vfprintf , +and +.Fn vsprintf +functions +conform to +.St -ansiC +and +.St -isoC-99 . +With the same reservation, the +.Fn snprintf +and +.Fn vsnprintf +functions conform to +.St -isoC-99 . +.Sh HISTORY +The functions +.Fn asprintf +and +.Fn vasprintf +first appeared in the +.Tn GNU C +library. +These were implemented by +.An Peter Wemm Aq peter@FreeBSD.org +in +.Fx 2.2 , +but were later replaced with a different implementation +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 +and +.Cm %p +conversions, as well as other +nonsensical combinations such as +.Cm %Ld , +are not standard; such combinations +should be avoided. +.Pp +The +.Nm +family of functions do not correctly handle multibyte characters in the +.Fa format +argument. diff --git a/stdio/printf_l.3 b/stdio/printf_l.3 index aa3c1c1..0f1f67c 100644 --- a/stdio/printf_l.3 +++ b/stdio/printf_l.3 @@ -40,8 +40,16 @@ .Dt PRINTF_L 3 .Os .Sh NAME -.Nm printf_l , fprintf_l , sprintf_l , snprintf_l , asprintf_l , -.Nm vprintf_l , vfprintf_l , vsprintf_l , vsnprintf_l , vasprintf_l +.Nm asprintf_l , +.Nm fprintf_l , +.Nm printf_l , +.Nm snprintf_l , +.Nm sprintf_l , +.Nm vasprintf_l , +.Nm vfprintf_l , +.Nm vprintf_l , +.Nm vsnprintf_l , +.Nm vsprintf_l .Nd formatted output conversion .Sh LIBRARY .Lb libc @@ -49,26 +57,77 @@ .In stdio.h .In xlocale.h .Ft int -.Fn printf_l "locale_t loc" "const char * restrict format" ... +.Fo asprintf_l +.Fa "char **ret" +.Fa "locale_t loc" +.Fa "const char *format" +.Fa ... +.Fc .Ft int -.Fn fprintf_l "FILE * restrict stream" "locale_t loc" "const char * restrict format" ... +.Fo fprintf_l +.Fa "FILE * restrict stream" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa ... +.Fc .Ft int -.Fn sprintf_l "char * restrict str" "locale_t loc" "const char * restrict format" ... +.Fo printf_l +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa ... +.Fc .Ft int -.Fn snprintf_l "char * restrict str" "size_t size" "locale_t loc" "const char * restrict format" ... +.Fo snprintf_l +.Fa "char * restrict str" +.Fa "size_t size" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa ... +.Fc .Ft int -.Fn asprintf_l "char **ret" "locale_t loc" "const char *format" ... +.Fo sprintf_l +.Fa "char * restrict str" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa ... +.Fc .In stdarg.h +.In xlocale.h .Ft int -.Fn vprintf_l "locale_t loc" "const char * restrict format" "va_list ap" +.Fo vasprintf_l +.Fa "char **ret" +.Fa "locale_t loc" +.Fa "const char *format" +.Fa "va_list ap" +.Fc .Ft int -.Fn vfprintf_l "FILE * restrict stream" "locale_t loc" "const char * restrict format" "va_list ap" +.Fo vfprintf_l +.Fa "FILE * restrict stream" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa "va_list ap" +.Fc .Ft int -.Fn vsprintf_l "char * restrict str" "locale_t loc" "const char * restrict format" "va_list ap" +.Fo vprintf_l +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa "va_list ap" +.Fc .Ft int -.Fn vsnprintf_l "char * restrict str" "size_t size" "locale_t loc" "const char * restrict format" "va_list ap" +.Fo vsnprintf_l +.Fa "char * restrict str" +.Fa "size_t size" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa "va_list ap" +.Fc .Ft int -.Fn vasprintf_l "char **ret" "locale_t loc" "const char *format" "va_list ap" +.Fo vsprintf_l +.Fa "char * restrict str" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa "va_list ap" +.Fc .Sh DESCRIPTION The .Fn printf_l , diff --git a/stdio/putc-fbsd.c b/stdio/putc-fbsd.c new file mode 100644 index 0000000..e78bb42 --- /dev/null +++ b/stdio/putc-fbsd.c @@ -0,0 +1,63 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +#undef putc + +int +putc(c, fp) + int c; + FILE *fp; +{ + int retval; + FLOCKFILE(fp); + /* Orientation set by __sputc() when buffer is full. */ + /* ORIENT(fp, -1); */ + retval = __sputc(c, fp); + FUNLOCKFILE(fp); + return (retval); +} diff --git a/stdio/putc.3 b/stdio/putc.3 new file mode 100644 index 0000000..877a92b --- /dev/null +++ b/stdio/putc.3 @@ -0,0 +1,185 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd January 10, 2003 +.Dt PUTC 3 +.Os +.Sh NAME +.Nm fputc , +.Nm putc , +.Nm putc_unlocked , +.Nm putchar , +.Nm putchar_unlocked , +.Nm putw +.Nd output a character or word to a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft int +.Fo fputc +.Fa "int c" +.Fa "FILE *stream" +.Fc +.Ft int +.Fo putc +.Fa "int c" +.Fa "FILE *stream" +.Fc +.Ft int +.Fo putc_unlocked +.Fa "int c" +.Fa "FILE *stream" +.Fc +.Ft int +.Fo putchar +.Fa "int c" +.Fc +.Ft int +.Fo putchar_unlocked +.Fa "int c" +.Fc +.Ft int +.Fo putw +.Fa "int w" +.Fa "FILE *stream" +.Fc +.Sh DESCRIPTION +The +.Fn fputc +function +writes the character +.Fa c +(converted to an ``unsigned char'') +to the output stream pointed to by +.Fa stream . +.Pp +The +.Fn putc +macro acts essentially identically to +.Fn fputc , +but is a macro that expands in-line. +It may evaluate +.Fa stream +more than once, so arguments given to +.Fn putc +should not be expressions with potential side effects. +.Pp +The +.Fn putchar +function +is identical to +.Fn putc +with an output stream of +.Dv stdout . +.Pp +The +.Fn putw +function +writes the specified +.Vt int +to the named output +.Fa stream . +.Pp +The +.Fn putc_unlocked +and +.Fn putchar_unlocked +functions are equivalent to +.Fn putc +and +.Fn putchar +respectively, +except that the caller is responsible for locking the stream +with +.Xr flockfile 3 +before calling them. +These functions may be used to avoid the overhead of locking the stream +for each character, and to avoid output being interspersed from multiple +threads writing to the same stream. +.Sh RETURN VALUES +The functions, +.Fn fputc , +.Fn putc , +.Fn putchar , +.Fn putc_unlocked , +and +.Fn putchar_unlocked +return the character written. +If an error occurs, the value +.Dv EOF +is returned. +The +.Fn putw +function +returns 0 on success; +.Dv EOF +is returned if +a write error occurs, +or if an attempt is made to write a read-only stream. +.Sh SEE ALSO +.Xr ferror 3 , +.Xr flockfile 3 , +.Xr fopen 3 , +.Xr getc 3 , +.Xr putwc 3 , +.Xr stdio 3 +.Sh STANDARDS +The functions +.Fn fputc , +.Fn putc , +and +.Fn putchar , +conform to +.St -isoC . +The +.Fn putc_unlocked +and +.Fn putchar_unlocked +functions conform to +.St -p1003.1-2001 . +A function +.Fn putw +function appeared in +.At v6 . +.Sh BUGS +The size and byte order of an +.Vt int +varies from one machine to another, and +.Fn putw +is not recommended for portable applications. diff --git a/stdio/putchar-fbsd.c b/stdio/putchar-fbsd.c new file mode 100644 index 0000000..d23161d --- /dev/null +++ b/stdio/putchar-fbsd.c @@ -0,0 +1,67 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +#undef putchar + +/* + * A subroutine version of the macro putchar + */ +int +putchar(c) + int c; +{ + int retval; + FILE *so = stdout; + + FLOCKFILE(so); + /* Orientation set by __sputc() when buffer is full. */ + /* ORIENT(so, -1); */ + retval = __sputc(c, so); + FUNLOCKFILE(so); + return (retval); +} diff --git a/stdio/puts-fbsd.c b/stdio/puts-fbsd.c new file mode 100644 index 0000000..ef7faed --- /dev/null +++ b/stdio/puts-fbsd.c @@ -0,0 +1,81 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "fvwrite.h" +#include "libc_private.h" +#include "local.h" + +// 3340719: __puts_null__ is used if string is NULL. Shared by fputs.c +__private_extern__ char const __puts_null__[] = "(null)"; + +/* + * Write the given string to stdout, appending a newline. + */ +int +puts(s) + char const *s; +{ + int retval; + size_t c; + struct __suio uio; + struct __siov iov[2]; + + // 3340719: __puts_null__ is used if s is NULL + if(s == NULL) + s = __puts_null__; + iov[0].iov_base = (void *)s; + iov[0].iov_len = c = strlen(s); + iov[1].iov_base = "\n"; + iov[1].iov_len = 1; + uio.uio_resid = c + 1; + uio.uio_iov = &iov[0]; + uio.uio_iovcnt = 2; + FLOCKFILE(stdout); + ORIENT(stdout, -1); + retval = __sfvwrite(stdout, &uio) ? EOF : '\n'; + FUNLOCKFILE(stdout); + return (retval); +} diff --git a/stdio/putw-fbsd.c b/stdio/putw-fbsd.c new file mode 100644 index 0000000..ee0c23b --- /dev/null +++ b/stdio/putw-fbsd.c @@ -0,0 +1,66 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "fvwrite.h" +#include "libc_private.h" + +int +putw(w, fp) + int w; + FILE *fp; +{ + int retval; + struct __suio uio; + struct __siov iov; + + iov.iov_base = &w; + iov.iov_len = uio.uio_resid = sizeof(w); + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + FLOCKFILE(fp); + retval = __sfvwrite(fp, &uio); + FUNLOCKFILE(fp); + return (retval); +} diff --git a/stdio/putwc-fbsd.c b/stdio/putwc-fbsd.c new file mode 100644 index 0000000..e854309 --- /dev/null +++ b/stdio/putwc-fbsd.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2002 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/putwc.c,v 1.3 2004/05/25 10:42:52 tjr Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +#undef putwc + +/* + * Synonym for fputwc(). The only difference is that putwc(), if it is a + * macro, may evaluate `fp' more than once. + */ +wint_t +putwc(wchar_t wc, FILE *fp) +{ + + return (fputwc_l(wc, fp, __current_locale())); +} + +wint_t +putwc_l(wchar_t wc, FILE *fp, locale_t loc) +{ + + /* no need to call NORMALIZE_LOCALE(loc) because fputwc_l will */ + return (fputwc_l(wc, fp, loc)); +} diff --git a/stdio/putwc.3 b/stdio/putwc.3 new file mode 100644 index 0000000..f727d91 --- /dev/null +++ b/stdio/putwc.3 @@ -0,0 +1,122 @@ +.\" $NetBSD: putwc.3,v 1.2 2002/02/07 07:00:26 ross Exp $ +.\" +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd March 3, 2004 +.Dt PUTWC 3 +.Os +.Sh NAME +.Nm fputwc , +.Nm putwc , +.Nm putwchar +.Nd output a wide character to a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft wint_t +.Fo fputwc +.Fa "wchar_t wc" +.Fa "FILE *stream" +.Fc +.Ft wint_t +.Fo putwc +.Fa "wchar_t wc" +.Fa "FILE *stream" +.Fc +.Ft wint_t +.Fo putwchar +.Fa "wchar_t wc" +.Fc +.Sh DESCRIPTION +The +.Fn fputwc +function +writes the wide character +.Fa wc +to the output stream pointed to by +.Fa stream . +.Pp +The +.Fn putwc +function +acts essentially identically to +.Fn fputwc . +.Pp +The +.Fn putwchar +function +is identical to +.Fn putwc +with an output stream of +.Dv stdout . +.Pp +Extended locale versions of these functions are documented in +.Xr putwc_l 3 . +See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn fputwc , +.Fn putwc , +and +.Fn putwchar +functions +return the wide character written. +If an error occurs, the value +.Dv WEOF +is returned. +.Sh SEE ALSO +.Xr ferror 3 , +.Xr fopen 3 , +.Xr getwc 3 , +.Xr putc 3 , +.Xr putwc_l 3 , +.Xr stdio 3 +.Sh STANDARDS +The +.Fn fputwc , +.Fn putwc , +and +.Fn putwchar +functions +conform to +.St -isoC-99 . diff --git a/stdio/putwchar-fbsd.c b/stdio/putwchar-fbsd.c new file mode 100644 index 0000000..bc3ef1f --- /dev/null +++ b/stdio/putwchar-fbsd.c @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2002 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/putwchar.c,v 1.3 2004/05/25 10:42:52 tjr Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +#undef putwchar + +/* + * Synonym for fputwc(wc, stdout). + */ +wint_t +putwchar(wchar_t wc) +{ + + return (fputwc_l(wc, stdout, __current_locale())); +} + +wint_t +putwchar_l(wchar_t wc, locale_t loc) +{ + + /* no need to call NORMALIZE_LOCALE(loc) because fputwc_l will */ + return (fputwc_l(wc, stdout, loc)); +} diff --git a/stdio/refill-fbsd.c b/stdio/refill-fbsd.c new file mode 100644 index 0000000..edd8bb6 --- /dev/null +++ b/stdio/refill-fbsd.c @@ -0,0 +1,150 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" +#include "local.h" + +static int lflush(FILE *); + +static int +lflush(FILE *fp) +{ + int ret = 0; + + if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) { + FLOCKFILE(fp); + ret = __sflush(fp); + FUNLOCKFILE(fp); + } + return (ret); +} + +/* + * Refill a stdio buffer. + * Return EOF on eof or error, 0 otherwise. + */ +int +__srefill(FILE *fp) +{ + + /* make sure stdio is set up */ + if (!__sdidinit) + __sinit(); + + ORIENT(fp, -1); + + fp->_r = 0; /* largely a convenience for callers */ + + /* SysV does not make this test; take it out for compatibility */ + if (fp->_flags & __SEOF) + return (EOF); + + /* if not already reading, have to be reading and writing */ + if ((fp->_flags & __SRD) == 0) { + if ((fp->_flags & __SRW) == 0) { + errno = EBADF; + fp->_flags |= __SERR; + return (EOF); + } + /* switch to reading */ + if (fp->_flags & __SWR) { + if (__sflush(fp)) + return (EOF); + fp->_flags &= ~__SWR; + fp->_w = 0; + fp->_lbfsize = 0; + } + fp->_flags |= __SRD; + } else { + /* + * We were reading. If there is an ungetc buffer, + * we must have been reading from that. Drop it, + * restoring the previous buffer (if any). If there + * is anything in that buffer, return. + */ + if (HASUB(fp)) { + FREEUB(fp); + if ((fp->_r = fp->_ur) != 0) { + fp->_p = fp->_extra->_up; + return (0); + } + } + } + + if (fp->_bf._base == NULL) + __smakebuf(fp); + + /* + * Before reading from a line buffered or unbuffered file, + * flush all line buffered output files, per the ANSI C + * standard. + */ + if (fp->_flags & (__SLBF|__SNBF)) { + /* Ignore this file in _fwalk to avoid potential deadlock. */ + fp->_flags |= __SIGN; + (void) _fwalk(lflush); + fp->_flags &= ~__SIGN; + + /* Now flush this file without locking it. */ + if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) + __sflush(fp); + } + fp->_p = fp->_bf._base; + fp->_r = _sread(fp, (char *)fp->_p, fp->_bf._size); + fp->_flags &= ~__SMOD; /* buffer contents are again pristine */ + if (fp->_r <= 0) { + if (fp->_r == 0) + fp->_flags |= __SEOF; + else { + fp->_r = 0; + fp->_flags |= __SERR; + } + return (EOF); + } + return (0); +} diff --git a/stdio/remove-fbsd.c b/stdio/remove-fbsd.c new file mode 100644 index 0000000..2553f64 --- /dev/null +++ b/stdio/remove-fbsd.c @@ -0,0 +1,59 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include +#include +#include + +int +remove(file) + const char *file; +{ + struct stat sb; + + if (lstat(file, &sb) < 0) + return (-1); + if (S_ISDIR(sb.st_mode)) + return (rmdir(file)); + return (unlink(file)); +} diff --git a/stdio/remove.3 b/stdio/remove.3 new file mode 100644 index 0000000..42745de --- /dev/null +++ b/stdio/remove.3 @@ -0,0 +1,87 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt REMOVE 3 +.Os +.Sh NAME +.Nm remove +.Nd remove directory entry +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft int +.Fn remove "const char *path" +.Sh DESCRIPTION +The +.Fn remove +function removes the file or directory specified by +.Fa path . +.Pp +If +.Fa path +specifies a directory, +.Fn remove "path" +is the equivalent of +.Fn rmdir "path" . +Otherwise, it is the equivalent of +.Fn unlink "path" . +.Sh RETURN VALUES +.Rv -std remove +.Sh ERRORS +The +.Fn remove +function +may fail and set +.Va errno +for any of the errors specified for the routines +.Xr lstat 2 , +.Xr rmdir 2 , +or +.Xr unlink 2 . +.Sh SEE ALSO +.Xr rmdir 2 , +.Xr unlink 2 +.Sh STANDARDS +The +.Fn remove +function conforms to +.St -isoC +and +.St -xpg4.2 . diff --git a/stdio/rewind-fbsd.c b/stdio/rewind-fbsd.c new file mode 100644 index 0000000..9ade822 --- /dev/null +++ b/stdio/rewind-fbsd.c @@ -0,0 +1,65 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +void +rewind(FILE *fp) +{ + int serrno = errno; + + /* make sure stdio is set up */ + if (!__sdidinit) + __sinit(); + + FLOCKFILE(fp); + if (_fseeko(fp, (off_t)0, SEEK_SET, 1) == 0) { + errno = serrno; + } + clearerr_unlocked(fp); /* POSIX: clear stdio error regardless */ + FUNLOCKFILE(fp); +} diff --git a/stdio/rget-fbsd.c b/stdio/rget-fbsd.c new file mode 100644 index 0000000..9b7f586 --- /dev/null +++ b/stdio/rget-fbsd.c @@ -0,0 +1,59 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include "local.h" + +/* + * Handle getc() when the buffer ran out: + * Refill, then return the first character + * in the newly-filled buffer. + */ +int +__srget(FILE *fp) +{ + if (__srefill(fp) == 0) { + fp->_r--; + return (*fp->_p++); + } + return (EOF); +} diff --git a/stdio/scanf-fbsd.c b/stdio/scanf-fbsd.c new file mode 100644 index 0000000..f4cb68d --- /dev/null +++ b/stdio/scanf-fbsd.c @@ -0,0 +1,79 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +int +scanf(char const * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + FLOCKFILE(stdin); + ret = __svfscanf_l(stdin, __current_locale(), fmt, ap); + FUNLOCKFILE(stdin); + va_end(ap); + return (ret); +} + +int +scanf_l(locale_t loc, char const * __restrict fmt, ...) +{ + int ret; + va_list ap; + + NORMALIZE_LOCALE(loc); + va_start(ap, fmt); + FLOCKFILE(stdin); + ret = __svfscanf_l(stdin, loc, fmt, ap); + FUNLOCKFILE(stdin); + va_end(ap); + return (ret); +} diff --git a/stdio/scanf.3 b/stdio/scanf.3 new file mode 100644 index 0000000..fcf015b --- /dev/null +++ b/stdio/scanf.3 @@ -0,0 +1,543 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd January 4, 2003 +.Dt SCANF 3 +.Os +.Sh NAME +.Nm fscanf , +.Nm scanf , +.Nm sscanf , +.Nm vfscanf , +.Nm vscanf , +.Nm vsscanf +.Nd input format conversion +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft int +.Fo fscanf +.Fa "FILE *restrict stream" +.Fa "const char *restrict format" ... +.Fc +.Ft int +.Fo scanf +.Fa "const char *restrict format" ... +.Fc +.Ft int +.Fo sscanf +.Fa "const char *restrict s" +.Fa "const char *restrict format" ... +.Fc +.In stdarg.h +.In stdio.h +.Ft int +.Fo vfscanf +.Fa "FILE *restrict stream" +.Fa "const char *restrict format" +.Fa "va_list arg" +.Fc +.Ft int +.Fo vscanf +.Fa "const char *restrict format" +.Fa "va_list arg" +.Fc +.Ft int +.Fo vsscanf +.Fa "const char *restrict s" +.Fa "const char *restrict format" +.Fa "va_list arg" +.Fc +.Sh DESCRIPTION +The +.Fn scanf +family of functions scans input according to a +.Fa format , +as described below. +This format may contain +.Em conversion specifiers ; +the results from such conversions, if any, +are stored through the +.Em pointer +arguments. +The +.Fn scanf +function +reads input from the standard input stream +.Dv stdin , +.Fn fscanf +reads input from the stream pointer +.Fa stream , +and +.Fn sscanf +reads its input from the character string pointed to by +.Fa s . +.Pp +The +.Fn vfscanf +function +is analogous to +.Xr vfprintf 3 +and reads input from the stream pointer +.Fa stream +using a variable argument list of pointers (see +.Xr stdarg 3 ) . +The +.Fn vscanf +function scans a variable argument list from the standard input and +the +.Fn vsscanf +function scans it from a string; +these are analogous to +the +.Fn vprintf +and +.Fn vsprintf +functions, respectively. +.Pp +Each successive +.Em pointer +argument must correspond properly with +each successive conversion specifier +(but see the +.Cm * +conversion below). +All conversions are introduced by the +.Cm % +(percent sign) character. +The +.Fa format +string +may also contain other characters. +White space (such as blanks, tabs, or newlines) in the +.Fa format +string match any amount of white space, including none, in the input. +Everything else +matches only itself. +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). +.Pp +Extended locale versions of these functions are documented in +.Xr scanf_l 3 . +See +.Xr xlocale 3 +for more information. +.Sh CONVERSIONS +Following the +.Cm % +character introducing a conversion, +there may be a number of +.Em flag +characters, as follows: +.Bl -tag -width ".Cm l No (ell)" +.It Cm * +Suppresses assignment. +The conversion that follows occurs as usual, but no pointer is used; +the result of the conversion is simply discarded. +.It Cm hh +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt char +(rather than +.Vt int ) . +.It Cm h +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt "short int" +(rather than +.Vt int ) . +.It Cm l No (ell) +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt "long int" +(rather than +.Vt int ) , +that the conversion will be one of +.Cm a , e , f , +or +.Cm g +and the next pointer is a pointer to +.Vt double +(rather than +.Vt float ) , +or that the conversion will be one of +.Cm c , +.Cm s +or +.Cm \&[ +and the next pointer is a pointer to an array of +.Vt wchar_t +(rather than +.Vt char ) . +.It Cm ll No (ell ell) +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt "long long int" +(rather than +.Vt int ) . +.It Cm L +Indicates that the conversion will be one of +.Cm a , e , f , +or +.Cm g +and the next pointer is a pointer to +.Vt "long double" . +.It Cm j +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt intmax_t +(rather than +.Vt int ) . +.It Cm t +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt ptrdiff_t +(rather than +.Vt int ) . +.It Cm z +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt size_t +(rather than +.Vt int ) . +.It Cm q +(deprecated.) +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt "long long int" +(rather than +.Vt int ) . +.El +.Pp +In addition to these flags, +there may be an optional maximum field width, +expressed as a decimal integer, +between the +.Cm % +and the conversion. +If no width is given, +a default of +.Dq infinity +is used (with one exception, below); +otherwise at most this many bytes are scanned +in processing the conversion. +In the case of the +.Cm lc , +.Cm ls +and +.Cm l[ +conversions, the field width specifies the maximum number +of multibyte characters that will be scanned. +Before conversion begins, +most conversions skip white space; +this white space is not counted against the field width. +.Pp +The following conversions are available: +.Bl -tag -width XXXX +.It Cm % +Matches a literal +.Ql % . +That is, +.Dq Li %% +in the format string +matches a single input +.Ql % +character. +No conversion is done, and assignment does not occur. +.It Cm d +Matches an optionally signed decimal integer; +the next pointer must be a pointer to +.Vt int . +.It Cm i +Matches an optionally signed integer; +the next pointer must be a pointer to +.Vt int . +The integer is read in base 16 if it begins +with +.Ql 0x +or +.Ql 0X , +in base 8 if it begins with +.Ql 0 , +and in base 10 otherwise. +Only characters that correspond to the base are used. +.It Cm o +Matches an octal integer; +the next pointer must be a pointer to +.Vt "unsigned int" . +.It Cm u +Matches an optionally signed decimal integer; +the next pointer must be a pointer to +.Vt "unsigned int" . +.It Cm x , X +Matches an optionally signed hexadecimal integer; +the next pointer must be a pointer to +.Vt "unsigned int" . +.It Cm a , A , e , E , f , F , g , G +Matches a floating-point number in the style of +.Xr strtod 3 . +The next pointer must be a pointer to +.Vt float +(unless +.Cm l +or +.Cm L +is specified.) +.It Cm s +Matches a sequence of non-white-space characters; +the next pointer must be a pointer to +.Vt char , +and the array must be large enough to accept all the sequence and the +terminating +.Dv NUL +character. +The input string stops at white space +or at the maximum field width, whichever occurs first. +.Pp +If an +.Cm l +qualifier is present, the next pointer must be a pointer to +.Vt wchar_t , +into which the input will be placed after conversion by +.Xr mbrtowc 3 . +.It Cm S +The same as +.Cm ls . +.It Cm c +Matches a sequence of +.Em width +count +characters (default 1); +the next pointer must be a pointer to +.Vt char , +and there must be enough room for all the characters +(no terminating +.Dv NUL +is added). +The usual skip of leading white space is suppressed. +To skip white space first, use an explicit space in the format. +.Pp +If an +.Cm l +qualifier is present, the next pointer must be a pointer to +.Vt wchar_t , +into which the input will be placed after conversion by +.Xr mbrtowc 3 . +.It Cm C +The same as +.Cm lc . +.It Cm \&[ +Matches a nonempty sequence of characters from the specified set +of accepted characters; +the next pointer must be a pointer to +.Vt char , +and there must be enough room for all the characters in the string, +plus a terminating +.Dv NUL +character. +The usual skip of leading white space is suppressed. +The string is to be made up of characters in +(or not in) +a particular set; +the set is defined by the characters between the open bracket +.Cm [ +character +and a close bracket +.Cm ] +character. +The set +.Em excludes +those characters +if the first character after the open bracket is a circumflex +.Cm ^ . +To include a close bracket in the set, +make it the first character after the open bracket +or the circumflex; +any other position will end the set. +The hyphen character +.Cm - +is also special; +when placed between two other characters, +it adds all intervening characters to the set. +To include a hyphen, +make it the last character before the final close bracket. +For instance, +.Ql [^]0-9-] +means the set +.Dq "everything except close bracket, zero through nine, and hyphen" . +The string ends with the appearance of a character not in the +(or, with a circumflex, in) set +or when the field width runs out. +.Pp +If an +.Cm l +qualifier is present, the next pointer must be a pointer to +.Vt wchar_t , +into which the input will be placed after conversion by +.Xr mbrtowc 3 . +.It Cm p +Matches a pointer value (as printed by +.Ql %p +in +.Xr printf 3 ) ; +the next pointer must be a pointer to +.Vt void . +.It Cm n +Nothing is expected; +instead, the number of characters consumed thus far from the input +is stored through the next pointer, +which must be a pointer to +.Vt int . +This is +.Em not +a conversion, although it can be suppressed with the +.Cm * +flag. +.El +.Pp +The decimal point +character is defined in the program's locale (category +.Dv LC_NUMERIC ) . +.Pp +For backwards compatibility, a +.Dq conversion +of +.Ql %\e0 +causes an immediate return of +.Dv EOF . +.Sh RETURN VALUES +These functions return the number of input items assigned. +This can be fewer than provided for, or even zero, +in the event of a matching failure. +Zero indicates that, although there was input available, +no conversions were assigned; +typically this is due to an invalid input character, +such as an alphabetic character for a +.Ql %d +conversion. +The value +.Dv EOF +is returned if an input failure occurs before any conversion such as an +end-of-file occurs. +If an error or end-of-file occurs after conversion +has begun, +the number of conversions which were successfully completed is returned. +.Sh SEE ALSO +.Xr getc 3 , +.Xr mbrtowc 3 , +.Xr printf 3 , +.Xr scanf_l 3 , +.Xr strtod 3 , +.Xr strtol 3 , +.Xr strtoul 3 , +.Xr wscanf 3 +.Sh STANDARDS +The functions +.Fn fscanf , +.Fn scanf , +.Fn sscanf , +.Fn vfscanf , +.Fn vscanf , +and +.Fn vsscanf +conform to +.St -isoC-99 . +.Sh BUGS +Earlier implementations of +.Nm +treated +.Cm \&%D , \&%E , \&%F , \&%O +and +.Cm \&%X +as their lowercase equivalents with an +.Cm l +modifier. +In addition, +.Nm +treated an unknown conversion character as +.Cm \&%d +or +.Cm \&%D , +depending on its case. +This functionality has been removed. +.Pp +Numerical strings are truncated to 512 characters; for example, +.Cm %f +and +.Cm %d +are implicitly +.Cm %512f +and +.Cm %512d . +.Pp +The +.Cm %n$ +modifiers for positional arguments are not implemented. +.Pp +The +.Nm +family of functions do not correctly handle multibyte characters in the +.Fa format +argument. diff --git a/stdio/scanf_l.3 b/stdio/scanf_l.3 index a63cedf..90bea68 100644 --- a/stdio/scanf_l.3 +++ b/stdio/scanf_l.3 @@ -40,12 +40,12 @@ .Dt SCANF_L 3 .Os .Sh NAME -.Nm scanf_l , .Nm fscanf_l , +.Nm scanf_l , .Nm sscanf_l , +.Nm vfscanf_l , .Nm vscanf_l , -.Nm vsscanf_l , -.Nm vfscanf_l +.Nm vsscanf_l .Nd input format conversion .Sh LIBRARY .Lb libc @@ -53,18 +53,47 @@ .In stdio.h .In xlocale.h .Ft int -.Fn scanf_l "locale_t loc" "const char * restrict format" ... +.Fo fscanf_l +.Fa "FILE * restrict stream" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa ... +.Fc .Ft int -.Fn fscanf_l "FILE * restrict stream" "locale_t loc" "const char * restrict format" ... +.Fo scanf_l +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa ... +.Fc .Ft int -.Fn sscanf_l "const char * restrict str" "locale_t loc" "const char * restrict format" ... +.Fo sscanf_l +.Fa "const char * restrict str" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa ... +.Fc .In stdarg.h +.In xlocale.h .Ft int -.Fn vscanf_l "locale_t loc" "const char * restrict format" "va_list ap" +.Fo vfscanf_l +.Fa "FILE * restrict stream" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa "va_list ap" +.Fc .Ft int -.Fn vsscanf_l "const char * restrict str" "locale_t loc" "const char * restrict format" "va_list ap" +.Fo vscanf_l +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa "va_list ap" +.Fc .Ft int -.Fn vfscanf_l "FILE * restrict stream" "locale_t loc" "const char * restrict format" "va_list ap" +.Fo vsscanf_l +.Fa "const char * restrict str" +.Fa "locale_t loc" +.Fa "const char * restrict format" +.Fa "va_list ap" +.Fc .Sh DESCRIPTION The .Fn scanf_l , diff --git a/stdio/setbuf-fbsd.c b/stdio/setbuf-fbsd.c new file mode 100644 index 0000000..5eb6fb1 --- /dev/null +++ b/stdio/setbuf-fbsd.c @@ -0,0 +1,50 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include "local.h" + +void +setbuf(FILE * __restrict fp, char * __restrict buf) +{ + (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ); +} diff --git a/stdio/setbuf.3 b/stdio/setbuf.3 new file mode 100644 index 0000000..da56bf4 --- /dev/null +++ b/stdio/setbuf.3 @@ -0,0 +1,226 @@ +.\" Copyright (c) 1980, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt SETBUF 3 +.Os +.Sh NAME +.Nm setbuf , +.Nm setbuffer , +.Nm setlinebuf , +.Nm setvbuf +.Nd stream buffering operations +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft void +.Fo setbuf +.Fa "FILE *restrict stream" +.Fa "char *restrict buf" +.Fc +.Ft void +.Fo setbuffer +.Fa "FILE *stream" +.Fa "char *buf" +.Fa "int size" +.Fc +.Ft int +.Fo setlinebuf +.Fa "FILE *stream" +.Fc +.Ft int +.Fo setvbuf +.Fa "FILE *restrict stream" +.Fa "char *restrict buf" +.Fa "int type" +.Fa "size_t size" +.Fc +.Sh DESCRIPTION +Three types of buffering are available: +unbuffered, block buffered, and line buffered. +When an output stream is unbuffered, information appears on the +destination file or terminal as soon as written; +when it is block buffered, +many characters are saved up and written as a block; +when it is line buffered, +characters are saved up until a newline is output +or input is read from any stream attached to a terminal device +(typically +.Dv stdin ) . +The function +.Xr fflush 3 +may be used to force the block out early. +(See +.Xr fclose 3 . ) +.Pp +Normally, all files are block buffered. +When the first +.Tn I/O +operation occurs on a file, +.Xr malloc 3 +is called and an optimally-sized buffer is obtained. +If a stream refers to a terminal +(as +.Dv stdout +normally does), it is line buffered. +The standard error stream +.Dv stderr +is always unbuffered. +.Pp +The +.Fn setvbuf +function +may be used to alter the buffering behavior of a stream. +The +.Fa type +argument must be one of the following three macros: +.Bl -tag -width _IOFBF -offset indent +.It Dv _IONBF +unbuffered +.It Dv _IOLBF +line buffered +.It Dv _IOFBF +fully buffered +.El +.Pp +The +.Fa size +argument may be given as zero +to obtain deferred optimal-size buffer allocation as usual. +If it is not zero, +then except for unbuffered files, the +.Fa buf +argument should point to a buffer at least +.Fa size +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 +.Xr free 3 +this buffer after closing the stream. +(If the +.Fa size +argument +is not zero but +.Fa buf +is +.Dv NULL , +a buffer of the given size will be allocated immediately, +and released on close. +This is an extension to ANSI C; +portable code should use a size of 0 with any +.Dv NULL +buffer.) +.Pp +The +.Fn setvbuf +function may be used at any time, +but may have peculiar side effects +(such as discarding input or flushing output) +if the stream is ``active''. +Portable applications should call it only once on any given stream, +and before any +.Tn I/O +is performed. +.Pp +The other three calls are, in effect, simply aliases for calls to +.Fn setvbuf . +Except for the lack of a return value, the +.Fn setbuf +function is exactly equivalent to the call +.Pp +.Dl "setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);" +.Pp +The +.Fn setbuffer +function +is the same, except that the size of the buffer is up to the caller, +rather than being determined by the default +.Dv BUFSIZ . +The +.Fn setlinebuf +function +is exactly equivalent to the call: +.Pp +.Dl "setvbuf(stream, (char *)NULL, _IOLBF, 0);" +.Sh RETURN VALUES +The +.Fn setvbuf +function returns 0 on success, or +.Dv EOF +if the request cannot be honored +(note that the stream is still functional in this case). +.Pp +The +.Fn setlinebuf +function returns what the equivalent +.Fn setvbuf +would have returned. +.Sh SEE ALSO +.Xr fclose 3 , +.Xr fopen 3 , +.Xr fread 3 , +.Xr malloc 3 , +.Xr printf 3 , +.Xr puts 3 +.Sh STANDARDS +The +.Fn setbuf +and +.Fn setvbuf +functions +conform to +.St -isoC . +.Sh BUGS +The +.Fn setbuffer +and +.Fn setlinebuf +functions are not portable to versions of +.Bx +before +.Bx 4.2 . +On +.Bx 4.2 +and +.Bx 4.3 +systems, +.Fn setbuf +always uses a suboptimal buffer size and should be avoided. diff --git a/stdio/setbuffer-fbsd.c b/stdio/setbuffer-fbsd.c new file mode 100644 index 0000000..6ec4376 --- /dev/null +++ b/stdio/setbuffer-fbsd.c @@ -0,0 +1,64 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +void +setbuffer(fp, buf, size) + FILE *fp; + char *buf; + int size; +{ + + (void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, (size_t)size); +} + +/* + * set line buffering + */ +int +setlinebuf(fp) + FILE *fp; +{ + + return (setvbuf(fp, (char *)NULL, _IOLBF, (size_t)0)); +} diff --git a/stdio/setvbuf-fbsd.c b/stdio/setvbuf-fbsd.c new file mode 100644 index 0000000..166d5b1 --- /dev/null +++ b/stdio/setvbuf-fbsd.c @@ -0,0 +1,165 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +/* + * Set one of the three kinds of buffering, optionally including + * a buffer. + */ +int +setvbuf(FILE * __restrict fp, char * __restrict buf, int mode, size_t size) +{ + int ret, flags; + size_t iosize; + int ttyflag; + + /* + * Verify arguments. The `int' limit on `size' is due to this + * particular implementation. Note, buf and size are ignored + * when setting _IONBF. + */ + if (mode != _IONBF) + if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0) + return (EOF); + + FLOCKFILE(fp); + /* + * Write current buffer, if any. Discard unread input (including + * ungetc data), cancel line buffering, and free old buffer if + * malloc()ed. We also clear any eof condition, as if this were + * a seek. + */ + ret = 0; + (void)__sflush(fp); + if (HASUB(fp)) + FREEUB(fp); + fp->_r = fp->_lbfsize = 0; + flags = fp->_flags; + if (flags & __SMBF) + free((void *)fp->_bf._base); + flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SOFF | __SNPT | __SEOF); + + /* If setting unbuffered mode, skip all the hard work. */ + if (mode == _IONBF) + goto nbf; + + /* + * Find optimal I/O size for seek optimization. This also returns + * a `tty flag' to suggest that we check isatty(fd), but we do not + * care since our caller told us how to buffer. + */ + flags |= __swhatbuf(fp, &iosize, &ttyflag); + if (size == 0) { + buf = NULL; /* force local allocation */ + size = iosize; + } + + /* Allocate buffer if needed. */ + if (buf == NULL) { + if ((buf = malloc(size)) == NULL) { + /* + * Unable to honor user's request. We will return + * failure, but try again with file system size. + */ + ret = EOF; + if (size != iosize) { + size = iosize; + buf = malloc(size); + } + } + if (buf == NULL) { + /* No luck; switch to unbuffered I/O. */ +nbf: + fp->_flags = flags | __SNBF; + fp->_w = 0; + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; + FUNLOCKFILE(fp); + return (ret); + } + flags |= __SMBF; + } + + /* + * Kill any seek optimization if the buffer is not the + * right size. + * + * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)? + */ + if (size != iosize) + flags |= __SNPT; + + /* + * Fix up the FILE fields, and set __cleanup for output flush on + * exit (since we are buffered in some way). + */ + if (mode == _IOLBF) + flags |= __SLBF; + fp->_flags = flags; + fp->_bf._base = fp->_p = (unsigned char *)buf; + fp->_bf._size = size; + /* fp->_lbfsize is still 0 */ + if (flags & __SWR) { + /* + * Begin or continue writing: see __swsetup(). Note + * that __SNBF is impossible (it was handled earlier). + */ + if (flags & __SLBF) { + fp->_w = 0; + fp->_lbfsize = -fp->_bf._size; + } else + fp->_w = size; + } else { + /* begin/continue reading, or stay in intermediate state */ + fp->_w = 0; + } + __cleanup = _cleanup; + + FUNLOCKFILE(fp); + return (ret); +} diff --git a/stdio/snprintf-fbsd.c b/stdio/snprintf-fbsd.c new file mode 100644 index 0000000..6f4f83c --- /dev/null +++ b/stdio/snprintf-fbsd.c @@ -0,0 +1,107 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#include + +#include "local.h" + +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'; + va_end(ap); + return (ret); +} + +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'; + va_end(ap); + return (ret); +} diff --git a/stdio/sprintf-fbsd.c b/stdio/sprintf-fbsd.c new file mode 100644 index 0000000..38d534e --- /dev/null +++ b/stdio/sprintf-fbsd.c @@ -0,0 +1,91 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include "local.h" + +int +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); + va_end(ap); + *f._p = 0; + return (ret); +} + +int +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); + va_end(ap); + *f._p = 0; + return (ret); +} diff --git a/stdio/sscanf-fbsd.c b/stdio/sscanf-fbsd.c new file mode 100644 index 0000000..992032d --- /dev/null +++ b/stdio/sscanf-fbsd.c @@ -0,0 +1,108 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#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); + va_end(ap); + return (ret); +} + +int +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); + va_end(ap); + return (ret); +} diff --git a/stdio/stdio-fbsd.c b/stdio/stdio-fbsd.c new file mode 100644 index 0000000..233427c --- /dev/null +++ b/stdio/stdio-fbsd.c @@ -0,0 +1,191 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "local.h" + +/* + * Small standard I/O/seek/close functions. + */ +int +__sread(cookie, buf, n) + void *cookie; + char *buf; + int n; +{ + FILE *fp = cookie; + + return(_read(fp->_file, buf, (size_t)n)); +} + +int +__swrite(cookie, buf, n) + void *cookie; + char const *buf; + int n; +{ + FILE *fp = cookie; + + return (_write(fp->_file, buf, (size_t)n)); +} + +fpos_t +__sseek(cookie, offset, whence) + void *cookie; + fpos_t offset; + int whence; +{ + FILE *fp = cookie; + + return (lseek(fp->_file, (off_t)offset, whence)); +} + +int +__sclose(cookie) + void *cookie; +{ + + return (_close(((FILE *)cookie)->_file)); +} + +/* + * Higher level wrappers. + */ +int +_sread(fp, buf, n) + FILE *fp; + char *buf; + int n; +{ + int ret; + + ret = (*fp->_read)(fp->_cookie, buf, n); + if (ret > 0) { + if (fp->_flags & __SOFF) { + if (fp->_offset <= OFF_MAX - ret) + fp->_offset += ret; + else + fp->_flags &= ~__SOFF; + } + } else if (ret < 0) + fp->_flags &= ~__SOFF; + return (ret); +} + +int +_swrite(fp, buf, n) + FILE *fp; + char const *buf; + int n; +{ + int ret; + int serrno; + + if (fp->_flags & __SAPP) { + serrno = errno; + if (_sseek(fp, (fpos_t)0, SEEK_END) == -1 && + (fp->_flags & __SOPT)) + return (-1); + errno = serrno; + } + ret = (*fp->_write)(fp->_cookie, buf, n); + /* __SOFF removed even on success in case O_APPEND mode is set. */ + if (ret >= 0) { + if ((fp->_flags & (__SAPP|__SOFF)) == (__SAPP|__SOFF) && + fp->_offset <= OFF_MAX - ret) + fp->_offset += ret; + else + fp->_flags &= ~__SOFF; + + } else if (ret < 0) + fp->_flags &= ~__SOFF; + return (ret); +} + +fpos_t +_sseek(fp, offset, whence) + FILE *fp; + fpos_t offset; + int whence; +{ + fpos_t ret; + int serrno, errret; + + serrno = errno; + errno = 0; + ret = (*fp->_seek)(fp->_cookie, offset, whence); + errret = errno; + if (errno == 0) + errno = serrno; + /* + * Disallow negative seeks per POSIX. + * It is needed here to help upper level caller + * in the cases it can't detect. + */ + if (ret < 0) { + if (errret == 0) { + if (offset != 0 || whence != SEEK_CUR) { + if (HASUB(fp)) + FREEUB(fp); + fp->_p = fp->_bf._base; + fp->_r = 0; + fp->_flags &= ~__SEOF; + } + fp->_flags |= __SERR; + errno = EINVAL; + } else if (errret == ESPIPE) + fp->_flags &= ~__SAPP; + fp->_flags &= ~__SOFF; + ret = -1; + } else if (fp->_flags & __SOPT) { + fp->_flags |= __SOFF; + fp->_offset = ret; + } + return (ret); +} diff --git a/stdio/stdio.3 b/stdio/stdio.3 new file mode 100644 index 0000000..9831af0 --- /dev/null +++ b/stdio/stdio.3 @@ -0,0 +1,368 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd January 10, 2003 +.Dt STDIO 3 +.Os +.Sh NAME +.Nm stdio +.Nd standard input/output library functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Vt FILE *stdin ; +.Vt FILE *stdout ; +.Vt FILE *stderr ; +.Pp +Note: +The current implementation does not allow these variables +to be evaluated at C compile/link time. +That is, a runtime calculation must be performed, such as: +.Bd -literal -offset indent +#include + +static FILE *var; + +int main() { + var = stdout; +} +.Ed +.Sh DESCRIPTION +The standard +.Tn I/O +library provides a simple and efficient buffered stream +.Tn I/O +interface. +Input and output is mapped into logical data streams +and the physical +.Tn I/O +characteristics are concealed. +The functions and macros are listed +below; more information is available from the individual man pages. +.Pp +A stream is associated with an external file (which may be a physical +device) by +.Em opening +a file, which may involve creating a new file. +Creating an +existing file causes its former contents to be discarded. +If a file can support positioning requests (such as a disk file, as opposed +to a terminal) then a +.Em file position indicator +associated with the stream is positioned at the start of the file (byte +zero), unless the file is opened with append mode. +If append mode +is used, the position indicator will be placed at the end-of-file. +The position indicator is maintained by subsequent reads, writes +and positioning requests. +All input occurs as if the characters +were read by successive calls to the +.Xr fgetc 3 +function; all output takes place as if all characters were +written by successive calls to the +.Xr fputc 3 +function. +.Pp +A file is disassociated from a stream by +.Em closing +the file. +Output streams are flushed (any unwritten buffer contents are transferred +to the host environment) before the stream is disassociated from the file. +The value of a pointer to a +.Dv FILE +object is indeterminate (garbage) after a file is closed. +.Pp +A file may be subsequently reopened, by the same or another program +execution, and its contents reclaimed or modified (if it can be repositioned +at the start). +If the main function returns to its original caller, or +the +.Xr exit 3 +function is called, all open files are closed (hence all output +streams are flushed) before program termination. +Other methods +of program termination may not close files properly and hence +buffered output may be lost. +In particular, +.Xr _exit 2 +does not flush stdio files. +Neither does an exit due to a signal. +Buffers are flushed by +.Xr abort 3 +as required by POSIX, although previous implementations did not. +.Pp +This implementation makes no distinction between +.Dq text +and +.Dq binary +streams. +In effect, all streams are binary. +No translation is performed and no extra padding appears on any stream. +.Pp +At program startup, three streams are predefined and need not be +opened explicitly: +.Bl -bullet -compact -offset indent +.It +.Em standard input +(for reading conventional input), +.It +.Em standard output +(for writing conventional output), and +.It +.Em standard error +(for writing diagnostic output). +.El +These streams are abbreviated +.Dv stdin , stdout +and +.Dv stderr . +Initially, the standard error stream +is unbuffered; the standard input and output streams are +fully buffered if and only if the streams do not refer to +an interactive or +.Dq terminal +device, as determined by the +.Xr isatty 3 +function. +In fact, +.Em all +freshly-opened streams that refer to terminal devices +default to line buffering, and +pending output to such streams is written automatically +whenever such an input stream is read. +Note that this applies only to +.Dq "true reads" ; +if the read request can be satisfied by existing buffered data, +no automatic flush will occur. +In these cases, +or when a large amount of computation is done after printing +part of a line on an output terminal, it is necessary to +.Xr fflush 3 +the standard output before going off and computing so that the output +will appear. +Alternatively, these defaults may be modified via the +.Xr setvbuf 3 +function. +.Pp +The +.Nm +library is a part of the library +.Nm libc +and routines are automatically loaded as needed by the C compiler. +The +.Tn SYNOPSIS +sections of the following manual pages indicate which include files +are to be used, what the compiler declaration for the function +looks like and which external variables are of interest. +.Pp +The following are defined as macros; +these names may not be re-used +without first removing their current definitions with +.Ic #undef : +.Dv BUFSIZ , +.Dv EOF , +.Dv FILENAME_MAX , +.Dv FOPEN_MAX , +.Dv L_ctermid , +.Dv L_cuserid , +.Dv L_tmpnam , +.Dv NULL , +.Dv P_tmpdir , +.Dv SEEK_CUR , +.Dv SEEK_END , +.Dv SEEK_SET , +.Dv TMP_MAX , +.Dv clearerr , +.Dv clearerr_unlocked , +.Dv feof , +.Dv feof_unlocked , +.Dv ferror , +.Dv ferror_unlocked , +.Dv fileno , +.Dv fileno_unlocked , +.Dv fropen , +.Dv fwopen , +.Dv getc , +.Dv getc_unlocked , +.Dv getchar , +.Dv getchar_unlocked , +.Dv putc , +.Dv putc_unlocked , +.Dv putchar , +.Dv putchar_unlocked , +.Dv stderr , +.Dv stdin +and +.Dv stdout . +Function versions of the macro functions +.Dv clearerr , +.Dv clearerr_unlocked , +.Dv feof , +.Dv feof_unlocked , +.Dv ferror , +.Dv ferror_unlocked , +.Dv fileno , +.Dv fileno_unlocked , +.Dv getc , +.Dv getc_unlocked , +.Dv getchar , +.Dv getchar_unlocked , +.Dv putc , +.Dv putc_unlocked , +.Dv putchar , +and +.Dv putchar_unlocked +exist and will be used if the macro +definitions are explicitly removed. +.Sh LEGACY SYNOPSIS +The -D_NONSTD_SOURCE flag can be used +to allow stdin, stdout, and/or stderr +to be evaluated at compile/link time, as: +.Bd -literal -offset indent +#include + +static FILE *var = stdout; +.Ed +.Sh SEE ALSO +.Xr close 2 , +.Xr open 2 , +.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 +library conforms to +.St -isoC-99 . +.Sh LIST OF FUNCTIONS +.Bl -column "Description" +.It Sy "Function Description" +.It "asprintf formatted output conversion" +.It "" +.It "clearerr check and reset stream status" +.It "" +.It "fclose close a stream" +.It "fdopen stream open functions" +.It "feof check and reset stream status" +.It "ferror check and reset stream status" +.It "fflush flush a stream" +.It "fgetc get next character or word from input stream" +.It "fgetln get a line from a stream" +.It "fgetpos reposition a stream" +.It "fgets get a line from a stream" +.It "fgetwc get next wide character from input stream" +.It "fgetws get a line of wide characters from a stream" +.It "fileno check and reset stream status" +.It "fopen stream open functions" +.It "fprintf formatted output conversion" +.It "fpurge flush a stream" +.It "fputc output a character or word to a stream" +.It "fputs output a line to a stream" +.It "fputwc output a wide character to a stream" +.It "fputws output a line of wide characters to a stream" +.It "fread binary stream input/output" +.It "freopen stream open functions" +.It "fropen open a stream" +.It "fscanf input format conversion" +.It "fseek reposition a stream" +.It "fsetpos reposition a stream" +.It "ftell reposition a stream" +.It "funopen open a stream" +.It "fwide set/get orientation of stream" +.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 "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" +.It "" +.It "mkdtemp create unique temporary directory" +.It "mkstemp create unique temporary file" +.It "mktemp create unique temporary file" +.It "" +.It "perror system error messages" +.It "printf formatted output conversion" +.It "putc output a character or word to a stream" +.It "putchar output a character or word to a stream" +.It "puts output a line to a stream" +.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" +.It "" +.It "remove remove directory entry" +.It "rewind reposition a stream" +.It "" +.It "scanf input format conversion" +.It "setbuf stream buffering operations" +.It "setbuffer stream buffering operations" +.It "setlinebuf stream buffering operations" +.It "setvbuf stream buffering operations" +.It "snprintf formatted output conversion" +.It "sprintf formatted output conversion" +.It "sscanf input format conversion" +.It "strerror system error messages" +.It "swprintf formatted wide character output conversion" +.It "sys_errlist system error messages" +.It "sys_nerr system error messages" +.It "" +.It "tempnam temporary file routines" +.It "tmpfile temporary file routines" +.It "tmpnam temporary file routines" +.It "" +.It "ungetc un-get character from input stream" +.It "ungetwc un-get wide character from input stream" +.It "" +.It "vasprintf formatted output conversion" +.It "vfprintf formatted output conversion" +.It "vfscanf input format conversion" +.It "vfwprintf formatted wide character output conversion" +.It "vprintf formatted output conversion" +.It "vscanf input format conversion" +.It "vsnprintf formatted output conversion" +.It "vsprintf formatted output conversion" +.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 diff --git a/stdio/swprintf-fbsd.c b/stdio/swprintf-fbsd.c new file mode 100644 index 0000000..698b6c8 --- /dev/null +++ b/stdio/swprintf-fbsd.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2002 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/swprintf.c,v 1.1 2002/09/21 13:00:30 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include + +int +swprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vswprintf_l(s, n, __current_locale(), fmt, ap); + va_end(ap); + + return (ret); +} + +int +swprintf_l(wchar_t * __restrict s, size_t n, locale_t loc, + const wchar_t * __restrict fmt, ...) +{ + int ret; + va_list ap; + + /* no need to call NORMALIZE_LOCALE(loc) because vswprintf_l will */ + va_start(ap, fmt); + ret = vswprintf_l(s, n, loc, fmt, ap); + va_end(ap); + + return (ret); +} diff --git a/stdio/swscanf-fbsd.c b/stdio/swscanf-fbsd.c new file mode 100644 index 0000000..4fc850a --- /dev/null +++ b/stdio/swscanf-fbsd.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2002 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/swscanf.c,v 1.1 2002/09/23 12:40:06 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include + +int +swscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, ...) +{ + va_list ap; + int r; + + va_start(ap, fmt); + r = vswscanf_l(str, __current_locale(), fmt, ap); + va_end(ap); + + return (r); +} + +int +swscanf_l(const wchar_t * __restrict str, locale_t loc, + const wchar_t * __restrict fmt, ...) +{ + va_list ap; + int r; + + /* no need to call NORMALIZE_LOCALE(loc) because vswscanf_l will */ + va_start(ap, fmt); + r = vswscanf_l(str, loc, fmt, ap); + va_end(ap); + + return (r); +} diff --git a/stdio/tempnam-fbsd.c b/stdio/tempnam-fbsd.c new file mode 100644 index 0000000..83b4575 --- /dev/null +++ b/stdio/tempnam-fbsd.c @@ -0,0 +1,121 @@ +/* + * 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[] = "@(#)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 $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +__warn_references(tempnam, + "warning: tempnam() possibly used unsafely; consider using mkstemp()"); + +extern char *_mktemp(char *); + +char * +tempnam(dir, pfx) + const char *dir, *pfx; +{ + int sverrno; + char *f, *name; + +#if __DARWIN_UNIX03 + struct stat sb; +#endif /* __DARWIN_UNIX03 */ + if (!(name = malloc(MAXPATHLEN))) { + return(NULL); + } + + if (!pfx) + pfx = "tmp."; + +#if !__DARWIN_UNIX03 + if (issetugid() == 0 && (f = getenv("TMPDIR"))) { + (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, + *(f + strlen(f) - 1) == '/'? "": "/", pfx); + if ((f = _mktemp(name))) { + return(f); + } + } +#endif /* !__DARWIN_UNIX03 */ + if ((f = (char *)dir)) { +#if __DARWIN_UNIX03 + if (!access(dir, W_OK)) { +#endif /* __DARWIN_UNIX03 */ + (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, + *(f + strlen(f) - 1) == '/'? "": "/", pfx); + if ((f = _mktemp(name))) { + return(f); + } +#if __DARWIN_UNIX03 + } +#endif /* __DARWIN_UNIX03 */ + } + + f = P_tmpdir; +#if __DARWIN_UNIX03 + if (stat(f, &sb) == 0) { /* directory accessible? */ +#endif /* __DARWIN_UNIX03 */ + (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); + if ((f = _mktemp(name))) { + return(f); + } + +#if __DARWIN_UNIX03 + } +#endif /* __DARWIN_UNIX03 */ + f = _PATH_TMP; +#if __DARWIN_UNIX03 + if (stat(f, &sb) < 0) { + f = "./"; /* directory inaccessible */ + } +#endif /* __DARWIN_UNIX03 */ + (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); + if ((f = _mktemp(name))) { + return(f); + } + + sverrno = errno; + free(name); + errno = sverrno; + return(NULL); +} diff --git a/stdio/tmpfile-fbsd.c b/stdio/tmpfile-fbsd.c new file mode 100644 index 0000000..cf5b70a --- /dev/null +++ b/stdio/tmpfile-fbsd.c @@ -0,0 +1,96 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +FILE * +tmpfile() +{ + sigset_t set, oset; + FILE *fp; + int fd, sverrno; +#define TRAILER "tmp.XXXXXX" + char *buf; + const char *tmpdir; + + tmpdir = NULL; + if (issetugid() == 0) + tmpdir = getenv("TMPDIR"); + if (tmpdir == NULL) + tmpdir = _PATH_TMP; + + (void)asprintf(&buf, "%s%s%s", tmpdir, + (tmpdir[strlen(tmpdir) - 1] == '/') ? "" : "/", TRAILER); + if (buf == NULL) + return (NULL); + + sigfillset(&set); + (void)_sigprocmask(SIG_BLOCK, &set, &oset); + + fd = mkstemp(buf); + if (fd != -1) + (void)unlink(buf); + + free(buf); + + (void)_sigprocmask(SIG_SETMASK, &oset, NULL); + + if (fd == -1) + return (NULL); + + if ((fp = fdopen(fd, "w+")) == NULL) { + sverrno = errno; + (void)_close(fd); + errno = sverrno; + return (NULL); + } + return (fp); +} diff --git a/stdio/tmpnam-fbsd.c b/stdio/tmpnam-fbsd.c new file mode 100644 index 0000000..38fcdd6 --- /dev/null +++ b/stdio/tmpnam-fbsd.c @@ -0,0 +1,65 @@ +/*- + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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.5 2002/03/22 21:53:04 obrien Exp $"); + +#include + +#include +#include + +__warn_references(tmpnam, + "warning: tmpnam() possibly used unsafely; consider using mkstemp()"); + +extern char *_mktemp(char *); + +char * +tmpnam(s) + char *s; +{ + static u_long tmpcount; + static char buf[L_tmpnam]; + + if (s == NULL) + s = 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 new file mode 100644 index 0000000..f7d0c83 --- /dev/null +++ b/stdio/tmpnam.3 @@ -0,0 +1,247 @@ +.\" Copyright (c) 1988, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd November 17, 1993 +.Dt TMPFILE 3 +.Os +.Sh NAME +.Nm tempnam , +.Nm tmpfile , +.Nm tmpnam +.Nd temporary file routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft FILE * +.Fo tmpfile +.Fa void +.Fc +.Ft char * +.Fo tmpnam +.Fa "char *s" +.Fc +.Ft char * +.Fo tempnam +.Fa "const char *dir" +.Fa "const char *pfx" +.Fc +.Sh DESCRIPTION +The +.Fn tmpfile +function +returns a pointer to a stream associated with a file descriptor returned +by the routine +.Xr mkstemp 3 . +The created file is unlinked before +.Fn tmpfile +returns, causing the file to be automatically deleted when the last +reference to it is closed. +The file is opened with the access value +.Ql w+ . +If the environment variable +.Ev TMPDIR +is defined, +the file is created in the specified directory. +The default location, if +.Ev TMPDIR +is not set, is +.Pa /tmp . +.Pp +The +.Fn tmpnam +function +returns a pointer to a file name, in the +.Dv P_tmpdir +directory, which +did not reference an existing file at some indeterminate point in the +past. +.Dv P_tmpdir +is defined in the include file +.In stdio.h . +If the argument +.Fa s +is +.Pf non- Dv NULL , +the file name is copied to the buffer it references. +Otherwise, the file name is copied to a static buffer. +In either case, +.Fn tmpnam +returns a pointer to the file name. +.Pp +The buffer referenced by +.Fa s +is expected to be at least +.Dv L_tmpnam +bytes in length. +.Dv L_tmpnam +is defined in the include file +.In stdio.h . +.Pp +The +.Fn tempnam +function +is similar to +.Fn tmpnam , +but provides the ability to specify the directory which will +contain the temporary file and the file name prefix. +.Pp +The environment variable +.Ev TMPDIR +(if set), the argument +.Fa dir +(if +.Pf non- Dv NULL ) , +the directory +.Dv P_tmpdir , +and the directory +.Pa /tmp +are tried, in the listed order, as directories in which to store the +temporary file. +.Pp +The argument +.Fa pfx , +if +.Pf non- Dv NULL , +is used to specify a file name prefix, which will be the +first part of the created file name. +The +.Fn tempnam +function +allocates memory in which to store the file name; the returned pointer +may be used as a subsequent argument to +.Xr free 3 . +.Sh RETURN VALUES +The +.Fn tmpfile +function +returns a pointer to an open file stream on success, and a +.Dv NULL +pointer +on error. +.Pp +The +.Fn tmpnam +and +.Fn tempfile +functions +return a pointer to a file name on success, and a +.Dv NULL +pointer +on error. +.Sh ERRORS +The +.Fn tmpfile +function +may fail and set the global variable +.Va errno +for any of the errors specified for the library functions +.Xr fdopen 3 +or +.Xr mkstemp 3 . +.Pp +The +.Fn tmpnam +function +may fail and set +.Va errno +for any of the errors specified for the library function +.Xr mktemp 3 . +.Pp +The +.Fn tempnam +function +may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr malloc 3 +or +.Xr mktemp 3 . +.Sh SECURITY CONSIDERATIONS +The +.Fn tmpnam +and +.Fn tempnam +functions are susceptible to a race condition +occurring between the selection of the file name +and the creation of the file, +which allows malicious users +to potentially overwrite arbitrary files in the system, +depending on the level of privilege of the running program. +Additionally, there is no means by which +file permissions may be specified. +It is strongly suggested that +.Xr mkstemp 3 +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 +.Sh STANDARDS +The +.Fn tmpfile +and +.Fn tmpnam +functions +conform to +.St -isoC . diff --git a/stdio/ungetc-fbsd.c b/stdio/ungetc-fbsd.c new file mode 100644 index 0000000..2217259 --- /dev/null +++ b/stdio/ungetc-fbsd.c @@ -0,0 +1,172 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" + +static int __submore(FILE *); + +/* + * Expand the ungetc buffer `in place'. That is, adjust fp->_p when + * the buffer moves, so that it points the same distance from the end, + * and move the bytes in the buffer around as necessary so that they + * are all at the end (stack-style). + */ +static int +__submore(FILE *fp) +{ + int i; + unsigned char *p; + + if (fp->_ub._base == fp->_ubuf) { + /* + * Get a new buffer (rather than expanding the old one). + */ + if ((p = malloc((size_t)BUFSIZ)) == NULL) + return (EOF); + fp->_ub._base = p; + fp->_ub._size = BUFSIZ; + p += BUFSIZ - sizeof(fp->_ubuf); + for (i = sizeof(fp->_ubuf); --i >= 0;) + p[i] = fp->_ubuf[i]; + fp->_p = p; + return (0); + } + i = fp->_ub._size; + p = realloc(fp->_ub._base, (size_t)(i << 1)); + if (p == NULL) + return (EOF); + /* no overlap (hence can use memcpy) because we doubled the size */ + (void)memcpy((void *)(p + i), (void *)p, (size_t)i); + fp->_p = p + i; + fp->_ub._base = p; + fp->_ub._size = i << 1; + return (0); +} + +/* + * MT-safe version + */ +int +ungetc(int c, FILE *fp) +{ + int ret; + + if (!__sdidinit) + __sinit(); + FLOCKFILE(fp); + ORIENT(fp, -1); + ret = __ungetc(c, fp); + FUNLOCKFILE(fp); + return (ret); +} + +/* + * Non-MT-safe version + */ +int +__ungetc(int c, FILE *fp) +{ + + if (c == EOF) + return (EOF); + if ((fp->_flags & __SRD) == 0) { + /* + * Not already reading: no good unless reading-and-writing. + * Otherwise, flush any current write stuff. + */ + if ((fp->_flags & __SRW) == 0) + return (EOF); + if (fp->_flags & __SWR) { + if (__sflush(fp)) + return (EOF); + fp->_flags &= ~__SWR; + fp->_w = 0; + fp->_lbfsize = 0; + } + fp->_flags |= __SRD; + } + c = (unsigned char)c; + + /* + * If we are in the middle of ungetc'ing, just continue. + * This may require expanding the current ungetc buffer. + */ + if (HASUB(fp)) { + if (fp->_r >= fp->_ub._size && __submore(fp)) + return (EOF); + *--fp->_p = c; + fp->_r++; + return (c); + } + fp->_flags &= ~__SEOF; + + /* + * If we can handle this by simply backing up, do so, + * but never replace the original character. + * (This makes sscanf() work when scanning `const' data.) + */ + if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && + fp->_p[-1] == c) { + fp->_p--; + fp->_r++; + return (c); + } + + /* + * Create an ungetc buffer. + * Initially, we will use the `reserve' buffer. + */ + fp->_ur = fp->_r; + fp->_extra->_up = fp->_p; + fp->_ub._base = fp->_ubuf; + fp->_ub._size = sizeof(fp->_ubuf); + fp->_ubuf[sizeof(fp->_ubuf) - 1] = c; + fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1]; + fp->_r = 1; + return (c); +} diff --git a/stdio/ungetc.3 b/stdio/ungetc.3 new file mode 100644 index 0000000..3b3f686 --- /dev/null +++ b/stdio/ungetc.3 @@ -0,0 +1,105 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt UNGETC 3 +.Os +.Sh NAME +.Nm ungetc +.Nd un-get character from input stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft int +.Fo ungetc +.Fa "int c" +.Fa "FILE *stream" +.Fc +.Sh DESCRIPTION +The +.Fn ungetc +function pushes the character +.Fa c +(converted to an unsigned char) +back onto the input stream pointed to by +.Fa stream . +The pushed-back characters will be returned (in reverse order) +by subsequent reads on the stream. +A successful intervening call +to one of the file positioning functions +.Xr ( fseek 3 , +.Xr fsetpos 3 , +or +.Xr rewind 3 ) , +using the same stream, +will discard the pushed-back characters. +.Pp +Only one character of push-back is guaranteed, +but as long as there is sufficient memory, +an effectively infinite amount of push-back is allowed. +.Pp +If a character is successfully pushed-back, +the end-of-file indicator for the stream is cleared. +The file-position indicator is decremented +by each successful call to +.Fn ungetc ; +if its value was 0 before a call, its value is unspecified after +the call. +.Sh RETURN VALUES +The +.Fn ungetc +function returns the character pushed-back after the conversion, +or +.Dv EOF +if the operation fails. +If the value of the argument +.Fa c +character equals +.Dv EOF , +the operation will fail and the stream will remain unchanged. +.Sh SEE ALSO +.Xr fseek 3 , +.Xr getc 3 , +.Xr setvbuf 3 , +.Xr ungetwc 3 +.Sh STANDARDS +The +.Fn ungetc +function conforms to +.St -isoC . diff --git a/stdio/ungetwc-fbsd.c b/stdio/ungetwc-fbsd.c new file mode 100644 index 0000000..f221940 --- /dev/null +++ b/stdio/ungetwc-fbsd.c @@ -0,0 +1,92 @@ +/*- + * 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/ungetwc.c,v 1.9 2004/07/20 08:27:27 tjr Exp $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" +#include "mblocal.h" + +/* + * Non-MT-safe version. + */ +wint_t +__ungetwc(wint_t wc, FILE *fp, locale_t loc) +{ + char buf[MB_LEN_MAX]; + size_t len; + + if (wc == WEOF) + return (WEOF); + if ((len = loc->__lc_ctype->__wcrtomb(buf, wc, &fp->_extra->mbstate, loc)) == (size_t)-1) { + fp->_flags |= __SERR; + return (WEOF); + } + while (len-- != 0) + if (__ungetc((unsigned char)buf[len], fp) == EOF) + return (WEOF); + + return (wc); +} + +/* + * MT-safe version. + */ +wint_t +ungetwc(wint_t wc, FILE *fp) +{ + wint_t r; + + FLOCKFILE(fp); + ORIENT(fp, 1); + r = __ungetwc(wc, fp, __current_locale()); + FUNLOCKFILE(fp); + + return (r); +} + +wint_t +ungetwc_l(wint_t wc, FILE *fp, locale_t loc) +{ + wint_t r; + + NORMALIZE_LOCALE(loc); + FLOCKFILE(fp); + ORIENT(fp, 1); + r = __ungetwc(wc, fp, loc); + FUNLOCKFILE(fp); + + return (r); +} diff --git a/stdio/ungetwc.3 b/stdio/ungetwc.3 new file mode 100644 index 0000000..039a57d --- /dev/null +++ b/stdio/ungetwc.3 @@ -0,0 +1,122 @@ +.\" $NetBSD: ungetwc.3,v 1.3 2002/02/07 07:00:27 ross Exp $ +.\" +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd March 3, 2004 +.Dt UNGETWC 3 +.Os +.Sh NAME +.Nm ungetwc , +.Nm ungetwc_l +.Nd un-get wide character from input stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft wint_t +.Fo ungetwc +.Fa "wint_t wc" +.Fa "FILE *stream" +.Fc +.In stdio.h +.In wchar.h +.In xlocale.h +.Ft wint_t +.Fo ungetwc_l +.Fa "wint_t wc" +.Fa "FILE *stream" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn ungetwc +function pushes the wide character +.Fa wc +(converted to an +.Vt wchar_t ) +back onto the input stream pointed to by +.Fa stream . +The pushed-backed wide characters will be returned (in reverse order) +by subsequent reads on the stream. +A successful intervening call to one of the file +positioning functions +.Xr fseek 3 , +.Xr fsetpos 3 , +or +.Xr rewind 3 , +using the same stream, +will discard the pushed-back wide characters. +.Pp +Only one wide character of push-back is guaranteed, +but as long as there is sufficient memory, +an effectively infinite amount of push-back is allowed. +.Pp +If a character is successfully pushed-back, +the end-of-file indicator for the stream is cleared. +.Pp +Although the +.Fn ungetwc +function uses the current locale, the +.Fn ungetwc_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn ungetwc +function +returns +the wide character pushed-back after the conversion, or +.Dv WEOF +if the operation fails. +If the value of the argument +.Fa c +character equals +.Dv WEOF , +the operation will fail and the stream will remain unchanged. +.Sh SEE ALSO +.Xr fseek 3 , +.Xr getwc 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn ungetwc +function conforms to +.St -isoC-99 . diff --git a/stdio/unlocked-fbsd.c b/stdio/unlocked-fbsd.c new file mode 100644 index 0000000..6b1c0ef --- /dev/null +++ b/stdio/unlocked-fbsd.c @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 2003 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/unlocked.c,v 1.1 2003/01/10 04:35:08 tjr 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) +{ + + return (__sputc(ch, fp)); +} + +#undef feof_unlocked +int +feof_unlocked(FILE *fp) +{ + + return (__sfeof(fp)); +} + +#undef ferror_unlocked +int +ferror_unlocked(FILE *fp) +{ + + return (__sferror(fp)); +} + +#undef clearerr_unlocked +void +clearerr_unlocked(FILE *fp) +{ + + __sclearerr(fp); +} + +#undef fileno_unlocked +int +fileno_unlocked(FILE *fp) +{ + + return (__sfileno(fp)); +} diff --git a/stdio/vasprintf-fbsd.c b/stdio/vasprintf-fbsd.c new file mode 100644 index 0000000..f90d0a6 --- /dev/null +++ b/stdio/vasprintf-fbsd.c @@ -0,0 +1,106 @@ +/* $OpenBSD: vasprintf.c,v 1.4 1998/06/21 22:13:47 millert 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. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.18 2002/09/26 13:11:24 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include "local.h" + +int +vasprintf(str, fmt, ap) + char **str; + const char *fmt; + __va_list ap; +{ + int ret; + 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); + 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 +vasprintf_l(str, loc, 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); +} diff --git a/stdio/vfprintf-fbsd.c b/stdio/vfprintf-fbsd.c new file mode 100644 index 0000000..f9e3719 --- /dev/null +++ b/stdio/vfprintf-fbsd.c @@ -0,0 +1,2101 @@ +/*- + * 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. + */ + +#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/vfprintf.c,v 1.68 2004/08/26 06:25:28 des Exp $"); + +#include "xlocale_private.h" + +/* + * Actual printf innards. + * + * This code is large and complicated... + */ + +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "un-namespace.h" + +#include "libc_private.h" +#include "local.h" +#include "fvwrite.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; + 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 */ +}; + +/* + * 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_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 __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 *); + +/* + * 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) +{ + int err; + + if (uio->uio_resid == 0) { + uio->uio_iovcnt = 0; + return (0); + } + err = __sfvwrite(fp, uio); + uio->uio_resid = 0; + uio->uio_iovcnt = 0; + return (err); +} + +/* + * Helper function for `fprintf to unbuffered unix file': creates a + * temporary buffer. We only work on write-only files; this avoids + * worries about ungetc buffers and so forth. + */ +static int +__sbprintf(FILE *fp, locale_t loc, const char *fmt, va_list ap) +{ + int ret; + FILE fake; + unsigned char buf[BUFSIZ]; + + /* 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; + + /* set up the buffer */ + fake._bf._base = fake._p = buf; + fake._bf._size = fake._w = sizeof(buf); + fake._lbfsize = 0; /* not actually used, but Just In Case */ + + /* do the work, then copy any error status */ + ret = __vfprintf(&fake, loc, fmt, ap); + if (ret >= 0 && __fflush(&fake)) + ret = EOF; + if (fake._flags & __SERR) + fp->_flags |= __SERR; + 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. + */ +static char * +__wcsconv(wchar_t *wcsarg, int prec, locale_t loc) +{ + static const mbstate_t initial; + mbstate_t mbs; + char buf[MB_LEN_MAX]; + wchar_t *p; + char *convbuf, *mbp; + size_t clen = 0, 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 { + p = wcsarg; + mbs = initial; + nbytes = wcsrtombs_l(NULL, (const wchar_t **)&p, 0, &mbs, loc); + if (nbytes == (size_t)-1) + return (NULL); + } + 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; + 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) { + free(convbuf); + return (NULL); + } + *mbp = '\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) + +{ + int ret; + + FLOCKFILE(fp); + 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); + 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. + */ +#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 */ + +/* + * Non-MT-safe version + */ +__private_extern__ int +__vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) +{ + 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) */ + 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 */ +#ifndef NO_FLOATING_POINT + /* + * We can decompose the printed representation of floating + * point numbers into several parts, some of which may be empty: + * + * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ + * A B ---C--- D E F + * + * A: 'sign' holds this value if present; '\0' otherwise + * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal + * C: cp points to the string MMMNNN. Leading and trailing + * zeros are not in the string and must be added. + * 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 */ + int signflag; /* true if float is negative */ + union { /* floating point arguments %[aAeEfFgG] */ + double dbl; + long double ldbl; + } fparg; + int expt; /* integer value of exponent */ + 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. */ + char *pct; /* Pointer to '%' at beginning of specifier. */ + char vsep; /* Vector separator character. */ +#endif + u_long ulval; /* integer arguments %[diouxX] */ + uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ + int base; /* base for [diouxX] conversion */ + int dprec; /* a copy of prec if [diouxX], 0 otherwise */ + int realsz; /* field size expanded by dprec, sign, etc */ + 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 */ + 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 */ + union arg statargtable [STATIC_ARG_TBL_SIZE]; + int nextarg; /* 1-based argument index */ + 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'. + */ +#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; \ + } \ +} +#define PAD(howmany, with) { \ + if ((n = (howmany)) > 0) { \ + while (n > PADSIZE) { \ + PRINT(with, PADSIZE); \ + n -= PADSIZE; \ + } \ + PRINT(with, n); \ + } \ +} +#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)) \ + goto error; \ + uio.uio_iovcnt = 0; \ + iovp = iov; \ +} + + /* + * Get the argument indexed by nextarg. If the argument table is + * built, use it to get the argument. If its not, get the next + * argument (and arguments must be gotten sequentially). + */ +#define GETARG(type) \ + ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ + (nextarg++, va_arg(ap, type))) + + /* + * To extend shorts properly, we need both signed and unsigned + * argument extraction methods. + */ +#define SARG() \ + (flags&LONGINT ? GETARG(long) : \ + flags&SHORTINT ? (long)(short)GETARG(int) : \ + flags&CHARINT ? (long)(signed char)GETARG(int) : \ + (long)GETARG(int)) +#define UARG() \ + (flags&LONGINT ? GETARG(u_long) : \ + flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \ + flags&CHARINT ? (u_long)(u_char)GETARG(int) : \ + (u_long)GETARG(u_int)) +#define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) +#define SJARG() \ + (flags&INTMAXT ? GETARG(intmax_t) : \ + flags&SIZET ? (intmax_t)GETARG(ssize_t) : \ + flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ + (intmax_t)GETARG(long long)) +#define UJARG() \ + (flags&INTMAXT ? GETARG(uintmax_t) : \ + flags&SIZET ? (uintmax_t)GETARG(size_t) : \ + flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ + (uintmax_t)GETARG(unsigned long long)) + + /* + * Get * arguments, including the form *nn$. Preserve the nextarg + * that the argument can be gotten once the type is determined. + */ +#define GETASTER(val) \ + n2 = 0; \ + cp = fmt; \ + while (is_digit(*cp)) { \ + n2 = 10 * n2 + to_digit(*cp); \ + cp++; \ + } \ + if (*cp == '$') { \ + int hold = nextarg; \ + if (argtable == NULL) { \ + argtable = statargtable; \ + __find_arguments (fmt0, orgap, &argtable); \ + } \ + nextarg = n2; \ + val = GETARG (int); \ + nextarg = hold; \ + fmt = ++cp; \ + } else { \ + val = GETARG (int); \ + } + + thousands_sep = '\0'; + grouping = NULL; + convbuf = NULL; +#ifndef NO_FLOATING_POINT + dtoaresult = NULL; + decimal_point = localeconv_l(loc)->decimal_point; +#endif + /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ + if (prepwrite(fp) != 0) { + errno = EBADF; + return (EOF); + } + 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)); + + fmt = (char *)fmt0; + argtable = NULL; + nextarg = 1; + va_copy(orgap, ap); + uio.uio_iov = iovp = iov; + uio.uio_resid = 0; + uio.uio_iovcnt = 0; + ret = 0; + + /* + * Scan the format for conversions (`%' character). + */ + for (;;) { + for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) + /* void */; + if ((n = fmt - cp) != 0) { + if ((unsigned)ret + n > INT_MAX) { + ret = EOF; + goto error; + } + PRINT(cp, n); + ret += n; + } + if (ch == '\0') + goto done; +#ifdef VECTORS + pct = fmt; +#endif /* VECTORS */ + fmt++; /* skip over '%' */ + + flags = 0; + dprec = 0; + width = 0; + prec = -1; + sign = '\0'; + ox[1] = '\0'; +#ifdef VECTORS + vsep = 'X'; /* Illegal value, changed to defaults later. */ +#endif /* VECTORS */ + +rflag: ch = *fmt++; +reswitch: switch (ch) { + case ' ': + /*- + * ``If the space and + flags both appear, the space + * flag will be ignored.'' + * -- ANSI X3J11 + */ + if (!sign) + sign = ' '; + goto rflag; + case '#': + flags |= ALT; + goto rflag; +#ifdef VECTORS + case ',': case ';': case ':': case '_': + vsep = ch; + goto rflag; +#endif /* VECTORS */ + case '*': + /*- + * ``A negative field width argument is taken as a + * - flag followed by a positive field width.'' + * -- ANSI X3J11 + * They don't exclude field widths read from args. + */ + GETASTER (width); + if (width >= 0) + goto rflag; + width = -width; + /* FALLTHROUGH */ + case '-': + flags |= LADJUST; + goto rflag; + case '+': + sign = '+'; + 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++) == '*') { + GETASTER (prec); + goto rflag; + } + prec = 0; + while (is_digit(ch)) { + prec = 10 * prec + to_digit(ch); + ch = *fmt++; + } + goto reswitch; + case '0': + /*- + * ``Note that 0 is taken as a flag, not as the + * beginning of a field width.'' + * -- ANSI X3J11 + */ + flags |= ZEROPAD; + 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; + if (argtable == NULL) { + argtable = statargtable; + __find_arguments (fmt0, orgap, + &argtable); + } + 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': +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + if (flags & LONGINT) { + static const mbstate_t initial; + mbstate_t mbs; + size_t mbseqlen; + + mbs = initial; + mbseqlen = wcrtomb_l(cp = buf, + (wchar_t)GETARG(wint_t), &mbs, loc); + if (mbseqlen == (size_t)-1) { + fp->_flags |= __SERR; + goto error; + } + size = (int)mbseqlen; + } else { + *(cp = buf) = GETARG(int); + size = 1; + } + sign = '\0'; + break; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + if (flags & INTMAX_SIZE) { + ujval = SJARG(); + if ((intmax_t)ujval < 0) { + ujval = -ujval; + sign = '-'; + } + } else { + ulval = SARG(); + if ((long)ulval < 0) { + ulval = -ulval; + sign = '-'; + } + } + base = 10; + goto number; +#ifndef NO_FLOATING_POINT + case 'a': + case 'A': +#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; + break; + } +#endif /* VECTORS */ + if (ch == 'a') { + ox[1] = 'x'; + xdigs = xdigs_lower; + expchar = 'p'; + } else { + ox[1] = 'X'; + xdigs = xdigs_upper; + expchar = 'P'; + } + if (prec >= 0) + prec++; + if (dtoaresult != NULL) + freedtoa(dtoaresult); +#ifdef LDBL_COMPAT + fparg.dbl = GETARG(double); + dtoaresult = cp = + __hdtoa(fparg.dbl, xdigs, prec, + &expt, &signflag, &dtoaend); +#else /* !LDBL_COMPAT */ + if (flags & LONGDBL) { + fparg.ldbl = GETARG(long double); + dtoaresult = cp = + __hldtoa(fparg.ldbl, xdigs, prec, + &expt, &signflag, &dtoaend); + } else { + fparg.dbl = GETARG(double); + dtoaresult = cp = + __hdtoa(fparg.dbl, xdigs, prec, + &expt, &signflag, &dtoaend); + } +#endif /* LDBL_COMPAT */ + if (prec < 0) + prec = dtoaend - cp; + if (expt == INT_MAX) + ox[1] = '\0'; + goto fp_common; + case 'e': + case 'E': +#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; + break; + } +#endif /* VECTORS */ + expchar = ch; + if (prec < 0) /* account for digit before decpt */ + prec = DEFPREC + 1; + else + prec++; + goto fp_begin; + case 'f': + case 'F': +#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; + break; + } +#endif /* VECTORS */ + expchar = '\0'; + goto fp_begin; + case 'g': + case 'G': +#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; + break; + } +#endif /* VECTORS */ + expchar = ch - ('g' - 'e'); + if (prec == 0) + prec = 1; +fp_begin: + if (prec < 0) + prec = DEFPREC; + if (dtoaresult != NULL) + freedtoa(dtoaresult); +#ifdef LDBL_COMPAT + fparg.dbl = GETARG(double); + dtoaresult = cp = + dtoa(fparg.dbl, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); + if (expt == 9999) + expt = INT_MAX; +#else /* !LDBL_COMPAT */ + if (flags & LONGDBL) { + fparg.ldbl = GETARG(long double); + dtoaresult = cp = + __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); + } else { + fparg.dbl = GETARG(double); + dtoaresult = cp = + dtoa(fparg.dbl, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); + if (expt == 9999) + expt = INT_MAX; + } +#endif /* LDBL_COMPAT */ +fp_common: + if (signflag) + sign = '-'; + if (expt == INT_MAX) { /* inf or nan */ + if (*cp == 'N') { + cp = (ch >= 'a') ? "nan" : "NAN"; + sign = '\0'; + } else + cp = (ch >= 'a') ? "inf" : "INF"; + size = 3; + break; + } + flags |= FPT; + ndig = dtoaend - cp; + if (ch == 'g' || ch == 'G') { + if (expt > -4 && expt <= prec) { + /* Make %[gG] smell like %[fF] */ + expchar = '\0'; + if (flags & ALT) + prec -= expt; + else + prec = ndig - expt; + if (prec < 0) + prec = 0; + } else { + /* + * Make %[gG] smell like %[eE], but + * trim trailing zeroes if no # flag. + */ + if (!(flags & ALT)) + prec = ndig; + } + } + if (expchar) { + expsize = exponent(expstr, expt - 1, expchar); + size = expsize + prec; + if (prec > 1 || flags & ALT) + ++size; + } else { + /* space for digits before decimal point */ + if (expt > 0) + size = expt; + else /* "0" */ + 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; + } + 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; + else if (flags & SIZET) + *GETARG(ssize_t *) = (ssize_t)ret; + else if (flags & PTRDIFFT) + *GETARG(ptrdiff_t *) = ret; + else if (flags & INTMAXT) + *GETARG(intmax_t *) = ret; + else if (flags & LONGINT) + *GETARG(long *) = ret; + else if (flags & SHORTINT) + *GETARG(short *) = ret; + else if (flags & CHARINT) + *GETARG(signed char *) = ret; + else + *GETARG(int *) = ret; + continue; /* no output */ + case 'O': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else + ulval = UARG(); + base = 8; + goto nosign; + case 'p': + /*- + * ``The argument shall be a pointer to void. The + * value of the pointer is converted to a sequence + * of printable characters, in an implementation- + * defined manner.'' + * -- ANSI X3J11 + */ +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + ujval = (uintmax_t)(uintptr_t)GETARG(void *); + base = 16; + xdigs = xdigs_lower; + flags = flags | INTMAXT; + ox[1] = 'x'; + goto nosign; + case 'S': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 's': + if (flags & LONGINT) { + wchar_t *wcp; + + if (convbuf != NULL) + free(convbuf); + if ((wcp = GETARG(wchar_t *)) == NULL) + cp = "(null)"; + else { + convbuf = __wcsconv(wcp, prec, loc); + if (convbuf == NULL) { + fp->_flags |= __SERR; + goto error; + } + cp = convbuf; + } + } 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); + sign = '\0'; + break; + case 'U': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else + ulval = UARG(); + base = 10; + goto nosign; + case 'X': + xdigs = xdigs_upper; + goto hex; + case 'x': + xdigs = xdigs_lower; +hex: +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else + ulval = UARG(); + base = 16; + /* leading 0x/X only if non-zero */ + if (flags & ALT && + (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) + ox[1] = ch; + + flags &= ~GROUPING; + /* unsigned conversions */ +nosign: sign = '\0'; + /*- + * ``... diouXx conversions ... if a precision is + * specified, the 0 flag will be ignored.'' + * -- ANSI X3J11 + */ +number: if ((dprec = prec) >= 0) + flags &= ~ZEROPAD; + + /*- + * ``The result of converting a zero value with an + * explicit precision of zero is no characters.'' + * -- ANSI X3J11 + * except for %#.0o and zero value + */ + cp = buf + BUF; + if (flags & INTMAX_SIZE) { + if (ujval != 0 || prec != 0) + cp = __ujtoa(ujval, cp, base, + flags & ALT, xdigs, + flags & GROUPING, thousands_sep, + grouping); + } else { + if (ulval != 0 || prec != 0 || (flags & ALT)) + cp = __ultoa(ulval, cp, base, + flags & ALT, xdigs, + flags & GROUPING, thousands_sep, + grouping); + } + size = buf + BUF - cp; + if (size > BUF) /* should never happen */ + abort(); + break; +#ifdef VECTORS + case 'v': + flags |= VECTOR; + goto rflag; +#endif /* VECTORS */ + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; + /* pretend it was %c with argument ch */ + cp = buf; + *cp = ch; + size = 1; + sign = '\0'; + break; + } + +#ifdef VECTORS + if (flags & VECTOR) { + /* + * Do the minimum amount of work necessary to construct + * a format specifier that can be used to recursively + * call vfprintf() for each element in the vector. + */ + int i, j; /* Counter. */ + int vcnt; /* Number of elements in vector. */ + char *vfmt; /* Pointer to format specifier. */ +#define EXTRAHH 2 + char vfmt_buf[32 + EXTRAHH]; /* Static buffer for format spec. */ + int vwidth = 0; /* Width specified via '*'. */ + int vprec = 0; /* Precision specified via '*'. */ + char *vstr; /* Used for asprintf(). */ + int vlen; /* Length returned by asprintf(). */ + enum { + V_CHAR, V_SHORT, V_INT, + V_PCHAR, V_PSHORT, V_PINT, + V_FLOAT, +#ifdef V64TYPE + V_LONGLONG, V_PLONGLONG, + V_DOUBLE, +#endif /* V64TYPE */ + } vtype; + + vval.vectorarg = GETARG(VECTORTYPE); + /* + * Set vfmt. If vfmt_buf may not be big enough, + * malloc() space, taking care to free it later. + * (EXTRAHH is for possible extra "hh") + */ + if (&fmt[-1] - pct + EXTRAHH < sizeof(vfmt_buf)) + vfmt = vfmt_buf; + else + vfmt = (char *)malloc(&fmt[-1] - pct + EXTRAHH + 1); + + /* Set the separator character, if not specified. */ + if (vsep == 'X') { + if (ch == 'c') + vsep = '\0'; + else + vsep = ' '; + } + + /* Create the format specifier. */ + for (i = j = 0; i < &fmt[-1] - pct; i++) { + switch (pct[i]) { + case ',': case ';': case ':': case '_': + case 'v': case 'h': case 'l': + /* Ignore. */ + break; + case '*': + if (pct[i - 1] != '.') + vwidth = 1; + else + vprec = 1; + /* FALLTHROUGH */ + default: + vfmt[j++] = pct[i]; + } + } + + /* + * Determine the number of elements in the vector and + * finish up the format specifier. + */ + if (flags & SHORTINT) { + switch (ch) { + case 'c': + vtype = V_SHORT; + break; + case 'p': + vtype = V_PSHORT; + break; + default: + vfmt[j++] = 'h'; + vtype = V_SHORT; + break; + } + vcnt = 8; + } else if (flags & LONGINT) { + vcnt = 4; + vtype = (ch == 'p') ? V_PINT : V_INT; +#ifdef V64TYPE + } else if (flags & LLONGINT) { + switch (ch) { + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + vcnt = 2; + vtype = V_DOUBLE; + break; + case 'd': + case 'i': + case 'u': + case 'o': + case 'p': + case 'x': + case 'X': + vfmt[j++] = 'l'; + vfmt[j++] = 'l'; + vcnt = 2; + vtype = (ch == 'p') ? V_PLONGLONG : V_LONGLONG; + break; + default: + /* + * The default case should never + * happen. + */ + case 'c': + vcnt = 16; + vtype = V_CHAR; + } +#endif /* V64TYPE */ + } else { + switch (ch) { + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + vcnt = 4; + vtype = V_FLOAT; + break; + default: + /* + * The default case should never + * happen. + */ + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + vfmt[j++] = 'h'; + vfmt[j++] = 'h'; + /* drop through */ + case 'p': + case 'c': + vcnt = 16; + vtype = (ch == 'p') ? V_PCHAR : V_CHAR; + } + } + vfmt[j++] = ch; + vfmt[j++] = '\0'; + +/* Get a vector element. */ +#ifdef V64TYPE +#define VPRINT(type, ind, args...) do { \ + switch (type) { \ + case V_CHAR: \ + 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]); \ + 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]); \ + 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]); \ + 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]); \ + break; \ + case V_FLOAT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ + break; \ + case V_DOUBLE: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vdoublearg[ind]); \ + break; \ + } \ + ret += vlen; \ + PRINT(vstr, vlen); \ + FLUSH(); \ + free(vstr); \ +} while (0) +#else /* !V64TYPE */ +#define VPRINT(type, ind, args...) do { \ + switch (type) { \ + case V_CHAR: \ + 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]); \ + 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]); \ + 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]); \ + break; \ + case V_FLOAT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ + break; \ + } \ + ret += vlen; \ + PRINT(vstr, vlen); \ + FLUSH(); \ + free(vstr); \ +} while (0) +#endif /* V64TYPE */ + + /* Actually print. */ + if (vwidth == 0) { + if (vprec == 0) { + /* First element. */ + VPRINT(vtype, 0); + for (i = 1; i < vcnt; i++) { + /* Separator. */ + if(vsep) + PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vtype, i); + } + } else { + /* First element. */ + VPRINT(vtype, 0, prec); + for (i = 1; i < vcnt; i++) { + /* Separator. */ + if(vsep) + PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vtype, i, prec); + } + } + } else { + if (vprec == 0) { + /* First element. */ + VPRINT(vtype, 0, width); + for (i = 1; i < vcnt; i++) { + /* Separator. */ + if(vsep) + PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vtype, i, width); + } + } else { + /* First element. */ + VPRINT(vtype, 0, width, prec); + for (i = 1; i < vcnt; i++) { + /* Separator. */ + if(vsep) + PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vtype, i, width, prec); + } + } + } +#undef VPRINT + + if (vfmt != vfmt_buf) + free(vfmt); + + continue; + } +#endif /* VECTORS */ + /* + * All reasonable formats wind up here. At this point, `cp' + * points to a string which (if not flags&LADJUST) should be + * padded out to `width' places. If flags&ZEROPAD, it should + * first be prefixed by any sign or other prefix; otherwise, + * it should be blank padded before the prefix is emitted. + * After any left-hand padding and prefixing, emit zeroes + * required by a decimal [diouxX] precision, then print the + * string proper, then emit zeroes required by any leftover + * floating precision; finally, if LADJUST, pad with blanks. + * + * Compute actual size, so we know how much to pad. + * size excludes decimal prec; realsz includes it. + */ + realsz = dprec > size ? dprec : size; + if (sign) + realsz++; + if (ox[1]) + realsz += 2; + + prsize = width > realsz ? width : realsz; + if ((unsigned)ret + prsize > INT_MAX) { + ret = EOF; + goto error; + } + + /* right-adjusting blank padding */ + if ((flags & (LADJUST|ZEROPAD)) == 0) + PAD(width - realsz, blanks); + + /* prefix */ + if (sign) + PRINT(&sign, 1); + + if (ox[1]) { /* ox[1] is either x, X, or \0 */ + ox[0] = '0'; + PRINT(ox, 2); + } + + /* right-adjusting zero padding */ + 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); + } 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)); + 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 (prec || flags & ALT) + 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++; + PRINT(buf, 1); + PRINT(decimal_point, strlen(decimal_point)); + PRINT(cp, ndig-1); + PAD(prec - ndig, zeroes); + } else /* XeYYY */ + PRINT(cp, 1); + PRINT(expstr, expsize); + } + } +#else + PRINT(cp, size); +#endif + /* left-adjusting padding (always blank) */ + if (flags & LADJUST) + PAD(width - realsz, blanks); + + /* finally, adjust ret */ + ret += prsize; + + FLUSH(); /* copy out the I/O vectors */ + } +done: + FLUSH(); +error: + va_end(orgap); +#ifndef NO_FLOATING_POINT + if (dtoaresult != NULL) + freedtoa(dtoaresult); +#endif + if (convbuf != NULL) + free(convbuf); + if (__sferror(fp)) + ret = EOF; + if ((argtable != NULL) && (argtable != statargtable)) + free (argtable); + 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 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) + 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/vfscanf-fbsd.c b/stdio/vfscanf-fbsd.c new file mode 100644 index 0000000..8bf6170 --- /dev/null +++ b/stdio/vfscanf-fbsd.c @@ -0,0 +1,1168 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "collate.h" +#include "libc_private.h" +#include "local.h" + +#ifndef NO_FLOATING_POINT +#include +#endif + +#define BUF 513 /* Maximum length of numeric string. */ + +/* + * Flags used during conversion. + */ +#define LONG 0x01 /* l: long or double */ +#define LONGDBL 0x02 /* L: long double */ +#define SHORT 0x04 /* h: short */ +#define SUPPRESS 0x08 /* *: suppress assignment */ +#define POINTER 0x10 /* p: void * (as hex) */ +#define NOSKIP 0x20 /* [ or c: do not skip blanks */ +#define LONGLONG 0x400 /* ll: long long (+ deprecated q: quad) */ +#define INTMAXT 0x800 /* j: intmax_t */ +#define PTRDIFFT 0x1000 /* t: ptrdiff_t */ +#define SIZET 0x2000 /* z: size_t */ +#define SHORTSHORT 0x4000 /* hh: char */ +#define UNSIGNED 0x8000 /* %[oupxX] conversions */ + +/* + * The following are used in integral conversions only: + * SIGNOK, NDIGITS, PFXOK, and NZDIGITS + */ +#define SIGNOK 0x40 /* +/- is (still) legal */ +#define NDIGITS 0x80 /* no digits detected */ +#define PFXOK 0x100 /* 0x prefix is (still) legal */ +#define NZDIGITS 0x200 /* no zero digits detected */ +#define HAVESIGN 0x10000 /* sign detected */ + +/* + * Conversion types. + */ +#define CT_CHAR 0 /* %c conversion */ +#define CT_CCL 1 /* %[...] conversion */ +#define CT_STRING 2 /* %s conversion */ +#define CT_INT 3 /* %[dioupxX] conversion */ +#define CT_FLOAT 4 /* %[efgEFG] conversion */ + +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 */ + +__weak_reference(__vfscanf, vfscanf); + +/* + * __vfscanf - MT-safe version + */ +int +__vfscanf(FILE * __restrict fp, char const * __restrict fmt0, va_list ap) +{ + int ret; + + FLOCKFILE(fp); + ret = __svfscanf_l(fp, __current_locale(), fmt0, ap); + FUNLOCKFILE(fp); + return (ret); +} + +int +vfscanf_l(FILE * __restrict fp, locale_t loc, char const * __restrict fmt0, va_list ap) +{ + int ret; + + NORMALIZE_LOCALE(loc); + FLOCKFILE(fp); + ret = __svfscanf_l(fp, loc, fmt0, ap); + FUNLOCKFILE(fp); + return (ret); +} + +/* + * __svfscanf - non-MT-safe version of __vfscanf + */ +__private_extern__ int +__svfscanf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, va_list ap) +{ + const u_char *fmt = (const u_char *)fmt0; + int c; /* character from format, or conversion */ + size_t width; /* field width, or 0 */ + char *p; /* points into all kinds of strings */ + int n; /* handy integer */ + int flags; /* flags as defined above */ + char *p0; /* saves original value of p when necessary */ + int nassigned; /* number of fields assigned */ + int nread; /* number of characters consumed from fp */ + int base; /* base argument to conversion function */ + 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 */ + static const mbstate_t initial; + mbstate_t mbs; + int mb_cur_max; + + /* `basefix' is used to avoid `if' tests in the integer scanner */ + static short basefix[17] = + { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + + NORMALIZE_LOCALE(loc); + mb_cur_max = MB_CUR_MAX_L(loc); + ORIENT(fp, -1); + + nassigned = 0; + nread = 0; + va_copy(ap_orig, ap); + for (;;) { + c = *fmt++; + if (c == 0) + return (nassigned); + if (isspace_l(c, loc)) { + while ((fp->_r > 0 || __srefill(fp) == 0) && isspace_l(*fp->_p, loc)) + nread++, fp->_r--, fp->_p++; + continue; + } + if (c != '%') + goto literal; + width = 0; + flags = 0; + /* + * switch on the format. continue if done; + * break once format type is derived. + */ +again: c = *fmt++; + switch (c) { + case '%': +literal: + if (fp->_r <= 0 && __srefill(fp)) + goto input_failure; + if (*fp->_p != c) + goto match_failure; + fp->_r--, fp->_p++; + nread++; + continue; + + case '$': + index = width; + if (index < 1 || index > NL_ARGMAX || fmt[-3] != '%') { + goto input_failure; + } + width = 0; + va_end(ap); + va_copy(ap, ap_orig); /* reset to %1$ */ + for (; index > 1; index--) { + va_arg(ap, void*); + } + goto again; + case '*': + flags |= SUPPRESS; + goto again; + case 'j': + flags |= INTMAXT; + goto again; + case 'l': + if (flags & LONG) { + flags &= ~LONG; + flags |= LONGLONG; + } else + flags |= LONG; + goto again; + case 'q': + flags |= LONGLONG; /* not quite */ + goto again; + case 't': + flags |= PTRDIFFT; + goto again; + case 'z': + flags |= SIZET; + goto again; + case 'L': + flags |= LONGDBL; + goto again; + case 'h': + if (flags & SHORT) { + flags &= ~SHORT; + flags |= SHORTSHORT; + } else + flags |= SHORT; + goto again; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + width = width * 10 + c - '0'; + goto again; + + /* + * Conversions. + */ + case 'd': + c = CT_INT; + base = 10; + break; + + case 'i': + c = CT_INT; + base = 0; + break; + + case 'o': + c = CT_INT; + flags |= UNSIGNED; + base = 8; + break; + + case 'u': + c = CT_INT; + flags |= UNSIGNED; + base = 10; + break; + + case 'X': + case 'x': + flags |= PFXOK; /* enable 0x prefixing */ + c = CT_INT; + flags |= UNSIGNED; + base = 16; + break; + +#ifndef NO_FLOATING_POINT + case 'A': case 'E': case 'F': case 'G': + case 'a': case 'e': case 'f': case 'g': + c = CT_FLOAT; + break; +#endif + + case 'S': + flags |= LONG; + /* FALLTHROUGH */ + case 's': + c = CT_STRING; + break; + + case '[': + fmt = __sccl(ccltab, fmt, loc); + flags |= NOSKIP; + c = CT_CCL; + break; + + case 'C': + flags |= LONG; + /* FALLTHROUGH */ + case 'c': + flags |= NOSKIP; + c = CT_CHAR; + break; + + case 'p': /* pointer format is like hex */ + flags |= POINTER | PFXOK; + c = CT_INT; /* assumes sizeof(uintmax_t) */ + flags |= UNSIGNED; /* >= sizeof(uintptr_t) */ + base = 16; + break; + + case 'n': + if (flags & SUPPRESS) /* ??? */ + continue; + if (flags & SHORTSHORT) + *va_arg(ap, char *) = nread; + else if (flags & SHORT) + *va_arg(ap, short *) = nread; + else if (flags & LONG) + *va_arg(ap, long *) = nread; + else if (flags & LONGLONG) + *va_arg(ap, long long *) = nread; + else if (flags & INTMAXT) + *va_arg(ap, intmax_t *) = nread; + else if (flags & SIZET) + *va_arg(ap, size_t *) = nread; + else if (flags & PTRDIFFT) + *va_arg(ap, ptrdiff_t *) = nread; + else + *va_arg(ap, int *) = nread; + continue; + + default: + goto match_failure; + + /* + * Disgusting backwards compatibility hack. XXX + */ + case '\0': /* compat */ + return (EOF); + } + + /* + * We have a conversion that requires input. + */ + if (fp->_r <= 0 && __srefill(fp)) + goto input_failure; + + /* + * Consume leading white space, except for formats + * that suppress this. + */ + if ((flags & NOSKIP) == 0) { + while (isspace_l(*fp->_p, loc)) { + nread++; + if (--fp->_r > 0) + fp->_p++; + else if (__srefill(fp)) + goto input_failure; + } + /* + * Note that there is at least one character in + * the buffer, so conversions that do not set NOSKIP + * ca no longer result in an input failure. + */ + } + + /* + * Do the conversion. + */ + switch (c) { + + case CT_CHAR: + /* scan arbitrary characters (sets NOSKIP) */ + if (width == 0) + width = 1; + if (flags & LONG) { + if ((flags & SUPPRESS) == 0) + wcp = va_arg(ap, wchar_t *); + else + wcp = NULL; + n = 0; + while (width != 0) { + if (n == mb_cur_max) { + fp->_flags |= __SERR; + goto input_failure; + } + buf[n++] = *fp->_p; + fp->_p++; + fp->_r--; + mbs = initial; + nconv = mbrtowc_l(wcp, buf, n, &mbs, loc); + if (nconv == (size_t)-1) { + fp->_flags |= __SERR; + goto input_failure; + } + if (nconv == 0 && !(flags & SUPPRESS)) + *wcp = L'\0'; + if (nconv != (size_t)-2) { + nread += n; + width--; + if (!(flags & SUPPRESS)) + wcp++; + n = 0; + } + if (fp->_r <= 0 && __srefill(fp)) { + if (n != 0) { + fp->_flags |= __SERR; + goto input_failure; + } + break; + } + } + if (!(flags & SUPPRESS)) + nassigned++; + } else if (flags & SUPPRESS) { + size_t sum = 0; + for (;;) { + if ((n = fp->_r) < width) { + sum += n; + width -= n; + fp->_p += n; + if (__srefill(fp)) { + if (sum == 0) + goto input_failure; + break; + } + } else { + sum += width; + fp->_r -= width; + fp->_p += width; + break; + } + } + nread += sum; + } else { + size_t r = fread((void *)va_arg(ap, char *), 1, + width, fp); + + if (r == 0) + goto input_failure; + nread += r; + nassigned++; + } + break; + + case CT_CCL: + /* scan a (nonempty) character class (sets NOSKIP) */ + if (width == 0) + width = (size_t)~0; /* `infinity' */ + /* take only those things in the class */ + if (flags & LONG) { + wchar_t twc; + int nchars; + + if ((flags & SUPPRESS) == 0) + wcp = wcp0 = va_arg(ap, wchar_t *); + else + wcp = wcp0 = &twc; + n = 0; + nchars = 0; + while (width != 0) { + if (n == mb_cur_max) { + fp->_flags |= __SERR; + goto input_failure; + } + buf[n++] = *fp->_p; + fp->_p++; + fp->_r--; + mbs = initial; + nconv = mbrtowc_l(wcp, buf, n, &mbs, loc); + if (nconv == (size_t)-1) { + fp->_flags |= __SERR; + goto input_failure; + } + if (nconv == 0) + *wcp = L'\0'; + if (nconv != (size_t)-2) { + if (wctob_l(*wcp, loc) != EOF && + !ccltab[wctob_l(*wcp, loc)]) { + while (n != 0) { + n--; + __ungetc(buf[n], + fp); + } + break; + } + nread += n; + width--; + if (!(flags & SUPPRESS)) + wcp++; + nchars++; + n = 0; + } + if (fp->_r <= 0 && __srefill(fp)) { + if (n != 0) { + fp->_flags |= __SERR; + goto input_failure; + } + break; + } + } + if (n != 0) { + fp->_flags |= __SERR; + goto input_failure; + } + n = nchars; + if (n == 0) + goto match_failure; + if (!(flags & SUPPRESS)) { + *wcp = L'\0'; + nassigned++; + } + } else if (flags & SUPPRESS) { + n = 0; + while (ccltab[*fp->_p]) { + n++, fp->_r--, fp->_p++; + if (--width == 0) + break; + if (fp->_r <= 0 && __srefill(fp)) { + if (n == 0) + goto input_failure; + break; + } + } + if (n == 0) + goto match_failure; + } else { + p0 = p = va_arg(ap, char *); + while (ccltab[*fp->_p]) { + fp->_r--; + *p++ = *fp->_p++; + if (--width == 0) + break; + if (fp->_r <= 0 && __srefill(fp)) { + if (p == p0) + goto input_failure; + break; + } + } + n = p - p0; + if (n == 0) + goto match_failure; + *p = 0; + nassigned++; + } + nread += n; + break; + + case CT_STRING: + /* like CCL, but zero-length string OK, & no NOSKIP */ + if (width == 0) + width = (size_t)~0; + if (flags & LONG) { + wchar_t twc; + + if ((flags & SUPPRESS) == 0) + wcp = va_arg(ap, wchar_t *); + else + wcp = &twc; + n = 0; + while (width != 0) { + if (n == mb_cur_max) { + fp->_flags |= __SERR; + goto input_failure; + } + buf[n++] = *fp->_p; + fp->_p++; + fp->_r--; + mbs = initial; + nconv = mbrtowc_l(wcp, buf, n, &mbs, loc); + if (nconv == (size_t)-1) { + fp->_flags |= __SERR; + goto input_failure; + } + if (nconv == 0) + *wcp = L'\0'; + if (nconv != (size_t)-2) { + if (iswspace_l(*wcp, loc)) { + while (n != 0) { + n--; + __ungetc(buf[n], + fp); + } + break; + } + nread += n; + width--; + if (!(flags & SUPPRESS)) + wcp++; + n = 0; + } + if (fp->_r <= 0 && __srefill(fp)) { + if (n != 0) { + fp->_flags |= __SERR; + goto input_failure; + } + break; + } + } + if (!(flags & SUPPRESS)) { + *wcp = L'\0'; + nassigned++; + } + } else if (flags & SUPPRESS) { + n = 0; + while (!isspace_l(*fp->_p, loc)) { + n++, fp->_r--, fp->_p++; + if (--width == 0) + break; + if (fp->_r <= 0 && __srefill(fp)) + break; + } + nread += n; + } else { + p0 = p = va_arg(ap, char *); + while (!isspace_l(*fp->_p, loc)) { + fp->_r--; + *p++ = *fp->_p++; + if (--width == 0) + break; + if (fp->_r <= 0 && __srefill(fp)) + break; + } + *p = 0; + nread += p - p0; + nassigned++; + } + continue; + + case CT_INT: + /* scan an integer as if by the conversion function */ +#ifdef hardway + if (width == 0 || width > sizeof(buf) - 1) + width = sizeof(buf) - 1; +#else + /* size_t is unsigned, hence this optimisation */ + if (--width > sizeof(buf) - 2) + width = sizeof(buf) - 2; + width++; +#endif + flags |= SIGNOK | NDIGITS | NZDIGITS; + for (p = buf; width; width--) { + c = *fp->_p; + /* + * Switch on the character; `goto ok' + * if we accept it as a part of number. + */ + switch (c) { + + /* + * The digit 0 is always legal, but is + * special. For %i conversions, if no + * digits (zero or nonzero) have been + * scanned (only signs), we will have + * base==0. In that case, we should set + * it to 8 and enable 0x prefixing. + * Also, if we have not scanned zero digits + * before this, do not turn off prefixing + * (someone else will turn it off if we + * have scanned any nonzero digits). + */ + case '0': + if (base == 0) { + base = 8; + flags |= PFXOK; + } + if (flags & NZDIGITS) + flags &= ~(SIGNOK|NZDIGITS|NDIGITS); + else + flags &= ~(SIGNOK|PFXOK|NDIGITS); + goto ok; + + /* 1 through 7 always legal */ + case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + base = basefix[base]; + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* digits 8 and 9 ok iff decimal or hex */ + case '8': case '9': + base = basefix[base]; + if (base <= 8) + break; /* not legal here */ + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* letters ok iff hex */ + case 'A': case 'B': case 'C': + case 'D': case 'E': case 'F': + case 'a': case 'b': case 'c': + case 'd': case 'e': case 'f': + /* no need to fix base here */ + if (base <= 10) + break; /* not legal here */ + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* sign ok only as first character */ + case '+': case '-': + if (flags & SIGNOK) { + flags &= ~SIGNOK; + flags |= HAVESIGN; + goto ok; + } + break; + + /* + * x ok iff flag still set & 2nd char (or + * 3rd char if we have a sign). + */ + case 'x': case 'X': + if (flags & PFXOK && p == + buf + 1 + !!(flags & HAVESIGN)) { + base = 16; /* if %i */ + flags &= ~PFXOK; + goto ok; + } + break; + } + + /* + * If we got here, c is not a legal character + * for a number. Stop accumulating digits. + */ + break; + ok: + /* + * c is legal: store it and look at the next. + */ + *p++ = c; + if (--fp->_r > 0) + fp->_p++; + else if (__srefill(fp)) + break; /* EOF */ + } + /* + * If we had only a sign, it is no good; push + * back the sign. If the number ends in `x', + * it was [sign] '0' 'x', so push back the x + * and treat it as [sign] '0'. + */ + if (flags & NDIGITS) { + if (p > buf) + (void) __ungetc(*(u_char *)--p, fp); + goto match_failure; + } + c = ((u_char *)p)[-1]; + if (c == 'x' || c == 'X') { + --p; + (void) __ungetc(c, fp); + } + if ((flags & SUPPRESS) == 0) { + uintmax_t res; + + *p = 0; + if ((flags & UNSIGNED) == 0) + res = strtoimax_l(buf, (char **)NULL, base, loc); + else + res = strtoumax_l(buf, (char **)NULL, base, loc); + if (flags & POINTER) + *va_arg(ap, void **) = + (void *)(uintptr_t)res; + else if (flags & SHORTSHORT) + *va_arg(ap, char *) = res; + else if (flags & SHORT) + *va_arg(ap, short *) = res; + else if (flags & LONG) + *va_arg(ap, long *) = res; + else if (flags & LONGLONG) + *va_arg(ap, long long *) = res; + else if (flags & INTMAXT) + *va_arg(ap, intmax_t *) = res; + else if (flags & PTRDIFFT) + *va_arg(ap, ptrdiff_t *) = res; + else if (flags & SIZET) + *va_arg(ap, size_t *) = res; + else + *va_arg(ap, int *) = res; + nassigned++; + } + nread += p - buf; + break; + +#ifndef NO_FLOATING_POINT + case CT_FLOAT: + { + char *pbuf; + /* scan a floating point number as if by strtod */ + if ((width = parsefloat(fp, &pbuf, width, loc)) == 0) + goto match_failure; + if ((flags & SUPPRESS) == 0) { + if (flags & LONGDBL) { + long double res = strtold_l(pbuf, &p, loc); + *va_arg(ap, long double *) = res; + } else if (flags & LONG) { + double res = strtod_l(pbuf, &p, loc); + *va_arg(ap, double *) = res; + } else { + float res = strtof_l(pbuf, &p, loc); + *va_arg(ap, float *) = res; + } + if (__scanfdebug && p - pbuf != width) + abort(); + nassigned++; + } + nread += width; + break; + } +#endif /* !NO_FLOATING_POINT */ + } + } +input_failure: + return (nassigned ? nassigned : EOF); +match_failure: + return (nassigned); +} + +int +__svfscanf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) +{ + return __svfscanf_l(fp, __current_locale(), fmt0, ap); +} + +/* + * Fill in the given table from the scanset at the given format + * (just after `['). Return a pointer to the character past the + * closing `]'. The table has a 1 wherever characters should be + * considered part of the scanset. + */ +static const u_char * +__sccl(tab, fmt, loc) + char *tab; + const u_char *fmt; + locale_t loc; +{ + int c, n, v, i; + + /* first `clear' the whole table */ + c = *fmt++; /* first char hat => negated scanset */ + if (c == '^') { + v = 1; /* default => accept */ + c = *fmt++; /* get new first char */ + } else + v = 0; /* default => reject */ + + /* XXX: Will not work if sizeof(tab*) > sizeof(char) */ + (void) memset(tab, v, 256); + + if (c == 0) + return (fmt - 1);/* format ended before closing ] */ + + /* + * Now set the entries corresponding to the actual scanset + * to the opposite of the above. + * + * The first character may be ']' (or '-') without being special; + * the last character may be '-'. + */ + v = 1 - v; + for (;;) { + tab[c] = v; /* take character c */ +doswitch: + n = *fmt++; /* and examine the next */ + switch (n) { + + case 0: /* format ended too soon */ + return (fmt - 1); + + case '-': + { + /* + * A scanset of the form + * [01+-] + * is defined as `the digit 0, the digit 1, + * the character +, the character -', but + * the effect of a scanset such as + * [a-zA-Z0-9] + * is implementation defined. The V7 Unix + * scanf treats `a-z' as `the letters a through + * z', but treats `a-a' as `the letter a, the + * character -, and the letter a'. + * + * For compatibility, the `-' is not considerd + * to define a range if the character following + * it is either a close bracket (required by ANSI) + * or is not numerically greater than the character + * we just stored in the table (c). + */ + n = *fmt; + if (n == ']' + || (loc->__collate_load_error ? n < c : + __collate_range_cmp (n, c, loc) < 0 + ) + ) { + c = '-'; + break; /* resume the for(;;) */ + } + fmt++; + /* fill in the range */ + if (loc->__collate_load_error) { + do { + tab[++c] = v; + } while (c < n); + } else { + for (i = 0; i < 256; i ++) + if ( __collate_range_cmp (c, i, loc) < 0 + && __collate_range_cmp (i, n, loc) <= 0 + ) + tab[i] = v; + } +#if 1 /* XXX another disgusting compatibility hack */ + c = n; + /* + * Alas, the V7 Unix scanf also treats formats + * such as [a-c-e] as `the letters a through e'. + * This too is permitted by the standard.... + */ + goto doswitch; +#else + c = *fmt++; + if (c == 0) + return (fmt - 1); + if (c == ']') + return (fmt); +#endif + break; + } + case ']': /* end of scanset */ + return (fmt); + + default: /* just another character */ + c = n; + break; + } + } + /* NOTREACHED */ +} + +#ifndef NO_FLOATING_POINT +static int +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_DECIMAL_POINT + } state = S_START; + unsigned char c; + unsigned char *decpt = (unsigned char *)localeconv_l(loc)->decimal_point; + char *decpt_start; + _Bool gotmantdig = 0, ishex = 0; + static char *b = NULL; + static size_t bsiz = 0; + char *e; + size_t s; + + if (bsiz = 0) { + b = (char *)malloc(BUF); + if (b == NULL) { + *buf = NULL; + return 0; + } + bsiz = BUF; + } + s = (width == 0 ? BUF : (width + 1)); + if (s > bsiz) { + b = (char *)reallocf(b, s); + if (b == NULL) { + bsiz = 0; + *buf = NULL; + return 0; + } + bsiz = s; + } + e = b + (s - 1); + /* + * We set commit = p whenever the string we have read so far + * constitutes a valid representation of a floating point + * number by itself. At some point, the parse will complete + * or fail, and we will ungetc() back to the last commit point. + * To ensure that the file offset gets updated properly, it is + * always necessary to read at least one character that doesn't + * match; thus, we can't short-circuit "infinity" or "nan(...)". + */ + commit = b - 1; + for (p = b; width == 0 || p < e; ) { + c = *fp->_p; +reswitch: + switch (state) { + case S_START: + state = S_GOTSIGN; + if (c == '-' || c == '+') + break; + else + goto reswitch; + case S_GOTSIGN: + switch (c) { + case '0': + state = S_MAYBEHEX; + commit = p; + break; + case 'I': + case 'i': + state = S_INF; + break; + case 'N': + case 'n': + state = S_NAN; + break; + default: + state = S_DIGITS; + goto reswitch; + } + break; + case S_INF: + if (infnanpos > 6 || + (c != "nfinity"[infnanpos] && + c != "NFINITY"[infnanpos])) + goto parsedone; + if (infnanpos == 1 || infnanpos == 6) + commit = p; /* inf or infinity */ + infnanpos++; + 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; + break; + case 1: + if (c != 'N' && c != 'n') + goto parsedone; + else + commit = p; + break; + case 2: + if (c != '(') + goto parsedone; + break; + default: + if (c == ')') { + commit = p; + infnanpos = -2; + } else if (!isalnum_l(c, loc) && c != '_') + goto parsedone; + break; + } + infnanpos++; + break; + case S_MAYBEHEX: + state = S_DIGITS; + if (c == 'X' || c == 'x') { + ishex = 1; + break; + } else { /* we saw a '0', but no 'x' */ + gotmantdig = 1; + goto reswitch; + } + case S_DIGITS: + 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; + 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)) { + if (!gotmantdig) + goto parsedone; + else + state = S_EXP; + } else if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc)) { + commit = p; + gotmantdig = 1; + } else + goto parsedone; + break; + case S_EXP: + state = S_EXPDIGITS; + if (c == '-' || c == '+') + break; + else + goto reswitch; + case S_EXPDIGITS: + if (isdigit_l(c, loc)) + commit = p; + else + goto parsedone; + break; + default: + abort(); + } + if (p >= e) { + ssize_t diff = (p - b); + ssize_t com = (commit - b); + s += BUF; + b = (char *)reallocf(b, s); + if (b == NULL) { + bsiz = 0; + *buf = NULL; + return 0; + } + bsiz = s; + e = b + (s - 1); + p = b + diff; + commit = b + com; + } + *p++ = c; + if (--fp->_r > 0) + fp->_p++; + else if (__srefill(fp)) + break; /* EOF */ + } + +parsedone: + while (commit < --p) + __ungetc(*(u_char *)p, fp); + *++commit = '\0'; + *buf = b; + return (commit - b); +} +#endif diff --git a/stdio/vfwprintf-fbsd.c b/stdio/vfwprintf-fbsd.c new file mode 100644 index 0000000..9460ef7 --- /dev/null +++ b/stdio/vfwprintf-fbsd.c @@ -0,0 +1,2096 @@ +/*- + * 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. + */ + +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +/* + * Actual wprintf innards. + * + * Avoid making gratuitous changes to this source file; it should be kept + * as close as possible to vfprintf.c for ease of maintenance. + */ + +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" +#include "local.h" +#include "fvwrite.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; + 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 */ +}; + +/* + * 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_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 *, 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 *); + +/* + * Helper function for `fprintf to unbuffered unix file': creates a + * temporary buffer. We only work on write-only files; this avoids + * worries about ungetc buffers and so forth. + */ +static int +__sbprintf(FILE *fp, locale_t loc, const wchar_t *fmt, va_list ap) +{ + int ret; + FILE fake; + unsigned char buf[BUFSIZ]; + + /* 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; + + /* set up the buffer */ + fake._bf._base = fake._p = buf; + fake._bf._size = fake._w = sizeof(buf); + fake._lbfsize = 0; /* not actually used, but Just In Case */ + + /* do the work, then copy any error status */ + ret = __vfwprintf(&fake, loc, fmt, ap); + if (ret >= 0 && __fflush(&fake)) + ret = WEOF; + if (fake._flags & __SERR) + fp->_flags |= __SERR; + return (ret); +} + +/* + * Like __fputwc, but handles fake string (__SSTR) files properly. + * File must already be locked. + */ +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; + struct __siov iov; + size_t len; + + if ((fp->_flags & __SSTR) == 0) + return (__fputwc(wc, fp, loc)); + + mbs = initial; + if ((len = wcrtomb_l(buf, wc, &mbs, loc)) == (size_t)-1) { + fp->_flags |= __SERR; + return (WEOF); + } + uio.uio_iov = &iov; + uio.uio_resid = len; + uio.uio_iovcnt = 1; + iov.iov_base = buf; + iov.iov_len = len; + 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 + * to output. If ``prec'' is greater than or equal to zero, we can't assume + * that the multibyte char. string ends in a null character. + */ +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; + size_t insize, nchars, nconv = 0; + int mb_cur_max = MB_CUR_MAX_L(loc); + + if (mbsarg == NULL) + return (NULL); + + /* + * Supplied argument is a multibyte string; convert it to wide + * characters first. + */ + if (prec >= 0) { + /* + * String is not guaranteed to be NUL-terminated. Find the + * number of characters to print. + */ + p = mbsarg; + insize = nchars = 0; + mbs = initial; + while (nchars != (size_t)prec) { + nconv = mbrlen_l(p, mb_cur_max, &mbs, loc); + if (nconv == 0 || nconv == (size_t)-1 || + nconv == (size_t)-2) + break; + p += nconv; + nchars++; + insize += nconv; + } + if (nconv == (size_t)-1 || nconv == (size_t)-2) + return (NULL); + } else + insize = strlen(mbsarg); + + /* + * Allocate buffer for the result and perform the conversion, + * converting at most `size' bytes of the input multibyte string to + * wide characters for printing. + */ + convbuf = malloc((insize + 1) * sizeof(*convbuf)); + if (convbuf == NULL) + return (NULL); + wcp = convbuf; + p = mbsarg; + mbs = initial; + while (insize != 0) { + nconv = mbrtowc_l(wcp, p, insize, &mbs, loc); + if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) + break; + wcp++; + p += nconv; + insize -= nconv; + } + if (nconv == (size_t)-1 || nconv == (size_t)-2) { + free(convbuf); + return (NULL); + } + *wcp = L'\0'; + + return (convbuf); +} + +/* + * MT-safe version + */ +__private_extern__ const char *__fix_nogrouping(const char *); + +int +vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) + +{ + int ret; + + FLOCKFILE(fp); + 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); + 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. + */ +#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 */ + +/* + * Non-MT-safe version + */ +__private_extern__ int +__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) */ + 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 */ +#ifndef NO_FLOATING_POINT + /* + * We can decompose the printed representation of floating + * point numbers into several parts, some of which may be empty: + * + * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ + * A B ---C--- D E F + * + * A: 'sign' holds this value if present; '\0' otherwise + * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal + * C: cp points to the string MMMNNN. Leading and trailing + * zeros are not in the string and must be added. + * 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 + */ + 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; + long double ldbl; + } fparg; + int expt; /* integer value of exponent */ + 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. */ + wchar_t *pct; /* Pointer to '%' at beginning of specifier. */ + wchar_t vsep; /* Vector separator character. */ +#endif + u_long ulval; /* integer arguments %[diouxX] */ + uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ + int base; /* base for [diouxX] conversion */ + int dprec; /* a copy of prec if [diouxX], 0 otherwise */ + int realsz; /* field size expanded by dprec, sign, etc */ + int size; /* size of converted field or string */ + int prsize; /* max size of printed field */ + const char *xdigs; /* digits for [xX] conversion */ + 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 */ + union arg statargtable [STATIC_ARG_TBL_SIZE]; + int nextarg; /* 1-based argument index */ + 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'. + */ +#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); \ + } \ +} 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) + + /* + * Get the argument indexed by nextarg. If the argument table is + * built, use it to get the argument. If its not, get the next + * argument (and arguments must be gotten sequentially). + */ +#define GETARG(type) \ + ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ + (nextarg++, va_arg(ap, type))) + + /* + * To extend shorts properly, we need both signed and unsigned + * argument extraction methods. + */ +#define SARG() \ + (flags&LONGINT ? GETARG(long) : \ + flags&SHORTINT ? (long)(short)GETARG(int) : \ + flags&CHARINT ? (long)(signed char)GETARG(int) : \ + (long)GETARG(int)) +#define UARG() \ + (flags&LONGINT ? GETARG(u_long) : \ + flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \ + flags&CHARINT ? (u_long)(u_char)GETARG(int) : \ + (u_long)GETARG(u_int)) +#define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) +#define SJARG() \ + (flags&INTMAXT ? GETARG(intmax_t) : \ + flags&SIZET ? (intmax_t)GETARG(ssize_t) : \ + flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ + (intmax_t)GETARG(long long)) +#define UJARG() \ + (flags&INTMAXT ? GETARG(uintmax_t) : \ + flags&SIZET ? (uintmax_t)GETARG(size_t) : \ + flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ + (uintmax_t)GETARG(unsigned long long)) + + /* + * Get * arguments, including the form *nn$. Preserve the nextarg + * that the argument can be gotten once the type is determined. + */ +#define GETASTER(val) \ + n2 = 0; \ + cp = fmt; \ + while (is_digit(*cp)) { \ + n2 = 10 * n2 + to_digit(*cp); \ + cp++; \ + } \ + if (*cp == '$') { \ + int hold = nextarg; \ + if (argtable == NULL) { \ + argtable = statargtable; \ + __find_arguments (fmt0, orgap, &argtable); \ + } \ + nextarg = n2; \ + val = GETARG (int); \ + nextarg = hold; \ + fmt = ++cp; \ + } else { \ + 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; + return (EOF); + } + 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)); + + fmt = (wchar_t *)fmt0; + argtable = NULL; + nextarg = 1; + va_copy(orgap, ap); + ret = 0; + + /* + * Scan the format for conversions (`%' character). + */ + for (;;) { + for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) + /* void */; + if ((n = fmt - cp) != 0) { + if ((unsigned)ret + n > INT_MAX) { + ret = EOF; + goto error; + } + PRINT(cp, n); + ret += n; + } + if (ch == '\0') + goto done; +#ifdef VECTORS + pct = fmt; +#endif /* VECTORS */ + fmt++; /* skip over '%' */ + + flags = 0; + dprec = 0; + width = 0; + prec = -1; + sign = '\0'; + ox[1] = '\0'; +#ifdef VECTORS + vsep = 'X'; /* Illegal value, changed to defaults later. */ +#endif /* VECTORS */ + +rflag: ch = *fmt++; +reswitch: switch (ch) { + case ' ': + /*- + * ``If the space and + flags both appear, the space + * flag will be ignored.'' + * -- ANSI X3J11 + */ + if (!sign) + sign = ' '; + goto rflag; + case '#': + flags |= ALT; + goto rflag; +#ifdef VECTORS + case ',': case ';': case ':': case '_': + vsep = ch; + goto rflag; +#endif /* VECTORS */ + case '*': + /*- + * ``A negative field width argument is taken as a + * - flag followed by a positive field width.'' + * -- ANSI X3J11 + * They don't exclude field widths read from args. + */ + GETASTER (width); + if (width >= 0) + goto rflag; + width = -width; + /* FALLTHROUGH */ + case '-': + flags |= LADJUST; + goto rflag; + case '+': + sign = '+'; + 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++) == '*') { + GETASTER (prec); + goto rflag; + } + prec = 0; + while (is_digit(ch)) { + prec = 10 * prec + to_digit(ch); + ch = *fmt++; + } + goto reswitch; + case '0': + /*- + * ``Note that 0 is taken as a flag, not as the + * beginning of a field width.'' + * -- ANSI X3J11 + */ + flags |= ZEROPAD; + 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; + if (argtable == NULL) { + argtable = statargtable; + __find_arguments (fmt0, orgap, + &argtable); + } + 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': +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + if (flags & LONGINT) + *(cp = buf) = (wchar_t)GETARG(wint_t); + else + *(cp = buf) = (wchar_t)btowc_l(GETARG(int), loc); + size = 1; + sign = '\0'; + break; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + if (flags & INTMAX_SIZE) { + ujval = SJARG(); + if ((intmax_t)ujval < 0) { + ujval = -ujval; + sign = '-'; + } + } else { + ulval = SARG(); + if ((long)ulval < 0) { + ulval = -ulval; + sign = '-'; + } + } + base = 10; + goto number; +#ifndef NO_FLOATING_POINT + case 'a': + case 'A': +#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; + break; + } +#endif /* VECTORS */ + if (ch == 'a') { + ox[1] = 'x'; + xdigs = xdigs_lower; + expchar = 'p'; + } else { + ox[1] = 'X'; + xdigs = xdigs_upper; + expchar = 'P'; + } + if (prec >= 0) + prec++; +#ifdef LDBL_COMPAT + fparg.dbl = GETARG(double); + dtoaresult = + __hdtoa(fparg.dbl, xdigs, prec, + &expt, &signflag, &dtoaend); +#else /* !LDBL_COMPAT */ + if (flags & LONGDBL) { + fparg.ldbl = GETARG(long double); + dtoaresult = + __hldtoa(fparg.ldbl, xdigs, prec, + &expt, &signflag, &dtoaend); + } else { + fparg.dbl = GETARG(double); + dtoaresult = + __hdtoa(fparg.dbl, xdigs, prec, + &expt, &signflag, &dtoaend); + } +#endif /* LDBL_COMPAT */ + if (prec < 0) + prec = dtoaend - dtoaresult; + if (expt == INT_MAX) + ox[1] = '\0'; + if (convbuf != NULL) + free(convbuf); + ndig = dtoaend - dtoaresult; + cp = convbuf = __mbsconv(dtoaresult, -1, loc); + freedtoa(dtoaresult); + goto fp_common; + case 'e': + case 'E': +#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; + break; + } +#endif /* VECTORS */ + expchar = ch; + if (prec < 0) /* account for digit before decpt */ + prec = DEFPREC + 1; + else + prec++; + goto fp_begin; + case 'f': + case 'F': +#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; + break; + } +#endif /* VECTORS */ + expchar = '\0'; + goto fp_begin; + case 'g': + case 'G': +#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; + break; + } +#endif /* VECTORS */ + expchar = ch - ('g' - 'e'); + if (prec == 0) + prec = 1; +fp_begin: + if (prec < 0) + prec = DEFPREC; + if (convbuf != NULL) + free(convbuf); +#ifdef LDBL_COMPAT + fparg.dbl = GETARG(double); + dtoaresult = + dtoa(fparg.dbl, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); + if (expt == 9999) + expt = INT_MAX; +#else /* !LDBL_COMPAT */ + if (flags & LONGDBL) { + fparg.ldbl = GETARG(long double); + dtoaresult = + __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); + } else { + fparg.dbl = GETARG(double); + dtoaresult = + dtoa(fparg.dbl, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); + if (expt == 9999) + expt = INT_MAX; + } +#endif /* LDBL_COMPAT */ + ndig = dtoaend - dtoaresult; + cp = convbuf = __mbsconv(dtoaresult, -1, loc); + freedtoa(dtoaresult); +fp_common: + if (signflag) + sign = '-'; + if (expt == INT_MAX) { /* inf or nan */ + if (*cp == 'N') { + cp = (ch >= 'a') ? L"nan" : L"NAN"; + sign = '\0'; + } else + cp = (ch >= 'a') ? L"inf" : L"INF"; + size = 3; + break; + } + flags |= FPT; + if (ch == 'g' || ch == 'G') { + if (expt > -4 && expt <= prec) { + /* Make %[gG] smell like %[fF] */ + expchar = '\0'; + if (flags & ALT) + prec -= expt; + else + prec = ndig - expt; + if (prec < 0) + prec = 0; + } else { + /* + * Make %[gG] smell like %[eE], but + * trim trailing zeroes if no # flag. + */ + if (!(flags & ALT)) + prec = ndig; + } + } + if (expchar) { + expsize = exponent(expstr, expt - 1, expchar); + size = expsize + prec; + if (prec > 1 || flags & ALT) + ++size; + } else { + /* space for digits before decimal point */ + if (expt > 0) + size = expt; + else /* "0" */ + 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; + } + 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; + else if (flags & SIZET) + *GETARG(ssize_t *) = (ssize_t)ret; + else if (flags & PTRDIFFT) + *GETARG(ptrdiff_t *) = ret; + else if (flags & INTMAXT) + *GETARG(intmax_t *) = ret; + else if (flags & LONGINT) + *GETARG(long *) = ret; + else if (flags & SHORTINT) + *GETARG(short *) = ret; + else if (flags & CHARINT) + *GETARG(signed char *) = ret; + else + *GETARG(int *) = ret; + continue; /* no output */ + case 'O': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else + ulval = UARG(); + base = 8; + goto nosign; + case 'p': + /*- + * ``The argument shall be a pointer to void. The + * value of the pointer is converted to a sequence + * of printable characters, in an implementation- + * defined manner.'' + * -- ANSI X3J11 + */ +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + ujval = (uintmax_t)(uintptr_t)GETARG(void *); + base = 16; + xdigs = xdigs_lower; + flags = flags | INTMAXT; + ox[1] = 'x'; + goto nosign; + case 'S': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 's': + if (flags & LONGINT) { + if ((cp = GETARG(wchar_t *)) == NULL) + cp = L"(null)"; + } else { + char *mbp; + + if (convbuf != NULL) + free(convbuf); + if ((mbp = GETARG(char *)) == NULL) + cp = L"(null)"; + else { + convbuf = __mbsconv(mbp, prec, loc); + if (convbuf == NULL) { + fp->_flags |= __SERR; + goto error; + } + 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); + sign = '\0'; + break; + case 'U': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else + ulval = UARG(); + base = 10; + goto nosign; + case 'X': + xdigs = xdigs_upper; + goto hex; + case 'x': + xdigs = xdigs_lower; +hex: +#ifdef VECTORS + if (flags & VECTOR) + break; +#endif /* VECTORS */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else + ulval = UARG(); + base = 16; + /* leading 0x/X only if non-zero */ + if (flags & ALT && + (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) + ox[1] = ch; + + flags &= ~GROUPING; + /* unsigned conversions */ +nosign: sign = '\0'; + /*- + * ``... diouXx conversions ... if a precision is + * specified, the 0 flag will be ignored.'' + * -- ANSI X3J11 + */ +number: if ((dprec = prec) >= 0) + flags &= ~ZEROPAD; + + /*- + * ``The result of converting a zero value with an + * explicit precision of zero is no characters.'' + * -- ANSI X3J11 + * except for %#.0o and zero value + */ + cp = buf + BUF; + if (flags & INTMAX_SIZE) { + if (ujval != 0 || prec != 0) + cp = __ujtoa(ujval, cp, base, + flags & ALT, xdigs, + flags & GROUPING, thousands_sep, + grouping); + } else { + if (ulval != 0 || prec != 0 || (flags & ALT)) + cp = __ultoa(ulval, cp, base, + flags & ALT, xdigs, + flags & GROUPING, thousands_sep, + grouping); + } + size = buf + BUF - cp; + if (size > BUF) /* should never happen */ + abort(); + break; +#ifdef VECTORS + case 'v': + flags |= VECTOR; + goto rflag; +#endif /* VECTORS */ + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; + /* pretend it was %c with argument ch */ + cp = buf; + *cp = ch; + size = 1; + sign = '\0'; + break; + } + +#ifdef VECTORS + if (flags & VECTOR) { + /* + * Do the minimum amount of work necessary to construct + * a format specifier that can be used to recursively + * call vfprintf() for each element in the vector. + */ + int i, j; /* Counter. */ + int vcnt; /* Number of elements in vector. */ + char *vfmt; /* Pointer to format specifier. */ +#define EXTRAHH 2 + char vfmt_buf[32 + EXTRAHH]; /* Static buffer for format spec. */ + int vwidth = 0; /* Width specified via '*'. */ + int vprec = 0; /* Precision specified via '*'. */ + char *vstr; /* Used for asprintf(). */ + int vlen; /* Length returned by asprintf(). */ + enum { + V_CHAR, V_SHORT, V_INT, + V_PCHAR, V_PSHORT, V_PINT, + V_FLOAT, +#ifdef V64TYPE + V_LONGLONG, V_PLONGLONG, + V_DOUBLE, +#endif /* V64TYPE */ + } vtype; + + vval.vectorarg = GETARG(VECTORTYPE); + /* + * Set vfmt. If vfmt_buf may not be big enough, + * malloc() space, taking care to free it later. + * (EXTRAHH is for possible extra "hh") + */ + if (&fmt[-1] - pct + EXTRAHH < sizeof(vfmt_buf)) + vfmt = vfmt_buf; + else + vfmt = (char *)malloc(&fmt[-1] - pct + EXTRAHH + 1); + + /* Set the separator character, if not specified. */ + if (vsep == 'X') { + if (ch == 'c') + vsep = '\0'; + else + vsep = ' '; + } + + /* Create the format specifier. */ + for (i = j = 0; i < &fmt[-1] - pct; i++) { + switch (pct[i]) { + case ',': case ';': case ':': case '_': + case 'v': case 'h': case 'l': + /* Ignore. */ + break; + case '*': + if (pct[i - 1] != '.') + vwidth = 1; + else + vprec = 1; + /* FALLTHROUGH */ + default: + vfmt[j++] = pct[i]; + } + } + + /* + * Determine the number of elements in the vector and + * finish up the format specifier. + */ + if (flags & SHORTINT) { + switch (ch) { + case 'c': + vtype = V_SHORT; + break; + case 'p': + vtype = V_PSHORT; + break; + default: + vfmt[j++] = 'h'; + vtype = V_SHORT; + break; + } + vcnt = 8; + } else if (flags & LONGINT) { + vcnt = 4; + vtype = (ch == 'p') ? V_PINT : V_INT; +#ifdef V64TYPE + } else if (flags & LLONGINT) { + switch (ch) { + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + vcnt = 2; + vtype = V_DOUBLE; + break; + case 'd': + case 'i': + case 'u': + case 'o': + case 'p': + case 'x': + case 'X': + vfmt[j++] = 'l'; + vfmt[j++] = 'l'; + vcnt = 2; + vtype = (ch == 'p') ? V_PLONGLONG : V_LONGLONG; + break; + default: + /* + * The default case should never + * happen. + */ + case 'c': + vcnt = 16; + vtype = V_CHAR; + } +#endif /* V64TYPE */ + } else { + switch (ch) { + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + vcnt = 4; + vtype = V_FLOAT; + break; + default: + /* + * The default case should never + * happen. + */ + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + vfmt[j++] = 'h'; + vfmt[j++] = 'h'; + /* drop through */ + case 'p': + case 'c': + vcnt = 16; + vtype = (ch == 'p') ? V_PCHAR : V_CHAR; + } + } + vfmt[j++] = ch; + vfmt[j++] = '\0'; + +/* Get a vector element. */ +#ifdef V64TYPE +#define VPRINT(type, ind, args...) do { \ + switch (type) { \ + case V_CHAR: \ + 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]); \ + 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]); \ + 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]); \ + 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]); \ + break; \ + case V_FLOAT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ + break; \ + case V_DOUBLE: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vdoublearg[ind]); \ + break; \ + } \ + ret += vlen; \ + PRINT(vstr, vlen); \ + free(vstr); \ +} while (0) +#else /* !V64TYPE */ +#define VPRINT(type, ind, args...) do { \ + switch (type) { \ + case V_CHAR: \ + 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]); \ + 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]); \ + 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]); \ + break; \ + case V_FLOAT: \ + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ + break; \ + } \ + ret += vlen; \ + PRINT(vstr, vlen); \ + free(vstr); \ +} while (0) +#endif /* V64TYPE */ + + /* Actually print. */ + if (vwidth == 0) { + if (vprec == 0) { + /* First element. */ + VPRINT(vtype, 0); + for (i = 1; i < vcnt; i++) { + /* Separator. */ + if(vsep) + PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vtype, i); + } + } else { + /* First element. */ + VPRINT(vtype, 0, prec); + for (i = 1; i < vcnt; i++) { + /* Separator. */ + if(vsep) + PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vtype, i, prec); + } + } + } else { + if (vprec == 0) { + /* First element. */ + VPRINT(vtype, 0, width); + for (i = 1; i < vcnt; i++) { + /* Separator. */ + if(vsep) + PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vtype, i, width); + } + } else { + /* First element. */ + VPRINT(vtype, 0, width, prec); + for (i = 1; i < vcnt; i++) { + /* Separator. */ + if(vsep) + PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vtype, i, width, prec); + } + } + } +#undef VPRINT + + if (vfmt != vfmt_buf) + free(vfmt); + + continue; + } +#endif /* VECTORS */ + /* + * All reasonable formats wind up here. At this point, `cp' + * points to a string which (if not flags&LADJUST) should be + * padded out to `width' places. If flags&ZEROPAD, it should + * first be prefixed by any sign or other prefix; otherwise, + * it should be blank padded before the prefix is emitted. + * After any left-hand padding and prefixing, emit zeroes + * required by a decimal [diouxX] precision, then print the + * string proper, then emit zeroes required by any leftover + * floating precision; finally, if LADJUST, pad with blanks. + * + * Compute actual size, so we know how much to pad. + * size excludes decimal prec; realsz includes it. + */ + realsz = dprec > size ? dprec : size; + if (sign) + realsz++; + if (ox[1]) + realsz += 2; + + prsize = width > realsz ? width : realsz; + if ((unsigned)ret + prsize > INT_MAX) { + ret = EOF; + goto error; + } + + /* right-adjusting blank padding */ + if ((flags & (LADJUST|ZEROPAD)) == 0) + PAD(width - realsz, blanks); + + /* prefix */ + if (sign) + PRINT(&sign, 1); + + if (ox[1]) { /* ox[1] is either x, X, or \0 */ + ox[0] = '0'; + PRINT(ox, 2); + } + + /* right-adjusting zero padding */ + 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); + } 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); + 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) { + 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; + PRINT(buf, 2); + PRINT(cp, ndig-1); + PAD(prec - ndig, zeroes); + } else /* XeYYY */ + PRINT(cp, 1); + PRINT(expstr, expsize); + } + } +#else + PRINT(cp, size); +#endif + /* left-adjusting padding (always blank) */ + if (flags & LADJUST) + PAD(width - realsz, blanks); + + /* finally, adjust ret */ + ret += prsize; + } +done: +error: + va_end(orgap); + if (convbuf != NULL) + free(convbuf); + if (__sferror(fp)) + ret = EOF; + if ((argtable != NULL) && (argtable != statargtable)) + free (argtable); + 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) + 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/vfwscanf-fbsd.c b/stdio/vfwscanf-fbsd.c new file mode 100644 index 0000000..2bee85d --- /dev/null +++ b/stdio/vfwscanf-fbsd.c @@ -0,0 +1,948 @@ +/*- + * 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. + */ + +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" +#include "local.h" + +#ifndef NO_FLOATING_POINT +#include +#endif + +#define BUF 513 /* Maximum length of numeric string. */ + +/* + * Flags used during conversion. + */ +#define LONG 0x01 /* l: long or double */ +#define LONGDBL 0x02 /* L: long double */ +#define SHORT 0x04 /* h: short */ +#define SUPPRESS 0x08 /* *: suppress assignment */ +#define POINTER 0x10 /* p: void * (as hex) */ +#define NOSKIP 0x20 /* [ or c: do not skip blanks */ +#define LONGLONG 0x400 /* ll: long long (+ deprecated q: quad) */ +#define INTMAXT 0x800 /* j: intmax_t */ +#define PTRDIFFT 0x1000 /* t: ptrdiff_t */ +#define SIZET 0x2000 /* z: size_t */ +#define SHORTSHORT 0x4000 /* hh: char */ +#define UNSIGNED 0x8000 /* %[oupxX] conversions */ + +/* + * The following are used in integral conversions only: + * SIGNOK, NDIGITS, PFXOK, and NZDIGITS + */ +#define SIGNOK 0x40 /* +/- is (still) legal */ +#define NDIGITS 0x80 /* no digits detected */ +#define PFXOK 0x100 /* 0x prefix is (still) legal */ +#define NZDIGITS 0x200 /* no zero digits detected */ +#define HAVESIGN 0x10000 /* sign detected */ + +/* + * Conversion types. + */ +#define CT_CHAR 0 /* %c conversion */ +#define CT_CCL 1 /* %[...] conversion */ +#define CT_STRING 2 /* %s conversion */ +#define CT_INT 3 /* %[dioupxX] conversion */ +#define CT_FLOAT 4 /* %[efgEFG] conversion */ + +#ifndef NO_FLOATING_POINT +static int parsefloat(FILE *, wchar_t **, size_t, locale_t loc); +#endif /* !NO_FLOATING_POINT */ + +extern int __scanfdebug; + +#define INCCL(_c) \ + (cclcompl ? (wmemchr(ccls, (_c), ccle - ccls) == NULL) : \ + (wmemchr(ccls, (_c), ccle - ccls) != NULL)) + +/* + * MT-safe version. + */ +int +vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap) +{ + int ret; + + FLOCKFILE(fp); + ORIENT(fp, 1); + ret = __vfwscanf(fp, __current_locale(), fmt, ap); + FUNLOCKFILE(fp); + return (ret); +} + +int +vfwscanf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt, + va_list ap) +{ + int ret; + + NORMALIZE_LOCALE(loc); + FLOCKFILE(fp); + ORIENT(fp, 1); + ret = __vfwscanf(fp, loc, fmt, ap); + FUNLOCKFILE(fp); + return (ret); +} + +/* + * Non-MT-safe version. + */ +__private_extern__ int +__vfwscanf(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt, + va_list ap) +{ + wint_t c; /* character from format, or conversion */ + size_t width; /* field width, or 0 */ + wchar_t *p; /* points into all kinds of strings */ + int n; /* handy integer */ + int flags; /* flags as defined above */ + wchar_t *p0; /* saves original value of p when necessary */ + int nassigned; /* number of fields assigned */ + int nread; /* number of characters consumed from fp */ + int base; /* base argument to conversion function */ + wchar_t buf[BUF]; /* buffer for numeric conversions */ + const wchar_t *ccls; /* character class start */ + const wchar_t *ccle; /* character class end */ + int cclcompl; /* ccl is complemented? */ + wint_t wi; /* handy wint_t */ + 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); + + /* `basefix' is used to avoid `if' tests in the integer scanner */ + static short basefix[17] = + { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + + nassigned = 0; + nread = 0; + ccls = ccle = NULL; + va_copy(ap_orig, ap); + for (;;) { + c = *fmt++; + if (c == 0) + return (nassigned); + if (iswspace_l(c, loc)) { + while ((c = __fgetwc(fp, loc)) != WEOF && + iswspace_l(c, loc)) + ; + if (c != WEOF) + __ungetwc(c, fp, loc); + continue; + } + if (c != '%') + goto literal; + width = 0; + flags = 0; + /* + * switch on the format. continue if done; + * break once format type is derived. + */ +again: c = *fmt++; + switch (c) { + case '%': +literal: + if ((wi = __fgetwc(fp, loc)) == WEOF) + goto input_failure; + if (wi != c) { + __ungetwc(wi, fp, loc); + goto match_failure; + } + nread++; + continue; + + case '$': + index = width; + if (index < 1 || index > NL_ARGMAX || fmt[-3] != '%') { + goto input_failure; + } + width = 0; + va_end(ap); + va_copy(ap, ap_orig); /* reset to %1$ */ + for (; index > 1; index--) { + va_arg(ap, void*); + } + goto again; + case '*': + flags |= SUPPRESS; + goto again; + case 'j': + flags |= INTMAXT; + goto again; + case 'l': + if (flags & LONG) { + flags &= ~LONG; + flags |= LONGLONG; + } else + flags |= LONG; + goto again; + case 'q': + flags |= LONGLONG; /* not quite */ + goto again; + case 't': + flags |= PTRDIFFT; + goto again; + case 'z': + flags |= SIZET; + goto again; + case 'L': + flags |= LONGDBL; + goto again; + case 'h': + if (flags & SHORT) { + flags &= ~SHORT; + flags |= SHORTSHORT; + } else + flags |= SHORT; + goto again; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + width = width * 10 + c - '0'; + goto again; + + /* + * Conversions. + */ + case 'd': + c = CT_INT; + base = 10; + break; + + case 'i': + c = CT_INT; + base = 0; + break; + + case 'o': + c = CT_INT; + flags |= UNSIGNED; + base = 8; + break; + + case 'u': + c = CT_INT; + flags |= UNSIGNED; + base = 10; + break; + + case 'X': + case 'x': + flags |= PFXOK; /* enable 0x prefixing */ + c = CT_INT; + flags |= UNSIGNED; + base = 16; + break; + +#ifndef NO_FLOATING_POINT + case 'A': case 'E': case 'F': case 'G': + case 'a': case 'e': case 'f': case 'g': + c = CT_FLOAT; + break; +#endif + + case 'S': + flags |= LONG; + /* FALLTHROUGH */ + case 's': + c = CT_STRING; + break; + + case '[': + ccls = fmt; + if (*fmt == '^') { + cclcompl = 1; + fmt++; + } else + cclcompl = 0; + if (*fmt == ']') + fmt++; + while (*fmt != '\0' && *fmt != ']') + fmt++; + ccle = fmt; + fmt++; + flags |= NOSKIP; + c = CT_CCL; + break; + + case 'C': + flags |= LONG; + /* FALLTHROUGH */ + case 'c': + flags |= NOSKIP; + c = CT_CHAR; + break; + + case 'p': /* pointer format is like hex */ + flags |= POINTER | PFXOK; + c = CT_INT; /* assumes sizeof(uintmax_t) */ + flags |= UNSIGNED; /* >= sizeof(uintptr_t) */ + base = 16; + break; + + case 'n': + if (flags & SUPPRESS) /* ??? */ + continue; + if (flags & SHORTSHORT) + *va_arg(ap, char *) = nread; + else if (flags & SHORT) + *va_arg(ap, short *) = nread; + else if (flags & LONG) + *va_arg(ap, long *) = nread; + else if (flags & LONGLONG) + *va_arg(ap, long long *) = nread; + else if (flags & INTMAXT) + *va_arg(ap, intmax_t *) = nread; + else if (flags & SIZET) + *va_arg(ap, size_t *) = nread; + else if (flags & PTRDIFFT) + *va_arg(ap, ptrdiff_t *) = nread; + else + *va_arg(ap, int *) = nread; + continue; + + default: + goto match_failure; + + /* + * Disgusting backwards compatibility hack. XXX + */ + case '\0': /* compat */ + return (EOF); + } + + /* + * Consume leading white space, except for formats + * that suppress this. + */ + if ((flags & NOSKIP) == 0) { + while ((wi = __fgetwc(fp, loc)) != WEOF && iswspace_l(wi, loc)) + nread++; + if (wi == WEOF) + goto input_failure; + __ungetwc(wi, fp, loc); + } + + /* + * Do the conversion. + */ + switch (c) { + + case CT_CHAR: + /* scan arbitrary characters (sets NOSKIP) */ + if (width == 0) + width = 1; + if (flags & LONG) { + if (!(flags & SUPPRESS)) + p = va_arg(ap, wchar_t *); + n = 0; + while (width-- != 0 && + (wi = __fgetwc(fp, loc)) != WEOF) { + if (!(flags & SUPPRESS)) + *p++ = (wchar_t)wi; + n++; + } + if (n == 0) + goto input_failure; + nread += n; + if (!(flags & SUPPRESS)) + nassigned++; + } else { + if (!(flags & SUPPRESS)) + mbp = va_arg(ap, char *); + n = 0; + mbs = initial; + while (width != 0 && + (wi = __fgetwc(fp, loc)) != WEOF) { + if (width >= mb_cur_max && + !(flags & SUPPRESS)) { + nconv = wcrtomb_l(mbp, wi, &mbs, loc); + if (nconv == (size_t)-1) + goto input_failure; + } else { + nconv = wcrtomb_l(mbbuf, wi, + &mbs, loc); + if (nconv == (size_t)-1) + goto input_failure; + if (nconv > width) { + __ungetwc(wi, fp, loc); + break; + } + if (!(flags & SUPPRESS)) + memcpy(mbp, mbbuf, + nconv); + } + if (!(flags & SUPPRESS)) + mbp += nconv; + width -= nconv; + n++; + } + if (n == 0) + goto input_failure; + nread += n; + if (!(flags & SUPPRESS)) + nassigned++; + } + break; + + case CT_CCL: + /* scan a (nonempty) character class (sets NOSKIP) */ + if (width == 0) + width = (size_t)~0; /* `infinity' */ + /* take only those things in the class */ + if ((flags & SUPPRESS) && (flags & LONG)) { + n = 0; + while ((wi = __fgetwc(fp, loc)) != WEOF && + width-- != 0 && INCCL(wi)) + n++; + if (wi != WEOF) + __ungetwc(wi, fp, loc); + if (n == 0) + goto match_failure; + } else if (flags & LONG) { + p0 = p = va_arg(ap, wchar_t *); + while ((wi = __fgetwc(fp, loc)) != WEOF && + width-- != 0 && INCCL(wi)) + *p++ = (wchar_t)wi; + if (wi != WEOF) + __ungetwc(wi, fp, loc); + n = p - p0; + if (n == 0) + goto match_failure; + *p = 0; + nassigned++; + } else { + if (!(flags & SUPPRESS)) + mbp = va_arg(ap, char *); + n = 0; + mbs = initial; + while ((wi = __fgetwc(fp, loc)) != WEOF && + width != 0 && INCCL(wi)) { + if (width >= mb_cur_max && + !(flags & SUPPRESS)) { + nconv = wcrtomb_l(mbp, wi, &mbs, loc); + if (nconv == (size_t)-1) + goto input_failure; + } else { + nconv = wcrtomb_l(mbbuf, wi, + &mbs, loc); + if (nconv == (size_t)-1) + goto input_failure; + if (nconv > width) + break; + if (!(flags & SUPPRESS)) + memcpy(mbp, mbbuf, + nconv); + } + if (!(flags & SUPPRESS)) + mbp += nconv; + width -= nconv; + n++; + } + if (wi != WEOF) + __ungetwc(wi, fp, loc); + if (n == 0) + goto match_failure; + if (!(flags & SUPPRESS)) { + *mbp = 0; + nassigned++; + } + } + nread += n; + break; + + case CT_STRING: + /* like CCL, but zero-length string OK, & no NOSKIP */ + if (width == 0) + width = (size_t)~0; + if ((flags & SUPPRESS) && (flags & LONG)) { + while ((wi = __fgetwc(fp, loc)) != WEOF && + width-- != 0 && + !iswspace_l(wi, loc)) + nread++; + if (wi != WEOF) + __ungetwc(wi, fp, loc); + } else if (flags & LONG) { + p0 = p = va_arg(ap, wchar_t *); + while ((wi = __fgetwc(fp, loc)) != WEOF && + width-- != 0 && + !iswspace_l(wi, loc)) { + *p++ = (wchar_t)wi; + nread++; + } + if (wi != WEOF) + __ungetwc(wi, fp, loc); + *p = '\0'; + nassigned++; + } else { + if (!(flags & SUPPRESS)) + mbp = va_arg(ap, char *); + mbs = initial; + while ((wi = __fgetwc(fp, loc)) != WEOF && + width != 0 && + !iswspace_l(wi, loc)) { + if (width >= mb_cur_max && + !(flags & SUPPRESS)) { + nconv = wcrtomb_l(mbp, wi, &mbs, loc); + if (nconv == (size_t)-1) + goto input_failure; + } else { + nconv = wcrtomb_l(mbbuf, wi, + &mbs, loc); + if (nconv == (size_t)-1) + goto input_failure; + if (nconv > width) + break; + if (!(flags & SUPPRESS)) + memcpy(mbp, mbbuf, + nconv); + } + if (!(flags & SUPPRESS)) + mbp += nconv; + width -= nconv; + nread++; + } + if (wi != WEOF) + __ungetwc(wi, fp, loc); + if (!(flags & SUPPRESS)) { + *mbp = 0; + nassigned++; + } + } + continue; + + case CT_INT: + /* scan an integer as if by the conversion function */ + if (width == 0 || width > sizeof(buf) / + sizeof(*buf) - 1) + width = sizeof(buf) / sizeof(*buf) - 1; + flags |= SIGNOK | NDIGITS | NZDIGITS; + for (p = buf; width; width--) { + c = __fgetwc(fp, loc); + /* + * Switch on the character; `goto ok' + * if we accept it as a part of number. + */ + switch (c) { + + /* + * The digit 0 is always legal, but is + * special. For %i conversions, if no + * digits (zero or nonzero) have been + * scanned (only signs), we will have + * base==0. In that case, we should set + * it to 8 and enable 0x prefixing. + * Also, if we have not scanned zero digits + * before this, do not turn off prefixing + * (someone else will turn it off if we + * have scanned any nonzero digits). + */ + case '0': + if (base == 0) { + base = 8; + flags |= PFXOK; + } + if (flags & NZDIGITS) + flags &= ~(SIGNOK|NZDIGITS|NDIGITS); + else + flags &= ~(SIGNOK|PFXOK|NDIGITS); + goto ok; + + /* 1 through 7 always legal */ + case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + base = basefix[base]; + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* digits 8 and 9 ok iff decimal or hex */ + case '8': case '9': + base = basefix[base]; + if (base <= 8) + break; /* not legal here */ + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* letters ok iff hex */ + case 'A': case 'B': case 'C': + case 'D': case 'E': case 'F': + case 'a': case 'b': case 'c': + case 'd': case 'e': case 'f': + /* no need to fix base here */ + if (base <= 10) + break; /* not legal here */ + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* sign ok only as first character */ + case '+': case '-': + if (flags & SIGNOK) { + flags &= ~SIGNOK; + flags |= HAVESIGN; + goto ok; + } + break; + + /* + * x ok iff flag still set & 2nd char (or + * 3rd char if we have a sign). + */ + case 'x': case 'X': + if (flags & PFXOK && p == + buf + 1 + !!(flags & HAVESIGN)) { + base = 16; /* if %i */ + flags &= ~PFXOK; + goto ok; + } + break; + } + + /* + * If we got here, c is not a legal character + * for a number. Stop accumulating digits. + */ + if (c != WEOF) + __ungetwc(c, fp, loc); + break; + ok: + /* + * c is legal: store it and look at the next. + */ + *p++ = (wchar_t)c; + } + /* + * If we had only a sign, it is no good; push + * back the sign. If the number ends in `x', + * it was [sign] '0' 'x', so push back the x + * and treat it as [sign] '0'. + */ + if (flags & NDIGITS) { + if (p > buf) + __ungetwc(*--p, fp, loc); + goto match_failure; + } + c = p[-1]; + if (c == 'x' || c == 'X') { + --p; + __ungetwc(c, fp, loc); + } + if ((flags & SUPPRESS) == 0) { + uintmax_t res; + + *p = 0; + if ((flags & UNSIGNED) == 0) + res = wcstoimax_l(buf, NULL, base, loc); + else + res = wcstoumax_l(buf, NULL, base, loc); + if (flags & POINTER) + *va_arg(ap, void **) = + (void *)(uintptr_t)res; + else if (flags & SHORTSHORT) + *va_arg(ap, char *) = res; + else if (flags & SHORT) + *va_arg(ap, short *) = res; + else if (flags & LONG) + *va_arg(ap, long *) = res; + else if (flags & LONGLONG) + *va_arg(ap, long long *) = res; + else if (flags & INTMAXT) + *va_arg(ap, intmax_t *) = res; + else if (flags & PTRDIFFT) + *va_arg(ap, ptrdiff_t *) = res; + else if (flags & SIZET) + *va_arg(ap, size_t *) = res; + else + *va_arg(ap, int *) = res; + nassigned++; + } + nread += p - buf; + break; + +#ifndef NO_FLOATING_POINT + case CT_FLOAT: + { + wchar_t *pbuf; + /* scan a floating point number as if by strtod */ + if ((width = parsefloat(fp, &pbuf, width, loc)) == 0) + goto match_failure; + if ((flags & SUPPRESS) == 0) { + if (flags & LONGDBL) { + long double res = wcstold_l(pbuf, &p, loc); + *va_arg(ap, long double *) = res; + } else if (flags & LONG) { + double res = wcstod_l(pbuf, &p, loc); + *va_arg(ap, double *) = res; + } else { + float res = wcstof_l(pbuf, &p, loc); + *va_arg(ap, float *) = res; + } + if (__scanfdebug && p - pbuf != width) + abort(); + nassigned++; + } + nread += width; + break; + } +#endif /* !NO_FLOATING_POINT */ + } + } +input_failure: + return (nassigned ? nassigned : EOF); +match_failure: + return (nassigned); +} + +#ifndef NO_FLOATING_POINT +static int +parsefloat(FILE *fp, wchar_t **buf, size_t width, locale_t loc) +{ + wchar_t *commit, *p; + int infnanpos = 0; + enum { + S_START, S_GOTSIGN, S_INF, S_NAN, 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; + static wchar_t *b = NULL; + static size_t bsiz = 0; + wchar_t *e; + size_t s; + + if (bsiz == 0) { + b = (wchar_t *)malloc(BUF * sizeof(wchar_t)); + if (b == NULL) { + *buf = NULL; + return 0; + } + bsiz = BUF; + } + s = (width == 0 ? bsiz : (width + 1)); + if (s > bsiz) { + b = (wchar_t *)reallocf(b, s * sizeof(wchar_t)); + if (b == NULL) { + bsiz = 0; + *buf = NULL; + return 0; + } + bsiz = s; + } + e = b + (s - 1); + /* + * We set commit = p whenever the string we have read so far + * constitutes a valid representation of a floating point + * number by itself. At some point, the parse will complete + * or fail, and we will ungetc() back to the last commit point. + * To ensure that the file offset gets updated properly, it is + * always necessary to read at least one character that doesn't + * match; thus, we can't short-circuit "infinity" or "nan(...)". + */ + 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; +reswitch: + switch (state) { + case S_START: + state = S_GOTSIGN; + if (c == '-' || c == '+') + break; + else + goto reswitch; + case S_GOTSIGN: + switch (c) { + case '0': + state = S_MAYBEHEX; + commit = p; + break; + case 'I': + case 'i': + state = S_INF; + break; + case 'N': + case 'n': + state = S_NAN; + break; + default: + state = S_DIGITS; + goto reswitch; + } + break; + case S_INF: + if (infnanpos > 6 || + (c != "nfinity"[infnanpos] && + c != "NFINITY"[infnanpos])) + goto parsedone; + if (infnanpos == 1 || infnanpos == 6) + commit = p; /* inf or infinity */ + infnanpos++; + 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; + break; + case 1: + if (c != 'N' && c != 'n') + goto parsedone; + else + commit = p; + break; + case 2: + if (c != '(') + goto parsedone; + break; + default: + if (c == ')') { + commit = p; + infnanpos = -2; + } else if (!iswalnum_l(c, loc) && c != '_') + goto parsedone; + break; + } + infnanpos++; + break; + case S_MAYBEHEX: + state = S_DIGITS; + if (c == 'X' || c == 'x') { + ishex = 1; + break; + } else { /* we saw a '0', but no 'x' */ + gotmantdig = 1; + goto reswitch; + } + case S_DIGITS: + if ((ishex && iswxdigit_l(c, loc)) || iswdigit_l(c, loc)) + gotmantdig = 1; + else { + state = S_FRAC; + if (c != decpt) + goto reswitch; + } + if (gotmantdig) + commit = p; + break; + case S_FRAC: + if (((c == 'E' || c == 'e') && !ishex) || + ((c == 'P' || c == 'p') && ishex)) { + if (!gotmantdig) + goto parsedone; + else + state = S_EXP; + } else if ((ishex && iswxdigit_l(c, loc)) || iswdigit_l(c, loc)) { + commit = p; + gotmantdig = 1; + } else + goto parsedone; + break; + case S_EXP: + state = S_EXPDIGITS; + if (c == '-' || c == '+') + break; + else + goto reswitch; + case S_EXPDIGITS: + if (iswdigit_l(c, loc)) + commit = p; + else + goto parsedone; + break; + default: + abort(); + } + if (p >= e) { + ssize_t diff = (p - b); + ssize_t com = (commit - b); + s += BUF; + b = (wchar_t *)reallocf(b, s * sizeof(wchar_t)); + if (b == NULL) { + bsiz = 0; + *buf = NULL; + return 0; + } + bsiz = s; + e = b + (s - 1); + p = b + diff; + commit = b + com; + } + *p++ = c; + c = WEOF; + } + +parsedone: + if (c != WEOF) + __ungetwc(c, fp, loc); + while (commit < --p) + __ungetwc(*p, fp, loc); + *++commit = '\0'; + *buf = b; + return (commit - b); +} +#endif diff --git a/stdio/vprintf-fbsd.c b/stdio/vprintf-fbsd.c new file mode 100644 index 0000000..329816c --- /dev/null +++ b/stdio/vprintf-fbsd.c @@ -0,0 +1,60 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include + +int +vprintf(const char * __restrict fmt, __va_list ap) +{ + + return (vfprintf_l(stdout, __current_locale(), fmt, ap)); +} + +int +vprintf_l(locale_t loc, const char * __restrict fmt, __va_list ap) +{ + + /* no need to call NORMALIZE_LOCALE(loc) because vfprintf_l will */ + return (vfprintf_l(stdout, loc, fmt, ap)); +} diff --git a/stdio/vscanf-fbsd.c b/stdio/vscanf-fbsd.c new file mode 100644 index 0000000..f17456b --- /dev/null +++ b/stdio/vscanf-fbsd.c @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Donn Seeley at UUNET Technologies, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +int +vscanf(fmt, ap) + const char * __restrict fmt; + __va_list ap; +{ + int retval; + + FLOCKFILE(stdin); + retval = __svfscanf_l(stdin, __current_locale(), fmt, ap); + FUNLOCKFILE(stdin); + return (retval); +} + +int +vscanf_l(loc, fmt, ap) + locale_t loc; + const char * __restrict fmt; + __va_list ap; +{ + int retval; + + NORMALIZE_LOCALE(loc); + FLOCKFILE(stdin); + retval = __svfscanf_l(stdin, loc, fmt, ap); + FUNLOCKFILE(stdin); + return (retval); +} diff --git a/stdio/vsnprintf-fbsd.c b/stdio/vsnprintf-fbsd.c new file mode 100644 index 0000000..1a24ce3 --- /dev/null +++ b/stdio/vsnprintf-fbsd.c @@ -0,0 +1,116 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#include "local.h" + +int +vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, + __va_list ap) +{ + size_t on; + int ret; + 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; + 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, loc, fmt, ap); + if (on > 0) + *f._p = '\0'; + return (ret); +} diff --git a/stdio/vsprintf-fbsd.c b/stdio/vsprintf-fbsd.c new file mode 100644 index 0000000..24b7903 --- /dev/null +++ b/stdio/vsprintf-fbsd.c @@ -0,0 +1,85 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#include "local.h" + +int +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); + 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); + ret = __vfprintf(&f, loc, fmt, ap); + *f._p = 0; + return (ret); +} diff --git a/stdio/vsscanf-fbsd.c b/stdio/vsscanf-fbsd.c new file mode 100644 index 0000000..0ed3562 --- /dev/null +++ b/stdio/vsscanf-fbsd.c @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Donn Seeley at UUNET Technologies, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#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 +vsscanf(str, fmt, ap) + const char * __restrict str; + const char * __restrict fmt; + __va_list ap; +{ + FILE f; + struct __sFILEX ext; + + 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, __current_locale(), fmt, ap)); +} + +int +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; + + 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/vswprintf-fbsd.c b/stdio/vswprintf-fbsd.c new file mode 100644 index 0000000..c955981 --- /dev/null +++ b/stdio/vswprintf-fbsd.c @@ -0,0 +1,156 @@ +/* $OpenBSD: vasprintf.c,v 1.4 1998/06/21 22:13:47 millert 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. + * + * 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. + */ + +#include +#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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include "local.h" + +int +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; + 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 */ + 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); + } + + 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); +} diff --git a/stdio/vswscanf-fbsd.c b/stdio/vswscanf-fbsd.c new file mode 100644 index 0000000..bad7e18 --- /dev/null +++ b/stdio/vswscanf-fbsd.c @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Donn Seeley at UUNET Technologies, 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. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include +#include "local.h" + +static int eofread(void *, char *, int); + +static int +eofread(void *cookie, char *buf, int len) +{ + + return (0); +} + +int +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; + 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; + 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); + /* + * 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); +} diff --git a/stdio/vwprintf-fbsd.c b/stdio/vwprintf-fbsd.c new file mode 100644 index 0000000..634f06d --- /dev/null +++ b/stdio/vwprintf-fbsd.c @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2002 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/vwprintf.c,v 1.1 2002/09/21 13:00:30 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include + +int +vwprintf(const wchar_t * __restrict fmt, va_list ap) +{ + + return (vfwprintf_l(stdout, __current_locale(), fmt, ap)); +} + +int +vwprintf_l(locale_t loc, const wchar_t * __restrict fmt, va_list ap) +{ + + /* no need to call NORMALIZE_LOCALE(loc) because vfwprintf_l will */ + return (vfwprintf_l(stdout, loc, fmt, ap)); +} diff --git a/stdio/vwscanf-fbsd.c b/stdio/vwscanf-fbsd.c new file mode 100644 index 0000000..3b2fb28 --- /dev/null +++ b/stdio/vwscanf-fbsd.c @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2002 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/vwscanf.c,v 1.1 2002/09/23 12:40:06 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include + +int +vwscanf(const wchar_t * __restrict fmt, va_list ap) +{ + + return (vfwscanf_l(stdin, __current_locale(), fmt, ap)); +} + +int +vwscanf_l(locale_t loc, const wchar_t * __restrict fmt, va_list ap) +{ + + /* no need to call NORMALIZE_LOCALE(loc) because vfwscanf_l will */ + return (vfwscanf_l(stdin, loc, fmt, ap)); +} diff --git a/stdio/wbuf-fbsd.c b/stdio/wbuf-fbsd.c new file mode 100644 index 0000000..6d30d58 --- /dev/null +++ b/stdio/wbuf-fbsd.c @@ -0,0 +1,98 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include +#include "local.h" + +/* + * Write the given character into the (probably full) buffer for + * the given file. Flush the buffer out if it is or becomes full, + * or if c=='\n' and the file is line buffered. + * + * Non-MT-safe + */ +int +__swbuf(c, fp) + int c; + FILE *fp; +{ + int n; + + /* + * In case we cannot write, or longjmp takes us out early, + * make sure _w is 0 (if fully- or un-buffered) or -_bf._size + * (if line buffered) so that we will get called again. + * If we did not do this, a sufficient number of putc() + * calls might wrap _w from negative to positive. + */ + fp->_w = fp->_lbfsize; + if (prepwrite(fp) != 0) { + errno = EBADF; + return (EOF); + } + c = (unsigned char)c; + + ORIENT(fp, -1); + + /* + * If it is completely full, flush it out. Then, in any case, + * stuff c into the buffer. If this causes the buffer to fill + * completely, or if c is '\n' and the file is line buffered, + * flush it (perhaps a second time). The second flush will always + * happen on unbuffered streams, where _bf._size==1; fflush() + * guarantees that putc() will always call wbuf() by setting _w + * to 0, so we need not do anything else. + */ + n = fp->_p - fp->_bf._base; + if (n >= fp->_bf._size) { + if (__fflush(fp)) + return (EOF); + n = 0; + } + fp->_w--; + *fp->_p++ = c; + if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n')) + if (__fflush(fp)) + return (EOF); + return (c); +} diff --git a/stdio/wprintf-fbsd.c b/stdio/wprintf-fbsd.c new file mode 100644 index 0000000..42deed0 --- /dev/null +++ b/stdio/wprintf-fbsd.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2002 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/wprintf.c,v 1.1 2002/09/21 13:00:30 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include + +int +wprintf(const wchar_t * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfwprintf_l(stdout, __current_locale(), fmt, ap); + va_end(ap); + + return (ret); +} + +int +wprintf_l(locale_t loc, const wchar_t * __restrict fmt, ...) +{ + int ret; + va_list ap; + + /* no need to call NORMALIZE_LOCALE(loc) because vfwprintf_l will */ + va_start(ap, fmt); + ret = vfwprintf_l(stdout, loc, fmt, ap); + va_end(ap); + + return (ret); +} diff --git a/stdio/wprintf.3 b/stdio/wprintf.3 new file mode 100644 index 0000000..917ce76 --- /dev/null +++ b/stdio/wprintf.3 @@ -0,0 +1,659 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd July 5, 2003 +.Dt WPRINTF 3 +.Os +.Sh NAME +.Nm fwprintf , +.Nm swprintf , +.Nm vfwprintf , +.Nm vswprintf , +.Nm vwprintf , +.Nm wprintf +.Nd formatted wide character output conversion +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft int +.Fo fwprintf +.Fa "FILE *restrict stream" +.Fa "const wchar_t *restrict format" +.Fa ... +.Fc +.Ft int +.Fo swprintf +.Fa "wchar_t *restrict ws" +.Fa "size_t n" +.Fa "const wchar_t *restrict format" +.Fa ... +.Fc +.Ft int +.Fo wprintf +.Fa "const wchar_t *restrict format" +.Fa ... +.Fc +.In stdarg.h +.In stdio.h +.In wchar.h +.Ft int +.Fo vfwprintf +.Fa "FILE *restrict stream" +.Fa "const wchar_t *restrict format" +.Fa "va_list arg" +.Fc +.Ft int +.Fo vswprintf +.Fa "wchar_t *restrict ws" +.Fa "size_t n" +.Fa "const wchar_t *restrict format" +.Fa "va_list arg" +.Fc +.Ft int +.Fo vwprintf +.Fa "const wchar_t *restrict format" +.Fa "va_list arg" +.Fc +.Sh DESCRIPTION +The +.Fn wprintf +family of functions produces output according to a +.Fa format , +as described below. +The +.Fn wprintf +and +.Fn vwprintf +functions +write output to +.Dv stdout , +the standard output stream; +.Fn fwprintf +and +.Fn vfwprintf +write output to the given output +.Fa stream ; +.Fn swprintf +and +.Fn vswprintf +write to the wide character string +.Fa ws . +.Pp +Extended locale versions of these functions are documented in +.Xr wprintf_l 3 . +See +.Xr xlocale 3 +for more information. +.Pp +These functions write the output under the control of a +.Fa format +string that specifies how subsequent arguments +(or arguments accessed via the variable-length argument facilities of +.Xr stdarg 3 ) +are converted for output. +.Pp +These functions return the number of characters printed +(not including the trailing +.Ql \e0 , +used to end output to strings). +.Pp +The +.Fn swprintf +and +.Fn vswprintf +functions will fail if +.Fa n +or more wide characters were requested to be written, +.Pp +The format string is composed of zero or more directives: +ordinary +characters (not +.Cm % ) , +which are copied unchanged to the output stream; +and conversion specifications, each of which results +in fetching zero or more subsequent arguments. +Each conversion specification is introduced by +the +.Cm % +character. +The arguments must correspond properly (after type promotion) +with the conversion specifier. +After the +.Cm % , +the following appear in sequence: +.Bl -bullet +.It +An optional field, consisting of a decimal digit string followed by a +.Cm $ , +specifying the next argument to access. +If this field is not provided, the argument following the last +argument accessed will be used. +Arguments are numbered starting at +.Cm 1 . +If unaccessed arguments in the format string are interspersed with ones that +are accessed the results will be indeterminate. +.It +Zero or more of the following flags: +.Bl -tag -width ".So \ Sc (space)" +.It Sq Cm # +The value should be converted to an +.Dq alternate form . +For +.Cm c , d , i , n , p , s , +and +.Cm u +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). +For +.Cm x +and +.Cm X +conversions, a non-zero result has the string +.Ql 0x +(or +.Ql 0X +for +.Cm X +conversions) prepended to it. +For +.Cm a , A , e , E , f , F , g , +and +.Cm G +conversions, the result will always contain a decimal point, even if no +digits follow it (normally, a decimal point appears in the results of +those conversions only if a digit follows). +For +.Cm g +and +.Cm G +conversions, trailing zeros are not removed from the result as they +would otherwise be. +.It So Cm 0 Sc (zero) +Zero padding. +For all conversions except +.Cm n , +the converted value is padded on the left with zeros rather than blanks. +If a precision is given with a numeric conversion +.Cm ( d , i , o , u , i , x , +and +.Cm X ) , +the +.Cm 0 +flag is ignored. +.It Sq Cm \- +A negative field width flag; +the converted value is to be left adjusted on the field boundary. +Except for +.Cm n +conversions, the converted value is padded on the right with blanks, +rather than on the left with blanks or zeros. +A +.Cm \- +overrides a +.Cm 0 +if both are given. +.It So "\ " Sc (space) +A blank should be left before a positive number +produced by a signed conversion +.Cm ( a , A , d , e , E , f , F , g , G , +or +.Cm i ) . +.It Sq Cm + +A sign must always be placed before a +number produced by a signed conversion. +A +.Cm + +overrides a space if both are used. +.It Sq Cm ' +Decimal conversions +.Cm ( d , u , +or +.Cm i ) +or the integral portion of a floating point conversion +.Cm ( f +or +.Cm F ) +should be grouped and separated by thousands using +the non-monetary separator returned by +.Xr localeconv 3 . +.El +.It +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 +flag has been given) to fill out +the field width. +.It +An optional precision, in the form of a period +.Cm \&. +followed by an +optional digit string. +If the digit string is omitted, the precision is taken as zero. +This gives the minimum number of digits to appear for +.Cm d , i , o , u , x , +and +.Cm X +conversions, the number of digits to appear after the decimal-point for +.Cm a , A , e , E , f , +and +.Cm F +conversions, the maximum number of significant digits for +.Cm g +and +.Cm G +conversions, or the maximum number of characters to be printed from a +string for +.Cm s +conversions. +.It +An optional length modifier, that specifies the size of the argument. +The following length modifiers are valid for the +.Cm d , i , n , o , u , x , +or +.Cm X +conversion: +.Bl -column ".Cm q Em (deprecated)" ".Vt signed char" ".Vt unsigned long long" ".Vt long long *" +.It Sy Modifier Ta Cm d , i Ta Cm o , u , x , X Ta Cm n +.It Cm hh Ta Vt "signed char" Ta Vt "unsigned char" Ta Vt "signed char *" +.It Cm h Ta Vt short Ta Vt "unsigned short" Ta Vt "short *" +.It Cm l No (ell) Ta Vt long Ta Vt "unsigned long" Ta Vt "long *" +.It Cm ll No (ell ell) Ta Vt "long long" Ta Vt "unsigned long long" Ta Vt "long long *" +.It Cm j Ta Vt intmax_t Ta Vt uintmax_t Ta Vt "intmax_t *" +.It Cm t Ta Vt ptrdiff_t Ta (see note) Ta Vt "ptrdiff_t *" +.It Cm z Ta (see note) Ta Vt size_t Ta (see note) +.It Cm q Em (deprecated) Ta Vt quad_t Ta Vt u_quad_t Ta Vt "quad_t *" +.El +.Pp +Note: +the +.Cm t +modifier, when applied to a +.Cm o , u , x , +or +.Cm X +conversion, indicates that the argument is of an unsigned type +equivalent in size to a +.Vt ptrdiff_t . +The +.Cm z +modifier, when applied to a +.Cm d +or +.Cm i +conversion, indicates that the argument is of a signed type equivalent in +size to a +.Vt size_t . +Similarly, when applied to an +.Cm n +conversion, it indicates that the argument is a pointer to a signed type +equivalent in size to a +.Vt size_t . +.Pp +The following length modifier is valid for the +.Cm a , A , e , E , f , F , g , +or +.Cm G +conversion: +.Bl -column ".Sy Modifier" ".Cm a , A , e , E , f , F , g , G" +.It Sy Modifier Ta Cm a , A , e , E , f , F , g , G +.It Cm L Ta Vt "long double" +.El +.Pp +The following length modifier is valid for the +.Cm c +or +.Cm s +conversion: +.Bl -column ".Sy Modifier" ".Vt wint_t" ".Vt wchar_t *" +.It Sy Modifier Ta Cm c Ta Cm s +.It Cm l No (ell) Ta Vt wint_t Ta Vt "wchar_t *" +.El +.It +A character that specifies the type of conversion to be applied. +.El +.Pp +A field width or precision, or both, may be indicated by +an asterisk +.Ql * +or an asterisk followed by one or more decimal digits and a +.Ql $ +instead of a +digit string. +In this case, an +.Vt int +argument supplies the field width or precision. +A negative field width is treated as a left adjustment flag followed by a +positive field width; a negative precision is treated as though it were +missing. +If a single format directive mixes positional +.Pq Li nn$ +and non-positional arguments, the results are undefined. +.Pp +The conversion specifiers and their meanings are: +.Bl -tag -width ".Cm diouxX" +.It Cm diouxX +The +.Vt int +(or appropriate variant) argument is converted to signed decimal +.Cm ( d +and +.Cm i ) , +unsigned octal +.Pq Cm o , +unsigned decimal +.Pq Cm u , +or unsigned hexadecimal +.Cm ( x +and +.Cm X ) +notation. +The letters +.Dq Li abcdef +are used for +.Cm x +conversions; the letters +.Dq Li ABCDEF +are used for +.Cm X +conversions. +The precision, if any, gives the minimum number of digits that must +appear; if the converted value requires fewer digits, it is padded on +the left with zeros. +.It Cm DOU +The +.Vt "long int" +argument is converted to signed decimal, unsigned octal, or unsigned +decimal, as if the format had been +.Cm ld , lo , +or +.Cm lu +respectively. +These conversion characters are deprecated, and will eventually disappear. +.It Cm eE +The +.Vt double +argument is rounded and converted in the style +.Sm off +.Oo \- Oc Ar d Li \&. Ar ddd Li e \\*[Pm] Ar dd +.Sm on +where there is one digit before the +decimal-point character +and the number of digits after it is equal to the precision; +if the precision is missing, +it is taken as 6; if the precision is +zero, no decimal-point character appears. +An +.Cm E +conversion uses the letter +.Ql E +(rather than +.Ql e ) +to introduce the exponent. +The exponent always contains at least two digits; if the value is zero, +the exponent is 00. +.Pp +For +.Cm a , A , e , E , f , F , g , +and +.Cm G +conversions, positive and negative infinity are represented as +.Li inf +and +.Li -inf +respectively when using the lowercase conversion character, and +.Li INF +and +.Li -INF +respectively when using the uppercase conversion character. +Similarly, NaN is represented as +.Li nan +when using the lowercase conversion, and +.Li NAN +when using the uppercase conversion. +.It Cm fF +The +.Vt double +argument is rounded and converted to decimal notation in the style +.Sm off +.Oo \- Oc Ar ddd Li \&. Ar ddd , +.Sm on +where the number of digits after the decimal-point character +is equal to the precision specification. +If the precision is missing, it is taken as 6; if the precision is +explicitly zero, no decimal-point character appears. +If a decimal point appears, at least one digit appears before it. +.It Cm gG +The +.Vt double +argument is converted in style +.Cm f +or +.Cm e +(or +.Cm F +or +.Cm E +for +.Cm G +conversions). +The precision specifies the number of significant digits. +If the precision is missing, 6 digits are given; if the precision is zero, +it is treated as 1. +Style +.Cm e +is used if the exponent from its conversion is less than \-4 or greater than +or equal to the precision. +Trailing zeros are removed from the fractional part of the result; a +decimal point appears only if it is followed by at least one digit. +.It Cm aA +The +.Vt double +argument is converted to hexadecimal notation in the style +.Sm off +.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \\*[Pm] Oc Ar d , +.Sm on +where the number of digits after the hexadecimal-point character +is equal to the precision specification. +If the precision is missing, it is taken as enough to exactly +represent the floating-point number; if the precision is +explicitly zero, no hexadecimal-point character appears. +This is an exact conversion of the mantissa+exponent internal +floating point representation; the +.Sm off +.Oo \- Oc Li 0x Ar h Li \&. Ar hhh +.Sm on +portion represents exactly the mantissa; only denormalized +mantissas have a zero value to the left of the hexadecimal +point. +The +.Cm p +is a literal character +.Ql p ; +the exponent is preceded by a positive or negative sign +and is represented in decimal, using only enough characters +to represent the exponent. +The +.Cm A +conversion uses the prefix +.Dq Li 0X +(rather than +.Dq Li 0x ) , +the letters +.Dq Li ABCDEF +(rather than +.Dq Li abcdef ) +to represent the hex digits, and the letter +.Ql P +(rather than +.Ql p ) +to separate the mantissa and exponent. +.It Cm C +Treated as +.Cm c +with the +.Cm l +(ell) modifier. +.It Cm c +The +.Vt int +argument is converted to an +.Vt "unsigned char" , +then to a +.Vt wchar_t +as if by +.Xr btowc 3 , +and the resulting character is written. +.Pp +If the +.Cm l +(ell) modifier is used, the +.Vt wint_t +argument is converted to a +.Vt wchar_t +and written. +.It Cm S +Treated as +.Cm s +with the +.Cm l +(ell) modifier. +.It Cm s +The +.Vt "char *" +argument is expected to be a pointer to an array of character type (pointer +to a string) containing a multibyte sequence. +Characters from the array are converted to wide characters and written up to +(but not including) +a terminating +.Dv NUL +character; +if a precision is specified, no more than the number specified are +written. +If a precision is given, no null character +need be present; if the precision is not specified, or is greater than +the size of the array, the array must contain a terminating +.Dv NUL +character. +.Pp +If the +.Cm l +(ell) modifier is used, the +.Vt "wchar_t *" +argument is expected to be a pointer to an array of wide characters +(pointer to a wide string). +Each wide character in the string +is written. +Wide characters from the array are written up to (but not including) +a terminating wide +.Dv NUL +character; +if a precision is specified, no more than the number specified are +written (including shift sequences). +If a precision is given, no null character +need be present; if the precision is not specified, or is greater than +the number of characters in +the string, the array must contain a terminating wide +.Dv NUL +character. +.It Cm p +The +.Vt "void *" +pointer argument is printed in hexadecimal (as if by +.Ql %#x +or +.Ql %#lx ) . +.It Cm n +The number of characters written so far is stored into the +integer indicated by the +.Vt "int *" +(or variant) pointer argument. +No argument is converted. +.It Cm % +A +.Ql % +is written. +No argument is converted. +The complete conversion specification +is +.Ql %% . +.El +.Pp +The decimal point +character is defined in the program's locale (category +.Dv LC_NUMERIC ) . +.Pp +In no case does a non-existent or small field width cause truncation of +a numeric field; if the result of a conversion is wider than the field +width, the +field is expanded to contain the conversion result. +.Sh SECURITY CONSIDERATIONS +Refer to +.Xr printf 3 . +.Sh SEE ALSO +.Xr btowc 3 , +.Xr fputws 3 , +.Xr printf 3 , +.Xr putwc 3 , +.Xr setlocale 3 , +.Xr wcsrtombs 3 , +.Xr wprintf_l 3 , +.Xr wscanf 3 +.Sh STANDARDS +Subject to the caveats noted in the +.Sx BUGS +section +of +.Xr printf 3 , +the +.Fn wprintf , +.Fn fwprintf , +.Fn swprintf , +.Fn vwprintf , +.Fn vfwprintf , +and +.Fn vswprintf +functions +conform to +.St -isoC-99 . diff --git a/stdio/wscanf-fbsd.c b/stdio/wscanf-fbsd.c new file mode 100644 index 0000000..99dc48d --- /dev/null +++ b/stdio/wscanf-fbsd.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2002 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/wscanf.c,v 1.1 2002/09/23 12:40:06 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include + +int +wscanf(const wchar_t * __restrict fmt, ...) +{ + va_list ap; + int r; + + va_start(ap, fmt); + r = vfwscanf_l(stdin, __current_locale(), fmt, ap); + va_end(ap); + + return (r); +} + +int +wscanf_l(locale_t loc, const wchar_t * __restrict fmt, ...) +{ + va_list ap; + int r; + + /* no need to call NORMALIZE_LOCALE(loc) because vfwscanf_l will */ + va_start(ap, fmt); + r = vfwscanf_l(stdin, loc, fmt, ap); + va_end(ap); + + return (r); +} diff --git a/stdio/wscanf.3 b/stdio/wscanf.3 new file mode 100644 index 0000000..e07bc7a --- /dev/null +++ b/stdio/wscanf.3 @@ -0,0 +1,513 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd July 5, 2003 +.Dt WSCANF 3 +.Os +.Sh NAME +.Nm fwscanf , +.Nm swscanf , +.Nm vfwscanf , +.Nm vswscanf , +.Nm vwscanf , +.Nm wscanf +.Nd wide character input format conversion +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft int +.Fo fwscanf +.Fa "FILE *restrict stream" +.Fa "const wchar_t *restrict format" +.Fa ... +.Fc +.Ft int +.Fo swscanf +.Fa "const wchar_t *restrict ws" +.Fa "const wchar_t *restrict format" +.Fa ... +.Fc +.Ft int +.Fo wscanf +.Fa "const wchar_t *restrict format" +.Fa ... +.Fc +.In stdarg.h +.In stdio.h +.In wchar.h +.Ft int +.Fo vfwscanf +.Fa "FILE *restrict stream" +.Fa "const wchar_t *restrict format" +.Fa "va_list arg" +.Fc +.Ft int +.Fo vswscanf +.Fa "const wchar_t *restrict ws" +.Fa "const wchar_t *restrict format" +.Fa "va_list arg" +.Fc +.Ft int +.Fo vwscanf +.Fa "const wchar_t *restrict format" +.Fa "va_list arg" +.Fc +.Sh DESCRIPTION +The +.Fn wscanf +family of functions scans input, according to a +.Fa format +as described below. +This format may contain +.Em conversion specifiers ; +the results from such conversions, if any, +are stored through the +.Em pointer +arguments. +The +.Fn wscanf +function +reads input from the standard input stream +.Dv stdin , +.Fn fwscanf +reads input from the stream pointer +.Fa stream , +and +.Fn swscanf +reads its input from the wide character string pointed to by +.Fa ws . +.Pp +The +.Fn vfwscanf +function +is analogous to +.Xr vfwprintf 3 +and reads input from the stream pointer +.Fa stream +using a variable argument list of pointers (see +.Xr stdarg 3 ) . +The +.Fn vwscanf +function scans a variable argument list from the standard input and +the +.Fn vswscanf +function scans it from a wide character string; +these are analogous to +the +.Fn vwprintf +and +.Fn vswprintf +functions respectively. +Each successive +.Em pointer +argument must correspond properly with +each successive conversion specifier +(but see the +.Cm * +conversion below). +All conversions are introduced by the +.Cm % +(percent sign) character. +.Pp +The +.Fa format +string +may also contain other characters. +White space (such as blanks, tabs, or newlines) in the +.Fa format +string match any amount of white space, including none, in the input. +Everything else +matches only itself. +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). +.Pp +Extended locale versions of these functions are documented in +.Xr wscanf_l 3 . +See +.Xr xlocale 3 +for more information. +.Sh CONVERSIONS +Following the +.Cm % +character introducing a conversion, +there may be a number of +.Em flag +characters, as follows: +.Bl -tag -width ".Cm l No (ell)" +.It Cm * +Suppresses assignment. +The conversion that follows occurs as usual, but no pointer is used; +the result of the conversion is simply discarded. +.It Cm hh +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt char +(rather than +.Vt int ) . +.It Cm h +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt "short int" +(rather than +.Vt int ) . +.It Cm l No (ell) +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt "long int" +(rather than +.Vt int ) , +that the conversion will be one of +.Cm a , e , f , +or +.Cm g +and the next pointer is a pointer to +.Vt double +(rather than +.Vt float ) , +or that the conversion will be one of +.Cm c +or +.Cm s +and the next pointer is a pointer to an array of +.Vt wchar_t +(rather than +.Vt char ) . +.It Cm ll No (ell ell) +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt "long long int" +(rather than +.Vt int ) . +.It Cm L +Indicates that the conversion will be one of +.Cm a , e , f , +or +.Cm g +and the next pointer is a pointer to +.Vt "long double" . +.It Cm j +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt intmax_t +(rather than +.Vt int ) . +.It Cm t +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt ptrdiff_t +(rather than +.Vt int ) . +.It Cm z +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt size_t +(rather than +.Vt int ) . +.It Cm q +(deprecated.) +Indicates that the conversion will be one of +.Cm dioux +or +.Cm n +and the next pointer is a pointer to a +.Vt "long long int" +(rather than +.Vt int ) . +.El +.Pp +In addition to these flags, +there may be an optional maximum field width, +expressed as a decimal integer, +between the +.Cm % +and the conversion. +If no width is given, +a default of +.Dq infinity +is used (with one exception, below); +otherwise at most this many characters are scanned +in processing the conversion. +Before conversion begins, +most conversions skip white space; +this white space is not counted against the field width. +.Pp +The following conversions are available: +.Bl -tag -width XXXX +.It Cm % +Matches a literal +.Ql % . +That is, +.Dq Li %% +in the format string +matches a single input +.Ql % +character. +No conversion is done, and assignment does not occur. +.It Cm d +Matches an optionally signed decimal integer; +the next pointer must be a pointer to +.Vt int . +.It Cm i +Matches an optionally signed integer; +the next pointer must be a pointer to +.Vt int . +The integer is read in base 16 if it begins +with +.Ql 0x +or +.Ql 0X , +in base 8 if it begins with +.Ql 0 , +and in base 10 otherwise. +Only characters that correspond to the base are used. +.It Cm o +Matches an octal integer; +the next pointer must be a pointer to +.Vt "unsigned int" . +.It Cm u +Matches an optionally signed decimal integer; +the next pointer must be a pointer to +.Vt "unsigned int" . +.It Cm x , X +Matches an optionally signed hexadecimal integer; +the next pointer must be a pointer to +.Vt "unsigned int" . +.It Cm a , A , e , E , f , F , g , G +Matches a floating-point number in the style of +.Xr wcstod 3 . +The next pointer must be a pointer to +.Vt float +(unless +.Cm l +or +.Cm L +is specified.) +.It Cm s +Matches a sequence of non-white-space wide characters; +the next pointer must be a pointer to +.Vt char , +and the array must be large enough to accept the multibyte representation +of all the sequence and the +terminating +.Dv NUL +character. +The input string stops at white space +or at the maximum field width, whichever occurs first. +.Pp +If an +.Cm l +qualifier is present, the next pointer must be a pointer to +.Vt wchar_t , +into which the input will be placed. +.It Cm S +The same as +.Cm ls . +.It Cm c +Matches a sequence of +.Em width +count +wide characters (default 1); +the next pointer must be a pointer to +.Vt char , +and there must be enough room for the multibyte representation +of all the characters +(no terminating +.Dv NUL +is added). +The usual skip of leading white space is suppressed. +To skip white space first, use an explicit space in the format. +.Pp +If an +.Cm l +qualifier is present, the next pointer must be a pointer to +.Vt wchar_t , +into which the input will be placed. +.It Cm C +The same as +.Cm lc . +.It Cm \&[ +Matches a nonempty sequence of characters from the specified set +of accepted characters; +the next pointer must be a pointer to +.Vt char , +and there must be enough room for the multibyte representation of +all the characters in the string, +plus a terminating +.Dv NUL +character. +The usual skip of leading white space is suppressed. +The string is to be made up of characters in +(or not in) +a particular set; +the set is defined by the characters between the open bracket +.Cm [ +character +and a close bracket +.Cm ] +character. +The set +.Em excludes +those characters +if the first character after the open bracket is a circumflex +.Cm ^ . +To include a close bracket in the set, +make it the first character after the open bracket +or the circumflex; +any other position will end the set. +To include a hyphen in the set, +make it the last character before the final close bracket; +some implementations of +.Fn wscanf +use +.Dq Li A-Z +to represent the range of characters between +.Ql A +and +.Ql Z . +The string ends with the appearance of a character not in the +(or, with a circumflex, in) set +or when the field width runs out. +.Pp +If an +.Cm l +qualifier is present, the next pointer must be a pointer to +.Vt wchar_t , +into which the input will be placed. +.It Cm p +Matches a pointer value (as printed by +.Ql %p +in +.Xr wprintf 3 ) ; +the next pointer must be a pointer to +.Vt void . +.It Cm n +Nothing is expected; +instead, the number of characters consumed thus far from the input +is stored through the next pointer, +which must be a pointer to +.Vt int . +This is +.Em not +a conversion, although it can be suppressed with the +.Cm * +flag. +.El +.Pp +The decimal point +character is defined in the program's locale (category +.Dv LC_NUMERIC ) . +.Pp +For backwards compatibility, a +.Dq conversion +of +.Ql %\e0 +causes an immediate return of +.Dv EOF . +.Sh RETURN VALUES +These functions return the number of input items assigned, +which can be fewer than provided for, or even zero, +in the event of a matching failure. +Zero indicates that, while there was input available, +no conversions were assigned; +typically, this is due to an invalid input character, +such as an alphabetic character for a +.Ql %d +conversion. +The value +.Dv EOF +is returned if an input failure occurs before any conversion such as an +end-of-file occurs. +If an error or end-of-file occurs after conversion +has begun, +the number of conversions which were successfully completed is returned. +.Sh SEE ALSO +.Xr fgetwc 3 , +.Xr scanf 3 , +.Xr wcrtomb 3 , +.Xr wcstod 3 , +.Xr wcstol 3 , +.Xr wcstoul 3 , +.Xr wprintf 3 , +.Xr wscanf_l 3 +.Sh STANDARDS +The +.Fn fwscanf , +.Fn wscanf , +.Fn swscanf , +.Fn vfwscanf , +.Fn vwscanf , +and +.Fn vswscanf +functions +conform to +.St -isoC-99 . +.Sh BUGS +In addition to the bugs documented in +.Xr scanf 3 , +.Fn wscanf +does not support the +.Dq Li A-Z +notation for specifying character ranges with the character +class conversion +.Pq Sq Cm %[ . diff --git a/stdio/wscanf_l.3 b/stdio/wscanf_l.3 index 68f3ab2..907d00f 100644 --- a/stdio/wscanf_l.3 +++ b/stdio/wscanf_l.3 @@ -41,12 +41,12 @@ .Dt WSCANF_L 3 .Os .Sh NAME -.Nm wscanf_l , .Nm fwscanf_l , .Nm swscanf_l , -.Nm vwscanf_l , +.Nm vfwscanf_l , .Nm vswscanf_l , -.Nm vfwscanf_l +.Nm vwscanf_l , +.Nm wscanf_l .Nd wide character input format conversion .Sh LIBRARY .Lb libc @@ -55,18 +55,47 @@ .In wchar.h .In xlocale.h .Ft int -.Fn wscanf_l "locale_t loc" "const wchar_t * restrict format" ... +.Fo fwscanf_l +.Fa "FILE * restrict stream" +.Fa "locale_t loc" +.Fa "const wchar_t * restrict format" +.Fa ... +.Fc .Ft int -.Fn fwscanf_l "FILE * restrict stream" "locale_t loc" "const wchar_t * restrict format" ... +.Fo swscanf_l +.Fa "const wchar_t * restrict str" +.Fa "locale_t loc" +.Fa "const wchar_t * restrict format" +.Fa ... +.Fc .Ft int -.Fn swscanf_l "const wchar_t * restrict str" "locale_t loc" "const wchar_t * restrict format" ... +.Fo wscanf_l +.Fa "locale_t loc" +.Fa "const wchar_t * restrict format" +.Fa ... +.Fc .In stdarg.h +.In xlocale.h .Ft int -.Fn vwscanf_l "locale_t loc" "const wchar_t * restrict format" "va_list ap" +.Fo vfwscanf_l +.Fa "FILE * restrict stream" +.Fa "locale_t loc" +.Fa "const wchar_t * restrict format" +.Fa "va_list ap" +.Fc .Ft int -.Fn vswscanf_l "const wchar_t * restrict str" "locale_t loc" "const wchar_t * restrict format" "va_list ap" +.Fo vswscanf_l +.Fa "const wchar_t * restrict str" +.Fa "locale_t loc" +.Fa "const wchar_t * restrict format" +.Fa "va_list ap" +.Fc .Ft int -.Fn vfwscanf_l "FILE * restrict stream" "locale_t loc" "const wchar_t * restrict format" "va_list ap" +.Fo vwscanf_l +.Fa "locale_t loc" +.Fa "const wchar_t * restrict format" +.Fa "va_list ap" +.Fc .Sh DESCRIPTION The .Fn wscanf_l , diff --git a/stdio/wsetup-fbsd.c b/stdio/wsetup-fbsd.c new file mode 100644 index 0000000..7b120ff --- /dev/null +++ b/stdio/wsetup-fbsd.c @@ -0,0 +1,96 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include +#include +#include +#include "local.h" + +/* + * Various output routines call wsetup to be sure it is safe to write, + * because either _flags does not include __SWR, or _buf is NULL. + * _wsetup returns 0 if OK to write; otherwise, it returns EOF and sets errno. + */ +int +__swsetup(fp) + FILE *fp; +{ + /* make sure stdio is set up */ + if (!__sdidinit) + __sinit(); + + /* + * If we are not writing, we had better be reading and writing. + */ + if ((fp->_flags & __SWR) == 0) { + if ((fp->_flags & __SRW) == 0) { + errno = EBADF; + return (EOF); + } + if (fp->_flags & __SRD) { + /* clobber any ungetc data */ + if (HASUB(fp)) + FREEUB(fp); + fp->_flags &= ~(__SRD|__SEOF); + fp->_r = 0; + fp->_p = fp->_bf._base; + } + fp->_flags |= __SWR; + } + + /* + * Make a buffer if necessary, then set _w. + */ + if (fp->_bf._base == NULL) + __smakebuf(fp); + if (fp->_flags & __SLBF) { + /* + * It is line buffered, so make _lbfsize be -_bufsize + * for the putc() macro. We will change _lbfsize back + * to 0 whenever we turn off __SWR. + */ + fp->_w = 0; + fp->_lbfsize = -fp->_bf._size; + } else + fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size; + return (0); +} diff --git a/stdlib/FreeBSD/abort.c.patch b/stdlib/FreeBSD/abort.c.patch index f5a0482..f209119 100644 --- a/stdlib/FreeBSD/abort.c.patch +++ b/stdlib/FreeBSD/abort.c.patch @@ -1,11 +1,43 @@ ---- abort.c.orig 2003-08-16 04:43:57.000000000 -0700 -+++ abort.c 2004-10-26 17:29:31.000000000 -0700 -@@ -45,7 +45,7 @@ +--- abort.c.orig 2007-04-17 01:31:46.000000000 -0700 ++++ abort.c 2007-04-17 01:36:22.000000000 -0700 +@@ -45,7 +45,10 @@ #include #include "un-namespace.h" -void (*__cleanup)(); +extern void (*__cleanup)(); ++extern void __abort(void) __dead2; ++ ++#define TIMEOUT 10000 /* 10 milliseconds */ void abort() +@@ -67,11 +70,20 @@ + sigdelset(&act.sa_mask, SIGABRT); + (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)raise(SIGABRT); ++ usleep(TIMEOUT); /* give time for signal to happen */ + + /* + * If SIGABRT was ignored, or caught and the handler returns, do + * it again, only harder. + */ ++ __abort(); ++} ++ ++__private_extern__ void ++__abort() ++{ ++ struct sigaction act; ++ + act.sa_handler = SIG_DFL; + act.sa_flags = 0; + sigfillset(&act.sa_mask); +@@ -79,5 +91,6 @@ + sigdelset(&act.sa_mask, SIGABRT); + (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)raise(SIGABRT); +- exit(1); ++ usleep(TIMEOUT); /* give time for signal to happen */ ++ __builtin_trap(); /* never exit normally */ + } diff --git a/stdlib/FreeBSD/abs.3.patch b/stdlib/FreeBSD/abs.3.patch new file mode 100644 index 0000000..9e9ce75 --- /dev/null +++ b/stdlib/FreeBSD/abs.3.patch @@ -0,0 +1,20 @@ +--- 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 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft int +-.Fn abs "int j" ++.Fn abs "int i" + .Sh DESCRIPTION + The + .Fn abs +-function +-computes +-the absolute value of the integer +-.Fa j . ++function computes the absolute value of the integer ++.Fa i . + .Sh RETURN VALUES + The + .Fn abs diff --git a/stdlib/FreeBSD/atexit.3.patch b/stdlib/FreeBSD/atexit.3.patch new file mode 100644 index 0000000..ca9d12c --- /dev/null +++ b/stdlib/FreeBSD/atexit.3.patch @@ -0,0 +1,30 @@ +--- _SB/Libc/stdlib/FreeBSD/atexit.3 2003-05-20 15:23:24.000000000 -0700 ++++ _SB/Libc/stdlib/FreeBSD/atexit.3.edit 2006-06-28 16:55:52.000000000 -0700 +@@ -47,13 +47,13 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft int +-.Fn atexit "void (*function)(void)" ++.Fn atexit "void (*func)(void)" + .Sh DESCRIPTION + The + .Fn atexit + function +-registers the given +-.Fa function ++registers the function ++.Fa func + to be called at program exit, whether via + .Xr exit 3 + or via return from the program's +@@ -71,8 +71,8 @@ + process termination, for example by calling + .Xr abort 3 . ) + .Pp +-At least 32 functions can always be registered, +-and more are allowed as long as sufficient memory can be allocated. ++At least 32 functions can always be registered; ++more are allowed as long as sufficient memory can be allocated. + .\" XXX {ATEXIT_MAX} is not implemented yet + .Sh RETURN VALUES + .Rv -std atexit diff --git a/stdlib/FreeBSD/atexit.c.patch b/stdlib/FreeBSD/atexit.c.patch index 1aae327..1aa7e42 100644 --- a/stdlib/FreeBSD/atexit.c.patch +++ b/stdlib/FreeBSD/atexit.c.patch @@ -1,5 +1,5 @@ ---- atexit.c.orig 2004-03-11 13:16:53.000000000 -0800 -+++ atexit.c 2004-09-15 00:14:26.000000000 -0700 +--- atexit.c.orig 2006-04-09 01:23:25.000000000 -0700 ++++ atexit.c 2006-04-09 01:44:07.000000000 -0700 @@ -45,6 +45,9 @@ #include #include @@ -10,7 +10,23 @@ #include "atexit.h" #include "un-namespace.h" -@@ -125,7 +128,11 @@ +@@ -74,6 +77,7 @@ + }; + + static struct atexit *__atexit; /* points to head of LIFO stack */ ++static int new_registration; + + /* + * Register the function described by 'fptr' to be called at application +@@ -109,6 +113,7 @@ + __atexit = p; + } + p->fns[p->ind++] = *fptr; ++ new_registration = 1; + _MUTEX_UNLOCK(&atexit_mutex); + return 0; + } +@@ -125,7 +130,11 @@ fn.fn_type = ATEXIT_FN_STD; fn.fn_ptr.std_func = func;; fn.fn_arg = NULL; @@ -22,7 +38,7 @@ error = atexit_register(&fn); return (error); -@@ -156,7 +163,7 @@ +@@ -156,13 +165,14 @@ * handlers are called. */ void @@ -31,3 +47,27 @@ { struct atexit *p; struct atexit_fn fn; + int n; + + _MUTEX_LOCK(&atexit_mutex); ++restart: + for (p = __atexit; p; p = p->next) { + for (n = p->ind; --n >= 0;) { + if (p->fns[n].fn_type == ATEXIT_FN_EMPTY) +@@ -175,6 +185,7 @@ + has already been called. + */ + p->fns[n].fn_type = ATEXIT_FN_EMPTY; ++ new_registration = 0; + _MUTEX_UNLOCK(&atexit_mutex); + + /* Call the function of correct type. */ +@@ -183,6 +194,8 @@ + else if (fn.fn_type == ATEXIT_FN_STD) + fn.fn_ptr.std_func(); + _MUTEX_LOCK(&atexit_mutex); ++ if (new_registration) ++ goto restart; + } + } + _MUTEX_UNLOCK(&atexit_mutex); diff --git a/stdlib/FreeBSD/atof.3.patch b/stdlib/FreeBSD/atof.3.patch index e1e9ac7..b87bd4b 100644 --- a/stdlib/FreeBSD/atof.3.patch +++ b/stdlib/FreeBSD/atof.3.patch @@ -1,5 +1,5 @@ ---- atof.3.orig Fri Mar 11 10:10:58 2005 -+++ atof.3 Fri Mar 11 10:12:33 2005 +--- 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 @@ .Dt ATOF 3 .Os @@ -10,17 +10,31 @@ .Nd convert .Tn ASCII string to double -@@ -50,6 +51,9 @@ +@@ -49,24 +50,35 @@ + .Sh SYNOPSIS .In stdlib.h .Ft double - .Fn atof "const char *nptr" +-.Fn atof "const char *nptr" ++.Fn atof "const char *str" +.In xlocale.h +.Ft double -+.Fn atof_l "const char *nptr" "locale_t loc" ++.Fn atof_l "const char *str" "locale_t loc" .Sh DESCRIPTION The .Fn atof -@@ -67,6 +71,14 @@ + function converts the initial portion of the string pointed to by +-.Fa nptr ++.Fa str + to + .Vt double + representation. + .Pp + It is equivalent to: + .Bd -literal -offset indent +-strtod(nptr, (char **)NULL); ++strtod(str, (char **)NULL); + .Ed + .Pp The decimal point character is defined in the program's locale (category .Dv LC_NUMERIC ) . diff --git a/stdlib/FreeBSD/atoi.3.patch b/stdlib/FreeBSD/atoi.3.patch index f6354eb..f9f1ae2 100644 --- a/stdlib/FreeBSD/atoi.3.patch +++ b/stdlib/FreeBSD/atoi.3.patch @@ -1,5 +1,5 @@ ---- atoi.3.orig Fri Mar 11 10:13:22 2005 -+++ atoi.3 Fri Mar 11 10:14:49 2005 +--- 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 @@ .Dt ATOI 3 .Os @@ -10,19 +10,29 @@ .Nd convert .Tn ASCII string to integer -@@ -50,6 +51,9 @@ +@@ -49,20 +50,31 @@ + .Sh SYNOPSIS .In stdlib.h .Ft int - .Fn atoi "const char *nptr" +-.Fn atoi "const char *nptr" ++.Fn atoi "const char *str" +.In xlocale.h +.Ft int -+.Fn atoi_l "const char *nptr" "locale_t loc" ++.Fn atoi_l "const char *str" "locale_t loc" .Sh DESCRIPTION The .Fn atoi -@@ -63,6 +67,14 @@ + function converts the initial portion of the string pointed to by +-.Fa nptr ++.Fa str + to + .Vt int + representation. + .Pp + It is equivalent to: .Bd -literal -offset indent - (int)strtol(nptr, (char **)NULL, 10); +-(int)strtol(nptr, (char **)NULL, 10); ++(int)strtol(str, (char **)NULL, 10); .Ed +.Pp +While the diff --git a/stdlib/FreeBSD/atol.3.patch b/stdlib/FreeBSD/atol.3.patch index 908282d..c10d971 100644 --- a/stdlib/FreeBSD/atol.3.patch +++ b/stdlib/FreeBSD/atol.3.patch @@ -1,5 +1,5 @@ ---- atol.3.orig Fri Mar 11 10:15:17 2005 -+++ atol.3 Fri Mar 11 10:53:10 2005 +--- 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 @@ .Dt ATOL 3 .Os @@ -10,22 +10,50 @@ .Nd convert .Tn ASCII string to -@@ -56,6 +57,11 @@ - .Fn atol "const char *nptr" +@@ -53,14 +54,19 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft long +-.Fn atol "const char *nptr" ++.Fn atol "const char *str" .Ft "long long" - .Fn atoll "const char *nptr" +-.Fn atoll "const char *nptr" ++.Fn atoll "const char *str" +.In xlocale.h +.Ft long -+.Fn atol_l "const char *nptr" "locale_t loc" ++.Fn atol_l "const char *str" "locale_t loc" +.Ft "long long" -+.Fn atoll_l "const char *nptr" "locale_t loc" ++.Fn atoll_l "const char *str" "locale_t loc" .Sh DESCRIPTION The .Fn atol -@@ -82,6 +88,18 @@ + function converts the initial portion of the string pointed to by +-.Fa nptr ++.Fa str + to + .Vt long + integer +@@ -68,12 +74,12 @@ + .Pp + It is equivalent to: + .Pp +-.Dl "strtol(nptr, (char **)NULL, 10);" ++.Dl "strtol(str, (char **)NULL, 10);" + .Pp + The + .Fn atoll + function converts the initial portion of the string pointed to by +-.Fa nptr ++.Fa str + to + .Vt "long long" + integer +@@ -81,7 +87,19 @@ + .Pp It is equivalent to: .Pp - .Dl "strtoll(nptr, (char **)NULL, 10);" +-.Dl "strtoll(nptr, (char **)NULL, 10);" ++.Dl "strtoll(str, (char **)NULL, 10);" +.Pp +While the +.Fn atol diff --git a/stdlib/FreeBSD/bsearch.3.patch b/stdlib/FreeBSD/bsearch.3.patch new file mode 100644 index 0000000..9ce70e2 --- /dev/null +++ b/stdlib/FreeBSD/bsearch.3.patch @@ -0,0 +1,36 @@ +--- _SB/Libc/stdlib/FreeBSD/bsearch.3 2003-05-20 15:23:24.000000000 -0700 ++++ _SB/Libc/stdlib/FreeBSD/bsearch.3.edit 2006-06-28 16:55:52.000000000 -0700 +@@ -47,19 +47,19 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft void * +-.Fn bsearch "const void *key" "const void *base" "size_t nmemb" "size_t size" "int (*compar) (const void *, const void *)" ++.Fn bsearch "const void *key" "const void *base" "size_t nel" "size_t width" "int (*compar) (const void *, const void *)" + .Sh DESCRIPTION + The + .Fn bsearch + function searches an array of +-.Fa nmemb ++.Fa nel + objects, the initial member of which is + pointed to by + .Fa base , + for a member that matches the object pointed to by + .Fa key . +-The size of each member of the array is specified by +-.Fa size . ++The size (in bytes) of each member of the array is specified by ++.Fa width . + .Pp + The contents of the array should be in ascending sorted order according + to the comparison function referenced by +@@ -70,7 +70,8 @@ + is expected to have + two arguments which point to the + .Fa key +-object and to an array member, in that order, and should return an integer ++object and to an array member, in that order. ++It should return an integer which is + less than, equal to, or greater than zero if the + .Fa key + object is found, respectively, to be less than, to match, or be diff --git a/stdlib/FreeBSD/div.3.patch b/stdlib/FreeBSD/div.3.patch new file mode 100644 index 0000000..aa7cf1c --- /dev/null +++ b/stdlib/FreeBSD/div.3.patch @@ -0,0 +1,31 @@ +--- _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 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft div_t +-.Fn div "int num" "int denom" ++.Fn div "int numer" "int denom" + .Sh DESCRIPTION + The + .Fn div + function + computes the value +-.Fa num/denom +-and returns the quotient and remainder in a structure named ++.Fa numer/denom ++(numerator/denominator). ++It returns a structure named + .Fa div_t + that contains two + .Vt int + members named + .Va quot +-and +-.Va rem . ++(quotient) and ++.Va rem ++(remainder). + .Sh SEE ALSO + .Xr imaxdiv 3 , + .Xr ldiv 3 , diff --git a/stdlib/FreeBSD/exit.c.patch b/stdlib/FreeBSD/exit.c.patch index f1ac18e..0524eb0 100644 --- a/stdlib/FreeBSD/exit.c.patch +++ b/stdlib/FreeBSD/exit.c.patch @@ -1,9 +1,11 @@ ---- exit.c.orig Wed Mar 10 14:20:34 2004 -+++ exit.c Wed Mar 10 14:38:14 2004 -@@ -46,26 +46,12 @@ - void (*__cleanup)(); +--- 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" - /* + void (*__cleanup)(); +- +-/* - * This variable is zero until a process has created a thread. - * It is used to avoid calling locking functions in libc when they - * are not required. By default, libc is intended to be(come) @@ -11,11 +13,11 @@ - * processes. - */ -int __isthreaded = 0; -- --/* ++extern void __exit(int); + + /* * Exit, flushing stdio buffers if necessary. - */ - void +@@ -61,13 +53,8 @@ exit(status) int status; { @@ -27,3 +29,6 @@ __cxa_finalize(NULL); if (__cleanup) (*__cleanup)(); +- _exit(status); ++ __exit(status); + } diff --git a/stdlib/FreeBSD/getenv.3.patch b/stdlib/FreeBSD/getenv.3.patch new file mode 100644 index 0000000..2e2be3b --- /dev/null +++ b/stdlib/FreeBSD/getenv.3.patch @@ -0,0 +1,121 @@ +--- getenv.3 2004-11-25 11:38:41.000000000 -0800 ++++ getenv.3.edit 2006-09-17 20:33:52.000000000 -0700 +@@ -50,13 +50,23 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft char * +-.Fn getenv "const char *name" ++.Fo getenv ++.Fa "const char *name" ++.Fc + .Ft int +-.Fn setenv "const char *name" "const char *value" "int overwrite" ++.Fo putenv ++.Fa "char *string" ++.Fc + .Ft int +-.Fn putenv "const char *string" +-.Ft void +-.Fn unsetenv "const char *name" ++.Fo setenv ++.Fa "const char *name" ++.Fa "const char *value" ++.Fa "int overwrite" ++.Fc ++.Ft int ++.Fo unsetenv ++.Fa "const char *name" ++.Fc + .Sh DESCRIPTION + These functions set, unset and fetch environment variables from the + host +@@ -104,12 +114,26 @@ + setenv(name, value, 1); + .Ed + .Pp ++The string pointed to by ++.Fa string ++becomes part of the environment. ++A program should not alter or free the string, ++and should not use stack or other transient string variables ++as arguments to ++.Fn putenv . ++The ++.Fn setenv ++function is strongly preferred to ++.Fn putenv . ++.Pp + The + .Fn unsetenv + function + deletes all instances of the variable name pointed to by + .Fa name + from the list. ++Note that only the variable name (e.g., "NAME") should be given; ++"NAME=value" will not work. + .Sh RETURN VALUES + The + .Fn getenv +@@ -122,20 +146,60 @@ + .Dv NULL + is returned. + .Pp +-.Rv -std setenv putenv ++.Rv -std setenv putenv unsetenv + .Sh ERRORS + .Bl -tag -width Er ++.It Bq Er EINVAL ++The function ++.Fn unsetenv ++failed because ++.Fa name ++was not found in the environment list. + .It Bq Er ENOMEM + The function + .Fn setenv + or + .Fn putenv +-failed because they were unable to allocate memory for the environment. ++failed because it was unable to allocate memory for the environment. + .El ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Pp ++.Ft void ++.br ++.Fo unsetenv ++.Fa "const char *name" ++.Fc ; ++.Pp ++.Fn unsetenv ++doesn't return a value. ++.Sh COMPATIBILITY ++.Fn putenv ++no longer copies its input buffer. ++This often appears in crash logs as a crash in ++.Fn getenv . ++Avoid passing local buffers or freeing the memory ++that is passed to ++.Fn putenv . ++Use ++.Fn setenv , ++which still makes an internal copy of its buffers. ++.Pp ++.Fn unsetenv ++no longer parses the variable name; ++e.g., unsetenv ("FOO=BAR") no longer works. ++Use unsetenv("FOO"). ++.Fn unsetenv ++also now returns a status value and will set ++.Va errno ++to EINVAL if ++.Fa name ++is not a defined environment variable. + .Sh SEE ALSO + .Xr csh 1 , + .Xr sh 1 , + .Xr execve 2 , ++.Xr compat 5 , + .Xr environ 7 + .Sh STANDARDS + The diff --git a/stdlib/FreeBSD/getenv.c.patch b/stdlib/FreeBSD/getenv.c.patch index 4915edc..1b454e2 100644 --- a/stdlib/FreeBSD/getenv.c.patch +++ b/stdlib/FreeBSD/getenv.c.patch @@ -1,5 +1,5 @@ ---- getenv.c.orig 2004-12-01 20:08:48.000000000 -0800 -+++ getenv.c 2004-12-01 20:10:20.000000000 -0800 +--- 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 @@ #include #include @@ -7,16 +7,50 @@ +#include -inline char *__findenv(const char *, int *); -+inline char *__findenv(const char *, int *) __attribute__((always_inline)); ++__private_extern__ char *__findenv(const char *, int *, char **); /* * __findenv -- -@@ -57,7 +58,7 @@ +@@ -52,12 +53,12 @@ + * + * This routine *should* be a static; don't use it. + */ +-inline char * +-__findenv(name, offset) ++__private_extern__ char * ++__findenv(name, offset, environ) const char *name; int *offset; ++ char **environ; { - extern char **environ; -+ char **environ = *_NSGetEnviron(); int len, i; const char *np; char **p, *cp; +@@ -80,6 +81,19 @@ + } + + /* ++ * _getenvp -- SPI using an arbitrary pointer to string array (the array must ++ * have been created with malloc) and an env state, created by _allocenvstate(). ++ * Returns ptr to value associated with name, if any, else NULL. ++ */ ++char * ++_getenvp(const char *name, char ***envp, void *state __unused) ++{ ++ int offset; ++ ++ return (__findenv(name, &offset, *envp)); ++} ++ ++/* + * getenv -- + * Returns ptr to value associated with name, if any, else NULL. + */ +@@ -89,5 +103,5 @@ + { + int offset; + +- return (__findenv(name, &offset)); ++ return (__findenv(name, &offset, *_NSGetEnviron())); + } diff --git a/stdlib/FreeBSD/getopt.c.patch b/stdlib/FreeBSD/getopt.c.patch new file mode 100644 index 0000000..4b9ad71 --- /dev/null +++ b/stdlib/FreeBSD/getopt.c.patch @@ -0,0 +1,59 @@ +--- ../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 @@ + + #include "libc_private.h" + ++#ifndef BUILDING_VARIANT + int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ + char *optarg; /* argument associated with option */ ++#endif /* !BUILDING_VARIANT */ + + #define BADCH (int)'?' + #define BADARG (int)':' + #define EMSG "" + ++#if __DARWIN_UNIX03 ++#define PROGNAME nargv[0] ++#else ++#define PROGNAME _getprogname() ++#endif ++ + /* + * getopt -- + * Parse argc/argv argument vector. +@@ -103,8 +111,8 @@ + ++optind; + if (opterr && *ostr != ':') + (void)fprintf(stderr, +- "%s: illegal option -- %c\n", _getprogname(), +- optopt); ++ "%s: illegal option -- %c\n", ++ PROGNAME, optopt); + return (BADCH); + } + +@@ -123,13 +131,19 @@ + optarg = nargv[optind]; + else { + /* option-argument absent */ ++#if __DARWIN_UNIX03 ++ /* Yes, the standard will put optind past the last ++ argument */ ++ ++optind; ++ optarg = NULL; ++#endif /* __DARWIN_UNIX03 */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", +- _getprogname(), optopt); ++ PROGNAME, optopt); + return (BADCH); + } + place = EMSG; diff --git a/stdlib/FreeBSD/getsubopt.3.patch b/stdlib/FreeBSD/getsubopt.3.patch new file mode 100644 index 0000000..5b472e7 --- /dev/null +++ b/stdlib/FreeBSD/getsubopt.3.patch @@ -0,0 +1,69 @@ +--- _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 @@ + .In stdlib.h + .Vt extern char *suboptarg ; + .Ft int +-.Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep" ++.Fo getsubopt ++.Fa "char **optionp" ++.Fa "char *const *keylistp" ++.Fa "char **valuep" ++.Fc + .Sh DESCRIPTION + The + .Fn getsubopt + function +-parses a string containing tokens delimited by one or more tab, space or +-comma ++parses a string containing tokens that are delimited ++by one or more tab, space, or comma + .Pq Ql \&, + characters. +-It is intended for use in parsing groups of option arguments provided +-as part of a utility command line. ++It is intended for use in parsing groups of option arguments ++that are provided as part of a utility command line. + .Pp + The argument + .Fa optionp + is a pointer to a pointer to the string. + The argument +-.Fa tokens ++.Fa keylistp + is a pointer to a + .Dv NULL Ns -terminated + array of pointers to strings. +@@ -69,10 +73,10 @@ + .Fn getsubopt + function + returns the zero-based offset of the pointer in the +-.Fa tokens +-array referencing a string which matches the first token +-in the string, or, \-1 if the string contains no tokens or +-.Fa tokens ++.Fa keylistp ++array, referencing a string which matches the first token in the string ++ or \-1 if the string contains no tokens or ++.Fa keylistp + does not contain a matching string. + .Pp + If the token is of the form ``name=value'', the location referenced by +@@ -97,7 +101,7 @@ + if no ``value'' portion was present. + .Sh EXAMPLES + .Bd -literal -compact +-char *tokens[] = { ++char *keylistp[] = { + #define ONE 0 + "one", + #define TWO 1 +@@ -118,7 +122,7 @@ + case 'b': + options = optarg; + while (*options) { +- switch(getsubopt(&options, tokens, &value)) { ++ switch(getsubopt(&options, keylistp, &value)) { + case ONE: + /* process ``one'' sub option */ + break; diff --git a/stdlib/FreeBSD/grantpt.3.patch b/stdlib/FreeBSD/grantpt.3.patch deleted file mode 100644 index 4b3c64a..0000000 --- a/stdlib/FreeBSD/grantpt.3.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- /Volumes/XDisk/tmp/Libc/stdlib/FreeBSD/grantpt.3.orig 2003-09-14 06:41:57.000000000 -0700 -+++ /Volumes/XDisk/tmp/Libc/stdlib/FreeBSD/grantpt.3 2004-10-24 17:08:31.000000000 -0700 -@@ -44,6 +44,7 @@ - .Lb libc - .Sh SYNOPSIS - .In stdlib.h -+.In fcntl.h - .Ft int - .Fn grantpt "int fildes" - .Ft "char *" diff --git a/stdlib/FreeBSD/grantpt.c b/stdlib/FreeBSD/grantpt.c deleted file mode 100644 index 9902c54..0000000 --- a/stdlib/FreeBSD/grantpt.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2002 The FreeBSD Project, Inc. - * All rights reserved. - * - * This software includes code contributed to the FreeBSD Project - * by Ryan Younce of North Carolina State University. - * - * 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 FreeBSD Project 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 FREEBSD PROJECT 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 FREEBSD PROJECT OR ITS 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 -#ifndef lint -__FBSDID("$FreeBSD: src/lib/libc/stdlib/grantpt.c,v 1.2 2003/01/04 08:10:55 tjr Exp $"); -#endif /* not lint */ - -#include "namespace.h" -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "un-namespace.h" - -#define PTM_MAJOR 6 /* pseudo tty master major */ -#define PTS_MAJOR 5 /* pseudo tty slave major */ -#define PTM_PREFIX "pty" /* pseudo tty master naming convention */ -#define PTS_PREFIX "tty" /* pseudo tty slave naming convention */ - -/* - * The following are range values for pseudo TTY devices. Pseudo TTYs have a - * name of /dev/[pt]ty[p-sP-S][0-9a-v], yielding 256 combinations per major. - */ -#define PT_MAX 256 -#define PT_DEV1 "pqrsPQRS" -#define PT_DEV2 "0123456789abcdefghijklmnopqrstuv" - -/* - * grantpt(3) support utility. - */ -#define _PATH_PTCHOWN "/usr/libexec/pt_chown" - -/* - * ISPTM(x) returns 0 for struct stat x if x is not a pty master. - * The bounds checking may be unnecessary but it does eliminate doubt. - */ -#define ISPTM(x) (S_ISCHR((x).st_mode) && \ - major((x).st_rdev) == PTM_MAJOR && \ - minor((x).st_rdev) >= 0 && \ - minor((x).st_rdev) < PT_MAX) - -/* - * grantpt(): grant ownership of a slave pseudo-terminal device to the - * current user. - */ - -int -grantpt(int fildes) -{ - int retval, serrno, status; - pid_t pid, spid; - gid_t gid; - char *slave; - sigset_t oblock, nblock; - struct group *grp; - - retval = -1; - serrno = errno; - - if ((slave = ptsname(fildes)) != NULL) { - /* - * Block SIGCHLD. - */ - (void)sigemptyset(&nblock); - (void)sigaddset(&nblock, SIGCHLD); - (void)_sigprocmask(SIG_BLOCK, &nblock, &oblock); - - switch (pid = fork()) { - case -1: - break; - case 0: /* child */ - /* - * pt_chown expects the master pseudo TTY to be its - * standard input. - */ - (void)_dup2(fildes, STDIN_FILENO); - (void)_sigprocmask(SIG_SETMASK, &oblock, NULL); - execl(_PATH_PTCHOWN, _PATH_PTCHOWN, (char *)NULL); - _exit(EX_UNAVAILABLE); - /* NOTREACHED */ - default: /* parent */ - /* - * Just wait for the process. Error checking is - * done below. - */ - while ((spid = _waitpid(pid, &status, 0)) == -1 && - (errno == EINTR)) - ; - if (spid != -1 && WIFEXITED(status) && - WEXITSTATUS(status) == EX_OK) - retval = 0; - else - errno = EACCES; - break; - } - - /* - * Restore process's signal mask. - */ - (void)_sigprocmask(SIG_SETMASK, &oblock, NULL); - - if (retval) { - /* - * pt_chown failed. Try to manually change the - * permissions for the slave. - */ - gid = (grp = getgrnam("tty")) ? grp->gr_gid : -1; - if (chown(slave, getuid(), gid) == -1 || - chmod(slave, S_IRUSR | S_IWUSR | S_IWGRP) == -1) - errno = EACCES; - else - retval = 0; - } - } - - if (!retval) - errno = serrno; - - return (retval); -} - -/* - * posix_openpt(): open the first available master pseudo-terminal device - * and return descriptor. - */ -int -posix_openpt(int oflag) -{ - char *mc1, *mc2, master[] = _PATH_DEV PTM_PREFIX "XY"; - const char *pc1, *pc2; - int fildes, bflag, serrno; - - fildes = -1; - bflag = 0; - serrno = errno; - - /* - * Check flag validity. POSIX doesn't require it, - * but we still do so. - */ - if (oflag & ~(O_RDWR | O_NOCTTY)) - errno = EINVAL; - else { - mc1 = master + strlen(_PATH_DEV PTM_PREFIX); - mc2 = mc1 + 1; - - /* Cycle through all possible master PTY devices. */ - for (pc1 = PT_DEV1; !bflag && (*mc1 = *pc1); ++pc1) - for (pc2 = PT_DEV2; (*mc2 = *pc2) != '\0'; ++pc2) { - /* - * Break out if we successfully open a PTY, - * or if open() fails due to limits. - */ - if ((fildes = _open(master, oflag)) != -1 || - (errno == EMFILE || errno == ENFILE)) { - ++bflag; - break; - } - } - - if (fildes != -1) - errno = serrno; - else if (!bflag) - errno = EAGAIN; - } - - return (fildes); -} - -/* - * ptsname(): return the pathname of the slave pseudo-terminal device - * associated with the specified master. - */ -char * -ptsname(int fildes) -{ - static char slave[] = _PATH_DEV PTS_PREFIX "XY"; - char *retval; - struct stat sbuf; - - retval = NULL; - - if (_fstat(fildes, &sbuf) == 0) { - if (!ISPTM(sbuf)) - errno = EINVAL; - else { - (void)sprintf(slave, _PATH_DEV PTS_PREFIX "%c%c", - PT_DEV1[minor(sbuf.st_rdev) / 32], - PT_DEV2[minor(sbuf.st_rdev) % 32]); - retval = slave; - } - } - - return (retval); -} - -/* - * unlockpt(): unlock a pseudo-terminal device pair. - */ -int -unlockpt(int fildes) -{ - int retval; - struct stat sbuf; - - /* - * Unlocking a master/slave pseudo-terminal pair has no meaning in a - * non-streams PTY environment. However, we do ensure fildes is a - * valid master pseudo-terminal device. - */ - if ((retval = _fstat(fildes, &sbuf)) == 0 && !ISPTM(sbuf)) { - errno = EINVAL; - retval = -1; - } - - return (retval); -} diff --git a/stdlib/FreeBSD/grantpt.c.patch b/stdlib/FreeBSD/grantpt.c.patch deleted file mode 100644 index 2e73b70..0000000 --- a/stdlib/FreeBSD/grantpt.c.patch +++ /dev/null @@ -1,161 +0,0 @@ ---- grantpt.c.orig 2006-04-21 22:41:31.000000000 -0700 -+++ grantpt.c 2006-04-21 22:43:03.000000000 -0700 -@@ -54,18 +54,16 @@ - #include - #include "un-namespace.h" - --#define PTM_MAJOR 6 /* pseudo tty master major */ --#define PTS_MAJOR 5 /* pseudo tty slave major */ - #define PTM_PREFIX "pty" /* pseudo tty master naming convention */ - #define PTS_PREFIX "tty" /* pseudo tty slave naming convention */ - - /* - * The following are range values for pseudo TTY devices. Pseudo TTYs have a -- * name of /dev/[pt]ty[p-sP-S][0-9a-v], yielding 256 combinations per major. -+ * name of /dev/[pt]ty[p-w][0-9a-f], yielding 128 combinations per major. - */ --#define PT_MAX 256 --#define PT_DEV1 "pqrsPQRS" --#define PT_DEV2 "0123456789abcdefghijklmnopqrstuv" -+#define PT_MAX 128 -+#define PT_DEV1 "pqrstuvw" -+#define PT_DEV2 "0123456789abcdef" - - /* - * grantpt(3) support utility. -@@ -73,11 +71,32 @@ - #define _PATH_PTCHOWN "/usr/libexec/pt_chown" - - /* -+ * On Mac OS X, the major device number may not be the same between reboots. -+ * So we need to determine the major device number the first time. -+ */ -+#define _PATH_A_PTY (_PATH_DEV PTM_PREFIX "p0") -+ -+static int _ptm_major = -1; -+ -+static int -+_init_major(void) -+{ -+ struct stat st; -+ -+ if (_ptm_major >= 0) -+ return _ptm_major; -+ if (stat(_PATH_A_PTY, &st) < 0) -+ return -1; /* should never happen */ -+ _ptm_major = major(st.st_rdev); -+ return _ptm_major; -+} -+/* - * ISPTM(x) returns 0 for struct stat x if x is not a pty master. - * The bounds checking may be unnecessary but it does eliminate doubt. - */ --#define ISPTM(x) (S_ISCHR((x).st_mode) && \ -- major((x).st_rdev) == PTM_MAJOR && \ -+#define ISPTM(x) (_init_major() >= 0 && \ -+ S_ISCHR((x).st_mode) && \ -+ major((x).st_rdev) == _ptm_major && \ - minor((x).st_rdev) >= 0 && \ - minor((x).st_rdev) < PT_MAX) - -@@ -100,50 +119,53 @@ - serrno = errno; - - if ((slave = ptsname(fildes)) != NULL) { -- /* -- * Block SIGCHLD. -- */ -- (void)sigemptyset(&nblock); -- (void)sigaddset(&nblock, SIGCHLD); -- (void)_sigprocmask(SIG_BLOCK, &nblock, &oblock); -- -- switch (pid = fork()) { -- case -1: -- break; -- case 0: /* child */ -+ /* 4430299: if we are root, we don't need to fork/exec */ -+ if (geteuid() != 0) { - /* -- * pt_chown expects the master pseudo TTY to be its -- * standard input. -+ * Block SIGCHLD. - */ -- (void)_dup2(fildes, STDIN_FILENO); -- (void)_sigprocmask(SIG_SETMASK, &oblock, NULL); -- execl(_PATH_PTCHOWN, _PATH_PTCHOWN, (char *)NULL); -- _exit(EX_UNAVAILABLE); -- /* NOTREACHED */ -- default: /* parent */ -+ (void)sigemptyset(&nblock); -+ (void)sigaddset(&nblock, SIGCHLD); -+ (void)_sigprocmask(SIG_BLOCK, &nblock, &oblock); -+ -+ switch (pid = fork()) { -+ case -1: -+ break; -+ case 0: /* child */ -+ /* -+ * pt_chown expects the master pseudo TTY to be its -+ * standard input. -+ */ -+ (void)_dup2(fildes, STDIN_FILENO); -+ (void)_sigprocmask(SIG_SETMASK, &oblock, NULL); -+ execl(_PATH_PTCHOWN, _PATH_PTCHOWN, (char *)NULL); -+ _exit(EX_UNAVAILABLE); -+ /* NOTREACHED */ -+ default: /* parent */ -+ /* -+ * Just wait for the process. Error checking is -+ * done below. -+ */ -+ while ((spid = _waitpid(pid, &status, 0)) == -1 && -+ (errno == EINTR)) -+ ; -+ if (spid != -1 && WIFEXITED(status) && -+ WEXITSTATUS(status) == EX_OK) -+ retval = 0; -+ else -+ errno = EACCES; -+ break; -+ } -+ - /* -- * Just wait for the process. Error checking is -- * done below. -+ * Restore process's signal mask. - */ -- while ((spid = _waitpid(pid, &status, 0)) == -1 && -- (errno == EINTR)) -- ; -- if (spid != -1 && WIFEXITED(status) && -- WEXITSTATUS(status) == EX_OK) -- retval = 0; -- else -- errno = EACCES; -- break; -+ (void)_sigprocmask(SIG_SETMASK, &oblock, NULL); - } - -- /* -- * Restore process's signal mask. -- */ -- (void)_sigprocmask(SIG_SETMASK, &oblock, NULL); -- - if (retval) { - /* -- * pt_chown failed. Try to manually change the -+ * pt_chown failed (or we're root). Try to manually change the - * permissions for the slave. - */ - gid = (grp = getgrnam("tty")) ? grp->gr_gid : -1; -@@ -227,8 +249,8 @@ - errno = EINVAL; - else { - (void)sprintf(slave, _PATH_DEV PTS_PREFIX "%c%c", -- PT_DEV1[minor(sbuf.st_rdev) / 32], -- PT_DEV2[minor(sbuf.st_rdev) % 32]); -+ PT_DEV1[minor(sbuf.st_rdev) / 16], -+ PT_DEV2[minor(sbuf.st_rdev) % 16]); - retval = slave; - } - } diff --git a/stdlib/FreeBSD/imaxdiv.3.patch b/stdlib/FreeBSD/imaxdiv.3.patch new file mode 100644 index 0000000..8b7d615 --- /dev/null +++ b/stdlib/FreeBSD/imaxdiv.3.patch @@ -0,0 +1,25 @@ +--- _SB/Libc/stdlib/FreeBSD/imaxdiv.3 2003-05-20 15:23:24.000000000 -0700 ++++ _SB/Libc/stdlib/FreeBSD/imaxdiv.3.edit 2006-06-28 16:55:52.000000000 -0700 +@@ -40,10 +40,10 @@ + The + .Fn imaxdiv + function computes the value of +-.Fa numer ++.Fa numer , + divided by +-.Fa denom +-and returns the stored result in the form of the ++.Fa denom . ++The stored result is returned in the form of the + .Vt imaxdiv_t + type. + .Pp +@@ -52,7 +52,7 @@ + type is defined as: + .Bd -literal -offset indent + typedef struct { +- intmax_t quot; /* Quotient. */ ++ intmax_t quot; /* Quotient. */ + intmax_t rem; /* Remainder. */ + } imaxdiv_t; + .Ed diff --git a/stdlib/FreeBSD/insque.3.patch b/stdlib/FreeBSD/insque.3.patch new file mode 100644 index 0000000..8edc8e3 --- /dev/null +++ b/stdlib/FreeBSD/insque.3.patch @@ -0,0 +1,11 @@ +--- _SB/Libc/stdlib/FreeBSD/insque.3 2003-05-20 15:23:24.000000000 -0700 ++++ _SB/Libc/stdlib/FreeBSD/insque.3.edit 2006-06-28 16:55:52.000000000 -0700 +@@ -20,7 +20,7 @@ + .Sh SYNOPSIS + .In search.h + .Ft void +-.Fn insque "void *element1" "void *pred" ++.Fn insque "void *element" "void *pred" + .Ft void + .Fn remque "void *element" + .Sh DESCRIPTION diff --git a/stdlib/FreeBSD/labs.3.patch b/stdlib/FreeBSD/labs.3.patch new file mode 100644 index 0000000..79b3180 --- /dev/null +++ b/stdlib/FreeBSD/labs.3.patch @@ -0,0 +1,18 @@ +--- _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 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft long +-.Fn labs "long j" ++.Fn labs "long i" + .Sh DESCRIPTION + The + .Fn labs + function + returns the absolute value of the long integer +-.Fa j . ++.Fa i . + .Sh SEE ALSO + .Xr abs 3 , + .Xr cabs 3 , diff --git a/stdlib/FreeBSD/ldiv.3.patch b/stdlib/FreeBSD/ldiv.3.patch new file mode 100644 index 0000000..e70b205 --- /dev/null +++ b/stdlib/FreeBSD/ldiv.3.patch @@ -0,0 +1,21 @@ +--- _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 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft ldiv_t +-.Fn ldiv "long num" "long denom" ++.Fn ldiv "long numer" "long denom" + .Sh DESCRIPTION + The + .Fn ldiv + function + computes the value +-.Fa num Ns / Ns Fa denom +-and returns the quotient and remainder in a structure named ++.Fa numer Ns / Ns Fa denom ++(numerator/denominator). ++Ir returns the quotient and remainder in a structure named + .Vt ldiv_t + that contains two + .Vt long diff --git a/stdlib/FreeBSD/llabs.3.patch b/stdlib/FreeBSD/llabs.3.patch new file mode 100644 index 0000000..0ff3af8 --- /dev/null +++ b/stdlib/FreeBSD/llabs.3.patch @@ -0,0 +1,17 @@ +--- _SB/Libc/stdlib/FreeBSD/llabs.3 2003-05-20 15:23:24.000000000 -0700 ++++ _SB/Libc/stdlib/FreeBSD/llabs.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -35,12 +35,12 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft "long long" +-.Fn llabs "long long j" ++.Fn llabs "long long i" + .Sh DESCRIPTION + The + .Fn llabs + function returns the absolute value of +-.Fa j . ++.Fa i . + .Sh SEE ALSO + .Xr abs 3 , + .Xr fabs 3 , diff --git a/stdlib/FreeBSD/lldiv.3.patch b/stdlib/FreeBSD/lldiv.3.patch new file mode 100644 index 0000000..b5320de --- /dev/null +++ b/stdlib/FreeBSD/lldiv.3.patch @@ -0,0 +1,25 @@ +--- _SB/Libc/stdlib/FreeBSD/lldiv.3 2003-05-20 15:23:24.000000000 -0700 ++++ _SB/Libc/stdlib/FreeBSD/lldiv.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -40,10 +40,10 @@ + The + .Fn lldiv + function computes the value of +-.Fa numer ++.Fa numer , + divided by +-.Fa denom +-and returns the stored result in the form of the ++.Fa denom . ++It returns the stored result in the form of the + .Vt lldiv_t + type. + .Pp +@@ -52,7 +52,7 @@ + type is defined as: + .Bd -literal -offset indent + typedef struct { +- long long quot; /* Quotient. */ ++ long long quot; /* Quotient. */ + long long rem; /* Remainder. */ + } lldiv_t; + .Ed diff --git a/stdlib/FreeBSD/lsearch.3.patch b/stdlib/FreeBSD/lsearch.3.patch new file mode 100644 index 0000000..763bd27 --- /dev/null +++ b/stdlib/FreeBSD/lsearch.3.patch @@ -0,0 +1,41 @@ +--- _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 +@@ -12,21 +12,21 @@ + .Dt LSEARCH 3 + .Os + .Sh NAME +-.Nm lsearch , +-.Nm lfind ++.Nm lfind , ++.Nm lsearch + .Nd linear search and append + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In search.h + .Ft "void *" +-.Fo lsearch +-.Fa "const void *key" "void *base" "size_t *nelp" "size_t width" ++.Fo lfind ++.Fa "const void *key" "const void *base" "size_t *nelp" "size_t width" + .Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" + .Fc + .Ft "void *" +-.Fo lfind +-.Fa "const void *key" "const void *base" "size_t *nelp" "size_t width" ++.Fo lsearch ++.Fa "const void *key" "void *base" "size_t *nelp" "size_t width" + .Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" + .Fc + .Sh DESCRIPTION +@@ -34,8 +34,8 @@ + .Fn lsearch + and + .Fn lfind +-functions walk linearly through an array and compare each element with +-the one to be sought using a supplied comparison function. ++functions walk linearly through an array, comparing each element with ++the one to be sought, by means of a supplied comparison function. + .Pp + The + .Fa key diff --git a/stdlib/FreeBSD/memory.3.patch b/stdlib/FreeBSD/memory.3.patch new file mode 100644 index 0000000..d93412f --- /dev/null +++ b/stdlib/FreeBSD/memory.3.patch @@ -0,0 +1,118 @@ +--- 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 @@ + .Dt MEMORY 3 + .Os + .Sh NAME +-.Nm malloc , +-.Nm free , +-.Nm realloc , +-.Nm calloc , + .Nm alloca , +-.Nm mmap ++.Nm calloc , ++.Nm free , ++.Nm malloc , ++.Nm mmap , ++.Nm realloc + .Nd general memory allocation operations + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In stdlib.h + .Ft void * +-.Fn malloc "size_t size" +-.Ft void +-.Fn free "void *ptr" ++.Fo alloca ++.Fa "size_t size" ++.Fc + .Ft void * +-.Fn realloc "void *ptr" "size_t size" ++.Fo calloc ++.Fa "size_t nelem" ++.Fa "size_t elsize" ++.Fc ++.Ft void ++.Fo free ++.Fa "void *ptr" ++.Fc + .Ft void * +-.Fn calloc "size_t nelem" "size_t elsize" ++.Fo malloc ++.Fa "size_t size" ++.Fc + .Ft void * +-.Fn alloca "size_t size" +-.In sys/types.h ++.Fo realloc ++.Fa "void *ptr" ++.Fa "size_t size" ++.Fc + .In sys/mman.h + .Ft void * +-.Fn mmap "void * addr" "size_t len" "int prot" "int flags" "int fd" "off_t offset" ++.Fo mmap ++.Fa "void * addr" ++.Fa "size_t len" ++.Fa "int prot" ++.Fa "int flags" ++.Fa "int fildes" ++.Fa "off_t off" ++.Fc + .Sh DESCRIPTION + These functions allocate and free memory for the calling process. + They are described in the + individual manual pages. ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Pp ++.Ft void * ++.br ++.Fo mmap ++.Fa "void * addr" ++.Fa "size_t len" ++.Fa "int prot" ++.Fa "int flags" ++.Fa "int fildes" ++.Fa "off_t off" ++.Fc ; ++.Pp ++The include file ++.In sys/types.h ++is needed for this function. ++.Sh COMPATIBILITY ++.Fn mmap ++now returns with ++.Va errno ++set to EINVAL in places that historically succeeded. ++The rules have changed as follows: ++.Bl -bullet ++.It ++The ++.Fa flags ++parameter must specify either MAP_PRIVATE or MAP_SHARED. ++.It ++The ++.Fa size ++parameter must not be 0. ++.It ++The ++.Fa off ++parameter must be a multiple of pagesize, ++as returned by ++.Fn sysconf . ++.El + .Sh SEE ALSO + .Xr mmap 2 , + .Xr alloca 3 , + .Xr calloc 3 , + .Xr free 3 , + .Xr malloc 3 , +-.Xr realloc 3 ++.Xr realloc 3 , ++.Xr compat 5 + .Sh STANDARDS + These functions, with the exception of + .Fn alloca diff --git a/stdlib/FreeBSD/putenv.c.patch b/stdlib/FreeBSD/putenv.c.patch index 87a2de4..36017bc 100644 --- a/stdlib/FreeBSD/putenv.c.patch +++ b/stdlib/FreeBSD/putenv.c.patch @@ -1,32 +1,79 @@ ---- putenv.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ putenv.c 2004-10-24 01:10:20.000000000 -0700 -@@ -40,10 +40,22 @@ +--- 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 @@ + #include #include - -+#if __DARWIN_UNIX03 ++#include ++#include ++#include ++#include +#include -+__private_extern__ int __setenv(const char *, const char *, int, int); -+#endif /* __DARWIN_UNIX03 */ + ++extern malloc_zone_t *__zone0; ++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 ++/* ++ * _putenvp -- SPI using an arbitrary pointer to string array (the array must ++ * 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) +-putenv(str) - const char *str; -+ char *str; ++_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); ++ if (!__zone0) { ++ errno = ENOMEM; ++ return (-1); ++ } ++ } ++ return (__setenv(str, NULL, 1, 0, envp, (state ? (malloc_zone_t *)state : __zone0))); ++} ++#endif /* BUILDING_VARIANT */ + +- if ((p = strdup(str)) == NULL) ++int ++putenv(str) ++ char *str; ++{ +#if __DARWIN_UNIX03 + if (str == NULL || *str == 0 || index(str, '=') == NULL) { + errno = EINVAL; -+ return (-1); + return (-1); +- if ((equal = index(p, '=')) == NULL) { +- (void)free(p); + } -+ return (__setenv(str, NULL, 1, 0)); +#else /* !__DARWIN_UNIX03 */ - char *p, *equal; - int rval; - -@@ -57,4 +69,5 @@ - rval = setenv(p, equal + 1, 1); - (void)free(p); - return (rval); ++ if (index(str, '=') == NULL) + return (-1); ++#endif /* __DARWIN_UNIX03 */ ++ /* insure __zone0 is set up before calling __malloc_check_env_name */ ++ if (!__zone0) { ++ __zone0 = malloc_create_zone(0, 0); ++ if (!__zone0) { ++ errno = ENOMEM; ++ return (-1); ++ } + } +- *equal = '\0'; +- rval = setenv(p, equal + 1, 1); +- (void)free(p); +- return (rval); ++ __malloc_check_env_name(str); /* see if we are changing a malloc environment variable */ ++ return (__setenv(str, NULL, 1, ++#if __DARWIN_UNIX03 ++ 0, ++#else /* !__DARWIN_UNIX03 */ ++ -1, +#endif /* __DARWIN_UNIX03 */ ++ _NSGetEnviron(), __zone0)); } diff --git a/stdlib/FreeBSD/qsort.3.patch b/stdlib/FreeBSD/qsort.3.patch new file mode 100644 index 0000000..7717406 --- /dev/null +++ b/stdlib/FreeBSD/qsort.3.patch @@ -0,0 +1,141 @@ +--- _SB/Libc/stdlib/FreeBSD/qsort.3 2004-11-25 11:38:42.000000000 -0800 ++++ _SB/Libc/stdlib/FreeBSD/qsort.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -40,41 +40,44 @@ + .Dt QSORT 3 + .Os + .Sh NAME +-.Nm qsort , qsort_r , heapsort , mergesort ++.Nm heapsort , ++.Nm mergesort , ++.Nm qsort , ++.Nm qsort_r + .Nd sort functions + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In stdlib.h ++.Ft int ++.Fo heapsort ++.Fa "void *base" ++.Fa "size_t nel" ++.Fa "size_t width" ++.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" ++.Fc ++.Ft int ++.Fo mergesort ++.Fa "void *base" ++.Fa "size_t nel" ++.Fa "size_t width" ++.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" ++.Fc + .Ft void + .Fo qsort + .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]" + .Fc + .Ft void + .Fo qsort_r + .Fa "void *base" +-.Fa "size_t nmemb" +-.Fa "size_t size" ++.Fa "size_t nel" ++.Fa "size_t width" + .Fa "void *thunk" + .Fa "int \*[lp]*compar\*[rp]\*[lp]void *, const void *, const void *\*[rp]" + .Fc +-.Ft int +-.Fo heapsort +-.Fa "void *base" +-.Fa "size_t nmemb" +-.Fa "size_t size" +-.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" +-.Fc +-.Ft int +-.Fo mergesort +-.Fa "void *base" +-.Fa "size_t nmemb" +-.Fa "size_t size" +-.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" +-.Fc + .Sh DESCRIPTION + The + .Fn qsort +@@ -84,7 +87,7 @@ + function is a modified selection sort. + The + .Fn mergesort +-function is a modified merge sort with exponential search ++function is a modified merge sort with exponential search, + intended for sorting data with pre-existing order. + .Pp + The +@@ -92,18 +95,18 @@ + and + .Fn heapsort + functions sort an array of +-.Fa nmemb ++.Fa nel + objects, the initial member of which is pointed to by + .Fa base . + The size of each object is specified by +-.Fa size . ++.Fa width . + The + .Fn mergesort + function + behaves similarly, but + .Em requires + that +-.Fa size ++.Fa width + be greater than + .Dq "sizeof(void *) / 2" . + .Pp +@@ -139,7 +142,7 @@ + .Fn heapsort + are + .Em not +-stable, that is, if two members compare as equal, their order in ++stable; that is, if two members compare as equal, their order in + the sorted array is undefined. + The + .Fn mergesort +@@ -183,8 +186,8 @@ + The function + .Fn mergesort + requires additional memory of size +-.Fa nmemb * +-.Fa size ++.Fa nel * ++.Fa width + bytes; it should be used only when space is not at a premium. + The + .Fn mergesort +@@ -195,8 +198,8 @@ + Normally, + .Fn qsort + is faster than +-.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 + untrue. +@@ -218,10 +221,10 @@ + .Bl -tag -width Er + .It Bq Er EINVAL + The +-.Fa size ++.Fa width + argument is zero, or, + the +-.Fa size ++.Fa width + argument to + .Fn mergesort + is less than diff --git a/stdlib/FreeBSD/rand.3.patch b/stdlib/FreeBSD/rand.3.patch new file mode 100644 index 0000000..6286a4b --- /dev/null +++ b/stdlib/FreeBSD/rand.3.patch @@ -0,0 +1,59 @@ +--- _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 @@ + .Os + .Sh NAME + .Nm rand , ++.Nm rand_r , + .Nm srand , +-.Nm sranddev , +-.Nm rand_r ++.Nm sranddev + .Nd bad random number generator + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In stdlib.h +-.Ft void +-.Fn srand "unsigned seed" +-.Ft void +-.Fn sranddev void + .Ft int +-.Fn rand void ++.Fo rand ++.Fa void ++.Fc + .Ft int +-.Fn rand_r "unsigned *ctx" ++.Fo rand_r ++.Fa "unsigned *seed" ++.Fc ++.Ft void ++.Fo srand ++.Fa "unsigned seed" ++.Fc ++.Ft void ++.Fo sranddev ++.Fa void ++.Fc + .Sh DESCRIPTION + .Bf -symbolic + These interfaces are obsoleted by +@@ -89,7 +97,7 @@ + .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 @@ + provides the same functionality as + .Fn rand . + A pointer to the context value +-.Fa ctx ++.Fa seed + must be supplied by the caller. + .Sh SEE ALSO + .Xr random 3 , diff --git a/stdlib/FreeBSD/random.3.patch b/stdlib/FreeBSD/random.3.patch new file mode 100644 index 0000000..398385b --- /dev/null +++ b/stdlib/FreeBSD/random.3.patch @@ -0,0 +1,134 @@ +--- 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 @@ + .Dt RANDOM 3 + .Os + .Sh NAME ++.Nm initstate , + .Nm random , ++.Nm setstate , + .Nm srandom , +-.Nm srandomdev , +-.Nm initstate , +-.Nm setstate ++.Nm srandomdev + .Nd better random number generator; routines for changing generators + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In stdlib.h ++.Ft char * ++.Fo initstate ++.Fa "unsigned seed" ++.Fa "char *state" ++.Fa "size_t size" ++.Fc + .Ft long +-.Fn random void ++.Fo random ++.Fa void ++.Fc ++.Ft char * ++.Fo setstate ++.Fa "const char *state" ++.Fc + .Ft void +-.Fn srandom "unsigned long seed" ++.Fo srandom ++.Fa "unsigned seed" ++.Fc + .Ft void +-.Fn srandomdev void +-.Ft char * +-.Fn initstate "unsigned long seed" "char *state" "long n" +-.Ft char * +-.Fn setstate "char *state" ++.Fo srandomdev ++.Fa void ++.Fc + .Sh DESCRIPTION + The + .Fn random + function +-uses a non-linear additive feedback random number generator employing a +-default table of size 31 long integers to return successive pseudo-random ++uses a non-linear, additive feedback, random number generator, employing a ++default table of size 31 long integers. ++It returns successive pseudo-random + numbers in the range from 0 to + .if t 2\u\s731\s10\d\(mi1. + .if n (2**31)\(mi1. +@@ -82,7 +95,7 @@ + .Xr rand 3 + produces a much less random sequence \(em in fact, the low dozen bits + generated by rand go through a cyclic pattern. +-All the bits generated by ++All of the bits generated by + .Fn random + are usable. + For example, +@@ -102,7 +115,7 @@ + .Pp + The + .Fn srandomdev +-routine initializes a state array using the ++routine initializes a state array, using the + .Xr random 4 + random number device which returns good random numbers, + suitable for cryptographic use. +@@ -127,7 +140,7 @@ + the nearest known amount. + Using less than 8 bytes will cause an error.) + The seed for the initialization (which specifies a starting point for +-the random number sequence, and provides for restarting at the same ++the random number sequence and provides for restarting at the same + point) is also an argument. + The + .Fn initstate +@@ -166,7 +179,7 @@ + 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 @@ + .Fn setstate + detects that the state information has been garbled, error + messages are printed on the standard error output. ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Pp ++.Ft char * ++.br ++.Fo initstate ++.Fa "unsigned long seed" ++.Fa "char *state" ++.Fa "long size" ++.Fc ; ++.Pp ++.Ft char * ++.br ++.Fo setstate ++.Fa "char *state" ++.Fc ; ++.Pp ++.Ft void ++.br ++.Fo srandom ++.Fa "unsigned long seed" ++.Fc ; ++.Pp ++The type of each parameter is different in the legacy version. + .Sh SEE ALSO + .Xr arc4random 3 , + .Xr rand 3 , + .Xr srand 3 , +-.Xr random 4 ++.Xr random 4 , ++.Xr compat 5 + .Sh HISTORY + These + functions appeared in diff --git a/stdlib/FreeBSD/random.c.patch b/stdlib/FreeBSD/random.c.patch index ee1439a..2770cd5 100644 --- a/stdlib/FreeBSD/random.c.patch +++ b/stdlib/FreeBSD/random.c.patch @@ -1,5 +1,5 @@ ---- random.c.orig 2004-12-01 20:08:48.000000000 -0800 -+++ random.c 2004-12-01 20:12:11.000000000 -0800 +--- 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 @@ #include __FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.24 2004/01/20 03:02:18 das Exp $"); diff --git a/stdlib/FreeBSD/realpath.3.patch b/stdlib/FreeBSD/realpath.3.patch new file mode 100644 index 0000000..05f5c5d --- /dev/null +++ b/stdlib/FreeBSD/realpath.3.patch @@ -0,0 +1,107 @@ +--- realpath.3 2003-05-20 15:23:25.000000000 -0700 ++++ realpath.3.edit 2006-09-06 15:43:17.000000000 -0700 +@@ -44,26 +44,28 @@ + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS +-.In sys/param.h + .In stdlib.h + .Ft "char *" +-.Fn realpath "const char *pathname" "char resolved_path[PATH_MAX]" ++.Fo realpath ++.Fa "const char *restrict file_name" ++.Fa "char *restrict resolved_name" ++.Fc + .Sh DESCRIPTION + The + .Fn realpath + function resolves all symbolic links, extra + .Dq / +-characters and references to ++characters, and references to + .Pa /./ + and + .Pa /../ + in +-.Fa pathname , ++.Fa file_name , + and copies the resulting absolute pathname into + the memory referenced by +-.Fa resolved_path . ++.Fa resolved_name . + The +-.Fa resolved_path ++.Fa resolved_name + argument + .Em must + refer to a buffer capable of storing at least +@@ -74,9 +76,9 @@ + .Fn realpath + function will resolve both absolute and relative paths + and return the absolute pathname corresponding to +-.Fa pathname . +-All but the last component of +-.Fa pathname ++.Fa file_name . ++All components of ++.Fa file_name + must exist when + .Fn realpath + is called. +@@ -84,14 +86,14 @@ + The + .Fn realpath + function returns +-.Fa resolved_path ++.Fa resolved_name + on success. + If an error occurs, + .Fn realpath + returns +-.Dv NULL , ++.Dv NULL + and +-.Fa resolved_path ++.Fa resolved_name + contains the pathname which caused the problem. + .Sh ERRORS + The function +@@ -100,7 +102,7 @@ + .Va errno + for any of the errors specified for the library functions + .Xr lstat 2 , +-.Xr readlink 2 ++.Xr readlink 2 , + and + .Xr getcwd 3 . + .Sh CAVEATS +@@ -112,11 +114,26 @@ + version always returns absolute pathnames, + whereas the Solaris implementation will, + under certain circumstances, return a relative +-.Fa resolved_path ++.Fa resolved_name + when given a relative +-.Fa pathname . ++.Fa file_name . ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Pp ++The include file ++.In sys/param.h ++is necessary. ++.Sh LEGACY DESCRIPTION ++In legacy mode, ++the last component of ++.Fa file_name ++does not need to exist when ++.Fn realpath ++is called. + .Sh "SEE ALSO" +-.Xr getcwd 3 ++.Xr getcwd 3 , ++.Xr compat 5 + .Sh HISTORY + The + .Fn realpath diff --git a/stdlib/FreeBSD/realpath.c.patch b/stdlib/FreeBSD/realpath.c.patch index dd06685..addb8e7 100644 --- a/stdlib/FreeBSD/realpath.c.patch +++ b/stdlib/FreeBSD/realpath.c.patch @@ -1,6 +1,6 @@ ---- realpath.c.orig 2003-08-15 19:22:17.000000000 -0700 -+++ realpath.c 2004-12-04 14:47:52.000000000 -0800 -@@ -35,13 +35,35 @@ +--- realpath.c.orig 2006-09-16 19:12:28.000000000 -0700 ++++ realpath.c 2006-09-16 20:18:25.000000000 -0700 +@@ -35,13 +35,41 @@ #include "namespace.h" #include #include @@ -23,7 +23,8 @@ + char buf[PATH_MAX]; +}; + -+static struct attrlist alist = { ++#ifndef BUILDING_VARIANT ++__private_extern__ struct attrlist _rp_alist = { + ATTR_BIT_MAP_COUNT, + 0, + ATTR_CMN_NAME | ATTR_CMN_DEVID | ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID, @@ -32,11 +33,16 @@ + 0, + 0, +}; ++#else /* BUILDING_VARIANT */ ++__private_extern__ struct attrlist _rp_alist; ++#endif /* BUILDING_VARIANT */ ++ ++extern char * __private_getcwd(char *, size_t, int); + /* * char *realpath(const char *path, char resolved[PATH_MAX]); * -@@ -52,13 +74,25 @@ +@@ -52,24 +80,55 @@ char * realpath(const char *path, char resolved[PATH_MAX]) { @@ -55,29 +61,62 @@ + static int rootdev_inited = 0; + ino_t inode; ++ if (path == NULL) { ++ errno = EINVAL; ++ return (NULL); ++ } ++#if __DARWIN_UNIX03 ++ if (*path == 0) { ++ errno = ENOENT; ++ return (NULL); ++ } ++#endif /* __DARWIN_UNIX03 */ + if (!rootdev_inited) { + rootdev_inited = 1; -+ if (stat("/", &sb) < 0) ++ if (stat("/", &sb) < 0) { + return (NULL); ++ } + rootdev = sb.st_dev; + } serrno = errno; symlinks = 0; if (path[0] == '/') { -@@ -80,6 +114,12 @@ + resolved[0] = '/'; + resolved[1] = '\0'; +- if (path[1] == '\0') ++ if (path[1] == '\0') { + return (resolved); ++ } + resolved_len = 1; + left_len = strlcpy(left, path + 1, sizeof(left)); + } else { +- if (getcwd(resolved, PATH_MAX) == NULL) { ++#if !defined(VARIANT_DARWINEXTSN) && __DARWIN_UNIX03 ++ /* 4447159: don't use GETPATH, so this will fail if */ ++ /* if parent directories are not readable, as per POSIX */ ++ if (__private_getcwd(resolved, PATH_MAX, 0) == NULL) ++#else /* VARIANT_DARWINEXTSN || !__DARWIN_UNIX03 */ ++ if (__private_getcwd(resolved, PATH_MAX, 1) == NULL) ++#endif /* !VARIANT_DARWINEXTSN && __DARWIN_UNIX03 */ ++ { + strlcpy(resolved, ".", PATH_MAX); + return (NULL); + } +@@ -80,6 +139,13 @@ errno = ENAMETOOLONG; return (NULL); } + if (resolved_len > 1) { -+ if (stat(resolved, &sb) < 0) ++ if (stat(resolved, &sb) < 0) { + return (NULL); ++ } + lastdev = sb.st_dev; + } else + lastdev = rootdev; /* * Iterate over path components in `left'. -@@ -127,6 +167,13 @@ +@@ -127,6 +193,13 @@ } /* @@ -91,17 +130,17 @@ * 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,14 +183,72 @@ +@@ -136,25 +209,87 @@ errno = ENAMETOOLONG; return (NULL); } - if (lstat(resolved, &sb) != 0) { -+ if (getattrlist(resolved, &alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) { ++ if (getattrlist(resolved, &_rp_alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) { + useattrs = 1; + islink = (attrs.type == VLNK); + dev = attrs.dev; + inode = attrs.id.fid_objno; -+ } else if (errno == EOPNOTSUPP || errno == EINVAL) { ++ } else if (errno == ENOTSUP || errno == EINVAL) { + if ((useattrs = lstat(resolved, &sb)) == 0) { + islink = S_ISLNK(sb.st_mode); + dev = sb.st_dev; @@ -110,10 +149,12 @@ + } else + useattrs = -1; + if (useattrs < 0) { ++#if !__DARWIN_UNIX03 if (errno == ENOENT && p == NULL) { errno = serrno; return (resolved); } ++#endif /* !__DARWIN_UNIX03 */ return (NULL); } - if (S_ISLNK(sb.st_mode)) { @@ -166,7 +207,13 @@ if (symlinks++ > MAXSYMLINKS) { errno = ELOOP; return (NULL); -@@ -155,6 +260,7 @@ + } + slen = readlink(resolved, symlink, sizeof(symlink) - 1); +- if (slen < 0) ++ if (slen < 0) { + return (NULL); ++ } + symlink[slen] = '\0'; if (symlink[0] == '/') { resolved[1] = 0; resolved_len = 1; @@ -174,7 +221,7 @@ } else if (resolved_len > 1) { /* Strip the last path component. */ resolved[resolved_len - 1] = '\0'; -@@ -184,7 +290,30 @@ +@@ -184,7 +319,30 @@ } } left_len = strlcpy(left, symlink, sizeof(left)); diff --git a/stdlib/FreeBSD/setenv.c.patch b/stdlib/FreeBSD/setenv.c.patch index 0d45076..64a5a94 100644 --- a/stdlib/FreeBSD/setenv.c.patch +++ b/stdlib/FreeBSD/setenv.c.patch @@ -1,33 +1,48 @@ ---- setenv.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ setenv.c 2004-11-05 17:15:11.000000000 -0800 -@@ -40,81 +40,137 @@ +--- setenv.c.orig 2006-12-12 18:14:46.000000000 -0800 ++++ setenv.c 2006-12-12 18:22:12.000000000 -0800 +@@ -40,32 +40,60 @@ #include #include #include +#include +#include ++#include ++#include ++#include - char *__findenv(const char *, int *); -+__private_extern__ int __setenv(const char *, const char *, int, int); +-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 + /* - * setenv -- - * Set the value of the environmental variable "name" to be - * "value". If rewrite is set, replace any current value. -- */ ++ * The copy flag may have 3 values: ++ * 1 - make a copy of the name/value pair ++ * 0 - take the name as a user-supplied name=value string ++ * -1 - like 0, except we copy of the name=value string in name + */ -int -setenv(name, value, rewrite) -+#ifndef BUILDING_VARIANT +__private_extern__ int -+__setenv(name, value, rewrite, copy) ++__setenv(name, value, rewrite, copy, environp, envz) const char *name; const char *value; - int rewrite; + int rewrite, copy; ++ char ***environp; ++ malloc_zone_t *envz; { - extern char **environ; -+ char ***environp = _NSGetEnviron(); - static char **alloced; /* if allocated space before */ +- static char **alloced; /* if allocated space before */ char *c; - int l_value, offset; + int offset; @@ -35,17 +50,33 @@ - if (*value == '=') /* no `=' in value */ - ++value; - l_value = strlen(value); - if ((c = __findenv(name, &offset))) { /* find if already exists */ +- if ((c = __findenv(name, &offset))) { /* find if already exists */ ++ if ((c = __findenv(name, &offset, *environp))) { /* find if already exists */ ++ char *e; if (!rewrite) return (0); - if (strlen(c) >= l_value) { /* old larger; copy over */ -- while ( (*c++ = *value++) ); -- return (0); -- } -+ /* In UNIX03, we can't overwrite even if the string is long -+ * enough, because the putenv() string is owned by the user -+ * (ie, always malloc() a new string) */ - } else { /* create new slot */ ++ /* ++ * In UNIX03, we can overwrite only if we allocated the ++ * string. Then we can realloc it if it is too small. ++ */ ++ e = (*environp)[offset]; ++ if (copy > 0 && ZONE_OWNS_PTR(envz, e)) { ++ size_t l_value = strlen(value); ++ if (strlen(c) < l_value) { /* old smaller; resize*/ ++ char *r; ++ size_t len = c - e; ++ if ((r = realloc(e, l_value + len + 1)) == NULL) ++ return (-1); ++ if (r != e) { ++ (*environp)[offset] = r; ++ c = r + len; ++ } ++ } + while ( (*c++ = *value++) ); + return (0); + } +@@ -73,48 +101,250 @@ int cnt; char **p; @@ -53,23 +84,24 @@ - if (alloced == environ) { /* just increase size */ - p = (char **)realloc((char *)environ, + for (p = *environp, cnt = 0; *p; ++p, ++cnt); -+ if (alloced == *environp) { /* just increase size */ ++ if (ZONE_OWNS_PTR(envz, *environp)) { /* just increase size */ + p = (char **)realloc((char *)*environp, (size_t)(sizeof(char *) * (cnt + 2))); if (!p) return (-1); - alloced = environ = p; -+ alloced = *environp = p; ++ *environp = p; } else { /* get new space */ /* copy old entries into it */ - p = malloc((size_t)(sizeof(char *) * (cnt + 2))); +- p = malloc((size_t)(sizeof(char *) * (cnt + 2))); ++ p = malloc_zone_malloc(envz, (size_t)(sizeof(char *) * (cnt + 2))); if (!p) return (-1); - bcopy(environ, p, cnt * sizeof(char *)); - alloced = environ = p; + bcopy(*environp, p, cnt * sizeof(char *)); -+ alloced = *environp = p; ++ *environp = p; } - environ[cnt + 1] = NULL; + (*environp)[cnt + 1] = NULL; @@ -84,17 +116,141 @@ + /* For non Unix03, or UnixO3 setenv(), we make a copy of the user's + * strings. For Unix03 putenv(), we put the string directly in + * the environment. */ -+ if (copy) { ++ if (copy > 0) { + for (c = (char *)name; *c && *c != '='; ++c); /* no `=' in name */ + if (!((*environp)[offset] = /* name + `=' + value */ -+ malloc((size_t)((int)(c - name) + strlen(value) + 2)))) ++ malloc_zone_malloc(envz, (size_t)((int)(c - name) + strlen(value) + 2)))) + return (-1); + for (c = (*environp)[offset]; (*c = *name++) && *c != '='; ++c); + for (*c++ = '='; (*c++ = *value++); ); -+ } else -+ (*environp)[offset] = name; ++ } else { ++ /* the legacy behavior copies the string */ ++ if (copy < 0) { ++ size_t len = strlen(name); ++ if((c = malloc_zone_malloc(envz, len + 1)) == NULL) ++ return (-1); ++ memcpy(c, name, len + 1); ++ name = c; ++ } ++ /* if we malloc-ed the previous value, free it first */ ++ if ((*environp)[offset] != NULL && ZONE_OWNS_PTR(envz, (*environp)[offset])) ++ free((*environp)[offset]); ++ (*environp)[offset] = (char *)name; ++ } return (0); } + ++__private_extern__ void ++__unsetenv(const char *name, char **environ, malloc_zone_t *envz) ++{ ++ char **p; ++ int offset; ++ ++ while (__findenv(name, &offset, environ)) { /* if set multiple times */ ++ /* if we malloc-ed it, free it first */ ++ if (ZONE_OWNS_PTR(envz, environ[offset])) ++ free(environ[offset]); ++ for (p = &environ[offset];; ++p) ++ if (!(*p = *(p + 1))) ++ break; ++ } ++} ++ ++/****************************************************************************/ ++/* ++ * _allocenvstate -- SPI that creates a new state (opaque) ++ */ ++void * ++_allocenvstate(void) ++{ ++ return (void *)malloc_create_zone(1000 /* unused */, 0 /* unused */); ++} ++ ++/* ++ * _copyenv -- SPI that copies a NULL-tereminated char * array in a newly ++ * allocated buffer, compatible with the other SPI env routines. If env ++ * is NULL, a char * array composed of a single NULL is returned. NULL ++ * is returned on error. (This isn't needed anymore, as __setenv will ++ * automatically make a copy in the zone.) ++ */ ++char ** ++_copyenv(char **env) ++{ ++ char **p; ++ int cnt = 1; ++ ++ if (env) ++ for (p = env; *p; ++p, ++cnt); ++ p = (char **)malloc((size_t)(sizeof(char *) * cnt)); ++ if (!p) ++ return (NULL); ++ if (env) ++ bcopy(env, p, cnt * sizeof(char *)); ++ else ++ *p = NULL; ++ return p; ++} ++ ++/* ++ * _deallocenvstate -- SPI that frees all the memory associated with the state ++ * and all allocated strings, including the environment array itself if it ++ * was copied. ++ */ ++int ++_deallocenvstate(void *state) ++{ ++ malloc_zone_t *envz; ++ ++ if (!(envz = (malloc_zone_t *)state) || envz == __zone0) { ++ errno = EINVAL; ++ return -1; ++ } ++ malloc_destroy_zone(envz); ++ return 0; ++} ++ ++/* ++ * setenvp -- SPI using an arbitrary pointer to string array and an env state, ++ * created by _allocenvstate(). Initial checking is not done. ++ * ++ * Set the value of the environmental variable "name" to be ++ * "value". If rewrite is set, replace any current value. ++ */ ++int ++_setenvp(const char *name, const char *value, int rewrite, char ***envp, void *state) ++{ ++ /* insure __zone0 is set up */ ++ if (!__zone0) { ++ __zone0 = malloc_create_zone(0, 0); ++ if (!__zone0) { ++ errno = ENOMEM; ++ return (-1); ++ } ++ } ++ return (__setenv(name, value, rewrite, 1, envp, (state ? (malloc_zone_t *)state : __zone0))); ++} ++ ++/* ++ * unsetenv(name) -- SPI using an arbitrary pointer to string array and an env ++ * state, created by _allocenvstate(). Initial checking is not done. ++ * ++ * Delete environmental variable "name". ++ */ ++int ++_unsetenvp(const char *name, char ***envp, void *state) ++{ ++ /* insure __zone0 is set up */ ++ if (!__zone0) { ++ __zone0 = malloc_create_zone(0, 0); ++ if (!__zone0) { ++ errno = ENOMEM; ++ return (-1); ++ } ++ } ++ __unsetenv(name, *envp, (state ? (malloc_zone_t *)state : __zone0)); ++ return 0; ++} ++ +#endif /* !BUILD_VARIANT */ + +/* @@ -124,9 +280,18 @@ + + if (*value == '=') /* no `=' in value */ + ++value; -+ return (__setenv(name, value, rewrite, 1)); ++ /* insure __zone0 is set up before calling __malloc_check_env_name */ ++ if (!__zone0) { ++ __zone0 = malloc_create_zone(0, 0); ++ if (!__zone0) { ++ errno = ENOMEM; ++ return (-1); ++ } ++ } ++ __malloc_check_env_name(name); /* see if we are changing a malloc environment variable */ ++ return (__setenv(name, value, rewrite, 1, _NSGetEnviron(), __zone0)); +} - ++ /* * unsetenv(name) -- * Delete environmental variable "name". @@ -140,31 +305,45 @@ const char *name; { - extern char **environ; -+ char **environ = *_NSGetEnviron(); - char **p; - int offset; - +- char **p; +- int offset; +#if __DARWIN_UNIX03 + /* no null ptr or empty str */ + if(name == NULL || *name == 0) { + errno = EINVAL; + return (-1); + } -+ + +- while (__findenv(name, &offset)) /* if set multiple times */ +- for (p = &environ[offset];; ++p) +- if (!(*p = *(p + 1))) +- break; + /* no '=' in name */ + if (strchr(name, '=')) { + errno = EINVAL; + return (-1); + } ++ /* insure __zone0 is set up before calling __malloc_check_env_name */ ++ if (!__zone0) { ++ __zone0 = malloc_create_zone(0, 0); ++ if (!__zone0) { ++ errno = ENOMEM; ++ return (-1); ++ } ++ } +#else /* !__DARWIN_UNIX03 */ + /* no null ptr or empty str */ + if(name == NULL || *name == 0) + return; ++ /* insure __zone0 is set up before calling __malloc_check_env_name */ ++ if (!__zone0) { ++ __zone0 = malloc_create_zone(0, 0); ++ if (!__zone0) ++ return; ++ } +#endif /* __DARWIN_UNIX03 */ - while (__findenv(name, &offset)) /* if set multiple times */ - for (p = &environ[offset];; ++p) - if (!(*p = *(p + 1))) - break; ++ __malloc_check_env_name(name); /* see if we are changing a malloc environment variable */ ++ __unsetenv(name, *_NSGetEnviron(), __zone0); +#if __DARWIN_UNIX03 + return 0; +#endif /* __DARWIN_UNIX03 */ diff --git a/stdlib/FreeBSD/strfmon.3.patch b/stdlib/FreeBSD/strfmon.3.patch index 4cc0f91..8dbaa10 100644 --- a/stdlib/FreeBSD/strfmon.3.patch +++ b/stdlib/FreeBSD/strfmon.3.patch @@ -1,6 +1,6 @@ ---- strfmon.3.orig Fri Mar 11 10:06:33 2005 -+++ strfmon.3 Fri Mar 11 10:20:51 2005 -@@ -28,14 +28,18 @@ +--- _SB/Libc/stdlib/FreeBSD/strfmon.3 2003-05-20 15:23:25.000000000 -0700 ++++ _SB/Libc/stdlib/FreeBSD/strfmon.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -28,25 +28,49 @@ .Dt STRFMON 3 .Os .Sh NAME @@ -14,14 +14,31 @@ .In monetary.h .Ft ssize_t -.Fn strfmon "char * restrict s" "size_t maxsize" "const char * restrict format" "..." -+.Fn strfmon "char * s" "size_t maxsize" "const char *format" "..." ++.Fo strfmon ++.Fa "char *restrict s" ++.Fa "size_t maxsize" ++.Fa "const char *restrict format" ++.Fa "..." ++.Fc ++.In monetary.h +.In xlocale.h +.Ft ssize_t -+.Fn strfmon_l "char * s" "size_t maxsize" "locale_t loc" "const char *format" "..." ++.Fo strfmon_l ++.Fa "char *restrict s" ++.Fa "size_t maxsize" ++.Fa "locale_t loc" ++.Fa "const char *restrict format" ++.Fa "..." ++.Fc .Sh DESCRIPTION The .Fn strfmon -@@ -47,6 +51,14 @@ + function places characters into the array pointed to by +-.Fa s ++.Fa s , + as controlled by the string pointed to by + .Fa format . + No more than .Fa maxsize bytes are placed into the array. .Pp @@ -36,7 +53,19 @@ The format string is composed of zero or more directives: ordinary characters (not .Cm % ) , -@@ -142,7 +154,8 @@ +@@ -114,9 +138,9 @@ + .El + .El + .Sh RETURN VALUES +-If the total number of resulting bytes including the terminating ++If the total number of resulting bytes, including the terminating + .Dv NULL +-byte is not more than ++byte, is not more than + .Fa maxsize , + .Fn strfmon + returns the number of bytes placed into the array pointed to by +@@ -142,7 +166,8 @@ Not enough memory for temporary buffers. .El .Sh SEE ALSO diff --git a/stdlib/FreeBSD/strfmon.c.patch b/stdlib/FreeBSD/strfmon.c.patch index ca2f374..9ff3b5d 100644 --- a/stdlib/FreeBSD/strfmon.c.patch +++ b/stdlib/FreeBSD/strfmon.c.patch @@ -1,5 +1,5 @@ --- strfmon.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ strfmon.c 2005-02-27 11:52:19.000000000 -0800 ++++ strfmon.c 2005-04-27 23:34:08.000000000 -0700 @@ -28,6 +28,8 @@ #include __FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.14 2003/03/20 08:18:55 ache Exp $"); @@ -87,7 +87,19 @@ } /* Conversion Characters */ -@@ -239,21 +238,21 @@ +@@ -219,8 +218,10 @@ + + if (flags & USE_INTL_CURRENCY) { + currency_symbol = strdup(lc->int_curr_symbol); +- if (currency_symbol != NULL) ++ if (currency_symbol != NULL) { + space_char = *(currency_symbol+3); ++ currency_symbol[3] = '\0'; ++ } + } else + currency_symbol = strdup(lc->currency_symbol); + +@@ -239,21 +240,21 @@ /* fill left_prec with amount of padding chars */ if (left_prec >= 0) { pad_size = __calc_left_pad((flags ^ IS_NEGATIVE), @@ -113,7 +125,35 @@ /* * Description of some LC_MONETARY's values: -@@ -366,7 +365,6 @@ +@@ -313,8 +314,11 @@ + } else if (sep_by_space == 1) + PRINT(space_char); + } +- } else if (sign_posn == 1) ++ } else if (sign_posn == 1) { + PRINTS(signstr); ++ if (sep_by_space == 2) ++ PRINT(' '); ++ } + + PRINTS(asciivalue); + +@@ -348,8 +352,12 @@ + PRINTS(signstr); + } + +- if (sign_posn == 0 && (flags & IS_NEGATIVE)) +- PRINT(')'); ++ if (sign_posn == 0) { ++ if (flags & IS_NEGATIVE) ++ PRINT(')'); ++ else if (left_prec >= 0) ++ PRINT(' '); ++ } + + if (dst - tmpptr < width) { + if (flags & LEFT_JUSTIFY) { +@@ -366,7 +374,6 @@ } PRINT('\0'); @@ -121,7 +161,7 @@ free(asciivalue); free(currency_symbol); return (dst - s - 1); /* return size of put data except trailing '\0' */ -@@ -385,15 +383,12 @@ +@@ -385,15 +392,12 @@ if (currency_symbol != NULL) free(currency_symbol); errno = sverrno; @@ -138,7 +178,7 @@ if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) { *cs_precedes = lc->int_n_cs_precedes; -@@ -429,12 +424,12 @@ +@@ -429,12 +433,12 @@ } static int @@ -153,8 +193,23 @@ if (cs_precedes != 0) { left_chars += strlen(cur_symb); -@@ -480,7 +475,7 @@ +@@ -443,6 +447,10 @@ + } + + switch (sign_posn) { ++ case 0: ++ if (flags & IS_NEGATIVE) ++ left_chars++; ++ break; + case 1: + left_chars += strlen(signstr); + break; +@@ -478,9 +486,11 @@ + } + /* convert double to ASCII */ ++__private_extern__ const char *__fix_nogrouping(const char *); ++ static char * __format_grouped_double(double value, int *flags, - int left_prec, int right_prec, int pad_char) { @@ -162,7 +217,7 @@ char *rslt; char *avalue; -@@ -492,7 +487,6 @@ +@@ -492,14 +502,13 @@ int padded; @@ -170,7 +225,15 @@ char *grouping; char decimal_point; char thousands_sep; -@@ -526,9 +520,9 @@ + + int groups = 0; + +- grouping = lc->mon_grouping; ++ grouping = __fix_nogrouping(lc->mon_grouping); + decimal_point = *lc->mon_decimal_point; + if (decimal_point == '\0') + decimal_point = *lc->decimal_point; +@@ -526,9 +535,9 @@ left_prec += get_groups(left_prec, grouping); /* convert to string */ @@ -182,7 +245,7 @@ if (avalue_size < 0) return (NULL); -@@ -601,3 +595,30 @@ +@@ -601,3 +610,30 @@ free(avalue); return (rslt); } diff --git a/stdlib/FreeBSD/strtod.3.patch b/stdlib/FreeBSD/strtod.3.patch index 08f29f8..091602a 100644 --- a/stdlib/FreeBSD/strtod.3.patch +++ b/stdlib/FreeBSD/strtod.3.patch @@ -1,6 +1,55 @@ ---- strtod.3.orig Fri Mar 11 17:24:01 2005 -+++ strtod.3 Fri Mar 11 17:25:45 2005 -@@ -100,6 +100,12 @@ +--- 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 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft double +-.Fn strtod "const char * restrict nptr" "char ** restrict endptr" ++.Fo strtod ++.Fa "const char *restrict nptr" ++.Fa "char **restrict endptr" ++.Fc + .Ft float +-.Fn strtof "const char * restrict nptr" "char ** restrict endptr" ++.Fo strtof ++.Fa "const char *restrict nptr" ++.Fa "char **restrict endptr" ++.Fc + .Ft "long double" +-.Fn strtold "const char * restrict nptr" "char ** restrict endptr" ++.Fo strtold ++.Fa "const char *restrict nptr" ++.Fa "char **restrict endptr" ++.Fc + .Sh DESCRIPTION + These conversion + functions convert the initial portion of the string +@@ -66,16 +75,17 @@ + .Vt "long double" + representation, respectively. + .Pp +-The expected form of the string is an optional plus (``+'') or minus +-sign (``\-'') followed by either: ++The expected form of the string ++is an optional plus (``+'') or minus (``\-'') sign, ++followed by either: + .Bl -bullet + .It +-a decimal significand consisting of a sequence of decimal digits +-optionally containing a decimal-point character, or ++a decimal significand, consisting of a sequence of decimal digits ++(optionally containing a decimal-point character) or + .It +-a hexadecimal significand consisting of a ``0X'' or ``0x'' followed +-by a sequence of hexadecimal digits optionally containing a +-decimal-point character. ++a hexadecimal significand, consisting of a ``0X'' or ``0x'' followed ++by a sequence of hexadecimal digits ++(optionally containing a decimal-point character). + .El + .Pp + In both cases, the significand may be optionally followed by an +@@ -100,6 +110,12 @@ The decimal point character is defined in the program's locale (category .Dv LC_NUMERIC ) . @@ -13,13 +62,11 @@ .Sh RETURN VALUES The .Fn strtod , -@@ -146,7 +152,8 @@ +@@ -144,6 +160,7 @@ + .Xr atof 3 , + .Xr atoi 3 , .Xr atol 3 , ++.Xr strtod_l 3 , .Xr strtol 3 , .Xr strtoul 3 , --.Xr wcstod 3 -+.Xr wcstod 3 , -+.Xr strtod_l 3 - .Sh STANDARDS - The - .Fn strtod + .Xr wcstod 3 diff --git a/stdlib/FreeBSD/strtol.3 b/stdlib/FreeBSD/strtol.3 index 9f54054..aa92717 100644 --- a/stdlib/FreeBSD/strtol.3 +++ b/stdlib/FreeBSD/strtol.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtol.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/strtol.3,v 1.19 2002/10/10 04:31:57 tjr Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strtol.3,v 1.20 2005/01/22 18:02:58 ache Exp $ .\" .Dd November 28, 2001 .Dt STRTOL 3 @@ -173,7 +173,8 @@ 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). If an overflow or underflow occurs, .Va errno is set to @@ -193,7 +194,8 @@ to the following table. 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 diff --git a/stdlib/FreeBSD/strtol.3.patch b/stdlib/FreeBSD/strtol.3.patch index b5bf3c7..489f5e9 100644 --- a/stdlib/FreeBSD/strtol.3.patch +++ b/stdlib/FreeBSD/strtol.3.patch @@ -1,6 +1,109 @@ ---- strtol.3.orig Fri Mar 11 17:24:07 2005 -+++ strtol.3 Fri Mar 11 17:25:18 2005 -@@ -159,6 +159,12 @@ +--- 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 @@ + .Dt STRTOL 3 + .Os + .Sh NAME +-.Nm strtol , strtoll , strtoimax , strtoq ++.Nm strtoimax , ++.Nm strtol , ++.Nm strtoll , ++.Nm strtoq + .Nd "convert a string value to a" + .Vt long , "long long" , intmax_t + or +@@ -49,26 +52,41 @@ + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS ++.In inttypes.h ++.Ft intmax_t ++.Fo strtoimax ++.Fa "const char *restrict str" ++.Fa "char **restrict endptr" ++.Fa "int base" ++.Fc + .In stdlib.h +-.In limits.h + .Ft long +-.Fn strtol "const char * restrict nptr" "char ** restrict endptr" "int base" ++.Fo strtol ++.Fa "const char *restrict str" ++.Fa "char **restrict endptr" ++.Fa "int base" ++.Fc + .Ft long long +-.Fn strtoll "const char * restrict nptr" "char ** restrict endptr" "int base" +-.In inttypes.h +-.Ft intmax_t +-.Fn strtoimax "const char * restrict nptr" "char ** restrict endptr" "int base" ++.Fo strtoll ++.Fa "const char *restrict str" ++.Fa "char **restrict endptr" ++.Fa "int base" ++.Fc + .In sys/types.h + .In stdlib.h + .In limits.h + .Ft quad_t +-.Fn strtoq "const char *nptr" "char **endptr" "int base" ++.Fo strtoq ++.Fa "const char *str" ++.Fa "char **endptr" ++.Fa "int base" ++.Fc + .Sh DESCRIPTION + The + .Fn strtol + function + converts the string in +-.Fa nptr ++.Fa str + to a + .Vt long + value. +@@ -76,7 +94,7 @@ + .Fn strtoll + function + converts the string in +-.Fa nptr ++.Fa str + to a + .Vt "long long" + value. +@@ -84,7 +102,7 @@ + .Fn strtoimax + function + converts the string in +-.Fa nptr ++.Fa str + to an + .Vt intmax_t + value. +@@ -92,7 +110,7 @@ + .Fn strtoq + function + converts the string in +-.Fa nptr ++.Fa str + to a + .Vt quad_t + value. +@@ -147,11 +165,11 @@ + If there were no digits at all, however, + .Fn strtol + stores the original value of +-.Fa nptr ++.Fa str + in + .Fa *endptr . + (Thus, if +-.Fa *nptr ++.Fa *str + is not + .Ql \e0 + but +@@ -159,11 +177,17 @@ is .Ql \e0 on return, the entire string was valid.) @@ -13,13 +116,47 @@ .Sh RETURN VALUES The .Fn strtol , -@@ -203,7 +209,8 @@ + .Fn strtoll , +-.Fn strtoimax ++.Fn strtoimax , + and + .Fn strtoq + functions +@@ -181,8 +205,8 @@ + .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" ".Dv INTMAX_MIN" ".Dv INTMAX_MAX" ++.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 @@ + .It Bq Er ERANGE + The given string was out of range; the value converted has been clamped. + .El ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Pp ++.In limits.h ++is necessary for the ++.Fn strtol ++and ++.Fn strtoll ++functions. + .Sh SEE ALSO + .Xr atof 3 , + .Xr atoi 3 , .Xr atol 3 , .Xr strtod 3 , ++.Xr strtol_l 3 , .Xr strtoul 3 , -.Xr wcstol 3 +.Xr wcstol 3 , -+.Xr strtol_l 3 ++.Xr compat 5 .Sh STANDARDS The .Fn strtol diff --git a/stdlib/FreeBSD/strtoul.3.patch b/stdlib/FreeBSD/strtoul.3.patch index 2019dcd..f863d93 100644 --- a/stdlib/FreeBSD/strtoul.3.patch +++ b/stdlib/FreeBSD/strtoul.3.patch @@ -1,12 +1,125 @@ ---- strtoul.3.orig Fri Mar 11 10:46:00 2005 -+++ strtoul.3 Fri Mar 11 10:46:30 2005 -@@ -205,7 +205,8 @@ +--- 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 @@ + .Dt STRTOUL 3 + .Os + .Sh NAME +-.Nm strtoul , strtoull , strtoumax , strtouq ++.Nm strtoul , ++.Nm strtoull , ++.Nm strtoumax , ++.Nm strtouq + .Nd "convert a string to an" + .Vt "unsigned long" , "unsigned long long" , uintmax_t , + or +@@ -50,25 +53,40 @@ + .Lb libc + .Sh SYNOPSIS + .In stdlib.h +-.In limits.h + .Ft "unsigned long" +-.Fn strtoul "const char * restrict nptr" "char ** restrict endptr" "int base" ++.Fo strtoul ++.Fa "const char *restrict str" ++.Fa "char **restrict endptr" ++.Fa "int base" ++.Fc + .Ft "unsigned long long" +-.Fn strtoull "const char * restrict nptr" "char ** restrict endptr" "int base" ++.Fo strtoull ++.Fa "const char *restrict str" ++.Fa "char **restrict endptr" ++.Fa "int base" ++.Fc + .In inttypes.h + .Ft uintmax_t +-.Fn strtoumax "const char * restrict nptr" "char ** restrict endptr" "int base" ++.Fo strtoumax ++.Fa "const char *restrict str" ++.Fa "char **restrict endptr" ++.Fa "int base" ++.Fc + .In sys/types.h + .In stdlib.h + .In limits.h + .Ft u_quad_t +-.Fn strtouq "const char *nptr" "char **endptr" "int base" ++.Fo strtouq ++.Fa "const char *str" ++.Fa "char **endptr" ++.Fa "int base" ++.Fc + .Sh DESCRIPTION + The + .Fn strtoul + function + converts the string in +-.Fa nptr ++.Fa str + to an + .Vt "unsigned long" + value. +@@ -76,7 +94,7 @@ + .Fn strtoull + function + converts the string in +-.Fa nptr ++.Fa str + to an + .Vt "unsigned long long" + value. +@@ -84,7 +102,7 @@ + .Fn strtoumax + function + converts the string in +-.Fa nptr ++.Fa str + to an + .Vt uintmax_t + value. +@@ -92,7 +110,7 @@ + .Fn strtouq + function + converts the string in +-.Fa nptr ++.Fa str + to a + .Vt u_quad_t + value. +@@ -146,11 +164,11 @@ + If there were no digits at all, however, + .Fn strtoul + stores the original value of +-.Fa nptr ++.Fa str + in + .Fa *endptr . + (Thus, if +-.Fa *nptr ++.Fa *str + is not + .Ql \e0 + but +@@ -203,9 +221,21 @@ + .It Bq Er ERANGE + The given string was out of range; the value converted has been clamped. .El ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Pp ++.In limits.h ++is necessary for the ++.Fn strtoul ++and ++.Fn strtoull ++functions. .Sh SEE ALSO .Xr strtol 3 , -.Xr wcstoul 3 ++.Xr strtol_l 3 , +.Xr wcstoul 3 , -+.Xr strtol_l 3 ++.Xr compat 5 .Sh STANDARDS The .Fn strtoul diff --git a/stdlib/FreeBSD/system.3.patch b/stdlib/FreeBSD/system.3.patch new file mode 100644 index 0000000..434b325 --- /dev/null +++ b/stdlib/FreeBSD/system.3.patch @@ -0,0 +1,27 @@ +--- _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 @@ + .Sh SYNOPSIS + .In stdlib.h + .Ft int +-.Fn system "const char *string" ++.Fn system "const char *command" + .Sh DESCRIPTION + The + .Fn system + function + hands the argument +-.Fa string ++.Fa command + to the command interpreter + .Xr sh 1 . + The calling process waits for the shell +@@ -66,7 +66,7 @@ + .Dv SIGCHLD . + .Pp + If +-.Fa string ++.Fa command + is a + .Dv NULL + pointer, diff --git a/stdlib/FreeBSD/system.c.patch b/stdlib/FreeBSD/system.c.patch index 3dceff0..5d078a5 100644 --- a/stdlib/FreeBSD/system.c.patch +++ b/stdlib/FreeBSD/system.c.patch @@ -1,11 +1,36 @@ --- system.c.orig 2003-05-20 15:23:25.000000000 -0700 -+++ system.c 2004-08-31 12:00:07.000000000 -0700 -@@ -58,8 +58,12 @@ ++++ system.c 2006-06-24 18:48:47.000000000 -0700 +@@ -49,6 +49,16 @@ + #include "un-namespace.h" + #include "libc_private.h" + ++#if __DARWIN_UNIX03 ++#include ++ ++static pthread_mutex_t __systemfn_mutex = PTHREAD_MUTEX_INITIALIZER; ++extern int __unix_conforming; ++#ifdef VARIANT_CANCELABLE ++extern void _pthread_testcancel(pthread_t thread, int isconforming); ++#endif /* VARIANT_CANCELABLE */ ++#endif /* __DARWIN_UNIX03 */ ++ + int + __system(command) + const char *command; +@@ -58,9 +68,24 @@ struct sigaction ign, intact, quitact; sigset_t newsigblock, oldsigblock; - if (!command) /* just checking... */ - return(1); ++#if __DARWIN_UNIX03 ++ if (__unix_conforming == 0) ++ __unix_conforming = 1; ++#ifdef VARIANT_CANCELABLE ++ _pthread_testcancel(pthread_self(), 1); ++#endif /* VARIANT_CANCELABLE */ ++#endif /* __DARWIN_UNIX03 */ ++ + if (!command) { /* just checking... */ + if (access(_PATH_BSHELL, F_OK) == -1) /* if no sh or no access */ + return(0); @@ -13,5 +38,29 @@ + return(1); + } ++#if __DARWIN_UNIX03 ++ pthread_mutex_lock(&__systemfn_mutex); ++#endif /* __DARWIN_UNIX03 */ /* * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save + * existing signal dispositions. +@@ -83,6 +108,9 @@ + (void)_sigaction(SIGINT, &intact, NULL); + (void)_sigaction(SIGQUIT, &quitact, NULL); + (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); ++#if __DARWIN_UNIX03 ++ pthread_mutex_unlock(&__systemfn_mutex); ++#endif /* __DARWIN_UNIX03 */ + execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL); + _exit(127); + default: /* parent */ +@@ -95,6 +123,9 @@ + (void)_sigaction(SIGINT, &intact, NULL); + (void)_sigaction(SIGQUIT, &quitact, NULL); + (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); ++#if __DARWIN_UNIX03 ++ pthread_mutex_unlock(&__systemfn_mutex); ++#endif /* __DARWIN_UNIX03 */ + return(pid == -1 ? -1 : pstat); + } + diff --git a/stdlib/FreeBSD/tsearch.3.patch b/stdlib/FreeBSD/tsearch.3.patch new file mode 100644 index 0000000..77fa73a --- /dev/null +++ b/stdlib/FreeBSD/tsearch.3.patch @@ -0,0 +1,161 @@ +--- tsearch.3.orig 2007-03-06 15:44:54.000000000 -0800 ++++ tsearch.3 2007-03-06 16:04:48.000000000 -0800 +@@ -31,18 +31,36 @@ + .Dt TSEARCH 3 + .Os + .Sh NAME +-.Nm tsearch , tfind , tdelete , twalk ++.Nm tdelete , ++.Nm tfind , ++.Nm tsearch , ++.Nm twalk + .Nd manipulate binary search trees + .Sh SYNOPSIS + .In search.h + .Ft void * +-.Fn tdelete "const void * restrict key" "void ** restrict rootp" "int (*compar) (const void *, const void *)" ++.Fo tdelete ++.Fa "const void *restrict key" ++.Fa "void **restrict rootp" ++.Fa "int (*compar) (const void *key1, const void *key2)" ++.Fc + .Ft void * +-.Fn tfind "const void *key" "void * const *rootp" "int (*compar) (const void *, const void *)" ++.Fo tfind ++.Fa "const void *key" ++.Fa "void *const *rootp" ++.Fa "int (*compar) (const void *key1, const void *key2)" ++.Fc + .Ft void * +-.Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)" ++.Fo tsearch ++.Fa "const void *key" ++.Fa "void **rootp" ++.Fa "int (*compar) (const void *key1, const void *key2)" ++.Fc + .Ft void +-.Fn twalk "const void *root" "void (*compar) (const void *, VISIT, int)" ++.Fo twalk ++.Fa "const void *root" ++.Fa "void (*compar) (const void *node, VISIT order, int level)" ++.Fc + .Sh DESCRIPTION + The + .Fn tdelete , +@@ -50,39 +68,46 @@ + .Fn tsearch , + and + .Fn twalk +-functions manage binary search trees based on algorithms T and D ++functions manage binary search trees, based on algorithms T and D + from Knuth (6.2.2). + The comparison function passed in by +-the user has the same style of return values as ++the user takes two arguments, each of which is a key ++pointer. ++This function has the same style of return values as + .Xr strcmp 3 . + .Pp + The + .Fn tfind + function +-searches for the datum matched by the argument ++searches for a node whose key matches the argument + .Fa key + in the binary tree rooted at + .Fa rootp , +-returning a pointer to the datum if it is found and NULL ++returning a pointer to the node if it is found and NULL + if it is not. + .Pp ++Note that a node is itself a pointer to the key of the node. ++Thus, you should generally cast this result to a ++double pointer to the data type stored in the tree, for example ++(struct myType **), and use double indirection to retrieve the ++original key value. ++.Pp + The + .Fn tsearch +-function +-is identical to ++function is identical to + .Fn tfind +-except that if no match is found, ++except that, if no match is found, ++it inserts a new node for the + .Fa key +-is inserted into the tree and a pointer to it is returned. ++into the tree and returns a pointer to the node. + If + .Fa rootp +-points to a NULL value a new binary search tree is created. ++points to a NULL value, a new binary search tree is created. + .Pp + The + .Fn tdelete +-function +-deletes a node from the specified binary search tree and returns +-a pointer to the parent of the node to be deleted. ++function deletes a node from the specified binary search tree ++and returns a pointer to the parent of the node that was deleted. + It takes the same arguments as + .Fn tfind + and +@@ -93,20 +118,44 @@ + .Pp + The + .Fn twalk +-function +-walks the binary search tree rooted in ++function walks the binary search tree rooted in + .Fa root + and calls the function + .Fa action + on each node. + The + .Fa action +-function +-is called with three arguments: a pointer to the current node, ++function is called with three arguments: a pointer to the current node, + 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). ++.Pp ++As ++.Fn twalk ++traverses the tree, it calls the ++.Fa action ++function with the traversal type "preorder" ++before visiting the left subtree of the ++.Fa node , ++with the ++traversal type "postorder" before visiting the right subtree ++of the ++.Fa node , ++and with the traversal type "endorder" after ++visiting the right subtree of the ++.Fa node . ++.Pp. ++The ++.Fa action ++function is called only once for a leaf-node, with the ++traversal type "leaf." ++.Pp ++Note: the names for the traversal types differ somewhat from ++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 , +@@ -125,7 +174,7 @@ + functions + return NULL if + .Fa rootp +-is NULL or the datum cannot be found. ++is NULL or the node cannot be found. + .Pp + The + .Fn twalk diff --git a/stdlib/Makefile.inc b/stdlib/Makefile.inc index 5e894a2..530bfdc 100644 --- a/stdlib/Makefile.inc +++ b/stdlib/Makefile.inc @@ -1,20 +1,22 @@ # from @(#)Makefile.inc 8.3 (Berkeley) 2/4/95 # $FreeBSD: src/lib/libc/stdlib/Makefile.inc,v 1.45 2003/04/05 07:33:46 tjr Exp $ +.ifnmake autopatch # machine-dependent stdlib sources .if exists(${.CURDIR}/${MACHINE_ARCH}/stdlib/Makefile.inc) .include "${.CURDIR}/${MACHINE_ARCH}/stdlib/Makefile.inc" .endif +.endif # !autopatch # machine-independent stdlib sources .PATH: ${.CURDIR}/stdlib -MISRCS+=a64l.c l64a.c +MISRCS+=a64l.c grantpt.c l64a.c .include "Makefile.fbsd_begin" FBSDMISRCS=_Exit_.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \ bsearch.c div.c exit.c getenv.c getopt.c getopt_long.c getsubopt.c \ - grantpt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c insque.c labs.c \ + hcreate.c heapsort.c imaxabs.c imaxdiv.c insque.c labs.c \ ldiv.c llabs.c lldiv.c lsearch.c merge.c putenv.c qsort.c qsort_r.c \ radixsort.c rand.c random.c reallocf.c realpath.c remque.c setenv.c \ strfmon.c strhash.c strtoimax.c strtol.c strtoll.c strtoq.c strtoul.c \ @@ -22,21 +24,37 @@ FBSDMISRCS=_Exit_.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \ twalk.c FBSDHDRS= atexit.h .include "Makefile.fbsd_end" -PRIV_INSTHDRS += ${SYMROOT}/atexit.h + +# 4302056: compile qsort.c and bsearch.c with -fexceptions +.for _src in qsort-fbsd.c bsearch-fbsd.c +CFLAGS-${_src} += -fexceptions +.endfor + +PRIV_INSTHDRS += ${SRCROOT}/stdlib/atexit.h .include "Makefile.obsd_begin" OBSDMISRCS=ecvt.c gcvt.c .include "Makefile.obsd_end" -UNIX03SRCS+= putenv.c setenv.c +LEGACYSRCS+= getopt.c putenv.c realpath.c setenv.c system.c +DARWINEXTSNSRCS += realpath.c +CANCELABLESRCS += system.c + +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +CFLAGS-getopt-fbsd.c += -DLIBC_ALIAS_GETOPT +CFLAGS-putenv-fbsd.c += -DLIBC_ALIAS_PUTENV +CFLAGS-realpath-fbsd.c += -DLIBC_ALIAS_REALPATH +CFLAGS-setenv-fbsd.c += -DLIBC_ALIAS_SETENV -DLIBC_ALIAS_UNSETENV +CFLAGS-system-fbsd.c += -DLIBC_ALIAS_SYSTEM .if ${LIB} == "c" -MAN3+= a64l.3 +MAN3+= a64l.3 grantpt.3 MAN3+= strtod_l.3 strtol_l.3 .include "Makefile.fbsd_begin" FBSDMAN3= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ - div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 grantpt.3 \ + div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 \ hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \ lsearch.3 memory.3 qsort.3 radixsort.3 rand.3 random.3 realpath.3 \ strfmon.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3 @@ -46,30 +64,78 @@ FBSDMAN3= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ OBSDMAN3= ecvt.3 .include "Makefile.obsd_end" -MLINKS+=a64l.3 l64a.3 -MLINKS+=atof.3 atof_l.3 -MLINKS+=atoi.3 atoi_l.3 -MLINKS+=atol.3 atoll.3 -MLINKS+=atol.3 atol_l.3 atol.3 atoll_l.3 -MLINKS+=ecvt.3 fcvt.3 -MLINKS+=ecvt.3 gcvt.3 -MLINKS+=exit.3 _Exit.3 -MLINKS+=getenv.3 putenv.3 getenv.3 setenv.3 getenv.3 unsetenv.3 -MLINKS+=grantpt.3 posix_openpt.3 grantpt.3 ptsname.3 grantpt.3 unlockpt.3 -MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3 -MLINKS+=insque.3 remque.3 -MLINKS+=lsearch.3 lfind.3 -MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 qsort.3 qsort_r.3 -MLINKS+=rand.3 rand_r.3 rand.3 srand.3 rand.3 sranddev.3 -MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 \ - random.3 srandomdev.3 +MLINKS+= a64l.3 l64a.3 + +MLINKS+= atof.3 atof_l.3 + +MLINKS+= atoi.3 atoi_l.3 + +MLINKS+= atol.3 atol_l.3 \ + atol.3 atoll.3 \ + atol.3 atoll_l.3 + +MLINKS+= ecvt.3 fcvt.3 \ + ecvt.3 gcvt.3 + +MLINKS+= exit.3 _Exit.3 + +MLINKS+= getenv.3 putenv.3 \ + getenv.3 setenv.3 \ + getenv.3 unsetenv.3 + +MLINKS+= getopt_long.3 getopt_long_only.3 + +MLINKS+= grantpt.3 posix_openpt.3 \ + grantpt.3 ptsname.3 \ + grantpt.3 unlockpt.3 + +MLINKS+= hcreate.3 hdestroy.3 \ + hcreate.3 hsearch.3 + +MLINKS+= insque.3 remque.3 + +MLINKS+= lsearch.3 lfind.3 + +MLINKS+= qsort.3 heapsort.3 \ + qsort.3 mergesort.3 \ + qsort.3 qsort_r.3 + +MLINKS+= radixsort.3 sradixsort.3 + +MLINKS+= rand.3 rand_r.3 \ + rand.3 srand.3 \ + rand.3 sranddev.3 + +MLINKS+= random.3 initstate.3 \ + random.3 setstate.3 \ + random.3 srandom.3 \ + random.3 srandomdev.3 + MLINKS+=strfmon.3 strfmon_l.3 -MLINKS+=strtod.3 strtof.3 strtod.3 strtold.3 -MLINKS+=strtod_l.3 strtof_l.3 strtod_l.3 strtold_l.3 -MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3 strtol.3 strtoimax.3 -MLINKS+=strtol_l.3 strtoll_l.3 strtol_l.3 strtoimax_l.3 strtol_l.3 strtoq_l.3 \ - strtol_l.3 strtoull_l.3 strtol_l.3 strtoumax_l.3 strtol_l.3 strtouq_l.3 \ - strtol_l.3 strtoul_l.3 -MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3 strtoul.3 strtoumax.3 -MLINKS+=tsearch.3 tdelete.3 tsearch.3 tfind.3 tsearch.3 twalk.3 + +MLINKS+= strtod.3 strtof.3 \ + strtod.3 strtold.3 + +MLINKS+= strtod_l.3 strtof_l.3 \ + strtod_l.3 strtold_l.3 + +MLINKS+= strtol.3 strtoll.3 \ + strtol.3 strtoq.3 \ + strtol.3 strtoimax.3 + +MLINKS+= strtol_l.3 strtoimax_l.3 \ + strtol_l.3 strtoll_l.3 \ + strtol_l.3 strtoq_l.3 \ + strtol_l.3 strtoul_l.3 \ + strtol_l.3 strtoull_l.3 \ + strtol_l.3 strtoumax_l.3 \ + strtol_l.3 strtouq_l.3 + +MLINKS+= strtoul.3 strtoull.3 \ + strtoul.3 strtoumax.3 \ + strtoul.3 strtouq.3 + +MLINKS+= tsearch.3 tdelete.3 \ + tsearch.3 tfind.3 \ + tsearch.3 twalk.3 .endif diff --git a/stdlib/_Exit_-fbsd.c b/stdlib/_Exit_-fbsd.c new file mode 100644 index 0000000..3a2e94e --- /dev/null +++ b/stdlib/_Exit_-fbsd.c @@ -0,0 +1,22 @@ +/* + * This file is in the public domain. Written by Garrett A. Wollman, + * 2002-09-07. + * + * $FreeBSD: src/lib/libc/stdlib/_Exit.c,v 1.1 2002/09/10 02:04:49 wollman Exp $ + */ + +#include +#include + +/* + * ISO C99 added this function to provide for Standard C applications + * which needed something like POSIX _exit(). A new interface was created + * in case it turned out that _exit() was insufficient to meet the + * requirements of ISO C. (That's probably not the case, but here + * is where you would put the extra code if it were.) + */ +void +_Exit(int code) +{ + _exit(code); +} diff --git a/stdlib/a64l.3 b/stdlib/a64l.3 index 7876343..0ce2da8 100644 --- a/stdlib/a64l.3 +++ b/stdlib/a64l.3 @@ -37,7 +37,7 @@ .Ft long .Fn a64l "const char *s" .Ft char * -.Fn l64a "long l" +.Fn l64a "long value" .Sh DESCRIPTION The .Fn a64l @@ -86,7 +86,7 @@ larger than 32 bits, the return value will be sign-extended. .Pp .Fn l64a takes a long integer argument -.Fa l +.Fa value and returns a pointer to the corresponding radix-64 representation. .Sh RETURN VALUES On success, @@ -105,14 +105,14 @@ to On success, .Fn l64a returns a pointer to a string containing the radix-64 representation of -.Fa l . +.Fa value . If -.Fa l +.Fa value is 0, .Fn l64a returns a pointer to the empty string. If -.Fa l +.Fa value is negative, .Fn l64a returns a null pointer and sets the global variable diff --git a/stdlib/a64l.c b/stdlib/a64l.c index 8c2a9a3..b60b26e 100644 --- a/stdlib/a64l.c +++ b/stdlib/a64l.c @@ -1,25 +1,3 @@ -/* - * 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@ - */ /* * Written by J.T. Conklin . * Public domain. @@ -36,7 +14,7 @@ long a64l(s) const char *s; { - long value, digit, shift; + int value, digit, shift; int i; if (s == NULL) { diff --git a/stdlib/abort-fbsd.c b/stdlib/abort-fbsd.c new file mode 100644 index 0000000..ab7b12f --- /dev/null +++ b/stdlib/abort-fbsd.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1985, 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" + +extern void (*__cleanup)(); +extern void __abort(void) __dead2; + +#define TIMEOUT 10000 /* 10 milliseconds */ + +void +abort() +{ + struct sigaction act; + + /* + * POSIX requires we flush stdio buffers on abort. + * XXX ISO C requires that abort() be async-signal-safe. + */ + if (__cleanup) + (*__cleanup)(); + + sigfillset(&act.sa_mask); + /* + * Don't block SIGABRT to give any handler a chance; we ignore + * 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); + usleep(TIMEOUT); /* give time for signal to happen */ + + /* + * If SIGABRT was ignored, or caught and the handler returns, do + * it again, only harder. + */ + __abort(); +} + +__private_extern__ void +__abort() +{ + struct sigaction act; + + 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); + usleep(TIMEOUT); /* give time for signal to happen */ + __builtin_trap(); /* never exit normally */ +} diff --git a/stdlib/abort.3 b/stdlib/abort.3 new file mode 120000 index 0000000..4adb0ba --- /dev/null +++ b/stdlib/abort.3 @@ -0,0 +1 @@ +./abort.3 \ No newline at end of file diff --git a/stdlib/abs-fbsd.c b/stdlib/abs-fbsd.c new file mode 100644 index 0000000..26f87eb --- /dev/null +++ b/stdlib/abs-fbsd.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include + +int +abs(j) + int j; +{ + return(j < 0 ? -j : j); +} diff --git a/stdlib/abs.3 b/stdlib/abs.3 new file mode 100644 index 0000000..9252143 --- /dev/null +++ b/stdlib/abs.3 @@ -0,0 +1,77 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd November 14, 2001 +.Dt ABS 3 +.Os +.Sh NAME +.Nm abs +.Nd integer absolute value function +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn abs "int i" +.Sh DESCRIPTION +The +.Fn abs +function computes the absolute value of the integer +.Fa i . +.Sh RETURN VALUES +The +.Fn abs +function +returns +the absolute value. +.Sh SEE ALSO +.Xr cabs 3 , +.Xr fabs 3 , +.Xr floor 3 , +.Xr hypot 3 , +.Xr imaxabs 3 , +.Xr labs 3 , +.Xr llabs 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn abs +function conforms to +.St -isoC-99 . +.Sh BUGS +The absolute value of the most negative integer remains negative. diff --git a/gen/initgroups.3 b/stdlib/alloca.3 similarity index 67% rename from gen/initgroups.3 rename to stdlib/alloca.3 index 039b87f..fc58f0b 100644 --- a/gen/initgroups.3 +++ b/stdlib/alloca.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1983, 1991, 1993 +.\" 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 @@ -29,58 +29,58 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)initgroups.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/initgroups.3,v 1.10 2001/10/01 16:08:51 ru Exp $ +.\" @(#)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 $ .\" .Dd June 4, 1993 -.Dt INITGROUPS 3 +.Dt ALLOCA 3 .Os .Sh NAME -.Nm initgroups -.Nd initialize group access list +.Nm alloca +.Nd memory allocator .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In unistd.h -.Ft int -.Fn initgroups "const char *name" "int basegid" +.In alloca.h +or +.br +.In stdlib.h +.Ft void * +.Fn alloca "size_t size" .Sh DESCRIPTION The -.Fn initgroups +.Fn alloca function -uses the -.Xr getgrouplist 3 -function to calculate the group access list for the user -specified in -.Fa name . -This group list is then setup for the current process using -.Xr setgroups 2 . -The -.Fa basegid -is automatically included in the groups list. -Typically this value is given as -the group number from the password file. +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 initgroups -function -returns \-1 if it was not invoked by the super-user. +.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 setgroups 2 , -.Xr getgrouplist 3 +.Xr brk 2 , +.Xr calloc 3 , +.Xr getpagesize 3 , +.Xr malloc 3 , +.Xr realloc 3 .Sh HISTORY The -.Fn initgroups +.Fn alloca function appeared in -.Bx 4.2 . +.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 getgrouplist -function called by -.Fn initgroups -uses the routines based on -.Xr getgrent 3 . -If the invoking program uses any of these routines, -the group structure will -be overwritten in the call to -.Fn initgroups . +.Fn alloca +function +is machine and compiler dependent; +its use is discouraged. diff --git a/stdlib/atexit-fbsd.c b/stdlib/atexit-fbsd.c new file mode 100644 index 0000000..d8edf72 --- /dev/null +++ b/stdlib/atexit-fbsd.c @@ -0,0 +1,202 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#if defined(__DYNAMIC__) +#include +#endif /* defined(__DYNAMIC__) */ +#include "atexit.h" +#include "un-namespace.h" + +#include "libc_private.h" + +#define ATEXIT_FN_EMPTY 0 +#define ATEXIT_FN_STD 1 +#define ATEXIT_FN_CXA 2 + +static pthread_mutex_t atexit_mutex = PTHREAD_MUTEX_INITIALIZER; + +#define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x) +#define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x) + +struct atexit { + struct atexit *next; /* next in list */ + int ind; /* next index in this table */ + struct atexit_fn { + int fn_type; /* ATEXIT_? from above */ + union { + void (*std_func)(void); + void (*cxa_func)(void *); + } fn_ptr; /* function pointer */ + void *fn_arg; /* argument for CXA callback */ + void *fn_dso; /* shared module handle */ + } fns[ATEXIT_SIZE]; /* the table itself */ +}; + +static struct atexit *__atexit; /* points to head of LIFO stack */ +static int new_registration; + +/* + * Register the function described by 'fptr' to be called at application + * exit or owning shared object unload time. This is a helper function + * for atexit and __cxa_atexit. + */ +static int +atexit_register(struct atexit_fn *fptr) +{ + static struct atexit __atexit0; /* one guaranteed table */ + struct atexit *p; + + _MUTEX_LOCK(&atexit_mutex); + if ((p = __atexit) == NULL) + __atexit = p = &__atexit0; + else while (p->ind >= ATEXIT_SIZE) { + struct atexit *old__atexit; + old__atexit = __atexit; + _MUTEX_UNLOCK(&atexit_mutex); + if ((p = (struct atexit *)malloc(sizeof(*p))) == NULL) + return (-1); + _MUTEX_LOCK(&atexit_mutex); + if (old__atexit != __atexit) { + /* Lost race, retry operation */ + _MUTEX_UNLOCK(&atexit_mutex); + free(p); + _MUTEX_LOCK(&atexit_mutex); + p = __atexit; + continue; + } + p->ind = 0; + p->next = __atexit; + __atexit = p; + } + p->fns[p->ind++] = *fptr; + new_registration = 1; + _MUTEX_UNLOCK(&atexit_mutex); + return 0; +} + +/* + * Register a function to be performed at exit. + */ +int +atexit(void (*func)(void)) +{ + struct atexit_fn fn; + int error; + + fn.fn_type = ATEXIT_FN_STD; + fn.fn_ptr.std_func = func;; + fn.fn_arg = NULL; +#if defined(__DYNAMIC__) + fn.fn_dso = (void *)_dyld_get_image_header_containing_address((unsigned long) func); +#else /* ! defined(__DYNAMIC__) */ + fn.fn_dso = NULL; +#endif /* defined(__DYNAMIC__) */ + + error = atexit_register(&fn); + return (error); +} + +/* + * Register a function to be performed at exit or when an shared object + * with given dso handle is unloaded dynamically. + */ +int +__cxa_atexit(void (*func)(void *), void *arg, void *dso) +{ + struct atexit_fn fn; + int error; + + fn.fn_type = ATEXIT_FN_CXA; + fn.fn_ptr.cxa_func = func;; + fn.fn_arg = arg; + fn.fn_dso = dso; + + error = atexit_register(&fn); + return (error); +} + +/* + * Call all handlers registered with __cxa_atexit for the shared + * object owning 'dso'. Note: if 'dso' is NULL, then all remaining + * handlers are called. + */ +void +__cxa_finalize(const void *dso) +{ + struct atexit *p; + struct atexit_fn fn; + int n; + + _MUTEX_LOCK(&atexit_mutex); +restart: + for (p = __atexit; p; p = p->next) { + for (n = p->ind; --n >= 0;) { + if (p->fns[n].fn_type == ATEXIT_FN_EMPTY) + continue; /* already been called */ + if (dso != NULL && dso != p->fns[n].fn_dso) + continue; /* wrong DSO */ + fn = p->fns[n]; + /* + Mark entry to indicate that this particular handler + has already been called. + */ + p->fns[n].fn_type = ATEXIT_FN_EMPTY; + new_registration = 0; + _MUTEX_UNLOCK(&atexit_mutex); + + /* Call the function of correct type. */ + if (fn.fn_type == ATEXIT_FN_CXA) + fn.fn_ptr.cxa_func(fn.fn_arg); + else if (fn.fn_type == ATEXIT_FN_STD) + fn.fn_ptr.std_func(); + _MUTEX_LOCK(&atexit_mutex); + if (new_registration) + goto restart; + } + } + _MUTEX_UNLOCK(&atexit_mutex); +} diff --git a/stdlib/atexit.3 b/stdlib/atexit.3 new file mode 100644 index 0000000..3ad374d --- /dev/null +++ b/stdlib/atexit.3 @@ -0,0 +1,92 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd September 6, 2002 +.Dt ATEXIT 3 +.Os +.Sh NAME +.Nm atexit +.Nd register a function to be called on exit +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn atexit "void (*func)(void)" +.Sh DESCRIPTION +The +.Fn atexit +function +registers the function +.Fa func +to be called at program exit, whether via +.Xr exit 3 +or via return from the program's +.Fn main . +Functions so registered are called in reverse order; +no arguments are passed. +.Pp +These functions must not call +.Fn exit ; +if it should be necessary to terminate the process while in such a +function, the +.Xr _exit 2 +function should be used. +(Alternatively, the function may cause abnormal +process termination, for example by calling +.Xr abort 3 . ) +.Pp +At least 32 functions can always be registered; +more are allowed as long as sufficient memory can be allocated. +.\" XXX {ATEXIT_MAX} is not implemented yet +.Sh RETURN VALUES +.Rv -std atexit +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er ENOMEM +No memory was available to add the function to the list. +The existing list of functions is unmodified. +.El +.Sh SEE ALSO +.Xr exit 3 +.Sh STANDARDS +The +.Fn atexit +function +conforms to +.St -isoC . diff --git a/stdlib/atexit.h b/stdlib/atexit.h new file mode 100644 index 0000000..ac14b27 --- /dev/null +++ b/stdlib/atexit.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 1990, 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. + * + * @(#)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 $ + */ + +/* must be at least 32 to guarantee ANSI conformance */ +#define ATEXIT_SIZE 32 + +void __cxa_finalize(const void *dso); diff --git a/stdlib/atof-fbsd.c b/stdlib/atof-fbsd.c new file mode 100644 index 0000000..a958725 --- /dev/null +++ b/stdlib/atof-fbsd.c @@ -0,0 +1,58 @@ +/* + * 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include + +double +atof(ascii) + const char *ascii; +{ + return strtod_l(ascii, (char **)NULL, __current_locale()); +} + +double +atof_l(ascii, loc) + const char *ascii; + locale_t loc; +{ + /* no need to call NORMALIZE_LOCALE(loc) because strtod_l will */ + return strtod_l(ascii, (char **)NULL, loc); +} diff --git a/stdlib/atof.3 b/stdlib/atof.3 new file mode 100644 index 0000000..1d32d06 --- /dev/null +++ b/stdlib/atof.3 @@ -0,0 +1,112 @@ +.\" Copyright (c) 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt ATOF 3 +.Os +.Sh NAME +.Nm atof , +.Nm atof_l +.Nd convert +.Tn ASCII +string to double +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft double +.Fn atof "const char *str" +.In xlocale.h +.Ft double +.Fn atof_l "const char *str" "locale_t loc" +.Sh DESCRIPTION +The +.Fn atof +function converts the initial portion of the string pointed to by +.Fa str +to +.Vt double +representation. +.Pp +It is equivalent to: +.Bd -literal -offset indent +strtod(str, (char **)NULL); +.Ed +.Pp +The decimal point +character is defined in the program's locale (category +.Dv LC_NUMERIC ) . +.Pp +While the +.Fn atof +function uses the current locale, the +.Fn atof_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh IMPLEMENTATION NOTES +The +.Fn atof +function is not thread-safe and also not async-cancel-safe. +.Pp +The +.Fn atof +function has been deprecated by +.Fn strtod +and should not be used in new code. +.Sh ERRORS +The function +.Fn atof +need not affect the value of +.Va errno +on an error. +.Sh SEE ALSO +.Xr atoi 3 , +.Xr atol 3 , +.Xr strtod 3 , +.Xr strtol 3 , +.Xr strtoul 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn atof +function conforms to +.St -p1003.1-90 , +.St -isoC , +and +.St -isoC-99 . diff --git a/stdlib/atoi-fbsd.c b/stdlib/atoi-fbsd.c new file mode 100644 index 0000000..779bedc --- /dev/null +++ b/stdlib/atoi-fbsd.c @@ -0,0 +1,58 @@ +/* + * 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include + +int +atoi(str) + const char *str; +{ + return (int)strtol_l(str, (char **)NULL, 10, __current_locale()); +} + +int +atoi_l(str, loc) + const char *str; + locale_t loc; +{ + /* no need to call NORMALIZE_LOCALE(loc) because strtol_l will */ + return (int)strtol_l(str, (char **)NULL, 10, loc); +} diff --git a/stdlib/atoi.3 b/stdlib/atoi.3 new file mode 100644 index 0000000..7002274 --- /dev/null +++ b/stdlib/atoi.3 @@ -0,0 +1,108 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt ATOI 3 +.Os +.Sh NAME +.Nm atoi , +.Nm atoi_l +.Nd convert +.Tn ASCII +string to integer +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn atoi "const char *str" +.In xlocale.h +.Ft int +.Fn atoi_l "const char *str" "locale_t loc" +.Sh DESCRIPTION +The +.Fn atoi +function converts the initial portion of the string pointed to by +.Fa str +to +.Vt int +representation. +.Pp +It is equivalent to: +.Bd -literal -offset indent +(int)strtol(str, (char **)NULL, 10); +.Ed +.Pp +While the +.Fn atoi +function uses the current locale, the +.Fn atoi_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh IMPLEMENTATION NOTES +The +.Fn atoi +function is not thread-safe and also not async-cancel safe. +.Pp +The +.Fn atoi +function has been deprecated by +.Fn strtol +and should not be used in new code. +.Sh ERRORS +The function +.Fn atoi +need not affect the value of +.Va errno +on an error. +.Sh SEE ALSO +.Xr atof 3 , +.Xr atol 3 , +.Xr strtod 3 , +.Xr strtol 3 , +.Xr strtoul 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn atoi +function conforms to +.St -p1003.1-90 , +.St -isoC , +and +.St -isoC-99 . diff --git a/stdlib/atol-fbsd.c b/stdlib/atol-fbsd.c new file mode 100644 index 0000000..b8b9161 --- /dev/null +++ b/stdlib/atol-fbsd.c @@ -0,0 +1,58 @@ +/* + * 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include + +long +atol(str) + const char *str; +{ + return strtol_l(str, (char **)NULL, 10, __current_locale()); +} + +long +atol_l(str, loc) + const char *str; + locale_t loc; +{ + /* no need to call NORMALIZE_LOCALE(loc) because strtol_l will */ + return strtol_l(str, (char **)NULL, 10, loc); +} diff --git a/stdlib/atol.3 b/stdlib/atol.3 new file mode 100644 index 0000000..eb014ba --- /dev/null +++ b/stdlib/atol.3 @@ -0,0 +1,129 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd November 28, 2001 +.Dt ATOL 3 +.Os +.Sh NAME +.Nm atol , atoll , +.Nm atol_l , atoll_l +.Nd convert +.Tn ASCII +string to +.Vt long +or +.Vt "long long" +integer +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft long +.Fn atol "const char *str" +.Ft "long long" +.Fn atoll "const char *str" +.In xlocale.h +.Ft long +.Fn atol_l "const char *str" "locale_t loc" +.Ft "long long" +.Fn atoll_l "const char *str" "locale_t loc" +.Sh DESCRIPTION +The +.Fn atol +function converts the initial portion of the string pointed to by +.Fa str +to +.Vt long +integer +representation. +.Pp +It is equivalent to: +.Pp +.Dl "strtol(str, (char **)NULL, 10);" +.Pp +The +.Fn atoll +function converts the initial portion of the string pointed to by +.Fa str +to +.Vt "long long" +integer +representation. +.Pp +It is equivalent to: +.Pp +.Dl "strtoll(str, (char **)NULL, 10);" +.Pp +While the +.Fn atol +and +.Fn atoll +functions use the current locale, the +.Fn atol_l +and +.Fn atoll_l +functions may be passed locales directly. See +.Xr xlocale 3 +for more information. +.Sh ERRORS +The functions +.Fn atol +and +.Fn atoll +need not +affect the value of +.Va errno +on an error. +.Sh SEE ALSO +.Xr atof 3 , +.Xr atoi 3 , +.Xr strtod 3 , +.Xr strtol 3 , +.Xr strtoul 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn atol +function +conforms to +.St -isoC . +The +.Fn atoll +function +conforms to +.St -isoC-99 . diff --git a/stdlib/atoll-fbsd.c b/stdlib/atoll-fbsd.c new file mode 100644 index 0000000..e1e2176 --- /dev/null +++ b/stdlib/atoll-fbsd.c @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/atoll.c,v 1.4 2002/03/22 21:53:10 obrien Exp $"); + +#include "xlocale_private.h" + +#include + +long long +atoll(str) + const char *str; +{ + return strtoll_l(str, (char **)NULL, 10, __current_locale()); +} + +long long +atoll_l(str, loc) + const char *str; + locale_t loc; +{ + /* no need to call NORMALIZE_LOCALE(loc) because strtoll_l will */ + return strtoll_l(str, (char **)NULL, 10, loc); +} diff --git a/stdlib/bsearch-fbsd.c b/stdlib/bsearch-fbsd.c new file mode 100644 index 0000000..7717582 --- /dev/null +++ b/stdlib/bsearch-fbsd.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include +#include + +/* + * Perform a binary search. + * + * The code below is a bit sneaky. After a comparison fails, we + * divide the work in half by moving either left or right. If lim + * is odd, moving left simply involves halving lim: e.g., when lim + * is 5 we look at item 2, so we change lim to 2 so that we will + * look at items 0 & 1. If lim is even, the same applies. If lim + * is odd, moving right again involes halving lim, this time moving + * the base up one item past p: e.g., when lim is 5 we change base + * to item 3 and make lim 2 so that we will look at items 3 and 4. + * If lim is even, however, we have to shrink it by one before + * halving: e.g., when lim is 4, we still looked at item 2, so we + * have to make lim 3, then halve, obtaining 1, so that we will only + * look at item 3. + */ +void * +bsearch(key, base0, nmemb, size, compar) + const void *key; + const void *base0; + size_t nmemb; + size_t size; + int (*compar)(const void *, const void *); +{ + const char *base = base0; + size_t lim; + int cmp; + const void *p; + + for (lim = nmemb; lim != 0; lim >>= 1) { + p = base + (lim >> 1) * size; + cmp = (*compar)(key, p); + if (cmp == 0) + return ((void *)p); + if (cmp > 0) { /* key > p: move right */ + base = (char *)p + size; + lim--; + } /* else move left */ + } + return (NULL); +} diff --git a/stdlib/bsearch.3 b/stdlib/bsearch.3 new file mode 100644 index 0000000..dc91d91 --- /dev/null +++ b/stdlib/bsearch.3 @@ -0,0 +1,94 @@ +.\" Copyright (c) 1990, 1991, 1993, 1994 +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd April 19, 1994 +.Dt BSEARCH 3 +.Os +.Sh NAME +.Nm bsearch +.Nd binary search of a sorted table +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft void * +.Fn bsearch "const void *key" "const void *base" "size_t nel" "size_t width" "int (*compar) (const void *, const void *)" +.Sh DESCRIPTION +The +.Fn bsearch +function searches an array of +.Fa nel +objects, the initial member of which is +pointed to by +.Fa base , +for a member that matches the object pointed to by +.Fa key . +The size (in bytes) of each member of the array is specified by +.Fa width . +.Pp +The contents of the array should be in ascending sorted order according +to the comparison function referenced by +.Fa compar . +The +.Fa compar +routine +is expected to have +two arguments which point to the +.Fa key +object and to an array member, in that order. +It should return an integer which is +less than, equal to, or greater than zero if the +.Fa key +object is found, respectively, to be less than, to match, or be +greater than the array member. +.Sh RETURN VALUES +The +.Fn bsearch +function returns a pointer to a matching member of the array, or a null +pointer if no match is found. +If two members compare as equal, which member is matched is unspecified. +.Sh SEE ALSO +.Xr db 3 , +.Xr lsearch 3 , +.Xr qsort 3 +.\" .Xr tsearch 3 +.Sh STANDARDS +The +.Fn bsearch +function conforms to +.St -isoC . diff --git a/stdlib/div-fbsd.c b/stdlib/div-fbsd.c new file mode 100644 index 0000000..54278d6 --- /dev/null +++ b/stdlib/div-fbsd.c @@ -0,0 +1,81 @@ +/* + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include /* div_t */ + +div_t +div(num, denom) + int num, denom; +{ + div_t r; + + r.quot = num / denom; + r.rem = num % denom; + /* + * The ANSI standard says that |r.quot| <= |n/d|, where + * n/d is to be computed in infinite precision. In other + * words, we should always truncate the quotient towards + * 0, never -infinity. + * + * Machine division and remainer may work either way when + * one or both of n or d is negative. If only one is + * negative and r.quot has been truncated towards -inf, + * r.rem will have the same sign as denom and the opposite + * sign of num; if both are negative and r.quot has been + * truncated towards -inf, r.rem will be positive (will + * have the opposite sign of num). These are considered + * `wrong'. + * + * If both are num and denom are positive, r will always + * be positive. + * + * This all boils down to: + * if num >= 0, but r.rem < 0, we got the wrong answer. + * In that case, to get the right answer, add 1 to r.quot and + * subtract denom from r.rem. + */ + if (num >= 0 && r.rem < 0) { + r.quot++; + r.rem -= denom; + } + return (r); +} diff --git a/stdlib/div.3 b/stdlib/div.3 new file mode 100644 index 0000000..ed02b75 --- /dev/null +++ b/stdlib/div.3 @@ -0,0 +1,74 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd November 14, 2001 +.Dt DIV 3 +.Os +.Sh NAME +.Nm div +.Nd return quotient and remainder from division +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft div_t +.Fn div "int numer" "int denom" +.Sh DESCRIPTION +The +.Fn div +function +computes the value +.Fa numer/denom +(numerator/denominator). +It returns a structure named +.Fa div_t +that contains two +.Vt int +members named +.Va quot +(quotient) and +.Va rem +(remainder). +.Sh SEE ALSO +.Xr imaxdiv 3 , +.Xr ldiv 3 , +.Xr lldiv 3 +.Sh STANDARDS +The +.Fn div +function +conforms to +.St -isoC-99 . diff --git a/stdlib/ecvt-obsd.c b/stdlib/ecvt-obsd.c new file mode 100644 index 0000000..0a1e095 --- /dev/null +++ b/stdlib/ecvt-obsd.c @@ -0,0 +1,110 @@ +/* $OpenBSD: ecvt.c,v 1.3 2003/06/17 21:56:24 millert Exp $ */ + +/* + * Copyright (c) 2002 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 + * 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. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * 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 */ + +#include +#include +#include + +extern char *__dtoa(double, int, int, int *, int *, char **); +extern void __freedtoa(char *); /* special gdtoa free function */ +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; + size_t siz; + + if (ndigit == 0) { + *sign = value < 0.0; + *decpt = 0; + return (""); + } + + if (s) { + free(s); + s = NULL; + } + + if (ndigit < 0) + siz = -ndigit + 1; + else + siz = ndigit + 1; + + + /* __dtoa() doesn't allocate space for 0 so we do it by hand */ + if (value == 0.0) { + *decpt = 1 - fmode; /* 1 for 'e', 0 for 'f' */ + *sign = 0; + if ((rve = s = (char *)malloc(siz)) == NULL) + return(NULL); + *rve++ = '0'; + *rve = '\0'; + } else { + p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve); + if (*decpt == 9999) { + /* Nan or Infinity */ + *decpt = 0; + 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) { + __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) { + siz -= rve - s; + while (--siz) + *rve++ = '0'; + *rve = '\0'; + } + + return(s); +} + +char * +ecvt(double value, int ndigit, int * __restrict decpt, int * __restrict sign) +{ + return(__cvt(value, ndigit, decpt, sign, 0, 1)); +} + +char * +fcvt(double value, int ndigit, int * __restrict decpt, int * __restrict sign) +{ + return(__cvt(value, ndigit, decpt, sign, 1, 1)); +} diff --git a/stdlib/ecvt.3 b/stdlib/ecvt.3 new file mode 100644 index 0000000..5353d94 --- /dev/null +++ b/stdlib/ecvt.3 @@ -0,0 +1,165 @@ +.\" $OpenBSD: ecvt.3,v 1.7 2004/01/25 14:48:32 jmc Exp $ +.\" +.\" Copyright (c) 2002 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 +.\" 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. +.\" +.\" Sponsored in part by the Defense Advanced Research Projects +.\" Agency (DARPA) and Air Force Research Laboratory, Air Force +.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. +.\" +.Dd December 1, 2002 +.Dt ECVT 3 +.Os +.Sh NAME +.Nm ecvt , +.Nm fcvt , +.Nm gcvt +.Nd convert double to +.Tn ASCII +string +.Sh SYNOPSIS +.Fd #include +.Ft char * +.Fn ecvt "double value" "int ndigit" "int * restrict decpt" "int * restrict sign" +.Ft char * +.Fn fcvt "double value" "int ndigit" "int * restrict decpt" "int * restrict sign" +.Ft char * +.Fn gcvt "double value" "int ndigit" "char *buf" +.Sh DESCRIPTION +.Bf -symbolic +These functions are provided for compatibility with legacy code. +New code should use the +.Xr snprintf 3 +function for improved safety and portability. +.Ef +.Pp +The +.Fn ecvt , +.Fn fcvt +and +.Fn gcvt +functions convert the double precision floating-point number +.Fa value +to a NUL-terminated +.Tn ASCII +string. +.Pp +The +.Fn ecvt +function converts +.Fa value +to a NUL-terminated string of exactly +.Fa ndigit +digits and returns a pointer to that string. +The result is padded with zeroes from left to right as needed. +There are no leading zeroes unless +.Fa value +itself is 0. +The least significant digit is rounded in an implementation-dependent manner. +The position of the decimal point relative to the beginning of the string +is stored in +.Fa decpt . +A negative value indicates that the decimal point is located +to the left of the returned digits (this occurs when there is no +whole number component to +.Fa value ) . +If +.Fa value +is zero, it is unspecified whether the integer pointed to by +.Fa decpt +will be 0 or 1. +The decimal point itself is not included in the returned string. +If the sign of the result is negative, the integer pointed to by +.Fa sign +is non-zero; otherwise, it is 0. +.Pp +If the converted value is out of range or is not representable, +the contents of the returned string are unspecified. +.Pp +The +.Fn fcvt +function is identical to +.Fn ecvt +with the exception that +.Fa ndigit +specifies the number of digits after the decimal point (zero-padded as +needed). +.Pp +The +.Fn gcvt +function converts +.Fa value +to a NUL-terminated string similar to the %g +.Xr printf 3 +format specifier and stores the result in +.Fa buf . +It produces +.Fa ndigit +significant digits similar to the %f +.Xr printf 3 +format specifier where possible. +If +.Fa ndigit +does allow sufficient precision, the result is stored in +exponential notation similar to the %e +.Xr printf 3 +format specifier. +If +.Fa value +is less than zero, +.Fa buf +will be prefixed with a minus sign. +A decimal point is included in the returned string if +.Fa value +is not a whole number. +Unlike the +.Fn ecvt +and +.Fn fcvt +functions, +.Fa buf +is not zero-padded. +.Sh RETURN VALUES +The +.Fn ecvt , +.Fn fcvt +and +.Fn gcvt +functions return a NUL-terminated string representation of +.Fa value . +.Sh WARNINGS +The +.Fn ecvt +and +.Fn fcvt +functions return a pointer to internal storage space that will be +overwritten by subsequent calls to either function. +.Pp +The maximum possible precision of the return value is limited by the +precision of a double and may not be the same on all architectures. +.Pp +The +.Xr snprintf 3 +function is preferred over these functions for new code. +.Sh SEE ALSO +.Xr printf 3 , +.Xr strtod 3 +.Sh STANDARDS +The +.Fn ecvt , +.Fn fcvt +and +.Fn gcvt +functions conform to +.St -p1003.1-2001 . diff --git a/stdlib/exit-fbsd.c b/stdlib/exit-fbsd.c new file mode 100644 index 0000000..19fc265 --- /dev/null +++ b/stdlib/exit-fbsd.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "atexit.h" + +void (*__cleanup)(); +extern void __exit(int); + +/* + * Exit, flushing stdio buffers if necessary. + */ +void +exit(status) + int status; +{ + __cxa_finalize(NULL); + if (__cleanup) + (*__cleanup)(); + __exit(status); +} diff --git a/stdlib/exit.3 b/stdlib/exit.3 new file mode 120000 index 0000000..9110a44 --- /dev/null +++ b/stdlib/exit.3 @@ -0,0 +1 @@ +./exit.3 \ No newline at end of file diff --git a/stdlib/gcvt-obsd.c b/stdlib/gcvt-obsd.c new file mode 100644 index 0000000..08b65fc --- /dev/null +++ b/stdlib/gcvt-obsd.c @@ -0,0 +1,112 @@ +/* $OpenBSD: gcvt.c,v 1.5 2003/06/17 21:56:24 millert Exp $ */ + +/* + * Copyright (c) 2002, 2003 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 + * 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. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * 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; + char *decimal_point = localeconv()->decimal_point; + + if (ndigit == 0) { + buf[0] = '\0'; + return (buf); + } + + digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL); + if (decpt == 9999) { + /* Infinity or NaN, assume buffer is long enough. */ + dst = buf; + if (sign) + *dst++ = '-'; + strcpy(dst, (*digits == 'N') ? "nan" : "inf"); + __freedtoa(digits); + return (buf); + } + + dst = buf; + if (sign) + *dst++ = '-'; + + if (decpt < 0 || decpt > ndigit) { + /* exponential format */ + if (--decpt < 0) { + sign = 1; + decpt = -decpt; + } else + sign = 0; + src = digits; + *dst++ = *src++; + dst = stpcpy(dst, decimal_point); + while (*src != '\0') + *dst++ = *src++; + *dst++ = 'e'; + if (sign) + *dst++ = '-'; + else + *dst++ = '+'; + if (decpt < 10) { + *dst++ = '0'; + *dst++ = '0' + decpt; + *dst = '\0'; + } else { + /* XXX - optimize */ + for (sign = decpt, i = 0; (sign /= 10) != 0; i++) {} + dst[i + 1] = '\0'; + while (decpt != 0) { + dst[i--] = '0' + decpt % 10; + decpt /= 10; + } + } + } else { + /* standard format */ + for (i = 0, src = digits; i < decpt; i++) { + if (*src != '\0') + *dst++ = *src++; + else + *dst++ = '0'; + } + if (*src != '\0') { + if (src == digits) /* need leading zero */ + *dst++ = '0'; + dst = stpcpy(dst, decimal_point); + for (i = decpt; digits[i] != '\0'; i++) { + *dst++ = digits[i]; + } + } + *dst = '\0'; + } + __freedtoa(digits); + return (buf); +} diff --git a/stdlib/getenv-fbsd.c b/stdlib/getenv-fbsd.c new file mode 100644 index 0000000..3fdfe80 --- /dev/null +++ b/stdlib/getenv-fbsd.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1987, 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[] = "@(#)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 $"); + +#include +#include +#include +#include + +__private_extern__ char *__findenv(const char *, int *, char **); + +/* + * __findenv -- + * Returns pointer to value associated with name, if any, else NULL. + * Sets offset to be the offset of the name/value combination in the + * environmental array, for use by setenv(3) and unsetenv(3). + * Explicitly removes '=' in argument name. + * + * This routine *should* be a static; don't use it. + */ +__private_extern__ char * +__findenv(name, offset, environ) + const char *name; + int *offset; + char **environ; +{ + int len, i; + const char *np; + char **p, *cp; + + if (name == NULL || environ == NULL) + return (NULL); + for (np = name; *np && *np != '='; ++np) + continue; + len = np - name; + for (p = environ; (cp = *p) != NULL; ++p) { + for (np = name, i = len; i && *cp; i--) + if (*cp++ != *np++) + break; + if (i == 0 && *cp++ == '=') { + *offset = p - environ; + return (cp); + } + } + return (NULL); +} + +/* + * _getenvp -- SPI using an arbitrary pointer to string array (the array must + * have been created with malloc) and an env state, created by _allocenvstate(). + * Returns ptr to value associated with name, if any, else NULL. + */ +char * +_getenvp(const char *name, char ***envp, void *state __unused) +{ + int offset; + + return (__findenv(name, &offset, *envp)); +} + +/* + * getenv -- + * Returns ptr to value associated with name, if any, else NULL. + */ +char * +getenv(name) + const char *name; +{ + int offset; + + return (__findenv(name, &offset, *_NSGetEnviron())); +} diff --git a/stdlib/getenv.3 b/stdlib/getenv.3 new file mode 100644 index 0000000..498a365 --- /dev/null +++ b/stdlib/getenv.3 @@ -0,0 +1,238 @@ +.\" Copyright (c) 1988, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)getenv.3 8.2 (Berkeley) 12/11/93 +.\" $FreeBSD: src/lib/libc/stdlib/getenv.3,v 1.16 2004/07/07 19:57:13 ru Exp $ +.\" +.Dd December 11, 1993 +.Dt GETENV 3 +.Os +.Sh NAME +.Nm getenv , +.Nm putenv , +.Nm setenv , +.Nm unsetenv +.Nd environment variable functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft char * +.Fo getenv +.Fa "const char *name" +.Fc +.Ft int +.Fo putenv +.Fa "char *string" +.Fc +.Ft int +.Fo setenv +.Fa "const char *name" +.Fa "const char *value" +.Fa "int overwrite" +.Fc +.Ft int +.Fo unsetenv +.Fa "const char *name" +.Fc +.Sh DESCRIPTION +These functions set, unset and fetch environment variables from the +host +.Em environment list . +For compatibility with differing environment conventions, +the given arguments +.Fa name +and +.Fa value +may be appended and prepended, +respectively, +with an equal sign +.Dq Li \&= . +.Pp +The +.Fn getenv +function obtains the current value of the environment variable, +.Fa name . +.Pp +The +.Fn setenv +function inserts or resets the environment variable +.Fa name +in the current environment list. +If the variable +.Fa name +does not exist in the list, +it is inserted with the given +.Fa value . +If the variable does exist, the argument +.Fa overwrite +is tested; if +.Fa overwrite +is +zero, the +variable is not reset, otherwise it is reset +to the given +.Fa value . +.Pp +The +.Fn putenv +function takes an argument of the form ``name=value'' and is +equivalent to: +.Bd -literal -offset indent +setenv(name, value, 1); +.Ed +.Pp +The string pointed to by +.Fa string +becomes part of the environment. +A program should not alter or free the string, +and should not use stack or other transient string variables +as arguments to +.Fn putenv . +The +.Fn setenv +function is strongly preferred to +.Fn putenv . +.Pp +The +.Fn unsetenv +function +deletes all instances of the variable name pointed to by +.Fa name +from the list. +Note that only the variable name (e.g., "NAME") should be given; +"NAME=value" will not work. +.Sh RETURN VALUES +The +.Fn getenv +function returns the value of the environment variable as a +.Dv NUL Ns +-terminated string. +If the variable +.Fa name +is not in the current environment, +.Dv NULL +is returned. +.Pp +.Rv -std setenv putenv unsetenv +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EINVAL +The function +.Fn unsetenv +failed because +.Fa name +was not found in the environment list. +.It Bq Er ENOMEM +The function +.Fn setenv +or +.Fn putenv +failed because it was unable to allocate memory for the environment. +.El +.Sh LEGACY SYNOPSIS +.Fd #include +.Pp +.Ft void +.br +.Fo unsetenv +.Fa "const char *name" +.Fc ; +.Pp +.Fn unsetenv +doesn't return a value. +.Sh COMPATIBILITY +.Fn putenv +no longer copies its input buffer. +This often appears in crash logs as a crash in +.Fn getenv . +Avoid passing local buffers or freeing the memory +that is passed to +.Fn putenv . +Use +.Fn setenv , +which still makes an internal copy of its buffers. +.Pp +.Fn unsetenv +no longer parses the variable name; +e.g., unsetenv ("FOO=BAR") no longer works. +Use unsetenv("FOO"). +.Fn unsetenv +also now returns a status value and will set +.Va errno +to EINVAL if +.Fa name +is not a defined environment variable. +.Sh SEE ALSO +.Xr csh 1 , +.Xr sh 1 , +.Xr execve 2 , +.Xr compat 5 , +.Xr environ 7 +.Sh STANDARDS +The +.Fn getenv +function conforms to +.St -isoC . +.Sh BUGS +Successive calls to +.Fn setenv +or +.Fn putenv +assigning a differently sized +.Fa value +to the same +.Fa name +will result in a memory leak. +The +.Fx +semantics for these functions +(namely, that the contents of +.Fa value +are copied and that old values remain accessible indefinitely) make this +bug unavoidable. +Future versions may eliminate one or both of these +semantic guarantees in order to fix the bug. +.Sh HISTORY +The functions +.Fn setenv +and +.Fn unsetenv +appeared in +.At v7 . +The +.Fn putenv +function appeared in +.Bx 4.3 Reno . diff --git a/stdlib/getopt-fbsd.c b/stdlib/getopt-fbsd.c new file mode 100644 index 0000000..ce37be2 --- /dev/null +++ b/stdlib/getopt-fbsd.c @@ -0,0 +1,153 @@ +/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */ + +/* + * Copyright (c) 1987, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" + +#ifndef BUILDING_VARIANT +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +#endif /* !BUILDING_VARIANT */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +#if __DARWIN_UNIX03 +#define PROGNAME nargv[0] +#else +#define PROGNAME _getprogname() +#endif + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt(nargc, nargv, ostr) + int nargc; + char * const nargv[]; + const char *ostr; +{ + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + if (optreset || *place == 0) { /* update scanning pointer */ + optreset = 0; + place = nargv[optind]; + if (optind >= nargc || *place++ != '-') { + /* Argument is absent or is not an option */ + place = EMSG; + return (-1); + } + optopt = *place++; + if (optopt == '-' && *place == 0) { + /* "--" => end of options */ + ++optind; + place = EMSG; + return (-1); + } + if (optopt == 0) { + /* Solitary '-', treat as a '-' option + if the program (eg su) is looking for it. */ + place = EMSG; + if (strchr(ostr, '-') == NULL) + return (-1); + optopt = '-'; + } + } else + optopt = *place++; + + /* See if option letter is one the caller wanted... */ + if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) { + if (*place == 0) + ++optind; + if (opterr && *ostr != ':') + (void)fprintf(stderr, + "%s: illegal option -- %c\n", + PROGNAME, optopt); + return (BADCH); + } + + /* Does this option need an argument? */ + if (oli[1] != ':') { + /* don't need argument */ + optarg = NULL; + if (*place == 0) + ++optind; + } else { + /* Option-argument is either the rest of this argument or the + entire next argument. */ + if (*place) + optarg = place; + else if (nargc > ++optind) + optarg = nargv[optind]; + else { + /* option-argument absent */ +#if __DARWIN_UNIX03 + /* Yes, the standard will put optind past the last + argument */ + ++optind; + optarg = NULL; +#endif /* __DARWIN_UNIX03 */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + PROGNAME, optopt); + return (BADCH); + } + place = EMSG; + ++optind; + } + return (optopt); /* return option letter */ +} diff --git a/stdlib/getopt.3 b/stdlib/getopt.3 new file mode 120000 index 0000000..67219ac --- /dev/null +++ b/stdlib/getopt.3 @@ -0,0 +1 @@ +./getopt.3 \ No newline at end of file diff --git a/stdlib/getopt_long-fbsd.c b/stdlib/getopt_long-fbsd.c new file mode 100644 index 0000000..ef306bc --- /dev/null +++ b/stdlib/getopt_long-fbsd.c @@ -0,0 +1,642 @@ +/* $OpenBSD: getopt_long.c,v 1.17 2004/06/03 18:46:52 millert Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Copyright (c) 2002 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 + * 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. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and 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. + * 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. + */ + +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $"; +#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 $"); + +#include +#include +#include +#include +#include + +#define GNU_COMPATIBLE /* Be more compatible, configure's use us! */ + +#ifndef GNU_COMPATIBLE +#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ +#endif + +#ifdef REPLACE_GETOPT +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +#endif + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +#ifdef GNU_COMPATIBLE +#define NO_PREFIX (-1) +#define D_PREFIX 0 +#define DD_PREFIX 1 +#define W_PREFIX 2 +#endif + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char illoptchar[] = "illegal option -- %c"; /* From P1003.2 */ +#ifdef GNU_COMPATIBLE +static int dash_prefix = NO_PREFIX; +static const char gnuoptchar[] = "invalid option -- %c"; + +static const char recargstring[] = "option `%s%s' requires an argument"; +static const char ambig[] = "option `%s%.*s' is ambiguous"; +static const char noarg[] = "option `%s%.*s' doesn't allow an argument"; +static const char illoptstring[] = "unrecognized option `%s%s'"; +#else +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptstring[] = "unknown option -- %s"; +#endif + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too, int flags) +{ + char *current_argv, *has_equal; +#ifdef GNU_COMPATIBLE + char *current_dash; +#endif + size_t current_argv_len; + int i, match, exact_match, second_partial_match; + + current_argv = place; +#ifdef GNU_COMPATIBLE + switch (dash_prefix) { + case D_PREFIX: + current_dash = "-"; + break; + case DD_PREFIX: + current_dash = "--"; + break; + case W_PREFIX: + current_dash = "-W "; + break; + default: + current_dash = ""; + break; + } +#endif + match = -1; + exact_match = 0; + second_partial_match = 0; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + exact_match = 1; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* first partial match */ + match = i; + else if ((flags & FLAG_LONGONLY) || + long_options[i].has_arg != + long_options[match].has_arg || + long_options[i].flag != long_options[match].flag || + long_options[i].val != long_options[match].val) + second_partial_match = 1; + } + if (!exact_match && second_partial_match) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, +#ifdef GNU_COMPATIBLE + current_dash, +#endif + (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, +#ifdef GNU_COMPATIBLE + current_dash, +#endif + (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; +#ifdef GNU_COMPATIBLE + return (BADCH); +#else + return (BADARG); +#endif + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, +#ifdef GNU_COMPATIBLE + current_dash, +#endif + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, +#ifdef GNU_COMPATIBLE + current_dash, +#endif + current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + char *oli; /* option letter list index */ + int optchar, short_too; + int posixly_correct; + + if (options == NULL) + return (-1); + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + */ + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); +#ifdef GNU_COMPATIBLE + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; +#else + if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + else if (*options == '-') + flags |= FLAG_ALLARGS; +#endif + if (*options == '+' || *options == '-') + options++; + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || +#ifdef GNU_COMPATIBLE + place[1] == '\0') { +#else + (place[1] == '\0' && strchr(options, '-') == NULL)) { +#endif + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; +#ifdef GNU_COMPATIBLE + dash_prefix = D_PREFIX; +#endif + if (*place == '-') { + place++; /* --foo long option */ +#ifdef GNU_COMPATIBLE + dash_prefix = DD_PREFIX; +#endif + } else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too, flags); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + (optchar == (int)'-' && *place != '\0') || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; +#ifdef GNU_COMPATIBLE + if (PRINT_ERROR) + warnx(posixly_correct ? illoptchar : gnuoptchar, + optchar); +#else + if (PRINT_ERROR) + warnx(illoptchar, optchar); +#endif + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; +#ifdef GNU_COMPATIBLE + dash_prefix = W_PREFIX; +#endif + optchar = parse_long_options(nargv, options, long_options, + idx, 0, flags); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + 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; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + 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; + } + /* dump back option letter */ + return (optchar); +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the BSD getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} +#endif /* REPLACE_GETOPT */ + +/* + * getopt_long -- + * 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; +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * 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; +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} diff --git a/stdlib/getopt_long.3 b/stdlib/getopt_long.3 new file mode 120000 index 0000000..4cab876 --- /dev/null +++ b/stdlib/getopt_long.3 @@ -0,0 +1 @@ +./getopt_long.3 \ No newline at end of file diff --git a/stdlib/getsubopt-fbsd.c b/stdlib/getsubopt-fbsd.c new file mode 100644 index 0000000..488706a --- /dev/null +++ b/stdlib/getsubopt-fbsd.c @@ -0,0 +1,101 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include +#include + +/* + * The SVID interface to getsubopt provides no way of figuring out which + * part of the suboptions list wasn't matched. This makes error messages + * tricky... The extern variable suboptarg is a pointer to the token + * which didn't match. + */ +char *suboptarg; + +int +getsubopt(optionp, tokens, valuep) + char **optionp, **valuep; + char * const *tokens; +{ + int cnt; + char *p; + + suboptarg = *valuep = NULL; + + if (!optionp || !*optionp) + return(-1); + + /* skip leading white-space, commas */ + for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p); + + if (!*p) { + *optionp = p; + return(-1); + } + + /* save the start of the token, and skip the rest of the token. */ + for (suboptarg = p; + *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';); + + if (*p) { + /* + * If there's an equals sign, set the value pointer, and + * skip over the value part of the token. Terminate the + * token. + */ + if (*p == '=') { + *p = '\0'; + for (*valuep = ++p; + *p && *p != ',' && *p != ' ' && *p != '\t'; ++p); + if (*p) + *p++ = '\0'; + } else + *p++ = '\0'; + /* Skip any whitespace or commas after this token. */ + for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p); + } + + /* set optionp for next round. */ + *optionp = p; + + for (cnt = 0; *tokens; ++tokens, ++cnt) + if (!strcmp(suboptarg, *tokens)) + return(cnt); + return(-1); +} diff --git a/stdlib/getsubopt.3 b/stdlib/getsubopt.3 new file mode 100644 index 0000000..eb77d75 --- /dev/null +++ b/stdlib/getsubopt.3 @@ -0,0 +1,153 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 9, 1993 +.Dt GETSUBOPT 3 +.Os +.Sh NAME +.Nm getsubopt +.Nd get sub options from an argument +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Vt extern char *suboptarg ; +.Ft int +.Fo getsubopt +.Fa "char **optionp" +.Fa "char *const *keylistp" +.Fa "char **valuep" +.Fc +.Sh DESCRIPTION +The +.Fn getsubopt +function +parses a string containing tokens that are delimited +by one or more tab, space, or comma +.Pq Ql \&, +characters. +It is intended for use in parsing groups of option arguments +that are provided as part of a utility command line. +.Pp +The argument +.Fa optionp +is a pointer to a pointer to the string. +The argument +.Fa keylistp +is a pointer to a +.Dv NULL Ns -terminated +array of pointers to strings. +.Pp +The +.Fn getsubopt +function +returns the zero-based offset of the pointer in the +.Fa keylistp +array, referencing a string which matches the first token in the string + or \-1 if the string contains no tokens or +.Fa keylistp +does not contain a matching string. +.Pp +If the token is of the form ``name=value'', the location referenced by +.Fa valuep +will be set to point to the start of the ``value'' portion of the token. +.Pp +On return from +.Fn getsubopt , +.Fa optionp +will be set to point to the start of the next token in the string, +or the null at the end of the string if no more tokens are present. +The external variable +.Fa suboptarg +will be set to point to the start of the current token, or +.Dv NULL +if no +tokens were present. +The argument +.Fa valuep +will be set to point to the ``value'' portion of the token, or +.Dv NULL +if no ``value'' portion was present. +.Sh EXAMPLES +.Bd -literal -compact +char *keylistp[] = { + #define ONE 0 + "one", + #define TWO 1 + "two", + NULL +}; + +\&... + +extern char *optarg, *suboptarg; +char *options, *value; + +while ((ch = getopt(argc, argv, "ab:")) != \-1) { + switch(ch) { + case 'a': + /* process ``a'' option */ + break; + case 'b': + options = optarg; + while (*options) { + switch(getsubopt(&options, keylistp, &value)) { + case ONE: + /* process ``one'' sub option */ + break; + case TWO: + /* process ``two'' sub option */ + if (!value) + error("no value for two"); + i = atoi(value); + break; + case \-1: + if (suboptarg) + error("illegal sub option %s", + suboptarg); + else + error("missing sub option"); + break; + } + break; + } +.Ed +.Sh SEE ALSO +.Xr getopt 3 , +.Xr strsep 3 +.Sh HISTORY +The +.Fn getsubopt +function first appeared in +.Bx 4.4 . diff --git a/stdlib/FreeBSD/grantpt.3 b/stdlib/grantpt.3 similarity index 85% rename from stdlib/FreeBSD/grantpt.3 rename to stdlib/grantpt.3 index 795f4af..eb70e74 100644 --- a/stdlib/FreeBSD/grantpt.3 +++ b/stdlib/grantpt.3 @@ -31,28 +31,35 @@ .\" .\" $FreeBSD: src/lib/libc/stdlib/grantpt.3,v 1.3 2003/09/14 13:41:57 ru Exp $ .\" -.Dd December 23, 2002 +.Dd February 2, 2005 .Os .Dt GRANTPT 3 .Sh NAME .Nm grantpt , +.Nm posix_openpt , .Nm ptsname , -.Nm unlockpt , -.Nm posix_openpt +.Nm unlockpt .Nd pseudo-terminal access functions -.Sh LIBRARY -.Lb libc .Sh SYNOPSIS .In stdlib.h .Ft int -.Fn grantpt "int fildes" +.Fo grantpt +.Fa "int fildes" +.Fc .Ft "char *" -.Fn ptsname "int fildes" +.Fo ptsname +.Fa "int fildes" +.Fc .Ft int -.Fn unlockpt "int fildes" +.Fo unlockpt +.Fa "int fildes" +.Fc +.In stdlib.h .In fcntl.h .Ft int -.Fn posix_openpt "int mode" +.Fo posix_openpt +.Fa "int oflag" +.Fc .Sh DESCRIPTION The .Fn grantpt , @@ -73,10 +80,9 @@ of the slave device counterpart to the master device specified with .Fa fildes . The slave device's ownership is set to the real user ID -of the calling process, and the permissions are set to +of the calling process; its permissions are set to user readable-writable and group writable. -The group owner of the slave device is also set to the -group +The group owner of the slave device is also set to the group .Dq Li tty if it exists on the system; otherwise, it is left untouched. @@ -95,16 +101,17 @@ have been called. .Pp The .Fn unlockpt -function clears the lock held on the pseudo-terminal pair -for the master device specified with -.Fa fildes . +function unlocks the slave pseudo-terminal device associated +with the master device to which +.Fa fildes +refers. .Pp The .Fn posix_openpt function opens the first available master pseudo-terminal device and returns a descriptor to it. The -.Fa mode +.Fa oflag argument specifies the flags used for opening the device: .Bl -tag -width ".Dv O_NOCTTY" @@ -165,7 +172,7 @@ function may fail and set to: .Bl -tag -width Er .It Bq Er EINVAL -.Fa mode +.Fa oflag consists of an invalid mode bit. .It Bq Er EAGAIN The system has no available pseudo-terminal devices. @@ -189,10 +196,40 @@ function may also fail and set for any of the errors specified for the .Xr open 2 system call. +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +.Ft int +.br +.Fo grantpt +.Fa "int fildes" +.Fc ; +.Pp +.Ft "char *" +.br +.Fo ptsname +.Fa "int fildes" +.Fc ; +.Pp +.Ft int +.br +.Fo unlockpt +.Fa "int fildes" +.Fc ; +.Pp +.Fd #include +.Pp +.Ft int +.br +.Fo posix_openpt +.Fa "int oflag" +.Fc ; .Sh SEE ALSO .Xr open 2 , .Xr pty 4 , -.Xr tty 4 +.Xr tty 4 , +.Xr compat 5 .Sh STANDARDS The .Fn grantpt , @@ -202,24 +239,3 @@ and .Fn posix_openpt functions conform to .St -p1003.1-2001 . -.Sh HISTORY -The -.Fn grantpt , -.Fn ptsname , -.Fn unlockpt , -and -.Fn posix_openpt -functions appeared in -.Fx 5.0 . -.Sh NOTES -The purpose of the -.Fn unlockpt -function has no meaning in -.Fx . -.Pp -The flag -.Dv O_NOCTTY -is included for compatibility; in -.Fx , -opening a terminal does not cause it to become -a process's controlling terminal. diff --git a/stdlib/grantpt.c b/stdlib/grantpt.c new file mode 100644 index 0000000..d0411ba --- /dev/null +++ b/stdlib/grantpt.c @@ -0,0 +1,94 @@ +/* + * 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 +#include +#include + +/* + * posix_openpt call for cloning pty implementation. + * + * Just open /dev/ptmx + */ +int +posix_openpt(int flags) +{ + int fd = open("/dev/ptmx", flags); + if (fd >= 0) + return fd; + return -1; +} + +/* + * grantpt call for cloning pty implementation. + * + * Change UID and GID of slave pty associated with master pty whose + * fd is provided, to the real UID and real GID of the calling thread. + */ +int +grantpt(int fd) +{ + return ioctl(fd, TIOCPTYGRANT); +} + +/* + * ptsname call for cloning pty implementation. + * + * NOTE: Returns a pointer to a static buffer, which will be overwritten on + * subsequent calls. + */ +char * +ptsname(int fd) +{ + static char ptsnamebuf[ 128]; /* ioctl knows length */ + int error; + char *retval = NULL; + struct stat sbuf; + + error = ioctl(fd, TIOCPTYGNAME, ptsnamebuf); + if (!error) { + /* + * XXX TSD + * + * POSIX: Handle device rename test case, which is expected + * to fail if the pty has been renamed. + */ + if (stat(ptsnamebuf, &sbuf) == 0) + retval = ptsnamebuf; + } + + return (retval); +} + +/* + * unlockpt call for cloning pty implementation. + * + * Unlock the slave pty associated with the master to which fd refers. + */ +int +unlockpt(int fd) +{ + return ioctl(fd, TIOCPTYUNLK); +} diff --git a/stdlib/hcreate-fbsd.c b/stdlib/hcreate-fbsd.c new file mode 100644 index 0000000..6ab33e5 --- /dev/null +++ b/stdlib/hcreate-fbsd.c @@ -0,0 +1,185 @@ +/* $NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $ */ + +/* + * Copyright (c) 2001 Christopher G. Demetriou + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 4. 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 ``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. + * + * <> + */ + +/* + * hcreate() / hsearch() / hdestroy() + * + * SysV/XPG4 hash table functions. + * + * Implementation done based on NetBSD manual page and Solaris manual page, + * plus my own personal experience about how they're supposed to work. + * + * I tried to look at Knuth (as cited by the Solaris manual page), but + * nobody had a copy in the office, so... + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include +#include +#include +#include +#include +#include + +/* + * DO NOT MAKE THIS STRUCTURE LARGER THAN 32 BYTES (4 ptrs on 64-bit + * ptr machine) without adjusting MAX_BUCKETS_LG2 below. + */ +struct internal_entry { + SLIST_ENTRY(internal_entry) link; + ENTRY ent; +}; +SLIST_HEAD(internal_head, internal_entry); + +#define MIN_BUCKETS_LG2 4 +#define MIN_BUCKETS (1 << MIN_BUCKETS_LG2) + +/* + * max * sizeof internal_entry must fit into size_t. + * assumes internal_entry is <= 32 (2^5) bytes. + */ +#define MAX_BUCKETS_LG2 (sizeof (size_t) * 8 - 1 - 5) +#define MAX_BUCKETS ((size_t)1 << MAX_BUCKETS_LG2) + +/* Default hash function, from db/hash/hash_func.c */ +extern u_int32_t (*__default_hash)(const void *, size_t); + +static struct internal_head *htable; +static size_t htablesize; + +int +hcreate(size_t nel) +{ + size_t idx; + unsigned int p2; + + /* Make sure this this isn't called when a table already exists. */ + if (htable != NULL) { + errno = EINVAL; + return 0; + } + + /* If nel is too small, make it min sized. */ + if (nel < MIN_BUCKETS) + nel = MIN_BUCKETS; + + /* If it's 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 ((nel & (nel - 1)) != 0) { + for (p2 = 0; nel != 0; p2++) + nel >>= 1; + nel = 1 << p2; + } + + /* Allocate the table. */ + htablesize = nel; + htable = malloc(htablesize * sizeof htable[0]); + if (htable == NULL) { + errno = ENOMEM; + return 0; + } + + /* Initialize it. */ + for (idx = 0; idx < htablesize; idx++) + SLIST_INIT(&htable[idx]); + + return 1; +} + +void +hdestroy(void) +{ + struct internal_entry *ie; + size_t idx; + + if (htable == NULL) + return; + + for (idx = 0; idx < htablesize; idx++) { + while (!SLIST_EMPTY(&htable[idx])) { + ie = SLIST_FIRST(&htable[idx]); + SLIST_REMOVE_HEAD(&htable[idx], link); + free(ie->ent.key); + free(ie); + } + } + free(htable); + htable = NULL; +} + +ENTRY * +hsearch(ENTRY item, ACTION action) +{ + struct internal_head *head; + struct internal_entry *ie; + uint32_t hashval; + size_t len; + + len = strlen(item.key); + hashval = (*__default_hash)(item.key, len); + + head = &htable[hashval & (htablesize - 1)]; + ie = SLIST_FIRST(head); + while (ie != NULL) { + if (strcmp(ie->ent.key, item.key) == 0) + break; + ie = SLIST_NEXT(ie, link); + } + + if (ie != NULL) + return &ie->ent; + else if (action == FIND) + return NULL; + + ie = malloc(sizeof *ie); + if (ie == NULL) + return NULL; + ie->ent.key = item.key; + ie->ent.data = item.data; + + SLIST_INSERT_HEAD(head, ie, link); + return &ie->ent; +} diff --git a/stdlib/hcreate.3 b/stdlib/hcreate.3 new file mode 120000 index 0000000..94586da --- /dev/null +++ b/stdlib/hcreate.3 @@ -0,0 +1 @@ +./hcreate.3 \ No newline at end of file diff --git a/stdlib/heapsort-fbsd.c b/stdlib/heapsort-fbsd.c new file mode 100644 index 0000000..e846be2 --- /dev/null +++ b/stdlib/heapsort-fbsd.c @@ -0,0 +1,185 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ronnie Kon at Mindcraft Inc., Kevin Lew and Elmer Yglesias. + * + * 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[] = "@(#)heapsort.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/heapsort.c,v 1.4 2002/03/21 22:48:41 obrien Exp $"); + +#include +#include +#include + +/* + * Swap two areas of size number of bytes. Although qsort(3) permits random + * blocks of memory to be sorted, sorting pointers is almost certainly the + * common case (and, were it not, could easily be made so). Regardless, it + * isn't worth optimizing; the SWAP's get sped up by the cache, and pointer + * arithmetic gets lost in the time required for comparison function calls. + */ +#define SWAP(a, b, count, size, tmp) { \ + count = size; \ + do { \ + tmp = *a; \ + *a++ = *b; \ + *b++ = tmp; \ + } while (--count); \ +} + +/* Copy one block of size size to another. */ +#define COPY(a, b, count, size, tmp1, tmp2) { \ + count = size; \ + tmp1 = a; \ + tmp2 = b; \ + do { \ + *tmp1++ = *tmp2++; \ + } while (--count); \ +} + +/* + * Build the list into a heap, where a heap is defined such that for + * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N. + * + * There two cases. If j == nmemb, select largest of Ki and Kj. If + * j < nmemb, select largest of Ki, Kj and Kj+1. + */ +#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \ + for (par_i = initval; (child_i = par_i * 2) <= nmemb; \ + par_i = child_i) { \ + child = base + child_i * size; \ + if (child_i < nmemb && compar(child, child + size) < 0) { \ + child += size; \ + ++child_i; \ + } \ + par = base + par_i * size; \ + if (compar(child, par) <= 0) \ + break; \ + SWAP(par, child, count, size, tmp); \ + } \ +} + +/* + * Select the top of the heap and 'heapify'. Since by far the most expensive + * action is the call to the compar function, a considerable optimization + * in the average case can be achieved due to the fact that k, the displaced + * elememt, is ususally quite small, so it would be preferable to first + * heapify, always maintaining the invariant that the larger child is copied + * over its parent's record. + * + * Then, starting from the *bottom* of the heap, finding k's correct place, + * again maintianing the invariant. As a result of the invariant no element + * is 'lost' when k is assigned its correct place in the heap. + * + * The time savings from this optimization are on the order of 15-20% for the + * average case. See Knuth, Vol. 3, page 158, problem 18. + * + * XXX Don't break the #define SELECT line, below. Reiser cpp gets upset. + */ +#define SELECT(par_i, child_i, nmemb, par, child, size, k, count, tmp1, tmp2) { \ + for (par_i = 1; (child_i = par_i * 2) <= nmemb; par_i = child_i) { \ + child = base + child_i * size; \ + if (child_i < nmemb && compar(child, child + size) < 0) { \ + child += size; \ + ++child_i; \ + } \ + par = base + par_i * size; \ + COPY(par, child, count, size, tmp1, tmp2); \ + } \ + for (;;) { \ + child_i = par_i; \ + par_i = child_i / 2; \ + child = base + child_i * size; \ + par = base + par_i * size; \ + if (child_i == 1 || compar(k, par) < 0) { \ + COPY(child, k, count, size, tmp1, tmp2); \ + break; \ + } \ + COPY(child, par, count, size, tmp1, tmp2); \ + } \ +} + +/* + * Heapsort -- Knuth, Vol. 3, page 145. Runs in O (N lg N), both average + * and worst. While heapsort is faster than the worst case of quicksort, + * the BSD quicksort does median selection so that the chance of finding + * a data set that will trigger the worst case is nonexistent. Heapsort's + * only advantage over quicksort is that it requires little additional memory. + */ +int +heapsort(vbase, nmemb, size, compar) + void *vbase; + size_t nmemb, size; + int (*compar)(const void *, const void *); +{ + int cnt, i, j, l; + char tmp, *tmp1, *tmp2; + char *base, *k, *p, *t; + + if (nmemb <= 1) + return (0); + + if (!size) { + errno = EINVAL; + return (-1); + } + + if ((k = malloc(size)) == NULL) + return (-1); + + /* + * Items are numbered from 1 to nmemb, so offset from size bytes + * below the starting address. + */ + base = (char *)vbase - size; + + for (l = nmemb / 2 + 1; --l;) + CREATE(l, nmemb, i, j, t, p, size, cnt, tmp); + + /* + * For each element of the heap, save the largest element into its + * final slot, save the displaced element (k), then recreate the + * heap. + */ + while (nmemb > 1) { + COPY(k, base + nmemb * size, cnt, size, tmp1, tmp2); + COPY(base + nmemb * size, base + size, cnt, size, tmp1, tmp2); + --nmemb; + SELECT(i, j, nmemb, t, p, size, k, cnt, tmp1, tmp2); + } + free(k); + return (0); +} diff --git a/stdlib/imaxabs-fbsd.c b/stdlib/imaxabs-fbsd.c new file mode 100644 index 0000000..531de24 --- /dev/null +++ b/stdlib/imaxabs-fbsd.c @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * 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/stdlib/imaxabs.c,v 1.1 2001/11/15 02:05:03 mike Exp $"); + +#include + +intmax_t +imaxabs(intmax_t j) +{ + return (j < 0 ? -j : j); +} diff --git a/stdlib/imaxabs.3 b/stdlib/imaxabs.3 new file mode 120000 index 0000000..da7c29d --- /dev/null +++ b/stdlib/imaxabs.3 @@ -0,0 +1 @@ +./imaxabs.3 \ No newline at end of file diff --git a/stdlib/imaxdiv-fbsd.c b/stdlib/imaxdiv-fbsd.c new file mode 100644 index 0000000..ff3087b --- /dev/null +++ b/stdlib/imaxdiv-fbsd.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * 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/stdlib/imaxdiv.c,v 1.1 2001/11/15 02:05:03 mike Exp $"); + +#include + +/* See comments in div.c for implementation details. */ +imaxdiv_t +imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t retval; + + retval.quot = numer / denom; + retval.rem = numer % denom; + if (numer >= 0 && retval.rem < 0) { + retval.quot++; + retval.rem -= denom; + } + return (retval); +} diff --git a/stdlib/imaxdiv.3 b/stdlib/imaxdiv.3 new file mode 100644 index 0000000..a9f5e12 --- /dev/null +++ b/stdlib/imaxdiv.3 @@ -0,0 +1,73 @@ +.\" Copyright (c) 2001 Mike Barcroft +.\" 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/stdlib/imaxdiv.3,v 1.2 2001/11/21 16:19:50 ru Exp $ +.\" +.Dd November 14, 2001 +.Dt IMAXDIV 3 +.Os +.Sh NAME +.Nm imaxdiv +.Nd returns quotient and remainder +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In inttypes.h +.Ft imaxdiv_t +.Fn imaxdiv "intmax_t numer" "intmax_t denom" +.Sh DESCRIPTION +The +.Fn imaxdiv +function computes the value of +.Fa numer , +divided by +.Fa denom . +The stored result is returned in the form of the +.Vt imaxdiv_t +type. +.Pp +The +.Vt imaxdiv_t +type is defined as: +.Bd -literal -offset indent +typedef struct { + intmax_t quot; /* Quotient. */ + intmax_t rem; /* Remainder. */ +} imaxdiv_t; +.Ed +.Sh SEE ALSO +.Xr div 3 , +.Xr ldiv 3 , +.Xr lldiv 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn imaxdiv +function conforms to +.St -isoC-99 . +.Sh HISTORY +The +.Fn imaxdiv +function first appeared in +.Fx 5.0 . diff --git a/stdlib/insque-fbsd.c b/stdlib/insque-fbsd.c new file mode 100644 index 0000000..92984b0 --- /dev/null +++ b/stdlib/insque-fbsd.c @@ -0,0 +1,47 @@ +/* + * Initial implementation: + * Copyright (c) 2002 Robert Drehmel + * All rights reserved. + * + * As long as the above copyright statement and this notice remain + * unchanged, you can do what ever you want with this file. + */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/insque.c,v 1.3 2003/01/04 07:34:41 tjr Exp $"); + +#define _SEARCH_PRIVATE +#include +#ifdef DEBUG +#include +#else +#include /* for NULL */ +#endif + +void +insque(void *element, void *pred) +{ + struct que_elem *prev, *next, *elem; + + elem = (struct que_elem *)element; + prev = (struct que_elem *)pred; + + if (prev == NULL) { + elem->prev = elem->next = NULL; + return; + } + + next = prev->next; + if (next != NULL) { +#ifdef DEBUG + if (next->prev != prev) { + fprintf(stderr, "insque: Inconsistency detected:" + " next(%p)->prev(%p) != prev(%p)\n", + next, next->prev, prev); + } +#endif + next->prev = elem; + } + prev->next = elem; + elem->prev = prev; + elem->next = next; +} diff --git a/stdlib/insque.3 b/stdlib/insque.3 new file mode 100644 index 0000000..b1d47d6 --- /dev/null +++ b/stdlib/insque.3 @@ -0,0 +1,61 @@ +.\" +.\" Initial implementation: +.\" Copyright (c) 2002 Robert Drehmel +.\" All rights reserved. +.\" +.\" 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/insque.3,v 1.3 2003/02/25 21:59:36 robert Exp $ +.\" +.Dd October 10, 2002 +.Dt INSQUE 3 +.Os +.Sh NAME +.Nm insque , +.Nm remque +.Nd doubly-linked list management +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In search.h +.Ft void +.Fn insque "void *element" "void *pred" +.Ft void +.Fn remque "void *element" +.Sh DESCRIPTION +The +.Fn insque +and +.Fn remque +functions encapsulate the ever-repeating task of doing insertion and +removal operations on doubly linked lists. +The functions expect their +arguments to point to a structure whose first and second members are +pointers to the next and previous element, respectively. +The +.Fn insque +function also allows the +.Fa pred +argument to be a +.Dv NULL +pointer for the initialization of a new list's +head element. +.Sh STANDARDS +The +.Fn insque +and +.Fn remque +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn insque +and +.Fn remque +functions appeared in +.Bx 4.2 . +In +.Fx 5.0 , +they reappeared conforming to +.St -p1003.1-2001 . diff --git a/stdlib/l64a.c b/stdlib/l64a.c index cc4b60a..32b904b 100644 --- a/stdlib/l64a.c +++ b/stdlib/l64a.c @@ -1,25 +1,3 @@ -/* - * 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@ - */ /* * Written by J.T. Conklin . * Public domain. @@ -33,18 +11,28 @@ static char *rcsid = "$OpenBSD: l64a.c,v 1.3 1997/08/17 22:58:34 millert Exp $"; #include char * +#ifdef __LP64__ +l64a(v) + long v; +#else /* !__LP64__ */ l64a(value) long value; +#endif /* __LP64__ */ { static char buf[8]; +#ifdef __LP64__ + int value = v; +#endif /* __LP64__ */ char *s = buf; int digit; int i; +#ifndef __LP64__ if (value < 0) { errno = EINVAL; return(NULL); } +#endif /* __LP64__ */ for (i = 0; value != 0 && i < 6; i++) { digit = value & 0x3f; diff --git a/stdlib/labs-fbsd.c b/stdlib/labs-fbsd.c new file mode 100644 index 0000000..42e63d1 --- /dev/null +++ b/stdlib/labs-fbsd.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include + +long +labs(j) + long j; +{ + return(j < 0 ? -j : j); +} diff --git a/stdlib/labs.3 b/stdlib/labs.3 new file mode 100644 index 0000000..20bdf15 --- /dev/null +++ b/stdlib/labs.3 @@ -0,0 +1,71 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd November 14, 2001 +.Dt LABS 3 +.Os +.Sh NAME +.Nm labs +.Nd return the absolute value of a long integer +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft long +.Fn labs "long i" +.Sh DESCRIPTION +The +.Fn labs +function +returns the absolute value of the long integer +.Fa i . +.Sh SEE ALSO +.Xr abs 3 , +.Xr cabs 3 , +.Xr floor 3 , +.Xr imaxabs 3 , +.Xr llabs 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn labs +function +conforms to +.St -isoC . +.Sh BUGS +The absolute value of the most negative integer remains negative. diff --git a/stdlib/ldiv-fbsd.c b/stdlib/ldiv-fbsd.c new file mode 100644 index 0000000..560d5c2 --- /dev/null +++ b/stdlib/ldiv-fbsd.c @@ -0,0 +1,60 @@ +/* + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include /* ldiv_t */ + +ldiv_t +ldiv(num, denom) + long num, denom; +{ + ldiv_t r; + + /* see div.c for comments */ + + r.quot = num / denom; + r.rem = num % denom; + if (num >= 0 && r.rem < 0) { + r.quot++; + r.rem -= denom; + } + return (r); +} diff --git a/stdlib/ldiv.3 b/stdlib/ldiv.3 new file mode 100644 index 0000000..0d83562 --- /dev/null +++ b/stdlib/ldiv.3 @@ -0,0 +1,76 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd November 14, 2001 +.Dt LDIV 3 +.Os +.Sh NAME +.Nm ldiv +.Nd return quotient and remainder from division +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft ldiv_t +.Fn ldiv "long numer" "long denom" +.Sh DESCRIPTION +The +.Fn ldiv +function +computes the value +.Fa numer Ns / Ns Fa denom +(numerator/denominator). +Ir returns the quotient and remainder in a structure named +.Vt ldiv_t +that contains two +.Vt long +members named +.Va quot +and +.Va rem . +.Sh SEE ALSO +.Xr div 3 , +.Xr imaxdiv 3 , +.Xr lldiv 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn ldiv +function +conforms to +.St -isoC-99 . diff --git a/stdlib/llabs-fbsd.c b/stdlib/llabs-fbsd.c new file mode 100644 index 0000000..4721fce --- /dev/null +++ b/stdlib/llabs-fbsd.c @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * 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/stdlib/llabs.c,v 1.1 2001/11/15 02:05:03 mike Exp $"); + +#include + +long long +llabs(long long j) +{ + return (j < 0 ? -j : j); +} diff --git a/stdlib/llabs.3 b/stdlib/llabs.3 new file mode 100644 index 0000000..96b104f --- /dev/null +++ b/stdlib/llabs.3 @@ -0,0 +1,62 @@ +.\" Copyright (c) 2001 Mike Barcroft +.\" 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/stdlib/llabs.3,v 1.2 2001/11/21 16:19:50 ru Exp $ +.\" +.Dd November 14, 2001 +.Dt LLABS 3 +.Os +.Sh NAME +.Nm llabs +.Nd returns absolute value +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft "long long" +.Fn llabs "long long i" +.Sh DESCRIPTION +The +.Fn llabs +function returns the absolute value of +.Fa i . +.Sh SEE ALSO +.Xr abs 3 , +.Xr fabs 3 , +.Xr hypot 3 , +.Xr imaxabs 3 , +.Xr labs 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn llabs +function conforms to +.St -isoC-99 . +.Sh HISTORY +The +.Fn llabs +function first appeared in +.Fx 5.0 . +.Sh BUGS +The absolute value of the most negative integer remains negative. diff --git a/stdlib/lldiv-fbsd.c b/stdlib/lldiv-fbsd.c new file mode 100644 index 0000000..c9a4853 --- /dev/null +++ b/stdlib/lldiv-fbsd.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * 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/stdlib/lldiv.c,v 1.1 2001/11/15 02:05:03 mike Exp $"); + +#include + +/* See comments in div.c for implementation details. */ +lldiv_t +lldiv(long long numer, long long denom) +{ + lldiv_t retval; + + retval.quot = numer / denom; + retval.rem = numer % denom; + if (numer >= 0 && retval.rem < 0) { + retval.quot++; + retval.rem -= denom; + } + return (retval); +} diff --git a/stdlib/lldiv.3 b/stdlib/lldiv.3 new file mode 100644 index 0000000..98f4813 --- /dev/null +++ b/stdlib/lldiv.3 @@ -0,0 +1,73 @@ +.\" Copyright (c) 2001 Mike Barcroft +.\" 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/stdlib/lldiv.3,v 1.2 2001/11/21 16:19:50 ru Exp $ +.\" +.Dd November 14, 2001 +.Dt LLDIV 3 +.Os +.Sh NAME +.Nm lldiv +.Nd returns quotient and remainder +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft lldiv_t +.Fn lldiv "long long numer" "long long denom" +.Sh DESCRIPTION +The +.Fn lldiv +function computes the value of +.Fa numer , +divided by +.Fa denom . +It returns the stored result in the form of the +.Vt lldiv_t +type. +.Pp +The +.Vt lldiv_t +type is defined as: +.Bd -literal -offset indent +typedef struct { + long long quot; /* Quotient. */ + long long rem; /* Remainder. */ +} lldiv_t; +.Ed +.Sh SEE ALSO +.Xr div 3 , +.Xr imaxdiv 3 , +.Xr ldiv 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn lldiv +function conforms to +.St -isoC-99 . +.Sh HISTORY +The +.Fn lldiv +function first appeared in +.Fx 5.0 . diff --git a/stdlib/lsearch-fbsd.c b/stdlib/lsearch-fbsd.c new file mode 100644 index 0000000..791bc49 --- /dev/null +++ b/stdlib/lsearch-fbsd.c @@ -0,0 +1,64 @@ +/* + * Initial implementation: + * Copyright (c) 2002 Robert Drehmel + * All rights reserved. + * + * As long as the above copyright statement and this notice remain + * unchanged, you can do what ever you want with this file. + */ +#include +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/lsearch.c,v 1.1 2002/10/16 14:29:22 robert Exp $"); + +#define _SEARCH_PRIVATE +#include +#include /* for uint8_t */ +#include /* for NULL */ +#include /* for memcpy() prototype */ + +static void *lwork(const void *, const void *, size_t *, size_t, + int (*)(const void *, const void *), int); + +void *lsearch(const void *key, void *base, size_t *nelp, size_t width, + int (*compar)(const void *, const void *)) +{ + + return (lwork(key, base, nelp, width, compar, 1)); +} + +void *lfind(const void *key, const void *base, size_t *nelp, size_t width, + int (*compar)(const void *, const void *)) +{ + + return (lwork(key, base, nelp, width, compar, 0)); +} + +static void * +lwork(const void *key, const void *base, size_t *nelp, size_t width, + int (*compar)(const void *, const void *), int addelem) +{ + uint8_t *ep, *endp; + + /* + * Cast to an integer value first to avoid the warning for removing + * 'const' via a cast. + */ + ep = (uint8_t *)(uintptr_t)base; + for (endp = (uint8_t *)(ep + width * *nelp); ep < endp; ep += width) { + if (compar(key, ep) == 0) + return (ep); + } + + /* lfind() shall return when the key was not found. */ + if (!addelem) + return (NULL); + + /* + * lsearch() adds the key to the end of the table and increments + * the number of elements. + */ + memcpy(endp, key, width); + ++*nelp; + + return (endp); +} diff --git a/stdlib/lsearch.3 b/stdlib/lsearch.3 new file mode 100644 index 0000000..94fcee0 --- /dev/null +++ b/stdlib/lsearch.3 @@ -0,0 +1,105 @@ +.\" +.\" Initial implementation: +.\" Copyright (c) 2002 Robert Drehmel +.\" All rights reserved. +.\" +.\" 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 $ +.\" +.Dd October 11, 2002 +.Dt LSEARCH 3 +.Os +.Sh NAME +.Nm lfind , +.Nm lsearch +.Nd linear search and append +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In search.h +.Ft "void *" +.Fo lfind +.Fa "const void *key" "const void *base" "size_t *nelp" "size_t width" +.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" +.Fc +.Ft "void *" +.Fo lsearch +.Fa "const void *key" "void *base" "size_t *nelp" "size_t width" +.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" +.Fc +.Sh DESCRIPTION +The +.Fn lsearch +and +.Fn lfind +functions walk linearly through an array, comparing each element with +the one to be sought, by means of a supplied comparison function. +.Pp +The +.Fa key +argument +points to an element that matches the one that is searched. +The array's address in memory is denoted by the +.Fa base +argument. +The width of one element (i.e., the size as returned by +.Fn sizeof ) +is passed as the +.Fa width +argument. +The number of valid elements contained in the array (not the number of +elements the array has space reserved for) is given in the integer pointed +to by +.Fa nelp . +The +.Fa compar +argument points to a function which compares its two arguments and returns +zero if they are matching, and non-zero otherwise. +.Pp +If no matching element was found in the array, +.Fn lsearch +copies +.Fa key +into the position after the last element and increments the +integer pointed to by +.Fa nelp . +.Sh RETURN VALUES +The +.Fn lsearch +and +.Fn lfind +functions +return a pointer to the first element found. +If no element was found, +.Fn lsearch +returns a pointer to the newly added element, whereas +.Fn lfind +returns +.Dv NULL . +Both functions return +.Dv NULL +if an error occurs. +.Sh SEE ALSO +.Xr bsearch 3 , +.Xr hsearch 3 , +.Xr tsearch 3 +.Sh HISTORY +The +.Fn lsearch +and +.Fn lfind +functions appeared in +.Bx 4.2 . +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 new file mode 100644 index 0000000..d6ebc9b --- /dev/null +++ b/stdlib/memory.3 @@ -0,0 +1,140 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt MEMORY 3 +.Os +.Sh NAME +.Nm alloca , +.Nm calloc , +.Nm free , +.Nm malloc , +.Nm mmap , +.Nm realloc +.Nd general memory allocation operations +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft void * +.Fo alloca +.Fa "size_t size" +.Fc +.Ft void * +.Fo calloc +.Fa "size_t nelem" +.Fa "size_t elsize" +.Fc +.Ft void +.Fo free +.Fa "void *ptr" +.Fc +.Ft void * +.Fo malloc +.Fa "size_t size" +.Fc +.Ft void * +.Fo realloc +.Fa "void *ptr" +.Fa "size_t size" +.Fc +.In sys/mman.h +.Ft void * +.Fo mmap +.Fa "void * addr" +.Fa "size_t len" +.Fa "int prot" +.Fa "int flags" +.Fa "int fildes" +.Fa "off_t off" +.Fc +.Sh DESCRIPTION +These functions allocate and free memory for the calling process. +They are described in the +individual manual pages. +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +.Ft void * +.br +.Fo mmap +.Fa "void * addr" +.Fa "size_t len" +.Fa "int prot" +.Fa "int flags" +.Fa "int fildes" +.Fa "off_t off" +.Fc ; +.Pp +The include file +.In sys/types.h +is needed for this function. +.Sh COMPATIBILITY +.Fn mmap +now returns with +.Va errno +set to EINVAL in places that historically succeeded. +The rules have changed as follows: +.Bl -bullet +.It +The +.Fa flags +parameter must specify either MAP_PRIVATE or MAP_SHARED. +.It +The +.Fa size +parameter must not be 0. +.It +The +.Fa off +parameter must be a multiple of pagesize, +as returned by +.Fn sysconf . +.El +.Sh SEE ALSO +.Xr mmap 2 , +.Xr alloca 3 , +.Xr calloc 3 , +.Xr free 3 , +.Xr malloc 3 , +.Xr realloc 3 , +.Xr compat 5 +.Sh STANDARDS +These functions, with the exception of +.Fn alloca +and +.Fn mmap +conform to +.St -isoC . diff --git a/stdlib/merge-fbsd.c b/stdlib/merge-fbsd.c new file mode 100644 index 0000000..711b9cd --- /dev/null +++ b/stdlib/merge-fbsd.c @@ -0,0 +1,352 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Peter McIlroy. + * + * 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[] = "@(#)merge.c 8.2 (Berkeley) 2/14/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/merge.c,v 1.6 2002/03/21 22:48:42 obrien Exp $"); + +/* + * Hybrid exponential search/linear search merge sort with hybrid + * natural/pairwise first pass. Requires about .3% more comparisons + * for random data than LSMS with pairwise first pass alone. + * It works for objects as small as two bytes. + */ + +#define NATURAL +#define THRESHOLD 16 /* Best choice for natural merge cut-off. */ + +/* #define NATURAL to get hybrid natural merge. + * (The default is pairwise merging.) + */ + +#include + +#include +#include +#include + +static void setup(u_char *, u_char *, size_t, size_t, int (*)()); +static void insertionsort(u_char *, size_t, size_t, int (*)()); + +#define ISIZE sizeof(int) +#define PSIZE sizeof(u_char *) +#define ICOPY_LIST(src, dst, last) \ + do \ + *(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE; \ + while(src < last) +#define ICOPY_ELT(src, dst, i) \ + do \ + *(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE; \ + while (i -= ISIZE) + +#define CCOPY_LIST(src, dst, last) \ + do \ + *dst++ = *src++; \ + while (src < last) +#define CCOPY_ELT(src, dst, i) \ + do \ + *dst++ = *src++; \ + while (i -= 1) + +/* + * Find the next possible pointer head. (Trickery for forcing an array + * to do double duty as a linked list when objects do not align with word + * boundaries. + */ +/* Assumption: PSIZE is a power of 2. */ +#define EVAL(p) (u_char **) \ + ((u_char *)0 + \ + (((u_char *)p + PSIZE - 1 - (u_char *) 0) & ~(PSIZE - 1))) + +/* + * Arguments are as for qsort. + */ +int +mergesort(base, nmemb, size, cmp) + void *base; + size_t nmemb; + size_t size; + int (*cmp)(const void *, const void *); +{ + int i, sense; + int big, iflag; + u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; + u_char *list2, *list1, *p2, *p, *last, **p1; + + if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */ + errno = EINVAL; + return (-1); + } + + if (nmemb == 0) + return (0); + + /* + * XXX + * Stupid subtraction for the Cray. + */ + iflag = 0; + if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE)) + iflag = 1; + + if ((list2 = malloc(nmemb * size + PSIZE)) == NULL) + return (-1); + + list1 = base; + setup(list1, list2, nmemb, size, cmp); + last = list2 + nmemb * size; + i = big = 0; + while (*EVAL(list2) != last) { + l2 = list1; + p1 = EVAL(list1); + for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) { + p2 = *EVAL(p2); + f1 = l2; + f2 = l1 = list1 + (p2 - list2); + if (p2 != last) + p2 = *EVAL(p2); + l2 = list1 + (p2 - list2); + while (f1 < l1 && f2 < l2) { + if ((*cmp)(f1, f2) <= 0) { + q = f2; + b = f1, t = l1; + sense = -1; + } else { + q = f1; + b = f2, t = l2; + sense = 0; + } + if (!big) { /* here i = 0 */ + while ((b += size) < t && cmp(q, b) >sense) + if (++i == 6) { + big = 1; + goto EXPONENTIAL; + } + } else { +EXPONENTIAL: for (i = size; ; i <<= 1) + if ((p = (b + i)) >= t) { + if ((p = t - size) > b && + (*cmp)(q, p) <= sense) + t = p; + else + b = p; + break; + } else if ((*cmp)(q, p) <= sense) { + t = p; + if (i == size) + big = 0; + goto FASTCASE; + } else + b = p; + while (t > b+size) { + i = (((t - b) / size) >> 1) * size; + if ((*cmp)(q, p = b + i) <= sense) + t = p; + else + b = p; + } + goto COPY; +FASTCASE: while (i > size) + if ((*cmp)(q, + p = b + (i >>= 1)) <= sense) + t = p; + else + b = p; +COPY: b = t; + } + i = size; + if (q == f1) { + if (iflag) { + ICOPY_LIST(f2, tp2, b); + ICOPY_ELT(f1, tp2, i); + } else { + CCOPY_LIST(f2, tp2, b); + CCOPY_ELT(f1, tp2, i); + } + } else { + if (iflag) { + ICOPY_LIST(f1, tp2, b); + ICOPY_ELT(f2, tp2, i); + } else { + CCOPY_LIST(f1, tp2, b); + CCOPY_ELT(f2, tp2, i); + } + } + } + if (f2 < l2) { + if (iflag) + ICOPY_LIST(f2, tp2, l2); + else + CCOPY_LIST(f2, tp2, l2); + } else if (f1 < l1) { + if (iflag) + ICOPY_LIST(f1, tp2, l1); + else + CCOPY_LIST(f1, tp2, l1); + } + *p1 = l2; + } + tp2 = list1; /* swap list1, list2 */ + list1 = list2; + list2 = tp2; + last = list2 + nmemb*size; + } + if (base == list2) { + memmove(list2, list1, nmemb*size); + list2 = list1; + } + free(list2); + return (0); +} + +#define swap(a, b) { \ + s = b; \ + i = size; \ + do { \ + tmp = *a; *a++ = *s; *s++ = tmp; \ + } while (--i); \ + a -= size; \ + } +#define reverse(bot, top) { \ + s = top; \ + do { \ + i = size; \ + do { \ + tmp = *bot; *bot++ = *s; *s++ = tmp; \ + } while (--i); \ + s -= size2; \ + } while(bot < s); \ +} + +/* + * Optional hybrid natural/pairwise first pass. Eats up list1 in runs of + * increasing order, list2 in a corresponding linked list. Checks for runs + * when THRESHOLD/2 pairs compare with same sense. (Only used when NATURAL + * is defined. Otherwise simple pairwise merging is used.) + */ +void +setup(list1, list2, n, size, cmp) + size_t n, size; + int (*cmp)(const void *, const void *); + u_char *list1, *list2; +{ + int i, length, size2, tmp, sense; + u_char *f1, *f2, *s, *l2, *last, *p2; + + size2 = size*2; + if (n <= 5) { + insertionsort(list1, n, size, cmp); + *EVAL(list2) = (u_char*) list2 + n*size; + return; + } + /* + * Avoid running pointers out of bounds; limit n to evens + * for simplicity. + */ + i = 4 + (n & 1); + insertionsort(list1 + (n - i) * size, i, size, cmp); + last = list1 + size * (n - i); + *EVAL(list2 + (last - list1)) = list2 + n * size; + +#ifdef NATURAL + p2 = list2; + f1 = list1; + sense = (cmp(f1, f1 + size) > 0); + for (; f1 < last; sense = !sense) { + length = 2; + /* Find pairs with same sense. */ + for (f2 = f1 + size2; f2 < last; f2 += size2) { + if ((cmp(f2, f2+ size) > 0) != sense) + break; + length += 2; + } + if (length < THRESHOLD) { /* Pairwise merge */ + do { + p2 = *EVAL(p2) = f1 + size2 - list1 + list2; + if (sense > 0) + swap (f1, f1 + size); + } while ((f1 += size2) < f2); + } else { /* Natural merge */ + l2 = f2; + for (f2 = f1 + size2; f2 < l2; f2 += size2) { + if ((cmp(f2-size, f2) > 0) != sense) { + p2 = *EVAL(p2) = f2 - list1 + list2; + if (sense > 0) + reverse(f1, f2-size); + f1 = f2; + } + } + if (sense > 0) + reverse (f1, f2-size); + f1 = f2; + if (f2 < last || cmp(f2 - size, f2) > 0) + p2 = *EVAL(p2) = f2 - list1 + list2; + else + p2 = *EVAL(p2) = list2 + n*size; + } + } +#else /* pairwise merge only. */ + for (f1 = list1, p2 = list2; f1 < last; f1 += size2) { + p2 = *EVAL(p2) = p2 + size2; + if (cmp (f1, f1 + size) > 0) + swap(f1, f1 + size); + } +#endif /* NATURAL */ +} + +/* + * This is to avoid out-of-bounds addresses in sorting the + * last 4 elements. + */ +static void +insertionsort(a, n, size, cmp) + u_char *a; + size_t n, size; + int (*cmp)(const void *, const void *); +{ + u_char *ai, *s, *t, *u, tmp; + int i; + + for (ai = a+size; --n >= 1; ai += size) + for (t = ai; t > a; t -= size) { + u = t - size; + if (cmp(u, t) <= 0) + break; + swap(u, t); + } +} diff --git a/stdlib/putenv-fbsd.c b/stdlib/putenv-fbsd.c new file mode 100644 index 0000000..03cdb16 --- /dev/null +++ b/stdlib/putenv-fbsd.c @@ -0,0 +1,103 @@ +/*- + * 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[] = "@(#)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 $"); + +#include +#include +#include +#include +#include +#include +#include + +extern malloc_zone_t *__zone0; +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 +/* + * _putenvp -- SPI using an arbitrary pointer to string array (the array must + * have been created with malloc) and an env state, created by _allocenvstate(). + * Returns ptr to value associated with name, if any, else NULL. + */ +int +_putenvp(char *str, char ***envp, void *state) +{ + /* insure __zone0 is set up */ + if (!__zone0) { + __zone0 = malloc_create_zone(0, 0); + if (!__zone0) { + errno = ENOMEM; + return (-1); + } + } + return (__setenv(str, NULL, 1, 0, envp, (state ? (malloc_zone_t *)state : __zone0))); +} +#endif /* BUILDING_VARIANT */ + +int +putenv(str) + char *str; +{ +#if __DARWIN_UNIX03 + if (str == NULL || *str == 0 || index(str, '=') == NULL) { + errno = EINVAL; + return (-1); + } +#else /* !__DARWIN_UNIX03 */ + if (index(str, '=') == NULL) + return (-1); +#endif /* __DARWIN_UNIX03 */ + /* insure __zone0 is set up before calling __malloc_check_env_name */ + if (!__zone0) { + __zone0 = malloc_create_zone(0, 0); + if (!__zone0) { + errno = ENOMEM; + return (-1); + } + } + __malloc_check_env_name(str); /* see if we are changing a malloc environment variable */ + return (__setenv(str, NULL, 1, +#if __DARWIN_UNIX03 + 0, +#else /* !__DARWIN_UNIX03 */ + -1, +#endif /* __DARWIN_UNIX03 */ + _NSGetEnviron(), __zone0)); +} diff --git a/stdlib/qsort-fbsd.c b/stdlib/qsort-fbsd.c new file mode 100644 index 0000000..056bd87 --- /dev/null +++ b/stdlib/qsort-fbsd.c @@ -0,0 +1,197 @@ +/*- + * Copyright (c) 1992, 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[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/qsort.c,v 1.12 2002/09/10 02:04:49 wollman Exp $"); + +#include + +#ifdef I_AM_QSORT_R +typedef int cmp_t(void *, const void *, const void *); +#else +typedef int cmp_t(const void *, const void *); +#endif +static inline char *med3(char *, char *, char *, cmp_t *, void *) __attribute__((always_inline)); +static inline void swapfunc(char *, char *, int, int) __attribute__((always_inline)); + +#define min(a, b) (a) < (b) ? a : b + +/* + * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / sizeof (TYPE); \ + TYPE *pi = (TYPE *) (parmi); \ + TYPE *pj = (TYPE *) (parmj); \ + do { \ + TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static inline void +swapfunc(a, b, n, swaptype) + char *a, *b; + int n, swaptype; +{ + if(swaptype <= 1) + swapcode(long, a, b, n) + else + swapcode(char, a, b, n) +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(a); \ + *(long *)(a) = *(long *)(b); \ + *(long *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) + +#ifdef I_AM_QSORT_R +#define CMP(t, x, y) (cmp((t), (x), (y))) +#else +#define CMP(t, x, y) (cmp((x), (y))) +#endif + +static inline char * +med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk +#ifndef I_AM_QSORT_R +__unused +#endif +) +{ + return CMP(thunk, a, b) < 0 ? + (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) + :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); +} + +#ifdef I_AM_QSORT_R +void +qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) +#else +#define thunk NULL +void +qsort(void *a, size_t n, size_t es, cmp_t *cmp) +#endif +{ + char *pa, *pb, *pc, *pd, *pl, *pm, *pn; + int d, r, swaptype, swap_cnt; + +loop: SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) { + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *)a + (n / 2) * es; + if (n > 7) { + pl = a; + pn = (char *)a + (n - 1) * es; + if (n > 40) { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); + pm = med3(pm - d, pm, pm + d, cmp, thunk); + pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); + } + pm = med3(pl, pm, pn, cmp, thunk); + } + swap(a, pm); + pa = pb = (char *)a + es; + + pc = pd = (char *)a + (n - 1) * es; + for (;;) { + while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + if (swap_cnt == 0) { /* Switch to insertion sort */ + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + + pn = (char *)a + n * es; + r = min(pa - (char *)a, pb - pa); + vecswap(a, pb - r, r); + r = min(pd - pc, pn - pd - es); + vecswap(pb, pn - r, r); + if ((r = pb - pa) > es) +#ifdef I_AM_QSORT_R + qsort_r(a, r / es, es, thunk, cmp); +#else + qsort(a, r / es, es, cmp); +#endif + if ((r = pd - pc) > es) { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +/* qsort(pn - r, r / es, es, cmp);*/ +} diff --git a/stdlib/qsort.3 b/stdlib/qsort.3 new file mode 100644 index 0000000..5d6f5c6 --- /dev/null +++ b/stdlib/qsort.3 @@ -0,0 +1,293 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd September 30, 2003 +.Dt QSORT 3 +.Os +.Sh NAME +.Nm heapsort , +.Nm mergesort , +.Nm qsort , +.Nm qsort_r +.Nd sort functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fo heapsort +.Fa "void *base" +.Fa "size_t nel" +.Fa "size_t width" +.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" +.Fc +.Ft int +.Fo mergesort +.Fa "void *base" +.Fa "size_t nel" +.Fa "size_t width" +.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" +.Fc +.Ft void +.Fo qsort +.Fa "void *base" +.Fa "size_t nel" +.Fa "size_t width" +.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]" +.Fc +.Ft void +.Fo qsort_r +.Fa "void *base" +.Fa "size_t nel" +.Fa "size_t width" +.Fa "void *thunk" +.Fa "int \*[lp]*compar\*[rp]\*[lp]void *, const void *, const void *\*[rp]" +.Fc +.Sh DESCRIPTION +The +.Fn qsort +function is a modified partition-exchange sort, or quicksort. +The +.Fn heapsort +function is a modified selection sort. +The +.Fn mergesort +function is a modified merge sort with exponential search, +intended for sorting data with pre-existing order. +.Pp +The +.Fn qsort +and +.Fn heapsort +functions sort an array of +.Fa nel +objects, the initial member of which is pointed to by +.Fa base . +The size of each object is specified by +.Fa width . +The +.Fn mergesort +function +behaves similarly, but +.Em requires +that +.Fa width +be greater than +.Dq "sizeof(void *) / 2" . +.Pp +The contents of the array +.Fa base +are sorted in ascending order according to +a comparison function pointed to by +.Fa compar , +which requires two arguments pointing to the objects being +compared. +.Pp +The comparison function must return an integer less than, equal to, or +greater than zero if the first argument is considered to be respectively +less than, equal to, or greater than the second. +.Pp +The +.Fn qsort_r +function behaves identically to +.Fn qsort , +except that it takes an additional argument, +.Fa thunk , +which is passed unchanged as the first argument to function pointed to +.Fa compar . +This allows the comparison function to access additional +data without using global variables, and thus +.Fn qsort_r +is suitable for use in functions which must be reentrant. +.Pp +The algorithms implemented by +.Fn qsort , +.Fn qsort_r , +and +.Fn heapsort +are +.Em not +stable; that is, if two members compare as equal, their order in +the sorted array is undefined. +The +.Fn mergesort +algorithm is stable. +.Pp +The +.Fn qsort +and +.Fn qsort_r +functions are an implementation of C.A.R. +Hoare's +.Dq quicksort +algorithm, +a variant of partition-exchange sorting; in particular, see +.An D.E. Knuth Ns 's +.%T "Algorithm Q" . +.Sy Quicksort +takes O N lg N average time. +This implementation uses median selection to avoid its +O N**2 worst-case behavior. +.Pp +The +.Fn heapsort +function is an implementation of +.An "J.W.J. William" Ns 's +.Dq heapsort +algorithm, +a variant of selection sorting; in particular, see +.An "D.E. Knuth" Ns 's +.%T "Algorithm H" . +.Sy Heapsort +takes O N lg N worst-case time. +Its +.Em only +advantage over +.Fn qsort +is that it uses almost no additional memory; while +.Fn qsort +does not allocate memory, it is implemented using recursion. +.Pp +The function +.Fn mergesort +requires additional memory of size +.Fa nel * +.Fa width +bytes; it should be used only when space is not at a premium. +The +.Fn mergesort +function +is optimized for data with pre-existing order; its worst case +time is O N lg N; its best case is O N. +.Pp +Normally, +.Fn qsort +is faster than +.Fn mergesort , +which is faster than +.Fn heapsort . +Memory availability and pre-existing order in the data can make this +untrue. +.Sh RETURN VALUES +The +.Fn qsort +and +.Fn qsort_r +functions +return no value. +.Pp +.Rv -std heapsort mergesort +.Sh ERRORS +The +.Fn heapsort +and +.Fn mergesort +functions succeed unless: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa width +argument is zero, or, +the +.Fa width +argument to +.Fn mergesort +is less than +.Dq "sizeof(void *) / 2" . +.It Bq Er ENOMEM +The +.Fn heapsort +or +.Fn mergesort +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 +.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/qsort_r-fbsd.c b/stdlib/qsort_r-fbsd.c new file mode 100644 index 0000000..684d15c --- /dev/null +++ b/stdlib/qsort_r-fbsd.c @@ -0,0 +1,8 @@ +/* + * This file is in the public domain. Originally written by Garrett + * A. Wollman. + * + * $FreeBSD: src/lib/libc/stdlib/qsort_r.c,v 1.1 2002/09/10 02:04:49 wollman Exp $ + */ +#define I_AM_QSORT_R +#include "qsort-fbsd.c" diff --git a/stdlib/radixsort-fbsd.c b/stdlib/radixsort-fbsd.c new file mode 100644 index 0000000..b712f89 --- /dev/null +++ b/stdlib/radixsort-fbsd.c @@ -0,0 +1,331 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Peter McIlroy and by Dan Bernstein at New York University, + * + * 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[] = "@(#)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 $"); + +/* + * Radixsort routines. + * + * Program r_sort_a() is unstable but uses O(logN) extra memory for a stack. + * Use radixsort(a, n, trace, endchar) for this case. + * + * For stable sorting (using N extra pointers) use sradixsort(), which calls + * r_sort_b(). + * + * For a description of this code, see D. McIlroy, P. McIlroy, K. Bostic, + * "Engineering Radix Sort". + */ + +#include +#include +#include +#include + +typedef struct { + const u_char **sa; + int sn, si; +} stack; + +static inline void simplesort +(const u_char **, int, int, const u_char *, u_int) __attribute__((always_inline)); +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); + +#define THRESHOLD 20 /* Divert to simplesort(). */ +#define SIZE 512 /* Default stack size. */ + +#define SETUP { \ + if (tab == NULL) { \ + tr = tr0; \ + for (c = 0; c < endch; c++) \ + tr0[c] = c + 1; \ + tr0[c] = 0; \ + for (c++; c < 256; c++) \ + tr0[c] = c; \ + endch = 0; \ + } else { \ + endch = tab[endch]; \ + tr = tab; \ + if (endch != 0 && endch != 255) { \ + errno = EINVAL; \ + return (-1); \ + } \ + } \ +} + +int +radixsort(a, n, tab, endch) + const u_char **a, *tab; + int n; + u_int endch; +{ + const u_char *tr; + int c; + u_char tr0[256]; + + SETUP; + r_sort_a(a, n, 0, tr, endch); + return (0); +} + +int +sradixsort(a, n, tab, endch) + const u_char **a, *tab; + int n; + u_int endch; +{ + const u_char *tr, **ta; + int c; + u_char tr0[256]; + + SETUP; + if (n < THRESHOLD) + simplesort(a, n, 0, tr, endch); + else { + if ((ta = malloc(n * sizeof(a))) == NULL) + return (-1); + r_sort_b(a, ta, n, 0, tr, endch); + free(ta); + } + return (0); +} + +#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 +#define swap(a, b, t) t = a, a = b, b = t + +/* Unstable, in-place sort. */ +static void +r_sort_a(a, n, i, tr, endch) + const u_char **a; + int n, i; + const u_char *tr; + u_int endch; +{ + static int count[256], 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]; + + /* Set up stack. */ + sp = s; + push(a, n, i); + while (!empty(s)) { + pop(a, n, i); + if (n < THRESHOLD) { + simplesort(a, n, i, tr, endch); + continue; + } + an = a + n; + + /* Make character histogram. */ + if (nc == 0) { + bmin = 255; /* First occupied bin, excluding eos. */ + for (ak = a; ak < an;) { + c = tr[(*ak++)[i]]; + if (++count[c] == 1 && c != endch) { + if (c < bmin) + bmin = c; + nc++; + } + } + if (sp + nc > s + SIZE) { /* Get more stack. */ + r_sort_a(a, n, i, tr, endch); + continue; + } + } + + /* + * Special case: if all strings have the same + * character at position i, move on to the next + * character. + */ + if (nc == 1 && count[bmin] == n) { + push(a, n, i+1); + nc = count[bmin] = 0; + continue; + } + + /* + * Set top[]; push incompletely sorted bins onto stack. + * top[] = pointers to last out-of-place element in bins. + * count[] = counts of elements in bins. + * Before permuting: top[c-1] + count[c] = top[c]; + * during deal: top[c] counts down to top[c-1]. + */ + sp0 = sp1 = sp; /* Stack position of biggest bin. */ + bigc = 2; /* Size of biggest bin. */ + if (endch == 0) /* Special case: set top[eos]. */ + top[0] = ak = a + count[0]; + else { + ak = a; + top[255] = an; + } + for (cp = count + bmin; nc > 0; cp++) { + while (*cp == 0) /* Find next non-empty pile. */ + cp++; + if (*cp > 1) { + if (*cp > bigc) { + bigc = *cp; + sp1 = sp; + } + push(ak, *cp, i+1); + } + top[cp-count] = ak += *cp; + nc--; + } + swap(*sp0, *sp1, temp); /* Play it safe -- biggest bin last. */ + + /* + * Permute misplacements home. Already home: everything + * before aj, and in bin[c], items from top[c] on. + * Inner loop: + * r = next element to put in place; + * ak = top[r[i]] = location to put the next element. + * aj = bottom of 1st disordered bin. + * Outer loop: + * Once the 1st disordered bin is done, ie. aj >= ak, + * aj<-aj + count[c] connects the bins in a linked list; + * reset count[c]. + */ + for (aj = a; aj < an; *aj = r, aj += count[c], count[c] = 0) + for (r = *aj; aj < (ak = --top[c = tr[r[i]]]);) + swap(*ak, r, t); + } +} + +/* Stable sort, requiring additional memory. */ +static void +r_sort_b(a, ta, n, i, tr, endch) + const u_char **a, **ta; + int n, i; + const u_char *tr; + u_int endch; +{ + static int count[256], nc, bmin; + int c; + const u_char **ak, **ai; + stack s[512], *sp, *sp0, *sp1, temp; + const u_char **top[256]; + int *cp, bigc; + + sp = s; + push(a, n, i); + while (!empty(s)) { + pop(a, n, i); + if (n < THRESHOLD) { + simplesort(a, n, i, tr, endch); + continue; + } + + if (nc == 0) { + bmin = 255; + for (ak = a + n; --ak >= a;) { + c = tr[(*ak)[i]]; + if (++count[c] == 1 && c != endch) { + if (c < bmin) + bmin = c; + nc++; + } + } + if (sp + nc > s + SIZE) { + r_sort_b(a, ta, n, i, tr, endch); + continue; + } + } + + sp0 = sp1 = sp; + bigc = 2; + if (endch == 0) { + top[0] = ak = a + count[0]; + count[0] = 0; + } else { + ak = a; + top[255] = a + n; + count[255] = 0; + } + for (cp = count + bmin; nc > 0; cp++) { + while (*cp == 0) + cp++; + if ((c = *cp) > 1) { + if (c > bigc) { + bigc = c; + sp1 = sp; + } + push(ak, c, i+1); + } + top[cp-count] = ak += c; + *cp = 0; /* Reset count[]. */ + nc--; + } + swap(*sp0, *sp1, temp); + + for (ak = ta + n, ai = a+n; ak > ta;) /* Copy to temp. */ + *--ak = *--ai; + for (ak = ta+n; --ak >= ta;) /* Deal to piles. */ + *--top[tr[(*ak)[i]]] = *ak; + } +} + +static inline void +simplesort(a, n, b, tr, endch) /* insertion sort */ + const u_char **a; + int n, b; + const u_char *tr; + u_int endch; +{ + u_char ch; + const u_char **ak, **ai, *s, *t; + + for (ak = a+1; --n >= 1; ak++) + for (ai = ak; ai > a; ai--) { + for (s = ai[0] + b, t = ai[-1] + b; + (ch = tr[*s]) != endch; s++, t++) + if (ch != tr[*t]) + break; + if (ch >= tr[*t]) + break; + swap(ai[0], ai[-1], s); + } +} diff --git a/stdlib/radixsort.3 b/stdlib/radixsort.3 new file mode 120000 index 0000000..d5e498c --- /dev/null +++ b/stdlib/radixsort.3 @@ -0,0 +1 @@ +./radixsort.3 \ No newline at end of file diff --git a/stdlib/rand-fbsd.c b/stdlib/rand-fbsd.c new file mode 100644 index 0000000..359e12a --- /dev/null +++ b/stdlib/rand-fbsd.c @@ -0,0 +1,172 @@ +/*- + * Copyright (c) 1990, 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. + * + * Posix rand_r function added May 1999 by Wes Peters . + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "namespace.h" +#include /* for sranddev() */ +#include +#include /* for sranddev() */ +#include +#include /* for sranddev() */ +#include "un-namespace.h" + +#ifdef TEST +#include +#endif /* TEST */ + +static int +do_rand(unsigned long *ctx) +{ +#ifdef USE_WEAK_SEEDING +/* + * Historic implementation compatibility. + * The random sequences do not vary much with the seed, + * even with overflowing. + */ + return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)RAND_MAX + 1)); +#else /* !USE_WEAK_SEEDING */ +/* + * Compute x = (7^5 * x) mod (2^31 - 1) + * wihout 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, + * October 1988, p. 1195. + */ + long hi, lo, x; + + /* Can't be initialized with 0, so use another value. */ + if (*ctx == 0) + *ctx = 123459876; + hi = *ctx / 127773; + lo = *ctx % 127773; + x = 16807 * lo - 2836 * hi; + if (x < 0) + x += 0x7fffffff; + return ((*ctx = x) % ((u_long)RAND_MAX + 1)); +#endif /* !USE_WEAK_SEEDING */ +} + + +int +rand_r(unsigned int *ctx) +{ + u_long val = (u_long) *ctx; + int r = do_rand(&val); + + *ctx = (unsigned int) val; + return (r); +} + + +static u_long next = 1; + +int +rand() +{ + return (do_rand(&next)); +} + +void +srand(seed) +u_int seed; +{ + next = seed; +} + + +/* + * sranddev: + * + * Many programs choose the seed value in a totally predictable manner. + * This often causes problems. We seed the generator using the much more + * secure random(4) interface. + */ +void +sranddev() +{ + int fd, done; + + done = 0; + fd = _open("/dev/random", O_RDONLY, 0); + if (fd >= 0) { + if (_read(fd, (void *) &next, sizeof(next)) == sizeof(next)) + done = 1; + _close(fd); + } + + if (!done) { + struct timeval tv; + unsigned long junk; + + gettimeofday(&tv, NULL); + srand((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk); + } +} + + +#ifdef TEST + +main() +{ + int i; + unsigned myseed; + + printf("seeding rand with 0x19610910: \n"); + srand(0x19610910); + + printf("generating three pseudo-random numbers:\n"); + for (i = 0; i < 3; i++) + { + printf("next random number = %d\n", rand()); + } + + printf("generating the same sequence with rand_r:\n"); + myseed = 0x19610910; + for (i = 0; i < 3; i++) + { + printf("next random number = %d\n", rand_r(&myseed)); + } + + return 0; +} + +#endif /* TEST */ + diff --git a/stdlib/rand.3 b/stdlib/rand.3 new file mode 100644 index 0000000..a57c7d5 --- /dev/null +++ b/stdlib/rand.3 @@ -0,0 +1,127 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd May 25, 1999 +.Dt RAND 3 +.Os +.Sh NAME +.Nm rand , +.Nm rand_r , +.Nm srand , +.Nm sranddev +.Nd bad random number generator +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fo rand +.Fa void +.Fc +.Ft int +.Fo rand_r +.Fa "unsigned *seed" +.Fc +.Ft void +.Fo srand +.Fa "unsigned seed" +.Fc +.Ft void +.Fo sranddev +.Fa void +.Fc +.Sh DESCRIPTION +.Bf -symbolic +These interfaces are obsoleted by +.Xr random 3 . +.Ef +.Pp +The +.Fn rand +function computes a sequence of pseudo-random integers in the range +of 0 to +.Dv RAND_MAX +(as defined by the header file +.In stdlib.h ) . +.Pp +The +.Fn srand +function sets its argument +.Fa seed +as the seed for a new sequence of +pseudo-random numbers to be returned by +.Fn rand . +These sequences are repeatable by calling +.Fn srand +with the same seed value. +.Pp +If no +.Fa seed +value is provided, the functions are automatically +seeded with a value of 1. +.Pp +The +.Fn sranddev +function initializes a seed, using the +.Xr random 4 +random number device which returns good random numbers, +suitable for cryptographic use. +.Pp +The +.Fn rand_r +function +provides the same functionality as +.Fn rand . +A pointer to the context value +.Fa seed +must be supplied by the caller. +.Sh SEE ALSO +.Xr random 3 , +.Xr random 4 +.Sh STANDARDS +The +.Fn rand +and +.Fn srand +functions +conform to +.St -isoC . +.Pp +The +.Fn rand_r +function is as proposed in the POSIX.4a Draft #6 document. diff --git a/stdlib/random-fbsd.c b/stdlib/random-fbsd.c new file mode 100644 index 0000000..b422b4c --- /dev/null +++ b/stdlib/random-fbsd.c @@ -0,0 +1,514 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +/* + * We always compile with __DARWIN_UNIX03 set to one, relying on the fact that + * (for non-LP64) sizeof(int) == sizeof(long) == sizeof(size_t), so that we + * don't have to have two different versions of the prototypes. For LP64, + * we only support the POSIX-compatible prototypes. + */ +#undef __DARWIN_UNIX03 +#define __DARWIN_UNIX03 1 +#include "namespace.h" +#include /* for srandomdev() */ +#include /* for srandomdev() */ +#include +#include +#include +#include /* for srandomdev() */ +#include "un-namespace.h" + +/* + * random.c: + * + * An improved random number generation package. In addition to the standard + * rand()/srand() like interface, this package also has a special state info + * interface. The initstate() routine is called with a seed, an array of + * bytes, and a count of how many bytes are being passed in; this array is + * then initialized to contain information for random number generation with + * that much state information. Good sizes for the amount of state + * information are 32, 64, 128, and 256 bytes. The state can be switched by + * calling the setstate() routine with the same array as was initiallized + * with initstate(). By default, the package runs with 128 bytes of state + * information and generates far better random numbers than a linear + * congruential generator. If the amount of state information is less than + * 32 bytes, a simple linear congruential R.N.G. is used. + * + * Internally, the state information is treated as an array of uint32_t's; the + * zeroeth element of the array is the type of R.N.G. being used (small + * integer); the remainder of the array is the state information for the + * R.N.G. Thus, 32 bytes of state information will give 7 ints worth of + * state information, which will allow a degree seven polynomial. (Note: + * the zeroeth word of state information also has some other information + * stored in it -- see setstate() for details). + * + * The random number generation technique is a linear feedback shift register + * approach, employing trinomials (since there are fewer terms to sum up that + * way). In this approach, the least significant bit of all the numbers in + * the state table will act as a linear feedback shift register, and will + * have period 2^deg - 1 (where deg is the degree of the polynomial being + * used, assuming that the polynomial is irreducible and primitive). The + * higher order bits will have longer periods, since their values are also + * influenced by pseudo-random carries out of the lower bits. The total + * period of the generator is approximately deg*(2**deg - 1); thus doubling + * the amount of state information has a vast influence on the period of the + * generator. Note: the deg*(2**deg - 1) is an approximation only good for + * large deg, when the period of the shift is the dominant factor. + * With deg equal to seven, the period is actually much longer than the + * 7*(2**7 - 1) predicted by this formula. + * + * Modified 28 December 1994 by Jacob S. Rosenberg. + * The following changes have been made: + * All references to the type u_int have been changed to unsigned long. + * All references to type int have been changed to type long. Other + * cleanups have been made as well. A warning for both initstate and + * setstate has been inserted to the effect that on Sparc platforms + * the 'arg_state' variable must be forced to begin on word boundaries. + * This can be easily done by casting a long integer array to char *. + * The overall logic has been left STRICTLY alone. This software was + * tested on both a VAX and Sun SpacsStation with exactly the same + * results. The new version and the original give IDENTICAL results. + * The new version is somewhat faster than the original. As the + * documentation says: "By default, the package runs with 128 bytes of + * state information and generates far better random numbers than a linear + * congruential generator. If the amount of state information is less than + * 32 bytes, a simple linear congruential R.N.G. is used." For a buffer of + * 128 bytes, this new version runs about 19 percent faster and for a 16 + * byte buffer it is about 5 percent faster. + */ + +/* + * For each of the currently supported random number generators, we have a + * break value on the amount of state information (you need at least this + * many bytes of state info to support this random number generator), a degree + * for the polynomial (actually a trinomial) that the R.N.G. is based on, and + * the separation between the two lower order coefficients of the trinomial. + */ +#define TYPE_0 0 /* linear congruential */ +#define BREAK_0 8 +#define DEG_0 0 +#define SEP_0 0 + +#define TYPE_1 1 /* x**7 + x**3 + 1 */ +#define BREAK_1 32 +#define DEG_1 7 +#define SEP_1 3 + +#define TYPE_2 2 /* x**15 + x + 1 */ +#define BREAK_2 64 +#define DEG_2 15 +#define SEP_2 1 + +#define TYPE_3 3 /* x**31 + x**3 + 1 */ +#define BREAK_3 128 +#define DEG_3 31 +#define SEP_3 3 + +#define TYPE_4 4 /* x**63 + x + 1 */ +#define BREAK_4 256 +#define DEG_4 63 +#define SEP_4 1 + +/* + * Array versions of the above information to make code run faster -- + * relies on fact that TYPE_i == i. + */ +#define MAX_TYPES 5 /* max number of types above */ + +#ifdef USE_WEAK_SEEDING +#define NSHUFF 0 +#else /* !USE_WEAK_SEEDING */ +#define NSHUFF 50 /* to drop some "seed -> 1st value" linearity */ +#endif /* !USE_WEAK_SEEDING */ + +static const int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; +static const int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; + +/* + * Initially, everything is set up as if from: + * + * initstate(1, randtbl, 128); + * + * Note that this initialization takes advantage of the fact that srandom() + * advances the front and rear pointers 10*rand_deg times, and hence the + * rear pointer which starts at 0 will also end up at zero; thus the zeroeth + * element of the state information, which contains info about the current + * position of the rear pointer is just + * + * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. + */ + +static uint32_t randtbl[DEG_3 + 1] = { + TYPE_3, +#ifdef USE_WEAK_SEEDING +/* Historic implementation compatibility */ +/* The random sequences do not vary much with the seed */ + 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, + 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, + 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, + 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, + 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, + 0x27fb47b9, +#else /* !USE_WEAK_SEEDING */ + 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05, + 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454, + 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471, + 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1, + 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41, + 0xf3bec5da +#endif /* !USE_WEAK_SEEDING */ +}; + +/* + * fptr and rptr are two pointers into the state info, a front and a rear + * pointer. These two pointers are always rand_sep places aparts, as they + * cycle cyclically through the state information. (Yes, this does mean we + * could get away with just one pointer, but the code for random() is more + * efficient this way). The pointers are left positioned as they would be + * from the call + * + * initstate(1, randtbl, 128); + * + * (The position of the rear pointer, rptr, is really 0 (as explained above + * in the initialization of randtbl) because the state table pointer is set + * to point to randtbl[1] (as explained below). + */ +static uint32_t *fptr = &randtbl[SEP_3 + 1]; +static uint32_t *rptr = &randtbl[1]; + +/* + * The following things are the pointer to the state information table, the + * type of the current generator, the degree of the current polynomial being + * used, and the separation between the two pointers. Note that for efficiency + * of random(), we remember the first location of the state information, not + * the zeroeth. Hence it is valid to access state[-1], which is used to + * store the type of the R.N.G. Also, we remember the last location, since + * this is more efficient than indexing every time to find the address of + * the last element to see if the front and rear pointers have wrapped. + */ +static uint32_t *state = &randtbl[1]; +static int rand_type = TYPE_3; +static int rand_deg = DEG_3; +static int rand_sep = SEP_3; +static uint32_t *end_ptr = &randtbl[DEG_3 + 1]; + +static inline uint32_t good_rand(int32_t) __attribute__((always_inline)); + +static inline uint32_t good_rand (x) + int32_t x; +{ +#ifdef USE_WEAK_SEEDING +/* + * Historic implementation compatibility. + * The random sequences do not vary much with the seed, + * even with overflowing. + */ + return (1103515245 * x + 12345); +#else /* !USE_WEAK_SEEDING */ +/* + * Compute x = (7^5 * x) mod (2^31 - 1) + * wihout overflowing 31 bits: + * (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, + * October 1988, p. 1195. + */ + int32_t hi, lo; + + /* Can't be initialized with 0, so use another value. */ + if (x == 0) + x = 123459876; + hi = x / 127773; + lo = x % 127773; + x = 16807 * lo - 2836 * hi; + if (x < 0) + x += 0x7fffffff; + return (x); +#endif /* !USE_WEAK_SEEDING */ +} + +/* + * srandom: + * + * Initialize the random number generator based on the given seed. If the + * type is the trivial no-state-information type, just remember the seed. + * Otherwise, initializes state[] based on the given "seed" via a linear + * congruential generator. Then, the pointers are set to known locations + * that are exactly rand_sep places apart. Lastly, it cycles the state + * information a given number of times to get rid of any initial dependencies + * introduced by the L.C.R.N.G. Note that the initialization of randtbl[] + * for default usage relies on values produced by this routine. + */ +void +srandom(x) + unsigned x; +{ + int i, lim; + + state[0] = (uint32_t)x; + if (rand_type == TYPE_0) + lim = NSHUFF; + else { + for (i = 1; i < rand_deg; i++) + state[i] = good_rand(state[i - 1]); + fptr = &state[rand_sep]; + rptr = &state[0]; + lim = 10 * rand_deg; + } + for (i = 0; i < lim; i++) + (void)random(); +} + +/* + * srandomdev: + * + * Many programs choose the seed value in a totally predictable manner. + * This often causes problems. We seed the generator using the much more + * secure random(4) interface. Note that this particular seeding + * procedure can generate states which are impossible to reproduce by + * calling srandom() with any value, since the succeeding terms in the + * state buffer are no longer derived from the LC algorithm applied to + * a fixed seed. + */ +void +srandomdev() +{ + int fd, done; + size_t len; + + if (rand_type == TYPE_0) + len = sizeof state[0]; + else + len = rand_deg * sizeof state[0]; + + done = 0; + fd = _open("/dev/random", O_RDONLY, 0); + if (fd >= 0) { + if (_read(fd, (void *) state, len) == (ssize_t) len) + done = 1; + _close(fd); + } + + if (!done) { + struct timeval tv; + unsigned long junk; + + gettimeofday(&tv, NULL); + srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk); + return; + } + + if (rand_type != TYPE_0) { + fptr = &state[rand_sep]; + rptr = &state[0]; + } +} + +/* + * initstate: + * + * Initialize the state information in the given array of n bytes for future + * random number generation. Based on the number of bytes we are given, and + * the break values for the different R.N.G.'s, we choose the best (largest) + * one we can and set things up for it. srandom() is then called to + * initialize the state information. + * + * Note that on return from srandom(), we set state[-1] to be the type + * multiplexed with the current value of the rear pointer; this is so + * successive calls to initstate() won't lose this information and will be + * able to restart with setstate(). + * + * Note: the first thing we do is save the current state, if any, just like + * setstate() so that it doesn't matter when initstate is called. + * + * Returns a pointer to the old state. + * + * Note: The Sparc platform requires that arg_state begin on an int + * word boundary; otherwise a bus error will occur. Even so, lint will + * complain about mis-alignment, but you should disregard these messages. + */ +char * +initstate(seed, arg_state, n) + unsigned seed; /* seed for R.N.G. */ + char *arg_state; /* pointer to state array */ + size_t n; /* # bytes of state info */ +{ + char *ostate = (char *)(&state[-1]); + uint32_t *int_arg_state = (uint32_t *)arg_state; + + if (rand_type == TYPE_0) + state[-1] = rand_type; + else + state[-1] = MAX_TYPES * (rptr - state) + rand_type; + if (n < BREAK_0) { + (void)fprintf(stderr, + "random: not enough state (%ld bytes); ignored.\n", n); + return(0); + } + if (n < BREAK_1) { + rand_type = TYPE_0; + rand_deg = DEG_0; + rand_sep = SEP_0; + } else if (n < BREAK_2) { + rand_type = TYPE_1; + rand_deg = DEG_1; + rand_sep = SEP_1; + } else if (n < BREAK_3) { + rand_type = TYPE_2; + rand_deg = DEG_2; + rand_sep = SEP_2; + } else if (n < BREAK_4) { + rand_type = TYPE_3; + rand_deg = DEG_3; + rand_sep = SEP_3; + } else { + rand_type = TYPE_4; + rand_deg = DEG_4; + rand_sep = SEP_4; + } + state = int_arg_state + 1; /* first location */ + end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ + srandom(seed); + if (rand_type == TYPE_0) + int_arg_state[0] = rand_type; + else + int_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type; + return(ostate); +} + +/* + * setstate: + * + * Restore the state from the given state array. + * + * Note: it is important that we also remember the locations of the pointers + * in the current state information, and restore the locations of the pointers + * from the old state information. This is done by multiplexing the pointer + * location into the zeroeth word of the state information. + * + * Note that due to the order in which things are done, it is OK to call + * setstate() with the same state as the current state. + * + * Returns a pointer to the old state information. + * + * Note: The Sparc platform requires that arg_state begin on an int + * word boundary; otherwise a bus error will occur. Even so, lint will + * complain about mis-alignment, but you should disregard these messages. + */ +char * +setstate(arg_state) + const char *arg_state; /* pointer to state array */ +{ + uint32_t *new_state = (uint32_t *)arg_state; + uint32_t type = new_state[0] % MAX_TYPES; + uint32_t rear = new_state[0] / MAX_TYPES; + char *ostate = (char *)(&state[-1]); + + if (rand_type == TYPE_0) + state[-1] = rand_type; + else + state[-1] = MAX_TYPES * (rptr - state) + rand_type; + switch(type) { + case TYPE_0: + case TYPE_1: + case TYPE_2: + case TYPE_3: + case TYPE_4: + rand_type = type; + rand_deg = degrees[type]; + rand_sep = seps[type]; + break; + default: + (void)fprintf(stderr, + "random: state info corrupted; not changed.\n"); + } + state = new_state + 1; + if (rand_type != TYPE_0) { + rptr = &state[rear]; + fptr = &state[(rear + rand_sep) % rand_deg]; + } + end_ptr = &state[rand_deg]; /* set end_ptr too */ + return(ostate); +} + +/* + * random: + * + * If we are using the trivial TYPE_0 R.N.G., just do the old linear + * congruential bit. Otherwise, we do our fancy trinomial stuff, which is + * the same in all the other cases due to all the global variables that have + * been set up. The basic operation is to add the number at the rear pointer + * into the one at the front pointer. Then both pointers are advanced to + * the next location cyclically in the table. The value returned is the sum + * generated, reduced to 31 bits by throwing away the "least random" low bit. + * + * Note: the code takes advantage of the fact that both the front and + * rear pointers can't wrap on the same call by not testing the rear + * pointer if the front one has wrapped. + * + * Returns a 31-bit random number. + */ +long +random() +{ + uint32_t i; + uint32_t *f, *r; + + if (rand_type == TYPE_0) { + i = state[0]; + state[0] = i = (good_rand(i)) & 0x7fffffff; + } else { + /* + * Use local variables rather than static variables for speed. + */ + f = fptr; r = rptr; + *f += *r; + i = (*f >> 1) & 0x7fffffff; /* chucking least random bit */ + if (++f >= end_ptr) { + f = state; + ++r; + } + else if (++r >= end_ptr) { + r = state; + } + + fptr = f; rptr = r; + } + return((long)i); +} diff --git a/stdlib/random.3 b/stdlib/random.3 new file mode 100644 index 0000000..b4cdd05 --- /dev/null +++ b/stdlib/random.3 @@ -0,0 +1,237 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt RANDOM 3 +.Os +.Sh NAME +.Nm initstate , +.Nm random , +.Nm setstate , +.Nm srandom , +.Nm srandomdev +.Nd better random number generator; routines for changing generators +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft char * +.Fo initstate +.Fa "unsigned seed" +.Fa "char *state" +.Fa "size_t size" +.Fc +.Ft long +.Fo random +.Fa void +.Fc +.Ft char * +.Fo setstate +.Fa "const char *state" +.Fc +.Ft void +.Fo srandom +.Fa "unsigned seed" +.Fc +.Ft void +.Fo srandomdev +.Fa void +.Fc +.Sh DESCRIPTION +The +.Fn random +function +uses a non-linear, additive feedback, random number generator, employing a +default table of size 31 long integers. +It returns successive pseudo-random +numbers in the range from 0 to +.if t 2\u\s731\s10\d\(mi1. +.if n (2**31)\(mi1. +The period of this random number generator is very large, approximately +.if t 16\(mu(2\u\s731\s10\d\(mi1). +.if n 16*((2**31)\(mi1). +.Pp +The +.Fn random +and +.Fn srandom +functions have (almost) the same calling sequence and initialization properties as the +.Xr rand 3 +and +.Xr srand 3 +functions. +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. +All of the bits generated by +.Fn random +are usable. +For example, +.Sq Li random()&01 +will produce a random binary +value. +.Pp +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. +.Pp +The +.Fn srandomdev +routine initializes a state array, using the +.Xr random 4 +random number device which returns good random numbers, +suitable for cryptographic use. +Note that this particular seeding +procedure can generate states which are impossible to reproduce by +calling +.Fn srandom +with any value, since the succeeding terms in the +state buffer are no longer derived from the LC algorithm applied to +a fixed seed. +.Pp +The +.Fn initstate +routine allows a state array, passed in as an argument, to be initialized +for future use. +The size of the state array (in bytes) is used by +.Fn initstate +to decide how sophisticated a random number generator it should use \(em the +more state, the better the random numbers will be. +(Current "optimal" values for the amount of state information are +8, 32, 64, 128, and 256 bytes; other amounts will be rounded down to +the nearest known amount. +Using less than 8 bytes will cause an error.) +The seed for the initialization (which specifies a starting point for +the random number sequence and provides for restarting at the same +point) is also an argument. +The +.Fn initstate +function +returns a pointer to the previous state information array. +.Pp +Once a state has been initialized, the +.Fn setstate +routine provides for rapid switching between states. +The +.Fn setstate +function +returns a pointer to the previous state array; its +argument state array is used for further random number generation +until the next call to +.Fn initstate +or +.Fn setstate . +.Pp +Once a state array has been initialized, it may be restarted at a +different point either by calling +.Fn initstate +(with the desired seed, the state array, and its size) or by calling +both +.Fn setstate +(with the state array) and +.Fn srandom +(with the desired seed). +The advantage of calling both +.Fn setstate +and +.Fn srandom +is that the size of the state array does not have to be remembered after +it is initialized. +.Pp +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 , +which should be sufficient for most purposes. +.Sh AUTHORS +.An Earl T. Cohen +.Sh DIAGNOSTICS +If +.Fn initstate +is called with less than 8 bytes of state information, or if +.Fn setstate +detects that the state information has been garbled, error +messages are printed on the standard error output. +.Sh LEGACY SYNOPSIS +.Fd #include +.Pp +.Ft char * +.br +.Fo initstate +.Fa "unsigned long seed" +.Fa "char *state" +.Fa "long size" +.Fc ; +.Pp +.Ft char * +.br +.Fo setstate +.Fa "char *state" +.Fc ; +.Pp +.Ft void +.br +.Fo srandom +.Fa "unsigned long seed" +.Fc ; +.Pp +The type of each parameter is different in the legacy version. +.Sh SEE ALSO +.Xr arc4random 3 , +.Xr rand 3 , +.Xr srand 3 , +.Xr random 4 , +.Xr compat 5 +.Sh HISTORY +These +functions appeared in +.Bx 4.2 . +.Sh BUGS +About 2/3 the speed of +.Xr rand 3 . +.Pp +The historical implementation used to have a very weak seeding; the +random sequence did not vary much with the seed. +The current implementation employs a better pseudo-random number +generator for the initial state calculation. +.Pp +Applications requiring cryptographic quality randomness should use +.Xr arc4random 3 . diff --git a/stdlib/reallocf-fbsd.c b/stdlib/reallocf-fbsd.c new file mode 100644 index 0000000..d502006 --- /dev/null +++ b/stdlib/reallocf-fbsd.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 1998, M. Warner Losh + * 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/stdlib/reallocf.c,v 1.4 2002/03/22 21:53:10 obrien Exp $"); + +#include + +void * +reallocf(void *ptr, size_t size) +{ + void *nptr; + + nptr = realloc(ptr, size); + if (!nptr && ptr) + free(ptr); + return (nptr); +} diff --git a/stdlib/realpath-fbsd.c b/stdlib/realpath-fbsd.c new file mode 100644 index 0000000..34c5bc8 --- /dev/null +++ b/stdlib/realpath-fbsd.c @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2003 Constantin S. Svintsoff + * + * 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 names of the authors 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)realpath.c 8.1 (Berkeley) 2/16/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/realpath.c,v 1.20 2003/05/28 08:23:01 fjoe Exp $"); + +#include "namespace.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +struct attrs { + u_int32_t len; + attrreference_t name; + dev_t dev; + fsobj_type_t type; + fsobj_id_t id; + char buf[PATH_MAX]; +}; + +#ifndef BUILDING_VARIANT +__private_extern__ struct attrlist _rp_alist = { + ATTR_BIT_MAP_COUNT, + 0, + ATTR_CMN_NAME | ATTR_CMN_DEVID | ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID, + 0, + 0, + 0, + 0, +}; +#else /* BUILDING_VARIANT */ +__private_extern__ struct attrlist _rp_alist; +#endif /* BUILDING_VARIANT */ + +extern char * __private_getcwd(char *, size_t, int); + +/* + * char *realpath(const char *path, char resolved[PATH_MAX]); + * + * Find the real name of path, by removing all ".", ".." and symlink + * components. Returns (resolved) on success, or (NULL) on failure, + * in which case the path which caused trouble is left in (resolved). + */ +char * +realpath(const char *path, char resolved[PATH_MAX]) +{ + struct attrs attrs; + struct stat sb; + char *p, *q, *s; + size_t left_len, resolved_len, save_resolved_len; + unsigned symlinks; + int serrno, slen, useattrs, islink; + char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; + dev_t dev, lastdev; + struct statfs sfs; + static dev_t rootdev; + static int rootdev_inited = 0; + ino_t inode; + + if (path == NULL) { + errno = EINVAL; + return (NULL); + } +#if __DARWIN_UNIX03 + if (*path == 0) { + errno = ENOENT; + return (NULL); + } +#endif /* __DARWIN_UNIX03 */ + if (!rootdev_inited) { + rootdev_inited = 1; + if (stat("/", &sb) < 0) { + return (NULL); + } + rootdev = sb.st_dev; + } + serrno = errno; + symlinks = 0; + if (path[0] == '/') { + resolved[0] = '/'; + resolved[1] = '\0'; + if (path[1] == '\0') { + return (resolved); + } + resolved_len = 1; + left_len = strlcpy(left, path + 1, sizeof(left)); + } else { +#if !defined(VARIANT_DARWINEXTSN) && __DARWIN_UNIX03 + /* 4447159: don't use GETPATH, so this will fail if */ + /* if parent directories are not readable, as per POSIX */ + if (__private_getcwd(resolved, PATH_MAX, 0) == NULL) +#else /* VARIANT_DARWINEXTSN || !__DARWIN_UNIX03 */ + if (__private_getcwd(resolved, PATH_MAX, 1) == NULL) +#endif /* !VARIANT_DARWINEXTSN && __DARWIN_UNIX03 */ + { + strlcpy(resolved, ".", PATH_MAX); + return (NULL); + } + resolved_len = strlen(resolved); + left_len = strlcpy(left, path, sizeof(left)); + } + if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { + errno = ENAMETOOLONG; + return (NULL); + } + if (resolved_len > 1) { + if (stat(resolved, &sb) < 0) { + return (NULL); + } + lastdev = sb.st_dev; + } else + lastdev = rootdev; + + /* + * Iterate over path components in `left'. + */ + while (left_len != 0) { + /* + * Extract the next path component and adjust `left' + * and its length. + */ + p = strchr(left, '/'); + s = p ? p : left + left_len; + if (s - left >= sizeof(next_token)) { + errno = ENAMETOOLONG; + return (NULL); + } + memcpy(next_token, left, s - left); + next_token[s - left] = '\0'; + left_len -= s - left; + if (p != NULL) + memmove(left, s + 1, left_len + 1); + if (resolved[resolved_len - 1] != '/') { + if (resolved_len + 1 >= PATH_MAX) { + errno = ENAMETOOLONG; + return (NULL); + } + resolved[resolved_len++] = '/'; + resolved[resolved_len] = '\0'; + } + if (next_token[0] == '\0') + continue; + else if (strcmp(next_token, ".") == 0) + continue; + else if (strcmp(next_token, "..") == 0) { + /* + * Strip the last path component except when we have + * single "/" + */ + if (resolved_len > 1) { + resolved[resolved_len - 1] = '\0'; + q = strrchr(resolved, '/') + 1; + *q = '\0'; + resolved_len = q - resolved; + } + continue; + } + + /* + * Save resolved_len, so that we can later null out + * the the appended next_token, and replace with the + * real name (matters on case-insensitive filesystems). + */ + save_resolved_len = resolved_len; + + /* + * Append the next path component and lstat() it. If + * lstat() fails we still can return successfully if + * there are no more path components left. + */ + resolved_len = strlcat(resolved, next_token, PATH_MAX); + if (resolved_len >= PATH_MAX) { + errno = ENAMETOOLONG; + return (NULL); + } + if (getattrlist(resolved, &_rp_alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) { + useattrs = 1; + islink = (attrs.type == VLNK); + dev = attrs.dev; + inode = attrs.id.fid_objno; + } else if (errno == ENOTSUP || errno == EINVAL) { + if ((useattrs = lstat(resolved, &sb)) == 0) { + islink = S_ISLNK(sb.st_mode); + dev = sb.st_dev; + inode = sb.st_ino; + } + } else + useattrs = -1; + if (useattrs < 0) { +#if !__DARWIN_UNIX03 + if (errno == ENOENT && p == NULL) { + errno = serrno; + return (resolved); + } +#endif /* !__DARWIN_UNIX03 */ + return (NULL); + } + if (dev != lastdev) { + /* + * We have crossed a mountpoint. For volumes like UDF + * the getattrlist name may not match the actual + * mountpoint, so we just copy the mountpoint directly. + * (3703138). However, the mountpoint may not be + * accessible, as when chroot-ed, so check first. + * There may be a file on the chroot-ed volume with + * the same name as the mountpoint, so compare device + * and inode numbers. + */ + lastdev = dev; + if (statfs(resolved, &sfs) == 0 && lstat(sfs.f_mntonname, &sb) == 0 && dev == sb.st_dev && inode == sb.st_ino) { + /* + * However, it's possible that the mountpoint + * path matches, even though it isn't the real + * path in the chroot-ed environment, so check + * that each component of the mountpoint + * is a directory (and not a symlink) + */ + char temp[MNAMELEN]; + char *cp; + int ok = 1; + + strcpy(temp, sfs.f_mntonname); + for(;;) { + if ((cp = strrchr(temp, '/')) == NULL) { + ok = 0; + break; + } + if (cp <= temp) + break; + *cp = 0; + if (lstat(temp, &sb) < 0 || (sb.st_mode & S_IFMT) != S_IFDIR) { + ok = 0; + break; + } + } + if (ok) { + resolved_len = strlcpy(resolved, sfs.f_mntonname, PATH_MAX); + continue; + } + } + /* if we fail, use the other methods. */ + } + if (islink) { + if (symlinks++ > MAXSYMLINKS) { + errno = ELOOP; + return (NULL); + } + slen = readlink(resolved, symlink, sizeof(symlink) - 1); + if (slen < 0) { + return (NULL); + } + symlink[slen] = '\0'; + if (symlink[0] == '/') { + resolved[1] = 0; + resolved_len = 1; + lastdev = rootdev; + } else if (resolved_len > 1) { + /* Strip the last path component. */ + resolved[resolved_len - 1] = '\0'; + q = strrchr(resolved, '/') + 1; + *q = '\0'; + resolved_len = q - resolved; + } + + /* + * If there are any path components left, then + * append them to symlink. The result is placed + * in `left'. + */ + if (p != NULL) { + if (symlink[slen - 1] != '/') { + if (slen + 1 >= sizeof(symlink)) { + errno = ENAMETOOLONG; + return (NULL); + } + symlink[slen] = '/'; + symlink[slen + 1] = 0; + } + left_len = strlcat(symlink, left, sizeof(left)); + if (left_len >= sizeof(left)) { + errno = ENAMETOOLONG; + return (NULL); + } + } + left_len = strlcpy(left, symlink, sizeof(left)); + } else if (useattrs) { + /* + * attrs already has the real name. + */ + + resolved[save_resolved_len] = '\0'; + resolved_len = strlcat(resolved, (const char *)&attrs.name + attrs.name.attr_dataoffset, PATH_MAX); + if (resolved_len >= PATH_MAX) { + errno = ENAMETOOLONG; + return (NULL); + } + } + /* + * For the case of useattrs == 0, we could scan the directory + * and try to match the inode. There are many problems with + * this: (1) the directory may not be readable, (2) for multiple + * hard links, we would find the first, but not necessarily + * the one specified in the path, (3) we can't try to do + * a case-insensitive search to match the right one in (2), + * because the underlying filesystem may do things like + * decompose composed characters. For most cases, doing + * nothing is the right thing when useattrs == 0, so we punt + * for now. + */ + } + + /* + * Remove trailing slash except when the resolved pathname + * is a single "/". + */ + if (resolved_len > 1 && resolved[resolved_len - 1] == '/') + resolved[resolved_len - 1] = '\0'; + return (resolved); +} diff --git a/stdlib/realpath.3 b/stdlib/realpath.3 new file mode 100644 index 0000000..6213fd2 --- /dev/null +++ b/stdlib/realpath.3 @@ -0,0 +1,141 @@ +.\" Copyright (c) 1994 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Jan-Simon Pendry. +.\" +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd February 16, 1994 +.Dt REALPATH 3 +.Os +.Sh NAME +.Nm realpath +.Nd returns the canonicalized absolute pathname +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft "char *" +.Fo realpath +.Fa "const char *restrict file_name" +.Fa "char *restrict resolved_name" +.Fc +.Sh DESCRIPTION +The +.Fn realpath +function resolves all symbolic links, extra +.Dq / +characters, and references to +.Pa /./ +and +.Pa /../ +in +.Fa file_name , +and copies the resulting absolute pathname into +the memory referenced by +.Fa resolved_name . +The +.Fa resolved_name +argument +.Em must +refer to a buffer capable of storing at least +.Dv PATH_MAX +characters. +.Pp +The +.Fn realpath +function will resolve both absolute and relative paths +and return the absolute pathname corresponding to +.Fa file_name . +All components of +.Fa file_name +must exist when +.Fn realpath +is called. +.Sh "RETURN VALUES" +The +.Fn realpath +function returns +.Fa resolved_name +on success. +If an error occurs, +.Fn realpath +returns +.Dv NULL +and +.Fa resolved_name +contains the pathname which caused the problem. +.Sh ERRORS +The function +.Fn realpath +may fail and set the external variable +.Va errno +for any of the errors specified for the library functions +.Xr lstat 2 , +.Xr readlink 2 , +and +.Xr getcwd 3 . +.Sh CAVEATS +This implementation of +.Fn realpath +differs slightly from the Solaris implementation. +The +.Bx 4.4 +version always returns absolute pathnames, +whereas the Solaris implementation will, +under certain circumstances, return a relative +.Fa resolved_name +when given a relative +.Fa file_name . +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +The include file +.In sys/param.h +is necessary. +.Sh LEGACY DESCRIPTION +In legacy mode, +the last component of +.Fa file_name +does not need to exist when +.Fn realpath +is called. +.Sh "SEE ALSO" +.Xr getcwd 3 , +.Xr compat 5 +.Sh HISTORY +The +.Fn realpath +function first appeared in +.Bx 4.4 . diff --git a/stdlib/remque-fbsd.c b/stdlib/remque-fbsd.c new file mode 100644 index 0000000..068a75f --- /dev/null +++ b/stdlib/remque-fbsd.c @@ -0,0 +1,30 @@ +/* + * Initial implementation: + * Copyright (c) 2002 Robert Drehmel + * All rights reserved. + * + * As long as the above copyright statement and this notice remain + * unchanged, you can do what ever you want with this file. + */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/remque.c,v 1.3 2003/01/04 07:34:41 tjr Exp $"); + +#define _SEARCH_PRIVATE +#include +#include /* for NULL */ + +void +remque(void *element) +{ + struct que_elem *prev, *next, *elem; + + elem = (struct que_elem *)element; + + prev = elem->prev; + next = elem->next; + + if (prev != NULL) + prev->next = next; + if (next != NULL) + next->prev = prev; +} diff --git a/stdlib/setenv-fbsd.c b/stdlib/setenv-fbsd.c new file mode 100644 index 0000000..fdc6fe1 --- /dev/null +++ b/stdlib/setenv-fbsd.c @@ -0,0 +1,350 @@ +/* + * Copyright (c) 1987, 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[] = "@(#)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 $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +/* + * The copy flag may have 3 values: + * 1 - make a copy of the name/value pair + * 0 - take the name as a user-supplied name=value string + * -1 - like 0, except we copy of the name=value string in name + */ +__private_extern__ int +__setenv(name, value, rewrite, copy, environp, envz) + const char *name; + const char *value; + int rewrite, copy; + char ***environp; + malloc_zone_t *envz; +{ + char *c; + int offset; + + if ((c = __findenv(name, &offset, *environp))) { /* find if already exists */ + char *e; + if (!rewrite) + return (0); + /* + * In UNIX03, we can overwrite only if we allocated the + * string. Then we can realloc it if it is too small. + */ + e = (*environp)[offset]; + if (copy > 0 && ZONE_OWNS_PTR(envz, e)) { + size_t l_value = strlen(value); + if (strlen(c) < l_value) { /* old smaller; resize*/ + char *r; + size_t len = c - e; + if ((r = realloc(e, l_value + len + 1)) == NULL) + return (-1); + if (r != e) { + (*environp)[offset] = r; + c = r + len; + } + } + while ( (*c++ = *value++) ); + return (0); + } + } else { /* create new slot */ + int cnt; + char **p; + + for (p = *environp, cnt = 0; *p; ++p, ++cnt); + if (ZONE_OWNS_PTR(envz, *environp)) { /* just increase size */ + p = (char **)realloc((char *)*environp, + (size_t)(sizeof(char *) * (cnt + 2))); + if (!p) + return (-1); + *environp = p; + } + else { /* get new space */ + /* copy old entries into it */ + p = malloc_zone_malloc(envz, (size_t)(sizeof(char *) * (cnt + 2))); + if (!p) + return (-1); + bcopy(*environp, p, cnt * sizeof(char *)); + *environp = p; + } + (*environp)[cnt + 1] = NULL; + offset = cnt; + } + /* For non Unix03, or UnixO3 setenv(), we make a copy of the user's + * strings. For Unix03 putenv(), we put the string directly in + * the environment. */ + if (copy > 0) { + for (c = (char *)name; *c && *c != '='; ++c); /* no `=' in name */ + if (!((*environp)[offset] = /* name + `=' + value */ + malloc_zone_malloc(envz, (size_t)((int)(c - name) + strlen(value) + 2)))) + return (-1); + for (c = (*environp)[offset]; (*c = *name++) && *c != '='; ++c); + for (*c++ = '='; (*c++ = *value++); ); + } else { + /* the legacy behavior copies the string */ + if (copy < 0) { + size_t len = strlen(name); + if((c = malloc_zone_malloc(envz, len + 1)) == NULL) + return (-1); + memcpy(c, name, len + 1); + name = c; + } + /* if we malloc-ed the previous value, free it first */ + if ((*environp)[offset] != NULL && ZONE_OWNS_PTR(envz, (*environp)[offset])) + free((*environp)[offset]); + (*environp)[offset] = (char *)name; + } + return (0); +} + +__private_extern__ void +__unsetenv(const char *name, char **environ, malloc_zone_t *envz) +{ + char **p; + int offset; + + while (__findenv(name, &offset, environ)) { /* if set multiple times */ + /* if we malloc-ed it, free it first */ + if (ZONE_OWNS_PTR(envz, environ[offset])) + free(environ[offset]); + for (p = &environ[offset];; ++p) + if (!(*p = *(p + 1))) + break; + } +} + +/****************************************************************************/ +/* + * _allocenvstate -- SPI that creates a new state (opaque) + */ +void * +_allocenvstate(void) +{ + return (void *)malloc_create_zone(1000 /* unused */, 0 /* unused */); +} + +/* + * _copyenv -- SPI that copies a NULL-tereminated char * array in a newly + * allocated buffer, compatible with the other SPI env routines. If env + * is NULL, a char * array composed of a single NULL is returned. NULL + * is returned on error. (This isn't needed anymore, as __setenv will + * automatically make a copy in the zone.) + */ +char ** +_copyenv(char **env) +{ + char **p; + int cnt = 1; + + if (env) + for (p = env; *p; ++p, ++cnt); + p = (char **)malloc((size_t)(sizeof(char *) * cnt)); + if (!p) + return (NULL); + if (env) + bcopy(env, p, cnt * sizeof(char *)); + else + *p = NULL; + return p; +} + +/* + * _deallocenvstate -- SPI that frees all the memory associated with the state + * and all allocated strings, including the environment array itself if it + * was copied. + */ +int +_deallocenvstate(void *state) +{ + malloc_zone_t *envz; + + if (!(envz = (malloc_zone_t *)state) || envz == __zone0) { + errno = EINVAL; + return -1; + } + malloc_destroy_zone(envz); + return 0; +} + +/* + * setenvp -- SPI using an arbitrary pointer to string array and an env state, + * created by _allocenvstate(). Initial checking is not done. + * + * Set the value of the environmental variable "name" to be + * "value". If rewrite is set, replace any current value. + */ +int +_setenvp(const char *name, const char *value, int rewrite, char ***envp, void *state) +{ + /* insure __zone0 is set up */ + if (!__zone0) { + __zone0 = malloc_create_zone(0, 0); + if (!__zone0) { + errno = ENOMEM; + return (-1); + } + } + return (__setenv(name, value, rewrite, 1, envp, (state ? (malloc_zone_t *)state : __zone0))); +} + +/* + * unsetenv(name) -- SPI using an arbitrary pointer to string array and an env + * state, created by _allocenvstate(). Initial checking is not done. + * + * Delete environmental variable "name". + */ +int +_unsetenvp(const char *name, char ***envp, void *state) +{ + /* insure __zone0 is set up */ + if (!__zone0) { + __zone0 = malloc_create_zone(0, 0); + if (!__zone0) { + errno = ENOMEM; + return (-1); + } + } + __unsetenv(name, *envp, (state ? (malloc_zone_t *)state : __zone0)); + return 0; +} + +#endif /* !BUILD_VARIANT */ + +/* + * setenv -- + * Set the value of the environmental variable "name" to be + * "value". If rewrite is set, replace any current value. + */ +int +setenv(name, value, rewrite) + const char *name; + const char *value; + int rewrite; +{ + /* no null ptr or empty str */ + if(name == NULL || *name == 0) { + errno = EINVAL; + return (-1); + } + +#if __DARWIN_UNIX03 + /* no '=' in name */ + if (strchr(name, '=')) { + errno = EINVAL; + return (-1); + } +#endif /* __DARWIN_UNIX03 */ + + if (*value == '=') /* no `=' in value */ + ++value; + /* insure __zone0 is set up before calling __malloc_check_env_name */ + if (!__zone0) { + __zone0 = malloc_create_zone(0, 0); + if (!__zone0) { + errno = ENOMEM; + return (-1); + } + } + __malloc_check_env_name(name); /* see if we are changing a malloc environment variable */ + return (__setenv(name, value, rewrite, 1, _NSGetEnviron(), __zone0)); +} + +/* + * unsetenv(name) -- + * Delete environmental variable "name". + */ +#if __DARWIN_UNIX03 +int +#else /* !__DARWIN_UNIX03 */ +void +#endif /* __DARWIN_UNIX03 */ +unsetenv(name) + const char *name; +{ +#if __DARWIN_UNIX03 + /* no null ptr or empty str */ + if(name == NULL || *name == 0) { + errno = EINVAL; + return (-1); + } + + /* no '=' in name */ + if (strchr(name, '=')) { + errno = EINVAL; + return (-1); + } + /* insure __zone0 is set up before calling __malloc_check_env_name */ + if (!__zone0) { + __zone0 = malloc_create_zone(0, 0); + if (!__zone0) { + errno = ENOMEM; + return (-1); + } + } +#else /* !__DARWIN_UNIX03 */ + /* no null ptr or empty str */ + if(name == NULL || *name == 0) + return; + /* insure __zone0 is set up before calling __malloc_check_env_name */ + if (!__zone0) { + __zone0 = malloc_create_zone(0, 0); + if (!__zone0) + return; + } +#endif /* __DARWIN_UNIX03 */ + __malloc_check_env_name(name); /* see if we are changing a malloc environment variable */ + __unsetenv(name, *_NSGetEnviron(), __zone0); +#if __DARWIN_UNIX03 + return 0; +#endif /* __DARWIN_UNIX03 */ +} diff --git a/stdlib/strfmon-fbsd.c b/stdlib/strfmon-fbsd.c new file mode 100644 index 0000000..3ffb346 --- /dev/null +++ b/stdlib/strfmon-fbsd.c @@ -0,0 +1,639 @@ +/*- + * Copyright (c) 2001 Alexey Zelkin + * 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/stdlib/strfmon.c,v 1.14 2003/03/20 08:18:55 ache Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* internal flags */ +#define NEED_GROUPING 0x01 /* print digits grouped (default) */ +#define SIGN_POSN_USED 0x02 /* '+' or '(' usage flag */ +#define LOCALE_POSN 0x04 /* use locale defined +/- (default) */ +#define PARENTH_POSN 0x08 /* enclose negative amount in () */ +#define SUPRESS_CURR_SYMBOL 0x10 /* supress the currency from output */ +#define LEFT_JUSTIFY 0x20 /* left justify */ +#define USE_INTL_CURRENCY 0x40 /* use international currency symbol */ +#define IS_NEGATIVE 0x80 /* is argument value negative ? */ + +/* internal macros */ +#define PRINT(CH) do { \ + if (dst >= s + maxsize) \ + goto e2big_error; \ + *dst++ = CH; \ +} while (0) + +#define PRINTS(STR) do { \ + char *tmps = STR; \ + while (*tmps != '\0') \ + PRINT(*tmps++); \ +} while (0) + +#define GET_NUMBER(VAR,LOC) do { \ + VAR = 0; \ + while (isdigit_l((unsigned char)*fmt, (LOC))) { \ + VAR *= 10; \ + VAR += *fmt - '0'; \ + fmt++; \ + } \ +} while (0) + +#define GRPCPY(howmany) do { \ + int i = howmany; \ + while (i-- > 0) { \ + avalue_size--; \ + *--bufend = *(avalue+avalue_size+padded); \ + } \ +} while (0) + +#define GRPSEP do { \ + *--bufend = thousands_sep; \ + groups++; \ +} while (0) + +static void __setup_vars(int, char *, char *, char *, char **, struct lconv *); +static int __calc_left_pad(int, char *, struct lconv *); +static char *__format_grouped_double(double, int *, int, int, int, struct lconv *, locale_t); + +static ssize_t +_strfmon(char * __restrict s, size_t maxsize, locale_t loc, + const char * __restrict format, va_list ap) +{ + char *dst; /* output destination pointer */ + const char *fmt; /* current format poistion pointer */ + struct lconv *lc; /* pointer to lconv structure */ + char *asciivalue; /* formatted double pointer */ + + int flags; /* formatting options */ + int pad_char; /* padding character */ + int pad_size; /* pad size */ + int width; /* field width */ + int left_prec; /* left precision */ + int right_prec; /* right precision */ + double value; /* just value */ + char space_char = ' '; /* space after currency */ + + char cs_precedes, /* values gathered from struct lconv */ + sep_by_space, + sign_posn, + *signstr, + *currency_symbol; + + char *tmpptr; /* temporary vars */ + int sverrno; + + lc = localeconv_l(loc); + dst = s; + fmt = format; + asciivalue = NULL; + currency_symbol = NULL; + pad_size = 0; + + while (*fmt) { + /* pass nonformating characters AS IS */ + if (*fmt != '%') + goto literal; + + /* '%' found ! */ + + /* "%%" mean just '%' */ + if (*(fmt+1) == '%') { + fmt++; + literal: + PRINT(*fmt++); + continue; + } + + /* set up initial values */ + flags = (NEED_GROUPING|LOCALE_POSN); + pad_char = ' '; /* padding character is "space" */ + left_prec = -1; /* no left precision specified */ + right_prec = -1; /* no right precision specified */ + width = -1; /* no width specified */ + value = 0; /* we have no value to print now */ + + /* Flags */ + while (1) { + switch (*++fmt) { + case '=': /* fill character */ + pad_char = *++fmt; + if (pad_char == '\0') + goto format_error; + continue; + case '^': /* not group currency */ + flags &= ~(NEED_GROUPING); + continue; + case '+': /* use locale defined signs */ + if (flags & SIGN_POSN_USED) + goto format_error; + flags |= (SIGN_POSN_USED|LOCALE_POSN); + continue; + case '(': /* enclose negatives with () */ + if (flags & SIGN_POSN_USED) + goto format_error; + flags |= (SIGN_POSN_USED|PARENTH_POSN); + continue; + case '!': /* suppress currency symbol */ + flags |= SUPRESS_CURR_SYMBOL; + continue; + case '-': /* alignment (left) */ + flags |= LEFT_JUSTIFY; + continue; + default: + break; + } + break; + } + + /* field Width */ + if (isdigit_l((unsigned char)*fmt, loc)) { + GET_NUMBER(width, loc); + /* Do we have enough space to put number with + * required width ? + */ + if (dst + width >= s + maxsize) + goto e2big_error; + } + + /* Left precision */ + if (*fmt == '#') { + if (!isdigit_l((unsigned char)*++fmt, loc)) + goto format_error; + GET_NUMBER(left_prec, loc); + } + + /* Right precision */ + if (*fmt == '.') { + if (!isdigit_l((unsigned char)*++fmt, loc)) + goto format_error; + GET_NUMBER(right_prec, loc); + } + + /* Conversion Characters */ + switch (*fmt++) { + case 'i': /* use internaltion currency format */ + flags |= USE_INTL_CURRENCY; + break; + case 'n': /* use national currency format */ + flags &= ~(USE_INTL_CURRENCY); + break; + default: /* required character is missing or + premature EOS */ + goto format_error; + } + + if (flags & USE_INTL_CURRENCY) { + currency_symbol = strdup(lc->int_curr_symbol); + if (currency_symbol != NULL) { + space_char = *(currency_symbol+3); + currency_symbol[3] = '\0'; + } + } else + currency_symbol = strdup(lc->currency_symbol); + + if (currency_symbol == NULL) + goto end_error; /* ENOMEM. */ + + /* value itself */ + value = va_arg(ap, double); + + /* detect sign */ + if (value < 0) { + flags |= IS_NEGATIVE; + value = -value; + } + + /* fill left_prec with amount of padding chars */ + if (left_prec >= 0) { + pad_size = __calc_left_pad((flags ^ IS_NEGATIVE), + currency_symbol, lc) - + __calc_left_pad(flags, currency_symbol, lc); + if (pad_size < 0) + pad_size = 0; + } + + asciivalue = __format_grouped_double(value, &flags, + left_prec, right_prec, pad_char, lc, loc); + if (asciivalue == NULL) + goto end_error; /* errno already set */ + /* to ENOMEM by malloc() */ + + /* set some variables for later use */ + __setup_vars(flags, &cs_precedes, &sep_by_space, + &sign_posn, &signstr, lc); + + /* + * Description of some LC_MONETARY's values: + * + * p_cs_precedes & n_cs_precedes + * + * = 1 - $currency_symbol precedes the value + * for a monetary quantity with a non-negative value + * = 0 - symbol succeeds the value + * + * p_sep_by_space & n_sep_by_space + * + * = 0 - no space separates $currency_symbol + * from the value for a monetary quantity with a + * non-negative value + * = 1 - space separates the symbol from the value + * = 2 - space separates the symbol and the sign string, + * if adjacent. + * + * p_sign_posn & n_sign_posn + * + * = 0 - parentheses enclose the quantity and the + * $currency_symbol + * = 1 - the sign string precedes the quantity and the + * $currency_symbol + * = 2 - the sign string succeeds the quantity and the + * $currency_symbol + * = 3 - the sign string precedes the $currency_symbol + * = 4 - the sign string succeeds the $currency_symbol + * + */ + + tmpptr = dst; + + while (pad_size-- > 0) + PRINT(' '); + + if (sign_posn == 0 && (flags & IS_NEGATIVE)) + PRINT('('); + + if (cs_precedes == 1) { + if (sign_posn == 1 || sign_posn == 3) { + PRINTS(signstr); + if (sep_by_space == 2) /* XXX: ? */ + PRINT(' '); + } + + if (!(flags & SUPRESS_CURR_SYMBOL)) { + PRINTS(currency_symbol); + + if (sign_posn == 4) { + if (sep_by_space == 2) + PRINT(space_char); + PRINTS(signstr); + if (sep_by_space == 1) + PRINT(' '); + } else if (sep_by_space == 1) + PRINT(space_char); + } + } else if (sign_posn == 1) { + PRINTS(signstr); + if (sep_by_space == 2) + PRINT(' '); + } + + PRINTS(asciivalue); + + if (cs_precedes == 0) { + if (sign_posn == 3) { + if (sep_by_space == 1) + PRINT(' '); + PRINTS(signstr); + } + + if (!(flags & SUPRESS_CURR_SYMBOL)) { + if ((sign_posn == 3 && sep_by_space == 2) + || (sep_by_space == 1 + && (sign_posn == 0 + || sign_posn == 1 + || sign_posn == 2 + || sign_posn == 4))) + PRINT(space_char); + PRINTS(currency_symbol); /* XXX: len */ + if (sign_posn == 4) { + if (sep_by_space == 2) + PRINT(' '); + PRINTS(signstr); + } + } + } + + if (sign_posn == 2) { + if (sep_by_space == 2) + PRINT(' '); + PRINTS(signstr); + } + + if (sign_posn == 0) { + if (flags & IS_NEGATIVE) + PRINT(')'); + else if (left_prec >= 0) + PRINT(' '); + } + + if (dst - tmpptr < width) { + if (flags & LEFT_JUSTIFY) { + while (dst - tmpptr < width) + PRINT(' '); + } else { + pad_size = dst-tmpptr; + memmove(tmpptr + width-pad_size, tmpptr, + pad_size); + memset(tmpptr, ' ', width-pad_size); + dst += width-pad_size; + } + } + } + + PRINT('\0'); + free(asciivalue); + free(currency_symbol); + return (dst - s - 1); /* return size of put data except trailing '\0' */ + +e2big_error: + errno = E2BIG; + goto end_error; + +format_error: + errno = EINVAL; + +end_error: + sverrno = errno; + if (asciivalue != NULL) + free(asciivalue); + if (currency_symbol != NULL) + free(currency_symbol); + errno = sverrno; + return (-1); +} + +static void +__setup_vars(int flags, char *cs_precedes, char *sep_by_space, + char *sign_posn, char **signstr, struct lconv *lc) { + + if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) { + *cs_precedes = lc->int_n_cs_precedes; + *sep_by_space = lc->int_n_sep_by_space; + *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->int_n_sign_posn; + *signstr = (lc->negative_sign == '\0') ? "-" + : lc->negative_sign; + } else if (flags & USE_INTL_CURRENCY) { + *cs_precedes = lc->int_p_cs_precedes; + *sep_by_space = lc->int_p_sep_by_space; + *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->int_p_sign_posn; + *signstr = lc->positive_sign; + } else if (flags & IS_NEGATIVE) { + *cs_precedes = lc->n_cs_precedes; + *sep_by_space = lc->n_sep_by_space; + *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->n_sign_posn; + *signstr = (lc->negative_sign == '\0') ? "-" + : lc->negative_sign; + } else { + *cs_precedes = lc->p_cs_precedes; + *sep_by_space = lc->p_sep_by_space; + *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->p_sign_posn; + *signstr = lc->positive_sign; + } + + /* Set defult values for unspecified information. */ + if (*cs_precedes != 0) + *cs_precedes = 1; + if (*sep_by_space == CHAR_MAX) + *sep_by_space = 0; + if (*sign_posn == CHAR_MAX) + *sign_posn = 0; +} + +static int +__calc_left_pad(int flags, char *cur_symb, struct lconv *lc) { + + char cs_precedes, sep_by_space, sign_posn, *signstr; + int left_chars = 0; + + __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr, lc); + + if (cs_precedes != 0) { + left_chars += strlen(cur_symb); + if (sep_by_space != 0) + left_chars++; + } + + switch (sign_posn) { + case 0: + if (flags & IS_NEGATIVE) + left_chars++; + break; + case 1: + left_chars += strlen(signstr); + break; + case 3: + case 4: + if (cs_precedes != 0) + left_chars += strlen(signstr); + } + return (left_chars); +} + +static int +get_groups(int size, char *grouping) { + + int chars = 0; + + if (*grouping == CHAR_MAX || *grouping <= 0) /* no grouping ? */ + return (0); + + while (size > (int)*grouping) { + chars++; + size -= (int)*grouping++; + /* no more grouping ? */ + if (*grouping == CHAR_MAX) + break; + /* rest grouping with same value ? */ + if (*grouping == 0) { + chars += (size - 1) / *(grouping - 1); + break; + } + } + return (chars); +} + +/* convert double to ASCII */ +__private_extern__ const char *__fix_nogrouping(const char *); + +static char * +__format_grouped_double(double value, int *flags, + int left_prec, int right_prec, int pad_char, struct lconv *lc, locale_t loc) { + + char *rslt; + char *avalue; + int avalue_size; + char fmt[32]; + + size_t bufsize; + char *bufend; + + int padded; + + char *grouping; + char decimal_point; + char thousands_sep; + + int groups = 0; + + grouping = __fix_nogrouping(lc->mon_grouping); + decimal_point = *lc->mon_decimal_point; + if (decimal_point == '\0') + decimal_point = *lc->decimal_point; + thousands_sep = *lc->mon_thousands_sep; + if (thousands_sep == '\0') + thousands_sep = *lc->thousands_sep; + + /* fill left_prec with default value */ + if (left_prec == -1) + left_prec = 0; + + /* fill right_prec with default value */ + if (right_prec == -1) { + if (*flags & USE_INTL_CURRENCY) + right_prec = lc->int_frac_digits; + else + right_prec = lc->frac_digits; + + if (right_prec == CHAR_MAX) /* POSIX locale ? */ + right_prec = 2; + } + + if (*flags & NEED_GROUPING) + left_prec += get_groups(left_prec, grouping); + + /* convert to string */ + snprintf_l(fmt, sizeof(fmt), loc, "%%%d.%df", left_prec + right_prec + 1, + right_prec); + avalue_size = asprintf_l(&avalue, loc, fmt, value); + if (avalue_size < 0) + return (NULL); + + /* make sure that we've enough space for result string */ + bufsize = strlen(avalue)*2+1; + rslt = malloc(bufsize); + if (rslt == NULL) { + free(avalue); + return (NULL); + } + memset(rslt, 0, bufsize); + bufend = rslt + bufsize - 1; /* reserve space for trailing '\0' */ + + /* skip spaces at beggining */ + padded = 0; + while (avalue[padded] == ' ') { + padded++; + avalue_size--; + } + + if (right_prec > 0) { + bufend -= right_prec; + memcpy(bufend, avalue + avalue_size+padded-right_prec, + right_prec); + *--bufend = decimal_point; + avalue_size -= (right_prec + 1); + } + + if ((*flags & NEED_GROUPING) && + thousands_sep != '\0' && /* XXX: need investigation */ + *grouping != CHAR_MAX && + *grouping > 0) { + while (avalue_size > (int)*grouping) { + GRPCPY(*grouping); + GRPSEP; + grouping++; + + /* no more grouping ? */ + if (*grouping == CHAR_MAX) + break; + + /* rest grouping with same value ? */ + if (*grouping == 0) { + grouping--; + while (avalue_size > *grouping) { + GRPCPY(*grouping); + GRPSEP; + } + } + } + if (avalue_size != 0) + GRPCPY(avalue_size); + padded -= groups; + + } else { + bufend -= avalue_size; + memcpy(bufend, avalue+padded, avalue_size); + if (right_prec == 0) + padded--; /* decrease assumed $decimal_point */ + } + + /* do padding with pad_char */ + if (padded > 0) { + bufend -= padded; + memset(bufend, pad_char, padded); + } + + bufsize = bufsize - (bufend - rslt) + 1; + memmove(rslt, bufend, bufsize); + free(avalue); + return (rslt); +} + +ssize_t +strfmon(char * __restrict s, size_t maxsize, const char * __restrict format, + ...) +{ + ssize_t ret; + va_list ap; + + va_start(ap, format); + ret = _strfmon(s, maxsize, __current_locale(), format, ap); + va_end(ap); + return ret; +} + +ssize_t +strfmon_l(char * __restrict s, size_t maxsize, locale_t loc, + const char * __restrict format, ...) +{ + ssize_t ret; + va_list ap; + + NORMALIZE_LOCALE(loc); + va_start(ap, format); + ret = _strfmon(s, maxsize, loc, format, ap); + va_end(ap); + return ret; +} diff --git a/stdlib/strfmon.3 b/stdlib/strfmon.3 new file mode 100644 index 0000000..3634fbb --- /dev/null +++ b/stdlib/strfmon.3 @@ -0,0 +1,192 @@ +.\" Copyright (c) 2001 Jeroen Ruigrok van der Werven +.\" 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 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/stdlib/strfmon.3,v 1.7 2003/01/06 06:21:25 tjr Exp $ +.\" +.Dd October 12, 2002 +.Dt STRFMON 3 +.Os +.Sh NAME +.Nm strfmon , +.Nm strfmon_l +.Nd convert monetary value to string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In monetary.h +.Ft ssize_t +.Fo strfmon +.Fa "char *restrict s" +.Fa "size_t maxsize" +.Fa "const char *restrict format" +.Fa "..." +.Fc +.In monetary.h +.In xlocale.h +.Ft ssize_t +.Fo strfmon_l +.Fa "char *restrict s" +.Fa "size_t maxsize" +.Fa "locale_t loc" +.Fa "const char *restrict format" +.Fa "..." +.Fc +.Sh DESCRIPTION +The +.Fn strfmon +function places characters into the array pointed to by +.Fa s , +as controlled by the string pointed to by +.Fa format . +No more than +.Fa maxsize +bytes are placed into the array. +.Pp +While the +.Fn strfmon +function uses the current locale, the +.Fn strfmon_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Pp +The format string is composed of zero or more directives: +ordinary characters (not +.Cm % ) , +which are copied unchanged to the output stream; and conversion +specifications, each of which results in fetching zero or more subsequent +arguments. +Each conversion specification is introduced by the +.Cm % +character. +After the +.Cm % , +the following appear in sequence: +.Bl -bullet +.It +Zero or more of the following flags: +.Bl -tag -width "XXX" +.It Cm = Ns Ar f +A +.Sq Cm = +character followed by another character +.Ar f +which is used as the numeric fill character. +.It Cm ^ +Do not use grouping characters, regardless of the current locale default. +.It Cm + +Represent positive values by prefixing them with a positive sign, +and negative values by prefixing them with a negative sign. +This is the default. +.It Cm \&( +Enclose negative values in parentheses. +.It Cm \&! +Do not include a currency symbol in the output. +.It Cm \- +Left justify the result. +Only valid when a field width is specified. +.El +.It +An optional minimum field width as a decimal number. +By default, there is no minimum width. +.It +A +.Sq Cm # +sign followed by a decimal number specifying the maximum +expected number of digits after the radix character. +.It +A +.Sq Cm \&. +character followed by a decimal number specifying the number +the number of digits after the radix character. +.It +One of the following conversion specifiers: +.Bl -tag -width "XXX" +.It Cm i +The +.Vt double +argument is formatted as an international monetary amount. +.It Cm n +The +.Vt double +argument is formatted as a national monetary amount. +.It Cm % +A +.Sq Li % +character is written. +.El +.El +.Sh RETURN VALUES +If the total number of resulting bytes, including the terminating +.Dv NULL +byte, is not more than +.Fa maxsize , +.Fn strfmon +returns the number of bytes placed into the array pointed to by +.Fa s , +not including the terminating +.Dv NULL +byte. +Otherwise, \-1 is returned, +the contents of the array are indeterminate, +and +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn strfmon +function will fail if: +.Bl -tag -width Er +.It Bq Er E2BIG +Conversion stopped due to lack of space in the buffer. +.It Bq Er EINVAL +The format string is invalid. +.It Bq Er ENOMEM +Not enough memory for temporary buffers. +.El +.Sh SEE ALSO +.Xr localeconv 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn strfmon +function +conforms to +.St -p1003.1-2001 . +.Sh AUTHORS +.An -nosplit +The +.Fn strfmon +function was implemented by +.An Alexey Zelkin Aq phantom@FreeBSD.org . +.Pp +This manual page was written by +.An Jeroen Ruigrok van der Werven Aq asmodai@FreeBSD.org +based on the standards' text. +.Sh BUGS +The +.Fn strfmon +function does not correctly handle multibyte characters in the +.Fa format +argument. diff --git a/stdlib/strhash-fbsd.c b/stdlib/strhash-fbsd.c new file mode 100644 index 0000000..60cacbd --- /dev/null +++ b/stdlib/strhash-fbsd.c @@ -0,0 +1,406 @@ +/* + * + * Copyright 1990 + * Terry Jones & Jordan Hubbard + * + * PCS Computer Systeme, GmbH. + * Munich, West Germany + * + * + * All rights reserved. + * + * This is unsupported software and is subject to change without notice. + * the author makes no representations about the suitability of this software + * for any purpose. It is supplied "as is" without express or implied + * warranty. + * + * 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 the name of the author not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + */ + +/* + * This is a fairly simple open addressing hash scheme. + * Terry did all the code, I just did the spec. + * Thanks again, you crazy Aussie.. + * + */ + +/* + * $Log: strhash.c,v $ + * Revision 2.0 90/03/26 01:44:26 jkh + * pre-beta check-in + * + * Revision 1.8 90/03/09 19:22:35 jkh + * Fixed bogus comment. + * + * Revision 1.7 90/03/09 19:01:08 jkh + * Added comments, GPL. + * + * Revision 1.6 90/03/08 17:55:58 terry + * Rearranged hash_purge to be a tiny bit more efficient. + * Added verbose option to hash_stats. + * + * Revision 1.5 90/03/08 17:19:54 terry + * Added hash_purge. Added arg to hash_traverse. Changed all + * void * to Generic. + * + * Revision 1.4 90/03/08 12:02:35 terry + * Fixed problems with allocation that I screwed up last night. + * Changed bucket lists to be singly linked. Thanks to JKH, my hero. + * + * Revision 1.3 90/03/07 21:33:33 terry + * Cleaned up a few decls to keep gcc -Wall quiet. + * + * Revision 1.2 90/03/07 21:14:53 terry + * Comments. Added HASH_STATS define. Removed hash_find() + * and new_node(). + * + * Revision 1.1 90/03/07 20:49:45 terry + * Initial revision + * + * + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strhash.c,v 1.10 2002/03/22 21:53:10 obrien Exp $"); + +#include +#include +#include +#include +#include + +#define HASH_NULL (hash_table *)0 +#define NODE_NULL (hash_node *)0 +#define GENERIC_NULL (void *)0 + +#define HASH_SZ 97 + + +static int _hash(int size, char *key); +static hash_node *list_find(caddr_t key, hash_node *head); +static int assign_key(char *key, hash_node *node); + + +/* + * hash_create() + * + * Malloc room for a new hash table and then room for its + * bucket pointers. Then set all the buckets to + * point to 0. Return the address of the new table. + */ +hash_table * +hash_create(int size) +{ + int i; + hash_table *new = (hash_table *)malloc(sizeof(hash_table)); + + if (!new || size < 0){ + return HASH_NULL; + } + + if (size == 0){ + size = HASH_SZ; + } + + if (!(new->buckets = (hash_node **)malloc(size * sizeof(hash_node *)))){ + return HASH_NULL; + } + + for (i = 0; i < size; i++){ + new->buckets[i] = NODE_NULL; + } + new->size = size; + + return new; +} + + +/* + * list_find() + * + * Find the key in the linked list pointed to by head. + */ +static hash_node * +list_find(caddr_t key, hash_node *head) +{ + while (head){ + if (!strcmp(head->key, key)){ + return head; + } + head = head->next; + } + return NODE_NULL; +} + + +/* + * _hash() + * + * Compute the hash value for the given key. + */ +static int +_hash(int size, char *key) +{ + unsigned int h = 0x0; + + while (*key){ + h = (h << 1) ^ (h ^ (unsigned char) *key++); + } + + h %= size; + return h; +} + +/* + * hash_destroy() + * + * Find the key and (if it's there) remove it entirely. + * The function (*nukefunc)() is in charge of disposing + * of the storage help by the data associated with the node. + */ +void +hash_destroy(hash_table *table, char *key, void (*nukefunc)()) +{ + int bucket = _hash(table->size, key); + hash_node *found = table->buckets[bucket]; + hash_node *to_free = NODE_NULL; + + if (!found) { + return; + } + + if (!strcmp(found->key, key)) { + /* + * It was the head of the list. + */ + table->buckets[bucket] = found->next; + to_free = found; + } + else { + /* + * Walk the list, looking one ahead. + */ + while (found->next) { + if (!strcmp(found->next->key, key)) { + to_free = found->next; + found->next = found->next->next; + break; + } + found = found->next; + } + + if (!to_free){ + return; + } + } + + if (nukefunc) + (*nukefunc)(to_free->key, to_free->data); + free(to_free); + return; +} + + +/* + * hash_search() + * + * Search the table for the given key. Then: + * + * 1) If you find it and there is no replacement function, just + * return what you found. (This is a simple search). + * 2) If you find it and there is a replacement function, run + * the function on the data you found, and replace the old + * data with whatever is passed in datum. Return 0. + * 3) If you don't find it and there is some datum, insert a + * new item into the table. Insertions go at the front of + * the bucket. Return 0. + * 4) Otherwise just return 0. + * + */ +void * +hash_search(hash_table *table, caddr_t key, void *datum, + void (*replace_func)()) +{ + int bucket = _hash(table->size, key); + hash_node *found = list_find(key, table->buckets[bucket]); + + if (found){ + if (!replace_func){ + return found->data; + } + else{ + (*replace_func)(found->data); + found->data = datum; + } + } + else{ + if (datum){ + + hash_node *new = (hash_node *)malloc(sizeof(hash_node)); + + if (!new || !assign_key(key, new)){ + return GENERIC_NULL; + } + new->data = datum; + new->next = table->buckets[bucket]; + table->buckets[bucket] = new; + return new; + } + } + return GENERIC_NULL; +} + + +/* + * assign_key() + * + * Set the key value of a node to be 'key'. Get some space from + * malloc and copy it in etc. Return 1 if all is well, 0 otherwise. + */ +static int +assign_key(char *key, hash_node *node) +{ + if (!node || !key){ + return 0; + } + + if (!(node->key = (char *)malloc(strlen(key) + 1))){ + return 0; + } + + node->key[0] = '\0'; + strcat(node->key, key); + return 1; +} + +/* + * hash_traverse() + * + * Traverse the hash table and run the function func on the + * data found at each node and the argument we're passed for it. + */ +void +hash_traverse(hash_table *table, int (*func)(), void *arg) +{ + int i; + int size = table->size; + + if (!func) + return; + + for (i = 0; i < size; i++) { + hash_node *n = table->buckets[i]; + while (n) { + if ((*func)(n->key, n->data, arg) == 0) + return; + n = n->next; + } + } + return; +} + +/* + * hash_purge() + * + * Run through the entire hash table. Call purge_func + * on the data found at each node, and then free the node. + * Set all the bucket pointers to 0. + */ +void +hash_purge(hash_table *table, void (*purge_func)(char *p1, void *p2)) +{ + int i; + int size = table->size; + + for (i = 0; i < size; i++) { + hash_node *n = table->buckets[i]; + if (n) { + do { + hash_node *to_free = n; + if (purge_func) { + (*purge_func)(n->key, n->data); + } + n = n->next; + free(to_free); + } while (n); + table->buckets[i] = NODE_NULL; + } + } +} + +#undef min +#define min(a, b) (a) < (b) ? (a) : (b) + +/* + * hash_stats() + * + * Print statistics about the current table allocation to stdout. + */ +void +hash_stats(hash_table *table, int verbose) +{ + int i; + int total_elements = 0; + int non_empty_buckets = 0; + int max_count = 0; + int max_repeats = 0; + int *counts; + int size = table->size; + + if (!(counts = (int *)malloc(size * sizeof(int)))){ + fprintf(stderr, "malloc returns 0\n"); + exit(1); + } + + for (i = 0; i < size; i++){ + int x = 0; + hash_node *n = table->buckets[i]; + counts[i] = 0; + while (n){ + if (!x){ + x = 1; + non_empty_buckets++; + if (verbose){ + printf("bucket %2d: ", i); + } + } + if (verbose){ + printf(" %s", n->key); + } + counts[i]++; + n = n->next; + } + + total_elements += counts[i]; + if (counts[i] > max_count){ + max_count = counts[i]; + max_repeats = 1; + } + else if (counts[i] == max_count){ + max_repeats++; + } + + if (counts[i] && verbose){ + printf(" (%d)\n", counts[i]); + } + } + + printf("\n"); + printf("%d element%s in storage.\n", total_elements, total_elements == 1 ? "" : "s"); + + if (total_elements){ + printf("%d of %d (%.2f%%) buckets are in use\n", non_empty_buckets, size, + (double)100 * (double)non_empty_buckets / (double)(size)); + printf("the maximum number of elements in a bucket is %d (%d times)\n", max_count, max_repeats); + printf("average per bucket is %f\n", (double)total_elements / (double)non_empty_buckets); + printf("optimal would be %f\n", (double)total_elements / (double)(min(size, total_elements))); + } + return; +} diff --git a/stdlib/strtod.3 b/stdlib/strtod.3 new file mode 100644 index 0000000..b57f810 --- /dev/null +++ b/stdlib/strtod.3 @@ -0,0 +1,202 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd March 2, 2003 +.Dt STRTOD 3 +.Os +.Sh NAME +.Nm strtod , strtof , strtold +.Nd convert +.Tn ASCII +string to floating point +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft double +.Fo strtod +.Fa "const char *restrict nptr" +.Fa "char **restrict endptr" +.Fc +.Ft float +.Fo strtof +.Fa "const char *restrict nptr" +.Fa "char **restrict endptr" +.Fc +.Ft "long double" +.Fo strtold +.Fa "const char *restrict nptr" +.Fa "char **restrict endptr" +.Fc +.Sh DESCRIPTION +These conversion +functions convert the initial portion of the string +pointed to by +.Fa nptr +to +.Vt double , +.Vt float , +and +.Vt "long double" +representation, respectively. +.Pp +The expected form of the string +is an optional plus (``+'') or minus (``\-'') sign, +followed by either: +.Bl -bullet +.It +a decimal significand, consisting of a sequence of decimal digits +(optionally containing a decimal-point character) or +.It +a hexadecimal significand, consisting of a ``0X'' or ``0x'' followed +by a sequence of hexadecimal digits +(optionally containing a decimal-point character). +.El +.Pp +In both cases, the significand may be optionally followed by an +exponent. +An exponent consists of an ``E'' or ``e'' (for decimal +constants) or a ``P'' or ``p'' (for hexadecimal constants), +followed by an optional plus or minus sign, followed by a +sequence of decimal digits. +For decimal constants, the exponent indicates the power of 10 by +which the significand should be scaled. +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. +.Pp +In any of the above cases, leading white-space characters in the +string (as defined by the +.Xr isspace 3 +function) are skipped. +The decimal point +character is defined in the program's locale (category +.Dv LC_NUMERIC ) . +.Pp +Extended locale versions of these functions are documented in +.Xr strtod_l 3 . +See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn strtod , +.Fn strtof , +and +.Fn strtold +functions return the converted value, if any. +.Pp +If +.Fa endptr +is not +.Dv NULL , +a pointer to the character after the last character used +in the conversion is stored in the location referenced by +.Fa endptr . +.Pp +If no conversion is performed, zero is returned and the value of +.Fa nptr +is stored in the location referenced by +.Fa endptr . +.Pp +If the correct value would cause overflow, plus or minus +.Dv HUGE_VAL , +.Dv HUGE_VALF , +or +.Dv HUGE_VALL +is returned (according to the sign and type of the return value), and +.Er ERANGE +is stored in +.Va errno . +If the correct value would cause underflow, zero is +returned and +.Er ERANGE +is stored in +.Va errno . +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er ERANGE +Overflow or underflow occurred. +.El +.Sh SEE ALSO +.Xr atof 3 , +.Xr atoi 3 , +.Xr atol 3 , +.Xr strtod_l 3 , +.Xr strtol 3 , +.Xr strtoul 3 , +.Xr wcstod 3 +.Sh STANDARDS +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. +.Sh AUTHORS +The author of this software is +.An David M. Gay . +.Pp +.Bd -literal +Copyright (c) 1998 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. +.Ed diff --git a/stdlib/strtoimax-fbsd.c b/stdlib/strtoimax-fbsd.c new file mode 100644 index 0000000..38d8ee8 --- /dev/null +++ b/stdlib/strtoimax-fbsd.c @@ -0,0 +1,151 @@ +/*- + * Copyright (c) 1992, 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[] = "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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include + +/* + * Convert a string to an intmax_t integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +intmax_t +strtoimax_l(const char * __restrict nptr, char ** __restrict endptr, int base, + locale_t loc) +{ + const char *s; + uintmax_t acc; + char c; + uintmax_t cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace_l((unsigned char)c, loc)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for intmax_t is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set 'any' if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? (uintmax_t)-(INTMAX_MIN + INTMAX_MAX) + INTMAX_MAX + : INTMAX_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? INTMAX_MIN : INTMAX_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +intmax_t +strtoimax(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + return strtoimax_l(nptr, endptr, base, __current_locale()); +} diff --git a/stdlib/strtol-fbsd.c b/stdlib/strtol-fbsd.c new file mode 100644 index 0000000..1ee81f4 --- /dev/null +++ b/stdlib/strtol-fbsd.c @@ -0,0 +1,151 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include + + +/* + * Convert a string to a long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long +strtol_l(const char * __restrict nptr, char ** __restrict endptr, int base, + locale_t loc) +{ + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace_l((unsigned char)c, loc)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set 'any' if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX + : LONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LONG_MIN : LONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +long +strtol(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + return strtol_l(nptr, endptr, base, __current_locale()); +} diff --git a/stdlib/strtol.3 b/stdlib/strtol.3 new file mode 100644 index 0000000..dfa12fe --- /dev/null +++ b/stdlib/strtol.3 @@ -0,0 +1,261 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd November 28, 2001 +.Dt STRTOL 3 +.Os +.Sh NAME +.Nm strtoimax , +.Nm strtol , +.Nm strtoll , +.Nm strtoq +.Nd "convert a string value to a" +.Vt long , "long long" , intmax_t +or +.Vt quad_t +integer +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In inttypes.h +.Ft intmax_t +.Fo strtoimax +.Fa "const char *restrict str" +.Fa "char **restrict endptr" +.Fa "int base" +.Fc +.In stdlib.h +.Ft long +.Fo strtol +.Fa "const char *restrict str" +.Fa "char **restrict endptr" +.Fa "int base" +.Fc +.Ft long long +.Fo strtoll +.Fa "const char *restrict str" +.Fa "char **restrict endptr" +.Fa "int base" +.Fc +.In sys/types.h +.In stdlib.h +.In limits.h +.Ft quad_t +.Fo strtoq +.Fa "const char *str" +.Fa "char **endptr" +.Fa "int base" +.Fc +.Sh DESCRIPTION +The +.Fn strtol +function +converts the string in +.Fa str +to a +.Vt long +value. +The +.Fn strtoll +function +converts the string in +.Fa str +to a +.Vt "long long" +value. +The +.Fn strtoimax +function +converts the string in +.Fa str +to an +.Vt intmax_t +value. +The +.Fn strtoq +function +converts the string in +.Fa str +to a +.Vt quad_t +value. +The conversion is done according to the given +.Fa base , +which must be between 2 and 36 inclusive, +or be the special value 0. +.Pp +The string may begin with an arbitrary amount of white space +(as determined by +.Xr isspace 3 ) +followed by a single optional +.Ql + +or +.Ql - +sign. +If +.Fa base +is zero or 16, +the string may then include a +.Dq Li 0x +prefix, +and the number will be read in base 16; otherwise, a zero +.Fa base +is taken as 10 (decimal) unless the next character is +.Ql 0 , +in which case it is taken as 8 (octal). +.Pp +The remainder of the string is converted to a +.Vt long , "long long" , intmax_t +or +.Vt quad_t +value in the obvious manner, +stopping at the first character which is not a valid digit +in the given base. +(In bases above 10, the letter +.Ql A +in either upper or lower case +represents 10, +.Ql B +represents 11, and so forth, with +.Ql Z +representing 35.) +.Pp +If +.Fa endptr +is not +.Dv NULL , +.Fn strtol +stores the address of the first invalid character in +.Fa *endptr . +If there were no digits at all, however, +.Fn strtol +stores the original value of +.Fa str +in +.Fa *endptr . +(Thus, if +.Fa *str +is not +.Ql \e0 +but +.Fa **endptr +is +.Ql \e0 +on return, the entire string was valid.) +.Pp +Extended locale versions of these functions are documented in +.Xr strtol_l 3 . +See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn strtol , +.Fn strtoll , +.Fn strtoimax , +and +.Fn strtoq +functions +return the result of the conversion, +unless the value would underflow or overflow. +If no conversion could be performed, 0 is returned and +the global variable +.Va errno +is set to +.Er EINVAL +(the last feature is not portable across all platforms). +If an overflow or underflow occurs, +.Va errno +is set to +.Er ERANGE +and the function return value is clamped according +to the following table. +.Bl -column -offset indent ".Fn strtoimax" ".Dv INTMAX_MIN" ".Dv INTMAX_MAX" +.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 +.It Fn strtoq Ta Dv LLONG_MIN Ta Dv LLONG_MAX +.El +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EINVAL +The value of +.Fa base +is not supported or +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 LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +.In limits.h +is necessary for the +.Fn strtol +and +.Fn strtoll +functions. +.Sh SEE ALSO +.Xr atof 3 , +.Xr atoi 3 , +.Xr atol 3 , +.Xr strtod 3 , +.Xr strtol_l 3 , +.Xr strtoul 3 , +.Xr wcstol 3 , +.Xr compat 5 +.Sh STANDARDS +The +.Fn strtol +function +conforms to +.St -isoC . +The +.Fn strtoll +and +.Fn strtoimax +functions +conform to +.St -isoC-99 . +The +.Bx +.Fn strtoq +function is deprecated. diff --git a/stdlib/strtoll-fbsd.c b/stdlib/strtoll-fbsd.c new file mode 100644 index 0000000..2a3f9de --- /dev/null +++ b/stdlib/strtoll-fbsd.c @@ -0,0 +1,151 @@ +/*- + * Copyright (c) 1992, 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include + +/* + * Convert a string to a long long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long long +strtoll_l(const char * __restrict nptr, char ** __restrict endptr, int base, + locale_t loc) +{ + const char *s; + unsigned long long acc; + char c; + unsigned long long cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace_l((unsigned char)c, loc)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for quads is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set 'any' if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX + : LLONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LLONG_MIN : LLONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +long long +strtoll(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + return strtoll_l(nptr, endptr, base, __current_locale()); +} diff --git a/stdlib/strtoq-fbsd.c b/stdlib/strtoq-fbsd.c new file mode 100644 index 0000000..f6d28b1 --- /dev/null +++ b/stdlib/strtoq-fbsd.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 1992, 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include + +#include + +/* + * Convert a string to a quad integer. + */ +quad_t +strtoq(const char *nptr, char **endptr, int base) +{ + + return strtoll_l(nptr, endptr, base, __current_locale()); +} + +quad_t +strtoq_l(const char *nptr, char **endptr, int base, locale_t loc) +{ + + /* no need to call NORMALIZE_LOCALE(loc) because strtoll_l will */ + return strtoll_l(nptr, endptr, base, loc); +} diff --git a/stdlib/strtoul-fbsd.c b/stdlib/strtoul-fbsd.c new file mode 100644 index 0000000..816068a --- /dev/null +++ b/stdlib/strtoul-fbsd.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include + +/* + * Convert a string to an unsigned long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long +strtoul_l(const char * __restrict nptr, char ** __restrict endptr, int base, + locale_t loc) +{ + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace_l((unsigned char)c, loc)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = ULONG_MAX / base; + cutlim = ULONG_MAX % base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +unsigned long +strtoul(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + return strtoul_l(nptr, endptr, base, __current_locale()); +} diff --git a/stdlib/strtoul.3 b/stdlib/strtoul.3 new file mode 100644 index 0000000..b7f916d --- /dev/null +++ b/stdlib/strtoul.3 @@ -0,0 +1,255 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd November 28, 2001 +.Dt STRTOUL 3 +.Os +.Sh NAME +.Nm strtoul , +.Nm strtoull , +.Nm strtoumax , +.Nm strtouq +.Nd "convert a string to an" +.Vt "unsigned long" , "unsigned long long" , uintmax_t , +or +.Vt u_quad_t +integer +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft "unsigned long" +.Fo strtoul +.Fa "const char *restrict str" +.Fa "char **restrict endptr" +.Fa "int base" +.Fc +.Ft "unsigned long long" +.Fo strtoull +.Fa "const char *restrict str" +.Fa "char **restrict endptr" +.Fa "int base" +.Fc +.In inttypes.h +.Ft uintmax_t +.Fo strtoumax +.Fa "const char *restrict str" +.Fa "char **restrict endptr" +.Fa "int base" +.Fc +.In sys/types.h +.In stdlib.h +.In limits.h +.Ft u_quad_t +.Fo strtouq +.Fa "const char *str" +.Fa "char **endptr" +.Fa "int base" +.Fc +.Sh DESCRIPTION +The +.Fn strtoul +function +converts the string in +.Fa str +to an +.Vt "unsigned long" +value. +The +.Fn strtoull +function +converts the string in +.Fa str +to an +.Vt "unsigned long long" +value. +The +.Fn strtoumax +function +converts the string in +.Fa str +to an +.Vt uintmax_t +value. +The +.Fn strtouq +function +converts the string in +.Fa str +to a +.Vt u_quad_t +value. +The conversion is done according to the given +.Fa base , +which must be between 2 and 36 inclusive, +or be the special value 0. +.Pp +The string may begin with an arbitrary amount of white space +(as determined by +.Xr isspace 3 ) +followed by a single optional +.Ql + +or +.Ql - +sign. +If +.Fa base +is zero or 16, +the string may then include a +.Dq Li 0x +prefix, +and the number will be read in base 16; otherwise, a zero +.Fa base +is taken as 10 (decimal) unless the next character is +.Ql 0 , +in which case it is taken as 8 (octal). +.Pp +The remainder of the string is converted to an +.Vt "unsigned long" +value in the obvious manner, +stopping at the end of the string +or at the first character that does not produce a valid digit +in the given base. +(In bases above 10, the letter +.Ql A +in either upper or lower case +represents 10, +.Ql B +represents 11, and so forth, with +.Ql Z +representing 35.) +.Pp +If +.Fa endptr +is not +.Dv NULL , +.Fn strtoul +stores the address of the first invalid character in +.Fa *endptr . +If there were no digits at all, however, +.Fn strtoul +stores the original value of +.Fa str +in +.Fa *endptr . +(Thus, if +.Fa *str +is not +.Ql \e0 +but +.Fa **endptr +is +.Ql \e0 +on return, the entire string was valid.) +.Sh RETURN VALUES +The +.Fn strtoul , +.Fn strtoull , +.Fn strtoumax +and +.Fn strtouq +functions +return either the result of the conversion +or, if there was a leading minus sign, +the negation of the result of the conversion, +unless the original (non-negated) value would overflow; +in the latter case, +.Fn strtoul +returns +.Dv ULONG_MAX , +.Fn strtoull +returns +.Dv ULLONG_MAX , +.Fn strtoumax +returns +.Dv UINTMAX_MAX , +and +.Fn strtouq +returns +.Dv ULLONG_MAX . +In all cases, +.Va errno +is set to +.Er ERANGE . +If no conversion could be performed, 0 is returned and +the global variable +.Va errno +is set to +.Er EINVAL . +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EINVAL +The value of +.Fa base +is not supported or +no conversion could be performed. +.It Bq Er ERANGE +The given string was out of range; the value converted has been clamped. +.El +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +.In limits.h +is necessary for the +.Fn strtoul +and +.Fn strtoull +functions. +.Sh SEE ALSO +.Xr strtol 3 , +.Xr strtol_l 3 , +.Xr wcstoul 3 , +.Xr compat 5 +.Sh STANDARDS +The +.Fn strtoul +function +conforms to +.St -isoC . +The +.Fn strtoull +and +.Fn strtoumax +functions +conform to +.St -isoC-99 . +The +.Bx +.Fn strtouq +function is deprecated. diff --git a/stdlib/strtoull-fbsd.c b/stdlib/strtoull-fbsd.c new file mode 100644 index 0000000..a26c033 --- /dev/null +++ b/stdlib/strtoull-fbsd.c @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 1992, 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include + +/* + * Convert a string to an unsigned long long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long long +strtoull_l(const char * __restrict nptr, char ** __restrict endptr, int base, + locale_t loc) +{ + const char *s; + unsigned long long acc; + char c; + unsigned long long cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * See strtoq for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace_l((unsigned char)c, loc)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = ULLONG_MAX / base; + cutlim = ULLONG_MAX % base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULLONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +unsigned long long +strtoull(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + return strtoull_l(nptr, endptr, base, __current_locale()); +} diff --git a/stdlib/strtoumax-fbsd.c b/stdlib/strtoumax-fbsd.c new file mode 100644 index 0000000..de4dcb3 --- /dev/null +++ b/stdlib/strtoumax-fbsd.c @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 1992, 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[] = "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 $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include + +/* + * Convert a string to a uintmax_t integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +uintmax_t +strtoumax_l(const char * __restrict nptr, char ** __restrict endptr, int base, + locale_t loc) +{ + const char *s; + uintmax_t acc; + char c; + uintmax_t cutoff; + int neg, any, cutlim; + + NORMALIZE_LOCALE(loc); + /* + * See strtoimax for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace_l((unsigned char)c, loc)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = UINTMAX_MAX / base; + cutlim = UINTMAX_MAX % base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = UINTMAX_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +uintmax_t +strtoumax(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + return strtoumax_l(nptr, endptr, base, __current_locale()); +} diff --git a/stdlib/strtouq-fbsd.c b/stdlib/strtouq-fbsd.c new file mode 100644 index 0000000..a8ea87c --- /dev/null +++ b/stdlib/strtouq-fbsd.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 1992, 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include + +#include + +/* + * Convert a string to an unsigned quad integer. + */ +u_quad_t +strtouq(const char *nptr, char **endptr, int base) +{ + + return strtoull_l(nptr, endptr, base, __current_locale()); +} + +u_quad_t +strtouq_l(const char *nptr, char **endptr, int base, locale_t loc) +{ + + /* no need to call NORMALIZE_LOCALE(loc) because strtoull_l will */ + return strtoull_l(nptr, endptr, base, loc); +} diff --git a/stdlib/system-fbsd.c b/stdlib/system-fbsd.c new file mode 100644 index 0000000..5173959 --- /dev/null +++ b/stdlib/system-fbsd.c @@ -0,0 +1,133 @@ +/* + * 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[] = "@(#)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 $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" + +#if __DARWIN_UNIX03 +#include + +static pthread_mutex_t __systemfn_mutex = PTHREAD_MUTEX_INITIALIZER; +extern int __unix_conforming; +#ifdef VARIANT_CANCELABLE +extern void _pthread_testcancel(pthread_t thread, int isconforming); +#endif /* VARIANT_CANCELABLE */ +#endif /* __DARWIN_UNIX03 */ + +int +__system(command) + const char *command; +{ + pid_t pid, savedpid; + int pstat; + struct sigaction ign, intact, quitact; + sigset_t newsigblock, oldsigblock; + +#if __DARWIN_UNIX03 + if (__unix_conforming == 0) + __unix_conforming = 1; +#ifdef VARIANT_CANCELABLE + _pthread_testcancel(pthread_self(), 1); +#endif /* VARIANT_CANCELABLE */ +#endif /* __DARWIN_UNIX03 */ + + if (!command) { /* just checking... */ + if (access(_PATH_BSHELL, F_OK) == -1) /* if no sh or no access */ + return(0); + else + return(1); + } + +#if __DARWIN_UNIX03 + pthread_mutex_lock(&__systemfn_mutex); +#endif /* __DARWIN_UNIX03 */ + /* + * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save + * existing signal dispositions. + */ + ign.sa_handler = SIG_IGN; + (void)sigemptyset(&ign.sa_mask); + ign.sa_flags = 0; + (void)_sigaction(SIGINT, &ign, &intact); + (void)_sigaction(SIGQUIT, &ign, &quitact); + (void)sigemptyset(&newsigblock); + (void)sigaddset(&newsigblock, SIGCHLD); + (void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); + switch(pid = fork()) { + case -1: /* error */ + break; + case 0: /* child */ + /* + * Restore original signal dispositions and exec the command. + */ + (void)_sigaction(SIGINT, &intact, NULL); + (void)_sigaction(SIGQUIT, &quitact, NULL); + (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); +#if __DARWIN_UNIX03 + pthread_mutex_unlock(&__systemfn_mutex); +#endif /* __DARWIN_UNIX03 */ + execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL); + _exit(127); + default: /* parent */ + savedpid = pid; + do { + pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0); + } while (pid == -1 && errno == EINTR); + break; + } + (void)_sigaction(SIGINT, &intact, NULL); + (void)_sigaction(SIGQUIT, &quitact, NULL); + (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); +#if __DARWIN_UNIX03 + pthread_mutex_unlock(&__systemfn_mutex); +#endif /* __DARWIN_UNIX03 */ + return(pid == -1 ? -1 : pstat); +} + +__weak_reference(__system, system); +__weak_reference(__system, _system); diff --git a/stdlib/system.3 b/stdlib/system.3 new file mode 100644 index 0000000..52dc99a --- /dev/null +++ b/stdlib/system.3 @@ -0,0 +1,103 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt SYSTEM 3 +.Os +.Sh NAME +.Nm system +.Nd pass a command to the shell +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn system "const char *command" +.Sh DESCRIPTION +The +.Fn system +function +hands the argument +.Fa command +to the command interpreter +.Xr sh 1 . +The calling process waits for the shell +to finish executing the command, +ignoring +.Dv SIGINT +and +.Dv SIGQUIT , +and blocking +.Dv SIGCHLD . +.Pp +If +.Fa command +is a +.Dv NULL +pointer, +.Fn system +will return non-zero if the command interpreter +.Xr sh 1 +is available, and zero if it is not. +.Pp +The +.Fn system +function +returns the exit status of the shell as returned by +.Xr waitpid 2 , +or \-1 if an error occurred when invoking +.Xr fork 2 +or +.Xr waitpid 2 . +A return value of 127 means the execution of the shell +failed. +.Sh SEE ALSO +.Xr sh 1 , +.Xr execve 2 , +.Xr fork 2 , +.Xr waitpid 2 , +.Xr popen 3 +.Sh STANDARDS +The +.Fn system +function +conforms to +.St -isoC +and is expected to be +.St -p1003.2 +compatible. diff --git a/stdlib/tdelete-fbsd.c b/stdlib/tdelete-fbsd.c new file mode 100644 index 0000000..7fb6893 --- /dev/null +++ b/stdlib/tdelete-fbsd.c @@ -0,0 +1,71 @@ +/* $NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $ */ + +/* + * Tree search generalized from Knuth (6.2.2) Algorithm T just like + * the AT&T man page says. + * + * The node_t structure is for internal use only, lint doesn't grok it. + * + * Written by reading the System V Interface Definition, not the code. + * + * Totally public domain. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $"); +#endif /* LIBC_SCCS and not lint */ +#endif +__FBSDID("$FreeBSD: src/lib/libc/stdlib/tdelete.c,v 1.6 2003/01/05 02:43:18 tjr Exp $"); + +#define _SEARCH_PRIVATE +#include +#include + + +/* + * delete node with given key + * + * vkey: key to be deleted + * vrootp: address of the root of the tree + * compar: function to carry out node comparisons + */ +void * +tdelete(const void * __restrict vkey, void ** __restrict vrootp, + int (*compar)(const void *, const void *)) +{ + node_t **rootp = (node_t **)vrootp; + node_t *p, *q, *r; + int cmp; + + if (rootp == NULL || (p = *rootp) == NULL) + return NULL; + + while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0) { + p = *rootp; + rootp = (cmp < 0) ? + &(*rootp)->llink : /* follow llink branch */ + &(*rootp)->rlink; /* follow rlink branch */ + if (*rootp == NULL) + return NULL; /* key not found */ + } + r = (*rootp)->rlink; /* D1: */ + if ((q = (*rootp)->llink) == NULL) /* Left NULL? */ + q = r; + else if (r != NULL) { /* Right link is NULL? */ + if (r->llink == NULL) { /* D2: Find successor */ + r->llink = q; + q = r; + } else { /* D3: Find NULL link */ + for (q = r->llink; q->llink != NULL; q = r->llink) + r = q; + r->llink = q->rlink; + q->llink = (*rootp)->llink; + q->rlink = (*rootp)->rlink; + } + } + free(*rootp); /* D4: Free node */ + *rootp = q; /* link parent to new node */ + return p; +} diff --git a/stdlib/tfind-fbsd.c b/stdlib/tfind-fbsd.c new file mode 100644 index 0000000..b58ed88 --- /dev/null +++ b/stdlib/tfind-fbsd.c @@ -0,0 +1,48 @@ +/* $NetBSD: tfind.c,v 1.2 1999/09/16 11:45:37 lukem Exp $ */ + +/* + * Tree search generalized from Knuth (6.2.2) Algorithm T just like + * the AT&T man page says. + * + * The node_t structure is for internal use only, lint doesn't grok it. + * + * Written by reading the System V Interface Definition, not the code. + * + * Totally public domain. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: tfind.c,v 1.2 1999/09/16 11:45:37 lukem Exp $"); +#endif /* LIBC_SCCS and not lint */ +#endif +__FBSDID("$FreeBSD: src/lib/libc/stdlib/tfind.c,v 1.5 2003/01/05 02:43:18 tjr Exp $"); + +#define _SEARCH_PRIVATE +#include +#include + +/* find a node, or return 0 */ +void * +tfind(vkey, vrootp, compar) + const void *vkey; /* key to be found */ + void * const *vrootp; /* address of the tree root */ + int (*compar)(const void *, const void *); +{ + node_t **rootp = (node_t **)vrootp; + + if (rootp == NULL) + return NULL; + + while (*rootp != NULL) { /* T1: */ + int r; + + if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */ + return *rootp; /* key found */ + rootp = (r < 0) ? + &(*rootp)->llink : /* T3: follow left branch */ + &(*rootp)->rlink; /* T4: follow right branch */ + } + return NULL; +} diff --git a/stdlib/tsearch-fbsd.c b/stdlib/tsearch-fbsd.c new file mode 100644 index 0000000..edeccde --- /dev/null +++ b/stdlib/tsearch-fbsd.c @@ -0,0 +1,58 @@ +/* $NetBSD: tsearch.c,v 1.3 1999/09/16 11:45:37 lukem Exp $ */ + +/* + * Tree search generalized from Knuth (6.2.2) Algorithm T just like + * the AT&T man page says. + * + * The node_t structure is for internal use only, lint doesn't grok it. + * + * Written by reading the System V Interface Definition, not the code. + * + * Totally public domain. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: tsearch.c,v 1.3 1999/09/16 11:45:37 lukem Exp $"); +#endif /* LIBC_SCCS and not lint */ +#endif +__FBSDID("$FreeBSD: src/lib/libc/stdlib/tsearch.c,v 1.4 2003/01/05 02:43:18 tjr Exp $"); + +#define _SEARCH_PRIVATE +#include +#include + +/* find or insert datum into search tree */ +void * +tsearch(vkey, vrootp, compar) + const void *vkey; /* key to be located */ + void **vrootp; /* address of tree root */ + int (*compar)(const void *, const void *); +{ + node_t *q; + node_t **rootp = (node_t **)vrootp; + + if (rootp == NULL) + return NULL; + + while (*rootp != NULL) { /* Knuth's T1: */ + int r; + + if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */ + return *rootp; /* we found it! */ + + rootp = (r < 0) ? + &(*rootp)->llink : /* T3: follow left branch */ + &(*rootp)->rlink; /* T4: follow right branch */ + } + + q = malloc(sizeof(node_t)); /* T5: key not found */ + if (q != 0) { /* make new node */ + *rootp = q; /* link new node to old */ + /* LINTED const castaway ok */ + q->key = (void *)vkey; /* initialize new node */ + q->llink = q->rlink = NULL; + } + return q; +} diff --git a/stdlib/tsearch.3 b/stdlib/tsearch.3 new file mode 100644 index 0000000..64a8b2b --- /dev/null +++ b/stdlib/tsearch.3 @@ -0,0 +1,181 @@ +.\" $NetBSD$ +.\" 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. +.\" +.\" 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. +.\" +.\" 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 $ +.\" +.Dd June 15, 1997 +.Dt TSEARCH 3 +.Os +.Sh NAME +.Nm tdelete , +.Nm tfind , +.Nm tsearch , +.Nm twalk +.Nd manipulate binary search trees +.Sh SYNOPSIS +.In search.h +.Ft void * +.Fo tdelete +.Fa "const void *restrict key" +.Fa "void **restrict rootp" +.Fa "int (*compar) (const void *key1, const void *key2)" +.Fc +.Ft void * +.Fo tfind +.Fa "const void *key" +.Fa "void *const *rootp" +.Fa "int (*compar) (const void *key1, const void *key2)" +.Fc +.Ft void * +.Fo tsearch +.Fa "const void *key" +.Fa "void **rootp" +.Fa "int (*compar) (const void *key1, const void *key2)" +.Fc +.Ft void +.Fo twalk +.Fa "const void *root" +.Fa "void (*compar) (const void *node, VISIT order, int level)" +.Fc +.Sh DESCRIPTION +The +.Fn tdelete , +.Fn tfind , +.Fn tsearch , +and +.Fn twalk +functions manage binary search trees, based on algorithms T and D +from Knuth (6.2.2). +The comparison function passed in by +the user takes two arguments, each of which is a key +pointer. +This function has the same style of return values as +.Xr strcmp 3 . +.Pp +The +.Fn tfind +function +searches for a node whose key matches the argument +.Fa key +in the binary tree rooted at +.Fa rootp , +returning a pointer to the node if it is found and NULL +if it is not. +.Pp +Note that a node is itself a pointer to the key of the node. +Thus, you should generally cast this result to a +double pointer to the data type stored in the tree, for example +(struct myType **), and use double indirection to retrieve the +original key value. +.Pp +The +.Fn tsearch +function is identical to +.Fn tfind +except that, if no match is found, +it inserts a new node for the +.Fa key +into the tree and returns a pointer to the node. +If +.Fa rootp +points to a NULL value, a new binary search tree is created. +.Pp +The +.Fn tdelete +function deletes a node from the specified binary search tree +and returns a pointer to the parent of the node that was deleted. +It takes the same arguments as +.Fn tfind +and +.Fn tsearch . +If the node to be deleted is the root of the binary search tree, +.Fa rootp +will be adjusted. +.Pp +The +.Fn twalk +function walks the binary search tree rooted in +.Fa root +and calls the function +.Fa action +on each node. +The +.Fa action +function is called with three arguments: a pointer to the current node, +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). +.Pp +As +.Fn twalk +traverses the tree, it calls the +.Fa action +function with the traversal type "preorder" +before visiting the left subtree of the +.Fa node , +with the +traversal type "postorder" before visiting the right subtree +of the +.Fa node , +and with the traversal type "endorder" after +visiting the right subtree of the +.Fa node . +.Pp. +The +.Fa action +function is called only once for a leaf-node, with the +traversal type "leaf." +.Pp +Note: the names for the traversal types differ somewhat from +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 +function returns NULL if allocation of a new node fails (usually +due to a lack of free memory). +.Pp +The +.Fn tfind , +.Fn tsearch , +and +.Fn tdelete +functions +return NULL if +.Fa rootp +is NULL or the node cannot be found. +.Pp +The +.Fn twalk +function returns no value. diff --git a/stdlib/twalk-fbsd.c b/stdlib/twalk-fbsd.c new file mode 100644 index 0000000..516ef44 --- /dev/null +++ b/stdlib/twalk-fbsd.c @@ -0,0 +1,58 @@ +/* $NetBSD: twalk.c,v 1.1 1999/02/22 10:33:16 christos Exp $ */ + +/* + * Tree search generalized from Knuth (6.2.2) Algorithm T just like + * the AT&T man page says. + * + * The node_t structure is for internal use only, lint doesn't grok it. + * + * Written by reading the System V Interface Definition, not the code. + * + * Totally public domain. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: twalk.c,v 1.1 1999/02/22 10:33:16 christos Exp $"); +#endif /* LIBC_SCCS and not lint */ +#endif +__FBSDID("$FreeBSD: src/lib/libc/stdlib/twalk.c,v 1.5 2003/01/05 02:43:18 tjr Exp $"); + +#define _SEARCH_PRIVATE +#include +#include + +static void trecurse(const node_t *, + void (*action)(const void *, VISIT, int), int level); + +/* Walk the nodes of a tree */ +static void +trecurse(root, action, level) + const node_t *root; /* Root of the tree to be walked */ + void (*action)(const void *, VISIT, int); + int level; +{ + + if (root->llink == NULL && root->rlink == NULL) + (*action)(root, leaf, level); + else { + (*action)(root, preorder, level); + if (root->llink != NULL) + trecurse(root->llink, action, level + 1); + (*action)(root, postorder, level); + if (root->rlink != NULL) + trecurse(root->rlink, action, level + 1); + (*action)(root, endorder, level); + } +} + +/* Walk the nodes of a tree */ +void +twalk(vroot, action) + const void *vroot; /* Root of the tree to be walked */ + void (*action)(const void *, VISIT, int); +{ + if (vroot != NULL && action != NULL) + trecurse(vroot, action, 0); +} diff --git a/stdtime/FreeBSD/asctime.c.patch b/stdtime/FreeBSD/asctime.c.patch new file mode 100644 index 0000000..b0683a7 --- /dev/null +++ b/stdtime/FreeBSD/asctime.c.patch @@ -0,0 +1,13 @@ +--- asctime.c.orig 2004-11-25 11:38:44.000000000 -0800 ++++ asctime.c 2004-12-07 23:48:08.000000000 -0800 +@@ -23,9 +23,7 @@ + */ + + char * +-asctime_r(timeptr, buf) +-const struct tm * timeptr; +-char * buf; ++asctime_r(const struct tm * __restrict timeptr, char * __restrict buf) + { + static const char wday_name[][3] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" diff --git a/stdtime/FreeBSD/ctime.3.patch b/stdtime/FreeBSD/ctime.3.patch new file mode 100644 index 0000000..e046ce8 --- /dev/null +++ b/stdtime/FreeBSD/ctime.3.patch @@ -0,0 +1,224 @@ +--- _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 @@ + .In time.h + .Vt extern char *tzname[2] ; + .Ft char * ++.Fn asctime "const struct tm *timeptr" ++.Ft char * ++.Fn asctime_r "const struct tm *restrict timeptr" "char *restrict buf" ++.Ft char * + .Fn ctime "const time_t *clock" ++.Ft char * ++.Fn ctime_r "const time_t *clock" "char *buf" + .Ft double + .Fn difftime "time_t time1" "time_t time0" +-.Ft char * +-.Fn asctime "const struct tm *tm" ++.Ft struct tm * ++.Fn gmtime "const time_t *clock" ++.Ft struct tm * ++.Fn gmtime_r "const time_t *clock" "struct tm *result" + .Ft struct tm * + .Fn localtime "const time_t *clock" + .Ft struct tm * +-.Fn gmtime "const time_t *clock" ++.Fn localtime_r "const time_t *clock" "struct tm *result" + .Ft time_t +-.Fn mktime "struct tm *tm" ++.Fn mktime "struct tm *timeptr" + .Ft time_t +-.Fn timegm "struct tm *tm" +-.Ft char * +-.Fn ctime_r "const time_t *clock" "char *buf" +-.Ft struct tm * +-.Fn localtime_r "const time_t *clock" "struct tm *result" +-.Ft struct tm * +-.Fn gmtime_r "const time_t *clock" "struct tm *result" +-.Ft char * +-.Fn asctime_r "const struct tm *tm" "char *buf" ++.Fn timegm "struct tm *timeptr" + .Sh DESCRIPTION + The functions + .Fn ctime , +-.Fn gmtime ++.Fn gmtime , + and + .Fn localtime + all take as an argument a time value representing the time in seconds since +@@ -92,10 +92,10 @@ + The function + .Fn localtime + converts the time value pointed at by +-.Fa clock , +-and returns a pointer to a ++.Fa clock . ++It returns a pointer to a + .Dq Fa struct tm +-(described below) which contains ++(described below), which contains + 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 @@ + .Fn localtime + uses + .Xr tzset 3 +-to initialize time conversion information if ++to initialize time conversion information, if + .Xr tzset 3 + has not already been called by the process. + .Pp +@@ -118,36 +118,36 @@ + .Fa tzname + to a pointer to an + .Tn ASCII +-string that's the time zone abbreviation to be ++string containing the time zone abbreviation to be + used with + .Fn localtime Ns 's + return value. + .Pp + The function + .Fn gmtime +-similarly converts the time value, but without any time zone adjustment, +-and returns a pointer to a tm structure (described below). ++also converts the time value, but makes no time zone adjustment. ++It returns a pointer to a tm structure (described below). + .Pp + The + .Fn ctime + function +-adjusts the time value for the current time zone in the same manner as +-.Fn localtime , +-and returns a pointer to a 26-character string of the form: ++adjusts the time value for the current time zone, in the same manner as ++.Fn localtime . ++It returns a pointer to a 26-character string of the form: + .Bd -literal -offset indent + Thu Nov 24 18:22:48 1986\en\e0 + .Ed + .Pp +-All the fields have constant width. ++All of the fields have constant width. + .Pp + The + .Fn ctime_r + function + provides the same functionality as +-.Fn ctime +-except the caller must provide the output buffer ++.Fn ctime , ++except that the caller must provide the output buffer + .Fa buf +-to store the result, which must be at least 26 characters long. ++(which must be at least 26 characters long) to store the result. + The + .Fn localtime_r + and +@@ -156,17 +156,17 @@ + provide the same functionality as + .Fn localtime + and +-.Fn gmtime ++.Fn gmtime , + respectively, except the caller must provide the output buffer + .Fa result . + .Pp + The + .Fn asctime + function +-converts the broken down time in the structure ++converts the broken-out time in the structure + .Fa tm +-pointed at by +-.Fa *tm ++(pointed at by ++.Fa *timeptr ) + to the form + shown in the example above. + .Pp +@@ -174,17 +174,19 @@ + .Fn asctime_r + function + provides the same functionality as +-.Fn asctime +-except the caller provide the output buffer ++.Fn asctime , ++except that the caller provides the output buffer + .Fa buf +-to store the result, which must be at least 26 characters long. ++(which must be at least 26 characters long) to store the result. + .Pp + The functions + .Fn mktime + and + .Fn timegm +-convert the broken-down time in the structure +-pointed to by tm into a time value with the same encoding as that of the ++convert the broken-out time ++(in the structure pointed to by ++.Fa *timeptr ) ++into a time value with the same encoding as that of the + values returned by the + .Xr time 3 + function (that is, seconds from the Epoch, +@@ -197,17 +199,17 @@ + .Xr tzset 3 ) . + The + .Fn timegm +-function +-interprets the input structure as representing Universal Coordinated Time ++function interprets the input structure ++as representing Universal Coordinated Time + .Pq Tn UTC . + .Pp + The original values of the + .Fa tm_wday + and + .Fa tm_yday +-components of the structure are ignored, and the original values of the +-other components are not restricted to their normal ranges, and will be +-normalized if needed. ++components of the structure are ignored. The original values of the ++other components are not restricted to their normal ranges and will be ++normalized, if need be. + For example, + October 40 is changed into November 9, + a +@@ -223,7 +225,7 @@ + causes + .Fn mktime + to presume initially that summer time (for example, Daylight Saving Time) +-is or is not in effect for the specified time, respectively. ++is or is not (respectively) in effect for the specified time. + A negative value for + .Fa tm_isdst + causes the +@@ -265,7 +267,8 @@ + .Fa time0 ) , + expressed in seconds. + .Pp +-External declarations as well as the tm structure definition are in the ++External declarations, as well as the tm structure definition, ++are contained in the + .In time.h + include file. + The tm structure includes at least the following fields: +@@ -286,14 +289,14 @@ + The + field + .Fa tm_isdst +-is non-zero if summer time is in effect. ++is non-zero if summer (i.e., Daylight Saving) time is in effect. + .Pp + The field + .Fa tm_gmtoff + is the offset (in seconds) of the time represented from + .Tn UTC , + with positive +-values indicating east of the Prime Meridian. ++values indicating locations east of the Prime Meridian. + .Sh SEE ALSO + .Xr date 1 , + .Xr gettimeofday 2 , diff --git a/stdtime/FreeBSD/ftime.3.patch b/stdtime/FreeBSD/ftime.3.patch index c5d12ff..0f04f6c 100644 --- a/stdtime/FreeBSD/ftime.3.patch +++ b/stdtime/FreeBSD/ftime.3.patch @@ -1,11 +1,48 @@ ---- ftime.3.orig Sat Jan 3 18:59:56 2004 -+++ ftime.3 Tue Jan 13 17:41:55 2004 -@@ -38,8 +38,6 @@ +--- ftime.3 2004-04-15 16:20:14.000000000 -0700 ++++ ftime.3.edit 2006-07-12 11:19:27.000000000 -0700 +@@ -38,13 +38,12 @@ .Sh NAME .Nm ftime .Nd get date and time -.Sh LIBRARY -.Lb libcompat .Sh SYNOPSIS - .In sys/types.h +-.In sys/types.h .In sys/timeb.h + .Ft int +-.Fn ftime "struct timeb *tp" ++.Fo ftime ++.Fa "struct timeb *tp" ++.Fc + .Sh DESCRIPTION + .Bf -symbolic + This interface is obsoleted by +@@ -69,16 +68,24 @@ + }; + .Ed + .Pp +-The structure contains the time since the epoch in seconds, +-up to 1000 milliseconds of more-precise interval, +-the local time zone (measured in minutes of time westward from Greenwich), ++The structure contains the time since the epoch, in seconds; ++up to 1000 milliseconds of more-precise interval; ++the local time zone (measured in minutes of time westward from Greenwich); + and a flag that, if nonzero, indicates that + Daylight Saving time applies locally during the appropriate part of the year. ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Fd #include ++.Pp ++The include file ++.In sys/types.h ++is necessary. + .Sh SEE ALSO + .Xr gettimeofday 2 , + .Xr settimeofday 2 , + .Xr ctime 3 , +-.Xr time 3 ++.Xr time 3 , ++.Xr compat 5 + .Sh HISTORY + The + .Nm diff --git a/stdtime/FreeBSD/localtime.c.patch b/stdtime/FreeBSD/localtime.c.patch index 6dc7819..0bdf074 100644 --- a/stdtime/FreeBSD/localtime.c.patch +++ b/stdtime/FreeBSD/localtime.c.patch @@ -1,9 +1,13 @@ ---- localtime.c.orig 2004-11-01 23:24:08.000000000 -0800 -+++ localtime.c 2004-11-05 23:43:55.000000000 -0800 -@@ -24,6 +24,18 @@ +--- localtime.c.orig 2007-05-23 18:18:18.000000000 -0700 ++++ localtime.c 2007-05-23 18:20:52.000000000 -0700 +@@ -22,8 +22,22 @@ + #include "namespace.h" + #include #include ++#include #include #include ++#include +#ifdef NOTIFY_TZ +//#define NOTIFY_TZ_DEBUG +//#define NOTIFY_TZ_DEBUG_FILE "/var/log/localtime.debug" @@ -19,7 +23,15 @@ #include "private.h" #include "un-namespace.h" -@@ -135,6 +147,16 @@ +@@ -33,6 +47,7 @@ + + #define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x) + #define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x) ++extern int __pthread_tsd_first; + + /* + ** SunOS 4.1.1 headers lack O_BINARY. +@@ -135,40 +150,96 @@ #define DAY_OF_YEAR 1 /* n - day of year */ #define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ @@ -36,7 +48,52 @@ /* ** Prototypes for static functions. */ -@@ -154,6 +176,10 @@ ++#define localsub _st_localsub ++#define time1 _st_time1 ++#define tzset_basic _st_tzset_basic ++__private_extern__ ++#ifdef __LP64__ ++struct tm * localsub(const time_t * timep, long offset, ++ struct tm * tmp); ++#else /* !__LP64__ */ ++void localsub(const time_t * timep, long offset, ++ struct tm * tmp); ++#endif /* __LP64__ */ ++__private_extern__ ++time_t time1(struct tm * tmp, ++#ifdef __LP64__ ++ struct tm *(*funcp) (const time_t *, ++ long, struct tm *), ++#else /* !__LP64__ */ ++ void(*funcp) (const time_t *, ++ long, struct tm *), ++#endif /* __LP64__ */ ++ long offset, ++ int unix03); ++__private_extern__ ++void tzset_basic(void); ++ ++#define lcl_mutex _st_lcl_mutex + ++#if !BUILDING_VARIANT + static long detzcode(const char * codep); +-static const char * getzname(const char * strp); ++static const char * getzname(const char * strp, char **name, size_t *len); + static const char * getnum(const char * strp, int * nump, int min, + int max); + static const char * getsecs(const char * strp, long * secsp); + static const char * getoffset(const char * strp, long * offsetp); + static const char * getrule(const char * strp, struct rule * rulep); + static void gmtload(struct state * sp); +-static void gmtsub(const time_t * timep, long offset, ++#ifdef __LP64__ ++static struct tm * gmtsub(const time_t * timep, long offset, + struct tm * tmp); +-static void localsub(const time_t * timep, long offset, ++#else /* !__LP64__ */ ++static void gmtsub(const time_t * timep, long offset, + struct tm * tmp); ++#endif /* __LP64__ */ static int increment_overflow(int * number, int delta); static int normalize_overflow(int * tensptr, int * unitsptr, int base); @@ -45,9 +102,42 @@ +static void notify_register_tz(char *file, notify_tz_t *p); +#endif /* NOTIFY_TZ */ static void settzname(void); - static time_t time1(struct tm * tmp, +-static time_t time1(struct tm * tmp, +- void(*funcp) (const time_t *, +- long, struct tm *), +- long offset); + static time_t time2(struct tm *tmp, ++#ifdef __LP64__ ++ struct tm *(*funcp) (const time_t *, ++ long, struct tm*), ++#else /* !__LP64__ */ + void(*funcp) (const time_t *, + long, struct tm*), +- long offset, int * okayp); ++#endif /* __LP64__ */ ++ long offset, int * okayp, int unix03); + static time_t time2sub(struct tm *tmp, ++#ifdef __LP64__ ++ struct tm *(*funcp) (const time_t *, ++ long, struct tm*), ++#else /* !__LP64__ */ void(*funcp) (const time_t *, -@@ -194,8 +220,13 @@ + long, struct tm*), +- long offset, int * okayp, int do_norm_secs); ++#endif /* __LP64__ */ ++ long offset, int * okayp, int do_norm_secs, ++ int unix03); ++#ifdef __LP64__ ++static struct tm * timesub(const time_t * timep, long offset, ++ const struct state * sp, struct tm * tmp); ++#else /* !__LP64__ */ + static void timesub(const time_t * timep, long offset, + const struct state * sp, struct tm * tmp); ++#endif /* __LP64__ */ + static int tmcomp(const struct tm * atmp, + const struct tm * btmp); + static time_t transtime(time_t janfirst, int year, +@@ -194,10 +265,15 @@ #endif /* !defined TZ_STRLEN_MAX */ static char lcl_TZname[TZ_STRLEN_MAX + 1]; @@ -57,11 +147,15 @@ +#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; +#endif /* NOTIFY_TZ */ - static pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER; - static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; ++__private_extern__ pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER; ++static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; -@@ -214,15 +245,62 @@ + char * tzname[2] = { + wildabbr, +@@ -214,15 +290,62 @@ static struct tm tm; @@ -126,7 +220,7 @@ static long detzcode(codep) const char * const codep; -@@ -246,14 +324,14 @@ +@@ -246,14 +369,14 @@ tzname[1] = wildabbr; #ifdef USG_COMPAT daylight = 0; @@ -143,7 +237,7 @@ return; } #endif /* defined ALL_STATE */ -@@ -266,7 +344,7 @@ +@@ -266,7 +389,7 @@ if (ttisp->tt_isdst) daylight = 1; if (i == 0 || !ttisp->tt_isdst) @@ -152,7 +246,7 @@ #endif /* defined USG_COMPAT */ #ifdef ALTZONE if (i == 0 || ttisp->tt_isdst) -@@ -286,6 +364,117 @@ +@@ -286,6 +409,119 @@ } } @@ -193,6 +287,8 @@ +#endif /* NOTIFY_TZ_DEBUG */ +} + ++extern uint32_t notify_monitor_file(int token, char *path, int flags); ++ +static void +notify_register_tz(char *file, notify_tz_t *p) +{ @@ -270,7 +366,7 @@ static int tzload(name, sp) const char * name; -@@ -295,6 +484,9 @@ +@@ -295,6 +531,9 @@ int i; int fid; @@ -280,7 +376,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 +504,15 @@ +@@ -312,7 +551,15 @@ ** to hold the longest file name string that the implementation ** guarantees can be opened." */ @@ -296,7 +392,7 @@ if (name[0] == ':') ++name; -@@ -320,7 +520,11 @@ +@@ -320,7 +567,11 @@ if (!doaccess) { if ((p = TZDIR) == NULL) return -1; @@ -308,7 +404,7 @@ return -1; (void) strcpy(fullname, p); (void) strcat(fullname, "/"); -@@ -332,6 +536,10 @@ +@@ -332,6 +583,10 @@ doaccess = TRUE; name = fullname; } @@ -319,7 +415,7 @@ if (doaccess && access(name, R_OK) != 0) return -1; if ((fid = _open(name, OPEN_MODE)) == -1) -@@ -350,6 +558,9 @@ +@@ -350,6 +605,9 @@ int ttisstdcnt; int ttisgmtcnt; @@ -329,7 +425,52 @@ i = _read(fid, u.buf, sizeof u.buf); if (_close(fid) != 0) return -1; -@@ -764,6 +975,9 @@ +@@ -456,14 +714,24 @@ + */ + + static const char * +-getzname(strp) ++getzname(strp, name, len) + const char * strp; ++char ** name; ++size_t * len; + { + char c; ++ char * ket; + ++ if (*strp == '<' && (ket = strchr(strp, '>')) != NULL) { ++ *name = (char *)(strp + 1); ++ *len = ket - strp - 1; ++ return ket + 1; ++ } ++ *name = (char *)strp; + while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && + c != '+') + ++strp; ++ *len = strp - *name; + return strp; + } + +@@ -743,16 +1011,15 @@ + int load_result; + + INITIALIZE(dstname); +- stdname = name; + if (lastditch) { ++ stdname = name; + stdlen = strlen(name); /* length of standard zone name */ + name += stdlen; + if (stdlen >= sizeof sp->chars) + stdlen = (sizeof sp->chars) - 1; + stdoffset = 0; + } else { +- name = getzname(name); +- stdlen = name - stdname; ++ name = getzname(name, (char **)&stdname, &stdlen); + if (stdlen < 3) + return -1; + if (*name == '\0') +@@ -764,12 +1031,14 @@ } } load_result = tzload(TZDEFRULES, sp); @@ -339,7 +480,14 @@ if (load_result != 0) sp->leapcnt = 0; /* so, we're off a little */ if (*name != '\0') { -@@ -951,8 +1165,19 @@ + dstname = name; +- name = getzname(name); +- dstlen = name - dstname; /* length of DST zone name */ ++ name = getzname(name, (char **)&dstname, &dstlen); + if (dstlen < 3) + return -1; + if (*name != '\0' && *name != ',' && *name != ';') { +@@ -951,8 +1220,19 @@ static void tzsetwall_basic(void) { @@ -359,7 +507,7 @@ lcl_is_set = -1; #ifdef ALL_STATE -@@ -966,12 +1191,18 @@ +@@ -966,18 +1246,24 @@ #endif /* defined ALL_STATE */ if (tzload((char *) NULL, lclptr) != 0) gmtload(lclptr); @@ -378,7 +526,14 @@ _MUTEX_LOCK(&lcl_mutex); tzsetwall_basic(); _MUTEX_UNLOCK(&lcl_mutex); -@@ -988,8 +1219,18 @@ + } + +-static void ++__private_extern__ void + tzset_basic(void) + { + const char * name; +@@ -988,8 +1274,18 @@ return; } @@ -397,7 +552,7 @@ lcl_is_set = strlen(name) < sizeof lcl_TZname; if (lcl_is_set) (void) strcpy(lcl_TZname, name); -@@ -1014,15 +1255,25 @@ +@@ -1014,15 +1310,25 @@ lclptr->ttis[0].tt_gmtoff = 0; lclptr->ttis[0].tt_abbrind = 0; (void) strcpy(lclptr->chars, gmt); @@ -423,7 +578,20 @@ _MUTEX_LOCK(&lcl_mutex); tzset_basic(); _MUTEX_UNLOCK(&lcl_mutex); -@@ -1049,6 +1300,9 @@ +@@ -1038,7 +1344,11 @@ + */ + + /*ARGSUSED*/ +-static void ++#ifdef __LP64__ ++__private_extern__ struct tm * ++#else /* !__LP64__ */ ++__private_extern__ void ++#endif /* __LP64__ */ + localsub(timep, offset, tmp) + const time_t * const timep; + const long offset; +@@ -1049,11 +1359,18 @@ int i; const time_t t = *timep; @@ -433,16 +601,100 @@ sp = lclptr; #ifdef ALL_STATE if (sp == NULL) { -@@ -1094,7 +1348,7 @@ ++#ifdef __LP64__ ++ return gmtsub(timep, offset, tmp); ++#else /* !__LP64__ */ + gmtsub(timep, offset, tmp); + return; ++#endif /* __LP64__ */ + } + #endif /* defined ALL_STATE */ + if (sp->timecnt == 0 || t < sp->ats[0]) { +@@ -1076,12 +1393,20 @@ + ** t += ttisp->tt_gmtoff; + ** timesub(&t, 0L, sp, tmp); + */ ++#ifdef __LP64__ ++ if (timesub(&t, ttisp->tt_gmtoff, sp, tmp) == NULL) ++ return NULL; ++#else /* !__LP64__ */ + timesub(&t, ttisp->tt_gmtoff, sp, tmp); ++#endif /* __LP64__ */ + tmp->tm_isdst = ttisp->tt_isdst; + tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; + #ifdef TM_ZONE + tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; + #endif /* defined TM_ZONE */ ++#ifdef __LP64__ ++ return tmp; ++#endif /* __LP64__ */ + } + + struct tm * +@@ -1094,8 +1419,9 @@ 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) { - if (_pthread_key_create(&localtime_key, free) < 0) { ++ localtime_key = __pthread_tsd_first + 2; ++ if (pthread_key_init_np(localtime_key, free) < 0) { _pthread_mutex_unlock(&localtime_mutex); return(NULL); -@@ -1146,14 +1400,30 @@ + } +@@ -1110,13 +1436,21 @@ + } + _pthread_mutex_lock(&lcl_mutex); + tzset_basic(); ++#ifdef __LP64__ ++ p_tm = localsub(timep, 0L, p_tm); ++#else /* !__LP64__ */ + localsub(timep, 0L, p_tm); ++#endif /* __LP64__ */ + _pthread_mutex_unlock(&lcl_mutex); + return(p_tm); + } else { + tzset_basic(); ++#ifdef __LP64__ ++ return localsub(timep, 0L, &tm); ++#else /* !__LP64__ */ + localsub(timep, 0L, &tm); + return(&tm); ++#endif /* __LP64__ */ + } + } + +@@ -1125,13 +1459,15 @@ + */ + + struct tm * +-localtime_r(timep, tm) +-const time_t * const timep; +-struct tm * tm; ++localtime_r(const time_t * const __restrict timep, struct tm * __restrict tm) + { + _MUTEX_LOCK(&lcl_mutex); + tzset_basic(); ++#ifdef __LP64__ ++ tm = localsub(timep, 0L, tm); ++#else /* !__LP64__ */ + localsub(timep, 0L, tm); ++#endif /* __LP64__ */ + _MUTEX_UNLOCK(&lcl_mutex); + return tm; + } +@@ -1140,23 +1476,48 @@ + ** gmtsub is to gmtime as localsub is to localtime. + */ + ++#ifdef __LP64__ ++static struct tm * ++#else /* !__LP64__ */ + static void ++#endif /* __LP64__ */ + gmtsub(timep, offset, tmp) + const time_t * const timep; const long offset; struct tm * const tmp; { @@ -473,8 +725,16 @@ +#endif /* NOTIFY_TZ */ } _MUTEX_UNLOCK(&gmt_mutex); ++#ifdef __LP64__ ++ if(timesub(timep, offset, gmtptr, tmp) == NULL) ++ return NULL; ++#else /* !__LP64__ */ timesub(timep, offset, gmtptr, tmp); -@@ -1168,7 +1438,7 @@ ++#endif /* __LP64__ */ + #ifdef TM_ZONE + /* + ** Could get fancy here and deliver something such as +@@ -1168,7 +1529,7 @@ else { #ifdef ALL_STATE if (gmtptr == NULL) @@ -483,12 +743,379 @@ else tmp->TM_ZONE = gmtptr->chars; #endif /* defined ALL_STATE */ #ifndef ALL_STATE -@@ -1188,7 +1458,7 @@ +@@ -1176,6 +1537,9 @@ + #endif /* State Farm */ + } + #endif /* defined TM_ZONE */ ++#ifdef __LP64__ ++ return tmp; ++#endif /* __LP64__ */ + } + struct tm * +@@ -1186,10 +1550,12 @@ + static pthread_key_t gmtime_key = -1; + 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) { - if (_pthread_key_create(&gmtime_key, free) < 0) { ++ gmtime_key = __pthread_tsd_first + 3; ++ if (pthread_key_init_np(gmtime_key, free) < 0) { _pthread_mutex_unlock(&gmtime_mutex); return(NULL); + } +@@ -1206,12 +1572,20 @@ + } + _pthread_setspecific(gmtime_key, p_tm); + } ++#ifdef __LP64__ ++ return gmtsub(timep, 0L, p_tm); ++#else /* !__LP64__ */ + gmtsub(timep, 0L, p_tm); + return(p_tm); ++#endif /* __LP64__ */ + } + else { ++#ifdef __LP64__ ++ return gmtsub(timep, 0L, &tm); ++#else /* !__LP64__ */ + gmtsub(timep, 0L, &tm); + return(&tm); ++#endif /* __LP64__ */ + } + } + +@@ -1224,8 +1598,13 @@ + const time_t * const timep; + struct tm * tm; + { ++ ++#ifdef __LP64__ ++ return gmtsub(timep, 0L, tm); ++#else /* !__LP64__ */ + gmtsub(timep, 0L, tm); + return tm; ++#endif /* __LP64__ */ + } + + #ifdef STD_INSPIRED +@@ -1235,13 +1614,21 @@ + const time_t * const timep; + const long offset; + { ++#ifdef __LP64__ ++ return gmtsub(timep, offset, &tm); ++#else /* !__LP64__ */ + gmtsub(timep, offset, &tm); + return &tm; ++#endif /* __LP64__ */ + } + + #endif /* defined STD_INSPIRED */ + ++#ifdef __LP64__ ++static struct tm * ++#else /* !__LP64__ */ + static void ++#endif /* __LP64__ */ + timesub(timep, offset, sp, tmp) + const time_t * const timep; + const long offset; +@@ -1330,7 +1717,16 @@ + LEAPS_THRU_END_OF(y - 1); + y = newy; + } ++#ifdef __LP64__ ++ y -= TM_YEAR_BASE; ++ if (y < INT_MIN || y > INT_MAX) { ++ errno = EOVERFLOW; ++ return NULL; ++ } ++ tmp->tm_year = y; ++#else /* !__LP64__ */ + tmp->tm_year = y - TM_YEAR_BASE; ++#endif /* __LP64__ */ + 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 +1736,9 @@ + #ifdef TM_GMTOFF + tmp->TM_GMTOFF = offset; + #endif /* defined TM_GMTOFF */ ++#ifdef __LP64__ ++ return tmp; ++#endif /* __LP64__ */ + } + + char * +@@ -1427,12 +1826,17 @@ + } + + static time_t +-time2sub(tmp, funcp, offset, okayp, do_norm_secs) ++time2sub(tmp, funcp, offset, okayp, do_norm_secs, unix03) + struct tm * const tmp; ++#ifdef __LP64__ ++struct tm *(* const funcp)(const time_t*, long, struct tm*); ++#else /* !__LP64__ */ + void (* const funcp)(const time_t*, long, struct tm*); ++#endif /* __LP64__ */ + const long offset; + int * const okayp; + const int do_norm_secs; ++int unix03; + { + const struct state * sp; + int dir; +@@ -1442,6 +1846,9 @@ + time_t newt; + time_t t; + struct tm yourtm, mytm; ++#ifdef __LP64__ ++ long year, il; ++#endif /* __LP64__ */ + + *okayp = FALSE; + yourtm = *tmp; +@@ -1460,33 +1867,64 @@ + ** Turn yourtm.tm_year into an actual year number for now. + ** It is converted back to an offset from TM_YEAR_BASE later. + */ ++#ifdef __LP64__ ++ year = (long)yourtm.tm_year + TM_YEAR_BASE; ++#else /* !__LP64__ */ + if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE)) + return WRONG; ++#endif /* __LP64__ */ + while (yourtm.tm_mday <= 0) { ++#ifdef __LP64__ ++ year--; ++ il = year + (1 < yourtm.tm_mon); ++ yourtm.tm_mday += year_lengths[isleap(il)]; ++#else /* !__LP64__ */ + if (increment_overflow(&yourtm.tm_year, -1)) + return WRONG; + i = yourtm.tm_year + (1 < yourtm.tm_mon); + yourtm.tm_mday += year_lengths[isleap(i)]; ++#endif /* __LP64__ */ + } + while (yourtm.tm_mday > DAYSPERLYEAR) { ++#ifdef __LP64__ ++ il = year + (1 < yourtm.tm_mon); ++ yourtm.tm_mday -= year_lengths[isleap(il)]; ++ year++; ++#else /* !__LP64__ */ + i = yourtm.tm_year + (1 < yourtm.tm_mon); + yourtm.tm_mday -= year_lengths[isleap(i)]; + if (increment_overflow(&yourtm.tm_year, 1)) + return WRONG; ++#endif /* __LP64__ */ + } + for ( ; ; ) { ++#ifdef __LP64__ ++ i = mon_lengths[isleap(year)][yourtm.tm_mon]; ++#else /* !__LP64__ */ + i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon]; ++#endif /* __LP64__ */ + if (yourtm.tm_mday <= i) + break; + yourtm.tm_mday -= i; + if (++yourtm.tm_mon >= MONSPERYEAR) { + yourtm.tm_mon = 0; ++#ifdef __LP64__ ++ year++; ++#else /* !__LP64__ */ + if (increment_overflow(&yourtm.tm_year, 1)) + return WRONG; ++#endif /* __LP64__ */ + } + } ++#ifdef __LP64__ ++ year -= TM_YEAR_BASE; ++ if (year > INT_MAX || year < INT_MIN) ++ return WRONG; ++ yourtm.tm_year = year; ++#else /* !__LP64__ */ + if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE)) + return WRONG; ++#endif /* __LP64__ */ + /* Don't go below 1900 for POLA */ + if (yourtm.tm_year < 0) + return WRONG; +@@ -1527,8 +1965,19 @@ + */ + t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits); + for ( ; ; ) { ++#ifdef __LP64__ ++ if ((*funcp)(&t, offset, &mytm) == NULL) { ++ /* we overflowed, so t is too big */ ++ dir = 1; ++ goto skip_tmcomp; ++ } ++#else /* !__LP64__ */ + (*funcp)(&t, offset, &mytm); ++#endif /* __LP64__ */ + dir = tmcomp(&mytm, &yourtm); ++#ifdef __LP64__ ++skip_tmcomp: ++#endif /* __LP64__ */ + if (dir != 0) { + if (bits-- < 0) + return WRONG; +@@ -1539,6 +1988,9 @@ + else t += ((time_t) 1) << bits; + continue; + } ++ sp = (funcp == localsub) ? lclptr : gmtptr; ++ if (unix03 && sp->typecnt == 1 && yourtm.tm_isdst > 0) ++ yourtm.tm_isdst = 0; /* alternative time does not apply */ + if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) + break; + /* +@@ -1547,7 +1999,6 @@ + ** It's okay to guess wrong since the guess + ** gets checked. + */ +- sp = (funcp == localsub) ? lclptr : gmtptr; + #ifdef ALL_STATE + if (sp == NULL) + return WRONG; +@@ -1560,7 +2011,12 @@ + continue; + newt = t + sp->ttis[j].tt_gmtoff - + sp->ttis[i].tt_gmtoff; ++#ifdef __LP64__ ++ if ((*funcp)(&newt, offset, &mytm) == NULL) ++ return WRONG; ++#else /* !__LP64__ */ + (*funcp)(&newt, offset, &mytm); ++#endif /* __LP64__ */ + if (tmcomp(&mytm, &yourtm) != 0) + continue; + if (mytm.tm_isdst != yourtm.tm_isdst) +@@ -1579,17 +2035,27 @@ + if ((newt < t) != (saved_seconds < 0)) + return WRONG; + t = newt; ++#ifdef __LP64__ ++ if ((*funcp)(&t, offset, tmp) == NULL) ++ return WRONG; ++#else /* !__LP64__ */ + (*funcp)(&t, offset, tmp); ++#endif /* __LP64__ */ + *okayp = TRUE; + return t; + } + + static time_t +-time2(tmp, funcp, offset, okayp) ++time2(tmp, funcp, offset, okayp, unix03) + struct tm * const tmp; ++#ifdef __LP64__ ++struct tm *(* const funcp)(const time_t*, long, struct tm*); ++#else /* !__LP64__ */ + void (* const funcp)(const time_t*, long, struct tm*); ++#endif /* __LP64__ */ + const long offset; + int * const okayp; ++int unix03; + { + time_t t; + +@@ -1598,15 +2064,20 @@ + ** (in case tm_sec contains a value associated with a leap second). + ** If that fails, try with normalization of seconds. + */ +- t = time2sub(tmp, funcp, offset, okayp, FALSE); +- return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE); ++ t = time2sub(tmp, funcp, offset, okayp, FALSE, unix03); ++ return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE, unix03); + } + +-static time_t +-time1(tmp, funcp, offset) ++__private_extern__ time_t ++time1(tmp, funcp, offset, unix03) + struct tm * const tmp; ++#ifdef __LP64__ ++struct tm *(* const funcp)(const time_t *, long, struct tm *); ++#else /* !__LP64__ */ + void (* const funcp)(const time_t *, long, struct tm *); ++#endif /* __LP64__ */ + const long offset; ++int unix03; + { + time_t t; + const struct state * sp; +@@ -1620,7 +2091,7 @@ + + if (tmp->tm_isdst > 1) + tmp->tm_isdst = 1; +- t = time2(tmp, funcp, offset, &okay); ++ t = time2(tmp, funcp, offset, &okay, unix03); + #ifdef PCTS + /* + ** PCTS code courtesy Grant Sullivan (grant@osf.org). +@@ -1664,7 +2135,7 @@ + tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; +- t = time2(tmp, funcp, offset, &okay); ++ t = time2(tmp, funcp, offset, &okay, unix03); + if (okay) + return t; + tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - +@@ -1674,19 +2145,25 @@ + } + return WRONG; + } ++#else /* BUILDING_VARIANT */ ++__private_extern__ pthread_mutex_t lcl_mutex; ++#endif /* BUILDING_VARIANT */ + + time_t + mktime(tmp) + struct tm * const tmp; + { + time_t mktime_return_value; ++ int serrno = errno; + _MUTEX_LOCK(&lcl_mutex); + tzset_basic(); +- mktime_return_value = time1(tmp, localsub, 0L); ++ mktime_return_value = time1(tmp, localsub, 0L, __DARWIN_UNIX03); + _MUTEX_UNLOCK(&lcl_mutex); ++ errno = serrno; + return(mktime_return_value); + } + ++#if !BUILDING_VARIANT + #ifdef STD_INSPIRED + + time_t +@@ -1702,7 +2179,7 @@ + struct tm * const tmp; + { + tmp->tm_isdst = 0; +- return time1(tmp, gmtsub, 0L); ++ return time1(tmp, gmtsub, 0L, __DARWIN_UNIX03); + } + + time_t +@@ -1711,7 +2188,7 @@ + const long offset; + { + tmp->tm_isdst = 0; +- return time1(tmp, gmtsub, offset); ++ return time1(tmp, gmtsub, offset, __DARWIN_UNIX03); + } + + #endif /* defined STD_INSPIRED */ +@@ -1811,3 +2288,4 @@ + } + + #endif /* defined STD_INSPIRED */ ++#endif /* !BUILDING_VARIANT */ diff --git a/stdtime/FreeBSD/strftime.3.patch b/stdtime/FreeBSD/strftime.3.patch index a895006..71386b9 100644 --- a/stdtime/FreeBSD/strftime.3.patch +++ b/stdtime/FreeBSD/strftime.3.patch @@ -1,5 +1,5 @@ ---- strftime.3.orig Fri Mar 11 07:33:40 2005 -+++ strftime.3 Fri Mar 11 07:43:03 2005 +--- _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 @@ .Dt STRFTIME 3 .Os @@ -10,27 +10,44 @@ .Nd format date and time .Sh LIBRARY .Lb libc -@@ -53,6 +54,15 @@ - .Fa "const char * restrict format" - .Fa "const struct tm * restrict timeptr" - .Fc +@@ -48,10 +49,20 @@ + .In time.h + .Ft size_t + .Fo strftime +-.Fa "char * restrict buf" ++.Fa "char *restrict s" + .Fa "size_t maxsize" +-.Fa "const char * restrict format" +-.Fa "const struct tm * restrict timeptr" ++.Fa "const char *restrict format" ++.Fa "const struct tm *restrict timeptr" ++.Fc ++.In time.h +.In xlocale.h +.Ft size_t +.Fo strftime_l -+.Fa "char * restrict buf" ++.Fa "char *restrict s" +.Fa "size_t maxsize" -+.Fa "const char * restrict format" -+.Fa "const struct tm * restrict timeptr" ++.Fa "const char *restrict format" ++.Fa "const struct tm *restrict timeptr" +.Fa "locale_t loc" -+.Fc + .Fc .Sh DESCRIPTION The - .Fn strftime -@@ -83,6 +93,14 @@ +@@ -59,7 +70,7 @@ + function formats the information from + .Fa timeptr + into the buffer +-.Fa buf ++.Fa s , + according to the string pointed to by + .Fa format . + .Pp +@@ -83,6 +94,14 @@ terminating NUL. Otherwise, zero is returned and the buffer contents are indeterminate. .Pp -+While the ++Although the +.Fn strftime +function uses the current locale, the +.Fn strftime_l @@ -41,7 +58,7 @@ The conversion specifications are copied to the buffer after expansion as follows:- .Bl -tag -width "xxxx" -@@ -226,7 +244,8 @@ +@@ -226,7 +245,8 @@ .Xr ctime 3 , .Xr printf 3 , .Xr strptime 3 , @@ -51,3 +68,17 @@ .Sh STANDARDS The .Fn strftime +@@ -253,11 +273,12 @@ + .Ql %u , + .Ql \&%V , + .Ql %z , ++and + .Ql %+ . + .Pp + The peculiar week number and year in the replacements of + .Ql %G , +-.Ql %g ++.Ql %g , + and + .Ql \&%V + are defined in ISO 8601: 1988. diff --git a/stdtime/FreeBSD/strptime.3.patch b/stdtime/FreeBSD/strptime.3.patch index 45367f9..5945d79 100644 --- a/stdtime/FreeBSD/strptime.3.patch +++ b/stdtime/FreeBSD/strptime.3.patch @@ -1,5 +1,5 @@ ---- strptime.3.orig Fri Mar 11 07:33:44 2005 -+++ strptime.3 Fri Mar 11 07:40:29 2005 +--- strptime.3.orig 2007-04-03 12:19:24.000000000 -0700 ++++ strptime.3 2007-04-03 12:54:12.000000000 -0700 @@ -29,7 +29,8 @@ .Dt STRPTIME 3 .Os @@ -10,23 +10,55 @@ .Nd parse date and time string .Sh LIBRARY .Lb libc -@@ -41,6 +42,14 @@ - .Fa "const char * restrict format" - .Fa "struct tm * restrict timeptr" - .Fc +@@ -37,19 +38,28 @@ + .In time.h + .Ft char * + .Fo strptime +-.Fa "const char * restrict buf" +-.Fa "const char * restrict format" +-.Fa "struct tm * restrict timeptr" ++.Fa "const char *restrict buf" ++.Fa "const char *restrict format" ++.Fa "struct tm *restrict tm" ++.Fc ++.In time.h +.In xlocale.h +.Ft char * +.Fo strptime_l -+.Fa "const char * restrict buf" -+.Fa "const char * restrict format" -+.Fa "struct tm * restrict timeptr" ++.Fa "const char *restrict buf" ++.Fa "const char *restrict format" ++.Fa "struct tm *restrict tm" +.Fa "locale_t loc" -+.Fc + .Fc .Sh DESCRIPTION The .Fn strptime -@@ -94,6 +103,14 @@ - .Fa timeptr + function parses the string in the buffer +-.Fa buf ++.Fa buf , + according to the string pointed to by + .Fa format , + and fills in the elements of the structure pointed to by +-.Fa timeptr . ++.Fa tm . + 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 @@ + specify the resulting + .Vt struct tm , + the unspecified members of +-.Va timeptr ++.Va tm + are left untouched. + For example, if + .Fa format +@@ -91,9 +101,17 @@ + .Va tm_min + will be modified. + If time relative to today is desired, initialize the +-.Fa timeptr ++.Fa tm structure with today's date before passing it to .Fn strptime . +.Pp @@ -40,7 +72,15 @@ .Sh RETURN VALUES Upon successful completion, .Fn strptime -@@ -107,7 +124,8 @@ +@@ -104,10 +122,16 @@ + It returns + .Dv NULL + if one of the conversions failed. ++.Sh LEGACY DESCRIPTION ++In legacy mode, the ++.Fa %Y ++format specifier expects exactly 4 digits (leaving any trailing digits for the ++next specifier). .Sh SEE ALSO .Xr date 1 , .Xr scanf 3 , diff --git a/stdtime/FreeBSD/strptime.c.patch b/stdtime/FreeBSD/strptime.c.patch index 498fcd5..2c6acc5 100644 --- a/stdtime/FreeBSD/strptime.c.patch +++ b/stdtime/FreeBSD/strptime.c.patch @@ -1,6 +1,6 @@ ---- strptime.c.orig 2004-11-25 11:38:45.000000000 -0800 -+++ strptime.c 2005-02-24 01:09:32.000000000 -0800 -@@ -61,6 +61,8 @@ +--- strptime.c.orig 2007-04-03 12:19:24.000000000 -0700 ++++ strptime.c 2007-04-03 12:39:20.000000000 -0700 +@@ -61,10 +61,13 @@ #endif /* not lint */ __FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.35 2003/11/17 04:19:15 nectar Exp $"); @@ -9,22 +9,33 @@ #include "namespace.h" #include #include -@@ -72,19 +74,19 @@ + #include ++#include + #include + #include + #include +@@ -72,30 +75,41 @@ #include "libc_private.h" #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); ++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])) ++enum {CONVERT_NONE, CONVERT_GMT, CONVERT_ZONE}; ++ static char * -_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp) -+_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp, locale_t loc) ++_strptime(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t loc) { char c; const char *ptr; int i, ++ year = -1, ++ yday = 0, ++ wday = -1, len; int Ealternative, Oalternative; - struct lc_time_T *tptr = __get_current_time_locale(); @@ -32,7 +43,16 @@ ptr = fmt; while (*ptr != 0) { -@@ -94,8 +96,8 @@ +- if (*buf == 0) +- break; ++ if (*buf == 0) { ++ fmt = ptr; ++ while (isspace_l((unsigned char)*ptr, loc)) { ++ ptr++; ++ } ++ return ((*ptr)==0) ? fmt : 0; /* trailing whitespace is ok */ ++ } + c = *ptr++; if (c != '%') { @@ -43,12 +63,12 @@ buf++; else if (c != *buf++) return 0; -@@ -114,18 +116,18 @@ +@@ -114,18 +128,18 @@ break; case '+': - buf = _strptime(buf, tptr->date_fmt, tm, GMTp); -+ buf = _strptime(buf, tptr->date_fmt, tm, GMTp, loc); ++ buf = _strptime(buf, tptr->date_fmt, tm, convp, loc); if (buf == 0) return 0; break; @@ -65,63 +85,79 @@ i *= 10; i += *buf - '0'; len--; -@@ -137,13 +139,13 @@ +@@ -133,17 +147,21 @@ + if (i < 19) + return 0; + ++ if (year != -1) ++ tm->tm_year = (year % 100) + i * 100 - 1900; ++ else + tm->tm_year = i * 100 - 1900; ++ year = tm->tm_year; break; case 'c': - buf = _strptime(buf, tptr->c_fmt, tm, GMTp); -+ buf = _strptime(buf, tptr->c_fmt, tm, GMTp, loc); ++ buf = _strptime(buf, tptr->c_fmt, tm, convp, loc); if (buf == 0) return 0; break; case 'D': - buf = _strptime(buf, "%m/%d/%y", tm, GMTp); -+ buf = _strptime(buf, "%m/%d/%y", tm, GMTp, loc); ++ buf = _strptime(buf, "%m/%d/%y", tm, convp, loc); if (buf == 0) return 0; break; -@@ -161,47 +163,47 @@ +@@ -161,47 +179,55 @@ goto label; case 'F': - buf = _strptime(buf, "%Y-%m-%d", tm, GMTp); -+ buf = _strptime(buf, "%Y-%m-%d", tm, GMTp, loc); ++ buf = _strptime(buf, "%Y-%m-%d", tm, convp, loc); if (buf == 0) return 0; break; case 'R': - buf = _strptime(buf, "%H:%M", tm, GMTp); -+ buf = _strptime(buf, "%H:%M", tm, GMTp, loc); ++ buf = _strptime(buf, "%H:%M", tm, convp, loc); if (buf == 0) return 0; break; case 'r': - buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp); -+ buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp, loc); ++ buf = _strptime(buf, tptr->ampm_fmt, tm, convp, loc); if (buf == 0) return 0; break; ++ case 'n': ++ case 't': ++ if (!isspace((unsigned char)*buf)) ++ return 0; ++ while (isspace((unsigned char)*buf)) ++ buf++; ++ break; ++ case 'T': - buf = _strptime(buf, "%H:%M:%S", tm, GMTp); -+ buf = _strptime(buf, "%H:%M:%S", tm, GMTp, loc); ++ buf = _strptime(buf, "%H:%M:%S", tm, convp, loc); if (buf == 0) return 0; break; case 'X': - buf = _strptime(buf, tptr->X_fmt, tm, GMTp); -+ buf = _strptime(buf, tptr->X_fmt, tm, GMTp, loc); ++ buf = _strptime(buf, tptr->X_fmt, tm, convp, loc); if (buf == 0) return 0; break; case 'x': - buf = _strptime(buf, tptr->x_fmt, tm, GMTp); -+ buf = _strptime(buf, tptr->x_fmt, tm, GMTp, loc); ++ buf = _strptime(buf, tptr->x_fmt, tm, convp, loc); if (buf == 0) return 0; break; @@ -137,7 +173,13 @@ i *= 10; i += *buf - '0'; len--; -@@ -214,14 +216,14 @@ +@@ -209,19 +235,19 @@ + if (i < 1 || i > 366) + return 0; + +- tm->tm_yday = i - 1; ++ tm->tm_yday = yday = i - 1; + break; case 'M': case 'S': @@ -155,18 +197,18 @@ i *= 10; i += *buf - '0'; len--; -@@ -237,8 +239,8 @@ +@@ -237,8 +263,8 @@ tm->tm_sec = i; } - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) -+ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc)) ++ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') ptr++; break; -@@ -254,11 +256,11 @@ +@@ -254,11 +280,11 @@ * XXX The %l specifier may gobble one too many * digits if used incorrectly. */ @@ -180,18 +222,18 @@ i *= 10; i += *buf - '0'; len--; -@@ -271,8 +273,8 @@ +@@ -271,8 +297,8 @@ tm->tm_hour = i; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) -+ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc)) ++ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') ptr++; break; -@@ -282,7 +284,7 @@ +@@ -282,7 +308,7 @@ * specifiers. */ len = strlen(tptr->am); @@ -200,7 +242,7 @@ if (tm->tm_hour > 12) return 0; if (tm->tm_hour == 12) -@@ -292,7 +294,7 @@ +@@ -292,7 +318,7 @@ } len = strlen(tptr->pm); @@ -209,7 +251,7 @@ if (tm->tm_hour > 12) return 0; if (tm->tm_hour != 12) -@@ -307,12 +309,12 @@ +@@ -307,34 +333,28 @@ case 'a': for (i = 0; i < asizeof(tptr->weekday); i++) { len = strlen(tptr->weekday[i]); @@ -226,11 +268,24 @@ break; } if (i == asizeof(tptr->weekday)) -@@ -330,11 +332,11 @@ - * point to calculate a real value, so just check the - * range for now. - */ + return 0; + +- tm->tm_wday = i; ++ tm->tm_wday = wday = i; + buf += len; + break; + +- case 'U': +- case 'W': +- /* +- * XXX This is bogus, as we can not assume any valid +- * information present in the tm structure at this +- * point to calculate a real value, so just check the +- * range for now. +- */ - if (!isdigit((unsigned char)*buf)) ++ case 'U': /* Sunday week */ ++ case 'W': /* Monday week */ + if (!isdigit_l((unsigned char)*buf, loc)) return 0; @@ -240,60 +295,97 @@ i *= 10; i += *buf - '0'; len--; -@@ -342,13 +344,13 @@ +@@ -342,23 +362,46 @@ if (i > 53) return 0; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) ++ /* Calculate yday if we have enough data */ ++ if ((year != -1) && (wday != -1)) { ++ struct tm mktm; ++ mktm.tm_year = year; ++ mktm.tm_mon = 0; ++ mktm.tm_mday = 1; ++ mktm.tm_sec = 1; ++ mktm.tm_min = mktm.tm_hour = 0; ++ mktm.tm_isdst = 0; ++ mktm.tm_gmtoff = 0; ++ if (mktime(&mktm) != -1) { ++ /* yday0 == Jan 1 == mktm.tm_wday */ ++ int delta = wday - mktm.tm_wday; ++ if (!wday && c =='W') ++ i++; /* Sunday is part of the following week */ ++ yday = 7 * i + delta; ++ if (yday < 0) ++ yday += 7; ++ tm->tm_yday = yday; ++ } ++ } + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) -+ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc)) ++ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') ptr++; break; - case 'w': +- case 'w': - if (!isdigit((unsigned char)*buf)) ++ case 'u': /* [1,7] */ ++ case 'w': /* [0,6] */ + if (!isdigit_l((unsigned char)*buf, loc)) return 0; i = *buf - '0'; -@@ -357,8 +359,8 @@ - - tm->tm_wday = i; - +- if (i > 6) ++ if (i > 6 + (c == 'u')) + return 0; +- +- tm->tm_wday = i; +- - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) ++ if (i == 7) ++ i = 0; ++ tm->tm_wday = wday = i; ++ buf++; + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) -+ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc)) ++ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') ptr++; break; -@@ -372,11 +374,11 @@ +@@ -372,11 +415,18 @@ * XXX The %e specifier may gobble one too many * digits if used incorrectly. */ - if (!isdigit((unsigned char)*buf)) ++ /* Leading space is ok if date is single digit */ ++ len = 2; ++ if (isspace_l((unsigned char)buf[0], loc) && ++ isdigit_l((unsigned char)buf[1], loc) && ++ !isdigit_l((unsigned char)buf[2], loc)) { ++ len = 1; ++ buf++; ++ } + if (!isdigit_l((unsigned char)*buf, loc)) return 0; - len = 2; +- len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { i *= 10; i += *buf - '0'; len--; -@@ -386,8 +388,8 @@ +@@ -386,8 +436,8 @@ tm->tm_mday = i; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) -+ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc)) ++ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') ptr++; break; -@@ -398,19 +400,19 @@ +@@ -398,19 +448,19 @@ if (Oalternative) { if (c == 'B') { len = strlen(tptr->alt_month[i]); @@ -319,7 +411,7 @@ break; } } -@@ -422,11 +424,11 @@ +@@ -422,11 +472,11 @@ break; case 'm': @@ -333,18 +425,18 @@ i *= 10; i += *buf - '0'; len--; -@@ -436,8 +438,8 @@ +@@ -436,8 +486,8 @@ tm->tm_mon = i - 1; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) -+ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc)) ++ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') ptr++; break; -@@ -450,7 +452,7 @@ +@@ -450,7 +500,7 @@ sverrno = errno; errno = 0; @@ -353,7 +445,14 @@ if (errno == ERANGE || (long)(t = n) != n) { errno = sverrno; return 0; -@@ -464,14 +466,14 @@ +@@ -458,24 +508,37 @@ + errno = sverrno; + buf = cp; + gmtime_r(&t, tm); +- *GMTp = 1; ++ *convp = CONVERT_GMT; + } + break; case 'Y': case 'y': @@ -365,56 +464,122 @@ + if (!isdigit_l((unsigned char)*buf, loc)) return 0; ++#if __DARWIN_UNIX03 ++ if (c == 'Y') { ++ for (i = 0; *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { ++ i *= 10; ++ i += *buf - '0'; ++ } ++ } else { ++ len = 2; ++#else /* !__DARWIN_UNIX03 */ len = (c == 'Y') ? 4 : 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { ++#endif /* __DARWIN_UNIX03 */ + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { i *= 10; i += *buf - '0'; len--; -@@ -485,8 +487,8 @@ + } ++#if __DARWIN_UNIX03 ++ } ++#endif /* __DARWIN_UNIX03 */ + if (c == 'Y') + i -= 1900; + if (c == 'y' && i < 69) +@@ -483,10 +546,10 @@ + if (i < 0) + return 0; - tm->tm_year = i; +- tm->tm_year = i; ++ tm->tm_year = year = i; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) -+ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc)) ++ while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') ptr++; break; -@@ -495,7 +497,7 @@ - const char *cp; - char *zonestr; - -- for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) {/*empty*/} -+ for (cp = buf; *cp && isupper_l((unsigned char)*cp, loc); ++cp) {/*empty*/} - if (cp - buf) { - zonestr = alloca(cp - buf + 1); - strncpy(zonestr, buf, cp - buf); -@@ -528,7 +530,25 @@ - int gmt; - - gmt = 0; -- ret = _strptime(buf, fmt, tm, &gmt); -+ ret = _strptime(buf, fmt, tm, &gmt, __current_locale()); -+ if (ret && gmt) { -+ time_t t = timegm(tm); -+ localtime_r(&t, tm); -+ } +@@ -502,7 +565,7 @@ + zonestr[cp - buf] = '\0'; + tzset(); + if (0 == strcmp(zonestr, "GMT")) { +- *GMTp = 1; ++ *convp = CONVERT_GMT; + } else if (0 == strcmp(zonestr, tzname[0])) { + tm->tm_isdst = 0; + } else if (0 == strcmp(zonestr, tzname[1])) { +@@ -514,6 +577,26 @@ + } + } + break; ++ ++ case 'z': ++ { ++ char sign; ++ int hr, min; + -+ return (ret); ++ 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; ++ } ++ break; + } + } + return (char *)buf; +@@ -524,14 +607,39 @@ + strptime(const char * __restrict buf, const char * __restrict fmt, + struct tm * __restrict tm) + { ++ return strptime_l(buf, fmt, tm, __current_locale()); +} + ++extern time_t timeoff(struct tm *, long); ++ +char * +strptime_l(const char * __restrict buf, const char * __restrict fmt, + struct tm * __restrict tm, locale_t loc) +{ -+ char *ret; -+ int gmt; -+ + char *ret; +- int gmt; ++ int conv; + +- gmt = 0; +- ret = _strptime(buf, fmt, tm, &gmt); +- if (ret && gmt) { +- time_t t = timegm(tm); +- localtime_r(&t, tm); + NORMALIZE_LOCALE(loc); -+ gmt = 0; -+ ret = _strptime(buf, fmt, tm, &gmt, loc); - if (ret && gmt) { - time_t t = timegm(tm); - localtime_r(&t, tm); ++ conv = CONVERT_NONE; ++ tm->tm_zone = NULL; ++ ret = _strptime(buf, fmt, tm, &conv, loc); ++ if (ret) { ++ time_t t; ++ ++ switch(conv) { ++ case CONVERT_GMT: ++ t = timegm(tm); ++ localtime_r(&t, tm); ++ break; ++ case CONVERT_ZONE: ++ { ++ long offset = tm->tm_gmtoff; ++ tm->tm_gmtoff = 0; ++ t = timeoff(tm, offset); ++ localtime_r(&t, tm); ++ break; ++ } ++ } + } + + return (ret); diff --git a/stdtime/FreeBSD/tzfile.5.patch b/stdtime/FreeBSD/tzfile.5.patch new file mode 100644 index 0000000..7545cfc --- /dev/null +++ b/stdtime/FreeBSD/tzfile.5.patch @@ -0,0 +1,11 @@ +--- tzfile.5.orig 2006-02-03 12:54:23.000000000 -0800 ++++ tzfile.5 2006-02-03 12:54:44.000000000 -0800 +@@ -6,7 +6,7 @@ + .Nm tzfile + .Nd timezone information + .Sh SYNOPSIS +-.Fd #include \&"/usr/src/lib/libc/stdtime/tzfile.h\&" ++.In tzfile.h + .Sh DESCRIPTION + The time zone information files used by + .Xr tzset 3 diff --git a/stdtime/Makefile.inc b/stdtime/Makefile.inc index ac5d512..bb3a497 100644 --- a/stdtime/Makefile.inc +++ b/stdtime/Makefile.inc @@ -3,18 +3,26 @@ .PATH: ${.CURDIR}/stdtime +CFLAGS += -I${.CURDIR}/stdtime + CFLAGS-localtime-fbsd.c += -DNOTIFY_TZ -UNIX03SRCS += strftime.c +LEGACYSRCS += localtime.c strftime.c strptime.c MISRCS += getdate.c timezone_unix03.c +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +CFLAGS-localtime-fbsd.c += -DLIBC_ALIAS_MKTIME +CFLAGS-strftime-fbsd.c += -DLIBC_ALIAS_STRFTIME -DLIBC_ALIAS_STRFTIME_L +CFLAGS-strptime-fbsd.c += -DLIBC_ALIAS_STRPTIME -DLIBC_ALIAS_STRPTIME_L + .include "Makefile.fbsd_begin" FBSDMISRCS= asctime.c difftime.c ftime.c localtime.c \ strftime.c strptime.c timelocal.c time32.c FBSDHDRS= private.h timelocal.h tzfile.h .include "Makefile.fbsd_end" -INSTHDRS_AUTOPATCH += tzfile.h +INSTHDRS += ${.CURDIR}/stdtime/tzfile.h .if ${LIB} == "c" .include "Makefile.fbsd_begin" diff --git a/stdtime/asctime-fbsd.c b/stdtime/asctime-fbsd.c new file mode 100644 index 0000000..bcdc85e --- /dev/null +++ b/stdtime/asctime-fbsd.c @@ -0,0 +1,76 @@ +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +*/ + +#include +#ifndef lint +#ifndef NOID +static char elsieid[] __unused = "@(#)asctime.c 7.9"; +#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 $"); + +/*LINTLIBRARY*/ + +#include "namespace.h" +#include "private.h" +#include "un-namespace.h" +#include "tzfile.h" + +/* +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, Second Edition, 1996-07-12. +*/ + +char * +asctime_r(const struct tm * __restrict timeptr, char * __restrict buf) +{ + static const char wday_name[][3] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + static const char mon_name[][3] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + const char * wn; + const char * mn; + + if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) + wn = "???"; + else wn = wday_name[timeptr->tm_wday]; + if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR) + 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. + */ + (void) sprintf(buf, "%.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); + 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]; + + return asctime_r(timeptr, result); +} diff --git a/stdtime/ctime.3 b/stdtime/ctime.3 new file mode 100644 index 0000000..7326071 --- /dev/null +++ b/stdtime/ctime.3 @@ -0,0 +1,381 @@ +.\" Copyright (c) 1989, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Arthur Olson. +.\" 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. +.\" +.\" 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 $ +.\" +.Dd January 2, 1999 +.Dt CTIME 3 +.Os +.Sh NAME +.Nm asctime , +.Nm asctime_r , +.Nm ctime , +.Nm ctime_r , +.Nm difftime , +.Nm gmtime , +.Nm gmtime_r , +.Nm localtime , +.Nm localtime_r , +.Nm mktime , +.Nm timegm +.Nd transform binary date and time values +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In time.h +.Vt extern char *tzname[2] ; +.Ft char * +.Fn asctime "const struct tm *timeptr" +.Ft char * +.Fn asctime_r "const struct tm *restrict timeptr" "char *restrict buf" +.Ft char * +.Fn ctime "const time_t *clock" +.Ft char * +.Fn ctime_r "const time_t *clock" "char *buf" +.Ft double +.Fn difftime "time_t time1" "time_t time0" +.Ft struct tm * +.Fn gmtime "const time_t *clock" +.Ft struct tm * +.Fn gmtime_r "const time_t *clock" "struct tm *result" +.Ft struct tm * +.Fn localtime "const time_t *clock" +.Ft struct tm * +.Fn localtime_r "const time_t *clock" "struct tm *result" +.Ft time_t +.Fn mktime "struct tm *timeptr" +.Ft time_t +.Fn timegm "struct tm *timeptr" +.Sh DESCRIPTION +The functions +.Fn ctime , +.Fn gmtime , +and +.Fn localtime +all take as an argument a time value representing the time in seconds since +the Epoch (00:00:00 +.Tn UTC , +January 1, 1970; see +.Xr time 3 ) . +.Pp +The function +.Fn localtime +converts the time value pointed at by +.Fa clock . +It returns a pointer to a +.Dq Fa struct tm +(described below), which contains +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 +.Ev TZ +environment variable (see +.Xr tzset 3 ) . +The function +.Fn localtime +uses +.Xr tzset 3 +to initialize time conversion information, if +.Xr tzset 3 +has not already been called by the process. +.Pp +After filling in the tm structure, +.Fn localtime +sets the +.Fa tm_isdst Ns 'th +element of +.Fa tzname +to a pointer to an +.Tn ASCII +string containing the time zone abbreviation to be +used with +.Fn localtime Ns 's +return value. +.Pp +The function +.Fn gmtime +also converts the time value, but makes no time zone adjustment. +It returns a pointer to a tm structure (described below). +.Pp +The +.Fn ctime +function +adjusts the time value for the current time zone, in the same manner as +.Fn localtime . +It returns a pointer to a 26-character string of the form: +.Bd -literal -offset indent +Thu Nov 24 18:22:48 1986\en\e0 +.Ed +.Pp +All of the fields have constant width. +.Pp +The +.Fn ctime_r +function +provides the same functionality as +.Fn ctime , +except that the caller must provide the output buffer +.Fa buf +(which must be at least 26 characters long) to store the result. +The +.Fn localtime_r +and +.Fn gmtime_r +functions +provide the same functionality as +.Fn localtime +and +.Fn gmtime , +respectively, except the caller must provide the output buffer +.Fa result . +.Pp +The +.Fn asctime +function +converts the broken-out time in the structure +.Fa tm +(pointed at by +.Fa *timeptr ) +to the form +shown in the example above. +.Pp +The +.Fn asctime_r +function +provides the same functionality as +.Fn asctime , +except that the caller provides the output buffer +.Fa buf +(which must be at least 26 characters long) to store the result. +.Pp +The functions +.Fn mktime +and +.Fn timegm +convert the broken-out time +(in the structure pointed to by +.Fa *timeptr ) +into a time value with the same encoding as that of the +values returned by the +.Xr time 3 +function (that is, seconds from the Epoch, +.Tn UTC ) . +The +.Fn mktime +function +interprets the input structure according to the current timezone setting +(see +.Xr tzset 3 ) . +The +.Fn timegm +function interprets the input structure +as representing Universal Coordinated Time +.Pq Tn UTC . +.Pp +The original values of the +.Fa tm_wday +and +.Fa tm_yday +components of the structure are ignored. The original values of the +other components are not restricted to their normal ranges and will be +normalized, if need be. +For example, +October 40 is changed into November 9, +a +.Fa tm_hour +of \-1 means 1 hour before midnight, +.Fa tm_mday +of 0 means the day preceding the current month, and +.Fa tm_mon +of \-2 means 2 months before January of +.Fa tm_year . +(A positive or zero value for +.Fa tm_isdst +causes +.Fn mktime +to presume initially that summer time (for example, Daylight Saving Time) +is or is not (respectively) in effect for the specified time. +A negative value for +.Fa tm_isdst +causes the +.Fn mktime +function to attempt to divine whether summer time is in effect for the +specified time. +The +.Fa tm_isdst +and +.Fa tm_gmtoff +members are forced to zero by +.Fn timegm . ) +.Pp +On successful completion, the values of the +.Fa tm_wday +and +.Fa tm_yday +components of the structure are set appropriately, and the other components +are set to represent the specified calendar time, but with their values +forced to their normal ranges; the final value of +.Fa tm_mday +is not set until +.Fa tm_mon +and +.Fa tm_year +are determined. +The +.Fn mktime +function +returns the specified calendar time; if the calendar time cannot be +represented, it returns \-1; +.Pp +The +.Fn difftime +function +returns the difference between two calendar times, +.Pf ( Fa time1 +- +.Fa time0 ) , +expressed in seconds. +.Pp +External declarations, as well as the tm structure definition, +are contained in the +.In time.h +include file. +The tm structure includes at least the following fields: +.Bd -literal -offset indent +int tm_sec; /\(** seconds (0 - 60) \(**/ +int tm_min; /\(** minutes (0 - 59) \(**/ +int tm_hour; /\(** hours (0 - 23) \(**/ +int tm_mday; /\(** day of month (1 - 31) \(**/ +int tm_mon; /\(** month of year (0 - 11) \(**/ +int tm_year; /\(** year \- 1900 \(**/ +int tm_wday; /\(** day of week (Sunday = 0) \(**/ +int tm_yday; /\(** day of year (0 - 365) \(**/ +int tm_isdst; /\(** is summer time in effect? \(**/ +char \(**tm_zone; /\(** abbreviation of timezone name \(**/ +long tm_gmtoff; /\(** offset from UTC in seconds \(**/ +.Ed +.Pp +The +field +.Fa tm_isdst +is non-zero if summer (i.e., Daylight Saving) time is in effect. +.Pp +The field +.Fa tm_gmtoff +is the offset (in seconds) of the time represented from +.Tn UTC , +with positive +values indicating locations east of the Prime Meridian. +.Sh SEE ALSO +.Xr date 1 , +.Xr gettimeofday 2 , +.Xr getenv 3 , +.Xr time 3 , +.Xr tzset 3 , +.Xr tzfile 5 +.Sh STANDARDS +The +.Fn asctime , +.Fn ctime , +.Fn difftime , +.Fn gmtime , +.Fn localtime , +and +.Fn mktime +functions conform to +.St -isoC , +and conform to +.St -p1003.1-96 +provided the selected local timezone does not contain a leap-second table +(see +.Xr zic 8 ) . +.Pp +The +.Fn asctime_r , +.Fn ctime_r , +.Fn gmtime_r , +and +.Fn localtime_r +functions are expected to conform to +.St -p1003.1-96 +(again provided the selected local timezone does not contain a leap-second +table). +.Pp +The +.Fn timegm +function is not specified by any standard; its function cannot be +completely emulated using the standard functions described above. +.Sh HISTORY +This manual page is derived from +the time package contributed to Berkeley by +.An Arthur Olson +and which appeared in +.Bx 4.3 . +.Sh BUGS +Except for +.Fn difftime , +.Fn mktime , +and the +.Fn \&_r +variants of the other functions, +these functions leaves their result in an internal static object and return +a pointer to that object. +Subsequent calls to these +function will modify the same object. +.Pp +The C Standard provides no mechanism for a program to modify its current +local timezone setting, and the +.Tn POSIX Ns No \&-standard +method is not reentrant. +(However, thread-safe implementations are provided +in the +.Tn POSIX +threaded environment.) +.Pp +The +.Va tm_zone +field of a returned +.Vt tm +structure points to a static array of characters, +which will also be overwritten by any subsequent calls (as well as by +subsequent calls to +.Xr tzset 3 +and +.Xr tzsetwall 3 ) . +.Pp +Use of the external variable +.Fa tzname +is discouraged; the +.Fa tm_zone +entry in the tm structure is preferred. diff --git a/stdtime/difftime-fbsd.c b/stdtime/difftime-fbsd.c new file mode 100644 index 0000000..df55753 --- /dev/null +++ b/stdtime/difftime-fbsd.c @@ -0,0 +1,87 @@ +/* +** This file is in the public domain, so clarified as of +** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov). +*/ + +#include +#ifndef lint +#ifndef NOID +static char elsieid[] __unused = "@(#)difftime.c 7.9"; +#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 $"); + +/*LINTLIBRARY*/ + +#include "namespace.h" +#include "private.h" +#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 (time1 < time0) + return -difftime(time0, time1); + /* + ** As much as possible, avoid loss of precision + ** by computing the difference before converting to double. + */ + delta = time1 - time0; + if (delta >= 0) + return delta; + /* + ** Repair delta overflow. + */ + hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1); + /* + ** 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. + */ + return delta - 2 * (long_double) hibit; +} diff --git a/stdtime/ftime-fbsd.c b/stdtime/ftime-fbsd.c new file mode 100644 index 0000000..6bb3f03 --- /dev/null +++ b/stdtime/ftime-fbsd.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1994 Christopher G. Demetriou + * 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 Christopher G. Demetriou. + * 4. 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 ``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. + */ + +#ifndef lint +static char rcsid[] = "$FreeBSD: /repoman/r/ncvs/src/lib/libcompat/4.1/ftime.c,v 1.5 1999/08/28 00:04:12 peter Exp $"; +#endif /* not lint */ + +#include +#include +#include + +int +ftime(tbp) + struct timeb *tbp; +{ + struct timezone tz; + struct timeval t; + + if (gettimeofday(&t, &tz) < 0) + return (-1); + tbp->millitm = t.tv_usec / 1000; + tbp->time = t.tv_sec; + tbp->timezone = tz.tz_minuteswest; + tbp->dstflag = tz.tz_dsttime; + + return (0); +} diff --git a/stdtime/ftime.3 b/stdtime/ftime.3 new file mode 100644 index 0000000..4676bd8 --- /dev/null +++ b/stdtime/ftime.3 @@ -0,0 +1,93 @@ +.\" 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. +.\" +.\" @(#)ftime.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: /repoman/r/ncvs/src/lib/libcompat/4.1/ftime.3,v 1.11 2001/10/01 16:09:14 ru Exp $ +.\" +.Dd June 4, 1993 +.Dt FTIME 3 +.Os +.Sh NAME +.Nm ftime +.Nd get date and time +.Sh SYNOPSIS +.In sys/timeb.h +.Ft int +.Fo ftime +.Fa "struct timeb *tp" +.Fc +.Sh DESCRIPTION +.Bf -symbolic +This interface is obsoleted by +.Xr gettimeofday 2 . +.Ef +.Pp +The +.Fn ftime +routine fills in a structure pointed to by its argument, +as defined by +.Aq Pa sys/timeb.h : +.Bd -literal -offset indent +/* + * Structure returned by ftime system call + */ +struct timeb +{ + time_t time; + unsigned short millitm; + short timezone; + short dstflag; +}; +.Ed +.Pp +The structure contains the time since the epoch, in seconds; +up to 1000 milliseconds of more-precise interval; +the local time zone (measured in minutes of time westward from Greenwich); +and a flag that, if nonzero, indicates that +Daylight Saving time applies locally during the appropriate part of the year. +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +The include file +.In sys/types.h +is necessary. +.Sh SEE ALSO +.Xr gettimeofday 2 , +.Xr settimeofday 2 , +.Xr ctime 3 , +.Xr time 3 , +.Xr compat 5 +.Sh HISTORY +The +.Nm +function appeared in +.Bx 4.2 . diff --git a/stdtime/getdate.c b/stdtime/getdate.c index b5e9d35..7e3bc79 100644 --- a/stdtime/getdate.c +++ b/stdtime/getdate.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -48,7 +49,7 @@ enum { #define TM_YEAR_SET 0x04 #define UNDEFINED -1 -static struct tm tmundef = { +static const struct tm tmundef = { UNDEFINED, UNDEFINED, UNDEFINED, @@ -69,10 +70,11 @@ int getdate_err; struct tm * getdate(const char *str) { - static struct tm tm, *now, *result = NULL; + static struct tm tm; + struct tm *now, *result = NULL; time_t t; FILE *fp; - int bufsiz, offset, len, dateset, timeset, saveerrno, wday_set; + int bufsiz, offset, len, dateset, timeset, saveerrno, wday_set, save_mon; char *buf; struct stat st; char *file = getenv(DATEMSK); @@ -218,7 +220,7 @@ getdate(const char *str) case TM_YEAR_SET: case TM_YEAR_SET | TM_MON_SET: if(!(dateset & TM_MON_SET)) - tm.tm_mon = 1; + tm.tm_mon = 0; tm.tm_mday = 1; break; @@ -232,10 +234,13 @@ getdate(const char *str) tm.tm_wday = now->tm_wday; tm.tm_gmtoff = now->tm_gmtoff; /* XXX: can't grok timezones */ tm.tm_isdst = -1; - + save_mon = tm.tm_mon; if(mktime(&tm) == (time_t)-1) { getdate_err = INVALID_DATE; break; + } else if ((dateset & TM_MON_SET) && (tm.tm_mon != save_mon)) { /* Did mktime fixup an overflow date? */ + getdate_err = INVALID_DATE; + break; } if(wday_set != UNDEFINED) { int delta = wday_set - tm.tm_wday; @@ -252,6 +257,7 @@ getdate(const char *str) } } result = &tm; + break; } } while(0); diff --git a/stdtime/localtime-fbsd.c b/stdtime/localtime-fbsd.c new file mode 100644 index 0000000..46dc949 --- /dev/null +++ b/stdtime/localtime-fbsd.c @@ -0,0 +1,2291 @@ +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +*/ + +#include +#ifndef lint +#ifndef NOID +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 $"); + +/* +** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu). +** POSIX-style TZ environment variable handling from Guy Harris +** (guy@auspex.com). +*/ + +/*LINTLIBRARY*/ + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#ifdef NOTIFY_TZ +//#define NOTIFY_TZ_DEBUG +//#define NOTIFY_TZ_DEBUG_FILE "/var/log/localtime.debug" +//#define NOTIFY_TZ_LOG "/var/log/localtime.log" +/* force ALL_STATE if NOTIFY_TZ is set */ +#ifndef ALL_STATE +#define ALL_STATE +#endif /* ALL_STATE */ +#include +#include +#include +#endif /* NOTIFY_TZ */ +#include "private.h" +#include "un-namespace.h" + +#include "tzfile.h" + +#include "libc_private.h" + +#define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x) +#define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x) +extern int __pthread_tsd_first; + +/* +** SunOS 4.1.1 headers lack O_BINARY. +*/ + +#ifdef O_BINARY +#define OPEN_MODE (O_RDONLY | O_BINARY) +#endif /* defined O_BINARY */ +#ifndef O_BINARY +#define OPEN_MODE O_RDONLY +#endif /* !defined O_BINARY */ + +#ifndef WILDABBR +/* +** Someone might make incorrect use of a time zone abbreviation: +** 1. They might reference tzname[0] before calling tzset (explicitly +** or implicitly). +** 2. They might reference tzname[1] before calling tzset (explicitly +** or implicitly). +** 3. They might reference tzname[1] after setting to a time zone +** in which Daylight Saving Time is never observed. +** 4. They might reference tzname[0] after setting to a time zone +** in which Standard Time is never observed. +** 5. They might reference tm.TM_ZONE after calling offtime. +** What's best to do in the above cases is open to debate; +** for now, we just set things up so that in any of the five cases +** WILDABBR is used. Another possibility: initialize tzname[0] to the +** string "tzname[0] used before set", and similarly for the other cases. +** And another: initialize tzname[0] to "ERA", with an explanation in the +** manual page of what this "time zone abbreviation" means (doing this so +** that tzname[0] has the "normal" length of three characters). +*/ +#define WILDABBR " " +#endif /* !defined WILDABBR */ + +static char wildabbr[] = "WILDABBR"; + +/* + * In June 2004 it was decided UTC was a more appropriate default time + * zone than GMT. + */ + +static const char gmt[] = "UTC"; + +/* +** The DST rules to use if TZ has no rules and we can't load TZDEFRULES. +** We default to US rules as of 1999-08-17. +** POSIX 1003.1 section 8.1.1 says that the default DST rules are +** implementation dependent; for historical reasons, US rules are a +** common default. +*/ +#ifndef TZDEFRULESTRING +#define TZDEFRULESTRING ",M4.1.0,M10.5.0" +#endif /* !defined TZDEFDST */ + +struct ttinfo { /* time type information */ + long tt_gmtoff; /* UTC offset in seconds */ + int tt_isdst; /* used to set tm_isdst */ + int tt_abbrind; /* abbreviation list index */ + int tt_ttisstd; /* TRUE if transition is std time */ + int tt_ttisgmt; /* TRUE if transition is UTC */ +}; + +struct lsinfo { /* leap second information */ + time_t ls_trans; /* transition time */ + long ls_corr; /* correction to apply */ +}; + +#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) + +#ifdef TZNAME_MAX +#define MY_TZNAME_MAX TZNAME_MAX +#endif /* defined TZNAME_MAX */ +#ifndef TZNAME_MAX +#define MY_TZNAME_MAX 255 +#endif /* !defined TZNAME_MAX */ + +struct state { + int leapcnt; + int timecnt; + int typecnt; + int charcnt; + time_t ats[TZ_MAX_TIMES]; + unsigned char types[TZ_MAX_TIMES]; + struct ttinfo ttis[TZ_MAX_TYPES]; + char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), + (2 * (MY_TZNAME_MAX + 1)))]; + struct lsinfo lsis[TZ_MAX_LEAPS]; +}; + +struct rule { + int r_type; /* type of rule--see below */ + int r_day; /* day number of rule */ + int r_week; /* week number of rule */ + int r_mon; /* month number of rule */ + long r_time; /* transition time of rule */ +}; + +#define JULIAN_DAY 0 /* Jn - Julian day */ +#define DAY_OF_YEAR 1 /* n - day of year */ +#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ + +#ifdef NOTIFY_TZ +typedef struct { + int token; + int notify_was_off; + int is_set; +} notify_tz_t; + +#define NOTIFY_TZ_NAME "com.apple.system.timezone" +#endif /* NOTIFY_TZ */ + +/* +** Prototypes for static functions. +*/ +#define localsub _st_localsub +#define time1 _st_time1 +#define tzset_basic _st_tzset_basic +__private_extern__ +#ifdef __LP64__ +struct tm * localsub(const time_t * timep, long offset, + struct tm * tmp); +#else /* !__LP64__ */ +void localsub(const time_t * timep, long offset, + struct tm * tmp); +#endif /* __LP64__ */ +__private_extern__ +time_t time1(struct tm * tmp, +#ifdef __LP64__ + struct tm *(*funcp) (const time_t *, + long, struct tm *), +#else /* !__LP64__ */ + void(*funcp) (const time_t *, + long, struct tm *), +#endif /* __LP64__ */ + long offset, + int unix03); +__private_extern__ +void tzset_basic(void); + +#define lcl_mutex _st_lcl_mutex + +#if !BUILDING_VARIANT +static long detzcode(const char * codep); +static const char * getzname(const char * strp, char **name, size_t *len); +static const char * getnum(const char * strp, int * nump, int min, + int max); +static const char * getsecs(const char * strp, long * secsp); +static const char * getoffset(const char * strp, long * offsetp); +static const char * getrule(const char * strp, struct rule * rulep); +static void gmtload(struct state * sp); +#ifdef __LP64__ +static struct tm * gmtsub(const time_t * timep, long offset, + struct tm * tmp); +#else /* !__LP64__ */ +static void gmtsub(const time_t * timep, long offset, + struct tm * tmp); +#endif /* __LP64__ */ +static int increment_overflow(int * number, int delta); +static int normalize_overflow(int * tensptr, int * unitsptr, + int base); +#ifdef NOTIFY_TZ +static void notify_check_tz(notify_tz_t *p); +static void notify_register_tz(char *file, notify_tz_t *p); +#endif /* NOTIFY_TZ */ +static void settzname(void); +static time_t time2(struct tm *tmp, +#ifdef __LP64__ + struct tm *(*funcp) (const time_t *, + long, struct tm*), +#else /* !__LP64__ */ + void(*funcp) (const time_t *, + long, struct tm*), +#endif /* __LP64__ */ + long offset, int * okayp, int unix03); +static time_t time2sub(struct tm *tmp, +#ifdef __LP64__ + struct tm *(*funcp) (const time_t *, + long, struct tm*), +#else /* !__LP64__ */ + void(*funcp) (const time_t *, + long, struct tm*), +#endif /* __LP64__ */ + long offset, int * okayp, int do_norm_secs, + int unix03); +#ifdef __LP64__ +static struct tm * timesub(const time_t * timep, long offset, + const struct state * sp, struct tm * tmp); +#else /* !__LP64__ */ +static void timesub(const time_t * timep, long offset, + const struct state * sp, struct tm * tmp); +#endif /* __LP64__ */ +static int tmcomp(const struct tm * atmp, + const struct tm * btmp); +static time_t transtime(time_t janfirst, int year, + const struct rule * rulep, long offset); +static int tzload(const char * name, struct state * sp); +static int tzparse(const char * name, struct state * sp, + int lastditch); + +#ifdef ALL_STATE +static struct state * lclptr; +static struct state * gmtptr; +#endif /* defined ALL_STATE */ + +#ifndef ALL_STATE +static struct state lclmem; +static struct state gmtmem; +#define lclptr (&lclmem) +#define gmtptr (&gmtmem) +#endif /* State Farm */ + +#ifndef TZ_STRLEN_MAX +#define TZ_STRLEN_MAX 255 +#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) +#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; + +char * tzname[2] = { + wildabbr, + wildabbr +}; + +/* +** Section 4.12.3 of X3.159-1989 requires that +** Except for the strftime function, these functions [asctime, +** ctime, gmtime, localtime] return values in one of two static +** objects: a broken-down time structure and an array of char. +** Thanks to Paul Eggert (eggert@twinsun.com) for noting this. +*/ + +static struct tm tm; + +#define USG_COMPAT +#define ALTZONE +#ifdef USG_COMPAT +int daylight = 0; +__private_extern__ void _st_set_timezone(long); +#endif /* defined USG_COMPAT */ + +#ifdef ALTZONE +__private_extern__ long __darwin_altzone = 0; +#define altzone __darwin_altzone +#endif /* defined ALTZONE */ + +#ifdef NOTIFY_TZ +#ifdef NOTIFY_TZ_DEBUG +#ifdef NOTIFY_TZ_DEBUG_FILE +#define NOTIFY_TZ_PRINTF(fmt, args...) \ +{ \ + FILE *_notify_tz_fp_; \ + if((_notify_tz_fp_ = fopen(NOTIFY_TZ_DEBUG_FILE, "a")) != NULL) { \ + fprintf(_notify_tz_fp_, "%d: " fmt, getpid(), ## args); \ + fclose(_notify_tz_fp_); \ + } \ +} +#else /* ! NOTIFY_TZ_DEBUG_FILE */ +#define NOTIFY_TZ_PRINTF(args...) fprintf(stdout, ## args) +#endif /* NOTIFY_TZ_DEBUG_FILE */ +#endif /* NOTIFY_TZ_DEBUG */ +#ifdef NOTIFY_TZ_LOG +#define NOTIFY_LOG(fmt, args...) \ +{ \ + FILE *_notify_log_fp_; \ + if((_notify_log_fp_ = fopen(NOTIFY_TZ_LOG, "a")) != NULL) { \ + fprintf(_notify_log_fp_, "%d: " fmt, getpid(), ## args); \ + fclose(_notify_log_fp_); \ + } \ +} +#endif /* NOTIFY_TZ_LOG */ +/*-------------------------------------------------------------------- + * __notify_78945668_info__ is a global variable (defined in Libnotify) + * that can be used to disable the notify mechanism. Set to a negative + * value to disable. It can then be set back to zero to re-enable. + *-------------------------------------------------------------------- */ +extern int __notify_78945668_info__; + +/*-------------------------------------------------------------------- + * fullname is used to pass the actual path of the timezone file to the + * notify routines. If it is a nil string, that means no timezone file + * is being used. + *-------------------------------------------------------------------- */ +static char * fullname = NULL; + +static notify_tz_t gmt_notify = {-1, 0, 0}; +static notify_tz_t lcl_notify = {-1, 0, 0}; +static char notify_tz_name[] = NOTIFY_TZ_NAME; +#endif /* NOTIFY_TZ */ + +static long +detzcode(codep) +const char * const codep; +{ + long result; + int i; + + result = (codep[0] & 0x80) ? ~0L : 0L; + for (i = 0; i < 4; ++i) + result = (result << 8) | (codep[i] & 0xff); + return result; +} + +static void +settzname(void) +{ + struct state * sp = lclptr; + int i; + + tzname[0] = wildabbr; + tzname[1] = wildabbr; +#ifdef USG_COMPAT + daylight = 0; + _st_set_timezone(0); +#endif /* defined USG_COMPAT */ +#ifdef ALTZONE + altzone = 0; +#endif /* defined ALTZONE */ +#ifdef ALL_STATE + if (sp == NULL) { + tzname[0] = tzname[1] = (char *)gmt; + return; + } +#endif /* defined ALL_STATE */ + for (i = 0; i < sp->typecnt; ++i) { + const struct ttinfo * const ttisp = &sp->ttis[i]; + + tzname[ttisp->tt_isdst] = + &sp->chars[ttisp->tt_abbrind]; +#ifdef USG_COMPAT + if (ttisp->tt_isdst) + daylight = 1; + if (i == 0 || !ttisp->tt_isdst) + _st_set_timezone(-(ttisp->tt_gmtoff)); +#endif /* defined USG_COMPAT */ +#ifdef ALTZONE + if (i == 0 || ttisp->tt_isdst) + 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 NOTIFY_TZ +static void +notify_check_tz(notify_tz_t *p) +{ + unsigned int nstat; + int ncheck; + + if (__notify_78945668_info__ < 0) { +#ifdef NOTIFY_TZ_DEBUG + if(!p->notify_was_off) NOTIFY_TZ_PRINTF("notify_check_tz: setting %s_notify->notify_was_off\n", (p == &lcl_notify ? "lcl" : "gmt")); +#endif /* NOTIFY_TZ_DEBUG */ + p->notify_was_off = 1; + return; + } + /* force rereading the timezone file if notify was off */ + if (p->notify_was_off) { +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("notify_check_tz: saw %s_notify->notify_was_off\n", (p == &lcl_notify ? "lcl" : "gmt")); +#endif /* NOTIFY_TZ_DEBUG */ + p->is_set = 0; + p->notify_was_off = 0; + return; + } + if (p->token < 0) + return; + nstat = notify_check(p->token, &ncheck); + if (nstat || ncheck) { + p->is_set = 0; +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("notify_check_tz: %s changed\n", (p == &lcl_notify) ? "lcl" : "gmt"); +#endif /* NOTIFY_TZ_DEBUG */ + } +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("notify_check_tz: %s unchanged\n", (p == &lcl_notify) ? "lcl" : "gmt"); +#endif /* NOTIFY_TZ_DEBUG */ +} + +extern uint32_t notify_monitor_file(int token, char *path, int flags); + +static void +notify_register_tz(char *file, notify_tz_t *p) +{ + char *name; + unsigned int nstat; + int ncheck; + + if (__notify_78945668_info__ < 0) + return; + /*---------------------------------------------------------------- + * Since we don't record the last time zone filename, just cancel + * (which should remove the file monitor) and setup from scratch + *----------------------------------------------------------------*/ + if (p->token >= 0) + notify_cancel(p->token); + if (!file || *file == 0) { + /* no time zone file to monitor */ + p->token = -1; + return; + } + /*---------------------------------------------------------------- + * Just use com.apple.system.timezone if the path is /etc/localtime. + * Otherwise use com.apple.system.timezone. + *----------------------------------------------------------------*/ + if (TZDEFAULT && strcmp(file, TZDEFAULT) == 0) + name = notify_tz_name; + else { + name = alloca(sizeof(notify_tz_name) + strlen(file) + 1); + if (name == NULL) { + p->token = -1; + return; + } + strcpy(name, notify_tz_name); + strcat(name, "."); + strcat(name, file); + } +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("notify_register_tz: file=%s name=%s\n", file, name); +#endif /* NOTIFY_TZ_DEBUG */ + nstat = notify_register_check(name, &p->token); + if (nstat != 0) { + p->token = -1; + p->is_set = 0; +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("***notify_register_tz: notify_register_check failed: %u\n", nstat); +#endif /* NOTIFY_TZ_DEBUG */ +#ifdef NOTIFY_TZ_LOG + NOTIFY_LOG("notify_register_check(%s) failed: %u\n", name, nstat); +#endif /* NOTIFY_TZ_LOG */ + return; + } + /* don't need to request monitoring /etc/localtime */ + if (name != notify_tz_name) { +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("notify_register_tz: monitor %s\n", file); +#endif /* NOTIFY_TZ_DEBUG */ + nstat = notify_monitor_file(p->token, file, 0); + if (nstat != 0) { + notify_cancel(p->token); + p->token = -1; + p->is_set = 0; +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("***notify_register_tz: notify_monitor_file failed: %u\n", nstat); +#endif /* NOTIFY_TZ_DEBUG */ +#ifdef NOTIFY_TZ_LOG + NOTIFY_LOG("notify_monitor_file(%s) failed: %u\n", file, nstat); +#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; +struct state * const sp; +{ + const char * p; + int i; + int fid; + +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("tzload: name=%s\n", name); +#endif /* NOTIFY_TZ_DEBUG */ + /* XXX The following is from OpenBSD, and I'm not sure it is correct */ + if (name != NULL && issetugid() != 0) + if ((name[0] == ':' && name[1] == '/') || + name[0] == '/' || strchr(name, '.')) + name = NULL; + if (name == NULL && (name = TZDEFAULT) == NULL) + return -1; + { + int doaccess; + struct stat stab; + /* + ** Section 4.9.1 of the C standard says that + ** "FILENAME_MAX expands to an integral constant expression + ** that is the size needed for an array of char large enough + ** to hold the longest file name string that the implementation + ** guarantees can be opened." + */ +#ifdef NOTIFY_TZ + if (!fullname) { + fullname = malloc(FILENAME_MAX + 1); + if (!fullname) + return -1; + } +#else /* ! NOTIFY_TZ */ + char fullname[FILENAME_MAX + 1]; +#endif /* NOTIFY_TZ */ + + if (name[0] == ':') + ++name; + doaccess = name[0] == '/'; + if (!doaccess) { + if ((p = TZDIR) == NULL) + return -1; +#ifdef NOTIFY_TZ + if ((strlen(p) + 1 + strlen(name) + 1) >= (FILENAME_MAX + 1)) +#else /* ! NOTIFY_TZ */ + if ((strlen(p) + 1 + strlen(name) + 1) >= sizeof fullname) +#endif /* NOTIFY_TZ */ + return -1; + (void) strcpy(fullname, p); + (void) strcat(fullname, "/"); + (void) strcat(fullname, name); + /* + ** Set doaccess if '.' (as in "../") shows up in name. + */ + if (strchr(name, '.') != NULL) + doaccess = TRUE; + name = fullname; + } +#ifdef NOTIFY_TZ + else + strcpy(fullname, name); +#endif /* NOTIFY_TZ */ + if (doaccess && access(name, R_OK) != 0) + return -1; + if ((fid = _open(name, OPEN_MODE)) == -1) + return -1; + if ((_fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) { + _close(fid); + return -1; + } + } + { + struct tzhead * tzhp; + union { + struct tzhead tzhead; + char buf[sizeof *sp + sizeof *tzhp]; + } u; + int ttisstdcnt; + int ttisgmtcnt; + +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("tzload: reading %s\n", name); +#endif /* NOTIFY_TZ_DEBUG */ + i = _read(fid, u.buf, sizeof u.buf); + if (_close(fid) != 0) + return -1; + ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt); + ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt); + sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt); + sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt); + sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt); + sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt); + p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt; + if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS || + sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES || + sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES || + sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS || + (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || + (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) + return -1; + if (i - (p - u.buf) < sp->timecnt * 4 + /* ats */ + sp->timecnt + /* types */ + sp->typecnt * (4 + 2) + /* ttinfos */ + sp->charcnt + /* chars */ + sp->leapcnt * (4 + 4) + /* lsinfos */ + ttisstdcnt + /* ttisstds */ + ttisgmtcnt) /* ttisgmts */ + return -1; + for (i = 0; i < sp->timecnt; ++i) { + sp->ats[i] = detzcode(p); + p += 4; + } + for (i = 0; i < sp->timecnt; ++i) { + sp->types[i] = (unsigned char) *p++; + if (sp->types[i] >= sp->typecnt) + return -1; + } + for (i = 0; i < sp->typecnt; ++i) { + struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + ttisp->tt_gmtoff = detzcode(p); + p += 4; + ttisp->tt_isdst = (unsigned char) *p++; + if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) + return -1; + ttisp->tt_abbrind = (unsigned char) *p++; + if (ttisp->tt_abbrind < 0 || + ttisp->tt_abbrind > sp->charcnt) + return -1; + } + for (i = 0; i < sp->charcnt; ++i) + sp->chars[i] = *p++; + sp->chars[i] = '\0'; /* ensure '\0' at end */ + for (i = 0; i < sp->leapcnt; ++i) { + struct lsinfo * lsisp; + + lsisp = &sp->lsis[i]; + lsisp->ls_trans = detzcode(p); + p += 4; + lsisp->ls_corr = detzcode(p); + p += 4; + } + for (i = 0; i < sp->typecnt; ++i) { + struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + if (ttisstdcnt == 0) + ttisp->tt_ttisstd = FALSE; + else { + ttisp->tt_ttisstd = *p++; + if (ttisp->tt_ttisstd != TRUE && + ttisp->tt_ttisstd != FALSE) + return -1; + } + } + for (i = 0; i < sp->typecnt; ++i) { + struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + if (ttisgmtcnt == 0) + ttisp->tt_ttisgmt = FALSE; + else { + ttisp->tt_ttisgmt = *p++; + if (ttisp->tt_ttisgmt != TRUE && + ttisp->tt_ttisgmt != FALSE) + return -1; + } + } + } + return 0; +} + +static const int mon_lengths[2][MONSPERYEAR] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +static const int year_lengths[2] = { + DAYSPERNYEAR, DAYSPERLYEAR +}; + +/* +** Given a pointer into a time zone string, scan until a character that is not +** a valid character in a zone name is found. Return a pointer to that +** character. +*/ + +static const char * +getzname(strp, name, len) +const char * strp; +char ** name; +size_t * len; +{ + char c; + char * ket; + + if (*strp == '<' && (ket = strchr(strp, '>')) != NULL) { + *name = (char *)(strp + 1); + *len = ket - strp - 1; + return ket + 1; + } + *name = (char *)strp; + while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && + c != '+') + ++strp; + *len = strp - *name; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a number from that string. +** Check that the number is within a specified range; if it is not, return +** NULL. +** Otherwise, return a pointer to the first character not part of the number. +*/ + +static const char * +getnum(strp, nump, min, max) +const char * strp; +int * const nump; +const int min; +const int max; +{ + char c; + int num; + + if (strp == NULL || !is_digit(c = *strp)) + return NULL; + num = 0; + do { + num = num * 10 + (c - '0'); + if (num > max) + return NULL; /* illegal value */ + c = *++strp; + } while (is_digit(c)); + if (num < min) + return NULL; /* illegal value */ + *nump = num; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a number of seconds, +** in hh[:mm[:ss]] form, from the string. +** If any error occurs, return NULL. +** Otherwise, return a pointer to the first character not part of the number +** of seconds. +*/ + +static const char * +getsecs(strp, secsp) +const char * strp; +long * const secsp; +{ + int num; + + /* + ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like + ** "M10.4.6/26", which does not conform to Posix, + ** but which specifies the equivalent of + ** ``02:00 on the first Sunday on or after 23 Oct''. + */ + strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); + if (strp == NULL) + return NULL; + *secsp = num * (long) SECSPERHOUR; + if (*strp == ':') { + ++strp; + strp = getnum(strp, &num, 0, MINSPERHOUR - 1); + if (strp == NULL) + return NULL; + *secsp += num * SECSPERMIN; + if (*strp == ':') { + ++strp; + /* `SECSPERMIN' allows for leap seconds. */ + strp = getnum(strp, &num, 0, SECSPERMIN); + if (strp == NULL) + return NULL; + *secsp += num; + } + } + return strp; +} + +/* +** Given a pointer into a time zone string, extract an offset, in +** [+-]hh[:mm[:ss]] form, from the string. +** If any error occurs, return NULL. +** Otherwise, return a pointer to the first character not part of the time. +*/ + +static const char * +getoffset(strp, offsetp) +const char * strp; +long * const offsetp; +{ + int neg = 0; + + if (*strp == '-') { + neg = 1; + ++strp; + } else if (*strp == '+') + ++strp; + strp = getsecs(strp, offsetp); + if (strp == NULL) + return NULL; /* illegal time */ + if (neg) + *offsetp = -*offsetp; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a rule in the form +** date[/time]. See POSIX section 8 for the format of "date" and "time". +** If a valid rule is not found, return NULL. +** Otherwise, return a pointer to the first character not part of the rule. +*/ + +static const char * +getrule(strp, rulep) +const char * strp; +struct rule * const rulep; +{ + if (*strp == 'J') { + /* + ** Julian day. + */ + rulep->r_type = JULIAN_DAY; + ++strp; + strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); + } else if (*strp == 'M') { + /* + ** Month, week, day. + */ + rulep->r_type = MONTH_NTH_DAY_OF_WEEK; + ++strp; + strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); + if (strp == NULL) + return NULL; + if (*strp++ != '.') + return NULL; + strp = getnum(strp, &rulep->r_week, 1, 5); + if (strp == NULL) + return NULL; + if (*strp++ != '.') + return NULL; + strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); + } else if (is_digit(*strp)) { + /* + ** Day of year. + */ + rulep->r_type = DAY_OF_YEAR; + strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); + } else return NULL; /* invalid format */ + if (strp == NULL) + return NULL; + if (*strp == '/') { + /* + ** Time specified. + */ + ++strp; + strp = getsecs(strp, &rulep->r_time); + } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ + return strp; +} + +/* +** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the +** year, a rule, and the offset from UTC at the time that rule takes effect, +** calculate the Epoch-relative time that rule takes effect. +*/ + +static time_t +transtime(janfirst, year, rulep, offset) +const time_t janfirst; +const int year; +const struct rule * const rulep; +const long offset; +{ + int leapyear; + time_t value; + int i; + int d, m1, yy0, yy1, yy2, dow; + + INITIALIZE(value); + leapyear = isleap(year); + switch (rulep->r_type) { + + case JULIAN_DAY: + /* + ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap + ** years. + ** In non-leap years, or if the day number is 59 or less, just + ** add SECSPERDAY times the day number-1 to the time of + ** January 1, midnight, to get the day. + */ + value = janfirst + (rulep->r_day - 1) * SECSPERDAY; + if (leapyear && rulep->r_day >= 60) + value += SECSPERDAY; + break; + + case DAY_OF_YEAR: + /* + ** n - day of year. + ** Just add SECSPERDAY times the day number to the time of + ** January 1, midnight, to get the day. + */ + value = janfirst + rulep->r_day * SECSPERDAY; + break; + + case MONTH_NTH_DAY_OF_WEEK: + /* + ** Mm.n.d - nth "dth day" of month m. + */ + value = janfirst; + for (i = 0; i < rulep->r_mon - 1; ++i) + value += mon_lengths[leapyear][i] * SECSPERDAY; + + /* + ** Use Zeller's Congruence to get day-of-week of first day of + ** month. + */ + m1 = (rulep->r_mon + 9) % 12 + 1; + yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; + yy1 = yy0 / 100; + yy2 = yy0 % 100; + dow = ((26 * m1 - 2) / 10 + + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; + if (dow < 0) + dow += DAYSPERWEEK; + + /* + ** "dow" is the day-of-week of the first day of the month. Get + ** the day-of-month (zero-origin) of the first "dow" day of the + ** month. + */ + d = rulep->r_day - dow; + if (d < 0) + d += DAYSPERWEEK; + for (i = 1; i < rulep->r_week; ++i) { + if (d + DAYSPERWEEK >= + mon_lengths[leapyear][rulep->r_mon - 1]) + break; + d += DAYSPERWEEK; + } + + /* + ** "d" is the day-of-month (zero-origin) of the day we want. + */ + value += d * SECSPERDAY; + break; + } + + /* + ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in + ** question. To get the Epoch-relative time of the specified local + ** time on that day, add the transition time and the current offset + ** from UTC. + */ + return value + rulep->r_time + offset; +} + +/* +** Given a POSIX section 8-style TZ string, fill in the rule tables as +** appropriate. +*/ + +static int +tzparse(name, sp, lastditch) +const char * name; +struct state * const sp; +const int lastditch; +{ + const char * stdname; + const char * dstname; + size_t stdlen; + size_t dstlen; + long stdoffset; + long dstoffset; + time_t * atp; + unsigned char * typep; + char * cp; + int load_result; + + INITIALIZE(dstname); + if (lastditch) { + stdname = name; + stdlen = strlen(name); /* length of standard zone name */ + name += stdlen; + if (stdlen >= sizeof sp->chars) + stdlen = (sizeof sp->chars) - 1; + stdoffset = 0; + } else { + name = getzname(name, (char **)&stdname, &stdlen); + if (stdlen < 3) + return -1; + if (*name == '\0') + return -1; /* was "stdoffset = 0;" */ + else { + name = getoffset(name, &stdoffset); + if (name == NULL) + return -1; + } + } + load_result = tzload(TZDEFRULES, sp); +#ifdef NOTIFY_TZ + *fullname = 0; /* mark fullname as invalid */ +#endif /* NOTIFY_TZ */ + if (load_result != 0) + sp->leapcnt = 0; /* so, we're off a little */ + if (*name != '\0') { + dstname = name; + name = getzname(name, (char **)&dstname, &dstlen); + if (dstlen < 3) + return -1; + if (*name != '\0' && *name != ',' && *name != ';') { + name = getoffset(name, &dstoffset); + if (name == NULL) + return -1; + } else dstoffset = stdoffset - SECSPERHOUR; + if (*name == '\0' && load_result != 0) + name = TZDEFRULESTRING; + if (*name == ',' || *name == ';') { + struct rule start; + struct rule end; + int year; + time_t janfirst; + time_t starttime; + time_t endtime; + + ++name; + if ((name = getrule(name, &start)) == NULL) + return -1; + if (*name++ != ',') + return -1; + if ((name = getrule(name, &end)) == NULL) + return -1; + if (*name != '\0') + return -1; + sp->typecnt = 2; /* standard time and DST */ + /* + ** Two transitions per year, from EPOCH_YEAR to 2037. + */ + sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1); + if (sp->timecnt > TZ_MAX_TIMES) + return -1; + sp->ttis[0].tt_gmtoff = -dstoffset; + sp->ttis[0].tt_isdst = 1; + sp->ttis[0].tt_abbrind = stdlen + 1; + sp->ttis[1].tt_gmtoff = -stdoffset; + sp->ttis[1].tt_isdst = 0; + sp->ttis[1].tt_abbrind = 0; + atp = sp->ats; + typep = sp->types; + janfirst = 0; + for (year = EPOCH_YEAR; year <= 2037; ++year) { + starttime = transtime(janfirst, year, &start, + stdoffset); + endtime = transtime(janfirst, year, &end, + dstoffset); + if (starttime > endtime) { + *atp++ = endtime; + *typep++ = 1; /* DST ends */ + *atp++ = starttime; + *typep++ = 0; /* DST begins */ + } else { + *atp++ = starttime; + *typep++ = 0; /* DST begins */ + *atp++ = endtime; + *typep++ = 1; /* DST ends */ + } + janfirst += year_lengths[isleap(year)] * + SECSPERDAY; + } + } else { + long theirstdoffset; + long theirdstoffset; + long theiroffset; + int isdst; + int i; + int j; + + if (*name != '\0') + return -1; + /* + ** Initial values of theirstdoffset and theirdstoffset. + */ + theirstdoffset = 0; + for (i = 0; i < sp->timecnt; ++i) { + j = sp->types[i]; + if (!sp->ttis[j].tt_isdst) { + theirstdoffset = + -sp->ttis[j].tt_gmtoff; + break; + } + } + theirdstoffset = 0; + for (i = 0; i < sp->timecnt; ++i) { + j = sp->types[i]; + if (sp->ttis[j].tt_isdst) { + theirdstoffset = + -sp->ttis[j].tt_gmtoff; + break; + } + } + /* + ** Initially we're assumed to be in standard time. + */ + isdst = FALSE; + theiroffset = theirstdoffset; + /* + ** Now juggle transition times and types + ** tracking offsets as you do. + */ + for (i = 0; i < sp->timecnt; ++i) { + j = sp->types[i]; + sp->types[i] = sp->ttis[j].tt_isdst; + if (sp->ttis[j].tt_ttisgmt) { + /* No adjustment to transition time */ + } else { + /* + ** If summer time is in effect, and the + ** transition time was not specified as + ** standard time, add the summer time + ** offset to the transition time; + ** otherwise, add the standard time + ** offset to the transition time. + */ + /* + ** Transitions from DST to DDST + ** will effectively disappear since + ** POSIX provides for only one DST + ** offset. + */ + if (isdst && !sp->ttis[j].tt_ttisstd) { + sp->ats[i] += dstoffset - + theirdstoffset; + } else { + sp->ats[i] += stdoffset - + theirstdoffset; + } + } + theiroffset = -sp->ttis[j].tt_gmtoff; + if (sp->ttis[j].tt_isdst) + theirdstoffset = theiroffset; + else theirstdoffset = theiroffset; + } + /* + ** Finally, fill in ttis. + ** ttisstd and ttisgmt need not be handled. + */ + sp->ttis[0].tt_gmtoff = -stdoffset; + sp->ttis[0].tt_isdst = FALSE; + sp->ttis[0].tt_abbrind = 0; + sp->ttis[1].tt_gmtoff = -dstoffset; + sp->ttis[1].tt_isdst = TRUE; + sp->ttis[1].tt_abbrind = stdlen + 1; + sp->typecnt = 2; + } + } else { + dstlen = 0; + sp->typecnt = 1; /* only standard time */ + sp->timecnt = 0; + sp->ttis[0].tt_gmtoff = -stdoffset; + sp->ttis[0].tt_isdst = 0; + sp->ttis[0].tt_abbrind = 0; + } + sp->charcnt = stdlen + 1; + if (dstlen != 0) + sp->charcnt += dstlen + 1; + if ((size_t) sp->charcnt > sizeof sp->chars) + return -1; + cp = sp->chars; + (void) strncpy(cp, stdname, stdlen); + cp += stdlen; + *cp++ = '\0'; + if (dstlen != 0) { + (void) strncpy(cp, dstname, dstlen); + *(cp + dstlen) = '\0'; + } + return 0; +} + +static void +gmtload(sp) +struct state * const sp; +{ + if (tzload(gmt, sp) != 0) + (void) tzparse(gmt, sp, TRUE); +} + +static void +tzsetwall_basic(void) +{ +#ifdef NOTIFY_TZ + notify_check_tz(&lcl_notify); +#endif /* NOTIFY_TZ */ +#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) + return; +#endif /* NOTIFY_TZ_DEBUG */ + lcl_is_set = -1; + +#ifdef ALL_STATE + if (lclptr == NULL) { + lclptr = (struct state *) malloc(sizeof *lclptr); + if (lclptr == NULL) { + settzname(); /* all we can do */ + return; + } + } +#endif /* defined ALL_STATE */ + if (tzload((char *) NULL, lclptr) != 0) + gmtload(lclptr); +#ifdef NOTIFY_TZ + notify_register_tz(fullname, &lcl_notify); +#endif /* NOTIFY_TZ */ + settzname(); +} + +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); +} + +__private_extern__ void +tzset_basic(void) +{ + const char * name; + + name = getenv("TZ"); + if (name == NULL) { + tzsetwall_basic(); + return; + } + +#ifdef NOTIFY_TZ + notify_check_tz(&lcl_notify); +#endif /* NOTIFY_TZ */ +#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) + return; +#endif /* NOTIFY_TZ_DEBUG */ + lcl_is_set = strlen(name) < sizeof lcl_TZname; + if (lcl_is_set) + (void) strcpy(lcl_TZname, name); + +#ifdef ALL_STATE + if (lclptr == NULL) { + lclptr = (struct state *) malloc(sizeof *lclptr); + if (lclptr == NULL) { + settzname(); /* all we can do */ + return; + } + } +#endif /* defined ALL_STATE */ + if (*name == '\0') { + /* + ** User wants it fast rather than right. + */ + lclptr->leapcnt = 0; /* so, we're off a little */ + lclptr->timecnt = 0; + lclptr->typecnt = 0; + lclptr->ttis[0].tt_isdst = 0; + lclptr->ttis[0].tt_gmtoff = 0; + lclptr->ttis[0].tt_abbrind = 0; + (void) strcpy(lclptr->chars, gmt); +#ifdef NOTIFY_TZ + if (fullname) + *fullname = 0; +#endif /* NOTIFY_TZ */ + } else if (tzload(name, lclptr) != 0) + if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) + (void) gmtload(lclptr); +#ifdef NOTIFY_TZ + notify_register_tz(fullname, &lcl_notify); +#endif /* NOTIFY_TZ */ + settzname(); +} + +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); +} + +/* +** The easy way to behave "as if no library function calls" localtime +** is to not call it--so we drop its guts into "localsub", which can be +** freely called. (And no, the PANS doesn't require the above behavior-- +** but it *is* desirable.) +** +** The unused offset argument is for the benefit of mktime variants. +*/ + +/*ARGSUSED*/ +#ifdef __LP64__ +__private_extern__ struct tm * +#else /* !__LP64__ */ +__private_extern__ void +#endif /* __LP64__ */ +localsub(timep, offset, tmp) +const time_t * const timep; +const long offset; +struct tm * const tmp; +{ + struct state * sp; + const struct ttinfo * ttisp; + int i; + const time_t t = *timep; + +#ifdef NOTIFY_TZ_DEBUG + NOTIFY_TZ_PRINTF("localsub called\n"); +#endif /* NOTIFY_TZ_DEBUG */ + sp = lclptr; +#ifdef ALL_STATE + if (sp == NULL) { +#ifdef __LP64__ + return gmtsub(timep, offset, tmp); +#else /* !__LP64__ */ + gmtsub(timep, offset, tmp); + return; +#endif /* __LP64__ */ + } +#endif /* defined ALL_STATE */ + if (sp->timecnt == 0 || t < sp->ats[0]) { + i = 0; + while (sp->ttis[i].tt_isdst) + if (++i >= sp->typecnt) { + i = 0; + break; + } + } else { + for (i = 1; i < sp->timecnt; ++i) + if (t < sp->ats[i]) + break; + i = sp->types[i - 1]; + } + ttisp = &sp->ttis[i]; + /* + ** To get (wrong) behavior that's compatible with System V Release 2.0 + ** you'd replace the statement below with + ** t += ttisp->tt_gmtoff; + ** timesub(&t, 0L, sp, tmp); + */ +#ifdef __LP64__ + if (timesub(&t, ttisp->tt_gmtoff, sp, tmp) == NULL) + return NULL; +#else /* !__LP64__ */ + timesub(&t, ttisp->tt_gmtoff, sp, tmp); +#endif /* __LP64__ */ + tmp->tm_isdst = ttisp->tt_isdst; + tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; +#ifdef TM_ZONE + tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; +#endif /* defined TM_ZONE */ +#ifdef __LP64__ + return tmp; +#endif /* __LP64__ */ +} + +struct tm * +localtime(timep) +const time_t * const timep; +{ + static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_key_t localtime_key = -1; + struct tm *p_tm; + + if (__isthreaded != 0) { + _pthread_mutex_lock(&localtime_mutex); + if (localtime_key == (pthread_key_t)-1) { + localtime_key = __pthread_tsd_first + 2; + if (pthread_key_init_np(localtime_key, free) < 0) { + _pthread_mutex_unlock(&localtime_mutex); + return(NULL); + } + } + _pthread_mutex_unlock(&localtime_mutex); + p_tm = _pthread_getspecific(localtime_key); + if (p_tm == NULL) { + if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) + == NULL) + return(NULL); + _pthread_setspecific(localtime_key, p_tm); + } + _pthread_mutex_lock(&lcl_mutex); + tzset_basic(); +#ifdef __LP64__ + p_tm = localsub(timep, 0L, p_tm); +#else /* !__LP64__ */ + localsub(timep, 0L, p_tm); +#endif /* __LP64__ */ + _pthread_mutex_unlock(&lcl_mutex); + return(p_tm); + } else { + tzset_basic(); +#ifdef __LP64__ + return localsub(timep, 0L, &tm); +#else /* !__LP64__ */ + localsub(timep, 0L, &tm); + return(&tm); +#endif /* __LP64__ */ + } +} + +/* +** Re-entrant version of localtime. +*/ + +struct tm * +localtime_r(const time_t * const __restrict timep, struct tm * __restrict tm) +{ + _MUTEX_LOCK(&lcl_mutex); + tzset_basic(); +#ifdef __LP64__ + tm = localsub(timep, 0L, tm); +#else /* !__LP64__ */ + localsub(timep, 0L, tm); +#endif /* __LP64__ */ + _MUTEX_UNLOCK(&lcl_mutex); + return tm; +} + +/* +** gmtsub is to gmtime as localsub is to localtime. +*/ + +#ifdef __LP64__ +static struct tm * +#else /* !__LP64__ */ +static void +#endif /* __LP64__ */ +gmtsub(timep, offset, tmp) +const time_t * const timep; +const long offset; +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; +#ifdef ALL_STATE +#ifdef NOTIFY_TZ + if (gmtptr == NULL) +#endif /* NOTIFY_TZ */ + gmtptr = (struct state *) malloc(sizeof *gmtptr); + if (gmtptr != NULL) +#ifdef NOTIFY_TZ + { +#endif /* NOTIFY_TZ */ +#endif /* defined ALL_STATE */ + gmtload(gmtptr); +#ifdef NOTIFY_TZ + notify_register_tz(fullname, &gmt_notify); + } +#endif /* NOTIFY_TZ */ + } + _MUTEX_UNLOCK(&gmt_mutex); +#ifdef __LP64__ + if(timesub(timep, offset, gmtptr, tmp) == NULL) + return NULL; +#else /* !__LP64__ */ + timesub(timep, offset, gmtptr, tmp); +#endif /* __LP64__ */ +#ifdef TM_ZONE + /* + ** Could get fancy here and deliver something such as + ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero, + ** but this is no time for a treasure hunt. + */ + if (offset != 0) + tmp->TM_ZONE = wildabbr; + else { +#ifdef ALL_STATE + if (gmtptr == NULL) + tmp->TM_ZONE = (char *)gmt; + else tmp->TM_ZONE = gmtptr->chars; +#endif /* defined ALL_STATE */ +#ifndef ALL_STATE + tmp->TM_ZONE = gmtptr->chars; +#endif /* State Farm */ + } +#endif /* defined TM_ZONE */ +#ifdef __LP64__ + return tmp; +#endif /* __LP64__ */ +} + +struct tm * +gmtime(timep) +const time_t * const timep; +{ + static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER; + 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 = __pthread_tsd_first + 3; + if (pthread_key_init_np(gmtime_key, free) < 0) { + _pthread_mutex_unlock(&gmtime_mutex); + return(NULL); + } + } + _pthread_mutex_unlock(&gmtime_mutex); + /* + * Changed to follow POSIX.1 threads standard, which + * is what BSD currently has. + */ + if ((p_tm = _pthread_getspecific(gmtime_key)) == NULL) { + if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) + == NULL) { + return(NULL); + } + _pthread_setspecific(gmtime_key, p_tm); + } +#ifdef __LP64__ + return gmtsub(timep, 0L, p_tm); +#else /* !__LP64__ */ + gmtsub(timep, 0L, p_tm); + return(p_tm); +#endif /* __LP64__ */ + } + else { +#ifdef __LP64__ + return gmtsub(timep, 0L, &tm); +#else /* !__LP64__ */ + gmtsub(timep, 0L, &tm); + return(&tm); +#endif /* __LP64__ */ + } +} + +/* +* Re-entrant version of gmtime. +*/ + +struct tm * +gmtime_r(timep, tm) +const time_t * const timep; +struct tm * tm; +{ + +#ifdef __LP64__ + return gmtsub(timep, 0L, tm); +#else /* !__LP64__ */ + gmtsub(timep, 0L, tm); + return tm; +#endif /* __LP64__ */ +} + +#ifdef STD_INSPIRED + +struct tm * +offtime(timep, offset) +const time_t * const timep; +const long offset; +{ +#ifdef __LP64__ + return gmtsub(timep, offset, &tm); +#else /* !__LP64__ */ + gmtsub(timep, offset, &tm); + return &tm; +#endif /* __LP64__ */ +} + +#endif /* defined STD_INSPIRED */ + +#ifdef __LP64__ +static struct tm * +#else /* !__LP64__ */ +static void +#endif /* __LP64__ */ +timesub(timep, offset, sp, tmp) +const time_t * const timep; +const long offset; +const struct state * const sp; +struct tm * const tmp; +{ + const struct lsinfo * lp; + long days; + long rem; + long y; + int yleap; + const int * ip; + long corr; + int hit; + int i; + + corr = 0; + hit = 0; +#ifdef ALL_STATE + i = (sp == NULL) ? 0 : sp->leapcnt; +#endif /* defined ALL_STATE */ +#ifndef ALL_STATE + i = sp->leapcnt; +#endif /* State Farm */ + while (--i >= 0) { + lp = &sp->lsis[i]; + if (*timep >= lp->ls_trans) { + if (*timep == lp->ls_trans) { + hit = ((i == 0 && lp->ls_corr > 0) || + lp->ls_corr > sp->lsis[i - 1].ls_corr); + if (hit) + while (i > 0 && + sp->lsis[i].ls_trans == + sp->lsis[i - 1].ls_trans + 1 && + sp->lsis[i].ls_corr == + sp->lsis[i - 1].ls_corr + 1) { + ++hit; + --i; + } + } + corr = lp->ls_corr; + break; + } + } + days = *timep / SECSPERDAY; + rem = *timep % SECSPERDAY; +#ifdef mc68k + if (*timep == 0x80000000) { + /* + ** A 3B1 muffs the division on the most negative number. + */ + days = -24855; + rem = -11648; + } +#endif /* defined mc68k */ + rem += (offset - corr); + while (rem < 0) { + rem += SECSPERDAY; + --days; + } + while (rem >= SECSPERDAY) { + rem -= SECSPERDAY; + ++days; + } + tmp->tm_hour = (int) (rem / SECSPERHOUR); + rem = rem % SECSPERHOUR; + tmp->tm_min = (int) (rem / SECSPERMIN); + /* + ** A positive leap second requires a special + ** representation. This uses "... ??:59:60" et seq. + */ + tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; + tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); + if (tmp->tm_wday < 0) + tmp->tm_wday += DAYSPERWEEK; + y = EPOCH_YEAR; +#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) + while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { + long newy; + + newy = y + days / DAYSPERNYEAR; + if (days < 0) + --newy; + days -= (newy - y) * DAYSPERNYEAR + + LEAPS_THRU_END_OF(newy - 1) - + LEAPS_THRU_END_OF(y - 1); + y = newy; + } +#ifdef __LP64__ + y -= TM_YEAR_BASE; + if (y < INT_MIN || y > INT_MAX) { + errno = EOVERFLOW; + return NULL; + } + tmp->tm_year = y; +#else /* !__LP64__ */ + tmp->tm_year = y - TM_YEAR_BASE; +#endif /* __LP64__ */ + tmp->tm_yday = (int) days; + ip = mon_lengths[yleap]; + for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon)) + days = days - (long) ip[tmp->tm_mon]; + tmp->tm_mday = (int) (days + 1); + tmp->tm_isdst = 0; +#ifdef TM_GMTOFF + tmp->TM_GMTOFF = offset; +#endif /* defined TM_GMTOFF */ +#ifdef __LP64__ + return tmp; +#endif /* __LP64__ */ +} + +char * +ctime(timep) +const time_t * const timep; +{ +/* +** Section 4.12.3.2 of X3.159-1989 requires that +** The ctime function converts the calendar time pointed to by timer +** to local time in the form of a string. It is equivalent to +** asctime(localtime(timer)) +*/ + return asctime(localtime(timep)); +} + +char * +ctime_r(timep, buf) +const time_t * const timep; +char * buf; +{ + struct tm tm; + + return asctime_r(localtime_r(timep, &tm), buf); +} + +/* +** Adapted from code provided by Robert Elz, who writes: +** The "best" way to do mktime I think is based on an idea of Bob +** Kridle's (so its said...) from a long time ago. +** [kridle@xinet.com as of 1996-01-16.] +** It does a binary search of the time_t space. Since time_t's are +** just 32 bits, its a max of 32 iterations (even at 64 bits it +** would still be very reasonable). +*/ + +#ifndef WRONG +#define WRONG (-1) +#endif /* !defined WRONG */ + +/* +** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com). +*/ + +static int +increment_overflow(number, delta) +int * number; +int delta; +{ + int number0; + + number0 = *number; + *number += delta; + return (*number < number0) != (delta < 0); +} + +static int +normalize_overflow(tensptr, unitsptr, base) +int * const tensptr; +int * const unitsptr; +const int base; +{ + int tensdelta; + + tensdelta = (*unitsptr >= 0) ? + (*unitsptr / base) : + (-1 - (-1 - *unitsptr) / base); + *unitsptr -= tensdelta * base; + return increment_overflow(tensptr, tensdelta); +} + +static int +tmcomp(atmp, btmp) +const struct tm * const atmp; +const struct tm * const btmp; +{ + int result; + + if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && + (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) + result = atmp->tm_sec - btmp->tm_sec; + return result; +} + +static time_t +time2sub(tmp, funcp, offset, okayp, do_norm_secs, unix03) +struct tm * const tmp; +#ifdef __LP64__ +struct tm *(* const funcp)(const time_t*, long, struct tm*); +#else /* !__LP64__ */ +void (* const funcp)(const time_t*, long, struct tm*); +#endif /* __LP64__ */ +const long offset; +int * const okayp; +const int do_norm_secs; +int unix03; +{ + const struct state * sp; + int dir; + int bits; + int i, j ; + int saved_seconds; + time_t newt; + time_t t; + struct tm yourtm, mytm; +#ifdef __LP64__ + long year, il; +#endif /* __LP64__ */ + + *okayp = FALSE; + yourtm = *tmp; + if (do_norm_secs) { + if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, + SECSPERMIN)) + return WRONG; + } + if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) + return WRONG; + if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) + return WRONG; + if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR)) + return WRONG; + /* + ** Turn yourtm.tm_year into an actual year number for now. + ** It is converted back to an offset from TM_YEAR_BASE later. + */ +#ifdef __LP64__ + year = (long)yourtm.tm_year + TM_YEAR_BASE; +#else /* !__LP64__ */ + if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE)) + return WRONG; +#endif /* __LP64__ */ + while (yourtm.tm_mday <= 0) { +#ifdef __LP64__ + year--; + il = year + (1 < yourtm.tm_mon); + yourtm.tm_mday += year_lengths[isleap(il)]; +#else /* !__LP64__ */ + if (increment_overflow(&yourtm.tm_year, -1)) + return WRONG; + i = yourtm.tm_year + (1 < yourtm.tm_mon); + yourtm.tm_mday += year_lengths[isleap(i)]; +#endif /* __LP64__ */ + } + while (yourtm.tm_mday > DAYSPERLYEAR) { +#ifdef __LP64__ + il = year + (1 < yourtm.tm_mon); + yourtm.tm_mday -= year_lengths[isleap(il)]; + year++; +#else /* !__LP64__ */ + i = yourtm.tm_year + (1 < yourtm.tm_mon); + yourtm.tm_mday -= year_lengths[isleap(i)]; + if (increment_overflow(&yourtm.tm_year, 1)) + return WRONG; +#endif /* __LP64__ */ + } + for ( ; ; ) { +#ifdef __LP64__ + i = mon_lengths[isleap(year)][yourtm.tm_mon]; +#else /* !__LP64__ */ + i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon]; +#endif /* __LP64__ */ + if (yourtm.tm_mday <= i) + break; + yourtm.tm_mday -= i; + if (++yourtm.tm_mon >= MONSPERYEAR) { + yourtm.tm_mon = 0; +#ifdef __LP64__ + year++; +#else /* !__LP64__ */ + if (increment_overflow(&yourtm.tm_year, 1)) + return WRONG; +#endif /* __LP64__ */ + } + } +#ifdef __LP64__ + year -= TM_YEAR_BASE; + if (year > INT_MAX || year < INT_MIN) + return WRONG; + yourtm.tm_year = year; +#else /* !__LP64__ */ + if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE)) + return WRONG; +#endif /* __LP64__ */ + /* Don't go below 1900 for POLA */ + if (yourtm.tm_year < 0) + return WRONG; + if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) + saved_seconds = 0; + else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) { + /* + ** We can't set tm_sec to 0, because that might push the + ** time below the minimum representable time. + ** Set tm_sec to 59 instead. + ** This assumes that the minimum representable time is + ** not in the same minute that a leap second was deleted from, + ** which is a safer assumption than using 58 would be. + */ + if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) + return WRONG; + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = SECSPERMIN - 1; + } else { + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = 0; + } + /* + ** Divide the search space in half + ** (this works whether time_t is signed or unsigned). + */ + bits = TYPE_BIT(time_t) - 1; + /* + ** 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 time_t is signed, then 0 is just above the median, + ** assuming two's complement arithmetic. + ** If time_t is unsigned, then (1 << bits) is just above the median. + */ + t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits); + for ( ; ; ) { +#ifdef __LP64__ + if ((*funcp)(&t, offset, &mytm) == NULL) { + /* we overflowed, so t is too big */ + dir = 1; + goto skip_tmcomp; + } +#else /* !__LP64__ */ + (*funcp)(&t, offset, &mytm); +#endif /* __LP64__ */ + dir = tmcomp(&mytm, &yourtm); +#ifdef __LP64__ +skip_tmcomp: +#endif /* __LP64__ */ + if (dir != 0) { + if (bits-- < 0) + return WRONG; + if (bits < 0) + --t; /* may be needed if new t is minimal */ + else if (dir > 0) + t -= ((time_t) 1) << bits; + else t += ((time_t) 1) << bits; + continue; + } + sp = (funcp == localsub) ? lclptr : gmtptr; + if (unix03 && sp->typecnt == 1 && yourtm.tm_isdst > 0) + yourtm.tm_isdst = 0; /* alternative time does not apply */ + if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) + break; + /* + ** Right time, wrong type. + ** Hunt for right time, right type. + ** It's okay to guess wrong since the guess + ** gets checked. + */ +#ifdef ALL_STATE + if (sp == NULL) + return WRONG; +#endif /* defined ALL_STATE */ + for (i = sp->typecnt - 1; i >= 0; --i) { + if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) + continue; + for (j = sp->typecnt - 1; j >= 0; --j) { + if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) + continue; + newt = t + sp->ttis[j].tt_gmtoff - + sp->ttis[i].tt_gmtoff; +#ifdef __LP64__ + if ((*funcp)(&newt, offset, &mytm) == NULL) + return WRONG; +#else /* !__LP64__ */ + (*funcp)(&newt, offset, &mytm); +#endif /* __LP64__ */ + if (tmcomp(&mytm, &yourtm) != 0) + continue; + if (mytm.tm_isdst != yourtm.tm_isdst) + continue; + /* + ** We have a match. + */ + t = newt; + goto label; + } + } + return WRONG; + } +label: + newt = t + saved_seconds; + if ((newt < t) != (saved_seconds < 0)) + return WRONG; + t = newt; +#ifdef __LP64__ + if ((*funcp)(&t, offset, tmp) == NULL) + return WRONG; +#else /* !__LP64__ */ + (*funcp)(&t, offset, tmp); +#endif /* __LP64__ */ + *okayp = TRUE; + return t; +} + +static time_t +time2(tmp, funcp, offset, okayp, unix03) +struct tm * const tmp; +#ifdef __LP64__ +struct tm *(* const funcp)(const time_t*, long, struct tm*); +#else /* !__LP64__ */ +void (* const funcp)(const time_t*, long, struct tm*); +#endif /* __LP64__ */ +const long offset; +int * const okayp; +int unix03; +{ + time_t t; + + /* + ** First try without normalization of seconds + ** (in case tm_sec contains a value associated with a leap second). + ** If that fails, try with normalization of seconds. + */ + t = time2sub(tmp, funcp, offset, okayp, FALSE, unix03); + return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE, unix03); +} + +__private_extern__ time_t +time1(tmp, funcp, offset, unix03) +struct tm * const tmp; +#ifdef __LP64__ +struct tm *(* const funcp)(const time_t *, long, struct tm *); +#else /* !__LP64__ */ +void (* const funcp)(const time_t *, long, struct tm *); +#endif /* __LP64__ */ +const long offset; +int unix03; +{ + time_t t; + const struct state * sp; + int samei, otheri; + int sameind, otherind; + int i; + int nseen; + int seen[TZ_MAX_TYPES]; + int types[TZ_MAX_TYPES]; + int okay; + + if (tmp->tm_isdst > 1) + tmp->tm_isdst = 1; + t = time2(tmp, funcp, offset, &okay, unix03); +#ifdef PCTS + /* + ** PCTS code courtesy Grant Sullivan (grant@osf.org). + */ + if (okay) + return t; + if (tmp->tm_isdst < 0) + tmp->tm_isdst = 0; /* reset to std and try again */ +#endif /* defined PCTS */ +#ifndef PCTS + if (okay || tmp->tm_isdst < 0) + return t; +#endif /* !defined PCTS */ + /* + ** We're supposed to assume that somebody took a time of one type + ** and did some math on it that yielded a "struct tm" that's bad. + ** We try to divine the type they started from and adjust to the + ** type they need. + */ + sp = (funcp == localsub) ? lclptr : gmtptr; +#ifdef ALL_STATE + if (sp == NULL) + return WRONG; +#endif /* defined ALL_STATE */ + for (i = 0; i < sp->typecnt; ++i) + seen[i] = FALSE; + nseen = 0; + for (i = sp->timecnt - 1; i >= 0; --i) + if (!seen[sp->types[i]]) { + seen[sp->types[i]] = TRUE; + types[nseen++] = sp->types[i]; + } + for (sameind = 0; sameind < nseen; ++sameind) { + samei = types[sameind]; + if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) + continue; + for (otherind = 0; otherind < nseen; ++otherind) { + otheri = types[otherind]; + if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) + continue; + tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; + t = time2(tmp, funcp, offset, &okay, unix03); + if (okay) + return t; + tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; + } + } + return WRONG; +} +#else /* BUILDING_VARIANT */ +__private_extern__ pthread_mutex_t lcl_mutex; +#endif /* BUILDING_VARIANT */ + +time_t +mktime(tmp) +struct tm * const tmp; +{ + time_t mktime_return_value; + int serrno = errno; + _MUTEX_LOCK(&lcl_mutex); + tzset_basic(); + mktime_return_value = time1(tmp, localsub, 0L, __DARWIN_UNIX03); + _MUTEX_UNLOCK(&lcl_mutex); + errno = serrno; + return(mktime_return_value); +} + +#if !BUILDING_VARIANT +#ifdef STD_INSPIRED + +time_t +timelocal(tmp) +struct tm * const tmp; +{ + tmp->tm_isdst = -1; /* in case it wasn't initialized */ + return mktime(tmp); +} + +time_t +timegm(tmp) +struct tm * const tmp; +{ + tmp->tm_isdst = 0; + return time1(tmp, gmtsub, 0L, __DARWIN_UNIX03); +} + +time_t +timeoff(tmp, offset) +struct tm * const tmp; +const long offset; +{ + tmp->tm_isdst = 0; + return time1(tmp, gmtsub, offset, __DARWIN_UNIX03); +} + +#endif /* defined STD_INSPIRED */ + +#ifdef CMUCS + +/* +** The following is supplied for compatibility with +** previous versions of the CMUCS runtime library. +*/ + +long +gtime(tmp) +struct tm * const tmp; +{ + const time_t t = mktime(tmp); + + if (t == WRONG) + return -1; + return t; +} + +#endif /* defined CMUCS */ + +/* +** XXX--is the below the right way to conditionalize?? +*/ + +#ifdef STD_INSPIRED + +/* +** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599 +** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which +** is not the case if we are accounting for leap seconds. +** So, we provide the following conversion routines for use +** when exchanging timestamps with POSIX conforming systems. +*/ + +static long +leapcorr(timep) +time_t * timep; +{ + struct state * sp; + struct lsinfo * lp; + int i; + + sp = lclptr; + i = sp->leapcnt; + while (--i >= 0) { + lp = &sp->lsis[i]; + if (*timep >= lp->ls_trans) + return lp->ls_corr; + } + return 0; +} + +time_t +time2posix(t) +time_t t; +{ + tzset(); + return t - leapcorr(&t); +} + +time_t +posix2time(t) +time_t t; +{ + time_t x; + time_t y; + + tzset(); + /* + ** For a positive leap second hit, the result + ** is not unique. For a negative leap second + ** hit, the corresponding time doesn't exist, + ** so we return an adjacent second. + */ + x = t + leapcorr(&t); + y = x - leapcorr(&x); + if (y < t) { + do { + x++; + y = x - leapcorr(&x); + } while (y < t); + if (t != y) + return x - 1; + } else if (y > t) { + do { + --x; + y = x - leapcorr(&x); + } while (y > t); + if (t != y) + return x + 1; + } + return x; +} + +#endif /* defined STD_INSPIRED */ +#endif /* !BUILDING_VARIANT */ diff --git a/stdtime/private.h b/stdtime/private.h new file mode 100644 index 0000000..9878a1a --- /dev/null +++ b/stdtime/private.h @@ -0,0 +1,260 @@ +#ifndef PRIVATE_H + +#define PRIVATE_H + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** +** $FreeBSD: src/lib/libc/stdtime/private.h,v 1.10 2004/06/14 10:31:52 stefanf Exp $ +*/ + +/* Stuff moved from Makefile.inc to reduce clutter */ +#ifndef TM_GMTOFF +#define TM_GMTOFF tm_gmtoff +#define TM_ZONE tm_zone +#define STD_INSPIRED 1 +#define PCTS 1 +#define HAVE_LONG_DOUBLE 1 +#define HAVE_STRERROR 1 +#define HAVE_UNISTD_H 1 +#define LOCALE_HOME _PATH_LOCALE +#define TZDIR "/usr/share/zoneinfo" +#endif /* ndef TM_GMTOFF */ + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** ID +*/ + +#ifndef lint +#ifndef NOID +/* +static char privatehid[] = "@(#)private.h 7.53"; +*/ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* +** Defaults for preprocessor symbols. +** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. +*/ + +#ifndef HAVE_ADJTIME +#define HAVE_ADJTIME 1 +#endif /* !defined HAVE_ADJTIME */ + +#ifndef HAVE_GETTEXT +#define HAVE_GETTEXT 0 +#endif /* !defined HAVE_GETTEXT */ + +#ifndef HAVE_INCOMPATIBLE_CTIME_R +#define HAVE_INCOMPATIBLE_CTIME_R 0 +#endif /* !defined INCOMPATIBLE_CTIME_R */ + +#ifndef HAVE_SETTIMEOFDAY +#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 */ + +#ifndef HAVE_SYS_STAT_H +#define HAVE_SYS_STAT_H 1 +#endif /* !defined HAVE_SYS_STAT_H */ + +#ifndef HAVE_SYS_WAIT_H +#define HAVE_SYS_WAIT_H 1 +#endif /* !defined HAVE_SYS_WAIT_H */ + +#ifndef HAVE_UNISTD_H +#define HAVE_UNISTD_H 1 +#endif /* !defined HAVE_UNISTD_H */ + +#ifndef HAVE_UTMPX_H +#define HAVE_UTMPX_H 0 +#endif /* !defined HAVE_UTMPX_H */ + +#ifndef LOCALE_HOME +#define LOCALE_HOME "/usr/lib/locale" +#endif /* !defined LOCALE_HOME */ + +#if HAVE_INCOMPATIBLE_CTIME_R +#define asctime_r _incompatible_asctime_r +#define ctime_r _incompatible_ctime_r +#endif /* HAVE_INCOMPATIBLE_CTIME_R */ + +/* +** Nested includes +*/ + +#include "sys/types.h" /* for time_t */ +#include "stdio.h" +#include "errno.h" +#include "string.h" +#include "limits.h" /* for CHAR_BIT */ +#include "time.h" +#include "stdlib.h" + +#if HAVE_GETTEXT - 0 +#include "libintl.h" +#endif /* HAVE_GETTEXT - 0 */ + +#if HAVE_SYS_WAIT_H - 0 +#include /* for WIFEXITED and WEXITSTATUS */ +#endif /* HAVE_SYS_WAIT_H - 0 */ + +#ifndef WIFEXITED +#define WIFEXITED(status) (((status) & 0xff) == 0) +#endif /* !defined WIFEXITED */ +#ifndef WEXITSTATUS +#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 - 0) +#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) */ + +/* 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. +*/ + +#ifndef FILENAME_MAX + +#ifndef MAXPATHLEN +#ifdef unix +#include "sys/param.h" +#endif /* defined unix */ +#endif /* !defined MAXPATHLEN */ + +#ifdef MAXPATHLEN +#define FILENAME_MAX MAXPATHLEN +#endif /* defined MAXPATHLEN */ +#ifndef MAXPATHLEN +#define FILENAME_MAX 1024 /* Pure guesswork */ +#endif /* !defined MAXPATHLEN */ + +#endif /* !defined FILENAME_MAX */ + +/* +** 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); + + +/* +** Finally, some convenience items. +*/ + +#ifndef TRUE +#define TRUE 1 +#endif /* !defined TRUE */ + +#ifndef FALSE +#define FALSE 0 +#endif /* !defined FALSE */ + +#ifndef TYPE_BIT +#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT) +#endif /* !defined TYPE_BIT */ + +#ifndef TYPE_SIGNED +#define TYPE_SIGNED(type) (((type) -1) < 0) +#endif /* !defined TYPE_SIGNED */ + +#ifndef INT_STRLEN_MAXIMUM +/* +** 302 / 1000 is log10(2.0) rounded up. +** Subtract one for the sign bit if the type is signed; +** add one for integer division truncation; +** 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)) +#endif /* !defined INT_STRLEN_MAXIMUM */ + +/* +** INITIALIZE(x) +*/ + +#ifndef GNUC_or_lint +#ifdef lint +#define GNUC_or_lint +#endif /* defined lint */ +#ifndef lint +#ifdef __GNUC__ +#define GNUC_or_lint +#endif /* defined __GNUC__ */ +#endif /* !defined lint */ +#endif /* !defined GNUC_or_lint */ + +#ifndef INITIALIZE +#ifdef GNUC_or_lint +#define INITIALIZE(x) ((x) = 0) +#endif /* defined GNUC_or_lint */ +#ifndef GNUC_or_lint +#define INITIALIZE(x) +#endif /* !defined GNUC_or_lint */ +#endif /* !defined INITIALIZE */ + +/* +** For the benefit of GNU folk... +** `_(MSGID)' uses the current locale's message library string for MSGID. +** The default is to use gettext if available, and use MSGID otherwise. +*/ + +#ifndef _ +#if HAVE_GETTEXT - 0 +#define _(msgid) gettext(msgid) +#else /* !(HAVE_GETTEXT - 0) */ +#define _(msgid) msgid +#endif /* !(HAVE_GETTEXT - 0) */ +#endif /* !defined _ */ + +#ifndef TZ_DOMAIN +#define TZ_DOMAIN "tz" +#endif /* !defined TZ_DOMAIN */ + +#if HAVE_INCOMPATIBLE_CTIME_R +#undef asctime_r +#undef ctime_r +char *asctime_r(struct tm const *, char *); +char *ctime_r(time_t const *, char *); +#endif /* HAVE_INCOMPATIBLE_CTIME_R */ + +/* +** UNIX was a registered trademark of The Open Group in 2003. +*/ + +#endif /* !defined PRIVATE_H */ diff --git a/stdtime/strftime-fbsd.c b/stdtime/strftime-fbsd.c new file mode 100644 index 0000000..ba29d1a --- /dev/null +++ b/stdtime/strftime-fbsd.c @@ -0,0 +1,574 @@ +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * 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 + * 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 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +#ifndef NOID +static const char elsieid[] = "@(#)strftime.c 7.64"; +/* +** Based on the UCB version with the ID appearing below. +** This is ANSIish only when "multibyte character == plain character". +*/ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +#include "xlocale_private.h" + +#include "namespace.h" +#include "private.h" + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include "tzfile.h" +#include +#include +#include +#include "un-namespace.h" +#include "timelocal.h" + +#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 */ +#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); + +extern char * tzname[]; +__private_extern__ long __darwin_altzone; /* DST timezone offset */ +#define altzone __darwin_altzone +__private_extern__ long _st_get_timezone(void); + +#ifndef YEAR_2000_NAME +#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 + +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) { + (void) fputs("\n", stderr); + if (format == NULL) + (void) fputs("NULL strftime format ", stderr); + else (void) fprintf_l(stderr, loc, "strftime format \"%s\" ", + format); + (void) fputs("yields only two digits of years in ", stderr); + if (warn == IN_SOME) + (void) fputs("some locales", stderr); + else if (warn == IN_THIS) + (void) fputs("the current locale", stderr); + else (void) fputs("all locales", stderr); + (void) fputs("\n", stderr); + } +#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */ + if (p == s + maxsize) + return 0; + *p = '\0'; + return p - s; +} + +size_t +strftime(char * __restrict s, size_t maxsize, const char * __restrict format, + const struct tm * __restrict t) +{ + return strftime_l(s, maxsize, format, t, __current_locale()); +} + +#ifndef BUILDING_VARIANT +__private_extern__ char * +_fmt(format, t, pt, ptlim, warnp, tptr, loc) +const char * format; +const struct tm * const t; +char * pt; +const char * const ptlim; +int * warnp; +struct lc_time_T * tptr; +locale_t loc; +{ + int Ealternative, Oalternative; + + for ( ; *format; ++format) { + if (*format == '%') { + Ealternative = 0; + Oalternative = 0; +label: + switch (*++format) { + case '\0': + --format; + break; + case 'A': + pt = _add((t->tm_wday < 0 || + t->tm_wday >= DAYSPERWEEK) ? + "?" : tptr->weekday[t->tm_wday], + pt, ptlim); + continue; + case 'a': + pt = _add((t->tm_wday < 0 || + t->tm_wday >= DAYSPERWEEK) ? + "?" : tptr->wday[t->tm_wday], + pt, ptlim); + continue; + case 'B': + pt = _add((t->tm_mon < 0 || + t->tm_mon >= MONSPERYEAR) ? + "?" : (Oalternative ? tptr->alt_month : + tptr->month)[t->tm_mon], + pt, ptlim); + continue; + case 'b': + case 'h': + pt = _add((t->tm_mon < 0 || + t->tm_mon >= MONSPERYEAR) ? + "?" : tptr->mon[t->tm_mon], + pt, ptlim); + continue; + case 'C': + /* + ** %C used to do a... + ** _fmt("%a %b %e %X %Y", t); + ** ...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); + continue; + case 'c': + { + int warn2 = IN_SOME; + + pt = _fmt(tptr->c_fmt, t, pt, ptlim, warnp, tptr, loc); + if (warn2 == IN_ALL) + warn2 = IN_THIS; + if (warn2 > *warnp) + *warnp = warn2; + } + continue; + case 'D': + pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp, tptr, loc); + continue; + case 'd': + pt = _conv(t->tm_mday, "%02d", pt, ptlim, loc); + continue; + case 'E': + if (Ealternative || Oalternative) + break; + Ealternative++; + goto label; + case 'O': + /* + ** C99 locale modifiers. + ** The sequences + ** %Ec %EC %Ex %EX %Ey %EY + ** %Od %oe %OH %OI %Om %OM + ** %OS %Ou %OU %OV %Ow %OW %Oy + ** are supposed to provide alternate + ** representations. + ** + ** FreeBSD extension + ** %OB + */ + if (Ealternative || Oalternative) + break; + Oalternative++; + goto label; + case 'e': + pt = _conv(t->tm_mday, "%2d", 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); + continue; + case 'I': + pt = _conv((t->tm_hour % 12) ? + (t->tm_hour % 12) : 12, + "%02d", pt, ptlim, loc); + continue; + case 'j': + pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim, loc); + continue; + case 'k': + /* + ** This used to be... + ** _conv(t->tm_hour % 12 ? + ** 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 + ** "%l" have been swapped. + ** (ado, 1993-05-24) + */ + pt = _conv(t->tm_hour, "%2d", pt, ptlim, loc); + continue; +#ifdef KITCHEN_SINK + case 'K': + /* + ** After all this time, still unclaimed! + */ + pt = _add("kitchen sink", pt, ptlim); + continue; +#endif /* defined KITCHEN_SINK */ + case 'l': + /* + ** This used to be... + ** _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 + ** "%l" have been swapped. + ** (ado, 1993-05-24) + */ + pt = _conv((t->tm_hour % 12) ? + (t->tm_hour % 12) : 12, + "%2d", pt, ptlim, loc); + continue; + case 'M': + pt = _conv(t->tm_min, "%02d", pt, ptlim, loc); + continue; + case 'm': + pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim, loc); + continue; + case 'n': + pt = _add("\n", pt, ptlim); + continue; + case 'p': + pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ? + tptr->pm : + tptr->am, + pt, ptlim); + continue; + case 'R': + pt = _fmt("%H:%M", t, pt, ptlim, warnp, tptr, loc); + continue; + case 'r': + pt = _fmt(tptr->ampm_fmt, t, pt, ptlim, + warnp, tptr, loc); + continue; + case 'S': + pt = _conv(t->tm_sec, "%02d", pt, ptlim, loc); + continue; + case 's': + { + struct tm tm; + char buf[INT_STRLEN_MAXIMUM( + time_t) + 1]; + time_t mkt; + + tm = *t; + mkt = mktime(&tm); + if (TYPE_SIGNED(time_t)) + (void) sprintf_l(buf, loc, "%ld", + (long) mkt); + else (void) sprintf_l(buf, loc, "%lu", + (unsigned long) mkt); + pt = _add(buf, pt, ptlim); + } + continue; + case 'T': + pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp, tptr, loc); + continue; + case 't': + pt = _add("\t", pt, ptlim); + continue; + case 'U': + pt = _conv((t->tm_yday + DAYSPERWEEK - + t->tm_wday) / DAYSPERWEEK, + "%02d", pt, ptlim, loc); + continue; + case 'u': + /* + ** From Arnold Robbins' strftime version 3.0: + ** "ISO 8601: Weekday as a decimal number + ** [1 (Monday) - 7]" + ** (ado, 1993-05-24) + */ + pt = _conv((t->tm_wday == 0) ? + DAYSPERWEEK : t->tm_wday, + "%d", pt, ptlim, loc); + continue; + case 'V': /* ISO 8601 week number */ + 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 +** year (the first Monday as the first day of week 1) as a decimal number +** (01-53)." +** (ado, 1993-05-24) +** +** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn: +** "Week 01 of a year is per definition the first week which has the +** Thursday in this year, which is equivalent to the week which contains +** the fourth day of January. In other words, the first week of a new year +** is the week which has the majority of its days in the new year. Week 01 +** 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 +** 1997 lasts from 1996-12-30 to 1997-01-05..." +** (ado, 1996-01-02) +*/ + { + int year; + int yday; + int wday; + int w; + + year = t->tm_year + TM_YEAR_BASE; + yday = t->tm_yday; + wday = t->tm_wday; + for ( ; ; ) { + int len; + int bot; + int top; + + len = isleap(year) ? + DAYSPERLYEAR : + DAYSPERNYEAR; + /* + ** What yday (-3 ... 3) does + ** the ISO year begin on? + */ + bot = ((yday + 11 - wday) % + DAYSPERWEEK) - 3; + /* + ** What yday does the NEXT + ** ISO year begin on? + */ + top = bot - + (len % DAYSPERWEEK); + if (top < -3) + top += DAYSPERWEEK; + top += len; + if (yday >= top) { + ++year; + w = 1; + break; + } + if (yday >= bot) { + w = 1 + ((yday - bot) / + DAYSPERWEEK); + break; + } + --year; + yday += isleap(year) ? + DAYSPERLYEAR : + DAYSPERNYEAR; + } +#ifdef XPG4_1994_04_09 + 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, ptlim, loc); + else if (*format == 'g') { + *warnp = IN_ALL; + pt = _conv(year % 100, "%02d", + pt, ptlim, loc); + } else pt = _conv(year, "%04d", + pt, ptlim, loc); + } + continue; + case 'v': + /* + ** From Arnold Robbins' strftime version 3.0: + ** "date as dd-bbb-YYYY" + ** (ado, 1993-05-24) + */ + pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp, tptr, loc); + continue; + case 'W': + pt = _conv((t->tm_yday + DAYSPERWEEK - + (t->tm_wday ? + (t->tm_wday - 1) : + (DAYSPERWEEK - 1))) / DAYSPERWEEK, + "%02d", pt, ptlim, loc); + continue; + case 'w': + pt = _conv(t->tm_wday, "%d", pt, ptlim, loc); + continue; + case 'X': + pt = _fmt(tptr->X_fmt, t, pt, ptlim, warnp, tptr, loc); + continue; + case 'x': + { + int warn2 = IN_SOME; + + pt = _fmt(tptr->x_fmt, t, pt, ptlim, &warn2, tptr, loc); + if (warn2 == IN_ALL) + warn2 = IN_THIS; + if (warn2 > *warnp) + *warnp = warn2; + } + continue; + case 'y': + *warnp = IN_ALL; + pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, + "%02d", pt, ptlim, loc); + continue; + case 'Y': + pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", + pt, ptlim, loc); + continue; + case 'Z': +#ifdef TM_ZONE + if (t->TM_ZONE != NULL) + pt = _add(t->TM_ZONE, pt, ptlim); + else +#endif /* defined TM_ZONE */ + if (t->tm_isdst >= 0) + pt = _add(tzname[t->tm_isdst != 0], + pt, ptlim); + /* + ** C99 says that %Z must be replaced by the + ** empty string if the time zone is not + ** determinable. + */ + continue; + case 'z': + { + int diff; + char const * sign; + + if (t->tm_isdst < 0) + continue; +#ifdef TM_GMTOFF + diff = t->TM_GMTOFF; +#else /* !defined TM_GMTOFF */ + /* + ** C99 says that the UTC offset must + ** be computed by looking only at + ** 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 + ** tricky and requires disobeying C99; + ** see GNU C strftime for details. + ** For now, punt and conform to the + ** standard, even though it's incorrect. + ** + ** C99 says that %z must be replaced by the + ** empty string if the time zone is not + ** determinable, so output nothing if the + ** appropriate variables are not available. + */ + if (t->tm_isdst == 0) +#ifdef USG_COMPAT + diff = -_st_get_timezone(); +#else /* !defined USG_COMPAT */ + continue; +#endif /* !defined USG_COMPAT */ + else +#ifdef ALTZONE + diff = -altzone; +#else /* !defined ALTZONE */ + continue; +#endif /* !defined ALTZONE */ +#endif /* !defined TM_GMTOFF */ + 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); + } + continue; + case '+': + pt = _fmt(tptr->date_fmt, t, pt, ptlim, + warnp, tptr, loc); + continue; + case '%': + /* + ** X311J/88-090 (4.12.3.5): if conversion char is + ** undefined, behavior is undefined. Print out the + ** character itself as printf(3) also does. + */ + default: + break; + } + } + if (pt == ptlim) + break; + *pt++ = *format; + } + return pt; +} + +static char * +_conv(n, format, pt, ptlim, loc) +const int n; +const char * const format; +char * const pt; +const char * const ptlim; +locale_t loc; +{ + char buf[INT_STRLEN_MAXIMUM(int) + 1]; + + (void) sprintf_l(buf, loc, format, n); + return _add(buf, pt, ptlim); +} + +static char * +_add(str, pt, ptlim) +const char * str; +char * pt; +const char * const ptlim; +{ + while (pt < ptlim && (*pt = *str++) != '\0') + ++pt; + return pt; +} +#endif /* !BUILDING_VARIANT */ diff --git a/stdtime/strftime.3 b/stdtime/strftime.3 new file mode 100644 index 0000000..a2f6366 --- /dev/null +++ b/stdtime/strftime.3 @@ -0,0 +1,292 @@ +.\" Copyright (c) 1989, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd January 4, 2003 +.Dt STRFTIME 3 +.Os +.Sh NAME +.Nm strftime , +.Nm strftime_l +.Nd format date and time +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In time.h +.Ft size_t +.Fo strftime +.Fa "char *restrict s" +.Fa "size_t maxsize" +.Fa "const char *restrict format" +.Fa "const struct tm *restrict timeptr" +.Fc +.In time.h +.In xlocale.h +.Ft size_t +.Fo strftime_l +.Fa "char *restrict s" +.Fa "size_t maxsize" +.Fa "const char *restrict format" +.Fa "const struct tm *restrict timeptr" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn strftime +function formats the information from +.Fa timeptr +into the buffer +.Fa s , +according to the string pointed to by +.Fa format . +.Pp +The +.Fa format +string consists of zero or more conversion specifications and +ordinary characters. +All ordinary characters are copied directly into the buffer. +A conversion specification consists of a percent sign +.Dq Ql % +and one other character. +.Pp +No more than +.Fa maxsize +characters will be placed into the array. +If the total number of resulting characters, including the terminating +NUL character, is not more than +.Fa maxsize , +.Fn strftime +returns the number of characters in the array, not counting the +terminating NUL. +Otherwise, zero is returned and the buffer contents are indeterminate. +.Pp +Although the +.Fn strftime +function uses the current locale, the +.Fn strftime_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Pp +The conversion specifications are copied to the buffer after expansion +as follows:- +.Bl -tag -width "xxxx" +.It Cm \&%A +is replaced by national representation of the full weekday name. +.It Cm %a +is replaced by national representation of +the abbreviated weekday name. +.It Cm \&%B +is replaced by national representation of the full month name. +.It Cm %b +is replaced by national representation of +the abbreviated month name. +.It Cm \&%C +is replaced by (year / 100) as decimal number; single +digits are preceded by a zero. +.It Cm %c +is replaced by national representation of time and date. +.It Cm \&%D +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* +POSIX locale extensions. +The sequences +%Ec %EC %Ex %EX %Ey %EY +%Od %Oe %OH %OI %Om %OM +%OS %Ou %OU %OV %Ow %OW %Oy +are supposed to provide alternate +representations. +.Pp +Additionly %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 +digits are preceded by a blank. +.It Cm \&%F +is equivalent to +.Dq Li %Y-%m-%d . +.It Cm \&%G +is replaced by a year as a decimal number with century. +This year is the one that contains the greater part of +the week (Monday as the first day of the week). +.It Cm %g +is replaced by the same year as in +.Dq Li %G , +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. +.It Cm \&%I +is replaced by the hour (12-hour clock) as a decimal number (01-12). +.It Cm %j +is replaced by the day of the year as a decimal number (001-366). +.It Cm %k +is replaced by the hour (24-hour clock) as a decimal number (0-23); +single digits are preceded by a blank. +.It Cm %l +is replaced by the hour (12-hour clock) as a decimal number (1-12); +single digits are preceded by a blank. +.It Cm \&%M +is replaced by the minute as a decimal number (00-59). +.It Cm %m +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 %p +is replaced by national representation of either +"ante meridiem" +or +"post meridiem" +as appropriate. +.It Cm \&%R +is equivalent to +.Dq Li %H:%M . +.It Cm %r +is equivalent to +.Dq Li %I:%M:%S %p . +.It Cm \&%S +is replaced by the second as a decimal number (00-60). +.It Cm %s +is replaced by the number of seconds since the Epoch, UTC (see +.Xr mktime 3 ) . +.It Cm \&%T +is equivalent to +.Dq Li %H:%M:%S . +.It Cm %t +is replaced by a tab. +.It Cm \&%U +is replaced by the week number of the year (Sunday as the first day of +the week) as a decimal number (00-53). +.It Cm %u +is replaced by the weekday (Monday as the first day of the week) +as a decimal number (1-7). +.It Cm \&%V +is replaced by the week number of the year (Monday as the first day of +the week) as a decimal number (01-53). +If the week containing January +1 has four or more days in the new year, then it is week 1; otherwise +it is the last week of the previous year, and the next week is week 1. +.It Cm %v +is equivalent to +.Dq Li %e-%b-%Y . +.It Cm \&%W +is replaced by the week number of the year (Monday as the first day of +the week) as a decimal number (00-53). +.It Cm %w +is replaced by the weekday (Sunday as the first day of the week) +as a decimal number (0-6). +.It Cm \&%X +is replaced by national representation of the time. +.It Cm %x +is replaced by national representation of the date. +.It Cm \&%Y +is replaced by the year with century as a decimal number. +.It Cm %y +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 +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 +RFC 822 date headers). +.It Cm %+ +is replaced by national representation of the date and time +(the format is similar to that produced by +.Xr date 1 ) . +.It Cm %% +is replaced by +.Ql % . +.El +.Sh SEE ALSO +.Xr date 1 , +.Xr printf 1 , +.Xr ctime 3 , +.Xr printf 3 , +.Xr strptime 3 , +.Xr wcsftime 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn strftime +function +conforms to +.St -isoC +with a lot of extensions including +.Ql %C , +.Ql \&%D , +.Ql %E* , +.Ql %e , +.Ql %G , +.Ql %g , +.Ql %h , +.Ql %k , +.Ql %l , +.Ql %n , +.Ql %O* , +.Ql \&%R , +.Ql %r , +.Ql %s , +.Ql \&%T , +.Ql %t , +.Ql %u , +.Ql \&%V , +.Ql %z , +and +.Ql %+ . +.Pp +The peculiar week number and year in the replacements of +.Ql %G , +.Ql %g , +and +.Ql \&%V +are defined in ISO 8601: 1988. +.Sh BUGS +There is no conversion specification for the phase of the moon. +.Pp +The +.Fn strftime +function does not correctly handle multibyte characters in the +.Fa format +argument. diff --git a/stdtime/strptime-fbsd.c b/stdtime/strptime-fbsd.c new file mode 100644 index 0000000..064ddca --- /dev/null +++ b/stdtime/strptime-fbsd.c @@ -0,0 +1,646 @@ +/* + * Powerdog Industries kindly requests feedback from anyone modifying + * this function: + * + * Date: Thu, 05 Jun 1997 23:17:17 -0400 + * From: Kevin Ruddy + * To: James FitzGibbon + * Subject: Re: Use of your strptime(3) code (fwd) + * + * The reason for the "no mod" clause was so that modifications would + * come back and we could integrate them and reissue so that a wider + * audience could use it (thereby spreading the wealth). This has + * made it possible to get strptime to work on many operating systems. + * I'm not sure why that's "plain unacceptable" to the FreeBSD team. + * + * Anyway, you can change it to "with or without modification" as + * you see fit. Enjoy. + * + * Kevin Ruddy + * Powerdog Industries, Inc. + */ +/* + * Copyright (c) 1994 Powerdog Industries. 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 Powerdog Industries. + * 4. The name of Powerdog Industries may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``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 POWERDOG INDUSTRIES 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 +#ifndef lint +#ifndef NOID +static char copyright[] __unused = +"@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved."; +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 $"); + +#include "xlocale_private.h" + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#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])) + +enum {CONVERT_NONE, CONVERT_GMT, CONVERT_ZONE}; + +static char * +_strptime(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t loc) +{ + char c; + const char *ptr; + int i, + year = -1, + yday = 0, + wday = -1, + len; + int Ealternative, Oalternative; + struct lc_time_T *tptr = __get_current_time_locale(loc); + + ptr = fmt; + while (*ptr != 0) { + if (*buf == 0) { + fmt = ptr; + while (isspace_l((unsigned char)*ptr, loc)) { + ptr++; + } + return ((*ptr)==0) ? fmt : 0; /* trailing whitespace is ok */ + } + + c = *ptr++; + + if (c != '%') { + if (isspace_l((unsigned char)c, loc)) + while (*buf != 0 && isspace_l((unsigned char)*buf, loc)) + buf++; + else if (c != *buf++) + return 0; + continue; + } + + Ealternative = 0; + Oalternative = 0; +label: + c = *ptr++; + switch (c) { + case 0: + case '%': + if (*buf++ != '%') + return 0; + break; + + case '+': + buf = _strptime(buf, tptr->date_fmt, tm, convp, loc); + if (buf == 0) + return 0; + break; + + case 'C': + if (!isdigit_l((unsigned char)*buf, loc)) + return 0; + + /* XXX This will break for 3-digit centuries. */ + len = 2; + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (i < 19) + return 0; + + if (year != -1) + tm->tm_year = (year % 100) + i * 100 - 1900; + else + tm->tm_year = i * 100 - 1900; + year = tm->tm_year; + break; + + case 'c': + buf = _strptime(buf, tptr->c_fmt, tm, convp, loc); + if (buf == 0) + return 0; + break; + + case 'D': + buf = _strptime(buf, "%m/%d/%y", tm, convp, loc); + if (buf == 0) + return 0; + break; + + case 'E': + if (Ealternative || Oalternative) + break; + Ealternative++; + goto label; + + case 'O': + if (Ealternative || Oalternative) + break; + Oalternative++; + goto label; + + case 'F': + buf = _strptime(buf, "%Y-%m-%d", tm, convp, loc); + if (buf == 0) + return 0; + break; + + case 'R': + buf = _strptime(buf, "%H:%M", tm, convp, loc); + if (buf == 0) + return 0; + break; + + case 'r': + buf = _strptime(buf, tptr->ampm_fmt, tm, convp, loc); + if (buf == 0) + return 0; + break; + + case 'n': + case 't': + if (!isspace((unsigned char)*buf)) + return 0; + while (isspace((unsigned char)*buf)) + buf++; + break; + + case 'T': + buf = _strptime(buf, "%H:%M:%S", tm, convp, loc); + if (buf == 0) + return 0; + break; + + case 'X': + buf = _strptime(buf, tptr->X_fmt, tm, convp, loc); + if (buf == 0) + return 0; + break; + + case 'x': + buf = _strptime(buf, tptr->x_fmt, tm, convp, loc); + if (buf == 0) + return 0; + break; + + case 'j': + if (!isdigit_l((unsigned char)*buf, loc)) + return 0; + + len = 3; + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (i < 1 || i > 366) + return 0; + + tm->tm_yday = yday = i - 1; + break; + + case 'M': + case 'S': + if (*buf == 0 || isspace_l((unsigned char)*buf, loc)) + break; + + if (!isdigit_l((unsigned char)*buf, loc)) + return 0; + + len = 2; + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + + if (c == 'M') { + if (i > 59) + return 0; + tm->tm_min = i; + } else { + if (i > 60) + return 0; + tm->tm_sec = i; + } + + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') + ptr++; + break; + + case 'H': + case 'I': + case 'k': + case 'l': + /* + * Of these, %l is the only specifier explicitly + * documented as not being zero-padded. However, + * there is no harm in allowing zero-padding. + * + * XXX The %l specifier may gobble one too many + * digits if used incorrectly. + */ + if (!isdigit_l((unsigned char)*buf, loc)) + return 0; + + len = 2; + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (c == 'H' || c == 'k') { + if (i > 23) + return 0; + } else if (i > 12) + return 0; + + tm->tm_hour = i; + + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') + ptr++; + break; + + case 'p': + /* + * XXX This is bogus if parsed before hour-related + * specifiers. + */ + len = strlen(tptr->am); + if (strncasecmp_l(buf, tptr->am, len, loc) == 0) { + if (tm->tm_hour > 12) + return 0; + if (tm->tm_hour == 12) + tm->tm_hour = 0; + buf += len; + break; + } + + len = strlen(tptr->pm); + if (strncasecmp_l(buf, tptr->pm, len, loc) == 0) { + if (tm->tm_hour > 12) + return 0; + if (tm->tm_hour != 12) + tm->tm_hour += 12; + buf += len; + break; + } + + return 0; + + case 'A': + case 'a': + for (i = 0; i < asizeof(tptr->weekday); i++) { + len = strlen(tptr->weekday[i]); + if (strncasecmp_l(buf, tptr->weekday[i], + len, loc) == 0) + break; + len = strlen(tptr->wday[i]); + if (strncasecmp_l(buf, tptr->wday[i], + len, loc) == 0) + break; + } + if (i == asizeof(tptr->weekday)) + return 0; + + tm->tm_wday = wday = i; + buf += len; + break; + + case 'U': /* Sunday week */ + case 'W': /* Monday week */ + if (!isdigit_l((unsigned char)*buf, loc)) + return 0; + + len = 2; + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (i > 53) + return 0; + + /* Calculate yday if we have enough data */ + if ((year != -1) && (wday != -1)) { + struct tm mktm; + mktm.tm_year = year; + mktm.tm_mon = 0; + mktm.tm_mday = 1; + mktm.tm_sec = 1; + mktm.tm_min = mktm.tm_hour = 0; + mktm.tm_isdst = 0; + mktm.tm_gmtoff = 0; + if (mktime(&mktm) != -1) { + /* yday0 == Jan 1 == mktm.tm_wday */ + int delta = wday - mktm.tm_wday; + if (!wday && c =='W') + i++; /* Sunday is part of the following week */ + yday = 7 * i + delta; + if (yday < 0) + yday += 7; + tm->tm_yday = yday; + } + } + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') + ptr++; + break; + + case 'u': /* [1,7] */ + case 'w': /* [0,6] */ + if (!isdigit_l((unsigned char)*buf, loc)) + return 0; + + i = *buf - '0'; + if (i > 6 + (c == 'u')) + return 0; + if (i == 7) + i = 0; + tm->tm_wday = wday = i; + buf++; + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') + ptr++; + break; + + case 'd': + case 'e': + /* + * The %e specifier is explicitly documented as not + * being zero-padded but there is no harm in allowing + * such padding. + * + * XXX The %e specifier may gobble one too many + * digits if used incorrectly. + */ + /* Leading space is ok if date is single digit */ + len = 2; + if (isspace_l((unsigned char)buf[0], loc) && + isdigit_l((unsigned char)buf[1], loc) && + !isdigit_l((unsigned char)buf[2], loc)) { + len = 1; + buf++; + } + if (!isdigit_l((unsigned char)*buf, loc)) + return 0; + + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (i > 31) + return 0; + + tm->tm_mday = i; + + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') + ptr++; + break; + + case 'B': + case 'b': + case 'h': + for (i = 0; i < asizeof(tptr->month); i++) { + if (Oalternative) { + if (c == 'B') { + len = strlen(tptr->alt_month[i]); + if (strncasecmp_l(buf, + tptr->alt_month[i], + len, loc) == 0) + break; + } + } else { + len = strlen(tptr->month[i]); + if (strncasecmp_l(buf, tptr->month[i], + len, loc) == 0) + break; + len = strlen(tptr->mon[i]); + if (strncasecmp_l(buf, tptr->mon[i], + len, loc) == 0) + break; + } + } + if (i == asizeof(tptr->month)) + return 0; + + tm->tm_mon = i; + buf += len; + break; + + case 'm': + if (!isdigit_l((unsigned char)*buf, loc)) + return 0; + + len = 2; + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (i < 1 || i > 12) + return 0; + + tm->tm_mon = i - 1; + + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') + ptr++; + break; + + case 's': + { + char *cp; + int sverrno; + long n; + time_t t; + + sverrno = errno; + errno = 0; + n = strtol_l(buf, &cp, 10, loc); + if (errno == ERANGE || (long)(t = n) != n) { + errno = sverrno; + return 0; + } + errno = sverrno; + buf = cp; + gmtime_r(&t, tm); + *convp = CONVERT_GMT; + } + break; + + case 'Y': + case 'y': + if (*buf == 0 || isspace_l((unsigned char)*buf, loc)) + break; + + if (!isdigit_l((unsigned char)*buf, loc)) + return 0; + +#if __DARWIN_UNIX03 + if (c == 'Y') { + for (i = 0; *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + i *= 10; + i += *buf - '0'; + } + } else { + len = 2; +#else /* !__DARWIN_UNIX03 */ + len = (c == 'Y') ? 4 : 2; +#endif /* __DARWIN_UNIX03 */ + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } +#if __DARWIN_UNIX03 + } +#endif /* __DARWIN_UNIX03 */ + if (c == 'Y') + i -= 1900; + if (c == 'y' && i < 69) + i += 100; + if (i < 0) + return 0; + + tm->tm_year = year = i; + + if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') + ptr++; + break; + + case 'Z': + { + const char *cp; + char *zonestr; + + for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) {/*empty*/} + if (cp - buf) { + zonestr = alloca(cp - buf + 1); + strncpy(zonestr, buf, cp - buf); + zonestr[cp - buf] = '\0'; + tzset(); + if (0 == strcmp(zonestr, "GMT")) { + *convp = CONVERT_GMT; + } else if (0 == strcmp(zonestr, tzname[0])) { + tm->tm_isdst = 0; + } else if (0 == strcmp(zonestr, tzname[1])) { + tm->tm_isdst = 1; + } else { + return 0; + } + buf += cp - buf; + } + } + break; + + 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; + } + break; + } + } + return (char *)buf; +} + + +char * +strptime(const char * __restrict buf, const char * __restrict fmt, + struct tm * __restrict tm) +{ + return strptime_l(buf, fmt, tm, __current_locale()); +} + +extern time_t timeoff(struct tm *, long); + +char * +strptime_l(const char * __restrict buf, const char * __restrict fmt, + struct tm * __restrict tm, locale_t loc) +{ + char *ret; + int conv; + + NORMALIZE_LOCALE(loc); + conv = CONVERT_NONE; + tm->tm_zone = NULL; + ret = _strptime(buf, fmt, tm, &conv, loc); + if (ret) { + time_t t; + + switch(conv) { + case CONVERT_GMT: + t = timegm(tm); + localtime_r(&t, tm); + break; + case CONVERT_ZONE: + { + long offset = tm->tm_gmtoff; + tm->tm_gmtoff = 0; + t = timeoff(tm, offset); + localtime_r(&t, tm); + break; + } + } + } + + return (ret); +} diff --git a/stdtime/strptime.3 b/stdtime/strptime.3 new file mode 100644 index 0000000..eb41e8d --- /dev/null +++ b/stdtime/strptime.3 @@ -0,0 +1,197 @@ +.\" +.\" Copyright (c) 1997 Joerg Wunsch +.\" +.\" 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 DEVELOPERS ``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 DEVELOPERS 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/stdtime/strptime.3,v 1.23 2004/07/02 23:52:12 ru Exp $ +.\" " +.Dd January 4, 2003 +.Dt STRPTIME 3 +.Os +.Sh NAME +.Nm strptime , +.Nm strptime_l +.Nd parse date and time string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In time.h +.Ft char * +.Fo strptime +.Fa "const char *restrict buf" +.Fa "const char *restrict format" +.Fa "struct tm *restrict tm" +.Fc +.In time.h +.In xlocale.h +.Ft char * +.Fo strptime_l +.Fa "const char *restrict buf" +.Fa "const char *restrict format" +.Fa "struct tm *restrict tm" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn strptime +function parses the string in the buffer +.Fa buf , +according to the string pointed to by +.Fa format , +and fills in the elements of the structure pointed to by +.Fa tm . +The resulting values will be relative to the local time zone. +Thus, it can be considered the reverse operation of +.Xr strftime 3 . +.Pp +The +.Fa format +string consists of zero or more conversion specifications and +ordinary characters. +All ordinary characters are matched exactly with the buffer, where +white space in the format string will match any amount of white space +in the buffer. +All conversion specifications are identical to those described in +.Xr strftime 3 . +.Pp +Two-digit year values, including formats +.Fa %y +and +.Fa \&%D , +are now interpreted as beginning at 1969 per POSIX requirements. +Years 69-00 are interpreted in the 20th century (1969-2000), years +01-68 in the 21st century (2001-2068). +.Pp +If the +.Fa format +string does not contain enough conversion specifications to completely +specify the resulting +.Vt struct tm , +the unspecified members of +.Va tm +are left untouched. +For example, if +.Fa format +is +.Dq Li "%H:%M:%S" , +only +.Va tm_hour , +.Va tm_sec +and +.Va tm_min +will be modified. +If time relative to today is desired, initialize the +.Fa tm +structure with today's date before passing it to +.Fn strptime . +.Pp +While the +.Fn strptime +function uses the current locale, the +.Fn strptime_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +Upon successful completion, +.Fn strptime +returns the pointer to the first character in +.Fa buf +that has not been required to satisfy the specified conversions in +.Fa format . +It returns +.Dv NULL +if one of the conversions failed. +.Sh LEGACY DESCRIPTION +In legacy mode, the +.Fa %Y +format specifier expects exactly 4 digits (leaving any trailing digits for the +next specifier). +.Sh SEE ALSO +.Xr date 1 , +.Xr scanf 3 , +.Xr strftime 3 , +.Xr xlocale 3 +.Sh AUTHORS +The +.Fn strptime +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 +and +.Fa %l +format specifiers may incorrectly scan one too many digits +if the intended values comprise only a single digit +and that digit is followed immediately by another digit. +Both specifiers accept zero-padded values, +even though they are both defined as taking unpadded values. +.Pp +The +.Fa %p +format specifier has no effect unless it is parsed +.Em after +hour-related specifiers. +Specifying +.Fa %l +without +.Fa %p +will produce undefined results. +Note that 12AM +(ante meridiem) +is taken as midnight +and 12PM +(post meridiem) +is taken as noon. +.Pp +The +.Fa %U +and +.Fa %W +format specifiers accept any value within the range 00 to 53 +without validating against other values supplied (like month +or day of the year, for example). +.Pp +The +.Fa %Z +format specifier only accepts time zone abbreviations of the local time zone, +or the value "GMT". +This limitation is because of ambiguity due to of the over loading of time +zone abbreviations. +One such example is +.Fa EST +which is both Eastern Standard Time and Eastern Australia Summer Time. +.Pp +The +.Fn strptime +function does not correctly handle multibyte characters in the +.Fa format +argument. diff --git a/stdtime/time2posix.3 b/stdtime/time2posix.3 new file mode 100644 index 0000000..95f39b8 --- /dev/null +++ b/stdtime/time2posix.3 @@ -0,0 +1,120 @@ +.\" $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/time32-fbsd.c b/stdtime/time32-fbsd.c new file mode 100644 index 0000000..5085dd7 --- /dev/null +++ b/stdtime/time32-fbsd.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2001 FreeBSD Inc. + * All rights reserved. + * + * These routines are for converting time_t to fixed-bit representations + * for use in protocols or storage. When converting time to a larger + * representation of time_t these routines are expected to assume temporal + * locality and use the 50-year rule to properly set the msb bits. XXX + * + * Redistribution and use under the terms of the COPYRIGHT file at the + * base of the source tree. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/stdtime/time32.c,v 1.5 2002/06/17 01:42:29 wollman Exp $"); + +#include +#include + +/* + * Convert a 32 bit representation of time_t into time_t. XXX needs to + * implement the 50-year rule to handle post-2038 conversions. + */ +time_t +_time32_to_time(__int32_t t32) +{ + return((time_t)t32); +} + +/* + * Convert time_t to a 32 bit representation. If time_t is 64 bits we can + * simply chop it down. The resulting 32 bit representation can be + * converted back to a temporally local 64 bit time_t using time32_to_time. + */ +__int32_t +_time_to_time32(time_t t) +{ + return((__int32_t)t); +} + +/* + * Convert a 64 bit representation of time_t into time_t. If time_t is + * represented as 32 bits we can simply chop it and not support times + * past 2038. + */ +time_t +_time64_to_time(__int64_t t64) +{ + return((time_t)t64); +} + +/* + * Convert time_t to a 64 bit representation. If time_t is represented + * as 32 bits we simply sign-extend and do not support times past 2038. + */ +__int64_t +_time_to_time64(time_t t) +{ + return((__int64_t)t); +} + +/* + * Convert to/from 'long'. Depending on the sizeof(long) this may or + * may not require using the 50-year rule. + */ +long +_time_to_long(time_t t) +{ + if (sizeof(long) == sizeof(__int64_t)) + return(_time_to_time64(t)); + return((long)t); +} + +time_t +_long_to_time(long tlong) +{ + if (sizeof(long) == sizeof(__int32_t)) + return(_time32_to_time(tlong)); + return((time_t)tlong); +} + +/* + * Convert to/from 'int'. Depending on the sizeof(int) this may or + * may not require using the 50-year rule. + */ +int +_time_to_int(time_t t) +{ + if (sizeof(int) == sizeof(__int64_t)) + return(_time_to_time64(t)); + return((int)t); +} + +time_t +_int_to_time(int tint) +{ + if (sizeof(int) == sizeof(__int32_t)) + return(_time32_to_time(tint)); + return((time_t)tint); +} diff --git a/stdtime/timelocal-fbsd.c b/stdtime/timelocal-fbsd.c new file mode 100644 index 0000000..e3673be --- /dev/null +++ b/stdtime/timelocal-fbsd.c @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 2001 Alexey Zelkin + * Copyright (c) 1997 FreeBSD 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. + * + * 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/stdtime/timelocal.c,v 1.25 2003/06/13 00:14:07 jkh Exp $"); + +#include "xlocale_private.h" + +#include +#include + +#include "ldpart.h" +#include "timelocal.h" + +#define LCTIME_SIZE (sizeof(struct lc_time_T) / sizeof(char *)) + +static const struct lc_time_T _C_time_locale = { + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }, { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }, { + "Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat" + }, { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }, + + /* X_fmt */ + "%H:%M:%S", + + /* + * x_fmt + * Since the C language standard calls for + * "date, using locale's date format," anything goes. + * Using just numbers (as here) makes Quakers happier; + * it's also compatible with SVR4. + */ + "%m/%d/%y", + + /* + * c_fmt + */ + "%a %b %e %H:%M:%S %Y", + + /* am */ + "AM", + + /* pm */ + "PM", + + /* date_fmt */ + "%a %b %e %H:%M:%S %Z %Y", + + /* alt_month + * Standalone months forms for %OB + */ + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }, + + /* md_order + * Month / day order in dates + */ + "md", + + /* ampm_fmt + * To determine 12-hour clock format time (empty, if N/A) + */ + "%I:%M:%S %p" +}; + +__private_extern__ struct lc_time_T * +__get_current_time_locale(locale_t loc) +{ + return (loc->_time_using_locale + ? &loc->__lc_time->_time_locale + : (struct lc_time_T *)&_C_time_locale); +} + +__private_extern__ int +__time_load_locale(const char *name, locale_t loc) +{ + int ret; + struct __xlocale_st_time *xp; + static struct __xlocale_st_time *cache = NULL; + + /* 'name' must be already checked. */ + if (strcmp(name, "C") == 0 || strcmp(name, "POSIX") == 0) { + loc->_time_using_locale = 0; + XL_RELEASE(loc->__lc_time); + loc->__lc_time = NULL; + return (_LDP_CACHE); + } + + /* + * If the locale name is the same as our cache, use the cache. + */ + if (cache && cache->_time_locale_buf && strcmp(name, cache->_time_locale_buf) == 0) { + loc->_time_using_locale = 1; + XL_RELEASE(loc->__lc_time); + loc->__lc_time = cache; + XL_RETAIN(loc->__lc_time); + return (_LDP_CACHE); + } + if ((xp = (struct __xlocale_st_time *)malloc(sizeof(*xp))) == NULL) + return _LDP_ERROR; + xp->__refcount = 1; + xp->__free_extra = (__free_extra_t)__ldpart_free_extra; + xp->_time_locale_buf = NULL; + + ret = __part_load_locale(name, &loc->_time_using_locale, + &xp->_time_locale_buf, "LC_TIME", + LCTIME_SIZE, LCTIME_SIZE, + (const char **)&xp->_time_locale); + if (ret == _LDP_LOADED) { + XL_RELEASE(loc->__lc_time); + loc->__lc_time = xp; + XL_RELEASE(cache); + cache = xp; + XL_RETAIN(cache); + } else if (ret == _LDP_ERROR) + free(xp); + + return (ret); +} diff --git a/stdtime/timelocal.h b/stdtime/timelocal.h new file mode 100644 index 0000000..02806e8 --- /dev/null +++ b/stdtime/timelocal.h @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 1997-2002 FreeBSD Project. + * 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/stdtime/timelocal.h,v 1.11 2002/01/24 15:07:44 phantom Exp $ + */ + +#ifndef _TIMELOCAL_H_ +#define _TIMELOCAL_H_ + +#include + +/* + * Private header file for the strftime and strptime localization + * stuff. + */ +struct lc_time_T { + const char *mon[12]; + const char *month[12]; + const char *wday[7]; + const char *weekday[7]; + const char *X_fmt; + const char *x_fmt; + const char *c_fmt; + const char *am; + const char *pm; + const char *date_fmt; + const char *alt_month[12]; + const char *md_order; + const char *ampm_fmt; +}; + +struct lc_time_T *__get_current_time_locale(locale_t); +int __time_load_locale(const char *, locale_t); + +#endif /* !_TIMELOCAL_H_ */ diff --git a/stdtime/timezone_unix03.c b/stdtime/timezone_unix03.c index b3a3da6..ad15a78 100644 --- a/stdtime/timezone_unix03.c +++ b/stdtime/timezone_unix03.c @@ -21,8 +21,6 @@ * @APPLE_LICENSE_HEADER_END@ */ -#undef __DARWIN_UNIX03 -#define __DARWIN_UNIX03 1 #include long timezone = 0; diff --git a/stdtime/tzfile.5 b/stdtime/tzfile.5 new file mode 100644 index 0000000..6dcbc27 --- /dev/null +++ b/stdtime/tzfile.5 @@ -0,0 +1,138 @@ +.\" $FreeBSD: src/lib/libc/stdtime/tzfile.5,v 1.10 2001/07/10 13:41:23 ru Exp $ +.Dd September 13, 1994 +.Dt TZFILE 5 +.Os +.Sh NAME +.Nm tzfile +.Nd timezone information +.Sh SYNOPSIS +.In tzfile.h +.Sh DESCRIPTION +The time zone information files used by +.Xr tzset 3 +begin with the magic characters +.Dq Li TZif +to identify them as +time zone information files, +followed by sixteen bytes reserved for future use, +followed by four four-byte values +written in a ``standard'' byte order +(the high-order byte of the value is written first). +These values are, +in order: +.Pp +.Bl -tag -compact -width tzh_ttisstdcnt +.It Va tzh_ttisgmtcnt +The number of UTC/local indicators stored in the file. +.It Va tzh_ttisstdcnt +The number of standard/wall indicators stored in the file. +.It Va tzh_leapcnt +The number of leap seconds for which data is stored in the file. +.It Va tzh_timecnt +The number of ``transition times'' for which data is stored +in the file. +.It Va tzh_typecnt +The number of ``local time types'' for which data is stored +in the file (must not be zero). +.It Va tzh_charcnt +The number of characters of ``time zone abbreviation strings'' +stored in the file. +.El +.Pp +The above header is followed by +.Va tzh_timecnt +four-byte values of type +.Fa long , +sorted in ascending order. +These values are written in ``standard'' byte order. +Each is used as a transition time (as returned by +.Xr time 3 ) +at which the rules for computing local time change. +Next come +.Va tzh_timecnt +one-byte values of type +.Fa "unsigned char" ; +each one tells which of the different types of ``local time'' types +described in the file is associated with the same-indexed transition time. +These values serve as indices into an array of +.Fa ttinfo +structures that appears next in the file; +these structures are defined as follows: +.Pp +.Bd -literal -offset indent +struct ttinfo { + long tt_gmtoff; + int tt_isdst; + unsigned int tt_abbrind; +}; +.Ed +.Pp +Each structure is written as a four-byte value for +.Va tt_gmtoff +of type +.Fa long , +in a standard byte order, followed by a one-byte value for +.Va tt_isdst +and a one-byte value for +.Va tt_abbrind . +In each structure, +.Va tt_gmtoff +gives the number of seconds to be added to UTC, +.Li tt_isdst +tells whether +.Li tm_isdst +should be set by +.Xr localtime 3 +and +.Va tt_abbrind +serves as an index into the array of time zone abbreviation characters +that follow the +.Li ttinfo +structure(s) in the file. +.Pp +Then there are +.Va tzh_leapcnt +pairs of four-byte values, written in standard byte order; +the first value of each pair gives the time +(as returned by +.Xr time 3 ) +at which a leap second occurs; +the second gives the +.Em total +number of leap seconds to be applied after the given time. +The pairs of values are sorted in ascending order by time. +.Pp +Then there are +.Va tzh_ttisstdcnt +standard/wall indicators, each stored as a one-byte value; +they tell whether the transition times associated with local time types +were specified as standard time or wall clock time, +and are used when a time zone file is used in handling POSIX-style +time zone environment variables. +.Pp +Finally there are +.Va tzh_ttisgmtcnt +UTC/local indicators, each stored as a one-byte value; +they tell whether the transition times associated with local time types +were specified as UTC or local time, +and are used when a time zone file is used in handling POSIX-style +time zone environment variables. +.Pp +.Nm localtime +uses the first standard-time +.Li ttinfo +structure in the file +(or simply the first +.Li ttinfo +structure in the absence of a standard-time structure) +if either +.Li tzh_timecnt +is zero or the time argument is less than the first transition time recorded +in the file. +.Sh SEE ALSO +.Xr ctime 3 , +.Xr time2posix 3 , +.Xr zic 8 +.\" @(#)tzfile.5 7.2 +.\" This file is in the public domain, so clarified as of +.\" 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). diff --git a/stdtime/tzfile.h b/stdtime/tzfile.h new file mode 100644 index 0000000..378d7ae --- /dev/null +++ b/stdtime/tzfile.h @@ -0,0 +1,192 @@ +#ifndef TZFILE_H +#define TZFILE_H + + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** +** $FreeBSD: src/lib/libc/stdtime/tzfile.h,v 1.8 2002/03/22 23:42:05 obrien Exp $ +*/ + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** ID +*/ + +#ifndef lint +#ifndef NOID +/* +static char tzfilehid[] = "@(#)tzfile.h 7.14"; +*/ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* +** Information about time zone files. +*/ + +#ifndef TZDIR +#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */ +#endif /* !defined TZDIR */ + +#ifndef TZDEFAULT +#define TZDEFAULT "/etc/localtime" +#endif /* !defined TZDEFAULT */ + +#ifndef TZDEFRULES +#define TZDEFRULES "posixrules" +#endif /* !defined TZDEFRULES */ + +/* +** Each file begins with. . . +*/ + +#define TZ_MAGIC "TZif" + +struct tzhead { + char tzh_magic[4]; /* TZ_MAGIC */ + char tzh_reserved[16]; /* reserved for future use */ + char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ + char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ + char tzh_leapcnt[4]; /* coded number of leap seconds */ + char tzh_timecnt[4]; /* coded number of transition times */ + char tzh_typecnt[4]; /* coded number of local time types */ + char tzh_charcnt[4]; /* coded number of abbr. chars */ +}; + +/* +** . . .followed by. . . +** +** tzh_timecnt (char [4])s coded transition times a la time(2) +** tzh_timecnt (unsigned char)s types of local time starting at above +** tzh_typecnt repetitions of +** one (char [4]) coded UTC offset in seconds +** one (unsigned char) used to set tm_isdst +** one (unsigned char) that's an abbreviation list index +** tzh_charcnt (char)s '\0'-terminated zone abbreviations +** tzh_leapcnt repetitions of +** one (char [4]) coded leap second transition times +** one (char [4]) total correction after above +** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition +** time is standard time, if FALSE, +** transition time is wall clock time +** if absent, transition times are +** assumed to be wall clock time +** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition +** time is UTC, if FALSE, +** transition time is local time +** if absent, transition times are +** assumed to be local time +*/ + +/* +** In the current implementation, "tzset()" refuses to deal with files that +** exceed any of the limits below. +*/ + +#ifndef TZ_MAX_TIMES +/* +** The TZ_MAX_TIMES value below is enough to handle a bit more than a +** year's worth of solar time (corrected daily to the nearest second) or +** 138 years of Pacific Presidential Election time +** (where there are three time zone transitions every fourth year). +*/ +#define TZ_MAX_TIMES 370 +#endif /* !defined TZ_MAX_TIMES */ + +#ifndef TZ_MAX_TYPES +#ifndef NOSOLAR +#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ +#endif /* !defined NOSOLAR */ +#ifdef NOSOLAR +/* +** Must be at least 14 for Europe/Riga as of Jan 12 1995, +** as noted by Earl Chew . +*/ +#define TZ_MAX_TYPES 20 /* Maximum number of local time types */ +#endif /* !defined NOSOLAR */ +#endif /* !defined TZ_MAX_TYPES */ + +#ifndef TZ_MAX_CHARS +#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ + /* (limited by what unsigned chars can hold) */ +#endif /* !defined TZ_MAX_CHARS */ + +#ifndef TZ_MAX_LEAPS +#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ +#endif /* !defined TZ_MAX_LEAPS */ + +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define HOURSPERDAY 24 +#define DAYSPERWEEK 7 +#define DAYSPERNYEAR 365 +#define DAYSPERLYEAR 366 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) +#define MONSPERYEAR 12 + +#define TM_SUNDAY 0 +#define TM_MONDAY 1 +#define TM_TUESDAY 2 +#define TM_WEDNESDAY 3 +#define TM_THURSDAY 4 +#define TM_FRIDAY 5 +#define TM_SATURDAY 6 + +#define TM_JANUARY 0 +#define TM_FEBRUARY 1 +#define TM_MARCH 2 +#define TM_APRIL 3 +#define TM_MAY 4 +#define TM_JUNE 5 +#define TM_JULY 6 +#define TM_AUGUST 7 +#define TM_SEPTEMBER 8 +#define TM_OCTOBER 9 +#define TM_NOVEMBER 10 +#define TM_DECEMBER 11 + +#define TM_YEAR_BASE 1900 + +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY TM_THURSDAY + +/* +** Accurate only for the past couple of centuries; +** that will probably do. +*/ + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) + +#ifndef USG + +/* +** Use of the underscored variants may cause problems if you move your code to +** certain System-V-based systems; for maximum portability, use the +** underscore-free variants. The underscored variants are provided for +** backward compatibility only; they may disappear from future versions of +** this file. +*/ + +#define SECS_PER_MIN SECSPERMIN +#define MINS_PER_HOUR MINSPERHOUR +#define HOURS_PER_DAY HOURSPERDAY +#define DAYS_PER_WEEK DAYSPERWEEK +#define DAYS_PER_NYEAR DAYSPERNYEAR +#define DAYS_PER_LYEAR DAYSPERLYEAR +#define SECS_PER_HOUR SECSPERHOUR +#define SECS_PER_DAY SECSPERDAY +#define MONS_PER_YEAR MONSPERYEAR + +#endif /* !defined USG */ + +#endif /* !defined TZFILE_H */ diff --git a/string/FreeBSD/bcmp.3.patch b/string/FreeBSD/bcmp.3.patch new file mode 100644 index 0000000..d2bdbfb --- /dev/null +++ b/string/FreeBSD/bcmp.3.patch @@ -0,0 +1,25 @@ +--- _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 @@ + .Sh SYNOPSIS + .In strings.h + .Ft int +-.Fn bcmp "const void *b1" "const void *b2" "size_t len" ++.Fn bcmp "const void *s1" "const void *s2" "size_t n" + .Sh DESCRIPTION + The + .Fn bcmp + function + compares byte string +-.Fa b1 ++.Fa s1 + against byte string +-.Fa b2 , ++.Fa s2 , + returning zero if they are identical, non-zero otherwise. + Both strings are assumed to be +-.Fa len ++.Fa n + bytes long. + Zero-length strings are always identical. + .Pp diff --git a/string/FreeBSD/bcopy.3.patch b/string/FreeBSD/bcopy.3.patch new file mode 100644 index 0000000..e06b82f --- /dev/null +++ b/string/FreeBSD/bcopy.3.patch @@ -0,0 +1,28 @@ +--- _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 @@ + .Sh SYNOPSIS + .In strings.h + .Ft void +-.Fn bcopy "const void *src" "void *dst" "size_t len" ++.Fn bcopy "const void *s1" "void *s2" "size_t n" + .Sh DESCRIPTION + The + .Fn bcopy + function + copies +-.Fa len ++.Fa n + bytes from string +-.Fa src ++.Fa s1 + to string +-.Fa dst . ++.Fa s2 . + The two strings may overlap. + If +-.Fa len ++.Fa n + is zero, no bytes are copied. + .Sh SEE ALSO + .Xr memccpy 3 , diff --git a/string/FreeBSD/bstring.3.patch b/string/FreeBSD/bstring.3.patch new file mode 100644 index 0000000..79c87c1 --- /dev/null +++ b/string/FreeBSD/bstring.3.patch @@ -0,0 +1,101 @@ +--- 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 @@ + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS +-.In string.h ++.In strings.h + .Ft int +-.Fn bcmp "const void *b1" "const void *b2" "size_t len" ++.Fo bcmp ++.Fa "const void *s1" ++.Fa "const void *s2" ++.Fa "size_t n" ++.Fc + .Ft void +-.Fn bcopy "const void *src" "void *dst" "size_t len" ++.Fo bcopy ++.Fa "const void *s1" ++.Fa "void *s2" ++.Fa "size_t n" ++.Fc + .Ft void +-.Fn bzero "void *b" "size_t len" ++.Fo bzero ++.Fa "void *s" ++.Fa "size_t n" ++.Fc ++.In string.h + .Ft void * +-.Fn memchr "const void *b" "int c" "size_t len" +-.Ft int +-.Fn memcmp "const void *b1" "const void *b2" "size_t len" ++.Fo memccpy ++.Fa "void *restrict s1" ++.Fa "const void *restrict s2" ++.Fa "int c" ++.Fa "size_t n" ++.Fc + .Ft void * +-.Fn memccpy "void *dst" "const void *src" "int c" "size_t len" ++.Fo memchr ++.Fa "const void *s" ++.Fa "int c" ++.Fa "size_t n" ++.Fc ++.Ft int ++.Fo memcmp ++.Fa "const void *s1" ++.Fa "const void *s2" ++.Fa "size_t n" ++.Fc + .Ft void * +-.Fn memcpy "void *dst" "const void *src" "size_t len" ++.Fo memcpy ++.Fa "void *restrict s1" ++.Fa "const void *restrict s2" ++.Fa "size_t n" ++.Fc + .Ft void * +-.Fn memmove "void *dst" "const void *src" "size_t len" ++.Fo memmove ++.Fa "void *s1" ++.Fa "const void *s2" ++.Fa "size_t n" ++.Fc + .Ft void * +-.Fn memset "void *b" "int c" "size_t len" ++.Fo memset ++.Fa "void *s" ++.Fa "int c" ++.Fa "size_t n" ++.Fc + .Sh DESCRIPTION + These functions operate on variable length strings of bytes. +-They do not check for terminating null bytes as the routines ++They do not check for terminating null bytes, as the routines + listed in + .Xr string 3 + do. + .Pp + See the specific manual pages for more information. ++.Sh LEGACY SYNOPSIS ++.Fd #include ++.Pp ++The include file ++.In string.h ++is necessary and sufficient for all functions. + .Sh SEE ALSO + .Xr bcmp 3 , + .Xr bcopy 3 , +@@ -87,7 +130,8 @@ + .Xr memcmp 3 , + .Xr memcpy 3 , + .Xr memmove 3 , +-.Xr memset 3 ++.Xr memset 3 , ++.Xr compat 5 + .Sh STANDARDS + The functions + .Fn memchr , diff --git a/string/FreeBSD/bzero.3.patch b/string/FreeBSD/bzero.3.patch new file mode 100644 index 0000000..17f0185 --- /dev/null +++ b/string/FreeBSD/bzero.3.patch @@ -0,0 +1,25 @@ +--- _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 @@ + .Sh SYNOPSIS + .In strings.h + .Ft void +-.Fn bzero "void *b" "size_t len" ++.Fn bzero "void *s" "size_t n" + .Sh DESCRIPTION + The + .Fn bzero + function + writes +-.Fa len +-zero bytes to the string +-.Fa b . ++.Fa n ++zeroed bytes to the string ++.Fa s . + If +-.Fa len ++.Fa n + is zero, + .Fn bzero + does nothing. diff --git a/string/FreeBSD/ffs.3.patch b/string/FreeBSD/ffs.3.patch new file mode 100644 index 0000000..dd1b81a --- /dev/null +++ b/string/FreeBSD/ffs.3.patch @@ -0,0 +1,46 @@ +--- _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 @@ + .Sh SYNOPSIS + .In strings.h + .Ft int +-.Fn ffs "int value" ++.Fn ffs "int i" + .Ft int +-.Fn ffsl "long value" ++.Fn ffsl "long i" + .Ft int +-.Fn fls "int value" ++.Fn fls "int i" + .Ft int +-.Fn flsl "long value" ++.Fn flsl "long i" + .Sh DESCRIPTION + The + .Fn ffs + and + .Fn ffsl + functions find the first bit set in +-.Fa value ++.Fa i + and return the index of that bit. + .Pp + The +@@ -69,7 +69,7 @@ + and + .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 @@ + .Pp + The + .Fn ffsl , +-.Fn fls ++.Fn fls , + and + .Fn flsl + functions appeared in diff --git a/string/FreeBSD/index.3.patch b/string/FreeBSD/index.3.patch new file mode 100644 index 0000000..cd10d6d --- /dev/null +++ b/string/FreeBSD/index.3.patch @@ -0,0 +1,22 @@ +--- _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 @@ + .Vt char ) + in the string pointed to by + .Fa s . +-The terminating null character is considered part of the string; +-therefore if ++The terminating null character is considered to be part of the string; ++therefore, if + .Fa c + is + .Ql \e0 , +@@ -70,7 +70,7 @@ + .Fn rindex + function is identical to + .Fn index , +-except it locates the last occurrence of ++except that it locates the last occurrence of + .Fa c . + .Sh RETURN VALUES + The functions diff --git a/string/FreeBSD/memccpy.3.patch b/string/FreeBSD/memccpy.3.patch new file mode 100644 index 0000000..de3913f --- /dev/null +++ b/string/FreeBSD/memccpy.3.patch @@ -0,0 +1,40 @@ +--- _SB/Libc/string/FreeBSD/memccpy.3 2003-05-20 15:23:54.000000000 -0700 ++++ _SB/Libc/string/FreeBSD/memccpy.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -43,26 +43,31 @@ + .Sh SYNOPSIS + .In string.h + .Ft void * +-.Fn memccpy "void *dst" "const void *src" "int c" "size_t len" ++.Fo memccpy ++.Fa "void *restrict s1" ++.Fa "const void *restrict s2" ++.Fa "int c" ++.Fa "size_t n" ++.Fc + .Sh DESCRIPTION + The + .Fn memccpy + function + copies bytes from string +-.Fa src ++.Fa s2 + to string +-.Fa dst . ++.Fa s1 . + If the character + .Fa c + (as converted to an unsigned char) occurs in the string +-.Fa src , ++.Fa s2 , + the copy stops and a pointer to the byte after the copy of + .Fa c + in the string +-.Fa dst ++.Fa s1 + is returned. + Otherwise, +-.Fa len ++.Fa n + bytes are copied, and a NULL pointer is returned. + .Sh SEE ALSO + .Xr bcopy 3 , diff --git a/string/FreeBSD/memchr.3.patch b/string/FreeBSD/memchr.3.patch new file mode 100644 index 0000000..0142127 --- /dev/null +++ b/string/FreeBSD/memchr.3.patch @@ -0,0 +1,32 @@ +--- _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 @@ + .Sh SYNOPSIS + .In string.h + .Ft void * +-.Fn memchr "const void *b" "int c" "size_t len" ++.Fo memchr ++.Fa "const void *s" ++.Fa "int c" ++.Fa "size_t n" ++.Fc + .Sh DESCRIPTION + The + .Fn memchr +@@ -56,14 +60,14 @@ + .Fa c + (converted to an unsigned char) + in string +-.Fa b . ++.Fa s . + .Sh RETURN VALUES + The + .Fn memchr + 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 strchr 3 , diff --git a/string/FreeBSD/memcmp.3.patch b/string/FreeBSD/memcmp.3.patch new file mode 100644 index 0000000..9b92c7e --- /dev/null +++ b/string/FreeBSD/memcmp.3.patch @@ -0,0 +1,28 @@ +--- _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 @@ + .Sh SYNOPSIS + .In string.h + .Ft int +-.Fn memcmp "const void *b1" "const void *b2" "size_t len" ++.Fo memcmp ++.Fa "const void *s1" ++.Fa "const void *s2" ++.Fa "size_t n" ++.Fc + .Sh DESCRIPTION + The + .Fn memcmp + function + compares byte string +-.Fa b1 ++.Fa s1 + against byte string +-.Fa b2 . ++.Fa s2 . + Both strings are assumed to be +-.Fa len ++.Fa n + bytes long. + .Sh RETURN VALUES + The diff --git a/string/FreeBSD/memcpy.3.patch b/string/FreeBSD/memcpy.3.patch index 536697a..19f2f88 100644 --- a/string/FreeBSD/memcpy.3.patch +++ b/string/FreeBSD/memcpy.3.patch @@ -1,6 +1,6 @@ ---- memcpy.3.orig Fri May 28 17:44:25 2004 -+++ memcpy.3 Fri May 28 17:45:22 2004 -@@ -41,7 +41,7 @@ +--- _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 @@ .Os .Sh NAME .Nm memcpy @@ -9,32 +9,52 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -@@ -54,10 +54,22 @@ + .In string.h + .Ft void * +-.Fn memcpy "void *dst" "const void *src" "size_t len" ++.Fo memcpy ++.Fa "void *restrict s1" ++.Fa "const void *restrict s2" ++.Fa "size_t n" ++.Fc + .Sh DESCRIPTION + The + .Fn memcpy function copies - .Fa len +-.Fa len -bytes from string -+bytes from memory area - .Fa src +-.Fa src -to string +-.Fa dst . ++.Fa n ++bytes from memory area ++.Fa s2 +to memory area - .Fa dst . ++.Fa s1 . +If -+.Fa src ++.Fa s1 +and -+.Fa dst ++.Fa s2 +overlap, behavior is undefined. +Applications in which -+.Fa src ++.Fa s1 +and -+.Fa dst ++.Fa s2 +might overlap should use +.Xr memmove 3 +instead. .Sh RETURN VALUES The .Fn memcpy -@@ -75,17 +87,3 @@ + function + returns the original value of +-.Fa dst . ++.Fa s1 . + .Sh SEE ALSO + .Xr bcopy 3 , + .Xr memccpy 3 , +@@ -75,17 +91,3 @@ function conforms to .St -isoC . diff --git a/string/FreeBSD/memmove.3.patch b/string/FreeBSD/memmove.3.patch new file mode 100644 index 0000000..6fdf054 --- /dev/null +++ b/string/FreeBSD/memmove.3.patch @@ -0,0 +1,36 @@ +--- 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 @@ + .Sh SYNOPSIS + .In string.h + .Ft void * +-.Fn memmove "void *dst" "const void *src" "size_t len" ++.Fo memmove ++.Fa "void *s1" ++.Fa "const void *s2" ++.Fa "size_t n" ++.Fc + .Sh DESCRIPTION + The + .Fn memmove + function + copies +-.Fa len ++.Fa n + bytes from string +-.Fa src ++.Fa s2 + to string +-.Fa dst . ++.Fa s1 . + The two strings may overlap; + the copy is always done in a non-destructive manner. + .Sh RETURN VALUES + The + .Fn memmove + function returns the original value of +-.Fa dst . ++.Fa s1 . + .Sh SEE ALSO + .Xr bcopy 3 , + .Xr memccpy 3 , diff --git a/string/FreeBSD/memset.3.patch b/string/FreeBSD/memset.3.patch new file mode 100644 index 0000000..6836f0d --- /dev/null +++ b/string/FreeBSD/memset.3.patch @@ -0,0 +1,41 @@ +--- memset.3 2003-05-20 15:23:54.000000000 -0700 ++++ memset.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -41,29 +41,34 @@ + .Os + .Sh NAME + .Nm memset +-.Nd write a byte to byte string ++.Nd write a byte to a byte string + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In string.h + .Ft void * +-.Fn memset "void *b" "int c" "size_t len" ++.Fo memset ++.Fa "void *b" ++.Fa "int c" ++.Fa "size_t n" ++.Fc + .Sh DESCRIPTION + The + .Fn memset + function + writes +-.Fa len ++.Fa n + bytes of value + .Fa c + (converted to an unsigned char) to the string +-.Fa b . ++.Fa s . + .Sh RETURN VALUES + The + .Fn memset + function returns its first argument. + .Sh SEE ALSO + .Xr bzero 3 , ++.Xr memset_pattern 3 , + .Xr swab 3 + .Sh STANDARDS + The diff --git a/string/FreeBSD/rindex.3.patch b/string/FreeBSD/rindex.3.patch new file mode 100644 index 0000000..03b5fe5 --- /dev/null +++ b/string/FreeBSD/rindex.3.patch @@ -0,0 +1,13 @@ +--- _SB/Libc/string/FreeBSD/rindex.3 2003-05-20 15:23:54.000000000 -0700 ++++ _SB/Libc/string/FreeBSD/rindex.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -58,8 +58,8 @@ + in the null-terminated string + .Fa s . + .Sh RETURN VALUES +-A pointer to the character is returned if it is found; otherwise +-NULL is returned. ++A pointer to the character is returned if it is found; ++otherwise, NULL is returned. + If + .Fa c + is diff --git a/string/FreeBSD/strcasecmp.3.patch b/string/FreeBSD/strcasecmp.3.patch index 52000bd..de13f67 100644 --- a/string/FreeBSD/strcasecmp.3.patch +++ b/string/FreeBSD/strcasecmp.3.patch @@ -1,34 +1,58 @@ ---- strcasecmp.3.orig Fri Mar 11 08:37:27 2005 -+++ strcasecmp.3 Fri Mar 11 08:38:54 2005 -@@ -39,7 +39,9 @@ +--- _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 @@ .Os .Sh NAME .Nm strcasecmp , -.Nm strncasecmp -+.Nm strncasecmp , +.Nm strcasecmp_l , ++.Nm strncasecmp , +.Nm strncasecmp_l .Nd compare strings, ignoring case .Sh LIBRARY .Lb libc -@@ -49,6 +51,11 @@ - .Fn strcasecmp "const char *s1" "const char *s2" + .Sh SYNOPSIS + .In strings.h .Ft int - .Fn strncasecmp "const char *s1" "const char *s2" "size_t len" +-.Fn strcasecmp "const char *s1" "const char *s2" ++.Fo strcasecmp ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc + .Ft int +-.Fn strncasecmp "const char *s1" "const char *s2" "size_t len" ++.Fo strncasecmp ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fa "size_t n" ++.Fc ++.In strings.h +.In xlocale.h +.Ft int -+.Fn strcasecmp_l "const char *s1" "const char *s2" "locale_t loc" ++.Fo strcasecmp_l ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fa "locale_t loc" ++.Fc +.Ft int -+.Fn strncasecmp_l "const char *s1" "const char *s2" "size_t len" "locale_t loc" ++.Fo strncasecmp_l ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fa "size_t n" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn strcasecmp -@@ -65,6 +72,18 @@ +@@ -63,8 +87,20 @@ + The + .Fn strncasecmp compares at most - .Fa len +-.Fa len ++.Fa n characters. +.Pp -+While the ++Although the +.Fn strcasecmp +and +.Fn strncasecmp @@ -42,7 +66,7 @@ .Sh RETURN VALUES The .Fn strcasecmp -@@ -87,7 +106,8 @@ +@@ -87,7 +123,8 @@ .Xr strcmp 3 , .Xr strcoll 3 , .Xr strxfrm 3 , diff --git a/string/FreeBSD/strcat.3.patch b/string/FreeBSD/strcat.3.patch index 1824d98..22104e3 100644 --- a/string/FreeBSD/strcat.3.patch +++ b/string/FreeBSD/strcat.3.patch @@ -1,6 +1,71 @@ ---- strcat.3.orig Fri May 28 16:23:18 2004 -+++ strcat.3 Fri May 28 16:23:32 2004 -@@ -114,7 +114,7 @@ +--- _SB/Libc/string/FreeBSD/strcat.3 2003-05-20 15:23:54.000000000 -0700 ++++ _SB/Libc/string/FreeBSD/strcat.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -40,16 +40,24 @@ + .Dt STRCAT 3 + .Os + .Sh NAME +-.Nm strcat ++.Nm strcat , ++.Nm strncat + .Nd concatenate strings + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .In string.h + .Ft char * +-.Fn strcat "char * restrict s" "const char * restrict append" ++.Fo strcat ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fc + .Ft char * +-.Fn strncat "char * restrict s" "const char * restrict append" "size_t count" ++.Fo strncat ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fa "size_t n" ++.Fc + .Sh DESCRIPTION + The + .Fn strcat +@@ -57,22 +65,22 @@ + .Fn strncat + functions + append a copy of the null-terminated string +-.Fa append ++.Fa s2 + to the end of the null-terminated string +-.Fa s , ++.Fa s1 , + then add a terminating + .Ql \e0 . + The string +-.Fa s ++.Fa s1 + must have sufficient space to hold the result. + .Pp + The + .Fn strncat + function + appends not more than +-.Fa count ++.Fa n + characters from +-.Fa append , ++.Fa s2 , + and then adds a terminating + .Ql \e0 . + .Sh RETURN VALUES +@@ -82,7 +90,7 @@ + .Fn strncat + functions + return the pointer +-.Fa s . ++.Fa s1 . + .Sh SECURITY CONSIDERATIONS + The + .Fn strcat +@@ -114,7 +122,7 @@ void foo(const char *arbitrary_string) { @@ -9,7 +74,7 @@ #if defined(BAD) /* -@@ -149,11 +149,6 @@ +@@ -149,11 +157,6 @@ .Xr strcpy 3 , .Xr strlcat 3 , .Xr strlcpy 3 diff --git a/string/FreeBSD/strchr.3.patch b/string/FreeBSD/strchr.3.patch new file mode 100644 index 0000000..69bf2a3 --- /dev/null +++ b/string/FreeBSD/strchr.3.patch @@ -0,0 +1,38 @@ +--- _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 @@ + .Sh SYNOPSIS + .In string.h + .Ft "char *" +-.Fn strchr "const char *s" "int c" ++.Fo strchr ++.Fa "const char *s" ++.Fa "int c" ++.Fc + .Ft "char *" +-.Fn strrchr "const char *s" "int c" ++.Fo strrchr ++.Fa "const char *s" ++.Fa "int c" ++.Fc + .Sh DESCRIPTION + The + .Fn strchr +@@ -59,7 +65,7 @@ + .Vt char ) + in the string pointed to by + .Fa s . +-The terminating null character is considered part of the string; ++The terminating null character is considered to be part of the string; + therefore if + .Fa c + is +@@ -70,7 +76,7 @@ + The + .Fn strrchr + function is identical to +-.Fn strchr ++.Fn strchr , + except it locates the last occurrence of + .Fa c . + .Sh RETURN VALUES diff --git a/string/FreeBSD/strcmp.3.patch b/string/FreeBSD/strcmp.3.patch new file mode 100644 index 0000000..292eaa4 --- /dev/null +++ b/string/FreeBSD/strcmp.3.patch @@ -0,0 +1,30 @@ +--- _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 @@ + .Sh SYNOPSIS + .In string.h + .Ft int +-.Fn strcmp "const char *s1" "const char *s2" ++.Fo strcmp ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc + .Ft int +-.Fn strncmp "const char *s1" "const char *s2" "size_t len" ++.Fo strncmp ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fa "size_t n" ++.Fc + .Sh DESCRIPTION + The + .Fn strcmp +@@ -66,7 +73,7 @@ + .Fn strncmp + function + compares not more than +-.Fa len ++.Fa n + characters. + Because + .Fn strncmp diff --git a/string/FreeBSD/strcoll.3.patch b/string/FreeBSD/strcoll.3.patch index d3301c8..317d110 100644 --- a/string/FreeBSD/strcoll.3.patch +++ b/string/FreeBSD/strcoll.3.patch @@ -1,31 +1,53 @@ ---- strcoll.3.orig Fri Mar 11 08:36:09 2005 -+++ strcoll.3 Fri Mar 11 09:43:41 2005 -@@ -40,7 +40,8 @@ +--- _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 @@ .Dt STRCOLL 3 .Os .Sh NAME -.Nm strcoll +-.Nd compare strings according to current collation +.Nm strcoll , +.Nm strcoll_l - .Nd compare strings according to current collation ++.Nd compare strings, according to current collation .Sh LIBRARY .Lb libc -@@ -48,6 +49,9 @@ + .Sh SYNOPSIS .In string.h .Ft int - .Fn strcoll "const char *s1" "const char *s2" +-.Fn strcoll "const char *s1" "const char *s2" ++.Fo strcoll ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc ++.In string.h +.In xlocale.h +.Ft int -+.Fn strcoll_l "const char *s1" "const char *s2" "locale_t loc" ++.Fo strcoll_l ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn strcoll -@@ -63,11 +67,20 @@ +@@ -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 . +.Pp -+While the ++Although the +.Fn strcoll +function uses the current locale, the +.Fn strcoll_l diff --git a/string/FreeBSD/strcoll.c.patch b/string/FreeBSD/strcoll.c.patch index 47bae59..4dce6b4 100644 --- a/string/FreeBSD/strcoll.c.patch +++ b/string/FreeBSD/strcoll.c.patch @@ -1,6 +1,6 @@ --- strcoll.c.orig 2003-05-20 15:23:54.000000000 -0700 -+++ strcoll.c 2005-02-17 10:37:14.000000000 -0800 -@@ -28,26 +28,30 @@ ++++ strcoll.c 2005-03-30 15:16:28.000000000 -0800 +@@ -28,59 +28,44 @@ #include __FBSDID("$FreeBSD: src/lib/libc/string/strcoll.c,v 1.13 2001/11/07 19:55:16 obrien Exp $"); @@ -8,6 +8,8 @@ + #include #include ++#include ++#include #include "collate.h" int @@ -16,53 +18,66 @@ const char *s, *s2; + locale_t loc; { - int len, len2, prim, prim2, sec, sec2, ret, ret2; - const char *t, *t2; - char *tt, *tt2; +- int len, len2, prim, prim2, sec, sec2, ret, ret2; +- const char *t, *t2; +- char *tt, *tt2; ++ int ret; ++ const wchar_t *t = NULL, *t2 = NULL; ++ int sverrno; - if (__collate_load_error) + NORMALIZE_LOCALE(loc); -+ if (loc->__collate_load_error) ++ if (loc->__collate_load_error || (t = __collate_mbstowcs(s, loc)) == NULL || (t2 = __collate_mbstowcs(s2, loc)) == NULL) { ++ sverrno = errno; ++ free((void *)t); ++ free((void *)t2); ++ errno = sverrno; return strcmp(s, s2); - - len = len2 = 1; - ret = ret2 = 0; +- +- len = len2 = 1; +- ret = ret2 = 0; - if (__collate_substitute_nontrivial) { - t = tt = __collate_substitute(s); - t2 = tt2 = __collate_substitute(s2); -+ if (loc->__collate_substitute_nontrivial) { -+ t = tt = (char *)__collate_substitute_l((unsigned char *)s, loc); -+ t2 = tt2 = (char *)__collate_substitute_l((unsigned char *)s2, loc); - } else { - tt = tt2 = NULL; - t = s; -@@ -56,11 +60,11 @@ - while(*t && *t2) { - prim = prim2 = 0; - while(*t && !prim) { +- } else { +- tt = tt2 = NULL; +- t = s; +- t2 = s2; + } +- while(*t && *t2) { +- prim = prim2 = 0; +- while(*t && !prim) { - __collate_lookup(t, &len, &prim, &sec); -+ __collate_lookup_l((unsigned char *)t, &len, &prim, &sec, loc); - t += len; - } - while(*t2 && !prim2) { +- t += len; +- } +- while(*t2 && !prim2) { - __collate_lookup(t2, &len2, &prim2, &sec2); -+ __collate_lookup_l((unsigned char *)t2, &len2, &prim2, &sec2, loc); - t2 += len2; - } - if(!prim || !prim2) -@@ -73,9 +77,9 @@ - ret2 = sec - sec2; - } - if(!*t && *t2) +- t2 += len2; +- } +- if(!prim || !prim2) +- break; +- if(prim != prim2) { +- ret = prim - prim2; +- goto end; +- } +- if(!ret2) +- ret2 = sec - sec2; +- } +- if(!*t && *t2) - ret = -(int)((u_char)*t2); -+ ret = -(int)((unsigned char)*t2); - else if(*t && !*t2) +- else if(*t && !*t2) - ret = (u_char)*t; -+ ret = (unsigned char)*t; - else if(!*t && !*t2) - ret = ret2; - end: -@@ -84,3 +88,10 @@ +- else if(!*t && !*t2) +- ret = ret2; +- end: +- free(tt); +- free(tt2); ++ ++ ret = wcscoll_l(t, t2, loc); ++ sverrno = errno; ++ free((void *)t); ++ free((void *)t2); ++ errno = sverrno; return ret; } diff --git a/string/FreeBSD/strcpy.3.patch b/string/FreeBSD/strcpy.3.patch index 1860713..f7f2be7 100644 --- a/string/FreeBSD/strcpy.3.patch +++ b/string/FreeBSD/strcpy.3.patch @@ -1,11 +1,119 @@ -Index: strcpy.3 -=================================================================== -RCS file: /cvs/root/Libc/string/FreeBSD/strcpy.3,v -retrieving revision 1.2 -diff -u -r1.2 strcpy.3 ---- strcpy.3 2003/05/20 22:23:54 1.2 -+++ strcpy.3 2003/10/24 18:27:22 -@@ -179,11 +179,6 @@ +--- _SB/Libc/string/FreeBSD/strcpy.3 2003-05-20 15:23:54.000000000 -0700 ++++ _SB/Libc/string/FreeBSD/strcpy.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -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 + .Sh SYNOPSIS + .In string.h + .Ft char * +-.Fn stpcpy "char *dst" "const char *src" ++.Fo stpcpy ++.Fa "char *s1" ++.Fa "const char *s2" ++.Fc + .Ft char * +-.Fn strcpy "char * restrict dst" "const char * restrict src" ++.Fo strcpy ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fc + .Ft char * +-.Fn strncpy "char * restrict dst" "const char * restrict src" "size_t len" ++.Fo strncpy ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fa "size_t n" ++.Fc + .Sh DESCRIPTION + The + .Fn stpcpy +@@ -59,33 +71,33 @@ + .Fn strcpy + functions + copy the string +-.Fa src ++.Fa s2 + to +-.Fa dst ++.Fa s1 + (including the terminating + .Ql \e0 +-character.) ++character). + .Pp + The + .Fn strncpy + function copies at most +-.Fa len ++.Fa n + characters from +-.Fa src ++.Fa s2 + into +-.Fa dst . ++.Fa s1 . + If +-.Fa src ++.Fa s2 + is less than +-.Fa len ++.Fa n + characters long, + the remainder of +-.Fa dst ++.Fa s1 + is filled with + .Ql \e0 + characters. + Otherwise, +-.Fa dst ++.Fa s1 + is + .Em not + terminated. +@@ -96,13 +108,13 @@ + .Fn strncpy + functions + return +-.Fa dst . ++.Fa s1 . + The + .Fn stpcpy + function returns a pointer to the terminating + .Ql \e0 + character of +-.Fa dst . ++.Fa s1 . + .Sh EXAMPLES + The following sets + .Va chararray +@@ -128,7 +140,7 @@ + .Em not + .Tn NUL + terminate +-.Va chararray ++.Va chararray , + because the length of the source string is greater than or equal + to the length argument. + .Pp +@@ -159,7 +171,7 @@ + .Pp + .Dl "(void)strlcpy(buf, input, sizeof(buf));" + .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 +191,6 @@ .Xr memcpy 3 , .Xr memmove 3 , .Xr strlcpy 3 diff --git a/string/FreeBSD/strcspn.3.patch b/string/FreeBSD/strcspn.3.patch new file mode 100644 index 0000000..3525890 --- /dev/null +++ b/string/FreeBSD/strcspn.3.patch @@ -0,0 +1,39 @@ +--- _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 @@ + .Sh SYNOPSIS + .In string.h + .Ft size_t +-.Fn strcspn "const char *s" "const char *charset" ++.Fo strcspn ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc + .Sh DESCRIPTION + The + .Fn strcspn + function + spans the initial part of the null-terminated string +-.Fa s ++.Fa s1 , + as long as the characters from +-.Fa s ++.Fa s1 + do not occur in string +-.Fa charset ++.Fa s2 + (it + spans the + .Em complement + of +-.Fa charset ) . ++.Fa s2 ) . + .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/strcspn.c b/string/FreeBSD/strcspn.c index 48354a6..55acb8b 100644 --- a/string/FreeBSD/strcspn.c +++ b/string/FreeBSD/strcspn.c @@ -1,9 +1,6 @@ /*- - * 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. + * Copyright (c) 2005 David Schultz + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -13,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) @@ -34,36 +24,49 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)strcspn.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strcspn.c,v 1.4 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strcspn.c,v 1.5 2005/04/02 18:52:44 das Exp $"); +#include +#include #include -/* - * Span the complement of string s2. - */ +#define IDX(c) ((u_char)(c) / LONG_BIT) +#define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT)) + size_t -strcspn(s1, s2) - const char *s1; - const char *s2; +strcspn(const char *s, const char *charset) { - const char *p, *spanp; - char c, sc; - /* - * Stop as soon as we find any character from s2. Note that there - * must be a NUL in s2; it suffices to stop when we find that, too. + * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to + * generate better code. Without them, gcc gets a little confused. */ - for (p = s1;;) { - c = *p++; - spanp = s2; - do { - if ((sc = *spanp++) == c) - return (p - 1 - s1); - } while (sc != 0); + const char *s1; + u_long bit; + u_long tbl[(UCHAR_MAX + 1) / LONG_BIT]; + int idx; + + if(*s == '\0') + return (0); + +#if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */ + tbl[0] = 1; + tbl[3] = tbl[2] = tbl[1] = 0; +#else + for (tbl[0] = idx = 1; idx < sizeof(tbl) / sizeof(tbl[0]); idx++) + tbl[idx] = 0; +#endif + for (; *charset != '\0'; charset++) { + idx = IDX(*charset); + bit = BIT(*charset); + tbl[idx] |= bit; + } + + for(s1 = s; ; s1++) { + idx = IDX(*s1); + bit = BIT(*s1); + if ((tbl[idx] & bit) != 0) + break; } - /* NOTREACHED */ + return (s1 - s); } diff --git a/string/FreeBSD/strdup.3.patch b/string/FreeBSD/strdup.3.patch new file mode 100644 index 0000000..e05470d --- /dev/null +++ b/string/FreeBSD/strdup.3.patch @@ -0,0 +1,21 @@ +--- _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 @@ + .Sh SYNOPSIS + .In string.h + .Ft char * +-.Fn strdup "const char *str" ++.Fo strdup ++.Fa "const char *s1" ++.Fc + .Sh DESCRIPTION + The + .Fn strdup + function + allocates sufficient memory for a copy + of the string +-.Fa str , ++.Fa s1 , + does the copy, and returns a pointer to it. + The pointer may subsequently be used as an + argument to the function diff --git a/string/FreeBSD/strerror.3.patch b/string/FreeBSD/strerror.3.patch new file mode 100644 index 0000000..ed73088 --- /dev/null +++ b/string/FreeBSD/strerror.3.patch @@ -0,0 +1,42 @@ +--- _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 @@ + .Sh SYNOPSIS + .In stdio.h + .Ft void +-.Fn perror "const char *string" ++.Fo perror ++.Fa "const char *s" ++.Fc + .Vt extern const char * const sys_errlist[] ; + .Vt extern const int sys_nerr ; + .In string.h + .Ft "char *" +-.Fn strerror "int errnum" ++.Fo strerror ++.Fa "int errnum" ++.Fc + .Ft int +-.Fn strerror_r "int errnum" "char *strerrbuf" "size_t buflen" ++.Fo strerror_r ++.Fa "int errnum" ++.Fa "char *strerrbuf" ++.Fa "size_t buflen" ++.Fc + .Sh DESCRIPTION + The + .Fn strerror , +-.Fn strerror_r ++.Fn strerror_r , + and + .Fn perror + functions look up the error message string corresponding to an +@@ -92,7 +100,7 @@ + and writes it, followed by a newline, to the + standard error file descriptor. + If the argument +-.Fa string ++.Fa s + is + .Pf non- Dv NULL + and does not point to the null character, diff --git a/string/FreeBSD/strerror.c.patch b/string/FreeBSD/strerror.c.patch new file mode 100644 index 0000000..077e741 --- /dev/null +++ b/string/FreeBSD/strerror.c.patch @@ -0,0 +1,49 @@ +--- 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 @@ + */ + #define EBUFSIZE (20 + sizeof(UPREFIX)) + ++#ifndef BUILDING_VARIANT + /* + * 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) ++__private_extern__ void ++__errstr(int num, char *buf, size_t len) + { + char *t; + unsigned int uerr; +@@ -77,14 +78,17 @@ + strerror_r(int errnum, char *strerrbuf, size_t buflen) + { + +- if (errnum < 1 || errnum >= sys_nerr) { +- errstr(errnum, strerrbuf, buflen); ++ if (errnum < 0 || errnum >= sys_nerr) { ++ __errstr(errnum, strerrbuf, buflen); + return (EINVAL); + } + if (strlcpy(strerrbuf, sys_errlist[errnum], buflen) >= buflen) + return (ERANGE); + return (0); + } ++#else /* BUILDING_VARIANT */ ++__private_extern__ void __errstr(int, char *, size_t); ++#endif /* !BUILDING_VARIANT */ + + char * + strerror(int num) +@@ -93,7 +97,9 @@ + + if (num > 0 && num < sys_nerr) + return ((char *)sys_errlist[num]); ++#if !__DARWIN_UNIX03 + errno = EINVAL; +- errstr(num, ebuf, sizeof(ebuf)); ++#endif /* !__DARWIN_UNIX03 */ ++ __errstr(num, ebuf, sizeof(ebuf)); + return (ebuf); + } diff --git a/string/FreeBSD/string.3.patch b/string/FreeBSD/string.3.patch new file mode 100644 index 0000000..7acc472 --- /dev/null +++ b/string/FreeBSD/string.3.patch @@ -0,0 +1,193 @@ +--- _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 @@ + .Dt STRING 3 + .Os + .Sh NAME ++.Nm index , ++.Nm rindex , + .Nm stpcpy , ++.Nm strcasecmp , + .Nm strcat , +-.Nm strncat , + .Nm strchr , +-.Nm strrchr , + .Nm strcmp , +-.Nm strncmp , +-.Nm strcasecmp , +-.Nm strncasecmp , + .Nm strcpy , +-.Nm strncpy , ++.Nm strcspn , + .Nm strerror , + .Nm strlen , ++.Nm strncasecmp , ++.Nm strncat , ++.Nm strncmp , ++.Nm strncpy , + .Nm strpbrk , ++.Nm strrchr , + .Nm strsep , + .Nm strspn , +-.Nm strcspn , + .Nm strstr , +-.Nm strtok , +-.Nm index , +-.Nm rindex ++.Nm strtok + .Nd string specific functions + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS +-.In string.h ++.In strings.h + .Ft char * +-.Fn stpcpy "char *dst" "const char *src" +-.Ft char * +-.Fn strcat "char *s" "const char * append" +-.Ft char * +-.Fn strncat "char *s" "const char *append" "size_t count" +-.Ft char * +-.Fn strchr "const char *s" "int c" +-.Ft char * +-.Fn strrchr "const char *s" "int c" +-.Ft int +-.Fn strcmp "const char *s1" "const char *s2" ++.Fo index ++.Fa "const char *s" ++.Fa "int c" ++.Fc ++.Ft char * ++.Fo rindex ++.Fa "const char *s" ++.Fa "int c" ++.Fc + .Ft int +-.Fn strncmp "const char *s1" "const char *s2" "size_t count" ++.Fo strcasecmp ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc + .Ft int +-.Fn strcasecmp "const char *s1" "const char *s2" +-.Ft int +-.Fn strncasecmp "const char *s1" "const char *s2" "size_t count" +-.Ft char * +-.Fn strcpy "char *dst" "const char *src" +-.Ft char * +-.Fn strncpy "char *dst" "const char *src" "size_t count" ++.Fo strncasecmp ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fa "size_t n" ++.Fc ++.In string.h + .Ft char * +-.Fn strerror "int errno" ++.Fo stpcpy ++.Fa "char *dst" ++.Fa "const char *src" ++.Fc ++.Ft char * ++.Fo strcat ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fc ++.Ft char * ++.Fo strchr ++.Fa "const char *s" ++.Fa "int c" ++.Fc ++.Ft int ++.Fo strcmp ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc ++.Ft char * ++.Fo strcpy ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fc + .Ft size_t +-.Fn strlen "const char *s" +-.Ft char * +-.Fn strpbrk "const char *s" "const char *charset" +-.Ft char * +-.Fn strsep "char **stringp" "const char *delim" ++.Fo strcspn ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc ++.Ft char * ++.Fo strerror ++.Fa "int errnum" ++.Fc + .Ft size_t +-.Fn strspn "const char *s" "const char *charset" ++.Fo strlen ++.Fa "const char *s" ++.Fc ++.Ft char * ++.Fo strncat ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fa "size_t n" ++.Fc ++.Ft int ++.Fo strncmp ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fa "size_t n" ++.Fc ++.Ft char * ++.Fo strncpy ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fa "size_t n" ++.Fc ++.Ft char * ++.Fo strpbrk ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc ++.Ft char * ++.Fo strrchr ++.Fa "const char *s" ++.Fa "int c" ++.Fc ++.Ft char * ++.Fo strsep ++.Fa "char **stringp" ++.Fa "const char *delim" ++.Fc + .Ft size_t +-.Fn strcspn "const char *s" "const char *charset" +-.Ft char * +-.Fn strstr "const char *big" "const char *little" +-.Ft char * +-.Fn strtok "char *s" "const char *delim" +-.Ft char * +-.Fn index "const char *s" "int c" +-.Ft char * +-.Fn rindex "const char *s" "int c" ++.Fo strspn ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc ++.Ft char * ++.Fo strstr ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc ++.Ft char * ++.Fo strtok ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fc + .Sh DESCRIPTION + The string +-functions manipulate strings terminated by a ++functions manipulate strings that are terminated by a + null byte. + .Pp + See the specific manual pages for more information. diff --git a/string/FreeBSD/strmode.3.patch b/string/FreeBSD/strmode.3.patch new file mode 100644 index 0000000..3653596 --- /dev/null +++ b/string/FreeBSD/strmode.3.patch @@ -0,0 +1,14 @@ +--- 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 @@ + .Sh SYNOPSIS + .In string.h + .Ft void +-.Fn strmode "mode_t mode" "char *bp" ++.Fo strmode ++.Fa "int mode" ++.Fa "char *bp" ++.Fc + .Sh DESCRIPTION + The + .Fn strmode diff --git a/string/FreeBSD/strnstr.c b/string/FreeBSD/strnstr.c index 9f3b038..abe2f8d 100644 --- a/string/FreeBSD/strnstr.c +++ b/string/FreeBSD/strnstr.c @@ -39,7 +39,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.2 2001/11/07 19:55:16 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strnstr.c,v 1.3 2005/02/11 21:07:51 pjd Exp $"); #include @@ -60,7 +60,7 @@ strnstr(s, find, slen) len = strlen(find); do { do { - if ((sc = *s++) == '\0' || slen-- < 1) + if (slen-- < 1 || (sc = *s++) == '\0') return (NULL); } while (sc != c); if (len > slen) diff --git a/string/FreeBSD/strpbrk.3.patch b/string/FreeBSD/strpbrk.3.patch new file mode 100644 index 0000000..6befc6f --- /dev/null +++ b/string/FreeBSD/strpbrk.3.patch @@ -0,0 +1,32 @@ +--- _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 @@ + .Sh SYNOPSIS + .In string.h + .Ft char * +-.Fn strpbrk "const char *s" "const char *charset" ++.Fo strpbrk ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc + .Sh DESCRIPTION + The + .Fn strpbrk + function + locates in the null-terminated string +-.Fa s ++.Fa s1 + the first occurrence of any character in the string +-.Fa charset +-and returns a pointer to this character. ++.Fa s2 , ++returning a pointer to this character. + If no characters from +-.Fa charset ++.Fa s2 + occur anywhere in +-.Fa s ++.Fa s1 , + .Fn strpbrk + returns NULL. + .Sh SEE ALSO diff --git a/string/FreeBSD/strrchr.3.patch b/string/FreeBSD/strrchr.3.patch new file mode 100644 index 0000000..2e8fe81 --- /dev/null +++ b/string/FreeBSD/strrchr.3.patch @@ -0,0 +1,14 @@ +--- _SB/Libc/string/FreeBSD/strrchr.3 2003-05-20 15:23:55.000000000 -0700 ++++ _SB/Libc/string/FreeBSD/strrchr.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -47,7 +47,10 @@ + .Sh SYNOPSIS + .In string.h + .Ft char * +-.Fn strrchr "const char *s" "int c" ++.Fo strrchr ++.Fa "const char *s" ++.Fa "int c" ++.Fc + .Sh DESCRIPTION + The + .Fn strrchr diff --git a/string/FreeBSD/strspn.3.patch b/string/FreeBSD/strspn.3.patch new file mode 100644 index 0000000..3db7258 --- /dev/null +++ b/string/FreeBSD/strspn.3.patch @@ -0,0 +1,27 @@ +--- _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 @@ + .Sh SYNOPSIS + .In string.h + .Ft size_t +-.Fn strspn "const char *s" "const char *charset" ++.Fo strspn ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc + .Sh DESCRIPTION + The + .Fn strspn + function + spans the initial part of the null-terminated string +-.Fa s ++.Fa s1 , + as long as the characters from +-.Fa s ++.Fa s1 + occur in string +-.Fa charset . ++.Fa s2 . + .Sh RETURN VALUES + The + .Fn strspn diff --git a/string/FreeBSD/strspn.c b/string/FreeBSD/strspn.c index ae28642..3b96365 100644 --- a/string/FreeBSD/strspn.c +++ b/string/FreeBSD/strspn.c @@ -1,6 +1,6 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. +/*- + * Copyright (c) 2005 David Schultz + * 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,32 +24,48 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)strspn.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strspn.c,v 1.4 2002/03/21 18:44:54 obrien Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strspn.c,v 1.5 2005/04/02 18:52:44 das Exp $"); +#include +#include #include -/* - * Span the string s2 (skip characters that are in s2). - */ +#define IDX(c) ((u_char)(c) / LONG_BIT) +#define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT)) + size_t -strspn(s1, s2) - const char *s1; - const char *s2; +strspn(const char *s, const char *charset) { - const char *p = s1, *spanp; - char c, sc; - /* - * Skip any characters in s2, excluding the terminating \0. + * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to + * generate better code. Without them, gcc gets a little confused. */ -cont: - c = *p++; - for (spanp = s2; (sc = *spanp++) != 0;) - if (sc == c) - goto cont; - return (p - 1 - s1); + const char *s1; + u_long bit; + u_long tbl[(UCHAR_MAX + 1) / LONG_BIT]; + int idx; + + if(*s == '\0') + return (0); + +#if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */ + tbl[3] = tbl[2] = tbl[1] = tbl[0] = 0; +#else + for (idx = 0; idx < sizeof(tbl) / sizeof(tbl[0]); idx++) + tbl[idx] = 0; +#endif + for (; *charset != '\0'; charset++) { + idx = IDX(*charset); + bit = BIT(*charset); + tbl[idx] |= bit; + } + + for(s1 = s; ; s1++) { + idx = IDX(*s1); + bit = BIT(*s1); + if ((tbl[idx] & bit) == 0) + break; + } + return (s1 - s); } diff --git a/string/FreeBSD/strstr.3.patch b/string/FreeBSD/strstr.3.patch index 3621361..2b7900a 100644 --- a/string/FreeBSD/strstr.3.patch +++ b/string/FreeBSD/strstr.3.patch @@ -1,25 +1,75 @@ ---- strstr.3.orig Fri Mar 11 08:33:31 2005 -+++ strstr.3 Fri Mar 11 08:35:28 2005 -@@ -41,7 +41,7 @@ +--- _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 @@ .Dt STRSTR 3 .Os .Sh NAME -.Nm strstr , strcasestr , strnstr -+.Nm strstr , strcasestr , strnstr , strcasestr_l ++.Nm strcasestr , ++.Nm strcasestr_l , ++.Nm strnstr , ++.Nm strstr .Nd locate a substring in a string .Sh LIBRARY .Lb libc -@@ -53,6 +53,9 @@ - .Fn strcasestr "const char *big" "const char *little" + .Sh SYNOPSIS + .In string.h .Ft char * - .Fn strnstr "const char *big" "const char *little" "size_t len" +-.Fn strstr "const char *big" "const char *little" ++.Fo strcasestr ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc + .Ft char * +-.Fn strcasestr "const char *big" "const char *little" ++.Fo strnstr ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fa "size_t n" ++.Fc + .Ft char * +-.Fn strnstr "const char *big" "const char *little" "size_t len" ++.Fo strstr ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fc ++.In string.h +.In xlocale.h +.Ft char * -+.Fn strcasestr_l "const char *big" "const char *little" "locale_t loc" ++.Fo strcasestr_l ++.Fa "const char *s1" ++.Fa "const char *s2" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn strstr -@@ -86,6 +89,14 @@ + function + locates the first occurrence of the null-terminated string +-.Fa little ++.Fa s2 + in the null-terminated string +-.Fa big . ++.Fa s1 . + .Pp + The + .Fn strcasestr +@@ -72,11 +93,11 @@ + .Fn strnstr + function + locates the first occurrence of the null-terminated string +-.Fa little ++.Fa s2 + in the string +-.Fa big , ++.Fa s1 , + where not more than +-.Fa len ++.Fa n + characters are searched. + Characters that appear after a + .Ql \e0 +@@ -86,20 +107,28 @@ function is a .Fx specific API, it should only be used when portability is not a concern. @@ -33,8 +83,27 @@ +for more information. .Sh RETURN VALUES If - .Fa little -@@ -138,7 +149,8 @@ +-.Fa little ++.Fa s2 + is an empty string, +-.Fa big ++.Fa s1 + is returned; + if +-.Fa little ++.Fa s2 + occurs nowhere in +-.Fa big , ++.Fa s1 , + .Dv NULL + is returned; + otherwise a pointer to the first character of the first occurrence of +-.Fa little ++.Fa s2 + is returned. + .Sh EXAMPLES + The following sets the pointer +@@ -138,7 +167,8 @@ .Xr strrchr 3 , .Xr strsep 3 , .Xr strspn 3 , diff --git a/string/FreeBSD/strtok.3.patch b/string/FreeBSD/strtok.3.patch new file mode 100644 index 0000000..c8ae652 --- /dev/null +++ b/string/FreeBSD/strtok.3.patch @@ -0,0 +1,21 @@ +--- _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 @@ + .Sh SYNOPSIS + .In string.h + .Ft char * +-.Fn strtok "char *str" "const char *sep" ++.Fo strtok ++.Fa "char *restrict str" ++.Fa "const char *restrict sep" ++.Fc + .Ft char * +-.Fn strtok_r "char *str" "const char *sep" "char **last" ++.Fo strtok_r ++.Fa "char *restrict str" ++.Fa "const char *restrict sep" ++.Fa "char **restrict lasts" ++.Fc + .Sh DESCRIPTION + .Bf -symbolic + This interface is obsoleted by diff --git a/string/FreeBSD/strxfrm.3.patch b/string/FreeBSD/strxfrm.3.patch index b28b55e..4675a6a 100644 --- a/string/FreeBSD/strxfrm.3.patch +++ b/string/FreeBSD/strxfrm.3.patch @@ -1,6 +1,6 @@ ---- strxfrm.3.orig Fri Mar 11 08:32:37 2005 -+++ strxfrm.3 Fri Mar 11 09:46:23 2005 -@@ -40,7 +40,8 @@ +--- _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 @@ .Dt STRXFRM 3 .Os .Sh NAME @@ -10,22 +10,57 @@ .Nd transform a string under locale .Sh LIBRARY .Lb libc -@@ -48,6 +49,9 @@ + .Sh SYNOPSIS .In string.h .Ft size_t - .Fn strxfrm "char * restrict dst" "const char * restrict src" "size_t n" +-.Fn strxfrm "char * restrict dst" "const char * restrict src" "size_t n" ++.Fo strxfrm ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fa "size_t n" ++.Fc ++.In string.h +.In xlocale.h +.Ft size_t -+.Fn strxfrm_l "char * restrict dst" "const char * restrict src" "size_t n" "locale_t loc" ++.Fo strxfrm_l ++.Fa "char *restrict s1" ++.Fa "const char *restrict s2" ++.Fa "size_t n" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn strxfrm -@@ -77,6 +81,14 @@ + function transforms a null-terminated string pointed to by +-.Fa src ++.Fa s2 + according to the current locale collation if any, + then copies the transformed string + into +-.Fa dst . ++.Fa s1 . + Not more than + .Fa n + characters are copied into +-.Fa dst , ++.Fa s1 , + including the terminating null character added. + If + .Fa n + is set to 0 + (it helps to determine an actual size needed + for transformation), +-.Fa dst ++.Fa s1 + is permitted to be a NULL pointer. + .Pp + Comparing two strings using +@@ -77,6 +91,14 @@ is equal to comparing two original strings with .Fn strcoll . +.Pp -+While the ++Although the +.Fn strxfrm +function uses the current locale, the +.Fn strxfrm_l @@ -35,7 +70,14 @@ .Sh RETURN VALUES Upon successful completion, .Fn strxfrm -@@ -91,7 +103,8 @@ +@@ -85,13 +107,14 @@ + If this value is + .Fa n + or more, the contents of +-.Fa dst ++.Fa s1 + are indeterminate. + .Sh SEE ALSO .Xr setlocale 3 , .Xr strcmp 3 , .Xr strcoll 3 , diff --git a/string/FreeBSD/strxfrm.c.patch b/string/FreeBSD/strxfrm.c.patch index 77753a2..221d31f 100644 --- a/string/FreeBSD/strxfrm.c.patch +++ b/string/FreeBSD/strxfrm.c.patch @@ -1,6 +1,6 @@ --- strxfrm.c.orig 2003-05-20 15:23:55.000000000 -0700 -+++ strxfrm.c 2005-02-17 15:06:28.000000000 -0800 -@@ -28,24 +28,28 @@ ++++ strxfrm.c 2005-04-02 17:59:53.000000000 -0800 +@@ -28,24 +28,59 @@ #include __FBSDID("$FreeBSD: src/lib/libc/string/strxfrm.c,v 1.15 2002/09/06 11:24:06 tjr Exp $"); @@ -8,43 +8,134 @@ + #include #include ++#include ++#include #include "collate.h" ++/* ++ * In the non-POSIX case, we transform each character into a string of ++ * characters representing the character's priority. Since char is usually ++ * signed, we are limited by 7 bits per byte. To avoid zero, we need to add ++ * XFRM_OFFSET, so we can't use a full 7 bits. For simplicity, we choose 6 ++ * bits per byte. We choose 4 bytes per character as a good compromise ++ * between maximum coverage and minimum size. This gives 24 bits, or 16M ++ * priorities. So we choose COLLATE_MAX_PRIORITY to be (2^24 - 1). This ++ * this can be increased if more is needed. ++ */ ++ ++#define XFRM_BYTES 4 ++#define XFRM_OFFSET ('0') /* make all printable characters */ ++#define XFRM_SHIFT 6 ++#define XFRM_MASK ((1 << XFRM_SHIFT) - 1) ++ ++static void ++xfrm(unsigned char *p, int pri) ++{ ++ ++ p[3] = (pri & XFRM_MASK) + XFRM_OFFSET; ++ pri >>= XFRM_SHIFT; ++ p[2] = (pri & XFRM_MASK) + XFRM_OFFSET; ++ pri >>= XFRM_SHIFT; ++ p[1] = (pri & XFRM_MASK) + XFRM_OFFSET; ++ pri >>= XFRM_SHIFT; ++ p[0] = (pri & XFRM_MASK) + XFRM_OFFSET; ++} ++ size_t -strxfrm(char * __restrict dest, const char * __restrict src, size_t len) +strxfrm_l(char * __restrict dest, const char * __restrict src, size_t len, + locale_t loc) { - int prim, sec, l; +- int prim, sec, l; size_t slen; - char *s, *ss; +- char *s, *ss; ++ wchar_t *wcs, *xf[2]; ++ int sverrno; -+ NORMALIZE_LOCALE(loc); - if (!*src) { +- if (!*src) { ++ if (!*src && dest) { if (len > 0) *dest = '\0'; return 0; } - if (__collate_load_error) { -+ if (loc->__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) -@@ -60,10 +64,10 @@ +@@ -58,26 +93,63 @@ + return slen; + } - slen = 0; - prim = sec = 0; +- slen = 0; +- prim = sec = 0; - ss = s = __collate_substitute(src); -+ ss = s = (char *)__collate_substitute_l((unsigned char *)src, loc); - while (*s) { - while (*s && !prim) { +- while (*s) { +- while (*s && !prim) { - __collate_lookup(s, &l, &prim, &sec); -+ __collate_lookup_l((unsigned char *)s, &l, &prim, &sec, loc); - s += l; +- s += l; ++ __collate_xfrm(wcs, xf, loc); ++ ++ slen = wcslen(xf[0]) * XFRM_BYTES; ++ if (xf[1]) ++ slen += (wcslen(xf[1]) + 1) * XFRM_BYTES; ++ if (len > 0) { ++ wchar_t *w = xf[0]; ++ int b = 0; ++ unsigned char buf[XFRM_BYTES]; ++ unsigned char *bp; ++ while (len > 1) { ++ if (!b) { ++ if (!*w) ++ break; ++ xfrm(bp = buf, *w++); ++ b = XFRM_BYTES; ++ } ++ *dest++ = *(char *)bp++; ++ b--; ++ len--; + } +- if (prim) { +- if (len > 1) { +- *dest++ = (char)prim; ++ if ((w = xf[1]) != NULL) { ++ xfrm(bp = buf, 0); ++ b = XFRM_BYTES; ++ while (len > 1) { ++ if (!b) ++ break; ++ *dest++ = *(char *)bp++; ++ b--; ++ len--; ++ } ++ b = 0; ++ while (len > 1) { ++ if (!b) { ++ if (!*w) ++ break; ++ xfrm(bp = buf, *w++); ++ b = XFRM_BYTES; ++ } ++ *dest++ = *(char *)bp++; ++ b--; + len--; + } +- slen++; +- prim = 0; } - if (prim) { -@@ -81,3 +85,9 @@ +- } +- free(ss); +- if (len > 0) +- *dest = '\0'; ++ *dest = 0; ++ } ++ sverrno = errno; ++ free(wcs); ++ free(xf[0]); ++ free(xf[1]); ++ errno = sverrno; return slen; } diff --git a/string/FreeBSD/swab.3.patch b/string/FreeBSD/swab.3.patch new file mode 100644 index 0000000..8c915b3 --- /dev/null +++ b/string/FreeBSD/swab.3.patch @@ -0,0 +1,57 @@ +--- 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 + .Sh SYNOPSIS +-.In string.h ++.In unistd.h + .Ft void +-.Fn swab "const void * restrict src" "void * restrict dst" "size_t len" ++.Fo swab ++.Fa "const void *restrict src" ++.Fa "void *restrict dest" ++.Fa "ssize_t nbytes" ++.Fc + .Sh DESCRIPTION + The function + .Fn swab + copies +-.Fa len ++.Fa nbytes + bytes from the location referenced by + .Fa src + to the location referenced by +-.Fa dst , ++.Fa dest , + swapping adjacent bytes. + .Pp + The argument +-.Fa len ++.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 ++.Fa nbytes ++has changed. + .Sh SEE ALSO + .Xr bzero 3 , +-.Xr memset 3 ++.Xr memset 3 , ++.Xr compat 5 + .Sh HISTORY + A + .Fn swab diff --git a/string/FreeBSD/wcscoll.3.patch b/string/FreeBSD/wcscoll.3.patch index dfd866d..1fca854 100644 --- a/string/FreeBSD/wcscoll.3.patch +++ b/string/FreeBSD/wcscoll.3.patch @@ -1,6 +1,6 @@ ---- wcscoll.3.orig Fri Mar 11 08:27:51 2005 -+++ wcscoll.3 Fri Mar 11 08:29:43 2005 -@@ -41,7 +41,8 @@ +--- _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 @@ .Dt WCSCOLL 3 .Os .Sh NAME @@ -10,22 +10,41 @@ .Nd compare wide strings according to current collation .Sh LIBRARY .Lb libc -@@ -49,6 +50,9 @@ + .Sh SYNOPSIS .In wchar.h .Ft int - .Fn wcscoll "const wchar_t *s1" "const wchar_t *s2" +-.Fn wcscoll "const wchar_t *s1" "const wchar_t *s2" ++.Fo wcscoll ++.Fa "const wchar_t *ws1" ++.Fa "const wchar_t *ws2" ++.Fc ++.In wchar.h +.In xlocale.h +.Ft int -+.Fn wcscoll_l "const wchar_t *s1" "const wchar_t *s2" "locale_t loc" ++.Fo wcscoll_l ++.Fa "const wchar_t *ws1" ++.Fa "const wchar_t *ws2" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn wcscoll -@@ -63,6 +67,14 @@ + function compares the null-terminated strings +-.Fa s1 ++.Fa ws1 + and +-.Fa s2 +-according to the current locale collation order. ++.Fa ws2 , ++according to the current locale's collation order. + In the + .Dq Li C + locale, .Fn wcscoll is equivalent to .Fn wcscmp . +.Pp -+While the ++Although the +.Fn wcscoll +function uses the current locale, the +.Fn wcscoll_l @@ -35,7 +54,18 @@ .Sh RETURN VALUES The .Fn wcscoll -@@ -95,7 +107,8 @@ + function + returns an integer greater than, equal to, or less than 0, + if +-.Fa s1 ++.Fa ws1 + is greater than, equal to, or less than +-.Fa s2 . ++.Fa ws2 . + .Pp + No return value is reserved to indicate errors; + callers should set +@@ -95,7 +115,8 @@ .Xr setlocale 3 , .Xr strcoll 3 , .Xr wcscmp 3 , diff --git a/string/FreeBSD/wcscoll.c.patch b/string/FreeBSD/wcscoll.c.patch index 36d6102..5f0d2e9 100644 --- a/string/FreeBSD/wcscoll.c.patch +++ b/string/FreeBSD/wcscoll.c.patch @@ -1,6 +1,6 @@ --- wcscoll.c.orig 2004-11-25 11:38:47.000000000 -0800 -+++ wcscoll.c 2005-02-18 18:17:11.000000000 -0800 -@@ -27,13 +27,15 @@ ++++ wcscoll.c 2005-04-11 15:44:35.000000000 -0700 +@@ -27,72 +27,222 @@ #include __FBSDID("$FreeBSD: src/lib/libc/string/wcscoll.c,v 1.3 2004/04/07 09:47:56 tjr Exp $"); @@ -13,72 +13,259 @@ #include "collate.h" -static char *__mbsdup(const wchar_t *); -+static char *__mbsdup(const wchar_t *, locale_t); ++#define NOTFORWARD (DIRECTIVE_BACKWARD | DIRECTIVE_POSITION) - /* - * Placeholder implementation of wcscoll(). Attempts to use the single-byte -@@ -41,12 +43,13 @@ - * with extended character sets. - */ +-/* +- * Placeholder implementation of wcscoll(). Attempts to use the single-byte +- * collation ordering where possible, and falls back on wcscmp() in locales +- * with extended character sets. +- */ int -wcscoll(const wchar_t *ws1, const wchar_t *ws2) +wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t loc) { - char *mbs1, *mbs2; - int diff, sverrno; +- char *mbs1, *mbs2; +- int diff, sverrno; ++ int sverrno; ++ int len, len2, prim, prim2, sec, sec2, ret, ret2; ++ const wchar_t *t, *t2; ++ wchar_t *tt = NULL, *tt2 = NULL; ++ wchar_t *tr = NULL, *tr2 = NULL; ++ wchar_t w, w2; ++ struct __collate_st_info *info; - if (__collate_load_error || MB_CUR_MAX > 1) + NORMALIZE_LOCALE(loc); -+ if (loc->__collate_load_error || MB_CUR_MAX_L(loc) > 1) ++ if (loc->__collate_load_error) /* - * Locale has no special collating order, could not be - * loaded, or has an extended character set; do a fast binary -@@ -54,7 +57,7 @@ +- * Locale has no special collating order, could not be +- * loaded, or has an extended character set; do a fast binary +- * comparison. ++ * Locale has no special collating order or could not be ++ * loaded, do a fast binary comparison. */ return (wcscmp(ws1, ws2)); - if ((mbs1 = __mbsdup(ws1)) == NULL || (mbs2 = __mbsdup(ws2)) == NULL) { -+ if ((mbs1 = __mbsdup(ws1, loc)) == NULL || (mbs2 = __mbsdup(ws2, loc)) == NULL) { - /* - * Out of memory or illegal wide chars; fall back to wcscmp() - * but leave errno indicating the error. Callers that don't -@@ -67,7 +70,7 @@ - return (wcscmp(ws1, ws2)); +- /* +- * Out of memory or illegal wide chars; fall back to wcscmp() +- * but leave errno indicating the error. Callers that don't +- * check for error will get a reasonable but often slightly +- * incorrect result. +- */ +- sverrno = errno; +- free(mbs1); +- errno = sverrno; +- return (wcscmp(ws1, ws2)); ++ info = &loc->__lc_collate->__info; ++ len = len2 = 1; ++ ret = ret2 = 0; ++ ++ if ((info->directive[0] & NOTFORWARD) || ++ (info->directive[1] & NOTFORWARD) || ++ (!(info->flags && COLLATE_SUBST_DUP) && ++ (info->subst_count[0] > 0 || info->subst_count[1] > 0))) { ++ int direc, pass; ++ for(pass = 0; pass < info->directive_count; pass++) { ++ direc = info->directive[pass]; ++ if (pass == 0 || !(info->flags & COLLATE_SUBST_DUP)) { ++ free(tt); ++ tt = __collate_substitute(ws1, pass, loc); ++ free(tt2); ++ tt2 = tt ? __collate_substitute(ws2, pass, loc) : NULL; ++ } ++ if (direc & DIRECTIVE_BACKWARD) { ++ wchar_t *bp, *fp, c; ++ tr = __collate_wcsdup(tt ? tt : ws1); ++ bp = tr; ++ fp = tr + wcslen(tr) - 1; ++ while(bp < fp) { ++ c = *bp; ++ *bp++ = *fp; ++ *fp-- = c; ++ } ++ tr2 = __collate_wcsdup(tt2 ? tt2 : ws2); ++ bp = tr2; ++ fp = tr2 + wcslen(tr2) - 1; ++ while(bp < fp) { ++ c = *bp; ++ *bp++ = *fp; ++ *fp-- = c; ++ } ++ t = (const wchar_t *)tr; ++ t2 = (const wchar_t *)tr2; ++ } else if (tt) { ++ t = (const wchar_t *)tt; ++ t2 = (const wchar_t *)tt2; ++ } else { ++ t = (const wchar_t *)ws1; ++ t2 = (const wchar_t *)ws2; ++ } ++ if(direc & DIRECTIVE_POSITION) { ++ while(*t && *t2) { ++ prim = prim2 = 0; ++ __collate_lookup_which(t, &len, &prim, pass, loc); ++ if (prim <= 0) { ++ if (prim < 0) { ++ errno = EINVAL; ++ ret = -1; ++ goto end; ++ } ++ prim = COLLATE_MAX_PRIORITY; ++ } ++ __collate_lookup_which(t2, &len2, &prim2, pass, loc); ++ if (prim2 <= 0) { ++ if (prim2 < 0) { ++ errno = EINVAL; ++ ret = -1; ++ goto end; ++ } ++ prim2 = COLLATE_MAX_PRIORITY; ++ } ++ if(prim != prim2) { ++ ret = prim - prim2; ++ goto end; ++ } ++ t += len; ++ t2 += len2; ++ } ++ } else { ++ while(*t && *t2) { ++ prim = prim2 = 0; ++ while(*t) { ++ __collate_lookup_which(t, &len, &prim, pass, loc); ++ if(prim > 0) ++ break; ++ if (prim < 0) { ++ errno = EINVAL; ++ ret = -1; ++ goto end; ++ } ++ t += len; ++ } ++ while(*t2) { ++ __collate_lookup_which(t2, &len2, &prim2, pass, loc); ++ if(prim2 > 0) ++ break; ++ if (prim2 < 0) { ++ errno = EINVAL; ++ ret = -1; ++ goto end; ++ } ++ t2 += len2; ++ } ++ if(!prim || !prim2) ++ break; ++ if(prim != prim2) { ++ ret = prim - prim2; ++ goto end; ++ } ++ t += len; ++ t2 += len2; ++ } ++ } ++ if(!*t) { ++ if(*t2) { ++ ret = -(int)*t2; ++ goto end; ++ } ++ } else { ++ ret = *t; ++ goto end; ++ } ++ } ++ ret = 0; ++ goto end; } - diff = strcoll(mbs1, mbs2); -+ diff = strcoll_l(mbs1, mbs2, loc); ++ /* optimized common case: order_start forward;forward and duplicate ++ * (or no) substitute tables */ ++ tt = __collate_substitute(ws1, 0, loc); ++ if (tt == NULL) { ++ tt2 = NULL; ++ t = (const wchar_t *)ws1; ++ t2 = (const wchar_t *)ws2; ++ } else { ++ tt2 = __collate_substitute(ws2, 0, loc); ++ t = (const wchar_t *)tt; ++ t2 = (const wchar_t *)tt2; ++ } ++ while(*t && *t2) { ++ prim = prim2 = 0; ++ while(*t) { ++ __collate_lookup_l(t, &len, &prim, &sec, loc); ++ if (prim > 0) ++ break; ++ if (prim < 0) { ++ errno = EINVAL; ++ ret = -1; ++ goto end; ++ } ++ t += len; ++ } ++ while(*t2) { ++ __collate_lookup_l(t2, &len2, &prim2, &sec2, loc); ++ if (prim2 > 0) ++ break; ++ if (prim2 < 0) { ++ errno = EINVAL; ++ ret = -1; ++ goto end; ++ } ++ t2 += len2; ++ } ++ if(!prim || !prim2) ++ break; ++ if(prim != prim2) { ++ ret = prim - prim2; ++ goto end; ++ } ++ if(!ret2) ++ ret2 = sec - sec2; ++ t += len; ++ t2 += len2; ++ } ++ if(!*t && *t2) ++ ret = -(int)*t2; ++ else if(*t && !*t2) ++ ret = *t; ++ else if(!*t && !*t2) ++ ret = ret2; ++ end: sverrno = errno; - free(mbs1); - free(mbs2); -@@ -76,8 +79,14 @@ - return (diff); +- free(mbs1); +- free(mbs2); ++ free(tt); ++ free(tt2); ++ free(tr); ++ free(tr2); + errno = sverrno; + +- return (diff); ++ return ret; } +-static char * +-__mbsdup(const wchar_t *ws) +int +wcscoll(const wchar_t *ws1, const wchar_t *ws2) -+{ -+ return wcscoll_l(ws1, ws2, __current_locale()); -+} -+ - static char * --__mbsdup(const wchar_t *ws) -+__mbsdup(const wchar_t *ws, locale_t loc) { - static const mbstate_t initial; - mbstate_t st; -@@ -87,12 +96,12 @@ - - wcp = ws; - st = initial; +- static const mbstate_t initial; +- mbstate_t st; +- const wchar_t *wcp; +- size_t len; +- char *mbs; +- +- wcp = ws; +- st = initial; - if ((len = wcsrtombs(NULL, &wcp, 0, &st)) == (size_t)-1) -+ if ((len = wcsrtombs_l(NULL, &wcp, 0, &st, loc)) == (size_t)-1) - return (NULL); - if ((mbs = malloc(len + 1)) == NULL) - return (NULL); - st = initial; +- return (NULL); +- if ((mbs = malloc(len + 1)) == NULL) +- return (NULL); +- st = initial; - wcsrtombs(mbs, &ws, len + 1, &st); -+ wcsrtombs_l(mbs, &ws, len + 1, &st, loc); - - return (mbs); +- +- return (mbs); ++ return wcscoll_l(ws1, ws2, __current_locale()); } diff --git a/string/FreeBSD/wcstok.3.patch b/string/FreeBSD/wcstok.3.patch new file mode 100644 index 0000000..233597e --- /dev/null +++ b/string/FreeBSD/wcstok.3.patch @@ -0,0 +1,62 @@ +--- _SB/Libc/string/FreeBSD/wcstok.3 2003-05-20 15:23:56.000000000 -0700 ++++ _SB/Libc/string/FreeBSD/wcstok.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -60,28 +60,32 @@ + .Sh SYNOPSIS + .In wchar.h + .Ft wchar_t * +-.Fn wcstok "wchar_t * restrict str" "const wchar_t * restrict sep" "wchar_t ** restrict last" ++.Fo wcstok ++.Fa "wchar_t *restrict ws1" ++.Fa "const wchar_t *restrict ws2" ++.Fa "wchar_t **restrict ptr" ++.Fc + .Sh DESCRIPTION + The + .Fn wcstok + function + is used to isolate sequential tokens in a null-terminated wide character + string, +-.Fa str . ++.Fa ws1 . + These tokens are separated in the string by at least one of the + characters in +-.Fa sep . ++.Fa ws2 . + The first time that + .Fn wcstok + is called, +-.Fa str ++.Fa ws1 + should be specified; subsequent calls, wishing to obtain further tokens + from the same string, should pass a null pointer instead. + The separator string, +-.Fa sep , ++.Fa ws2 , + must be supplied each time, and may change between calls. +-The context pointer +-.Fa last ++The context pointer, ++.Fa ptr , + must be provided on each call. + .Pp + The +@@ -99,8 +103,8 @@ + .Sh EXAMPLES + The following code fragment splits a wide character string on + .Tn ASCII +-space, tab and newline characters and writes the tokens to +-standard output: ++space, tab, and newline characters, ++writing the resulting tokens to standard output: + .Bd -literal -offset indent + const wchar_t *seps = L" \et\en"; + wchar_t *last, *tok, text[] = L" \enone\ettwo\et\etthree \en"; +@@ -114,7 +118,7 @@ + .Fn wcstok + omit the + context pointer argument, +-.Fa last , ++.Fa ptr , + and maintain state across calls in a static variable like + .Fn strtok + does. diff --git a/string/FreeBSD/wcswidth.3.patch b/string/FreeBSD/wcswidth.3.patch index 847ecb8..e679795 100644 --- a/string/FreeBSD/wcswidth.3.patch +++ b/string/FreeBSD/wcswidth.3.patch @@ -1,6 +1,6 @@ ---- wcswidth.3.orig Fri Mar 11 08:30:37 2005 -+++ wcswidth.3 Fri Mar 11 08:31:35 2005 -@@ -28,7 +28,8 @@ +--- _SB/Libc/string/FreeBSD/wcswidth.3 2003-05-20 15:23:56.000000000 -0700 ++++ _SB/Libc/string/FreeBSD/wcswidth.3.edit 2006-06-28 16:55:53.000000000 -0700 +@@ -28,14 +28,26 @@ .Dt WCSWIDTH 3 .Os .Sh NAME @@ -10,22 +10,31 @@ .Nd "number of column positions in wide-character string" .Sh LIBRARY .Lb libc -@@ -36,6 +37,9 @@ + .Sh SYNOPSIS .In wchar.h .Ft int - .Fn wcswidth "const wchar_t *pwcs" "size_t n" +-.Fn wcswidth "const wchar_t *pwcs" "size_t n" ++.Fo wcswidth ++.Fa "const wchar_t *pwcs" ++.Fa "size_t n" ++.Fc ++.In wchar.h +.In xlocale.h +.Ft int -+.Fn wcswidth_l "const wchar_t *pwcs" "size_t n" "locale_t loc" ++.Fo wcswidth_l ++.Fa "const wchar_t *pwcs" ++.Fa "size_t n" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn wcswidth -@@ -44,6 +48,14 @@ +@@ -44,17 +56,26 @@ characters of .Fa pwcs , or until a null wide character (L'\e0') is encountered. +.Pp -+While the ++Although the +.Fn wcswidth +function uses the current locale, the +.Fn wcswidth_l @@ -35,8 +44,13 @@ .Sh RETURN VALUES The .Fn wcswidth -@@ -54,7 +66,8 @@ - otherwise it returns the number of column positions occupied. + function returns 0 if + .Fa pwcs + is an empty string (L""), +-\-1 if a non-printing wide character is encountered, +-otherwise it returns the number of column positions occupied. ++\-1 if a non-printing wide character is encountered; ++otherwise, it returns the number of column positions occupied. .Sh SEE ALSO .Xr iswprint 3 , -.Xr wcwidth 3 diff --git a/string/FreeBSD/wcsxfrm.3.patch b/string/FreeBSD/wcsxfrm.3.patch index cb36869..781420c 100644 --- a/string/FreeBSD/wcsxfrm.3.patch +++ b/string/FreeBSD/wcsxfrm.3.patch @@ -1,6 +1,6 @@ ---- wcsxfrm.3.orig Fri Mar 11 08:31:43 2005 -+++ wcsxfrm.3 Fri Mar 11 09:44:27 2005 -@@ -41,7 +41,8 @@ +--- _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 @@ .Dt WCSXFRM 3 .Os .Sh NAME @@ -10,22 +10,60 @@ .Nd transform a wide string under locale .Sh LIBRARY .Lb libc -@@ -49,6 +50,9 @@ + .Sh SYNOPSIS .In wchar.h .Ft size_t - .Fn wcsxfrm "wchar_t * restrict dst" "const wchar_t * restrict src" "size_t n" +-.Fn wcsxfrm "wchar_t * restrict dst" "const wchar_t * restrict src" "size_t n" ++.Fo wcsxfrm ++.Fa "wchar_t *restrict ws1" ++.Fa "const wchar_t *restrict ws2" ++.Fa "size_t n" ++.Fc ++.In wchar.h +.In xlocale.h +.Ft size_t -+.Fn wcsxfrm_l "wchar_t * restrict dst" "const wchar_t * restrict src" "size_t n" "locale_t loc" ++.Fo wcsxfrm_l ++.Fa "wchar_t *restrict ws1" ++.Fa "const wchar_t *restrict ws2" ++.Fa "size_t n" ++.Fa "locale_t loc" ++.Fc .Sh DESCRIPTION The .Fn wcsxfrm -@@ -80,6 +84,14 @@ + function transforms a null-terminated wide character string pointed to by +-.Fa src +-according to the current locale collation order +-then copies the transformed string +-into +-.Fa dst . ++.Fa ws2 , ++according to the current locale's collation order, ++then copies the transformed string into ++.Fa ws1 . + No more than + .Fa n + wide characters are copied into +-.Fa dst , +-including the terminating null character added. ++.Fa ws1 , ++including the terminating null character. + If + .Fa n + is set to 0 + (it helps to determine an actual size needed + for transformation), +-.Fa dst ++.Fa ws1 + is permitted to be a + .Dv NULL + pointer. +@@ -80,6 +93,14 @@ is equivalent to comparing two original strings with .Fn wcscoll . +.Pp -+While the ++Although the +.Fn wcsxfrm +function uses the current locale, the +.Fn wcsxfrm_l @@ -35,7 +73,14 @@ .Sh RETURN VALUES Upon successful completion, .Fn wcsxfrm -@@ -94,7 +106,8 @@ +@@ -88,13 +109,14 @@ + If this value is + .Fa n + or more, the contents of +-.Fa dst ++.Fa ws1 + are indeterminate. + .Sh SEE ALSO .Xr setlocale 3 , .Xr strxfrm 3 , .Xr wcscmp 3 , @@ -45,3 +90,12 @@ .Sh STANDARDS The .Fn wcsxfrm +@@ -120,7 +142,7 @@ + .Fn wcscoll ; + .Fn wcsxfrm + only stores information about primary collation weights into +-.Fa dst , ++.Fa ws1 , + whereas + .Fn wcscoll + compares characters using both primary and secondary weights. diff --git a/string/FreeBSD/wcsxfrm.c.patch b/string/FreeBSD/wcsxfrm.c.patch index eafc39d..a1a9e0c 100644 --- a/string/FreeBSD/wcsxfrm.c.patch +++ b/string/FreeBSD/wcsxfrm.c.patch @@ -1,6 +1,6 @@ ---- wcsxfrm.c.orig Thu Nov 25 11:38:47 2004 -+++ wcsxfrm.c Fri Feb 18 15:01:58 2005 -@@ -31,31 +31,35 @@ +--- wcsxfrm.c.orig 2004-11-25 11:38:47.000000000 -0800 ++++ wcsxfrm.c 2005-03-30 15:06:45.000000000 -0800 +@@ -31,23 +31,23 @@ #endif __FBSDID("$FreeBSD: src/lib/libc/string/wcsxfrm.c,v 1.3 2004/04/07 09:47:56 tjr Exp $"); @@ -9,81 +9,115 @@ #include #include #include ++#include #include "collate.h" -static char *__mbsdup(const wchar_t *); -+static char *__mbsdup(const wchar_t *, locale_t); ++#define WCS_XFRM_OFFSET 1 - /* - * Placeholder wcsxfrm() implementation. See wcscoll.c for a description of - * the logic used. - */ +-/* +- * Placeholder wcsxfrm() implementation. See wcscoll.c for a description of +- * the logic used. +- */ size_t -wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len) +wcsxfrm_l(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len, + locale_t loc) { - int prim, sec, l; +- int prim, sec, l; size_t slen; - char *mbsrc, *s, *ss; +- char *mbsrc, *s, *ss; ++ wchar_t *xf[2]; ++ int sverrno; -+ NORMALIZE_LOCALE(loc); if (*src == L'\0') { if (len != 0) - *dest = L'\0'; +@@ -55,7 +55,8 @@ return (0); } - if (__collate_load_error || MB_CUR_MAX > 1) { -+ if (loc->__collate_load_error || MB_CUR_MAX_L(loc) > 1) { ++ NORMALIZE_LOCALE(loc); ++ if (loc->__collate_load_error) { slen = wcslen(src); if (len > 0) { if (slen < len) -@@ -68,13 +72,13 @@ +@@ -68,49 +69,41 @@ return (slen); } - mbsrc = __mbsdup(src); -+ mbsrc = __mbsdup(src, loc); - slen = 0; - prim = sec = 0; +- slen = 0; +- prim = sec = 0; - ss = s = __collate_substitute(mbsrc); -+ ss = s = (char *)__collate_substitute_l((unsigned char *)mbsrc, loc); - while (*s != '\0') { - while (*s != '\0' && prim == 0) { +- while (*s != '\0') { +- while (*s != '\0' && prim == 0) { - __collate_lookup(s, &l, &prim, &sec); -+ __collate_lookup_l((unsigned char *)s, &l, &prim, &sec, loc); - s += l; +- s += l; ++ __collate_xfrm(src, xf, loc); ++ ++ slen = wcslen(xf[0]); ++ if (xf[1]) ++ slen += wcslen(xf[1]) + 1; ++ if (len > 0) { ++ wchar_t *w = xf[0]; ++ while (len > 1) { ++ if (!*w) ++ break; ++ *dest++ = *w++ + WCS_XFRM_OFFSET; ++ len--; } - if (prim != 0) { -@@ -94,8 +98,14 @@ +- if (prim != 0) { +- if (len > 1) { +- *dest++ = (wchar_t)prim; ++ if ((w = xf[1]) != NULL) { ++ if (len > 1) ++ *dest++ = WCS_XFRM_OFFSET; ++ while (len > 1) { ++ if (!*w) ++ break; ++ *dest++ = *w++ + WCS_XFRM_OFFSET; + len--; + } +- slen++; +- prim = 0; + } +- } +- free(ss); +- free(mbsrc); +- if (len != 0) +- *dest = L'\0'; +- ++ *dest = 0; ++ } ++ sverrno = errno; ++ free(xf[0]); ++ free(xf[1]); ++ errno = sverrno; ++ return (slen); } +-static char * +-__mbsdup(const wchar_t *ws) +size_t +wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len) -+{ -+ return wcsxfrm_l(dest, src, len, __current_locale()); -+} -+ - static char * --__mbsdup(const wchar_t *ws) -+__mbsdup(const wchar_t *ws, locale_t loc) { - static const mbstate_t initial; - mbstate_t st; -@@ -105,12 +115,12 @@ - - wcp = ws; - st = initial; +- static const mbstate_t initial; +- mbstate_t st; +- const wchar_t *wcp; +- size_t len; +- char *mbs; +- +- wcp = ws; +- st = initial; - if ((len = wcsrtombs(NULL, &wcp, 0, &st)) == (size_t)-1) -+ if ((len = wcsrtombs_l(NULL, &wcp, 0, &st, loc)) == (size_t)-1) - return (NULL); - if ((mbs = malloc(len + 1)) == NULL) - return (NULL); - st = initial; +- return (NULL); +- if ((mbs = malloc(len + 1)) == NULL) +- return (NULL); +- st = initial; - wcsrtombs(mbs, &ws, len + 1, &st); -+ wcsrtombs_l(mbs, &ws, len + 1, &st, loc); - - return (mbs); +- +- return (mbs); ++ return wcsxfrm_l(dest, src, len, __current_locale()); } diff --git a/string/FreeBSD/wmemchr.3.patch b/string/FreeBSD/wmemchr.3.patch new file mode 100644 index 0000000..40fc3e5 --- /dev/null +++ b/string/FreeBSD/wmemchr.3.patch @@ -0,0 +1,183 @@ +--- _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 @@ + .Dt WMEMCHR 3 + .Os + .Sh NAME +-.Nm wmemchr , +-.Nm wmemcmp , +-.Nm wmemcpy , +-.Nm wmemmove , +-.Nm wmemset , + .Nm wcscat , + .Nm wcschr , + .Nm wcscmp , +@@ -62,57 +57,131 @@ + .Nm wcspbrk , + .Nm wcsrchr , + .Nm wcsspn , +-.Nm wcsstr ++.Nm wcsstr , ++.Nm wmemchr , ++.Nm wmemcmp , ++.Nm wmemcpy , ++.Nm wmemmove , ++.Nm wmemset + .Nd wide character string manipulation operations + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS + .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 +-.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" +-.Ft wchar_t * +-.Fn wmemmove "wchar_t *s1" "const wchar_t *s2" "size_t n" +-.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 ++.Ft wchar_t * ++.Fo wmemchr ++.Fa "const wchar_t *ws" ++.Fa "wchar_t wc" ++.Fa "size_t n" ++.Fc ++.Ft int ++.Fo wmemcmp ++.Fa "const wchar_t *ws1" ++.Fa "const wchar_t *ws2" ++.Fa "size_t n" ++.Fc ++.Ft wchar_t * ++.Fo wmemcpy ++.Fa "wchar_t *restrict ws1" ++.Fa "const wchar_t *restrict ws2" ++.Fa "size_t n" ++.Fc ++.Ft wchar_t * ++.Fo wmemmove ++.Fa "wchar_t *ws1" ++.Fa "const wchar_t *ws2" ++.Fa "size_t n" ++.Fc ++.Ft wchar_t * ++.Fo wmemset ++.Fa "wchar_t *ws" ++.Fa "wchar_t wc" ++.Fa "size_t n" ++.Fc + .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 , diff --git a/string/Makefile.inc b/string/Makefile.inc index 3f8bc05..14ce753 100644 --- a/string/Makefile.inc +++ b/string/Makefile.inc @@ -1,10 +1,12 @@ # @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # $FreeBSD: src/lib/libc/string/Makefile.inc,v 1.32 2002/11/18 09:50:56 ru Exp $ +.ifnmake autopatch # machine-dependent string sources .if exists(${.CURDIR}/${MACHINE_ARCH}/string/Makefile.inc) .include "${.CURDIR}/${MACHINE_ARCH}/string/Makefile.inc" .endif +.endif # !autopatch .PATH: ${.CURDIR}/string @@ -12,7 +14,7 @@ CFLAGS+= -I${.CURDIR}/locale .include "Makefile.fbsd_begin" # machine-independent string sources -FBSDMISRCS+=bcmp.c ffs.c index.c memccpy.c memchr.c memcmp.c \ +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 \ @@ -26,6 +28,12 @@ FBSDMISRCS+=bcmp.c ffs.c index.c memccpy.c memchr.c memcmp.c \ wmemcpy.c wmemmove.c wmemset.c .include "Makefile.fbsd_end" +LEGACYSRCS+= strerror.c + +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +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 \ @@ -36,33 +44,68 @@ FBSDMAN3= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \ wcswidth.3 wcsxfrm.3 wmemchr.3 .include "Makefile.fbsd_end" -MLINKS+=strcasecmp.3 strncasecmp.3 -MLINKS+=strcasecmp.3 strcasecmp_l.3 -MLINKS+=strcasecmp.3 strncasecmp_l.3 -MLINKS+=strcat.3 strncat.3 -MLINKS+=strcmp.3 strncmp.3 -MLINKS+=strcoll.3 strcoll_l.3 -MLINKS+=strcpy.3 stpcpy.3 -MLINKS+=strcpy.3 strncpy.3 -MLINKS+=strerror.3 perror.3 strerror.3 sys_errlist.3 strerror.3 sys_nerr.3 -MLINKS+=strerror.3 strerror_r.3 -MLINKS+=strlcpy.3 strlcat.3 -MLINKS+=strtok.3 strtok_r.3 -MLINKS+=strstr.3 strcasestr.3 -MLINKS+=strstr.3 strnstr.3 -MLINKS+=strstr.3 strcasestr_l.3 -MLINKS+=strxfrm.3 strxfrm_l.3 -MLINKS+=wcscoll.3 wcscoll_l.3 -MLINKS+=wcswidth.3 wcswidth_l.3 -MLINKS+=wcsxfrm.3 wcsxfrm_l.3 -MLINKS+=wmemchr.3 wmemcmp.3 wmemchr.3 wmemcpy.3 \ - wmemchr.3 wmemmove.3 wmemchr.3 wmemset.3 \ - wmemchr.3 wcscat.3 wmemchr.3 wcschr.3 \ - wmemchr.3 wcscmp.3 wmemchr.3 wcscpy.3 \ - wmemchr.3 wcscspn.3 wmemchr.3 wcslcat.3 \ - wmemchr.3 wcslcpy.3 wmemchr.3 wcslen.3 \ - wmemchr.3 wcsncat.3 wmemchr.3 wcsncmp.3 \ - wmemchr.3 wcsncpy.3 wmemchr.3 wcspbrk.3 \ - wmemchr.3 wcsrchr.3 wmemchr.3 wcsspn.3 \ - wmemchr.3 wcsstr.3 +MLINKS+= ffs.3 ffsl.3 \ + ffs.3 fls.3 \ + ffs.3 flsl.3 + +MLINKS+= strcasecmp.3 strcasecmp_l.3 \ + strcasecmp.3 strncasecmp.3 \ + strcasecmp.3 strncasecmp_l.3 + +MLINKS+= strcat.3 strncat.3 + +MLINKS+= strcmp.3 strncmp.3 + +MLINKS+= strcoll.3 strcoll_l.3 + +MLINKS+= strcpy.3 stpcpy.3 \ + strcpy.3 strncpy.3 + +MLINKS+= strerror.3 perror.3 \ + strerror.3 strerror_r.3 \ + strerror.3 sys_errlist.3 \ + strerror.3 sys_nerr.3 + +MLINKS+= strlcpy.3 strlcat.3 + +MLINKS+= strtok.3 strtok_r.3 + +MLINKS+= strstr.3 strcasestr.3 \ + strstr.3 strcasestr_l.3 \ + strstr.3 strnstr.3 + +MLINKS+= strxfrm.3 strxfrm_l.3 + +MLINKS+= wcscoll.3 wcscoll_l.3 + +MLINKS+= wcswidth.3 wcswidth_l.3 + +MLINKS+= wcsxfrm.3 wcsxfrm_l.3 + +MLINKS+= wmemchr.3 wmemcmp.3 \ + wmemchr.3 wmemcpy.3 \ + wmemchr.3 wmemmove.3 \ + wmemchr.3 wmemset.3 \ + wmemchr.3 wcscat.3 \ + wmemchr.3 wcschr.3 \ + wmemchr.3 wcscmp.3 \ + wmemchr.3 wcscpy.3 \ + wmemchr.3 wcscspn.3 \ + wmemchr.3 wcslcat.3 \ + wmemchr.3 wcslcpy.3 \ + wmemchr.3 wcslen.3 \ + wmemchr.3 wcsncat.3 \ + wmemchr.3 wcsncmp.3 \ + wmemchr.3 wcsncpy.3 \ + wmemchr.3 wcspbrk.3 \ + wmemchr.3 wcsrchr.3 \ + wmemchr.3 wcsspn.3 \ + wmemchr.3 wcsstr.3 + +MAN3+= memset_pattern.3 + +MLINKS+= memset_pattern.3 memset_pattern4.3 \ + memset_pattern.3 memset_pattern8.3 \ + memset_pattern.3 memset_pattern16.3 + .endif diff --git a/string/bcmp-fbsd.c b/string/bcmp-fbsd.c new file mode 100644 index 0000000..f5227df --- /dev/null +++ b/string/bcmp-fbsd.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1987, 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[] = "@(#)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 $"); + +#include + +/* + * bcmp -- vax cmpc3 instruction + */ +int +bcmp(const void *b1, const void *b2, size_t length) +{ + char *p1, *p2; + + if (length == 0) + return (0); + p1 = (char *)b1; + p2 = (char *)b2; + do + if (*p1++ != *p2++) + break; + while (--length); + return (length); +} diff --git a/string/bcmp.3 b/string/bcmp.3 new file mode 100644 index 0000000..e3cc973 --- /dev/null +++ b/string/bcmp.3 @@ -0,0 +1,81 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt BCMP 3 +.Os +.Sh NAME +.Nm bcmp +.Nd compare byte string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In strings.h +.Ft int +.Fn bcmp "const void *s1" "const void *s2" "size_t n" +.Sh DESCRIPTION +The +.Fn bcmp +function +compares byte string +.Fa s1 +against byte string +.Fa s2 , +returning zero if they are identical, non-zero otherwise. +Both strings are assumed to be +.Fa n +bytes long. +Zero-length strings are always identical. +.Pp +The strings may overlap. +.Sh SEE ALSO +.Xr memcmp 3 , +.Xr strcasecmp 3 , +.Xr strcmp 3 , +.Xr strcoll 3 , +.Xr strxfrm 3 +.Sh HISTORY +A +.Fn bcmp +function first appeared in +.Bx 4.2 . +Its prototype existed previously in +.In string.h +before it was moved to +.In strings.h +for +.St -p1003.1-2001 +compliance. diff --git a/string/bcopy.3 b/string/bcopy.3 new file mode 100644 index 0000000..129e753 --- /dev/null +++ b/string/bcopy.3 @@ -0,0 +1,81 @@ +.\" 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. +.\" +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt BCOPY 3 +.Os +.Sh NAME +.Nm bcopy +.Nd copy byte string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In strings.h +.Ft void +.Fn bcopy "const void *s1" "void *s2" "size_t n" +.Sh DESCRIPTION +The +.Fn bcopy +function +copies +.Fa n +bytes from string +.Fa s1 +to string +.Fa s2 . +The two strings may overlap. +If +.Fa n +is zero, no bytes are copied. +.Sh SEE ALSO +.Xr memccpy 3 , +.Xr memcpy 3 , +.Xr memmove 3 , +.Xr strcpy 3 , +.Xr strncpy 3 +.Sh HISTORY +A +.Fn bcopy +function appeared in +.Bx 4.2 . +Its prototype existed previously in +.In string.h +before it was moved to +.In strings.h +for +.St -p1003.1-2001 +compliance. diff --git a/string/bstring.3 b/string/bstring.3 new file mode 100644 index 0000000..becca80 --- /dev/null +++ b/string/bstring.3 @@ -0,0 +1,156 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt BSTRING 3 +.Os +.Sh NAME +.Nm bcmp , +.Nm bcopy , +.Nm bzero , +.Nm memccpy , +.Nm memchr , +.Nm memcmp , +.Nm memcpy , +.Nm memmove , +.Nm memset +.Nd byte string operations +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In strings.h +.Ft int +.Fo bcmp +.Fa "const void *s1" +.Fa "const void *s2" +.Fa "size_t n" +.Fc +.Ft void +.Fo bcopy +.Fa "const void *s1" +.Fa "void *s2" +.Fa "size_t n" +.Fc +.Ft void +.Fo bzero +.Fa "void *s" +.Fa "size_t n" +.Fc +.In string.h +.Ft void * +.Fo memccpy +.Fa "void *restrict s1" +.Fa "const void *restrict s2" +.Fa "int c" +.Fa "size_t n" +.Fc +.Ft void * +.Fo memchr +.Fa "const void *s" +.Fa "int c" +.Fa "size_t n" +.Fc +.Ft int +.Fo memcmp +.Fa "const void *s1" +.Fa "const void *s2" +.Fa "size_t n" +.Fc +.Ft void * +.Fo memcpy +.Fa "void *restrict s1" +.Fa "const void *restrict s2" +.Fa "size_t n" +.Fc +.Ft void * +.Fo memmove +.Fa "void *s1" +.Fa "const void *s2" +.Fa "size_t n" +.Fc +.Ft void * +.Fo memset +.Fa "void *s" +.Fa "int c" +.Fa "size_t n" +.Fc +.Sh DESCRIPTION +These functions operate on variable length strings of bytes. +They do not check for terminating null bytes, as the routines +listed in +.Xr string 3 +do. +.Pp +See the specific manual pages for more information. +.Sh LEGACY SYNOPSIS +.Fd #include +.Pp +The include file +.In string.h +is necessary and sufficient for all functions. +.Sh SEE ALSO +.Xr bcmp 3 , +.Xr bcopy 3 , +.Xr bzero 3 , +.Xr memccpy 3 , +.Xr memchr 3 , +.Xr memcmp 3 , +.Xr memcpy 3 , +.Xr memmove 3 , +.Xr memset 3 , +.Xr compat 5 +.Sh STANDARDS +The functions +.Fn memchr , +.Fn memcmp , +.Fn memcpy , +.Fn memmove , +and +.Fn memset +conform to +.St -isoC . +.Sh HISTORY +The functions +.Fn bzero +and +.Fn memccpy +appeared in +.Bx 4.3 ; +the functions +.Fn bcmp , +.Fn bcopy , +appeared in +.Bx 4.2 . diff --git a/string/bzero.3 b/string/bzero.3 new file mode 100644 index 0000000..1fb20f8 --- /dev/null +++ b/string/bzero.3 @@ -0,0 +1,78 @@ +.\" 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. +.\" +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt BZERO 3 +.Os +.Sh NAME +.Nm bzero +.Nd write zeroes to a byte string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In strings.h +.Ft void +.Fn bzero "void *s" "size_t n" +.Sh DESCRIPTION +The +.Fn bzero +function +writes +.Fa n +zeroed bytes to the string +.Fa s . +If +.Fa n +is zero, +.Fn bzero +does nothing. +.Sh SEE ALSO +.Xr memset 3 , +.Xr swab 3 +.Sh HISTORY +A +.Fn bzero +function +appeared in +.Bx 4.3 . +Its prototype existed previously in +.In string.h +before it was moved to +.In strings.h +for +.St -p1003.1-2001 +compliance. diff --git a/string/ffs.3 b/string/ffs.3 new file mode 100644 index 0000000..b5607d4 --- /dev/null +++ b/string/ffs.3 @@ -0,0 +1,100 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd January 13, 2004 +.Dt FFS 3 +.Os +.Sh NAME +.Nm ffs , +.Nm ffsl , +.Nm fls , +.Nm flsl +.Nd find first or last bit set in a bit string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In strings.h +.Ft int +.Fn ffs "int i" +.Ft int +.Fn ffsl "long i" +.Ft int +.Fn fls "int i" +.Ft int +.Fn flsl "long i" +.Sh DESCRIPTION +The +.Fn ffs +and +.Fn ffsl +functions find the first bit set in +.Fa i +and return the index of that bit. +.Pp +The +.Fn fls +and +.Fn flsl +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. +A return value of zero from any of these functions means that the +argument was zero. +.Sh SEE ALSO +.Xr bitstring 3 +.Sh HISTORY +The +.Fn ffs +function appeared in +.Bx 4.3 . +Its prototype existed previously in +.In string.h +before it was moved to +.In strings.h +for +.St -p1003.1-2001 +compliance. +.Pp +The +.Fn ffsl , +.Fn fls , +and +.Fn flsl +functions appeared in +.Fx 5.3 . diff --git a/string/index-fbsd.c b/string/index-fbsd.c new file mode 100644 index 0000000..be2c052 --- /dev/null +++ b/string/index-fbsd.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include + +#ifdef STRCHR +#include + +char * +strchr +#else +#include + +char * +index +#endif +(const char *p, int ch) +{ + char c; + + c = ch; + for (;; ++p) { + if (*p == c) + return ((char *)p); + if (*p == '\0') + return (NULL); + } + /* NOTREACHED */ +} diff --git a/string/index.3 b/string/index.3 new file mode 100644 index 0000000..28b558f --- /dev/null +++ b/string/index.3 @@ -0,0 +1,106 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt INDEX 3 +.Os +.Sh NAME +.Nm index , rindex +.Nd locate character in string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In strings.h +.Ft "char *" +.Fn index "const char *s" "int c" +.Ft "char *" +.Fn rindex "const char *s" "int c" +.Sh DESCRIPTION +The +.Fn index +function +locates the first occurrence of +.Fa c +(converted to a +.Vt char ) +in the string pointed to by +.Fa s . +The terminating null character is considered to be part of the string; +therefore, if +.Fa c +is +.Ql \e0 , +the functions locate the terminating +.Ql \e0 . +.Pp +The +.Fn rindex +function is identical to +.Fn index , +except that it locates the last occurrence of +.Fa c . +.Sh RETURN VALUES +The functions +.Fn index +and +.Fn rindex +return a pointer to the located character, or +.Dv NULL +if the character does not appear in the string. +.Sh SEE ALSO +.Xr memchr 3 , +.Xr strchr 3 , +.Xr strcspn 3 , +.Xr strpbrk 3 , +.Xr strrchr 3 , +.Xr strsep 3 , +.Xr strspn 3 , +.Xr strstr 3 , +.Xr strtok 3 +.Sh HISTORY +The +.Fn index +and +.Fn rindex +functions appeared in +.At v6 . +Their prototypes existed previously in +.In string.h +before they were moved to +.In strings.h +for +.St -p1003.1-2001 +compliance. diff --git a/string/memccpy-fbsd.c b/string/memccpy-fbsd.c new file mode 100644 index 0000000..0bc6a11 --- /dev/null +++ b/string/memccpy-fbsd.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include + +void * +memccpy(t, f, c, n) + void *t; + const void *f; + int c; + size_t n; +{ + + if (n) { + unsigned char *tp = t; + const unsigned char *fp = f; + unsigned char uc = c; + do { + if ((*tp++ = *fp++) == uc) + return (tp); + } while (--n != 0); + } + return (0); +} diff --git a/string/memccpy.3 b/string/memccpy.3 new file mode 100644 index 0000000..1d4c3ef --- /dev/null +++ b/string/memccpy.3 @@ -0,0 +1,81 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 9, 1993 +.Dt MEMCCPY 3 +.Os +.Sh NAME +.Nm memccpy +.Nd copy string until character found +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft void * +.Fo memccpy +.Fa "void *restrict s1" +.Fa "const void *restrict s2" +.Fa "int c" +.Fa "size_t n" +.Fc +.Sh DESCRIPTION +The +.Fn memccpy +function +copies bytes from string +.Fa s2 +to string +.Fa s1 . +If the character +.Fa c +(as converted to an unsigned char) occurs in the string +.Fa s2 , +the copy stops and a pointer to the byte after the copy of +.Fa c +in the string +.Fa s1 +is returned. +Otherwise, +.Fa n +bytes are copied, and a NULL pointer is returned. +.Sh SEE ALSO +.Xr bcopy 3 , +.Xr memcpy 3 , +.Xr memmove 3 , +.Xr strcpy 3 +.Sh HISTORY +The +.Fn memccpy +function first appeared in +.Bx 4.4 . diff --git a/string/memchr-fbsd.c b/string/memchr-fbsd.c new file mode 100644 index 0000000..e3c6679 --- /dev/null +++ b/string/memchr-fbsd.c @@ -0,0 +1,60 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +void * +memchr(s, c, n) + const void *s; + unsigned char c; + size_t n; +{ + if (n != 0) { + const unsigned char *p = s; + + do { + if (*p++ == c) + return ((void *)(p - 1)); + } while (--n != 0); + } + return (NULL); +} diff --git a/string/memchr.3 b/string/memchr.3 new file mode 100644 index 0000000..80eb092 --- /dev/null +++ b/string/memchr.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 +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt MEMCHR 3 +.Os +.Sh NAME +.Nm memchr +.Nd locate byte in byte string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft void * +.Fo memchr +.Fa "const void *s" +.Fa "int c" +.Fa "size_t n" +.Fc +.Sh DESCRIPTION +The +.Fn memchr +function +locates the first occurrence of +.Fa c +(converted to an unsigned char) +in string +.Fa s . +.Sh RETURN VALUES +The +.Fn memchr +function +returns a pointer to the byte located, +or NULL if no such byte exists within +.Fa n +bytes. +.Sh SEE ALSO +.Xr strchr 3 , +.Xr strcspn 3 , +.Xr strpbrk 3 , +.Xr strrchr 3 , +.Xr strsep 3 , +.Xr strspn 3 , +.Xr strstr 3 , +.Xr strtok 3 +.Sh STANDARDS +The +.Fn memchr +function +conforms to +.St -isoC . diff --git a/string/memcmp-fbsd.c b/string/memcmp-fbsd.c new file mode 100644 index 0000000..045e4d9 --- /dev/null +++ b/string/memcmp-fbsd.c @@ -0,0 +1,62 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +/* + * Compare memory regions. + */ +int +memcmp(s1, s2, n) + const void *s1, *s2; + size_t n; +{ + if (n != 0) { + const unsigned char *p1 = s1, *p2 = s2; + + do { + if (*p1++ != *p2++) + return (*--p1 - *--p2); + } while (--n != 0); + } + return (0); +} diff --git a/string/memcmp.3 b/string/memcmp.3 new file mode 100644 index 0000000..8c1ae2c --- /dev/null +++ b/string/memcmp.3 @@ -0,0 +1,89 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt MEMCMP 3 +.Os +.Sh NAME +.Nm memcmp +.Nd compare byte string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft int +.Fo memcmp +.Fa "const void *s1" +.Fa "const void *s2" +.Fa "size_t n" +.Fc +.Sh DESCRIPTION +The +.Fn memcmp +function +compares byte string +.Fa s1 +against byte string +.Fa s2 . +Both strings are assumed to be +.Fa n +bytes long. +.Sh RETURN VALUES +The +.Fn memcmp +function +returns zero if the two strings are identical, +otherwise returns the difference between the first two differing bytes +(treated as unsigned char values, so that +.Sq Li \e200 +is greater than +.Sq Li \&\e0 , +for example). +Zero-length strings are always identical. +.Sh SEE ALSO +.Xr bcmp 3 , +.Xr strcasecmp 3 , +.Xr strcmp 3 , +.Xr strcoll 3 , +.Xr strxfrm 3 +.Sh STANDARDS +The +.Fn memcmp +function +conforms to +.St -isoC . diff --git a/string/memcpy.3 b/string/memcpy.3 new file mode 100644 index 0000000..326680d --- /dev/null +++ b/string/memcpy.3 @@ -0,0 +1,93 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt MEMCPY 3 +.Os +.Sh NAME +.Nm memcpy +.Nd copy memory area +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft void * +.Fo memcpy +.Fa "void *restrict s1" +.Fa "const void *restrict s2" +.Fa "size_t n" +.Fc +.Sh DESCRIPTION +The +.Fn memcpy +function +copies +.Fa n +bytes from memory area +.Fa s2 +to memory area +.Fa s1 . +If +.Fa s1 +and +.Fa s2 +overlap, behavior is undefined. +Applications in which +.Fa s1 +and +.Fa s2 +might overlap should use +.Xr memmove 3 +instead. +.Sh RETURN VALUES +The +.Fn memcpy +function +returns the original value of +.Fa s1 . +.Sh SEE ALSO +.Xr bcopy 3 , +.Xr memccpy 3 , +.Xr memmove 3 , +.Xr strcpy 3 +.Sh STANDARDS +The +.Fn memcpy +function +conforms to +.St -isoC . diff --git a/string/memmove.3 b/string/memmove.3 new file mode 100644 index 0000000..c29073b --- /dev/null +++ b/string/memmove.3 @@ -0,0 +1,82 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt MEMMOVE 3 +.Os +.Sh NAME +.Nm memmove +.Nd copy byte string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft void * +.Fo memmove +.Fa "void *s1" +.Fa "const void *s2" +.Fa "size_t n" +.Fc +.Sh DESCRIPTION +The +.Fn memmove +function +copies +.Fa n +bytes from string +.Fa s2 +to string +.Fa s1 . +The two strings may overlap; +the copy is always done in a non-destructive manner. +.Sh RETURN VALUES +The +.Fn memmove +function returns the original value of +.Fa s1 . +.Sh SEE ALSO +.Xr bcopy 3 , +.Xr memccpy 3 , +.Xr memcpy 3 , +.Xr strcpy 3 +.Sh STANDARDS +The +.Fn memmove +function +conforms to +.St -isoC . diff --git a/string/memset-fbsd.c b/string/memset-fbsd.c new file mode 100644 index 0000000..1cb8644 --- /dev/null +++ b/string/memset-fbsd.c @@ -0,0 +1,132 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Hibler and 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +#include + +#define wsize sizeof(u_int) +#define wmask (wsize - 1) + +#ifdef BZERO +#include + +#define RETURN return +#define VAL 0 +#define WIDEVAL 0 + +void +bzero(void *dst0, size_t length) +#else +#include + +#define RETURN return (dst0) +#define VAL c0 +#define WIDEVAL c + +void * +memset(void *dst0, int c0, size_t length) +#endif +{ + size_t t; +#ifndef BZERO + u_int c; +#endif + u_char *dst; + + dst = dst0; + /* + * If not enough words, just fill bytes. A length >= 2 words + * guarantees that at least one of them is `complete' after + * any necessary alignment. For instance: + * + * |-----------|-----------|-----------| + * |00|01|02|03|04|05|06|07|08|09|0A|00| + * ^---------------------^ + * dst dst+length-1 + * + * but we use a minimum of 3 here since the overhead of the code + * to do word writes is substantial. + */ + if (length < 3 * wsize) { + while (length != 0) { + *dst++ = VAL; + --length; + } + RETURN; + } + +#ifndef BZERO + if ((c = (u_char)c0) != 0) { /* Fill the word. */ + c = (c << 8) | c; /* u_int is 16 bits. */ +#if UINT_MAX > 0xffff + c = (c << 16) | c; /* u_int is 32 bits. */ +#endif +#if UINT_MAX > 0xffffffff + c = (c << 32) | c; /* u_int is 64 bits. */ +#endif + } +#endif + /* Align destination by filling in bytes. */ + if ((t = (long)dst & wmask) != 0) { + t = wsize - t; + length -= t; + do { + *dst++ = VAL; + } while (--t != 0); + } + + /* Fill words. Length was >= 2*words so we know t >= 1 here. */ + t = length / wsize; + do { + *(u_int *)dst = WIDEVAL; + dst += wsize; + } while (--t != 0); + + /* Mop up trailing bytes, if any. */ + t = length & wmask; + if (t != 0) + do { + *dst++ = VAL; + } while (--t != 0); + RETURN; +} diff --git a/gen/valloc.3 b/string/memset.3 similarity index 73% rename from gen/valloc.3 rename to string/memset.3 index 051922b..639efc1 100644 --- a/gen/valloc.3 +++ b/string/memset.3 @@ -1,6 +1,10 @@ -.\" Copyright (c) 1980, 1991, 1993 +.\" 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: @@ -29,46 +33,46 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)valloc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/valloc.3,v 1.9 2001/10/01 16:08:51 ru Exp $ +.\" @(#)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 $ .\" .Dd June 4, 1993 -.Dt VALLOC 3 +.Dt MEMSET 3 .Os .Sh NAME -.Nm valloc -.Nd aligned memory allocation function +.Nm memset +.Nd write a byte to a byte string .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In unistd.h +.In string.h .Ft void * -.Fn valloc "size_t size" +.Fo memset +.Fa "void *b" +.Fa "int c" +.Fa "size_t n" +.Fc .Sh DESCRIPTION -.Bf -symbolic The -.Fn valloc +.Fn memset function -allocates -.Fa size -bytes aligned on a page boundary. -It is implemented by calling -.Xr malloc 3 -with a slightly larger request, saving the true beginning of the block -allocated, and returning a properly aligned pointer. +writes +.Fa n +bytes of value +.Fa c +(converted to an unsigned char) to the string +.Fa s . .Sh RETURN VALUES The -.Fn valloc -function returns -a pointer to the allocated space if successful; otherwise -a null pointer is returned -.Sh HISTORY +.Fn memset +function returns its first argument. +.Sh SEE ALSO +.Xr bzero 3 , +.Xr memset_pattern 3 , +.Xr swab 3 +.Sh STANDARDS The -.Fn valloc -function appeared in -.Bx 3.0 . -.Sh BUGS -A -.Em vfree +.Fn memset function -has not been implemented. +conforms to +.St -isoC . diff --git a/string/memset_pattern.3 b/string/memset_pattern.3 new file mode 100644 index 0000000..df7150a --- /dev/null +++ b/string/memset_pattern.3 @@ -0,0 +1,43 @@ +.Dd October 14, 2005 +.Dt MEMSET_PATTERN 3 +.Os Darwin +.Sh NAME +.Nm memset_pattern4 , +.Nm memset_pattern8 , +.Nm memset_pattern16 +.Nd memset of a multi-byte pattern +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft void +.Fn memset_pattern4 "void *b" "const void *pattern4" "size_t len" +.Ft void +.Fn memset_pattern8 "void *b" "const void *pattern8" "size_t len" +.Ft void +.Fn memset_pattern16 "void *b" "const void *pattern16" "size_t len" +.Sh DESCRIPTION +These are analogous to +.Fn memset , +except that they +fill memory with a replicated pattern either 4, 8, or 16 bytes long. +.Fa b +points to a buffer of size +.Fa len +bytes which is to be filled. The second parameter points to the pattern. +If the buffer length is not an even multiple +of the pattern length, the last instance of the pattern will be truncated. +Neither the buffer nor the pattern pointer need be aligned. +.Sh EXAMPLES +The following example: +.Bd -literal -offset indent +char buf[10]; + +memset_pattern4( buf, "1234", sizeof(buf) ); +.Ed +.Pp +will set the buffer to the value "1234123412". +.Sh SEE ALSO +.Xr memset 3 +.Sh HISTORY +These functions first appeared in Mac OS 10.5. \ No newline at end of file diff --git a/string/rindex-fbsd.c b/string/rindex-fbsd.c new file mode 100644 index 0000000..697b69a --- /dev/null +++ b/string/rindex-fbsd.c @@ -0,0 +1,66 @@ +/* + * 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[] = "@(#)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 $"); + +#include + +#ifdef STRRCHR +#include + +char * +strrchr +#else +#include + +char * +rindex +#endif +(const char *p, int ch) +{ + char *save; + char c; + + c = ch; + for (save = NULL;; ++p) { + if (*p == c) + save = (char *)p; + if (*p == '\0') + return (save); + } + /* NOTREACHED */ +} diff --git a/string/rindex.3 b/string/rindex.3 new file mode 100644 index 0000000..f1a80e1 --- /dev/null +++ b/string/rindex.3 @@ -0,0 +1,92 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)rindex.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: src/lib/libc/string/rindex.3,v 1.8 2002/12/18 13:33:03 ru Exp $ +.\" +.Dd June 4, 1993 +.Dt RINDEX 3 +.Os +.Sh NAME +.Nm rindex +.Nd locate character in string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In strings.h +.Ft char * +.Fn rindex "const char *s" "int c" +.Sh DESCRIPTION +The +.Fn rindex +function +locates the last character +matching +.Fa c +(converted to a +.Vt char ) +in the null-terminated string +.Fa s . +.Sh RETURN VALUES +A pointer to the character is returned if it is found; +otherwise, NULL is returned. +If +.Fa c +is +.Ql \e0 , +.Fn rindex +locates the terminating +.Ql \e0 . +.Sh SEE ALSO +.Xr index 3 , +.Xr memchr 3 , +.Xr strchr 3 , +.Xr strcspn 3 , +.Xr strpbrk 3 , +.Xr strrchr 3 , +.Xr strsep 3 , +.Xr strspn 3 , +.Xr strstr 3 , +.Xr strtok 3 +.Sh HISTORY +A +.Fn rindex +function appeared in +.At v6 . +Its prototype existed previously in +.Aq Pa string.h +before it was moved to +.Aq Pa strings.h +for +.St -p1003.1-2001 +compliance. diff --git a/string/stpcpy-fbsd.c b/string/stpcpy-fbsd.c new file mode 100644 index 0000000..2742bf7 --- /dev/null +++ b/string/stpcpy-fbsd.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/stpcpy.c,v 1.1 2002/10/03 19:39:20 obrien Exp $"); + +#include + +char * +stpcpy(char * to, const char * from) +{ + + for (; (*to = *from); ++from, ++to); + return(to); +} diff --git a/string/strcasecmp-fbsd.c b/string/strcasecmp-fbsd.c new file mode 100644 index 0000000..e85897a --- /dev/null +++ b/string/strcasecmp-fbsd.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1987, 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[] = "@(#)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 $"); + +#include "xlocale_private.h" + +#include +#include + +typedef unsigned char u_char; + +int +strcasecmp_l(s1, s2, loc) + const char *s1, *s2; + locale_t loc; +{ + const u_char + *us1 = (const u_char *)s1, + *us2 = (const u_char *)s2; + + NORMALIZE_LOCALE(loc); + while (tolower_l(*us1, loc) == tolower_l(*us2++, loc)) + if (*us1++ == '\0') + return (0); + return (tolower_l(*us1, loc) - tolower_l(*--us2, loc)); +} + +int +strcasecmp(s1, s2) + const char *s1, *s2; +{ + return strcasecmp_l(s1, s2, __current_locale()); +} + +int +strncasecmp_l(s1, s2, n, loc) + const char *s1, *s2; + size_t n; + locale_t loc; +{ + NORMALIZE_LOCALE(loc); + if (n != 0) { + const u_char + *us1 = (const u_char *)s1, + *us2 = (const u_char *)s2; + + do { + if (tolower_l(*us1, loc) != tolower_l(*us2++, loc)) + return (tolower_l(*us1, loc) - tolower_l(*--us2, loc)); + if (*us1++ == '\0') + break; + } while (--n != 0); + } + return (0); +} + +int +strncasecmp(s1, s2, n) + const char *s1, *s2; + size_t n; +{ + return strncasecmp_l(s1, s2, n, __current_locale()); +} diff --git a/string/strcasecmp.3 b/string/strcasecmp.3 new file mode 100644 index 0000000..52fb0e5 --- /dev/null +++ b/string/strcasecmp.3 @@ -0,0 +1,141 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 9, 1993 +.Dt STRCASECMP 3 +.Os +.Sh NAME +.Nm strcasecmp , +.Nm strcasecmp_l , +.Nm strncasecmp , +.Nm strncasecmp_l +.Nd compare strings, ignoring case +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In strings.h +.Ft int +.Fo strcasecmp +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Ft int +.Fo strncasecmp +.Fa "const char *s1" +.Fa "const char *s2" +.Fa "size_t n" +.Fc +.In strings.h +.In xlocale.h +.Ft int +.Fo strcasecmp_l +.Fa "const char *s1" +.Fa "const char *s2" +.Fa "locale_t loc" +.Fc +.Ft int +.Fo strncasecmp_l +.Fa "const char *s1" +.Fa "const char *s2" +.Fa "size_t n" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn strcasecmp +and +.Fn strncasecmp +functions +compare the null-terminated strings +.Fa s1 +and +.Fa s2 . +.Pp +The +.Fn strncasecmp +compares at most +.Fa n +characters. +.Pp +Although the +.Fn strcasecmp +and +.Fn strncasecmp +functions use the current locale, the +.Fn strcasecmp_l +and +.Fn strncasecmp_l +functions may be passed locales directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn strcasecmp +and +.Fn strncasecmp +return an integer greater than, equal to, or less than 0, +according as +.Fa s1 +is lexicographically greater than, equal to, or less than +.Fa s2 +after translation of each corresponding character to lower-case. +The strings themselves are not modified. +The comparison is done using unsigned characters, so that +.Sq Li \e200 +is greater than +.Ql \e0 . +.Sh SEE ALSO +.Xr bcmp 3 , +.Xr memcmp 3 , +.Xr strcmp 3 , +.Xr strcoll 3 , +.Xr strxfrm 3 , +.Xr tolower 3 , +.Xr xlocale 3 +.Sh HISTORY +The +.Fn strcasecmp +and +.Fn strncasecmp +functions first appeared in +.Bx 4.4 . +Their prototypes existed previously in +.In string.h +before they were moved to +.In strings.h +for +.St -p1003.1-2001 +compliance. diff --git a/string/strcasestr-fbsd.c b/string/strcasestr-fbsd.c new file mode 100644 index 0000000..ef30b54 --- /dev/null +++ b/string/strcasestr-fbsd.c @@ -0,0 +1,76 @@ +/*- + * 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. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/string/strcasestr.c,v 1.3 2002/03/21 18:44:54 obrien Exp $"); + +#include "xlocale_private.h" + +#include +#include + +/* + * Find the first occurrence of find in s, ignore case. + */ +char * +strcasestr_l(s, find, loc) + const char *s, *find; + locale_t loc; +{ + char c, sc; + size_t len; + + NORMALIZE_LOCALE(loc); + if ((c = *find++) != 0) { + c = tolower_l((unsigned char)c, loc); + len = strlen(find); + do { + do { + if ((sc = *s++) == 0) + return (NULL); + } while ((char)tolower_l((unsigned char)sc, loc) != c); + } while (strncasecmp_l(s, find, len, loc) != 0); + s--; + } + return ((char *)s); +} + +char * +strcasestr(s, find) + const char *s, *find; +{ + return strcasestr_l(s, find, __current_locale()); +} diff --git a/string/strcat-fbsd.c b/string/strcat-fbsd.c new file mode 100644 index 0000000..5d28c86 --- /dev/null +++ b/string/strcat-fbsd.c @@ -0,0 +1,50 @@ +/* + * 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[] = "@(#)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 $"); + +#include + +char * +strcat(char * __restrict s, const char * __restrict append) +{ + char *save = s; + + for (; *s; ++s); + while ((*s++ = *append++)); + return(save); +} diff --git a/string/strcat.3 b/string/strcat.3 new file mode 100644 index 0000000..2986070 --- /dev/null +++ b/string/strcat.3 @@ -0,0 +1,167 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt STRCAT 3 +.Os +.Sh NAME +.Nm strcat , +.Nm strncat +.Nd concatenate strings +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft char * +.Fo strcat +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fc +.Ft char * +.Fo strncat +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fa "size_t n" +.Fc +.Sh DESCRIPTION +The +.Fn strcat +and +.Fn strncat +functions +append a copy of the null-terminated string +.Fa s2 +to the end of the null-terminated string +.Fa s1 , +then add a terminating +.Ql \e0 . +The string +.Fa s1 +must have sufficient space to hold the result. +.Pp +The +.Fn strncat +function +appends not more than +.Fa n +characters from +.Fa s2 , +and then adds a terminating +.Ql \e0 . +.Sh RETURN VALUES +The +.Fn strcat +and +.Fn strncat +functions +return the pointer +.Fa s1 . +.Sh SECURITY CONSIDERATIONS +The +.Fn strcat +function is 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.) +.Pp +Avoid using +.Fn strcat . +Instead, use +.Fn strncat +or +.Fn strlcat +and ensure that no more characters are copied to the destination buffer +than it can hold. +.Pp +Note that +.Fn strncat +can also be problematic. +It may be a security concern for a string to be truncated at all. +Since the truncated string will not be as long as the original, +it may refer to a completely different resource +and usage of the truncated resource +could result in very incorrect behavior. +Example: +.Bd -literal +void +foo(const char *arbitrary_string) +{ + char onstack[8] = ""; + +#if defined(BAD) + /* + * This first strcat is bad behavior. Do not use strcat! + */ + (void)strcat(onstack, arbitrary_string); /* BAD! */ +#elif defined(BETTER) + /* + * The following two lines demonstrate better use of + * strncat(). + */ + (void)strncat(onstack, arbitrary_string, + sizeof(onstack) - strlen(onstack) - 1); +#elif defined(BEST) + /* + * These lines are even more robust due to testing for + * truncation. + */ + if (strlen(arbitrary_string) + 1 > + sizeof(onstack) - strlen(onstack)) + err(1, "onstack would be truncated"); + (void)strncat(onstack, arbitrary_string, + sizeof(onstack) - strlen(onstack) - 1); +#endif +} +.Ed +.Sh SEE ALSO +.Xr bcopy 3 , +.Xr memccpy 3 , +.Xr memcpy 3 , +.Xr memmove 3 , +.Xr strcpy 3 , +.Xr strlcat 3 , +.Xr strlcpy 3 +.Sh STANDARDS +The +.Fn strcat +and +.Fn strncat +functions +conform to +.St -isoC . diff --git a/string/strchr-fbsd.c b/string/strchr-fbsd.c new file mode 100644 index 0000000..26433c0 --- /dev/null +++ b/string/strchr-fbsd.c @@ -0,0 +1,5 @@ +#include +__FBSDID("$FreeBSD: src/lib/libc/string/strchr.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); + +#define STRCHR +#include "index-fbsd.c" diff --git a/string/strchr.3 b/string/strchr.3 new file mode 100644 index 0000000..72e81b2 --- /dev/null +++ b/string/strchr.3 @@ -0,0 +1,104 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd April 19, 1994 +.Dt STRCHR 3 +.Os +.Sh NAME +.Nm strchr , strrchr +.Nd locate character in string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft "char *" +.Fo strchr +.Fa "const char *s" +.Fa "int c" +.Fc +.Ft "char *" +.Fo strrchr +.Fa "const char *s" +.Fa "int c" +.Fc +.Sh DESCRIPTION +The +.Fn strchr +function locates the first occurrence of +.Fa c +(converted to a +.Vt char ) +in the string pointed to by +.Fa s . +The terminating null character is considered to be part of the string; +therefore if +.Fa c +is +.Ql \e0 , +the functions locate the terminating +.Ql \e0 . +.Pp +The +.Fn strrchr +function is identical to +.Fn strchr , +except it locates the last occurrence of +.Fa c . +.Sh RETURN VALUES +The functions +.Fn strchr +and +.Fn strrchr +return a pointer to the located character, or +.Dv NULL +if the character does not appear in the string. +.Sh SEE ALSO +.Xr memchr 3 , +.Xr strcspn 3 , +.Xr strpbrk 3 , +.Xr strsep 3 , +.Xr strspn 3 , +.Xr strstr 3 , +.Xr strtok 3 +.Sh STANDARDS +The functions +.Fn strchr +and +.Fn strrchr +conform to +.St -isoC . diff --git a/string/strcmp.3 b/string/strcmp.3 new file mode 100644 index 0000000..602e85d --- /dev/null +++ b/string/strcmp.3 @@ -0,0 +1,111 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd October 11, 2001 +.Dt STRCMP 3 +.Os +.Sh NAME +.Nm strcmp , +.Nm strncmp +.Nd compare strings +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft int +.Fo strcmp +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Ft int +.Fo strncmp +.Fa "const char *s1" +.Fa "const char *s2" +.Fa "size_t n" +.Fc +.Sh DESCRIPTION +The +.Fn strcmp +and +.Fn strncmp +functions +lexicographically compare the null-terminated strings +.Fa s1 +and +.Fa s2 . +.Pp +The +.Fn strncmp +function +compares not more than +.Fa n +characters. +Because +.Fn strncmp +is designed for comparing strings rather than binary data, +characters that appear after a +.Ql \e0 +character are not compared. +.Sh RETURN VALUES +The +.Fn strcmp +and +.Fn strncmp +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 +.Fa s2 . +The comparison is done using unsigned characters, so that +.Ql \e200 +is greater than +.Ql \e0 . +.Sh SEE ALSO +.Xr bcmp 3 , +.Xr memcmp 3 , +.Xr strcasecmp 3 , +.Xr strcoll 3 , +.Xr strxfrm 3 +.Sh STANDARDS +The +.Fn strcmp +and +.Fn strncmp +functions +conform to +.St -isoC . diff --git a/string/strcoll-fbsd.c b/string/strcoll-fbsd.c new file mode 100644 index 0000000..92d842d --- /dev/null +++ b/string/strcoll-fbsd.c @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 1995 Alex Tatmanjants + * at Electronni Visti IA, Kiev, Ukraine. + * 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 ``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 +__FBSDID("$FreeBSD: src/lib/libc/string/strcoll.c,v 1.13 2001/11/07 19:55:16 obrien Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include "collate.h" + +int +strcoll_l(s, s2, loc) + const char *s, *s2; + locale_t loc; +{ + int ret; + const wchar_t *t = NULL, *t2 = NULL; + int sverrno; + + NORMALIZE_LOCALE(loc); + if (loc->__collate_load_error || (t = __collate_mbstowcs(s, loc)) == NULL || (t2 = __collate_mbstowcs(s2, loc)) == NULL) { + sverrno = errno; + free((void *)t); + free((void *)t2); + errno = sverrno; + return strcmp(s, s2); + } + + ret = wcscoll_l(t, t2, loc); + sverrno = errno; + free((void *)t); + free((void *)t2); + errno = sverrno; + + return ret; +} + +int +strcoll(s, s2) + const char *s, *s2; +{ + return strcoll_l(s, s2, __current_locale()); +} diff --git a/string/strcoll.3 b/string/strcoll.3 new file mode 100644 index 0000000..267c836 --- /dev/null +++ b/string/strcoll.3 @@ -0,0 +1,98 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt STRCOLL 3 +.Os +.Sh NAME +.Nm strcoll , +.Nm strcoll_l +.Nd compare strings, according to current collation +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft int +.Fo strcoll +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.In string.h +.In xlocale.h +.Ft int +.Fo strcoll_l +.Fa "const char *s1" +.Fa "const char *s2" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn strcoll +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 +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 . +.Pp +Although the +.Fn strcoll +function uses the current locale, the +.Fn strcoll_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh SEE ALSO +.Xr setlocale 3 , +.Xr strcmp 3 , +.Xr strxfrm 3 , +.Xr wcscoll 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn strcoll +function +conforms to +.St -isoC . diff --git a/string/strcpy-fbsd.c b/string/strcpy-fbsd.c new file mode 100644 index 0000000..5cd2f45 --- /dev/null +++ b/string/strcpy-fbsd.c @@ -0,0 +1,49 @@ +/* + * 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[] = "@(#)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 $"); + +#include + +char * +strcpy(char * __restrict to, const char * __restrict from) +{ + char *save = to; + + for (; (*to = *from); ++from, ++to); + return(save); +} diff --git a/string/strcpy.3 b/string/strcpy.3 new file mode 100644 index 0000000..fd196fb --- /dev/null +++ b/string/strcpy.3 @@ -0,0 +1,214 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd August 9, 2001 +.Dt STRCPY 3 +.Os +.Sh NAME +.Nm stpcpy , +.Nm strcpy , +.Nm strncpy +.Nd copy strings +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft char * +.Fo stpcpy +.Fa "char *s1" +.Fa "const char *s2" +.Fc +.Ft char * +.Fo strcpy +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fc +.Ft char * +.Fo strncpy +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fa "size_t n" +.Fc +.Sh DESCRIPTION +The +.Fn stpcpy +and +.Fn strcpy +functions +copy the string +.Fa s2 +to +.Fa s1 +(including the terminating +.Ql \e0 +character). +.Pp +The +.Fn strncpy +function copies at most +.Fa n +characters from +.Fa s2 +into +.Fa s1 . +If +.Fa s2 +is less than +.Fa n +characters long, +the remainder of +.Fa s1 +is filled with +.Ql \e0 +characters. +Otherwise, +.Fa s1 +is +.Em not +terminated. +.Sh RETURN VALUES +The +.Fn strcpy +and +.Fn strncpy +functions +return +.Fa s1 . +The +.Fn stpcpy +function returns a pointer to the terminating +.Ql \e0 +character of +.Fa s1 . +.Sh EXAMPLES +The following sets +.Va chararray +to +.Dq Li abc\e0\e0\e0 : +.Bd -literal -offset indent +char chararray[6]; + +(void)strncpy(chararray, "abc", sizeof(chararray)); +.Ed +.Pp +The following sets +.Va chararray +to +.Dq Li abcdef : +.Bd -literal -offset indent +char chararray[6]; + +(void)strncpy(chararray, "abcdefgh", sizeof(chararray)); +.Ed +.Pp +Note that it does +.Em not +.Tn NUL +terminate +.Va chararray , +because the length of the source string is greater than or equal +to the length argument. +.Pp +The following copies as many characters from +.Va input +to +.Va buf +as will fit and +.Tn NUL +terminates the result. +Because +.Fn strncpy +does +.Em not +guarantee to +.Tn NUL +terminate the string itself, this must be done explicitly. +.Bd -literal -offset indent +char buf[1024]; + +(void)strncpy(buf, input, sizeof(buf) - 1); +buf[sizeof(buf) - 1] = '\e0'; +.Ed +.Pp +This could be better achieved using +.Xr strlcpy 3 , +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 +to arbitrarily change a running program's functionality through a +buffer overflow attack. +(See +the FSA +and +.Sx EXAMPLES . ) +.Sh SEE ALSO +.Xr bcopy 3 , +.Xr memccpy 3 , +.Xr memcpy 3 , +.Xr memmove 3 , +.Xr strlcpy 3 +.Sh STANDARDS +The +.Fn strcpy +and +.Fn strncpy +functions +conform to +.St -isoC . +The +.Fn stpcpy +function is an MS-DOS and GNUism. +The +.Fn stpcpy +function +conforms to no standard. +.Sh HISTORY +The +.Fn stpcpy +function first appeared in +.Fx 4.4 , +coming from 1998-vintage Linux. diff --git a/string/strcspn-fbsd.c b/string/strcspn-fbsd.c new file mode 100644 index 0000000..55acb8b --- /dev/null +++ b/string/strcspn-fbsd.c @@ -0,0 +1,72 @@ +/*- + * Copyright (c) 2005 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/strcspn.c,v 1.5 2005/04/02 18:52:44 das Exp $"); + +#include +#include +#include + +#define IDX(c) ((u_char)(c) / LONG_BIT) +#define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT)) + +size_t +strcspn(const char *s, const char *charset) +{ + /* + * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to + * generate better code. Without them, gcc gets a little confused. + */ + const char *s1; + u_long bit; + u_long tbl[(UCHAR_MAX + 1) / LONG_BIT]; + int idx; + + if(*s == '\0') + return (0); + +#if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */ + tbl[0] = 1; + tbl[3] = tbl[2] = tbl[1] = 0; +#else + for (tbl[0] = idx = 1; idx < sizeof(tbl) / sizeof(tbl[0]); idx++) + tbl[idx] = 0; +#endif + for (; *charset != '\0'; charset++) { + idx = IDX(*charset); + bit = BIT(*charset); + tbl[idx] |= bit; + } + + for(s1 = s; ; s1++) { + idx = IDX(*s1); + bit = BIT(*s1); + if ((tbl[idx] & bit) != 0) + break; + } + return (s1 - s); +} diff --git a/string/strcspn.3 b/string/strcspn.3 new file mode 100644 index 0000000..7d17774 --- /dev/null +++ b/string/strcspn.3 @@ -0,0 +1,87 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt STRCSPN 3 +.Os +.Sh NAME +.Nm strcspn +.Nd span the complement of a string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft size_t +.Fo strcspn +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Sh DESCRIPTION +The +.Fn strcspn +function +spans the initial part of the null-terminated string +.Fa s1 , +as long as the characters from +.Fa s1 +do not occur in string +.Fa s2 +(it +spans the +.Em complement +of +.Fa s2 ) . +.Sh RETURN VALUES +The +.Fn strcspn +function returns the number of characters spanned. +.Sh SEE ALSO +.Xr memchr 3 , +.Xr strchr 3 , +.Xr strpbrk 3 , +.Xr strrchr 3 , +.Xr strsep 3 , +.Xr strspn 3 , +.Xr strstr 3 , +.Xr strtok 3 +.Sh STANDARDS +The +.Fn strcspn +function +conforms to +.St -isoC . diff --git a/string/strdup-fbsd.c b/string/strdup-fbsd.c new file mode 100644 index 0000000..a9881a1 --- /dev/null +++ b/string/strdup-fbsd.c @@ -0,0 +1,56 @@ +/* + * 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[] = "@(#)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 $"); + +#include +#include +#include + +char * +strdup(str) + const char *str; +{ + size_t len; + char *copy; + + len = strlen(str) + 1; + if ((copy = malloc(len)) == NULL) + return (NULL); + memcpy(copy, str, len); + return (copy); +} diff --git a/string/strdup.3 b/string/strdup.3 new file mode 100644 index 0000000..506c19a --- /dev/null +++ b/string/strdup.3 @@ -0,0 +1,72 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 9, 1993 +.Dt STRDUP 3 +.Os +.Sh NAME +.Nm strdup +.Nd save a copy of a string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft char * +.Fo strdup +.Fa "const char *s1" +.Fc +.Sh DESCRIPTION +The +.Fn strdup +function +allocates sufficient memory for a copy +of the string +.Fa s1 , +does the copy, and returns a pointer to it. +The pointer may subsequently be used as an +argument to the function +.Xr free 3 . +.Pp +If insufficient memory is available, NULL is returned and +.Va errno +is set to +.Er ENOMEM . +.Sh SEE ALSO +.Xr free 3 , +.Xr malloc 3 +.Sh HISTORY +The +.Fn strdup +function first appeared in +.Bx 4.4 . diff --git a/string/strerror-fbsd.c b/string/strerror-fbsd.c new file mode 100644 index 0000000..798dbb4 --- /dev/null +++ b/string/strerror-fbsd.c @@ -0,0 +1,105 @@ +/*- + * 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[] = "@(#)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 $"); + +#include +#include +#include + +#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. + */ +#define EBUFSIZE (20 + sizeof(UPREFIX)) + +#ifndef BUILDING_VARIANT +/* + * Doing this by hand instead of linking with stdio(3) avoids bloat for + * statically linked binaries. + */ +__private_extern__ void +__errstr(int num, char *buf, size_t len) +{ + char *t; + unsigned int uerr; + char tmp[EBUFSIZE]; + + t = tmp + sizeof(tmp); + *--t = '\0'; + uerr = (num >= 0) ? num : -num; + do { + *--t = "0123456789"[uerr % 10]; + } while (uerr /= 10); + if (num < 0) + *--t = '-'; + strlcpy(buf, UPREFIX, len); + strlcat(buf, t, len); +} + +int +strerror_r(int errnum, char *strerrbuf, size_t buflen) +{ + + if (errnum < 0 || errnum >= sys_nerr) { + __errstr(errnum, strerrbuf, buflen); + return (EINVAL); + } + if (strlcpy(strerrbuf, sys_errlist[errnum], buflen) >= buflen) + return (ERANGE); + return (0); +} +#else /* BUILDING_VARIANT */ +__private_extern__ void __errstr(int, char *, size_t); +#endif /* !BUILDING_VARIANT */ + +char * +strerror(int num) +{ + static char ebuf[EBUFSIZE]; + + if (num > 0 && num < sys_nerr) + return ((char *)sys_errlist[num]); +#if !__DARWIN_UNIX03 + errno = EINVAL; +#endif /* !__DARWIN_UNIX03 */ + __errstr(num, ebuf, sizeof(ebuf)); + return (ebuf); +} diff --git a/string/strerror.3 b/string/strerror.3 new file mode 100644 index 0000000..b7166f1 --- /dev/null +++ b/string/strerror.3 @@ -0,0 +1,198 @@ +.\" Copyright (c) 1980, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd October 12, 2004 +.Dt STRERROR 3 +.Os +.Sh NAME +.Nm perror , +.Nm strerror , +.Nm strerror_r , +.Nm sys_errlist , +.Nm sys_nerr +.Nd system error messages +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft void +.Fo perror +.Fa "const char *s" +.Fc +.Vt extern const char * const sys_errlist[] ; +.Vt extern const int sys_nerr ; +.In string.h +.Ft "char *" +.Fo strerror +.Fa "int errnum" +.Fc +.Ft int +.Fo strerror_r +.Fa "int errnum" +.Fa "char *strerrbuf" +.Fa "size_t buflen" +.Fc +.Sh DESCRIPTION +The +.Fn strerror , +.Fn strerror_r , +and +.Fn perror +functions look up the error message string corresponding to an +error number. +.Pp +The +.Fn strerror +function accepts an error number argument +.Fa errnum +and returns a pointer to the corresponding +message string. +.Pp +The +.Fn strerror_r +function renders the same result into +.Fa strerrbuf +for a maximum of +.Fa buflen +characters and returns 0 upon success. +.Pp +The +.Fn perror +function finds the error message corresponding to the current +value of the global variable +.Va errno +.Pq Xr intro 2 +and writes it, followed by a newline, to the +standard error file descriptor. +If the argument +.Fa s +is +.Pf non- Dv NULL +and does not point to the null character, +this string is prepended to the message +string and separated from it by +a colon and space +.Pq Dq Li ":\ " ; +otherwise, only the error message string is printed. +.Pp +If the error number is not recognized, these functions return an error message +string containing +.Dq Li "Unknown error:\ " +followed by the error number in decimal. +The +.Fn strerror +and +.Fn strerror_r +functions return +.Er EINVAL +as a warning. +Error numbers recognized by this implementation fall in +the range 0 < +.Fa errnum +< +.Fa sys_nerr . +.Pp +If insufficient storage is provided in +.Fa strerrbuf +(as specified in +.Fa buflen ) +to contain the error string, +.Fn strerror_r +returns +.Er ERANGE +and +.Fa strerrbuf +will contain an error message that has been truncated and +.Dv NUL +terminated to fit the length specified by +.Fa buflen . +.Pp +The message strings can be accessed directly using the external +array +.Va sys_errlist . +The external value +.Va sys_nerr +contains a count of the messages in +.Va sys_errlist . +The use of these variables is deprecated; +.Fn strerror +or +.Fn strerror_r +should be used instead. +.Sh SEE ALSO +.Xr intro 2 , +.Xr psignal 3 +.Sh STANDARDS +The +.Fn perror +and +.Fn strerror +functions conform to +.St -isoC-99 . +The +.Fn strerror_r +function conforms to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn strerror +and +.Fn perror +functions first appeared in +.Bx 4.4 . +The +.Fn strerror_r +function was implemented in +.Fx 4.4 +by +.An Wes Peters Aq wes@FreeBSD.org . +.Sh BUGS +For unknown error numbers, the +.Fn strerror +function will return its result in a static buffer which +may be overwritten by subsequent calls. +.Pp +The return type for +.Fn strerror +is missing a type-qualifier; it should actually be +.Vt const char * . +.Pp +Programs that use the deprecated +.Va sys_errlist +variable often fail to compile because they declare it +inconsistently. diff --git a/string/string.3 b/string/string.3 new file mode 100644 index 0000000..2b43279 --- /dev/null +++ b/string/string.3 @@ -0,0 +1,227 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd December 11, 1993 +.Dt STRING 3 +.Os +.Sh NAME +.Nm index , +.Nm rindex , +.Nm stpcpy , +.Nm strcasecmp , +.Nm strcat , +.Nm strchr , +.Nm strcmp , +.Nm strcpy , +.Nm strcspn , +.Nm strerror , +.Nm strlen , +.Nm strncasecmp , +.Nm strncat , +.Nm strncmp , +.Nm strncpy , +.Nm strpbrk , +.Nm strrchr , +.Nm strsep , +.Nm strspn , +.Nm strstr , +.Nm strtok +.Nd string specific functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In strings.h +.Ft char * +.Fo index +.Fa "const char *s" +.Fa "int c" +.Fc +.Ft char * +.Fo rindex +.Fa "const char *s" +.Fa "int c" +.Fc +.Ft int +.Fo strcasecmp +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Ft int +.Fo strncasecmp +.Fa "const char *s1" +.Fa "const char *s2" +.Fa "size_t n" +.Fc +.In string.h +.Ft char * +.Fo stpcpy +.Fa "char *dst" +.Fa "const char *src" +.Fc +.Ft char * +.Fo strcat +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fc +.Ft char * +.Fo strchr +.Fa "const char *s" +.Fa "int c" +.Fc +.Ft int +.Fo strcmp +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Ft char * +.Fo strcpy +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fc +.Ft size_t +.Fo strcspn +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Ft char * +.Fo strerror +.Fa "int errnum" +.Fc +.Ft size_t +.Fo strlen +.Fa "const char *s" +.Fc +.Ft char * +.Fo strncat +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fa "size_t n" +.Fc +.Ft int +.Fo strncmp +.Fa "const char *s1" +.Fa "const char *s2" +.Fa "size_t n" +.Fc +.Ft char * +.Fo strncpy +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fa "size_t n" +.Fc +.Ft char * +.Fo strpbrk +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Ft char * +.Fo strrchr +.Fa "const char *s" +.Fa "int c" +.Fc +.Ft char * +.Fo strsep +.Fa "char **stringp" +.Fa "const char *delim" +.Fc +.Ft size_t +.Fo strspn +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Ft char * +.Fo strstr +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Ft char * +.Fo strtok +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fc +.Sh DESCRIPTION +The string +functions manipulate strings that are terminated by a +null byte. +.Pp +See the specific manual pages for more information. +For manipulating variable length generic objects as byte +strings (without the null byte check), see +.Xr bstring 3 . +.Pp +Except as noted in their specific manual pages, +the string functions do not test the destination +for size limitations. +.Sh SEE ALSO +.Xr bstring 3 , +.Xr index 3 , +.Xr rindex 3 , +.Xr stpcpy 3 , +.Xr strcasecmp 3 , +.Xr strcat 3 , +.Xr strchr 3 , +.Xr strcmp 3 , +.Xr strcpy 3 , +.Xr strcspn 3 , +.Xr strerror 3 , +.Xr strlen 3 , +.Xr strpbrk 3 , +.Xr strrchr 3 , +.Xr strsep 3 , +.Xr strspn 3 , +.Xr strstr 3 , +.Xr strtok 3 +.Sh STANDARDS +The +.Fn strcat , +.Fn strncat , +.Fn strchr , +.Fn strrchr , +.Fn strcmp , +.Fn strncmp , +.Fn strcpy , +.Fn strncpy , +.Fn strerror , +.Fn strlen , +.Fn strpbrk , +.Fn strspn , +.Fn strcspn , +.Fn strstr , +and +.Fn strtok +functions +conform to +.St -isoC . diff --git a/string/strlcat-fbsd.c b/string/strlcat-fbsd.c new file mode 100644 index 0000000..b8f0ff3 --- /dev/null +++ b/string/strlcat-fbsd.c @@ -0,0 +1,75 @@ +/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 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. + * + * 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. + */ + +#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 $"); + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff --git a/string/strlcpy-fbsd.c b/string/strlcpy-fbsd.c new file mode 100644 index 0000000..9383236 --- /dev/null +++ b/string/strlcpy-fbsd.c @@ -0,0 +1,70 @@ +/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 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. + * + * 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. + */ + +#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 $"); + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * 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; +{ + 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) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} diff --git a/string/strlcpy.3 b/string/strlcpy.3 new file mode 120000 index 0000000..c31802f --- /dev/null +++ b/string/strlcpy.3 @@ -0,0 +1 @@ +./strlcpy.3 \ No newline at end of file diff --git a/string/strlen-fbsd.c b/string/strlen-fbsd.c new file mode 100644 index 0000000..c67667d --- /dev/null +++ b/string/strlen-fbsd.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include + +size_t +strlen(str) + const char *str; +{ + const char *s; + + for (s = str; *s; ++s); + return(s - str); +} + diff --git a/string/strlen.3 b/string/strlen.3 new file mode 120000 index 0000000..de61b5f --- /dev/null +++ b/string/strlen.3 @@ -0,0 +1 @@ +./strlen.3 \ No newline at end of file diff --git a/string/strmode-fbsd.c b/string/strmode-fbsd.c new file mode 100644 index 0000000..2409b4e --- /dev/null +++ b/string/strmode-fbsd.c @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include +#include +#include + +void +strmode(mode, p) + mode_t mode; + char *p; +{ + /* print type */ + switch (mode & S_IFMT) { + case S_IFDIR: /* directory */ + *p++ = 'd'; + break; + case S_IFCHR: /* character special */ + *p++ = 'c'; + break; + case S_IFBLK: /* block special */ + *p++ = 'b'; + break; + case S_IFREG: /* regular */ + *p++ = '-'; + break; + case S_IFLNK: /* symbolic link */ + *p++ = 'l'; + break; + case S_IFSOCK: /* socket */ + *p++ = 's'; + break; +#ifdef S_IFIFO + case S_IFIFO: /* fifo */ + *p++ = 'p'; + break; +#endif +#ifdef S_IFWHT + case S_IFWHT: /* whiteout */ + *p++ = 'w'; + break; +#endif + default: /* unknown */ + *p++ = '?'; + break; + } + /* usr */ + if (mode & S_IRUSR) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWUSR) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXUSR | S_ISUID)) { + case 0: + *p++ = '-'; + break; + case S_IXUSR: + *p++ = 'x'; + break; + case S_ISUID: + *p++ = 'S'; + break; + case S_IXUSR | S_ISUID: + *p++ = 's'; + break; + } + /* group */ + if (mode & S_IRGRP) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWGRP) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXGRP | S_ISGID)) { + case 0: + *p++ = '-'; + break; + case S_IXGRP: + *p++ = 'x'; + break; + case S_ISGID: + *p++ = 'S'; + break; + case S_IXGRP | S_ISGID: + *p++ = 's'; + break; + } + /* other */ + if (mode & S_IROTH) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWOTH) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXOTH | S_ISVTX)) { + case 0: + *p++ = '-'; + break; + case S_IXOTH: + *p++ = 'x'; + break; + case S_ISVTX: + *p++ = 'T'; + break; + case S_IXOTH | S_ISVTX: + *p++ = 't'; + break; + } + *p++ = ' '; /* will be a '+' if ACL's implemented */ + *p = '\0'; +} diff --git a/string/strmode.3 b/string/strmode.3 new file mode 100644 index 0000000..535baa1 --- /dev/null +++ b/string/strmode.3 @@ -0,0 +1,151 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd July 28, 1994 +.Dt STRMODE 3 +.Os +.Sh NAME +.Nm strmode +.Nd convert inode status information into a symbolic string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft void +.Fo strmode +.Fa "int mode" +.Fa "char *bp" +.Fc +.Sh DESCRIPTION +The +.Fn strmode +function +converts a file +.Fa mode +(the type and permission information associated with an inode, see +.Xr stat 2 ) +into a symbolic string which is stored in the location referenced by +.Fa bp . +This stored string is eleven characters in length plus a trailing +.Dv NUL . +.Pp +The first character is the inode type, and will be one of the following: +.Pp +.Bl -tag -width flag -offset indent -compact +.It \- +regular file +.It b +block special +.It c +character special +.It d +directory +.It l +symbolic link +.It p +fifo +.It s +socket +.It w +whiteout +.It ? +unknown inode type +.El +.Pp +The next nine characters encode three sets of permissions, in three +characters each. +The first three characters are the permissions for the owner of the +file, the second three for the group the file belongs to, and the +third for the ``other'', or default, set of users. +.Pp +Permission checking is done as specifically as possible. +If read permission is denied to the owner of a file in the first set +of permissions, the owner of the file will not be able to read the file. +This is true even if the owner is in the file's group and the group +permissions allow reading or the ``other'' permissions allow reading. +.Pp +If the first character of the three character set is an ``r'', the file is +readable for that set of users; if a dash ``\-'', it is not readable. +.Pp +If the second character of the three character set is a ``w'', the file is +writable for that set of users; if a dash ``\-'', it is not writable. +.Pp +The third character is the first of the following characters that apply: +.Bl -tag -width xxxx +.It S +If the character is part of the owner permissions and the file is not +executable or the directory is not searchable by the owner, and the +set-user-id bit is set. +.It S +If the character is part of the group permissions and the file is not +executable or the directory is not searchable by the group, and the +set-group-id bit is set. +.It T +If the character is part of the other permissions and the file is not +executable or the directory is not searchable by others, and the ``sticky'' +.Pq Dv S_ISVTX +bit is set. +.It s +If the character is part of the owner permissions and the file is +executable or the directory searchable by the owner, and the set-user-id +bit is set. +.It s +If the character is part of the group permissions and the file is +executable or the directory searchable by the group, and the set-group-id +bit is set. +.It t +If the character is part of the other permissions and the file is +executable or the directory searchable by others, and the ``sticky'' +.Pq Dv S_ISVTX +bit is set. +.It x +The file is executable or the directory is searchable. +.It \- +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. +.Sh SEE ALSO +.Xr chmod 1 , +.Xr find 1 , +.Xr stat 2 , +.Xr getmode 3 , +.Xr setmode 3 +.Sh HISTORY +The +.Fn strmode +function first appeared in +.Bx 4.4 . diff --git a/string/strncat-fbsd.c b/string/strncat-fbsd.c new file mode 100644 index 0000000..e05e030 --- /dev/null +++ b/string/strncat-fbsd.c @@ -0,0 +1,66 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +/* + * Concatenate src on the end of dst. At most strlen(dst)+n+1 bytes + * are written at dst (at most n+1 bytes being appended). Return dst. + */ +char * +strncat(char * __restrict dst, const char * __restrict src, size_t n) +{ + if (n != 0) { + char *d = dst; + const char *s = src; + + while (*d != 0) + d++; + do { + if ((*d = *s++) == 0) + break; + d++; + } while (--n != 0); + *d = 0; + } + return (dst); +} diff --git a/string/strncmp-fbsd.c b/string/strncmp-fbsd.c new file mode 100644 index 0000000..6b0cfc8 --- /dev/null +++ b/string/strncmp-fbsd.c @@ -0,0 +1,58 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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[] = "@(#)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 $"); + +#include + +int +strncmp(s1, s2, n) + const char *s1, *s2; + size_t n; +{ + + if (n == 0) + return (0); + do { + if (*s1 != *s2++) + return (*(const unsigned char *)s1 - + *(const unsigned char *)(s2 - 1)); + if (*s1++ == 0) + break; + } while (--n != 0); + return (0); +} diff --git a/string/strncpy-fbsd.c b/string/strncpy-fbsd.c new file mode 100644 index 0000000..2fcc957 --- /dev/null +++ b/string/strncpy-fbsd.c @@ -0,0 +1,66 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +/* + * Copy src to dst, truncating or null-padding to always copy n bytes. + * Return dst. + */ +char * +strncpy(char * __restrict dst, const char * __restrict src, size_t n) +{ + if (n != 0) { + char *d = dst; + const char *s = src; + + do { + if ((*d++ = *s++) == 0) { + /* NUL pad the remaining n-1 bytes */ + while (--n != 0) + *d++ = 0; + break; + } + } while (--n != 0); + } + return (dst); +} diff --git a/string/strnstr-fbsd.c b/string/strnstr-fbsd.c new file mode 100644 index 0000000..abe2f8d --- /dev/null +++ b/string/strnstr-fbsd.c @@ -0,0 +1,72 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +/* + * Find the first occurrence of find in s, where the search is limited to the + * first slen characters of s. + */ +char * +strnstr(s, find, slen) + const char *s; + const char *find; + size_t slen; +{ + char c, sc; + size_t len; + + if ((c = *find++) != '\0') { + len = strlen(find); + do { + do { + if (slen-- < 1 || (sc = *s++) == '\0') + return (NULL); + } while (sc != c); + if (len > slen) + return (NULL); + } while (strncmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} diff --git a/string/strpbrk-fbsd.c b/string/strpbrk-fbsd.c new file mode 100644 index 0000000..fb0e1d4 --- /dev/null +++ b/string/strpbrk-fbsd.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1985, 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[] = "@(#)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 $"); + +#include + +/* + * Find the first occurrence in s1 of a character in s2 (excluding NUL). + */ +char * +strpbrk(s1, s2) + const char *s1, *s2; +{ + const char *scanp; + int c, sc; + + while ((c = *s1++) != 0) { + for (scanp = s2; (sc = *scanp++) != 0;) + if (sc == c) + return ((char *)(s1 - 1)); + } + return (NULL); +} diff --git a/string/strpbrk.3 b/string/strpbrk.3 new file mode 100644 index 0000000..81e579e --- /dev/null +++ b/string/strpbrk.3 @@ -0,0 +1,83 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt STRPBRK 3 +.Os +.Sh NAME +.Nm strpbrk +.Nd locate multiple characters in string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft char * +.Fo strpbrk +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Sh DESCRIPTION +The +.Fn strpbrk +function +locates in the null-terminated string +.Fa s1 +the first occurrence of any character in the string +.Fa s2 , +returning a pointer to this character. +If no characters from +.Fa s2 +occur anywhere in +.Fa s1 , +.Fn strpbrk +returns NULL. +.Sh SEE ALSO +.Xr memchr 3 , +.Xr strchr 3 , +.Xr strcspn 3 , +.Xr strrchr 3 , +.Xr strsep 3 , +.Xr strspn 3 , +.Xr strstr 3 , +.Xr strtok 3 +.Sh STANDARDS +The +.Fn strpbrk +function +conforms to +.St -isoC . diff --git a/string/strrchr-fbsd.c b/string/strrchr-fbsd.c new file mode 100644 index 0000000..bdf8f06 --- /dev/null +++ b/string/strrchr-fbsd.c @@ -0,0 +1,5 @@ +#include +__FBSDID("$FreeBSD: src/lib/libc/string/strrchr.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); + +#define STRRCHR +#include "rindex-fbsd.c" diff --git a/string/strrchr.3 b/string/strrchr.3 new file mode 100644 index 0000000..ef14451 --- /dev/null +++ b/string/strrchr.3 @@ -0,0 +1,94 @@ +.\" 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. +.\" +.\" @(#)strrchr.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: src/lib/libc/string/strrchr.3,v 1.9 2001/10/01 16:09:00 ru Exp $ +.\" +.Dd June 4, 1993 +.Dt STRRCHR 3 +.Os +.Sh NAME +.Nm strrchr +.Nd locate character in string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft char * +.Fo strrchr +.Fa "const char *s" +.Fa "int c" +.Fc +.Sh DESCRIPTION +The +.Fn strrchr +function +locates the last occurrence of +.Fa c +(converted to a char) +in the string +.Fa s . +If +.Fa c +is +.Ql \e0 , +.Fn strrchr +locates the terminating +.Ql \e0 . +.Sh RETURN VALUES +The +.Fn strrchr +function +returns a pointer to the character, +or a null +pointer if +.Fa c +does not occur anywhere in +.Fa s . +.Sh SEE ALSO +.Xr memchr 3 , +.Xr strchr 3 , +.Xr strcspn 3 , +.Xr strpbrk 3 , +.Xr strsep 3 , +.Xr strspn 3 , +.Xr strstr 3 , +.Xr strtok 3 +.Sh STANDARDS +The +.Fn strrchr +function +conforms to +.St -isoC . diff --git a/string/strsep-fbsd.c b/string/strsep-fbsd.c new file mode 100644 index 0000000..d0bccce --- /dev/null +++ b/string/strsep-fbsd.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 1990, 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[] = "@(#)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 $"); + +#include +#include + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char * +strsep(stringp, delim) + char **stringp; + const char *delim; +{ + char *s; + const char *spanp; + int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} diff --git a/string/strsep.3 b/string/strsep.3 new file mode 120000 index 0000000..5d61434 --- /dev/null +++ b/string/strsep.3 @@ -0,0 +1 @@ +./strsep.3 \ No newline at end of file diff --git a/string/strsignal-fbsd.c b/string/strsignal-fbsd.c new file mode 100644 index 0000000..523bb42 --- /dev/null +++ b/string/strsignal-fbsd.c @@ -0,0 +1,74 @@ +/* + * 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[] = "@(#)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 $"); + +#include +#include +#include + +char * +strsignal(num) + int num; +{ +#define UPREFIX "Unknown signal: " + static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ + unsigned int signum; + char *p, *t; + char tmp[40]; + + signum = num; /* convert to unsigned */ + if (signum < NSIG) + return ((char *)sys_siglist[signum]); + + /* Do this by hand, so we don't link to stdio(3). */ + t = tmp; + if (num < 0) + signum = -signum; + do { + *t++ = "0123456789"[signum % 10]; + } while (signum /= 10); + if (num < 0) + *t++ = '-'; + for (p = ebuf + sizeof(UPREFIX) - 1;;) { + *p++ = *--t; + if (t <= tmp) + break; + } + *p = '\0'; + return (ebuf); +} diff --git a/string/strspn-fbsd.c b/string/strspn-fbsd.c new file mode 100644 index 0000000..3b96365 --- /dev/null +++ b/string/strspn-fbsd.c @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2005 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/strspn.c,v 1.5 2005/04/02 18:52:44 das Exp $"); + +#include +#include +#include + +#define IDX(c) ((u_char)(c) / LONG_BIT) +#define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT)) + +size_t +strspn(const char *s, const char *charset) +{ + /* + * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to + * generate better code. Without them, gcc gets a little confused. + */ + const char *s1; + u_long bit; + u_long tbl[(UCHAR_MAX + 1) / LONG_BIT]; + int idx; + + if(*s == '\0') + return (0); + +#if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */ + tbl[3] = tbl[2] = tbl[1] = tbl[0] = 0; +#else + for (idx = 0; idx < sizeof(tbl) / sizeof(tbl[0]); idx++) + tbl[idx] = 0; +#endif + for (; *charset != '\0'; charset++) { + idx = IDX(*charset); + bit = BIT(*charset); + tbl[idx] |= bit; + } + + for(s1 = s; ; s1++) { + idx = IDX(*s1); + bit = BIT(*s1); + if ((tbl[idx] & bit) == 0) + break; + } + return (s1 - s); +} diff --git a/string/strspn.3 b/string/strspn.3 new file mode 100644 index 0000000..1528966 --- /dev/null +++ b/string/strspn.3 @@ -0,0 +1,83 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt STRSPN 3 +.Os +.Sh NAME +.Nm strspn +.Nd span a string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft size_t +.Fo strspn +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Sh DESCRIPTION +The +.Fn strspn +function +spans the initial part of the null-terminated string +.Fa s1 , +as long as the characters from +.Fa s1 +occur in string +.Fa s2 . +.Sh RETURN VALUES +The +.Fn strspn +function +returns the number of characters spanned. +.Sh SEE ALSO +.Xr memchr 3 , +.Xr strchr 3 , +.Xr strcspn 3 , +.Xr strpbrk 3 , +.Xr strrchr 3 , +.Xr strsep 3 , +.Xr strstr 3 , +.Xr strtok 3 +.Sh STANDARDS +The +.Fn strspn +function +conforms to +.St -isoC . diff --git a/string/strstr-fbsd.c b/string/strstr-fbsd.c new file mode 100644 index 0000000..f51d170 --- /dev/null +++ b/string/strstr-fbsd.c @@ -0,0 +1,66 @@ +/*- + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +/* + * Find the first occurrence of find in s. + */ +char * +strstr(s, find) + const char *s, *find; +{ + char c, sc; + size_t len; + + if ((c = *find++) != 0) { + len = strlen(find); + do { + do { + if ((sc = *s++) == 0) + return (NULL); + } while (sc != c); + } while (strncmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} diff --git a/string/strstr.3 b/string/strstr.3 new file mode 100644 index 0000000..1654b96 --- /dev/null +++ b/string/strstr.3 @@ -0,0 +1,177 @@ +.\" Copyright (c) 2001 Mike Barcroft +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd October 11, 2001 +.Dt STRSTR 3 +.Os +.Sh NAME +.Nm strcasestr , +.Nm strcasestr_l , +.Nm strnstr , +.Nm strstr +.Nd locate a substring in a string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft char * +.Fo strcasestr +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.Ft char * +.Fo strnstr +.Fa "const char *s1" +.Fa "const char *s2" +.Fa "size_t n" +.Fc +.Ft char * +.Fo strstr +.Fa "const char *s1" +.Fa "const char *s2" +.Fc +.In string.h +.In xlocale.h +.Ft char * +.Fo strcasestr_l +.Fa "const char *s1" +.Fa "const char *s2" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn strstr +function +locates the first occurrence of the null-terminated string +.Fa s2 +in the null-terminated string +.Fa s1 . +.Pp +The +.Fn strcasestr +function is similar to +.Fn strstr , +but ignores the case of both strings. +.Pp +The +.Fn strnstr +function +locates the first occurrence of the null-terminated string +.Fa s2 +in the string +.Fa s1 , +where not more than +.Fa n +characters are searched. +Characters that appear after a +.Ql \e0 +character are not searched. +Since the +.Fn strnstr +function is a +.Fx +specific API, it should only be used when portability is not a concern. +.Pp +While the +.Fn strcasestr +function uses the current locale, the +.Fn strcasestr_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +If +.Fa s2 +is an empty string, +.Fa s1 +is returned; +if +.Fa s2 +occurs nowhere in +.Fa s1 , +.Dv NULL +is returned; +otherwise a pointer to the first character of the first occurrence of +.Fa s2 +is returned. +.Sh EXAMPLES +The following sets the pointer +.Va ptr +to the +.Qq Li Bar Baz +portion of +.Va largestring : +.Bd -literal -offset indent +const char *largestring = "Foo Bar Baz"; +const char *smallstring = "Bar"; +char *ptr; + +ptr = strstr(largestring, smallstring); +.Ed +.Pp +The following sets the pointer +.Va ptr +to +.Dv NULL , +because only the first 4 characters of +.Va largestring +are searched: +.Bd -literal -offset indent +const char *largestring = "Foo Bar Baz"; +const char *smallstring = "Bar"; +char *ptr; + +ptr = strnstr(largestring, smallstring, 4); +.Ed +.Sh SEE ALSO +.Xr memchr 3 , +.Xr strchr 3 , +.Xr strcspn 3 , +.Xr strpbrk 3 , +.Xr strrchr 3 , +.Xr strsep 3 , +.Xr strspn 3 , +.Xr strtok 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn strstr +function +conforms to +.St -isoC . diff --git a/string/strtok-fbsd.c b/string/strtok-fbsd.c new file mode 100644 index 0000000..6aec194 --- /dev/null +++ b/string/strtok-fbsd.c @@ -0,0 +1,140 @@ +/*- + * Copyright (c) 1998 Softweyr LLC. All rights reserved. + * + * strtok_r, from Berkeley strtok + * Oct 13, 1998 by Wes Peters + * + * 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 + * notices, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, 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 SOFTWEYR LLC, 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[] = "@(#)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 $"); + +#include +#ifdef DEBUG_STRTOK +#include +#endif +#include + +char *__strtok_r(char *, const char *, char **); + +__weak_reference(__strtok_r, strtok_r); + +char * +__strtok_r(char *s, const char *delim, char **last) +{ + char *spanp, *tok; + int c, sc; + + if (s == NULL && (s = *last) == NULL) + return (NULL); + + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } + + if (c == 0) { /* no non-delimiter characters */ + *last = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = '\0'; + *last = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +char * +strtok(char *s, const char *delim) +{ + static char *last; + + return (__strtok_r(s, delim, &last)); +} + +#ifdef DEBUG_STRTOK +/* + * Test the tokenizer. + */ +int +main(void) +{ + char blah[80], test[80]; + char *brkb, *brkt, *phrase, *sep, *word; + + sep = "\\/:;=-"; + phrase = "foo"; + + printf("String tokenizer test:\n"); + strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function."); + for (word = strtok(test, sep); word; word = strtok(NULL, sep)) + printf("Next word is \"%s\".\n", word); + strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function."); + + for (word = strtok_r(test, sep, &brkt); word; + word = strtok_r(NULL, sep, &brkt)) { + strcpy(blah, "blah:blat:blab:blag"); + + for (phrase = strtok_r(blah, sep, &brkb); phrase; + phrase = strtok_r(NULL, sep, &brkb)) + printf("So far we're at %s:%s\n", word, phrase); + } + + return (0); +} + +#endif /* DEBUG_STRTOK */ diff --git a/string/strtok.3 b/string/strtok.3 new file mode 100644 index 0000000..7322193 --- /dev/null +++ b/string/strtok.3 @@ -0,0 +1,185 @@ +.\" Copyright (c) 1998 Softweyr LLC. All rights reserved. +.\" +.\" strtok_r, from Berkeley strtok +.\" Oct 13, 1998 by Wes Peters +.\" +.\" Copyright (c) 1988, 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 +.\" notices, this list of conditions and the following disclaimer. +.\" +.\" 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 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 +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, 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 SOFTWEYR LLC, 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. +.\" +.\" @(#)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 $ +.\" +.Dd November 27, 1998 +.Dt STRTOK 3 +.Os +.Sh NAME +.Nm strtok , strtok_r +.Nd string tokens +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft char * +.Fo strtok +.Fa "char *restrict str" +.Fa "const char *restrict sep" +.Fc +.Ft char * +.Fo strtok_r +.Fa "char *restrict str" +.Fa "const char *restrict sep" +.Fa "char **restrict lasts" +.Fc +.Sh DESCRIPTION +.Bf -symbolic +This interface is obsoleted by +.Xr strsep 3 . +.Ef +.Pp +The +.Fn strtok +function +is used to isolate sequential tokens in a null-terminated string, +.Fa str . +These tokens are separated in the string by at least one of the +characters in +.Fa sep . +The first time that +.Fn strtok +is called, +.Fa str +should be specified; subsequent calls, wishing to obtain further tokens +from the same string, should pass a null pointer instead. +The separator string, +.Fa sep , +must be supplied each time, and may change between calls. +.Pp +The implementation will behave as if no library function calls +.Fn strtok . +.Pp +The +.Fn strtok_r +function is a reentrant version of +.Fn strtok . +The context pointer +.Fa last +must be provided on each call. +The +.Fn strtok_r +function +may also be used to nest two parsing loops within one another, as +long as separate context pointers are used. +.Pp +The +.Fn strtok +and +.Fn strtok_r +functions +return a pointer to the beginning of each subsequent token in the string, +after replacing the token itself with a +.Dv NUL +character. +When no more tokens remain, a null pointer is returned. +.Sh EXAMPLES +The following uses +.Fn strtok_r +to parse two strings using separate contexts: +.Bd -literal +char test[80], blah[80]; +char *sep = "\e\e/:;=-"; +char *word, *phrase, *brkt, *brkb; + +strcpy(test, "This;is.a:test:of=the/string\e\etokenizer-function."); + +for (word = strtok_r(test, sep, &brkt); + word; + word = strtok_r(NULL, sep, &brkt)) +{ + strcpy(blah, "blah:blat:blab:blag"); + + for (phrase = strtok_r(blah, sep, &brkb); + phrase; + phrase = strtok_r(NULL, sep, &brkb)) + { + printf("So far we're at %s:%s\en", word, phrase); + } +} +.Ed +.Sh SEE ALSO +.Xr memchr 3 , +.Xr strchr 3 , +.Xr strcspn 3 , +.Xr strpbrk 3 , +.Xr strrchr 3 , +.Xr strsep 3 , +.Xr strspn 3 , +.Xr strstr 3 , +.Xr wcstok 3 +.Sh STANDARDS +The +.Fn strtok +function +conforms to +.St -isoC . +.Sh BUGS +The System V +.Fn strtok , +if handed a string containing only delimiter characters, +will not alter the next starting point, so that a call to +.Fn strtok +with a different (or empty) delimiter string +may return a +.Pf non- Dv NULL +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 new file mode 100644 index 0000000..d365c98 --- /dev/null +++ b/string/strxfrm-fbsd.c @@ -0,0 +1,155 @@ +/*- + * Copyright (c) 1995 Alex Tatmanjants + * at Electronni Visti IA, Kiev, Ukraine. + * 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 ``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 +__FBSDID("$FreeBSD: src/lib/libc/string/strxfrm.c,v 1.15 2002/09/06 11:24:06 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include "collate.h" + +/* + * In the non-POSIX case, we transform each character into a string of + * characters representing the character's priority. Since char is usually + * signed, we are limited by 7 bits per byte. To avoid zero, we need to add + * XFRM_OFFSET, so we can't use a full 7 bits. For simplicity, we choose 6 + * bits per byte. We choose 4 bytes per character as a good compromise + * between maximum coverage and minimum size. This gives 24 bits, or 16M + * priorities. So we choose COLLATE_MAX_PRIORITY to be (2^24 - 1). This + * this can be increased if more is needed. + */ + +#define XFRM_BYTES 4 +#define XFRM_OFFSET ('0') /* make all printable characters */ +#define XFRM_SHIFT 6 +#define XFRM_MASK ((1 << XFRM_SHIFT) - 1) + +static void +xfrm(unsigned char *p, int pri) +{ + + p[3] = (pri & XFRM_MASK) + XFRM_OFFSET; + pri >>= XFRM_SHIFT; + p[2] = (pri & XFRM_MASK) + XFRM_OFFSET; + pri >>= XFRM_SHIFT; + p[1] = (pri & XFRM_MASK) + XFRM_OFFSET; + pri >>= XFRM_SHIFT; + p[0] = (pri & XFRM_MASK) + XFRM_OFFSET; +} + +size_t +strxfrm_l(char * __restrict dest, const char * __restrict src, size_t len, + locale_t loc) +{ + size_t slen; + wchar_t *wcs, *xf[2]; + int sverrno; + + if (!*src && dest) { + if (len > 0) + *dest = '\0'; + return 0; + } + + 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; + } + + __collate_xfrm(wcs, xf, loc); + + slen = wcslen(xf[0]) * XFRM_BYTES; + if (xf[1]) + slen += (wcslen(xf[1]) + 1) * XFRM_BYTES; + if (len > 0) { + wchar_t *w = xf[0]; + int b = 0; + unsigned char buf[XFRM_BYTES]; + unsigned char *bp; + while (len > 1) { + if (!b) { + if (!*w) + break; + xfrm(bp = buf, *w++); + b = XFRM_BYTES; + } + *dest++ = *(char *)bp++; + b--; + len--; + } + if ((w = xf[1]) != NULL) { + xfrm(bp = buf, 0); + b = XFRM_BYTES; + while (len > 1) { + if (!b) + break; + *dest++ = *(char *)bp++; + b--; + len--; + } + b = 0; + while (len > 1) { + if (!b) { + if (!*w) + break; + xfrm(bp = buf, *w++); + b = XFRM_BYTES; + } + *dest++ = *(char *)bp++; + b--; + len--; + } + } + *dest = 0; + } + sverrno = errno; + free(wcs); + free(xf[0]); + free(xf[1]); + errno = sverrno; + + return slen; +} + +size_t +strxfrm(char * __restrict dest, const char * __restrict src, size_t len) +{ + return strxfrm_l(dest, src, len, __current_locale()); +} diff --git a/string/strxfrm.3 b/string/strxfrm.3 new file mode 100644 index 0000000..5412422 --- /dev/null +++ b/string/strxfrm.3 @@ -0,0 +1,123 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt STRXFRM 3 +.Os +.Sh NAME +.Nm strxfrm , +.Nm strxfrm_l +.Nd transform a string under locale +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft size_t +.Fo strxfrm +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fa "size_t n" +.Fc +.In string.h +.In xlocale.h +.Ft size_t +.Fo strxfrm_l +.Fa "char *restrict s1" +.Fa "const char *restrict s2" +.Fa "size_t n" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn strxfrm +function transforms a null-terminated string pointed to by +.Fa s2 +according to the current locale collation if any, +then copies the transformed string +into +.Fa s1 . +Not more than +.Fa n +characters are copied into +.Fa s1 , +including the terminating null character added. +If +.Fa n +is set to 0 +(it helps to determine an actual size needed +for transformation), +.Fa s1 +is permitted to be a NULL pointer. +.Pp +Comparing two strings using +.Fn strcmp +after +.Fn strxfrm +is equal to comparing +two original strings with +.Fn strcoll . +.Pp +Although the +.Fn strxfrm +function uses the current locale, the +.Fn strxfrm_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +Upon successful completion, +.Fn strxfrm +returns the length of the transformed string not including +the terminating null character. +If this value is +.Fa n +or more, the contents of +.Fa s1 +are indeterminate. +.Sh SEE ALSO +.Xr setlocale 3 , +.Xr strcmp 3 , +.Xr strcoll 3 , +.Xr wcsxfrm 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn strxfrm +function +conforms to +.St -isoC . diff --git a/string/swab-fbsd.c b/string/swab-fbsd.c new file mode 100644 index 0000000..41d3b24 --- /dev/null +++ b/string/swab-fbsd.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jeffrey Mogul. + * + * 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[] = "@(#)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 $"); + +#include + +void +swab(const void * __restrict from, void * __restrict to, ssize_t len) +{ + unsigned long temp; + int n; + char *fp, *tp; + + if (len <= 0) + return; + n = len >> 1; + fp = (char *)from; + tp = (char *)to; +#define STEP temp = *fp++,*tp++ = *fp++,*tp++ = temp + /* round to multiple of 8 */ + for (; n & 0x7; --n) + STEP; + for (n >>= 3; n > 0; --n) { + STEP; STEP; STEP; STEP; + STEP; STEP; STEP; STEP; + } +} diff --git a/string/swab.3 b/string/swab.3 new file mode 100644 index 0000000..42b8a9d --- /dev/null +++ b/string/swab.3 @@ -0,0 +1,90 @@ +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the 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. +.\" +.\" @(#)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 $ +.\" +.Dd June 4, 1993 +.Dt SWAB 3 +.Os +.Sh NAME +.Nm swab +.Nd swap adjacent bytes +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft void +.Fo swab +.Fa "const void *restrict src" +.Fa "void *restrict dest" +.Fa "ssize_t nbytes" +.Fc +.Sh DESCRIPTION +The function +.Fn swab +copies +.Fa nbytes +bytes from the location referenced by +.Fa src +to the location referenced by +.Fa dest , +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 +.Fa nbytes +has changed. +.Sh SEE ALSO +.Xr bzero 3 , +.Xr memset 3 , +.Xr compat 5 +.Sh HISTORY +A +.Fn swab +function appeared in +.At v7 . diff --git a/string/wcscat-fbsd.c b/string/wcscat-fbsd.c new file mode 100644 index 0000000..cf7812f --- /dev/null +++ b/string/wcscat-fbsd.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wcscat.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include + +wchar_t * +wcscat(s1, s2) + wchar_t * __restrict s1; + const wchar_t * __restrict s2; +{ + wchar_t *cp; + + cp = s1; + while (*cp != L'\0') + cp++; + while ((*cp++ = *s2++) != L'\0') + ; + + return (s1); +} diff --git a/string/wcschr-fbsd.c b/string/wcschr-fbsd.c new file mode 100644 index 0000000..0fae132 --- /dev/null +++ b/string/wcschr-fbsd.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2002 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/wcschr.c,v 1.7 2002/10/23 10:47:47 tjr Exp $"); + +#include + +wchar_t * +wcschr(const wchar_t *s, wchar_t c) +{ + + while (*s != c && *s != L'\0') + s++; + if (*s == c) + return ((wchar_t *)s); + return (NULL); +} diff --git a/string/wcscmp-fbsd.c b/string/wcscmp-fbsd.c new file mode 100644 index 0000000..20152b2 --- /dev/null +++ b/string/wcscmp-fbsd.c @@ -0,0 +1,61 @@ +/*- + * 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. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strcmp.c 8.1 (Berkeley) 6/4/93"; +#if 0 +__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 $"); + +#include + +/* + * Compare strings. + */ +int +wcscmp(s1, s2) + const wchar_t *s1, *s2; +{ + + while (*s1 == *s2++) + if (*s1++ == 0) + return (0); + /* XXX assumes wchar_t = int */ + return (*(const unsigned int *)s1 - *(const unsigned int *)--s2); +} diff --git a/string/wcscoll-fbsd.c b/string/wcscoll-fbsd.c new file mode 100644 index 0000000..ce09e41 --- /dev/null +++ b/string/wcscoll-fbsd.c @@ -0,0 +1,248 @@ +/*- + * Copyright (c) 2002 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/wcscoll.c,v 1.3 2004/04/07 09:47:56 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include "collate.h" + +#define NOTFORWARD (DIRECTIVE_BACKWARD | DIRECTIVE_POSITION) + +int +wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t loc) +{ + int sverrno; + int len, len2, prim, prim2, sec, sec2, ret, ret2; + const wchar_t *t, *t2; + wchar_t *tt = NULL, *tt2 = NULL; + wchar_t *tr = NULL, *tr2 = NULL; + wchar_t w, w2; + struct __collate_st_info *info; + + NORMALIZE_LOCALE(loc); + if (loc->__collate_load_error) + /* + * Locale has no special collating order or could not be + * loaded, do a fast binary comparison. + */ + return (wcscmp(ws1, ws2)); + + info = &loc->__lc_collate->__info; + len = len2 = 1; + ret = ret2 = 0; + + if ((info->directive[0] & NOTFORWARD) || + (info->directive[1] & NOTFORWARD) || + (!(info->flags && COLLATE_SUBST_DUP) && + (info->subst_count[0] > 0 || info->subst_count[1] > 0))) { + int direc, pass; + for(pass = 0; pass < info->directive_count; pass++) { + direc = info->directive[pass]; + if (pass == 0 || !(info->flags & COLLATE_SUBST_DUP)) { + free(tt); + tt = __collate_substitute(ws1, pass, loc); + free(tt2); + tt2 = tt ? __collate_substitute(ws2, pass, loc) : NULL; + } + if (direc & DIRECTIVE_BACKWARD) { + wchar_t *bp, *fp, c; + tr = __collate_wcsdup(tt ? tt : ws1); + bp = tr; + fp = tr + wcslen(tr) - 1; + while(bp < fp) { + c = *bp; + *bp++ = *fp; + *fp-- = c; + } + tr2 = __collate_wcsdup(tt2 ? tt2 : ws2); + bp = tr2; + fp = tr2 + wcslen(tr2) - 1; + while(bp < fp) { + c = *bp; + *bp++ = *fp; + *fp-- = c; + } + t = (const wchar_t *)tr; + t2 = (const wchar_t *)tr2; + } else if (tt) { + t = (const wchar_t *)tt; + t2 = (const wchar_t *)tt2; + } else { + t = (const wchar_t *)ws1; + t2 = (const wchar_t *)ws2; + } + if(direc & DIRECTIVE_POSITION) { + while(*t && *t2) { + prim = prim2 = 0; + __collate_lookup_which(t, &len, &prim, pass, loc); + if (prim <= 0) { + if (prim < 0) { + errno = EINVAL; + ret = -1; + goto end; + } + prim = COLLATE_MAX_PRIORITY; + } + __collate_lookup_which(t2, &len2, &prim2, pass, loc); + if (prim2 <= 0) { + if (prim2 < 0) { + errno = EINVAL; + ret = -1; + goto end; + } + prim2 = COLLATE_MAX_PRIORITY; + } + if(prim != prim2) { + ret = prim - prim2; + goto end; + } + t += len; + t2 += len2; + } + } else { + while(*t && *t2) { + prim = prim2 = 0; + while(*t) { + __collate_lookup_which(t, &len, &prim, pass, loc); + if(prim > 0) + break; + if (prim < 0) { + errno = EINVAL; + ret = -1; + goto end; + } + t += len; + } + while(*t2) { + __collate_lookup_which(t2, &len2, &prim2, pass, loc); + if(prim2 > 0) + break; + if (prim2 < 0) { + errno = EINVAL; + ret = -1; + goto end; + } + t2 += len2; + } + if(!prim || !prim2) + break; + if(prim != prim2) { + ret = prim - prim2; + goto end; + } + t += len; + t2 += len2; + } + } + if(!*t) { + if(*t2) { + ret = -(int)*t2; + goto end; + } + } else { + ret = *t; + goto end; + } + } + ret = 0; + goto end; + } + + /* optimized common case: order_start forward;forward and duplicate + * (or no) substitute tables */ + tt = __collate_substitute(ws1, 0, loc); + if (tt == NULL) { + tt2 = NULL; + t = (const wchar_t *)ws1; + t2 = (const wchar_t *)ws2; + } else { + tt2 = __collate_substitute(ws2, 0, loc); + t = (const wchar_t *)tt; + t2 = (const wchar_t *)tt2; + } + while(*t && *t2) { + prim = prim2 = 0; + while(*t) { + __collate_lookup_l(t, &len, &prim, &sec, loc); + if (prim > 0) + break; + if (prim < 0) { + errno = EINVAL; + ret = -1; + goto end; + } + t += len; + } + while(*t2) { + __collate_lookup_l(t2, &len2, &prim2, &sec2, loc); + if (prim2 > 0) + break; + if (prim2 < 0) { + errno = EINVAL; + ret = -1; + goto end; + } + t2 += len2; + } + if(!prim || !prim2) + break; + if(prim != prim2) { + ret = prim - prim2; + goto end; + } + if(!ret2) + ret2 = sec - sec2; + t += len; + t2 += len2; + } + if(!*t && *t2) + ret = -(int)*t2; + else if(*t && !*t2) + ret = *t; + else if(!*t && !*t2) + ret = ret2; + end: + sverrno = errno; + free(tt); + free(tt2); + free(tr); + free(tr2); + errno = sverrno; + + return ret; +} + +int +wcscoll(const wchar_t *ws1, const wchar_t *ws2) +{ + return wcscoll_l(ws1, ws2, __current_locale()); +} diff --git a/string/wcscoll.3 b/string/wcscoll.3 new file mode 100644 index 0000000..5ffe761 --- /dev/null +++ b/string/wcscoll.3 @@ -0,0 +1,133 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd October 4, 2002 +.Dt WCSCOLL 3 +.Os +.Sh NAME +.Nm wcscoll , +.Nm wcscoll_l +.Nd compare wide strings according to current collation +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft int +.Fo wcscoll +.Fa "const wchar_t *ws1" +.Fa "const wchar_t *ws2" +.Fc +.In wchar.h +.In xlocale.h +.Ft int +.Fo wcscoll_l +.Fa "const wchar_t *ws1" +.Fa "const wchar_t *ws2" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wcscoll +function compares the null-terminated strings +.Fa ws1 +and +.Fa ws2 , +according to the current locale's collation order. +In the +.Dq Li C +locale, +.Fn wcscoll +is equivalent to +.Fn wcscmp . +.Pp +Although the +.Fn wcscoll +function uses the current locale, the +.Fn wcscoll_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn wcscoll +function +returns an integer greater than, equal to, or less than 0, +if +.Fa ws1 +is greater than, equal to, or less than +.Fa ws2 . +.Pp +No return value is reserved to indicate errors; +callers should set +.Va errno +to 0 before calling +.Fn wcscoll . +If it is non-zero upon return from +.Fn wcscoll , +an error has occurred. +.Sh ERRORS +The +.Fn wcscoll +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid wide character code was specified. +.It Bq Er ENOMEM +Cannot allocate enough memory for temporary buffers. +.El +.Sh SEE ALSO +.Xr setlocale 3 , +.Xr strcoll 3 , +.Xr wcscmp 3 , +.Xr wcsxfrm 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn wcscoll +function +conforms to +.St -isoC-99 . +.Sh BUGS +The current implementation of +.Fn wcscoll +only works in single-byte +.Dv LC_CTYPE +locales, and falls back to using +.Fn wcscmp +in locales with extended character sets. diff --git a/string/wcscpy-fbsd.c b/string/wcscpy-fbsd.c new file mode 100644 index 0000000..b4c236a --- /dev/null +++ b/string/wcscpy-fbsd.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wcscpy.c,v 1.2 2000/12/21 04:51:09 itojun Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include + +wchar_t * +wcscpy(s1, s2) + wchar_t * __restrict s1; + const wchar_t * __restrict s2; +{ + wchar_t *cp; + + cp = s1; + while ((*cp++ = *s2++) != L'\0') + ; + + return (s1); +} diff --git a/string/wcscspn-fbsd.c b/string/wcscspn-fbsd.c new file mode 100644 index 0000000..c16f270 --- /dev/null +++ b/string/wcscspn-fbsd.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wcscspn.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include + +size_t +wcscspn(s, set) + const wchar_t *s; + const wchar_t *set; +{ + const wchar_t *p; + const wchar_t *q; + + p = s; + while (*p) { + q = set; + while (*q) { + if (*p == *q) + goto done; + q++; + } + p++; + } + +done: + return (p - s); +} diff --git a/string/wcslcat-fbsd.c b/string/wcslcat-fbsd.c new file mode 100644 index 0000000..f3b9a63 --- /dev/null +++ b/string/wcslcat-fbsd.c @@ -0,0 +1,77 @@ +/* + * 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. + * + * 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. + * + * from OpenBSD: strlcat.c,v 1.3 2000/11/24 11:10:02 itojun Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include +#include + +/* + * Appends src to string dst of size siz (unlike wcsncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns wcslen(initial dst) + wcslen(src); if retval >= siz, + * truncation occurred. + */ +size_t +wcslcat(dst, src, siz) + wchar_t *dst; + const wchar_t *src; + size_t siz; +{ + wchar_t *d = dst; + const wchar_t *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (*d != '\0' && n-- != 0) + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + wcslen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff --git a/string/wcslcpy-fbsd.c b/string/wcslcpy-fbsd.c new file mode 100644 index 0000000..273c8fd --- /dev/null +++ b/string/wcslcpy-fbsd.c @@ -0,0 +1,73 @@ +/* + * 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. + * + * 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. + * + * from OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns wcslen(src); if retval >= siz, truncation occurred. + */ +size_t +wcslcpy(dst, src, siz) + wchar_t *dst; + const wchar_t *src; + size_t siz; +{ + wchar_t *d = dst; + const wchar_t *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} diff --git a/string/wcslen-fbsd.c b/string/wcslen-fbsd.c new file mode 100644 index 0000000..5e462a1 --- /dev/null +++ b/string/wcslen-fbsd.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wcslen.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include + +size_t +wcslen(s) + const wchar_t *s; +{ + const wchar_t *p; + + p = s; + while (*p) + p++; + + return p - s; +} diff --git a/string/wcsncat-fbsd.c b/string/wcsncat-fbsd.c new file mode 100644 index 0000000..5abb442 --- /dev/null +++ b/string/wcsncat-fbsd.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wcsncat.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include + +wchar_t * +wcsncat(s1, s2, n) + wchar_t * __restrict s1; + const wchar_t * __restrict s2; + size_t n; +{ + wchar_t *p; + wchar_t *q; + const wchar_t *r; + + p = s1; + while (*p) + p++; + q = p; + r = s2; + while (*r && n) { + *q++ = *r++; + n--; + } + *q = '\0'; + return s1; +} diff --git a/string/wcsncmp-fbsd.c b/string/wcsncmp-fbsd.c new file mode 100644 index 0000000..7043e06 --- /dev/null +++ b/string/wcsncmp-fbsd.c @@ -0,0 +1,63 @@ +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the 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 +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +int +wcsncmp(s1, s2, n) + const wchar_t *s1, *s2; + size_t n; +{ + + if (n == 0) + return (0); + do { + if (*s1 != *s2++) { + /* XXX assumes wchar_t = int */ + return (*(const unsigned int *)s1 - + *(const unsigned int *)--s2); + } + if (*s1++ == 0) + break; + } while (--n != 0); + return (0); +} diff --git a/string/wcsncpy-fbsd.c b/string/wcsncpy-fbsd.c new file mode 100644 index 0000000..fb9cef0 --- /dev/null +++ b/string/wcsncpy-fbsd.c @@ -0,0 +1,68 @@ +/*- + * 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. + */ + +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +/* + * Copy src to dst, truncating or null-padding to always copy n bytes. + * Return dst. + */ +wchar_t * +wcsncpy(wchar_t * __restrict dst, const wchar_t * __restrict src, size_t n) +{ + if (n != 0) { + wchar_t *d = dst; + const wchar_t *s = src; + + do { + if ((*d++ = *s++) == L'\0') { + /* NUL pad the remaining n-1 bytes */ + while (--n != 0) + *d++ = L'\0'; + break; + } + } while (--n != 0); + } + return (dst); +} diff --git a/string/wcspbrk-fbsd.c b/string/wcspbrk-fbsd.c new file mode 100644 index 0000000..5502440 --- /dev/null +++ b/string/wcspbrk-fbsd.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wcspbrk.c,v 1.2 2000/12/21 05:07:25 itojun Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include + +wchar_t * +wcspbrk(s, set) + const wchar_t *s; + const wchar_t *set; +{ + const wchar_t *p; + const wchar_t *q; + + p = s; + while (*p) { + q = set; + while (*q) { + if (*p == *q) { + /* LINTED interface specification */ + return (wchar_t *)p; + } + q++; + } + p++; + } + return NULL; +} diff --git a/string/wcsrchr-fbsd.c b/string/wcsrchr-fbsd.c new file mode 100644 index 0000000..093dd08 --- /dev/null +++ b/string/wcsrchr-fbsd.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2002 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/wcsrchr.c,v 1.7 2002/10/23 10:52:04 tjr Exp $"); + +#include + +wchar_t * +wcsrchr(const wchar_t *s, wchar_t c) +{ + const wchar_t *last; + + last = NULL; + for (;;) { + if (*s == c) + last = s; + if (*s == L'\0') + break; + s++; + } + + return ((wchar_t *)last); +} diff --git a/string/wcsspn-fbsd.c b/string/wcsspn-fbsd.c new file mode 100644 index 0000000..d4101c7 --- /dev/null +++ b/string/wcsspn-fbsd.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wcsspn.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include + +size_t +wcsspn(s, set) + const wchar_t *s; + const wchar_t *set; +{ + const wchar_t *p; + const wchar_t *q; + + p = s; + while (*p) { + q = set; + while (*q) { + if (*p == *q) + break; + q++; + } + if (!*q) + goto done; + p++; + } + +done: + return (p - s); +} diff --git a/string/wcsstr-fbsd.c b/string/wcsstr-fbsd.c new file mode 100644 index 0000000..0533e59 --- /dev/null +++ b/string/wcsstr-fbsd.c @@ -0,0 +1,67 @@ +/*- + * 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. + */ + +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +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 $"); + +#include + +/* + * Find the first occurrence of find in s. + */ +wchar_t * +wcsstr(const wchar_t * __restrict s, const wchar_t * __restrict find) +{ + wchar_t c, sc; + size_t len; + + if ((c = *find++) != 0) { + len = wcslen(find); + do { + do { + if ((sc = *s++) == L'\0') + return (NULL); + } while (sc != c); + } while (wcsncmp(s, find, len) != 0); + s--; + } + return ((wchar_t *)s); +} diff --git a/string/wcstok-fbsd.c b/string/wcstok-fbsd.c new file mode 100644 index 0000000..5781adb --- /dev/null +++ b/string/wcstok-fbsd.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 1998 Softweyr LLC. All rights reserved. + * + * strtok_r, from Berkeley strtok + * Oct 13, 1998 by Wes Peters + * + * 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 + * notices, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, 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 SOFTWEYR LLC, 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/wcstok.c,v 1.2 2003/03/12 06:41:49 tjr Exp $"); + +#include + +wchar_t * +wcstok(wchar_t * __restrict s, const wchar_t * __restrict delim, + wchar_t ** __restrict last) +{ + const wchar_t *spanp; + wchar_t *tok; + wchar_t c, sc; + + if (s == NULL && (s = *last) == NULL) + return (NULL); + + /* + * Skip (span) leading delimiters (s += wcsspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = delim; (sc = *spanp++) != L'\0';) { + if (c == sc) + goto cont; + } + + if (c == L'\0') { /* no non-delimiter characters */ + *last = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += wcscspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == L'\0') + s = NULL; + else + s[-1] = L'\0'; + *last = s; + return (tok); + } + } while (sc != L'\0'); + } + /* NOTREACHED */ +} diff --git a/string/wcstok.3 b/string/wcstok.3 new file mode 100644 index 0000000..2b8de3f --- /dev/null +++ b/string/wcstok.3 @@ -0,0 +1,137 @@ +.\" Copyright (c) 1998 Softweyr LLC. All rights reserved. +.\" +.\" strtok_r, from Berkeley strtok +.\" Oct 13, 1998 by Wes Peters +.\" +.\" Copyright (c) 1988, 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 +.\" notices, this list of conditions and the following disclaimer. +.\" +.\" 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 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 +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, 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 SOFTWEYR LLC, 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/string/wcstok.3,v 1.4 2002/10/15 09:49:54 tjr Exp $ +.\" +.Dd October 3, 2002 +.Dt WCSTOK 3 +.Os +.Sh NAME +.Nm wcstok +.Nd split wide-character string into tokens +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft wchar_t * +.Fo wcstok +.Fa "wchar_t *restrict ws1" +.Fa "const wchar_t *restrict ws2" +.Fa "wchar_t **restrict ptr" +.Fc +.Sh DESCRIPTION +The +.Fn wcstok +function +is used to isolate sequential tokens in a null-terminated wide character +string, +.Fa ws1 . +These tokens are separated in the string by at least one of the +characters in +.Fa ws2 . +The first time that +.Fn wcstok +is called, +.Fa ws1 +should be specified; subsequent calls, wishing to obtain further tokens +from the same string, should pass a null pointer instead. +The separator string, +.Fa ws2 , +must be supplied each time, and may change between calls. +The context pointer, +.Fa ptr , +must be provided on each call. +.Pp +The +.Fn wcstok +function is the wide character counterpart of the +.Fn strtok_r +function. +.Sh RETURN VALUES +The +.Fn wcstok +function +returns a pointer to the beginning of each subsequent token in the string, +after replacing the token itself with a null wide character (L'\e0'). +When no more tokens remain, a null pointer is returned. +.Sh EXAMPLES +The following code fragment splits a wide character string on +.Tn ASCII +space, tab, and newline characters, +writing the resulting tokens to standard output: +.Bd -literal -offset indent +const wchar_t *seps = L" \et\en"; +wchar_t *last, *tok, text[] = L" \enone\ettwo\et\etthree \en"; + +for (tok = wcstok(text, seps, &last); tok != NULL; + tok = wcstok(NULL, seps, &last)) + wprintf(L"%ls\en", tok); +.Ed +.Sh COMPATIBILITY +Some early implementations of +.Fn wcstok +omit the +context pointer argument, +.Fa ptr , +and maintain state across calls in a static variable like +.Fn strtok +does. +.Sh SEE ALSO +.Xr strtok 3 , +.Xr wcschr 3 , +.Xr wcscspn 3 , +.Xr wcspbrk 3 , +.Xr wcsrchr 3 , +.Xr wcsspn 3 +.Sh STANDARDS +The +.Fn wcstok +function +conforms to +.St -isoC-99 . diff --git a/locale/FreeBSD/isctype.c b/string/wcswidth-fbsd.c similarity index 53% rename from locale/FreeBSD/isctype.c rename to string/wcswidth-fbsd.c index d718b77..798590d 100644 --- a/locale/FreeBSD/isctype.c +++ b/string/wcswidth-fbsd.c @@ -39,195 +39,33 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)isctype.c 8.3 (Berkeley) 2/24/94"; -#endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/isctype.c,v 1.9 2002/08/17 20:03:44 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/wcswidth.c,v 1.6 2002/08/20 02:06:28 ache Exp $"); -#include +#include "xlocale_private.h" -#undef digittoint -int -digittoint(c) - int c; -{ - return (__maskrune(c, 0xFF)); -} +#include -#undef isalnum int -isalnum(c) - int c; +wcswidth_l(const wchar_t *pwcs, size_t n, locale_t loc) { - return (__istype(c, _CTYPE_A|_CTYPE_D)); -} + wchar_t wc; + int len, l; -#undef isalpha -int -isalpha(c) - int c; -{ - return (__istype(c, _CTYPE_A)); + NORMALIZE_LOCALE(loc); + len = 0; + while (n-- > 0 && (wc = *pwcs++) != L'\0') { + if ((l = wcwidth_l(wc, loc)) < 0) + return (-1); + len += l; + } + return (len); } -#undef isascii -int -isascii(c) - int c; -{ - return ((c & ~0x7F) == 0); -} - -#undef isblank -int -isblank(c) - int c; -{ - return (__istype(c, _CTYPE_B)); -} - -#undef iscntrl -int -iscntrl(c) - int c; -{ - return (__istype(c, _CTYPE_C)); -} - -#undef isdigit -int -isdigit(c) - int c; -{ - return (__isctype(c, _CTYPE_D)); -} - -#undef isgraph -int -isgraph(c) - int c; -{ - return (__istype(c, _CTYPE_G)); -} - -#undef ishexnumber -int -ishexnumber(c) - int c; -{ - return (__istype(c, _CTYPE_X)); -} - -#undef isideogram -int -isideogram(c) - int c; -{ - return (__istype(c, _CTYPE_I)); -} - -#undef islower -int -islower(c) - int c; -{ - return (__istype(c, _CTYPE_L)); -} - -#undef isnumber -int -isnumber(c) - int c; -{ - return (__istype(c, _CTYPE_D)); -} - -#undef isphonogram -int -isphonogram(c) - int c; -{ - return (__istype(c, _CTYPE_Q)); -} - -#undef isprint -int -isprint(c) - int c; -{ - return (__istype(c, _CTYPE_R)); -} - -#undef ispunct -int -ispunct(c) - int c; -{ - return (__istype(c, _CTYPE_P)); -} - -#undef isrune -int -isrune(c) - int c; -{ - return (__istype(c, 0xFFFFFF00L)); -} - -#undef isspace -int -isspace(c) - int c; -{ - return (__istype(c, _CTYPE_S)); -} - -#undef isspecial -int -isspecial(c) - int c; -{ - return (__istype(c, _CTYPE_T)); -} - -#undef isupper -int -isupper(c) - int c; -{ - return (__istype(c, _CTYPE_U)); -} - -#undef isxdigit -int -isxdigit(c) - int c; -{ - return (__isctype(c, _CTYPE_X)); -} - -#undef toascii -int -toascii(c) - int c; -{ - return (c & 0x7F); -} - -#undef tolower -int -tolower(c) - int c; -{ - return (__tolower(c)); -} -#undef toupper int -toupper(c) - int c; +wcswidth(const wchar_t *pwcs, size_t n) { - return (__toupper(c)); + return wcswidth_l(pwcs, n, __current_locale()); } diff --git a/string/wcswidth.3 b/string/wcswidth.3 new file mode 100644 index 0000000..07eb058 --- /dev/null +++ b/string/wcswidth.3 @@ -0,0 +1,83 @@ +.\" Copyright (c) 2002 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. +.\" +.\" $FreeBSD: src/lib/libc/string/wcswidth.3,v 1.2 2002/12/09 14:04:05 ru Exp $ +.\" +.Dd August 20, 2002 +.Dt WCSWIDTH 3 +.Os +.Sh NAME +.Nm wcswidth , +.Nm wcswidth_l +.Nd "number of column positions in wide-character string" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft int +.Fo wcswidth +.Fa "const wchar_t *pwcs" +.Fa "size_t n" +.Fc +.In wchar.h +.In xlocale.h +.Ft int +.Fo wcswidth_l +.Fa "const wchar_t *pwcs" +.Fa "size_t n" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wcswidth +function determines the number of column positions required for the first +.Fa n +characters of +.Fa pwcs , +or until a null wide character (L'\e0') is encountered. +.Pp +Although the +.Fn wcswidth +function uses the current locale, the +.Fn wcswidth_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +The +.Fn wcswidth +function returns 0 if +.Fa pwcs +is an empty string (L""), +\-1 if a non-printing wide character is encountered; +otherwise, it returns the number of column positions occupied. +.Sh SEE ALSO +.Xr iswprint 3 , +.Xr wcwidth 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn wcswidth +function conforms to +.St -p1003.1-2001 . diff --git a/string/wcsxfrm-fbsd.c b/string/wcsxfrm-fbsd.c new file mode 100644 index 0000000..eae9360 --- /dev/null +++ b/string/wcsxfrm-fbsd.c @@ -0,0 +1,109 @@ +/*- + * Copyright (c) 1995 Alex Tatmanjants + * at Electronni Visti IA, Kiev, Ukraine. + * 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 ``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 +#if 0 +__FBSDID("FreeBSD: src/lib/libc/string/strxfrm.c,v 1.15 2002/09/06 11:24:06 tjr Exp "); +#endif +__FBSDID("$FreeBSD: src/lib/libc/string/wcsxfrm.c,v 1.3 2004/04/07 09:47:56 tjr Exp $"); + +#include "xlocale_private.h" + +#include +#include +#include +#include +#include "collate.h" + +#define WCS_XFRM_OFFSET 1 + +size_t +wcsxfrm_l(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len, + locale_t loc) +{ + size_t slen; + wchar_t *xf[2]; + int sverrno; + + if (*src == L'\0') { + if (len != 0) + *dest = L'\0'; + return (0); + } + + NORMALIZE_LOCALE(loc); + if (loc->__collate_load_error) { + slen = wcslen(src); + if (len > 0) { + if (slen < len) + wcscpy(dest, src); + else { + wcsncpy(dest, src, len - 1); + dest[len - 1] = L'\0'; + } + } + return (slen); + } + + __collate_xfrm(src, xf, loc); + + slen = wcslen(xf[0]); + if (xf[1]) + slen += wcslen(xf[1]) + 1; + if (len > 0) { + wchar_t *w = xf[0]; + while (len > 1) { + if (!*w) + break; + *dest++ = *w++ + WCS_XFRM_OFFSET; + len--; + } + if ((w = xf[1]) != NULL) { + if (len > 1) + *dest++ = WCS_XFRM_OFFSET; + while (len > 1) { + if (!*w) + break; + *dest++ = *w++ + WCS_XFRM_OFFSET; + len--; + } + } + *dest = 0; + } + sverrno = errno; + free(xf[0]); + free(xf[1]); + errno = sverrno; + + return (slen); +} + +size_t +wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len) +{ + return wcsxfrm_l(dest, src, len, __current_locale()); +} diff --git a/string/wcsxfrm.3 b/string/wcsxfrm.3 new file mode 100644 index 0000000..f54a02b --- /dev/null +++ b/string/wcsxfrm.3 @@ -0,0 +1,148 @@ +.\" 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. +.\" +.\" @(#)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 $ +.\" +.Dd October 4, 2002 +.Dt WCSXFRM 3 +.Os +.Sh NAME +.Nm wcsxfrm , +.Nm wcsxfrm_l +.Nd transform a wide string under locale +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo wcsxfrm +.Fa "wchar_t *restrict ws1" +.Fa "const wchar_t *restrict ws2" +.Fa "size_t n" +.Fc +.In wchar.h +.In xlocale.h +.Ft size_t +.Fo wcsxfrm_l +.Fa "wchar_t *restrict ws1" +.Fa "const wchar_t *restrict ws2" +.Fa "size_t n" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn wcsxfrm +function transforms a null-terminated wide character string pointed to by +.Fa ws2 , +according to the current locale's collation order, +then copies the transformed string into +.Fa ws1 . +No more than +.Fa n +wide characters are copied into +.Fa ws1 , +including the terminating null character. +If +.Fa n +is set to 0 +(it helps to determine an actual size needed +for transformation), +.Fa ws1 +is permitted to be a +.Dv NULL +pointer. +.Pp +Comparing two strings using +.Fn wcscmp +after +.Fn wcsxfrm +is equivalent to comparing +two original strings with +.Fn wcscoll . +.Pp +Although the +.Fn wcsxfrm +function uses the current locale, the +.Fn wcsxfrm_l +function may be passed a locale directly. See +.Xr xlocale 3 +for more information. +.Sh RETURN VALUES +Upon successful completion, +.Fn wcsxfrm +returns the length of the transformed string not including +the terminating null character. +If this value is +.Fa n +or more, the contents of +.Fa ws1 +are indeterminate. +.Sh SEE ALSO +.Xr setlocale 3 , +.Xr strxfrm 3 , +.Xr wcscmp 3 , +.Xr wcscoll 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn wcsxfrm +function +conforms to +.St -isoC-99 . +.Sh BUGS +The current implementation of +.Fn wcsxfrm +only works in single-byte +.Dv LC_CTYPE +locales, and falls back to using +.Fn wcsncpy +in locales with extended character sets. +.Pp +Comparing two strings using +.Fn wcscmp +after +.Fn wcsxfrm +is +.Em not +always equivalent to comparison with +.Fn wcscoll ; +.Fn wcsxfrm +only stores information about primary collation weights into +.Fa ws1 , +whereas +.Fn wcscoll +compares characters using both primary and secondary weights. diff --git a/string/wmemchr-fbsd.c b/string/wmemchr-fbsd.c new file mode 100644 index 0000000..0b09f94 --- /dev/null +++ b/string/wmemchr-fbsd.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wmemchr.c,v 1.2 2000/12/20 14:08:31 itojun Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include + +wchar_t * +wmemchr(s, c, n) + const wchar_t *s; + wchar_t c; + size_t n; +{ + size_t i; + + for (i = 0; i < n; i++) { + if (*s == c) { + /* LINTED const castaway */ + return (wchar_t *)s; + } + s++; + } + return NULL; +} diff --git a/string/wmemchr.3 b/string/wmemchr.3 new file mode 100644 index 0000000..8638b59 --- /dev/null +++ b/string/wmemchr.3 @@ -0,0 +1,214 @@ +.\" $NetBSD: wmemchr.3,v 1.4 2001/01/02 11:26:23 itojun Exp $ +.\" +.\" 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. +.\" +.\" 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 $ +.\" +.Dd December 22, 2000 +.Dt WMEMCHR 3 +.Os +.Sh NAME +.Nm wcscat , +.Nm wcschr , +.Nm wcscmp , +.Nm wcscpy , +.Nm wcscspn , +.Nm wcslcat , +.Nm wcslcpy , +.Nm wcslen , +.Nm wcsncat , +.Nm wcsncmp , +.Nm wcsncpy , +.Nm wcspbrk , +.Nm wcsrchr , +.Nm wcsspn , +.Nm wcsstr , +.Nm wmemchr , +.Nm wmemcmp , +.Nm wmemcpy , +.Nm wmemmove , +.Nm wmemset +.Nd wide character string manipulation operations +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft wchar_t * +.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 +.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 +.Fo wcscspn +.Fa "const wchar_t *ws1" +.Fa "const wchar_t *ws2" +.Fc +.Ft size_t +.Fo wcslcat +.Fa "wchar_t *ws1" +.Fa "const wchar_t *ws2" +.Fa "size_t n" +.Fc +.Ft size_t +.Fo wcslcpy +.Fa "wchar_t *ws1" +.Fa "const wchar_t *ws2" +.Fa "size_t n" +.Fc +.Ft size_t +.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 +.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 +.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 +.Ft wchar_t * +.Fo wmemchr +.Fa "const wchar_t *ws" +.Fa "wchar_t wc" +.Fa "size_t n" +.Fc +.Ft int +.Fo wmemcmp +.Fa "const wchar_t *ws1" +.Fa "const wchar_t *ws2" +.Fa "size_t n" +.Fc +.Ft wchar_t * +.Fo wmemcpy +.Fa "wchar_t *restrict ws1" +.Fa "const wchar_t *restrict ws2" +.Fa "size_t n" +.Fc +.Ft wchar_t * +.Fo wmemmove +.Fa "wchar_t *ws1" +.Fa "const wchar_t *ws2" +.Fa "size_t n" +.Fc +.Ft wchar_t * +.Fo wmemset +.Fa "wchar_t *ws" +.Fa "wchar_t wc" +.Fa "size_t n" +.Fc +.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 +.Xr memchr 3 . +.Sh SEE ALSO +.Xr memchr 3 , +.Xr memcmp 3 , +.Xr memcpy 3 , +.Xr memmove 3 , +.Xr memset 3 , +.Xr strcat 3 , +.Xr strchr 3 , +.Xr strcmp 3 , +.Xr strcpy 3 , +.Xr strcspn 3 , +.Xr strlcat 3 , +.Xr strlcpy 3 , +.Xr strlen 3 , +.Xr strncat 3 , +.Xr strncmp 3 , +.Xr strncpy 3 , +.Xr strpbrk 3 , +.Xr strrchr 3 , +.Xr strspn 3 , +.Xr strstr 3 +.Sh STANDARDS +These functions conform to +.St -isoC-99 , +with the exception of +.Fn wcslcat +and +.Fn wcslcpy , +which are extensions. diff --git a/string/wmemcmp-fbsd.c b/string/wmemcmp-fbsd.c new file mode 100644 index 0000000..3014041 --- /dev/null +++ b/string/wmemcmp-fbsd.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wmemcmp.c,v 1.2 2000/12/20 14:08:31 itojun Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include + +int +wmemcmp(s1, s2, n) + const wchar_t *s1; + const wchar_t *s2; + size_t n; +{ + size_t i; + + for (i = 0; i < n; i++) { + if (*s1 != *s2) { + /* wchar might be unsigned */ + return *s1 > *s2 ? 1 : -1; + } + s1++; + s2++; + } + return 0; +} diff --git a/string/wmemcpy-fbsd.c b/string/wmemcpy-fbsd.c new file mode 100644 index 0000000..4391309 --- /dev/null +++ b/string/wmemcpy-fbsd.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wmemcpy.c,v 1.2 2000/12/20 14:08:31 itojun Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include +#include + +wchar_t * +wmemcpy(d, s, n) + 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/wmemmove-fbsd.c b/string/wmemmove-fbsd.c new file mode 100644 index 0000000..dd2036c --- /dev/null +++ b/string/wmemmove-fbsd.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wmemmove.c,v 1.2 2000/12/20 14:08:31 itojun Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include +#include + +wchar_t * +wmemmove(d, s, n) + wchar_t *d; + const wchar_t *s; + size_t n; +{ + + return (wchar_t *)memmove(d, s, n * sizeof(wchar_t)); +} diff --git a/string/wmemset-fbsd.c b/string/wmemset-fbsd.c new file mode 100644 index 0000000..df91537 --- /dev/null +++ b/string/wmemset-fbsd.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * citrus Id: wmemset.c,v 1.2 2000/12/20 14:08:31 itojun Exp + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__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 $"); + +#include + +wchar_t * +wmemset(s, c, n) + wchar_t *s; + wchar_t c; + size_t n; +{ + size_t i; + wchar_t *p; + + p = (wchar_t *)s; + for (i = 0; i < n; i++) { + *p = c; + p++; + } + return s; +} diff --git a/sys/Makefile.inc b/sys/Makefile.inc index 9e6510b..296066b 100644 --- a/sys/Makefile.inc +++ b/sys/Makefile.inc @@ -6,9 +6,11 @@ # MDASM names override the default syscall names in MIASM. # NOASM will prevent the default syscall code from being generated. # +.ifnmake autopatch .if exists(${.CURDIR}/${MACHINE_ARCH}/sys/Makefile.inc) .include "${.CURDIR}/${MACHINE_ARCH}/sys/Makefile.inc" .endif +.endif # !autopatch # sys sources .PATH: ${.CURDIR}/sys @@ -20,25 +22,115 @@ # Sources common to both syscall interfaces: # 3375657: patches for sem_open() sem_unlink() shm_open() shm_unlink() -MISRCS+= errno.c gettimeofday.c sigcatch.c sigsuspend.c \ - sigaction.c sigtramp.c crt_externs.c \ - sem_open.c sem_unlink.c shm_open.c shm_unlink.c fix-3375657.c \ - accessx_np.c chmodx_np.c getsgroups_np.c \ - getwgroups_np.c openx_np.c mmap.c \ - pthread_getuid_np.c pthread_setuid_np.c setsgroups_np.c \ - setwgroups_np.c statx_np.c umaskx_np.c \ - semctl.c shmctl.c msgctl.c \ - mprotect.c msync.c munmap.c other_libc_init.c +MISRCS+= chmod.c chmodx_np.c crt_externs.c \ + errno.c fchmod.c fix-3375657.c \ + getiopolicy_np.c getrlimit.c gettimeofday.c \ + kill.c __libc_init.c \ + mmap.c \ + openx_np.c \ + posix_spawn.c \ + select.c sem_open.c sem_unlink.c semctl.c \ + setrlimit.c \ + shm_open.c shm_unlink.c sigaction.c sigcatch.c sigsuspend.c \ + sigtramp.c statx_np.c \ + umaskx_np.c -.for _src in sem_open.c sem_unlink.c shm_open.c shm_unlink.c fix-3375657.c -CFLAGS-${_src} += -D__APPLE_PR3375657_HACK__ -.endfor +.if (${MACHINE_ARCH} != ppc) +.if (${MACHINE_ARCH} != i386) +MISRCS+= context-stubs.c +.endif +.endif + +.ifdef LP64 +MISRCS+= fcntl.c ioctl.c +PRE1050SRCS+= select.c +.endif .include "Makefile.obsd_begin" OBSDMISRCS= stack_protector.c .include "Makefile.obsd_end" -UNIX03SRCS += mmap.c mprotect.c msgctl.c msync.c munmap.c semctl.c shmctl.c +.for _src in sem_open.c sem_unlink.c shm_open.c shm_unlink.c fix-3375657.c +CFLAGS-${_src} += -D__APPLE_PR3375657_HACK__ +.endfor + +INODE32SRCS += statx_np.c + +CANCELABLESRCS += select.c sigsuspend.c + +.ifdef LP64 +CANCELABLESRCS+= fcntl.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 + +# we need to create open.h, which just contains a definition for O_NOCTTY +open.do open.o open.po open.So: open.h +open.h : + ${CC} -E -dD ${CFLAGS} -include fcntl.h -x c /dev/null | grep O_NOCTTY > ${.TARGET} + +.for _src in msgctl.c semctl.c shmctl.c +CFLAGS-${_src} += -DKERNEL +.endfor + +# sigtramp.c can only compile with __DARWIN_UNIX03=0 (for ppc64) because +# the structure field names are renamed with __ prefix when __DARWIN_UNIX03=1. +# If sigtramp.c ever needs to build variant, this will have to be fix properly +CFLAGS-sigtramp.c = -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0 + +# set the LIBC_ALIAS_* macros so we can decorate the symbol independent +# of other macro settings +CFLAGS-accept.c += -DLIBC_ALIAS_ACCEPT +#CFLAGS-aio_suspend.c += -DLIBC_ALIAS_AIO_SUSPEND +CFLAGS-bind.c += -DLIBC_ALIAS_BIND +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-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 +#CFLAGS-read.c += -DLIBC_ALIAS_READ +#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-waitid.c += -DLIBC_ALIAS_WAITID +#CFLAGS-write.c += -DLIBC_ALIAS_WRITE +#CFLAGS-writev.c += -DLIBC_ALIAS_WRITEV # Add machine dependent asm sources: SRCS+=${MDASM} @@ -67,36 +159,73 @@ SRCS+= ${SASM} ${SPSEUDO} CLEANFILES+= ${SASM} ${SPSEUDO} ${SASM}: - printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' > ${.TARGET} + printf '#include \nRSYSCALL(${.PREFIX})\n' > ${.TARGET} ${SPSEUDO}: - printf '#include "SYS.h"\nPSEUDO(${.PREFIX:S/_//})\n' \ + printf '#include \nPSEUDO(${.PREFIX:S/_//})\n' \ > ${.TARGET} +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_trywait.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 -MAN3+= atomic.3 barrier.3 spinlock.3 + nanosleep.2 undelete.2 +MAN3+= atomic.3 barrier.3 getiopolicy_np.3 spinlock.3 cache.3 MLINKS+= atomic.3 OSAtomicAdd32.3 -MLINKS+= atomic.3 OSAtomicIncrement32.3 -MLINKS+= atomic.3 OSAtomicDecrement32.3 -MLINKS+= atomic.3 OSAtomicOr32.3 -MLINKS+= atomic.3 OSAtomicAnd32.3 -MLINKS+= atomic.3 OSAtomicXor32.3 +MLINKS+= atomic.3 OSAtomicAdd32Barrier.3 MLINKS+= atomic.3 OSAtomicAdd64.3 -MLINKS+= atomic.3 OSAtomicIncrement64.3 -MLINKS+= atomic.3 OSAtomicDecrement64.3 +MLINKS+= atomic.3 OSAtomicAdd64Barrier.3 +MLINKS+= atomic.3 OSAtomicAnd32.3 +MLINKS+= atomic.3 OSAtomicAnd32Barrier.3 +MLINKS+= atomic.3 OSAtomicAnd32Orig.3 +MLINKS+= atomic.3 OSAtomicAnd32OrigBarrier.3 MLINKS+= atomic.3 OSAtomicCompareAndSwap32.3 +MLINKS+= atomic.3 OSAtomicCompareAndSwap32Barrier.3 MLINKS+= atomic.3 OSAtomicCompareAndSwap64.3 -MLINKS+= atomic.3 OSAtomicTestAndSet.3 +MLINKS+= atomic.3 OSAtomicCompareAndSwap64Barrier.3 +MLINKS+= atomic.3 OSAtomicCompareAndSwapInt.3 +MLINKS+= atomic.3 OSAtomicCompareAndSwapIntBarrier.3 +MLINKS+= atomic.3 OSAtomicCompareAndSwapLong.3 +MLINKS+= atomic.3 OSAtomicCompareAndSwapLongBarrier.3 +MLINKS+= atomic.3 OSAtomicCompareAndSwapPtr.3 +MLINKS+= atomic.3 OSAtomicCompareAndSwapPtrBarrier.3 +MLINKS+= atomic.3 OSAtomicDecrement32.3 +MLINKS+= atomic.3 OSAtomicDecrement32Barrier.3 +MLINKS+= atomic.3 OSAtomicDecrement64.3 +MLINKS+= atomic.3 OSAtomicDecrement64Barrier.3 +MLINKS+= atomic.3 OSAtomicDequeue.3 +MLINKS+= atomic.3 OSAtomicEnqueue.3 +MLINKS+= atomic.3 OSAtomicIncrement32.3 +MLINKS+= atomic.3 OSAtomicIncrement32Barrier.3 +MLINKS+= atomic.3 OSAtomicIncrement64.3 +MLINKS+= atomic.3 OSAtomicIncrement64Barrier.3 +MLINKS+= atomic.3 OSAtomicOr32.3 +MLINKS+= atomic.3 OSAtomicOr32Barrier.3 +MLINKS+= atomic.3 OSAtomicOr32Orig.3 +MLINKS+= atomic.3 OSAtomicOr32OrigBarrier.3 MLINKS+= atomic.3 OSAtomicTestAndClear.3 +MLINKS+= atomic.3 OSAtomicTestAndClearBarrier.3 +MLINKS+= atomic.3 OSAtomicTestAndSet.3 +MLINKS+= atomic.3 OSAtomicTestAndSetBarrier.3 +MLINKS+= atomic.3 OSAtomicXor32.3 +MLINKS+= atomic.3 OSAtomicXor32Barrier.3 +MLINKS+= atomic.3 OSAtomicXor32Orig.3 +MLINKS+= atomic.3 OSAtomicXor32OrigBarrier.3 MLINKS+= barrier.3 OSMemoryBarrier.3 -MLINKS+= spinlock.3 OSSpinLockTry.3 -MLINKS+= spinlock.3 OSSpinLockLock.3 -MLINKS+= spinlock.3 OSSpinLockUnlock.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 + +MLINKS+= spinlock.3 OSSpinLockLock.3 \ + spinlock.3 OSSpinLockTry.3 \ + spinlock.3 OSSpinLockUnlock.3 #MAN+= _exit.2 accept.2 access.2 acct.2 adjtime.2 \ # aio_cancel.2 aio_error.2 aio_read.2 aio_return.2 \ @@ -112,7 +241,7 @@ MLINKS+= spinlock.3 OSSpinLockUnlock.3 # getsockopt.2 gettimeofday.2 getuid.2 \ # intro.2 ioctl.2 issetugid.2 jail.2 kill.2 \ # kldfind.2 kldfirstmod.2 kldload.2 kldnext.2 kldstat.2 kldsym.2 \ -# kldunload.2 ktrace.2 kqueue.2 link.2 listen.2 lseek.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 \ # modfind.2 modnext.2 modstat.2 \ # mount.2 mprotect.2 msync.2 munmap.2 nanosleep.2 \ diff --git a/sys/OpenBSD/stack_protector.c.patch b/sys/OpenBSD/stack_protector.c.patch index 64c5df1..e6766cc 100644 --- a/sys/OpenBSD/stack_protector.c.patch +++ b/sys/OpenBSD/stack_protector.c.patch @@ -1,15 +1,69 @@ ---- stack_protector.c.orig 2006-10-05 00:09:07.000000000 -0700 -+++ stack_protector.c 2006-10-05 00:18:28.000000000 -0700 -@@ -34,10 +34,10 @@ +Index: stack_protector.c +=================================================================== +--- stack_protector.c (revision 31377) ++++ stack_protector.c (working copy) +@@ -32,44 +32,41 @@ static char rcsid[] = "$OpenBSD: stack_p + #include + #include #include ++#include ++#include ++#include ++ ++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"))); ++void __stack_chk_fail(void); - long __guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +-long __guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -static void __guard_setup(void) __attribute__ ((constructor)); -+__private_extern__ void __guard_setup(void); - void __stack_smash_handler(char func[], int damaged __attribute__((unused))); - +-void __stack_smash_handler(char func[], int damaged __attribute__((unused))); +- -static void -+__private_extern__ void ++void __guard_setup(void) { 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; + } + + 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); +- +- 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()); + +- _exit(127); ++ __abort(); + } diff --git a/sys/SYSCALL-LIST b/sys/SYSCALL-LIST index 5bc2cac..edaf3fc 100644 --- a/sys/SYSCALL-LIST +++ b/sys/SYSCALL-LIST @@ -57,7 +57,6 @@ geteuid ioctl kill killpg -ktrace link listen lseek @@ -144,5 +143,6 @@ wait waitpid wait3 wait4 +waitid write writev diff --git a/i386/mach/mach_absolute_time.c b/sys/__libc_init.c similarity index 50% rename from i386/mach/mach_absolute_time.c rename to sys/__libc_init.c index 6bd72c1..d365f5f 100644 --- a/i386/mach/mach_absolute_time.c +++ b/sys/__libc_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005-2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,29 +20,38 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#if !defined(__ppc__) +/* + * __libc_init() is called from libSystem_initializer() + */ + #include -#include -#include -#define __APPLE_API_PRIVATE -#include -#undef __APPLE_API_PRIVATE +#include +#include + +struct ProgramVars; /* forward reference */ + +extern void _program_vars_init(const struct ProgramVars *vars); +extern pthread_lock_t _malloc_lock; +extern void __xlocale_init(void); +extern void __guard_setup(void); -extern mach_port_t clock_port; +#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 */ -#define COMM_PAGE_VERSION \ - (*((short *) _COMM_PAGE_VERSION)) - -#define COMM_PAGE_NANOTIME() \ - (((uint64_t (*)()) _COMM_PAGE_NANOTIME)()) +__private_extern__ void +__libc_init(const struct ProgramVars *vars) +{ + _program_vars_init(vars); + LOCK_INIT(_malloc_lock); + __xlocale_init(); + __guard_setup(); -uint64_t -mach_absolute_time(void) { - if (__builtin_expect(COMM_PAGE_VERSION == 1, 0)) { - mach_timespec_t now; - (void)clock_get_time(clock_port, &now); - return (uint64_t)now.tv_sec * NSEC_PER_SEC + now.tv_nsec; - } - return COMM_PAGE_NANOTIME(); +#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 */ } -#endif diff --git a/sys/accept.c b/sys/accept.c new file mode 100644 index 0000000..149ca52 --- /dev/null +++ b/sys/accept.c @@ -0,0 +1,48 @@ +/* + * 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/atomic.3 b/sys/atomic.3 index a7bb0fb..6af9721 100644 --- a/sys/atomic.3 +++ b/sys/atomic.3 @@ -10,16 +10,28 @@ .Nm OSAtomicDecrement32Barrier , .Nm OSAtomicOr32 , .Nm OSAtomicOr32Barrier , +.Nm OSAtomicOr32Orig , +.Nm OSAtomicOr32OrigBarrier , .Nm OSAtomicAnd32 , .Nm OSAtomicAnd32Barrier , +.Nm OSAtomicAnd32Orig , +.Nm OSAtomicAnd32OrigBarrier , .Nm OSAtomicXor32 , .Nm OSAtomicXor32Barrier , +.Nm OSAtomicXor32Orig , +.Nm OSAtomicXor32OrigBarrier , .Nm OSAtomicAdd64 , .Nm OSAtomicAdd64Barrier , .Nm OSAtomicIncrement64 , .Nm OSAtomicIncrement64Barrier , .Nm OSAtomicDecrement64 , .Nm OSAtomicDecrement64Barrier , +.Nm OSAtomicCompareAndSwapInt , +.Nm OSAtomicCompareAndSwapIntBarrier , +.Nm OSAtomicCompareAndSwapLong , +.Nm OSAtomicCompareAndSwapLongBarrier , +.Nm OSAtomicCompareAndSwapPtr , +.Nm OSAtomicCompareAndSwapPtrBarrier , .Nm OSAtomicCompareAndSwap32 , .Nm OSAtomicCompareAndSwap32Barrier , .Nm OSAtomicCompareAndSwap64 , @@ -27,67 +39,106 @@ .Nm OSAtomicTestAndSet , .Nm OSAtomicTestAndSetBarrier , .Nm OSAtomicTestAndClear , -.Nm OSAtomicTestAndClearBarrier -.Nd atomic add, increment, decrement, or, and, xor, compare and swap, test and set, and test and clear +.Nm OSAtomicTestAndClearBarrier , +.Nm OSSpinLockTry , +.Nm OSSpinLockLock , +.Nm OSSpinLockUnlock , +.Nm OSAtomicEnqueue , +.Nm OSAtomicDequeue +.Nd atomic add, increment, decrement, or, and, xor, compare and swap, test and set, test and clear, spinlocks, and lockless queues .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In libkern/OSAtomic.h .Ft int32_t -.Fn OSAtomicAdd32 "int32_t theAmount, int32_t *theValue" +.Fn OSAtomicAdd32 "int32_t theAmount" "volatile int32_t *theValue" .Ft int32_t -.Fn OSAtomicAdd32Barrier "int32_t theAmount, int32_t *theValue" +.Fn OSAtomicAdd32Barrier "int32_t theAmount" "volatile int32_t *theValue" .Ft int32_t -.Fn OSAtomicIncrement32 "int32_t *theValue" +.Fn OSAtomicIncrement32 "volatile int32_t *theValue" .Ft int32_t -.Fn OSAtomicIncrement32Barrier "int32_t *theValue" +.Fn OSAtomicIncrement32Barrier "volatile int32_t *theValue" .Ft int32_t -.Fn OSAtomicDecrement32 "int32_t *theValue" +.Fn OSAtomicDecrement32 "volatile int32_t *theValue" .Ft int32_t -.Fn OSAtomicDecrement32Barrier "int32_t *theValue" +.Fn OSAtomicDecrement32Barrier "volatile int32_t *theValue" .Ft int32_t -.Fn OSAtomicOr32 "uint32_t theMask, uint32_t *theValue" +.Fn OSAtomicOr32 "uint32_t theMask" "volatile uint32_t *theValue" .Ft int32_t -.Fn OSAtomicOr32Barrier "uint32_t theMask, uint32_t *theValue" +.Fn OSAtomicOr32Barrier "uint32_t theMask" "volatile uint32_t *theValue" .Ft int32_t -.Fn OSAtomicAnd32 "uint32_t theMask, uint32_t *theValue" +.Fn OSAtomicAnd32 "uint32_t theMask" "volatile uint32_t *theValue" .Ft int32_t -.Fn OSAtomicAnd32Barrier "uint32_t theMask, uint32_t *theValue" +.Fn OSAtomicAnd32Barrier "uint32_t theMask" "volatile uint32_t *theValue" .Ft int32_t -.Fn OSAtomicXor32 "uint32_t theMask, uint32_t *theValue" +.Fn OSAtomicXor32 "uint32_t theMask" "volatile uint32_t *theValue" .Ft int32_t -.Fn OSAtomicXor32Barrier "uint32_t theMask, uint32_t *theValue" +.Fn OSAtomicXor32Barrier "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicOr32Orig "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicOr32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicAnd32Orig "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicAnd32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicXor32Orig "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicXor32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" .Ft int64_t -.Fn OSAtomicAdd64 "int64_t theAmount, int64_t *theValue" +.Fn OSAtomicAdd64 "int64_t theAmount" "volatile int64_t *theValue" .Ft int64_t -.Fn OSAtomicAdd64Barrier "int64_t theAmount, int64_t *theValue" +.Fn OSAtomicAdd64Barrier "int64_t theAmount" "volatile int64_t *theValue" .Ft int64_t -.Fn OSAtomicIncrement64 "int64_t *theValue" +.Fn OSAtomicIncrement64 "volatile int64_t *theValue" .Ft int64_t -.Fn OSAtomicIncrement64Barrier "int64_t *theValue" +.Fn OSAtomicIncrement64Barrier "volatile int64_t *theValue" .Ft int64_t -.Fn OSAtomicDecrement64 "int64_t *theValue" +.Fn OSAtomicDecrement64 "volatile int64_t *theValue" .Ft int64_t -.Fn OSAtomicDecrement64Barrier "int64_t *theValue" +.Fn OSAtomicDecrement64Barrier "volatile int64_t *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwapInt "int oldValue" "int newValue" "volatile int *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwapIntBarrier "int oldValue" "int newValue" "volatile int *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwapLong "long oldValue" "long newValue" "volatile long *theValue" .Ft bool -.Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "int32_t *theValue" +.Fn OSAtomicCompareAndSwapLongBarrier "long oldValue" "long newValue" "volatile long *theValue" .Ft bool -.Fn OSAtomicCompareAndSwap32Barrier "int32_t oldValue" "int32_t newValue" "int32_t *theValue" +.Fn OSAtomicCompareAndSwapPtr "void* oldValue" "void* newValue" "void* volatile *theValue" .Ft bool -.Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "int64_t *theValue" +.Fn OSAtomicCompareAndSwapPtrBarrier "void* oldValue" "void* newValue" "void* volatile *theValue" .Ft bool -.Fn OSAtomicCompareAndSwap64Barrier "int64_t oldValue" "int64_t newValue" "int64_t *theValue" +.Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue" .Ft bool -.Fn OSAtomicTestAndSet "uint32_t n, void *theAddress" +.Fn OSAtomicCompareAndSwap32Barrier "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue" .Ft bool -.Fn OSAtomicTestAndSetBarrier "uint32_t n, void *theAddress" +.Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "volatile int64_t *theValue" .Ft bool -.Fn OSAtomicTestAndClear "uint32_t n, void *theAddress" +.Fn OSAtomicCompareAndSwap64Barrier "int64_t oldValue" "int64_t newValue" "volatile int64_t *theValue" .Ft bool -.Fn OSAtomicTestAndClearBarrier "uint32_t n, void *theAddress" +.Fn OSAtomicTestAndSet "uint32_t n" "volatile void *theAddress" +.Ft bool +.Fn OSAtomicTestAndSetBarrier "uint32_t n" "volatile void *theAddress" +.Ft bool +.Fn OSAtomicTestAndClear "uint32_t n" "volatile void *theAddress" +.Ft bool +.Fn OSAtomicTestAndClearBarrier "uint32_t n" "volatile void *theAddress" +.Ft bool +.Fn OSSpinLockTry "OSSpinLock *lock" +.Ft void +.Fn OSSpinLockLock "OSSpinLock *lock" +.Ft void +.Fn OSSpinLockUnlock "OSSpinLock *lock" +.Ft void +.Fn OSAtomicEnqueue "OSQueueHead *list" "void *new" "size_t offset" +.Ft void* +.Fn OSAtomicDequeue "OSQueueHead *list" "size_t offset" .Sh DESCRIPTION These functions are thread and multiprocessor safe. For each function, there -is a version that does and anoother that does not incorporate a memory barrier. +is a version that does and another that does not incorporate a memory barrier. 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 @@ -97,9 +148,9 @@ On a multiprocessor, the barrier can be quite expensive. 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 a shared data structure and then atomically increment a variable to indicate -that the initialization is complete, then you MUST use OSAtomicIncrement32Barrier() +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(), +Likewise, the consumer of that data structure must use 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 much @@ -108,20 +159,24 @@ the barrier variants as they are safer. .Pp The logical (and, or, xor) and bit test operations are layered on top of the .Fn OSAtomicCompareAndSwap -primitives. +primitives. There are four versions of each logical operation, depending on whether +or not there is a barrier, and whether the return value is the result of the +operation (eg, +.Fn OSAtomicOr32 +) or the original value before the operation (eg, +.Fn OSAtomicOr32Orig +). .Pp The memory address .Fa theValue must be naturally aligned, ie 32-bit aligned for 32-bit operations and 64-bit aligned for 64-bit operations. .Pp -The 64-bit operations are only implemented for -64-bit processes. +The 64-bit operations are not implemented for 32-bit processes on PPC platforms. .Pp -.Fn OSAtomicCompareAndSwap32 -and -.Fn OSAtomicCompareAndSwap64 -compare +The +.Fn OSAtomicCompareAndSwap +operations compare .Fa oldValue to .Fa *theValue , @@ -144,11 +199,48 @@ operate on bit (0x80 >> ( >> 3)). They set the named bit to either 1 or 0, respectively. .Fa theAddress need not be aligned. +.Pp +The routines +.Fn OSAtomicEnqueue +and +.Fn OSAtomicDequeue +operate on singly linked LIFO queues. Ie, a dequeue operation will return the +most recently enqueued element, or NULL if the list is empty. The operations +are lockless, and barriers are used as necessary to permit thread-safe access to +the queue element. +.Fa offset +is the offset in bytes to the link field in the queue element. For example: +.Bd -literal -offset indent + typedef struct elem { + long data1; + struct elem *link; + int data2; + } elem_t; + + elem_t fred, mary, *p; + + OSQueueHead q = OS_ATOMIC_QUEUE_INIT; + + OSAtomicEnqueue( &q, &fred, offsetof(elem_t,link) ); + OSAtomicEnqueue( &q, &mary, offsetof(elem_t,link) ); + + p = OSAtomicDequeue( &q, offsetof(elem_t,link) ); + +.Ed +In this example, the call of +.Fn OSAtomicDequeue +will return a ptr to mary. .Sh RETURN VALUES -The arithmetic and logical operations return the new value, after the operation has been performed. +The arithmetic operations return the new value, after the operation has been performed. +The boolean operations come in two styles, one of which returns the new value, and one +of which (the "Orig" versions) returns the old. The compare-and-swap operations return true if the comparison was equal, ie if the swap occured. The bit test and set/clear operations return the original value of the bit. +The dequeue operation returns the most recently enqueued element, or NULL if the list in empty. .Sh SEE ALSO -.Xr atomicqueue 3 , .Xr spinlock 3 , .Xr barrier 3 +.Sh HISTORY +Most of these functions first appeared in Mac OS 10.4 (Tiger). The "Orig" forms of the +boolean operations, the "int", "long" and "ptr" forms of compare-and-swap, and lockless +enqueue/dequeue first appeared in Mac OS 10.5 (Leopard). diff --git a/sys/barrier.3 b/sys/barrier.3 index 5e9cc9f..de5fed8 100644 --- a/sys/barrier.3 +++ b/sys/barrier.3 @@ -21,5 +21,4 @@ spinlock or queue/dequeue operations. Note that this barrier does not order unc and stores. On a uniprocessor, the barrier operation is typically optimized into a nop. .Sh SEE ALSO .Xr atomic 3 , -.Xr atomicqueue 3 , -.Xr spinlock 3 \ No newline at end of file +.Xr spinlock 3 diff --git a/sys/pthread_setuid_np.c b/sys/bind.c similarity index 61% rename from sys/pthread_setuid_np.c rename to sys/bind.c index 38fe114..01879e3 100644 --- a/sys/pthread_setuid_np.c +++ b/sys/bind.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,13 +20,29 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#include -#include -#include +/* + * 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 -pthread_setugid_np(uid_t uid, gid_t gid) +bind(int s, const struct sockaddr *name, socklen_t namelen) { - return syscall(SYS_settid, uid, gid); + int ret = __bind(s, name, namelen); + + /* use ENOTSUP for legacy behavior */ + if (ret < 0 && errno == EOPNOTSUPP) + errno = ENOTSUP; + return ret; } diff --git a/sys/cache.3 b/sys/cache.3 new file mode 100644 index 0000000..0dbe77d --- /dev/null +++ b/sys/cache.3 @@ -0,0 +1,55 @@ +.Dd September 21, 2006 +.Dt CACHE 3 +.Os Darwin +.Sh NAME +.Nm sys_cache_control , +.Nm sys_icache_invalidate , +.Nm sys_dcache_flush +.Nd cache control +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In libkern/OSCacheControl.h +.Ft int +.Fn sys_cache_control "int function" "void *start" "size_t len" +.Ft void +.Fn sys_icache_invalidate "void *start" "size_t len" +.Ft void +.Fn sys_dcache_flush "void *start" "size_t len" +.Sh DESCRIPTION +.Pp +These functions operate on every cache line containing one of the +.Fa len +bytes of memory pointed to by +.Fa start . +Normally the operations apply to every +processor in the system, but the exact semantics of these +operations is platform dependent. They should be used with caution. +.Pp +.Fn sys_cache_control +performs the operation specified by +.Fa function . +Refer to the header file for a list of currently supported functions. +.Pp +.Fn sys_icache_invalidate +prepares memory for execution, typically by invalidating the instruction +cache for the indicated range. This should be called +after writing machine instructions to memory, and before +executing them. On IA32 processors this function is a NOP, because +their instruction caches are coherent. +.Pp +.Fn sys_dcache_flush +writes modified data cache lines to main memory, +and then invalidates all lines in the range being operated on. +It can be useful when dealing with cache incoherent +devices or DMA. +.Sh RETURN VALUES +.Fn sys_cache_control +returns zero on success, ENOTSUP if +.Fa function +is not valid. +.Sh SEE ALSO +.Xr atomic 3 , +.Xr barrier 3 +.Sh HISTORY +These functions first appeared in Mac OS 10.5 (Leopard). \ No newline at end of file diff --git a/sys/chmod.c b/sys/chmod.c new file mode 100644 index 0000000..175316c --- /dev/null +++ b/sys/chmod.c @@ -0,0 +1,55 @@ +/* + * 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/chmodx_np.c b/sys/chmodx_np.c index 099610e..6896298 100644 --- a/sys/chmodx_np.c +++ b/sys/chmodx_np.c @@ -21,7 +21,6 @@ * @APPLE_LICENSE_HEADER_END@ */ #include -#include #include #include #include @@ -61,19 +60,22 @@ fchmodx_np(int fd, filesec_t fsec) /* * Chmod syscalls. */ +extern int __chmod_extended(char *, uid_t, gid_t, int, struct kauth_filesec *); +extern int __fchmod_extended(int, uid_t, gid_t, int, struct kauth_filesec *); + static int chmodx_syscall(void *obj, uid_t fsowner, gid_t fsgrp, int mode, struct kauth_filesec *fsacl) { char *path = *(char **)obj; - return(syscall(SYS_chmod_extended, path, fsowner, fsgrp, mode, fsacl)); + return(__chmod_extended(path, fsowner, fsgrp, mode, fsacl)); } static int fchmodx_syscall(void *obj, uid_t fsowner, gid_t fsgrp, int mode, struct kauth_filesec *fsacl) { int fd = *(int *)obj; - return(syscall(SYS_fchmod_extended, fd, fsowner, fsgrp, mode, fsacl)); + return(__fchmod_extended(fd, fsowner, fsgrp, mode, fsacl)); } /* diff --git a/sys/connect.c b/sys/connect.c new file mode 100644 index 0000000..dbaade7 --- /dev/null +++ b/sys/connect.c @@ -0,0 +1,48 @@ +/* + * 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/i386/sys/bind.s b/sys/context-stubs.c similarity index 65% rename from i386/sys/bind.s rename to sys/context-stubs.c index 0fcb725..39f3dcc 100644 --- a/i386/sys/bind.s +++ b/sys/context-stubs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,18 +20,12 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include -#ifdef __LP64__ -UNIX_SYSCALL(bind, 3) - ret -#else /* !__LP64__ */ -PSEUDO(bind$UNIX2003, bind, 3) - ret +#include +#include -UNIX_SYSCALL_ERR(bind, 3, cerror_cvt) - ret -#endif /* !__LP64__ */ +/* stubs for ppc64 and i386, until real support is available */ +int getcontext(ucontext_t *u) { errno = ENOTSUP; return -1; } +void makecontext(ucontext_t *u, void (*f)(void), int a, ...) {} +int setcontext(const ucontext_t *u) { errno = ENOTSUP; return -1; } +int swapcontext(ucontext_t * __restrict u1, const ucontext_t * __restrict u2) { errno = ENOTSUP; return -1; } diff --git a/sys/crt_externs.c b/sys/crt_externs.c index c1c4546..5367740 100644 --- a/sys/crt_externs.c +++ b/sys/crt_externs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -63,36 +63,79 @@ #define USE_VAR(var) (& var) #endif +DECLARE_VAR(NXArgv, char **); +DECLARE_VAR(NXArgc, int); +DECLARE_VAR(environ, char **); +DECLARE_VAR(_mh_execute_header, struct mach_header); +DECLARE_PROGNAME(__progname, char *); + char ***_NSGetArgv(void) { - DECLARE_VAR(NXArgv, char **); SETUP_VAR(NXArgv); return(USE_VAR(NXArgv)); } int *_NSGetArgc(void) { - DECLARE_VAR(NXArgc, int); SETUP_VAR(NXArgc); return(USE_VAR(NXArgc)); } char ***_NSGetEnviron(void) { - DECLARE_VAR(environ, char **); SETUP_VAR(environ); return(USE_VAR(environ)); } char **_NSGetProgname(void) { - DECLARE_PROGNAME(__progname, char *); SETUP_PROGNAME(__progname); return(USE_VAR(__progname)); } struct mach_header *_NSGetMachExecuteHeader(void) { - DECLARE_VAR(_mh_execute_header, struct mach_header); SETUP_VAR(_mh_execute_header); return(USE_VAR(_mh_execute_header)); } +#if __DYNAMIC__ +struct ProgramVars +{ + void* mh; + int* NXArgcPtr; + char*** NXArgvPtr; + char*** environPtr; + char** __prognamePtr; +}; + +/* + * dyld calls libSystem_initializer() and passes it a ProgramVars struct containing pointers to the + * main executable's NXArg* global variables. libSystem_initializer() calls __libc_init() which calls + * _program_vars_init() passing the ProgramVars parameter. + */ +void __attribute__((visibility("hidden"))) +_program_vars_init(const struct ProgramVars* vars) { + // to support transitional 10.5 main executables that don't have extended __dyld section and instead call _NSSetProgramVars, + // don't overwrite values set by _NSSetProgramVars() + if ( NXArgv_pointer != NULL ) + return; + NXArgv_pointer = vars->NXArgvPtr; + NXArgc_pointer = vars->NXArgcPtr; + environ_pointer = vars->environPtr; + __progname_pointer = vars->__prognamePtr; + _mh_execute_header_pointer = vars->mh; +} + +/* + * This is only called by main executables built with pre 10-5 GM crt1.10.5.o. In those programs, + * there is no extended __dyld section, dyld cannot tell _program_vars_init() where the real program + * variables are, so they get temp values and are set for real here. + */ +void _NSSetProgramVars(int* crt_argc, char*** crt_argv, char*** crt_environ, struct mach_header* crt_mh, char** crt_progname) { + NXArgv_pointer = crt_argv; + NXArgc_pointer = crt_argc; + environ_pointer = crt_environ; + __progname_pointer = crt_progname; + _mh_execute_header_pointer = crt_mh; +} +#endif + /* * Fix for Radar bug 2200596 -- * EH symbol definitions for gcc 2.7.2.x implementation of diff --git a/sys/fchmod.c b/sys/fchmod.c new file mode 100644 index 0000000..c0c8152 --- /dev/null +++ b/sys/fchmod.c @@ -0,0 +1,55 @@ +/* + * 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/fcntl64.c b/sys/fcntl.c similarity index 77% rename from sys/fcntl64.c rename to sys/fcntl.c index e791a63..bf8024e 100644 --- a/sys/fcntl64.c +++ b/sys/fcntl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004, 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,10 +23,18 @@ #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. + * argument when int and void * are different sizes. Also add pthread + * cancelability. + * + * This is for LP64 only. */ int fcntl(int fd, int cmd, ...) @@ -54,5 +62,9 @@ fcntl(int fd, int cmd, ...) 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/ppc/sys/getattrlist.s b/sys/getattrlist.c similarity index 50% rename from ppc/sys/getattrlist.s rename to sys/getattrlist.c index 2976fa9..8285491 100644 --- a/ppc/sys/getattrlist.s +++ b/sys/getattrlist.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,15 +20,40 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* Copyright 1998 Apple Computer, Inc. */ +/* + * 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 "SYS.h" +#include #ifdef __LP64__ -SYSCALL(getattrlist, 0) +extern int __getattrlist(const char *, void *, void *, size_t, unsigned int); #else /* !__LP64__ */ -PSEUDO(getattrlist$UNIX2003, getattrlist, 0) - blr +extern int __getattrlist(const char *, void *, void *, size_t, unsigned long); +#endif /* __LP64__ */ -SYSCALL_ERR(getattrlist, 0, cerror_cvt) +/* + * 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/getiopolicy_np.3 b/sys/getiopolicy_np.3 new file mode 100644 index 0000000..0e77798 --- /dev/null +++ b/sys/getiopolicy_np.3 @@ -0,0 +1,143 @@ +.Dd July 18, 2006 +.Dt getiopolicy_np 3 +.Os +.Sh NAME +.Nm getiopolicy_np, setiopolicy_np +.Nd manipulate the I/O policy of a process or thread +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/resource.h +.Ft int +.Fn getiopolicy_np "int iotype" "int scope" +.Ft int +.Fn setiopolicy_np "int iotype" "int scope" "int policy" +.Sh DESCRIPTION +The +.Fn getiopolicy_np +and +.Fn setiopolicy_np +functions are provided to get or set the I/O policy of the current process +or the current thread. The policy of the I/O of the given type +.Fa iotype +can be get or set for the given +.Fa scope . +.Pp +The I/O type is specified in the argument +.Fa iotype . +The currently supported I/O type is +.Dv IOPOL_TYPE_DISK , +which means the I/O policy for I/Os to local disks can be get or set. I/Os to +local disks are I/Os sent to the media without going through a network, +including I/Os to internal and external hard drives, optical media in internal +and external drives, flash drives, floppy disks, ram disks, and mounted disk +images which reside on these media, but not including remote volumes mounted +through networks (AFP, SMB, NFS, etc) or disk images residing on remote volumes. +.Pp +The scope that the I/O policy takes effect is specified in the argument +.Fa scope +as follows: +.Bl -tag -width IOPOL_SCOPE_PROCESS +.It IOPOL_SCOPE_PROCESS +The I/O policy of all I/Os issued by the current process is get or set. +.It IOPOL_SCOPE_THREAD +The I/O policy of all I/Os issued by the current thread is get or set. +.El +.Pp +In +.Fn getiopolicy_np , +the I/O policy of the given I/O type and scope is returned. In +.Fn setiopolicy_np , +the argument +.Fa policy +is an integer which contains the new I/O policy to be set for the given I/O +type and scope. The I/O policy can have the following values: +.Bl -tag -width IOPOL_PASSIVEXX +.It IOPOL_DEFAULT +This is the default I/O policy for the first process and every new created thread. +.It IOPOL_NORMAL +I/Os with NORMAL policy are called NORMAL I/Os. They are handled by the +system using best-effort. +.It IOPOL_THROTTLE +I/Os with THROTTLE policy are called THROTTLE I/Os. If a THROTTLE I/O request +occurs within a small time window (usually a fraction of a second) of another +NORMAL I/O request, the thread that issues the THROTTLE I/O is forced to sleep +for a certain interval. This slows down the thread that issues the THROTTLE I/O +so that NORMAL I/Os can utilize most of the disk I/O bandwidth. +.It IOPOL_PASSIVE +The PASSIVE I/Os are a special type of NORMAL I/O that are processed the same as +NORMAL I/Os but are ignored by the THROTTLE I/Os so that the threads issuing +THROTTLE I/Os are not slowed down by PASSIVE I/Os. The PASSIVE I/O policy is +useful for server type applications. The I/Os generated by these applications +are called passive I/Os because these I/Os are caused directly or indirectly by +the I/O requests they receive from client applications. For example, when an +image file is mounted by DiskImages, DiskImages generate passive I/Os. +DiskImages should mark these I/Os using the PASSIVE I/O policy so that when +client applications that issue THROTTLE I/Os access the volume managed by +DiskImages, these client applications will not be slowed down by the I/Os +generated by DiskImages. +.El +.Pp +The I/O policy of a new created process is inherited from its parent +process. The I/O policy of an I/O request depends on the I/O policy of +both the current thread and the current process. If the I/O policy of the +current thread is IOPOL_DEFAULT, the I/O policy of the current process is +used; if the I/O policy of the current thread is not IOPOL_DEFAULT, the +I/O policy of the current thread overrides the I/O policy of the current +process; if the I/O policy of the current process is IOPOL_DEFAULT, the +policy of I/Os issued by this process is NORMAL. For example, given the +following thread and process I/O policy in the first two columns, the I/O +policy of all I/Os issued by the thread is given in the third column: +.Bl -column "Process I/O ScopeXXX" "Thread I/O ScopeXXX" "I/O Policy" -offset indent +.It Sy "Process I/O Policy Thread I/O Policy I/O Policy" +.It "DEFAULT DEFAULT NORMAL" +.It "DEFAULT PASSIVE PASSIVE" +.It "THROTTLE DEFAULT THROTTLE" +.It "THROTTLE PASSIVE PASSIVE" +.It "PASSIVE NORMAL NORMAL" +.El +.Pp +The thread or process with THROTTLE I/O policy enabled may be slowed down when +it issues reads, but will not be slowed down when it issues writes. +If it issues far more writes than reads (e.g., an application +downloading large amounts of data through the network), these writes compete with the +normal I/Os of other processes and may have an adverse effect on the I/O +throughput or latency of those processes. +.Pp +.Sh RETURN VALUES +The +.Fn getiopolicy_np +call returns the I/O policy of the given I/O type and scope. If error +happens, -1 is returned. The +.Fn setiopolicy_np +call returns 0 if there is no error, or -1 if there is an error. When error +happens, the error code is stored in the external variable +.Fa errno . +.Sh ERRORS +.Fn Getiopolicy_np +and +.Fn setiopolicy_np +will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +Io_type or scope is not one of the values defined in this manual. +.El +.Pp +In addition to the errors indicated above, +.Fn setiopolicy_np +will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +Policy is not one of the values defined in this manual. +.El +.Sh SEE ALSO +.Xr nice 3 , +.Xr getpriority 2 , +.Xr setpriority 2 , +.Xr renice 8 +.Sh HISTORY +The +.Fn getiopolicy_np +and +.Fn setiopolicy_np +function call first appeared in Mac OS X 10.5 (Leopard) . diff --git a/sys/getiopolicy_np.c b/sys/getiopolicy_np.c new file mode 100644 index 0000000..8475a6e --- /dev/null +++ b/sys/getiopolicy_np.c @@ -0,0 +1,93 @@ +/* + * 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 + +extern int __iopolicysys(int, struct _iopol_param_t *); + +int +getiopolicy_np(int iotype, int scope) +{ + int policy, error; + struct _iopol_param_t iop_param; + + if (iotype != IOPOL_TYPE_DISK || + (scope != IOPOL_SCOPE_PROCESS && scope != IOPOL_SCOPE_THREAD)) { + errno = EINVAL; + policy = -1; + goto exit; + } + + iop_param.iop_scope = scope; + iop_param.iop_iotype = iotype; + error = __iopolicysys(IOPOL_CMD_GET, &iop_param); + if (error != 0) { + errno = error; + policy = -1; + goto exit; + } + + policy = iop_param.iop_policy; + + exit: + return policy; +} + +int +setiopolicy_np(int iotype, int scope, int policy) +{ + int error; + struct _iopol_param_t iop_param; + + if (iotype != IOPOL_TYPE_DISK || + (scope != IOPOL_SCOPE_PROCESS && scope != IOPOL_SCOPE_THREAD)) { + errno = EINVAL; + error = -1; + goto exit; + } + + switch (policy) { + case IOPOL_DEFAULT: + case IOPOL_NORMAL: + case IOPOL_THROTTLE: + case IOPOL_PASSIVE: + break; + default: + errno = EINVAL; + error = -1; + goto exit; + } + + iop_param.iop_scope = scope; + iop_param.iop_iotype = iotype; + iop_param.iop_policy = policy; + error = __iopolicysys(IOPOL_CMD_SET, &iop_param); + if (error != 0) { + errno = error; + error = -1; + goto exit; + } + + exit: + return error; +} diff --git a/mach/port_obj.c b/sys/getpeername.c similarity index 58% rename from mach/port_obj.c rename to sys/getpeername.c index 9690eab..743f6fe 100644 --- a/mach/port_obj.c +++ b/sys/getpeername.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,31 +21,28 @@ * @APPLE_LICENSE_HEADER_END@ */ /* - * @OSF_COPYRIGHT@ + * 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 -/* - * Define a service to map from a kernel-generated port name - * to server-defined "type" and "value" data to be associated - * with the port. - */ -#include -#include - -#define DEFAULT_TABLE_SIZE (64 * 1024) +#include +#include -struct port_obj_tentry *port_obj_table; -int port_obj_table_size = DEFAULT_TABLE_SIZE; +extern int __getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict); -void port_obj_init( - int maxsize) +/* + * getpeername stub, legacy version + */ +int +getpeername(int socket, struct sockaddr * __restrict address, + socklen_t * __restrict address_len) { - kern_return_t kr; + int ret = __getpeername(socket, address, address_len); - kr = vm_allocate(mach_task_self(), - (vm_offset_t *)&port_obj_table, - (vm_size_t)(maxsize * sizeof (*port_obj_table)), - TRUE); - if (kr != KERN_SUCCESS) - panic("port_obj_init: can't vm_allocate"); + /* use ENOTSUP for legacy behavior */ + if (ret < 0 && errno == EOPNOTSUPP) + errno = ENOTSUP; + return ret; } diff --git a/sys/pthread_getuid_np.c b/sys/getrlimit.c similarity index 71% rename from sys/pthread_getuid_np.c rename to sys/getrlimit.c index 00c07d0..249d443 100644 --- a/sys/pthread_getuid_np.c +++ b/sys/getrlimit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,11 +21,19 @@ * @APPLE_LICENSE_HEADER_END@ */ #include -#include -#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 -pthread_getugid_np(uid_t *uidp, gid_t *gidp) +getrlimit(int resource, struct rlimit *rlp) { - return syscall(SYS_gettid, uidp, gidp); + resource |= _RLIMIT_POSIX_FLAG; + return(__getrlimit(resource, rlp)); } diff --git a/sys/getsockname.c b/sys/getsockname.c new file mode 100644 index 0000000..9641972 --- /dev/null +++ b/sys/getsockname.c @@ -0,0 +1,48 @@ +/* + * 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/gettimeofday.c b/sys/gettimeofday.c index 959bbf5..56d9312 100644 --- a/sys/gettimeofday.c +++ b/sys/gettimeofday.c @@ -30,45 +30,45 @@ #include #include #include -#include #include #define __APPLE_API_PRIVATE #include #undef __APPLE_API_PRIVATE +extern int __gettimeofday(struct timeval *, struct timezone *); +extern int __commpage_gettimeofday(struct timeval *); -int gettimeofday (struct timeval *tp, struct timezone *tzp) +int gettimeofday (struct timeval *tp, void *vtzp) { - extern int __gettimeofday(struct timeval *, struct timezone *); - extern int __commpage_gettimeofday(struct timeval *); - static int validtz = 0; - static struct timezone cached_tz = {0}; - struct timeval atv; - - if (tp == NULL) { - if (tzp == NULL) - return (0); - tp = &atv; - } + static int validtz = 0; + static struct timezone cached_tz = {0}; + struct timezone *tzp = (struct timezone *)vtzp; + struct timeval atv; - if (__commpage_gettimeofday(tp)) { /* first try commpage */ - if (__gettimeofday(tp, tzp) < 0) { /* if it fails, use syscall */ - return (-1); - } + if (tp == NULL) { + if (tzp == NULL) + return (0); + tp = &atv; + } + + if (__commpage_gettimeofday(tp)) { /* first try commpage */ + if (__gettimeofday(tp, NULL) < 0) { /* if it fails, use syscall */ + return (-1); } + } - if (tzp) { - if (validtz == 0) { - struct tm *localtm = localtime ((time_t *)&tp->tv_sec); - cached_tz.tz_dsttime = localtm->tm_isdst; - cached_tz.tz_minuteswest = - (-localtm->tm_gmtoff / SECSPERMIN) + - (localtm->tm_isdst * MINSPERHOUR); - validtz = 1; - } - tzp->tz_dsttime = cached_tz.tz_dsttime; - tzp->tz_minuteswest = cached_tz.tz_minuteswest; - } - return (0); + if (tzp) { + if (validtz == 0) { + struct tm *localtm = localtime ((time_t *)&tp->tv_sec); + cached_tz.tz_dsttime = localtm->tm_isdst; + cached_tz.tz_minuteswest = + (-localtm->tm_gmtoff / SECSPERMIN) + + (localtm->tm_isdst * MINSPERHOUR); + validtz = 1; + } + tzp->tz_dsttime = cached_tz.tz_dsttime; + tzp->tz_minuteswest = cached_tz.tz_minuteswest; + } + return (0); } diff --git a/sys/ioctl64.c b/sys/ioctl.c similarity index 97% rename from sys/ioctl64.c rename to sys/ioctl.c index e0656f4..c735d0c 100644 --- a/sys/ioctl64.c +++ b/sys/ioctl.c @@ -26,6 +26,8 @@ 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, ...) diff --git a/sys/kill.c b/sys/kill.c new file mode 100644 index 0000000..466e624 --- /dev/null +++ b/sys/kill.c @@ -0,0 +1,42 @@ +/* + * 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 new file mode 100644 index 0000000..7146b4b --- /dev/null +++ b/sys/lchown.c @@ -0,0 +1,47 @@ +/* + * 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 + +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 new file mode 100644 index 0000000..efaef30 --- /dev/null +++ b/sys/libc.syscall @@ -0,0 +1,18 @@ +__exit ___exit +_accessx_np ___access_extended +_fstat$INODE64 ___fstat64 +_fstatfs$INODE64 ___fstatfs64 +_getfsstat$INODE64 ___getfsstat64 +_getsgroups_np ___getsgroups +_getwgroups_np ___getwgroups +# initgroups wrapper is defined in Libinfo +_initgroups +_lstat$INODE64 ___lstat64 +_posix_madvise ___madvise +_pthread_getugid_np ___gettid +_pthread_setugid_np ___settid +_setsgroups_np ___setsgroups +_setwgroups_np ___setwgroups +_stat$INODE64 ___stat64 +_statfs$INODE64 ___statfs64 +_wait4 ___wait4_nocancel diff --git a/sys/listen.c b/sys/listen.c new file mode 100644 index 0000000..e89502e --- /dev/null +++ b/sys/listen.c @@ -0,0 +1,47 @@ +/* + * 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 index 6809e9f..136028b 100644 --- a/sys/mmap.c +++ b/sys/mmap.c @@ -21,7 +21,6 @@ * @APPLE_LICENSE_HEADER_END@ */ #include -#include #include #include @@ -30,11 +29,12 @@ 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) { -#if __DARWIN_UNIX03 /* * Preemptory failures: * @@ -50,7 +50,6 @@ mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) cthread_set_errno_self(EINVAL); return(MAP_FAILED); } -#endif /* __DARWIN_UNIX03 */ return(__mmap(addr, len, prot, flags, fildes, off)); } diff --git a/sys/mprotect.c b/sys/mprotect.c index 2dcc7c7..3e6e98d 100644 --- a/sys/mprotect.c +++ b/sys/mprotect.c @@ -24,18 +24,18 @@ #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) { -#if __DARWIN_UNIX03 - return syscall(SYS_mprotect, addr, len, prot); -#else /* !__DARWIN_UNIX03 */ void *aligned_addr; int page_mask; size_t offset; @@ -50,7 +50,7 @@ mprotect(void *addr, size_t len, int prot) offset = ((uintptr_t) addr) & page_mask; aligned_addr = (void *) (((uintptr_t) addr) & ~page_mask); len += offset; - rv = syscall(SYS_mprotect, aligned_addr, len, prot); + rv = __mprotect(aligned_addr, len, prot); if (rv == -1 && errno == ENOMEM) { /* * Standards now require that we return ENOMEM if there was @@ -60,5 +60,4 @@ mprotect(void *addr, size_t len, int prot) errno = EINVAL; } return rv; -#endif /* !__DARWIN_UNIX03 */ } diff --git a/sys/msgctl.c b/sys/msgctl.c index f453219..32a1ba2 100644 --- a/sys/msgctl.c +++ b/sys/msgctl.c @@ -23,19 +23,19 @@ #include #include #include -#include /* * Stub function to account for the differences in the ipc_perm structure, * while maintaining binary backward compatibility. + * + * This is only the legacy behavior. */ +extern int __msgctl(int, int, struct msqid_ds *); + int msgctl(int msqid, int cmd, struct msqid_ds *ds) { -#ifdef __DARWIN_UNIX03 - return syscall(SYS_msgctl, msqid, cmd, ds); -#else /* !__DARWIN_UNIX03 */ - struct __msqid_ds_old *ds_old = ds; + struct __msqid_ds_old *ds_old = (struct __msqid_ds_old *)ds; struct __msqid_ds_new ds2; struct __msqid_ds_new *ds_new = &ds2; int rv; @@ -71,7 +71,7 @@ msgctl(int msqid, int cmd, struct msqid_ds *ds) _UP_CVT(msg_pad4[3]); /* binary compatibility */ } - rv = syscall(SYS_msgctl, msqid, semnum, cmd, ds_new); + rv = __msgctl(msqid, cmd, ds_new); if (cmd == IPC_STAT) { /* convert after call */ @@ -80,8 +80,8 @@ msgctl(int msqid, int cmd, struct msqid_ds *ds) _DN_CVT(msg_perm.cuid); /* warning! precision loss! */ _DN_CVT(msg_perm.cgid); /* warning! precision loss! */ _DN_CVT(msg_perm.mode); - ds_new->msg_perm.seq = ds_old->msg_perm._seq; - ds_new->msg_perm.key = ds_old->msg_perm._key; + ds_old->msg_perm.seq = ds_new->msg_perm._seq; + ds_old->msg_perm.key = ds_new->msg_perm._key; _DN_CVT(msg_first); _DN_CVT(msg_last); _DN_CVT(msg_cbytes); @@ -102,5 +102,4 @@ msgctl(int msqid, int cmd, struct msqid_ds *ds) } return (rv); -#endif /* !__DARWIN_UNIX03 */ } diff --git a/sys/msync.c b/sys/msync.c index 0ba0634..ea062f8 100644 --- a/sys/msync.c +++ b/sys/msync.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004, 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,21 +23,17 @@ #include #include #include -#include + +int __msync_nocancel(void *, size_t, int); /* - * Stub function to account for the differences in standard compliance - * while maintaining binary backward compatibility. + * Stub function for legacy version */ int msync(void *addr, size_t len, int flags) { -#if __DARWIN_UNIX03 - return syscall(SYS_msync, addr, len, flags); -#else /* !__DARWIN_UNIX03 */ int page_mask; size_t offset; - int rv; /* * Page-align "addr" since the system now requires it @@ -48,7 +44,5 @@ msync(void *addr, size_t len, int flags) offset = ((uintptr_t) addr) & page_mask; addr = (void *) (((uintptr_t) addr) & ~page_mask); len += offset; - rv = syscall(SYS_msync, addr, len, flags); - return rv; -#endif /* !__DARWIN_UNIX03 */ + return __msync_nocancel(addr, len, flags); } diff --git a/sys/munmap.c b/sys/munmap.c index debd5ca..be99a85 100644 --- a/sys/munmap.c +++ b/sys/munmap.c @@ -23,21 +23,20 @@ #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 __munmap(void *, size_t); + int munmap(void *addr, size_t len) { -#if __DARWIN_UNIX03 - return syscall(SYS_munmap, addr, len); -#else /* !__DARWIN_UNIX03 */ int page_mask; size_t offset; - int rv; if (len == 0) { /* @@ -56,7 +55,5 @@ munmap(void *addr, size_t len) offset = ((uintptr_t) addr) & page_mask; addr = (void *) (((uintptr_t) addr) & ~page_mask); len += offset; - rv = syscall(SYS_munmap, addr, len); - return rv; -#endif /* !__DARWIN_UNIX03 */ + return __munmap(addr, len); } diff --git a/sys/nanosleep.2 b/sys/nanosleep.2 index ef75207..0b41b9b 100644 --- a/sys/nanosleep.2 +++ b/sys/nanosleep.2 @@ -46,25 +46,33 @@ .Sh SYNOPSIS .In time.h .Ft int -.Fn nanosleep "const struct timespec *rqtp" "struct timespec *rmtp" +.Fo nanosleep +.Fa "const struct timespec *rqtp" +.Fa "struct timespec *rmtp" +.Fc .Sh DESCRIPTION -.Fn Nanosleep -causes the calling thread to sleep for the specified time +The +.Fn nanosleep +function causes the calling thread to sleep +for the amount of time specified in +.Fa rqtp (the actual time slept may be longer, due to system latencies and possible limitations in the timer resolution of the hardware). An unmasked signal will -cause it to terminate the sleep early, regardless of the +cause +.Fn nanosleep +to terminate the sleep early, regardless of the .Dv SA_RESTART value on the interrupting signal. .Sh RETURN VALUES -If the +If .Fn nanosleep -function returns because the requested time has elapsed, the value -returned will be zero. +returns because the requested time has elapsed, +the value returned will be zero. .Pp -If the +If .Fn nanosleep -function returns due to the delivery of a signal, the value returned +returns due to the delivery of a signal, the value returned will be the -1, and the global variable .Va errno will be set to indicate the interruption. diff --git a/sys/open.c b/sys/open.c new file mode 100644 index 0000000..041d32c --- /dev/null +++ b/sys/open.c @@ -0,0 +1,45 @@ +/* + * 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 +/* + * We need O_NOCTTY from fcntl.h, but that would also drag in the variadic + * prototype for open(), and so we'd have to use stdarg.h to get the mode. + * So open.h just contains O_NOCTTY, which it gets from fcntl.h. + * + * This is for legacy only. + */ +#include "open.h" + +int __open_nocancel(const char *path, int flags, mode_t mode); +int open(const char *path, int flags, mode_t mode) LIBC_ALIAS_C(open); + +/* + * 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) +{ + return(__open_nocancel(path, flags | O_NOCTTY, mode)); +} diff --git a/sys/openx_np.c b/sys/openx_np.c index 28e31e9..c71f4d0 100644 --- a/sys/openx_np.c +++ b/sys/openx_np.c @@ -23,11 +23,16 @@ #include #include #include -#include #include #include #include +enum {OPENX, MKFIFOX, MKDIRX}; + +extern int __open_extended(const char *, int, uid_t, gid_t, int, struct kauth_filesec *); +extern int __mkfifo_extended(const char *, uid_t, gid_t, int, struct kauth_filesec *); +extern int __mkdir_extended(const char *, uid_t, gid_t, int, struct kauth_filesec *); + static int _mkfilex_np(int opcode, const char *path, int flags, filesec_t fsec) { @@ -92,11 +97,17 @@ _mkfilex_np(int opcode, const char *path, int flags, filesec_t fsec) fsacl = NULL; } - if (opcode == SYS_open_extended) { - return(syscall(opcode, path, flags, owner, group, mode, fsacl)); - } else { - return(syscall(opcode, path, owner, group, mode, fsacl)); + switch (opcode) { + case OPENX: + return(__open_extended(path, flags, owner, group, mode, fsacl)); + case MKFIFOX: + return(__mkfifo_extended(path, owner, group, mode, fsacl)); + case MKDIRX: + return(__mkdir_extended(path, owner, group, mode, fsacl)); } + /* should never get here */ + errno = EINVAL; + return(-1); } int @@ -105,17 +116,17 @@ openx_np(const char *path, int flags, filesec_t fsec) /* optimise for the simple case */ if (!(flags & O_CREAT) || (fsec == NULL)) return(open(path, flags)); - return(_mkfilex_np(SYS_open_extended, path, flags, fsec)); + return(_mkfilex_np(OPENX, path, flags, fsec)); } int mkfifox_np(const char *path, filesec_t fsec) { - return(_mkfilex_np(SYS_mkfifo_extended, path, 0, fsec)); + return(_mkfilex_np(MKFIFOX, path, 0, fsec)); } int mkdirx_np(const char *path, filesec_t fsec) { - return(_mkfilex_np(SYS_mkdir_extended, path, 0, fsec)); + return(_mkfilex_np(MKDIRX, path, 0, fsec)); } diff --git a/sys/posix_spawn.c b/sys/posix_spawn.c new file mode 100644 index 0000000..cdb0fed --- /dev/null +++ b/sys/posix_spawn.c @@ -0,0 +1,1213 @@ +/* + * 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@ + */ + +/* + * [SPN] Support for _POSIX_SPAWN + */ + +#include /* for user_size_t */ +#include +#include +#include +#include +#include /* for OPEN_MAX, PATH_MAX */ +#include /* for offsetof() */ +#include /* for strlcpy() */ +#include /* for _PATH_DEFPATH */ +#include /* for struct stat */ +#include +#include + + +/* + * posix_spawnattr_init + * + * Description: Initialize a spawn attributes object attr with default values + * + * Parameters: attr The spawn attributes object to be + * initialized + * + * Returns: 0 Success + * ENOMEM Insufficient memory exists to + * initialize the spawn attributes object. + * + * Note: As an implementation detail, the externally visibily type + * posix_spawnattr_t is defined to be a void *, and initialization + * involves allocation of a memory object. Subsequent changes to + * the spawn attributes may result in reallocation under the + * covers. + * + * Reinitialization of an already initialized spawn attributes + * object will result in memory being leaked. Because spawn + * attributes are not required to be used in conjunction with a + * static initializer, there is no way to distinguish a spawn + * attribute with stack garbage from one that's been initialized. + * This is arguably an API design error. + */ +int +posix_spawnattr_init(posix_spawnattr_t *attr) +{ + _posix_spawnattr_t *psattrp = (_posix_spawnattr_t *)attr; + int err = 0; + + if ((*psattrp = (_posix_spawnattr_t)malloc(sizeof(struct _posix_spawnattr))) == NULL) { + err = ENOMEM; + } else { + + /* + * The default value of this attribute shall be as if no + * flags were set + */ + (*psattrp)->psa_flags = 0; + + /* + * The default value of this attribute shall be an empty + * signal set + */ + (*psattrp)->psa_sigdefault = 0; + + /* The default value of this attribute is unspecified */ + (*psattrp)->psa_sigmask = 0; + + /* The default value of this attribute shall be zero */ + (*psattrp)->psa_pgroup = 0; /* doesn't matter */ + + /* Default is no binary preferences, i.e. use normal grading */ + memset((*psattrp)->psa_binprefs, 0, + sizeof((*psattrp)->psa_binprefs)); + + /* Default is no port actions to take */ + (*psattrp)->psa_ports = NULL; + } + + return (err); +} + + +/* + * posix_spawnattr_destroy + * + * Description: Destroy a spawn attributes object that was previously + * initialized via posix_spawnattr_init() by freeing any + * memory associated with it and setting it to an invalid value. + * + * Parameters: attr The spawn attributes object to be + * destroyed. + * + * Returns: 0 Success + * + * Notes: The destroyed spawn attribute results in the void * pointer + * being set to NULL; subsequent use without reinitialization + * will result in explicit program failure (rather than merely + * "undefined behaviour"). + * + * NOTIMP: Allowed failures (checking NOT required): + * EINVAL The value specified by attr is invalid. + */ +int +posix_spawnattr_destroy(posix_spawnattr_t *attr) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + posix_spawn_destroyportactions_np(attr); + + free(psattr); + *attr = NULL; + + return (0); +} + + +/* + * posix_spawnattr_setflags + * + * Description: Set the spawn flags attribute for the spawn attribute object + * referred to by 'attr'. + * + * Parameters: attr The spawn attributes object whose flags + * are to be set + * flags The flags value to set + * + * Returns: 0 Success + * + * NOTIMP: Allowed failures (checking NOT required): + * EINVAL The value specified by attr is invalid. + * EINVAL The value of the attribute being set is not valid. + */ +int +posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + psattr->psa_flags = flags; + + return (0); +} + + +/* + * posix_spawnattr_getflags + * + * Description: Retrieve the spawn attributes flag for the spawn attributes + * object referenced by 'attr' and place them in the memory + * location referenced by 'flagsp' + * + * Parameters: attr The spawn attributes object whose flags + * are to be retrieved + * flagsp A pointer to a short value to receive + * the flags + * + * Returns: 0 Success + * + * Implicit Returns: + * *flagps (modified) The flags value from the spawn + * attributes object + * + * NOTIMP: Allowed failures (checking NOT required): + * EINVAL The value specified by attr is invalid. + * EINVAL The value of the attribute being set is not valid. + */ +int +posix_spawnattr_getflags(const posix_spawnattr_t * __restrict attr, + short * __restrict flagsp) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + *flagsp = psattr->psa_flags; + + return (0); +} + + +/* + * posix_spawnattr_getsigdefault + * + * Description: Retrieve the set of signals to be set to default according to + * the spawn attribute value referenced by 'attr' and place the + * result into the memory containing the sigset_t referenced by + * 'sigdefault' + * + * Parameters: attr The spawn attributes object whose + * signal set for default signals is to + * be retrieved + * sigdefault A pointer to the sigset_t to receive + * the signal set + * + * Returns: 0 Success + * + * Implicit Returns: + * *sigdefault (modified) The signal set of signals to default + * from the spawn attributes object + */ +int +posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict attr, + sigset_t * __restrict sigdefault) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + *sigdefault = psattr->psa_sigdefault; + + return (0); +} + + +/* + * posix_spawnattr_getpgroup + * + * Description: Obtain the value of the spawn process group attribute from the + * spawn attributes object referenced by 'attr' and place the + * results in the memory location referenced by 'pgroup' + * + * Parameters: attr The spawn attributes object whose + * process group information is to be + * retrieved + * pgroup A pointer to the pid_t to receive the + * process group + * + * Returns: 0 Success + * + * Implicit Returns: + * *pgroup (modified) The process group information from the + * spawn attributes object + */ +int +posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict attr, + pid_t * __restrict pgroup) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + *pgroup = psattr->psa_pgroup; + + return (0); +} + + +/* + * posix_spawnattr_getsigmask + * + * Description: Obtain the value of the spawn signal mask attribute from the + * spawn attributes object referenced by 'attr' and place the + * result into the memory containing the sigset_t referenced by + * 'sigmask' + * + * Parameters: attr The spawn attributes object whose + * signal set for masked signals is to + * be retrieved + * sigmask A pointer to the sigset_t to receive + * the signal set + * + * Returns: 0 Success + * + * Implicit Returns: + * *sigmask (modified) The signal set of signals to mask + * from the spawn attributes object + */ +int +posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict attr, + sigset_t * __restrict sigmask) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + *sigmask = psattr->psa_sigmask; + + return (0); +} + +/* + * posix_spawnattr_getbinpref_np + * + * Description: Obtain the value of the spawn binary preferences attribute from + * the spawn attributes object referenced by 'attr' and place the + * result into the memory referenced by 'pref'. + * + * Parameters: attr The spawn attributes object whose + * binary preferences are to be retrieved + * count The size of the cpu_type_t array + * pref An array of cpu types + * ocount The actual number copied + * + * Returns: 0 No binary preferences found + * > 0 The number of cpu types (less than + * count) copied over from 'attr'. + * + * Implicit Returns: + * *pref (modified) The binary preferences array + * from the spawn attributes object + */ +int +posix_spawnattr_getbinpref_np(const posix_spawnattr_t * __restrict attr, + size_t count, cpu_type_t *pref, size_t * __restrict ocount) +{ + _posix_spawnattr_t psattr; + int i = 0; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + for (i = 0; i < count && i < 4; i++) { + pref[i] = psattr->psa_binprefs[i]; + } + + if (ocount) + *ocount = i; + return 0; +} +/* + * posix_spawnattr_setsigdefault + * + * Description: Set the set of signals to be set to default for the spawn + * attribute value referenced by 'attr' from the memory + * containing the sigset_t referenced by 'sigdefault' + * + * Parameters: attr The spawn attributes object whose + * signal set for default signals is to + * be set + * sigdefault A pointer to the sigset_t from which to + * obtain the signal set + * + * Returns: 0 Success + */ +int +posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict attr, + const sigset_t * __restrict sigdefault) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + psattr->psa_sigdefault = *sigdefault; + + return (0); +} + + +/* + * posix_spawnattr_setpgroup + * + * Description: Set the value of the spawn process group attribute for the + * spawn attributes object referenced by 'attr' from the value + * of 'pgroup' + * + * Parameters: attr The spawn attributes object for which + * the process group information is to be + * set + * pgroup The process group to set + * + * Returns: 0 Success + */ +int +posix_spawnattr_setpgroup(posix_spawnattr_t * attr, pid_t pgroup) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + psattr->psa_pgroup = pgroup; + + return (0); +} + + +/* + * posix_spawnattr_setsigmask + * + * Description: Set the set of signals to be masked for the spawn attribute + * value referenced by 'attr' from the memory containing the + * sigset_t referenced by 'sigmask' + * + * Parameters: attr The spawn attributes object whose + * signal set for masked signals is to + * be set + * sigmask A pointer to the sigset_t from which to + * obtain the signal set + * + * Returns: 0 Success + */ +int +posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict attr, + const sigset_t * __restrict sigmask) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + psattr->psa_sigmask = *sigmask; + + return (0); +} + + +/* + * posix_spawnattr_setbinpref_np + * + * Description: Set the universal binary preferences for the spawn attribute + * value referenced by 'attr' from the memory containing the + * cpu_type_t array referenced by 'pref', size of 'count' + * + * Parameters: attr The spawn attributes object whose + * binary preferences are to be set + * count Size of the array pointed to by 'pref' + * pref cpu_type_t array of binary preferences + * ocount The actual number copied + * + * Returns: 0 No preferences copied + * > 0 Number of preferences copied + * + * Note: The posix_spawnattr_t currently only holds four cpu_type_t's. + * If the caller provides more preferences than this limit, they + * will be ignored, as reflected in the return value. + */ +int +posix_spawnattr_setbinpref_np(posix_spawnattr_t * __restrict attr, + size_t count, cpu_type_t *pref, size_t * __restrict ocount) +{ + _posix_spawnattr_t psattr; + int i = 0; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + for (i = 0; i < count && i < 4; i++) { + psattr->psa_binprefs[i] = pref[i]; + } + + /* return number of binprefs copied over */ + if (ocount) + *ocount = i; + return 0; +} + +/* + * posix_spawn_createportactions_np + * Description: create a new posix_spawn_port_actions struct and link + * it into the posix_spawnattr. + */ +int +posix_spawn_createportactions_np(posix_spawnattr_t *attr) +{ + _posix_spawnattr_t psattr; + _posix_spawn_port_actions_t acts; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + acts = (_posix_spawn_port_actions_t)malloc(PS_PORT_ACTIONS_SIZE(2)); + if (acts == NULL) + return ENOMEM; + + acts->pspa_alloc = 2; + acts->pspa_count = 0; + + psattr->psa_ports = acts; + return 0; +} + +/* + * posix_spawn_growportactions_np + * Description: Enlarge the size of portactions if necessary + */ +int +posix_spawn_growportactions_np(posix_spawnattr_t *attr) +{ + _posix_spawnattr_t psattr; + _posix_spawn_port_actions_t acts; + int newnum; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + acts = psattr->psa_ports; + if (acts == NULL) + return EINVAL; + + /* Double number of port actions allocated for */ + newnum = 2 * acts->pspa_alloc; + acts = realloc(acts, PS_PORT_ACTIONS_SIZE(newnum)); + if (acts == NULL) + return ENOMEM; + + acts->pspa_alloc = newnum; + return 0; +} + +/* + * posix_spawn_destroyportactions_np + * Description: clean up portactions struct in posix_spawnattr_t attr + */ +int +posix_spawn_destroyportactions_np(posix_spawnattr_t *attr) +{ + _posix_spawnattr_t psattr; + _posix_spawn_port_actions_t acts; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + acts = psattr->psa_ports; + if (acts == NULL) + return EINVAL; + + free(acts); + return 0; +} + + +/* + * posix_spawnattr_setspecialport_np + * + * Description: Set a new value for a mach special port in the spawned task. + * + * Parameters: attr The spawn attributes object for the + * new process + * new_port The new value for the special port + * which The particular port to be set + * (see task_set_special_port for details) + * + * Returns: 0 Success + * ENOMEM Couldn't allocate memory + */ +int +posix_spawnattr_setspecialport_np( + posix_spawnattr_t *attr, + mach_port_t new_port, + int which) +{ + _posix_spawnattr_t psattr; + int err = 0; + _ps_port_action_t *action; + _posix_spawn_port_actions_t ports; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + ports = psattr->psa_ports; + /* Have any port actions been created yet? */ + if (ports == NULL) { + err = posix_spawn_createportactions_np(attr); + if (err) + return err; + ports = psattr->psa_ports; + } + + /* Is there enough room? */ + if (ports->pspa_alloc == ports->pspa_count) { + err = posix_spawn_growportactions_np(attr); + if (err) + return err; + } + + /* Add this action to next spot in array */ + action = &ports->pspa_actions[ports->pspa_count]; + action->port_type = PSPA_SPECIAL; + action->new_port = new_port; + action->which = which; + + ports->pspa_count++; + return err; +} + +/* + * posix_spawnattr_setexceptionports_np + * + * Description: Set a new port for a set of exception ports in the spawned task. + * + * Parameters: attr The spawn attributes object for the + * new process + * mask A bitfield indicating which exceptions + * to associate the port with + * new_port The new value for the exception port + * behavior The default behavior for the port + * flavor The default flavor for the port + * (see task_set_exception_ports) + * + * Returns: 0 Success + */ +int +posix_spawnattr_setexceptionports_np( + posix_spawnattr_t *attr, + exception_mask_t mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t flavor) +{ + _posix_spawnattr_t psattr; + int err = 0; + _ps_port_action_t *action; + _posix_spawn_port_actions_t ports; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + ports = psattr->psa_ports; + /* Have any port actions been created yet? */ + if (ports == NULL) { + err = posix_spawn_createportactions_np(attr); + if (err) + return err; + ports = psattr->psa_ports; + } + + /* Is there enough room? */ + if (ports->pspa_alloc == ports->pspa_count) { + err = posix_spawn_growportactions_np(attr); + if (err) + return err; + } + + /* Add this action to next spot in array */ + action = &ports->pspa_actions[ports->pspa_count]; + action->port_type = PSPA_EXCEPTION; + action->mask = mask; + action->new_port = new_port; + action->behavior = behavior; + action->flavor = flavor; + + ports->pspa_count++; + return err; +} + + +/* + * posix_spawn_file_actions_init + * + * Description: Initialize a spawn file actions object attr with default values + * + * Parameters: file_actions The spawn file actions object to be + * initialized + * + * Returns: 0 Success + * ENOMEM Insufficient memory exists to + * initialize the spawn file actions + * object. + * + * Note: As an implementation detail, the externally visibily type + * posix_spawn_file_actions_t is defined to be a void *, and + * initialization involves allocation of a memory object. + * Subsequent changes to the spawn file actions may result in + * reallocation under the covers. + * + * Reinitialization of an already initialized spawn file actions + * object will result in memory being leaked. Because spawn + * file actions are not required to be used in conjunction with a + * static initializer, there is no way to distinguish a spawn + * file actions with stack garbage from one that's been + * initialized. This is arguably an API design error. + */ +int +posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions) +{ + _posix_spawn_file_actions_t *psactsp = (_posix_spawn_file_actions_t *)file_actions; + int err = 0; + + if ((*psactsp = (_posix_spawn_file_actions_t)malloc(PSF_ACTIONS_SIZE(PSF_ACTIONS_INIT_COUNT))) == NULL) { + err = ENOMEM; + } else { + (*psactsp)->psfa_act_alloc = PSF_ACTIONS_INIT_COUNT; + (*psactsp)->psfa_act_count = 0; + } + + return (err); +} + + +/* + * posix_spawn_file_actions_destroy + * + * Description: Destroy a spawn file actions object that was previously + * initialized via posix_spawn_file_actions_init() by freeing any + * memory associated with it and setting it to an invalid value. + * + * Parameters: attr The spawn file actions object to be + * destroyed. + * + * Returns: 0 Success + * + * Notes: The destroyed spawn file actions results in the void * pointer + * being set to NULL; subsequent use without reinitialization + * will result in explicit program failure (rather than merely + * "undefined behaviour"). + * + * NOTIMP: Allowed failures (checking NOT required): + * EINVAL The value specified by file_actions is invalid. + */ +int +posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *file_actions) +{ + _posix_spawn_file_actions_t psacts; + + if (file_actions == NULL || *file_actions == NULL) + return EINVAL; + + psacts = *(_posix_spawn_file_actions_t *)file_actions; + free(psacts); + *file_actions = NULL; + + return (0); +} + + +/* + * _posix_spawn_file_actions_grow + * + * Description: Grow the available list of file actions associated with the + * pointer to the structure provided; replace the contents of the + * pointer as a side effect. + * + * Parameters: psactsp Pointer to _posix_spawn_file_actions_t + * to grow + * + * Returns: 0 Success + * ENOMEM Insufficient memory for operation + * + * Notes: This code is common to all posix_spawn_file_actions_*() + * functions, since we use a naieve data structure implementation + * at present. Future optimization will likely change this. + */ +static int +_posix_spawn_file_actions_grow(_posix_spawn_file_actions_t *psactsp) +{ + int new_alloc = (*psactsp)->psfa_act_alloc * 2; + _posix_spawn_file_actions_t new_psacts; + + /* + * XXX may want to impose an administrative limit here; POSIX does + * XXX not provide for an administrative error return in this case, + * XXX so it's probably acceptable to just fail catastrophically + * XXX instead of implementing one. + */ + if ((new_psacts = (_posix_spawn_file_actions_t)realloc((*psactsp), PSF_ACTIONS_SIZE(new_alloc))) == NULL) { + return (ENOMEM); + } + new_psacts->psfa_act_alloc = new_alloc; + *psactsp = new_psacts; + + return (0); +} + + +/* + * posix_spawn_file_actions_addopen + * + * Description: Add an open action to the object referenced by 'file_actions' + * that will cause the file named by 'path' to be attempted to be + * 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 + * filedes fd that open is to use + * path path to file to open + * oflag open file flags + * mode open file mode + * + * 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_addopen( + posix_spawn_file_actions_t * __restrict file_actions, + int filedes, const char * __restrict path, int oflag, + mode_t mode) +{ + _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 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_OPEN; + psfileact->psfaa_filedes = filedes; + psfileact->psfaa_openargs.psfao_oflag = oflag; + psfileact->psfaa_openargs.psfao_mode = mode; + strlcpy(psfileact->psfaa_openargs.psfao_path, path, PATH_MAX); + + return (0); +} + + +/* + * posix_spawn_file_actions_addclose + * + * Description: Add a close action to the object referenced by 'file_actions' + * 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 + * filedes fd to close + * + * 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_addclose(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 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_CLOSE; + psfileact->psfaa_filedes = filedes; + + return (0); +} + + +/* + * posix_spawn_file_actions_adddup2 + * + * Description: Add a dpu2 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 + * filedes fd to dup2 + * newfiledes fd to dup2 it to + * + * Returns: 0 Success + * EBADF The value specified by either fildes + * or by newfiledes 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_adddup2(posix_spawn_file_actions_t *file_actions, + int filedes, int newfiledes) +{ + _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 || + newfiledes < 0 || newfiledes >= OPEN_MAX) + return (EBADF); + + /* 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_DUP2; + psfileact->psfaa_filedes = filedes; + psfileact->psfaa_openargs.psfao_oflag = newfiledes; + + return (0); +} + + +/* + * posix_spawnp + * + * Description: Create a new process from the process image corresponding to + * the supplied 'file' argument and the parent processes path + * environment. + * + * Parameters: pid Pointer to pid_t to receive the + * PID of the spawned process, if + * successful and 'pid' != NULL + * file Name of image file to spawn + * file_actions spawn file actions object which + * describes file actions to be + * performed during the spawn + * attrp spawn attributes object which + * describes attributes to be + * applied during the spawn + * argv argument vector array; NULL + * terminated + * envp environment vector array; NULL + * terminated + * + * Returns: 0 Success + * !0 An errno value indicating the + * cause of the failure to spawn + * + * Notes: Much of this function is derived from code from execvP() from + * exec.c in libc; this common code should be factored out at + * some point to prevent code duplication or desynchronization vs. + * bug fixes applied to one set of code but not the other. + */ +int +posix_spawnp(pid_t * __restrict pid, const char * __restrict file, + const posix_spawn_file_actions_t *file_actions, + const posix_spawnattr_t * __restrict attrp, + char *const argv[ __restrict], char *const envp[ __restrict]) +{ + const char *env_path; + char *bp; + char *cur; + char *p; + char **memp; + int lp; + int ln; + int cnt; + int err = 0; + int eacces = 0; + struct stat sb; + char path_buf[PATH_MAX]; + + if ((env_path = getenv("PATH")) == NULL) + env_path = _PATH_DEFPATH; + + /* If it's an absolute or relative path name, it's easy. */ + if (index(file, '/')) { + bp = (char *)file; + cur = NULL; + goto retry; + } + bp = path_buf; + + /* If it's an empty path name, fail in the usual POSIX way. */ + if (*file == '\0') + return (ENOENT); + + if ((cur = alloca(strlen(env_path) + 1)) == NULL) + return ENOMEM; + strcpy(cur, env_path); + while ((p = strsep(&cur, ":")) != NULL) { + /* + * It's a SHELL path -- double, leading and trailing colons + * mean the current directory. + */ + if (*p == '\0') { + p = "."; + lp = 1; + } else { + lp = strlen(p); + } + ln = strlen(file); + + /* + * If the path is too long complain. This is a possible + * security issue; given a way to make the path too long + * the user may spawn the wrong program. + */ + if (lp + ln + 2 > sizeof(path_buf)) { + err = ENAMETOOLONG; + goto done; + } + bcopy(p, path_buf, lp); + path_buf[lp] = '/'; + bcopy(file, path_buf + lp + 1, ln); + path_buf[lp + ln + 1] = '\0'; + +retry: err = posix_spawn(pid, bp, file_actions, attrp, argv, envp); + switch (err) { + case E2BIG: + case ENOMEM: + case ETXTBSY: + goto done; + case ELOOP: + case ENAMETOOLONG: + case ENOENT: + case ENOTDIR: + break; + case ENOEXEC: + for (cnt = 0; argv[cnt]; ++cnt) + ; + memp = alloca((cnt + 2) * sizeof(char *)); + if (memp == NULL) { + /* errno = ENOMEM; XXX override ENOEXEC? */ + goto done; + } + memp[0] = "sh"; + memp[1] = bp; + bcopy(argv + 1, memp + 2, cnt * sizeof(char *)); + err = posix_spawn(pid, _PATH_BSHELL, file_actions, attrp, memp, envp); + goto done; + default: + /* + * EACCES may be for an inaccessible directory or + * a non-executable file. Call stat() to decide + * which. This also handles ambiguities for EFAULT + * and EIO, and undocumented errors like ESTALE. + * We hope that the race for a stat() is unimportant. + */ + if (stat(bp, &sb) != 0) + break; + if (err == EACCES) { + eacces = 1; + continue; + } + goto done; + } + } + if (eacces) + err = EACCES; + else + err = ENOENT; +done: + return (err); +} + + +/* + * posix_spawn + * + * Description: Create a new process from the process image corresponding to + * the supplied 'path' argument. + * + * Parameters: pid Pointer to pid_t to receive the + * PID of the spawned process, if + * successful and 'pid' != NULL + * path Path of image file to spawn + * file_actions spawn file actions object which + * describes file actions to be + * performed during the spawn + * attrp spawn attributes object which + * describes attributes to be + * applied during the spawn + * argv argument vector array; NULL + * terminated + * envp environment vector array; NULL + * terminated + * + * Returns: 0 Success + * !0 An errno value indicating the + * cause of the failure to spawn + * + * Notes: Unlike other system calls, the return value of this system + * call is expected to either be a 0 or an errno, rather than a + * 0 or a -1, with the 'errno' variable being set. + */ +extern int __posix_spawn(pid_t * __restrict, const char * __restrict, + struct _posix_spawn_args_desc *, + char *const argv[ __restrict], char *const envp[ __restrict]); + +int +posix_spawn(pid_t * __restrict pid, const char * __restrict path, + const posix_spawn_file_actions_t *file_actions, + const posix_spawnattr_t * __restrict attrp, + char *const argv[ __restrict], char *const envp[ __restrict]) +{ + int saveerrno = errno; + int ret; + /* + * Only do extra work if we have file actions or attributes to push + * down. We use a descriptor to push this information down, since we + * want to have size information, which will let us (1) preallocate a + * single chunk of memory for the copyin(), and (2) allow us to do a + * single copyin() per attributes or file actions as a monlithic block. + * + * Note: A future implementation may attempt to do the same + * thing for the argv/envp data, which could potentially + * result in a performance improvement due to increased + * kernel efficiency, even though it would mean copying + * the data in user space. + */ + if ((file_actions != NULL && (*file_actions != NULL) && (*(_posix_spawn_file_actions_t *)file_actions)->psfa_act_count > 0) || attrp != NULL) { + struct _posix_spawn_args_desc ad; + + memset(&ad, 0, sizeof(ad)); + if (attrp != NULL && *attrp != NULL) { + _posix_spawnattr_t psattr = *(_posix_spawnattr_t *)attrp; + ad.attr_size = sizeof(struct _posix_spawnattr); + ad.attrp = psattr; + + if (psattr->psa_ports != NULL) { + ad.port_actions = psattr->psa_ports; + ad.port_actions_size = PS_PORT_ACTIONS_SIZE( + ad.port_actions->pspa_count); + } + } + if (file_actions != NULL && *file_actions != NULL) { + _posix_spawn_file_actions_t psactsp = + *(_posix_spawn_file_actions_t *)file_actions; + + if (psactsp->psfa_act_count > 0) { + ad.file_actions_size = PSF_ACTIONS_SIZE(psactsp->psfa_act_count); + ad.file_actions = psactsp; + } + } + + ret = __posix_spawn(pid, path, &ad, argv, envp); + } else + ret = __posix_spawn(pid, path, NULL, argv, envp); + + if (ret < 0) + ret = errno; + errno = saveerrno; + return ret; +} + diff --git a/sys/pthread_kill.2 b/sys/pthread_kill.2 index c76f456..8c83b99 100644 --- a/sys/pthread_kill.2 +++ b/sys/pthread_kill.2 @@ -35,7 +35,6 @@ .Nm pthread_kill .Nd send a signal to a specified thread .Sh SYNOPSIS -.In pthread.h .In signal.h .Ft int .Fn pthread_kill "pthread_t thread" "int sig" @@ -58,17 +57,25 @@ Otherwise, an error number is returned. .Fn pthread_kill will fail if: .Bl -tag -width Er -.It Bq Er ESRCH -.Fa thread -is an invalid thread ID. .It Bq Er EINVAL .Fa sig is an invalid or unsupported signal number. +.It Bq Er ESRCH +.Fa thread +is an invalid thread ID. .El +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +The include file +.In pthread.h +is necessary. .Sh SEE ALSO .Xr kill 2 , .Xr pthread_self 3 , -.Xr raise 3 +.Xr raise 3 , +.Xr compat 5 .Sh STANDARDS .Fn pthread_kill conforms to ISO/IEC 9945-1:1996 (``POSIX.1'') diff --git a/sys/pthread_sigmask.2 b/sys/pthread_sigmask.2 index 83dd291..5680dd2 100644 --- a/sys/pthread_sigmask.2 +++ b/sys/pthread_sigmask.2 @@ -33,10 +33,13 @@ .Nm pthread_sigmask .Nd examine and/or change a thread's signal mask .Sh SYNOPSIS -.In pthread.h .In signal.h .Ft int -.Fn pthread_sigmask "int how" "const sigset_t *set" "sigset_t *oset" +.Fo pthread_sigmask +.Fa "int how" +.Fa "const sigset_t *restrict set" +.Fa "sigset_t *restrict oset" +.Fc .Sh DESCRIPTION The .Fn pthread_sigmask @@ -82,12 +85,20 @@ will fail if: .Fa how is not one of the defined values. .El +.Sh LEGACY SYNOPSIS +.Fd #include +.Fd #include +.Pp +The include file +.In pthread.h +is necessary. .Sh SEE ALSO .Xr sigaction 2 , .Xr sigpending 2 , .Xr sigprocmask 2 , .Xr sigsuspend 2 , -.Xr sigsetops 3 +.Xr sigsetops 3 , +.Xr compat 5 .Sh STANDARDS .Fn pthread_sigmask conforms to ISO/IEC 9945-1:1996 (``POSIX.1'') diff --git a/sys/recvfrom.c b/sys/recvfrom.c new file mode 100644 index 0000000..320858b --- /dev/null +++ b/sys/recvfrom.c @@ -0,0 +1,47 @@ +/* + * 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/x86_64/sys/getpid.s b/sys/recvmsg.c similarity index 61% rename from x86_64/sys/getpid.s rename to sys/recvmsg.c index f3a738a..7acc6b0 100644 --- a/x86_64/sys/getpid.s +++ b/sys/recvmsg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,31 +21,27 @@ * @APPLE_LICENSE_HEADER_END@ */ /* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved + * We need conformance on so that EOPNOTSUPP=102. But the routine symbol + * will still be the legacy (undecorated) one. */ -#include +#undef __DARWIN_UNIX03 +#define __DARWIN_UNIX03 1 - .data - .private_extern __current_pid -__current_pid: - .long 0 +#include +#include + +ssize_t __recvmsg_nocancel(int, struct msghdr *, int); /* - * If __current_pid is > 0, return it, else make syscall. - * If __current_pid is 0, cache result of syscall. + * recvmsg stub, legacy version */ -TEXT -LEAF(_getpid, 0) - movl __current_pid(%rip), %eax - testl %eax, %eax - jle 1f - ret -1: - UNIX_SYSCALL_NONAME(getpid, 0) - movl %eax, %edx - xorl %eax, %eax - leaq __current_pid(%rip), %rcx - lock - cmpxchgl %edx, (%rcx) - movl %edx, %eax - ret +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/select.c b/sys/select.c new file mode 100644 index 0000000..c975899 --- /dev/null +++ b/sys/select.c @@ -0,0 +1,80 @@ +/* + * 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 index 60fc5b6..cdff87c 100644 --- a/sys/sem_close.2 +++ b/sys/sem_close.2 @@ -49,12 +49,12 @@ succeeds unless: is not a valid semaphore descriptor. .El .Sh SEE ALSO -.Xr semctl 2 , -.Xr semget 2 , -.Xr semop 2 , .Xr sem_init 2 , .Xr sem_open 2 , -.Xr sem_unlink 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 index 5f4d923..423e98a 100644 --- a/sys/sem_open.2 +++ b/sys/sem_open.2 @@ -29,17 +29,24 @@ .Sh SYNOPSIS .Fd #include .Ft sem_t * -.Fn sem_open "const char *name" "int flags" -.Ft sem_t * -.Fn sem_open "const char *name" "int flags" "mode_t mode" "unsigned int value" +.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 flags +.Fa oflag and a semaphore descriptor is returned to the calling process. .Pp -The flags specified are formed by +The value of +.Fa oflag +is formed by .Em or Ns 'ing the following values: .Pp @@ -49,8 +56,8 @@ O_EXCL error if create and semaphore exists .Ed .Pp If -.Dv O_CREATE -if specified, +.Dv O_CREAT +is specified, .Fn sem_open requires an additional two arguments. .Fa mode @@ -77,7 +84,7 @@ and set. .Pp When a new semaphore is created, it is given the user ID and group ID -which coorespond to the effective user and group IDs of the calling +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 @@ -148,14 +155,14 @@ is specified, the file does not exist, and there is insufficient space available to create the semaphore. .El .Sh SEE ALSO -.Xr semctl 2 , -.Xr semget 2 , -.Xr semop 2 , .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 diff --git a/sys/sem_open.c b/sys/sem_open.c index 8728234..dd9116b 100644 --- a/sys/sem_open.c +++ b/sys/sem_open.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #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, ...) @@ -62,7 +62,7 @@ sem_open (const char *name, int flags, ...) value = va_arg(ap, unsigned int); va_end(ap); - return syscall (SYS_sem_open, name, flags, mode, value); + return __sem_open(name, flags, mode, value); } #endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/sem_post.2 b/sys/sem_post.2 index d5afd23..36d06fd 100644 --- a/sys/sem_post.2 +++ b/sys/sem_post.2 @@ -31,7 +31,7 @@ .Ft int .Fn sem_post "sem_t *sem" .Sh DESCRIPTION -The the semaphore referenced by +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. @@ -54,12 +54,12 @@ succeeds unless: is not a valid semaphore descriptor. .El .Sh SEE ALSO -.Xr semctl 2 , -.Xr semget 2 , -.Xr semop 2 , .Xr sem_open 2 , .Xr sem_trywait 2 , -.Xr sem_wait 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_trywait.2 b/sys/sem_trywait.2 deleted file mode 100644 index c0db675..0000000 --- a/sys/sem_trywait.2 +++ /dev/null @@ -1 +0,0 @@ -.so man2/sem_wait.2 diff --git a/sys/sem_unlink.2 b/sys/sem_unlink.2 index 6aea5ff..7fc7e9c 100644 --- a/sys/sem_unlink.2 +++ b/sys/sem_unlink.2 @@ -33,9 +33,9 @@ .Sh DESCRIPTION The named semaphore named .Fa name -is removed. If the semaphore is in use my other processes, then +is removed. If the semaphore is in use by other processes, then .Fa name -is immeditately dissasociated with the semaphore, but the semaphore +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 @@ -64,11 +64,11 @@ characters. 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 , -.Xr sem_close 2 , -.Xr sem_open 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 index 49c8cc8..2249f7d 100644 --- a/sys/sem_unlink.c +++ b/sys/sem_unlink.c @@ -24,13 +24,13 @@ #ifdef __APPLE_PR3375657_HACK__ #include -#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) @@ -51,7 +51,7 @@ sem_unlink (const char *name) name = buffer; } - return syscall (SYS_sem_unlink, name); + return __sem_unlink(name); } #endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/sem_wait.2 b/sys/sem_wait.2 index feeff3b..02f8d85 100644 --- a/sys/sem_wait.2 +++ b/sys/sem_wait.2 @@ -24,27 +24,27 @@ .Dt SEM_WAIT 2 .Os Darwin .Sh NAME -.Nm sem_wait, sem_trywait +.Nm sem_trywait, sem_wait .Nd lock a semaphore .Sh SYNOPSIS .Fd #include .Ft int -.Fn sem_wait "sem_t *sem" -.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 aquired or until the call is interrupted by a +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 aquired), +If successful (the lock was acquired), .Fn sem_wait and .Fn sem_trywait @@ -59,13 +59,13 @@ succeed unless: .Bl -tag -width Er .It Bq Er EAGAIN The semaphore is already locked. -.It Bq Er EINVAL -.Fa sem -is not a valid semaphore descriptor. .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 @@ -76,11 +76,11 @@ 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 , -.Xr sem_open 2 , -.Xr sem_post 2 +.Xr semop 2 .Sh HISTORY .Fn sem_wait and diff --git a/sys/semctl.c b/sys/semctl.c index d6d599b..77d5ab0 100644 --- a/sys/semctl.c +++ b/sys/semctl.c @@ -23,38 +23,63 @@ #include #include #include -#include + +#if !__DARWIN_UNIX03 +#include +/* + * Because KERNEL is defined, including errno.h doesn't define errno, so + * we have to do it ourselves. + */ +extern int * __error(void); +#define errno (*__error()) +#endif /* !__DARWIN_UNIX03 */ /* * Stub function to account for the differences in the ipc_perm structure, * while maintaining binary backward compatibility. */ +extern int __semctl(int semid, int semnum, int cmd, void *); + int semctl(int semid, int semnum, int cmd, ...) { -#ifdef __DARWIN_UNIX03 va_list ap; + int rv; + int val = 0; +#if __DARWIN_UNIX03 struct __semid_ds_new *ds; va_start(ap, cmd); - ds = va_arg(ap, struct __semid_ds_new *); + if (cmd == SETVAL) { + val = va_arg(ap, int); + rv = __semctl(semid, semnum, cmd, (void *)val); + } else { + ds = va_arg(ap, struct __semid_ds_new *); + rv = __semctl(semid, semnum, cmd, (void *)ds); + } va_end(ap); - return syscall(SYS_semctl, semid, semnum, cmd, ds); + return rv; #else /* !__DARWIN_UNIX03 */ - va_list ap; - struct __semid_ds_old *ds_old; struct __semid_ds_new ds; struct __semid_ds_new *ds_new = &ds; - int rv; + struct __semid_ds_old *ds_old = NULL; va_start(ap, cmd); - ds_old = va_arg(ap, struct __semid_ds_old *); + if (cmd == SETVAL) + val = va_arg(ap, int); + else + ds_old = va_arg(ap, struct __semid_ds_old *); va_end(ap); #define _UP_CVT(x) ds_new-> x = ds_old-> x #define _DN_CVT(x) ds_old-> x = ds_new-> x + if ((cmd == IPC_SET || cmd == IPC_STAT) && ds_old == NULL) { + /* Return EFAULT if ds_old is NULL (like the kernel would do) */ + errno = EFAULT; + return -1; + } if (cmd == IPC_SET) { /* convert before call */ _UP_CVT(sem_perm.uid); @@ -75,8 +100,19 @@ semctl(int semid, int semnum, int cmd, ...) _UP_CVT(sem_pad3[2]); /* binary compatibility */ _UP_CVT(sem_pad3[3]); /* binary compatibility */ } - - rv = syscall(SYS_semctl, semid, semnum, cmd, &ds); + switch (cmd) { + case SETVAL: + /* syscall must use LP64 quantities */ + rv = __semctl(semid, semnum, cmd, (void *)val); + break; + case IPC_SET: + case IPC_STAT: + rv = __semctl(semid, semnum, cmd, ds_new); + break; + default: + rv = __semctl(semid, semnum, cmd, ds_old); + break; + } if (cmd == IPC_STAT) { /* convert after call */ @@ -85,8 +121,8 @@ semctl(int semid, int semnum, int cmd, ...) _DN_CVT(sem_perm.cuid); /* warning! precision loss! */ _DN_CVT(sem_perm.cgid); /* warning! precision loss! */ _DN_CVT(sem_perm.mode); - ds_new->sem_perm.seq = ds_old->sem_perm._seq; - ds_new->sem_perm.key = ds_old->sem_perm._key; + ds_old->sem_perm.seq = ds_new->sem_perm._seq; + ds_old->sem_perm.key = ds_new->sem_perm._key; _DN_CVT(sem_base); _DN_CVT(sem_nsems); _DN_CVT(sem_otime); diff --git a/sys/sendmsg.c b/sys/sendmsg.c new file mode 100644 index 0000000..48480a3 --- /dev/null +++ b/sys/sendmsg.c @@ -0,0 +1,48 @@ +/* + * 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 __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 new file mode 100644 index 0000000..b1fa075 --- /dev/null +++ b/sys/sendto.c @@ -0,0 +1,48 @@ +/* + * 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 new file mode 100644 index 0000000..c8b529a --- /dev/null +++ b/sys/setattrlist.c @@ -0,0 +1,59 @@ +/* + * 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 index 39f95d8..47d7916 100644 --- a/sys/setregid.2 +++ b/sys/setregid.2 @@ -60,8 +60,8 @@ The 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, -and its purpose is now better served by the use of the +This function did not work correctly; +its purpose is now better served by the use of the .Fn setegid function (see .Xr setuid 2 ) . diff --git a/sys/setreuid.2 b/sys/setreuid.2 index 1215a59..13cfead 100644 --- a/sys/setreuid.2 +++ b/sys/setreuid.2 @@ -37,7 +37,7 @@ .Os .Sh NAME .Nm setreuid -.Nd set real and effective user ID's +.Nd set real and effective user IDs .Sh LIBRARY .Lb libc .Sh SYNOPSIS diff --git a/sys/setrlimit.c b/sys/setrlimit.c new file mode 100644 index 0000000..3d1bad8 --- /dev/null +++ b/sys/setrlimit.c @@ -0,0 +1,39 @@ +/* + * 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/setsgroups_np.c b/sys/setsgroups_np.c deleted file mode 100644 index 414f1eb..0000000 --- a/sys/setsgroups_np.c +++ /dev/null @@ -1,31 +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 - -int -setsgroups_np(int uuidsetlen, const uuid_t uuidset) -{ - return syscall(SYS_setsgroups, uuidsetlen, uuidset); -} diff --git a/sys/setwgroups_np.c b/sys/setwgroups_np.c deleted file mode 100644 index a942bfd..0000000 --- a/sys/setwgroups_np.c +++ /dev/null @@ -1,30 +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 -setwgroups_np(int uuidsetlen, const uuid_t uuidset) -{ - return syscall(SYS_setwgroups, uuidsetlen, uuidset); -} diff --git a/sys/shm_open.2 b/sys/shm_open.2 index ebf2fd3..6a31b7d 100644 --- a/sys/shm_open.2 +++ b/sys/shm_open.2 @@ -29,12 +29,18 @@ .Sh SYNOPSIS .Fd #include .Ft int -.Fn shm_open "const char *name" "int flags" "mode_t mode" +.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 flags +.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 @@ -51,7 +57,7 @@ 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 flags +.Fa oflag argument may indicate the file is to be created if it does not exist (by specifying the .Dv O_CREAT @@ -62,7 +68,9 @@ as described in and modified by the process' umask value (see .Xr umask 2 ) . .Pp -The flags specified are formed by +The value of +.Fa oflag +is formed by .Em or Ns 'ing the following values: .Pp diff --git a/sys/shm_open.c b/sys/shm_open.c index 064ac1e..0bb319e 100644 --- a/sys/shm_open.c +++ b/sys/shm_open.c @@ -24,13 +24,13 @@ #ifdef __APPLE_PR3375657_HACK__ #include -#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) @@ -51,7 +51,7 @@ shm_open (const char *name, int flags, mode_t mode) name = buffer; } - return syscall (SYS_shm_open, name, flags, mode); + return __shm_open(name, flags, mode); } #endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/shm_unlink.2 b/sys/shm_unlink.2 index 0d85afd..dd57a49 100644 --- a/sys/shm_unlink.2 +++ b/sys/shm_unlink.2 @@ -20,7 +20,7 @@ .\" .\" @APPLE_LICENSE_HEADER_END@ .\" -.Dd September 20, 1999 +.Dd August 31, 2006 .Dt SHM_UNLINK 2 .Os Darwin .Sh NAME @@ -33,19 +33,30 @@ .Sh DESCRIPTION The .Fn shm_unlink -function removes the shared memory object named by -.Fa name . -If no process has the file open, then all resources associated -with the object are reclaimed. -If one or more process have the object open, the name removed, -but the removal of the memory object is delayed until all -references to it have been closed. +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. +is set to indicate the error, +and the named shared memory object will remain unchanged. .Sh ERRORS The .Fn shm_unlink @@ -65,9 +76,9 @@ The named object does not exist. .Xr close 2 , .Xr mmap 2 , .Xr munmap 2 , +.Xr shm_open 2 , .Xr shmat 2 , -.Xr shmctl 2 , -.Xr shm_open 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 index dc813d9..5c52b4b 100644 --- a/sys/shm_unlink.c +++ b/sys/shm_unlink.c @@ -24,13 +24,13 @@ #ifdef __APPLE_PR3375657_HACK__ #include -#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) @@ -51,7 +51,7 @@ shm_unlink (const char *name) name = buffer; } - return syscall (SYS_shm_unlink, name); + return __shm_unlink(name); } #endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/shmctl.c b/sys/shmctl.c index 36a4317..952d484 100644 --- a/sys/shmctl.c +++ b/sys/shmctl.c @@ -22,19 +22,19 @@ */ #include #include -#include /* * Stub function to account for the differences in the ipc_perm structure, * while maintaining binary backward compatibility. + * + * This is only the legacy behavior. */ +extern int __shmctl(int, int, void *); + int shmctl(int shmid, int cmd, struct shmid_ds *ds) { -#ifdef __DARWIN_UNIX03 - return syscall(SYS_shmctl, shmid, cmd, ds); -#else /* !__DARWIN_UNIX03 */ - struct __shmid_ds_old *ds_old = ds; + struct __shmid_ds_old *ds_old = (struct __shmid_ds_old *)ds; struct __shmid_ds_new ds2; struct __shmid_ds_new *ds_new = &ds2; int rv; @@ -61,7 +61,7 @@ shmctl(int shmid, int cmd, struct shmid_ds *ds) _UP_CVT(shm_internal); } - rv = syscall(SYS_shmctl, shmid, cmd, ds_new); + rv = __shmctl(shmid, cmd, (void *)ds_new); if (cmd == IPC_STAT) { /* convert after call */ @@ -70,18 +70,17 @@ shmctl(int shmid, int cmd, struct shmid_ds *ds) _DN_CVT(shm_perm.cuid); /* warning! precision loss! */ _DN_CVT(shm_perm.cgid); /* warning! precision loss! */ _DN_CVT(shm_perm.mode); - ds_new->shm_perm.seq = ds_old->shm_perm._seq; - ds_new->shm_perm.key = ds_old->shm_perm._key; - _UP_CVT(shm_segsz); - _UP_CVT(shm_lpid); - _UP_CVT(shm_cpid); - _UP_CVT(shm_nattch); - _UP_CVT(shm_atime); - _UP_CVT(shm_dtime); - _UP_CVT(shm_ctime); - _UP_CVT(shm_internal); + ds_old->shm_perm.seq = ds_new->shm_perm._seq; + ds_old->shm_perm.key = ds_new->shm_perm._key; + _DN_CVT(shm_segsz); + _DN_CVT(shm_lpid); + _DN_CVT(shm_cpid); + _DN_CVT(shm_nattch); + _DN_CVT(shm_atime); + _DN_CVT(shm_dtime); + _DN_CVT(shm_ctime); + _DN_CVT(shm_internal); } return (rv); -#endif /* !__DARWIN_UNIX03 */ } diff --git a/sys/sigaction.c b/sys/sigaction.c index 7686b1e..2e9652c 100644 --- a/sys/sigaction.c +++ b/sys/sigaction.c @@ -26,7 +26,6 @@ * @(#)sigaction.c 1.0 */ -#include #include #include #include @@ -37,6 +36,7 @@ * as the signal handler instead. The code here is derived * from sigvec in sys/kern_sig.c. */ +extern int __sigaction (int, struct __sigaction * __restrict, struct sigaction * __restrict); int sigaction (int sig, const struct sigaction * __restrict nsv, struct sigaction * __restrict osv) @@ -57,10 +57,7 @@ sigaction (int sig, const struct sigaction * __restrict nsv, struct sigaction * sa.sa_flags = nsv->sa_flags; sap = &sa; } - if (syscall (SYS_sigaction, sig, sap, osv) < 0) { - return (-1); - } - return (0); + return __sigaction(sig, sap, osv); } // XXX diff --git a/sys/sigsuspend.c b/sys/sigsuspend.c index f7fbfb0..fcaab4c 100644 --- a/sys/sigsuspend.c +++ b/sys/sigsuspend.c @@ -22,21 +22,28 @@ */ /* @(#)sigsuspend.c 1.0 9/22/95 (c) 1995 NeXT */ -#include -#include +#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 -) +sigsuspend (const sigset_t *sigmask_p) { sigset_t mask; - + if (sigmask_p) mask = *sigmask_p; else sigemptyset(&mask); - return syscall (SYS_sigsuspend, mask); +#ifdef VARIANT_CANCELABLE + return __sigsuspend(mask); +#else /* !VARIANT_CANCELABLE */ + return __sigsuspend_nocancel(mask); +#endif /* VARIANT_CANCELABLE */ } diff --git a/sys/sigtramp.c b/sys/sigtramp.c index da72b83..74f4963 100644 --- a/sys/sigtramp.c +++ b/sys/sigtramp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -26,9 +26,13 @@ #import "sigcatch.h" #import #import +#import +#import #import #import +extern int __sigreturn(ucontext_t *, int); + /* * sigvec registers _sigtramp as the handler for any signal requiring * user-mode intervention. All _sigtramp does is find the real handler, @@ -36,7 +40,9 @@ * * Note that the kernel saves/restores all of our register state. */ -#if defined(__DYNAMIC__) + +/* On i386, i386/sys/_sigtramp.s defines this. */ +#if defined(__DYNAMIC__) && ! defined(__i386__) int __in_sigtramp = 0; #endif @@ -62,7 +68,10 @@ int __in_sigtramp = 0; #define UC_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int)) #endif -#if defined(__ppc__) || defined(__ppc64__) +#define UC_SET_ALT_STACK 0x40000000 +#define UC_RESET_ALT_STACK 0x80000000 + +#if defined(__ppc__) /* This routine will be replaced by an assembly soon */ static int restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle) @@ -73,47 +82,47 @@ restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle) return(0); if (mctx->ss.r0 != (unsigned int)mctx64->ss.r0) return(0); - if (mctx->ss.r1 != (unsigned int)mctx->ss.r1) + if (mctx->ss.r1 != (unsigned int)mctx64->ss.r1) return(0); - if (mctx->ss.r2 != (unsigned int)mctx->ss.r2) + if (mctx->ss.r2 != (unsigned int)mctx64->ss.r2) return(0); - if (mctx->ss.r3 != (unsigned int)mctx->ss.r3) + if (mctx->ss.r3 != (unsigned int)mctx64->ss.r3) return(0); - if (mctx->ss.r4 != (unsigned int)mctx->ss.r4) + if (mctx->ss.r4 != (unsigned int)mctx64->ss.r4) return(0); - if (mctx->ss.r5 != (unsigned int)mctx->ss.r5) + if (mctx->ss.r5 != (unsigned int)mctx64->ss.r5) return(0); - if (mctx->ss.r6 != (unsigned int)mctx->ss.r6) + if (mctx->ss.r6 != (unsigned int)mctx64->ss.r6) return(0); - if (mctx->ss.r7 != (unsigned int)mctx->ss.r7) + if (mctx->ss.r7 != (unsigned int)mctx64->ss.r7) return(0); - if (mctx->ss.r8 != (unsigned int)mctx->ss.r8) + if (mctx->ss.r8 != (unsigned int)mctx64->ss.r8) return(0); - if (mctx->ss.r9 != (unsigned int)mctx->ss.r9) + if (mctx->ss.r9 != (unsigned int)mctx64->ss.r9) return(0); - if (mctx->ss.r10 != (unsigned int)mctx->ss.r10) + if (mctx->ss.r10 != (unsigned int)mctx64->ss.r10) return(0); - if (mctx->ss.r11 != (unsigned int)mctx->ss.r11) + if (mctx->ss.r11 != (unsigned int)mctx64->ss.r11) return(0); - if (mctx->ss.r12 != (unsigned int)mctx->ss.r12) + if (mctx->ss.r12 != (unsigned int)mctx64->ss.r12) return(0); - if (mctx->ss.r13 != (unsigned int)mctx->ss.r13) + if (mctx->ss.r13 != (unsigned int)mctx64->ss.r13) return(0); - if (mctx->ss.r14 != (unsigned int)mctx->ss.r14) + if (mctx->ss.r14 != (unsigned int)mctx64->ss.r14) return(0); - if (mctx->ss.r15 != (unsigned int)mctx->ss.r15) + if (mctx->ss.r15 != (unsigned int)mctx64->ss.r15) return(0); - if (mctx->ss.r16 != (unsigned int)mctx->ss.r16) + if (mctx->ss.r16 != (unsigned int)mctx64->ss.r16) return(0); - if (mctx->ss.r17 != (unsigned int)mctx->ss.r17) + if (mctx->ss.r17 != (unsigned int)mctx64->ss.r17) return(0); - if (mctx->ss.r18 != (unsigned int)mctx->ss.r18) + if (mctx->ss.r18 != (unsigned int)mctx64->ss.r18) return(0); - if (mctx->ss.r19 != (unsigned int)mctx->ss.r19) + if (mctx->ss.r19 != (unsigned int)mctx64->ss.r19) return(0); - if (mctx->ss.r20 != (unsigned int)mctx->ss.r20) + if (mctx->ss.r20 != (unsigned int)mctx64->ss.r20) return(0); - if (mctx->ss.r21 != (unsigned int)mctx->ss.r21) + if (mctx->ss.r21 != (unsigned int)mctx64->ss.r21) return(0); if (mctx->ss.r22 != (unsigned int)mctx64->ss.r22) return(0); @@ -145,7 +154,7 @@ restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle) if (mctx->ss.ctr != (unsigned int)mctx64->ss.ctr) return(0); - if (bcmp(&mctx->fs, &mctx64->ss, (PPC_FLOAT_STATE_COUNT * sizeof(int)))) + if (bcmp(&mctx->fs, &mctx64->fs, (PPC_FLOAT_STATE_COUNT * sizeof(int)))) return(0); if ((sigstyle == UC_DUAL_VEC) && bcmp(&mctx->vs, &mctx64->vs, (PPC_VECTOR_STATE_COUNT * sizeof(int)))) return(0); @@ -154,38 +163,18 @@ restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle) } -#endif +/* This routine is called from ppc/sys/_sigtramp.s on return from + sa_handler. */ void -_sigtramp( - union __sigaction_u __sigaction_u, - int sigstyle, - int sig, - siginfo_t *sinfo, - ucontext_t *uctx +__finish_sigtramp( + ucontext_t *uctx, + int sigstyle ) { int ctxstyle = UC_FLAVOR; -#if defined(__ppc__) || defined(__ppc64__) mcontext_t mctx; mcontext64_t mctx64; -#endif - -#if defined(__DYNAMIC__) - __in_sigtramp++; -#endif -#if defined(__i386__) || defined(__x86_64__) - if (sigstyle == UC_TRAD) - sa_handler(sig); - else { - sa_sigaction(sig, sinfo, uctx); - } -#elif defined(__ppc__) || defined(__ppc64__) - if ((sigstyle == UC_TRAD) || (sigstyle == UC_TRAD64) || (sigstyle == UC_TRAD64_VEC)) - sa_handler(sig); - else - sa_sigaction(sig, sinfo, uctx); - if ((sigstyle == UC_DUAL) || (sigstyle == UC_DUAL_VEC)) { mctx = uctx->uc_mcontext; mctx64 = (mcontext64_t)((char *)(uctx->uc_mcontext) + sizeof(struct mcontext)); @@ -207,13 +196,64 @@ _sigtramp( } } else ctxstyle = sigstyle; -#endif /* __ppc__ || __ppc64__ */ + +#if defined(__DYNAMIC__) + __in_sigtramp--; +#endif + + __sigreturn (uctx, ctxstyle); +} + +#endif /* ppc */ + +/* + * Reset the kernel's idea of the use of an alternate stack; this is used by + * both longjmp() and siglongjmp(). Nothing other than this reset is needed, + * since restoring the registers and other operations that would normally be + * done by sigreturn() are handled in user space, so we do not pass a user + * context (in PPC, a user context is not the same as a jmpbuf mcontext, due + * to having more than one set of registers, etc., for the various 32/64 etc. + * contexts).. + */ +void +_sigunaltstack(int set) +{ + /* sigreturn(uctx, ctxstyle); */ + /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */ + __sigreturn (NULL, (set == SS_ONSTACK) ? UC_SET_ALT_STACK : UC_RESET_ALT_STACK); +} + +/* On these architectures, _sigtramp is implemented in assembly to + ensure it matches its DWARF unwind information. */ +#if ! defined (__ppc__) && ! defined (__ppc64__) && ! defined (__i386__) \ + && ! defined (__x86_64__) + +void +_sigtramp( + union __sigaction_u __sigaction_u, + int sigstyle, + int sig, + siginfo_t *sinfo, + ucontext_t *uctx +) { + int ctxstyle = UC_FLAVOR; + +#if defined(__DYNAMIC__) + __in_sigtramp++; +#endif + + if (sigstyle == UC_TRAD) + sa_handler(sig); + else { + sa_sigaction(sig, sinfo, uctx); + } #if defined(__DYNAMIC__) __in_sigtramp--; #endif /* sigreturn(uctx, ctxstyle); */ /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */ - syscall (184, uctx, ctxstyle); + __sigreturn (uctx, ctxstyle); } +#endif /* not ppc nor ppc64 nor i386 nor x86_64 */ diff --git a/sys/sigwait.2 b/sys/sigwait.2 index e72d736..1ffc52c 100644 --- a/sys/sigwait.2 +++ b/sys/sigwait.2 @@ -35,7 +35,7 @@ .Sh SYNOPSIS .In signal.h .Ft int -.Fn sigwait "const sigset_t *set" "int *sig" +.Fn sigwait "const sigset_t *restrict set" "int *restrict sig" .Sh DESCRIPTION The .Fn sigwait @@ -58,8 +58,8 @@ should be blocked, but not ignored, at the time of the call to .Pp Processes which call .Fn sigwait -on ignored signals will wait indefinately. Ignored -signals are dropped immeadiately by the system, before delivery +on ignored signals will wait indefinitely. Ignored +signals are dropped immediately by the system, before delivery to a waiting process. .Sh RETURN VALUES If successful, @@ -77,11 +77,11 @@ will fail if: specifies one or more invalid signal numbers. .El .Sh SEE ALSO +.Xr pthread_sigmask 2 , .Xr sigaction 2 , .Xr sigpending 2 , .Xr sigsuspend 2 , -.Xr pause 3 , -.Xr pthread_sigmask 2 +.Xr pause 3 .Sh STANDARDS .Fn sigwait conforms to ISO/IEC 9945-1:1996 (``POSIX.1'') diff --git a/sys/socketpair.c b/sys/socketpair.c new file mode 100644 index 0000000..fbe1b79 --- /dev/null +++ b/sys/socketpair.c @@ -0,0 +1,49 @@ +/* + * 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/stack_protector-obsd.c b/sys/stack_protector-obsd.c new file mode 100644 index 0000000..4463619 --- /dev/null +++ b/sys/stack_protector-obsd.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat. + * 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 AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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(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 void __abort(void) __dead2; +long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +void __guard_setup(void) __attribute__ ((visibility ("hidden"))); +void __stack_chk_fail(void); + +void +__guard_setup(void) +{ + 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; +} + +void +__stack_chk_fail() +{ + const char message[] = "[%d] stack overflow"; + + /* this may fail on a chroot jail, though luck */ + syslog(LOG_CRIT, message, getpid()); + + __abort(); +} diff --git a/sys/statx_np.c b/sys/statx_np.c index f87e720..3159378 100644 --- a/sys/statx_np.c +++ b/sys/statx_np.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004, 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -34,13 +33,13 @@ #define ACL_MIN_SIZE_HEURISTIC (sizeof(struct kauth_filesec) + 16 * sizeof(struct kauth_ace)) -static int statx_syscall(void *obj, struct stat *sb, void *fsacl, size_t *fsacl_size); -static int fstatx_syscall(void *obj, struct stat *sb, void *fsacl, size_t *fsacl_size); -static int lstatx_syscall(void *obj, struct stat *sb, void *fsacl, size_t *fsacl_size); +static int statx_syscall(void *obj, void *sbptr, void *fsacl, size_t *fsacl_size); +static int fstatx_syscall(void *obj, void *sbptr, void *fsacl, size_t *fsacl_size); +static int lstatx_syscall(void *obj, void *sbptr, void *fsacl, size_t *fsacl_size); static int statx1(void *obj, - int (* stat_syscall)(void *obj, struct stat *sb, void *fsacl, size_t *fsacl_size), - struct stat *sb, filesec_t fsec); + int (* stat_syscall)(void *obj, void *sbptr, void *fsacl, size_t *fsacl_size), + void *sbptr, filesec_t fsec); /* * Stat interfaces. @@ -50,7 +49,7 @@ statx_np(const char *path, struct stat *sb, filesec_t fsec) { if (fsec == NULL) return(stat(path, sb)); - return(statx1((void *)&path, statx_syscall, sb, fsec)); + return(statx1((void *)&path, statx_syscall, (void *)sb, fsec)); } int @@ -58,7 +57,7 @@ fstatx_np(int fd, struct stat *sb, filesec_t fsec) { if (fsec == NULL) return(fstat(fd, sb)); - return(statx1((void *)&fd, fstatx_syscall, sb, fsec)); + return(statx1((void *)&fd, fstatx_syscall, (void *)sb, fsec)); } int @@ -66,32 +65,74 @@ lstatx_np(const char *path, struct stat *sb, filesec_t fsec) { if (fsec == NULL) return(lstat(path, sb)); - return(statx1((void *)&path, lstatx_syscall, sb, fsec)); + return(statx1((void *)&path, lstatx_syscall, (void *)sb, fsec)); } + +#if __DARWIN_64_BIT_INO_T +int +statx64_np(const char *path, struct stat64 *sb, filesec_t fsec) +{ + return(statx_np(path, (struct stat *)sb, fsec)); +} + +int +fstatx64_np(int fd, struct stat64 *sb, filesec_t fsec) +{ + return(fstatx_np(fd, (struct stat *)sb, fsec)); +} + +int +lstatx64_np(const char *path, struct stat64 *sb, filesec_t fsec) +{ + return(lstatx_np(path, (struct stat *)sb, fsec)); +} +#endif /* __DARWIN_64_BIT_INO_T */ + /* * Stat syscalls */ +#if __DARWIN_64_BIT_INO_T +extern int __fstat64_extended(int, struct stat *, void *, size_t *); +extern int __lstat64_extended(const char *, struct stat *, void *, size_t *); +extern int __stat64_extended(const char *, struct stat *, void *, size_t *); +#else /* !__DARWIN_64_BIT_INO_T */ +extern int __fstat_extended(int, struct stat *, void *, size_t *); +extern int __lstat_extended(const char *, struct stat *, void *, size_t *); +extern int __stat_extended(const char *, struct stat *, void *, size_t *); +#endif /* __DARWIN_64_BIT_INO_T */ + static int -statx_syscall(void *obj, struct stat *sb, void *fsacl, size_t *fsacl_size) +statx_syscall(void *obj, void *sb, void *fsacl, size_t *fsacl_size) { const char *path = *(const char **)obj; - - return(syscall(SYS_stat_extended, path, sb, fsacl, fsacl_size)); +#if __DARWIN_64_BIT_INO_T + return(__stat64_extended(path, (struct stat *)sb, fsacl, fsacl_size)); +#else /* !__DARWIN_64_BIT_INO_T */ + return(__stat_extended(path, (struct stat *)sb, fsacl, fsacl_size)); +#endif /* __DARWIN_64_BIT_INO_T */ } static int -fstatx_syscall(void *obj, struct stat *sb, void *fsacl, size_t *fsacl_size) +fstatx_syscall(void *obj, void *sb, void *fsacl, size_t *fsacl_size) { int fd = *(int *)obj; - return(syscall(SYS_fstat_extended, fd, sb, fsacl, fsacl_size)); +#if __DARWIN_64_BIT_INO_T + return(__fstat64_extended(fd, (struct stat *)sb, fsacl, fsacl_size)); +#else /* !__DARWIN_64_BIT_INO_T */ + return(__fstat_extended(fd, (struct stat *)sb, fsacl, fsacl_size)); +#endif /* __DARWIN_64_BIT_INO_T */ } static int -lstatx_syscall(void *obj, struct stat *sb, void *fsacl, size_t *fsacl_size) +lstatx_syscall(void *obj, void *sb, void *fsacl, size_t *fsacl_size) { const char *path = *(const char **)obj; - return(syscall(SYS_lstat_extended, path, sb, fsacl, fsacl_size)); +#if __DARWIN_64_BIT_INO_T + return(__lstat64_extended(path, (struct stat *)sb, fsacl, fsacl_size)); +#else /* !__DARWIN_64_BIT_INO_T */ + return(__lstat_extended(path, (struct stat *)sb, fsacl, fsacl_size)); +#endif /* __DARWIN_64_BIT_INO_T */ } /* @@ -99,16 +140,19 @@ lstatx_syscall(void *obj, struct stat *sb, void *fsacl, size_t *fsacl_size) */ static int statx1(void *obj, - int (* stat_syscall)(void *obj, struct stat *sb, void *fsacl, size_t *fsacl_size), - struct stat *sb, filesec_t fsec) + int (* stat_syscall)(void *obj, void *sbptr, void *fsacl, size_t *fsacl_size), + void *sbptr, filesec_t fsec) { struct kauth_filesec *fsacl, *ofsacl; size_t fsacl_size, buffer_size; int error; + struct stat * sb = (struct stat *)0; fsacl = NULL; error = 0; + sb = (struct stat *)sbptr; + /* * Allocate an initial buffer. */ @@ -123,7 +167,8 @@ statx1(void *obj, */ for (;;) { fsacl_size = buffer_size; - if ((error = stat_syscall(obj, sb, fsacl, &fsacl_size)) != 0) + + if ((error = stat_syscall(obj, sbptr, fsacl, &fsacl_size)) != 0) goto out; /* diff --git a/sys/umaskx_np.c b/sys/umaskx_np.c index b0632ba..478332c 100644 --- a/sys/umaskx_np.c +++ b/sys/umaskx_np.c @@ -23,10 +23,11 @@ #include #include #include -#include #include #include +extern int __umask_extended(int, acl_t); + int umaskx_np(filesec_t fsec) { @@ -46,5 +47,5 @@ umaskx_np(filesec_t fsec) if (size == 0) acl = NULL; } - return syscall(SYS_umask_extended, newmask, acl); + return __umask_extended(newmask, acl); } diff --git a/sys/undelete.2 b/sys/undelete.2 new file mode 100644 index 0000000..ea5fef4 --- /dev/null +++ b/sys/undelete.2 @@ -0,0 +1,109 @@ +.\" 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 981911b..6495b95 100644 --- a/threads/Makefile.inc +++ b/threads/Makefile.inc @@ -1,7 +1,9 @@ .PATH: ${.CURDIR}/${MACHINE_ARCH}/threads ${.CURDIR}/threads +.ifnmake autopatch .if exists(${.CURDIR}/${MACHINE_ARCH}/threads/Makefile.inc) .include "${.CURDIR}/${MACHINE_ARCH}/threads/Makefile.inc" .endif +.endif # !autopatch MISRCS += cprocs.c cthreads.c lu_utils.c mig_support.c diff --git a/threads/cthreads.c b/threads/cthreads.c index 3578c37..3468d02 100644 --- a/threads/cthreads.c +++ b/threads/cthreads.c @@ -119,7 +119,12 @@ void _cthread_fork_prepare() struct pthread_atfork_entry *e; _spin_lock(&pthread_atfork_lock); - TAILQ_FOREACH_REVERSE(e, &pthread_atfork_queue, qentry, pthread_atfork_queue_head) { +#ifdef TAILQ_FOREACH_REVERSE_LEGACY_ORDER + TAILQ_FOREACH_REVERSE(e, &pthread_atfork_queue, qentry, pthread_atfork_queue_head) +#else /* !TAILQ_FOREACH_REVERSE_LEGACY_ORDER */ + TAILQ_FOREACH_REVERSE(e, &pthread_atfork_queue, pthread_atfork_queue_head, qentry) +#endif /* TAILQ_FOREACH_REVERSE_LEGACY_ORDER */ + { if (e->prepare != NULL) e->prepare(); } diff --git a/threads/lu_utils.c b/threads/lu_utils.c index ce686dc..58b1258 100644 --- a/threads/lu_utils.c +++ b/threads/lu_utils.c @@ -39,25 +39,32 @@ #include mach_port_t _lu_port = MACH_PORT_NULL; +mach_port_t _ds_port = MACH_PORT_NULL; + static name_t LOOKUP_NAME = "lookup daemon v2"; -mach_port_t _lookupd_port(mach_port_t port) { - kern_return_t ret; +#ifndef kDSStdMachDSLookupPortName +#define kDSStdMachDSLookupPortName "com.apple.system.DirectoryService.libinfo_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(); - if (port != MACH_PORT_NULL) { - ret = bootstrap_register(bootstrap_port, LOOKUP_NAME, port); - if (ret != BOOTSTRAP_SUCCESS) { - mach_error("bootstrap_register() failed", ret); - abort(); - } - return port; - } else if ((_lu_port == MACH_PORT_NULL) && (getpid() > 1)) { - ret = bootstrap_look_up(bootstrap_port, LOOKUP_NAME, &_lu_port); - if (ret != BOOTSTRAP_SUCCESS && ret != BOOTSTRAP_UNKNOWN_SERVICE) { - mach_error("bootstrap_look_up() failed", ret); - _lu_port = MACH_PORT_NULL; - } + 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; } @@ -66,20 +73,31 @@ void _lu_fork_child() { _lu_port = MACH_PORT_NULL; + _ds_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); - } + 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)); + 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; + + return (_ds_port != MACH_PORT_NULL); } diff --git a/util/Makefile.inc b/util/Makefile.inc index a38699a..34271ca 100644 --- a/util/Makefile.inc +++ b/util/Makefile.inc @@ -4,5 +4,10 @@ MISRCS += login.c login_tty.c logout.c logwtmp.c pty.c fparseln.c \ opendev.c .if ${LIB} == "c" -MAN3 += fparseln.3 opendev.3 +MAN3 += fparseln.3 login.3 opendev.3 openpty.3 + +MLINKS += openpty.3 forkpty.3 +MLINKS += openpty.3 login_tty.3 +MLINKS += login.3 logwtmp.3 +MLINKS += login.3 logout.3 .endif diff --git a/util/fparseln.c b/util/fparseln.c index 3c02056..04aa82e 100644 --- a/util/fparseln.c +++ b/util/fparseln.c @@ -1,25 +1,3 @@ -/* - * 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@ - */ /* $NetBSD: fparseln.c,v 1.9 1999/09/20 04:48:06 lukem Exp $ */ /* diff --git a/util/login.3 b/util/login.3 new file mode 100644 index 0000000..a741beb --- /dev/null +++ b/util/login.3 @@ -0,0 +1,112 @@ +.\" Copyright (c) 1995 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software developed by the Computer Systems +.\" Engineering group at Lawrence Berkeley Laboratory under DARPA contract +.\" BG 91-66 and contributed to Berkeley. +.\" +.\" 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. +.\" +.Dd December 14, 1995 +.Dt LOGIN 3 +.Os +.Sh NAME +.Nm login , +.Nm logout , +.Nm logwtmp +.Nd login utility functions (DEPRECATED) +.Sh SYNOPSIS +.Fd #include +.Ft void +.Fn login "struct utmp *ut" +.Ft int +.Fn logout "const char *line" +.Ft void +.Fn logwtmp "const char *line" "const char *name" "const char *host" +.Sh DESCRIPTION +The +.Fn login , +.Fn logout , +and +.Fn logwtmp +functions are +.Sy DEPRECATED ; +use +.Xr pututxline 3 +instead. +.Pp +These functions operate on the database of current users in +.Pa /var/run/utmpx +and the system log file. +Superuser permission is required. +.Pp +The +.Fn login +function updates the +.Pa /var/run/utmpx +files with user information contained in +.Fa ut +(after converting to a struct utmpx, as described in +.Xr pututxline 3 ) . +.Pp +The +.Fn logout +function removes the entry from +.Pa /var/run/utmpx +corresponding to the device +.Fa line . +.Pp +The +.Fn logwtmp +function adds an entry to +the system log file. +Since +.Fn login +will add the appropriate entry +during a login, +.Fn logwtmp +is usually used for logouts. +.Sh RETURN VALUES +.Fn logout +returns non-zero if it was able to find and delete an entry for +.Fa line , +and zero if there is no entry for +.Fa line +in +.Pa /var/run/utmpx . +However, there is no error indication due to lack of permissions. +.Sh FILES +.Bl -tag -width /var/run/wtmp -compact +.It Pa /dev/\(** +.It Pa /var/run/utmpx +.El +.Sh SEE ALSO +.Xr pututxline 3 , +.Xr utmp 5 , +.Xr utmpx 5 diff --git a/util/login.c b/util/login.c index 9780bcd..2ce03d3 100644 --- a/util/login.c +++ b/util/login.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -55,28 +55,19 @@ #include - -#include -#include -#include #include -#include +#include +#include void -login(ut) - struct utmp *ut; +login(struct utmp *ut) { - register int fd; - int tty; + struct utmpx ux; - tty = ttyslot(); - if (tty > 0 && (fd = open(_PATH_UTMP, O_WRONLY|O_CREAT, 0644)) >= 0) { - (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), L_SET); - (void)write(fd, ut, sizeof(struct utmp)); - (void)close(fd); - } - if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) { - (void)write(fd, ut, sizeof(struct utmp)); - (void)close(fd); - } + getutmpx(ut, &ux); + /* ut_id will automatically be calculated in the call to pututxline() */ + ux.ut_type |= UTMPX_AUTOFILL_MASK; + setutxent(); + pututxline(&ux); + endutxent(); } diff --git a/util/login_tty.c b/util/login_tty.c index 46f09c2..8da0d67 100644 --- a/util/login_tty.c +++ b/util/login_tty.c @@ -1,25 +1,3 @@ -/* - * 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) 1990, 1993 * The Regents of the University of California. All rights reserved. diff --git a/util/logout.c b/util/logout.c index fd8ac27..a2d20bb 100644 --- a/util/logout.c +++ b/util/logout.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -53,39 +53,47 @@ * SUCH DAMAGE. */ - #include #include -#include +#ifdef UTMP_COMPAT #include +#endif /* UTMP_COMPAT */ +#include +#include #include -#include #include -typedef struct utmp UTMP; - int -logout(line) - register char *line; +logout(char *line) { - register int fd; - UTMP ut; - int rval; + struct utmpx *ux, utx; +#ifdef UTMP_COMPAT +#ifdef __LP64__ + struct utmp32 u; +#else /* __LP64__ */ + struct utmp u; +#endif /* __LP64__ */ + int which; +#endif /* UTMP_COMPAT */ - if ((fd = open(_PATH_UTMP, O_RDWR, 0)) < 0) - return(0); - rval = 0; - while (read(fd, &ut, sizeof(UTMP)) == sizeof(UTMP)) { - if (!ut.ut_name[0] || strncmp(ut.ut_line, line, UT_LINESIZE)) - continue; - bzero(ut.ut_name, UT_NAMESIZE); - bzero(ut.ut_host, UT_HOSTSIZE); - (void)time(&ut.ut_time); - (void)lseek(fd, -(off_t)sizeof(UTMP), L_INCR); - (void)write(fd, &ut, sizeof(UTMP)); - rval = 1; + bzero(&utx, sizeof(utx)); + 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); + setutxent(); + ux = _pututxline(&utx); + endutxent(); + if (!ux) + return 0; +#ifdef UTMP_COMPAT + if (utfile_system) { /* only if we are using _PATH_UTMPX */ + which = _utmp_compat(ux, &u); + if (which & UTMP_COMPAT_UTMP0) + _write_utmp(&u, 0); + else if (which & UTMP_COMPAT_UTMP1) + _write_utmp(&u, 1); } - (void)close(fd); - return(rval); +#endif /* UTMP_COMPAT */ + return 1; } diff --git a/util/logwtmp.c b/util/logwtmp.c index b792b40..82dc503 100644 --- a/util/logwtmp.c +++ b/util/logwtmp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -55,32 +55,50 @@ #include -#include #include -#include +#include #include +#ifdef UTMP_COMPAT #include +#endif /* UTMP_COMPAT */ +#include +#include -void logwtmp(line, name, host) - char *line, *name, *host; +void +logwtmp(char *line, char *name, char *host) { - struct utmp ut; - struct stat buf; - int fd; - time_t time(); - char *strncpy(); + struct utmpx utx; +#ifdef UTMP_COMPAT +#ifdef __LP64__ + struct utmp32 u; +#else /* __LP64__ */ + struct utmp u; +#endif /* __LP64__ */ + int which; +#endif /* UTMP_COMPAT */ - if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0) - return; - if (fstat(fd, &buf) == 0) { - (void) strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void) strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void) strncpy(ut.ut_host, host, sizeof(ut.ut_host)); - (void) time(&ut.ut_time); - if (write(fd, (char *)&ut, sizeof(struct utmp)) != - sizeof(struct utmp)) - (void) ftruncate(fd, buf.st_size); + bzero(&utx, sizeof(utx)); + /* + * line should never be "|" or "{", because this interface doesn't allow + * setting ut_tv. + */ + if (strcmp(line, "~") == 0) + utx.ut_type = strcmp(name, "reboot") == 0 ? BOOT_TIME : SHUTDOWN_TIME; + else { + strncpy(utx.ut_user, name, sizeof(utx.ut_user)); + strncpy(utx.ut_line, line, sizeof(utx.ut_line)); + utx.ut_pid = getpid(); + utx.ut_type = *name ? USER_PROCESS : DEAD_PROCESS; + strncpy(utx.ut_host, host, sizeof(utx.ut_host)); } - (void) close(fd); + (void)gettimeofday(&utx.ut_tv, NULL); + _utmpx_asl(&utx); +#ifdef UTMP_COMPAT + which = _utmp_compat(&utx, &u); + if (which & UTMP_COMPAT_WTMP) + _write_wtmp(&u); + if (which & UTMP_COMPAT_LASTLOG) + _write_lastlog(&u, NULL); +#endif /* UTMP_COMPAT */ } diff --git a/util/opendev.c b/util/opendev.c index 7f11a9c..e16c707 100644 --- a/util/opendev.c +++ b/util/opendev.c @@ -1,27 +1,3 @@ -/* - * 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@ - */ -/* $OpenBSD: opendev.c,v 1.7 2002/06/09 22:18:43 fgsch Exp $ */ - /* * Copyright (c) 2000, Todd C. Miller. All rights reserved. * Copyright (c) 1996, Jason Downs. All rights reserved. diff --git a/util/openpty.3 b/util/openpty.3 new file mode 100644 index 0000000..fce8501 --- /dev/null +++ b/util/openpty.3 @@ -0,0 +1,163 @@ +.\" $OpenBSD: openpty.3,v 1.3 1996/11/24 23:53:12 millert Exp $ +.\" Copyright (c) 1995 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software developed by the Computer Systems +.\" Engineering group at Lawrence Berkeley Laboratory under DARPA contract +.\" BG 91-66 and contributed to Berkeley. +.\" +.\" 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. +.\" +.Dd November 4, 1996 +.Dt OPENPTY 3 +.Os +.Sh NAME +.Nm openpty , +.Nm login_tty , +.Nm forkpty +.Nd tty utility functions +.Sh SYNOPSIS +.Fd #include +.Ft int +.Fn openpty "int *amaster" "int *aslave" "char *name" "struct termios *termp" "struct winsize *winp" +.Ft int +.Fn login_tty "int fd" +.Ft pid_t +.Fn forkpty "int *amaster" "char *name" "struct termios *termp" "struct winsize *winp" +.Sh DESCRIPTION +The +.Fn openpty , +.Fn login_tty , +and +.Fn forkpty +functions perform manipulations on ttys and pseudo-ttys. +.Pp +The +.Fn openpty +function finds an available pseudo-tty and returns file descriptors +for the master and slave in +.Fa amaster +and +.Fa aslave . +If +.Fa name +is non-null, the filename of the slave is returned in +.Fa name . +If +.Fa termp +is non-null, the terminal parameters of the slave will be set to the +values in +.Fa termp . +If +.Fa winp +is non-null, the window size of the slave will be set to the values in +.Fa winp . +.Pp +The +.Fn login_tty +function prepares for a login on the tty +.Fa fd +(which may be a real tty device, or the slave of a pseudo-tty as +returned by +.Fn openpty ) +by creating a new session, making +.Fa fd +the controlling terminal for the current process, setting +.Fa fd +to be the standard input, output, and error streams of the current +process, and closing +.Fa fd . +.Pp +The +.Fn forkpty +function combines +.Fn openpty , +.Fn fork , +and +.Fn login_tty +to creates a new process operating in a pseudo-tty. The file +descriptor of the master side of the pseudo-tty is returned in +.Fa amaster , +and the filename of the slave in +.Fa name +if it is non-null. The +.Fa termp +and +.Fa winp +parameters, if non-null, will determine the terminal attributes and +window size of the slave side of the pseudo-tty. +.Sh RETURN VALUES +If a call to +.Fn openpty , +.Fn login_tty , +or +.Fn forkpty +is not successful, -1 is returned and +.Va errno +is set to indicate the error. Otherwise, +.Fn openpty , +.Fn login_tty , +and the child process of +.Fn forkpty +return 0, and the parent process of +.Fn forkpty +returns the process ID of the child process. +.Sh ERRORS +.Fn openpty +will fail if: +.Bl -tag -width Er +.It Bq Er ENOENT +There are no available ttys. +.El +.Pp +.Fn login_tty +will fail if +.Fn ioctl +fails to set +.Fa fd +to the controlling terminal of the current process. +.Fn forkpty +will fail if either +.Fn openpty +or +.Fn fork +fails. +.Sh FILES +.Bl -tag -width /dev/[pt]ty[pqrstuwxyzPQRST][0123456789abcdef] -compact +.It Pa /dev/[pt]ty[pqrstuwxyzPQRST][0123456789abcdef] +.El +.Sh SEE ALSO +.Xr fork 2 +.Sh BUGS +The names of the virtual consoles for the i386 PCVT console driver +conflict with what would be the seventh group of pseudo-ttys, so +.Fn openpty +skips +.Pa /dev/[pt]tyv[0123456789abcdef] +while looking for pseudo-ttys. diff --git a/util/pty.c b/util/pty.c index 0a59b91..369ad48 100644 --- a/util/pty.c +++ b/util/pty.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -67,6 +67,9 @@ #include #include #include +#include + +static char ptytemplate[] = "/dev/ptyXX"; int openpty(amaster, aslave, name, termp, winp) int *amaster, *aslave; @@ -74,47 +77,26 @@ int openpty(amaster, aslave, name, termp, winp) struct termios *termp; struct winsize *winp; { - static char line[] = "/dev/ptyXX"; - register const char *cp1, *cp2; - register int master, slave, ttygid; - struct group *gr; - - if ((gr = getgrnam("tty")) != NULL) - ttygid = gr->gr_gid; - else - ttygid = -1; + int master, slave; + char *sname; - for (cp1 = "pqrstuvwxy"; *cp1; cp1++) { - line[8] = *cp1; - for (cp2 = "0123456789abcdef"; *cp2; cp2++) { - line[5] = 'p'; - line[9] = *cp2; - if ((master = open(line, O_RDWR, 0)) == -1) { - if (errno == ENOENT) - return (-1); /* out of ptys */ - } else { - line[5] = 't'; - (void) grantpt(master); - (void) revoke(line); - if ((slave = open(line, O_RDWR, 0)) != -1) { - *amaster = master; - *aslave = slave; - if (name) - strcpy(name, line); - if (termp) - (void) tcsetattr(slave, - TCSAFLUSH, termp); - if (winp) - (void) ioctl(slave, TIOCSWINSZ, - (char *)winp); - return (0); - } - (void) close(master); - } - } + if ((master = posix_openpt(O_RDWR|O_NOCTTY)) < 0) + return -1; + if (grantpt(master) < 0 || unlockpt(master) < 0 + || (sname = ptsname(master)) == NULL + || (slave = open(sname, O_RDWR|O_NOCTTY, 0)) < 0) { + (void) close(master); + return -1; } - errno = ENOENT; /* out of ptys */ - return (-1); + *amaster = master; + *aslave = slave; + if (name) + strcpy(name, sname); + if (termp) + (void) tcsetattr(slave, TCSAFLUSH, termp); + if (winp) + (void) ioctl(slave, TIOCSWINSZ, (char *)winp); + return (0); } int @@ -136,7 +118,19 @@ forkpty(amaster, name, termp, winp) * child */ (void) close(master); - login_tty(slave); + /* + * 4300297: login_tty() may fail to set the controlling tty. + * Since we have already forked, the best we can do is to + * dup the slave as if login_tty() succeeded. + */ + if (login_tty(slave) < 0) { + syslog(LOG_ERR, "forkpty: login_tty could't make controlling tty"); + (void) dup2(slave, 0); + (void) dup2(slave, 1); + (void) dup2(slave, 2); + if (slave > 2) + (void) close(slave); + } return (0); } /* diff --git a/uuid/Makefile.inc b/uuid/Makefile.inc index 7cfeeb9..f7fcd6e 100644 --- a/uuid/Makefile.inc +++ b/uuid/Makefile.inc @@ -8,27 +8,45 @@ UUIDSRCS = clear.c compare.c copy.c gen_uuid.c isnull.c pack.c parse.c \ UUIDHDRS = uuidP.h UUIDFROMMAN = libuuid.3.in UUIDTOMAN = uuid.3.in -UUIDMAN3 = uuid_clear.3.in uuid_compare.3.in uuid_copy.3.in uuid_generate.3.in \ - uuid_is_null.3.in uuid_parse.3.in uuid_unparse.3.in +UUIDMAN3 = uuid_clear.3.in uuid_compare.3.in uuid_copy.3.in \ + uuid_generate.3.in uuid_is_null.3.in uuid_parse.3.in \ + uuid_unparse.3.in PRIVUUID_INSTHDRS += ${.CURDIR}/uuid/namespace.h .for _src in ${UUIDSRCS} -${SYMROOT}/${_src:R}-uuid.${_src:E}: uuidsrc/${_src} _AUTOPATCHSYM +.ifmake autopatch +${_src:R}-uuid.${_src:E}: uuidsrc/${_src} _AUTOPATCHCUR +AUTOPATCHSRCS+= ${_src:R}-uuid.${_src:E} +.else # !autopatch MISRCS+= ${_src} -AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-uuid.${_src:E} +.endif # autopatch .endfor +.ifmake autopatch .for _src in ${UUIDHDRS} -${SYMROOT}/${_src}: uuidsrc/${_src} _AUTOPATCHSYM -AUTOPATCHHDRS+= ${SYMROOT}/${_src} +${_src}: uuidsrc/${_src} _AUTOPATCHCUR +AUTOPATCHHDRS+= ${_src} .endfor +.endif # autopatch .for _src in ${UUIDMAN3} +.ifmake autopatch ${_src:R}-uuid.${_src:E}: uuidsrc/${_src} _AUTOPATCH -MAN3+= ${_src:R} AUTOPATCHMAN+= ${_src:R} +.else # !autopatch +MAN3+= ${_src:R} +.endif # autopatch .endfor +MLINKS+= uuid_generate.3 uuid_generate_random.3 \ + uuid_generate.3 uuid_generate_time.3 + +MLINKS+= uuid_unparse.3 uuid_unparse_lower.3 \ + uuid_unparse.3 uuid_unparse_upper.3 + +.ifmake autopatch ${UUIDTOMAN:R}-uuid.${UUIDTOMAN:E}: uuidsrc/${UUIDFROMMAN} _AUTOPATCH -MAN3+= ${UUIDTOMAN:R} AUTOPATCHMAN+= ${UUIDTOMAN:R} +.else # !autopatch +MAN3+= ${UUIDTOMAN:R} +.endif # autopatch diff --git a/uuid/clear-uuid.c b/uuid/clear-uuid.c new file mode 100644 index 0000000..f3a1005 --- /dev/null +++ b/uuid/clear-uuid.c @@ -0,0 +1,43 @@ +/* + * clear.c -- Clear a UUID + * + * 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 "string.h" + +#include "uuidP.h" + +void uuid_clear(uuid_t uu) +{ + memset(uu, 0, 16); +} + diff --git a/uuid/compare-uuid.c b/uuid/compare-uuid.c new file mode 100644 index 0000000..a9c505c --- /dev/null +++ b/uuid/compare-uuid.c @@ -0,0 +1,55 @@ +/* + * compare.c --- compare whether or not two UUID's are the same + * + * Returns 0 if the two UUID's are different, and 1 if they are the same. + * + * 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 "uuidP.h" +#include + +#define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1); + +int uuid_compare(const uuid_t uu1, const uuid_t uu2) +{ + struct uuid uuid1, uuid2; + + uuid_unpack(uu1, &uuid1); + uuid_unpack(uu2, &uuid2); + + UUCMP(uuid1.time_low, uuid2.time_low); + UUCMP(uuid1.time_mid, uuid2.time_mid); + UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version); + UUCMP(uuid1.clock_seq, uuid2.clock_seq); + return memcmp(uuid1.node, uuid2.node, 6); +} + diff --git a/uuid/copy-uuid.c b/uuid/copy-uuid.c new file mode 100644 index 0000000..963bc81 --- /dev/null +++ b/uuid/copy-uuid.c @@ -0,0 +1,45 @@ +/* + * copy.c --- copy UUIDs + * + * 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 "uuidP.h" + +void uuid_copy(uuid_t dst, const uuid_t src) +{ + unsigned char *cp1; + const unsigned char *cp2; + int i; + + for (i=0, cp1 = dst, cp2 = src; i < 16; i++) + *cp1++ = *cp2++; +} diff --git a/uuid/gen_uuid-uuid.c b/uuid/gen_uuid-uuid.c new file mode 100644 index 0000000..651ce93 --- /dev/null +++ b/uuid/gen_uuid-uuid.c @@ -0,0 +1,272 @@ +/* + * gen_uuid.c --- generate a DCE-compatible uuid + * + * Copyright (C) 1996, 1997, 1998, 1999 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% + */ + +/* + * Force inclusion of SVID stuff since we need it if we're compiling in + * gcc-wall wall mode + */ +#define _SVID_SOURCE + +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NET_IF_DL_H +#include +#endif + +#include "uuidP.h" + +/* + * Generate a series of random bytes, using arc4random + */ +static void get_random_bytes(void *buf, int nbytes) +{ + unsigned char *cp = (unsigned char *) buf; + u_int32_t u; + int n = nbytes / sizeof(u); + + while (n-- > 0) { + u = arc4random(); + memcpy(cp, &u, sizeof(u)); + cp += sizeof(u); + } + if ((n = nbytes % sizeof(u)) > 0) { + u = arc4random(); + memcpy(cp, &u, n); + } + return; +} + +/* + * Get the ethernet hardware address, if we can find it... + */ +static int get_node_id(unsigned char *node_id) +{ +#ifdef HAVE_NET_IF_H + int sd; + struct ifreq ifr, *ifrp; + struct ifconf ifc; + char buf[1024]; + int n, i; + unsigned char *a; +#ifdef AF_LINK + struct sockaddr_dl *sdlp; +#endif + +/* + * BSD 4.4 defines the size of an ifreq to be + * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len + * However, under earlier systems, sa_len isn't present, so the size is + * just sizeof(struct ifreq) + */ +#ifdef HAVE_SA_LEN +#ifndef max +#define max(a,b) ((a) > (b) ? (a) : (b)) +#endif +#define ifreq_size(i) max(sizeof(struct ifreq),\ + sizeof((i).ifr_name)+(i).ifr_addr.sa_len) +#else +#define ifreq_size(i) sizeof(struct ifreq) +#endif /* HAVE_SA_LEN*/ + + sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + if (sd < 0) { + return -1; + } + memset(buf, 0, sizeof(buf)); + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) { + close(sd); + return -1; + } + n = ifc.ifc_len; + for (i = 0; i < n; i+= ifreq_size(*ifrp) ) { + ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i); + strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ); +#ifdef SIOCGIFHWADDR + if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) + continue; + a = (unsigned char *) &ifr.ifr_hwaddr.sa_data; +#else +#ifdef SIOCGENADDR + if (ioctl(sd, SIOCGENADDR, &ifr) < 0) + continue; + a = (unsigned char *) ifr.ifr_enaddr; +#else +#ifdef AF_LINK + sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr; + if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6)) + continue; + a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen]; +#else + /* + * XXX we don't have a way of getting the hardware + * address + */ + close(sd); + return 0; +#endif /* AF_LINK */ +#endif /* SIOCGENADDR */ +#endif /* SIOCGIFHWADDR */ + if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) + continue; + if (node_id) { + memcpy(node_id, a, 6); + close(sd); + return 1; + } + } + close(sd); +#endif + return 0; +} + +/* Assume that the gettimeofday() has microsecond granularity */ +#define MAX_ADJUSTMENT 10 + +static int get_clock(uint32_t *clock_high, uint32_t *clock_low, uint16_t *ret_clock_seq) +{ + static int adjustment = 0; + static struct timeval last = {0, 0}; + static uint16_t clock_seq; + struct timeval tv; + unsigned long long clock_reg; + +try_again: + gettimeofday(&tv, 0); + if ((last.tv_sec == 0) && (last.tv_usec == 0)) { + get_random_bytes(&clock_seq, sizeof(clock_seq)); + clock_seq &= 0x3FFF; + last = tv; + last.tv_sec--; + } + if ((tv.tv_sec < last.tv_sec) || + ((tv.tv_sec == last.tv_sec) && + (tv.tv_usec < last.tv_usec))) { + clock_seq = (clock_seq+1) & 0x3FFF; + adjustment = 0; + last = tv; + } else if ((tv.tv_sec == last.tv_sec) && + (tv.tv_usec == last.tv_usec)) { + if (adjustment >= MAX_ADJUSTMENT) + goto try_again; + adjustment++; + } else { + adjustment = 0; + last = tv; + } + + clock_reg = tv.tv_usec*10 + adjustment; + clock_reg += ((unsigned long long) tv.tv_sec)*10000000; + clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000; + + *clock_high = clock_reg >> 32; + *clock_low = clock_reg; + *ret_clock_seq = clock_seq; + return 0; +} + +void uuid_generate_time(uuid_t out) +{ + static unsigned char node_id[6]; + static int has_init = 0; + struct uuid uu; + uint32_t clock_mid; + + if (!has_init) { + if (get_node_id(node_id) <= 0) { + get_random_bytes(node_id, 6); + /* + * Set multicast bit, to prevent conflicts + * with IEEE 802 addresses obtained from + * network cards + */ + node_id[0] |= 0x01; + } + has_init = 1; + } + get_clock(&clock_mid, &uu.time_low, &uu.clock_seq); + uu.clock_seq |= 0x8000; + uu.time_mid = (uint16_t) clock_mid; + uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000; + memcpy(uu.node, node_id, 6); + uuid_pack(&uu, out); +} + +void uuid_generate_random(uuid_t out) +{ + uuid_t buf; + struct uuid uu; + + get_random_bytes(buf, sizeof(buf)); + uuid_unpack(buf, &uu); + + uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000; + uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000; + uuid_pack(&uu, out); +} + +/* + * This is the generic front-end + */ +void uuid_generate(uuid_t out) +{ + uuid_generate_random(out); +} diff --git a/uuid/isnull-uuid.c b/uuid/isnull-uuid.c new file mode 100644 index 0000000..54a8300 --- /dev/null +++ b/uuid/isnull-uuid.c @@ -0,0 +1,48 @@ +/* + * isnull.c --- Check whether or not the UUID is null + * + * 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 "uuidP.h" + +/* Returns 1 if the uuid is the NULL uuid */ +int uuid_is_null(const uuid_t uu) +{ + const unsigned char *cp; + int i; + + for (i=0, cp = uu; i < 16; i++) + if (*cp++) + return 0; + return 1; +} + diff --git a/uuid/pack-uuid.c b/uuid/pack-uuid.c new file mode 100644 index 0000000..348d432 --- /dev/null +++ b/uuid/pack-uuid.c @@ -0,0 +1,69 @@ +/* + * Internal routine for packing UUID's + * + * 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" + +void uuid_pack(const struct uuid *uu, uuid_t ptr) +{ + uint32_t tmp; + unsigned char *out = ptr; + + tmp = uu->time_low; + out[3] = (unsigned char) tmp; + tmp >>= 8; + out[2] = (unsigned char) tmp; + tmp >>= 8; + out[1] = (unsigned char) tmp; + tmp >>= 8; + out[0] = (unsigned char) tmp; + + tmp = uu->time_mid; + out[5] = (unsigned char) tmp; + tmp >>= 8; + out[4] = (unsigned char) tmp; + + tmp = uu->time_hi_and_version; + out[7] = (unsigned char) tmp; + tmp >>= 8; + out[6] = (unsigned char) tmp; + + tmp = uu->clock_seq; + out[9] = (unsigned char) tmp; + tmp >>= 8; + out[8] = (unsigned char) tmp; + + memcpy(out+10, uu->node, 6); +} + diff --git a/uuid/parse-uuid.c b/uuid/parse-uuid.c new file mode 100644 index 0000000..07b894d --- /dev/null +++ b/uuid/parse-uuid.c @@ -0,0 +1,79 @@ +/* + * parse.c --- UUID parsing + * + * 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 +#include +#include + +#include "uuidP.h" + +int uuid_parse(const char *in, uuid_t uu) +{ + struct uuid uuid; + int i; + const char *cp; + char buf[3]; + + if (strlen(in) != 36) + return -1; + for (i=0, cp = in; i <= 36; i++,cp++) { + if ((i == 8) || (i == 13) || (i == 18) || + (i == 23)) { + if (*cp == '-') + continue; + else + return -1; + } + if (i== 36) + if (*cp == 0) + continue; + if (!isxdigit(*cp)) + return -1; + } + uuid.time_low = strtoul(in, NULL, 16); + uuid.time_mid = strtoul(in+9, NULL, 16); + uuid.time_hi_and_version = strtoul(in+14, NULL, 16); + uuid.clock_seq = strtoul(in+19, NULL, 16); + cp = in+24; + buf[2] = 0; + for (i=0; i < 6; i++) { + buf[0] = *cp++; + buf[1] = *cp++; + uuid.node[i] = strtoul(buf, NULL, 16); + } + + uuid_pack(&uuid, uu); + return 0; +} diff --git a/uuid/unpack-uuid.c b/uuid/unpack-uuid.c new file mode 100644 index 0000000..9502fc2 --- /dev/null +++ b/uuid/unpack-uuid.c @@ -0,0 +1,63 @@ +/* + * Internal routine for unpacking UUID + * + * 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" + +void uuid_unpack(const uuid_t in, struct uuid *uu) +{ + const uint8_t *ptr = in; + uint32_t tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_low = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_mid = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_hi_and_version = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->clock_seq = tmp; + + memcpy(uu->node, ptr, 6); +} + diff --git a/uuid/unparse-uuid.c b/uuid/unparse-uuid.c new file mode 100644 index 0000000..c0e08ef --- /dev/null +++ b/uuid/unparse-uuid.c @@ -0,0 +1,76 @@ +/* + * 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 = + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"; + +static const char *fmt_upper = + "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"; + +#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) +{ + 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]); +} + +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.3 b/uuid/uuid.3 new file mode 100644 index 0000000..79e5b28 --- /dev/null +++ b/uuid/uuid.3 @@ -0,0 +1,66 @@ +.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca) +.\" +.\" %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% +.\" +.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger +.TH UUID 3 "April 2004" "1.36" +.SH NAME +uuid \- DCE compatible Universally Unique Identifier library +.SH SYNOPSIS +.B #include +.SH DESCRIPTION +The +UUID +library is used to generate unique identifiers for objects that may be +accessible beyond the local system. This library +generates UUIDs compatible with those created by the Open Software +Foundation (OSF) Distributed Computing Environment (DCE) utility +.BR uuidgen . +.sp +The UUIDs generated by this library can be reasonably expected to be +unique within a system, and unique across all systems. They could +be used, for instance, to generate unique HTTP cookies across multiple +web servers without communication between the servers, and without fear +of a name clash. +.SH "CONFORMING TO" +OSF DCE 1.1 +.SH AUTHOR +Theodore Y. Ts'o +.SH AVAILABILITY +.UR http://e2fsprogs.sourceforge.net/ +http://e2fsprogs.sourceforge.net/ +.UE +.SH "SEE ALSO" +.BR uuid_clear (3), +.BR uuid_compare (3), +.BR uuid_copy (3), +.BR uuid_generate (3), +.BR uuid_is_null (3), +.BR uuid_parse (3), +.BR uuid_unparse (3) diff --git a/uuid/uuid.3-uuid.in b/uuid/uuid.3-uuid.in new file mode 120000 index 0000000..236dc3a --- /dev/null +++ b/uuid/uuid.3-uuid.in @@ -0,0 +1 @@ +./libuuid.3.in \ No newline at end of file diff --git a/uuid/uuidP.h b/uuid/uuidP.h new file mode 100644 index 0000000..a75e45a --- /dev/null +++ b/uuid/uuidP.h @@ -0,0 +1,78 @@ +/* + * uuid.h -- private header file for uuids + * + * 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% + */ + +#ifdef HAVE_STDINT_H +#include +#else +#include +#endif +#include +#include +#include + +#include + +/* + * Offset between 15-Oct-1582 and 1-Jan-70 + */ +#define TIME_OFFSET_HIGH 0x01B21DD2 +#define TIME_OFFSET_LOW 0x13814000 + +struct uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint16_t clock_seq; + uint8_t node[6]; +}; + +/* UUID Variant definitions */ +#define UUID_VARIANT_NCS 0 +#define UUID_VARIANT_DCE 1 +#define UUID_VARIANT_MICROSOFT 2 +#define UUID_VARIANT_OTHER 3 + +/* UUID Type definitions */ +#define UUID_TYPE_DCE_TIME 1 +#define UUID_TYPE_DCE_RANDOM 4 + +/* + * prototypes + */ +void uuid_pack(const struct uuid *uu, uuid_t ptr); +void uuid_unpack(const uuid_t in, struct uuid *uu); + +time_t uuid_time(const uuid_t uu, struct timeval *ret_tv); +int uuid_type(const uuid_t uu); +int uuid_variant(const uuid_t uu); diff --git a/uuid/uuid_clear.3 b/uuid/uuid_clear.3 new file mode 100644 index 0000000..a90694e --- /dev/null +++ b/uuid/uuid_clear.3 @@ -0,0 +1,60 @@ +.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca) +.\" +.\" %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% +.\" +.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger +.TH UUID_CLEAR 3 "April 2004" "1.36" +.SH NAME +uuid_clear \- reset value of UUID variable to the NULL value +.SH SYNOPSIS +.nf +.B #include +.sp +.BI "void uuid_clear(uuid_t " uu ); +.fi +.SH DESCRIPTION +The +.B uuid_clear +function sets the value of the supplied uuid variable +.I uu +to the NULL value. +.SH AUTHOR +Theodore Y. Ts'o +.SH AVAILABILITY +.UR http://e2fsprogs.sourceforge.net/ +http://e2fsprogs.sourceforge.net/ +.UE +.SH "SEE ALSO" +.BR uuid (3), +.BR uuid_compare (3), +.BR uuid_copy (3), +.BR uuid_generate (3), +.BR uuid_is_null (3), +.BR uuid_parse (3), +.BR uuid_unparse (3) diff --git a/uuid/uuid_clear.3-uuid.in b/uuid/uuid_clear.3-uuid.in new file mode 120000 index 0000000..32ce86e --- /dev/null +++ b/uuid/uuid_clear.3-uuid.in @@ -0,0 +1 @@ +./uuid_clear.3.in \ No newline at end of file diff --git a/uuid/uuid_compare.3 b/uuid/uuid_compare.3 new file mode 100644 index 0000000..7dac2d1 --- /dev/null +++ b/uuid/uuid_compare.3 @@ -0,0 +1,66 @@ +.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca) +.\" +.\" %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% +.\" +.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger +.TH UUID_COMPARE 3 "April 2004" "1.36" +.SH NAME +uuid_compare \- compare whether two UUIDs are the same +.SH SYNOPSIS +.nf +.B #include +.sp +.BI "int uuid_compare(uuid_t " uu1 ", uuid_t " uu2) +.fi +.SH DESCRIPTION +The +.B uuid_compare +function compares the two supplied uuid variables +.IR uu1 " and " uu2 +to each other. +.SH RETURN VALUE +Returns an integer less than, equal to, or greater than zero if +.I uu1 +is found, respectively, to be lexigraphically less than, equal, or +greater than +.IR uu2 . +.SH AUTHOR +Theodore Y. Ts'o +.SH AVAILABILITY +.UR http://e2fsprogs.sourceforge.net/ +http://e2fsprogs.sourceforge.net/ +.UE +.SH "SEE ALSO" +.BR uuid (3), +.BR uuid_clear (3), +.BR uuid_copy (3), +.BR uuid_generate (3), +.BR uuid_is_null (3), +.BR uuid_parse (3), +.BR uuid_unparse (3) diff --git a/uuid/uuid_compare.3-uuid.in b/uuid/uuid_compare.3-uuid.in new file mode 120000 index 0000000..cae5088 --- /dev/null +++ b/uuid/uuid_compare.3-uuid.in @@ -0,0 +1 @@ +./uuid_compare.3.in \ No newline at end of file diff --git a/uuid/uuid_copy.3 b/uuid/uuid_copy.3 new file mode 100644 index 0000000..e0a3fbd --- /dev/null +++ b/uuid/uuid_copy.3 @@ -0,0 +1,62 @@ +.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca) +.\" +.\" %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% +.\" +.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger +.TH UUID_COPY 3 "April 2004" "1.36" +.SH NAME +uuid_copy \- copy a UUID value +.SH SYNOPSIS +.nf +.B #include +.sp +.BI "void uuid_copy(uuid_t " dst ", uuid_t " src); +.fi +.SH DESCRIPTION +The +.B uuid_copy +function copies the UUID variable +.IR src " to " dst . +.SH RETURN VALUE +The copied UUID is returned in the location pointed to by +.IR dst . +.SH AUTHOR +Theodore Y. Ts'o +.SH AVAILABILITY +.UR http://e2fsprogs.sourceforge.net/ +http://e2fsprogs.sourceforge.net/ +.UE +.SH "SEE ALSO" +.BR uuid (3), +.BR uuid_clear (3), +.BR uuid_compare (3), +.BR uuid_generate (3), +.BR uuid_is_null (3), +.BR uuid_parse (3), +.BR uuid_unparse (3) diff --git a/uuid/uuid_copy.3-uuid.in b/uuid/uuid_copy.3-uuid.in new file mode 120000 index 0000000..bf39bbc --- /dev/null +++ b/uuid/uuid_copy.3-uuid.in @@ -0,0 +1 @@ +./uuid_copy.3.in \ No newline at end of file diff --git a/uuid/uuid_generate.3 b/uuid/uuid_generate.3 new file mode 100644 index 0000000..c33fa5d --- /dev/null +++ b/uuid/uuid_generate.3 @@ -0,0 +1,103 @@ +.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca) +.\" +.\" %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% +.\" +.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger +.TH UUID_GENERATE 3 "April 2004" "1.36" +.SH NAME +uuid_generate, uuid_generate_random, uuid_generate_time \- create a new unique UUID value +.SH SYNOPSIS +.nf +.B #include +.sp +.BI "void uuid_generate(uuid_t " out ); +.BI "void uuid_generate_random(uuid_t " out ); +.BI "void uuid_generate_time(uuid_t " out ); +.fi +.SH DESCRIPTION +The +.B uuid_generate +function creates a new universally unique identifier (UUID). The uuid will +be generated based on high-quality randomness from +.IR /dev/urandom , +if available. If it is not available, then +.B uuid_generate +will use an alternative algorithm which uses the current time, the +local ethernet MAC address (if available), and random data generated +using a pseudo-random generator. +.sp +The +.B uuid_generate_random +function forces the use of the all-random UUID format, even if +a high-quality random number generator (i.e., +.IR /dev/urandom ) +is not available, in which case a pseudo-random +generator will be subsituted. Note that the use of a pseudo-random +generator may compromise the uniqueness of UUID's +generated in this fashion. +.sp +The +.B uuid_generate_time +function forces the use of the alternative algorithm which uses the +current time and the local ethernet MAC address (if available). +This algorithm used to be the default one used to generate UUID, but +because of the use of the ethernet MAC address, it can leak +information about when and where the UUID was generated. This can cause +privacy problems in some applications, so the +.B uuid_generate +function only uses this algorithm if a high-quality source of +randomness is not available. +.sp +The UUID is 16 bytes (128 bits) long, which gives approximately 3.4x10^38 +unique values (there are approximately 10^80 elemntary particles in +the universe according to Carl Sagan's +.IR Cosmos ). +The new UUID can reasonably be considered unique among all UUIDs created +on the local system, and among UUIDs created on other systems in the past +and in the future. +.SH RETURN VALUE +The newly created UUID is returned in the memory location pointed to by +.IR out . +.SH "CONFORMING TO" +OSF DCE 1.1 +.SH AUTHOR +Theodore Y. Ts'o +.SH AVAILABILITY +.UR http://e2fsprogs.sourceforge.net/ +http://e2fsprogs.sourceforge.net/ +.UE +.SH "SEE ALSO" +.BR uuid (3), +.BR uuidgen (1), +.BR uuid_clear (3), +.BR uuid_compare (3), +.BR uuid_copy (3), +.BR uuid_is_null (3), +.BR uuid_parse (3), +.BR uuid_unparse (3) diff --git a/uuid/uuid_generate.3-uuid.in b/uuid/uuid_generate.3-uuid.in new file mode 120000 index 0000000..0c031b8 --- /dev/null +++ b/uuid/uuid_generate.3-uuid.in @@ -0,0 +1 @@ +./uuid_generate.3.in \ No newline at end of file diff --git a/uuid/uuid_is_null.3 b/uuid/uuid_is_null.3 new file mode 100644 index 0000000..cfd2169 --- /dev/null +++ b/uuid/uuid_is_null.3 @@ -0,0 +1,61 @@ +.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca) +.\" +.\" %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% +.\" +.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger +.TH UUID_IS_NULL 3 "April 2004" "1.36" +.SH NAME +uuid_is_null \- compare the value of the UUID to the NULL value +.SH SYNOPSIS +.nf +.B #include +.sp +.BI "int uuid_is_null(uuid_t " uu ); +.fi +.SH DESCRIPTION +The +.B uuid_is_null +function compares the value of the supplied UUID variable +.I uu +to the NULL value. If the value is equal to the NULL UUID, 1 is returned, +otherwise 0 is returned. +.SH AUTHOR +Theodore Y. Ts'o +.SH AVAILABILITY +.UR http://e2fsprogs.sourceforge.net/ +http://e2fsprogs.sourceforge.net/ +.UE +.SH "SEE ALSO" +.BR uuid (3), +.BR uuid_clear (3), +.BR uuid_compare (3), +.BR uuid_copy (3), +.BR uuid_generate (3), +.BR uuid_parse (3), +.BR uuid_unparse (3) diff --git a/uuid/uuid_is_null.3-uuid.in b/uuid/uuid_is_null.3-uuid.in new file mode 120000 index 0000000..2694458 --- /dev/null +++ b/uuid/uuid_is_null.3-uuid.in @@ -0,0 +1 @@ +./uuid_is_null.3.in \ No newline at end of file diff --git a/uuid/uuid_parse.3 b/uuid/uuid_parse.3 new file mode 100644 index 0000000..253a261 --- /dev/null +++ b/uuid/uuid_parse.3 @@ -0,0 +1,70 @@ +.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca) +.\" +.\" %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% +.\" +.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger +.TH UUID_PARSE 3 "April 2004" "1.36" +.SH NAME +uuid_parse \- convert an input UUID string into binary representation +.SH SYNOPSIS +.nf +.B #include +.sp +.BI "int uuid_parse( char *" in ", uuid_t " uu ); +.fi +.SH DESCRIPTION +The +.B uuid_parse +function converts the UUID string given by +.I in +into the binary representation. The input UUID is a string of the form +1b4e28ba\-2fa1\-11d2\-883f\-b9a761bde3fb (in +.BR printf (3) +format "%08x\-%04x\-%04x\-%04x\-%012x", 36 bytes plus the trailing '\\0'). +.SH RETURN VALUE +Upon successfully parsing the input string, 0 is returned, and the UUID is +stored in the location pointed to by +.IR uu , +otherwise \-1 is returned. +.SH "CONFORMING TO" +OSF DCE 1.1 +.SH AUTHOR +Theodore Y. Ts'o +.SH AVAILABILITY +.UR http://e2fsprogs.sourceforge.net/ +http://e2fsprogs.sourceforge.net/ +.UE +.SH "SEE ALSO" +.BR uuid (3), +.BR uuid_clear (3), +.BR uuid_compare (3), +.BR uuid_copy (3), +.BR uuid_generate (3), +.BR uuid_is_null (3), +.BR uuid_unparse (3) diff --git a/uuid/uuid_parse.3-uuid.in b/uuid/uuid_parse.3-uuid.in new file mode 120000 index 0000000..24e0f63 --- /dev/null +++ b/uuid/uuid_parse.3-uuid.in @@ -0,0 +1 @@ +./uuid_parse.3.in \ No newline at end of file diff --git a/uuid/uuid_unparse.3 b/uuid/uuid_unparse.3 new file mode 100644 index 0000000..7d05561 --- /dev/null +++ b/uuid/uuid_unparse.3 @@ -0,0 +1,87 @@ +.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca) +.\" +.\" %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% +.\" +.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger +.TH UUID_UNPARSE 3 "April 2004" "1.36" +.SH NAME +uuid_unparse \- convert an UUID from binary representation to a string +.SH SYNOPSIS +.nf +.B #include +.sp +\fIvoid\fP +.br +\fBuuid_unparse\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +.sp +\fIvoid\fP +.br +\fBuuid_unparse_lower\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +.sp +\fIvoid\fP +.br +\fBuuid_unparse_upper\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +.sp +.fi +.SH DESCRIPTION +The +.B uuid_unparse +function converts the supplied UUID +.I uu +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 +character string pointed to by +.IR out . +The case of the hex digits returned by +.B uuid_unparse +may be upper or lower case, and is +dependent on the system-dependent local default. +.PP +If the case of the +hex digits is important then the functions +.B uuid_unparse_upper +and +.B uuid_unparse_lower +may be used. +.SH "CONFORMING TO" +OSF DCE 1.1 +.SH AUTHOR +Theodore Y. Ts'o +.SH AVAILABILITY +.UR http://e2fsprogs.sourceforge.net/ +http://e2fsprogs.sourceforge.net/ +.UE +.SH "SEE ALSO" +.BR uuid (3), +.BR uuid_clear (3), +.BR uuid_compare (3), +.BR uuid_copy (3), +.BR uuid_generate (3), +.BR uuid_is_null (3), +.BR uuid_parse (3) diff --git a/uuid/uuid_unparse.3-uuid.in b/uuid/uuid_unparse.3-uuid.in new file mode 100644 index 0000000..34ff1ab --- /dev/null +++ b/uuid/uuid_unparse.3-uuid.in @@ -0,0 +1,87 @@ +.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca) +.\" +.\" %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% +.\" +.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger +.TH UUID_UNPARSE 3 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "@E2FSPROGS_VERSION@" +.SH NAME +uuid_unparse \- convert an UUID from binary representation to a string +.SH SYNOPSIS +.nf +.B #include +.sp +\fIvoid\fP +.br +\fBuuid_unparse\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +.sp +\fIvoid\fP +.br +\fBuuid_unparse_lower\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +.sp +\fIvoid\fP +.br +\fBuuid_unparse_upper\fP(\fIuuid_t uu\fP, \fIchar * out\fP); +.sp +.fi +.SH DESCRIPTION +The +.B uuid_unparse +function converts the supplied UUID +.I uu +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 +character string pointed to by +.IR out . +The case of the hex digits returned by +.B uuid_unparse +may be upper or lower case, and is +dependent on the system-dependent local default. +.PP +If the case of the +hex digits is important then the functions +.B uuid_unparse_upper +and +.B uuid_unparse_lower +may be used. +.SH "CONFORMING TO" +OSF DCE 1.1 +.SH AUTHOR +Theodore Y. Ts'o +.SH AVAILABILITY +.UR http://e2fsprogs.sourceforge.net/ +http://e2fsprogs.sourceforge.net/ +.UE +.SH "SEE ALSO" +.BR uuid (3), +.BR uuid_clear (3), +.BR uuid_compare (3), +.BR uuid_copy (3), +.BR uuid_generate (3), +.BR uuid_is_null (3), +.BR uuid_parse (3) diff --git a/uuid/uuidsrc/gen_uuid.c.patch b/uuid/uuidsrc/gen_uuid.c.patch new file mode 100644 index 0000000..ee2b833 --- /dev/null +++ b/uuid/uuidsrc/gen_uuid.c.patch @@ -0,0 +1,94 @@ +--- gen_uuid.c.orig 2006-02-19 03:05:40.000000000 -0800 ++++ gen_uuid.c 2006-02-20 12:51:07.000000000 -0800 +@@ -72,62 +72,24 @@ + + #include "uuidP.h" + +-#ifdef HAVE_SRANDOM +-#define srand(x) srandom(x) +-#define rand() random() +-#endif +- +-static int get_random_fd(void) +-{ +- struct timeval tv; +- static int fd = -2; +- int i; +- +- if (fd == -2) { +- gettimeofday(&tv, 0); +- fd = open("/dev/urandom", O_RDONLY); +- if (fd == -1) +- fd = open("/dev/random", O_RDONLY | O_NONBLOCK); +- srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec); +- } +- /* Crank the random number generator a few times */ +- gettimeofday(&tv, 0); +- for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) +- rand(); +- return fd; +-} +- +- + /* +- * Generate a series of random bytes. Use /dev/urandom if possible, +- * and if not, use srandom/random. ++ * Generate a series of random bytes, using arc4random + */ + static void get_random_bytes(void *buf, int nbytes) + { +- int i, n = nbytes, fd = get_random_fd(); +- int lose_counter = 0; + unsigned char *cp = (unsigned char *) buf; ++ u_int32_t u; ++ int n = nbytes / sizeof(u); + +- if (fd >= 0) { +- while (n > 0) { +- i = read(fd, cp, n); +- if (i <= 0) { +- if (lose_counter++ > 16) +- break; +- continue; +- } +- n -= i; +- cp += i; +- lose_counter = 0; +- } ++ while (n-- > 0) { ++ u = arc4random(); ++ memcpy(cp, &u, sizeof(u)); ++ cp += sizeof(u); ++ } ++ if ((n = nbytes % sizeof(u)) > 0) { ++ u = arc4random(); ++ memcpy(cp, &u, n); + } +- +- /* +- * We do this all the time, but this is the only source of +- * randomness if /dev/random/urandom is out to lunch. +- */ +- for (cp = buf, i = 0; i < nbytes; i++) +- *cp++ ^= (rand() >> 7) & 0xFF; + return; + } + +@@ -302,15 +264,9 @@ + } + + /* +- * This is the generic front-end to uuid_generate_random and +- * uuid_generate_time. It uses uuid_generate_random only if +- * /dev/urandom is available, since otherwise we won't have +- * high-quality randomness. ++ * This is the generic front-end + */ + void uuid_generate(uuid_t out) + { +- if (get_random_fd() >= 0) +- uuid_generate_random(out); +- else +- uuid_generate_time(out); ++ uuid_generate_random(out); + } diff --git a/uuid/uuidsrc/uuid_unparse.3.in.patch b/uuid/uuidsrc/uuid_unparse.3.in.patch new file mode 100644 index 0000000..8d68223 --- /dev/null +++ b/uuid/uuidsrc/uuid_unparse.3.in.patch @@ -0,0 +1,24 @@ +--- uuid_unparse.3.in 2004-06-02 17:18:30.000000000 -0700 ++++ uuid_unparse.3.in.edit 2006-09-07 18:22:58.000000000 -0700 +@@ -36,9 +36,18 @@ + .nf + .B #include + .sp +-.BI "void uuid_unparse(uuid_t " uu ", char *" out ); +-.BI "void uuid_unparse_upper(uuid_t " uu ", char *" out ); +-.BI "void uuid_unparse_lower(uuid_t " uu ", char *" out ); ++\fIvoid\fP ++.br ++\fBuuid_unparse\fP(\fIuuid_t uu\fP, \fIchar * out\fP); ++.sp ++\fIvoid\fP ++.br ++\fBuuid_unparse_lower\fP(\fIuuid_t uu\fP, \fIchar * out\fP); ++.sp ++\fIvoid\fP ++.br ++\fBuuid_unparse_upper\fP(\fIuuid_t uu\fP, \fIchar * out\fP); ++.sp + .fi + .SH DESCRIPTION + The diff --git a/ppc/sys/getppid.s b/x86_64/gen/icacheinval.s similarity index 64% rename from ppc/sys/getppid.s rename to x86_64/gen/icacheinval.s index a4d8f0a..ee6a225 100644 --- a/ppc/sys/getppid.s +++ b/x86_64/gen/icacheinval.s @@ -1,5 +1,6 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,11 +21,25 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ + + + #include -#import -#import "SYS.h" + .text + .align 4, 0x00 -SYSCALL(getppid,0) +/* void sys_icache_invalidate(addr_t start, int length) */ +.globl _sys_icache_invalidate +_sys_icache_invalidate: + movq $(_COMM_PAGE_FLUSH_ICACHE), %rax + jmp *%rax + + +/* void sys_dcache_flush(addr_t start, int length) */ + +.globl _sys_dcache_flush +_sys_dcache_flush: + movq $(_COMM_PAGE_FLUSH_DCACHE), %rax + jmp *%rax diff --git a/x86_64/gen/mcount.s b/x86_64/gen/mcount.s index 2311cbb..3456862 100644 --- a/x86_64/gen/mcount.s +++ b/x86_64/gen/mcount.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,30 +23,30 @@ #import .text - .globl mcount + .globl mcount mcount: - pushq %rbp // setup mcount's frame - movq %rsp,%rbp + pushq %rbp // setup mcount's frame + movq %rsp, %rbp + subq $64, %rsp // allocate space for storage and alignment + movq %rax, 0(%rsp) + movq %rdi, 8(%rsp) + movq %rsi, 16(%rsp) + movq %rdx, 24(%rsp) + movq %rcx, 32(%rsp) + movq %r8, 40(%rsp) + movq %r9, 48(%rsp) + movq (%rbp), %rsi // load the frame pointer of mcount's caller + movq 8(%rsi), %rsi // load mcount's caller's return address + movq 8(%rbp), %rdi // set up the selfpc parameter for moncount() + CALL_EXTERN(_moncount) // call moncount() + movq 48(%rsp), %r9 + movq 40(%rsp), %r8 + movq 32(%rsp), %rcx + movq 24(%rsp), %rdx + movq 16(%rsp), %rsi + movq 8(%rsp), %rdi + movq 0(%rsp), %rax - // The compiler doesn't preserve registers when calling mcount - // so we have to ensure that we don't trash any. - subq $8, %rsp // maintain 16-byte alignment - pushq %rdi - pushq %rsi - pushq %rax - - movq (%rbp),%rax // load the frame pointer of mcount's caller - movq 8(%rax),%rax // load mcount's caller's return address - movq 8(%rbp),%rdi // set up the selfpc parameter for moncount() - movq %rax,%rsi // set up the frompc parameter for moncount() - CALL_EXTERN(_moncount) // call moncount() - - popq %rax - popq %rsi - popq %rdi - // No need for an addq because we're restoring %rsp in the - // next instruction. - - movq %rbp,%rsp // tear down mcount's frame - popq %rbp - ret + movq %rbp, %rsp + popq %rbp // tear down frame + ret diff --git a/x86_64/mach/Makefile.inc b/x86_64/mach/Makefile.inc index 980ba6b..00a5da1 100644 --- a/x86_64/mach/Makefile.inc +++ b/x86_64/mach/Makefile.inc @@ -1,3 +1,4 @@ -# searching i386 directory as a fallback to avoid unnecessary code duplication -.PATH: ${.CURDIR}/i386/mach -MDSRCS += mach_absolute_time.c + +.PATH: ${.CURDIR}/x86_64/mach + +MDSRCS += mach_absolute_time.s diff --git a/x86_64/sys/__fcntl.s b/x86_64/mach/mach_absolute_time.s similarity index 86% rename from x86_64/sys/__fcntl.s rename to x86_64/mach/mach_absolute_time.s index aaedd45..7c53025 100644 --- a/x86_64/sys/__fcntl.s +++ b/x86_64/mach/mach_absolute_time.s @@ -20,10 +20,13 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include -PSEUDO(__fcntl, fcntl, 3) - ret +#include + + + .text + .align 2 + .globl _mach_absolute_time +_mach_absolute_time: + movq $(_COMM_PAGE_NANOTIME), %rax + jmp *%rax diff --git a/x86_64/pthreads/Makefile.inc b/x86_64/pthreads/Makefile.inc index cfe58fd..b3c9885 100644 --- a/x86_64/pthreads/Makefile.inc +++ b/x86_64/pthreads/Makefile.inc @@ -6,4 +6,7 @@ MDSRCS += \ get_cpu_capabilities.s \ pthread_set_self.s \ pthread_self.s \ - pthread_getspecific.s + pthread_getspecific.s \ + start_wqthread.s \ + thread_start.s + diff --git a/i386/sys/i386_set_ldt.s b/x86_64/pthreads/start_wqthread.s similarity index 72% rename from i386/sys/i386_set_ldt.s rename to x86_64/pthreads/start_wqthread.s index 3eeb2a5..2013e09 100644 --- a/i386/sys/i386_set_ldt.s +++ b/x86_64/pthreads/start_wqthread.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,15 +21,17 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include -#include -#include +#include "pthread_machdep.h" .text -.globl cerror -LEAF(_i386_set_ldt, 0) - movl $5,%eax - MACHDEP_SYSCALL_TRAP - jnb 2f - BRANCH_EXTERN(cerror) -2: ret +.align 2, 0x90 +.globl _start_wqthread +_start_wqthread: +// This routine is never called directly by user code, jumped from kernel + push %rbp + mov %rsp,%rbp + sub $24,%rsp // align the stack + call __pthread_wqthread + leave + ret + diff --git a/i386/sys/i386_get_ldt.s b/x86_64/pthreads/thread_start.s similarity index 72% rename from i386/sys/i386_get_ldt.s rename to x86_64/pthreads/thread_start.s index 4a6611f..acb3fbd 100644 --- a/i386/sys/i386_get_ldt.s +++ b/x86_64/pthreads/thread_start.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,15 +21,17 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include -#include -#include +#include "pthread_machdep.h" .text -.globl cerror -LEAF(_i386_get_ldt, 0) - movl $6,%eax - MACHDEP_SYSCALL_TRAP - jnb 2f - BRANCH_EXTERN(cerror) -2: ret +.align 2, 0x90 +.globl _thread_start +_thread_start: +// This routine is never called directly by user code, jumped from kernel + push %rbp + mov %rsp,%rbp + sub $24,%rsp // align the stack + call __pthread_start + leave + ret + diff --git a/x86_64/stdlib/gdtoa.mk b/x86_64/stdlib/gdtoa.mk index 6a6a67d..9099369 100644 --- a/x86_64/stdlib/gdtoa.mk +++ b/x86_64/stdlib/gdtoa.mk @@ -1,2 +1,2 @@ # Long double is 80 bits -FBSDSRCS+=gdtoa_strtopx.c machdep_ldisx.c +GDTOA_FBSDSRCS+=gdtoa_strtopx.c machdep_ldisx.c diff --git a/x86_64/string/Makefile.inc b/x86_64/string/Makefile.inc index 80c0b9d..c0a9b6c 100644 --- a/x86_64/string/Makefile.inc +++ b/x86_64/string/Makefile.inc @@ -10,6 +10,8 @@ MDSRCS += bcopy.s \ bzero.s \ memcpy.s \ memmove.s \ + strlcat.s \ + strlcpy.s \ strlen.s \ strcpy.s \ strcmp.s \ @@ -17,4 +19,5 @@ MDSRCS += bcopy.s \ strncmp.s \ memcmp.s \ bcmp.s \ - memset.s + memset.s \ + ffs.s diff --git a/i386/sys/accept.s b/x86_64/string/ffs.s similarity index 66% rename from i386/sys/accept.s rename to x86_64/string/ffs.s index e0f3fcd..8a4eb83 100644 --- a/i386/sys/accept.s +++ b/x86_64/string/ffs.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,18 +20,44 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include -#ifdef __LP64__ -UNIX_SYSCALL(accept, 3) + .text + + .align 2 + .globl _ffs +_ffs: + movl $(-1), %edx + bsfl %edi, %eax + cmovel %edx, %eax + incl %eax ret -#else /* !__LP64__ */ -PSEUDO(accept$UNIX2003, accept, 3) + + + .align 2 + .globl _ffsl +_ffsl: + movl $(-1), %edx + bsfq %rdi, %rax + cmovel %edx, %eax + incl %eax ret -UNIX_SYSCALL_ERR(accept, 3, cerror_cvt) + + .align 2 + .globl _fls +_fls: + movl $(-1), %edx + bsrl %edi, %eax + cmovel %edx, %eax + incl %eax + ret + + + .align 2 + .globl _flsl +_flsl: + movl $(-1), %edx + bsrq %rdi, %rax + cmovel %edx, %eax + incl %eax ret -#endif /* !__LP64__ */ diff --git a/x86_64/string/strlcat.s b/x86_64/string/strlcat.s new file mode 100644 index 0000000..50a45a8 --- /dev/null +++ b/x86_64/string/strlcat.s @@ -0,0 +1,254 @@ +/* + * 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@ + */ + + +// ***************** +// * S T R L C A T * +// ***************** +// +// size_t strlcat(char *dst, const char *src, size_t size); +// +// Using 8- or 16-byte parallel loops introduce a complication: +// if we blindly did parallel load/stores until finding +// a 0, we might get a spurious page fault by touching bytes past it. +// To avoid this, we never do a load that crosses a page boundary, +// or store unnecessary bytes. +// +// The word parallel test for 0s relies on the following inobvious +// but very efficient test: +// x = dataWord + 0xFEFEFEFF +// y = ~dataWord & 0x80808080 +// if (x & y) == 0 then no zero found +// The test maps any non-zero byte to zero, and any zero byte to 0x80, +// with one exception: 0x01 bytes preceeding the first zero are also +// mapped to 0x80. +// +// On Core2 class machines, this algorithm seems to be faster than the +// naive byte-by-byte version for operands longer than about 11 bytes. + + .text + .globl _strlcat + + + +// Use SSE to find the 0-byte at current end of buffer. +// This is just a minor variant of strlen(). +// Initial registers: +// %rdi = dest or buffer ptr +// %rsi = source ptr +// %rdx = size + + .align 4 +_strlcat: // size_t *strlcat(char *dst, const char *src, size_t size); + movl %edi,%ecx // copy buffer ptr + movq %rdi,%r10 // save copies of buffer ptr and length + movq %rdx,%r11 + andq $(-16),%rdi // 16-byte align buffer ptr + pxor %xmm0,%xmm0 // get some 0s + andl $15,%ecx // get #bytes in dq before start of buffer + movl $16,%r8d + orl $(-1),%eax + subl %ecx,%r8d // #bytes from buffer start to end of dq + subq %r8,%rdx // does buffer end before end of dq? + jb LShortBuf1 // yes, drop into byte-by-byte mode + movdqa (%rdi),%xmm1 // get first aligned chunk of buffer + addq $16,%rdi + pcmpeqb %xmm0,%xmm1 // check for 0s + shl %cl,%eax // create mask for the bytes of aligned dq in operand + pmovmskb %xmm1,%ecx // collect mask of 0-bytes + andl %eax,%ecx // mask out any 0s that occur before buffer start + jnz 2f // found end of buffer +1: + subq $16,%rdx // another dq in buffer? + jb LShortBuf2 // no, drop into byte-by-byte mode + movdqa (%rdi),%xmm1 // get next chunk + addq $16,%rdi + pcmpeqb %xmm0,%xmm1 // check for 0s + pmovmskb %xmm1,%ecx // collect mask of 0-bytes + testl %ecx,%ecx // any 0-bytes? + jz 1b // no +2: + bsf %ecx,%ecx // find first 1-bit (ie, first 0-byte) + subq $16,%rdi // back up ptr into buffer + addq $16,%rdx // recover length remaining as of start of dq + addq %rcx,%rdi // point to 0-byte + subq %rcx,%rdx // compute #bytes remaining in buffer + + +// Copy byte-by-byte until source is 8-byte aligned. +// %rdi = points to 1st byte available in buffer +// %rsi = src ptr +// %rdx = buffer length remaining (ie, starting at %rdi) +// %r10 = original buffer ptr + + movl %esi,%ecx // copy source ptr + negl %ecx + andl $7,%ecx // how many bytes to align source ptr? + jz LAligned // already aligned + + +// Loop over bytes. +// %rdi = dest ptr +// %rsi = source ptr +// %rdx = length remaining in buffer +// %ecx = number of bytes to copy (>0, may not fit in buffer) +// %r10 = original buffer ptr + +LLoopOverBytes: + movzb (%rsi),%eax // get source byte before checking buffer length + testq %rdx,%rdx // buffer full? + jz L0NotFound // yes + incq %rsi + decq %rdx + movb %al,(%rdi) // pack into dest + incq %rdi + testl %eax,%eax // 0? + jz LDone // yes, done + decl %ecx // more to go? + jnz LLoopOverBytes + + +// Source is aligned. Loop over quadwords until end of buffer. We +// align the source, rather than the dest, to avoid getting spurious page faults. +// %rdi = dest ptr (unaligned) +// %rsi = source ptr (quadword aligned) +// %rdx = length remaining in buffer +// %r10 = original buffer ptr + +LAligned: + movl $9,%ecx // if buffer almost exhausted, prepare to copy rest byte-by-byte + cmpq $8,%rdx // enough for at least one quadword? + jb LLoopOverBytes + movq $0xFEFEFEFEFEFEFEFF,%r8 // get magic constants + movq $0x8080808080808080,%r9 + + +// Loop over quadwords. +// %rdi = dest ptr (unaligned) +// %rsi = source ptr (quadword aligned) +// %rdx = length remaining in buffer (>=8) +// %r8 = 0xFEFEFEFEFEFEFEFF +// %r9 = 0x8080808080808080 +// %r10 = original buffer ptr + +LLoopOverQuads: + movq (%rsi),%rax // get next 8 bytes of source + subq $8,%rdx + addq $8,%rsi + movq %rax,%r11 // make 2 copies of quadword + movq %rax,%rcx + notq %r11 // use magic word-parallel test for 0s + addq %r8,%rcx + andq %r9,%r11 + testq %rcx,%r11 + jnz L0Found // one of the bytes of %rax is a 0 + movq %rax,(%rdi) // pack 8 bytes into destination + addq $8,%rdi + cmpq $8,%rdx // room in buffer for another quadword? + jae LLoopOverQuads // yes + + movl %edx,%ecx // copy leftovers in byte loop + jmp LLoopOverBytes + +// Found a 0-byte in the quadword of source. Store a byte at a time until the 0. +// %rdi = dest ptr (unaligned) +// %rax = last word of source, known to have a 0-byte +// %r10 = original buffer ptr + +LNextByte: + shrq $8,%rax // next byte +L0Found: + movb %al,(%rdi) // pack in next byte + incq %rdi + testb %al,%al // 0? + jnz LNextByte + + +// Done storing string. +// %rdi = ptr to byte after 0-byte +// %r10 = original buffer ptr + +LDone: + subq %r10,%rdi // subtract original dest ptr to get length stored + lea -1(%rdi),%rax // minus one for 0-byte, and move to return value + ret + +// Buffer filled but 0-byte not found. We return the length of the buffer plus the length +// of the source string. This is not optimized, as it is an error condition. +// %edi = dest ptr (ie, 1 past end of buffer) +// %esi = source ptr (ptr to 1st byte that does not fit) +// %rdx = 0 (ie, length remaining in buffer) +// %r10 = original buffer ptr + +L0NotFound: + movq %rdi,%rax // buffer end... + subq %r10,%rax // ...minus start is buffer length + jz LScanSourceTo0 // buffer is null so cannot store a 0 + movb %dl,-1(%rdi) // store a 0 at end of buffer to delimit string + + +// Scan source to end. +// %rsi = ptr to rest of source +// %rax = return value so far + +LScanSourceTo0: + movzb (%rsi),%ecx // get next byte of source + incq %rsi + incq %rax // increment length + testl %ecx,%ecx // 0? + jnz LScanSourceTo0 + decq %rax // don't count the 0-byte + ret + + +// Buffer too short to reach end of even one 16-byte aligned chunk. +// %rsi = src ptr +// %r10 = original buffer ptr +// %r11 = original buffer length + +LShortBuf1: + movq %r10,%rdi // recover buffer ptr + movq %r11,%rdx // recover buffer length + jmp LShortBuf3 + + +// Out of aligned dq's of buffer, 0-byte still not found. +// %rsi = src ptr +// %rdi = ptr to 1st buffer byte not checked for 0 +// %rdx = length remaining - 16 +// %r10 = original buffer ptr +// %r11 = original buffer length + +LShortBuf2: + addq $16,%rdx // recover length remaining +LShortBuf3: + movq %r11,%rax // in case we goto LScanSourceTo0 + movl $17,%ecx // in case we goto LLoopOverBytes +1: + testq %rdx,%rdx // no 0s in buffer at all? + jz LScanSourceTo0 // yes, cannot store a 0 + cmpb $0,(%rdi) // is this the 0? + jz LLoopOverBytes // yes, append source + incq %rdi + decq %rdx + jmp 1b // loop looking for 0 diff --git a/x86_64/string/strlcpy.s b/x86_64/string/strlcpy.s new file mode 100644 index 0000000..6564dd2 --- /dev/null +++ b/x86_64/string/strlcpy.s @@ -0,0 +1,167 @@ +/* + * 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@ + */ + + +// ***************** +// * S T R L C P Y * +// ***************** +// +// size_t strlcpy(char *dst, const char *src, size_t size); +// +// We optimize the move by doing it quadword parallel. This introduces +// a complication: if we blindly did quadword load/stores until finding +// a 0, we might get a spurious page fault by touching bytes past it. +// To avoid this, we never do a load that crosses a page boundary, +// or store unnecessary bytes. +// +// The test for 0s relies on the following inobvious but very efficient +// word-parallel test: +// x = dataWord + 0xFEFEFEFF +// y = ~dataWord & 0x80808080 +// if (x & y) == 0 then no zero found +// The test maps any non-zero byte to zero, and any zero byte to 0x80, +// with one exception: 0x01 bytes preceeding the first zero are also +// mapped to 0x80. + + .text + .globl _strlcpy + +// When initially entered: +// %rdi = dest buffer ptr +// %rsi = source ptr +// %rdx = length + + .align 4 +_strlcpy: // size_t *strlcpy(char *dst, const char *src, size_t size); + movl %esi,%ecx // copy source ptr + movq %rdi,%r10 // copy dest ptr + negl %ecx + andl $7,%ecx // how many bytes to align source ptr? + jz LAligned // already aligned + + +// Loop over bytes. +// %rdi = dest ptr +// %rsi = source ptr +// %rdx = length remaining in buffer +// %ecx = number of bytes to copy (>0, may not fit in buffer) +// %r10 = original dest ptr + +LLoopOverBytes: + movzb (%rsi),%eax // get source byte before checking buffer length + testq %rdx,%rdx // buffer full? + jz L0NotFound // yes + incq %rsi + decq %rdx + movb %al,(%rdi) // pack into dest + incq %rdi + testl %eax,%eax // 0? + jz LDone // yes, done + decl %ecx // more to go? + jnz LLoopOverBytes + + +// Source is aligned. Loop over quadwords until end of buffer. We +// align the source, rather than the dest, to avoid getting spurious page faults. +// %rdi = dest ptr (unaligned) +// %rsi = source ptr (quadword aligned) +// %rdx = length remaining in buffer +// %r10 = original dest ptr + +LAligned: + movl $9,%ecx // if buffer almost exhausted, prepare to copy rest byte-by-byte + cmpq $8,%rdx // enough for at least one word? + jb LLoopOverBytes + movq $0xFEFEFEFEFEFEFEFF,%rcx // load magic constants + movq $0x8080808080808080,%r11 + + +// Loop over quadwords. +// %rdi = dest ptr (unaligned) +// %rsi = source ptr (word aligned) +// %rdx = length remaining in buffer (>=8) +// %rcx = 0xFEFEFEFEFEFEFEFF +// %r11 = 0x8080808080808080 +// %r10 = original dest ptr + +LLoopOverQuads: + movq (%rsi),%rax // get next 8 bytes of source + subq $8,%rdx + addq $8,%rsi + movq %rax,%r8 // make 2 copies of quadword + movq %rax,%r9 + notq %r8 // use magic word-parallel test for 0s + addq %rcx,%r9 + andq %r11,%r8 + testq %r8,%r9 + jnz L0Found // one of the bytes of %rax is a 0 + movq %rax,(%rdi) // pack 8 bytes into destination + addq $8,%rdi + cmpq $8,%rdx // room in buffer for another quadword? + jae LLoopOverQuads // yes + + movl %edx,%ecx // copy leftovers in byte loop + jmp LLoopOverBytes + +// Found a 0-byte in the quadword of source. Store a byte at a time until the 0. +// %rdi = dest ptr (unaligned) +// %rax = last quadword of source, known to have a 0-byte +// %r10 = original dest ptr + +LNextByte: + shrq $8,%rax // next byte +L0Found: + movb %al,(%rdi) // pack in next byte + incq %rdi + testb %al,%al // 0? + jnz LNextByte + +// Done storing string. +// %rdi = ptr to byte after 0-byte +// %r10 = original dest ptr + +LDone: + subq %r10,%rdi // subtract original dest ptr to get length stored + lea -1(%rdi),%rax // minus one for 0-byte, and move to return value + ret + +// Buffer filled but 0-byte not found. We return the length of the source string. +// This is not optimized, as it is an error condition. +// %rdi = dest ptr (ie, 1 past end of buffer) +// %rsi = source ptr (ptr to 1st byte that does not fit) +// %r10 = original dest ptr + +L0NotFound: + movq %rdi,%rax // end of buffer... + subq %r10,%rax // ...minus start is buffer length + jz 1f // 0-length buffer, cannot store a 0 + xorl %edx,%edx // get a 0 + movb %dl,-1(%rdi) // store a 0 at end of buffer to delimit string +1: + movzb (%rsi),%ecx // get next byte of source + incq %rsi + incq %rax + testl %ecx,%ecx // 0? + jnz 1b + decq %rax // don't count the 0-byte + ret diff --git a/x86_64/string/strlen.s b/x86_64/string/strlen.s index 51def0c..54ea653 100644 --- a/x86_64/string/strlen.s +++ b/x86_64/string/strlen.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005-2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -36,8 +36,8 @@ .align 4, 0x90 _strlen: // size_t strlen(char *b); pxor %xmm0,%xmm0 // zero %xmm0 - movq %rdi,%rcx // copy ptr - movq %rdi,%rdx // make another copy + movl %edi,%ecx // copy low half of ptr + movq %rdi,%rdx // make another full copy andq $(-16),%rdi // 16-byte align ptr orl $(-1),%eax pcmpeqb (%rdi),%xmm0 // check whole qw for 0s @@ -53,9 +53,8 @@ _strlen: // size_t strlen(char *b); LFoundIt: bsf %ecx,%eax // find first 1-bit (ie, first 0-byte) - movq %rdx,%rcx // recover ptr to 1st byte in string - addq %rdi,%rax // get address of the 0-byte - subq %rcx,%rax // subtract address of 1st byte to get string length + subq %rdx,%rdi // get length to start of 16-byte block while we wait + addq %rdi,%rax // add bytes in 16-byte block ret // Loop over aligned 16-byte blocks: diff --git a/x86_64/sys/Makefile.inc b/x86_64/sys/Makefile.inc index 792418f..04738a1 100644 --- a/x86_64/sys/Makefile.inc +++ b/x86_64/sys/Makefile.inc @@ -1,232 +1,11 @@ .PATH: ${.CURDIR}/x86_64/sys ${.CURDIR}/i386/sys AINC+= -I${.CURDIR}/x86_64/sys -MDSRCS+= ATPgetreq.s \ - ATPgetrsp.s \ - ATPsndreq.s \ - ATPsndrsp.s \ - ATgetmsg.s \ - ATputmsg.s \ - ATsocket.s \ - _exit.s \ - __fcntl.s \ - _getlogin.s \ - __ioctl.s \ - __mmap.s \ - _pthread_kill.s \ - __pthread_canceled.s \ - __pthread_markcancel.s \ - __semwait_signal.s \ - _setjmp.s \ - _setlogin.s \ - _sysctl.s \ - accept.s \ - access.s \ - acct.s \ - add_profil.s \ - adjtime.s \ - aio_cancel.s \ - aio_error.s \ - aio_fsync.s \ - aio_read.s \ - aio_return.s \ - aio_suspend.s \ - aio_write.s \ - audit.s \ - auditctl.s \ - auditon.s \ - bind.s \ - cerror.s \ - chdir.s \ - checkuseraccess.s \ - chflags.s \ - chmod.s \ - chown.s \ - commpage.c \ - chroot.s \ - close.s \ - connect.s \ - dup.s \ - dup2.s \ - exchangedata.s \ - execve.s \ - fchdir.s \ - fchflags.s \ - fchmod.s \ - fchown.s \ - fgetxattr.s \ - fhopen.s \ - flistxattr.s \ - flock.s \ - fork.s \ - fpathconf.s \ - fremovexattr.s \ - fsctl.s \ - fsetxattr.s \ - fstat.s \ - fstatfs.s \ - fstatv.s \ - fsync.s \ - ftruncate.s \ - futimes.s \ - getattrlist.s \ - getaudit.s \ - getaudit_addr.s \ - getauid.s \ - getdirentries.s \ - getdirentriesattr.s \ - getdtablesize.s \ - getegid.s \ - geteuid.s \ - getfh.s \ - getfsstat.s \ - getgid.s \ - getgroups.s \ - getitimer.s \ - getpeername.s \ - getpgid.s \ - getpgrp.s \ - getpid.s \ - getppid.s \ - getpriority.s \ - getrlimit.s \ - getrusage.s \ - getsid.s \ - getsockname.s \ - getsockopt.s \ - getuid.s \ - getxattr.s \ + +MDSRCS+= OSAtomic.s \ i386_gettimeofday.s \ - i386_get_ldt.s \ - i386_set_ldt.s \ - issetugid.s \ - kevent.s \ - kill.s \ - kqueue.s \ - kqueue_from_portset_np.s \ - kqueue_portset_np.s \ - ktrace.s \ - lchown.s \ - link.s \ - lio_listio.s \ - listen.s \ - listxattr.s \ - load_shared_file.s \ - lseek.s \ - lstat.s \ - lstatv.s \ - madvise.s \ - mincore.s \ - minherit.s \ - mkcomplex.s \ - mkdir.s \ - mkfifo.s \ - mknod.s \ - mlock.s \ - mlockall.s \ - mount.s \ - msgget.s \ - msgrcv.s \ - msgsnd.s \ - msgsys.s \ - munlock.s \ - munlockall.s \ - new_system_shared_regions.s \ - nfsclnt.s \ - nfssvc.s \ - open.s \ - OSAtomic.s \ - pathconf.s \ - pipe.s \ - poll.s \ - posix_madvise.s \ - pread.s \ - profil.s \ - pthread_sigmask.s \ - ptrace.s \ - pwrite.s \ - quota.s \ - quotactl.s \ - read.s \ - readlink.s \ - readv.s \ - reboot.s \ - recvfrom.s \ - recvmsg.s \ - removexattr.s \ - rename.s \ - reset_shared_file.s \ - revoke.s \ - rmdir.s \ - searchfs.s \ - select.s \ - sem_close.s \ - sem_destroy.s \ - sem_getvalue.s \ - sem_init.s \ - sem_post.s \ - sem_trywait.s \ - sem_wait.s \ - semget.s \ - semop.s \ - semsys.s \ - sendmsg.s \ - sendto.s \ - setattrlist.s \ - setaudit.s \ - setaudit_addr.s \ - setauid.s \ - setegid.s \ - seteuid.s \ - setgid.s \ - setgroups.s \ - setitimer.s \ + _setjmp.s \ setjmp.s \ - setpgid.s \ - setpriority.s \ - setprivexec.s \ - setquota.s \ - setrlimit.s \ - setsid.s \ - setsockopt.s \ - settimeofday.s \ - setuid.s \ - setxattr.s \ - shmat.s \ - shmdt.s \ - shmget.s \ - shmsys.s \ - shutdown.s \ - sigaltstack.s \ - sigpending.s \ - sigprocmask.s \ - sigreturn.s \ - sigwait.s \ - socket.s \ - socketpair.s \ - stat.s \ - statfs.s \ - statv.s \ - swapon.s \ - symlink.s \ - sync.s \ - syscall.s \ - systable.s \ - truncate.s \ - umask.s \ - undelete.s \ - unlink.s \ - unmount.s \ - utimes.s \ - vfork.s \ - wait4.s \ - write.s \ - writev.s - -MISRCS+= fcntl64.c ioctl64.c - -.for _src in fhopen.s getfh.s nfsclnt.s -CFLAGS-${_src} += -DNFSCLIENT -.endfor + _sigtramp.s -CFLAGS-nfssvc.s += -DNFSSERVER +MDCOPYFILES+= ${.CURDIR}/x86_64/sys/libc.syscall.x86_64 diff --git a/x86_64/sys/OSAtomic.s b/x86_64/sys/OSAtomic.s index 1d3f778..b4c5e9c 100644 --- a/x86_64/sys/OSAtomic.s +++ b/x86_64/sys/OSAtomic.s @@ -1,4 +1,5 @@ /* + * Copyright (c) 2007 Apple Inc. All rights reserved. * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ @@ -81,19 +82,72 @@ DECLARE(_OSAtomicXor32) 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 + 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 + 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 + 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 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 sete %al + movzbl %al,%eax // widen in case caller assumes we return an int ret @@ -121,6 +175,7 @@ DECLARE(_OSAtomicTestAndSet) 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 ret @@ -130,12 +185,15 @@ DECLARE(_OSAtomicTestAndClear) 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 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 @@ -143,7 +201,11 @@ _OSSpinLockTry: // 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 @@ -151,7 +213,11 @@ _OSSpinLockLock: // void OSSpinLockUnlock( OSSpinLock *lock ); .align 2, 0x90 .globl _OSSpinLockUnlock + .globl _spin_unlock + .globl __spin_unlock _OSSpinLockUnlock: +_spin_unlock: +__spin_unlock: movl $0, (%rdi) ret @@ -160,4 +226,53 @@ _OSSpinLockUnlock: .align 2, 0x90 .globl _OSMemoryBarrier _OSMemoryBarrier: + movq $(_COMM_PAGE_MEMORY_BARRIER), %rax + jmp *%rax + + +/* + * 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: // %rdi == list head, %rsi == new, %rdx == offset + pushq %rbx + movq %rsi,%rbx // %rbx == new + movq %rdx,%rsi // %rsi == offset + movq (%rdi),%rax // %rax == ptr to 1st element in Q + movq 8(%rdi),%rdx // %rdx == current generation count +1: + movq %rax,(%rbx,%rsi)// link to old list head from new element + movq %rdx,%rcx + incq %rcx // increment generation count + lock // always lock for now... + cmpxchg16b (%rdi) // ...push on new element + jnz 1b + popq %rbx ret + + +/* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */ + .align 2 + .globl _OSAtomicDequeue +_OSAtomicDequeue: // %rdi == list head, %rsi == offset + pushq %rbx + movq (%rdi),%rax // %rax == ptr to 1st element in Q + movq 8(%rdi),%rdx // %rdx == current generation count +1: + testq %rax,%rax // list empty? + jz 2f // yes + movq (%rax,%rsi),%rbx // point to 2nd in Q + movq %rdx,%rcx + incq %rcx // increment generation count + lock // always lock for now... + cmpxchg16b (%rdi) // ...pop off 1st element + jnz 1b +2: + popq %rbx + ret // ptr to 1st element in Q still in %rax diff --git a/x86_64/sys/SYS.h b/x86_64/sys/SYS.h index dbe69be..da953ca 100644 --- a/x86_64/sys/SYS.h +++ b/x86_64/sys/SYS.h @@ -77,32 +77,3 @@ LEAF(_##name, 0) ;\ #define PSEUDO(pseudo, name, nargs) \ LEAF(_##pseudo, 0) ;\ UNIX_SYSCALL_NONAME(name, nargs) - -#if !defined(SYS_getdirentriesattr) -#define SYS_getdirentriesattr 222 -#endif - -#if !defined(SYS_semsys) -#define SYS_semsys 251 -#define SYS_msgsys 252 -#define SYS_shmsys 253 -#define SYS_semctl 254 -#define SYS_semget 255 -#define SYS_semop 256 -/*#define SYS_semconfig 257*/ -#define SYS_msgctl 258 -#define SYS_msgget 259 -#define SYS_msgsnd 260 -#define SYS_msgrcv 261 -#define SYS_shmat 262 -#define SYS_shmctl 263 -#define SYS_shmdt 264 -#define SYS_shmget 265 -#endif - -#if !defined(SYS___pthread_canceled) -#define SYS___pthread_markcancel 332 -#define SYS___pthread_canceled 333 -#define SYS___semwait_signal 334 -#endif - diff --git a/x86_64/sys/_sigtramp.s b/x86_64/sys/_sigtramp.s new file mode 100644 index 0000000..bb1eebf --- /dev/null +++ b/x86_64/sys/_sigtramp.s @@ -0,0 +1,249 @@ +/* + * 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 + +#define UC_TRAD 1 +#define UC_FLAVOR 30 + +/* Structure fields for ucontext and mcontext. */ +#define UCONTEXT_UC_MCONTEXT 48 + +#define MCONTEXT_ES_EXCEPTION 0 +#define MCONTEXT_SS_RAX 16 +#define MCONTEXT_SS_RBX 24 +#define MCONTEXT_SS_RCX 32 +#define MCONTEXT_SS_RDX 40 +#define MCONTEXT_SS_RDI 48 +#define MCONTEXT_SS_RSI 56 +#define MCONTEXT_SS_RBP 64 +#define MCONTEXT_SS_RSP 72 +#define MCONTEXT_SS_R8 80 +#define MCONTEXT_SS_RIP 144 + +/* register use: + %rbx uctx + +void +_sigtramp( + union __sigaction_u __sigaction_u, %rdi + int sigstyle, %rsi + int sig, %rdx + siginfo_t *sinfo, %rcx + ucontext_t *uctx %r8 +) +*/ + + .globl __sigtramp + .text + .align 4,0x90 +__sigtramp: + /* Although this routine does not need any stack frame, various parts + of the OS can't analyse the stack without them. */ + pushq %rbp + movq %rsp, %rbp + + movq %rdi, %rax # set up address for call + +#if defined(__DYNAMIC__) + incl ___in_sigtramp(%rip) +#endif + /* Save uctx in %rbx. */ + movq %r8, %rbx + /* Call the signal handler. + Some variants are not supposed to get the last two parameters, + but the test to prevent this is more expensive than just passing + them. */ + movl %edx, %edi + movq %rcx, %rsi + movq %r8, %rdx +Lcall_start: + call *%rax +Lcall_end: +#if defined(__DYNAMIC__) + decl ___in_sigtramp(%rip) +#endif + movq %rbx, %rdi + movl $ UC_FLAVOR, %esi + jmp ___sigreturn + +/* DWARF unwind table #defines. */ +#define DW_CFA_advance_loc_4 0x44 +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_def_cfa_expression 0x0F +#define DW_CFA_expression 0x10 +#define DW_CFA_val_expression 0x16 +#define DW_CFA_offset(column) 0x80+(column) + +/* DWARF expression #defines. */ +#define DW_OP_deref 0x06 +#define DW_OP_const1u 0x08 +#define DW_OP_dup 0x12 +#define DW_OP_drop 0x13 +#define DW_OP_over 0x14 +#define DW_OP_pick 0x15 +#define DW_OP_swap 0x16 +#define DW_OP_rot 0x17 +#define DW_OP_abs 0x19 +#define DW_OP_and 0x1a +#define DW_OP_div 0x1b +#define DW_OP_minus 0x1c +#define DW_OP_mod 0x1d +#define DW_OP_mul 0x1e +#define DW_OP_neg 0x1f +#define DW_OP_not 0x20 +#define DW_OP_or 0x21 +#define DW_OP_plus 0x22 +#define DW_OP_plus_uconst 0x23 +#define DW_OP_shl 0x24 +#define DW_OP_shr 0x25 +#define DW_OP_shra 0x26 +#define DW_OP_xor 0x27 +#define DW_OP_skip 0x2f +#define DW_OP_bra 0x28 +#define DW_OP_eq 0x29 +#define DW_OP_ge 0x2A +#define DW_OP_gt 0x2B +#define DW_OP_le 0x2C +#define DW_OP_lt 0x2D +#define DW_OP_ne 0x2E +#define DW_OP_lit(n) 0x30+(n) +#define DW_OP_breg(n) 0x70+(n) +#define DW_OP_deref_size 0x94 + +/* The location expression we'll use. */ + +#define loc_expr_for_reg(regno, offs) \ + .byte DW_CFA_expression, regno, 5 /* block length */, \ + DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \ + DW_OP_plus_uconst, offs + +/* For r8 through r13 */ +#define loc_expr_rN(regno) \ + loc_expr_for_reg(regno, MCONTEXT_SS_R8+(8*(regno-8))) + +/* For r14 through r15 */ +#define loc_expr_rN_long(regno) \ + .byte DW_CFA_expression, regno, 6 /* block length */, \ + DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \ + DW_OP_plus_uconst, MCONTEXT_SS_R8+(8*(regno-8)), 1 + + /* Unwind tables. */ + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .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 # uleb128 0x1; CIE Code Alignment Factor + .byte 0x78 # sleb128 -8; CIE Data Alignment Factor + .byte 0x10 # CIE RA Column + .byte 0x1 # uleb128 0x1; Augmentation size + .byte 0x10 # FDE Encoding (pcrel) + .byte DW_CFA_def_cfa + .byte 0x7 # uleb128 0x5 + .byte 0x8 # uleb128 0x4 + .byte DW_CFA_offset(16) + .byte 0x1 # uleb128 0x1 + .align 3 +LECIE1: + .globl _sigtramp.eh +_sigtramp.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .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 L$set$2 # FDE address range + .byte 0x0 # uleb128 0x0; Augmentation size + + /* Now for the expressions, which all compute + uctx->uc_mcontext->register + for each register. + + Describe even the registers that are not call-saved because they + might be being used in the prologue to save other registers. + Only integer registers are described at present. */ + + loc_expr_for_reg (0, MCONTEXT_SS_RAX) + loc_expr_for_reg (1, MCONTEXT_SS_RBX) + loc_expr_for_reg (2, MCONTEXT_SS_RCX) + loc_expr_for_reg (3, MCONTEXT_SS_RDX) + loc_expr_for_reg (4, MCONTEXT_SS_RSI) + loc_expr_for_reg (5, MCONTEXT_SS_RDI) + loc_expr_for_reg (6, MCONTEXT_SS_RBP) + loc_expr_for_reg (7, MCONTEXT_SS_RSP) + loc_expr_rN (8) + loc_expr_rN (9) + loc_expr_rN (10) + loc_expr_rN (11) + loc_expr_rN (12) + loc_expr_rN (13) + loc_expr_rN_long (14) + loc_expr_rN_long (15) + + /* The Intel architecture classifies exceptions into three categories, + 'faults' which put the address of the faulting instruction + in EIP, 'traps' which put the following instruction in EIP, + and 'aborts' which don't typically report the instruction + causing the exception. + + The traps are #BP and #OF. */ + + .byte DW_CFA_val_expression, 16 + .set L$set$3,Lpc_end-Lpc_start + .byte L$set$3 +Lpc_start: + /* Push the mcontext address twice. */ + .byte DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, DW_OP_dup + /* Find the value of EIP. */ + .byte DW_OP_plus_uconst, MCONTEXT_SS_RIP, MCONTEXT_SS_RIP >> 7 + .byte DW_OP_deref, DW_OP_swap + /* Determine the exception type. */ + .byte DW_OP_plus_uconst, MCONTEXT_ES_EXCEPTION, DW_OP_deref_size, 4 + /* Check whether it is #BP (3) or #OF (4). */ + .byte DW_OP_dup, DW_OP_lit(3), DW_OP_ne + .byte DW_OP_swap, DW_OP_lit(4), DW_OP_ne, DW_OP_and + /* If it is not, then add 1 to the instruction address, so as to point + within or past the faulting instruction. */ + .byte DW_OP_plus +Lpc_end: + + /* The CFA will have been saved as the value of RSP (it is not + RSP+8). */ + .byte DW_CFA_def_cfa_expression + .set L$set$4,Lcfa_end-Lcfa_start + .byte L$set$4 +Lcfa_start: + .byte DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref + .byte DW_OP_plus_uconst, MCONTEXT_SS_RSP, DW_OP_deref +Lcfa_end: + + .align 3 +LEFDE1: + + .subsections_via_symbols diff --git a/x86_64/sys/cerror.s b/x86_64/sys/cerror.s deleted file mode 100644 index 1f7d10d..0000000 --- a/x86_64/sys/cerror.s +++ /dev/null @@ -1,47 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - - .globl _errno - -LABEL(cerror_cvt) - cmpq $102, %rax /* EOPNOTSUPP? */ - jnz cerror - movl $45, %eax /* Yes; make ENOTSUP for compatibility */ -LABEL(cerror) - REG_TO_EXTERN(%rax, _errno) - mov %rsp,%rdx - andq $-16,%rsp - subq $16,%rsp - // Preserve the original stack - movq %rdx,(%rsp) - movq %rax,%rdi - CALL_EXTERN(_cthread_set_errno_self) - // Restore the original stack - movq (%rsp),%rsp - movq $-1,%rax - movq $-1,%rdx /* in case a 128-bit value is returned */ - ret diff --git a/x86_64/sys/fork.s b/x86_64/sys/fork.s deleted file mode 100644 index 3fe1c1e..0000000 --- a/x86_64/sys/fork.s +++ /dev/null @@ -1,131 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -LEAF(_fork, 0) - subq $24, %rsp // Align the stack, plus room for local storage - CALL_EXTERN(__cthread_fork_prepare) -#if defined(__DYNAMIC__) -// Just like __cthread_fork_prepare we need to prevent threads on the child's -// side from doing a mach call in the dynamic linker until __dyld_fork_child -// is run (see below). So we call __dyld_fork_prepare which takes out the dyld -// lock to prevent all other threads but this one from entering dyld. -.cstring -LC1: - .ascii "__dyld_fork_prepare\0" -.text - // Give a pointer to 8(%rsp) to _dyld_func_lookup for it to fill in. - leaq 8(%rsp),%rsi // get the address where we're going to store the pointer - leaq LC1(%rip), %rdi // copy the name of the function to look up - call __dyld_func_lookup - movq 8(%rsp),%rax // move the value returned in address parameter - call *%rax // call __dyld_fork_prepare -#endif - - movl $ SYSCALL_CONSTRUCT_UNIX(SYS_fork),%eax; // code for fork -> rax - UNIX_SYSCALL_TRAP // do the system call - jnc L1 // jump if CF==0 - -#if defined(__DYNAMIC__) -// __dyld_fork_parent() is called by the parent process after a fork syscall. -// This releases the dyld lock acquired by __dyld_fork_prepare(). In this case -// we just use it to clean up after a fork error so the parent process can -// dyld after fork() errors without deadlocking. -.cstring -LC2: - .ascii "__dyld_fork_parent\0" -.text - movq %rax, 16(%rsp) // save the return value (errno) - leaq 8(%rsp),%rsi // get the address where we're going to store the pointer - leaq LC2(%rip), %rdi // copy the name of the function to look up - call __dyld_func_lookup - call *8(%rsp) // call __dyld_fork_parent indirectly - movq 16(%rsp), %rax // restore the return value (errno) -#endif - CALL_EXTERN(cerror) - CALL_EXTERN(__cthread_fork_parent) - movq $-1, %rax - addq $24, %rsp // restore the stack - ret - -L1: - orl %edx,%edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child - - //child here... -#if defined(__DYNAMIC__) -// Here on the child side of the fork we need to tell the dynamic linker that -// we have forked. To do this we call __dyld_fork_child in the dyanmic -// linker. But since we can't dynamically bind anything until this is done we -// do this by using the private extern __dyld_func_lookup() function to get the -// address of __dyld_fork_child (the 'C' code equivlent): -// -// _dyld_func_lookup("__dyld_fork_child", &address); -// address(); -// -.cstring -LC0: - .ascii "__dyld_fork_child\0" - -.text - leaq 8(%rsp),%rsi // get the address where we're going to store the pointer - leaq LC0(%rip), %rdi // copy the name of the function to look up - call __dyld_func_lookup - call *8(%rsp) // call __dyld_fork_child indirectly -#endif - xorq %rax, %rax - REG_TO_EXTERN(%rax, __current_pid) - CALL_EXTERN(__cthread_fork_child) -#if defined(__DYNAMIC__) -.cstring -LC10: - .ascii "__dyld_fork_child_final\0" - -.text - leaq 8(%rsp),%rsi // get the address where we're going to store the pointer - leaq LC10(%rip), %rdi // copy the name of the function to look up - call __dyld_func_lookup - call *8(%rsp) // call __dyld_fork_child_final indirectly -#endif - xorq %rax,%rax // zero rax - addq $24, %rsp // restore the stack - ret - - //parent here... -L2: - movl %eax, 16(%rsp) // save pid -#if defined(__DYNAMIC__) -// __dyld_fork_parent() is called by the parent process after a fork syscall. -// This releases the dyld lock acquired by __dyld_fork_prepare(). - leaq 8(%rsp),%rsi // get the address where we're going to store the pointer - leaq LC2(%rip), %rdi // copy the name of the function to look up - call __dyld_func_lookup - call *8(%rsp) // call __dyld_fork_parent indirectly -#endif - CALL_EXTERN_AGAIN(__cthread_fork_parent) - movl 16(%rsp), %eax // return pid - addq $24, %rsp // restore the stack - ret diff --git a/x86_64/sys/i386_gettimeofday.s b/x86_64/sys/i386_gettimeofday.s index 678ebf9..5b8932f 100644 --- a/x86_64/sys/i386_gettimeofday.s +++ b/x86_64/sys/i386_gettimeofday.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -31,13 +31,3 @@ LABEL(___commpage_gettimeofday) movq $(_COMM_PAGE_GETTIMEOFDAY),%rax jmp *%rax - -/* - * This syscall is special cased: the timeval is returned in rax:rdx. - */ -LABEL(___gettimeofday) - UNIX_SYSCALL_NONAME(gettimeofday,0) - movq %rax, (%rdi) - movl %edx, 8(%rdi) - xorl %eax, %eax - ret diff --git a/x86_64/sys/libc.syscall.x86_64 b/x86_64/sys/libc.syscall.x86_64 new file mode 100644 index 0000000..0c660de --- /dev/null +++ b/x86_64/sys/libc.syscall.x86_64 @@ -0,0 +1,25 @@ +_accept$NOCANCEL ___accept_nocancel +_aio_suspend$NOCANCEL ___aio_suspend_nocancel +_close$NOCANCEL ___close_nocancel +_connect$NOCANCEL ___connect_nocancel +_fsync$NOCANCEL ___fsync_nocancel +_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 +_waitid$NOCANCEL ___waitid_nocancel +_write$NOCANCEL ___write_nocancel +_writev$NOCANCEL ___writev_nocancel diff --git a/x86_64/sys/lseek.s b/x86_64/sys/lseek.s deleted file mode 100644 index f99bab2..0000000 --- a/x86_64/sys/lseek.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(lseek, 3) - ret diff --git a/x86_64/sys/pipe.s b/x86_64/sys/pipe.s deleted file mode 100644 index 5864575..0000000 --- a/x86_64/sys/pipe.s +++ /dev/null @@ -1,32 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(pipe, 0) - movl %eax, (%rdi) - movl %edx, 4(%rdi) - xorl %eax, %eax - ret diff --git a/x86_64/sys/ptrace.s b/x86_64/sys/ptrace.s deleted file mode 100644 index 6119772..0000000 --- a/x86_64/sys/ptrace.s +++ /dev/null @@ -1,34 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - - .globl _errno - -LEAF(_ptrace, 0) - xorq %rax,%rax - REG_TO_EXTERN(%rax,_errno) -UNIX_SYSCALL_NONAME(ptrace, 4) - ret diff --git a/x86_64/sys/setjmp.s b/x86_64/sys/setjmp.s index 05ca533..5866086 100644 --- a/x86_64/sys/setjmp.s +++ b/x86_64/sys/setjmp.s @@ -72,10 +72,11 @@ LEAF(_setjmp, 0) pushq %rdi // Preserve the jmp_buf across the call movl $1, %edi // how = SIG_BLOCK xorq %rsi, %rsi // set = NULL - subq $8, %rsp // Allocate space for the return from sigprocmask - movq %rsp, %rdx + subq $16, %rsp // Allocate space for the return from sigprocmask + 8 to align stack + movq %rsp, %rdx // oset = allocated space CALL_EXTERN(_sigprocmask) popq %rax // Save the mask + addq $8, %rsp // Restore the stack to before we align it popq %rdi // jmp_buf (struct sigcontext *) movq %rax, JB_MASK(%rdi) L_do__setjmp: @@ -93,8 +94,8 @@ LEAF(_longjmp, 0) pushq %rsi // Preserve the value across the call pushq JB_MASK(%rdi) // Put the mask on the stack movq $3, %rdi // how = SIG_SETMASK - movq %rsp, %rsi // set = address where we stored the mask - xorq %rdx, %rdx // oset = NULL + movq %rsp, %rsi // set = address where we stored the mask + xorq %rdx, %rdx // oset = NULL CALL_EXTERN_AGAIN(_sigprocmask) addq $8, %rsp popq %rsi // Restore the value diff --git a/x86_64/sys/sigaltstack.s b/x86_64/sys/sigaltstack.s deleted file mode 100644 index 819bb61..0000000 --- a/x86_64/sys/sigaltstack.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(sigaltstack, 3) - ret diff --git a/x86_64/sys/sigreturn.s b/x86_64/sys/sigreturn.s deleted file mode 100644 index 2c140b5..0000000 --- a/x86_64/sys/sigreturn.s +++ /dev/null @@ -1,29 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -UNIX_SYSCALL(sigreturn, 2) - ret diff --git a/x86_64/sys/syscall.s b/x86_64/sys/syscall.s deleted file mode 100644 index cc34346..0000000 --- a/x86_64/sys/syscall.s +++ /dev/null @@ -1,32 +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) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -// For x86-64, the kernel slides the argument list for us. -// The number of arguments here is variable, but our macros ignore -// that value anyway. -UNIX_SYSCALL(syscall, 0); - ret diff --git a/x86_64/sys/vfork.s b/x86_64/sys/vfork.s deleted file mode 100644 index 05229ef..0000000 --- a/x86_64/sys/vfork.s +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 1999-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@ - */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include - -/* - * If __current_pid >= 0, we want to put a -1 in there - * otherwise we just decrement it - */ - -LEAF(_vfork, 0) - movq __current_pid@GOTPCREL(%rip), %rax - movl (%rax), %eax -0: - xorl %ecx, %ecx - testl %eax, %eax - cmovs %eax, %ecx - subl $1, %ecx - movq __current_pid@GOTPCREL(%rip), %rdx - lock - cmpxchgl %ecx, (%rdx) - jne 0b - popq %rdi // return address in %rdi - movq $ SYSCALL_CONSTRUCT_UNIX(SYS_vfork), %rax // code for vfork -> rax - UNIX_SYSCALL_TRAP // do the system call - jnb L1 // jump if CF==0 - movq __current_pid@GOTPCREL(%rip), %rcx - lock - addq $1, (%rcx) - movq (%rcx), %rdi - BRANCH_EXTERN(cerror) - -L1: - testl %edx, %edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child - xorq %rax, %rax // zero rax - jmp *%rdi - -L2: - movq __current_pid@GOTPCREL(%rip), %rdx - lock - addq $1, (%rdx) - jmp *%rdi diff --git a/xdr/Makefile.inc b/xdr/Makefile.inc deleted file mode 100644 index d75da0d..0000000 --- a/xdr/Makefile.inc +++ /dev/null @@ -1,52 +0,0 @@ -# @(#)Makefile 5.11 (Berkeley) 9/6/90 -# $FreeBSD: src/lib/libc/xdr/Makefile.inc,v 1.12 2001/03/27 17:26:57 ru Exp $ - -.PATH: ${.CURDIR}/../libc/xdr ${.CURDIR}/. -MISRCS+= xdr.c xdr_array.c xdr_float.c xdr_mem.c \ - xdr_rec.c xdr_reference.c xdr_stdio.c - -.if ${LIB} == "c" -MAN+= xdr.3 - -MLINKS+= rpc_xdr.3 xdr_accepted_reply.3 \ - rpc_xdr.3 xdr_authsys_parms.3 \ - rpc_xdr.3 xdr_callhdr.3 \ - rpc_xdr.3 xdr_callmsg.3 \ - rpc_xdr.3 xdr_opaque_auth.3 \ - rpc_xdr.3 xdr_rejected_reply.3 \ - rpc_xdr.3 xdr_replymsg.3 \ - xdr.3 xdr_array.3 \ - xdr.3 xdr_bool.3 \ - xdr.3 xdr_bytes.3 \ - xdr.3 xdr_char.3 \ - xdr.3 xdr_destroy.3 \ - xdr.3 xdr_double.3 \ - xdr.3 xdr_enum.3 \ - xdr.3 xdr_float.3 \ - xdr.3 xdr_free.3 \ - xdr.3 xdr_getpos.3 \ - xdr.3 xdr_inline.3 \ - xdr.3 xdr_int.3 \ - xdr.3 xdr_long.3 \ - xdr.3 xdrmem_create.3 \ - xdr.3 xdr_opaque.3 \ - xdr.3 xdr_pointer.3 \ - xdr.3 xdrrec_create.3 \ - xdr.3 xdrrec_endofrecord.3 \ - xdr.3 xdrrec_eof.3 \ - xdr.3 xdrrec_skiprecord.3 \ - xdr.3 xdr_reference.3 \ - xdr.3 xdr_setpos.3 \ - xdr.3 xdr_short.3 \ - xdr.3 xdrstdio_create.3 \ - xdr.3 xdr_short.3 \ - xdr.3 xdrstdio_create.3 \ - xdr.3 xdr_string.3 \ - xdr.3 xdr_u_char.3 \ - xdr.3 xdr_u_long.3 \ - xdr.3 xdr_u_short.3 \ - xdr.3 xdr_union.3 \ - xdr.3 xdr_vector.3 \ - xdr.3 xdr_void.3 \ - xdr.3 xdr_wrapstring.3 -.endif diff --git a/yp/Makefile.inc b/yp/Makefile.inc deleted file mode 100644 index 09c8b06..0000000 --- a/yp/Makefile.inc +++ /dev/null @@ -1,17 +0,0 @@ -# from: @(#)Makefile.inc 5.3 (Berkeley) 2/20/91 -# $FreeBSD: src/lib/libc/yp/Makefile.inc,v 1.8 1999/08/28 00:02:58 peter Exp $ - -# yp sources -.PATH: ${.CURDIR}/../libc/yp - -MISRCS+= xdryp.c yp.h yp_xdr.c yplib.c -CLEANFILES+= yp.h yp_xdr.c - -RPCSRC= ${DESTDIR}/usr/include/rpcsvc/yp.x -RPCGEN= rpcgen -C - -yp_xdr.c: ${RPCSRC} - ${RPCGEN} -c -o ${.TARGET} ${RPCSRC} - -yp.h: ${RPCSRC} - ${RPCGEN} -h -o ${.TARGET} ${RPCSRC} -- 2.45.2